@litfamily/litopencode 1.0.7 → 1.0.10
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 +26 -0
- package/README-Ko-KR.md +348 -31
- package/README.md +347 -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 +15 -8
- package/dist/activation.js +61 -7
- package/dist/agents/defaults.js +14 -6
- package/dist/cli/command-aliases.js +24 -22
- package/dist/cli/doctor.js +5 -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/jev-skill-hint.d.ts +48 -0
- package/dist/jev-skill-hint.js +291 -0
- package/dist/motion-image-reads.d.ts +6 -0
- package/dist/motion-image-reads.js +46 -0
- package/dist/server.js +38 -20
- 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/privacy.md +12 -0
- package/docs/reference-Ko-KR.md +44 -1
- package/docs/reference.md +49 -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 +2 -8
- package/skills/lit-korean/SKILL.md +0 -231
|
@@ -0,0 +1,737 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* layout-resolver.js — Resolve AST slides against a template's layout mapping.
|
|
5
|
+
*
|
|
6
|
+
* Takes a compiled AST (from compile-deck.js) and a loaded template object
|
|
7
|
+
* (from template-registry.js) and produces a render-ready resolved spec with
|
|
8
|
+
* positioned regions and decoration elements for each slide.
|
|
9
|
+
*
|
|
10
|
+
* API:
|
|
11
|
+
* const { resolve } = require('./layout-resolver');
|
|
12
|
+
* const resolved = resolve(ast, templateObj);
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Minimal YAML parser (no external dependencies)
|
|
17
|
+
// Handles: key: value, nested maps via indentation, lists with "- ", comments
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Parse a YAML string into a JS object.
|
|
22
|
+
* Supports: maps, scalar values, quoted strings, dash lists, comments.
|
|
23
|
+
* @param {string} text — Raw YAML content
|
|
24
|
+
* @returns {object}
|
|
25
|
+
*/
|
|
26
|
+
function parseYaml(text) {
|
|
27
|
+
const lines = text.split("\n");
|
|
28
|
+
return parseBlock(lines, 0).value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Parse a block of YAML lines starting at a given indent level.
|
|
33
|
+
* Returns { value, end } where end is the next unparsed line index.
|
|
34
|
+
*/
|
|
35
|
+
function parseBlock(lines, start) {
|
|
36
|
+
if (start >= lines.length) return { value: null, end: lines.length };
|
|
37
|
+
|
|
38
|
+
const firstLine = stripComment(lines[start]);
|
|
39
|
+
const firstIndent = leadingSpaces(lines[start]);
|
|
40
|
+
|
|
41
|
+
// Empty/blank first line — skip ahead
|
|
42
|
+
if (!firstLine.trim()) {
|
|
43
|
+
return parseBlock(lines, start + 1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Determine if this is a list block or map block
|
|
47
|
+
if (firstLine.trimStart().startsWith("- ")) {
|
|
48
|
+
return parseList(lines, start, firstIndent);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return parseMap(lines, start, firstIndent);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Parse a YAML map block at a given indent level.
|
|
56
|
+
*/
|
|
57
|
+
function parseMap(lines, start, baseIndent) {
|
|
58
|
+
const obj = {};
|
|
59
|
+
let i = start;
|
|
60
|
+
|
|
61
|
+
while (i < lines.length) {
|
|
62
|
+
const raw = lines[i];
|
|
63
|
+
const line = stripComment(raw);
|
|
64
|
+
const indent = leadingSpaces(raw);
|
|
65
|
+
|
|
66
|
+
// Blank line — skip
|
|
67
|
+
if (!line.trim()) { i++; continue; }
|
|
68
|
+
|
|
69
|
+
// Dedent — end of this map
|
|
70
|
+
if (indent < baseIndent) break;
|
|
71
|
+
|
|
72
|
+
// List item at our indent — not part of this map
|
|
73
|
+
if (line.trimStart().startsWith("- ") && indent === baseIndent) break;
|
|
74
|
+
|
|
75
|
+
// Expect key: value
|
|
76
|
+
const colonIdx = line.indexOf(":");
|
|
77
|
+
if (colonIdx === -1) { i++; continue; }
|
|
78
|
+
|
|
79
|
+
const key = line.substring(0, colonIdx).trim();
|
|
80
|
+
const afterColon = line.substring(colonIdx + 1).trim();
|
|
81
|
+
|
|
82
|
+
if (afterColon === "") {
|
|
83
|
+
// Value is on subsequent lines (nested block)
|
|
84
|
+
const next = parseBlock(lines, i + 1);
|
|
85
|
+
if (next.value !== null) {
|
|
86
|
+
// Check if next block starts with a dash list
|
|
87
|
+
const nextLine = stripComment(lines[i + 1] || "");
|
|
88
|
+
if (nextLine.trimStart().startsWith("- ") && leadingSpaces(lines[i + 1]) > indent) {
|
|
89
|
+
obj[key] = next.value;
|
|
90
|
+
} else {
|
|
91
|
+
obj[key] = next.value;
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
obj[key] = null;
|
|
95
|
+
}
|
|
96
|
+
i = next.end;
|
|
97
|
+
} else {
|
|
98
|
+
obj[key] = parseScalar(afterColon);
|
|
99
|
+
i++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { value: obj, end: i };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Parse a YAML list block at a given indent level.
|
|
108
|
+
*/
|
|
109
|
+
function parseList(lines, start, baseIndent) {
|
|
110
|
+
const arr = [];
|
|
111
|
+
let i = start;
|
|
112
|
+
|
|
113
|
+
while (i < lines.length) {
|
|
114
|
+
const raw = lines[i];
|
|
115
|
+
const line = stripComment(raw);
|
|
116
|
+
const indent = leadingSpaces(raw);
|
|
117
|
+
|
|
118
|
+
if (!line.trim()) { i++; continue; }
|
|
119
|
+
if (indent < baseIndent) break;
|
|
120
|
+
|
|
121
|
+
const trimmed = line.trimStart();
|
|
122
|
+
if (trimmed.startsWith("- ") && indent === baseIndent) {
|
|
123
|
+
const itemText = trimmed.substring(2).trim();
|
|
124
|
+
if (itemText.includes(":")) {
|
|
125
|
+
// Inline map item: "- key: value"
|
|
126
|
+
const inlineObj = {};
|
|
127
|
+
const colonIdx = itemText.indexOf(":");
|
|
128
|
+
const k = itemText.substring(0, colonIdx).trim();
|
|
129
|
+
const v = itemText.substring(colonIdx + 1).trim();
|
|
130
|
+
inlineObj[k] = parseScalar(v);
|
|
131
|
+
|
|
132
|
+
// Check for continuation lines that belong to this item
|
|
133
|
+
const nextI = i + 1;
|
|
134
|
+
if (nextI < lines.length) {
|
|
135
|
+
const nextRaw = lines[nextI];
|
|
136
|
+
const nextIndent = leadingSpaces(nextRaw);
|
|
137
|
+
if (nextIndent > indent && !stripComment(nextRaw).trimStart().startsWith("- ")) {
|
|
138
|
+
const nested = parseMap(lines, nextI, nextIndent);
|
|
139
|
+
Object.assign(inlineObj, nested.value);
|
|
140
|
+
i = nested.end;
|
|
141
|
+
arr.push(inlineObj);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
arr.push(inlineObj);
|
|
146
|
+
} else {
|
|
147
|
+
arr.push(parseScalar(itemText));
|
|
148
|
+
}
|
|
149
|
+
i++;
|
|
150
|
+
} else {
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return { value: arr, end: i };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Parse a scalar YAML value (string, number, boolean, null) or inline array.
|
|
160
|
+
* Handles: [a, b, c] inline array syntax.
|
|
161
|
+
*/
|
|
162
|
+
function parseScalar(val) {
|
|
163
|
+
// Inline array: [item1, item2, ...]
|
|
164
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
165
|
+
const inner = val.slice(1, -1).trim();
|
|
166
|
+
if (inner === "") return [];
|
|
167
|
+
return inner.split(",").map((s) => parseScalar(s.trim()));
|
|
168
|
+
}
|
|
169
|
+
if (val === "null" || val === "~") return null;
|
|
170
|
+
if (val === "true") return true;
|
|
171
|
+
if (val === "false") return false;
|
|
172
|
+
// Quoted string
|
|
173
|
+
if ((val.startsWith('"') && val.endsWith('"')) ||
|
|
174
|
+
(val.startsWith("'") && val.endsWith("'"))) {
|
|
175
|
+
return val.slice(1, -1);
|
|
176
|
+
}
|
|
177
|
+
// Number
|
|
178
|
+
if (/^-?\d+(\.\d+)?$/.test(val)) return parseFloat(val);
|
|
179
|
+
return val;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Remove trailing # comment from a line, respecting quoted strings. */
|
|
183
|
+
function stripComment(line) {
|
|
184
|
+
let inQuote = false;
|
|
185
|
+
let quoteChar = "";
|
|
186
|
+
for (let i = 0; i < line.length; i++) {
|
|
187
|
+
const ch = line[i];
|
|
188
|
+
if (inQuote) {
|
|
189
|
+
if (ch === quoteChar) inQuote = false;
|
|
190
|
+
} else {
|
|
191
|
+
if (ch === '"' || ch === "'") {
|
|
192
|
+
inQuote = true;
|
|
193
|
+
quoteChar = ch;
|
|
194
|
+
} else if (ch === "#") {
|
|
195
|
+
return line.substring(0, i);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return line;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Count leading spaces of a line. */
|
|
203
|
+
function leadingSpaces(line) {
|
|
204
|
+
let count = 0;
|
|
205
|
+
for (let i = 0; i < line.length; i++) {
|
|
206
|
+
if (line[i] === " ") count++;
|
|
207
|
+
else break;
|
|
208
|
+
}
|
|
209
|
+
return count;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
// Block-to-region mapping
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Map a block type to the corresponding region name in the layout mapping.
|
|
218
|
+
* @param {string} blockType
|
|
219
|
+
* @param {object} block — The block object (used for summary-group position)
|
|
220
|
+
* @returns {string|null} — Region name or null if not mappable
|
|
221
|
+
*/
|
|
222
|
+
function blockToRegion(blockType, block, layout) {
|
|
223
|
+
switch (blockType) {
|
|
224
|
+
case "title": return "title";
|
|
225
|
+
case "body": return "body";
|
|
226
|
+
case "chart": return "chart";
|
|
227
|
+
case "kpi-table":
|
|
228
|
+
// content/summary layout defines "table" region; main layout defines "kpi_table" region
|
|
229
|
+
return (layout === "main") ? "kpi_table" : "table";
|
|
230
|
+
case "image": return "image";
|
|
231
|
+
case "main-box": return "main_box";
|
|
232
|
+
case "key-message": return "key_message";
|
|
233
|
+
case "table": return "table";
|
|
234
|
+
case "figure-caption": return "figure_caption";
|
|
235
|
+
case "table-caption": return "table_caption";
|
|
236
|
+
case "summary-group":
|
|
237
|
+
return block.position === "top" ? "group_top" : "group_bottom";
|
|
238
|
+
default:
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Would this table block render as KPI badges rather than as a table?
|
|
245
|
+
*
|
|
246
|
+
* The renderer decides that from the block's shape, and the answer changes how
|
|
247
|
+
* much vertical room the block needs, so the rule lives here where the geometry
|
|
248
|
+
* is worked out and the renderer reads it from here.
|
|
249
|
+
*/
|
|
250
|
+
function looksLikeKpi(content) {
|
|
251
|
+
const headers = (content && content.headers) || [];
|
|
252
|
+
const rows = (content && content.rows) || [];
|
|
253
|
+
const cols = headers.length;
|
|
254
|
+
if (cols < 2 || cols > 4) return false;
|
|
255
|
+
if (cols === 2) {
|
|
256
|
+
const pairs = [headers, ...rows];
|
|
257
|
+
return pairs.length <= 4 && pairs.every((p) => String(p[0]).length <= 12);
|
|
258
|
+
}
|
|
259
|
+
return rows.length === 1 && rows[0].every((c) => String(c).length <= 12);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// A KPI badge stacks a small label over a large value, so it stands roughly
|
|
263
|
+
// this tall no matter how few rows fed it.
|
|
264
|
+
const KPI_BLOCK_HEIGHT_IN = 1.75;
|
|
265
|
+
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
// Capability validation
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Capability rules: which block types each layout supports.
|
|
272
|
+
* Mirrors the structure in capabilities.yaml but kept as code
|
|
273
|
+
* so validation works even with minimal template data.
|
|
274
|
+
*/
|
|
275
|
+
const CAPABILITY_RULES = {
|
|
276
|
+
cover: new Set(["title", "notes"]),
|
|
277
|
+
section: new Set(["title", "notes"]),
|
|
278
|
+
content: new Set(["title", "key-message", "body", "chart", "image", "notes", "kpi-table", "figure-caption", "table-caption"]),
|
|
279
|
+
main: new Set(["title", "key-message", "body", "chart", "main-box", "kpi-table", "image", "notes", "figure-caption", "table-caption"]),
|
|
280
|
+
summary: new Set(["title", "key-message", "summary-group", "image", "kpi-table", "figure-caption", "table-caption"]),
|
|
281
|
+
closing: new Set(["title", "notes"]),
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// Blocks that carry their own position and so never claim a region.
|
|
285
|
+
const PLACEMENT_BLOCK_TYPES = new Set(["box", "shape", "columns"]);
|
|
286
|
+
|
|
287
|
+
// Notes are slide-level metadata; placement blocks position themselves. Neither
|
|
288
|
+
// depends on what regions a layout happens to declare.
|
|
289
|
+
const ALWAYS_ALLOWED = new Set(["notes", ...PLACEMENT_BLOCK_TYPES]);
|
|
290
|
+
|
|
291
|
+
// The inverse of blockToRegion. A template may declare a layout without also
|
|
292
|
+
// listing its supported blocks, and the regions it declares already say which
|
|
293
|
+
// blocks it can hold — deriving the answer keeps the layout set open without
|
|
294
|
+
// hardcoding another table that would drift from this one.
|
|
295
|
+
const REGION_TO_BLOCKS = {
|
|
296
|
+
title: ["title"],
|
|
297
|
+
body: ["body"],
|
|
298
|
+
chart: ["chart"],
|
|
299
|
+
table: ["kpi-table", "table"],
|
|
300
|
+
kpi_table: ["kpi-table"],
|
|
301
|
+
image: ["image"],
|
|
302
|
+
main_box: ["main-box"],
|
|
303
|
+
key_message: ["key-message"],
|
|
304
|
+
figure_caption: ["figure-caption"],
|
|
305
|
+
table_caption: ["table-caption"],
|
|
306
|
+
group_top: ["summary-group"],
|
|
307
|
+
group_bottom: ["summary-group"],
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// "free" needs no template declaration: it means "this slide uses no template
|
|
311
|
+
// region", so every template supports it by construction. A template may still
|
|
312
|
+
// declare its own free layout, and that declaration wins.
|
|
313
|
+
const FREE_LAYOUT = { layout_source: "none", decorations: null, regions: {} };
|
|
314
|
+
|
|
315
|
+
// A region holds one block. Images are the documented exception — they collapse
|
|
316
|
+
// into a grid. Captions are subordinate labels rather than content, and last-wins
|
|
317
|
+
// is how every existing deck already renders them.
|
|
318
|
+
const MERGEABLE_REGIONS = new Set(["image"]);
|
|
319
|
+
const SUBORDINATE_REGIONS = new Set(["figure_caption", "table_caption"]);
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Validate blocks against capability rules from the template's capabilities.
|
|
323
|
+
* @param {number} slideIndex
|
|
324
|
+
* @param {string} layout
|
|
325
|
+
* @param {Array} blocks
|
|
326
|
+
* @param {object} [templateCapabilities] — Parsed capabilities.yaml (optional)
|
|
327
|
+
* @param {object} [layoutConfig] — The layout's mapping entry, used to derive
|
|
328
|
+
* capabilities when the template publishes none for this layout
|
|
329
|
+
*/
|
|
330
|
+
function validateCapabilities(slideIndex, layout, blocks, templateCapabilities, layoutConfig) {
|
|
331
|
+
// Use template capabilities if provided, otherwise fall back to built-in
|
|
332
|
+
// rules, otherwise derive from the regions this layout declares.
|
|
333
|
+
let allowed;
|
|
334
|
+
if (templateCapabilities && templateCapabilities.supported_blocks &&
|
|
335
|
+
templateCapabilities.supported_blocks[layout]) {
|
|
336
|
+
allowed = new Set(templateCapabilities.supported_blocks[layout]);
|
|
337
|
+
} else if (CAPABILITY_RULES[layout]) {
|
|
338
|
+
allowed = CAPABILITY_RULES[layout];
|
|
339
|
+
} else if (layoutConfig && layoutConfig.regions) {
|
|
340
|
+
allowed = new Set(
|
|
341
|
+
Object.keys(layoutConfig.regions).flatMap((r) => REGION_TO_BLOCKS[r] || [])
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (!allowed) {
|
|
346
|
+
throw new Error(
|
|
347
|
+
`Slide ${slideIndex}: unknown layout "${layout}" with no capability rules`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
for (const block of blocks) {
|
|
352
|
+
if (ALWAYS_ALLOWED.has(block.type)) continue;
|
|
353
|
+
|
|
354
|
+
if (!allowed.has(block.type)) {
|
|
355
|
+
throw new Error(
|
|
356
|
+
`Slide ${slideIndex} (layout: ${layout}): ` +
|
|
357
|
+
`block type "${block.type}" is not allowed. ` +
|
|
358
|
+
`Allowed: ${[...allowed, ...ALWAYS_ALLOWED].join(", ") || "(placement blocks only)"}`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Divide a layout's body region into columns.
|
|
366
|
+
*
|
|
367
|
+
* Tracks are ratios, so the source carries no coordinates and the same deck
|
|
368
|
+
* still lands correctly on a template with a different canvas.
|
|
369
|
+
*
|
|
370
|
+
* @returns {Array<object>} one content-band placement per column
|
|
371
|
+
*/
|
|
372
|
+
function resolveColumns(slideIndex, layout, regionDefs, block) {
|
|
373
|
+
const bodyDef = regionDefs && regionDefs.body;
|
|
374
|
+
if (!bodyDef) {
|
|
375
|
+
throw new Error(
|
|
376
|
+
`Slide ${slideIndex} (layout: ${layout}): ":::: columns" divides the layout's ` +
|
|
377
|
+
`body region, but "${layout}" declares none. ` +
|
|
378
|
+
`Regions here: ${Object.keys(regionDefs || {}).join(", ") || "(none)"}`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const weights = block.tracks.map((track) => {
|
|
383
|
+
const value = parseFloat(String(track));
|
|
384
|
+
if (!isFinite(value) || value <= 0) {
|
|
385
|
+
throw new Error(
|
|
386
|
+
`Slide ${slideIndex}: column track "${track}" is not a positive ratio ` +
|
|
387
|
+
`(write them as "2fr 1fr").`
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
return value;
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const total = weights.reduce((sum, w) => sum + w, 0);
|
|
394
|
+
const gap = typeof block.gap === "number" ? block.gap : 0.25;
|
|
395
|
+
const inner = bodyDef.w - gap * (weights.length - 1);
|
|
396
|
+
if (inner <= 0) {
|
|
397
|
+
throw new Error(
|
|
398
|
+
`Slide ${slideIndex}: a gap of ${gap}in leaves no width for ${weights.length} columns ` +
|
|
399
|
+
`inside a body region ${bodyDef.w}in wide.`
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
let x = bodyDef.x;
|
|
404
|
+
return block.columns.map((column, i) => {
|
|
405
|
+
const w = inner * (weights[i] / total);
|
|
406
|
+
const placement = {
|
|
407
|
+
kind: "box",
|
|
408
|
+
z: "content",
|
|
409
|
+
x,
|
|
410
|
+
y: bodyDef.y,
|
|
411
|
+
w,
|
|
412
|
+
...(bodyDef.h !== undefined ? { h: bodyDef.h } : {}),
|
|
413
|
+
blocks: column.blocks || [],
|
|
414
|
+
};
|
|
415
|
+
x += w + gap;
|
|
416
|
+
return placement;
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
// Main resolve function
|
|
422
|
+
// ---------------------------------------------------------------------------
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Resolve a compiled AST against a template to produce render-ready specs.
|
|
426
|
+
*
|
|
427
|
+
* @param {object} ast — AST from compile-deck.js (conforms to slide-ast-v1)
|
|
428
|
+
* @param {object} templateObj — Template object from template-registry.js
|
|
429
|
+
* Expected shape:
|
|
430
|
+
* {
|
|
431
|
+
* name: "AZURE-PRO",
|
|
432
|
+
* mapping: "<yaml string of layout-mapping.yaml>",
|
|
433
|
+
* capabilities: "<yaml string of capabilities.yaml>",
|
|
434
|
+
* template: "<yaml string of template.yaml>"
|
|
435
|
+
* }
|
|
436
|
+
* @returns {object} — Resolved deck spec with positioned regions
|
|
437
|
+
*/
|
|
438
|
+
function resolve(ast, templateObj) {
|
|
439
|
+
if (!ast || !ast.slides) {
|
|
440
|
+
throw new Error("resolve(): invalid AST — expected an object with a slides array");
|
|
441
|
+
}
|
|
442
|
+
if (!templateObj) {
|
|
443
|
+
throw new Error("resolve(): templateObj is required");
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Parse YAML strings from template object
|
|
447
|
+
const mapping = typeof templateObj.mapping === "string"
|
|
448
|
+
? parseYaml(templateObj.mapping)
|
|
449
|
+
: templateObj.mapping;
|
|
450
|
+
const capabilities = typeof templateObj.capabilities === "string"
|
|
451
|
+
? parseYaml(templateObj.capabilities)
|
|
452
|
+
: templateObj.capabilities;
|
|
453
|
+
|
|
454
|
+
if (!mapping || !mapping.layouts) {
|
|
455
|
+
throw new Error(
|
|
456
|
+
`resolve(): template "${templateObj.name || "unknown"}" has no layout mapping`
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const resolvedSlides = [];
|
|
461
|
+
let figureCount = 0;
|
|
462
|
+
let tableCount = 0;
|
|
463
|
+
|
|
464
|
+
const deckMeta = ast.deck || {};
|
|
465
|
+
|
|
466
|
+
for (const slide of ast.slides) {
|
|
467
|
+
const resolved = resolveSlide(slide, mapping, capabilities, deckMeta);
|
|
468
|
+
// Auto-number captions across the deck
|
|
469
|
+
for (const [name, region] of Object.entries(resolved.regions || {})) {
|
|
470
|
+
if (region.content && region.content.type === "figure-caption") {
|
|
471
|
+
figureCount++;
|
|
472
|
+
region.content.number = figureCount;
|
|
473
|
+
region.content.prefix = "도";
|
|
474
|
+
}
|
|
475
|
+
if (region.content && region.content.type === "table-caption") {
|
|
476
|
+
tableCount++;
|
|
477
|
+
region.content.number = tableCount;
|
|
478
|
+
region.content.prefix = "표";
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
resolvedSlides.push(resolved);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return {
|
|
485
|
+
deck: { ...ast.deck },
|
|
486
|
+
slides: resolvedSlides,
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Resolve a single slide against the layout mapping.
|
|
492
|
+
*
|
|
493
|
+
* @param {object} slide — A slide from the AST
|
|
494
|
+
* @param {object} mapping — Parsed layout-mapping.yaml
|
|
495
|
+
* @param {object} [capabilities] — Parsed capabilities.yaml
|
|
496
|
+
* @returns {object} — Resolved slide spec
|
|
497
|
+
*/
|
|
498
|
+
function resolveSlide(slide, mapping, capabilities, deckMeta) {
|
|
499
|
+
const { index, layout, blocks } = slide;
|
|
500
|
+
|
|
501
|
+
// 1. Look up layout configuration
|
|
502
|
+
const layoutConfig = mapping.layouts[layout] ||
|
|
503
|
+
(layout === "free" ? FREE_LAYOUT : null);
|
|
504
|
+
if (!layoutConfig) {
|
|
505
|
+
throw new Error(
|
|
506
|
+
`Slide ${index}: layout "${layout}" not found in template mapping. ` +
|
|
507
|
+
`Available: ${Object.keys(mapping.layouts).join(", ")}, free`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// 2. Validate blocks against capabilities
|
|
512
|
+
validateCapabilities(index, layout, blocks, capabilities, layoutConfig);
|
|
513
|
+
|
|
514
|
+
// 3. Pick the variant, if the slide asked for one. A variant swaps the
|
|
515
|
+
// decoration set and may move the regions the new furniture displaces —
|
|
516
|
+
// a split cover needs a narrower title than a full-bleed one.
|
|
517
|
+
let decorKey = layoutConfig.decorations;
|
|
518
|
+
let regionDefs = layoutConfig.regions || {};
|
|
519
|
+
const variantName = slide.meta && slide.meta.variant;
|
|
520
|
+
if (variantName) {
|
|
521
|
+
const variants = layoutConfig.variants || {};
|
|
522
|
+
const variant = variants[variantName];
|
|
523
|
+
if (!variant) {
|
|
524
|
+
throw new Error(
|
|
525
|
+
`Slide ${index}: layout "${layout}" has no variant "${variantName}". ` +
|
|
526
|
+
`Available: ${Object.keys(variants).join(", ") || "(none — this layout declares no variants)"}`
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
if (variant.decorations) decorKey = variant.decorations;
|
|
530
|
+
if (variant.regions) regionDefs = { ...regionDefs, ...variant.regions };
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
let decorations = [];
|
|
534
|
+
if (decorKey && mapping.decorations && mapping.decorations[decorKey]) {
|
|
535
|
+
decorations = mapping.decorations[decorKey].elements || [];
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// 4. Map blocks to regions, and collect the blocks that place themselves
|
|
539
|
+
const regions = {};
|
|
540
|
+
const placements = [];
|
|
541
|
+
let hasColumns = false;
|
|
542
|
+
|
|
543
|
+
for (const block of blocks) {
|
|
544
|
+
if (block.type === "shape") {
|
|
545
|
+
const { type, ...rest } = block;
|
|
546
|
+
placements.push({ kind: "shape", ...rest });
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
if (block.type === "box") {
|
|
550
|
+
// A role that does not exist would otherwise fall back to a default and
|
|
551
|
+
// render in the wrong type, which is worse than not rendering: the deck
|
|
552
|
+
// looks finished and is quietly off-system.
|
|
553
|
+
const roles = (capabilities && capabilities.font_roles) || null;
|
|
554
|
+
if (block.role && roles && !roles[block.role]) {
|
|
555
|
+
throw new Error(
|
|
556
|
+
`Slide ${index}: "::: box role=${block.role}" names a font role this ` +
|
|
557
|
+
`template does not define. Available: ${Object.keys(roles).join(", ")}`
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
const { type, ...rest } = block;
|
|
561
|
+
placements.push({ kind: "box", ...rest });
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
if (block.type === "columns") {
|
|
565
|
+
placements.push(...resolveColumns(index, layout, regionDefs, block));
|
|
566
|
+
hasColumns = true;
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// An explicit "::: region name=" beats the block type's default region.
|
|
571
|
+
const regionName = block.regionHint || blockToRegion(block.type, block, layout);
|
|
572
|
+
if (!regionName) continue;
|
|
573
|
+
|
|
574
|
+
const regionDef = regionDefs[regionName];
|
|
575
|
+
if (!regionDef) {
|
|
576
|
+
throw new Error(
|
|
577
|
+
`Slide ${index} (layout: ${layout}): ` +
|
|
578
|
+
`block "${block.type}" maps to region "${regionName}" ` +
|
|
579
|
+
`which is not defined in the layout mapping. ` +
|
|
580
|
+
`Available regions: ${Object.keys(regionDefs).join(", ") || "(none)"}`
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Build the resolved region: position metadata + block content
|
|
585
|
+
const resolved = {
|
|
586
|
+
x: regionDef.x,
|
|
587
|
+
y: regionDef.y,
|
|
588
|
+
w: regionDef.w,
|
|
589
|
+
...(regionDef.h !== undefined ? { h: regionDef.h } : {}),
|
|
590
|
+
content: extractContent(block),
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// Copy region metadata (font roles, autofit, alignment, border, etc.)
|
|
594
|
+
for (const key of Object.keys(regionDef)) {
|
|
595
|
+
if (key === "x" || key === "y" || key === "w" || key === "h") continue;
|
|
596
|
+
resolved[key] = regionDef[key];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (regions[regionName]) {
|
|
600
|
+
if (MERGEABLE_REGIONS.has(regionName)) {
|
|
601
|
+
const existing = regions[regionName].content;
|
|
602
|
+
const images = existing && existing.type === "image-grid"
|
|
603
|
+
? existing.images
|
|
604
|
+
: [existing];
|
|
605
|
+
images.push(resolved.content);
|
|
606
|
+
regions[regionName].content = { type: "image-grid", images };
|
|
607
|
+
} else if (SUBORDINATE_REGIONS.has(regionName)) {
|
|
608
|
+
regions[regionName] = resolved;
|
|
609
|
+
} else {
|
|
610
|
+
throw new Error(
|
|
611
|
+
`Slide ${index} (layout: ${layout}): two blocks both claim region ` +
|
|
612
|
+
`"${regionName}", so one would be lost. A region holds one block — ` +
|
|
613
|
+
`send one of them elsewhere with "::: region name=<region>", or place ` +
|
|
614
|
+
`them side by side with ":::: columns". ` +
|
|
615
|
+
`Regions here: ${Object.keys(regionDefs).join(", ")}`
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
} else {
|
|
619
|
+
regions[regionName] = resolved;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Columns take over the body area, so the body region must not also render.
|
|
624
|
+
if (hasColumns) delete regions.body;
|
|
625
|
+
|
|
626
|
+
// When body + image coexist, narrow body to leave room for the image
|
|
627
|
+
if (regions.body && regions.image) {
|
|
628
|
+
const imageX = regions.image.x || 0;
|
|
629
|
+
if (imageX > 0 && imageX < (regions.body.x || 0) + (regions.body.w || 10)) {
|
|
630
|
+
regions.body.w = Math.max(1, imageX - (regions.body.x || 0) - 0.2);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// When a table + image coexist on one slide, narrow the table so it never
|
|
635
|
+
// overlaps the image (the image keeps its right-hand column with a gutter).
|
|
636
|
+
// Content layouts map the table to "table"; main layouts to "kpi_table".
|
|
637
|
+
const tableImageRegion = regions.kpi_table || regions.table;
|
|
638
|
+
if (tableImageRegion && regions.image) {
|
|
639
|
+
const imageX = regions.image.x || 0;
|
|
640
|
+
if (imageX > 0 && imageX < (tableImageRegion.x || 0) + (tableImageRegion.w || 10)) {
|
|
641
|
+
tableImageRegion.w = Math.max(1, imageX - (tableImageRegion.x || 0) - 0.2);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// When table + body coexist, offset body below the table. Content layouts
|
|
646
|
+
// map KPI tables to "table" while main layouts map them to "kpi_table".
|
|
647
|
+
const tableRegion = regions.kpi_table || regions.table;
|
|
648
|
+
if (tableRegion && regions.body) {
|
|
649
|
+
const tblY = tableRegion.y || 1.044;
|
|
650
|
+
const tblRows = (tableRegion.content && tableRegion.content.rows) || [];
|
|
651
|
+
const tblHeaders = (tableRegion.content && tableRegion.content.headers) || [];
|
|
652
|
+
const rowCount = tblRows.length + (tblHeaders.length > 0 ? 1 : 0);
|
|
653
|
+
const rowH = 0.35;
|
|
654
|
+
// The row model only describes a table drawn as a table. The same block
|
|
655
|
+
// renders as KPI badges when its shape suggests it, and those stand far
|
|
656
|
+
// taller than their row count, so a body placed by the row estimate alone
|
|
657
|
+
// lands on top of them.
|
|
658
|
+
const tableContent = tableRegion.content || {};
|
|
659
|
+
const needed = looksLikeKpi(tableContent)
|
|
660
|
+
? KPI_BLOCK_HEIGHT_IN
|
|
661
|
+
: rowCount * rowH;
|
|
662
|
+
const tableBottom = tblY + Math.max(needed, tableRegion.h || 0) + 0.3;
|
|
663
|
+
if ((regions.body.y || 1.044) < tableBottom) {
|
|
664
|
+
regions.body.y = tableBottom;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Cover slide: auto-populate date_line from deck metadata
|
|
669
|
+
if (layout === "cover" && deckMeta) {
|
|
670
|
+
const meta = deckMeta.metadata || {};
|
|
671
|
+
if (regionDefs.date_line && !regions.date_line) {
|
|
672
|
+
const parts = [];
|
|
673
|
+
if (meta.date) parts.push(meta.date);
|
|
674
|
+
if (meta.department) parts.push(meta.department);
|
|
675
|
+
if (parts.length > 0) {
|
|
676
|
+
const rd = regionDefs.date_line;
|
|
677
|
+
regions.date_line = {
|
|
678
|
+
x: rd.x, y: rd.y, w: rd.w,
|
|
679
|
+
...(rd.h !== undefined ? { h: rd.h } : {}),
|
|
680
|
+
content: parts.join(" | "),
|
|
681
|
+
};
|
|
682
|
+
for (const key of Object.keys(rd)) {
|
|
683
|
+
if (key === "x" || key === "y" || key === "w" || key === "h") continue;
|
|
684
|
+
regions.date_line[key] = rd[key];
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
// Auto-populate any cover region named after a frontmatter key (e.g. subtitle,
|
|
689
|
+
// eyebrow) so designed cover templates can surface deck metadata.
|
|
690
|
+
for (const [rname, rdef] of Object.entries(regionDefs)) {
|
|
691
|
+
if (regions[rname] || rname === "date_line" || rname === "title") continue;
|
|
692
|
+
if (meta[rname] == null) continue;
|
|
693
|
+
regions[rname] = { x: rdef.x, y: rdef.y, w: rdef.w, ...(rdef.h !== undefined ? { h: rdef.h } : {}), content: String(meta[rname]) };
|
|
694
|
+
for (const key of Object.keys(rdef)) {
|
|
695
|
+
if (["x", "y", "w", "h"].includes(key)) continue;
|
|
696
|
+
regions[rname][key] = rdef[key];
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return {
|
|
702
|
+
index,
|
|
703
|
+
layout,
|
|
704
|
+
layoutSource: layoutConfig.layout_source,
|
|
705
|
+
decorations,
|
|
706
|
+
regions,
|
|
707
|
+
placements,
|
|
708
|
+
blocks,
|
|
709
|
+
...(slide.meta ? { meta: slide.meta } : {}),
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Extract the primary text content from a block for the resolved region.
|
|
715
|
+
* @param {object} block
|
|
716
|
+
* @returns {string}
|
|
717
|
+
*/
|
|
718
|
+
function extractContent(block) {
|
|
719
|
+
if (block.type === "title") return block.content || "";
|
|
720
|
+
if (block.type === "main-box") return block.content || "";
|
|
721
|
+
if (block.type === "key-message") return block.content || "";
|
|
722
|
+
if (block.type === "notes") return block.content || "";
|
|
723
|
+
if (block.type === "body") return { type: "body", items: block.items || [] };
|
|
724
|
+
if (block.type === "chart") return { type: "chart", chartType: block.chartType, labels: block.labels, series: block.series };
|
|
725
|
+
if (block.type === "kpi-table") return { type: "kpi-table", headers: block.headers || [], rows: block.rows || [], caption: block.caption || "" };
|
|
726
|
+
if (block.type === "image") return { type: "image", src: block.src || "", caption: block.caption || "" };
|
|
727
|
+
if (block.type === "figure-caption") return { type: "figure-caption", caption: block.caption || "" };
|
|
728
|
+
if (block.type === "table-caption") return { type: "table-caption", caption: block.caption || "" };
|
|
729
|
+
if (block.type === "summary-group") return { type: "summary-group", heading: block.heading, items: block.items || [] };
|
|
730
|
+
return "";
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// ---------------------------------------------------------------------------
|
|
734
|
+
// Exports
|
|
735
|
+
// ---------------------------------------------------------------------------
|
|
736
|
+
|
|
737
|
+
module.exports = { resolve, extractContent, looksLikeKpi };
|