@litfamily/litopencode 1.0.7 → 1.0.9
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/CHANGELOG.md +18 -0
- package/README-Ko-KR.md +314 -31
- package/README.md +312 -29
- package/dist/activation-primary-prompts.d.ts +1 -0
- package/dist/activation-primary-prompts.js +16 -0
- package/dist/activation-probe.js +4 -1
- package/dist/activation-prompt-utils.d.ts +1 -1
- package/dist/activation-routing.d.ts +6 -1
- package/dist/activation-routing.js +174 -16
- package/dist/activation-workflow-prompts.d.ts +1 -1
- package/dist/activation-workflow-prompts.js +18 -17
- package/dist/activation.d.ts +3 -2
- package/dist/activation.js +6 -6
- package/dist/agents/defaults.js +14 -6
- package/dist/cli/command-aliases.js +24 -22
- package/dist/cli/doctor.js +3 -0
- package/dist/cli/install-report.d.ts +1 -0
- package/dist/cli/install-report.js +4 -0
- package/dist/cli/install.js +7 -4
- package/dist/cli/managed-skill-assets.d.ts +1 -1
- package/dist/cli/managed-skill-assets.js +15 -5
- package/dist/cli/motion-runtime.d.ts +6 -0
- package/dist/cli/motion-runtime.js +46 -0
- package/dist/cli/native-skill-install.js +32 -9
- package/dist/cli/native-skill-integrity.js +1 -0
- package/dist/cli/native-skills.d.ts +2 -0
- package/dist/cli/native-skills.js +2 -1
- package/dist/cli/office-dependencies.d.ts +14 -0
- package/dist/cli/office-dependencies.js +24 -0
- package/dist/cli.js +13 -3
- package/dist/commands.d.ts +2 -11
- package/dist/commands.js +9 -17
- package/dist/deliverable-hedge-guard.d.ts +20 -21
- package/dist/deliverable-hedge-guard.js +234 -275
- package/dist/features.d.ts +81 -2
- package/dist/features.js +80 -13
- package/dist/hooks.d.ts +3 -2
- package/dist/hooks.js +4 -4
- package/dist/ignition.d.ts +1 -1
- package/dist/ignition.js +15 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/interface-handoff.d.ts +1 -0
- package/dist/interface-handoff.js +1 -0
- package/dist/motion-image-reads.d.ts +6 -0
- package/dist/motion-image-reads.js +46 -0
- package/dist/server.js +13 -11
- package/dist/skill-renames.d.ts +4 -2
- package/dist/skill-renames.js +12 -4
- package/dist/skills.d.ts +31 -3
- package/dist/skills.js +53 -9
- package/dist/tools.js +4 -4
- package/docs/ab/S11/baseline-desktop.webp +0 -0
- package/docs/ab/S11/baseline-phone.webp +0 -0
- package/docs/ab/S11/lit-desktop.webp +0 -0
- package/docs/ab/S11/lit-phone.webp +0 -0
- package/docs/ab/S3/baseline-desktop.webp +0 -0
- package/docs/ab/S3/baseline-phone.webp +0 -0
- package/docs/ab/S3/lit-desktop.webp +0 -0
- package/docs/ab/S3/lit-phone.webp +0 -0
- package/docs/ab/S4/baseline-desktop.webp +0 -0
- package/docs/ab/S4/baseline-phone.webp +0 -0
- package/docs/ab/S4/lit-desktop.webp +0 -0
- package/docs/ab/S4/lit-phone.webp +0 -0
- package/docs/ab/S5/lit-slides.webp +0 -0
- package/docs/ab/S7/lit-diagram.webp +0 -0
- package/docs/ab/S8/baseline-slides.webp +0 -0
- package/docs/ab/S8/lit-slides.webp +0 -0
- package/docs/ab/S9/lit-pages.webp +0 -0
- package/docs/assets/cover-motion-still.webp +0 -0
- package/docs/assets/cover-motion.webp +0 -0
- package/docs/assets/readme/badge-version.svg +1 -1
- package/docs/assets/skills/autoconference.webp +0 -0
- package/docs/assets/skills/automatic-guards.webp +0 -0
- package/docs/assets/skills/autoresearch.webp +0 -0
- package/docs/assets/skills/browser-drive.webp +0 -0
- package/docs/assets/skills/debugging.webp +0 -0
- package/docs/assets/skills/deep-interview.webp +0 -0
- package/docs/assets/skills/doctor-installer.webp +0 -0
- package/docs/assets/skills/durable-litgoal.webp +0 -0
- package/docs/assets/skills/frontend-ui-ux.webp +0 -0
- package/docs/assets/skills/lit-burnoff-file.webp +0 -0
- package/docs/assets/skills/lit-burnoff.webp +0 -0
- package/docs/assets/skills/lit-code.webp +0 -0
- package/docs/assets/skills/lit-commit.webp +0 -0
- package/docs/assets/skills/lit-comprehend.webp +0 -0
- package/docs/assets/skills/lit-crucible.webp +0 -0
- package/docs/assets/skills/lit-diagram-drawer.webp +0 -0
- package/docs/assets/skills/lit-docx.webp +0 -0
- package/docs/assets/skills/lit-fetch.webp +0 -0
- package/docs/assets/skills/lit-handoff.webp +0 -0
- package/docs/assets/skills/lit-humanizer.webp +0 -0
- package/docs/assets/skills/lit-init.webp +0 -0
- package/docs/assets/skills/lit-plan.webp +0 -0
- package/docs/assets/skills/lit-pptx.webp +0 -0
- package/docs/assets/skills/lit-recap.webp +0 -0
- package/docs/assets/skills/lit-scientific-visualization.webp +0 -0
- package/docs/assets/skills/lit-typographic-motion.webp +0 -0
- package/docs/assets/skills/litresearch.webp +0 -0
- package/docs/assets/skills/litwork.webp +0 -0
- package/docs/assets/skills/lsp-setup.webp +0 -0
- package/docs/assets/skills/lsp.webp +0 -0
- package/docs/assets/skills/readme-studio.webp +0 -0
- package/docs/assets/skills/refactor.webp +0 -0
- package/docs/assets/skills/review-work.webp +0 -0
- package/docs/assets/skills/rules.webp +0 -0
- package/docs/assets/skills/start-work.webp +0 -0
- package/docs/assets/skills/structural-search.webp +0 -0
- package/docs/assets/skills/visual-qa.webp +0 -0
- package/docs/assets/skills/wikify.webp +0 -0
- package/docs/reference-Ko-KR.md +5 -1
- package/docs/reference.md +6 -2
- package/package.json +1 -1
- package/rules/bundled-rules/lit-humanizer.md +12 -0
- package/skills/autoconference/SKILL.md +1 -1
- package/skills/autoconference/assets/report_template.md +1 -1
- package/skills/autoresearch/references/type-checklists.md +1 -1
- package/skills/browser-drive/SKILL.md +19 -5
- package/skills/browser-drive/scripts/capability-probe.mjs +26 -5
- package/skills/frontend-ui-ux/SKILL.md +10 -15
- package/skills/frontend-ui-ux/data/THIRD-PARTY-NOTICE.txt +10 -0
- package/skills/frontend-ui-ux/references/adaptive-layout.md +3 -11
- package/skills/frontend-ui-ux/references/brand-and-imagery.md +6 -11
- package/skills/frontend-ui-ux/references/complete-contract.md +10 -3
- package/skills/frontend-ui-ux/references/composition.md +1 -7
- package/skills/frontend-ui-ux/references/craft-floor.md +94 -0
- package/skills/frontend-ui-ux/references/creative-directions.md +1 -7
- package/skills/frontend-ui-ux/references/evidence-review.md +2 -12
- package/skills/frontend-ui-ux/references/implementation-platforms.md +1 -4
- package/skills/frontend-ui-ux/references/inclusive-interface.md +1 -3
- package/skills/frontend-ui-ux/references/interaction-motion.md +1 -7
- package/skills/frontend-ui-ux/references/motion-guide.md +125 -0
- package/skills/frontend-ui-ux/references/operating-lanes.md +2 -8
- package/skills/frontend-ui-ux/references/product-direction.md +1 -6
- package/skills/frontend-ui-ux/references/production.md +12 -5
- package/skills/frontend-ui-ux/references/redesign-playbook.md +1 -7
- package/skills/frontend-ui-ux/references/slop-register.md +103 -0
- package/skills/frontend-ui-ux/references/system-foundations.md +1 -8
- package/skills/frontend-ui-ux/references/taste-direction.md +4 -11
- package/skills/frontend-ui-ux/references/visual-language.md +1 -6
- package/skills/frontend-ui-ux/references/visual-reconstruction.md +2 -7
- package/skills/frontend-ui-ux/scripts/probe-page.mjs +326 -0
- package/skills/frontend-ui-ux/scripts/probe-server.mjs +24 -0
- package/skills/frontend-ui-ux/scripts/probe-static.mjs +42 -0
- package/skills/frontend-ui-ux/scripts/probe-thresholds.json +86 -0
- package/skills/frontend-ui-ux/scripts/probe.mjs +183 -0
- package/skills/lit-comprehend/SKILL.md +10 -11
- package/skills/lit-comprehend/references/artifact-template.md +2 -18
- package/skills/lit-comprehend/scripts/verify-explainer.ts +0 -14
- package/skills/lit-diagram-drawer/NOTICE.md +33 -0
- package/skills/lit-diagram-drawer/SKILL.md +101 -0
- package/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
- package/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
- package/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
- package/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
- package/skills/lit-diagram-drawer/assets/fonts/provenance.json +23 -0
- package/skills/lit-diagram-drawer/assets/icons.html +231 -0
- package/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
- package/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
- package/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
- package/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
- package/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
- package/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
- package/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
- package/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
- package/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
- package/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
- package/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
- package/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
- package/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
- package/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
- package/skills/lit-diagram-drawer/references/accessibility.md +37 -0
- package/skills/lit-diagram-drawer/references/export.md +17 -0
- package/skills/lit-diagram-drawer/references/import-drawio.md +13 -0
- package/skills/lit-diagram-drawer/references/import-excalidraw.md +11 -0
- package/skills/lit-diagram-drawer/references/import-mermaid.md +12 -0
- package/skills/lit-diagram-drawer/references/import-schema.md +28 -0
- package/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
- package/skills/lit-diagram-drawer/references/motion.md +29 -0
- package/skills/lit-diagram-drawer/references/office-pptx-docx.md +28 -0
- package/skills/lit-diagram-drawer/references/output-spec.md +48 -0
- package/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
- package/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
- package/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
- package/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
- package/skills/lit-diagram-drawer/references/profiles.md +24 -0
- package/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
- package/skills/lit-diagram-drawer/references/style-guide.md +67 -0
- package/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
- package/skills/lit-diagram-drawer/references/type-bar.md +51 -0
- package/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
- package/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
- package/skills/lit-diagram-drawer/references/type-bump.md +49 -0
- package/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
- package/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
- package/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
- package/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
- package/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
- package/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
- package/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
- package/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
- package/skills/lit-diagram-drawer/references/type-er.md +49 -0
- package/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
- package/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
- package/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
- package/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
- package/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
- package/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
- package/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
- package/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
- package/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
- package/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
- package/skills/lit-diagram-drawer/references/type-journey.md +54 -0
- package/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
- package/skills/lit-diagram-drawer/references/type-layers.md +54 -0
- package/skills/lit-diagram-drawer/references/type-line.md +54 -0
- package/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
- package/skills/lit-diagram-drawer/references/type-loop.md +54 -0
- package/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
- package/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
- package/skills/lit-diagram-drawer/references/type-nested.md +59 -0
- package/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
- package/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
- package/skills/lit-diagram-drawer/references/type-polar.md +67 -0
- package/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
- package/skills/lit-diagram-drawer/references/type-process.md +58 -0
- package/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
- package/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
- package/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
- package/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
- package/skills/lit-diagram-drawer/references/type-radar.md +57 -0
- package/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
- package/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
- package/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
- package/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
- package/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
- package/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
- package/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
- package/skills/lit-diagram-drawer/references/type-state.md +59 -0
- package/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
- package/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
- package/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
- package/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
- package/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
- package/skills/lit-diagram-drawer/references/type-tree.md +54 -0
- package/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
- package/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
- package/skills/lit-diagram-drawer/references/type-venn.md +51 -0
- package/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
- package/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
- package/skills/lit-diagram-drawer/references/verifier-guide.md +59 -0
- package/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
- package/skills/lit-diagram-drawer/scripts/brief-contract.mjs +94 -0
- package/skills/lit-diagram-drawer/scripts/capability-probe.mjs +132 -0
- package/skills/lit-diagram-drawer/scripts/check-visible-text.mjs +15 -0
- package/skills/lit-diagram-drawer/scripts/craft-thresholds.json +15 -0
- package/skills/lit-diagram-drawer/scripts/diagram-metrics.mjs +216 -0
- package/skills/lit-diagram-drawer/scripts/doctor.mjs +8 -0
- package/skills/lit-diagram-drawer/scripts/drawio-extract.mjs +214 -0
- package/skills/lit-diagram-drawer/scripts/excalidraw-extract.mjs +151 -0
- package/skills/lit-diagram-drawer/scripts/export.mjs +133 -0
- package/skills/lit-diagram-drawer/scripts/import-shared.mjs +130 -0
- package/skills/lit-diagram-drawer/scripts/mermaid-extract.mjs +173 -0
- package/skills/lit-diagram-drawer/scripts/office-safety.mjs +120 -0
- package/skills/lit-diagram-drawer/scripts/renderer-safety.mjs +46 -0
- package/skills/lit-diagram-drawer/scripts/test-block-registry.mjs +20 -0
- package/skills/lit-diagram-drawer/scripts/test-brief-contract.mjs +27 -0
- package/skills/lit-diagram-drawer/scripts/test-importers.mjs +119 -0
- package/skills/lit-diagram-drawer/scripts/test-office-safety.mjs +67 -0
- package/skills/lit-diagram-drawer/scripts/test-sequence-verifier.mjs +28 -0
- package/skills/lit-diagram-drawer/scripts/test-visual-quality.mjs +68 -0
- package/skills/lit-diagram-drawer/scripts/verify-all.mjs +74 -0
- package/skills/lit-diagram-drawer/scripts/verify-brief.mjs +47 -0
- package/skills/lit-diagram-drawer/scripts/verify-coverage.mjs +56 -0
- package/skills/lit-diagram-drawer/scripts/verify-diagram.mjs +26 -0
- package/skills/lit-diagram-drawer/scripts/verify-motion.mjs +12 -0
- package/skills/lit-diagram-drawer/scripts/verify-type.mjs +48 -0
- package/skills/lit-diagram-drawer/scripts/visual-quality.mjs +363 -0
- package/skills/lit-docx/LICENSE-MIT.txt +21 -0
- package/skills/lit-docx/SKILL.md +78 -0
- package/skills/lit-docx/references/frontmatter_schema.md +42 -0
- package/skills/lit-docx/references/journal_style_spec.md +17 -0
- package/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
- package/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
- package/skills/lit-docx/references/slop_rules.md +35 -0
- package/skills/lit-docx/requirements.in +5 -0
- package/skills/lit-docx/requirements.lock +289 -0
- package/skills/lit-docx/run.py +64 -0
- package/skills/lit-docx/scripts/clean_markdown.py +95 -0
- package/skills/lit-docx/scripts/convert_md_to_docx.py +1047 -0
- package/skills/lit-docx/scripts/convert_md_to_pdf.py +281 -0
- package/skills/lit-docx/scripts/convert_pdf.py +130 -0
- package/skills/lit-docx/scripts/craft-thresholds.json +11 -0
- package/skills/lit-docx/scripts/craft_docx.py +83 -0
- package/skills/lit-docx/scripts/edit_docx.py +297 -0
- package/skills/lit-docx/scripts/embed_images.py +78 -0
- package/skills/lit-docx/scripts/generate_docx_templates.py +491 -0
- package/skills/lit-docx/scripts/slop_lint.py +485 -0
- package/skills/lit-docx/scripts/visual_audit.py +41 -0
- package/skills/lit-docx/templates/docx/acs.docx +0 -0
- package/skills/lit-docx/templates/docx/elsevier.docx +0 -0
- package/skills/lit-docx/templates/docx/ieee.docx +0 -0
- package/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
- package/skills/lit-docx/templates/docx/nature.docx +0 -0
- package/skills/lit-docx/templates/latex/acs/README.md +5 -0
- package/skills/lit-docx/templates/latex/acs/template.tex +37 -0
- package/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
- package/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
- package/skills/lit-docx/templates/latex/ieee/README.md +5 -0
- package/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
- package/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
- package/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
- package/skills/lit-docx/templates/latex/nature/README.md +5 -0
- package/skills/lit-docx/templates/latex/nature/template.tex +37 -0
- package/skills/lit-docx/templates/registry.yaml +1366 -0
- package/skills/lit-humanizer/NOTICE +160 -0
- package/skills/lit-humanizer/SKILL.md +122 -0
- package/skills/lit-humanizer/assets/always-on-rule.md +9 -0
- package/skills/lit-humanizer/assets/report-skeleton.md +25 -0
- package/skills/lit-humanizer/assets/slide-text-skeleton.md +28 -0
- package/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
- package/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
- package/skills/lit-humanizer/examples/api-reference/after.md +9 -0
- package/skills/lit-humanizer/examples/api-reference/before.md +15 -0
- package/skills/lit-humanizer/examples/changelog/after.md +5 -0
- package/skills/lit-humanizer/examples/changelog/before.md +12 -0
- package/skills/lit-humanizer/examples/code-comments/after.md +10 -0
- package/skills/lit-humanizer/examples/code-comments/before.md +19 -0
- package/skills/lit-humanizer/examples/commit/after.md +5 -0
- package/skills/lit-humanizer/examples/commit/before.md +7 -0
- package/skills/lit-humanizer/examples/data-release/after.md +7 -0
- package/skills/lit-humanizer/examples/data-release/before.md +9 -0
- package/skills/lit-humanizer/examples/english-essay/after.md +5 -0
- package/skills/lit-humanizer/examples/english-essay/before.md +5 -0
- package/skills/lit-humanizer/examples/incident-update/after.md +7 -0
- package/skills/lit-humanizer/examples/incident-update/before.md +7 -0
- package/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
- package/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
- package/skills/lit-humanizer/examples/ko-report/after.md +9 -0
- package/skills/lit-humanizer/examples/ko-report/before.md +13 -0
- package/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
- package/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
- package/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
- package/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
- package/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
- package/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
- package/skills/lit-humanizer/examples/pr/after.md +15 -0
- package/skills/lit-humanizer/examples/pr/before.md +17 -0
- package/skills/lit-humanizer/examples/project-update/after.md +7 -0
- package/skills/lit-humanizer/examples/project-update/before.md +9 -0
- package/skills/lit-humanizer/examples/readme/after.md +12 -0
- package/skills/lit-humanizer/examples/readme/before.md +14 -0
- package/skills/lit-humanizer/examples/report/after.md +13 -0
- package/skills/lit-humanizer/examples/report/before.md +11 -0
- package/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
- package/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
- package/skills/lit-humanizer/examples/slides/after.md +19 -0
- package/skills/lit-humanizer/examples/slides/before.md +19 -0
- package/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
- package/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
- package/skills/lit-humanizer/fixtures/ko-metrics-golden.json +49 -0
- package/skills/lit-humanizer/fixtures/office/minimal.docx +0 -0
- package/skills/lit-humanizer/fixtures/office/minimal.pptx +0 -0
- package/skills/lit-humanizer/fixtures/pos-real.txt +26 -0
- package/skills/lit-humanizer/fixtures/rule-cases.json +306 -0
- package/skills/lit-humanizer/references/code-patterns.md +468 -0
- package/skills/lit-humanizer/references/deliverable-channels.md +111 -0
- package/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
- package/skills/lit-humanizer/references/en-patterns-content.md +243 -0
- package/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
- package/skills/lit-humanizer/references/en-patterns.md +57 -0
- package/skills/lit-humanizer/references/ko-metrics.md +33 -0
- package/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
- package/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
- package/skills/lit-humanizer/references/ko-patterns.md +31 -0
- package/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
- package/skills/lit-humanizer/references/taxonomy.md +153 -0
- package/skills/lit-humanizer/rules.json +884 -0
- package/skills/lit-humanizer/scripts/core.mjs +208 -0
- package/skills/lit-humanizer/scripts/detect.mjs +91 -0
- package/skills/lit-humanizer/scripts/extract_office_text.py +89 -0
- package/skills/lit-humanizer/scripts/guard-scan.mjs +36 -0
- package/skills/lit-humanizer/scripts/ko-metrics.mjs +124 -0
- package/skills/lit-humanizer/scripts/test-fixtures.mjs +54 -0
- package/skills/lit-humanizer/scripts/test-ko-metrics.mjs +27 -0
- package/skills/lit-pptx/FORBIDDEN_TERMS.json +55 -0
- package/skills/lit-pptx/NOTICE.md +3 -0
- package/skills/lit-pptx/SKILL.md +76 -0
- package/skills/lit-pptx/agents/analyst.md +49 -0
- package/skills/lit-pptx/agents/antithesis.md +59 -0
- package/skills/lit-pptx/agents/architect.md +44 -0
- package/skills/lit-pptx/agents/critic.md +42 -0
- package/skills/lit-pptx/agents/synthesizer.md +47 -0
- package/skills/lit-pptx/agents/thesis.md +33 -0
- package/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
- package/skills/lit-pptx/assets/azure/circle-md.png +0 -0
- package/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
- package/skills/lit-pptx/fonts/a2z-font/A2Z-Black.otf +0 -0
- package/skills/lit-pptx/fonts/a2z-font/A2Z-Bold.otf +0 -0
- package/skills/lit-pptx/fonts/a2z-font/A2Z-Light.otf +0 -0
- package/skills/lit-pptx/fonts/a2z-font/A2Z-Medium.otf +0 -0
- package/skills/lit-pptx/fonts/a2z-font/A2Z-Regular.otf +0 -0
- package/skills/lit-pptx/fonts/a2z-font/OFL.txt +94 -0
- package/skills/lit-pptx/fonts/a2z-font/SOURCE.md +29 -0
- package/skills/lit-pptx/package-lock.json +747 -0
- package/skills/lit-pptx/package.json +13 -0
- package/skills/lit-pptx/pretendard-font/LICENSE.txt +94 -0
- package/skills/lit-pptx/pretendard-font/public/static/LitOpenCodeSans-Bold.otf +0 -0
- package/skills/lit-pptx/pretendard-font/public/static/LitOpenCodeSans-Regular.otf +0 -0
- package/skills/lit-pptx/requirements.in +2 -0
- package/skills/lit-pptx/requirements.lock +285 -0
- package/skills/lit-pptx/run.mjs +71 -0
- package/skills/lit-pptx/scripts/check_ooxml.py +47 -0
- package/skills/lit-pptx/scripts/compile-deck.js +447 -0
- package/skills/lit-pptx/scripts/craft-thresholds.json +26 -0
- package/skills/lit-pptx/scripts/craft_extras.py +224 -0
- package/skills/lit-pptx/scripts/embed_fonts.py +204 -0
- package/skills/lit-pptx/scripts/layout_inventory.py +70 -0
- package/skills/lit-pptx/scripts/learn_template.py +433 -0
- package/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
- package/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
- package/skills/lit-pptx/scripts/lib/font-map.js +79 -0
- package/skills/lit-pptx/scripts/lib/gen-bg.js +85 -0
- package/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +36 -0
- package/skills/lit-pptx/scripts/lib/layout-resolver.js +737 -0
- package/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
- package/skills/lit-pptx/scripts/lib/render-adapter-html.js +364 -0
- package/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +1848 -0
- package/skills/lit-pptx/scripts/lib/slide-ast.js +534 -0
- package/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
- package/skills/lit-pptx/scripts/lib/template-registry.js +355 -0
- package/skills/lit-pptx/scripts/qa_deck.py +773 -0
- package/skills/lit-pptx/scripts/validate_pptx.py +206 -0
- package/skills/lit-pptx/specs/markdown-slide-spec-v1.md +251 -0
- package/skills/lit-pptx/specs/markdown-slide-spec-v2.md +223 -0
- package/skills/lit-pptx/specs/slide-ast-v1.schema.json +229 -0
- package/skills/lit-pptx/specs/slide-ast-v2.schema.json +144 -0
- package/skills/lit-pptx/specs/template-enrollment-contract.md +379 -0
- package/skills/lit-pptx/templates/bauhaus_light.css +4 -0
- package/skills/lit-pptx/templates/boilerplate_professional.css +508 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +454 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +483 -0
- package/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
- package/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
- package/skills/lit-scientific-visualization/SKILL.md +2 -0
- package/skills/lit-typographic-motion/NOTICE +23 -0
- package/skills/lit-typographic-motion/SKILL.md +77 -0
- package/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +25 -0
- package/skills/lit-typographic-motion/audio-analysis.py +52 -0
- package/skills/lit-typographic-motion/engine/browser.mjs +83 -0
- package/skills/lit-typographic-motion/engine/constants.mjs +177 -0
- package/skills/lit-typographic-motion/engine/contrast.mjs +101 -0
- package/skills/lit-typographic-motion/engine/encode.mjs +46 -0
- package/skills/lit-typographic-motion/engine/flash.mjs +216 -0
- package/skills/lit-typographic-motion/engine/look.mjs +166 -0
- package/skills/lit-typographic-motion/engine/page/common.js +105 -0
- package/skills/lit-typographic-motion/engine/page/engine.js +451 -0
- package/skills/lit-typographic-motion/engine/page/gl.js +213 -0
- package/skills/lit-typographic-motion/engine/page/lines.js +88 -0
- package/skills/lit-typographic-motion/engine/page/passes.js +144 -0
- package/skills/lit-typographic-motion/engine/page/post.js +119 -0
- package/skills/lit-typographic-motion/engine/page/scenes.js +187 -0
- package/skills/lit-typographic-motion/engine/page/type.js +321 -0
- package/skills/lit-typographic-motion/engine/png.mjs +139 -0
- package/skills/lit-typographic-motion/engine/sound.mjs +291 -0
- package/skills/lit-typographic-motion/engine/stage/capture.mjs +133 -0
- package/skills/lit-typographic-motion/engine/stage/clock.js +171 -0
- package/skills/lit-typographic-motion/engine/stage/frame-worker.mjs +47 -0
- package/skills/lit-typographic-motion/engine/stage/gate.mjs +119 -0
- package/skills/lit-typographic-motion/engine/stage/qa-page.js +158 -0
- package/skills/lit-typographic-motion/engine/stage/qa.mjs +208 -0
- package/skills/lit-typographic-motion/engine/stage/render.mjs +418 -0
- package/skills/lit-typographic-motion/engine/stage/scan.mjs +162 -0
- package/skills/lit-typographic-motion/engine/stage/stage-kit.js +310 -0
- package/skills/lit-typographic-motion/engine/stills.mjs +60 -0
- package/skills/lit-typographic-motion/engine/text.mjs +126 -0
- package/skills/lit-typographic-motion/engine/timing.mjs +289 -0
- package/skills/lit-typographic-motion/engine/treatment.mjs +254 -0
- package/skills/lit-typographic-motion/fonts/Archivo-100-400.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-100-700.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-100-900.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-125-400.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-125-700.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-125-900.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-75-400.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-75-700.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-75-900.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Archivo-OFL.txt +93 -0
- package/skills/lit-typographic-motion/fonts/Silkscreen-Bold.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/Silkscreen-OFL.txt +93 -0
- package/skills/lit-typographic-motion/fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/VT323-OFL.txt +93 -0
- package/skills/lit-typographic-motion/fonts/VT323-Regular.ttf +0 -0
- package/skills/lit-typographic-motion/fonts/pins.json +44 -0
- package/skills/lit-typographic-motion/fonts/stroke/CREDITS +52 -0
- package/skills/lit-typographic-motion/fonts/stroke/EMSAllure.svg +216 -0
- package/skills/lit-typographic-motion/fonts/stroke/EMSFelix.svg +216 -0
- package/skills/lit-typographic-motion/fonts/stroke/EMSOsmotron.svg +216 -0
- package/skills/lit-typographic-motion/fonts/stroke/EMSReadability.svg +216 -0
- package/skills/lit-typographic-motion/fonts/stroke/EMSTech.svg +217 -0
- package/skills/lit-typographic-motion/fonts/stroke/OFL.txt +85 -0
- package/skills/lit-typographic-motion/gate.mjs +593 -0
- package/skills/lit-typographic-motion/package-lock.json +78 -0
- package/skills/lit-typographic-motion/package.json +11 -0
- package/skills/lit-typographic-motion/probe.mjs +74 -0
- package/skills/lit-typographic-motion/references/authoring.md +110 -0
- package/skills/lit-typographic-motion/references/craft-loop.md +110 -0
- package/skills/lit-typographic-motion/references/runtime.md +88 -0
- package/skills/lit-typographic-motion/references/stage.md +164 -0
- package/skills/lit-typographic-motion/references/style-bibles.md +88 -0
- package/skills/lit-typographic-motion/references/treatment.md +143 -0
- package/skills/lit-typographic-motion/references/type-craft.md +55 -0
- package/skills/lit-typographic-motion/render.mjs +654 -0
- package/skills/lit-typographic-motion/requirements-audio.in +1 -0
- package/skills/lit-typographic-motion/requirements-audio.txt +790 -0
- package/skills/lit-typographic-motion/runtime.mjs +259 -0
- package/skills/lit-typographic-motion/word-timing-models.json +25 -0
- package/skills/litresearch/SKILL.md +41 -12
- package/skills/managed-skill-manifest.json +2367 -63
- package/skills/skill-rename-aliases.json +6 -1
- package/tools/check-pack-payload.mjs +22 -1
- package/tools/check-payload-substance.mjs +2 -2
- package/tools/payload-reference-exemptions.json +4 -0
- package/tools/payload-substance-allowlist.json +2 -3
- package/tools/payload-substance-parity.json +7 -7
- package/tools/version-manifests.json +4 -4
- package/skills/lit-korean/SKILL.md +0 -231
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// Every number the motion engine and its gate use lives here. Rows marked [NEW] come from the
|
|
2
|
+
// family spec's own proposed defaults; no user sign-off is recorded for them yet, so they are
|
|
3
|
+
// PROVISIONAL. They are implemented exactly as written and must not be tuned in this wave.
|
|
4
|
+
|
|
5
|
+
export const EXIT = Object.freeze({
|
|
6
|
+
OK: 0,
|
|
7
|
+
BLOCKED_NO_CHROME: 10,
|
|
8
|
+
BLOCKED_NO_WEBGL2: 11,
|
|
9
|
+
BLOCKED_NO_FFMPEG_FOR_VIDEO: 12,
|
|
10
|
+
GATE_FAIL_QA: 13,
|
|
11
|
+
BLOCKED_DEPS_NOT_PREWARMED: 14,
|
|
12
|
+
BLOCKED_FONT_FETCH: 15,
|
|
13
|
+
BLOCKED_TREATMENT_INVALID: 16,
|
|
14
|
+
STAGE_CONTRACT_ERROR: 17,
|
|
15
|
+
STAGE_NONDETERMINISTIC: 18,
|
|
16
|
+
STAGE_NETWORK_REQUEST: 19,
|
|
17
|
+
SOUND_INVALID: 20
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export const FRAME = Object.freeze({ width: 1920, height: 1080, fps: 60 });
|
|
21
|
+
|
|
22
|
+
export const limits = Object.freeze({
|
|
23
|
+
defaultBpm: 100, // MO-A-14
|
|
24
|
+
generatorMargin: 1.25, // MO-A-09/10: Tier-1 pace = 1.25 x the reading floor
|
|
25
|
+
minSceneBeats: 2, // MO-A-16
|
|
26
|
+
beatSnapFrames: 1, // MO-A-15: <= 1 frame at 60 fps
|
|
27
|
+
masterSamples: 4, masterShutter: 0.5, // MO-A-26
|
|
28
|
+
previewSamples: 1, // MO-A-27
|
|
29
|
+
titleSafeX: 96, titleSafeY: 54, // MO-C-04
|
|
30
|
+
actionSafeX: 48, actionSafeY: 27, // MO-C-05 [NEW] provisional
|
|
31
|
+
bodyContrast: 4.5, largeContrast: 3, // MO-C-06
|
|
32
|
+
largeFontPx: 32, largeBoldFontPx: 25, largeBoldWeight: 700, // MO-C-06 [NEW] provisional
|
|
33
|
+
lineFloorLatin: 0.9, lineFloorHangul: 1.0, wordFloor: 0.5, revealFloor: 0.35, // MO-C-07/08 [NEW] provisional
|
|
34
|
+
secondsPerHangulSyllable: 0.2, latinWordsPerSecond: 3.3, latinCharsPerSecond: 17, // MO-C-07/08 [NEW] provisional
|
|
35
|
+
minFps: 30, minDurationSec: 3, warnDurationSec: 90, // MO-C-10..12 (30 fps floor and 3 s floor [NEW] provisional)
|
|
36
|
+
previewMaxBytes: 3 * 1000 * 1000, posterMaxBytes: 1000 * 1000, // MO-C-13 [NEW] provisional
|
|
37
|
+
mp4WarnBytesPer10s: 100 * 1000 * 1000, // MO-C-13 [NEW] provisional
|
|
38
|
+
stillInkRatio: 0.9, // MO-C-14 [NEW] provisional
|
|
39
|
+
displayTrackingFloorEm: -0.04, // MO-C-25 [NEW] provisional
|
|
40
|
+
lineHeightLatin: 1.5, lineHeightCjk: 1.6, lineHeightThreePlus: 1.4, // MO-C-26
|
|
41
|
+
measureMinCh: 60, measureMaxCh: 75, cjkMeasureMinCh: 30, cjkMeasureMaxCh: 45, // MO-C-27
|
|
42
|
+
clusterHueDeg: 15, clusterSaturation: 0.5, clusterMinSidePx: 24, // MO-C-29 [NEW] provisional
|
|
43
|
+
accentMaxEntries: 1, accentMaxFrameFraction: 0.1, // MO-C-29 [NEW] provisional
|
|
44
|
+
realGpuP95Ms: 40, softwareGpuP95Ms: 250, perfFrames: 120, // MO-D-02 [NEW] provisional
|
|
45
|
+
nearBlackLuminance: 0.05, nearBlackQuantile: 0.995, nearBlackFloorMultiple: 2, nearBlackFadeSec: 1, // MO-D-03 [NEW] provisional
|
|
46
|
+
missingGlyphsAllowed: 0, // MO-D-04 [NEW] provisional
|
|
47
|
+
flashLimitGeneral: 3, flashLimitRed: 3, // MO-C-03
|
|
48
|
+
eventsPerSecondPerShot: 2, // MO-SH-03
|
|
49
|
+
glitchHitRateCap: 2.0, glitchAreaCapPct: 20, // MO-SH-05
|
|
50
|
+
surgeRateCap: 2, surgeEdgeFloorSec: 0.1, // MO-SH-06
|
|
51
|
+
crtFlickerCap: 0.06, // MO-SH-07
|
|
52
|
+
maxTerminalLayers: 2, // MO-SH-11
|
|
53
|
+
fullFrameStepDelta: 0.1, fullFrameStepArea: 0.25 // MO-SH-04a
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Rules whose threshold is a [NEW] spec default; the report labels each one provisional.
|
|
57
|
+
export const provisionalRules = Object.freeze([
|
|
58
|
+
"MO-C-05", "MO-C-06", "MO-C-07", "MO-C-08", "MO-C-13", "MO-C-14", "MO-C-25", "MO-C-29",
|
|
59
|
+
"MO-D-02", "MO-D-03", "MO-D-04"
|
|
60
|
+
]);
|
|
61
|
+
|
|
62
|
+
// MO-C-03 flash audit geometry (logical px at 1920x1080).
|
|
63
|
+
export const flashGeometry = Object.freeze({
|
|
64
|
+
gridW: 320, gridH: 180, cellPx: 6,
|
|
65
|
+
windowCellsW: 107, windowCellsH: 60, // 640x360 logical px, a 10-degree field
|
|
66
|
+
areaFraction: 0.25, // more than 25% of one window (> 57,600 px)
|
|
67
|
+
deltaL: 0.1, darkerBelow: 0.8,
|
|
68
|
+
redRatio: 0.8, redScale: 320, redDelta: 20,
|
|
69
|
+
historyFrames: 3 // cells registered in frames [f-2, f]
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// MO-SH-09: the one canonical software-rasterizer list.
|
|
73
|
+
export const softwareRendererNames = Object.freeze([
|
|
74
|
+
"swiftshader", "llvmpipe", "softpipe", "lavapipe", "apple software renderer", "microsoft basic render driver"
|
|
75
|
+
]);
|
|
76
|
+
export const unknownRenderer = "unknown (debug-info extension unavailable)";
|
|
77
|
+
export function isSoftwareRenderer(name) {
|
|
78
|
+
const lower = String(name ?? "").toLowerCase();
|
|
79
|
+
return softwareRendererNames.some((part) => lower.includes(part));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// MO-A-51: per-platform GPU rung, then the SwiftShader rung; anti-throttling flags always appended.
|
|
83
|
+
export const alwaysChromeFlags = Object.freeze([
|
|
84
|
+
"--disable-background-timer-throttling", "--disable-renderer-backgrounding", "--disable-backgrounding-occluded-windows"
|
|
85
|
+
]);
|
|
86
|
+
// Every launch also carries these two, so headless Chrome under a custom profile or an isolated HOME
|
|
87
|
+
// never asks the macOS keychain for its safe-storage item (that request raises a dialog on the
|
|
88
|
+
// user's screen). The engine stores no credentials, so a mock keychain loses nothing.
|
|
89
|
+
export const keychainChromeFlags = Object.freeze(["--use-mock-keychain", "--password-store=basic"]);
|
|
90
|
+
export function chromeFlagRungs(platform = process.platform) {
|
|
91
|
+
const native = platform === "darwin" ? ["--use-angle=metal", "--enable-gpu-rasterization", "--ignore-gpu-blocklist"]
|
|
92
|
+
: platform === "win32" ? ["--use-angle=d3d11", "--enable-gpu-rasterization"]
|
|
93
|
+
: ["--use-angle=gl", "--enable-gpu-rasterization", "--ignore-gpu-blocklist"];
|
|
94
|
+
return [
|
|
95
|
+
{ name: "gpu", flags: [...native, ...alwaysChromeFlags, ...keychainChromeFlags] },
|
|
96
|
+
{ name: "swiftshader", flags: ["--use-angle=swiftshader", "--enable-unsafe-swiftshader", ...alwaysChromeFlags, ...keychainChromeFlags] }
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// MO-A-58: override vocabulary with a fixed type, range and neutral value per field.
|
|
101
|
+
export const postOverrideTable = Object.freeze({
|
|
102
|
+
exposure: { kind: "number", min: 0, exclusiveMin: true, max: Infinity, neutral: 1 },
|
|
103
|
+
bloom: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
104
|
+
bloomThreshold: { kind: "number", min: 0, max: 1, neutral: 0.85 },
|
|
105
|
+
bloomKnee: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
106
|
+
bloomRadius: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
107
|
+
halation: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
108
|
+
ca: { kind: "number", min: 0, max: Infinity, neutral: 0 },
|
|
109
|
+
grain: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
110
|
+
vignette: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
111
|
+
fade: { kind: "number", min: 0, max: 1, neutral: 1 },
|
|
112
|
+
flash: { kind: "number", min: 0, max: 1, neutral: 0 },
|
|
113
|
+
shake: { kind: "pair", neutral: [0, 0] },
|
|
114
|
+
zoom: { kind: "number", min: 0, exclusiveMin: true, max: Infinity, neutral: 1 },
|
|
115
|
+
invert: { kind: "boolean", neutral: false }
|
|
116
|
+
});
|
|
117
|
+
export const flashEventThreshold = 0.1; // each rise of `flash` above 0.1 is one MO-SH-03 event
|
|
118
|
+
|
|
119
|
+
export const passIds = Object.freeze(["glitch", "tidal-gradient", "crt", "dither", "swiss-grid", "terminal-ui"]);
|
|
120
|
+
|
|
121
|
+
// MO-B-00: whole-word keyword table, first match wins; an explicit style always wins.
|
|
122
|
+
export const presetKeywordTable = Object.freeze([
|
|
123
|
+
{ preset: "terminalcore", words: ["터미널", "crt", "해커", "terminal", "hacker"], reason: "terminal cue" },
|
|
124
|
+
{ preset: "tidal", words: ["물결", "파도", "잔잔한", "흐름", "gradient", "wave", "tide", "calm"], reason: "flow cue" }
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
// MO-B-01..03 style bibles, as data the engine reads. Colours are sRGB hex; the engine
|
|
128
|
+
// linearizes them once. The prose version lives in references/style-bibles.md.
|
|
129
|
+
export const presets = Object.freeze({
|
|
130
|
+
"swiss-signal": {
|
|
131
|
+
palette: { background: "#0C0E13", text: "#E9EBE4", signal: "#0F7A82", accent: "#D9A441", secondary: "#4B5058" },
|
|
132
|
+
passes: ["swiss-grid", "dither"],
|
|
133
|
+
voices: { display: "display", machine: "machine", body: "body" },
|
|
134
|
+
motion: { entrance: "slam", entranceSec: 0.18, hold: "hold", cut: "snap-cut" },
|
|
135
|
+
post: { exposure: 1, bloom: 0.18, bloomThreshold: 0.85, bloomKnee: 0.4, bloomRadius: 0.6, halation: 0.08, ca: 0.8, grain: 0.035, vignette: 0.22, fade: 1, flash: 0, shake: [0, 0], zoom: 1, invert: false },
|
|
136
|
+
params: {
|
|
137
|
+
"swiss-grid": { columns: 12, gutterPx: 24, marginPx: 96, baselinePx: 8, moduleSnap: true, showGuides: false, hairlineWidthPx: 1 },
|
|
138
|
+
dither: { mode: 1, paletteSize: 0, pixelScale: 1, ditherStrength: 0.3 }
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
terminalcore: {
|
|
142
|
+
palette: { background: "#05070A", panel: "#0C1116", text: "#39FF6A", signal: "#39FF6A", alternate: "#2FB6FF", secondary: "#7C8B93" },
|
|
143
|
+
passes: ["terminal-ui", "crt", "dither", "glitch"],
|
|
144
|
+
voices: { display: "pixel", machine: "machine", body: "pixel" },
|
|
145
|
+
motion: { entrance: "type-in", entranceSec: 0, hold: "hold", cut: "hard-cut", bootFlickerSec: 0.25 },
|
|
146
|
+
post: { exposure: 1, bloom: 0.22, bloomThreshold: 0.8, bloomKnee: 0.4, bloomRadius: 0.55, halation: 0.05, ca: 1.0, grain: 0.03, vignette: 0.3, fade: 1, flash: 0, shake: [0, 0], zoom: 1, invert: false },
|
|
147
|
+
params: {
|
|
148
|
+
"terminal-ui": { charGridPx: [14, 24], windowChromeWidthPx: 1.5, meterCount: 2, logLineRateCharsPerSec: 22, caretBlinkHz: 1.2, wordTimingSource: "reading-time" },
|
|
149
|
+
crt: { scanlineFreqPerFrame: 540, scanlineDepth: 0.22, phosphorPersistence: 0.15, bloomAmount: 0.15, curvature: 0.04, vignette: 0.3, triadMaskAmount: 0.12, flickerAmp: 0.03, flickerFreqHz: 8 },
|
|
150
|
+
dither: { mode: 1, paletteSize: 0, pixelScale: 2, ditherStrength: 0.35 },
|
|
151
|
+
glitch: { intensity: 0.35, sliceCount: 6, maxOffsetPx: 24, blockCorruptSize: [32, 18], rgbSplitPx: 3, holdFrames: 2, hitRatePerSec: 1.0, areaCapPct: 12 }
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
tidal: {
|
|
155
|
+
palette: { background: "#0E1420", text: "#E8ECEF", signal: "#124559", stopB: "#4C3B6E", accent: "#E07856" },
|
|
156
|
+
passes: ["tidal-gradient", "swiss-grid", "glitch"],
|
|
157
|
+
voices: { display: "display", machine: "machine", body: "body" },
|
|
158
|
+
motion: { entrance: "drift", entranceSec: 2.4, hold: "flow", cut: "hard-cut", punchSec: 0.3 },
|
|
159
|
+
post: { exposure: 1, bloom: 0.12, bloomThreshold: 0.85, bloomKnee: 0.4, bloomRadius: 0.7, halation: 0.04, ca: 0.6, grain: 0.03, vignette: 0.18, fade: 1, flash: 0, shake: [0, 0], zoom: 1, invert: false },
|
|
160
|
+
params: {
|
|
161
|
+
"tidal-gradient": { flowSpeed: 0.06, warpAmount: 0.35, curlStrength: 0.4, octaves: 4, surgeOnHit: 0.5, surgeAttackSec: 0.15, surgeDecaySec: 0.25, surgeCapPerSec: 2, bandingSteps: 0, ditherAmount: 0.02 },
|
|
162
|
+
"swiss-grid": { columns: 12, gutterPx: 24, marginPx: 96, baselinePx: 8, moduleSnap: true, showGuides: false, hairlineWidthPx: 1 },
|
|
163
|
+
glitch: { intensity: 0.3, sliceCount: 5, maxOffsetPx: 18, blockCorruptSize: [32, 18], rgbSplitPx: 2, holdFrames: 2, hitRatePerSec: 0.5, areaCapPct: 10 }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Named easing tokens (MO-A-08, MO-B-01..03). Scenes use these names only.
|
|
169
|
+
export const easeTokens = Object.freeze({
|
|
170
|
+
slam: [0.16, 1, 0.3, 1],
|
|
171
|
+
"surge-punch": [0.16, 1, 0.3, 1],
|
|
172
|
+
drift: [0.37, 0, 0.63, 1],
|
|
173
|
+
exit: [0.7, 0, 0.84, 0]
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
export const engineCredit = "mexicat/pdoom-video ca251e3dddda422b364385eb484b5a3593a0990d (MIT)";
|
|
177
|
+
export const engineCreditLine = "Typographic-motion engine adapted from mexicat/pdoom-video (MIT, Giacomo Magnanini), commit `ca251e3`.";
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// MO-C-06 type contrast measured on rendered frames with the glyph-coverage mask (CF-204's method
|
|
2
|
+
// on a video frame), and MO-C-29's saturated-hue cluster count.
|
|
3
|
+
import { linearLut } from "./flash.mjs";
|
|
4
|
+
import { limits } from "./constants.mjs";
|
|
5
|
+
|
|
6
|
+
const relative = (a, b) => (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
|
|
7
|
+
|
|
8
|
+
function percentile(values, q) {
|
|
9
|
+
if (values.length === 0) return NaN;
|
|
10
|
+
const sorted = Float64Array.from(values).sort();
|
|
11
|
+
return sorted[Math.min(sorted.length - 1, Math.max(0, Math.round(q * (sorted.length - 1))))];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// CRT barrel: output pixel (u, v) shows the source at (u, v) + d * |d|^2 * k, d = (u, v) - 0.5.
|
|
15
|
+
export function warpMask(mask, width, height, curvature) {
|
|
16
|
+
if (!curvature) return mask;
|
|
17
|
+
const out = new Uint8Array(mask.length);
|
|
18
|
+
for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {
|
|
19
|
+
const u = (x + 0.5) / width - 0.5, v = (y + 0.5) / height - 0.5;
|
|
20
|
+
const r2 = u * u + v * v;
|
|
21
|
+
const sx = Math.floor((u + u * r2 * curvature + 0.5) * width), sy = Math.floor((v + v * r2 * curvature + 0.5) * height);
|
|
22
|
+
if (sx >= 0 && sy >= 0 && sx < width && sy < height) out[y * width + x] = mask[sy * width + sx];
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function morph(mask, width, height, x0, y0, x1, y1, radius, erode) {
|
|
28
|
+
const out = new Uint8Array((x1 - x0) * (y1 - y0));
|
|
29
|
+
for (let y = y0; y < y1; y++) for (let x = x0; x < x1; x++) {
|
|
30
|
+
let value = erode ? 1 : 0;
|
|
31
|
+
for (let dy = -radius; dy <= radius && (erode ? value : !value); dy++) for (let dx = -radius; dx <= radius; dx++) {
|
|
32
|
+
const sx = x + dx, sy = y + dy;
|
|
33
|
+
const on = sx >= 0 && sy >= 0 && sx < width && sy < height && mask[sy * width + sx] > 127;
|
|
34
|
+
if (erode && !on) { value = 0; break; }
|
|
35
|
+
if (!erode && on) { value = 1; break; }
|
|
36
|
+
}
|
|
37
|
+
out[(y - y0) * (x1 - x0) + (x - x0)] = value;
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const lum = (rgba, i) => 0.2126 * linearLut[rgba[i]] + 0.7152 * linearLut[rgba[i + 1]] + 0.0722 * linearLut[rgba[i + 2]];
|
|
43
|
+
|
|
44
|
+
// One textBoxes entry: foreground = median linear luminance under the mask eroded by 1 px (5th and
|
|
45
|
+
// 95th percentiles for a gradient fill); background = 5th/95th percentiles inside the bbox grown by
|
|
46
|
+
// 0.25 x cap height, outside the mask dilated by 2 px. The ratio is the worst pairing.
|
|
47
|
+
// `large` overrides the type engine's size rule (the stage judges large as 3 % of the short side).
|
|
48
|
+
export function boxContrast(rgba, mask, width, height, box, scale = 1, large = undefined) {
|
|
49
|
+
const [bx0, by0, bx1, by1] = box.bbox.map((v) => v * scale);
|
|
50
|
+
const grow = 0.25 * box.capHeightPx * scale;
|
|
51
|
+
const clampX = (v) => Math.max(0, Math.min(width, Math.round(v))), clampY = (v) => Math.max(0, Math.min(height, Math.round(v)));
|
|
52
|
+
const ix0 = clampX(bx0), iy0 = clampY(by0), ix1 = clampX(bx1), iy1 = clampY(by1);
|
|
53
|
+
const ox0 = clampX(bx0 - grow), oy0 = clampY(by0 - grow), ox1 = clampX(bx1 + grow), oy1 = clampY(by1 + grow);
|
|
54
|
+
if (ix1 <= ix0 || iy1 <= iy0) return null;
|
|
55
|
+
const eroded = morph(mask, width, height, ix0, iy0, ix1, iy1, Math.max(1, Math.round(scale)), true);
|
|
56
|
+
const fg = [];
|
|
57
|
+
for (let y = iy0; y < iy1; y++) for (let x = ix0; x < ix1; x++) if (eroded[(y - iy0) * (ix1 - ix0) + (x - ix0)]) fg.push(lum(rgba, (y * width + x) * 4));
|
|
58
|
+
const dilated = morph(mask, width, height, ox0, oy0, ox1, oy1, Math.max(2, Math.round(2 * scale)), false);
|
|
59
|
+
const bg = [];
|
|
60
|
+
for (let y = oy0; y < oy1; y++) for (let x = ox0; x < ox1; x++) if (!dilated[(y - oy0) * (ox1 - ox0) + (x - ox0)]) bg.push(lum(rgba, (y * width + x) * 4));
|
|
61
|
+
if (fg.length < 4 || bg.length < 4) return null;
|
|
62
|
+
const fgValues = box.fill === "gradient" ? [percentile(fg, 0.05), percentile(fg, 0.95)] : [percentile(fg, 0.5)];
|
|
63
|
+
const bgValues = [percentile(bg, 0.05), percentile(bg, 0.95)];
|
|
64
|
+
let worst = Infinity;
|
|
65
|
+
for (const f of fgValues) for (const b of bgValues) worst = Math.min(worst, relative(f, b));
|
|
66
|
+
const isLarge = large ?? (box.fontSizePx >= limits.largeFontPx || (box.fontSizePx >= limits.largeBoldFontPx && box.weight >= limits.largeBoldWeight));
|
|
67
|
+
return { ratio: worst, floor: isLarge ? limits.largeContrast : limits.bodyContrast, large: isLarge, fgPixels: fg.length, bgPixels: bg.length };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function hexToHsl(hex) {
|
|
71
|
+
const n = parseInt(hex.replace("#", ""), 16);
|
|
72
|
+
const r = ((n >> 16) & 255) / 255, g = ((n >> 8) & 255) / 255, b = (n & 255) / 255;
|
|
73
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), l = (max + min) / 2;
|
|
74
|
+
if (max === min) return { h: 0, s: 0, l };
|
|
75
|
+
const d = max - min;
|
|
76
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
77
|
+
const h = max === r ? ((g - b) / d + (g < b ? 6 : 0)) * 60 : max === g ? ((b - r) / d + 2) * 60 : ((r - g) / d + 4) * 60;
|
|
78
|
+
return { h, s, l };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const hueDistance = (a, b) => { const d = Math.abs(a - b) % 360; return d > 180 ? 360 - d : d; };
|
|
82
|
+
|
|
83
|
+
// MO-C-29: saturated fills (HSL S >= 50%, region >= 24x24 logical px) grouped into +-15 degree hue
|
|
84
|
+
// clusters. Each observation is { color, frame, entryId }.
|
|
85
|
+
export function hueClusters(observations) {
|
|
86
|
+
const clusters = [];
|
|
87
|
+
for (const obs of observations) {
|
|
88
|
+
const { h, s } = hexToHsl(obs.color);
|
|
89
|
+
if (s < limits.clusterSaturation) continue;
|
|
90
|
+
let cluster = clusters.find((c) => hueDistance(c.hue, h) <= limits.clusterHueDeg);
|
|
91
|
+
if (!cluster) { cluster = { hue: h, colors: new Set(), frames: new Set(), entries: new Set() }; clusters.push(cluster); }
|
|
92
|
+
cluster.colors.add(obs.color.toUpperCase());
|
|
93
|
+
cluster.frames.add(obs.frame);
|
|
94
|
+
cluster.entries.add(obs.entryId);
|
|
95
|
+
}
|
|
96
|
+
return clusters.map((c) => ({ hue: Math.round(c.hue), colors: [...c.colors], frames: c.frames.size, entries: [...c.entries] }));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function bigEnough(bbox) {
|
|
100
|
+
return bbox && bbox[2] - bbox[0] >= limits.clusterMinSidePx && bbox[3] - bbox[1] >= limits.clusterMinSidePx;
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// The pinned encodes both render paths share: the H.264 master from raw RGBA frames (MO-A-03 args at
|
|
2
|
+
// the frame's own size and rate) and the looping preview's encoder ladder (MO-A-38).
|
|
3
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
4
|
+
import { once } from "node:events";
|
|
5
|
+
import { rmSync } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
|
|
8
|
+
export function encodeMaster(file, width, height, fps) {
|
|
9
|
+
const args = ["-y", "-loglevel", "error", "-f", "rawvideo", "-pix_fmt", "rgba", "-s", `${width}x${height}`, "-r", String(fps), "-i", "pipe:0",
|
|
10
|
+
"-vf", "scale=out_color_matrix=bt709:out_range=tv,format=yuv420p", "-c:v", "libx264", "-preset", "slow", "-crf", "16", "-tune", "grain",
|
|
11
|
+
"-x264-params", "aq-mode=3", "-colorspace", "bt709", "-color_primaries", "bt709", "-color_trc", "bt709", "-color_range", "tv", "-movflags", "+faststart", file];
|
|
12
|
+
const child = spawn("ffmpeg", args, { stdio: ["pipe", "ignore", "pipe"] });
|
|
13
|
+
const chunks = [];
|
|
14
|
+
child.stderr.on("data", (chunk) => chunks.push(chunk));
|
|
15
|
+
return { child, stderr: () => Buffer.concat(chunks).toString("utf8") };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function write(child, bytes) {
|
|
19
|
+
if (!child.stdin.write(bytes)) await once(child.stdin, "drain");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Preview size rungs: [long edge in px, fps]. The long edge is the width at 16:9 and the height at 9:16.
|
|
23
|
+
export function previewRungs() {
|
|
24
|
+
return [[960, 30], [720, 24], [540, 20]];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function previewSize(longEdge, width, height) {
|
|
28
|
+
return width >= height
|
|
29
|
+
? { width: longEdge, height: Math.round((longEdge * height) / width / 2) * 2 }
|
|
30
|
+
: { width: Math.round((longEdge * width) / height / 2) * 2, height: longEdge };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function encodePreview(runDir, frameDir, fps, count, encoder) {
|
|
34
|
+
const pattern = path.join(frameDir, "p%05d.png");
|
|
35
|
+
const target = path.join(runDir, encoder === "gif" ? "preview.gif" : "preview.webp");
|
|
36
|
+
rmSync(path.join(runDir, "preview.webp"), { force: true });
|
|
37
|
+
rmSync(path.join(runDir, "preview.gif"), { force: true });
|
|
38
|
+
let result;
|
|
39
|
+
if (encoder === "libwebp_anim") result = spawnSync("ffmpeg", ["-y", "-loglevel", "error", "-framerate", String(fps), "-i", pattern, "-c:v", "libwebp_anim", "-lossless", "0", "-q:v", "78", "-loop", "0", target], { encoding: "utf8", timeout: 600000 });
|
|
40
|
+
else if (encoder === "img2webp") {
|
|
41
|
+
const files = Array.from({ length: count }, (_, k) => path.join(frameDir, `p${String(k).padStart(5, "0")}.png`));
|
|
42
|
+
result = spawnSync("img2webp", ["-loop", "0", "-lossy", "-q", "78", "-m", "4", "-d", String(Math.round(1000 / fps)), ...files, "-o", target], { encoding: "utf8", timeout: 600000, maxBuffer: 16_000_000 });
|
|
43
|
+
} else result = spawnSync("ffmpeg", ["-y", "-loglevel", "error", "-framerate", String(fps), "-i", pattern, "-filter_complex", "[0:v]split[a][b];[a]palettegen=stats_mode=full[p];[b][p]paletteuse=dither=bayer:bayer_scale=4", "-loop", "0", target], { encoding: "utf8", timeout: 600000 });
|
|
44
|
+
if (result.status !== 0) throw new Error(`preview encode (${encoder}) failed: ${(result.stderr || result.error?.message || "").trim().split("\n").slice(-2).join(" ")}`);
|
|
45
|
+
return target;
|
|
46
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// MO-C-03 / MO-SH-04 / MO-SH-04a: the WCAG 2.3.1 excursion-method flash audit, written for this
|
|
2
|
+
// engine's own 8-bit output frames. The render feeds it the exact bytes it hands to ffmpeg and to the
|
|
3
|
+
// preview encoder and logs each frame's transitions; the gate counts flashes from those records.
|
|
4
|
+
import { flashGeometry as G, limits } from "./constants.mjs";
|
|
5
|
+
|
|
6
|
+
const toLinear = new Float64Array(256);
|
|
7
|
+
for (let i = 0; i < 256; i++) {
|
|
8
|
+
const c = i / 255;
|
|
9
|
+
toLinear[i] = c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
10
|
+
}
|
|
11
|
+
export const linearLut = toLinear;
|
|
12
|
+
|
|
13
|
+
// The audit geometry for a frame: the 320x180 grid and 107x60-cell window at 16:9, transposed to
|
|
14
|
+
// 180x320 cells and a 60x107-cell window for a 9:16 frame.
|
|
15
|
+
export function flashGeometryFor(width, height) {
|
|
16
|
+
if (width >= height) return G;
|
|
17
|
+
return Object.freeze({ ...G, gridW: G.gridH, gridH: G.gridW, windowCellsW: G.windowCellsH, windowCellsH: G.windowCellsW });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Area-average an RGBA frame of any size onto the audit grid (linear R, G, B and luminance).
|
|
21
|
+
// Integer block sizes take a fast path; other sizes use exact fractional area weights.
|
|
22
|
+
export function auditCells(rgba, width, height, geometry = flashGeometryFor(width, height)) {
|
|
23
|
+
const G = geometry;
|
|
24
|
+
const cells = G.gridW * G.gridH;
|
|
25
|
+
const R = new Float64Array(cells), Gc = new Float64Array(cells), B = new Float64Array(cells), L = new Float64Array(cells);
|
|
26
|
+
const bw = width / G.gridW, bh = height / G.gridH;
|
|
27
|
+
if (Number.isInteger(bw) && Number.isInteger(bh)) {
|
|
28
|
+
const area = bw * bh;
|
|
29
|
+
for (let cy = 0; cy < G.gridH; cy++) for (let cx = 0; cx < G.gridW; cx++) {
|
|
30
|
+
let r = 0, g = 0, b = 0;
|
|
31
|
+
for (let y = cy * bh; y < (cy + 1) * bh; y++) {
|
|
32
|
+
let at = (y * width + cx * bw) * 4;
|
|
33
|
+
for (let x = 0; x < bw; x++, at += 4) { r += toLinear[rgba[at]]; g += toLinear[rgba[at + 1]]; b += toLinear[rgba[at + 2]]; }
|
|
34
|
+
}
|
|
35
|
+
const i = cy * G.gridW + cx;
|
|
36
|
+
R[i] = r / area; Gc[i] = g / area; B[i] = b / area;
|
|
37
|
+
L[i] = 0.2126 * R[i] + 0.7152 * Gc[i] + 0.0722 * B[i];
|
|
38
|
+
}
|
|
39
|
+
return { R, G: Gc, B, L };
|
|
40
|
+
}
|
|
41
|
+
const xw = spans(width, G.gridW), yw = spans(height, G.gridH);
|
|
42
|
+
for (let cy = 0; cy < G.gridH; cy++) for (let cx = 0; cx < G.gridW; cx++) {
|
|
43
|
+
let r = 0, g = 0, b = 0, total = 0;
|
|
44
|
+
for (const [y, wy] of yw[cy]) for (const [x, wx] of xw[cx]) {
|
|
45
|
+
const w = wx * wy, at = (y * width + x) * 4;
|
|
46
|
+
r += toLinear[rgba[at]] * w; g += toLinear[rgba[at + 1]] * w; b += toLinear[rgba[at + 2]] * w; total += w;
|
|
47
|
+
}
|
|
48
|
+
const i = cy * G.gridW + cx;
|
|
49
|
+
R[i] = r / total; Gc[i] = g / total; B[i] = b / total;
|
|
50
|
+
L[i] = 0.2126 * R[i] + 0.7152 * Gc[i] + 0.0722 * B[i];
|
|
51
|
+
}
|
|
52
|
+
return { R, G: Gc, B, L };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function spans(size, count) {
|
|
56
|
+
const step = size / count;
|
|
57
|
+
return Array.from({ length: count }, (_, c) => {
|
|
58
|
+
const a = c * step, b = (c + 1) * step, out = [];
|
|
59
|
+
for (let p = Math.floor(a); p < Math.ceil(b); p++) {
|
|
60
|
+
const w = Math.min(b, p + 1) - Math.max(a, p);
|
|
61
|
+
if (w > 1e-9) out.push([p, w]);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function redValue(r, g, b) {
|
|
68
|
+
const sum = r + g + b;
|
|
69
|
+
if (sum <= 0 || r / sum < G.redRatio) return 0;
|
|
70
|
+
return Math.max(0, r - g - b) * G.redScale;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function windowHit(mask, G) {
|
|
74
|
+
const W = G.gridW, H = G.gridH, ww = G.windowCellsW, wh = G.windowCellsH;
|
|
75
|
+
const sat = new Uint32Array((W + 1) * (H + 1));
|
|
76
|
+
let any = false;
|
|
77
|
+
for (let y = 1; y <= H; y++) {
|
|
78
|
+
let row = 0;
|
|
79
|
+
for (let x = 1; x <= W; x++) {
|
|
80
|
+
row += mask[(y - 1) * W + x - 1];
|
|
81
|
+
sat[y * (W + 1) + x] = sat[(y - 1) * (W + 1) + x] + row;
|
|
82
|
+
}
|
|
83
|
+
if (row) any = true;
|
|
84
|
+
}
|
|
85
|
+
if (!any) return false;
|
|
86
|
+
const threshold = ww * wh * G.areaFraction;
|
|
87
|
+
for (let y = 0; y + wh <= H; y++) for (let x = 0; x + ww <= W; x++) {
|
|
88
|
+
const area = sat[(y + wh) * (W + 1) + x + ww] - sat[y * (W + 1) + x + ww] - sat[(y + wh) * (W + 1) + x] + sat[y * (W + 1) + x];
|
|
89
|
+
if (area > threshold) return true;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Streaming excursion detector. push() takes one frame's audit cells and returns that frame's
|
|
95
|
+
// frame-level transitions: an up/down general transition and an up/down red transition, each
|
|
96
|
+
// reported once at its onset frame, plus MO-SH-04a's full-frame luminance step flag.
|
|
97
|
+
export class ExcursionDetector {
|
|
98
|
+
constructor(geometry = G) {
|
|
99
|
+
this.G = geometry;
|
|
100
|
+
const n = geometry.gridW * geometry.gridH;
|
|
101
|
+
this.lo = new Float64Array(n); this.hi = new Float64Array(n);
|
|
102
|
+
this.rlo = new Float64Array(n); this.rhi = new Float64Array(n);
|
|
103
|
+
this.prevL = new Float64Array(n);
|
|
104
|
+
this.history = [];
|
|
105
|
+
this.active = { up: false, down: false, redUp: false, redDown: false };
|
|
106
|
+
this.frames = 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
push(cells) {
|
|
110
|
+
const G = this.G;
|
|
111
|
+
const n = G.gridW * G.gridH;
|
|
112
|
+
const up = new Uint8Array(n), down = new Uint8Array(n), redUp = new Uint8Array(n), redDown = new Uint8Array(n);
|
|
113
|
+
let stepped = 0;
|
|
114
|
+
for (let i = 0; i < n; i++) {
|
|
115
|
+
const l = cells.L[i];
|
|
116
|
+
const v = redValue(cells.R[i], cells.G[i], cells.B[i]);
|
|
117
|
+
if (this.frames === 0) {
|
|
118
|
+
this.lo[i] = this.hi[i] = l; this.rlo[i] = this.rhi[i] = v; this.prevL[i] = l;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (Math.abs(l - this.prevL[i]) >= limits.fullFrameStepDelta) stepped++;
|
|
122
|
+
this.prevL[i] = l;
|
|
123
|
+
if (l - this.lo[i] >= G.deltaL && Math.min(l, this.lo[i]) < G.darkerBelow) { up[i] = 1; this.lo[i] = this.hi[i] = l; }
|
|
124
|
+
else if (this.hi[i] - l >= G.deltaL && Math.min(l, this.hi[i]) < G.darkerBelow) { down[i] = 1; this.lo[i] = this.hi[i] = l; }
|
|
125
|
+
else { if (l < this.lo[i]) this.lo[i] = l; if (l > this.hi[i]) this.hi[i] = l; }
|
|
126
|
+
if (v - this.rlo[i] > G.redDelta) { redUp[i] = 1; this.rlo[i] = this.rhi[i] = v; }
|
|
127
|
+
else if (this.rhi[i] - v > G.redDelta) { redDown[i] = 1; this.rlo[i] = this.rhi[i] = v; }
|
|
128
|
+
else { if (v < this.rlo[i]) this.rlo[i] = v; if (v > this.rhi[i]) this.rhi[i] = v; }
|
|
129
|
+
}
|
|
130
|
+
const first = this.frames === 0;
|
|
131
|
+
this.frames++;
|
|
132
|
+
this.history.push({ up, down, redUp, redDown });
|
|
133
|
+
if (this.history.length > G.historyFrames) this.history.shift();
|
|
134
|
+
const union = (key) => {
|
|
135
|
+
const mask = new Uint8Array(n);
|
|
136
|
+
for (const frame of this.history) { const m = frame[key]; for (let i = 0; i < n; i++) mask[i] |= m[i]; }
|
|
137
|
+
return mask;
|
|
138
|
+
};
|
|
139
|
+
const result = { fullStep: !first && stepped > n * limits.fullFrameStepArea };
|
|
140
|
+
for (const key of ["up", "down", "redUp", "redDown"]) {
|
|
141
|
+
const hit = !first && windowHit(union(key), G);
|
|
142
|
+
result[key] = hit && !this.active[key];
|
|
143
|
+
this.active[key] = hit;
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Pair opposing transitions inside one window; a flash is one opposing pair.
|
|
150
|
+
function pairsIn(list) {
|
|
151
|
+
let pairs = 0, waiting = 0;
|
|
152
|
+
for (const direction of list) {
|
|
153
|
+
if (waiting === 0) waiting = direction;
|
|
154
|
+
else if (direction !== waiting) { pairs++; waiting = 0; }
|
|
155
|
+
}
|
|
156
|
+
return pairs;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Count flashes from per-frame transition records. `records[f]` = { up, down, redUp, redDown }.
|
|
160
|
+
// Master (looping=false): windows [s, s+fps) with s in [0, count-fps] and no wrap (MO-C-03 fixes a/b).
|
|
161
|
+
// Preview (looping=true): every start s, and the window wraps across the loop seam (MO-SH-04).
|
|
162
|
+
export function countFlashes(records, fps, looping) {
|
|
163
|
+
const count = records.length;
|
|
164
|
+
const events = { general: [], red: [] };
|
|
165
|
+
records.forEach((record, frame) => {
|
|
166
|
+
if (record.up) events.general.push([frame, 1]);
|
|
167
|
+
if (record.down) events.general.push([frame, -1]);
|
|
168
|
+
if (record.redUp) events.red.push([frame, 1]);
|
|
169
|
+
if (record.redDown) events.red.push([frame, -1]);
|
|
170
|
+
});
|
|
171
|
+
const worst = {};
|
|
172
|
+
for (const kind of ["general", "red"]) {
|
|
173
|
+
const list = events[kind];
|
|
174
|
+
let best = { flashes: 0, start: 0, transitions: [] };
|
|
175
|
+
const starts = looping ? count : Math.max(1, count - fps + 1);
|
|
176
|
+
for (let s = 0; s < starts; s++) {
|
|
177
|
+
let inWindow;
|
|
178
|
+
if (looping) {
|
|
179
|
+
inWindow = list.filter(([frame]) => ((frame - s + count) % count) < fps)
|
|
180
|
+
.sort((a, b) => ((a[0] - s + count) % count) - ((b[0] - s + count) % count));
|
|
181
|
+
} else {
|
|
182
|
+
const end = Math.min(s + fps, count);
|
|
183
|
+
inWindow = list.filter(([frame]) => frame >= s && frame < end);
|
|
184
|
+
}
|
|
185
|
+
const flashes = pairsIn(inWindow.map(([, direction]) => direction));
|
|
186
|
+
if (flashes > best.flashes) best = { flashes, start: s, transitions: inWindow.map(([frame, direction]) => `${frame}${direction > 0 ? "+" : "-"}`) };
|
|
187
|
+
}
|
|
188
|
+
worst[kind] = best;
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
general: worst.general.flashes, red: worst.red.flashes,
|
|
192
|
+
worstWindow: { general: worst.general, red: worst.red },
|
|
193
|
+
pass: worst.general.flashes <= limits.flashLimitGeneral && worst.red.flashes <= limits.flashLimitRed
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Run the detector over a whole in-memory sequence (fixtures, preview frames).
|
|
198
|
+
// A looping sequence runs one extra second past the seam so transitions at the wrap are seen.
|
|
199
|
+
export function auditSequence(frames, width, height, fps, looping) {
|
|
200
|
+
const geometry = flashGeometryFor(width, height);
|
|
201
|
+
const detector = new ExcursionDetector(geometry);
|
|
202
|
+
const records = [];
|
|
203
|
+
const steps = [];
|
|
204
|
+
const total = looping ? frames.length + fps : frames.length;
|
|
205
|
+
for (let i = 0; i < total; i++) {
|
|
206
|
+
const frame = frames[i % frames.length];
|
|
207
|
+
const record = detector.push(auditCells(frame, width, height, geometry));
|
|
208
|
+
if (i < frames.length) { records.push(record); steps.push(record.fullStep); }
|
|
209
|
+
else {
|
|
210
|
+
const target = records[i % frames.length];
|
|
211
|
+
for (const key of ["up", "down", "redUp", "redDown"]) target[key] = target[key] || record[key];
|
|
212
|
+
if (record.fullStep) steps[i % frames.length] = true;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return { records, ...countFlashes(records, fps, looping), fullStep: steps.some(Boolean) };
|
|
216
|
+
}
|