diff --git a/.gitignore b/.gitignore index f788d1d..364cde5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,9 @@ node_modules/ output/ .env !.claude/settings.local.json + +# Generated output HTML (template + data → output) +tasks/*/docs/*.output.html + +# Editor temp files (diffs, transient data) +tasks/*/temp/ diff --git a/CLAUDE.md b/CLAUDE.md index 268a255..c91b5d3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,15 +1,13 @@ # Math Tasks Generator -Printable math worksheet generator (A4 PDF) for children aged 7–9. Claude Code-driven workflow: user describes a task idea → Claude generates JSON config → creates HTML pages with Tailwind CSS → converts to PDF via Puppeteer. - -**No template engine.** Claude Code generates fresh HTML pages directly from JSON task configs each time. +Printable math worksheet generator (A4 PDF) for children aged 7–9. Claude Code is the central orchestrator: user describes a task idea → Claude creates/edits HTML templates → optional visual editor fine-tuning → PDF via Puppeteer. ## Commands ```bash pnpm build:css # Build Tailwind CSS (minified) pnpm build:css:watch # Watch mode for CSS -pnpm preview # Serve HTML at localhost:3000 with live-reload +pnpm preview # Serve at localhost:3300 with live-reload pnpm dev # CSS watch + preview server (concurrent) pnpm pdf -- # Convert HTML file to PDF pnpm remove-bg -- # Remove white background from PNG icons @@ -20,230 +18,202 @@ Generate images via `/gen-image` skill (uses Banatie API, reads `BANATIE_KEY` fr ## Directory Structure ``` +tasks/ + index.html — document index (Claude updates manually) + {task-type}/ — one folder per task type + CLAUDE.md — type-specific rules and conventions + editor.html — visual editor for this task type + scripts/ — type-specific scripts (validation, generation) + docs/ — document instances + {docId}.md — task description, problem patterns, notes (Claude reads/writes) + {docId}.template.html — near-final HTML maintained by Claude + {docId}.data.json — editor data layer (positions, values — may not exist) + {docId}.output.html — generated from template+data (gitignored) + temp/ — diffs and transient data (gitignored) + src/ - styles/main.css — Tailwind source with A4/print styles - templates/space-base.html — Base template (layout/styling reference) - examples/space-worksheet2.html — Finished 3-page example (output reference) + editor/editor-core.js — shared editor framework scripts/ - generate-pdf.mjs — HTML → PDF via Puppeteer - remove-bg.mjs — Remove white background from PNGs (flood fill) -tasks/ — JSON task definition files -assets/ - hero-images/ — spaceship1-6.jpeg (header hero images) - footers/ — planet1-6.jpeg (footer panorama images) - icons/pack1/ — minerals1-6 + plants1-6, 16 variants each ({name}-{row}-{col}.png) - backgrounds/ — large background images per theme (~1200x1700px) -output/ - html/ — generated HTML (gitignored) - pdf/ — generated PDFs (gitignored) - css/ — built Tailwind CSS (gitignored) + generate-pdf.mjs — HTML → PDF via Puppeteer (all types) + remove-bg.mjs — Remove white background from PNGs + split-sprites.mjs — Split sprite sheets into icons + generate-problems.mjs — Problem generation utility + styles/main.css — Tailwind source with A4/print styles + templates/space-base.html — Shared base template reference + +assets/ — images (hero, footer, icons, items, backgrounds) +output/pdf/ — generated PDFs (gitignored) ``` -## JSON Task Format +## Task Types -Each task is a JSON file in `tasks/` defining a multi-page document. See `tasks/space-exploration-1.json` for a real example. +Each task type lives in `tasks/{type-name}/` with its own CLAUDE.md, scripts, editor, and document instances. Current types: -```json -{ - "id": "space-exploration-1", - "title": "Исследуй Планету", - "description": "3-page space worksheet: addition ±, multiply by 5 ±, multiplication table ±", - "labels": { - "title": "Исследуй Планету", - "subtitle": "Собери ресурсы, решая примеры!", - "footerBubble": "Итого собрано на планете:" - }, - "theme": { - "style": "space", - "template": "space-base", - "icons": "assets/icons/pack1/" - }, - "layout": { - "columns": 2, - "problemsPerPage": 20 - }, - "pages": [ - { - "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship2.jpeg", - "footerImage": "assets/footers/planet3.jpeg", - "heroDirection": "row-reverse" - } - ] -} +- **space-exploration** — math problem worksheets with hero images and icon-decorated cards +- **collecting-asteroids** — match asteroids to cargo ships by weight sum +- **space-route** — navigate hex graph routes with difficulty constraints + +**Type-specific rules** (layout details, asset conventions, generation algorithms) live in each type's own CLAUDE.md — NOT in this file. Read `tasks/{type}/CLAUDE.md` before working on any task of that type. + +## Document File Set + +Each document instance consists of up to 4 files in `tasks/{type}/docs/`: + +| File | Purpose | Owner | +|------|---------|-------| +| `{docId}.md` | Task description, problem patterns, page notes | Claude writes, user reviews | +| `{docId}.template.html` | Near-final static HTML, maintained by Claude | Claude | +| `{docId}.data.json` | Editor data layer (positions, values) | Editor UI via save endpoint | +| `{docId}.output.html` | Final HTML = template + data applied | generate.mjs (gitignored) | + +**Key:** `.data.json` may not exist — and that's fine. When it doesn't exist, `.template.html` IS the final output. + +**The `.md` file does NOT directly drive HTML generation.** It's context for Claude — problem patterns, non-obvious details (e.g., hero orientation per page), things Claude needs to know when editing the template. It does NOT contain titles, footers, or asset paths that are already in the HTML. + +## Creating New Task Types + +1. Create folder `tasks/{type-name}/` +2. Create `CLAUDE.md` with type-specific rules +3. Create `scripts/generate.mjs` — template + data → output pipeline +4. Create `editor.html` importing `src/editor/editor-core.js` + type-specific logic +5. Create `scripts/` for any validation/generation utilities +6. Add section to `tasks/index.html` + +## Creating New Documents + +When the user asks to create a new document of an existing type: + +1. Copy the previous document's files with incremented number: + - `{type}-N.template.html` → `{type}-(N+1).template.html` + - `{type}-N.md` → `{type}-(N+1).md` +2. Update the `.md` file with new problem patterns / page descriptions +3. Edit `.template.html` as needed (new problems, different assets, etc.) +4. Add card to `tasks/index.html` + +**No script for this — Claude does it manually.** `.data.json` starts empty (created only when the editor is used). + +## Adding Pages to Existing Documents + +1. Read the `.md` file to understand existing patterns +2. Edit `.template.html` directly — add new page markup +3. Update `.md` if new patterns were added + +## Generation Pipeline + +``` +.template.html + .data.json (if exists) → scripts/generate.mjs → .output.html ``` -### Fields +- Same pipeline for both Claude-initiated regeneration and editor-save flow +- If no `.data.json` exists → template.html copied as-is to output.html +- `generate.mjs` is a per-task-type script, not a global one -- **pages[]** — array of pages, each with its own task and images -- **pages[].task** — free-text description of problems to generate (Claude reads this and creates concrete expressions) -- **pages[].problemCount** — how many problems on this page -- **pages[].heroImage** — path to hero image for this page -- **pages[].footerImage** — path to footer panorama for this page -- **pages[].heroDirection** — `row` (hero left) or `row-reverse` (hero right) -- **layout.columns** — 1 or 2 column layout -- **layout.problemsPerPage** — max problems per A4 page -- **labels** — all visible text (no hardcoded language) -- **theme.style** — visual theme name (e.g. "space") -- **theme.template** — which base template to use (e.g. "space-base") -- **theme.icons** — path to icon directory for problem cards +## Editor System -## Space Base Template +Each task type has its own `editor.html` in its folder. All editors share `src/editor/editor-core.js` for common functionality (drag, selection, keyboard, toolbar, save, toast). -Base template: `src/templates/space-base.html` -Finished example: `src/examples/space-worksheet2.html` (3-page output matching `tasks/space-worksheet2.json`) +**Opening in editor:** +``` +http://localhost:3300/tasks/{type}/editor.html?file={docId} +``` -The base template defines the visual design for all space-themed worksheets. The example shows a complete generated document. When generating a new worksheet, **read both files first**, then produce a new HTML with these variations: +**Save flow:** +1. User clicks Save in editor +2. Editor POST `/api/save-edits` with `{ taskType, docId, data }` +3. Server writes `docs/{docId}.data.json` +4. Server computes diff → writes `temp/{docId}.diff.json` +5. Server runs `generate.mjs` to regenerate output.html -### What to vary per worksheet +**Claude reviewing editor changes:** +```bash +cat tasks/{type}/temp/{docId}.diff.json +``` -1. **Hero image** — pick one from `assets/hero-images/spaceship{1-6}.jpeg` -2. **Footer image** — pick one from `assets/footers/planet{1-6}.jpeg` -3. **Hero position** — use `flex-row-reverse` class (hero right) or default flex direction (hero left) on the header div -4. **Problem icons** — pick from `assets/icons/pack1/` (minerals and plants, any variant `{name}-{row}-{col}.png`). **Every icon must be unique across the entire document** (no repeats across pages). Shuffle minerals and plants together randomly — do not sort by type -5. **Problem alignment** — for each problem card, randomly assign `justify-start`, `justify-center`, or `justify-end` within its grid column. No repeating patterns — should look chaotic/scattered -6. **Title, subtitle, footer text** — set from the task description -7. **Problems** — generate directly from the `task` text in JSON config. Claude reads the free-text description and creates concrete math expressions +## Index Page -### Layout structure (do not change) +`tasks/index.html` — Claude updates manually when creating new documents. Each document has View and Edit links. Different task types can have different card styles. -- Page: `w-[210mm] h-[297mm]` white container -- Footer: absolute bottom, `h-[80mm]`, with white-to-transparent fade on top. **No `overflow-hidden`** on footer container (causes 1px hairline artifact in PDF) -- Footer bubble: absolute `bottom-[12mm]`, pill-shaped with semi-transparent white bg -- Content area: `px-[12mm] pt-[4mm] pb-[65mm]` flex column -- Header: hero image `w-[48%]` + title block centered, use `flex-row-reverse` for hero-right -- Footer gradient: `linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%)` with `h-full` -- Problems: `grid grid-cols-2 gap-x-3 gap-y-[3px]` — 20 problems total -- Each problem: 58px icon outside pill + `text-[1.2rem]` expression + `w-16` answer underline inside pill -- Font: Nunito via Google Fonts -- Uses Tailwind CDN (` + + + + Собери Астероиды + + + + + + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
5
+
5
+
7
+ +
2
+
3
+
1
+
4
+
1
+
2
+
4
+
6
+
5
+
3
+
5
+
3
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
7
+
7
+
10
+ +
1
+
2
+
4
+
2
+
2
+
3
+
1
+
3
+
2
+
4
+
5
+
6
+
5
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
5
+
5
+
6
+ +
3
+
2
+
1
+
1
+
3
+
2
+
2
+
2
+
4
+
5
+
6
+
4
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
8
+
8
+
6
+ +
3
+
5
+
2
+
3
+
3
+
2
+
4
+
5
+
1
+
6
+
1
+
4
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
4
+
4
+
4
+ +
4
+
1
+
3
+
1
+
1
+
2
+
5
+
6
+
3
+
5
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
10
+
10
+
8
+ +
1
+
2
+
3
+
4
+
2
+
3
+
5
+
1
+
3
+
4
+
6
+
5
+
2
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
6
+
9
+
12
+ +
2
+
4
+
1
+
3
+
5
+
2
+
4
+
3
+
3
+
6
+
5
+
1
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
14
+
10
+
16
+ +
4
+
5
+
5
+
4
+
6
+
3
+
4
+
4
+
5
+
6
+
2
+
3
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
5
+
10
+
15
+ +
2
+
3
+
1
+
2
+
3
+
4
+
1
+
2
+
3
+
4
+
5
+
6
+
5
+
4
+
6
+
+
+
+ + + diff --git a/tasks/collecting-asteroids/docs/collecting-asteroids-2.md b/tasks/collecting-asteroids/docs/collecting-asteroids-2.md new file mode 100644 index 0000000..ecbea1d --- /dev/null +++ b/tasks/collecting-asteroids/docs/collecting-asteroids-2.md @@ -0,0 +1,35 @@ +# Collecting Asteroids 2 + +**Title:** Собери Астероиды +**Subtitle:** Загрузи трюмы кораблей! +**Footer bubble:** Итого загружено: + +## Notes + +v2: reshuffled assets, doubled difficulty compared to v1. + +## Layout + +- 3 ships per page, 2 asteroid types per page (70:30 ratio) +- Asteroids: assets/icons/pack3-asteroids/ +- Uses different splitters, cabins, cargo bays and asteroid types than v1 + +## Pages + +### Page 1 +- **Ships:** capacity 10 (fill 2), capacity 10 (fill 2), capacity 14 (fill 3) +- **Hero:** splitter5.png, direction: row +- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6 +- **Asteroid types:** asteroid7, asteroid14 + +### Page 2 +- **Ships:** capacity 14 (fill 3), capacity 14 (fill 3), capacity 20 (fill 4) +- **Hero:** splitter2.png, direction: row-reverse +- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9 +- **Asteroid types:** asteroid4, asteroid11 + +### Page 3 +- **Ships:** capacity 10 (fill 2), capacity 10 (fill 3), capacity 12 (fill 3) +- **Hero:** splitter8.png, direction: row +- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3 +- **Asteroid types:** asteroid2, asteroid9 diff --git a/tasks/collecting-asteroids/docs/collecting-asteroids-2.template.html b/tasks/collecting-asteroids/docs/collecting-asteroids-2.template.html new file mode 100644 index 0000000..cc4c18e --- /dev/null +++ b/tasks/collecting-asteroids/docs/collecting-asteroids-2.template.html @@ -0,0 +1,347 @@ + + + + + + + + + + Собери Астероиды + + + + + + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
10
+
10
+
14
+ +
6
+
4
+
2
+
8
+
10
+
4
+
6
+
12
+
10
+
8
+
2
+
12
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
14
+
14
+
20
+ +
6
+
8
+
4
+
10
+
2
+
12
+
6
+
4
+
8
+
2
+
10
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
10
+
10
+
12
+ +
4
+
8
+
2
+
6
+
10
+
4
+
2
+
6
+
8
+
12
+
10
+
4
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
16
+
16
+
12
+ +
8
+
6
+
10
+
4
+
12
+
2
+
6
+
8
+
12
+
4
+
10
+
8
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
8
+
8
+
8
+ +
6
+
2
+
8
+
4
+
10
+
2
+
12
+
4
+
6
+
8
+
10
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
20
+
20
+
16
+ +
4
+
6
+
8
+
10
+
2
+
6
+
12
+
4
+
2
+
8
+
10
+
6
+
4
+
12
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
12
+
18
+
24
+ +
6
+
4
+
2
+
10
+
8
+
4
+
12
+
6
+
8
+
2
+
10
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
28
+
20
+
32
+ +
10
+
6
+
8
+
4
+
12
+
2
+
6
+
10
+
8
+
12
+
4
+
6
+
10
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
10
+
20
+
30
+ +
6
+
4
+
2
+
8
+
10
+
4
+
6
+
12
+
2
+
8
+
6
+
10
+
4
+
12
+
8
+
+
+
+ + + diff --git a/tasks/collecting-asteroids/docs/collecting-asteroids-3.data.json b/tasks/collecting-asteroids/docs/collecting-asteroids-3.data.json new file mode 100644 index 0000000..6a052f6 --- /dev/null +++ b/tasks/collecting-asteroids/docs/collecting-asteroids-3.data.json @@ -0,0 +1,1250 @@ +{ + "file": "collecting-asteroids-3.html", + "pages": [ + { + "page": 1, + "asteroids": [ + { + "index": 0, + "left": "149mm", + "top": "78mm", + "rotate": "33deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid3" + }, + { + "index": 1, + "left": "81mm", + "top": "26mm", + "rotate": "-12deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid10" + }, + { + "index": 2, + "left": "64mm", + "top": "52mm", + "rotate": "23deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid3" + }, + { + "index": 3, + "left": "14mm", + "top": "28mm", + "rotate": "18deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid3" + }, + { + "index": 4, + "left": "50mm", + "top": "9mm", + "rotate": "-18deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid10" + }, + { + "index": 5, + "left": "87mm", + "top": "-2mm", + "rotate": "15deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid3" + }, + { + "index": 6, + "left": "82mm", + "top": "105mm", + "rotate": "10deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid3" + }, + { + "index": 7, + "left": "93mm", + "top": "60mm", + "rotate": "22deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid10" + }, + { + "index": 8, + "left": "66mm", + "top": "142mm", + "rotate": "0deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid3" + }, + { + "index": 9, + "left": "129mm", + "top": "-5mm", + "rotate": "15deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid3" + }, + { + "index": 10, + "left": "45mm", + "top": "117mm", + "rotate": "-80deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid10" + }, + { + "index": 11, + "left": "6mm", + "top": "123mm", + "rotate": "7deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid3" + } + ], + "ships": [ + { + "index": 0, + "left": "28%", + "top": "54%", + "value": 10 + }, + { + "index": 1, + "left": "72%", + "top": "44%", + "value": 11 + }, + { + "index": 2, + "left": "26%", + "top": "46%", + "value": 12 + } + ] + }, + { + "page": 2, + "asteroids": [ + { + "index": 0, + "left": "72mm", + "top": "-5mm", + "rotate": "20deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid6" + }, + { + "index": 1, + "left": "105mm", + "top": "10mm", + "rotate": "-15deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid13" + }, + { + "index": 2, + "left": "150mm", + "top": "19mm", + "rotate": "10deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid6" + }, + { + "index": 3, + "left": "52mm", + "top": "30mm", + "rotate": "-63deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid6" + }, + { + "index": 4, + "left": "85mm", + "top": "82mm", + "rotate": "22deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid13" + }, + { + "index": 5, + "left": "86mm", + "top": "51mm", + "rotate": "-25deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid6" + }, + { + "index": 6, + "left": "164mm", + "top": "127mm", + "rotate": "95deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid6" + }, + { + "index": 7, + "left": "44mm", + "top": "75mm", + "rotate": "15deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid13" + }, + { + "index": 8, + "left": "-5mm", + "top": "87mm", + "rotate": "-18deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid6" + }, + { + "index": 9, + "left": "108mm", + "top": "152mm", + "rotate": "12deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid6" + }, + { + "index": 10, + "left": "73mm", + "top": "120mm", + "rotate": "-12deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid13" + }, + { + "index": 11, + "left": "136mm", + "top": "154mm", + "rotate": "18deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid6" + } + ], + "ships": [ + { + "index": 0, + "left": "62%", + "top": "40%", + "value": 12 + }, + { + "index": 1, + "left": "28%", + "top": "39%", + "value": 12 + }, + { + "index": 2, + "left": "73%", + "top": "51%", + "value": 18 + } + ] + }, + { + "page": 3, + "asteroids": [ + { + "index": 0, + "left": "38mm", + "top": "8mm", + "rotate": "-13deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid2" + }, + { + "index": 1, + "left": "76mm", + "top": "10mm", + "rotate": "15deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid8" + }, + { + "index": 2, + "left": "109mm", + "top": "-5mm", + "rotate": "-8deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid2" + }, + { + "index": 3, + "left": "-4mm", + "top": "25mm", + "rotate": "22deg", + "scale": 1.65, + "value": 9, + "asteroid": "asteroid2" + }, + { + "index": 4, + "left": "64mm", + "top": "56mm", + "rotate": "-20deg", + "scale": 1.8, + "value": 10, + "asteroid": "asteroid8" + }, + { + "index": 5, + "left": "97mm", + "top": "49mm", + "rotate": "10deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid2" + }, + { + "index": 6, + "left": "175mm", + "top": "78mm", + "rotate": "25deg", + "scale": 2.1, + "value": 12, + "asteroid": "asteroid2" + }, + { + "index": 7, + "left": "-10mm", + "top": "124mm", + "rotate": "-12deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid8" + }, + { + "index": 8, + "left": "48mm", + "top": "113mm", + "rotate": "3deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid2" + }, + { + "index": 9, + "left": "65mm", + "top": "151mm", + "rotate": "-25deg", + "scale": 1.8, + "value": 10, + "asteroid": "asteroid2" + }, + { + "index": 10, + "left": "18mm", + "top": "144mm", + "rotate": "17deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid8" + }, + { + "index": 11, + "left": "106mm", + "top": "86mm", + "rotate": "13deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid2" + } + ], + "ships": [ + { + "index": 0, + "left": "28%", + "top": "34%", + "value": 7 + }, + { + "index": 1, + "left": "75%", + "top": "47%", + "value": 5 + }, + { + "index": 2, + "left": "22%", + "top": "39%", + "value": 6 + } + ] + }, + { + "page": 4, + "asteroids": [ + { + "index": 0, + "left": "64mm", + "top": "2mm", + "rotate": "-68deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 1, + "left": "58mm", + "top": "88mm", + "rotate": "-22deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid15" + }, + { + "index": 2, + "left": "160mm", + "top": "28mm", + "rotate": "8deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 3, + "left": "-10mm", + "top": "76mm", + "rotate": "-15deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 4, + "left": "63mm", + "top": "42mm", + "rotate": "20deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid15" + }, + { + "index": 5, + "left": "82mm", + "top": "71mm", + "rotate": "-5deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 6, + "left": "149mm", + "top": "132mm", + "rotate": "15deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 7, + "left": "22mm", + "top": "82mm", + "rotate": "-18deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid15" + }, + { + "index": 8, + "left": "121mm", + "top": "7mm", + "rotate": "22deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 9, + "left": "103mm", + "top": "120mm", + "rotate": "-10deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + }, + { + "index": 10, + "left": "62mm", + "top": "130mm", + "rotate": "10deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid15" + }, + { + "index": 11, + "left": "103mm", + "top": "155mm", + "rotate": "18deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid12" + } + ], + "ships": [ + { + "index": 0, + "left": "71%", + "top": "55%", + "value": 15 + }, + { + "index": 1, + "left": "28%", + "top": "43%", + "value": 10 + }, + { + "index": 2, + "left": "76%", + "top": "49%", + "value": 25 + } + ] + }, + { + "page": 5, + "asteroids": [ + { + "index": 0, + "left": "45mm", + "top": "5mm", + "rotate": "-15deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid1" + }, + { + "index": 1, + "left": "64mm", + "top": "62mm", + "rotate": "3deg", + "scale": 0.85, + "value": 1, + "asteroid": "asteroid9" + }, + { + "index": 2, + "left": "27mm", + "top": "160mm", + "rotate": "37deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid1" + }, + { + "index": 3, + "left": "-1mm", + "top": "32mm", + "rotate": "22deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid1" + }, + { + "index": 4, + "left": "82mm", + "top": "16mm", + "rotate": "-20deg", + "scale": 1.15, + "value": 3, + "asteroid": "asteroid9" + }, + { + "index": 5, + "left": "108mm", + "top": "65mm", + "rotate": "10deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid1" + }, + { + "index": 6, + "left": "7mm", + "top": "126mm", + "rotate": "75deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid1" + }, + { + "index": 7, + "left": "71mm", + "top": "104mm", + "rotate": "-12deg", + "scale": 1.45, + "value": 5, + "asteroid": "asteroid9" + }, + { + "index": 8, + "left": "145mm", + "top": "86mm", + "rotate": "15deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid1" + }, + { + "index": 9, + "left": "3mm", + "top": "4mm", + "rotate": "-22deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid1" + }, + { + "index": 10, + "left": "80mm", + "top": "154mm", + "rotate": "8deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid1" + } + ], + "ships": [ + { + "index": 0, + "left": "37%", + "top": "38%", + "value": 13 + }, + { + "index": 1, + "left": "71%", + "top": "41%", + "value": 11 + }, + { + "index": 2, + "left": "23%", + "top": "47%", + "value": 15 + } + ] + }, + { + "page": 6, + "asteroids": [ + { + "index": 0, + "left": "79mm", + "top": "24mm", + "rotate": "65deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid5" + }, + { + "index": 1, + "left": "65mm", + "top": "-5mm", + "rotate": "-22deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid16" + }, + { + "index": 2, + "left": "148mm", + "top": "18mm", + "rotate": "73deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid5" + }, + { + "index": 3, + "left": "99mm", + "top": "135mm", + "rotate": "-42deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid5" + }, + { + "index": 4, + "left": "47mm", + "top": "59mm", + "rotate": "20deg", + "scale": 0.45, + "value": 1, + "asteroid": "asteroid16" + }, + { + "index": 5, + "left": "84mm", + "top": "48mm", + "rotate": "40deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid5" + }, + { + "index": 6, + "left": "114mm", + "top": "21mm", + "rotate": "53deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid5" + }, + { + "index": 7, + "left": "7mm", + "top": "80mm", + "rotate": "-18deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid16" + }, + { + "index": 8, + "left": "65mm", + "top": "82mm", + "rotate": "10deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid5" + }, + { + "index": 9, + "left": "84mm", + "top": "82mm", + "rotate": "15deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid5" + }, + { + "index": 10, + "left": "146mm", + "top": "157mm", + "rotate": "22deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid16" + }, + { + "index": 11, + "left": "60mm", + "top": "108mm", + "rotate": "-8deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid5" + }, + { + "index": 12, + "left": "81mm", + "top": "113mm", + "rotate": "-18deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid5" + }, + { + "index": 13, + "left": "80mm", + "top": "160mm", + "rotate": "-15deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid5" + } + ], + "ships": [ + { + "index": 0, + "left": "65%", + "top": "50%", + "value": 18 + }, + { + "index": 1, + "left": "35%", + "top": "50%", + "value": 18 + }, + { + "index": 2, + "left": "65%", + "top": "50%", + "value": 14 + } + ] + }, + { + "page": 7, + "asteroids": [ + { + "index": 0, + "left": "37mm", + "top": "4mm", + "rotate": "-10deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid11" + }, + { + "index": 1, + "left": "78mm", + "top": "-3mm", + "rotate": "17deg", + "scale": 2.3, + "value": 8, + "asteroid": "asteroid7" + }, + { + "index": 2, + "left": "112mm", + "top": "-1mm", + "rotate": "50deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid11" + }, + { + "index": 3, + "left": "2mm", + "top": "13mm", + "rotate": "15deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid11" + }, + { + "index": 4, + "left": "65mm", + "top": "34mm", + "rotate": "-8deg", + "scale": 2.75, + "value": 11, + "asteroid": "asteroid7" + }, + { + "index": 5, + "left": "99mm", + "top": "45mm", + "rotate": "-5deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid11" + }, + { + "index": 6, + "left": "72mm", + "top": "107mm", + "rotate": "-55deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid11" + }, + { + "index": 7, + "left": "78mm", + "top": "71mm", + "rotate": "-15deg", + "scale": 2.6, + "value": 10, + "asteroid": "asteroid7" + }, + { + "index": 8, + "left": "132mm", + "top": "81mm", + "rotate": "18deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid11" + }, + { + "index": 9, + "left": "-10mm", + "top": "140mm", + "rotate": "-22deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid11" + }, + { + "index": 10, + "left": "38mm", + "top": "130mm", + "rotate": "5deg", + "scale": 3.05, + "value": 13, + "asteroid": "asteroid7" + }, + { + "index": 11, + "left": "88mm", + "top": "155mm", + "rotate": "-118deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid11" + } + ], + "ships": [ + { + "index": 0, + "left": "29%", + "top": "51%", + "value": 25 + }, + { + "index": 1, + "left": "71%", + "top": "45%", + "value": 21 + }, + { + "index": 2, + "left": "23%", + "top": "50%", + "value": 32 + } + ], + "baseScales": { + "asteroid7": 1.1 + } + }, + { + "page": 8, + "asteroids": [ + { + "index": 0, + "left": "70mm", + "top": "13mm", + "rotate": "-13deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid14" + }, + { + "index": 1, + "left": "172mm", + "top": "7mm", + "rotate": "-38deg", + "scale": 1.8, + "value": 10, + "asteroid": "asteroid4" + }, + { + "index": 2, + "left": "36mm", + "top": "-5mm", + "rotate": "-43deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid14" + }, + { + "index": 3, + "left": "108mm", + "top": "10mm", + "rotate": "-12deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid14" + }, + { + "index": 4, + "left": "41mm", + "top": "50mm", + "rotate": "15deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid4" + }, + { + "index": 5, + "left": "78mm", + "top": "63mm", + "rotate": "-8deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid14" + }, + { + "index": 6, + "left": "97mm", + "top": "41mm", + "rotate": "-30deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid14" + }, + { + "index": 7, + "left": "-5mm", + "top": "83mm", + "rotate": "-25deg", + "scale": 1.8, + "value": 10, + "asteroid": "asteroid4" + }, + { + "index": 8, + "left": "56mm", + "top": "88mm", + "rotate": "-35deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid14" + }, + { + "index": 9, + "left": "102mm", + "top": "100mm", + "rotate": "3deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid14" + }, + { + "index": 10, + "left": "147mm", + "top": "142mm", + "rotate": "20deg", + "scale": 1.8, + "value": 10, + "asteroid": "asteroid4" + }, + { + "index": 11, + "left": "59mm", + "top": "132mm", + "rotate": "5deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid14" + }, + { + "index": 12, + "left": "95mm", + "top": "146mm", + "rotate": "-7deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid14" + } + ], + "ships": [ + { + "index": 0, + "left": "65%", + "top": "35%", + "value": 26 + }, + { + "index": 1, + "left": "29%", + "top": "39%", + "value": 28 + }, + { + "index": 2, + "left": "74%", + "top": "51%", + "value": 30 + } + ] + }, + { + "page": 9, + "asteroids": [ + { + "index": 0, + "left": "45mm", + "top": "1mm", + "rotate": "-20deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid10" + }, + { + "index": 1, + "left": "95mm", + "top": "6mm", + "rotate": "15deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid6" + }, + { + "index": 2, + "left": "125mm", + "top": "-5mm", + "rotate": "-8deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid10" + }, + { + "index": 3, + "left": "-10mm", + "top": "16mm", + "rotate": "22deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid10" + }, + { + "index": 4, + "left": "72mm", + "top": "35mm", + "rotate": "-15deg", + "scale": 1.35, + "value": 7, + "asteroid": "asteroid6" + }, + { + "index": 5, + "left": "27mm", + "top": "38mm", + "rotate": "10deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid10" + }, + { + "index": 6, + "left": "120mm", + "top": "67mm", + "rotate": "25deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid10" + }, + { + "index": 7, + "left": "57mm", + "top": "91mm", + "rotate": "-12deg", + "scale": 1.65, + "value": 9, + "asteroid": "asteroid6" + }, + { + "index": 8, + "left": "91mm", + "top": "63mm", + "rotate": "18deg", + "scale": 0.6, + "value": 2, + "asteroid": "asteroid10" + }, + { + "index": 9, + "left": "175mm", + "top": "81mm", + "rotate": "-5deg", + "scale": 1.5, + "value": 8, + "asteroid": "asteroid10" + }, + { + "index": 10, + "left": "-5mm", + "top": "123mm", + "rotate": "12deg", + "scale": 0.9, + "value": 4, + "asteroid": "asteroid6" + }, + { + "index": 11, + "left": "67mm", + "top": "139mm", + "rotate": "-22deg", + "scale": 1.2, + "value": 6, + "asteroid": "asteroid10" + }, + { + "index": 12, + "left": "108mm", + "top": "95mm", + "rotate": "8deg", + "scale": 0.75, + "value": 3, + "asteroid": "asteroid10" + }, + { + "index": 13, + "left": "15mm", + "top": "155mm", + "rotate": "20deg", + "scale": 2.1, + "value": 12, + "asteroid": "asteroid10" + }, + { + "index": 14, + "left": "99mm", + "top": "160mm", + "rotate": "-18deg", + "scale": 1.05, + "value": 5, + "asteroid": "asteroid10" + } + ], + "ships": [ + { + "index": 0, + "left": "27%", + "top": "33%", + "value": 26 + }, + { + "index": 1, + "left": "65%", + "top": "50%", + "value": 18 + }, + { + "index": 2, + "left": "35%", + "top": "50%", + "value": 34 + } + ] + } + ] +} \ No newline at end of file diff --git a/tasks/collecting-asteroids/docs/collecting-asteroids-3.md b/tasks/collecting-asteroids/docs/collecting-asteroids-3.md new file mode 100644 index 0000000..373438d --- /dev/null +++ b/tasks/collecting-asteroids/docs/collecting-asteroids-3.md @@ -0,0 +1,36 @@ +# Collecting Asteroids 3 + +**Title:** Собери Астероиды +**Subtitle:** Загрузи трюмы кораблей! +**Footer bubble:** Итого загружено: + +## Notes + +v3: reshuffled assets, halved asteroid values. Includes explicit asteroidValues per page. + +## Layout + +- 3 ships per page, 2 asteroid types per page (70:30 ratio) +- Asteroids: assets/icons/pack3-asteroids/ + +## Pages + +### Page 1 +- **Ships:** capacity 11 (fill 2), capacity 9 (fill 2), capacity 13 (fill 6) +- **Hero:** splitter4.png, direction: row +- **Cargo bays:** cargo-bay7, cargo-bay8, cargo-bay9 +- **Asteroid types:** asteroid3, asteroid10 +- **Asteroid values:** 3, 2, 1, 4, 5, 2, 3, 6, 5, 4, 1, 6 + +### Page 2 +- **Ships:** capacity 12 (fill 3), capacity 12 (fill 3), capacity 18 (fill 4) +- **Hero:** splitter7.png, direction: row-reverse +- **Cargo bays:** cargo-bay1, cargo-bay2, cargo-bay3 +- **Asteroid types:** asteroid6, asteroid13 +- **Asteroid values:** 4, 5, 3, 6, 2, 7, 4, 3, 5, 2, 6, 4 + +### Page 3 +- **Ships:** capacity 9 (fill 5), capacity 9 (fill 5), capacity 11 (fill 2) +- **Hero:** splitter1.png, direction: row +- **Cargo bays:** cargo-bay4, cargo-bay5, cargo-bay6 +- **Asteroid types:** asteroid1, asteroid8 diff --git a/tasks/collecting-asteroids/docs/collecting-asteroids-3.template.html b/tasks/collecting-asteroids/docs/collecting-asteroids-3.template.html new file mode 100644 index 0000000..d02e812 --- /dev/null +++ b/tasks/collecting-asteroids/docs/collecting-asteroids-3.template.html @@ -0,0 +1,347 @@ + + + + + + + + + + Собери Астероиды + + + + + + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
10
+
11
+
12
+ +
3
+
2
+
2
+
4
+
4
+
2
+
4
+
6
+
6
+
4
+
2
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
12
+
12
+
18
+ +
4
+
5
+
3
+
6
+
2
+
7
+
4
+
3
+
5
+
2
+
6
+
4
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
7
+
5
+
6
+ +
4
+
8
+
3
+
9
+
10
+
2
+
12
+
2
+
4
+
10
+
8
+
3
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
15
+
10
+
25
+ +
5
+
3
+
5
+
5
+
3
+
5
+
5
+
2
+
5
+
5
+
2
+
5
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
13
+
11
+
15
+ +
2
+
1
+
4
+
2
+
3
+
2
+
6
+
5
+
6
+
6
+
4
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
18
+
18
+
14
+ +
2
+
7
+
6
+
6
+
1
+
4
+
6
+
3
+
2
+
4
+
5
+
4
+
2
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
25
+
21
+
32
+ +
4
+
8
+
2
+
8
+
11
+
3
+
7
+
10
+
6
+
4
+
13
+
5
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
26
+
28
+
30
+ +
8
+
10
+
7
+
5
+
8
+
3
+
5
+
10
+
5
+
7
+
10
+
7
+
6
+
+
+
+ + +
+
+
+ +
+
+
+ +
+

Собери Астероиды

+

Загрузи трюмы кораблей!

+
+
+
+
26
+
18
+
34
+ +
6
+
3
+
2
+
7
+
7
+
5
+
5
+
9
+
2
+
8
+
4
+
6
+
3
+
12
+
5
+
+
+
+ + + diff --git a/tasks/collecting-asteroids/editor.html b/tasks/collecting-asteroids/editor.html new file mode 100644 index 0000000..ad06848 --- /dev/null +++ b/tasks/collecting-asteroids/editor.html @@ -0,0 +1,489 @@ + + + + + + Asteroid Position Editor + + + + +
+ Asteroid Editor + +
+ + + + +
+ +
+ +
+ Click an asteroid or ship circle to select it + +
+ +
+
+ + + + + diff --git a/tasks/collecting-asteroids/scripts/generate.mjs b/tasks/collecting-asteroids/scripts/generate.mjs new file mode 100644 index 0000000..f5af939 --- /dev/null +++ b/tasks/collecting-asteroids/scripts/generate.mjs @@ -0,0 +1,171 @@ +#!/usr/bin/env node + +/** + * Generate output HTML from template + data for collecting-asteroids documents. + * + * Usage: node generate.mjs + * Example: node generate.mjs collecting-asteroids-3 + * + * Reads: docs/.template.html + * Reads: docs/.data.json (optional) + * Writes: docs/.output.html + * + * data.json format: + * { + * pages: [{ + * page: 1, + * asteroids: [{ index, left, top, rotate, scale, value, asteroid }], + * ships: [{ index, left, top, value }], + * baseScales: { "asteroid5": 0.35 } + * }] + * } + */ + +import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const docsDir = join(__dirname, '..', 'docs'); + +const docId = process.argv[2]; +if (!docId) { + console.error('Usage: node generate.mjs '); + process.exit(1); +} + +const templatePath = join(docsDir, `${docId}.template.html`); +const dataPath = join(docsDir, `${docId}.data.json`); +const outputPath = join(docsDir, `${docId}.output.html`); + +if (!existsSync(templatePath)) { + console.error(`Template not found: ${templatePath}`); + process.exit(1); +} + +let html = readFileSync(templatePath, 'utf-8'); + +if (existsSync(dataPath)) { + const data = JSON.parse(readFileSync(dataPath, 'utf-8')); + html = applyData(html, data); + console.log(`Applied data from ${data.pages?.length || 0} pages`); +} + +writeFileSync(outputPath, html); +console.log(`Generated: ${outputPath}`); + +function applyData(html, data) { + if (!data.pages) return html; + + // Split HTML into pages by PAGE comment markers or by w-[210mm] divs + const pageMarker = / + const parts = html.split(/( +

Исследуй Планету

+
+
+
Space Exploration 1 (3 pages)
+ +
+
+
Space Worksheet 2 (3 pages)
+ +
+
+
Space Worksheet 3 (9 pages)
+ +
+
+ + +

Собери Астероиды

+
+
+
Collecting Asteroids 1
+ +
+
+
Collecting Asteroids 2
+ +
+
+
Collecting Asteroids 3
+ +
+
+ + +

Проложи Маршрут

+
+
+
Space Route 1
+ +
+
+ + + diff --git a/tasks/space-exploration-1.json b/tasks/space-exploration-1.json deleted file mode 100644 index 9440da0..0000000 --- a/tasks/space-exploration-1.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "id": "space-exploration-1", - "title": "Исследуй Планету", - "description": "3-page space worksheet: addition ±, multiply by 5 ±, multiplication table ±", - "labels": { - "title": "Исследуй Планету", - "subtitle": "Собери ресурсы, решая примеры!", - "footerBubble": "Итого собрано на планете:" - }, - "theme": { - "style": "space", - "template": "space-base", - "icons": "assets/icons/pack1/" - }, - "layout": { - "columns": 2, - "problemsPerPage": 20 - }, - "pages": [ - { - "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship2.jpeg", - "footerImage": "assets/footers/planet3.jpeg", - "heroDirection": "row-reverse" - }, - { - "task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship4.jpeg", - "footerImage": "assets/footers/planet5.jpeg", - "heroDirection": "row" - }, - { - "task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship6.jpeg", - "footerImage": "assets/footers/planet1.jpeg", - "heroDirection": "row-reverse" - } - ] -} diff --git a/tasks/space-exploration/CLAUDE.md b/tasks/space-exploration/CLAUDE.md new file mode 100644 index 0000000..91a87ff --- /dev/null +++ b/tasks/space-exploration/CLAUDE.md @@ -0,0 +1,45 @@ +# Space Exploration Task Type + +Math problem worksheets with space theme: hero images, footer panoramas, icon-decorated problem cards. + +## Base References + +- Base template: `src/templates/space-base.html` (layout/styling reference) +- Example outputs in `docs/` (existing worksheets serve as reference for new ones) + +## What to Vary Per Worksheet + +1. **Hero image** — from `assets/hero-images/spaceship{1-9}.jpeg` +2. **Footer image** — from `assets/footers/planet{1-9}.jpeg` +3. **Hero position** — `flex-row-reverse` (hero right) or default (hero left) +4. **Problem icons** — from `assets/icons/pack1/` or `pack2/`. **Every icon must be unique across the entire document** (no repeats across pages). Shuffle minerals and plants randomly — do not sort by type +5. **Problem alignment** — randomly assign `justify-start`, `justify-center`, or `justify-end` per card. No patterns — should look chaotic/scattered +6. **Problems** — generate from the task description in the `.md` file + +## Layout Structure (do not change) + +- Page: `w-[210mm] h-[297mm]` white container +- Footer: absolute bottom, `h-[80mm]`, with white-to-transparent fade on top. **No `overflow-hidden`** on footer (causes 1px hairline artifact in PDF) +- Footer bubble: absolute `bottom-[12mm]`, pill-shaped with semi-transparent white bg +- Content area: `px-[12mm] pt-[4mm] pb-[65mm]` flex column +- Header: hero image `w-[48%]` + title block centered, `flex-row-reverse` for hero-right +- Footer gradient: `linear-gradient(to bottom, white 0%, rgba(255,255,255,0.6) 25%, transparent 50%)` with `h-full` +- Problems: `grid grid-cols-2 gap-x-3 gap-y-[3px]` — 20 problems total +- Each problem: 58px icon outside pill + `text-[1.2rem]` expression + `w-16` answer underline inside pill +- Font: Nunito via Google Fonts +- Uses Tailwind CDN + +## Color Palette (do not change) + +| Element | Hex | +|---------|-----| +| Title text | `text-indigo-950` (#1e1b4b) | +| Subtitle | `text-indigo-400` (#6366f1) | +| Card border | `border-indigo-100` (#e0e7ff) | +| Answer underline | `border-indigo-300` (#a5b4fc) | +| Card bg gradient | `from-white to-indigo-50/40` | +| Footer bubble border | `border-indigo-200` | + +## Scripts + +- `scripts/generate-worksheet3.mjs` — generator for 9-page combined worksheets diff --git a/tasks/space-exploration/docs/space-demo.html b/tasks/space-exploration/docs/space-demo.html new file mode 100644 index 0000000..f613e09 --- /dev/null +++ b/tasks/space-exploration/docs/space-demo.html @@ -0,0 +1,200 @@ + + + + + + + + + + Исследуй Планету + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ + + +
+ +
+
+ + 5 × 3 + 8 =   +
+
+ +
+
+ + 7 × 4 − 6 =   +
+
+ +
+
+ + 3 × 6 + 5 =   +
+
+ +
+
+ + 8 × 2 + 3 =   +
+
+ +
+
+ + 4 × 5 − 7 =   +
+
+ +
+
+ + 6 × 3 + 9 =   +
+
+ +
+
+ + 9 × 2 − 4 =   +
+
+ +
+
+ + 7 × 3 + 2 =   +
+
+ +
+
+ + 2 × 8 + 6 =   +
+
+ +
+
+ + 5 × 4 − 3 =   +
+
+ +
+
+ + 3 × 7 + 4 =   +
+
+ +
+
+ + 9 × 3 − 5 =   +
+
+ +
+
+ + 4 × 6 + 7 =   +
+
+ +
+
+ + 8 × 3 − 9 =   +
+
+ +
+
+ + 6 × 4 + 2 =   +
+
+ +
+
+ + 7 × 2 + 8 =   +
+
+ +
+
+ + 2 × 9 − 3 =   +
+
+ +
+
+ + 5 × 5 + 4 =   +
+
+ +
+
+ + 3 × 8 − 6 =   +
+
+ +
+
+ + 4 × 7 + 5 =   +
+
+ +
+
+
+ + + diff --git a/tasks/space-exploration/docs/space-exploration-1-example.html b/tasks/space-exploration/docs/space-exploration-1-example.html new file mode 100644 index 0000000..f13f677 --- /dev/null +++ b/tasks/space-exploration/docs/space-exploration-1-example.html @@ -0,0 +1,537 @@ + + + + + + + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 12 + 7 + 2 =   +
+
+ +
+
+ + 9 + 5 − 1 =   +
+
+ +
+
+ + 14 + 6 + 3 =   +
+
+ +
+
+ + 11 + 4 − 2 =   +
+
+ +
+
+ + 8 + 8 + 1 =   +
+
+ +
+
+ + 15 + 5 − 3 =   +
+
+ +
+
+ + 10 + 7 + 2 =   +
+
+ +
+
+ + 13 + 4 − 1 =   +
+
+ +
+
+ + 16 + 6 + 3 =   +
+
+ +
+
+ + 9 + 8 − 2 =   +
+
+ +
+
+ + 11 + 5 + 1 =   +
+
+ +
+
+ + 14 + 7 − 3 =   +
+
+ +
+
+ + 8 + 6 + 2 =   +
+
+ +
+
+ + 12 + 4 − 1 =   +
+
+ +
+
+ + 15 + 8 + 3 =   +
+
+ +
+
+ + 10 + 5 − 2 =   +
+
+ +
+
+ + 13 + 7 + 1 =   +
+
+ +
+
+ + 16 + 4 − 3 =   +
+
+ +
+
+ + 9 + 6 + 2 =   +
+
+ +
+
+ + 11 + 8 − 1 =   +
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 5 × 3 + 4 =   +
+
+ +
+
+ + 5 × 1 − 2 =   +
+
+ +
+
+ + 5 × 5 + 6 =   +
+
+ +
+
+ + 5 × 2 − 1 =   +
+
+ +
+
+ + 5 × 4 + 3 =   +
+
+ +
+
+ + 5 × 1 + 5 =   +
+
+ +
+
+ + 5 × 3 − 3 =   +
+
+ +
+
+ + 5 × 5 + 2 =   +
+
+ +
+
+ + 5 × 2 + 6 =   +
+
+ +
+
+ + 5 × 4 − 2 =   +
+
+ +
+
+ + 5 × 1 + 4 =   +
+
+ +
+
+ + 5 × 3 + 1 =   +
+
+ +
+
+ + 5 × 5 − 1 =   +
+
+ +
+
+ + 5 × 2 + 3 =   +
+
+ +
+
+ + 5 × 4 + 5 =   +
+
+ +
+
+ + 5 × 1 − 3 =   +
+
+ +
+
+ + 5 × 3 + 6 =   +
+
+ +
+
+ + 5 × 2 − 2 =   +
+
+ +
+
+ + 5 × 5 + 4 =   +
+
+ +
+
+ + 5 × 4 − 1 =   +
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ + 3 × 4 + 5 =   +
+
+ +
+
+ + 2 × 3 − 2 =   +
+
+ +
+
+ + 4 × 4 + 7 =   +
+
+ +
+
+ + 1 × 3 + 6 =   +
+
+ +
+
+ + 3 × 2 − 3 =   +
+
+ +
+
+ + 4 × 3 + 2 =   +
+
+ +
+
+ + 2 × 4 − 1 =   +
+
+ +
+
+ + 1 × 4 + 8 =   +
+
+ +
+
+ + 3 × 3 − 4 =   +
+
+ +
+
+ + 4 × 2 + 3 =   +
+
+ +
+
+ + 2 × 2 + 5 =   +
+
+ +
+
+ + 1 × 2 + 7 =   +
+
+ +
+
+ + 4 × 4 − 3 =   +
+
+ +
+
+ + 3 × 1 + 4 =   +
+
+ +
+
+ + 2 × 3 + 6 =   +
+
+ +
+
+ + 4 × 1 − 2 =   +
+
+ +
+
+ + 3 × 4 + 8 =   +
+
+ +
+
+ + 1 × 3 + 3 =   +
+
+ +
+
+ + 2 × 4 + 1 =   +
+
+ +
+
+ + 4 × 3 − 4 =   +
+
+ +
+
+
+ + + diff --git a/tasks/space-exploration/docs/space-exploration-1.md b/tasks/space-exploration/docs/space-exploration-1.md new file mode 100644 index 0000000..5235d8b --- /dev/null +++ b/tasks/space-exploration/docs/space-exploration-1.md @@ -0,0 +1,27 @@ +# Space Exploration 1 + +**Title:** Исследуй Планету +**Subtitle:** Собери ресурсы, решая примеры! +**Footer bubble:** Итого собрано на планете: + +## Layout + +- 2 columns, 20 problems per page +- Icons: assets/icons/pack1/ + +## Pages + +### Page 1 +- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly +- **Problem count:** 20 +- **Hero:** spaceship2.jpeg, direction: row-reverse + +### Page 2 +- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly +- **Problem count:** 20 +- **Hero:** spaceship4.jpeg, direction: row + +### Page 3 +- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly +- **Problem count:** 20 +- **Hero:** spaceship6.jpeg, direction: row-reverse diff --git a/tasks/space-exploration/docs/space-exploration-1.template.html b/tasks/space-exploration/docs/space-exploration-1.template.html new file mode 100644 index 0000000..98227c7 --- /dev/null +++ b/tasks/space-exploration/docs/space-exploration-1.template.html @@ -0,0 +1,657 @@ + + + + + + + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 12 + 7 + 2 =   +
+
+
+ +
+
+ +
+ 9 + 5 − 1 =   +
+
+
+ +
+
+ +
+ 14 + 6 + 3 =   +
+
+
+ +
+
+ +
+ 11 + 4 − 2 =   +
+
+
+ +
+
+ +
+ 8 + 8 + 1 =   +
+
+
+ +
+
+ +
+ 15 + 5 − 3 =   +
+
+
+ +
+
+ +
+ 10 + 7 + 2 =   +
+
+
+ +
+
+ +
+ 13 + 4 − 1 =   +
+
+
+ +
+
+ +
+ 16 + 6 + 3 =   +
+
+
+ +
+
+ +
+ 9 + 8 − 2 =   +
+
+
+ +
+
+ +
+ 11 + 5 + 1 =   +
+
+
+ +
+
+ +
+ 14 + 7 − 3 =   +
+
+
+ +
+
+ +
+ 8 + 6 + 2 =   +
+
+
+ +
+
+ +
+ 12 + 4 − 1 =   +
+
+
+ +
+
+ +
+ 15 + 8 + 3 =   +
+
+
+ +
+
+ +
+ 10 + 5 − 2 =   +
+
+
+ +
+
+ +
+ 13 + 7 + 1 =   +
+
+
+ +
+
+ +
+ 16 + 4 − 3 =   +
+
+
+ +
+
+ +
+ 9 + 6 + 2 =   +
+
+
+ +
+
+ +
+ 11 + 8 − 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 5 × 3 + 4 =   +
+
+
+ +
+
+ +
+ 5 × 1 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 2 − 1 =   +
+
+
+ +
+
+ +
+ 5 × 4 + 3 =   +
+
+
+ +
+
+ +
+ 5 × 1 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 2 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 1 + 4 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 1 =   +
+
+
+ +
+
+ +
+ 5 × 5 − 1 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 3 =   +
+
+
+ +
+
+ +
+ 5 × 4 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 1 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 2 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 4 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 3 × 4 + 5 =   +
+
+
+ +
+
+ +
+ 2 × 3 − 2 =   +
+
+
+ +
+
+ +
+ 4 × 4 + 7 =   +
+
+
+ +
+
+ +
+ 1 × 3 + 6 =   +
+
+
+ +
+
+ +
+ 3 × 2 − 3 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 2 =   +
+
+
+ +
+
+ +
+ 2 × 4 − 1 =   +
+
+
+ +
+
+ +
+ 1 × 4 + 8 =   +
+
+
+ +
+
+ +
+ 3 × 3 − 4 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 3 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 5 =   +
+
+
+ +
+
+ +
+ 1 × 2 + 7 =   +
+
+
+ +
+
+ +
+ 4 × 4 − 3 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 4 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 6 =   +
+
+
+ +
+
+ +
+ 4 × 1 − 2 =   +
+
+
+ +
+
+ +
+ 3 × 4 + 8 =   +
+
+
+ +
+
+ +
+ 1 × 3 + 3 =   +
+
+
+ +
+
+ +
+ 2 × 4 + 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 − 4 =   +
+
+
+ +
+
+
+ + + diff --git a/tasks/space-exploration/docs/space-worksheet2-example.html b/tasks/space-exploration/docs/space-worksheet2-example.html new file mode 100644 index 0000000..5019b5c --- /dev/null +++ b/tasks/space-exploration/docs/space-worksheet2-example.html @@ -0,0 +1,659 @@ + + + + + + + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 18 + 7 − 3 =   +
+
+
+ +
+
+ +
+ 15 − 9 + 4 =   +
+
+
+ +
+
+ +
+ 22 + 6 − 5 =   +
+
+
+ +
+
+ +
+ 12 − 8 + 2 =   +
+
+
+ +
+
+ +
+ 20 + 10 + 3 =   +
+
+
+ +
+
+ +
+ 16 − 7 − 4 =   +
+
+
+ +
+
+ +
+ 24 + 8 + 5 =   +
+
+
+ +
+
+ +
+ 14 − 6 + 3 =   +
+
+
+ +
+
+ +
+ 19 + 9 − 2 =   +
+
+
+ +
+
+ +
+ 13 − 10 + 5 =   +
+
+
+ +
+
+ +
+ 21 + 7 + 4 =   +
+
+
+ +
+
+ +
+ 17 − 8 − 3 =   +
+
+
+ +
+
+ +
+ 23 + 6 − 4 =   +
+
+
+ +
+
+ +
+ 12 + 10 − 5 =   +
+
+
+ +
+
+ +
+ 15 + 9 + 2 =   +
+
+
+ +
+
+ +
+ 20 − 7 + 3 =   +
+
+
+ +
+
+ +
+ 24 − 6 − 5 =   +
+
+
+ +
+
+ +
+ 18 + 8 − 2 =   +
+
+
+ +
+
+ +
+ 14 + 10 + 4 =   +
+
+
+ +
+
+ +
+ 16 − 9 + 5 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
Посчитай пятёрками: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 для зарядки расщепителя
+ +
+ +
+
+ +
+ 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 7 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 11 =   +
+
+
+ +
+
+ +
+ 5 × 5 − 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 9 =   +
+
+
+ +
+
+ +
+ 5 × 6 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 2 =   +
+
+
+ +
+
+ +
+ 5 × 8 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 4 =   +
+
+
+ +
+
+ +
+ 5 × 10 + 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 12 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 1 =   +
+
+
+ +
+
+ +
+ 5 × 7 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 8 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 6 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 3 × 2 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 1 =   +
+
+
+ +
+
+
+ + + diff --git a/tasks/space-exploration/docs/space-worksheet2.md b/tasks/space-exploration/docs/space-worksheet2.md new file mode 100644 index 0000000..4a12a64 --- /dev/null +++ b/tasks/space-exploration/docs/space-worksheet2.md @@ -0,0 +1,27 @@ +# Space Worksheet 2 + +**Title:** Исследуй Планету +**Subtitle:** Собери ресурсы, ре��ая примеры! +**Footer bubble:** Итого собрано на планете: + +## Layout + +- 2 columns, 20 problems per page +- Icons: assets/icons/pack2/ + +## Pages + +### Page 1 +- **Task:** A + B + C, where A from 12 to 24, B +/-(from 6 to 10), C +/-(from 2 to 5). Result from 0 to 40 inclusive +- **Problem count:** 20 +- **Hero:** spaceship1.jpeg, direction: row-reverse + +### Page 2 +- **Task:** 5 + 5 + 5 (adding fives: 2, 3 or 4 of them) OR 5 * N (N from 1 to 12) OR 5 * N +/- 5 +- **Problem count:** 20 +- **Hero:** spaceship3.png, direction: row + +### Page 3 +- **Task:** A * B + C * D, where A from 2 to 4, B from 1 to 3, C from 2 to 3, D from 1 to 2 +- **Problem count:** 20 +- **Hero:** spaceship5.jpeg, direction: row-reverse diff --git a/tasks/space-exploration/docs/space-worksheet2.template.html b/tasks/space-exploration/docs/space-worksheet2.template.html new file mode 100644 index 0000000..8fba40b --- /dev/null +++ b/tasks/space-exploration/docs/space-worksheet2.template.html @@ -0,0 +1,1293 @@ + + + + + + + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 18 + 7 − 3 =   +
+
+
+ +
+
+ +
+ 15 − 9 + 4 =   +
+
+
+ +
+
+ +
+ 22 + 6 − 5 =   +
+
+
+ +
+
+ +
+ 12 − 8 + 2 =   +
+
+
+ +
+
+ +
+ 20 + 10 + 3 =   +
+
+
+ +
+
+ +
+ 16 − 7 − 4 =   +
+
+
+ +
+
+ +
+ 24 + 8 + 5 =   +
+
+
+ +
+
+ +
+ 14 − 6 + 3 =   +
+
+
+ +
+
+ +
+ 19 + 9 − 2 =   +
+
+
+ +
+
+ +
+ 13 − 10 + 5 =   +
+
+
+ +
+
+ +
+ 21 + 7 + 4 =   +
+
+
+ +
+
+ +
+ 17 − 8 − 3 =   +
+
+
+ +
+
+ +
+ 23 + 6 − 4 =   +
+
+
+ +
+
+ +
+ 12 + 10 − 5 =   +
+
+
+ +
+
+ +
+ 15 + 9 + 2 =   +
+
+
+ +
+
+ +
+ 20 − 7 + 3 =   +
+
+
+ +
+
+ +
+ 24 − 6 − 5 =   +
+
+
+ +
+
+ +
+ 18 + 8 − 2 =   +
+
+
+ +
+
+ +
+ 14 + 10 + 4 =   +
+
+
+ +
+
+ +
+ 16 − 9 + 5 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
Посчитай пятёрками: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 для зарядки расщепителя
+ +
+ +
+
+ +
+ 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 7 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 11 =   +
+
+
+ +
+
+ +
+ 5 × 5 − 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 9 =   +
+
+
+ +
+
+ +
+ 5 × 6 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 2 =   +
+
+
+ +
+
+ +
+ 5 × 8 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 4 =   +
+
+
+ +
+
+ +
+ 5 × 10 + 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 12 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 1 =   +
+
+
+ +
+
+ +
+ 5 × 7 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 8 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 6 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 3 × 2 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 15 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 22 − 2 × 2 =   +
+
+
+ +
+
+ +
+ 10 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 24 − 3 × 1 =   +
+
+
+ +
+
+ +
+ 25 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 12 − 3 × 2 =   +
+
+
+ +
+
+ +
+ 20 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 14 − 2 × 2 =   +
+
+
+ +
+
+ +
+ 11 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 18 − 3 × 2 =   +
+
+
+ +
+
+ +
+ 13 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 21 − 3 × 2 =   +
+
+
+ +
+
+ +
+ 17 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 25 − 3 × 2 =   +
+
+
+ +
+
+ +
+ 10 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 16 − 2 × 1 =   +
+
+
+ +
+
+ +
+ 23 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 20 − 3 × 1 =   +
+
+
+ +
+
+ +
+ 11 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 14 + 3 × 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
Расщепитель перегрелся! Посчитай десятками до 100: 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, чтобы охладить его
+ +
+ +
+
+ +
+ 30 + 20 =   +
+
+
+ +
+
+ +
+ 70 − 30 =   +
+
+
+ +
+
+ +
+ 10 + 10 =   +
+
+
+ +
+
+ +
+ 50 − 20 =   +
+
+
+ +
+
+ +
+ 40 + 30 =   +
+
+
+ +
+
+ +
+ 60 − 10 =   +
+
+
+ +
+
+ +
+ 20 + 30 =   +
+
+
+ +
+
+ +
+ 50 − 30 =   +
+
+
+ +
+
+ +
+ 70 + 30 =   +
+
+
+ +
+
+ +
+ 30 − 30 =   +
+
+
+ +
+
+ +
+ 60 + 20 =   +
+
+
+ +
+
+ +
+ 40 − 10 =   +
+
+
+ +
+
+ +
+ 10 + 20 =   +
+
+
+ +
+
+ +
+ 20 − 10 =   +
+
+
+ +
+
+ +
+ 50 + 10 =   +
+
+
+ +
+
+ +
+ 70 − 20 =   +
+
+
+ +
+
+ +
+ 60 + 30 =   +
+
+
+ +
+
+ +
+ 40 − 20 =   +
+
+
+ +
+
+ +
+ 10 + 30 =   +
+
+
+ +
+
+ +
+ 30 − 10 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
Переключи расщепитель в режим деления, там, где увидишь знак « : »
+ +
+ +
+
+ +
+ 5 + 5 =   +
+
+
+ +
+
+ +
+ 16 : 2 =   +
+
+
+ +
+
+ +
+ 3 × 2 =   +
+
+
+ +
+
+ +
+ 8 + 8 =   +
+
+
+ +
+
+ +
+ 6 : 2 =   +
+
+
+ +
+
+ +
+ 7 × 2 =   +
+
+
+ +
+
+ +
+ 1 + 1 =   +
+
+
+ +
+
+ +
+ 20 : 2 =   +
+
+
+ +
+
+ +
+ 9 × 2 =   +
+
+
+ +
+
+ +
+ 4 + 4 =   +
+
+
+ +
+
+ +
+ 14 : 2 =   +
+
+
+ +
+
+ +
+ 6 × 2 =   +
+
+
+ +
+
+ +
+ 10 + 10 =   +
+
+
+ +
+
+ +
+ 8 : 2 =   +
+
+
+ +
+
+ +
+ 2 × 2 =   +
+
+
+ +
+
+ +
+ 7 + 7 =   +
+
+
+ +
+
+ +
+ 12 : 2 =   +
+
+
+ +
+
+ +
+ 5 × 2 =   +
+
+
+ +
+
+ +
+ 2 + 2 =   +
+
+
+ +
+
+ +
+ 18 : 2 =   +
+
+
+ +
+
+
+ + + diff --git a/tasks/space-exploration/docs/space-worksheet3.md b/tasks/space-exploration/docs/space-worksheet3.md new file mode 100644 index 0000000..beb2ac6 --- /dev/null +++ b/tasks/space-exploration/docs/space-worksheet3.md @@ -0,0 +1,53 @@ +# Space Worksheet 3 + +**Title:** Исследуй Планету +**Subtitle:** Собери ресу��сы, решая примеры! +**Footer bubble:** Итого собрано на планете: + +## Layout + +- 2 columns, 20 problems per page +- Icons: mixed from pack1 and pack2 + +## Notes + +9-page worksheet combining patterns from worksheet1 and worksheet2. +Pages 1-3 use pack1 icons, pages 4-6 use pack2 icons, pages 7-9 use pack1 icons. + +## Pages + +### Page 1 (pack1) +- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly +- **Hero:** spaceship1.jpeg, direction: row-reverse + +### Page 2 (pack1) +- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly +- **Hero:** spaceship2.jpeg, direction: row + +### Page 3 (pack1) +- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly +- **Hero:** spaceship3.png, direction: row-reverse + +### Page 4 (pack2) +- **Task:** A + B + C, where A from 12 to 24, B +/-(from 6 to 10), C +/-(from 2 to 5). Result from 0 to 40 inclusive +- **Hero:** spaceship4.jpeg, direction: row + +### Page 5 (pack2) +- **Task:** 5 + 5 + 5 (adding fives: 2, 3 or 4) OR 5 * N (N from 1 to 12) OR 5 * N +/- 5 +- **Hero:** spaceship5.jpeg, direction: row-reverse + +### Page 6 (pack2) +- **Task:** A * B + C * D, where A from 2 to 4, B from 1 to 3, C from 2 to 3, D from 1 to 2 +- **Hero:** spaceship6.jpeg, direction: row + +### Page 7 (pack1) +- **Task:** A + B +/- C, where A from 8 to 16, B from 4 to 8, C from 1 to 3. Sign +/- chosen randomly +- **Hero:** spaceship7.jpeg, direction: row-reverse + +### Page 8 (pack1) +- **Task:** 5 * N +/- C, where N from 1 to 5, C from 1 to 6. Sign +/- chosen randomly +- **Hero:** spaceship8.jpeg, direction: row + +### Page 9 (pack1) +- **Task:** A * B +/- C, where A and B from 1 to 4, C from 1 to 8. Sign +/- chosen randomly +- **Hero:** spaceship9.jpeg, direction: row-reverse diff --git a/tasks/space-exploration/docs/space-worksheet3.template.html b/tasks/space-exploration/docs/space-worksheet3.template.html new file mode 100644 index 0000000..f9fe2ff --- /dev/null +++ b/tasks/space-exploration/docs/space-worksheet3.template.html @@ -0,0 +1,1919 @@ + + + + + + + + + + Исследуй Планету + + + + + + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 9 + 7 − 1 =   +
+
+
+ +
+
+ +
+ 10 + 4 − 1 =   +
+
+
+ +
+
+ +
+ 11 + 7 + 1 =   +
+
+
+ +
+
+ +
+ 11 + 8 − 3 =   +
+
+
+ +
+
+ +
+ 8 + 8 − 3 =   +
+
+
+ +
+
+ +
+ 11 + 7 + 3 =   +
+
+
+ +
+
+ +
+ 13 + 7 + 1 =   +
+
+
+ +
+
+ +
+ 14 + 5 + 1 =   +
+
+
+ +
+
+ +
+ 16 + 8 + 2 =   +
+
+
+ +
+
+ +
+ 12 + 6 − 2 =   +
+
+
+ +
+
+ +
+ 10 + 5 + 3 =   +
+
+
+ +
+
+ +
+ 12 + 4 − 2 =   +
+
+
+ +
+
+ +
+ 8 + 4 + 1 =   +
+
+
+ +
+
+ +
+ 15 + 4 + 1 =   +
+
+
+ +
+
+ +
+ 13 + 5 − 2 =   +
+
+
+ +
+
+ +
+ 9 + 5 + 1 =   +
+
+
+ +
+
+ +
+ 12 + 4 + 3 =   +
+
+
+ +
+
+ +
+ 12 + 8 − 2 =   +
+
+
+ +
+
+ +
+ 12 + 7 − 1 =   +
+
+
+ +
+
+ +
+ 12 + 4 − 3 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 5 × 3 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 2 − 6 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 1 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 2 =   +
+
+
+ +
+
+ +
+ 5 × 1 + 2 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 3 =   +
+
+
+ +
+
+ +
+ 5 × 5 − 6 =   +
+
+
+ +
+
+ +
+ 5 × 2 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 3 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 4 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 4 =   +
+
+
+ +
+
+ +
+ 5 × 4 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 6 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 1 + 6 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 3 × 4 + 3 =   +
+
+
+ +
+
+ +
+ 1 × 2 − 1 =   +
+
+
+ +
+
+ +
+ 1 × 3 + 8 =   +
+
+
+ +
+
+ +
+ 2 × 3 − 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 − 2 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 8 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 − 4 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 7 =   +
+
+
+ +
+
+ +
+ 2 × 4 + 6 =   +
+
+
+ +
+
+ +
+ 4 × 2 − 6 =   +
+
+
+ +
+
+ +
+ 2 × 3 − 6 =   +
+
+
+ +
+
+ +
+ 4 × 4 + 2 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 2 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 3 =   +
+
+
+ +
+
+ +
+ 4 × 4 − 5 =   +
+
+
+ +
+
+ +
+ 4 × 4 + 8 =   +
+
+
+ +
+
+ +
+ 2 × 4 − 2 =   +
+
+
+ +
+
+ +
+ 1 × 2 + 2 =   +
+
+
+ +
+
+ +
+ 4 × 4 − 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 13 − 6 − 5 =   +
+
+
+ +
+
+ +
+ 23 + 6 + 4 =   +
+
+
+ +
+
+ +
+ 14 − 7 + 5 =   +
+
+
+ +
+
+ +
+ 18 + 10 + 5 =   +
+
+
+ +
+
+ +
+ 17 + 10 − 4 =   +
+
+
+ +
+
+ +
+ 12 + 9 + 4 =   +
+
+
+ +
+
+ +
+ 21 − 10 − 3 =   +
+
+
+ +
+
+ +
+ 23 − 8 + 4 =   +
+
+
+ +
+
+ +
+ 19 − 10 + 3 =   +
+
+
+ +
+
+ +
+ 18 + 7 + 4 =   +
+
+
+ +
+
+ +
+ 19 − 6 − 2 =   +
+
+
+ +
+
+ +
+ 18 − 8 − 5 =   +
+
+
+ +
+
+ +
+ 21 − 6 − 4 =   +
+
+
+ +
+
+ +
+ 22 + 8 + 4 =   +
+
+
+ +
+
+ +
+ 12 + 6 + 5 =   +
+
+
+ +
+
+ +
+ 12 + 10 + 5 =   +
+
+
+ +
+
+ +
+ 17 + 9 + 2 =   +
+
+
+ +
+
+ +
+ 23 + 8 + 5 =   +
+
+
+ +
+
+ +
+ 20 − 7 − 3 =   +
+
+
+ +
+
+ +
+ 23 + 9 − 5 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
Посчитай пятёрками: 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 для зарядки расщепителя
+ +
+ +
+
+ +
+ 5 × 10 =   +
+
+
+ +
+
+ +
+ 5 × 12 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 7 =   +
+
+
+ +
+
+ +
+ 5 × 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 4 =   +
+
+
+ +
+
+ +
+ 5 × 3 =   +
+
+
+ +
+
+ +
+ 5 × 9 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 6 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 1 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 5 =   +
+
+
+ +
+
+ +
+ 5 + 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 2 =   +
+
+
+ +
+
+ +
+ 5 × 10 − 5 =   +
+
+
+ +
+
+ +
+ 5 × 6 =   +
+
+
+ +
+
+ +
+ 5 × 11 =   +
+
+
+ +
+
+ +
+ 5 × 12 =   +
+
+
+ +
+
+ +
+ 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 9 =   +
+
+
+ +
+
+ +
+ 5 × 8 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 2 × 3 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 1 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 2 × 2 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 3 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 2 × 1 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 2 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 3 × 2 + 3 × 2 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 2 × 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 14 + 6 + 2 =   +
+
+
+ +
+
+ +
+ 14 + 5 − 2 =   +
+
+
+ +
+
+ +
+ 8 + 8 − 1 =   +
+
+
+ +
+
+ +
+ 8 + 8 − 3 =   +
+
+
+ +
+
+ +
+ 11 + 6 − 1 =   +
+
+
+ +
+
+ +
+ 10 + 5 − 1 =   +
+
+
+ +
+
+ +
+ 16 + 4 + 2 =   +
+
+
+ +
+
+ +
+ 15 + 7 + 1 =   +
+
+
+ +
+
+ +
+ 11 + 7 − 3 =   +
+
+
+ +
+
+ +
+ 10 + 7 − 2 =   +
+
+
+ +
+
+ +
+ 10 + 7 − 3 =   +
+
+
+ +
+
+ +
+ 13 + 5 − 3 =   +
+
+
+ +
+
+ +
+ 15 + 6 + 3 =   +
+
+
+ +
+
+ +
+ 10 + 8 + 3 =   +
+
+
+ +
+
+ +
+ 12 + 8 − 3 =   +
+
+
+ +
+
+ +
+ 9 + 6 − 3 =   +
+
+
+ +
+
+ +
+ 10 + 8 − 2 =   +
+
+
+ +
+
+ +
+ 13 + 4 − 1 =   +
+
+
+ +
+
+ +
+ 9 + 5 + 3 =   +
+
+
+ +
+
+ +
+ 11 + 5 + 2 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 5 × 5 − 4 =   +
+
+
+ +
+
+ +
+ 5 × 5 − 6 =   +
+
+
+ +
+
+ +
+ 5 × 3 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 2 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 1 + 1 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 1 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 1 − 4 =   +
+
+
+ +
+
+ +
+ 5 × 3 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 1 − 1 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 4 =   +
+
+
+ +
+
+ +
+ 5 × 4 + 5 =   +
+
+
+ +
+
+ +
+ 5 × 4 + 6 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 2 =   +
+
+
+ +
+
+ +
+ 5 × 5 + 2 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 2 =   +
+
+
+ +
+
+ +
+ 5 × 4 − 3 =   +
+
+
+ +
+
+ +
+ 5 × 2 + 1 =   +
+
+
+ +
+
+
+ + +
+ +
+
+ +
+ +
+
+ Итого собрано на планете:   +
+
+ +
+ +
+ +
+

Исследуй Планету

+

Собери ресурсы, решая примеры!

+
+
+ +
+ +
+
+ +
+ 3 × 3 − 5 =   +
+
+
+ +
+
+ +
+ 1 × 2 + 5 =   +
+
+
+ +
+
+ +
+ 2 × 4 + 2 =   +
+
+
+ +
+
+ +
+ 3 × 4 + 8 =   +
+
+
+ +
+
+ +
+ 3 × 4 − 1 =   +
+
+
+ +
+
+ +
+ 1 × 2 − 1 =   +
+
+
+ +
+
+ +
+ 2 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 4 × 2 − 1 =   +
+
+
+ +
+
+ +
+ 1 × 3 + 7 =   +
+
+
+ +
+
+ +
+ 3 × 4 + 4 =   +
+
+
+ +
+
+ +
+ 2 × 4 + 5 =   +
+
+
+ +
+
+ +
+ 1 × 3 + 5 =   +
+
+
+ +
+
+ +
+ 3 × 3 + 1 =   +
+
+
+ +
+
+ +
+ 2 × 1 + 4 =   +
+
+
+ +
+
+ +
+ 1 × 4 + 7 =   +
+
+
+ +
+
+ +
+ 1 × 1 + 8 =   +
+
+
+ +
+
+ +
+ 4 × 3 + 7 =   +
+
+
+ +
+
+ +
+ 4 × 2 − 6 =   +
+
+
+ +
+
+ +
+ 3 × 4 + 3 =   +
+
+
+ +
+
+ +
+ 3 × 1 + 7 =   +
+
+
+ +
+
+
+ + + diff --git a/src/scripts/generate-worksheet3.mjs b/tasks/space-exploration/scripts/generate-worksheet3.mjs similarity index 100% rename from src/scripts/generate-worksheet3.mjs rename to tasks/space-exploration/scripts/generate-worksheet3.mjs diff --git a/tasks/space-exploration/scripts/generate.mjs b/tasks/space-exploration/scripts/generate.mjs new file mode 100644 index 0000000..b2492d3 --- /dev/null +++ b/tasks/space-exploration/scripts/generate.mjs @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +/** + * Generate output HTML from template + data for space-exploration documents. + * + * Usage: node generate.mjs + * Example: node generate.mjs space-exploration-1 + * + * Reads: docs/.template.html + * Reads: docs/.data.json (optional — if missing, copies template as-is) + * Writes: docs/.output.html + */ + +import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const docsDir = join(__dirname, '..', 'docs'); + +const docId = process.argv[2]; +if (!docId) { + console.error('Usage: node generate.mjs '); + process.exit(1); +} + +const templatePath = join(docsDir, `${docId}.template.html`); +const dataPath = join(docsDir, `${docId}.data.json`); +const outputPath = join(docsDir, `${docId}.output.html`); + +if (!existsSync(templatePath)) { + console.error(`Template not found: ${templatePath}`); + process.exit(1); +} + +let html = readFileSync(templatePath, 'utf-8'); + +// If data.json exists, apply it (space-exploration currently has no editor data) +if (existsSync(dataPath)) { + const data = JSON.parse(readFileSync(dataPath, 'utf-8')); + console.log(`Data file found with ${data.pages?.length || 0} pages — no transforms defined yet for space-exploration`); +} + +writeFileSync(outputPath, html); +console.log(`Generated: ${outputPath}`); diff --git a/tasks/space-route/CLAUDE.md b/tasks/space-route/CLAUDE.md new file mode 100644 index 0000000..1e157b9 --- /dev/null +++ b/tasks/space-route/CLAUDE.md @@ -0,0 +1,43 @@ +# Space Route Task Type + +Navigate hex graph routes: player and enemy ships travel through a node graph. Child finds a path by following mathematical constraints between connected nodes. + +## Generation + +Generator script: `scripts/generate-route.mjs` + +### Grid Rules +- 7×9 hex grid with jitter, nodes evenly distributed across map area +- Start nodes: Enemy = top-left corner, Player = bottom-left corner +- Start nodes trimmed to exactly 2 edges + +### Route Rules +- No asteroids/decorations on route nodes or neighbors of start nodes +- Routes use waypoints: route goes toward an offset waypoint for ~40% of steps, then changes direction toward final target (prevents straight-line paths) +- Route length: 7-9 steps for enemy, player gets 10 empty cells +- Ship orientation: check each ship image and set `flipEnemy`/`flipPlayer` flags so ships face right + +### Difficulty +- `diffRange: [minNodeValue, maxSpread]` +- First number = minimum node value +- Second = max |difference| between connected neighbors + +## Scripts + +- `scripts/generate-route.mjs` — full page generation (grid, edges, values, routes, HTML) +- `scripts/apply-edits.mjs` — apply editor JSON back to HTML (regex-based style replacement) + +## Editor + +`editor.html?file={docId}` — two edit modes: + +**Objects mode** (default): drag space icons, edges auto-follow +**Nodes mode** (press M): Shift+click nodes, drag to reposition graph + +Key controls: +- `M`: toggle Objects/Nodes mode +- `R`: toggle enemy route highlight +- `H`: flip selected object horizontally +- `+/-`: resize proportionally +- `[/]`: rotate ±5° +- Save: writes to `docs/{docId}.data.json` diff --git a/tasks/space-route/docs/space-route-1.data.json b/tasks/space-route/docs/space-route-1.data.json new file mode 100644 index 0000000..094176a --- /dev/null +++ b/tasks/space-route/docs/space-route-1.data.json @@ -0,0 +1,111 @@ +{ + "file": "space-route-1.html", + "pages": [ + { + "page": 1, + "objects": [ + { "nodeId": 44, "type": "dest", "src": "asteroid5.png", "left": "157.0mm", "top": "183.5mm", "w": "30mm", "h": "30mm", "rotate": 5, "flipH": false }, + { "nodeId": 4, "type": "deco", "src": "asteroid3.png", "left": "133.5mm", "top": "54.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 15, "type": "deco", "src": "asteroid7.png", "left": "81.0mm", "top": "97.0mm", "w": "54mm", "h": "52mm", "rotate": -20, "flipH": false }, + { "nodeId": 17, "type": "deco", "src": "asteroid11.png", "left": "130.5mm", "top": "97.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 23, "type": "deco", "src": "pod1.png", "left": "115.5mm", "top": "122.0mm", "w": "34mm", "h": "22mm", "rotate": 0, "flipH": false }, + { "nodeId": 29, "type": "deco", "src": "pod2.png", "left": "109.0mm", "top": "146.5mm", "w": "38mm", "h": "24mm", "rotate": 50, "flipH": false }, + { "nodeId": 42, "type": "deco", "src": "freighter1.png", "left": "104.0mm", "top": "191.5mm", "w": "50mm", "h": "26mm", "rotate": -5, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "53.0mm", "top": "48.0mm" }, { "nodeId": 1, "left": "54.0mm", "top": "69.5mm" }, { "nodeId": 2, "left": "84.0mm", "top": "59.0mm" }, { "nodeId": 3, "left": "108.5mm", "top": "56.5mm" }, { "nodeId": 4, "left": "137.5mm", "top": "59.5mm" }, { "nodeId": 5, "left": "160.0mm", "top": "59.5mm" }, { "nodeId": 6, "left": "190.0mm", "top": "78.0mm" }, { "nodeId": 7, "left": "26.0mm", "top": "72.5mm" }, { "nodeId": 8, "left": "53.5mm", "top": "91.0mm" }, { "nodeId": 9, "left": "96.5mm", "top": "73.5mm" }, { "nodeId": 10, "left": "115.7mm", "top": "74.1mm" }, { "nodeId": 11, "left": "144.4mm", "top": "81.4mm" }, { "nodeId": 12, "left": "167.5mm", "top": "83.5mm" }, { "nodeId": 13, "left": "16.0mm", "top": "107.0mm" }, { "nodeId": 14, "left": "47.5mm", "top": "112.0mm" }, { "nodeId": 15, "left": "80.0mm", "top": "96.5mm" }, { "nodeId": 16, "left": "108.5mm", "top": "97.7mm" }, { "nodeId": 17, "left": "131.2mm", "top": "103.4mm" }, { "nodeId": 18, "left": "155.9mm", "top": "95.4mm" }, { "nodeId": 19, "left": "189.0mm", "top": "114.5mm" }, { "nodeId": 20, "left": "29.0mm", "top": "125.0mm" }, { "nodeId": 21, "left": "70.0mm", "top": "118.5mm" }, { "nodeId": 22, "left": "91.6mm", "top": "117.7mm" }, { "nodeId": 23, "left": "113.5mm", "top": "119.8mm" }, { "nodeId": 24, "left": "142.3mm", "top": "117.4mm" }, { "nodeId": 25, "left": "174.0mm", "top": "125.0mm" }, { "nodeId": 26, "left": "23.5mm", "top": "142.1mm" }, { "nodeId": 27, "left": "50.0mm", "top": "145.1mm" }, { "nodeId": 28, "left": "78.0mm", "top": "149.0mm" }, { "nodeId": 29, "left": "103.2mm", "top": "146.3mm" }, { "nodeId": 30, "left": "135.0mm", "top": "139.5mm" }, { "nodeId": 31, "left": "158.9mm", "top": "143.9mm" }, { "nodeId": 32, "left": "177.7mm", "top": "148.2mm" }, { "nodeId": 33, "left": "36.9mm", "top": "166.8mm" }, { "nodeId": 34, "left": "62.6mm", "top": "162.8mm" }, { "nodeId": 35, "left": "100.5mm", "top": "169.0mm" }, { "nodeId": 36, "left": "129.5mm", "top": "170.5mm" }, { "nodeId": 37, "left": "146.0mm", "top": "155.0mm" }, { "nodeId": 38, "left": "166.1mm", "top": "160.7mm" }, { "nodeId": 39, "left": "23.8mm", "top": "191.2mm" }, { "nodeId": 40, "left": "55.3mm", "top": "183.2mm" }, { "nodeId": 41, "left": "78.0mm", "top": "176.0mm" }, { "nodeId": 42, "left": "102.0mm", "top": "199.5mm" }, { "nodeId": 43, "left": "139.5mm", "top": "195.0mm" }, { "nodeId": 44, "left": "157.5mm", "top": "176.0mm" }, { "nodeId": 45, "left": "180.8mm", "top": "190.7mm" }, { "nodeId": 46, "left": "36.3mm", "top": "208.1mm" }, { "nodeId": 47, "left": "57.5mm", "top": "209.0mm" }, { "nodeId": 48, "left": "79.5mm", "top": "215.0mm" }, { "nodeId": 49, "left": "121.0mm", "top": "209.0mm" }, { "nodeId": 50, "left": "146.0mm", "top": "211.5mm" }, { "nodeId": 51, "left": "169.5mm", "top": "206.0mm" }, { "nodeId": 52, "left": "24.3mm", "top": "235.9mm" }, { "nodeId": 53, "left": "57.2mm", "top": "230.9mm" }, { "nodeId": 54, "left": "82.5mm", "top": "232.7mm" }, { "nodeId": 55, "left": "102.5mm", "top": "227.0mm" }, { "nodeId": 56, "left": "125.6mm", "top": "227.0mm" }, { "nodeId": 57, "left": "157.3mm", "top": "233.1mm" }, { "nodeId": 58, "left": "181.5mm", "top": "226.4mm" } + ] + }, + { + "page": 2, + "objects": [ + { "nodeId": 44, "type": "dest", "src": "pod6.png", "left": "174.5mm", "top": "179.5mm", "w": "20mm", "h": "19mm", "rotate": 0, "flipH": false }, + { "nodeId": 5, "type": "deco", "src": "asteroid9.png", "left": "157.2mm", "top": "56.0mm", "w": "54mm", "h": "52mm", "rotate": 55, "flipH": false }, + { "nodeId": 11, "type": "deco", "src": "asteroid14.png", "left": "146.9mm", "top": "82.1mm", "w": "16mm", "h": "15mm", "rotate": 0, "flipH": false }, + { "nodeId": 21, "type": "deco", "src": "asteroid2.png", "left": "60.5mm", "top": "122.0mm", "w": "24mm", "h": "24mm", "rotate": 0, "flipH": false }, + { "nodeId": 28, "type": "deco", "src": "pod4.png", "left": "85.0mm", "top": "142.5mm", "w": "24mm", "h": "15mm", "rotate": 0, "flipH": false }, + { "nodeId": 34, "type": "deco", "src": "pod5.png", "left": "62.0mm", "top": "168.0mm", "w": "24mm", "h": "15mm", "rotate": 0, "flipH": false }, + { "nodeId": 43, "type": "deco", "src": "freighter2.png", "left": "130.5mm", "top": "194.5mm", "w": "58mm", "h": "30mm", "rotate": -5, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "44.5mm", "top": "47.5mm" }, { "nodeId": 1, "left": "62.0mm", "top": "58.5mm" }, { "nodeId": 2, "left": "93.0mm", "top": "69.5mm" }, { "nodeId": 3, "left": "101.0mm", "top": "54.5mm" }, { "nodeId": 4, "left": "127.1mm", "top": "52.9mm" }, { "nodeId": 5, "left": "152.5mm", "top": "58.0mm" }, { "nodeId": 6, "left": "185.0mm", "top": "54.5mm" }, { "nodeId": 7, "left": "19.5mm", "top": "76.5mm" }, { "nodeId": 8, "left": "63.0mm", "top": "78.5mm" }, { "nodeId": 9, "left": "104.0mm", "top": "86.5mm" }, { "nodeId": 10, "left": "120.9mm", "top": "75.2mm" }, { "nodeId": 11, "left": "146.9mm", "top": "82.1mm" }, { "nodeId": 12, "left": "166.6mm", "top": "75.0mm" }, { "nodeId": 13, "left": "12.0mm", "top": "106.0mm" }, { "nodeId": 14, "left": "31.0mm", "top": "100.5mm" }, { "nodeId": 15, "left": "62.5mm", "top": "98.5mm" }, { "nodeId": 16, "left": "106.8mm", "top": "103.6mm" }, { "nodeId": 17, "left": "128.7mm", "top": "102.1mm" }, { "nodeId": 18, "left": "155.9mm", "top": "99.8mm" }, { "nodeId": 19, "left": "180.8mm", "top": "96.9mm" }, { "nodeId": 20, "left": "22.0mm", "top": "124.5mm" }, { "nodeId": 21, "left": "59.0mm", "top": "120.0mm" }, { "nodeId": 22, "left": "89.5mm", "top": "119.0mm" }, { "nodeId": 23, "left": "121.5mm", "top": "119.5mm" }, { "nodeId": 24, "left": "141.9mm", "top": "124.3mm" }, { "nodeId": 25, "left": "168.5mm", "top": "118.0mm" }, { "nodeId": 26, "left": "14.0mm", "top": "155.0mm" }, { "nodeId": 27, "left": "50.8mm", "top": "142.4mm" }, { "nodeId": 28, "left": "85.5mm", "top": "141.0mm" }, { "nodeId": 29, "left": "110.3mm", "top": "147.9mm" }, { "nodeId": 30, "left": "128.0mm", "top": "153.5mm" }, { "nodeId": 31, "left": "162.3mm", "top": "144.4mm" }, { "nodeId": 32, "left": "188.0mm", "top": "129.0mm" }, { "nodeId": 33, "left": "36.2mm", "top": "163.9mm" }, { "nodeId": 34, "left": "66.0mm", "top": "167.5mm" }, { "nodeId": 35, "left": "90.1mm", "top": "164.2mm" }, { "nodeId": 36, "left": "113.3mm", "top": "169.1mm" }, { "nodeId": 37, "left": "140.5mm", "top": "170.5mm" }, { "nodeId": 38, "left": "187.5mm", "top": "153.5mm" }, { "nodeId": 39, "left": "15.0mm", "top": "184.0mm" }, { "nodeId": 40, "left": "51.0mm", "top": "188.5mm" }, { "nodeId": 41, "left": "69.5mm", "top": "185.5mm" }, { "nodeId": 42, "left": "93.0mm", "top": "189.5mm" }, { "nodeId": 43, "left": "137.5mm", "top": "196.0mm" }, { "nodeId": 44, "left": "172.0mm", "top": "177.5mm" }, { "nodeId": 45, "left": "197.0mm", "top": "173.5mm" }, { "nodeId": 46, "left": "26.0mm", "top": "202.5mm" }, { "nodeId": 47, "left": "66.0mm", "top": "202.0mm" }, { "nodeId": 48, "left": "81.5mm", "top": "207.5mm" }, { "nodeId": 49, "left": "107.5mm", "top": "211.0mm" }, { "nodeId": 50, "left": "160.0mm", "top": "213.5mm" }, { "nodeId": 51, "left": "181.5mm", "top": "222.5mm" }, { "nodeId": 52, "left": "36.5mm", "top": "236.0mm" }, { "nodeId": 53, "left": "49.0mm", "top": "214.0mm" }, { "nodeId": 54, "left": "76.5mm", "top": "223.5mm" }, { "nodeId": 55, "left": "100.5mm", "top": "232.0mm" }, { "nodeId": 56, "left": "134.0mm", "top": "222.5mm" }, { "nodeId": 57, "left": "156.2mm", "top": "233.5mm" }, { "nodeId": 58, "left": "200.5mm", "top": "214.0mm" } + ] + }, + { + "page": 3, + "objects": [ + { "nodeId": 51, "type": "dest", "src": "freighter8.png", "left": "160.0mm", "top": "217.5mm", "w": "52mm", "h": "32mm", "rotate": -15, "flipH": false }, + { "nodeId": 2, "type": "deco", "src": "asteroid1.png", "left": "67.5mm", "top": "67.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 9, "type": "deco", "src": "asteroid10.png", "left": "93.5mm", "top": "74.0mm", "w": "26mm", "h": "26mm", "rotate": 0, "flipH": false }, + { "nodeId": 19, "type": "deco", "src": "asteroid6.png", "left": "187.6mm", "top": "100.3mm", "w": "16mm", "h": "15mm", "rotate": 0, "flipH": false }, + { "nodeId": 23, "type": "deco", "src": "pod8.png", "left": "113.1mm", "top": "126.1mm", "w": "20mm", "h": "12mm", "rotate": -25, "flipH": false }, + { "nodeId": 26, "type": "deco", "src": "pod10.png", "left": "19.5mm", "top": "143.0mm", "w": "36mm", "h": "23mm", "rotate": 0, "flipH": false }, + { "nodeId": 35, "type": "deco", "src": "freighter5.png", "left": "86.5mm", "top": "168.5mm", "w": "58mm", "h": "30mm", "rotate": 0, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "41.5mm", "top": "46.5mm" }, { "nodeId": 1, "left": "48.5mm", "top": "77.0mm" }, { "nodeId": 2, "left": "67.0mm", "top": "67.0mm" }, { "nodeId": 3, "left": "110.1mm", "top": "57.1mm" }, { "nodeId": 4, "left": "134.4mm", "top": "59.9mm" }, { "nodeId": 5, "left": "158.2mm", "top": "52.6mm" }, { "nodeId": 6, "left": "185.4mm", "top": "49.6mm" }, { "nodeId": 7, "left": "25.0mm", "top": "63.0mm" }, { "nodeId": 8, "left": "57.0mm", "top": "96.5mm" }, { "nodeId": 9, "left": "93.0mm", "top": "74.0mm" }, { "nodeId": 10, "left": "116.9mm", "top": "73.4mm" }, { "nodeId": 11, "left": "140.3mm", "top": "80.8mm" }, { "nodeId": 12, "left": "165.0mm", "top": "81.8mm" }, { "nodeId": 13, "left": "17.0mm", "top": "107.0mm" }, { "nodeId": 14, "left": "39.0mm", "top": "103.5mm" }, { "nodeId": 15, "left": "82.5mm", "top": "97.4mm" }, { "nodeId": 16, "left": "108.9mm", "top": "100.6mm" }, { "nodeId": 17, "left": "133.1mm", "top": "93.6mm" }, { "nodeId": 18, "left": "156.3mm", "top": "100.2mm" }, { "nodeId": 19, "left": "187.6mm", "top": "100.3mm" }, { "nodeId": 20, "left": "34.7mm", "top": "124.1mm" }, { "nodeId": 21, "left": "70.7mm", "top": "123.2mm" }, { "nodeId": 22, "left": "90.0mm", "top": "117.0mm" }, { "nodeId": 23, "left": "113.1mm", "top": "126.1mm" }, { "nodeId": 24, "left": "141.7mm", "top": "125.1mm" }, { "nodeId": 25, "left": "175.2mm", "top": "117.0mm" }, { "nodeId": 26, "left": "23.5mm", "top": "141.5mm" }, { "nodeId": 27, "left": "54.0mm", "top": "135.5mm" }, { "nodeId": 28, "left": "74.5mm", "top": "139.5mm" }, { "nodeId": 29, "left": "94.5mm", "top": "145.5mm" }, { "nodeId": 30, "left": "146.5mm", "top": "141.5mm" }, { "nodeId": 31, "left": "166.5mm", "top": "134.5mm" }, { "nodeId": 32, "left": "187.9mm", "top": "139.2mm" }, { "nodeId": 33, "left": "23.5mm", "top": "166.5mm" }, { "nodeId": 34, "left": "48.0mm", "top": "165.5mm" }, { "nodeId": 35, "left": "89.0mm", "top": "167.0mm" }, { "nodeId": 36, "left": "128.5mm", "top": "153.0mm" }, { "nodeId": 37, "left": "149.0mm", "top": "160.5mm" }, { "nodeId": 38, "left": "168.7mm", "top": "168.2mm" }, { "nodeId": 39, "left": "28.6mm", "top": "188.9mm" }, { "nodeId": 40, "left": "50.8mm", "top": "185.4mm" }, { "nodeId": 41, "left": "68.0mm", "top": "194.0mm" }, { "nodeId": 42, "left": "108.0mm", "top": "191.5mm" }, { "nodeId": 43, "left": "130.0mm", "top": "187.1mm" }, { "nodeId": 44, "left": "151.5mm", "top": "181.5mm" }, { "nodeId": 45, "left": "185.4mm", "top": "184.6mm" }, { "nodeId": 46, "left": "21.0mm", "top": "219.0mm" }, { "nodeId": 47, "left": "46.5mm", "top": "208.0mm" }, { "nodeId": 48, "left": "90.1mm", "top": "205.9mm" }, { "nodeId": 49, "left": "110.0mm", "top": "211.5mm" }, { "nodeId": 50, "left": "134.0mm", "top": "205.5mm" }, { "nodeId": 51, "left": "167.0mm", "top": "215.5mm" }, { "nodeId": 52, "left": "54.5mm", "top": "243.0mm" }, { "nodeId": 53, "left": "59.5mm", "top": "223.0mm" }, { "nodeId": 54, "left": "83.5mm", "top": "225.5mm" }, { "nodeId": 55, "left": "108.0mm", "top": "243.0mm" }, { "nodeId": 56, "left": "127.5mm", "top": "230.0mm" }, { "nodeId": 57, "left": "161.0mm", "top": "242.5mm" }, { "nodeId": 58, "left": "199.5mm", "top": "235.5mm" } + ] + }, + { + "page": 4, + "objects": [ + { "nodeId": 44, "type": "dest", "src": "pod16.png", "left": "157.5mm", "top": "189.5mm", "w": "58mm", "h": "49mm", "rotate": 0, "flipH": false }, + { "nodeId": 2, "type": "deco", "src": "asteroid12.png", "left": "73.5mm", "top": "69.5mm", "w": "20mm", "h": "20mm", "rotate": -60, "flipH": false }, + { "nodeId": 10, "type": "deco", "src": "asteroid4.png", "left": "122.0mm", "top": "78.5mm", "w": "16mm", "h": "15mm", "rotate": -35, "flipH": false }, + { "nodeId": 14, "type": "deco", "src": "asteroid15.png", "left": "38.0mm", "top": "103.5mm", "w": "20mm", "h": "20mm", "rotate": -35, "flipH": false }, + { "nodeId": 27, "type": "deco", "src": "pod11.png", "left": "49.0mm", "top": "139.8mm", "w": "30mm", "h": "19mm", "rotate": 0, "flipH": false }, + { "nodeId": 35, "type": "deco", "src": "pod13.png", "left": "91.1mm", "top": "166.1mm", "w": "32mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 40, "type": "deco", "src": "freighter3.png", "left": "52.5mm", "top": "190.0mm", "w": "58mm", "h": "34mm", "rotate": 0, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "40.0mm", "top": "49.0mm" }, { "nodeId": 1, "left": "43.0mm", "top": "84.5mm" }, { "nodeId": 2, "left": "74.0mm", "top": "70.0mm" }, { "nodeId": 3, "left": "99.6mm", "top": "49.7mm" }, { "nodeId": 4, "left": "133.4mm", "top": "53.4mm" }, { "nodeId": 5, "left": "155.4mm", "top": "52.9mm" }, { "nodeId": 6, "left": "178.0mm", "top": "62.5mm" }, { "nodeId": 7, "left": "20.0mm", "top": "65.0mm" }, { "nodeId": 8, "left": "73.5mm", "top": "87.5mm" }, { "nodeId": 9, "left": "93.3mm", "top": "77.4mm" }, { "nodeId": 10, "left": "122.5mm", "top": "79.0mm" }, { "nodeId": 11, "left": "146.3mm", "top": "81.5mm" }, { "nodeId": 12, "left": "166.5mm", "top": "81.0mm" }, { "nodeId": 13, "left": "14.0mm", "top": "84.0mm" }, { "nodeId": 14, "left": "38.5mm", "top": "104.0mm" }, { "nodeId": 15, "left": "81.9mm", "top": "100.0mm" }, { "nodeId": 16, "left": "101.1mm", "top": "96.3mm" }, { "nodeId": 17, "left": "135.6mm", "top": "97.4mm" }, { "nodeId": 18, "left": "152.0mm", "top": "99.0mm" }, { "nodeId": 19, "left": "180.4mm", "top": "100.8mm" }, { "nodeId": 20, "left": "26.5mm", "top": "117.5mm" }, { "nodeId": 21, "left": "66.3mm", "top": "126.0mm" }, { "nodeId": 22, "left": "86.5mm", "top": "123.1mm" }, { "nodeId": 23, "left": "117.3mm", "top": "120.7mm" }, { "nodeId": 24, "left": "149.4mm", "top": "117.2mm" }, { "nodeId": 25, "left": "166.6mm", "top": "123.3mm" }, { "nodeId": 26, "left": "18.0mm", "top": "139.0mm" }, { "nodeId": 27, "left": "48.0mm", "top": "137.5mm" }, { "nodeId": 28, "left": "81.6mm", "top": "143.1mm" }, { "nodeId": 29, "left": "102.5mm", "top": "141.1mm" }, { "nodeId": 30, "left": "127.0mm", "top": "144.8mm" }, { "nodeId": 31, "left": "158.0mm", "top": "137.9mm" }, { "nodeId": 32, "left": "181.3mm", "top": "142.7mm" }, { "nodeId": 33, "left": "27.0mm", "top": "160.0mm" }, { "nodeId": 34, "left": "68.0mm", "top": "166.8mm" }, { "nodeId": 35, "left": "91.5mm", "top": "168.0mm" }, { "nodeId": 36, "left": "131.5mm", "top": "161.0mm" }, { "nodeId": 37, "left": "154.0mm", "top": "154.0mm" }, { "nodeId": 38, "left": "172.1mm", "top": "163.0mm" }, { "nodeId": 39, "left": "9.5mm", "top": "175.0mm" }, { "nodeId": 40, "left": "62.0mm", "top": "190.0mm" }, { "nodeId": 41, "left": "99.0mm", "top": "195.5mm" }, { "nodeId": 42, "left": "111.5mm", "top": "176.5mm" }, { "nodeId": 43, "left": "133.5mm", "top": "181.0mm" }, { "nodeId": 44, "left": "158.5mm", "top": "192.0mm" }, { "nodeId": 45, "left": "184.1mm", "top": "184.2mm" }, { "nodeId": 46, "left": "10.5mm", "top": "199.0mm" }, { "nodeId": 47, "left": "72.0mm", "top": "218.5mm" }, { "nodeId": 48, "left": "98.0mm", "top": "220.5mm" }, { "nodeId": 49, "left": "122.0mm", "top": "207.5mm" }, { "nodeId": 50, "left": "145.6mm", "top": "207.9mm" }, { "nodeId": 51, "left": "168.9mm", "top": "207.7mm" }, { "nodeId": 52, "left": "35.5mm", "top": "241.0mm" }, { "nodeId": 53, "left": "40.5mm", "top": "221.0mm" }, { "nodeId": 54, "left": "82.7mm", "top": "234.9mm" }, { "nodeId": 55, "left": "112.0mm", "top": "242.0mm" }, { "nodeId": 56, "left": "127.5mm", "top": "226.9mm" }, { "nodeId": 57, "left": "160.6mm", "top": "226.6mm" }, { "nodeId": 58, "left": "178.5mm", "top": "235.8mm" } + ] + }, + { + "page": 5, + "objects": [ + { "nodeId": 44, "type": "dest", "src": "asteroid16.png", "left": "148.5mm", "top": "182.0mm", "w": "24mm", "h": "24mm", "rotate": 0, "flipH": false }, + { "nodeId": 4, "type": "deco", "src": "asteroid8.png", "left": "132.5mm", "top": "55.5mm", "w": "28mm", "h": "28mm", "rotate": -10, "flipH": false }, + { "nodeId": 9, "type": "deco", "src": "asteroid13.png", "left": "91.0mm", "top": "81.0mm", "w": "18mm", "h": "17mm", "rotate": -20, "flipH": false }, + { "nodeId": 13, "type": "deco", "src": "asteroid3.png", "left": "16.5mm", "top": "104.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 24, "type": "deco", "src": "pod7.png", "left": "146.5mm", "top": "125.0mm", "w": "40mm", "h": "25mm", "rotate": 10, "flipH": false }, + { "nodeId": 38, "type": "deco", "src": "pod9.png", "left": "179.5mm", "top": "159.5mm", "w": "26mm", "h": "17mm", "rotate": 15, "flipH": false }, + { "nodeId": 50, "type": "deco", "src": "freighter6.png", "left": "147.0mm", "top": "221.5mm", "w": "60mm", "h": "31mm", "rotate": 0, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "37.5mm", "top": "47.0mm" }, { "nodeId": 1, "left": "48.0mm", "top": "64.0mm" }, { "nodeId": 2, "left": "76.0mm", "top": "58.2mm" }, { "nodeId": 3, "left": "103.3mm", "top": "60.2mm" }, { "nodeId": 4, "left": "132.5mm", "top": "57.0mm" }, { "nodeId": 5, "left": "155.6mm", "top": "59.8mm" }, { "nodeId": 6, "left": "185.8mm", "top": "55.4mm" }, { "nodeId": 7, "left": "13.0mm", "top": "68.0mm" }, { "nodeId": 8, "left": "57.0mm", "top": "80.5mm" }, { "nodeId": 9, "left": "91.5mm", "top": "81.5mm" }, { "nodeId": 10, "left": "118.4mm", "top": "79.0mm" }, { "nodeId": 11, "left": "142.3mm", "top": "75.3mm" }, { "nodeId": 12, "left": "170.3mm", "top": "81.6mm" }, { "nodeId": 13, "left": "15.0mm", "top": "104.0mm" }, { "nodeId": 14, "left": "49.2mm", "top": "96.4mm" }, { "nodeId": 15, "left": "78.6mm", "top": "99.7mm" }, { "nodeId": 16, "left": "102.2mm", "top": "103.0mm" }, { "nodeId": 17, "left": "129.1mm", "top": "100.7mm" }, { "nodeId": 18, "left": "154.4mm", "top": "99.9mm" }, { "nodeId": 19, "left": "193.5mm", "top": "103.0mm" }, { "nodeId": 20, "left": "27.0mm", "top": "126.5mm" }, { "nodeId": 21, "left": "69.9mm", "top": "117.8mm" }, { "nodeId": 22, "left": "92.8mm", "top": "121.9mm" }, { "nodeId": 23, "left": "113.9mm", "top": "116.1mm" }, { "nodeId": 24, "left": "146.5mm", "top": "123.5mm" }, { "nodeId": 25, "left": "180.0mm", "top": "119.5mm" }, { "nodeId": 26, "left": "16.0mm", "top": "152.0mm" }, { "nodeId": 27, "left": "45.5mm", "top": "143.0mm" }, { "nodeId": 28, "left": "76.6mm", "top": "146.3mm" }, { "nodeId": 29, "left": "99.5mm", "top": "137.9mm" }, { "nodeId": 30, "left": "122.5mm", "top": "138.5mm" }, { "nodeId": 31, "left": "160.6mm", "top": "144.4mm" }, { "nodeId": 32, "left": "187.5mm", "top": "138.5mm" }, { "nodeId": 33, "left": "43.3mm", "top": "163.2mm" }, { "nodeId": 34, "left": "62.0mm", "top": "162.4mm" }, { "nodeId": 35, "left": "87.4mm", "top": "161.9mm" }, { "nodeId": 36, "left": "115.5mm", "top": "166.0mm" }, { "nodeId": 37, "left": "143.5mm", "top": "154.0mm" }, { "nodeId": 38, "left": "179.0mm", "top": "163.5mm" }, { "nodeId": 39, "left": "31.0mm", "top": "187.2mm" }, { "nodeId": 40, "left": "52.0mm", "top": "185.4mm" }, { "nodeId": 41, "left": "78.0mm", "top": "191.1mm" }, { "nodeId": 42, "left": "105.5mm", "top": "189.6mm" }, { "nodeId": 43, "left": "126.9mm", "top": "188.7mm" }, { "nodeId": 44, "left": "150.5mm", "top": "183.5mm" }, { "nodeId": 45, "left": "194.5mm", "top": "184.0mm" }, { "nodeId": 46, "left": "14.5mm", "top": "216.5mm" }, { "nodeId": 47, "left": "46.5mm", "top": "205.5mm" }, { "nodeId": 48, "left": "73.0mm", "top": "212.0mm" }, { "nodeId": 49, "left": "104.0mm", "top": "208.5mm" }, { "nodeId": 50, "left": "163.5mm", "top": "221.5mm" }, { "nodeId": 51, "left": "196.0mm", "top": "217.5mm" }, { "nodeId": 52, "left": "45.0mm", "top": "244.5mm" }, { "nodeId": 53, "left": "40.5mm", "top": "224.0mm" }, { "nodeId": 54, "left": "75.1mm", "top": "231.5mm" }, { "nodeId": 55, "left": "102.0mm", "top": "232.0mm" }, { "nodeId": 56, "left": "130.5mm", "top": "245.0mm" }, { "nodeId": 57, "left": "169.0mm", "top": "252.5mm" }, { "nodeId": 58, "left": "200.0mm", "top": "251.5mm" } + ] + }, + { + "page": 6, + "objects": [ + { "nodeId": 51, "type": "dest", "src": "freighter2.png", "left": "174.5mm", "top": "211.0mm", "w": "60mm", "h": "40mm", "rotate": 0, "flipH": false }, + { "nodeId": 4, "type": "deco", "src": "freighter9.png", "left": "133.5mm", "top": "48.5mm", "w": "52mm", "h": "27mm", "rotate": 0, "flipH": false }, + { "nodeId": 10, "type": "deco", "src": "freighter10.png", "left": "104.0mm", "top": "84.5mm", "w": "54mm", "h": "28mm", "rotate": -5, "flipH": false }, + { "nodeId": 13, "type": "deco", "src": "pod14.png", "left": "20.5mm", "top": "106.5mm", "w": "48mm", "h": "30mm", "rotate": -20, "flipH": false }, + { "nodeId": 24, "type": "deco", "src": "pod15.png", "left": "140.0mm", "top": "114.5mm", "w": "28mm", "h": "18mm", "rotate": 0, "flipH": false }, + { "nodeId": 32, "type": "deco", "src": "pod17.png", "left": "182.5mm", "top": "142.0mm", "w": "38mm", "h": "24mm", "rotate": 0, "flipH": false }, + { "nodeId": 35, "type": "deco", "src": "asteroid3.png", "left": "77.5mm", "top": "161.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 42, "type": "deco", "src": "asteroid11.png", "left": "101.0mm", "top": "191.5mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "35.5mm", "top": "49.5mm" }, { "nodeId": 1, "left": "53.5mm", "top": "68.0mm" }, { "nodeId": 2, "left": "82.1mm", "top": "54.4mm" }, { "nodeId": 3, "left": "102.5mm", "top": "59.5mm" }, { "nodeId": 4, "left": "132.0mm", "top": "53.5mm" }, { "nodeId": 5, "left": "164.5mm", "top": "49.0mm" }, { "nodeId": 6, "left": "189.5mm", "top": "52.0mm" }, { "nodeId": 7, "left": "18.5mm", "top": "80.0mm" }, { "nodeId": 8, "left": "60.9mm", "top": "80.5mm" }, { "nodeId": 9, "left": "84.5mm", "top": "70.5mm" }, { "nodeId": 10, "left": "101.5mm", "top": "85.5mm" }, { "nodeId": 11, "left": "155.0mm", "top": "75.5mm" }, { "nodeId": 12, "left": "189.5mm", "top": "80.0mm" }, { "nodeId": 13, "left": "26.5mm", "top": "103.5mm" }, { "nodeId": 14, "left": "56.0mm", "top": "99.8mm" }, { "nodeId": 15, "left": "78.0mm", "top": "104.0mm" }, { "nodeId": 16, "left": "107.7mm", "top": "103.0mm" }, { "nodeId": 17, "left": "133.0mm", "top": "93.8mm" }, { "nodeId": 18, "left": "158.8mm", "top": "97.4mm" }, { "nodeId": 19, "left": "188.1mm", "top": "104.0mm" }, { "nodeId": 20, "left": "40.0mm", "top": "123.0mm" }, { "nodeId": 21, "left": "62.0mm", "top": "131.5mm" }, { "nodeId": 22, "left": "92.1mm", "top": "121.0mm" }, { "nodeId": 23, "left": "113.5mm", "top": "123.5mm" }, { "nodeId": 24, "left": "141.0mm", "top": "114.5mm" }, { "nodeId": 25, "left": "174.8mm", "top": "122.5mm" }, { "nodeId": 26, "left": "20.0mm", "top": "140.5mm" }, { "nodeId": 27, "left": "49.1mm", "top": "138.9mm" }, { "nodeId": 28, "left": "74.5mm", "top": "144.0mm" }, { "nodeId": 29, "left": "107.5mm", "top": "142.0mm" }, { "nodeId": 30, "left": "127.9mm", "top": "142.6mm" }, { "nodeId": 31, "left": "146.5mm", "top": "146.5mm" }, { "nodeId": 32, "left": "177.0mm", "top": "140.0mm" }, { "nodeId": 33, "left": "23.0mm", "top": "162.5mm" }, { "nodeId": 34, "left": "53.5mm", "top": "157.5mm" }, { "nodeId": 35, "left": "77.5mm", "top": "160.0mm" }, { "nodeId": 36, "left": "119.0mm", "top": "160.5mm" }, { "nodeId": 37, "left": "141.5mm", "top": "173.5mm" }, { "nodeId": 38, "left": "174.0mm", "top": "168.5mm" }, { "nodeId": 39, "left": "30.0mm", "top": "186.9mm" }, { "nodeId": 40, "left": "53.7mm", "top": "181.6mm" }, { "nodeId": 41, "left": "73.6mm", "top": "190.8mm" }, { "nodeId": 42, "left": "101.0mm", "top": "192.5mm" }, { "nodeId": 43, "left": "121.0mm", "top": "186.0mm" }, { "nodeId": 44, "left": "153.7mm", "top": "187.6mm" }, { "nodeId": 45, "left": "182.3mm", "top": "189.9mm" }, { "nodeId": 46, "left": "13.5mm", "top": "210.5mm" }, { "nodeId": 47, "left": "42.5mm", "top": "207.0mm" }, { "nodeId": 48, "left": "79.5mm", "top": "209.5mm" }, { "nodeId": 49, "left": "115.9mm", "top": "208.0mm" }, { "nodeId": 50, "left": "132.5mm", "top": "212.5mm" }, { "nodeId": 51, "left": "176.5mm", "top": "212.5mm" }, { "nodeId": 52, "left": "44.5mm", "top": "243.5mm" }, { "nodeId": 53, "left": "46.0mm", "top": "224.0mm" }, { "nodeId": 54, "left": "81.5mm", "top": "225.9mm" }, { "nodeId": 55, "left": "96.5mm", "top": "242.5mm" }, { "nodeId": 56, "left": "124.5mm", "top": "243.0mm" }, { "nodeId": 57, "left": "147.5mm", "top": "230.0mm" }, { "nodeId": 58, "left": "180.0mm", "top": "240.0mm" } + ] + }, + { + "page": 7, + "objects": [ + { "nodeId": 43, "type": "dest", "src": "pod18.png", "left": "121.0mm", "top": "202.5mm", "w": "32mm", "h": "28mm", "rotate": 0, "flipH": false }, + { "nodeId": 4, "type": "deco", "src": "asteroid7.png", "left": "132.0mm", "top": "42.5mm", "w": "46mm", "h": "44mm", "rotate": -10, "flipH": false }, + { "nodeId": 12, "type": "deco", "src": "asteroid15.png", "left": "175.5mm", "top": "71.0mm", "w": "20mm", "h": "20mm", "rotate": 0, "flipH": false }, + { "nodeId": 23, "type": "deco", "src": "asteroid5.png", "left": "111.0mm", "top": "113.0mm", "w": "22mm", "h": "22mm", "rotate": -10, "flipH": false }, + { "nodeId": 31, "type": "deco", "src": "pod3.png", "left": "157.0mm", "top": "142.5mm", "w": "40mm", "h": "25mm", "rotate": 0, "flipH": false }, + { "nodeId": 29, "type": "deco", "src": "pod12.png", "left": "96.5mm", "top": "139.0mm", "w": "28mm", "h": "18mm", "rotate": 0, "flipH": false }, + { "nodeId": 44, "type": "deco", "src": "freighter4.png", "left": "159.5mm", "top": "189.5mm", "w": "58mm", "h": "30mm", "rotate": 0, "flipH": false } + ], + "nodes": [ + { "nodeId": 0, "left": "39.0mm", "top": "48.0mm" }, { "nodeId": 1, "left": "48.5mm", "top": "65.5mm" }, { "nodeId": 2, "left": "83.4mm", "top": "54.6mm" }, { "nodeId": 3, "left": "100.0mm", "top": "53.3mm" }, { "nodeId": 4, "left": "132.5mm", "top": "42.0mm" }, { "nodeId": 5, "left": "165.5mm", "top": "44.5mm" }, { "nodeId": 6, "left": "194.5mm", "top": "59.5mm" }, { "nodeId": 7, "left": "15.0mm", "top": "62.5mm" }, { "nodeId": 8, "left": "52.5mm", "top": "83.5mm" }, { "nodeId": 9, "left": "90.9mm", "top": "75.7mm" }, { "nodeId": 10, "left": "122.8mm", "top": "80.9mm" }, { "nodeId": 11, "left": "144.8mm", "top": "72.0mm" }, { "nodeId": 12, "left": "175.5mm", "top": "71.0mm" }, { "nodeId": 13, "left": "16.5mm", "top": "96.5mm" }, { "nodeId": 14, "left": "41.5mm", "top": "95.0mm" }, { "nodeId": 15, "left": "78.3mm", "top": "97.0mm" }, { "nodeId": 16, "left": "99.5mm", "top": "97.5mm" }, { "nodeId": 17, "left": "132.2mm", "top": "100.3mm" }, { "nodeId": 18, "left": "155.8mm", "top": "96.1mm" }, { "nodeId": 19, "left": "195.0mm", "top": "93.0mm" }, { "nodeId": 20, "left": "30.5mm", "top": "118.0mm" }, { "nodeId": 21, "left": "65.5mm", "top": "118.4mm" }, { "nodeId": 22, "left": "85.5mm", "top": "123.0mm" }, { "nodeId": 23, "left": "111.0mm", "top": "113.0mm" }, { "nodeId": 24, "left": "141.0mm", "top": "123.5mm" }, { "nodeId": 25, "left": "168.0mm", "top": "116.0mm" }, { "nodeId": 26, "left": "18.0mm", "top": "148.0mm" }, { "nodeId": 27, "left": "53.5mm", "top": "140.0mm" }, { "nodeId": 28, "left": "81.7mm", "top": "142.4mm" }, { "nodeId": 29, "left": "97.5mm", "top": "138.5mm" }, { "nodeId": 30, "left": "129.5mm", "top": "145.0mm" }, { "nodeId": 31, "left": "157.0mm", "top": "142.5mm" }, { "nodeId": 32, "left": "189.8mm", "top": "136.1mm" }, { "nodeId": 33, "left": "30.0mm", "top": "168.5mm" }, { "nodeId": 34, "left": "54.5mm", "top": "162.0mm" }, { "nodeId": 35, "left": "89.4mm", "top": "160.7mm" }, { "nodeId": 36, "left": "117.5mm", "top": "166.5mm" }, { "nodeId": 37, "left": "139.0mm", "top": "172.5mm" }, { "nodeId": 38, "left": "173.0mm", "top": "158.5mm" }, { "nodeId": 39, "left": "22.0mm", "top": "192.0mm" }, { "nodeId": 40, "left": "52.8mm", "top": "190.0mm" }, { "nodeId": 41, "left": "73.0mm", "top": "186.0mm" }, { "nodeId": 42, "left": "98.0mm", "top": "199.5mm" }, { "nodeId": 43, "left": "123.0mm", "top": "197.5mm" }, { "nodeId": 44, "left": "160.0mm", "top": "190.0mm" }, { "nodeId": 45, "left": "186.3mm", "top": "184.2mm" }, { "nodeId": 46, "left": "43.0mm", "top": "214.5mm" }, { "nodeId": 47, "left": "70.0mm", "top": "207.0mm" }, { "nodeId": 48, "left": "82.5mm", "top": "221.5mm" }, { "nodeId": 49, "left": "109.0mm", "top": "219.5mm" }, { "nodeId": 50, "left": "140.0mm", "top": "212.5mm" }, { "nodeId": 51, "left": "167.0mm", "top": "215.5mm" }, { "nodeId": 52, "left": "21.5mm", "top": "237.0mm" }, { "nodeId": 53, "left": "52.5mm", "top": "230.5mm" }, { "nodeId": 54, "left": "78.5mm", "top": "238.5mm" }, { "nodeId": 55, "left": "102.0mm", "top": "242.0mm" }, { "nodeId": 56, "left": "129.5mm", "top": "238.5mm" }, { "nodeId": 57, "left": "160.0mm", "top": "240.0mm" }, { "nodeId": 58, "left": "190.0mm", "top": "241.0mm" } + ] + } + ] +} diff --git a/tasks/space-route/docs/space-route-1.md b/tasks/space-route/docs/space-route-1.md new file mode 100644 index 0000000..038e790 --- /dev/null +++ b/tasks/space-route/docs/space-route-1.md @@ -0,0 +1,13 @@ +# Space Route 1 + +**Title:** Проложи Маршрут + +## Notes + +9-page space route worksheet. Player and enemy navigate a hex graph. +Generated by `scripts/generate-route.mjs` with per-page seed configs. + +See `scripts/generate-route.mjs` PAGES array for full page configs including: +- diffRange (difficulty), routeLength, seeds +- Ship/enemy images, destination objects, decorative objects +- flipEnemy/flipPlayer flags for ship orientation diff --git a/tasks/space-route/docs/space-route-1.template.html b/tasks/space-route/docs/space-route-1.template.html new file mode 100644 index 0000000..b108e8b --- /dev/null +++ b/tasks/space-route/docs/space-route-1.template.html @@ -0,0 +1,1097 @@ + + + + + + + + + + Проложи Маршрут + + + + + +
+
+
+ +
+
+ ··············· + + + + + + + + + + + + + +
8
+
7
+
12
+
4
+
7
+
10
+
11
+
5
+
9
+
6
+
5
+
8
+
6
+
10
+
4
+
10
+
3
+
4
+
9
+
13
+
11
+
8
+
11
+
6
+
12
+
5
+
5
+
9
+
12
+
7
+
11
+
4
+
10
+
7
+
10
+
13
+
8
+
9
+
6
+
12
+
4
+
11
+
5
+
11
+
5
+
7
+
5
+
3
+
9
+
4
+
10
+
3
+
11
+
7
+
10
+
12
+
7
+
8
+
4
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Пиратский крейсер:
+
8
-3
-1
+4
+4
+1
-5
+1
-4
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
11
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [3,8] | 59 nodes | values 3-13 | enemy 9 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ··········· + + + + + + + + + + + + + +
4
+
5
+
6
+
12
+
13
+
5
+
9
+
10
+
8
+
9
+
7
+
8
+
10
+
9
+
11
+
7
+
10
+
11
+
12
+
7
+
5
+
13
+
4
+
8
+
13
+
11
+
8
+
6
+
11
+
12
+
6
+
9
+
8
+
15
+
7
+
5
+
14
+
5
+
10
+
13
+
9
+
12
+
13
+
8
+
7
+
6
+
11
+
10
+
15
+
6
+
9
+
13
+
12
+
7
+
5
+
12
+
11
+
5
+
4
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Патрульный разведчик:
+
4
+6
+1
-4
-3
+4
-2
-1
+2
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
12
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [4,10] | 59 nodes | values 4-15 | enemy 9 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ··········· + + + + + + + + + + + + + +
14
+
7
+
13
+
14
+
8
+
13
+
6
+
10
+
11
+
10
+
12
+
11
+
9
+
6
+
12
+
9
+
6
+
7
+
10
+
12
+
13
+
7
+
15
+
12
+
8
+
15
+
14
+
8
+
10
+
13
+
11
+
6
+
16
+
9
+
12
+
14
+
5
+
7
+
13
+
16
+
13
+
15
+
8
+
9
+
12
+
10
+
10
+
11
+
6
+
10
+
15
+
7
+
9
+
14
+
13
+
5
+
16
+
13
+
8
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Контрабандист:
+
14
-7
+4
-2
+6
-2
-8
+4
+3
-5
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
9
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [2,18] | 59 nodes | values 5-16 | enemy 10 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ·········· + + + + + + + + + + + + + +
14
+
15
+
9
+
8
+
13
+
12
+
16
+
16
+
13
+
12
+
10
+
9
+
11
+
8
+
14
+
11
+
16
+
15
+
13
+
10
+
10
+
15
+
7
+
8
+
11
+
14
+
13
+
12
+
9
+
10
+
13
+
9
+
15
+
11
+
8
+
12
+
17
+
12
+
7
+
16
+
14
+
13
+
11
+
9
+
8
+
16
+
9
+
15
+
10
+
14
+
13
+
10
+
7
+
8
+
11
+
12
+
15
+
17
+
11
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Шахтёрский транспорт:
+
14
+1
-2
-2
-4
+3
+3
-1
-4
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
7
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [6,12] | 59 nodes | values 7-17 | enemy 9 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ············· + + + + + + + + + + + + + +
16
+
11
+
12
+
9
+
7
+
13
+
9
+
10
+
13
+
11
+
14
+
12
+
8
+
9
+
14
+
8
+
10
+
15
+
11
+
6
+
11
+
7
+
12
+
13
+
9
+
14
+
8
+
9
+
15
+
11
+
8
+
7
+
10
+
12
+
14
+
10
+
6
+
17
+
15
+
16
+
11
+
8
+
13
+
11
+
9
+
8
+
10
+
15
+
9
+
10
+
12
+
13
+
9
+
7
+
12
+
14
+
16
+
17
+
14
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Корабль-призрак:
+
16
-6
+4
-7
+8
-4
-3
+9
-8
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
9
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [4,15] | 59 nodes | values 6-17 | enemy 9 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ········ + + + + + + + + + + + + + + +
14
+
16
+
22
+
15
+
13
+
19
+
16
+
17
+
20
+
19
+
21
+
18
+
21
+
22
+
15
+
18
+
22
+
17
+
15
+
20
+
13
+
16
+
23
+
20
+
16
+
19
+
20
+
21
+
19
+
18
+
17
+
22
+
14
+
17
+
14
+
15
+
21
+
12
+
24
+
12
+
18
+
22
+
16
+
22
+
20
+
19
+
16
+
19
+
23
+
17
+
15
+
18
+
17
+
18
+
21
+
12
+
13
+
21
+
14
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Военный фрегат:
+
14
+3
-2
+1
+3
-1
+3
+1
-7
+3
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
17
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [8,20] | 59 nodes | values 12-24 | enemy 10 steps | player shortest 6 steps +
+
+
+
+
+
+ +
+
+ ··········· + + + + + + + + + + + + + +
9
+
11
+
13
+
3
+
11
+
10
+
5
+
8
+
7
+
6
+
9
+
8
+
7
+
4
+
10
+
12
+
13
+
5
+
6
+
12
+
11
+
9
+
7
+
10
+
11
+
9
+
8
+
5
+
6
+
8
+
4
+
5
+
14
+
10
+
12
+
13
+
6
+
9
+
8
+
9
+
7
+
5
+
10
+
5
+
10
+
4
+
6
+
4
+
7
+
4
+
7
+
12
+
10
+
12
+
8
+
11
+
13
+
6
+
11
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Торговый караван:
+
9
-1
+2
-1
-3
+7
-3
-4
-1
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
10
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [3,12] | 59 nodes | values 3-14 | enemy 9 steps | player shortest 5 steps +
+
+
+
+
+
+ +
+
+ ············ + + + + + + + + + + + + + +
8
+
3
+
11
+
10
+
12
+
11
+
7
+
4
+
5
+
6
+
4
+
6
+
5
+
9
+
7
+
9
+
8
+
7
+
3
+
8
+
8
+
3
+
10
+
12
+
9
+
4
+
11
+
4
+
5
+
6
+
13
+
5
+
12
+
6
+
7
+
3
+
11
+
7
+
6
+
5
+
3
+
9
+
4
+
12
+
10
+
2
+
2
+
8
+
6
+
5
+
4
+
8
+
6
+
7
+
12
+
10
+
7
+
9
+
11
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Исследователь:
+
8
-4
+3
+2
+1
-4
+5
+1
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
6
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [2,8] | 59 nodes | values 2-13 | enemy 8 steps | player shortest 5 steps +
+
+
+
+
+
+ +
+
+ ············· + + + + + + + + + + + + + + +
28
+
25
+
23
+
27
+
20
+
21
+
23
+
24
+
22
+
28
+
26
+
25
+
24
+
30
+
23
+
21
+
29
+
19
+
27
+
22
+
28
+
24
+
22
+
31
+
23
+
25
+
25
+
29
+
23
+
28
+
21
+
29
+
28
+
22
+
21
+
27
+
25
+
27
+
26
+
19
+
24
+
26
+
30
+
29
+
23
+
30
+
27
+
28
+
22
+
27
+
28
+
22
+
26
+
25
+
23
+
24
+
20
+
19
+
26
+ + +
+
+ +
+

Проложи Маршрут

+

Найди путь в космосе!

+
+
+
+ + +
+
+
Рейдер:
+
28
-3
+2
-7
+5
-6
+4
-2
+6
-4
+
+
📍 Проследи маршрут — куда он летит?
+
+ + + + + +
+
Рассчитай маршрут до цели перехвата
+
+
Твой истребитель:
+
26
+
+
✏️ Запиши разницу чисел, чтобы добраться до цели!
+
+ + +
+ [10,30] | 59 nodes | values 19-31 | enemy 10 steps | player shortest 6 steps +
+
+
+ + diff --git a/tasks/space-route/docs/space-route-prototype.html b/tasks/space-route/docs/space-route-prototype.html new file mode 100644 index 0000000..f8cf7b4 --- /dev/null +++ b/tasks/space-route/docs/space-route-prototype.html @@ -0,0 +1,687 @@ + + + + + + + + + + Проложи Маршрут + + + + + + + + + diff --git a/tasks/space-route/editor.html b/tasks/space-route/editor.html new file mode 100644 index 0000000..e2b3138 --- /dev/null +++ b/tasks/space-route/editor.html @@ -0,0 +1,792 @@ + + + + + + Space Route Editor + + + + +
+ Route Editor + +
+ + + +
+ + + + +
+ +
+ +
+ Click an object to select + + M: switch mode | Arrows: move | [ ] rotate | - + scale | H: flip | R: route +
+ +
+
+ + + + diff --git a/src/scripts/apply-route-edits.mjs b/tasks/space-route/scripts/apply-edits.mjs similarity index 100% rename from src/scripts/apply-route-edits.mjs rename to tasks/space-route/scripts/apply-edits.mjs diff --git a/src/scripts/generate-space-route.mjs b/tasks/space-route/scripts/generate-route.mjs similarity index 100% rename from src/scripts/generate-space-route.mjs rename to tasks/space-route/scripts/generate-route.mjs diff --git a/tasks/space-route/scripts/generate.mjs b/tasks/space-route/scripts/generate.mjs new file mode 100644 index 0000000..494a667 --- /dev/null +++ b/tasks/space-route/scripts/generate.mjs @@ -0,0 +1,161 @@ +#!/usr/bin/env node + +/** + * Generate output HTML from template + data for space-route documents. + * + * Usage: node generate.mjs + * Example: node generate.mjs space-route-1 + * + * Reads: docs/.template.html + * Reads: docs/.data.json (optional) + * Writes: docs/.output.html + * + * data.json format (from space-route editor): + * { + * pages: [{ + * page: 1, + * objects: [{ nodeId, type, src, left, top, w, h, rotate, flipH }], + * nodes: [{ nodeId, left, top }] + * }] + * } + */ + +import { readFileSync, writeFileSync, existsSync } from 'fs'; +import { join, dirname } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const docsDir = join(__dirname, '..', 'docs'); + +const docId = process.argv[2]; +if (!docId) { + console.error('Usage: node generate.mjs '); + process.exit(1); +} + +const templatePath = join(docsDir, `${docId}.template.html`); +const dataPath = join(docsDir, `${docId}.data.json`); +const outputPath = join(docsDir, `${docId}.output.html`); + +if (!existsSync(templatePath)) { + console.error(`Template not found: ${templatePath}`); + process.exit(1); +} + +let html = readFileSync(templatePath, 'utf-8'); + +if (existsSync(dataPath)) { + const data = JSON.parse(readFileSync(dataPath, 'utf-8')); + html = applyData(html, data); + console.log(`Applied data from ${data.pages?.length || 0} pages`); +} + +writeFileSync(outputPath, html); +console.log(`Generated: ${outputPath}`); + +function applyData(html, data) { + if (!data.pages) return html; + + // Split by page divs + const pageRegex = /
= 0; i--) { + const pageData = data.pages[i]; + const pageNum = pageData.page || (i + 1); + const pageIdx = pageNum - 1; + + if (pageIdx >= starts.length) continue; + + const pageStart = starts[pageIdx]; + const pageEnd = pageIdx + 1 < starts.length ? starts[pageIdx + 1] : html.length; + let pageHtml = html.slice(pageStart, pageEnd); + + // Apply object positions + if (pageData.objects) { + for (const obj of pageData.objects) { + pageHtml = applyObject(pageHtml, obj); + } + } + + // Apply node positions and update edges + if (pageData.nodes) { + for (const node of pageData.nodes) { + pageHtml = applyNode(pageHtml, node); + } + } + + html = html.slice(0, pageStart) + pageHtml + html.slice(pageEnd); + } + + return html; +} + +function applyObject(pageHtml, obj) { + // Match: ]*data-node-id="${nodeId}"[^>]*style=")([^"]*)(")` + ); + + return pageHtml.replace(regex, (match, prefix, oldStyle, suffix) => { + const parts = []; + parts.push(`left: ${obj.left}`); + parts.push(`top: ${obj.top}`); + if (obj.w) parts.push(`width: ${obj.w}`); + if (obj.h) parts.push(`height: ${obj.h}`); + + const transforms = []; + if (obj.rotate) transforms.push(`rotate(${obj.rotate}deg)`); + if (obj.flipH) transforms.push('scaleX(-1)'); + if (transforms.length) parts.push(`transform: ${transforms.join(' ')}`); + + // Preserve margin if present in old style + const marginMatch = oldStyle.match(/margin[^;]+;/); + if (marginMatch) parts.push(marginMatch[0].replace(/;$/, '')); + + return prefix + parts.join('; ') + ';' + suffix; + }); +} + +function applyNode(pageHtml, node) { + // Update node div position + const nodeRegex = new RegExp( + `(]*data-node-id="${node.nodeId}"[^>]*style=")([^"]*)(")` + ); + + pageHtml = pageHtml.replace(nodeRegex, (match, prefix, oldStyle, suffix) => { + const newStyle = oldStyle + .replace(/left:\s*[^;]+/, `left: ${node.left}`) + .replace(/top:\s*[^;]+/, `top: ${node.top}`); + return prefix + newStyle + suffix; + }); + + // Update edges connected to this node + const leftMm = parseFloat(node.left); + const topMm = parseFloat(node.top); + + // Edges where this node is first: ]*data-edge="${node.nodeId}-\\d+"[^>]*)(x1=")[^"]*("\\s*y1=")[^"]*(")`,'g' + ); + pageHtml = pageHtml.replace(edgeRegex1, (match, prefix, x1p, y1p, suffix) => { + return `${prefix}${x1p}${leftMm}mm${y1p}${topMm}mm${suffix}`; + }); + + // Edges where this node is second: ]*data-edge="\\d+-${node.nodeId}"[^>]*)(x2=")[^"]*("\\s*y2=")[^"]*(")`,'g' + ); + pageHtml = pageHtml.replace(edgeRegex2, (match, prefix, x2p, y2p, suffix) => { + return `${prefix}${x2p}${leftMm}mm${y2p}${topMm}mm${suffix}`; + }); + + return pageHtml; +} diff --git a/tasks/space-worksheet2.json b/tasks/space-worksheet2.json deleted file mode 100644 index 3c5cb48..0000000 --- a/tasks/space-worksheet2.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "id": "space-worksheet2", - "title": "Исследуй Планету", - "description": "3-page space worksheet: addition A+B±C (result 0-40), multiply by 5 variants, compound A×B+C×D", - "labels": { - "title": "Исследуй Планету", - "subtitle": "Собери ресурсы, решая примеры!", - "footerBubble": "Итого собрано на планете:" - }, - "theme": { - "style": "space", - "template": "space-base", - "icons": "assets/icons/pack2/" - }, - "layout": { - "columns": 2, - "problemsPerPage": 20 - }, - "pages": [ - { - "task": "A + B + C, где A от 12 до 24, B ±(от 6 до 10), C ±(от 2 до 5). Результат от 0 до 40 включительно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship1.jpeg", - "footerImage": "assets/footers/planet2.jpeg", - "heroDirection": "row-reverse" - }, - { - "task": "5 + 5 + 5 (сложение пятерок: 2, 3 или 4 штуки) ИЛИ 5 × N (N от 1 до 12) ИЛИ 5 × N ± 5", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship3.png", - "footerImage": "assets/footers/planet4.jpeg", - "heroDirection": "row" - }, - { - "task": "A × B + C × D, где A от 2 до 4, B от 1 до 3, C от 2 до 3, D от 1 до 2", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship5.jpeg", - "footerImage": "assets/footers/planet6.jpeg", - "heroDirection": "row-reverse" - } - ] -} diff --git a/tasks/space-worksheet3.json b/tasks/space-worksheet3.json deleted file mode 100644 index a8e50b1..0000000 --- a/tasks/space-worksheet3.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "id": "space-worksheet3", - "title": "Исследуй Планету", - "description": "9-page space worksheet combining patterns from worksheet1 and worksheet2: addition, multiply by 5, multiplication table, constrained addition, mixed fives, compound multiplication", - "labels": { - "title": "Исследуй Планету", - "subtitle": "Собери ресурсы, решая примеры!", - "footerBubble": "Итого собрано на планете:" - }, - "theme": { - "style": "space", - "template": "space-base", - "icons": ["assets/icons/pack1/", "assets/icons/pack2/"] - }, - "layout": { - "columns": 2, - "problemsPerPage": 20 - }, - "pages": [ - { - "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship1.jpeg", - "footerImage": "assets/footers/planet1.jpeg", - "heroDirection": "row-reverse", - "iconPack": "pack1" - }, - { - "task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship2.jpeg", - "footerImage": "assets/footers/planet2.jpeg", - "heroDirection": "row", - "iconPack": "pack1" - }, - { - "task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship3.png", - "footerImage": "assets/footers/planet3.jpeg", - "heroDirection": "row-reverse", - "iconPack": "pack1" - }, - { - "task": "A + B + C, где A от 12 до 24, B ±(от 6 до 10), C ±(от 2 до 5). Результат от 0 до 40 включительно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship4.jpeg", - "footerImage": "assets/footers/planet4.jpeg", - "heroDirection": "row", - "iconPack": "pack2" - }, - { - "task": "5 + 5 + 5 (сложение пятерок: 2, 3 или 4 штуки) ИЛИ 5 × N (N от 1 до 12) ИЛИ 5 × N ± 5", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship5.jpeg", - "footerImage": "assets/footers/planet5.jpeg", - "heroDirection": "row-reverse", - "iconPack": "pack2" - }, - { - "task": "A × B + C × D, где A от 2 до 4, B от 1 до 3, C от 2 до 3, D от 1 до 2", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship6.jpeg", - "footerImage": "assets/footers/planet6.jpeg", - "heroDirection": "row", - "iconPack": "pack2" - }, - { - "task": "A + B ± C, где A от 8 до 16, B от 4 до 8, C от 1 до 3. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship7.jpeg", - "footerImage": "assets/footers/planet7.jpeg", - "heroDirection": "row-reverse", - "iconPack": "pack1" - }, - { - "task": "5 × N ± C, где N от 1 до 5, C от 1 до 6. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship8.jpeg", - "footerImage": "assets/footers/planet8.jpeg", - "heroDirection": "row", - "iconPack": "pack1" - }, - { - "task": "A × B ± C, где A и B от 1 до 4, C от 1 до 8. Знак ± выбирается случайно", - "problemCount": 20, - "heroImage": "assets/hero-images/spaceship9.jpeg", - "footerImage": "assets/footers/planet9.jpeg", - "heroDirection": "row-reverse", - "iconPack": "pack1" - } - ] -}