#!/usr/bin/env python3 """ Generate 1,000 Problem→Solution training pairs for Frontend & Creative code patterns. Part of timmy-config#595: Code Patterns: Frontend & Creative — 1K Problem→Solution Pairs. Domains covered: - Three.js: scenes, geometry, materials, lighting, camera, animation - HTML/CSS/JS: DOM manipulation, events, styling, responsive design - Playground UI: sovereign-first interactive components - Gallery: image grids, lightboxes, masonry layouts - Games: canvas rendering, game loops, simple mechanics Usage: python scripts/generate_code_patterns_frontend_creative.py python scripts/generate_code_patterns_frontend_creative.py --output /path/to/output.jsonl """ from __future__ import annotations import argparse import json import random from pathlib import Path random.seed(595) # ============================================================ # Three.js Templates # ============================================================ THREEJS_TEMPLATES = [ # Scene setup { "problem": "Set up a Three.js scene with a renderer, camera, and animation loop.", "solution": "function initThreeJS(container: HTMLElement) {\n const scene = new THREE.Scene();\n scene.background = new THREE.Color(0x0a0a0a);\n\n const camera = new THREE.PerspectiveCamera(\n 75,\n container.clientWidth / container.clientHeight,\n 0.1,\n 1000\n );\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n function animate() {\n requestAnimationFrame(animate);\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-scene", }, # Geometry — sphere with wireframe { "problem": "Create a Three.js sphere with custom segment counts and a wireframe overlay.", "solution": "function createSphereWithWireframe(radius = 1, segments = 32) {\n const sphereGeom = new THREE.SphereGeometry(radius, segments, segments);\n const sphereMat = new THREE.MeshStandardMaterial({\n color: 0x4a90d9,\n roughness: 0.3,\n metalness: 0.7,\n });\n const sphere = new THREE.Mesh(sphereGeom, sphereMat);\n\n const wireframe = new THREE.LineSegments(\n new THREE.WireframeGeometry(sphereGeom),\n new THREE.LineBasicMaterial({ color: 0xffffff, opacity: 0.3, transparent: true })\n );\n sphere.add(wireframe);\n\n return sphere;\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-geometry", }, # Materials — PBR { "problem": "Apply a physically-based material with environment mapping to a Three.js object.", "solution": "function createReflectiveMaterial(envMap: THREE.CubeTexture) {\n return new THREE.MeshStandardMaterial({\n color: 0xffffff,\n metalness: 1.0,\n roughness: 0.1,\n envMap: envMap,\n envMapIntensity: 1.0,\n });\n}\n\n// Usage\nconst material = createReflectiveMaterial(cubeTexture);\nconst mesh = new THREE.Mesh(geometry, material);", "imports": "import * as THREE from 'three';", "domain": "threejs-materials", }, # --- Lighting --- { "problem": "Create a Three.js lighting setup with ambient, directional, and point lights.", "solution": "function setupLighting(scene: THREE.Scene) {\n const ambient = new THREE.AmbientLight(0x404040, 0.5);\n scene.add(ambient);\n\n const directional = new THREE.DirectionalLight(0xffffff, 1.0);\n directional.position.set(5, 10, 7);\n directional.castShadow = true;\n directional.shadow.mapSize.width = 2048;\n directional.shadow.mapSize.height = 2048;\n scene.add(directional);\n\n const point = new THREE.PointLight(0xff9000, 0.8, 20);\n point.position.set(-3, 2, 3);\n scene.add(point);\n\n return { ambient, directional, point };\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-lighting", }, # --- Camera OrbitControls --- { "problem": "Implement OrbitControls camera with constrained polar angles and smooth damping.", "solution": "function setupOrbitControls(camera: THREE.PerspectiveCamera, domElement: HTMLElement) {\n const controls = new THREE.OrbitControls(camera, domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n controls.minDistance = 2;\n controls.maxDistance = 20;\n controls.maxPolarAngle = Math.PI / 2;\n controls.minPolarAngle = Math.PI / 6;\n controls.enablePan = false;\n return controls;\n}", "imports": "import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';", "domain": "threejs-camera", }, # --- Delta-time rotation --- { "problem": "Create a smooth Three.js rotation animation using delta time.", "solution": "class RotatingObject {\n mesh: THREE.Mesh;\n speed: number;\n\n constructor(mesh: THREE.Mesh, rotationsPerSecond = 0.5) {\n this.mesh = mesh;\n this.speed = rotationsPerSecond * Math.PI * 2;\n }\n\n update(deltaSec: number) {\n this.mesh.rotation.y += this.speed * deltaSec;\n }\n}\n\n// In render loop:\nconst rotor = new RotatingObject(sphere, 0.25);\nlet last = performance.now();\nfunction animate(time: number) {\n const delta = (time - last) / 1000;\n last = time;\n rotor.update(delta);\n renderer.render(scene, camera);\n requestAnimationFrame(animate);\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-animation", }, # --- Texture loading async --- { "problem": "Load a Three.js texture asynchronously with proper error handling.", "solution": "async function loadTexture(url: string): Promise {\n const loader = new THREE.TextureLoader();\n try {\n return await new Promise((resolve, reject) => {\n loader.load(url, resolve, undefined, reject);\n });\n } catch (err) {\n console.error('Texture load failed:', url, err);\n throw err;\n }\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-textures", }, # --- Rounded box --- { "problem": "Create a rounded-box Three.js geometry using RoundedBoxGeometry.", "solution": "function createRoundedBox(width = 1, height = 1, depth = 1, segments = 2, radius = 0.1) {\n const geom = new THREE.RoundedBoxGeometry(width, height, depth, segments, radius);\n const mat = new THREE.MeshStandardMaterial({ color: 0x2ecc71 });\n return new THREE.Mesh(geom, mat);\n}", "imports": "import { RoundedBoxGeometry } from 'three/examples/jsm/geometries/RoundedBoxGeometry.js';", "domain": "threejs-geometry", }, # --- Fog --- { "problem": "Add depth fog to a Three.js scene for atmospheric perspective.", "solution": "function addFog(scene: THREE.Scene, color = 0x0a0a0a, near = 10, far = 50) {\n scene.fog = new THREE.Fog(color, near, far);\n scene.background = new THREE.Color(color);\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-scene", }, # --- ShaderMaterial --- { "problem": "Create a Three.js ShaderMaterial with uniform updates in the render loop.", "solution": "function createGlowShader() {\n return new THREE.ShaderMaterial({\n uniforms: {\n uTime: { value: 0 },\n uColor: { value: new THREE.Color(0x00ffff) },\n },\n vertexShader: `\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `,\n fragmentShader: `\n uniform float uTime;\n uniform vec3 uColor;\n varying vec2 vUv;\n void main() {\n float pulse = 0.5 + 0.5 * sin(uTime * 2.0);\n gl_FragColor = vec4(uColor * pulse, 1.0);\n }\n `,\n transparent: true,\n });\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-materials", }, # --- Group hierarchy --- { "problem": "Organize Three.js objects into a hierarchical group with local transforms.", "solution": "function createVehicleGroup() {\n const chassis = new THREE.Mesh(\n new THREE.BoxGeometry(2, 0.5, 4),\n new THREE.MeshStandardMaterial({ color: 0x333333 })\n );\n\n const wheels = new THREE.Group();\n const positions = [[-1, -0.3, -1.2], [1, -0.3, -1.2], [-1, -0.3, 1.2], [1, -0.3, 1.2]];\n positions.forEach(([x, y, z]) => {\n const wheel = new THREE.Mesh(\n new THREE.CylinderGeometry(0.3, 0.3, 0.2, 16),\n new THREE.MeshStandardMaterial({ color: 0x111111 })\n );\n wheel.rotation.z = Math.PI / 2;\n wheel.position.set(x, y, z);\n wheels.add(wheel);\n });\n\n const group = new THREE.Group();\n group.add(chassis);\n group.add(wheels);\n return group;\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-scene", }, # --- Raycasting --- { "problem": "Implement Three.js raycaster click picking with object metadata.", "solution": "function setupRaycaster(camera: THREE.Camera, dom: HTMLElement) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n dom.addEventListener('click', (e) => {\n const rect = dom.getBoundingClientRect();\n mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n if (intersects.length > 0) {\n const hit = intersects[0].object;\n console.log('Clicked:', hit.userData.name || hit.uuid);\n }\n });\n\n return raycaster;\n}", "imports": "import * as THREE from 'three';", "domain": "threejs-interaction", }, ] # ============================================================ # HTML/CSS/JS Templates # ============================================================ HTML_CSS_JS_TEMPLATES = [ # --- DOM element creation --- { "problem": "Create a DOM element with multiple classes and attributes in vanilla JavaScript.", "solution": "function createElement(tag: string, classes: string[] = [], attrs: Record = {}, children: Node[] = []) {\n const el = document.createElement(tag);\n el.classList.add(...classes);\n for (const [key, value] of Object.entries(attrs)) {\n el.setAttribute(key, value);\n }\n for (const child of children) {\n el.appendChild(child);\n }\n return el;\n}\n\n// Usage\nconst button = createElement('button', ['btn', 'btn-primary'], { 'aria-label': 'Submit' }, [\n document.createTextNode('Submit')\n]);", "imports": "", "domain": "html-dom", }, # --- Event delegation --- { "problem": "Implement event delegation for dynamic button clicks with proper type checking.", "solution": "function setupEventDelegation(container: HTMLElement) {\n container.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (!target.matches('button[data-action]')) return;\n\n const action = target.getAttribute('data-action');\n switch (action) {\n case 'save':\n handleSave();\n break;\n case 'delete':\n handleDelete();\n break;\n default:\n console.warn('Unknown action:', action);\n }\n });\n}", "imports": "", "domain": "html-dom", }, # --- Form validation --- { "problem": "Validate a form submission with HTML5 constraints and custom checks.", "solution": "function validateForm(form: HTMLFormElement): { isValid: boolean; errors: string[] } {\n const errors: string[] = [];\n const email = form.elements.namedItem('email') as HTMLInputElement;\n const password = form.elements.namedItem('password') as HTMLInputElement;\n\n if (!email.validity.valid) {\n errors.push('Please enter a valid email address.');\n }\n if (password.value.length < 8) {\n errors.push('Password must be at least 8 characters.');\n }\n if (password.value !== (form.elements.namedItem('confirm') as HTMLInputElement).value) {\n errors.push('Passwords do not match.');\n }\n\n return { isValid: errors.length === 0, errors };\n}", "imports": "", "domain": "html-forms", }, # --- CSS Grid --- { "problem": "Create a responsive CSS grid layout with auto-fill and gap.", "solution": "const style = document.createElement('style');\nstyle.textContent = `\n .card-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 1.5rem;\n padding: 1rem;\n }\n .card {\n background: var(--card-bg);\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n }\n @media (max-width: 600px) {\n .card-grid { grid-template-columns: 1fr; }\n }\n`;\ndocument.head.appendChild(style);", "imports": "", "domain": "css-layout", }, # --- CSS custom properties --- { "problem": "Set and read CSS custom properties (CSS variables) via JavaScript.", "solution": "function setThemeColor(root: HTMLElement, name: string, value: string) {\n root.style.setProperty(`--theme-${name}`, value);\n}\n\nfunction getComputedColor(root: HTMLElement, name: string): string {\n return getComputedStyle(root).getPropertyValue(`--theme-${name}`).trim();\n}\n\n// Initialize theme\nsetThemeColor(document.documentElement, 'primary', '#4a90d9');\nsetThemeColor(document.documentElement, 'accent', '#ff6b6b');", "imports": "", "domain": "css-variables", }, # --- Intersection Observer --- { "problem": "Use IntersectionObserver to lazy-load images when they enter the viewport.", "solution": "function setupLazyLoading(container: HTMLElement) {\n const images = container.querySelectorAll('img[data-src]');\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const img = entry.target as HTMLImageElement;\n img.src = img.dataset.src!;\n img.removeAttribute('data-src');\n observer.unobserve(img);\n }\n });\n }, { rootMargin: '50px' });\n\n images.forEach(img => observer.observe(img));\n}", "imports": "", "domain": "html-performance", }, ] # ============================================================ # Playground UI Templates # ============================================================ PLAYGROUND_UI_TEMPLATES = [ # --- Sovereignty badge --- { "problem": "Render a sovereignty badge displaying local-first status with tooltip.", "solution": "function SovereigntyBadge({ runningLocal }: { runningLocal: boolean }) {\n const badge = document.createElement('span');\n badge.className = 'sovereignty-badge';\n badge.innerHTML = runningLocal\n ? '\\ud83c\\uddf5\\ud83c\\uddf1\\u200d\\ud83c\\udfa8\\ufe0f Local'\n : '\\ud83d\\udd12 Cloud';\n badge.title = runningLocal\n ? 'This agent runs entirely on your machine'\n : 'This agent uses external inference';\n return badge;\n}", "imports": "", "domain": "playground-ui", }, # --- Token counter --- { "problem": "Build a token budget display showing used/total with a visual progress bar.", "solution": "function TokenBudgetDisplay({ used, total }: { used: number; total: number }) {\n const pct = Math.min((used / total) * 100, 100);\n const bar = document.createElement('div');\n bar.className = 'token-budget-bar';\n bar.innerHTML = `\n
\n
90 ? '#f44336' : '#4caf50'}\">
\n
\n ${used.toLocaleString()} / ${total.toLocaleString()} tokens\n `;\n return bar;\n}", "imports": "", "domain": "playground-ui", }, # --- Approval gate --- { "problem": "Create an approval gate component for dangerous commands with tiered risk colors.", "solution": "function ApprovalGate({ risk, onApprove, onDeny }: {\n risk: 'low' | 'medium' | 'high';\n onApprove: () => void;\n onDeny: () => void;\n}) {\n const colors = { low: '#4caf50', medium: '#ff9800', high: '#f44336' };\n const panel = document.createElement('div');\n panel.className = 'approval-gate';\n panel.style.borderColor = colors[risk];\n panel.innerHTML = `\n

