@litfamily/litclaude 1.0.10 → 1.0.13
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 +36 -0
- package/README.md +436 -45
- package/README_ko-KR.md +403 -17
- package/bin/install-ownership.mjs +155 -18
- package/bin/litclaude-ai.js +91 -9
- package/docs/ab/S11-baseline-desktop.webp +0 -0
- package/docs/ab/S11-baseline-phone.webp +0 -0
- package/docs/ab/S11-litclaude-desktop.webp +0 -0
- package/docs/ab/S11-litclaude-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-litclaude-desktop.webp +0 -0
- package/docs/ab/S3-litclaude-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-litclaude-desktop.webp +0 -0
- package/docs/ab/S4-litclaude-phone.webp +0 -0
- package/docs/ab/S5-baseline-pages.webp +0 -0
- package/docs/ab/S5-baseline-slides.webp +0 -0
- package/docs/ab/S5-litclaude-pages.webp +0 -0
- package/docs/ab/S5-litclaude-slides.webp +0 -0
- package/docs/ab/S7-litclaude-diagram.webp +0 -0
- package/docs/ab/S8-baseline-slides.webp +0 -0
- package/docs/ab/S8-litclaude-slides.webp +0 -0
- package/docs/ab/S9-litclaude-pages.webp +0 -0
- package/docs/agents.md +10 -7
- 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-checks.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/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-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-loop.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-team.webp +0 -0
- package/docs/assets/skills/lit-typographic-motion.webp +0 -0
- package/docs/assets/skills/litgoal.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/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/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/hooks.md +185 -41
- package/docs/migration.md +6 -3
- package/docs/privacy.md +6 -1
- package/package.json +4 -2
- package/plugins/litclaude/.claude-plugin/plugin.json +1 -1
- package/plugins/litclaude/agents/korean-prose-editor.md +1 -0
- package/plugins/litclaude/agents/korean-style-analyzer.md +1 -0
- package/plugins/litclaude/agents/meaning-preservation-auditor.md +1 -0
- package/plugins/litclaude/agents/native-flow-reviewer.md +1 -0
- package/plugins/litclaude/agents/polish-orchestrator.md +1 -0
- package/plugins/litclaude/bin/litclaude-hook.js +347 -35
- package/plugins/litclaude/bin/litclaude-hud.js +29 -1
- package/plugins/litclaude/bin/litclaude-mcp.js +1 -1
- package/plugins/litclaude/bundled-rules/lit-humanizer.md +14 -0
- package/plugins/litclaude/commands/korean-ai-slop-remover.md +2 -2
- package/plugins/litclaude/commands/lit-comprehend.md +11 -11
- package/plugins/litclaude/commands/lit-humanizer.md +75 -0
- package/plugins/litclaude/commands/lit-korean.md +4 -130
- package/plugins/litclaude/commands/litresearch.md +12 -10
- package/plugins/litclaude/hooks/hooks.json +1 -1
- package/plugins/litclaude/lib/canonical-runtime-commitments.mjs +2 -2
- package/plugins/litclaude/lib/canonical-skill-catalog.mjs +5 -1
- package/plugins/litclaude/lib/canonical-skill-resources.mjs +618 -13
- package/plugins/litclaude/lib/deliverable-hedge-guard.mjs +256 -350
- package/plugins/litclaude/lib/hud-accent-palette.mjs +33 -0
- package/plugins/litclaude/lib/interface-mode.mjs +33 -0
- package/plugins/litclaude/lib/interface-probe-gate.mjs +125 -0
- package/plugins/litclaude/lib/jev-skill-hint.mjs +445 -0
- package/plugins/litclaude/lib/motion-render-gate.mjs +164 -0
- package/plugins/litclaude/lib/mutated-file-paths.mjs +32 -1
- package/plugins/litclaude/lib/office-runtime-lock/package-lock.json +745 -0
- package/plugins/litclaude/lib/office-runtime-lock/package.json +12 -0
- package/plugins/litclaude/lib/office-runtime-lock/requirements.lock +15 -0
- package/plugins/litclaude/lib/office-runtime.mjs +255 -0
- package/plugins/litclaude/lib/office_data.py +493 -0
- package/plugins/litclaude/lib/office_runtime_bootstrap.py +61 -0
- package/plugins/litclaude/lib/ooxml_integrity.py +199 -0
- package/plugins/litclaude/lib/rename-aliases.mjs +3 -1
- package/plugins/litclaude/lib/render_pages.py +105 -0
- package/plugins/litclaude/skills/autoconference/SKILL.md +2 -0
- package/plugins/litclaude/skills/browser-drive/SKILL.md +19 -6
- package/plugins/litclaude/skills/browser-drive/scripts/capability-probe.mjs +44 -8
- package/plugins/litclaude/skills/frontend-ui-ux/ATTRIBUTION.md +26 -0
- package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +50 -16
- package/plugins/litclaude/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +9 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/complete-contract.md +32 -6
- package/plugins/litclaude/skills/frontend-ui-ux/references/craft-floor.md +257 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/default-editorial-pixel.json +6 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/interaction-motion.md +34 -88
- package/plugins/litclaude/skills/frontend-ui-ux/references/motion-guide.md +130 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/slop-register.md +150 -0
- package/plugins/litclaude/skills/frontend-ui-ux/references/visual-reconstruction.md +39 -85
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-page.mjs +1534 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-rules.mjs +141 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-server.mjs +57 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe-static.mjs +129 -0
- package/plugins/litclaude/skills/frontend-ui-ux/scripts/interface-probe.mjs +316 -0
- package/plugins/litclaude/skills/lit-comprehend/SKILL.md +34 -43
- package/plugins/litclaude/skills/lit-comprehend/references/artifact-template.md +5 -44
- package/plugins/litclaude/skills/lit-comprehend/scripts/verify-explainer.mjs +6 -16
- package/plugins/litclaude/skills/lit-diagram-drawer/NOTICE +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/SKILL.md +123 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-architecture-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-beeswarm-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bubble-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-bump-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-data-flow-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-datalake-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-db-schema-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dependency-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-deployment-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-integration-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-dp-security-matrix-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-er-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-fishbone-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-flowchart-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-gantt-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-heatmap-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-high-level-vertical-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-drawio-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-excalidraw-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-import-mermaid-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-it-state-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-journey-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-kanban-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-layers-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-line-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-loop-terminal-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-marimekko-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-medallion-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-nested-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-org-chart-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-paved-road-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-polar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-policy-trace-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-process-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-pyramid-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-consultant-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-quadrant-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-queue-animated-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-radar-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-ridgeline-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sankey-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-scatter-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-sequence-oauth-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-slopegraph-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-lifecycle-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-state-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-story-map-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-streamgraph-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-swimlane-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-timeline-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-block-decomposition-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-tree-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-treemap-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-uml-class-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-venn-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-wardley-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-dark.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-full.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/examples/type-waterfall-light.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/PretendardVariable.woff2 +0 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/fonts/provenance.json +22 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/icons.html +231 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/index.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/devicon-MIT.txt +20 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/diagram-design-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/log-z-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/simple-icons-CC0.md +30 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/assets/licenses/tabler-MIT.txt +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/01-service-architecture/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/01-service-architecture/brief.md +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/02-release-decision/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/02-release-decision/brief.md +18 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/03-data-retention/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/03-data-retention/brief.md +19 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/04-oauth-sequence/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/04-oauth-sequence/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/05-review-lanes/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/05-review-lanes/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/06-rollout-gates/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/06-rollout-gates/brief.md +17 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/07-deployment-boundary/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/07-deployment-boundary/brief.md +19 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/08-policy-traces/after.html +1 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/examples/08-policy-traces/brief.md +20 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/accessibility.md +37 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/export.md +29 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-drawio.md +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-excalidraw.md +14 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-mermaid.md +18 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/import-schema.md +28 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/korean-typography.md +34 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/motion.md +29 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/office-pptx-docx.md +42 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/output-spec.md +48 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-annotation.md +12 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-icons.md +21 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-sketchy.md +11 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/primitive-terminal.md +11 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/profiles.md +24 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/semantic-patterns.md +27 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/style-guide.md +67 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-architecture.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bar.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-beeswarm.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bubble.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-bump.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-catalog.json +1433 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-data-flow.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-datalake.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-db-schema.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dependency.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-deployment.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dp-integration.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-dp-security-matrix.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-er.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-fishbone.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-flowchart.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-gantt.md +49 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-heatmap.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-high-level-vertical.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-high-level.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-drawio.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-excalidraw.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-import-mermaid.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-it-state.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-journey.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-kanban.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-layers.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-line.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-loop-terminal.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-loop.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-marimekko.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-medallion.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-nested.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-org-chart.md +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-paved-road-animated.md +72 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-polar.md +67 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-policy-trace-animated.md +69 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-process.md +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-pyramid.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-quadrant-consultant.md +60 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-quadrant.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-queue-animated.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-radar.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-ridgeline.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sankey.md +68 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-scatter.md +60 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sequence-oauth.md +66 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-sequence.md +63 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-slopegraph.md +65 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-state-lifecycle.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-state.md +59 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-story-map.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-streamgraph.md +53 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-swimlane.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-timeline.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-tree-block-decomposition.md +57 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-tree.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-treemap.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-uml-class.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-venn.md +51 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-wardley.md +52 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/type-waterfall.md +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/references/verifier-guide.md +66 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/block-registry.mjs +43 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/brief-contract.mjs +94 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/check-visible-text.mjs +15 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/diagram-metrics.mjs +223 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/doctor.mjs +35 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/drawio-extract.mjs +635 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/excalidraw-extract.mjs +319 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/export.mjs +116 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/mermaid-extract.mjs +438 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/office-safety.mjs +54 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/renderer.mjs +33 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-all.mjs +58 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-brief.mjs +22 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-coverage.mjs +56 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-diagram.mjs +27 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-motion.mjs +12 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/verify-type.mjs +48 -0
- package/plugins/litclaude/skills/lit-diagram-drawer/scripts/visual-quality.mjs +376 -0
- package/plugins/litclaude/skills/lit-docx/NOTICE +33 -0
- package/plugins/litclaude/skills/lit-docx/SKILL.md +170 -0
- package/plugins/litclaude/skills/lit-docx/references/frontmatter_schema.md +42 -0
- package/plugins/litclaude/skills/lit-docx/references/journal_style_spec.md +17 -0
- package/plugins/litclaude/skills/lit-docx/references/markdown_quality_checklist.md +37 -0
- package/plugins/litclaude/skills/lit-docx/references/slop_phrase_list.yaml +58 -0
- package/plugins/litclaude/skills/lit-docx/references/slop_rules.md +35 -0
- package/plugins/litclaude/skills/lit-docx/scripts/clean_markdown.py +95 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_md_to_docx.py +1194 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_md_to_pdf.py +290 -0
- package/plugins/litclaude/skills/lit-docx/scripts/convert_pdf.py +139 -0
- package/plugins/litclaude/skills/lit-docx/scripts/edit_docx.py +306 -0
- package/plugins/litclaude/skills/lit-docx/scripts/embed_images.py +78 -0
- package/plugins/litclaude/skills/lit-docx/scripts/generate_docx_templates.py +500 -0
- package/plugins/litclaude/skills/lit-docx/scripts/qa_docx.py +177 -0
- package/plugins/litclaude/skills/lit-docx/scripts/slop_lint.py +561 -0
- package/plugins/litclaude/skills/lit-docx/scripts/visual_audit.py +48 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/acs.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/elsevier.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/ieee.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/korean-generic.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/docx/nature.docx +0 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/acs/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/acs/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/elsevier/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/elsevier/template.tex +38 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/ieee/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/ieee/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/korean-generic/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/korean-generic/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/nature/README.md +5 -0
- package/plugins/litclaude/skills/lit-docx/templates/latex/nature/template.tex +37 -0
- package/plugins/litclaude/skills/lit-docx/templates/registry.yaml +1366 -0
- package/plugins/litclaude/skills/lit-humanizer/NOTICE +160 -0
- package/plugins/litclaude/skills/lit-humanizer/SKILL.md +164 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/always-on-rule.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/report-skeleton.md +25 -0
- package/plugins/litclaude/skills/lit-humanizer/assets/slide-text-skeleton.md +28 -0
- package/plugins/litclaude/skills/lit-humanizer/bench/prompts.md +73 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/accessibility-note/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/accessibility-note/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/api-reference/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/api-reference/before.md +15 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/changelog/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/changelog/before.md +12 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/code-comments/after.md +10 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/code-comments/before.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/commit/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/commit/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/data-release/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/data-release/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/english-essay/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/english-essay/before.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/incident-update/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/incident-update/before.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-essay/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-essay/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-report/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-report/before.md +13 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-slide/after.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/ko-slide/before.md +21 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/meeting-brief/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/meeting-brief/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/policy-faq/after.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/policy-faq/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/pr/after.md +15 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/pr/before.md +17 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/project-update/after.md +7 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/project-update/before.md +9 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/readme/after.md +12 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/readme/before.md +14 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/report/after.md +13 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/report/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/research-abstract/after.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/research-abstract/before.md +5 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/slides/after.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/slides/before.md +19 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/troubleshooting/after.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/examples/troubleshooting/before.md +11 -0
- package/plugins/litclaude/skills/lit-humanizer/motion-guide.md +123 -0
- package/plugins/litclaude/skills/lit-humanizer/references/code-patterns.md +468 -0
- package/plugins/litclaude/skills/lit-humanizer/references/deliverable-channels.md +111 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-checklist.md +43 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-content.md +243 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns-structure.md +375 -0
- package/plugins/litclaude/skills/lit-humanizer/references/en-patterns.md +57 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-metrics.md +33 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns-a-d.md +659 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns-e-j.md +387 -0
- package/plugins/litclaude/skills/lit-humanizer/references/ko-patterns.md +31 -0
- package/plugins/litclaude/skills/lit-humanizer/references/rewrite-playbook.md +54 -0
- package/plugins/litclaude/skills/lit-humanizer/references/taxonomy.md +153 -0
- package/plugins/litclaude/skills/lit-humanizer/rules.json +884 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/artifact-text.mjs +38 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/core.mjs +207 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/detect.mjs +64 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/extract_office_text.py +112 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/ko-metrics.mjs +124 -0
- package/plugins/litclaude/skills/lit-humanizer/scripts/scan-input.mjs +29 -0
- package/plugins/litclaude/skills/lit-loop/SKILL.md +30 -1
- package/plugins/litclaude/skills/lit-plan/SKILL.md +4 -1
- package/plugins/litclaude/skills/lit-pptx/NOTICE +38 -0
- package/plugins/litclaude/skills/lit-pptx/SKILL.md +207 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-lg.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-md.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/assets/azure/circle-sm.png +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Black.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Bold.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Light.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Medium.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/A2Z-Regular.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/a2z/SOURCE.md +29 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/OFL.txt +94 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/Pretendard-Bold.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/pretendard/Pretendard-Regular.otf +0 -0
- package/plugins/litclaude/skills/lit-pptx/fonts/provenance.json +78 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/analyst.md +49 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/antithesis.md +59 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/architect.md +44 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/critic.md +42 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/synthesizer.md +47 -0
- package/plugins/litclaude/skills/lit-pptx/references/agents/thesis.md +33 -0
- package/plugins/litclaude/skills/lit-pptx/references/anti-slop-checklist.md +81 -0
- package/plugins/litclaude/skills/lit-pptx/references/authoring-guide.md +173 -0
- package/plugins/litclaude/skills/lit-pptx/references/consensus-protocol.md +125 -0
- package/plugins/litclaude/skills/lit-pptx/references/data-display-cookbook.md +45 -0
- package/plugins/litclaude/skills/lit-pptx/references/design-system-azure.md +58 -0
- package/plugins/litclaude/skills/lit-pptx/references/interview-protocol.md +113 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/autopilot.md +48 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/interview.md +52 -0
- package/plugins/litclaude/skills/lit-pptx/references/stages/plan.md +42 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/compile-deck.js +414 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/craft_extras.py +373 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/deck_craft.py +321 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/embed_fonts.py +215 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/forbidden-terms.json +55 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/layout_inventory.py +418 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/learn_template.py +446 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/derive-palette.js +176 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/directive-parser.js +244 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/font-map.js +79 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/gen-bg.js +86 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/gen-gradient-assets.js +37 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/layout-resolver.js +768 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/markdown-loader.js +136 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/render-adapter-html.js +356 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/render-adapter-pptx.js +2094 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/runtime-require.js +28 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/slide-ast.js +561 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/spec-validator.js +94 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/lib/template-registry.js +394 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/package.json +4 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/qa_deck.py +766 -0
- package/plugins/litclaude/skills/lit-pptx/scripts/validate_pptx.py +215 -0
- package/plugins/litclaude/skills/lit-pptx/specs/markdown-slide-spec-v1.md +251 -0
- package/plugins/litclaude/skills/lit-pptx/specs/markdown-slide-spec-v2.md +214 -0
- package/plugins/litclaude/skills/lit-pptx/specs/slide-ast-v1.schema.json +229 -0
- package/plugins/litclaude/skills/lit-pptx/specs/slide-ast-v2.schema.json +144 -0
- package/plugins/litclaude/skills/lit-pptx/specs/template-enrollment-contract.md +382 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/capabilities.yaml +146 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/layout-mapping.yaml +454 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-A2Z/template.yaml +37 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/capabilities.yaml +154 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/layout-mapping.yaml +475 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/AZURE-PRO/template.yaml +37 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/capabilities.yaml +179 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/layout-mapping.yaml +299 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-A2Z/template.yaml +45 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/capabilities.yaml +181 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/layout-mapping.yaml +299 -0
- package/plugins/litclaude/skills/lit-pptx/templates/enrolled/BOILERPLATE-PRETENDARD/template.yaml +44 -0
- package/plugins/litclaude/skills/lit-scientific-visualization/SKILL.md +1 -0
- package/plugins/litclaude/skills/lit-typographic-motion/SKILL.md +131 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/NOTICE +23 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/THIRD_PARTY_NOTICES +56 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/audio/beat_grid.py +56 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/audio/requirements.lock +1084 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/constants.mjs +211 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/contrast.mjs +90 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/events.mjs +46 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/flash.mjs +211 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/gate-rules.mjs +550 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/presets.mjs +123 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/text.mjs +100 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/timeline.mjs +142 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/util.mjs +167 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/core/voices.mjs +19 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/models/word-timing.json +198 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/analysis.mjs +108 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/brief.mjs +158 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/chrome.mjs +330 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/coverage.mjs +83 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/done.mjs +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/encode.mjs +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/frame-worker.mjs +36 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/look.mjs +128 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/pipeline.mjs +592 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/png.mjs +112 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/report.mjs +66 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/runtime.mjs +330 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/session.mjs +145 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/sound-cli.mjs +60 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/sound.mjs +641 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-capture.mjs +178 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-gate.mjs +122 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-qa.mjs +295 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage-serve.mjs +278 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stage.mjs +503 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/stills.mjs +100 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/treatment.mjs +343 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/node/ws-server.mjs +132 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/package-lock.json +25 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/package.json +10 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/init.js +288 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/qa.js +157 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/stage/stage-kit.js +701 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/boot.mjs +123 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/engine.mjs +281 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/gl.mjs +319 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/glsl-common.mjs +78 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/index.html +6 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/lines.mjs +112 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/crt.mjs +98 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/dither.mjs +49 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/glitch.mjs +77 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/swiss-grid.mjs +61 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/terminal-ui.mjs +88 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/passes/tidal-gradient.mjs +86 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/post.mjs +165 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scale.mjs +15 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scene.mjs +82 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/end-card.mjs +30 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/index.mjs +16 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/karaoke-line.mjs +47 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/kinetic-list.mjs +45 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/number-counter.mjs +29 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/signature.mjs +73 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/scenes/title-slam.mjs +73 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/stroke.mjs +236 -0
- package/plugins/litclaude/skills/lit-typographic-motion/engine/web/type.mjs +180 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w100-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w125-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-400.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-700.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/Archivo-w75-900.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/archivo/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/manifest.json +437 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/Silkscreen-Bold.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/silkscreen/Silkscreen-Regular.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/CREDITS +42 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSAllure.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSFelix.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSOsmotron.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSReadability.svg +216 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/EMSTech.svg +217 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/stroke/OFL.txt +91 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/vt323/OFL.txt +93 -0
- package/plugins/litclaude/skills/lit-typographic-motion/fonts/vt323/VT323-Regular.ttf +0 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/brief-schema.md +91 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/craft-loop.md +69 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/engine-contract.md +104 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/look.md +106 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/runtime.md +65 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/sound.md +83 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/stage.md +192 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/style-bibles.md +117 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/treatment.md +114 -0
- package/plugins/litclaude/skills/lit-typographic-motion/references/type-craft.md +79 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion-doctor.mjs +78 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion-runtime.mjs +67 -0
- package/plugins/litclaude/skills/lit-typographic-motion/scripts/motion.mjs +132 -0
- package/plugins/litclaude/skills/litresearch/SKILL.md +54 -18
- package/scripts/doctor.mjs +5 -0
- package/scripts/postinstall.mjs +1 -0
- package/plugins/litclaude/skills/lit-korean/SKILL.md +0 -327
- /package/plugins/litclaude/skills/{lit-korean/references/fidelity-checklist.md → lit-humanizer/references/litclaude-fidelity-checklist.md} +0 -0
- /package/plugins/litclaude/skills/{lit-korean/references/rewrite-rules.md → lit-humanizer/references/litclaude-rewrite-rules.md} +0 -0
- /package/plugins/litclaude/skills/{lit-korean/references/style-patterns.md → lit-humanizer/references/litclaude-style-patterns.md} +0 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""deck_craft.py — measurable deck-craft checks for the lit-pptx QA gate.
|
|
3
|
+
|
|
4
|
+
The layout inventory answers "does anything spill or collide". These checks answer
|
|
5
|
+
"does the deck look finished", with numbers a gate can hold:
|
|
6
|
+
|
|
7
|
+
sparse_slide a content slide whose content fills less than FILL_MIN of the
|
|
8
|
+
area under its title (a short table at the top of an empty slide)
|
|
9
|
+
table_only_deck three or more content slides, tables on at least 60% of them,
|
|
10
|
+
and not one chart in the deck
|
|
11
|
+
off_slide_shape a picture or shape that runs past the canvas edge and is not a
|
|
12
|
+
full-canvas background
|
|
13
|
+
stray_box a large outlined rectangle with no fill and no text in or on it
|
|
14
|
+
placeholder_text unfilled blanks: [제품명], [금액], XXX, TBD, ○○, {{…}}
|
|
15
|
+
long_foreign_note on a Korean deck, a source line (or any small caption) that is
|
|
16
|
+
mostly a long run of Latin text
|
|
17
|
+
|
|
18
|
+
Each finding carries the slide, the shape and a fix hint. A slide counts as a
|
|
19
|
+
display slide (cover, section, closing) when it holds text at 30 pt or more; display
|
|
20
|
+
slides are exempt from the fill and table checks.
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
python3 deck_craft.py deck.pptx # JSON report; exit 0 always
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import os as _os
|
|
29
|
+
import sys as _sys
|
|
30
|
+
|
|
31
|
+
_sys.dont_write_bytecode = True # the installed skill directory stays read-only
|
|
32
|
+
_sys.path.insert(0, _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "..", "..", "..", "lib"))
|
|
33
|
+
from office_runtime_bootstrap import ensure_runtime # noqa: E402
|
|
34
|
+
|
|
35
|
+
ensure_runtime(["pptx"])
|
|
36
|
+
|
|
37
|
+
import json # noqa: E402
|
|
38
|
+
import re # noqa: E402
|
|
39
|
+
from pathlib import Path # noqa: E402
|
|
40
|
+
|
|
41
|
+
from pptx import Presentation # noqa: E402
|
|
42
|
+
from pptx.enum.shapes import MSO_SHAPE_TYPE # noqa: E402
|
|
43
|
+
from pptx.util import Emu # noqa: E402
|
|
44
|
+
|
|
45
|
+
EMU = 914400.0
|
|
46
|
+
FILL_MIN = 0.45
|
|
47
|
+
DISPLAY_PT = 30.0
|
|
48
|
+
CAPTION_PT = 10.5
|
|
49
|
+
EDGE_TOL = 0.03
|
|
50
|
+
FULL_BLEED = 0.92
|
|
51
|
+
# A bracket with a digit in it is a citation marker ([1], [S3]); a blank has none.
|
|
52
|
+
PLACEHOLDER = re.compile(
|
|
53
|
+
r"\[(?![^\]\n]*\d)[^\]\n]{1,24}\]|\bX{3,}\b|\bTBD\b|\bTODO\b|○○|OOO|\{\{[^}]*\}\}|_{4,}|_{2,}|<[^<>\n]{1,20}(?:명|값|금액|날짜|이름)>"
|
|
54
|
+
)
|
|
55
|
+
MARKDOWN_LINK = re.compile(r"\[[^\]]+\]\([^)]+\)")
|
|
56
|
+
HANGUL = re.compile(r"[가-힣]")
|
|
57
|
+
LATIN = re.compile(r"[A-Za-z]")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _box(shape):
|
|
61
|
+
"""(left, top, width, height) in inches; a table's height is the sum of its rows,
|
|
62
|
+
which renderers grow to, not the frame height a writer declared."""
|
|
63
|
+
try:
|
|
64
|
+
if shape.left is None or shape.width is None:
|
|
65
|
+
return None
|
|
66
|
+
height = shape.height / EMU
|
|
67
|
+
if getattr(shape, "has_table", False) and shape.has_table:
|
|
68
|
+
height = max(height, sum(row.height for row in shape.table.rows) / EMU)
|
|
69
|
+
return (shape.left / EMU, shape.top / EMU, shape.width / EMU, height)
|
|
70
|
+
except (ValueError, TypeError):
|
|
71
|
+
# Writers sometimes emit fractional EMU values python-pptx refuses to parse.
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _flatten(shapes):
|
|
76
|
+
"""Top-level shapes only; a group counts as one box. Group children sit in the
|
|
77
|
+
group's own coordinate space, which is not the slide's."""
|
|
78
|
+
for shape in shapes:
|
|
79
|
+
yield shape
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _max_pt(shape):
|
|
83
|
+
"""Largest font size in the shape: run sizes, then paragraph defaults and end-of-paragraph
|
|
84
|
+
sizes, then PowerPoint's 18 pt default when a writer set none at all."""
|
|
85
|
+
if not getattr(shape, "has_text_frame", False) or not shape.has_text_frame:
|
|
86
|
+
return 0.0
|
|
87
|
+
sizes = []
|
|
88
|
+
for element in shape.text_frame._txBody.iter():
|
|
89
|
+
tag = element.tag.rsplit("}", 1)[-1]
|
|
90
|
+
if tag in ("rPr", "defRPr", "endParaRPr") and element.get("sz"):
|
|
91
|
+
try:
|
|
92
|
+
sizes.append(int(element.get("sz")) / 100.0)
|
|
93
|
+
except ValueError:
|
|
94
|
+
pass
|
|
95
|
+
return max(sizes) if sizes else 18.0
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _text(shape):
|
|
99
|
+
if getattr(shape, "has_text_frame", False) and shape.has_text_frame:
|
|
100
|
+
return shape.text_frame.text.strip()
|
|
101
|
+
if getattr(shape, "has_table", False) and shape.has_table:
|
|
102
|
+
return "\n".join(cell.text for row in shape.table.rows for cell in row.cells)
|
|
103
|
+
return ""
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _is_chart(shape):
|
|
107
|
+
return getattr(shape, "has_chart", False) and shape.has_chart
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _is_table(shape):
|
|
111
|
+
return getattr(shape, "has_table", False) and shape.has_table
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def _descr(shape):
|
|
115
|
+
element = shape._element
|
|
116
|
+
for tag in element.iter():
|
|
117
|
+
if tag.tag.endswith("}cNvPr"):
|
|
118
|
+
return (tag.get("descr") or "") + " " + (tag.get("name") or "")
|
|
119
|
+
return ""
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _decorative_picture(shape, page_area):
|
|
123
|
+
box = _box(shape)
|
|
124
|
+
if box is None:
|
|
125
|
+
return True
|
|
126
|
+
if box[2] * box[3] >= FULL_BLEED * page_area:
|
|
127
|
+
return True
|
|
128
|
+
return bool(re.search(r"circle-|template-image|deco", _descr(shape), re.I))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _filled(shape):
|
|
132
|
+
try:
|
|
133
|
+
return shape.fill.type is not None and shape.fill.type != 5 # 5 = background
|
|
134
|
+
except (AttributeError, TypeError):
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _outlined(shape):
|
|
139
|
+
line = shape._element.find(".//{http://schemas.openxmlformats.org/drawingml/2006/main}ln")
|
|
140
|
+
if line is None:
|
|
141
|
+
return False
|
|
142
|
+
if line.find("{http://schemas.openxmlformats.org/drawingml/2006/main}noFill") is not None:
|
|
143
|
+
return False
|
|
144
|
+
return len(line) > 0 or line.get("w") is not None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _contains(outer, inner, tol=0.05):
|
|
148
|
+
return (inner[0] >= outer[0] - tol and inner[1] >= outer[1] - tol
|
|
149
|
+
and inner[0] + inner[2] <= outer[0] + outer[2] + tol and inner[1] + inner[3] <= outer[1] + outer[3] + tol)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def slide_layout(shapes, W, H, page_area):
|
|
153
|
+
"""The slide's display flag, title, content area and content boxes, shared by the craft
|
|
154
|
+
checks here and in craft_extras.py so both judge the same region."""
|
|
155
|
+
texts = [(s, _text(s)) for s in shapes]
|
|
156
|
+
# Cover, section and closing slides: display-size type, no data visual, and at
|
|
157
|
+
# most two headline-sized lines. A KPI slide has several large numbers and is content.
|
|
158
|
+
has_visual = any(_is_table(s) or _is_chart(s) or (s.shape_type == MSO_SHAPE_TYPE.PICTURE and not _decorative_picture(s, page_area))
|
|
159
|
+
for s in shapes)
|
|
160
|
+
large = [s for s, t in texts if t and _max_pt(s) >= 18]
|
|
161
|
+
display = (any(_max_pt(s) >= DISPLAY_PT for s, t in texts if t) and not has_visual and len(large) <= 2)
|
|
162
|
+
|
|
163
|
+
# Title: the largest text near the top.
|
|
164
|
+
tops = [(s, _max_pt(s)) for s, t in texts if t and _box(s) and _box(s)[1] < H * 0.25]
|
|
165
|
+
title = max(tops, key=lambda item: item[1])[0] if tops else None
|
|
166
|
+
title_bottom = (_box(title)[1] + _box(title)[3]) if title is not None else H * 0.2
|
|
167
|
+
area = (0.5, title_bottom + 0.1, W - 1.0, max(0.1, H - 0.55 - title_bottom - 0.1))
|
|
168
|
+
|
|
169
|
+
visuals = []
|
|
170
|
+
boxes = []
|
|
171
|
+
for shape, text in texts:
|
|
172
|
+
if shape is title:
|
|
173
|
+
continue
|
|
174
|
+
box = _box(shape)
|
|
175
|
+
if box is None:
|
|
176
|
+
continue
|
|
177
|
+
if shape.shape_type == MSO_SHAPE_TYPE.PICTURE:
|
|
178
|
+
if _decorative_picture(shape, page_area):
|
|
179
|
+
continue
|
|
180
|
+
visuals.append("figure")
|
|
181
|
+
elif _is_chart(shape):
|
|
182
|
+
visuals.append("chart")
|
|
183
|
+
elif _is_table(shape):
|
|
184
|
+
visuals.append("table")
|
|
185
|
+
elif text:
|
|
186
|
+
if _max_pt(shape) <= CAPTION_PT:
|
|
187
|
+
continue
|
|
188
|
+
elif shape.shape_type in (MSO_SHAPE_TYPE.AUTO_SHAPE, MSO_SHAPE_TYPE.GROUP) and box[2] * box[3] >= 0.5 and (
|
|
189
|
+
shape.shape_type == MSO_SHAPE_TYPE.GROUP or _filled(shape)):
|
|
190
|
+
if box[2] * box[3] < FULL_BLEED * page_area:
|
|
191
|
+
visuals.append("card")
|
|
192
|
+
else:
|
|
193
|
+
continue
|
|
194
|
+
boxes.append(box)
|
|
195
|
+
return {"display": display, "title": title, "area": area, "boxes": boxes, "visuals": visuals}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def analyse(path: Path) -> dict:
|
|
199
|
+
prs = Presentation(str(path))
|
|
200
|
+
W, H = prs.slide_width / EMU, prs.slide_height / EMU
|
|
201
|
+
page_area = W * H
|
|
202
|
+
findings: list[dict] = []
|
|
203
|
+
all_text = []
|
|
204
|
+
per_slide = []
|
|
205
|
+
|
|
206
|
+
for number, slide in enumerate(prs.slides, start=1):
|
|
207
|
+
# The engine's sample-data tag is a label on every slide, not slide content.
|
|
208
|
+
shapes = [s for s in _flatten(slide.shapes) if not s.name.startswith("lit-notice")]
|
|
209
|
+
texts = [(s, _text(s)) for s in shapes]
|
|
210
|
+
all_text.extend(t for _, t in texts if t)
|
|
211
|
+
layout = slide_layout(shapes, W, H, page_area)
|
|
212
|
+
display = layout["display"]
|
|
213
|
+
|
|
214
|
+
# Placeholder blanks anywhere, display slides included.
|
|
215
|
+
for shape, text in texts:
|
|
216
|
+
cleaned = MARKDOWN_LINK.sub(" ", text)
|
|
217
|
+
hit = PLACEHOLDER.search(cleaned)
|
|
218
|
+
if hit:
|
|
219
|
+
findings.append({"check": "placeholder_text", "slide": number, "shape": shape.name,
|
|
220
|
+
"detail": hit.group(0),
|
|
221
|
+
"hint": "Fill the blank with a realistic value and label it as an example or assumption."})
|
|
222
|
+
|
|
223
|
+
# Anything past the canvas edge that is not a full-canvas background.
|
|
224
|
+
for shape in shapes:
|
|
225
|
+
box = _box(shape)
|
|
226
|
+
if box is None or box[2] * box[3] >= FULL_BLEED * page_area:
|
|
227
|
+
continue
|
|
228
|
+
if box[0] < -EDGE_TOL or box[1] < -EDGE_TOL or box[0] + box[2] > W + EDGE_TOL or box[1] + box[3] > H + EDGE_TOL:
|
|
229
|
+
findings.append({"check": "off_slide_shape", "slide": number, "shape": shape.name,
|
|
230
|
+
"detail": [round(v, 2) for v in box],
|
|
231
|
+
"hint": "Keep decorations inside the canvas; a cropped shape reads as a layout error."})
|
|
232
|
+
|
|
233
|
+
# Large outlined empty rectangles.
|
|
234
|
+
content_boxes = [_box(s) for s, t in texts if (t or _is_chart(s) or s.shape_type == MSO_SHAPE_TYPE.PICTURE) and _box(s)]
|
|
235
|
+
for shape in shapes:
|
|
236
|
+
if shape.shape_type != MSO_SHAPE_TYPE.AUTO_SHAPE or _text(shape):
|
|
237
|
+
continue
|
|
238
|
+
box = _box(shape)
|
|
239
|
+
if box is None or box[2] * box[3] < 1.0:
|
|
240
|
+
continue
|
|
241
|
+
try:
|
|
242
|
+
geometry = shape.auto_shape_type
|
|
243
|
+
rectangular = "RECTANGLE" in str(geometry)
|
|
244
|
+
except (NotImplementedError, ValueError):
|
|
245
|
+
rectangular = False
|
|
246
|
+
if not rectangular or _filled(shape) or not _outlined(shape):
|
|
247
|
+
continue
|
|
248
|
+
if any(_contains(box, inner) for inner in content_boxes if inner != box):
|
|
249
|
+
continue
|
|
250
|
+
findings.append({"check": "stray_box", "slide": number, "shape": shape.name,
|
|
251
|
+
"detail": [round(v, 2) for v in box],
|
|
252
|
+
"hint": "Remove the empty frame or put the message inside a tinted callout."})
|
|
253
|
+
|
|
254
|
+
if display:
|
|
255
|
+
per_slide.append({"slide": number, "display": True})
|
|
256
|
+
continue
|
|
257
|
+
|
|
258
|
+
title, area, boxes, visuals = layout["title"], layout["area"], layout["boxes"], layout["visuals"]
|
|
259
|
+
|
|
260
|
+
if not boxes and title is not None and len(_text(title)) <= 30:
|
|
261
|
+
# Only a short line on the slide: a closing or "Q&A" slide, not a sparse one.
|
|
262
|
+
per_slide.append({"slide": number, "display": True})
|
|
263
|
+
continue
|
|
264
|
+
if boxes:
|
|
265
|
+
left = max(area[0], min(b[0] for b in boxes))
|
|
266
|
+
top = max(area[1], min(b[1] for b in boxes))
|
|
267
|
+
right = min(area[0] + area[2], max(b[0] + b[2] for b in boxes))
|
|
268
|
+
bottom = min(area[1] + area[3], max(b[1] + b[3] for b in boxes))
|
|
269
|
+
fill = max(0.0, right - left) * max(0.0, bottom - top) / (area[2] * area[3])
|
|
270
|
+
else:
|
|
271
|
+
fill = 0.0
|
|
272
|
+
cards = visuals.count("card")
|
|
273
|
+
primary = ("chart" if "chart" in visuals else "figure" if "figure" in visuals else "table" if "table" in visuals
|
|
274
|
+
else "cards" if cards >= 2 else "text")
|
|
275
|
+
per_slide.append({"slide": number, "display": False, "fill": round(fill, 2), "primary": primary})
|
|
276
|
+
if fill < FILL_MIN:
|
|
277
|
+
findings.append({"check": "sparse_slide", "slide": number, "shape": None, "detail": round(fill, 2),
|
|
278
|
+
"hint": f"Content fills {fill:.0%} of the area under the title (floor {FILL_MIN:.0%}): "
|
|
279
|
+
"give the message a visual that uses the space (chart, KPI cards, a fuller table "
|
|
280
|
+
"with its takeaway), or merge the slide with its neighbour."})
|
|
281
|
+
|
|
282
|
+
content = [s for s in per_slide if not s["display"]]
|
|
283
|
+
tables = sum(1 for s in content if s["primary"] == "table")
|
|
284
|
+
charts = sum(1 for s in content if s["primary"] == "chart")
|
|
285
|
+
if len(content) >= 3 and charts == 0 and tables >= 2 and tables >= 0.6 * len(content):
|
|
286
|
+
findings.append({"check": "table_only_deck", "slide": None, "shape": None,
|
|
287
|
+
"detail": f"{tables} of {len(content)} content slides are tables and none is a chart",
|
|
288
|
+
"hint": "Numeric series belong in native charts (::: chart) and headline numbers in KPI "
|
|
289
|
+
"cards; keep tables for lookups a reader scans."})
|
|
290
|
+
|
|
291
|
+
corpus = "\n".join(all_text)
|
|
292
|
+
# One Hangul syllable carries about as much as two or three Latin letters.
|
|
293
|
+
korean = 2.5 * len(HANGUL.findall(corpus)) > len(LATIN.findall(corpus))
|
|
294
|
+
if korean:
|
|
295
|
+
for number, slide in enumerate(prs.slides, start=1):
|
|
296
|
+
for shape in _flatten(slide.shapes):
|
|
297
|
+
text = _text(shape)
|
|
298
|
+
if not text:
|
|
299
|
+
continue
|
|
300
|
+
source_line = bool(re.match(r"\s*(?:sources?|출처|자료)\b", text, re.I))
|
|
301
|
+
if _max_pt(shape) > CAPTION_PT + 0.5 and not source_line:
|
|
302
|
+
continue
|
|
303
|
+
latin, hangul = len(LATIN.findall(text)), len(HANGUL.findall(text))
|
|
304
|
+
if latin >= 60 and latin / max(1, latin + hangul) > 0.7:
|
|
305
|
+
findings.append({"check": "long_foreign_note", "slide": number, "shape": shape.name,
|
|
306
|
+
"detail": text[:80],
|
|
307
|
+
"hint": "On a Korean deck keep sources short and in Korean (기관, 문서명, 연도)."})
|
|
308
|
+
|
|
309
|
+
return {"file": str(path), "pass": not findings, "slides": per_slide, "findings": findings}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def main(argv: list[str]) -> int:
|
|
313
|
+
if not argv:
|
|
314
|
+
print(__doc__)
|
|
315
|
+
return 2
|
|
316
|
+
print(json.dumps(analyse(Path(argv[0])), ensure_ascii=False, indent=2))
|
|
317
|
+
return 0
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
if __name__ == "__main__":
|
|
321
|
+
raise SystemExit(main(_sys.argv[1:]))
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""embed_fonts.py — embed bundled fonts into a .pptx so it renders on machines
|
|
3
|
+
that do not have the fonts installed (self-contained deck).
|
|
4
|
+
|
|
5
|
+
python-pptx has no font-embedding API, so this post-processes the OOXML package
|
|
6
|
+
directly: it adds /ppt/fonts/*.fntdata parts, a fntdata content-type default,
|
|
7
|
+
presentation relationships, and a <p:embeddedFontLst> in ppt/presentation.xml.
|
|
8
|
+
|
|
9
|
+
Only families with a bundled OTF (fonts/pretendard, fonts/a2z) are embedded; unknown families (fonts a learned
|
|
10
|
+
template names but this skill does not bundle) are warned
|
|
11
|
+
about and skipped — never corrupting the file.
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
python3 scripts/embed_fonts.py <in.pptx> [<out.pptx>] # in-place if out omitted
|
|
15
|
+
"""
|
|
16
|
+
import os as _os
|
|
17
|
+
import sys as _sys
|
|
18
|
+
|
|
19
|
+
_sys.dont_write_bytecode = True # the installed skill directory stays read-only
|
|
20
|
+
_sys.path.insert(0, _os.path.join(_os.path.dirname(_os.path.abspath(__file__)), "..", "..", "..", "lib"))
|
|
21
|
+
from office_runtime_bootstrap import ensure_runtime # noqa: E402
|
|
22
|
+
|
|
23
|
+
ensure_runtime(["pptx"])
|
|
24
|
+
|
|
25
|
+
import os
|
|
26
|
+
import re
|
|
27
|
+
import sys
|
|
28
|
+
import shutil
|
|
29
|
+
import zipfile
|
|
30
|
+
|
|
31
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
32
|
+
|
|
33
|
+
FONT_REL_TYPE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font"
|
|
34
|
+
|
|
35
|
+
# A2Z english weight word -> bundled file
|
|
36
|
+
A2Z_WEIGHTS = {
|
|
37
|
+
"Thin", "ExtraLight", "Light", "Regular", "Medium",
|
|
38
|
+
"SemiBold", "Bold", "ExtraBold", "Black",
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _pretendard(weight):
|
|
43
|
+
p = os.path.join(ROOT, "fonts", "pretendard", f"Pretendard-{weight}.otf")
|
|
44
|
+
return p if os.path.exists(p) else None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _a2z(weight):
|
|
48
|
+
p = os.path.join(ROOT, "fonts", "a2z", f"A2Z-{weight}.otf")
|
|
49
|
+
return p if os.path.exists(p) else None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def resolve_family(typeface):
|
|
53
|
+
"""Return {slot: otf_path} for a typeface, or {} if no bundled file.
|
|
54
|
+
|
|
55
|
+
slot is one of regular/bold/italic/boldItalic (we only use regular/bold).
|
|
56
|
+
"""
|
|
57
|
+
tf = typeface.strip()
|
|
58
|
+
if tf == "Pretendard":
|
|
59
|
+
slots = {}
|
|
60
|
+
if _pretendard("Regular"):
|
|
61
|
+
slots["regular"] = _pretendard("Regular")
|
|
62
|
+
if _pretendard("Bold"):
|
|
63
|
+
slots["bold"] = _pretendard("Bold")
|
|
64
|
+
return slots
|
|
65
|
+
# Per-weight families: "에이투지체 7 Bold", "에이투지체 4 Regular", ...
|
|
66
|
+
last = tf.split()[-1] if tf.split() else ""
|
|
67
|
+
if ("에이투지체" in tf or tf.startswith("A2Z")) and last in A2Z_WEIGHTS:
|
|
68
|
+
f = _a2z(last)
|
|
69
|
+
return {"regular": f} if f else {}
|
|
70
|
+
return {}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def scan_typefaces(z):
|
|
74
|
+
faces = set()
|
|
75
|
+
for n in z.namelist():
|
|
76
|
+
if n.startswith("ppt/slides/slide") and n.endswith(".xml"):
|
|
77
|
+
xml = z.read(n).decode("utf-8", "ignore")
|
|
78
|
+
faces.update(re.findall(r'typeface="([^"]+)"', xml))
|
|
79
|
+
return faces
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def embed(in_path, out_path=None):
|
|
83
|
+
out_path = out_path or in_path
|
|
84
|
+
with zipfile.ZipFile(in_path) as z:
|
|
85
|
+
names = z.namelist()
|
|
86
|
+
data = {n: z.read(n) for n in names}
|
|
87
|
+
faces = scan_typefaces(z)
|
|
88
|
+
|
|
89
|
+
# Build embed plan: family -> {slot: otf_path}
|
|
90
|
+
plan = {}
|
|
91
|
+
skipped = []
|
|
92
|
+
for tf in sorted(faces):
|
|
93
|
+
slots = resolve_family(tf)
|
|
94
|
+
if slots:
|
|
95
|
+
plan[tf] = slots
|
|
96
|
+
else:
|
|
97
|
+
skipped.append(tf)
|
|
98
|
+
|
|
99
|
+
if not plan:
|
|
100
|
+
print(f"[embed_fonts] no bundled fonts matched typefaces: {sorted(faces)}")
|
|
101
|
+
if in_path != out_path:
|
|
102
|
+
shutil.copyfile(in_path, out_path)
|
|
103
|
+
return {"embedded": [], "skipped": skipped}
|
|
104
|
+
|
|
105
|
+
# Assign part names + relationship ids.
|
|
106
|
+
rels_xml = data["ppt/_rels/presentation.xml.rels"].decode("utf-8")
|
|
107
|
+
existing_ids = [int(m) for m in re.findall(r'Id="rId(\d+)"', rels_xml)]
|
|
108
|
+
next_id = (max(existing_ids) + 1) if existing_ids else 1
|
|
109
|
+
|
|
110
|
+
font_parts = [] # (part_name, bytes)
|
|
111
|
+
new_rels = [] # (rId, target)
|
|
112
|
+
embedded_lst = [] # xml fragments
|
|
113
|
+
part_idx = 1
|
|
114
|
+
embedded_report = []
|
|
115
|
+
|
|
116
|
+
for tf, slots in plan.items():
|
|
117
|
+
slot_xml = []
|
|
118
|
+
for slot in ("regular", "bold", "italic", "boldItalic"):
|
|
119
|
+
if slot not in slots:
|
|
120
|
+
continue
|
|
121
|
+
part_name = f"ppt/fonts/font{part_idx}.fntdata"
|
|
122
|
+
part_idx += 1
|
|
123
|
+
with open(slots[slot], "rb") as fh:
|
|
124
|
+
font_parts.append((part_name, fh.read()))
|
|
125
|
+
rid = f"rId{next_id}"
|
|
126
|
+
next_id += 1
|
|
127
|
+
new_rels.append((rid, "fonts/" + os.path.basename(part_name)))
|
|
128
|
+
slot_xml.append(f'<p:{slot} r:id="{rid}"/>')
|
|
129
|
+
embedded_report.append(f"{tf} [{slot}] <- {os.path.basename(slots[slot])}")
|
|
130
|
+
embedded_lst.append(
|
|
131
|
+
f'<p:embeddedFont><p:font typeface="{tf}"/>' + "".join(slot_xml) + "</p:embeddedFont>"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
# 1) [Content_Types].xml — add fntdata default
|
|
135
|
+
ct = data["[Content_Types].xml"].decode("utf-8")
|
|
136
|
+
if 'Extension="fntdata"' not in ct:
|
|
137
|
+
ct = ct.replace(
|
|
138
|
+
"</Types>",
|
|
139
|
+
'<Default Extension="fntdata" ContentType="application/x-fontdata"/></Types>',
|
|
140
|
+
)
|
|
141
|
+
data["[Content_Types].xml"] = ct.encode("utf-8")
|
|
142
|
+
|
|
143
|
+
# 2) presentation rels — add font relationships
|
|
144
|
+
rel_frag = "".join(
|
|
145
|
+
f'<Relationship Id="{rid}" Type="{FONT_REL_TYPE}" Target="{tgt}"/>'
|
|
146
|
+
for rid, tgt in new_rels
|
|
147
|
+
)
|
|
148
|
+
rels_xml = rels_xml.replace("</Relationships>", rel_frag + "</Relationships>")
|
|
149
|
+
data["ppt/_rels/presentation.xml.rels"] = rels_xml.encode("utf-8")
|
|
150
|
+
|
|
151
|
+
# 3) presentation.xml — flags + <p:embeddedFontLst>
|
|
152
|
+
pres = data["ppt/presentation.xml"].decode("utf-8")
|
|
153
|
+
# embedTrueTypeFonts + saveSubsetFonts on the root element
|
|
154
|
+
def _set_attr(xml, attr, value):
|
|
155
|
+
if re.search(rf'\b{attr}="[^"]*"', xml):
|
|
156
|
+
return re.sub(rf'\b{attr}="[^"]*"', f'{attr}="{value}"', xml, count=1)
|
|
157
|
+
# insert into the <p:presentation ...> opening tag
|
|
158
|
+
return re.sub(r"(<p:presentation\b)", rf'\1 {attr}="{value}"', xml, count=1)
|
|
159
|
+
|
|
160
|
+
pres = _set_attr(pres, "embedTrueTypeFonts", "1")
|
|
161
|
+
pres = _set_attr(pres, "saveSubsetFonts", "0")
|
|
162
|
+
lst = "<p:embeddedFontLst>" + "".join(embedded_lst) + "</p:embeddedFontLst>"
|
|
163
|
+
# embeddedFontLst must precede custShowLst/defaultTextStyle (schema order).
|
|
164
|
+
if "<p:defaultTextStyle" in pres:
|
|
165
|
+
pres = pres.replace("<p:defaultTextStyle", lst + "<p:defaultTextStyle", 1)
|
|
166
|
+
else:
|
|
167
|
+
pres = pres.replace("</p:presentation>", lst + "</p:presentation>", 1)
|
|
168
|
+
data["ppt/presentation.xml"] = pres.encode("utf-8")
|
|
169
|
+
|
|
170
|
+
# 4) write the new package (font parts last)
|
|
171
|
+
tmp_out = out_path + ".tmp"
|
|
172
|
+
with zipfile.ZipFile(tmp_out, "w", zipfile.ZIP_DEFLATED) as zout:
|
|
173
|
+
for n, b in data.items():
|
|
174
|
+
zout.writestr(n, b)
|
|
175
|
+
for part_name, b in font_parts:
|
|
176
|
+
zout.writestr(part_name, b)
|
|
177
|
+
os.replace(tmp_out, out_path)
|
|
178
|
+
|
|
179
|
+
if skipped:
|
|
180
|
+
print(f"[embed_fonts] WARNING — no bundled font, skipped: {skipped}")
|
|
181
|
+
print("[embed_fonts] embedded:")
|
|
182
|
+
for line in embedded_report:
|
|
183
|
+
print(" " + line)
|
|
184
|
+
|
|
185
|
+
_verify(out_path)
|
|
186
|
+
return {"embedded": embedded_report, "skipped": skipped}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _verify(pptx_path):
|
|
190
|
+
"""Integrity gate: the package check in plugins/litclaude/lib/ooxml_integrity.py
|
|
191
|
+
(zip, content types, well-formed XML, relationship targets, embedded font
|
|
192
|
+
parts) plus a python-pptx reopen."""
|
|
193
|
+
from pathlib import Path
|
|
194
|
+
from ooxml_integrity import check_package
|
|
195
|
+
|
|
196
|
+
report = check_package(Path(pptx_path))
|
|
197
|
+
if not report["pass"]:
|
|
198
|
+
raise RuntimeError(
|
|
199
|
+
"OOXML integrity failed after embedding:\n " + "\n ".join(report["problems"])
|
|
200
|
+
)
|
|
201
|
+
print("[embed_fonts] integrity OK (package structure + python-pptx reopen)")
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def main(argv):
|
|
205
|
+
if not argv:
|
|
206
|
+
print(__doc__)
|
|
207
|
+
return 1
|
|
208
|
+
in_path = argv[0]
|
|
209
|
+
out_path = argv[1] if len(argv) > 1 else None
|
|
210
|
+
embed(in_path, out_path)
|
|
211
|
+
return 0
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
if __name__ == "__main__":
|
|
215
|
+
sys.exit(main(sys.argv[1:]))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"case_insensitive": true,
|
|
3
|
+
"whole_word": false,
|
|
4
|
+
"terms": [
|
|
5
|
+
"click to add title",
|
|
6
|
+
"click to add subtitle",
|
|
7
|
+
"click to add text",
|
|
8
|
+
"content goes here",
|
|
9
|
+
"your logo",
|
|
10
|
+
"placeholder",
|
|
11
|
+
"lorem ipsum",
|
|
12
|
+
"tbd",
|
|
13
|
+
"fixme",
|
|
14
|
+
"todo",
|
|
15
|
+
"본 슬라이드는",
|
|
16
|
+
"슬라이드 7은",
|
|
17
|
+
"최종본에서 걸러냈다",
|
|
18
|
+
"[자사 확인 필요]",
|
|
19
|
+
"[출처 확인 필요]",
|
|
20
|
+
"[작성 중]"
|
|
21
|
+
],
|
|
22
|
+
"soft_terms": [
|
|
23
|
+
"revolutionary",
|
|
24
|
+
"cutting-edge",
|
|
25
|
+
"seamless",
|
|
26
|
+
"seamlessly",
|
|
27
|
+
"innovative",
|
|
28
|
+
"world-class",
|
|
29
|
+
"best-in-class",
|
|
30
|
+
"transformative",
|
|
31
|
+
"next-generation",
|
|
32
|
+
"game-changing",
|
|
33
|
+
"state-of-the-art",
|
|
34
|
+
"AI-powered",
|
|
35
|
+
"AI-generated",
|
|
36
|
+
"as an AI",
|
|
37
|
+
"unlock",
|
|
38
|
+
"empower",
|
|
39
|
+
"synergy",
|
|
40
|
+
"holistic",
|
|
41
|
+
"paradigm shift",
|
|
42
|
+
"frictionless",
|
|
43
|
+
"없다는 것이 발견",
|
|
44
|
+
"판이 굳었다",
|
|
45
|
+
"전제로 깐다",
|
|
46
|
+
"닫아야 할 게이트",
|
|
47
|
+
"역전 금지",
|
|
48
|
+
"논문이 없다",
|
|
49
|
+
"RAM",
|
|
50
|
+
"FTO",
|
|
51
|
+
"CNKI",
|
|
52
|
+
"코퍼스",
|
|
53
|
+
"전이원"
|
|
54
|
+
]
|
|
55
|
+
}
|