@bongos/core 1.24.78 → 1.24.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +498 -353
- package/.claude/skills/ask-for-help/SKILL.md +1 -1
- package/.claude/skills/builder-sequence/SKILL.md +1 -1
- package/.claude/skills/design/SKILL.md +1 -1
- package/.claude/skills/goal-create/SKILL.md +1 -1
- package/.claude/skills/planning-session/SKILL.md +1 -1
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +8 -0
- package/clients/bongos-client/index.cjs +8 -0
- package/clients/bongos-client/index.d.ts +11 -0
- package/clients/bongos-client/index.mjs +8 -0
- package/docs/adr/0274-one-kernel-three-role-packs.md +2 -2
- package/docs/adr/0399-the-visor-is-glass-over-the-scene-and-owns-no-camera.md +91 -0
- package/docs/adr/0400-a-chain-reserves-work-and-each-sub-quest-is-still-claimed-alone.md +109 -0
- package/docs/adr/0401-one-options-menu-opens-every-settings-screen-in-a-frame.md +53 -0
- package/docs/adr/README.md +3 -0
- package/docs/api/openapi.json +195 -3
- package/docs/api-reference.md +8 -4
- package/docs/architecture.md +7 -3
- package/docs/copy-inventory.md +390 -370
- package/docs/copy-registry.json +719 -518
- package/docs/design/characters/character-sprites-source.webp +0 -0
- package/docs/file-map.md +7 -8
- package/docs/module-api-changelog.md +4 -0
- package/docs/modules-contract.md +5 -0
- package/docs/onboarding/slash-commands.md +1 -1
- package/docs/packs/{engineer.md → artisan.md} +5 -5
- package/docs/packs/artist.md +50 -4
- package/docs/page-inventory.json +15 -4
- package/docs/page-readings.json +3182 -3336
- package/docs/{packs/ideator.md → recipes/ideation-playbook.md} +5 -48
- package/migrations/core_296_crafts_artisan_artist.sql +72 -0
- package/migrations/core_297_builder_character.sql +30 -0
- package/modules/copy-desk/proposals.js +1 -1
- package/modules/economy/credits-by-craft.js +29 -15
- package/modules/hall-ui/public/ai-studio.html +4 -4
- package/modules/hall-ui/public/atlas.html +5 -5
- package/modules/hall-ui/public/atlas.js +3 -1
- package/modules/hall-ui/public/blockers.html +5 -5
- package/modules/hall-ui/public/board-room.html +4 -4
- package/modules/hall-ui/public/characters/artisan.png +0 -0
- package/modules/hall-ui/public/characters/artist.png +0 -0
- package/modules/hall-ui/public/characters/patron.png +0 -0
- package/modules/hall-ui/public/city.css +2 -1
- package/modules/hall-ui/public/city.html +9 -6
- package/modules/hall-ui/public/city.js +7 -1
- package/modules/hall-ui/public/collab.html +4 -4
- package/modules/hall-ui/public/commands.html +4 -4
- package/modules/hall-ui/public/copy-desk.html +4 -4
- package/modules/hall-ui/public/craft-mode.js +258 -64
- package/modules/hall-ui/public/deploy.html +4 -4
- package/modules/hall-ui/public/diagram-viewer.js +2 -1
- package/modules/hall-ui/public/dom-utils.js +1 -1
- package/modules/hall-ui/public/goal-map.html +9 -6
- package/modules/hall-ui/public/goals.html +5 -5
- package/modules/hall-ui/public/government.html +4 -4
- package/modules/hall-ui/public/hall-render.js +3 -1
- package/modules/hall-ui/public/home-city-draw.js +3 -3
- package/modules/hall-ui/public/home-city.css +4 -0
- package/modules/hall-ui/public/home-city.js +17 -9
- package/modules/hall-ui/public/home-gallery.js +8 -1
- package/modules/hall-ui/public/home-idea-box.css +2 -2
- package/modules/hall-ui/public/home-idea-box.js +3 -3
- package/modules/hall-ui/public/idea.html +5 -5
- package/modules/hall-ui/public/ideas.html +5 -5
- package/modules/hall-ui/public/index.html +11 -7
- package/modules/hall-ui/public/market-watch-item.html +4 -4
- package/modules/hall-ui/public/market-watch-rules.html +4 -4
- package/modules/hall-ui/public/market-watch.html +6 -9
- package/modules/hall-ui/public/market-watch.js +22 -45
- package/modules/hall-ui/public/modules.html +4 -4
- package/modules/hall-ui/public/money.html +4 -4
- package/modules/hall-ui/public/my-agents.html +4 -4
- package/modules/hall-ui/public/options-menu.js +409 -0
- package/modules/hall-ui/public/paintbrush.js +3 -3
- package/modules/hall-ui/public/palette.js +11 -13
- package/modules/hall-ui/public/primer.html +5 -5
- package/modules/hall-ui/public/profile-crafts.js +1 -1
- package/modules/hall-ui/public/profile-roles.js +23 -19
- package/modules/hall-ui/public/profile.css +1 -1
- package/modules/hall-ui/public/profile.html +19 -18
- package/modules/hall-ui/public/profile.js +19 -18
- package/modules/hall-ui/public/profile.states.json +4 -4
- package/modules/hall-ui/public/project-settings.html +4 -4
- package/modules/hall-ui/public/roster.html +4 -4
- package/modules/hall-ui/public/roster.js +3 -3
- package/modules/hall-ui/public/settings.css +24 -4
- package/modules/hall-ui/public/settings.html +21 -17
- package/modules/hall-ui/public/settings.js +44 -44
- package/modules/hall-ui/public/shell-game.css +65 -0
- package/modules/hall-ui/public/shell-game.js +283 -3
- package/modules/hall-ui/public/shell.js +7 -26
- package/modules/hall-ui/public/sky-interaction.js +7 -0
- package/modules/hall-ui/public/speciality-tools.js +1 -2
- package/modules/hall-ui/public/street-inside.js +3 -4
- package/modules/hall-ui/public/street.html +4 -4
- package/modules/hall-ui/public/studio.html +5 -5
- package/modules/hall-ui/public/style.css +73 -47
- package/modules/hall-ui/public/task-detail.js +5 -4
- package/modules/hall-ui/public/task.html +5 -5
- package/modules/hall-ui/public/thinking.css +10 -0
- package/modules/hall-ui/public/thinking.html +9 -6
- package/modules/hall-ui/public/tweak-editor.html +5 -5
- package/modules/hall-ui/public/tweak-editor.js +5 -1
- package/modules/hall-ui/public/update-pill.js +91 -2
- package/modules/hall-ui/public/visor.css +80 -0
- package/modules/hall-ui/public/visor.js +316 -0
- package/modules/hall-ui/public/watch-repo-invite.js +159 -0
- package/modules/hall-ui/public/watch.html +6 -5
- package/modules/hall-ui/public/watch.js +17 -2
- package/modules/hall-ui/public/welcome-boot.js +15 -6
- package/modules/hall-ui/public/work.html +5 -5
- package/modules/hall-ui/records/builders-roster.md +2 -2
- package/modules/hall-ui/records/craft-mode.md +13 -11
- package/modules/hall-ui/records/game-mode.md +2 -2
- package/modules/hall-ui/records/governor-street.md +1 -1
- package/modules/hall-ui/records/home-city.md +3 -1
- package/modules/hall-ui/records/market-watch-settings.md +2 -0
- package/modules/hall-ui/records/options-menu.md +15 -0
- package/modules/hall-ui/records/profile-roles.md +11 -11
- package/modules/hall-ui/records/sky.md +3 -3
- package/modules/hall-ui/records/start-screen.md +21 -0
- package/modules/hall-ui/records/tweak-editor.md +1 -1
- package/modules/hall-ui/records/update-pill.md +12 -0
- package/modules/hall-ui/records/visor.md +23 -0
- package/modules/hall-ui/records/welcome-tower.md +5 -5
- package/modules/ideas/ideator-stats.js +3 -1
- package/modules/ideas/inbox.js +2 -2
- package/modules/lifecycle/activity.js +1 -1
- package/modules/lifecycle/cascade.js +4 -4
- package/modules/lifecycle/goal-spec-task.js +1 -1
- package/modules/lifecycle/help-requests.js +19 -15
- package/modules/lifecycle/kickoff-checklist.js +3 -3
- package/modules/lifecycle/kickoff-seed.js +1 -1
- package/modules/lifecycle/migrations/lifecycle_021_crafts_artisan_artist.sql +29 -0
- package/modules/lifecycle/mingle.js +4 -4
- package/modules/lifecycle/page-tweak-write.js +1 -1
- package/modules/lifecycle/routes/task-write-routes.js +3 -1
- package/modules/lifecycle/routes/tasks.js +3 -3
- package/modules/lifecycle/ship-card.js +2 -3
- package/modules/lifecycle/task-classifier.js +39 -29
- package/modules/lifecycle/tests/cascade.mjs +7 -7
- package/modules/onboarding/founding-mode.js +3 -0
- package/modules/onboarding/genesis-home.js +21 -1
- package/modules/onboarding/routes/onboarding.js +2 -0
- package/modules/page-notes/notes.js +3 -2
- package/modules/page-notes/split.js +1 -1
- package/modules/platform-identity/craft-rollup.js +35 -7
- package/modules/platform-identity/migrations/platform_identity_036_crafts_artisan_artist.sql +45 -0
- package/modules/platform-identity/platform-identity.js +2 -2
- package/modules/platform-identity/routes/community-leaderboard.js +2 -1
- package/modules/platform-identity/routes/community-search.js +2 -1
- package/modules/platform-identity/routes/sso.js +2 -1
- package/modules/platform-identity/tests/platform-identity.mjs +6 -6
- package/modules/public-landing/public/community.html +3 -5
- package/modules/public-landing/public/index.html +1 -1
- package/modules/public-landing/public/projects.html +1 -1
- package/modules/specialities/migrations/specialities_004_crafts_artisan_artist.sql +30 -0
- package/modules/specialities/routes/specialities.js +2 -2
- package/modules/status-ui/public/status.js +1 -1
- package/modules/ui-design/kit/fixtures/community-leaderboard.json +10 -10
- package/modules/ui-design/kit/fixtures/community-search.json +2 -2
- package/modules/ui-design/kit/fixtures/scouting-recruiter.json +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +76 -0
- package/scripts/bongos/autobongos-host.js +19 -4
- package/scripts/bongos/autobongos-loop.js +1 -1
- package/scripts/bongos/claude-materialize.js +20 -1
- package/scripts/bongos/discipline-modes.json +7 -12
- package/scripts/bongos/fitness.js +1 -1
- package/scripts/bongos/gen-hall-sitemap.js +7 -7
- package/scripts/bongos/grade-smoke.js +2 -2
- package/scripts/bongos/init.js +2 -2
- package/scripts/bongos/newcomer-floor.config.json +1 -2
- package/scripts/bongos/newcomer-floor.js +4 -3
- package/scripts/bongos/newcomer-floor.templates.json +10 -12
- package/scripts/bongos/newcomer-floor.test.js +47 -38
- package/scripts/bongos/role-pack-guard.js +5 -4
- package/scripts/bongos/seed-tasks.example.json +3 -3
- package/scripts/bongos/setup.js +20 -107
- package/scripts/bongos/start.js +2 -2
- package/scripts/bongos/task.js +5 -4
- package/scripts/bongos/triage.js +1 -1
- package/scripts/bongos/worktree.js +16 -4
- package/scripts/setup-builder.js +6 -46
- package/src/bongos/auth-admission.js +8 -8
- package/src/bongos/craft-mode.js +2 -0
- package/src/bongos/db.js +39 -1
- package/src/bongos/github-repos.js +78 -0
- package/src/bongos/module-scope-map.js +22 -0
- package/src/bongos/role-stats.js +27 -11
- package/src/bongos/routes/github.js +100 -2
- package/src/bongos/routes/me.js +33 -0
- package/src/bongos/serve-internal.js +26 -9
- package/src/crafts.js +66 -0
- package/src/module-api.js +6 -1
- package/src/module-loader/manifest-schema.js +16 -0
- package/src/modules.js +2 -2
- package/src/role-responsibilities.js +6 -5
- package/tests/acclaim_feed_evidence_db.mjs +1 -1
- package/tests/activity_rollup_as_of.mjs +1 -1
- package/tests/api_alias_caller_ratchet.mjs +3 -3
- package/tests/application_lifecycle.mjs +1 -1
- package/tests/artist_review.mjs +1 -1
- package/tests/artist_review_goal.mjs +1 -1
- package/tests/autobongos_host.mjs +19 -1
- package/tests/blocker_hall_live_proof.mjs +1 -1
- package/tests/blocker_tasks_named_db.mjs +2 -2
- package/tests/canonical_profile_url.mjs +1 -1
- package/tests/cap_newcomer_tasks.mjs +13 -13
- package/tests/character_creation.mjs +294 -0
- package/tests/claim_gate_open_blocker.mjs +2 -2
- package/tests/claim_gate_rebase.mjs +6 -6
- package/tests/claude_materialize.mjs +75 -1
- package/tests/clawback_confirmed_backlog.mjs +3 -3
- package/tests/collab_page.mjs +8 -9
- package/tests/collab_self_settling.mjs +2 -2
- package/tests/community_leaderboard_route.mjs +13 -5
- package/tests/community_proof_db.mjs +3 -0
- package/tests/community_search_route.mjs +7 -6
- package/tests/conductor.mjs +1 -1
- package/tests/conductor_main_e2e.mjs +8 -8
- package/tests/copy_desk_flags_db.mjs +1 -1
- package/tests/copy_desk_page_approve.mjs +2 -2
- package/tests/copy_desk_page_claim.mjs +2 -2
- package/tests/copy_desk_page_next.mjs +1 -1
- package/tests/copy_desk_page_release.mjs +1 -1
- package/tests/copy_desk_page_submit.mjs +2 -2
- package/tests/core_258_box_session_claims_db.mjs +1 -1
- package/tests/craft_mode.mjs +48 -34
- package/tests/craft_mode_home.mjs +20 -20
- package/tests/craft_mode_looks.mjs +16 -15
- package/tests/craft_mode_nav.mjs +31 -29
- package/tests/craft_review_mode.mjs +46 -41
- package/tests/crafts_vocabulary.mjs +70 -0
- package/tests/cross_discipline_priority_direction.mjs +5 -5
- package/tests/fitness.mjs +7 -11
- package/tests/funded_project_pays_proof_db.mjs +1 -1
- package/tests/genesis_home.mjs +21 -1
- package/tests/github_chip.mjs +3 -3
- package/tests/github_repo_invite.mjs +379 -0
- package/tests/goal_criterion_confirm_ui.mjs +1 -1
- package/tests/goal_invite_consent.mjs +1 -1
- package/tests/goal_map_page.mjs +2 -2
- package/tests/goal_sort_staleness.mjs +1 -1
- package/tests/goal_spec_task.mjs +1 -1
- package/tests/goal_spec_task_db.mjs +3 -3
- package/tests/grade_engine.mjs +2 -2
- package/tests/grader_no_artifact.mjs +1 -1
- package/tests/grader_prompt_fencing.mjs +1 -1
- package/tests/grader_prompt_window_bound.mjs +1 -1
- package/tests/grader_reader_lens.mjs +2 -2
- package/tests/grader_severity_gate.mjs +1 -1
- package/tests/grader_unbacked_score.mjs +1 -1
- package/tests/hall_approval_queue.mjs +1 -1
- package/tests/hall_board_world.mjs +2 -2
- package/tests/hall_builders_page_pass.mjs +1 -1
- package/tests/hall_city.mjs +1 -1
- package/tests/hall_fullscreen.mjs +27 -3
- package/tests/hall_kit_charts.mjs +1 -1
- package/tests/hall_landing_boot.mjs +1 -1
- package/tests/hall_my_agents.mjs +16 -16
- package/tests/hall_nav.mjs +22 -15
- package/tests/hall_options_menu.mjs +247 -0
- package/tests/hall_oversight_world.mjs +1 -1
- package/tests/hall_palette.mjs +8 -9
- package/tests/hall_profile_world.mjs +3 -3
- package/tests/hall_record_world.mjs +2 -2
- package/tests/hall_settings_world.mjs +2 -1
- package/tests/hall_sitemap.mjs +6 -5
- package/tests/hall_start_screen.mjs +244 -0
- package/tests/hall_street.mjs +2 -2
- package/tests/hall_street_inside.mjs +17 -9
- package/tests/hall_studio_world.mjs +3 -3
- package/tests/hall_visor.mjs +224 -0
- package/tests/help_requests.mjs +47 -15
- package/tests/helpers.mjs +4 -4
- package/tests/home_city.mjs +6 -4
- package/tests/home_city_widget.mjs +33 -14
- package/tests/home_gallery_widget.mjs +4 -4
- package/tests/home_idea_box.mjs +6 -6
- package/tests/hub_community_page.mjs +3 -3
- package/tests/hub_craft_rollup.mjs +75 -36
- package/tests/hub_recent_ships.mjs +3 -2
- package/tests/idea_cascade.mjs +2 -2
- package/tests/idea_credit_streams_db.mjs +1 -1
- package/tests/idea_detail_page.mjs +1 -1
- package/tests/idea_ideate_full.mjs +5 -2
- package/tests/idea_spark_hall.mjs +1 -1
- package/tests/init.mjs +3 -3
- package/tests/instance_manifest.mjs +2 -2
- package/tests/kickoff_checklist.mjs +1 -1
- package/tests/leaderboard_roles.mjs +34 -25
- package/tests/lifecycle_claim_ladder_refs.mjs +55 -0
- package/tests/lightbulb.mjs +14 -10
- package/tests/main_discipline.mjs +8 -8
- package/tests/markdown_line_endings.mjs +1 -1
- package/tests/market_watch_pages.mjs +52 -74
- package/tests/me_streak_leaderboard_queries.mjs +3 -3
- package/tests/migration_allocation.mjs +1 -1
- package/tests/mingle.mjs +36 -21
- package/tests/module-scope-map.mjs +22 -2
- package/tests/module_api.mjs +1 -0
- package/tests/module_contributions.mjs +13 -13
- package/tests/module_manifest.mjs +29 -0
- package/tests/module_skills_hook.mjs +2 -2
- package/tests/modules.mjs +14 -7
- package/tests/nav_permission_atoms.mjs +2 -1
- package/tests/needs_rebase.mjs +1 -1
- package/tests/newcomer_restock.mjs +13 -13
- package/tests/page_notes_panel.mjs +22 -22
- package/tests/page_tweak_no_block.mjs +1 -1
- package/tests/paintbrush.mjs +7 -7
- package/tests/privacy_matrix.mjs +1 -0
- package/tests/profile_activity.mjs +20 -23
- package/tests/profile_earnings.mjs +1 -1
- package/tests/profile_nudge_prefs.mjs +4 -4
- package/tests/profile_role_headline.mjs +73 -46
- package/tests/profile_role_stats.mjs +55 -45
- package/tests/profile_rollup_consent.mjs +19 -6
- package/tests/profile_route.mjs +12 -12
- package/tests/profile_ui_cross_project.mjs +4 -4
- package/tests/project_invite_suggestions.mjs +2 -2
- package/tests/promote_goal_id.mjs +1 -1
- package/tests/publish_manifest.mjs +1 -1
- package/tests/rank_floor_wiring.mjs +1 -1
- package/tests/regrade_actual_minutes.mjs +1 -1
- package/tests/removal_proposal.mjs +2 -2
- package/tests/reward_gate.mjs +4 -4
- package/tests/reward_mode_cost_plus_only.mjs +1 -1
- package/tests/role_responsibilities.mjs +18 -12
- package/tests/role_stats_db.mjs +17 -16
- package/tests/scouting_rollup_fanout.mjs +5 -5
- package/tests/seed_tasks.mjs +5 -2
- package/tests/session_earnings_mirror_db.mjs +1 -1
- package/tests/session_reward_on_land_db.mjs +1 -1
- package/tests/session_reward_reconcile_db.mjs +2 -2
- package/tests/sessions_kit_pager.mjs +1 -1
- package/tests/settings_art_key_absent.mjs +2 -2
- package/tests/settings_main_role.mjs +21 -20
- package/tests/setup_flow.mjs +3 -3
- package/tests/setup_smoke.mjs +20 -0
- package/tests/ship_card.mjs +6 -6
- package/tests/specialities.mjs +16 -4
- package/tests/speciality_db_shape.mjs +6 -6
- package/tests/speciality_injection.mjs +17 -17
- package/tests/speciality_offer_ui.mjs +5 -5
- package/tests/speciality_offered.mjs +6 -5
- package/tests/speciality_session_skills.mjs +7 -7
- package/tests/speciality_skills.mjs +11 -11
- package/tests/speciality_walkthrough_ui.mjs +2 -2
- package/tests/sso_checkin_identity_spoof.mjs +2 -1
- package/tests/task_classifier_vocab.mjs +10 -0
- package/tests/task_cli.mjs +11 -3
- package/tests/task_criteria_unlink_db.mjs +2 -2
- package/tests/task_discipline_required.mjs +38 -16
- package/tests/task_goal_required.mjs +4 -4
- package/tests/task_needs_db.mjs +1 -1
- package/tests/tweak_replaces_artist_review.mjs +1 -1
- package/tests/update_pill.mjs +153 -2
- package/tests/upkeep_home.mjs +1 -1
- package/tests/v3_c1_options_proof.mjs +145 -0
- package/tests/visual_review.mjs +3 -3
- package/tests/watch_applications_queue.mjs +8 -5
- package/tests/watch_sealed_floor.mjs +3 -1
- package/tests/welcome_boot.mjs +12 -9
- package/tests/welcome_boot_browser.mjs +13 -13
- package/tests/worktree_helper.mjs +16 -1
|
@@ -621,8 +621,7 @@
|
|
|
621
621
|
<span>Role it sits under</span>
|
|
622
622
|
<select name="discipline" required>
|
|
623
623
|
<option value="">Pick one…</option>
|
|
624
|
-
<option value="
|
|
625
|
-
<option value="ideator">Ideator</option>
|
|
624
|
+
<option value="artisan">Artisan</option>
|
|
626
625
|
<option value="artist">Artist</option>
|
|
627
626
|
<option value="ui">UI design</option>
|
|
628
627
|
</select>
|
|
@@ -81,7 +81,6 @@
|
|
|
81
81
|
let top = h;
|
|
82
82
|
if (craft === 'artist') { const bh = Math.round(h * 0.8); S.box(out, T, x, 0, w, bh, T.work, { d: 6, win: true, lit: lit }); S.sawtooth(out, x, -bh, w, 3, 12, T.roof, T.glass); top = bh + 12; }
|
|
83
83
|
else if (craft === 'ui') { S.box(out, T, x, 0, w, h, T.glass, { d: 6, grid: 3 }); S.box(out, T, x - 2, 0, w + 4, 4, T.roof, { d: 6, z: h }); top = h + 4; }
|
|
84
|
-
else if (craft === 'ideator') { S.box(out, T, x, 0, w, 22, T.work, { d: 6, door: true }); S.gable(out, x, -22, w, 14, T.roof); top = 36; }
|
|
85
84
|
else S.box(out, T, x, 0, w, h, T.work, { d: 6, win: true, lit: lit });
|
|
86
85
|
if (!lit) {
|
|
87
86
|
const fx = x + w / 2;
|
|
@@ -410,7 +409,7 @@
|
|
|
410
409
|
stageEdge: p.draw === 'awaiting a tester' ? 'rgba(251,149,105,0.6)' : T.ruleStrong,
|
|
411
410
|
})),
|
|
412
411
|
legend: [
|
|
413
|
-
{ key: 'a', text: 'Shape is the craft: tower for
|
|
412
|
+
{ key: 'a', text: 'Shape is the craft: tower for artisan, studio roof for artist, glass front for UI.' },
|
|
414
413
|
{ key: 'b', text: 'Stage is the status: staked plot, slab, scaffold, built, then lit once shipped. A flag means it waits on a check.' },
|
|
415
414
|
],
|
|
416
415
|
};
|
|
@@ -670,7 +669,7 @@
|
|
|
670
669
|
}
|
|
671
670
|
|
|
672
671
|
// ---------- the real districts ----------
|
|
673
|
-
const CRAFTS = Object.freeze(['
|
|
672
|
+
const CRAFTS = Object.freeze(['artisan', 'artist', 'ui']);
|
|
674
673
|
// A task's status as the prototype's construction stage: [drawing stage, pill words].
|
|
675
674
|
const STAGES = Object.freeze({
|
|
676
675
|
shipped: ['shipped', 'shipped'], confirmed: ['graded · landing', 'graded · landing'], completed: ['being graded', 'being graded'],
|
|
@@ -699,7 +698,7 @@
|
|
|
699
698
|
const shown = mine.slice().sort((a, b) => rank(a) - rank(b) || recent(a) - recent(b) || Number(a.id) - Number(b.id)).slice(0, MAX_ITEMS)
|
|
700
699
|
.sort((a, b) => PIPELINE.indexOf(a.status) - PIPELINE.indexOf(b.status) || Number(a.id) - Number(b.id));
|
|
701
700
|
const items = shown.map((t) => {
|
|
702
|
-
const craft = CRAFTS.indexOf(t.discipline) >= 0 ? t.discipline : '
|
|
701
|
+
const craft = CRAFTS.indexOf(t.discipline) >= 0 ? t.discipline : 'artisan';
|
|
703
702
|
const st = STAGES[t.status];
|
|
704
703
|
const built = ['ready', 'backlog'].indexOf(st[0]) < 0;
|
|
705
704
|
return [String(t.title || 'task ' + t.id), String(t.kind || 'task'), craft, st[0], built ? taskHeight(t) : 0, st[1], '/builders/task/' + encodeURIComponent(t.id)];
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<!-- The faces (Manrope, JetBrains Mono) come from the branding pack's font
|
|
11
11
|
links, injected into this head by the server like every hall page's
|
|
12
12
|
(tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet). -->
|
|
13
|
-
<link rel="stylesheet" href="/builders/style.css?v=2026-
|
|
13
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-11-10-options">
|
|
14
14
|
<link rel="stylesheet" href="/builders/street.css?v=2026-10-09-living3">
|
|
15
15
|
<link rel="stylesheet" href="/builders/street-card.css?v=2026-10-04-record1">
|
|
16
16
|
<link rel="stylesheet" href="/builders/street-deck.css?v=2026-10-17-tidy">
|
|
@@ -229,10 +229,10 @@
|
|
|
229
229
|
</div>
|
|
230
230
|
|
|
231
231
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
232
|
-
<script src="/builders/shell-game.js?v=2026-11-
|
|
232
|
+
<script src="/builders/shell-game.js?v=2026-11-10-options"></script>
|
|
233
233
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
234
|
-
<script src="/builders/craft-mode.js?v=2026-11-
|
|
235
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
234
|
+
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
235
|
+
<script src="/builders/shell.js?v=2026-11-10-character"></script>
|
|
236
236
|
<script src="/builders/hall-dialog.js"></script>
|
|
237
237
|
<script src="/builders/palette.js" defer></script>
|
|
238
238
|
<script src="/builders/gov-living.js?v=2026-10-09-positions1"></script>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
|
|
13
13
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
14
14
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
15
|
-
<link rel="stylesheet" href="/builders/style.css?v=2026-
|
|
15
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-11-10-options">
|
|
16
16
|
<link rel="stylesheet" href="/builders/studio.css?v=2026-10-09-day">
|
|
17
17
|
<link rel="stylesheet" href="/builders/approval-queue.css?v=2026-09-29-aqfix">
|
|
18
18
|
<link rel="stylesheet" href="/builders/home-gallery.css?v=2026-11-04-studio">
|
|
@@ -222,10 +222,10 @@
|
|
|
222
222
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
223
223
|
|
|
224
224
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
225
|
-
<script src="/builders/shell-game.js?v=2026-11-
|
|
225
|
+
<script src="/builders/shell-game.js?v=2026-11-10-options"></script>
|
|
226
226
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
227
|
-
<script src="/builders/craft-mode.js?v=2026-11-
|
|
228
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
227
|
+
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
228
|
+
<script src="/builders/shell.js?v=2026-11-10-character"></script>
|
|
229
229
|
<script src="/builders/hall-dialog.js"></script>
|
|
230
230
|
<script src="/builders/palette.js" defer></script>
|
|
231
231
|
<!-- The kit, for its ONE renderer: the full-size ship-time visual figure
|
|
@@ -243,7 +243,7 @@
|
|
|
243
243
|
<script src="/builders/studio-lib.js?v=2026-10-09-day"></script>
|
|
244
244
|
<script src="/builders/ai-studio-lib.js?v=2026-10-29-ais1"></script>
|
|
245
245
|
<script src="/builders/studio.js?v=2026-10-09-day"></script>
|
|
246
|
-
<script src="/builders/home-gallery.js?v=2026-11-
|
|
246
|
+
<script src="/builders/home-gallery.js?v=2026-11-10-options"></script>
|
|
247
247
|
<script src="/builders/home-studio.js?v=2026-11-04-studio"></script>
|
|
248
248
|
</body>
|
|
249
249
|
</html>
|
|
@@ -712,6 +712,16 @@ html[data-theme="dark"] .brand-mark__mark { --mark-ink: #e2e1e4; }
|
|
|
712
712
|
.founding-band { flex-wrap: wrap; row-gap: 2px; padding: 8px 16px; }
|
|
713
713
|
.founding-band__desc { display: none; }
|
|
714
714
|
.founding-band__stage { margin-left: 0; white-space: normal; }
|
|
715
|
+
/* task 1005148, the visor (visor.css): the top of a phone belongs to the scene and the shell’s
|
|
716
|
+
corner buttons, so the compass and the place line step aside and all three pills share the
|
|
717
|
+
bottom row: the main action, Actions (its dots and key only), the sprite with the credits. */
|
|
718
|
+
html[data-game="on"] .visor:not([hidden]) { --visor-inset-right: var(--ds-space-gutter-narrow); --visor-inset-left: var(--ds-space-gutter-narrow); --visor-inset-bottom: 40px; }
|
|
719
|
+
html[data-game="on"] .visor__place, html[data-game="on"] .visor__cell, html[data-game="on"] .visor__mark { display: none; }
|
|
720
|
+
html[data-game="on"] .visor__pill--actions { top: auto; right: auto; left: 50%; bottom: var(--visor-inset-bottom); transform: translateX(-50%); padding: 0 var(--ds-space-xs); }
|
|
721
|
+
html[data-game="on"] .visor__pill--actions > span:not(.visor__dots) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
722
|
+
html[data-game="on"] .visor__sheet { top: auto; bottom: calc(var(--visor-inset-bottom) + 56px); right: var(--visor-inset-right); max-height: 70vh; }
|
|
723
|
+
html[data-game="on"] .visor__me .visor__name { display: none; }
|
|
724
|
+
html[data-game="on"] .visor__me { padding: 4px var(--ds-space-xs) 4px 4px; }
|
|
715
725
|
}
|
|
716
726
|
/* task 1004424 (BV2.PS10): THE FOUNDING MARK. A pill in .rank-badge's grammar (same
|
|
717
727
|
height, type and radius) so it sits beside a rank without competing with it; the
|
|
@@ -1255,7 +1265,15 @@ html[data-fullscreen="on"] .app-topbar {
|
|
|
1255
1265
|
pointer-events: none;
|
|
1256
1266
|
}
|
|
1257
1267
|
html[data-fullscreen="on"] .app-topbar > :not(.topbar-side),
|
|
1258
|
-
html[data-fullscreen="on"] .topbar-side > :not(.fullscreen-toggle) { display: none; }
|
|
1268
|
+
html[data-fullscreen="on"] .topbar-side > :not(.fullscreen-toggle):not(.upd-pill) { display: none; }
|
|
1269
|
+
/* task 1005191: the Update pill stays with the bars away. Game mode opens every page
|
|
1270
|
+
this way, and an update nobody can see is an update nobody takes. */
|
|
1271
|
+
html[data-fullscreen="on"] .upd-pill {
|
|
1272
|
+
pointer-events: auto;
|
|
1273
|
+
min-height: 36px;
|
|
1274
|
+
margin-right: 8px;
|
|
1275
|
+
box-shadow: var(--shadow-pop);
|
|
1276
|
+
}
|
|
1259
1277
|
/* task 1004430: the way back must read on ANY ground. The hall's glass is
|
|
1260
1278
|
near-clear, so over the black sky in the light theme it was a dark glyph on
|
|
1261
1279
|
black — the page looked stuck without its bars. The card tone plus a drop
|
|
@@ -1281,6 +1299,16 @@ html[data-fullscreen="on"] .fullscreen-toggle:hover { color: var(--accent-ink);
|
|
|
1281
1299
|
/* A page with no full-screen layout of its own steps its content clear of the
|
|
1282
1300
|
corner button; the sky and the studio lay themselves out (shell.js `plain`). */
|
|
1283
1301
|
html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-top: 60px; }
|
|
1302
|
+
/* EMBEDDED (html[data-embed="on"], shell-game.js; task 1005144, ADR 0401): a screen
|
|
1303
|
+
opened inside the options menu's frame. The menu is the chrome, so the page keeps
|
|
1304
|
+
none of its own — no sidebar, scrim, foot or top bar — and sits on the frame's
|
|
1305
|
+
ground. The page keeps its one <header> in the DOM (hidden), as full screen does. */
|
|
1306
|
+
html[data-embed="on"] .app-sidebar,
|
|
1307
|
+
html[data-embed="on"] .app-scrim,
|
|
1308
|
+
html[data-embed="on"] .app-foot,
|
|
1309
|
+
html[data-embed="on"] .app-topbar { display: none; }
|
|
1310
|
+
html[data-embed="on"] .app-body { margin-left: 0; }
|
|
1311
|
+
html[data-embed="on"] .app-content { padding-top: 0; }
|
|
1284
1312
|
/* Said once on entering, since the choice is remembered and a page can open in it. */
|
|
1285
1313
|
.fullscreen-hint {
|
|
1286
1314
|
position: fixed;
|
|
@@ -1313,7 +1341,8 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
|
|
|
1313
1341
|
flex-shrink: 0;
|
|
1314
1342
|
}
|
|
1315
1343
|
.craft-switch__opt,
|
|
1316
|
-
.craft-switch__open
|
|
1344
|
+
.craft-switch__open,
|
|
1345
|
+
.craft-switch__me {
|
|
1317
1346
|
display: inline-flex;
|
|
1318
1347
|
align-items: center;
|
|
1319
1348
|
gap: 6px;
|
|
@@ -1330,10 +1359,12 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
|
|
|
1330
1359
|
white-space: nowrap;
|
|
1331
1360
|
}
|
|
1332
1361
|
.craft-switch__opt:hover,
|
|
1333
|
-
.craft-switch__open:hover
|
|
1362
|
+
.craft-switch__open:hover,
|
|
1363
|
+
.craft-switch__me:hover { color: var(--ink); background: var(--glass); }
|
|
1334
1364
|
.craft-switch__opt[aria-pressed="true"] { color: var(--ink); background: var(--glass-strong); }
|
|
1335
1365
|
.craft-switch__opt:focus-visible,
|
|
1336
|
-
.craft-switch__open:focus-visible
|
|
1366
|
+
.craft-switch__open:focus-visible,
|
|
1367
|
+
.craft-switch__me:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
|
|
1337
1368
|
.craft-switch__icon { width: 15px; height: 15px; flex-shrink: 0; }
|
|
1338
1369
|
.craft-switch__open { display: none; }
|
|
1339
1370
|
@media (max-width: 1180px) {
|
|
@@ -1344,7 +1375,23 @@ html[data-fullscreen="on"][data-fullscreen-plain="on"] .app-content { padding-to
|
|
|
1344
1375
|
.craft-switch { padding: 2px; }
|
|
1345
1376
|
.craft-switch__opt[aria-pressed="false"] { display: none; }
|
|
1346
1377
|
.craft-switch--unset .craft-switch__open { display: inline-flex; padding: 0 7px; }
|
|
1347
|
-
}
|
|
1378
|
+
.craft-switch__me { padding: 0 2px; }
|
|
1379
|
+
.craft-switch__me .craft-switch__label { display: none; }
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
/* THE CHARACTER (task 1005147). A builder who holds a character wears its sprite in
|
|
1383
|
+
the top bar in place of the switch: one button, which offers "Change character"
|
|
1384
|
+
(signing out). The sprites are pixel art, so they scale by whole pixels. */
|
|
1385
|
+
.craft-sprite { display: block; image-rendering: pixelated; object-fit: contain; }
|
|
1386
|
+
.craft-switch__me { padding: 0 10px 0 4px; color: var(--ink); }
|
|
1387
|
+
/* The chip is the figure's head: the portrait cropped round its top third. */
|
|
1388
|
+
.craft-sprite--chip { width: 26px; height: 26px; border-radius: var(--radius-pill); object-fit: cover; object-position: 50% 22%; }
|
|
1389
|
+
/* Character creation: each door is the owner's portrait — the figure on its plinth
|
|
1390
|
+
in the torch-lit hall — filling the top of the door, the words beneath it. */
|
|
1391
|
+
.craft-plinth { display: block; overflow: hidden; }
|
|
1392
|
+
.craft-sprite--door { width: 100%; height: auto; aspect-ratio: 250 / 290; transition: transform 200ms cubic-bezier(.2, .7, .3, 1); }
|
|
1393
|
+
.craft-door--character:hover .craft-sprite--door,
|
|
1394
|
+
.craft-door--character:focus-visible .craft-sprite--door { transform: scale(1.03); }
|
|
1348
1395
|
|
|
1349
1396
|
/* The picker: a dialog over a scrim, four doors in a row above the
|
|
1350
1397
|
"ask me again" box. Each door carries its scene from the approved prototype,
|
|
@@ -1427,7 +1474,8 @@ html.setup-gate-open { overflow: hidden; }
|
|
|
1427
1474
|
.setup-gate__craft[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-tint); }
|
|
1428
1475
|
/* The save is the shared primary door (controls.css, task 1005084). */
|
|
1429
1476
|
.setup-gate__save { margin-top: 12px; }
|
|
1430
|
-
.setup-gate__err
|
|
1477
|
+
.setup-gate__err,
|
|
1478
|
+
.craft-picker__error { margin: 8px 0 0; font-size: 14px; color: var(--danger); }
|
|
1431
1479
|
.setup-gate__foot { margin: 24px 0 0; font-size: 14px; }
|
|
1432
1480
|
.setup-gate__foot a { color: var(--ink-soft); }
|
|
1433
1481
|
@media (max-width: 640px) { .setup-gate__panel { padding: 28px 20px 20px; border-radius: 18px; } }
|
|
@@ -1525,9 +1573,9 @@ html.setup-gate-open { overflow: hidden; }
|
|
|
1525
1573
|
overflow: hidden;
|
|
1526
1574
|
background: #101012;
|
|
1527
1575
|
}
|
|
1528
|
-
.craft-art--
|
|
1576
|
+
.craft-art--artist { background: #0c1122; }
|
|
1529
1577
|
.craft-art--ideating { background: #05060d; }
|
|
1530
|
-
.craft-art--
|
|
1578
|
+
.craft-art--patron { background: #000; }
|
|
1531
1579
|
.craft-art__dot { position: absolute; border-radius: 999px; box-sizing: border-box; }
|
|
1532
1580
|
.craft-art__dot--star { background: #d8dcf0; }
|
|
1533
1581
|
.craft-art__dot--lit { background: var(--accent); border-radius: 0; }
|
|
@@ -1592,6 +1640,11 @@ html.setup-gate-open { overflow: hidden; }
|
|
|
1592
1640
|
.craft-door__head { padding: 10px 16px 0; }
|
|
1593
1641
|
.craft-door__name { font-size: 18px; }
|
|
1594
1642
|
.craft-door__line { flex: 0 0 100%; padding: 0 16px; box-sizing: border-box; }
|
|
1643
|
+
/* A phone stacks the three as rows: the portrait on the left, the words beside it. */
|
|
1644
|
+
.craft-door.craft-door--character { display: grid; grid-template-columns: 86px minmax(0, 1fr); grid-template-rows: auto 1fr; align-content: start; gap: 4px 14px; padding: 0; }
|
|
1645
|
+
.craft-plinth { grid-row: 1 / span 2; width: 86px; }
|
|
1646
|
+
.craft-door.craft-door--character > .craft-door__head { padding: 12px 14px 0 0; }
|
|
1647
|
+
.craft-door.craft-door--character > .craft-door__line { padding: 0 14px 12px 0; }
|
|
1595
1648
|
}
|
|
1596
1649
|
|
|
1597
1650
|
/* THE CRAFT MODE LOOKS (task 1004495; direction docs/design/craft-mode-direction.md).
|
|
@@ -1601,37 +1654,30 @@ html.setup-gate-open { overflow: hidden; }
|
|
|
1601
1654
|
what to press: the accent stays the action colour in every mode. Light values
|
|
1602
1655
|
clear 5.4:1 on the hall's paper; the dark values are the prototype's. Light
|
|
1603
1656
|
keeps the paper ground; only dark changes the ground and the glass. */
|
|
1604
|
-
html[data-craft="
|
|
1605
|
-
html[data-craft="
|
|
1606
|
-
html[data-craft="
|
|
1607
|
-
html[data-theme="dark"][data-craft="artistry"] {
|
|
1657
|
+
html[data-craft="artist"] { --craft: #2e3c6e; --craft-on: #f1e6d2; }
|
|
1658
|
+
html[data-craft="patron"] { --craft: #33479e; --craft-on: #eef1ff; }
|
|
1659
|
+
html[data-theme="dark"][data-craft="artist"] {
|
|
1608
1660
|
--craft: #f1e6d2; --craft-on: #0c1122;
|
|
1609
1661
|
--bg: #07080d; --bg-frame: #0a0b12;
|
|
1610
1662
|
--glass: rgba(150, 170, 230, .11); --glass-strong: rgba(170, 190, 240, .17);
|
|
1611
1663
|
--glass-edge: rgba(241, 230, 210, .16);
|
|
1612
1664
|
}
|
|
1613
|
-
html[data-theme="dark"][data-craft="
|
|
1614
|
-
--craft: #f2d27a; --craft-on: #1d1604;
|
|
1615
|
-
--bg: #05060d;
|
|
1616
|
-
--glass: rgba(140, 150, 225, .10); --glass-strong: rgba(160, 170, 240, .16);
|
|
1617
|
-
--glass-edge: rgba(242, 210, 122, .16);
|
|
1618
|
-
}
|
|
1619
|
-
html[data-theme="dark"][data-craft="governing"] {
|
|
1665
|
+
html[data-theme="dark"][data-craft="patron"] {
|
|
1620
1666
|
--craft: #aabeff; --craft-on: #0a1030;
|
|
1621
1667
|
--glass-edge: rgba(170, 190, 255, .16);
|
|
1622
1668
|
}
|
|
1623
1669
|
/* The shared treatment: the switch's current pill, the current tab and the top
|
|
1624
1670
|
bar's hairline take the mode colour. */
|
|
1625
|
-
html:is([data-craft="
|
|
1671
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .craft-switch__opt[aria-pressed="true"] {
|
|
1626
1672
|
background: var(--craft); color: var(--craft-on);
|
|
1627
1673
|
}
|
|
1628
|
-
html:is([data-craft="
|
|
1674
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active {
|
|
1629
1675
|
background: color-mix(in srgb, var(--craft) 14%, transparent); color: var(--craft);
|
|
1630
1676
|
}
|
|
1631
|
-
html:is([data-craft="
|
|
1632
|
-
html:is([data-craft="
|
|
1633
|
-
html:is([data-craft="
|
|
1634
|
-
html:is([data-craft="
|
|
1677
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active .nav-icon,
|
|
1678
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active .nav-item__label { color: var(--craft); }
|
|
1679
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .nav-item--active::before { background: var(--craft); }
|
|
1680
|
+
html:is([data-craft="artist"], [data-craft="patron"]) .app-topbar {
|
|
1635
1681
|
border-bottom-color: color-mix(in srgb, var(--craft) 30%, transparent);
|
|
1636
1682
|
}
|
|
1637
1683
|
/* The header mark: the mode's own words beside the page title (craft-mode.js
|
|
@@ -1735,7 +1781,7 @@ html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing
|
|
|
1735
1781
|
.craft-plate .craft-art { width: calc(100% / .582); transform: scale(.582); }
|
|
1736
1782
|
}
|
|
1737
1783
|
/* The plate follows the theme (owner, 2026-10-03): light shows each scene's day. */
|
|
1738
|
-
html[data-theme="light"] .craft-plate .craft-art--
|
|
1784
|
+
html[data-theme="light"] .craft-plate .craft-art--artist { background: #dfe3ef; }
|
|
1739
1785
|
html[data-theme="light"] .craft-plate .craft-art__dot--star { background: #2e3c6e; }
|
|
1740
1786
|
html[data-theme="light"] .craft-plate .craft-art__moon { background: #f3c98b; box-shadow: 0 0 0 9px rgba(243, 201, 139, .28); }
|
|
1741
1787
|
html[data-theme="light"] .craft-plate .craft-art__ground { background: #c3c9dc; }
|
|
@@ -1745,28 +1791,8 @@ html[data-theme="light"] .craft-plate .craft-art__dot--gold { background: #c9a23
|
|
|
1745
1791
|
html[data-theme="light"] .craft-plate .craft-art__dot--glow { background: #b8891c; box-shadow: 0 0 10px rgba(184, 137, 28, .45); }
|
|
1746
1792
|
html[data-theme="light"] .craft-plate .craft-art__dot--proto { box-shadow: inset 0 0 0 1px rgba(122, 90, 12, .6); }
|
|
1747
1793
|
html[data-theme="light"] .craft-plate .craft-art__ring { box-shadow: inset 0 0 0 1px rgba(122, 90, 12, .35); }
|
|
1748
|
-
html[data-theme="light"] .craft-plate .craft-art--
|
|
1794
|
+
html[data-theme="light"] .craft-plate .craft-art--patron { background: #e9ecf6; }
|
|
1749
1795
|
html[data-theme="light"] .craft-plate .craft-art__city { filter: invert(1) hue-rotate(180deg); }
|
|
1750
|
-
/* Ideating's star dust: a few faint fixed specks across the rail itself. */
|
|
1751
|
-
html[data-craft="ideating"] .app-sidebar {
|
|
1752
|
-
background-image:
|
|
1753
|
-
radial-gradient(1px 1px at 14px 40px, rgba(242, 210, 122, .5), transparent),
|
|
1754
|
-
radial-gradient(1px 1px at 46px 130px, rgba(242, 210, 122, .35), transparent),
|
|
1755
|
-
radial-gradient(1.5px 1.5px at 120px 90px, rgba(242, 210, 122, .4), transparent),
|
|
1756
|
-
radial-gradient(1px 1px at 200px 190px, rgba(242, 210, 122, .35), transparent),
|
|
1757
|
-
radial-gradient(1px 1px at 30px 230px, rgba(242, 210, 122, .3), transparent),
|
|
1758
|
-
radial-gradient(1.5px 1.5px at 170px 260px, rgba(242, 210, 122, .3), transparent);
|
|
1759
|
-
background-size: 246px 280px;
|
|
1760
|
-
}
|
|
1761
|
-
html[data-theme="light"][data-craft="ideating"] .app-sidebar {
|
|
1762
|
-
background-image:
|
|
1763
|
-
radial-gradient(1px 1px at 14px 40px, rgba(184, 137, 28, .45), transparent),
|
|
1764
|
-
radial-gradient(1px 1px at 46px 130px, rgba(184, 137, 28, .3), transparent),
|
|
1765
|
-
radial-gradient(1.5px 1.5px at 120px 90px, rgba(184, 137, 28, .35), transparent),
|
|
1766
|
-
radial-gradient(1px 1px at 200px 190px, rgba(184, 137, 28, .3), transparent),
|
|
1767
|
-
radial-gradient(1px 1px at 30px 230px, rgba(184, 137, 28, .25), transparent),
|
|
1768
|
-
radial-gradient(1.5px 1.5px at 170px 260px, rgba(184, 137, 28, .25), transparent);
|
|
1769
|
-
}
|
|
1770
1796
|
|
|
1771
1797
|
/* THE MODE TOOLS (task 1004496, craft-mode.js TOOLS): a round button beside the
|
|
1772
1798
|
switch, in the mode's colour, shown only in its own mode. Artistry's palette
|
|
@@ -451,8 +451,8 @@
|
|
|
451
451
|
// A create with no discipline the server cannot infer from the wording is
|
|
452
452
|
// refused (task 1002988), so the builder names the craft here. Engineer is
|
|
453
453
|
// the default, the same fallback bug routing uses (ideas/inbox.js).
|
|
454
|
-
var craftOptions = [['
|
|
455
|
-
return '<option value="' + c[0] + '"' + (c[0] === '
|
|
454
|
+
var craftOptions = [['artisan', 'Artisan'], ['artist', 'Artist'], ['ui', 'UI']].map(function (c) {
|
|
455
|
+
return '<option value="' + c[0] + '"' + (c[0] === 'artisan' ? ' selected' : '') + '>' + c[1] + '</option>';
|
|
456
456
|
}).join('');
|
|
457
457
|
box.innerHTML =
|
|
458
458
|
'<form class="td-form" data-form="promote">'
|
|
@@ -509,7 +509,7 @@
|
|
|
509
509
|
title: title,
|
|
510
510
|
description: body + provenance,
|
|
511
511
|
priority: Number(form.priority.value) || 3,
|
|
512
|
-
discipline: (form.discipline && form.discipline.value) || '
|
|
512
|
+
discipline: (form.discipline && form.discipline.value) || 'artisan',
|
|
513
513
|
source: 'idea_inbox',
|
|
514
514
|
source_ref: 'idea:' + idea.id,
|
|
515
515
|
};
|
|
@@ -750,7 +750,8 @@
|
|
|
750
750
|
}
|
|
751
751
|
|
|
752
752
|
window.addEventListener('keydown', function (e) {
|
|
753
|
-
|
|
753
|
+
// Spent once it closed the card (ADR 0399 §2.4 row 5, task 1005144).
|
|
754
|
+
if (e.key === 'Escape' && document.getElementById('deeplink-card')) { e.preventDefault(); clearLink(); }
|
|
754
755
|
});
|
|
755
756
|
window.addEventListener('hashchange', resolve);
|
|
756
757
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
|
|
9
9
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10
10
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
11
|
-
<link rel="stylesheet" href="/builders/style.css?v=2026-
|
|
11
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-11-10-options">
|
|
12
12
|
<!-- The record archetype (shared with idea.html) and this page's own two
|
|
13
13
|
shapes. Promoted out of an inline <style> by task 1003305 — the block was
|
|
14
14
|
the hall's last substantive one and sat at its hall_audit ratchet. -->
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
<!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
|
|
58
58
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
60
|
-
<script src="/builders/shell-game.js?v=2026-11-
|
|
60
|
+
<script src="/builders/shell-game.js?v=2026-11-10-options"></script>
|
|
61
61
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
62
|
-
<script src="/builders/craft-mode.js?v=2026-11-
|
|
63
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
62
|
+
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
63
|
+
<script src="/builders/shell.js?v=2026-11-10-character"></script>
|
|
64
64
|
<script src="/builders/hall-dialog.js"></script>
|
|
65
65
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
66
66
|
<script src="/builders/palette.js" defer></script>
|
|
67
67
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N deep-link overlay
|
|
68
68
|
(and the #/task/N → /task/N redirect, task 751); load it here too so those
|
|
69
69
|
links still resolve from this page. -->
|
|
70
|
-
<script src="/builders/task-detail.js?v=2026-
|
|
70
|
+
<script src="/builders/task-detail.js?v=2026-11-10-options" defer></script>
|
|
71
71
|
<script src="/builders/brand-apply.js?v=2026-06-19-r56" defer></script>
|
|
72
72
|
<script src="/builders/md-reader.js" defer></script>
|
|
73
73
|
<script src="/builders/hall-visual.js?v=2026-09-16-visual1" defer></script>
|
|
@@ -304,3 +304,13 @@ html[data-fullscreen="on"] .sky-stage .top { padding-right: 184px; }
|
|
|
304
304
|
.card { max-width: 240px; }
|
|
305
305
|
}
|
|
306
306
|
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
|
|
307
|
+
|
|
308
|
+
/* task 1005148: with the visor up (html.visor-on, game mode; visor.js), the sky's own layers keep
|
|
309
|
+
clear of the glass, as ADR 0399 §2.3 asks of a scene's pop-ups: the top row, the composer, the
|
|
310
|
+
jump field and the two side panels step below the compass and the place line, and the foot and
|
|
311
|
+
the tour rise above the visor's corner pills. Outside game mode nothing here applies. */
|
|
312
|
+
html.visor-on .top { padding-top: calc(60px + env(safe-area-inset-top, 0px)); }
|
|
313
|
+
html.visor-on .composer, html.visor-on .jump { top: calc(116px + env(safe-area-inset-top, 0px)); }
|
|
314
|
+
html.visor-on .panel, html.visor-on .room { top: calc(180px + env(safe-area-inset-top, 0px)); bottom: calc(200px + env(safe-area-inset-bottom, 0px)); }
|
|
315
|
+
html.visor-on .foot { padding-bottom: calc(132px + env(safe-area-inset-bottom, 0px)); }
|
|
316
|
+
html.visor-on .tour, html.visor-on .start { bottom: calc(210px + env(safe-area-inset-bottom, 0px)); }
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
links, injected into this head by the server like every hall page's
|
|
13
13
|
(tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet).
|
|
14
14
|
The template carried its own Google Fonts link for the same two faces. -->
|
|
15
|
-
<link rel="stylesheet" href="/builders/style.css?v=2026-
|
|
16
|
-
<link rel="stylesheet" href="/builders/
|
|
15
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-11-10-options">
|
|
16
|
+
<link rel="stylesheet" href="/builders/visor.css?v=2026-11-10-visor">
|
|
17
|
+
<link rel="stylesheet" href="/builders/thinking.css?v=2026-11-10-visor">
|
|
17
18
|
</head>
|
|
18
19
|
<!-- THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331, ADR 0227
|
|
19
20
|
§11). This page is docs/design/mocks/sky/sky.template.html — the prototype
|
|
@@ -139,11 +140,13 @@
|
|
|
139
140
|
</div>
|
|
140
141
|
|
|
141
142
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
142
|
-
<script src="/builders/shell-game.js?v=2026-11-
|
|
143
|
+
<script src="/builders/shell-game.js?v=2026-11-10-options"></script>
|
|
143
144
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
144
|
-
<script src="/builders/craft-mode.js?v=2026-11-
|
|
145
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
145
|
+
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
146
|
+
<script src="/builders/shell.js?v=2026-11-10-character"></script>
|
|
146
147
|
<script src="/builders/hall-dialog.js"></script>
|
|
148
|
+
<!-- task 1005148: the visor (glass over the scene, game mode only; ADR 0399), after the shell and hall-dialog.js -->
|
|
149
|
+
<script src="/builders/visor.js?v=2026-11-10-visor"></script>
|
|
147
150
|
<script src="/builders/palette.js" defer></script>
|
|
148
151
|
|
|
149
152
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -152,7 +155,7 @@
|
|
|
152
155
|
<script src="/builders/sky-data.js?v=2026-09-30-uat1"></script>
|
|
153
156
|
<script src="/builders/sky-layout.js?v=2026-09-27-split"></script>
|
|
154
157
|
<script src="/builders/sky-draw.js?v=2026-09-27-split"></script>
|
|
155
|
-
<script src="/builders/sky-interaction.js?v=2026-
|
|
158
|
+
<script src="/builders/sky-interaction.js?v=2026-11-10-visor"></script>
|
|
156
159
|
<script src="/builders/sky-panel.js?v=2026-09-30-uat1"></script>
|
|
157
160
|
<script src="/builders/sky-composer.js?v=2026-09-27-split"></script>
|
|
158
161
|
<script src="/builders/sky-tour.js?v=2026-09-27-split"></script>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<link rel="icon" href="/modules/ui-design/public/brand/favicon.svg" type="image/svg+xml">
|
|
11
11
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
12
12
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
13
|
-
<link rel="stylesheet" href="/builders/style.css?v=2026-
|
|
13
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-11-10-options">
|
|
14
14
|
<link rel="stylesheet" href="/builders/tweak-editor.css?v=2026-09-29-tw27-aqfix">
|
|
15
15
|
</head>
|
|
16
16
|
<!-- THE TWEAK EDITOR (task 1004321 / BV2.TW10, goal 1000095; ADR 0341 D4 and
|
|
@@ -143,14 +143,14 @@
|
|
|
143
143
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
144
144
|
|
|
145
145
|
<script src="/builders/dom-utils.js?v=2026-11-05-numbers"></script>
|
|
146
|
-
<script src="/builders/shell-game.js?v=2026-11-
|
|
146
|
+
<script src="/builders/shell-game.js?v=2026-11-10-options"></script>
|
|
147
147
|
<script src="/builders/shell-trail.js?v=2026-11-05-numbers"></script>
|
|
148
|
-
<script src="/builders/craft-mode.js?v=2026-11-
|
|
149
|
-
<script src="/builders/shell.js?v=2026-11-
|
|
148
|
+
<script src="/builders/craft-mode.js?v=2026-11-10-visor"></script>
|
|
149
|
+
<script src="/builders/shell.js?v=2026-11-10-character"></script>
|
|
150
150
|
<script src="/builders/hall-dialog.js"></script>
|
|
151
151
|
<script src="/builders/palette.js" defer></script>
|
|
152
152
|
<script src="/builders/brand-holes.js?v=2026-09-29-aqfix"></script>
|
|
153
153
|
<script src="/builders/tweak-editor-lib.js?v=2026-09-29-tw27"></script>
|
|
154
|
-
<script src="/builders/tweak-editor.js?v=2026-
|
|
154
|
+
<script src="/builders/tweak-editor.js?v=2026-11-10-options"></script>
|
|
155
155
|
</body>
|
|
156
156
|
</html>
|
|
@@ -647,7 +647,11 @@
|
|
|
647
647
|
if (ev.target && ev.target.classList && ev.target.classList.contains('tw-line')) flush();
|
|
648
648
|
});
|
|
649
649
|
document.addEventListener('keydown', (ev) => {
|
|
650
|
-
if (ev.key === 'Escape') {
|
|
650
|
+
if (ev.key === 'Escape') {
|
|
651
|
+
// Spent only when it closed something (ADR 0399 §2.4 row 5, task 1005144).
|
|
652
|
+
if (!$('tw-refused').hidden || $('tw-openwrap').classList.contains('is-open')) ev.preventDefault();
|
|
653
|
+
closeRefused(); setMenu(false);
|
|
654
|
+
}
|
|
651
655
|
if (ev.target && ev.target.id === 'tw-divider') {
|
|
652
656
|
const next = lib.splitFromKey(st.splitSize, ev.key);
|
|
653
657
|
if (next !== null) { ev.preventDefault(); setSize(next); remember(SIZE_KEY, String(st.splitSize)); }
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
'use strict';
|
|
39
39
|
|
|
40
40
|
var RUN_KEY = 'bongos.update.run';
|
|
41
|
+
var LATER_KEY = 'bongos.update.later';
|
|
42
|
+
var LATER_MS = 24 * 60 * 60 * 1000;
|
|
41
43
|
var MSG = 'bongos-update'; // the tag deploy-handoff.js answers to; both sides check it
|
|
42
44
|
var VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
43
45
|
// A hub door as the server words it (core-update.js updateDoor): an origin and
|
|
@@ -152,12 +154,34 @@
|
|
|
152
154
|
return slow ? 'slow' : 'starting';
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
// THE POP-UP (task 1005191). The owner, 2026-11-10: the pill alone was not seen. Game mode
|
|
158
|
+
// opens every page without its bars, and a project sat 3 minor versions behind. So an
|
|
159
|
+
// update that is ready also ASKS, once, in the hall's own dialog. Any way of closing it
|
|
160
|
+
// other than Update now is "later": that version is not asked about again in this browser
|
|
161
|
+
// for a day. The pill stays, so later never means lost.
|
|
162
|
+
function readLater(storage) {
|
|
163
|
+
var l = null;
|
|
164
|
+
try { l = JSON.parse((storage && storage.getItem(LATER_KEY)) || 'null'); } catch (e) { l = null; }
|
|
165
|
+
return l && isVersion(l.v) && isFinite(l.at) ? l : null;
|
|
166
|
+
}
|
|
167
|
+
function keepLater(storage, version, now) {
|
|
168
|
+
try { if (storage && isVersion(version)) storage.setItem(LATER_KEY, JSON.stringify({ v: version, at: now })); } catch (e) { /* it asks again next page */ }
|
|
169
|
+
}
|
|
170
|
+
/** Whether the pop-up opens: only for an update that is ready, and not for a version the
|
|
171
|
+
* owner already said "later" to inside the last day. A newer version asks again at once. */
|
|
172
|
+
function askDue(o) {
|
|
173
|
+
if (!o || o.face !== 'ready' || !isVersion(o.offered)) return false;
|
|
174
|
+
var l = o.later;
|
|
175
|
+
if (l && l.v === o.offered && o.now >= l.at && o.now - l.at < LATER_MS) return false;
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
|
|
155
179
|
// ---------- the page half ----------
|
|
156
180
|
|
|
157
181
|
var state = {
|
|
158
182
|
api: null, update: null, held: null, sw: null, swAsked: null, swError: null, ended: null, note: null,
|
|
159
183
|
face: 'none', stage: null, run: null, error: null, pill: null, card: null,
|
|
160
|
-
popup: null, plan: null, offered: null, looks: 0, timer: null, popupTimer: null, listening: false,
|
|
184
|
+
popup: null, plan: null, offered: null, asked: false, looks: 0, timer: null, popupTimer: null, listening: false,
|
|
161
185
|
};
|
|
162
186
|
|
|
163
187
|
function doc() { return root && root.document; }
|
|
@@ -316,7 +340,7 @@
|
|
|
316
340
|
d.body.appendChild(c);
|
|
317
341
|
state.card = c;
|
|
318
342
|
if (root.addEventListener) root.addEventListener('resize', function () { if (state.card && !state.card.hidden) placeCard(); });
|
|
319
|
-
d.addEventListener('keydown', function (e) { if (e.key === 'Escape' && state.card && !state.card.hidden) { closeCard(); if (state.pill) state.pill.focus(); } });
|
|
343
|
+
d.addEventListener('keydown', function (e) { if (e.key === 'Escape' && state.card && !state.card.hidden) { e.preventDefault(); closeCard(); if (state.pill) state.pill.focus(); } }); // spent: ADR 0399 §2.4, task 1005144
|
|
320
344
|
d.addEventListener('click', function (e) {
|
|
321
345
|
if (!state.card || state.card.hidden) return;
|
|
322
346
|
var t = e.target;
|
|
@@ -556,6 +580,69 @@
|
|
|
556
580
|
if (root.location && root.location.reload) root.location.reload();
|
|
557
581
|
}
|
|
558
582
|
|
|
583
|
+
// ---------- the pop-up ----------
|
|
584
|
+
|
|
585
|
+
// Not in the hub's handoff window, not on the update door itself, and not over the setup
|
|
586
|
+
// screen: each of those is already the thing the owner is doing.
|
|
587
|
+
function askAllowed() {
|
|
588
|
+
var d = doc();
|
|
589
|
+
if (!d || !root.OTBDialog || typeof root.OTBDialog.open !== 'function' || state.asked) return false;
|
|
590
|
+
var el = d.documentElement;
|
|
591
|
+
if (el && el.dataset && el.dataset.handoff === 'on') return false;
|
|
592
|
+
if (root.OTBSetupGate) return false;
|
|
593
|
+
return !(root.location && root.location.pathname === '/deploy');
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function askBodyHtml(plan) {
|
|
597
|
+
var u = state.update || {};
|
|
598
|
+
var h = highlights((state.sw.update || {}).whats_new, HIGHLIGHTS);
|
|
599
|
+
var list = h.lines.length ? '<ul class="upd-card__list">' + h.lines.map(function (l) { return '<li>' + esc(l) + '</li>'; }).join('') + '</ul>' : '';
|
|
600
|
+
var note = plan.kind === 'cli'
|
|
601
|
+
? 'This project is updated on the server that runs it: <code>bongos upgrade</code> there takes this version, and puts the old one back if it fails.'
|
|
602
|
+
: 'Takes a few minutes. The project restarts once, and goes back to the version it runs now on its own if the new one is not healthy.';
|
|
603
|
+
var versions = isVersion(u.running) && isVersion(state.offered) ? '<p class="upd-card__ver">' + mono(u.running) + ' → ' + mono(state.offered) + '</p>' : '';
|
|
604
|
+
return '<p>A newer version of Bongos is ready, with the latest changes and bug fixes.</p>' + list +
|
|
605
|
+
'<p class="upd-card__note">' + note + '</p>' + versions;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Asked from the same reading the card uses, so the pop-up and the card name one version
|
|
609
|
+
// and the two-step rule holds: the pop-up shows the version, Update now sends that one.
|
|
610
|
+
function maybeAsk() {
|
|
611
|
+
if (!askAllowed() || !askDue({ face: state.face, offered: state.offered, later: readLater(store()), now: now() })) return;
|
|
612
|
+
var read = readSoftwareUpdate();
|
|
613
|
+
if (!read) { ask(); return; }
|
|
614
|
+
read.then(ask);
|
|
615
|
+
}
|
|
616
|
+
function ask() {
|
|
617
|
+
if (!state.sw || !askAllowed() || !askDue({ face: state.face, offered: state.offered, later: readLater(store()), now: now() })) return;
|
|
618
|
+
var plan = doorPlan(state.sw);
|
|
619
|
+
if (plan.kind === 'none') return; // a viewer the door would refuse is not asked
|
|
620
|
+
var d = doc();
|
|
621
|
+
var body = d.createElement('div');
|
|
622
|
+
body.className = 'upd-ask';
|
|
623
|
+
body.innerHTML = askBodyHtml(plan);
|
|
624
|
+
var canGo = plan.kind === 'local' || plan.kind === 'hub';
|
|
625
|
+
var offered = state.offered;
|
|
626
|
+
var actions = canGo
|
|
627
|
+
? [{ label: 'Later', value: 'later', kind: 'ghost' }, { label: 'Update now', value: 'go' }]
|
|
628
|
+
: [{ label: 'Close', value: 'later', kind: 'ghost' }];
|
|
629
|
+
state.asked = true;
|
|
630
|
+
var dlg = root.OTBDialog.open({ title: 'Update the builders hall?', body: body, actions: actions, initialFocus: '[data-dialog-value="' + (actions.length - 1) + '"]' });
|
|
631
|
+
// Update now runs inside the press itself: a hosted project opens the hub's window, and
|
|
632
|
+
// a browser allows that only from the click, not from the dialog's settled promise.
|
|
633
|
+
if (canGo && dlg && dlg.el && dlg.el.addEventListener) {
|
|
634
|
+
dlg.el.addEventListener('click', function (e) {
|
|
635
|
+
var t = e && e.target;
|
|
636
|
+
var b = t && t.closest ? t.closest('[data-dialog-value]') : null;
|
|
637
|
+
if (!b || b.getAttribute('data-dialog-value') !== '1') return;
|
|
638
|
+
if (updateNow()) openCard();
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
if (dlg && dlg.result && dlg.result.then) {
|
|
642
|
+
dlg.result.then(function (v) { if (v !== 'go') keepLater(store(), offered, now()); });
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
559
646
|
/** shell.js hands over GET /core-update's answer; the pill decides what, if anything, to show. */
|
|
560
647
|
function mount(data, opts) {
|
|
561
648
|
state.api = opts && opts.api;
|
|
@@ -575,6 +662,7 @@
|
|
|
575
662
|
state.face = face;
|
|
576
663
|
drawPill();
|
|
577
664
|
if (face === 'running') schedule();
|
|
665
|
+
if (face === 'ready') maybeAsk();
|
|
578
666
|
return face;
|
|
579
667
|
}
|
|
580
668
|
|
|
@@ -590,6 +678,7 @@
|
|
|
590
678
|
// the pure half, for the tests
|
|
591
679
|
highlights: highlights, doorPlan: doorPlan, pillState: pillState, stageOf: stageOf,
|
|
592
680
|
readRun: readRun, keepRun: keepRun, forgetRun: forgetRun, isVersion: isVersion,
|
|
681
|
+
askDue: askDue, readLater: readLater, keepLater: keepLater, LATER_KEY: LATER_KEY, LATER_MS: LATER_MS,
|
|
593
682
|
RUN_KEY: RUN_KEY, MSG: MSG, SLOW_MS: SLOW_MS, GIVE_UP_MS: GIVE_UP_MS,
|
|
594
683
|
_state: state,
|
|
595
684
|
};
|