This action is ${risk} risk. Continue?

\n \n \n `;\n panel.querySelector('[data-action=\"approve\"]')!.addEventListener('click', onApprove);\n panel.querySelector('[data-action=\"deny\"]')!.addEventListener('click', onDeny);\n return panel;\n}", "imports": "", "domain": "playground-ui", }, # --- Skill card --- { "problem": "Render a skill card with metadata, status indicator, and toggle switch.", "solution": "function SkillCard({ skill, enabled, onToggle }: {\n skill: { name: string; description: string; category: string };\n enabled: boolean;\n onToggle: (name: string) => void;\n}) {\n const card = document.createElement('article');\n card.className = 'skill-card';\n card.innerHTML = `\n
\n

${skill.name}

\n \n
\n

${skill.description}

\n
Category: ${skill.category}
\n `;\n card.querySelector('input')!.addEventListener('change', () => onToggle(skill.name));\n return card;\n}", "imports": "", "domain": "playground-ui", }, ] # ============================================================ # Gallery Templates # ============================================================ GALLERY_TEMPLATES = [ # --- Masonry grid --- { "problem": "Implement a responsive masonry image grid using CSS columns.", "solution": "function createMasonryGallery(images: { src: string; alt: string }[], columns = 3) {\n const container = document.createElement('div');\n container.className = 'masonry-gallery';\n container.style.columnCount = String(columns);\n container.style.gap = '1rem';\n\n images.forEach(img => {\n const figure = document.createElement('figure');\n figure.innerHTML = `\"${img.alt}\"`;\n container.appendChild(figure);\n });\n\n // Responsive breakpoints\n const mq = window.matchMedia('(max-width: 768px)');\n mq.addEventListener('change', (e) => {\n container.style.columnCount = e.matches ? '2' : String(columns);\n });\n\n return container;\n}", "imports": "", "domain": "gallery-layout", }, # --- Lightbox modal --- { "problem": "Build a modal lightbox for full-screen image viewing with keyboard navigation.", "solution": "class Lightbox {\n private overlay!: HTMLElement;\n private img!: HTMLImageElement;\n\n constructor() {\n this.overlay = document.createElement('div');\n this.overlay.className = 'lightbox-overlay';\n this.overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:flex;align-items:center;justify-content:center;z-index:9999';\n this.img = document.createElement('img');\n this.overlay.appendChild(this.img);\n document.body.appendChild(this.overlay);\n\n this.overlay.addEventListener('click', () => this.close());\n document.addEventListener('keydown', (e) => e.key === 'Escape' && this.close());\n }\n\n open(src: string, alt: string) {\n this.img.src = src;\n this.img.alt = alt;\n this.overlay.style.display = 'flex';\n }\n\n close() {\n this.overlay.style.display = 'none';\n }\n}", "imports": "", "domain": "gallery-interaction", }, # --- Infinite scroll --- { "problem": "Implement infinite scroll loading with IntersectionObserver and abort handling.", "solution": "async function setupInfiniteScroll(container: HTMLElement, loadPage: (page: number) => Promise) {\n let page = 1;\n let loading = false;\n let done = false;\n\n const sentinel = document.createElement('div');\n sentinel.className = 'scroll-sentinel';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver(async (entries) => {\n if (entries[0].isIntersecting && !loading && !done) {\n loading = true;\n try {\n await loadPage(++page);\n } catch (err) {\n console.error('Failed to load page:', err);\n done = true;\n }\n loading = false;\n }\n }, { rootMargin: '200px' });\n\n observer.observe(sentinel);\n}", "imports": "", "domain": "gallery-performance", }, ] # ============================================================ # Game Templates # ============================================================ GAME_TEMPLATES = [ # --- Game loop --- { "problem": "Create a fixed-timestep game loop with accumulator pattern.", "solution": "class GameLoop {\n private lastTime = 0;\n private accumulator = 0;\n private readonly step = 1 / 60; // 60 Hz fixed step\n\n constructor(private readonly update: (dt: number) => void) {}\n\n start() {\n const frame = (time: number) => {\n const delta = (time - this.lastTime) / 1000;\n this.lastTime = time;\n this.accumulator += delta;\n\n while (this.accumulator >= this.step) {\n this.update(this.step);\n this.accumulator -= this.step;\n }\n\n requestAnimationFrame(frame);\n };\n requestAnimationFrame(frame);\n }\n}", "imports": "", "domain": "game-architecture", }, # --- Canvas setup --- { "problem": "Set up an HTML5 canvas with high-DPI scaling and clearing.", "solution": "function setupCanvas(canvas: HTMLCanvasElement, width = 800, height = 600) {\n const dpr = window.devicePixelRatio || 1;\n canvas.width = width * dpr;\n canvas.height = height * dpr;\n canvas.style.width = `${width}px`;\n canvas.style.height = `${height}px`;\n\n const ctx = canvas.getContext('2d')!;\n ctx.scale(dpr, dpr);\n\n return {\n clear() { ctx.clearRect(0, 0, width, height); },\n ctx,\n width,\n height,\n };\n}", "imports": "", "domain": "game-rendering", }, # --- Sprite animation --- { "problem": "Animate a sprite sheet with frame-based playback and loop support.", "solution": "class SpriteAnimator {\n private frame = 0;\n private lastTick = 0;\n\n constructor(\n private readonly image: HTMLImageElement,\n private readonly frameWidth: number,\n private readonly frameCount: number,\n private readonly fps: number = 12,\n private readonly loop: boolean = true,\n ) {}\n\n update(now: number) {\n const interval = 1000 / this.fps;\n if (now - this.lastTick >= interval) {\n this.lastTick = now;\n this.frame++;\n if (this.frame >= this.frameCount) {\n this.frame = this.loop ? 0 : this.frameCount - 1;\n }\n }\n }\n\n draw(ctx: CanvasRenderingContext2D, x: number, y: number) {\n ctx.drawImage(\n this.image,\n this.frame * this.frameWidth, 0,\n this.frameWidth, this.image.height,\n x, y,\n this.frameWidth, this.image.height\n );\n }\n}", "imports": "", "domain": "game-assets", }, # --- AABB collision --- { "problem": "Detect AABB (axis-aligned bounding box) collision between two rectangles.", "solution": "function aabbCollision(\n a: { x: number; y: number; w: number; h: number },\n b: { x: number; y: number; w: number; h: number }\n): boolean {\n return a.x < b.x + b.w &&\n a.x + a.w > b.x &&\n a.y < b.y + b.h &&\n a.y + a.h > b.y;\n}\n\n// Usage for game entities\nif (aabbCollision(player, enemy)) {\n handlePlayerHit();\n}", "imports": "", "domain": "game-physics", }, # --- Input handling --- { "problem": "Capture keyboard input state with smooth handling for game controls.", "solution": "class InputState {\n private keys = new Set();\n\n constructor() {\n window.addEventListener('keydown', (e) => this.keys.add(e.code));\n window.addEventListener('keyup', (e) => this.keys.delete(e.code));\n }\n\n isPressed(code: string): boolean {\n return this.keys.has(code);\n }\n\n hasAny(codes: string[]): boolean {\n return codes.some(c => this.keys.has(c));\n }\n}\n\n// In game loop:\nconst input = new InputState();\nif (input.isPressed('ArrowUp')) player.y -= speed * dt;", "imports": "", "domain": "game-input", }, ] # ============================================================ # Extra HTML/CSS/JS Templates # ============================================================ HTML_CSS_JS_TEMPLATES_EXTRA = [ # Debounce utility { "problem": "Write a debounce function that delays invoking a callback until after wait milliseconds.", "solution": "function debounce void>(\n fn: T,\n wait: number\n): (...args: Parameters) => void {\n let timeoutId: ReturnType | null = null;\n return (...args: Parameters) => {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), wait);\n };\n}", "imports": "", "domain": "html-utilities", }, # Throttle utility { "problem": "Implement a throttle function ensuring a callback runs at most once per interval.", "solution": "function throttle void>(\n fn: T,\n interval: number\n): (...args: Parameters) => void {\n let last = 0;\n return (...args: Parameters) => {\n const now = Date.now();\n if (now - last >= interval) {\n last = now;\n fn(...args);\n }\n };\n}", "imports": "", "domain": "html-utilities", }, # LocalStorage wrapper with TTL { "problem": "Wrap localStorage with JSON serialization and TTL expiration.", "solution": "class StorageWithTTL {\n set(key: string, value: any, ttlMs = 0) {\n const item = { value, expiry: ttlMs ? Date.now() + ttlMs : null };\n localStorage.setItem(key, JSON.stringify(item));\n }\n\n get(key: string): T | null {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n const { value, expiry } = JSON.parse(raw);\n if (expiry && Date.now() > expiry) {\n localStorage.removeItem(key);\n return null;\n }\n return value as T;\n }\n}", "imports": "", "domain": "html-storage", }, # Viewport meta { "problem": "Generate a responsive viewport meta tag for mobile-first web apps.", "solution": "const viewport = document.querySelector('meta[name=\"viewport\"]') ||\n document.createElement('meta');\nviewport.name = 'viewport';\nviewport.content = 'width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes, viewport-fit=cover';\ndocument.head.appendChild(viewport);", "imports": "", "domain": "html-meta", }, # Dynamic CSS variables { "problem": "Create and inject a dynamic stylesheet with CSS custom property overrides.", "solution": "function injectDynamicStyles(overrides: Record) {\n const style = document.createElement('style');\n let css = ':root {\\n';\n for (const [prop, val] of Object.entries(overrides)) {\n css += ` --${prop}: ${val};\\n`;\n }\n css += '}';\n style.textContent = css;\n document.head.appendChild(style);\n}", "imports": "", "domain": "css-variables", }, ] # ============================================================ # Extra Playground UI Templates # ============================================================ PLAYGROUND_UI_TEMPLATES_EXTRA = [ # Circuit/tier badge { "problem": "Render a circuit health badge showing approval-tier status with color-coded indicator.", "solution": "function CircuitBadge({ tier }: { tier: number }) {\n const colors = ['#f44336', '#ff9800', '#4caf50', '#2196f3', '#9c27b0'];\n const labels = ['BLOCKED', 'RESTRICTED', 'LIMITED', 'APPROVED', 'ELEVATED'];\n const color = colors[Math.min(tier, 4)];\n const label = labels[Math.min(tier, 4)];\n\n const badge = document.createElement('span');\n badge.className = 'circuit-badge';\n badge.style.backgroundColor = color;\n badge.textContent = label;\n badge.title = `Approval tier ${tier} — ${label.toLowerCase()} command set`;\n return badge;\n}", "imports": "", "domain": "playground-ui", }, # Memory usage bar { "problem": "Display a horizontal memory usage bar with gradient warning zones.", "solution": "function MemoryBar({ used, total }: { used: number; total: number }) {\n const pct = (used / total) * 100;\n const bar = document.createElement('div');\n bar.className = 'memory-bar';\n let color = '#4caf50';\n if (pct > 80) color = '#ff9800';\n if (pct > 95) color = '#f44336';\n\n bar.innerHTML = `\n
\n
\n
\n ${(used/1024/1024).toFixed(1)} MB / ${(total/1024/1024).toFixed(1)} MB\n `;\n return bar;\n}", "imports": "", "domain": "playground-ui", }, # Tool status dot { "problem": "Show a tool availability status dot with tooltip for the toolset panel.", "solution": "function ToolStatus({ name, ok }: { name: string; ok: boolean }) {\n const dot = document.createElement('span');\n dot.className = 'tool-status-dot';\n dot.style.backgroundColor = ok ? '#4caf50' : '#f44336';\n dot.title = `${name}: ${ok ? 'Available' : 'Disabled / missing API key'}`;\n return dot;\n}", "imports": "", "domain": "playground-ui", }, ] # ============================================================ # Extra Gallery Templates # ============================================================ GALLERY_TEMPLATES_EXTRA = [ # Grid + shared lightbox { "problem": "Build an image gallery grid that opens a shared lightbox on thumbnail click.", "solution": "let currentLightbox: HTMLDivElement | null = null;\n\nfunction buildGallery(images: { full: string; thumb: string; alt: string }[]) {\n const grid = document.createElement('div');\n grid.className = 'gallery-grid';\n grid.style.cssText = 'display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:0.5rem';\n\n images.forEach((img, idx) => {\n const thumb = document.createElement('img');\n thumb.src = img.thumb;\n thumb.alt = img.alt;\n thumb.style.cssText = 'cursor:pointer;width:100%;height:auto;object-fit:cover;border-radius:4px';\n thumb.addEventListener('click', () => openLightbox(idx));\n grid.appendChild(thumb);\n });\n\n return grid;\n}\n\nfunction openLightbox(index: number) {\n if (currentLightbox) currentLightbox.remove();\n currentLightbox = document.createElement('div');\n currentLightbox.className = 'lightbox';\n currentLightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.95);display:flex;align-items:center;justify-content:center;z-index:10000;cursor:pointer';\n const img = document.createElement('img');\n img.src = images[index].full;\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n currentLightbox.appendChild(img);\n currentLightbox.addEventListener('click', () => { currentLightbox?.remove(); currentLightbox = null; });\n document.body.appendChild(currentLightbox);\n}", "imports": "", "domain": "gallery-interaction", }, ] # ============================================================ # Extra Game Templates # ============================================================ GAME_TEMPLATES_EXTRA = [ # Particle system with typed array { "problem": "Create a simple particle system for explosions using a typed array buffer.", "solution": "class ParticleSystem {\n private particles = new Float32Array(1000 * 4); // x, y, vx, vy per particle\n private count = 0;\n private readonly max = 1000;\n\n emit(x: number, y: number, velocity = 200) {\n if (this.count >= this.max) return;\n const i = this.count * 4;\n this.particles[i] = x;\n this.particles[i + 1] = y;\n const angle = Math.random() * Math.PI * 2;\n const speed = Math.random() * velocity;\n this.particles[i + 2] = Math.cos(angle) * speed;\n this.particles[i + 3] = Math.sin(angle) * speed;\n this.count++;\n }\n\n update(dt: number) {\n for (let i = 0; i < this.count * 4; i += 4) {\n this.particles[i] += this.particles[i + 2] * dt;\n this.particles[i + 1] += this.particles[i + 3] * dt;\n this.particles[i + 3] += 500 * dt; // gravity\n }\n }\n\n draw(ctx: CanvasRenderingContext2D) {\n ctx.fillStyle = '#ff6600';\n for (let i = 0; i < this.count * 4; i += 4) {\n ctx.fillRect(this.particles[i], this.particles[i + 1], 3, 3);\n }\n }\n}", "imports": "", "domain": "game-physics", }, # State machine { "problem": "Implement a finite state machine for a game character with transitions.", "solution": "type State = 'idle' | 'walk' | 'run' | 'jump' | 'attack';\n\nclass StateMachine {\n private state: State = 'idle';\n private handlers: Record void>;\n\n constructor(handlers: Partial void>>) {\n this.handlers = handlers as Record void>;\n }\n\n transition(to: State) {\n console.log(`State: ${this.state} -> ${to}`);\n this.state = to;\n }\n\n dispatch(event: string) {\n const handler = this.handlers[this.state];\n if (handler) handler(event);\n }\n\n getState(): State {\n return this.state;\n }\n}\n\n// Usage\nconst sm = new StateMachine({\n idle: (e) => { if (e === 'move') sm.transition('walk'); },\n walk: (e) => { if (e === 'sprint') sm.transition('run'); if (e === 'jump') sm.transition('jump'); },\n run: (e) => { if (e === 'stop') sm.transition('idle'); },\n});", "imports": "", "domain": "game-architecture", }, ] # ============================================================ # Combined # ============================================================ ALL_TEMPLATES = ( THREEJS_TEMPLATES + HTML_CSS_JS_TEMPLATES + HTML_CSS_JS_TEMPLATES_EXTRA + PLAYGROUND_UI_TEMPLATES + PLAYGROUND_UI_TEMPLATES_EXTRA + GALLERY_TEMPLATES + GALLERY_TEMPLATES_EXTRA + GAME_TEMPLATES + GAME_TEMPLATES_EXTRA ) _VARIANT_PREFIXES = [ "Write code to", "Implement", "Build", "Create", "How would you", "Using the API, write code that", "Construct a function that", "Develop", "Write JavaScript that", "Create HTML/CSS for", "Design a Three.js", ] _VARIANT_SUFFIXES = [ " including error handling.", " with full docstrings.", " with JSDoc annotations.", " using modern best practices.", " that handles edge cases.", " with TypeScript types.", " that is performant.", " with clear variable names.", " and include example usage.", " with proper cleanup.", " that is accessible (a11y).", " with keyboard navigation support.", ] def vary_problem(base: str, idx: int) -> str: prefix = _VARIANT_PREFIXES[idx % len(_VARIANT_PREFIXES)] suffix = _VARIANT_SUFFIXES[idx % len(_VARIANT_SUFFIXES)] cleaned = base for article in ("Create a ", "Build a ", "Implement a ", "Write a ", "Develop a ", "Write JavaScript that ", "Create HTML/CSS for ", "Design a Three.js "): if cleaned.lower().startswith(article): cleaned = cleaned[len(article):] break cleaned = cleaned[0].lower() + cleaned[1:] if cleaned else "" return f"{prefix} {cleaned}{suffix}" def vary_solution(base: str, idx: int) -> str: var_names = ["data", "result", "value", "entry", "item", "node", "entity", "output", "obj", "element"] v = var_names[idx % len(var_names)] sol = base if idx % 3 == 0: for original in ["result", "data", "value", "output", "entry", "item", "obj", "element"]: if original in sol: sol = sol.replace(original, v) break if idx % 5 == 0: sol = f"// Variation {idx}\\n" + sol elif idx % 7 == 0: sol = f"# Generated variation {idx}\\n" + sol return sol def generate_pairs(count: int = 1000) -> list[dict]: pairs = [] template_cycle = list(ALL_TEMPLATES) random.shuffle(template_cycle) for i in range(count): template = template_cycle[i % len(template_cycle)] problem = vary_problem(template["problem"], i) solution = vary_solution(template["solution"], i) pair = { "problem": problem, "solution": solution, "imports": template["imports"], "domain": template["domain"], "id": f"frontend-creative-{i:04d}", } pairs.append(pair) return pairs def main(): parser = argparse.ArgumentParser(description="Generate Frontend & Creative code pattern training pairs") parser.add_argument("--output", "-o", default="training-data/code-patterns-frontend-&-creative.jsonl", help="Output JSONL path") parser.add_argument("--count", "-n", type=int, default=1000, help="Number of pairs to generate") args = parser.parse_args() out_path = Path(args.output) out_path.parent.mkdir(parents=True, exist_ok=True) pairs = generate_pairs(args.count) with open(out_path, "w", encoding="utf-8") as f: for pair in pairs: f.write(json.dumps(pair, ensure_ascii=False) + "\n") domains = {p["domain"] for p in pairs} print(f"Generated {len(pairs)} code pattern pairs → {out_path}") print(f" Size: {out_path.stat().st_size / 1024:.1f} KB") print(f" Domains ({len(domains)}): {sorted(domains)}") if __name__ == "__main__": main()