@ryanyahya/opendoc 0.4.0
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/.agents/skills/opendoc-apply-comments/SKILL.md +30 -0
- package/.agents/skills/opendoc-apply-comments/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create/SKILL.md +63 -0
- package/.agents/skills/opendoc-create/agents/openai.yaml +6 -0
- package/.agents/skills/opendoc-create-template/SKILL.md +50 -0
- package/.agents/skills/opendoc-create-template/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-create-template/references/structured-reports.md +11 -0
- package/.agents/skills/opendoc-create-theme/SKILL.md +40 -0
- package/.agents/skills/opendoc-create-theme/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/SKILL.md +32 -0
- package/.agents/skills/opendoc-current-document/agents/openai.yaml +4 -0
- package/.agents/skills/opendoc-current-document/references/context-fields.md +20 -0
- package/.agents/skills/opendoc-review-document/SKILL.md +60 -0
- package/.agents/skills/opendoc-review-document/agents/openai.yaml +4 -0
- package/AGENTS.md +69 -0
- package/CONTRIBUTING.md +38 -0
- package/LICENSE +21 -0
- package/README.md +179 -0
- package/SECURITY.md +9 -0
- package/THIRD_PARTY.md +49 -0
- package/VALIDATION.md +99 -0
- package/bin/opendoc.mjs +6 -0
- package/dist/assets/Markdown-sNZyjJi7.js +29 -0
- package/dist/assets/OpenDocSerif-Regular-D3OXs9A9.ttf +0 -0
- package/dist/assets/OpenDocSerif-Semibold-CjL9oDRo.ttf +0 -0
- package/dist/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
- package/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
- package/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/assets/index-DdrZ6ozO.css +1 -0
- package/dist/assets/index-DgNBz7mL.js +39 -0
- package/dist/assets/pdf-B7Emtyld.js +54 -0
- package/dist/assets/pdf.worker.min-Dswkl-cV.mjs +29 -0
- package/dist/assets/wordmark-DsqLlZpb.png +0 -0
- package/dist/index.html +17 -0
- package/docs/APPEARANCE.md +21 -0
- package/docs/ASSETS.md +176 -0
- package/docs/AUTHORING.md +178 -0
- package/docs/HEADLESS.md +120 -0
- package/docs/MEDIA.md +112 -0
- package/docs/PROJECTS.md +55 -0
- package/docs/PROSE.md +15 -0
- package/docs/SELECTION.md +59 -0
- package/docs/TEMPLATES.md +55 -0
- package/docs/THEMES.md +106 -0
- package/node_modules/@formepdf/core/LICENSE +21 -0
- package/node_modules/@formepdf/core/README.md +53 -0
- package/node_modules/@formepdf/core/dist/attachments.d.ts +55 -0
- package/node_modules/@formepdf/core/dist/attachments.js +59 -0
- package/node_modules/@formepdf/core/dist/extract.d.ts +8 -0
- package/node_modules/@formepdf/core/dist/extract.js +56 -0
- package/node_modules/@formepdf/core/dist/index.d.ts +311 -0
- package/node_modules/@formepdf/core/dist/index.js +167 -0
- package/node_modules/@formepdf/core/dist/layout.d.ts +132 -0
- package/node_modules/@formepdf/core/dist/layout.js +240 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.d.ts +19 -0
- package/node_modules/@formepdf/core/dist/shared/browserHelpers.js +128 -0
- package/node_modules/@formepdf/core/package.json +35 -0
- package/node_modules/@formepdf/core/pkg-node/LICENSE +21 -0
- package/node_modules/@formepdf/core/pkg-node/README.md +84 -0
- package/node_modules/@formepdf/core/pkg-node/forme.d.ts +39 -0
- package/node_modules/@formepdf/core/pkg-node/forme.js +394 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm +0 -0
- package/node_modules/@formepdf/core/pkg-node/forme_bg.wasm.d.ts +21 -0
- package/node_modules/@formepdf/core/pkg-node/package.json +25 -0
- package/node_modules/@formepdf/react/README.md +70 -0
- package/node_modules/@formepdf/react/dist/charts.d.ts +72 -0
- package/node_modules/@formepdf/react/dist/charts.js +338 -0
- package/node_modules/@formepdf/react/dist/components.d.ts +533 -0
- package/node_modules/@formepdf/react/dist/components.js +608 -0
- package/node_modules/@formepdf/react/dist/expr.d.ts +20 -0
- package/node_modules/@formepdf/react/dist/expr.js +39 -0
- package/node_modules/@formepdf/react/dist/font.d.ts +2 -0
- package/node_modules/@formepdf/react/dist/font.js +1 -0
- package/node_modules/@formepdf/react/dist/index.d.ts +11 -0
- package/node_modules/@formepdf/react/dist/index.js +15 -0
- package/node_modules/@formepdf/react/dist/render.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/render.js +15 -0
- package/node_modules/@formepdf/react/dist/serialize.d.ts +12 -0
- package/node_modules/@formepdf/react/dist/serialize.js +1470 -0
- package/node_modules/@formepdf/react/dist/stylesheet.d.ts +4 -0
- package/node_modules/@formepdf/react/dist/stylesheet.js +5 -0
- package/node_modules/@formepdf/react/dist/template-proxy.d.ts +38 -0
- package/node_modules/@formepdf/react/dist/template-proxy.js +100 -0
- package/node_modules/@formepdf/react/dist/types.d.ts +287 -0
- package/node_modules/@formepdf/react/dist/types.js +1 -0
- package/node_modules/@formepdf/react/package.json +41 -0
- package/node_modules/@formepdf/shared/README.md +7 -0
- package/node_modules/@formepdf/shared/dist/canvas.d.ts +6 -0
- package/node_modules/@formepdf/shared/dist/canvas.js +43 -0
- package/node_modules/@formepdf/shared/dist/charts.d.ts +100 -0
- package/node_modules/@formepdf/shared/dist/charts.js +98 -0
- package/node_modules/@formepdf/shared/dist/encode.d.ts +27 -0
- package/node_modules/@formepdf/shared/dist/encode.js +93 -0
- package/node_modules/@formepdf/shared/dist/font.d.ts +13 -0
- package/node_modules/@formepdf/shared/dist/font.js +52 -0
- package/node_modules/@formepdf/shared/dist/index.d.ts +10 -0
- package/node_modules/@formepdf/shared/dist/index.js +15 -0
- package/node_modules/@formepdf/shared/dist/parser.d.ts +30 -0
- package/node_modules/@formepdf/shared/dist/parser.js +756 -0
- package/node_modules/@formepdf/shared/dist/semantics.d.ts +15 -0
- package/node_modules/@formepdf/shared/dist/semantics.js +44 -0
- package/node_modules/@formepdf/shared/dist/style.d.ts +7 -0
- package/node_modules/@formepdf/shared/dist/style.js +1024 -0
- package/node_modules/@formepdf/shared/dist/types.d.ts +743 -0
- package/node_modules/@formepdf/shared/dist/types.js +2 -0
- package/node_modules/@formepdf/shared/package.json +35 -0
- package/node_modules/@types/node/LICENSE +21 -0
- package/node_modules/@types/node/README.md +15 -0
- package/node_modules/@types/node/assert/strict.d.ts +111 -0
- package/node_modules/@types/node/assert.d.ts +1078 -0
- package/node_modules/@types/node/async_hooks.d.ts +603 -0
- package/node_modules/@types/node/buffer.buffer.d.ts +472 -0
- package/node_modules/@types/node/buffer.d.ts +1934 -0
- package/node_modules/@types/node/child_process.d.ts +1476 -0
- package/node_modules/@types/node/cluster.d.ts +578 -0
- package/node_modules/@types/node/compatibility/disposable.d.ts +14 -0
- package/node_modules/@types/node/compatibility/index.d.ts +9 -0
- package/node_modules/@types/node/compatibility/indexable.d.ts +20 -0
- package/node_modules/@types/node/compatibility/iterators.d.ts +20 -0
- package/node_modules/@types/node/console.d.ts +452 -0
- package/node_modules/@types/node/constants.d.ts +21 -0
- package/node_modules/@types/node/crypto.d.ts +4545 -0
- package/node_modules/@types/node/dgram.d.ts +600 -0
- package/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
- package/node_modules/@types/node/dns/promises.d.ts +503 -0
- package/node_modules/@types/node/dns.d.ts +923 -0
- package/node_modules/@types/node/domain.d.ts +170 -0
- package/node_modules/@types/node/events.d.ts +976 -0
- package/node_modules/@types/node/fs/promises.d.ts +1306 -0
- package/node_modules/@types/node/fs.d.ts +4463 -0
- package/node_modules/@types/node/globals.d.ts +172 -0
- package/node_modules/@types/node/globals.typedarray.d.ts +38 -0
- package/node_modules/@types/node/http.d.ts +2097 -0
- package/node_modules/@types/node/http2.d.ts +2843 -0
- package/node_modules/@types/node/https.d.ts +579 -0
- package/node_modules/@types/node/index.d.ts +98 -0
- package/node_modules/@types/node/inspector.d.ts +253 -0
- package/node_modules/@types/node/inspector.generated.d.ts +4052 -0
- package/node_modules/@types/node/module.d.ts +891 -0
- package/node_modules/@types/node/net.d.ts +1076 -0
- package/node_modules/@types/node/os.d.ts +506 -0
- package/node_modules/@types/node/package.json +145 -0
- package/node_modules/@types/node/path.d.ts +200 -0
- package/node_modules/@types/node/perf_hooks.d.ts +968 -0
- package/node_modules/@types/node/process.d.ts +2084 -0
- package/node_modules/@types/node/punycode.d.ts +117 -0
- package/node_modules/@types/node/querystring.d.ts +152 -0
- package/node_modules/@types/node/readline/promises.d.ts +161 -0
- package/node_modules/@types/node/readline.d.ts +594 -0
- package/node_modules/@types/node/repl.d.ts +428 -0
- package/node_modules/@types/node/sea.d.ts +162 -0
- package/node_modules/@types/node/sqlite.d.ts +722 -0
- package/node_modules/@types/node/stream/consumers.d.ts +38 -0
- package/node_modules/@types/node/stream/promises.d.ts +90 -0
- package/node_modules/@types/node/stream/web.d.ts +573 -0
- package/node_modules/@types/node/stream.d.ts +1694 -0
- package/node_modules/@types/node/string_decoder.d.ts +67 -0
- package/node_modules/@types/node/test.d.ts +2265 -0
- package/node_modules/@types/node/timers/promises.d.ts +108 -0
- package/node_modules/@types/node/timers.d.ts +287 -0
- package/node_modules/@types/node/tls.d.ts +1319 -0
- package/node_modules/@types/node/trace_events.d.ts +197 -0
- package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +468 -0
- package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +34 -0
- package/node_modules/@types/node/ts5.6/index.d.ts +98 -0
- package/node_modules/@types/node/tty.d.ts +208 -0
- package/node_modules/@types/node/url.d.ts +984 -0
- package/node_modules/@types/node/util.d.ts +2606 -0
- package/node_modules/@types/node/v8.d.ts +920 -0
- package/node_modules/@types/node/vm.d.ts +1053 -0
- package/node_modules/@types/node/wasi.d.ts +181 -0
- package/node_modules/@types/node/web-globals/abortcontroller.d.ts +34 -0
- package/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
- package/node_modules/@types/node/web-globals/events.d.ts +97 -0
- package/node_modules/@types/node/web-globals/fetch.d.ts +55 -0
- package/node_modules/@types/node/web-globals/navigator.d.ts +22 -0
- package/node_modules/@types/node/web-globals/storage.d.ts +24 -0
- package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
- package/node_modules/@types/node/worker_threads.d.ts +819 -0
- package/node_modules/@types/node/zlib.d.ts +747 -0
- package/node_modules/@types/react/LICENSE +21 -0
- package/node_modules/@types/react/README.md +15 -0
- package/node_modules/@types/react/canary.d.ts +129 -0
- package/node_modules/@types/react/compiler-runtime.d.ts +4 -0
- package/node_modules/@types/react/experimental.d.ts +184 -0
- package/node_modules/@types/react/global.d.ts +166 -0
- package/node_modules/@types/react/index.d.ts +4378 -0
- package/node_modules/@types/react/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/jsx-runtime.d.ts +24 -0
- package/node_modules/@types/react/package.json +210 -0
- package/node_modules/@types/react/ts5.0/canary.d.ts +129 -0
- package/node_modules/@types/react/ts5.0/experimental.d.ts +184 -0
- package/node_modules/@types/react/ts5.0/global.d.ts +166 -0
- package/node_modules/@types/react/ts5.0/index.d.ts +4365 -0
- package/node_modules/@types/react/ts5.0/jsx-dev-runtime.d.ts +33 -0
- package/node_modules/@types/react/ts5.0/jsx-runtime.d.ts +24 -0
- package/node_modules/csstype/LICENSE +19 -0
- package/node_modules/csstype/README.md +291 -0
- package/node_modules/csstype/index.d.ts +22569 -0
- package/node_modules/csstype/index.js.flow +6863 -0
- package/node_modules/csstype/package.json +70 -0
- package/node_modules/entities/LICENSE +11 -0
- package/node_modules/entities/decode.d.ts +1 -0
- package/node_modules/entities/decode.js +3 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
- package/node_modules/entities/dist/commonjs/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts +209 -0
- package/node_modules/entities/dist/commonjs/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/decode.js +511 -0
- package/node_modules/entities/dist/commonjs/decode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts +22 -0
- package/node_modules/entities/dist/commonjs/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/encode.js +73 -0
- package/node_modules/entities/dist/commonjs/encode.js.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts +43 -0
- package/node_modules/entities/dist/commonjs/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/escape.js +121 -0
- package/node_modules/entities/dist/commonjs/escape.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +10 -0
- package/node_modules/entities/dist/commonjs/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js +13 -0
- package/node_modules/entities/dist/commonjs/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/commonjs/index.d.ts +96 -0
- package/node_modules/entities/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/entities/dist/commonjs/index.js +131 -0
- package/node_modules/entities/dist/commonjs/index.js.map +1 -0
- package/node_modules/entities/dist/commonjs/package.json +3 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts +19 -0
- package/node_modules/entities/dist/esm/decode-codepoint.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js +72 -0
- package/node_modules/entities/dist/esm/decode-codepoint.js.map +1 -0
- package/node_modules/entities/dist/esm/decode.d.ts +209 -0
- package/node_modules/entities/dist/esm/decode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/decode.js +497 -0
- package/node_modules/entities/dist/esm/decode.js.map +1 -0
- package/node_modules/entities/dist/esm/encode.d.ts +22 -0
- package/node_modules/entities/dist/esm/encode.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/encode.js +69 -0
- package/node_modules/entities/dist/esm/encode.js.map +1 -0
- package/node_modules/entities/dist/esm/escape.d.ts +43 -0
- package/node_modules/entities/dist/esm/escape.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/escape.js +117 -0
- package/node_modules/entities/dist/esm/escape.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-html.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts +2 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js +7 -0
- package/node_modules/entities/dist/esm/generated/decode-data-xml.js.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts +8 -0
- package/node_modules/entities/dist/esm/generated/encode-html.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js +10 -0
- package/node_modules/entities/dist/esm/generated/encode-html.js.map +1 -0
- package/node_modules/entities/dist/esm/index.d.ts +96 -0
- package/node_modules/entities/dist/esm/index.d.ts.map +1 -0
- package/node_modules/entities/dist/esm/index.js +107 -0
- package/node_modules/entities/dist/esm/index.js.map +1 -0
- package/node_modules/entities/dist/esm/package.json +3 -0
- package/node_modules/entities/escape.d.ts +1 -0
- package/node_modules/entities/escape.js +3 -0
- package/node_modules/entities/package.json +118 -0
- package/node_modules/entities/readme.md +122 -0
- package/node_modules/entities/src/decode-codepoint.ts +81 -0
- package/node_modules/entities/src/decode.spec.ts +320 -0
- package/node_modules/entities/src/decode.ts +620 -0
- package/node_modules/entities/src/encode.spec.ts +78 -0
- package/node_modules/entities/src/encode.ts +77 -0
- package/node_modules/entities/src/escape.spec.ts +14 -0
- package/node_modules/entities/src/escape.ts +148 -0
- package/node_modules/entities/src/generated/.eslintrc.json +10 -0
- package/node_modules/entities/src/generated/decode-data-html.ts +8 -0
- package/node_modules/entities/src/generated/decode-data-xml.ts +8 -0
- package/node_modules/entities/src/generated/encode-html.ts +17 -0
- package/node_modules/entities/src/index.spec.ts +125 -0
- package/node_modules/entities/src/index.ts +188 -0
- package/node_modules/parse5/LICENSE +19 -0
- package/node_modules/parse5/README.md +38 -0
- package/node_modules/parse5/dist/cjs/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/cjs/common/doctype.js +118 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/cjs/common/error-codes.js +66 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/cjs/common/foreign-content.js +237 -0
- package/node_modules/parse5/dist/cjs/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/cjs/common/html.js +528 -0
- package/node_modules/parse5/dist/cjs/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/common/token.js +24 -0
- package/node_modules/parse5/dist/cjs/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/cjs/common/unicode.js +70 -0
- package/node_modules/parse5/dist/cjs/index.d.ts +71 -0
- package/node_modules/parse5/dist/cjs/index.js +54 -0
- package/node_modules/parse5/dist/cjs/package.json +1 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/parser/formatting-element-list.js +114 -0
- package/node_modules/parse5/dist/cjs/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/cjs/parser/index.js +3240 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/cjs/parser/open-element-stack.js +328 -0
- package/node_modules/parse5/dist/cjs/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/cjs/serializer/index.js +172 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/cjs/tokenizer/index.js +2714 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/cjs/tokenizer/preprocessor.js +200 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/default.js +176 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/cjs/tree-adapters/interface.js +2 -0
- package/node_modules/parse5/dist/common/doctype.d.ts +4 -0
- package/node_modules/parse5/dist/common/doctype.js +114 -0
- package/node_modules/parse5/dist/common/error-codes.d.ts +67 -0
- package/node_modules/parse5/dist/common/error-codes.js +63 -0
- package/node_modules/parse5/dist/common/foreign-content.d.ts +9 -0
- package/node_modules/parse5/dist/common/foreign-content.js +228 -0
- package/node_modules/parse5/dist/common/html.d.ts +289 -0
- package/node_modules/parse5/dist/common/html.js +523 -0
- package/node_modules/parse5/dist/common/token.d.ts +84 -0
- package/node_modules/parse5/dist/common/token.js +20 -0
- package/node_modules/parse5/dist/common/unicode.d.ts +42 -0
- package/node_modules/parse5/dist/common/unicode.js +62 -0
- package/node_modules/parse5/dist/index.d.ts +71 -0
- package/node_modules/parse5/dist/index.js +42 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.d.ts +36 -0
- package/node_modules/parse5/dist/parser/formatting-element-list.js +110 -0
- package/node_modules/parse5/dist/parser/index.d.ts +221 -0
- package/node_modules/parse5/dist/parser/index.js +3245 -0
- package/node_modules/parse5/dist/parser/open-element-stack.d.ts +53 -0
- package/node_modules/parse5/dist/parser/open-element-stack.js +324 -0
- package/node_modules/parse5/dist/serializer/index.d.ts +60 -0
- package/node_modules/parse5/dist/serializer/index.js +168 -0
- package/node_modules/parse5/dist/tokenizer/index.d.ts +247 -0
- package/node_modules/parse5/dist/tokenizer/index.js +2710 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.d.ts +36 -0
- package/node_modules/parse5/dist/tokenizer/preprocessor.js +196 -0
- package/node_modules/parse5/dist/tree-adapters/default.d.ts +84 -0
- package/node_modules/parse5/dist/tree-adapters/default.js +173 -0
- package/node_modules/parse5/dist/tree-adapters/interface.d.ts +255 -0
- package/node_modules/parse5/dist/tree-adapters/interface.js +1 -0
- package/node_modules/parse5/package.json +50 -0
- package/node_modules/undici-types/LICENSE +21 -0
- package/node_modules/undici-types/README.md +6 -0
- package/node_modules/undici-types/agent.d.ts +31 -0
- package/node_modules/undici-types/api.d.ts +43 -0
- package/node_modules/undici-types/balanced-pool.d.ts +29 -0
- package/node_modules/undici-types/cache.d.ts +36 -0
- package/node_modules/undici-types/client.d.ts +108 -0
- package/node_modules/undici-types/connector.d.ts +34 -0
- package/node_modules/undici-types/content-type.d.ts +21 -0
- package/node_modules/undici-types/cookies.d.ts +28 -0
- package/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
- package/node_modules/undici-types/dispatcher.d.ts +256 -0
- package/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
- package/node_modules/undici-types/errors.d.ts +149 -0
- package/node_modules/undici-types/eventsource.d.ts +61 -0
- package/node_modules/undici-types/fetch.d.ts +209 -0
- package/node_modules/undici-types/file.d.ts +39 -0
- package/node_modules/undici-types/filereader.d.ts +54 -0
- package/node_modules/undici-types/formdata.d.ts +108 -0
- package/node_modules/undici-types/global-dispatcher.d.ts +9 -0
- package/node_modules/undici-types/global-origin.d.ts +7 -0
- package/node_modules/undici-types/handlers.d.ts +15 -0
- package/node_modules/undici-types/header.d.ts +4 -0
- package/node_modules/undici-types/index.d.ts +71 -0
- package/node_modules/undici-types/interceptors.d.ts +17 -0
- package/node_modules/undici-types/mock-agent.d.ts +50 -0
- package/node_modules/undici-types/mock-client.d.ts +25 -0
- package/node_modules/undici-types/mock-errors.d.ts +12 -0
- package/node_modules/undici-types/mock-interceptor.d.ts +93 -0
- package/node_modules/undici-types/mock-pool.d.ts +25 -0
- package/node_modules/undici-types/package.json +55 -0
- package/node_modules/undici-types/patch.d.ts +33 -0
- package/node_modules/undici-types/pool-stats.d.ts +19 -0
- package/node_modules/undici-types/pool.d.ts +39 -0
- package/node_modules/undici-types/proxy-agent.d.ts +28 -0
- package/node_modules/undici-types/readable.d.ts +65 -0
- package/node_modules/undici-types/retry-agent.d.ts +8 -0
- package/node_modules/undici-types/retry-handler.d.ts +116 -0
- package/node_modules/undici-types/util.d.ts +18 -0
- package/node_modules/undici-types/webidl.d.ts +228 -0
- package/node_modules/undici-types/websocket.d.ts +150 -0
- package/package.json +80 -0
- package/scripts/rebuild-forme.mjs +61 -0
- package/src/app/AppearanceControl.tsx +44 -0
- package/src/app/AssetThemeDefaults.tsx +87 -0
- package/src/app/AssetsBrowser.tsx +273 -0
- package/src/app/CommentDock.tsx +108 -0
- package/src/app/CreateDocumentDialog.tsx +51 -0
- package/src/app/DocumentActions.tsx +69 -0
- package/src/app/DocumentCard.tsx +50 -0
- package/src/app/DocumentViewControl.tsx +31 -0
- package/src/app/DocumentsBrowser.tsx +70 -0
- package/src/app/ExportHistoryDialog.tsx +86 -0
- package/src/app/ExportMenu.tsx +127 -0
- package/src/app/GuideDialog.tsx +80 -0
- package/src/app/InspectionLayer.tsx +77 -0
- package/src/app/LogoUploadDialog.tsx +92 -0
- package/src/app/Markdown.tsx +34 -0
- package/src/app/MaterialsBrowser.tsx +149 -0
- package/src/app/PageNumberInput.tsx +56 -0
- package/src/app/Pdf.tsx +561 -0
- package/src/app/ProjectDialogs.tsx +100 -0
- package/src/app/Reader.tsx +769 -0
- package/src/app/SearchField.tsx +13 -0
- package/src/app/Sidebar.tsx +86 -0
- package/src/app/SkillIndex.tsx +30 -0
- package/src/app/TemplatesBrowser.tsx +149 -0
- package/src/app/ThemesBrowser.tsx +159 -0
- package/src/app/api.ts +47 -0
- package/src/app/appearance.ts +35 -0
- package/src/app/assets.css +139 -0
- package/src/app/catalogPreview.ts +20 -0
- package/src/app/colors.css +167 -0
- package/src/app/comment-dock.css +53 -0
- package/src/app/commentDrafts.ts +67 -0
- package/src/app/componentCorrection.ts +17 -0
- package/src/app/edit-workbench.css +87 -0
- package/src/app/editSession.ts +238 -0
- package/src/app/editorRecovery.ts +25 -0
- package/src/app/export-history.css +31 -0
- package/src/app/export.css +17 -0
- package/src/app/guideLinks.ts +21 -0
- package/src/app/guides.css +40 -0
- package/src/app/main.tsx +221 -0
- package/src/app/materials.css +53 -0
- package/src/app/pdfLoading.ts +12 -0
- package/src/app/pdfSelection.ts +112 -0
- package/src/app/projects.css +63 -0
- package/src/app/reader-toolbar.css +65 -0
- package/src/app/selection.css +150 -0
- package/src/app/sidebar.css +60 -0
- package/src/app/skills.css +7 -0
- package/src/app/style.css +1061 -0
- package/src/app/templates.css +49 -0
- package/src/app/themes.css +80 -0
- package/src/app/ui/Icon.tsx +92 -0
- package/src/app/ui/README.md +27 -0
- package/src/app/ui/fonts.css +36 -0
- package/src/app/ui/index.tsx +223 -0
- package/src/app/ui/ui.css +388 -0
- package/src/app/useReaderPreview.ts +19 -0
- package/src/app/useTextEditing.ts +155 -0
- package/src/assets/adapter.ts +122 -0
- package/src/assets/files.ts +378 -0
- package/src/assets/import-worker.ts +294 -0
- package/src/assets/imports.ts +124 -0
- package/src/assets/index.ts +60 -0
- package/src/assets/store.ts +798 -0
- package/src/assets/usage.ts +118 -0
- package/src/cli/check.ts +25 -0
- package/src/cli/init.ts +119 -0
- package/src/cli/lock.ts +34 -0
- package/src/cli/main.ts +118 -0
- package/src/cli/process.ts +19 -0
- package/src/cli/start.ts +96 -0
- package/src/cli/update.ts +348 -0
- package/src/cli/workspace.ts +94 -0
- package/src/document/index.tsx +641 -0
- package/src/document/page.tsx +53 -0
- package/src/document/text-targets.tsx +162 -0
- package/src/media/files.ts +124 -0
- package/src/media/render.ts +63 -0
- package/src/rendering/resolve-sources.ts +84 -0
- package/src/runtime/jsx-dev-runtime.ts +2 -0
- package/src/runtime/jsx-runtime.ts +2 -0
- package/src/runtime/paths.ts +12 -0
- package/src/server/assets-cli.ts +162 -0
- package/src/server/assets-http.ts +100 -0
- package/src/server/client.ts +50 -0
- package/src/server/clipboard.ts +22 -0
- package/src/server/comments-cli.ts +64 -0
- package/src/server/comments.ts +130 -0
- package/src/server/create-cli.ts +33 -0
- package/src/server/create.ts +228 -0
- package/src/server/dependencies.ts +91 -0
- package/src/server/documents.ts +143 -0
- package/src/server/edits.ts +249 -0
- package/src/server/export-batch.ts +105 -0
- package/src/server/export-errors.ts +2 -0
- package/src/server/export-file.ts +57 -0
- package/src/server/export-inputs.ts +66 -0
- package/src/server/export-preview.ts +69 -0
- package/src/server/export.ts +32 -0
- package/src/server/exports.ts +283 -0
- package/src/server/files.ts +21 -0
- package/src/server/guides.ts +71 -0
- package/src/server/index.ts +432 -0
- package/src/server/materials.ts +39 -0
- package/src/server/media-cli.ts +73 -0
- package/src/server/media-mutations.ts +168 -0
- package/src/server/pptx.ts +160 -0
- package/src/server/preflight.ts +129 -0
- package/src/server/projects-cli.ts +29 -0
- package/src/server/projects.ts +187 -0
- package/src/server/render-error.ts +9 -0
- package/src/server/render-source.ts +24 -0
- package/src/server/render.ts +48 -0
- package/src/server/review-cli.ts +40 -0
- package/src/server/review.ts +161 -0
- package/src/server/selection.ts +23 -0
- package/src/server/source-overrides.ts +97 -0
- package/src/server/templates-cli.ts +51 -0
- package/src/server/templates.ts +186 -0
- package/src/server/text-layout.ts +41 -0
- package/src/server/text-source.ts +307 -0
- package/src/server/themes-cli.ts +59 -0
- package/src/server/themes.ts +215 -0
- package/src/server/ttf2eot.d.ts +3 -0
- package/src/server/worker.ts +166 -0
- package/src/server/workspace.ts +242 -0
- package/src/shared/anchors.ts +69 -0
- package/src/shared/assets.ts +154 -0
- package/src/shared/export.ts +34 -0
- package/src/shared/media.ts +33 -0
- package/src/shared/projects.ts +19 -0
- package/src/shared/selection.ts +94 -0
- package/src/shared/skill-index.ts +14 -0
- package/src/shared/starters.ts +19 -0
- package/src/shared/templates.ts +18 -0
- package/src/shared/themes.ts +24 -0
- package/src/shared/types.ts +39 -0
- package/src/template/index.ts +27 -0
- package/src/themes/index.ts +3 -0
- package/src/themes/neutral.ts +20 -0
- package/src/themes/types.ts +110 -0
- package/starter/assets/brand/wordmark.png +0 -0
- package/starter/assets/fonts/InterUI-LICENSE.txt +93 -0
- package/starter/assets/fonts/InterUI-Medium.ttf +0 -0
- package/starter/assets/fonts/InterUI-Regular.ttf +0 -0
- package/starter/assets/fonts/InterUI-source.json +19 -0
- package/starter/assets/fonts/OpenDocMono-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSans-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Italic.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Regular.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-Semibold.ttf +0 -0
- package/starter/assets/fonts/OpenDocSerif-SemiboldItalic.ttf +0 -0
- package/starter/assets/fonts/SourceCode-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSans-LICENSE.md +93 -0
- package/starter/assets/fonts/SourceSerif-LICENSE.md +93 -0
- package/starter/assets/fonts/geist/OFL.txt +93 -0
- package/starter/assets/fonts/geist/asset.json +7 -0
- package/starter/assets/fonts/geist/files/1a9874b3be0fc168692a3d2327bccb4d28835653d3b91537a755296a467a83e3.ttf +0 -0
- package/starter/assets/fonts/geist/files/a8eefb873ba9c9020665f8a98302697ce1f3b79ab2deef6ee508c0ca6a82e876.ttf +0 -0
- package/starter/assets/fonts/geist/files/ccce59465ae5c61930ada5453834f60500fbd95084d85db63e0e65fad0125455.ttf +0 -0
- package/starter/assets/fonts/geist/files/f5e95110d70593672515080bee9148463ada0a7f77b89ed65a3d43cb2b0ff83a.pdf +0 -0
- package/starter/assets/fonts/geist/revisions/9a2bc12fb2f23cb27bc227087e63e1407bb804ee0586480bd6b7966ec69fb474.json +60 -0
- package/starter/assets/fonts/inter/OFL.txt +93 -0
- package/starter/assets/fonts/inter/asset.json +7 -0
- package/starter/assets/fonts/inter/files/1b08e7fc267a5c7e1d614100f604b83e7e8a0be241f0f288faa2b3ac93a683ba.ttf +0 -0
- package/starter/assets/fonts/inter/files/5b6f0c6f26e5c554a64cdcc3a9b5d802b7f9aec6206f1dbcfcdcad7b5860a2a9.ttf +0 -0
- package/starter/assets/fonts/inter/files/957db8560d510a198a7d0333fae7b6b444b00c20801581126273978d778eb3c3.pdf +0 -0
- package/starter/assets/fonts/inter/files/b37284b5701b6b168dfc770aa1a4ac492106422fd3ba76bc7641e37434e8019c.ttf +0 -0
- package/starter/assets/fonts/inter/files/c1811d32ac0f6eed1bbf57529f2ecdfc6c717d48a969dd864942436315a1b198.ttf +0 -0
- package/starter/assets/fonts/inter/files/e7a1aaf7eda9f2fad4131725fa556265ec75ca7b2d756260173a040363e8d4f7.ttf +0 -0
- package/starter/assets/fonts/inter/files/ef8f755d933b9310804cc9152f1f18cb2ac460d6b05054ec913d889c9f11f79e.ttf +0 -0
- package/starter/assets/fonts/inter/revisions/600391517c413963b71e278a57c26c40366c81fa3939a6b9755f446206766d12.json +99 -0
- package/starter/assets/fonts/inter/source.json +57 -0
- package/starter/assets/fonts/lato/OFL.txt +93 -0
- package/starter/assets/fonts/lato/asset.json +7 -0
- package/starter/assets/fonts/lato/files/4a6b566dbb28adb473a8789ce5169306f42f0c8a070ac92bae93636f36348b0d.pdf +0 -0
- package/starter/assets/fonts/lato/files/5adeb6b334d8fb99ef053bc052b952773d544315e0e1d668a12c0ce8bd51375c.ttf +0 -0
- package/starter/assets/fonts/lato/files/62c1b7f0d2e74b45960154c3520efc337b553db0961bfdc950d5618334596cc8.ttf +0 -0
- package/starter/assets/fonts/lato/files/71b8b7decbe75a881ed267be539d402bd1e9420b799658aada4e0d1bd5af803c.ttf +0 -0
- package/starter/assets/fonts/lato/files/8a0aace75d33794eece4b28187bfc1df0bbd2888b5d8a56e01788c8d65d16be1.ttf +0 -0
- package/starter/assets/fonts/lato/files/d636e4683231f931eda222d588e944d082bfd3bdba02f928bee461c0f185b251.ttf +0 -0
- package/starter/assets/fonts/lato/files/e399c44efe1387100531d26c7e4800c5d12251b890d6654a3098c7c679cb1786.ttf +0 -0
- package/starter/assets/fonts/lato/revisions/49ccb93400a9d466fab7d9843b1ecf8916ec6d47a475dd79a597a22eb39616bc.json +99 -0
- package/starter/assets/fonts/lato/source.json +57 -0
- package/starter/assets/fonts/merriweather/OFL.txt +93 -0
- package/starter/assets/fonts/merriweather/asset.json +7 -0
- package/starter/assets/fonts/merriweather/files/1c54f91b910454251c4c2b7bd4e472e1abf265fba7ca3c0ef2eee2f41324099e.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/8bde8da2bb7f0265e27ba0481f70bb48d0f98a976c145f2f239c648ddd6532e0.pdf +0 -0
- package/starter/assets/fonts/merriweather/files/90b7db4460fcd1a5ca49575c2668a793f3cd6447664d312a068d690e1c01e6bc.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/afff81272b7653417bb6f8bef57add055b1f9fda36f27eba5f32b40752bd08da.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e029d3b71e5bae3877c73f4f2b15af28db16593d49b0aed2a328d37ff7075846.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/e9864a6790bf712a04e20f3662b206a1535186ed3e877fd859dd5fb9682335df.ttf +0 -0
- package/starter/assets/fonts/merriweather/files/fa71baebdd20a7d0de2e5e445a5922530fe9e1d740efbe791f113b682d3cb093.ttf +0 -0
- package/starter/assets/fonts/merriweather/revisions/1888e390b3e4f38a3d7cd2dc1bb805aeb6ce13f986a97656f0265fd436bc91d2.json +99 -0
- package/starter/assets/fonts/merriweather/source.json +57 -0
- package/starter/assets/fonts/open-sans/OFL.txt +92 -0
- package/starter/assets/fonts/open-sans/asset.json +7 -0
- package/starter/assets/fonts/open-sans/files/1bc0594a83762b2c25d38915a34464b7fec6088298ca22d151757bf98d6700ec.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/47ed1cfaa7ffca04a04ab850b2938fd52c09d1b44cfa3e2980878e166b0cbd87.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/574939af301f07df8e21cfff279465c5981dd9d9cf62086f7515897df951c6f5.pdf +0 -0
- package/starter/assets/fonts/open-sans/files/6d3884d0d57c1b67e9c50c54eca7b69c535c114e76bd7a9cfda0258588185553.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/733eb93b167e6d45de09aa768f6c0355647c2c26f5416dbc7407a08ed41e81c6.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/75367e6da7d914eaed87883ba51b2a2b5816b5cdbb39f96ec5c81a5b032bfd5a.ttf +0 -0
- package/starter/assets/fonts/open-sans/files/ff4fdc11204e0edd14e9a0bb6c374b847a9093b0ec2c16702e03afca79ac4ef7.ttf +0 -0
- package/starter/assets/fonts/open-sans/revisions/bbbe3a4915b9bccbc883c0decb4097511c43b6bd09ae22a1516aff128c219bc5.json +99 -0
- package/starter/assets/fonts/open-sans/source.json +57 -0
- package/starter/assets/fonts/roboto/OFL.txt +93 -0
- package/starter/assets/fonts/roboto/asset.json +7 -0
- package/starter/assets/fonts/roboto/files/22d45d989248a624252b8382067ac56550212fa675dcdbaf12f03d297dd87a58.pdf +0 -0
- package/starter/assets/fonts/roboto/files/35757eaa996b3359022f47f164a67ee9eac04971af24c5b8fbd4b89e844ff190.ttf +0 -0
- package/starter/assets/fonts/roboto/files/4d3035883c531846bd1ce2dc89f36d932e72dc114f56062c7e3a9cdd74f3d3ea.ttf +0 -0
- package/starter/assets/fonts/roboto/files/be7639306a4fc4a02ce2ae2ff59eb1335e4db4a7379dd0a384ed7cc053817789.ttf +0 -0
- package/starter/assets/fonts/roboto/files/d2920cbb1b60a3fd11fbf22049286e43a6baf522d37fdf1e7c89562319bcfea5.ttf +0 -0
- package/starter/assets/fonts/roboto/files/dece7c71bbe61710787f0839c722c65e87355dd2eb4a823e6b5488121ff81e4b.ttf +0 -0
- package/starter/assets/fonts/roboto/files/f478ba88b0292e685e487901dfbb1401457d32d6ebee4030cdfd5698235bffa8.ttf +0 -0
- package/starter/assets/fonts/roboto/revisions/bda5e2d84c17313373dd2dbf3e64fe0dd450c7e1b59e6929e69557e122fe976e.json +99 -0
- package/starter/assets/fonts/roboto/source.json +57 -0
- package/starter/assets/logos/opendoc/asset.json +6 -0
- package/starter/assets/logos/opendoc/files/831d5ccd9eb6709cc8439ea257c03d81452e81a28a3d1eedbd6a3b7daff687b6.png +0 -0
- package/starter/assets/logos/opendoc/revisions/834dde8926ddb81de687254195a168bb13bfb77803307f1257de1f2228be63b2.json +33 -0
- package/starter/assets/ui-fonts/geist/OFL.txt +93 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-ext-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-italic.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/geist-latin-wght-normal.woff2 +0 -0
- package/starter/assets/ui-fonts/geist/source.json +26 -0
- package/starter/documents/welcome/assets.json +7 -0
- package/starter/documents/welcome/index.tsx +160 -0
- package/starter/documents/welcome/media/.gitkeep +0 -0
- package/starter/documents/welcome/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome/media/studio-rhythm/chart.svg +2343 -0
- package/starter/documents/welcome/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome/media/studio-rhythm/meta.json +11 -0
- package/starter/documents/welcome/media/studio-rhythm/recipe.py +79 -0
- package/starter/documents/welcome/theme.tsx +5 -0
- package/starter/documents/welcome-presentation/assets.json +7 -0
- package/starter/documents/welcome-presentation/index.tsx +166 -0
- package/starter/documents/welcome-presentation/media/.gitkeep +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/image.png +0 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/meta.json +9 -0
- package/starter/documents/welcome-presentation/media/paper-architecture/prompt.txt +1 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/chart.svg +1336 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/data.json +234 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/generation.json +9 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/image.png +0 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/meta.json +13 -0
- package/starter/documents/welcome-presentation/media/studio-rhythm/recipe.py +49 -0
- package/starter/documents/welcome-presentation/theme.tsx +5 -0
- package/starter/projects.json +17 -0
- package/starter/templates/AGENTS.md +9 -0
- package/starter/templates/_shared/BusinessLogo.tsx +14 -0
- package/starter/templates/_shared/Pricing.tsx +40 -0
- package/starter/templates/_shared/commerce.ts +93 -0
- package/starter/templates/brand-guidelines/AGENTS.md +32 -0
- package/starter/templates/brand-guidelines/index.tsx +62 -0
- package/starter/templates/brand-guidelines/preview.tsx +181 -0
- package/starter/templates/brand-guidelines/starter.tsx +179 -0
- package/starter/templates/brand-guidelines/template.json +15 -0
- package/starter/templates/business-proposal/AGENTS.md +13 -0
- package/starter/templates/business-proposal/README.md +36 -0
- package/starter/templates/business-proposal/data.json +37 -0
- package/starter/templates/business-proposal/examples/long.json +142 -0
- package/starter/templates/business-proposal/examples/sparse.json +17 -0
- package/starter/templates/business-proposal/examples/typical.json +37 -0
- package/starter/templates/business-proposal/index.tsx +59 -0
- package/starter/templates/business-proposal/preview.tsx +47 -0
- package/starter/templates/business-proposal/schema.ts +14 -0
- package/starter/templates/business-proposal/starter.tsx +18 -0
- package/starter/templates/business-proposal/template.json +11 -0
- package/starter/templates/company-profile/AGENTS.md +48 -0
- package/starter/templates/company-profile/index.tsx +69 -0
- package/starter/templates/company-profile/preview.tsx +185 -0
- package/starter/templates/company-profile/starter.tsx +186 -0
- package/starter/templates/company-profile/template.json +15 -0
- package/starter/templates/consulting-report/AGENTS.md +11 -0
- package/starter/templates/consulting-report/README.md +13 -0
- package/starter/templates/consulting-report/RESEARCH.md +10 -0
- package/starter/templates/consulting-report/index.tsx +44 -0
- package/starter/templates/consulting-report/preview.tsx +39 -0
- package/starter/templates/consulting-report/starter.tsx +15 -0
- package/starter/templates/consulting-report/template.json +11 -0
- package/starter/templates/editorial-essay/AGENTS.md +11 -0
- package/starter/templates/editorial-essay/README.md +11 -0
- package/starter/templates/editorial-essay/index.tsx +30 -0
- package/starter/templates/editorial-essay/preview.tsx +26 -0
- package/starter/templates/editorial-essay/starter.tsx +15 -0
- package/starter/templates/editorial-essay/template.json +11 -0
- package/starter/templates/executive-brief/AGENTS.md +9 -0
- package/starter/templates/executive-brief/README.md +11 -0
- package/starter/templates/executive-brief/index.tsx +33 -0
- package/starter/templates/executive-brief/preview.tsx +37 -0
- package/starter/templates/executive-brief/starter.tsx +11 -0
- package/starter/templates/executive-brief/template.json +11 -0
- package/starter/templates/image-story/AGENTS.md +37 -0
- package/starter/templates/image-story/index.tsx +106 -0
- package/starter/templates/image-story/preview.tsx +33 -0
- package/starter/templates/image-story/starter.tsx +24 -0
- package/starter/templates/image-story/template.json +13 -0
- package/starter/templates/invoice/AGENTS.md +13 -0
- package/starter/templates/invoice/README.md +40 -0
- package/starter/templates/invoice/data.json +61 -0
- package/starter/templates/invoice/examples/long.json +241 -0
- package/starter/templates/invoice/examples/sparse.json +33 -0
- package/starter/templates/invoice/examples/typical.json +61 -0
- package/starter/templates/invoice/index.tsx +57 -0
- package/starter/templates/invoice/preview.tsx +12 -0
- package/starter/templates/invoice/schema.ts +45 -0
- package/starter/templates/invoice/starter.tsx +12 -0
- package/starter/templates/invoice/template.json +11 -0
- package/starter/templates/literary-text/AGENTS.md +9 -0
- package/starter/templates/literary-text/README.md +11 -0
- package/starter/templates/literary-text/index.tsx +31 -0
- package/starter/templates/literary-text/preview.tsx +20 -0
- package/starter/templates/literary-text/starter.tsx +11 -0
- package/starter/templates/literary-text/template.json +11 -0
- package/starter/templates/magazine-feature/AGENTS.md +11 -0
- package/starter/templates/magazine-feature/README.md +13 -0
- package/starter/templates/magazine-feature/index.tsx +41 -0
- package/starter/templates/magazine-feature/preview.tsx +34 -0
- package/starter/templates/magazine-feature/starter.tsx +15 -0
- package/starter/templates/magazine-feature/template.json +11 -0
- package/starter/templates/monthly-report/AGENTS.md +11 -0
- package/starter/templates/monthly-report/README.md +24 -0
- package/starter/templates/monthly-report/data.json +131 -0
- package/starter/templates/monthly-report/examples/long.json +519 -0
- package/starter/templates/monthly-report/examples/sparse.json +20 -0
- package/starter/templates/monthly-report/examples/typical.json +37 -0
- package/starter/templates/monthly-report/index.tsx +92 -0
- package/starter/templates/monthly-report/preview.tsx +14 -0
- package/starter/templates/monthly-report/schema.ts +127 -0
- package/starter/templates/monthly-report/starter.tsx +13 -0
- package/starter/templates/monthly-report/template.json +11 -0
- package/starter/templates/pitch-deck/AGENTS.md +32 -0
- package/starter/templates/pitch-deck/index.tsx +46 -0
- package/starter/templates/pitch-deck/preview.tsx +142 -0
- package/starter/templates/pitch-deck/starter.tsx +140 -0
- package/starter/templates/pitch-deck/template.json +15 -0
- package/starter/templates/proposal-deck/AGENTS.md +25 -0
- package/starter/templates/proposal-deck/index.tsx +52 -0
- package/starter/templates/proposal-deck/preview.tsx +172 -0
- package/starter/templates/proposal-deck/starter.tsx +168 -0
- package/starter/templates/proposal-deck/template.json +7 -0
- package/starter/templates/quotation/AGENTS.md +13 -0
- package/starter/templates/quotation/README.md +42 -0
- package/starter/templates/quotation/data.json +64 -0
- package/starter/templates/quotation/examples/long.json +272 -0
- package/starter/templates/quotation/examples/sparse.json +31 -0
- package/starter/templates/quotation/examples/typical.json +64 -0
- package/starter/templates/quotation/index.tsx +51 -0
- package/starter/templates/quotation/preview.tsx +12 -0
- package/starter/templates/quotation/schema.ts +27 -0
- package/starter/templates/quotation/starter.tsx +12 -0
- package/starter/templates/quotation/template.json +11 -0
- package/starter/templates/scientific-paper/AGENTS.md +11 -0
- package/starter/templates/scientific-paper/README.md +13 -0
- package/starter/templates/scientific-paper/index.tsx +47 -0
- package/starter/templates/scientific-paper/preview.tsx +43 -0
- package/starter/templates/scientific-paper/starter.tsx +15 -0
- package/starter/templates/scientific-paper/template.json +11 -0
- package/starter/themes/Specimen.tsx +54 -0
- package/starter/themes/civic-spectrum/components.tsx +92 -0
- package/starter/themes/civic-spectrum/design.md +70 -0
- package/starter/themes/civic-spectrum/index.ts +57 -0
- package/starter/themes/civic-spectrum/preview.tsx +66 -0
- package/starter/themes/field-manual/components.tsx +106 -0
- package/starter/themes/field-manual/design.md +72 -0
- package/starter/themes/field-manual/index.ts +57 -0
- package/starter/themes/field-manual/preview.tsx +82 -0
- package/starter/themes/index.ts +3 -0
- package/starter/themes/mckinsey-consulting/components.tsx +69 -0
- package/starter/themes/mckinsey-consulting/design.md +68 -0
- package/starter/themes/mckinsey-consulting/index.ts +60 -0
- package/starter/themes/mckinsey-consulting/preview.tsx +53 -0
- package/starter/themes/neutral/design.md +35 -0
- package/starter/themes/neutral/index.ts +21 -0
- package/starter/themes/neutral/preview.tsx +4 -0
- package/starter/themes/opendoc-neutral/components.tsx +77 -0
- package/starter/themes/opendoc-neutral/design.md +70 -0
- package/starter/themes/opendoc-neutral/index.ts +54 -0
- package/starter/themes/opendoc-neutral/preview.tsx +43 -0
- package/starter/themes/types.ts +3 -0
- package/tsconfig.workspace.json +24 -0
- package/vendor/formepdf/LICENSE +21 -0
- package/vendor/formepdf/README.md +97 -0
- package/vendor/formepdf/font-subset.patch +228 -0
- package/vendor/formepdf/text-writer.patch +507 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { Document, Pages, Paragraph, Section, TitleBlock, DataTable, Heading, TextSlot, Block, View, type TextFieldPath, type DocumentMeta } from 'opendoc';
|
|
3
|
+
import { defineTemplate } from 'opendoc/template';
|
|
4
|
+
import type { DocTheme } from 'opendoc/themes';
|
|
5
|
+
import { parseMonthlyReport, type MonthlyReportData, type ReportMetric } from './schema';
|
|
6
|
+
|
|
7
|
+
export { parseMonthlyReport } from './schema';
|
|
8
|
+
export type { MonthlyReportData, NarrativeItem, ReportMetric, ReportRisk, ReportAction } from './schema';
|
|
9
|
+
|
|
10
|
+
const dateLabel = (value: string) => {
|
|
11
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
12
|
+
return `${day} ${['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][month - 1]} ${year}`;
|
|
13
|
+
};
|
|
14
|
+
const metricValue = (value: number | undefined, metric: ReportMetric) => value === undefined ? '—' :
|
|
15
|
+
`${value.toLocaleString('en-US', { minimumFractionDigits: metric.precision, maximumFractionDigits: metric.precision })}${metric.unit ? `${metric.unit === '%' ? '' : ' '}${metric.unit}` : ''}`;
|
|
16
|
+
const statusLabel = { planned: 'Planned', 'in-progress': 'In progress', complete: 'Complete' };
|
|
17
|
+
// Length-prefixing separates record IDs from reserved child suffixes such as -heading.
|
|
18
|
+
const recordBlock = (kind: string, id: string) => `${kind}-${id.length}-${id}`;
|
|
19
|
+
|
|
20
|
+
/** Keep only a short opening with its heading; arbitrary data prose remains free to flow. */
|
|
21
|
+
function Narrative({ id, title, body, field, sectionHeading, level = 3, children }: {
|
|
22
|
+
id: string; title: ReactNode; body: string; field: TextFieldPath; sectionHeading?: ReactNode; level?: 2 | 3; children?: ReactNode;
|
|
23
|
+
}) {
|
|
24
|
+
const opening = (lead: ReactNode) => <View wrap={false}>
|
|
25
|
+
{sectionHeading}<Section id={id} title={title} level={level} lead={lead} />
|
|
26
|
+
</View>;
|
|
27
|
+
if (body.length <= 420) return <>{opening(<TextSlot slot="body" field={field}>{body}</TextSlot>)}{children}</>;
|
|
28
|
+
const sentence = body.match(/^.{1,420}?[.!?](?=\s|$)/s)?.[0];
|
|
29
|
+
const boundary = sentence?.length ?? body.lastIndexOf(' ', 420);
|
|
30
|
+
// Never alter a supplied word by cutting it to fit the opening.
|
|
31
|
+
if (boundary < 1) return <>
|
|
32
|
+
{sectionHeading}
|
|
33
|
+
<Heading id={`${id}-heading`} level={level}>{title}</Heading>
|
|
34
|
+
<Paragraph id={`${id}-body`}><TextSlot slot="body" field={field}>{body}</TextSlot></Paragraph>{children}
|
|
35
|
+
</>;
|
|
36
|
+
const reason = 'This narrative flows in multiple blocks. Ask your agent to edit its full text in data.json.';
|
|
37
|
+
return <>{opening(<TextSlot slot="body-opening" reason={reason}>{body.slice(0, boundary)}</TextSlot>)}
|
|
38
|
+
<Paragraph id={`${id}-body`}><TextSlot slot="body-continuation" reason={reason}>{body.slice(boundary).trimStart()}</TextSlot></Paragraph>{children}
|
|
39
|
+
</>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const monthlyReportTemplate = (theme: DocTheme) => defineTemplate<MonthlyReportData>({
|
|
43
|
+
parse: parseMonthlyReport,
|
|
44
|
+
meta: data => ({
|
|
45
|
+
title: data.title,
|
|
46
|
+
description: `An operational review for ${data.organization}, ${dateLabel(data.period.start)} to ${dateLabel(data.period.end)}.`,
|
|
47
|
+
kind: 'report', theme: theme.id, author: data.preparedBy ?? data.organization,
|
|
48
|
+
} satisfies DocumentMeta),
|
|
49
|
+
render: data => <Document title={data.title} author={data.preparedBy ?? data.organization} theme={theme}>
|
|
50
|
+
<Pages title={`${data.organization} / ${data.title}`}>
|
|
51
|
+
<TitleBlock id="report-title" eyebrow="Monthly review" title={<TextSlot slot="title" field={['title']}>{data.title}</TextSlot>}
|
|
52
|
+
subtitle={`${dateLabel(data.period.start)} – ${dateLabel(data.period.end)}`}
|
|
53
|
+
byline={<><TextSlot slot="organization" field={['organization']}>{data.organization}</TextSlot>{data.preparedBy ? <> · Prepared by <TextSlot slot="preparedBy" field={['preparedBy']}>{data.preparedBy}</TextSlot></> : ''} · Issued {dateLabel(data.issuedOn)}</>} />
|
|
54
|
+
{data.synthetic && <Paragraph id="sample-notice" role="small" baseStyle={{ fontSize: 9, color: theme.muted, marginBottom: 16 }}>
|
|
55
|
+
Illustrative report. All names, activities, and figures are synthetic; this example is not a performance record.
|
|
56
|
+
</Paragraph>}
|
|
57
|
+
<Narrative id="summary" title="The month in view" body={data.summary} field={['summary']} level={2} />
|
|
58
|
+
{!!data.metrics.length && <DataTable id="performance-table" columns={[
|
|
59
|
+
{ label: 'Measure', width: 2.3 }, { label: 'Actual', width: 1.15, align: 'right' },
|
|
60
|
+
{ label: 'Target', width: 1.15, align: 'right' }, { label: 'Context', width: 3 },
|
|
61
|
+
]} rowIds={data.metrics.map(metric => metric.id)} rows={data.metrics.map(metric => [
|
|
62
|
+
<TextSlot slot={`${recordBlock('metric', metric.id)}-label`} field={['metrics', { id: metric.id }, 'label']}>{metric.label}</TextSlot>,
|
|
63
|
+
<TextSlot slot={`${recordBlock('metric', metric.id)}-actual`} reason="Formatted numeric value. Ask your agent to change its inputs.">{metricValue(metric.value, metric)}</TextSlot>,
|
|
64
|
+
<TextSlot slot={`${recordBlock('metric', metric.id)}-target`} reason="Formatted numeric value. Ask your agent to change its inputs.">{metricValue(metric.target, metric)}</TextSlot>,
|
|
65
|
+
<TextSlot slot={`${recordBlock('metric', metric.id)}-note`} field={['metrics', { id: metric.id }, 'note']}>{metric.note ?? '—'}</TextSlot>,
|
|
66
|
+
])} caption="Performance at a glance" />}
|
|
67
|
+
{!!data.highlights.length && <Block id="highlights">
|
|
68
|
+
{data.highlights.map((item, index) => <Narrative key={item.id} id={recordBlock('highlight', item.id)} sectionHeading={index === 0 && <Heading id="highlights-heading">What changed</Heading>} title={<TextSlot slot="title" field={['highlights', { id: item.id }, 'title']}>{item.title}</TextSlot>} body={item.body} field={['highlights', { id: item.id }, 'body']} />)}
|
|
69
|
+
</Block>}
|
|
70
|
+
{!!data.risks.length && <Block id="risks">
|
|
71
|
+
{data.risks.map((risk, index) => <Narrative key={risk.id} id={recordBlock('risk', risk.id)} sectionHeading={index === 0 && <Heading id="risks-heading">Risks and responses</Heading>} title={<><TextSlot slot="title" field={['risks', { id: risk.id }, 'title']}>{risk.title}</TextSlot> / {risk.level.charAt(0).toUpperCase()}{risk.level.slice(1)}</>}
|
|
72
|
+
body={risk.mitigation} field={['risks', { id: risk.id }, 'mitigation']}>
|
|
73
|
+
<Paragraph id={`${recordBlock('risk', risk.id)}-owner`} role="small" baseStyle={{ fontSize: 9, color: theme.muted }}>Owner: <TextSlot slot="owner" field={['risks', { id: risk.id }, 'owner']}>{risk.owner}</TextSlot></Paragraph>
|
|
74
|
+
</Narrative>)}
|
|
75
|
+
</Block>}
|
|
76
|
+
{!!data.actions.length && <DataTable id="actions-table" columns={[
|
|
77
|
+
{ label: 'Commitment', width: 4 }, { label: 'Owner', width: 1.4 }, { label: 'Due', width: 1.4 }, { label: 'Status', width: 1.3 },
|
|
78
|
+
]} rowIds={data.actions.map(action => action.id)} rows={data.actions.map(action => [
|
|
79
|
+
<TextSlot slot={`${recordBlock('action', action.id)}-title`} field={['actions', { id: action.id }, 'title']}>{action.title}</TextSlot>,
|
|
80
|
+
<TextSlot slot={`${recordBlock('action', action.id)}-owner`} field={['actions', { id: action.id }, 'owner']}>{action.owner}</TextSlot>,
|
|
81
|
+
<TextSlot slot={`${recordBlock('action', action.id)}-due`} reason="Formatted date. Ask your agent to change its input.">{dateLabel(action.due)}</TextSlot>,
|
|
82
|
+
<TextSlot slot={`${recordBlock('action', action.id)}-status`} reason="Reported status. Ask your agent to change its input.">{statusLabel[action.status]}</TextSlot>,
|
|
83
|
+
])} caption="Next commitments" />}
|
|
84
|
+
{!!data.notes.length && <Block id="notes">
|
|
85
|
+
{data.notes.map((note, index) => <Narrative key={note.id} id={recordBlock('note', note.id)} sectionHeading={index === 0 && <Heading id="notes-heading">Reading the report</Heading>} title={<TextSlot slot="title" field={['notes', { id: note.id }, 'title']}>{note.title}</TextSlot>} body={note.body} field={['notes', { id: note.id }, 'body']} />)}
|
|
86
|
+
</Block>}
|
|
87
|
+
<Paragraph id="source-note" role="small" baseStyle={{ fontSize: 9, color: theme.muted, marginTop: 16 }}>
|
|
88
|
+
Basis of this report. <TextSlot slot="sourceNote" field={['sourceNote']}>{data.sourceNote}</TextSlot>
|
|
89
|
+
</Paragraph>
|
|
90
|
+
</Pages>
|
|
91
|
+
</Document>,
|
|
92
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { monthlyReportTemplate } from './index';
|
|
2
|
+
import { bindTemplate } from 'opendoc/template';
|
|
3
|
+
import { neutral } from '../../themes';
|
|
4
|
+
import { type DocTheme } from 'opendoc/themes';
|
|
5
|
+
import example from './examples/typical.json';
|
|
6
|
+
|
|
7
|
+
export const meta = { title: 'Monthly report specimen', description: 'A synthetic operational review showing the repeatable report template.', kind: 'report' as const, theme: neutral.id };
|
|
8
|
+
|
|
9
|
+
export function Specimen({ theme = neutral }: { theme?: DocTheme }) {
|
|
10
|
+
const bound = bindTemplate(monthlyReportTemplate(theme), example);
|
|
11
|
+
return <bound.Document />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default function Preview() { return <Specimen />; }
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export interface NarrativeItem { id: string; title: string; body: string }
|
|
2
|
+
export interface ReportMetric {
|
|
3
|
+
id: string; label: string; value: number; target?: number; unit?: string; precision: number; note?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ReportRisk {
|
|
6
|
+
id: string; title: string; level: 'low' | 'medium' | 'high'; owner: string; mitigation: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ReportAction {
|
|
9
|
+
id: string; title: string; owner: string; due: string; status: 'planned' | 'in-progress' | 'complete';
|
|
10
|
+
}
|
|
11
|
+
export interface MonthlyReportData {
|
|
12
|
+
schemaVersion: 1;
|
|
13
|
+
title: string;
|
|
14
|
+
organization: string;
|
|
15
|
+
preparedBy?: string;
|
|
16
|
+
period: { start: string; end: string };
|
|
17
|
+
issuedOn: string;
|
|
18
|
+
synthetic: boolean;
|
|
19
|
+
sourceNote: string;
|
|
20
|
+
summary: string;
|
|
21
|
+
metrics: ReportMetric[];
|
|
22
|
+
highlights: NarrativeItem[];
|
|
23
|
+
risks: ReportRisk[];
|
|
24
|
+
actions: ReportAction[];
|
|
25
|
+
notes: NarrativeItem[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Validate the report at its data boundary, before any PDF is rendered. */
|
|
29
|
+
export function parseMonthlyReport(input: unknown): MonthlyReportData {
|
|
30
|
+
const errors: string[] = [];
|
|
31
|
+
const fail = (path: string, message: string) => { errors.push(`${path}: ${message}`); };
|
|
32
|
+
const object = (value: unknown, path: string): Record<string, unknown> => {
|
|
33
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) { fail(path, 'expected an object'); return {}; }
|
|
34
|
+
return value as Record<string, unknown>;
|
|
35
|
+
};
|
|
36
|
+
const fields = (value: Record<string, unknown>, allowed: readonly string[], path: string) => {
|
|
37
|
+
for (const key of Object.keys(value)) if (!allowed.includes(key)) fail(`${path}.${key}`, 'unknown field');
|
|
38
|
+
};
|
|
39
|
+
const text = (value: unknown, path: string): string => {
|
|
40
|
+
if (typeof value !== 'string' || !value.trim()) { fail(path, 'expected non-empty text'); return ''; }
|
|
41
|
+
return value.trim();
|
|
42
|
+
};
|
|
43
|
+
const optionalText = (value: unknown, path: string): string | undefined => {
|
|
44
|
+
if (value === undefined || value === null || typeof value === 'string' && !value.trim()) return undefined;
|
|
45
|
+
return text(value, path);
|
|
46
|
+
};
|
|
47
|
+
const number = (value: unknown, path: string): number => {
|
|
48
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) { fail(path, 'expected a finite number'); return 0; }
|
|
49
|
+
return value;
|
|
50
|
+
};
|
|
51
|
+
const date = (value: unknown, path: string): string => {
|
|
52
|
+
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(value)) { fail(path, 'use a real date in YYYY-MM-DD format'); return ''; }
|
|
53
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
54
|
+
const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
55
|
+
const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
56
|
+
if (year < 1 || month < 1 || month > 12 || day < 1 || day > (days[month - 1] ?? 0)) {
|
|
57
|
+
fail(path, 'use a real calendar date'); return '';
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
};
|
|
61
|
+
const oneOf = <T extends string>(value: unknown, choices: readonly T[], path: string): T => {
|
|
62
|
+
if (typeof value !== 'string' || !choices.includes(value as T)) { fail(path, `choose ${choices.join(', ')}`); return choices[0]; }
|
|
63
|
+
return value as T;
|
|
64
|
+
};
|
|
65
|
+
const items = <T>(value: unknown, path: string, parse: (item: Record<string, unknown>, path: string, id: string) => T): T[] => {
|
|
66
|
+
if (value === undefined || value === null) return [];
|
|
67
|
+
if (!Array.isArray(value)) { fail(path, 'expected an array, or null for no entries'); return []; }
|
|
68
|
+
const seen = new Set<string>();
|
|
69
|
+
return value.map((entry, index) => {
|
|
70
|
+
const itemPath = `${path}[${index}]`;
|
|
71
|
+
const item = object(entry, itemPath);
|
|
72
|
+
const id = text(item.id, `${itemPath}.id`);
|
|
73
|
+
if (id && !/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(id)) fail(`${itemPath}.id`, 'use a stable ID with letters, numbers, dots, hyphens, or underscores');
|
|
74
|
+
if (seen.has(id)) fail(`${itemPath}.id`, `duplicate ID "${id}" in ${path}`);
|
|
75
|
+
seen.add(id);
|
|
76
|
+
return parse(item, itemPath, id);
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
const narrative = (item: Record<string, unknown>, path: string, id: string): NarrativeItem => {
|
|
80
|
+
fields(item, ['id', 'title', 'body'], path);
|
|
81
|
+
return { id, title: text(item.title, `${path}.title`), body: text(item.body, `${path}.body`) };
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const data = object(input, 'report');
|
|
85
|
+
fields(data, ['schemaVersion', 'title', 'organization', 'preparedBy', 'period', 'issuedOn', 'synthetic', 'sourceNote', 'summary', 'metrics', 'highlights', 'risks', 'actions', 'notes'], 'report');
|
|
86
|
+
if (data.schemaVersion !== 1) fail('report.schemaVersion', 'expected 1');
|
|
87
|
+
const period = object(data.period, 'report.period');
|
|
88
|
+
fields(period, ['start', 'end'], 'report.period');
|
|
89
|
+
const start = date(period.start, 'report.period.start');
|
|
90
|
+
const end = date(period.end, 'report.period.end');
|
|
91
|
+
if (start && end && start > end) fail('report.period.end', 'must be on or after period.start');
|
|
92
|
+
if (typeof data.synthetic !== 'boolean') fail('report.synthetic', 'expected true or false; explicitly identify illustrative data');
|
|
93
|
+
|
|
94
|
+
const result: MonthlyReportData = {
|
|
95
|
+
schemaVersion: 1,
|
|
96
|
+
title: text(data.title, 'report.title'),
|
|
97
|
+
organization: text(data.organization, 'report.organization'),
|
|
98
|
+
preparedBy: optionalText(data.preparedBy, 'report.preparedBy'),
|
|
99
|
+
period: { start, end },
|
|
100
|
+
issuedOn: date(data.issuedOn, 'report.issuedOn'),
|
|
101
|
+
synthetic: data.synthetic === true,
|
|
102
|
+
sourceNote: text(data.sourceNote, 'report.sourceNote'),
|
|
103
|
+
summary: text(data.summary, 'report.summary'),
|
|
104
|
+
metrics: items(data.metrics, 'report.metrics', (item, path, id) => {
|
|
105
|
+
fields(item, ['id', 'label', 'value', 'target', 'unit', 'precision', 'note'], path);
|
|
106
|
+
const precision = item.precision === undefined || item.precision === null ? 0 : number(item.precision, `${path}.precision`);
|
|
107
|
+
if (!Number.isInteger(precision) || precision < 0 || precision > 3) fail(`${path}.precision`, 'use a whole number from 0 to 3');
|
|
108
|
+
return { id, label: text(item.label, `${path}.label`), value: number(item.value, `${path}.value`),
|
|
109
|
+
target: item.target === undefined || item.target === null ? undefined : number(item.target, `${path}.target`),
|
|
110
|
+
unit: optionalText(item.unit, `${path}.unit`), precision, note: optionalText(item.note, `${path}.note`) };
|
|
111
|
+
}),
|
|
112
|
+
highlights: items(data.highlights, 'report.highlights', narrative),
|
|
113
|
+
risks: items(data.risks, 'report.risks', (item, path, id) => {
|
|
114
|
+
fields(item, ['id', 'title', 'level', 'owner', 'mitigation'], path);
|
|
115
|
+
return { id, title: text(item.title, `${path}.title`), level: oneOf(item.level, ['low', 'medium', 'high'], `${path}.level`),
|
|
116
|
+
owner: text(item.owner, `${path}.owner`), mitigation: text(item.mitigation, `${path}.mitigation`) };
|
|
117
|
+
}),
|
|
118
|
+
actions: items(data.actions, 'report.actions', (item, path, id) => {
|
|
119
|
+
fields(item, ['id', 'title', 'owner', 'due', 'status'], path);
|
|
120
|
+
return { id, title: text(item.title, `${path}.title`), owner: text(item.owner, `${path}.owner`),
|
|
121
|
+
due: date(item.due, `${path}.due`), status: oneOf(item.status, ['planned', 'in-progress', 'complete'], `${path}.status`) };
|
|
122
|
+
}),
|
|
123
|
+
notes: items(data.notes, 'report.notes', narrative),
|
|
124
|
+
};
|
|
125
|
+
if (errors.length) throw new Error(`Monthly report data needs attention:\n${errors.map(error => `- ${error}`).join('\n')}`);
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { bindTemplate } from 'opendoc/template';
|
|
2
|
+
import { monthlyReportTemplate } from '../../templates/monthly-report';
|
|
3
|
+
// @ts-ignore The selected local theme module is inserted when this starter becomes a document.
|
|
4
|
+
import { theme } from "__OPENDOC_THEME_MODULE__";
|
|
5
|
+
import data from './data.json';
|
|
6
|
+
|
|
7
|
+
const documentId = "__OPENDOC_DOCUMENT_ID__";
|
|
8
|
+
const themeId = "__OPENDOC_THEME__";
|
|
9
|
+
// This copied dataset is illustrative. Replace it with verified information before sharing.
|
|
10
|
+
const bound = bindTemplate(monthlyReportTemplate(theme), data);
|
|
11
|
+
export const meta = { ...bound.meta, theme: themeId };
|
|
12
|
+
export const provenance = { template: 'templates/monthly-report/index.tsx', dataFile: `documents/${documentId}/data.json` };
|
|
13
|
+
export default bound.Document;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Monthly report",
|
|
3
|
+
"description": "A repeatable operational review with validated local data, period measures, narrative highlights, risks, and dated actions. Empty sections are omitted and long reports flow naturally.",
|
|
4
|
+
"format": "A4 · Data-driven report",
|
|
5
|
+
"structure": [
|
|
6
|
+
"The title, organization, reporting period, and preparation details share the first page with an opening summary.",
|
|
7
|
+
"Optional performance measures use explicit units and targets. Tables repeat their headers across pages.",
|
|
8
|
+
"Highlights, risks, actions, and reading notes retain stable record identities as their data changes or moves.",
|
|
9
|
+
"Each document owns its JSON input. A visible source note records the evidence basis; synthetic examples are identified in the PDF."
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Pitch deck
|
|
2
|
+
|
|
3
|
+
A clear venture story with visual conviction: large statements, before/after contrast, an expansive product position, honest evidence, a readable market calculation and a concrete funding ask. This is a replaceable placeholder skeleton, not a fictional company or a claim that every founder needs fourteen slides.
|
|
4
|
+
|
|
5
|
+
## Research basis
|
|
6
|
+
|
|
7
|
+
Primary sources read on September 11, 2026:
|
|
8
|
+
|
|
9
|
+
- [Kevin Hale, How to Design a Better Pitch Deck, Y Combinator](https://www.ycombinator.com/blog/how-to-design-a-better-pitch-deck/) (2015). The design uses large type, high contrast, one principal idea per slide and explicit takeaways. Product visuals should show a single understandable result; simplify or crop a complex screenshot. Hale's short Demo Day context calls for roughly five to seven remembered ideas, not a full investor-meeting deck. Select a short sequence for that use rather than presenting every slide here.
|
|
10
|
+
- [Team Sequoia, Writing a Business Plan](https://sequoiacap.com/article/writing-a-business-plan) (2019). The skeleton covers company purpose, customer pain, solution, timing, market, alternatives, business model, team, financials when available and future vision. Its distinctive concern is clarity about the company and opportunity. These subjects are starting questions; their order and depth should follow the actual venture.
|
|
11
|
+
|
|
12
|
+
The fourteen-slide meeting skeleton, evidence-chart frame, bottom-up market calculation, dedicated go-to-market slide, actuals/assumptions separation and milestone-based ask are this template's synthesis. Neither source prescribes this exact sequence, these layouts or a universal page count. No affiliation or endorsement is implied.
|
|
13
|
+
|
|
14
|
+
## Editable story and sensible variations
|
|
15
|
+
|
|
16
|
+
`starter.tsx` copies every slide, text prompt, image position and local layout choice into the instance. `index.tsx` supplies only native composition helpers. Change the story in `documents/<id>/index.tsx`; do not edit the shared template to correct one company.
|
|
17
|
+
|
|
18
|
+
The starting order is purpose → pain → solution → product → timing → evidence → market → model → acquisition → alternatives → team → financial position → ask → vision. Move exceptional traction or uniquely relevant founders earlier. Merge pain and solution for a simple product. An unlaunched venture should show customer learning, a test or a real commitment instead of pretending to have commercial traction. Remove unavailable financial history; make planning assumptions explicit. Add appendix slides for financial detail, cohort evidence, market calculations, technical diligence or source records when needed.
|
|
19
|
+
|
|
20
|
+
For a short stage pitch, select about five to seven key ideas, increase secondary copy sizes and remove footer detail that belongs in the leave-behind. For an investor meeting or emailed deck, keep the narrative understandable without a presenter and retain useful source notes. Avoid universal market-percentage claims and charts that imply observations where none exist.
|
|
21
|
+
|
|
22
|
+
## Composition contract
|
|
23
|
+
|
|
24
|
+
- `PitchDeck` wraps `Presentation`; `PitchSlide` is one explicit 960 × 540 page. Header titles generally use 38 pt; hero statements use 48–64 pt. These are adaptable presentation sizes, not automatic fitting rules.
|
|
25
|
+
- `PitchText` places a bounded native paragraph with a transparent `body` slot. Its `x`, `y`, `w`, `h`, `size` and color are ordinary caller-controlled choices. A long title may use a smaller explicit size, a wider measure or a different composition. Keep a readable hierarchy; split a crowded slide instead of shrinking all copy.
|
|
26
|
+
- `PitchPanel` supplies structural paper/dark surfaces and rules. `PitchImage` takes an optional managed `image={{item:'id',fit:'contain'}}` source. Use contain for charts and UI that must remain whole; cover with an intentional position for photography. Omitted media shows a labeled empty state; a named missing item is an error.
|
|
27
|
+
- Catalog artwork stays empty. Import each company's actual media into that document's managed library, following [Media](../../docs/MEDIA.md). Use permissioned portraits and product images, and label concepts. The template includes no bundled brand logos or invented customer endorsements.
|
|
28
|
+
- Caller theme fonts, paper, ink and role styles remain live. The geometry and explicit display sizes serve a slide canvas. Dark slides pair theme ink with theme paper; review contrast if adapting to an unusual palette.
|
|
29
|
+
- Keep slide IDs, block IDs and `TextSlot` names stable when reordering or rewriting the same idea. All actual narrative props belong to the instance. New ideas receive new IDs.
|
|
30
|
+
- Each bounded box declares clipping so excess content is rejected rather than silently discarded. Rendering must produce exactly one page per slide. Review every slide after substantial text or theme changes.
|
|
31
|
+
|
|
32
|
+
The Neutral specimen shows the complete layout family. Sparse and long-title render checks, a second McKinsey Consulting theme and disposable creation checks exercise the contract. The current PDF remains the authority for visual review.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import * as F from '@formepdf/react';
|
|
3
|
+
import { Block, Heading, MediaFrame, Paragraph, Presentation, Slide, TextSlot, type ImageFrameOptions } from 'opendoc';
|
|
4
|
+
import { themePage, themeType, type DocTheme } from 'opendoc/themes';
|
|
5
|
+
|
|
6
|
+
type Box = { x: number; y: number; w: number; h: number };
|
|
7
|
+
const at = ({x,y,w,h}: Box): F.Style => ({position:'absolute',left:x,top:y,width:w,height:h,overflow:'hidden'});
|
|
8
|
+
export type PitchImageSource = Pick<ImageFrameOptions,'fit'|'position'|'radius'> & {item:string;alt?:string};
|
|
9
|
+
|
|
10
|
+
export function PitchDeck(props: Parameters<typeof Presentation>[0]) { return <Presentation {...props}/>; }
|
|
11
|
+
|
|
12
|
+
/** A fixed slide canvas with an optional claim-led header. All narrative stays with the caller. */
|
|
13
|
+
export function PitchSlide({id,theme,title,eyebrow,children,dark=false,titleSize=38,titleWidth=864,footer}: {
|
|
14
|
+
id:string;theme:DocTheme;title?:ReactNode;eyebrow?:ReactNode;children?:ReactNode;
|
|
15
|
+
dark?:boolean;titleSize?:number;titleWidth?:number;footer?:ReactNode;
|
|
16
|
+
}) {
|
|
17
|
+
const ink=dark?theme.paper:theme.ink;
|
|
18
|
+
return <Slide id={id} padding={0} style={{...themePage(theme).style,backgroundColor:dark?theme.ink:theme.paper,lineBreaking:'greedy'}}>
|
|
19
|
+
{eyebrow && <F.View style={at({x:48,y:32,w:864,h:22})}><Paragraph id={`${id}-eyebrow`} role="label" style={{fontFamily:theme.body,fontSize:11,lineHeight:1.2,marginBottom:0,color:ink}}><TextSlot slot="eyebrow" from="eyebrow">{eyebrow}</TextSlot></Paragraph></F.View>}
|
|
20
|
+
{title && <F.View style={at({x:48,y:66,w:titleWidth,h:102})}><Heading id={`${id}-title`} level={2} style={{fontSize:titleSize,lineHeight:1.12,marginTop:0,marginBottom:0,color:ink}}><TextSlot slot="title" from="title">{title}</TextSlot></Heading></F.View>}
|
|
21
|
+
{children}
|
|
22
|
+
{footer && <F.View style={at({x:48,y:502,w:802,h:20})}><Paragraph id={`${id}-footer`} role="caption" style={{fontFamily:theme.body,fontSize:10,lineHeight:1.15,marginBottom:0,color:ink}}><TextSlot slot="footer" from="footer">{footer}</TextSlot></Paragraph></F.View>}
|
|
23
|
+
<F.View style={at({x:888,y:502,w:24,h:20})}><F.Text style={{...themeType(theme,'small'),fontFamily:theme.body,fontSize:10,lineHeight:1.15,textAlign:'left',color:ink}}>{'{{pageNumber}}'}</F.Text></F.View>
|
|
24
|
+
</Slide>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Bounded, native, caller-owned copy. Explicit sizes are for presentation distance. */
|
|
28
|
+
export function PitchText({id,theme,body,size=22,weight=400,color,role='body',...box}: Box & {
|
|
29
|
+
id:string;theme:DocTheme;body:ReactNode;size?:number;weight?:400|600;color?:string;role?:'body'|'label'|'caption'|'display';
|
|
30
|
+
}) {
|
|
31
|
+
const typography = role==='display'?themeType(theme,'h1'):role==='body'?{fontFamily:theme.body}:themeType(theme,role);
|
|
32
|
+
return <F.View style={at(box)}><Paragraph id={id} style={{...typography,fontFamily:role==='display'?theme.heading:theme.body,fontSize:size,fontWeight:weight,lineHeight:role==='display'?1.06:1.25,marginTop:0,marginBottom:0,color:color??theme.ink}}><TextSlot slot="body" from="body">{body}</TextSlot></Paragraph></F.View>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Structural surfaces do not introduce content or identities based on page order. */
|
|
36
|
+
export function PitchPanel({id,theme,dark=false,rule=false,children,...box}:Box & {id:string;theme:DocTheme;dark?:boolean;rule?:boolean;children?:ReactNode}) {
|
|
37
|
+
return <Block id={id} style={{...at(box),backgroundColor:dark?theme.ink:theme.paper,...(rule?{borderWidth:1,borderColor:theme.line}:{})}}>{children}</Block>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** An omitted source is an intentional placeholder; a named missing item must fail normally. */
|
|
41
|
+
export function PitchImage({id,theme,image,label,detail,...box}:Box & {id:string;theme:DocTheme;image?:PitchImageSource;label:string;detail?:string}) {
|
|
42
|
+
return <Block id={id} style={at(box)}>{image ? <MediaFrame {...image} width={box.w} height={box.h}/> : <F.View style={{width:box.w,height:box.h,borderWidth:1,borderColor:theme.line,backgroundColor:theme.paper,justifyContent:'center',padding:24}}>
|
|
43
|
+
<Paragraph id={`${id}-label`} style={{fontFamily:theme.body,fontSize:18,fontWeight:600,lineHeight:1.2,textAlign:'center',marginBottom:detail?10:0,color:theme.ink}}><TextSlot slot="label" from="label">{label}</TextSlot></Paragraph>
|
|
44
|
+
{detail && <Paragraph id={`${id}-detail`} role="caption" style={{fontFamily:theme.body,fontSize:12,lineHeight:1.3,textAlign:'center',marginBottom:0,color:theme.muted}}><TextSlot slot="detail" from="detail">{detail}</TextSlot></Paragraph>}
|
|
45
|
+
</F.View>}</Block>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { PitchDeck, PitchSlide, PitchText, PitchPanel, PitchImage } from './index';
|
|
2
|
+
import { neutral } from '../../themes';
|
|
3
|
+
import { type DocTheme } from 'opendoc/themes';
|
|
4
|
+
|
|
5
|
+
const title = "Your company.\nOne clear promise.";
|
|
6
|
+
export const meta = { title, description:'A venture pitch. Replace all prompts with supported company material.', kind:'pitch deck', theme:"neutral" };
|
|
7
|
+
export const provenance = {template:'templates/pitch-deck/index.tsx'};
|
|
8
|
+
|
|
9
|
+
// This is your editable story, not a required slide order. Keep stable IDs when reordering.
|
|
10
|
+
// Add managed image={{item:'your-media-id'}} to a PitchImage after importing and reviewing media.
|
|
11
|
+
// Sources, dates and assumptions belong beside the relevant evidence. Move detail to explicit appendix slides.
|
|
12
|
+
export function Specimen({theme=neutral}: {theme?:DocTheme} = {}) {
|
|
13
|
+
return <PitchDeck title={title} theme={theme}>
|
|
14
|
+
<PitchSlide id="purpose" theme={theme} dark eyebrow="COMPANY PURPOSE" footer="[Founder name] / [Contact] / [Date]">
|
|
15
|
+
<PitchText id="company-name" theme={theme} x={48} y={108} w={680} h={150} body={title} role="display" size={64} weight={600} color={theme.paper}/>
|
|
16
|
+
<PitchText id="company-promise" theme={theme} x={48} y={290} w={720} h={112} body="We help [specific customer] achieve [valuable outcome]." size={32} color={theme.paper}/>
|
|
17
|
+
<PitchText id="round-context" theme={theme} x={48} y={448} w={760} h={30} body="[Fundraising stage] / One plain sentence. No category jargon." size={16} color={theme.paper}/>
|
|
18
|
+
</PitchSlide>
|
|
19
|
+
|
|
20
|
+
<PitchSlide id="problem" theme={theme} eyebrow="THE CUSTOMER PAIN" title="A real person. An expensive problem." footer="Evidence placeholder: source, date and customer context.">
|
|
21
|
+
<PitchText id="customer-situation" theme={theme} x={48} y={186} w={390} h={90} body="[Customer] struggles to [important job]." role="display" size={32} weight={600}/>
|
|
22
|
+
<PitchText id="customer-consequence" theme={theme} x={48} y={312} w={360} h={118} body="Describe the cost of the current workaround in time, money or lost opportunity." size={23}/>
|
|
23
|
+
<PitchPanel id="pain-evidence-panel" theme={theme} dark x={492} y={177} w={420} h={291}/>
|
|
24
|
+
<PitchText id="pain-evidence-label" theme={theme} x={524} y={208} w={356} h={25} body="VOICE OF THE CUSTOMER" role="label" size={11} color={theme.paper}/>
|
|
25
|
+
<PitchText id="pain-evidence" theme={theme} x={524} y={258} w={350} h={128} body="[A short, permissioned customer quote or measured observation.]" size={28} color={theme.paper}/>
|
|
26
|
+
<PitchText id="pain-attribution" theme={theme} x={524} y={425} w={350} h={25} body="[Attribution / study / interview date]" size={13} color={theme.paper}/>
|
|
27
|
+
</PitchSlide>
|
|
28
|
+
|
|
29
|
+
<PitchSlide id="solution" theme={theme} eyebrow="THE SOLUTION" title="Show the change your product makes." footer="Replace these prompts with one concrete customer outcome.">
|
|
30
|
+
<PitchPanel id="before-panel" theme={theme} rule x={48} y={178} w={416} h={286}/>
|
|
31
|
+
<PitchPanel id="after-panel" theme={theme} dark x={484} y={178} w={428} h={286}/>
|
|
32
|
+
<PitchText id="before-label" theme={theme} x={76} y={205} w={360} h={24} body="TODAY" role="label" size={12}/>
|
|
33
|
+
<PitchText id="before-outcome" theme={theme} x={76} y={252} w={360} h={110} body="[The frustrating status quo]" role="display" size={34} weight={600}/>
|
|
34
|
+
<PitchText id="before-detail" theme={theme} x={76} y={390} w={360} h={52} body="Describe the workaround, not a straw man." size={18}/>
|
|
35
|
+
<PitchText id="after-label" theme={theme} x={512} y={205} w={372} h={24} body="WITH YOUR PRODUCT" role="label" size={12} color={theme.paper}/>
|
|
36
|
+
<PitchText id="after-outcome" theme={theme} x={512} y={252} w={372} h={110} body="[A clear, valuable improvement]" role="display" size={34} weight={600} color={theme.paper}/>
|
|
37
|
+
<PitchText id="after-detail" theme={theme} x={512} y={390} w={372} h={52} body="Explain the unique insight that makes it possible." size={18} color={theme.paper}/>
|
|
38
|
+
</PitchSlide>
|
|
39
|
+
|
|
40
|
+
<PitchSlide id="product" theme={theme} eyebrow="THE PRODUCT" title="Make the experience immediately clear." footer="Product visual placeholder. Show the real experience; label concept work as a concept.">
|
|
41
|
+
<PitchImage id="product-visual" theme={theme} x={48} y={175} w={558} h={291} label="Product demonstration" detail="Use one cropped product view, physical product photograph or simplified demonstration."/>
|
|
42
|
+
<PitchText id="product-first" theme={theme} x={646} y={188} w={266} h={70} body="01 [Start with the customer's action]" size={23} weight={600}/>
|
|
43
|
+
<PitchText id="product-second" theme={theme} x={646} y={286} w={266} h={70} body="02 [Show the useful transformation]" size={23} weight={600}/>
|
|
44
|
+
<PitchText id="product-third" theme={theme} x={646} y={384} w={266} h={70} body="03 [End with the result]" size={23} weight={600}/>
|
|
45
|
+
</PitchSlide>
|
|
46
|
+
|
|
47
|
+
<PitchSlide id="why-now" theme={theme} dark eyebrow="WHY NOW" footer="Evidence placeholder: dates and sources for the enabling changes.">
|
|
48
|
+
<PitchText id="timing-claim" theme={theme} x={48} y={96} w={820} h={148} body={"What changed\nthat makes this possible now?"} role="display" size={53} weight={600} color={theme.paper}/>
|
|
49
|
+
<PitchText id="timing-shift" theme={theme} x={48} y={302} w={254} h={122} body={"[Technology shift]\nWhat became possible?"} size={25} color={theme.paper}/>
|
|
50
|
+
<PitchText id="timing-behavior" theme={theme} x={350} y={302} w={254} h={122} body={"[Behavior shift]\nWhat do customers now expect?"} size={25} color={theme.paper}/>
|
|
51
|
+
<PitchText id="timing-window" theme={theme} x={652} y={302} w={260} h={122} body={"[Market opening]\nWhy act in this window?"} size={25} color={theme.paper}/>
|
|
52
|
+
</PitchSlide>
|
|
53
|
+
|
|
54
|
+
<PitchSlide id="traction" theme={theme} eyebrow="TRACTION / VALIDATION" title="Lead with your strongest honest evidence." footer="Evidence placeholder: unit, period, cohort, source and whether observed or estimated.">
|
|
55
|
+
<PitchText id="traction-primary" theme={theme} x={48} y={190} w={304} h={93} body="[Metric]" role="display" size={60} weight={600}/>
|
|
56
|
+
<PitchText id="traction-definition" theme={theme} x={48} y={302} w={294} h={100} body="State what it measures and why it shows customers value the product." size={23}/>
|
|
57
|
+
<PitchText id="traction-stage-note" theme={theme} x={48} y={426} w={294} h={45} body="Pre-launch? Use validated learning or committed pilots." size={14}/>
|
|
58
|
+
<PitchImage id="traction-chart" theme={theme} x={400} y={180} w={512} h={285} label="Evidence chart or customer proof" detail="Add actual data with readable axes and a period. No invented growth curve."/>
|
|
59
|
+
</PitchSlide>
|
|
60
|
+
|
|
61
|
+
<PitchSlide id="market" theme={theme} eyebrow="MARKET POTENTIAL" title="Start with a customer you can actually reach." footer="Sizing placeholder: show source dates, assumptions, calculation and currency.">
|
|
62
|
+
<PitchText id="market-beachhead" theme={theme} x={48} y={177} w={830} h={55} body="[Specific initial customer segment + geography]" size={27} weight={600}/>
|
|
63
|
+
<PitchPanel id="market-formula-panel" theme={theme} dark x={48} y={255} w={864} h={122}/>
|
|
64
|
+
<PitchText id="market-count" theme={theme} x={76} y={276} w={244} h={77} body={"[Customers]\nReachable accounts"} size={24} color={theme.paper}/>
|
|
65
|
+
<PitchText id="market-multiply" theme={theme} x={338} y={289} w={40} h={50} body="×" size={36} color={theme.paper}/>
|
|
66
|
+
<PitchText id="market-value" theme={theme} x={398} y={276} w={224} h={77} body={"[Annual value]\nPer account"} size={24} color={theme.paper}/>
|
|
67
|
+
<PitchText id="market-equals" theme={theme} x={640} y={289} w={40} h={50} body="=" size={36} color={theme.paper}/>
|
|
68
|
+
<PitchText id="market-result" theme={theme} x={704} y={276} w={180} h={77} body={"[Market]\nAnnual value"} size={24} color={theme.paper}/>
|
|
69
|
+
<PitchText id="market-expansion" theme={theme} x={48} y={415} w={850} h={52} body="Then explain the credible path into adjacent customers or new uses." size={23}/>
|
|
70
|
+
</PitchSlide>
|
|
71
|
+
|
|
72
|
+
<PitchSlide id="business-model" theme={theme} eyebrow="BUSINESS MODEL" title="Who pays, for what, and why it works." footer="Economics placeholder: separate measured performance from assumptions.">
|
|
73
|
+
<PitchPanel id="business-pricing-panel" theme={theme} dark x={48} y={178} w={328} h={288}/>
|
|
74
|
+
<PitchText id="business-pricing-label" theme={theme} x={76} y={206} w={270} h={25} body="PRICING UNIT" role="label" size={12} color={theme.paper}/>
|
|
75
|
+
<PitchText id="business-pricing" theme={theme} x={76} y={256} w={270} h={116} body={"[Price]\nper [unit]"} role="display" size={42} weight={600} color={theme.paper}/>
|
|
76
|
+
<PitchText id="business-payer" theme={theme} x={76} y={404} w={270} h={42} body="[Buyer / budget owner]" size={19} color={theme.paper}/>
|
|
77
|
+
<PitchText id="business-value" theme={theme} x={424} y={192} w={472} h={98} body={"[Why this is worth paying for]\nConnect price with the buyer's value."} size={25} weight={600}/>
|
|
78
|
+
<PitchText id="business-economics" theme={theme} x={424} y={326} w={472} h={125} body={"[Economics that matter]\nExplain cost to serve, margin or repeat behavior using the measures relevant to your business."} size={23}/>
|
|
79
|
+
</PitchSlide>
|
|
80
|
+
|
|
81
|
+
<PitchSlide id="go-to-market" theme={theme} eyebrow="GO TO MARKET" title="A focused route to the first repeatable growth." footer="Channel evidence placeholder. Distinguish tested acquisition from the plan.">
|
|
82
|
+
<PitchText id="gtm-entry-label" theme={theme} x={48} y={185} w={252} h={40} body="01 / FIND" role="label" size={15}/>
|
|
83
|
+
<PitchText id="gtm-entry" theme={theme} x={48} y={247} w={252} h={170} body={"[Entry channel]\nWhere does your first audience already gather?"} size={25}/>
|
|
84
|
+
<PitchText id="gtm-convert-label" theme={theme} x={352} y={185} w={252} h={40} body="02 / CONVERT" role="label" size={15}/>
|
|
85
|
+
<PitchText id="gtm-convert" theme={theme} x={352} y={247} w={252} h={170} body={"[First value moment]\nWhat moves a prospect from interest into use?"} size={25}/>
|
|
86
|
+
<PitchText id="gtm-repeat-label" theme={theme} x={656} y={185} w={256} h={40} body="03 / REPEAT" role="label" size={15}/>
|
|
87
|
+
<PitchText id="gtm-repeat" theme={theme} x={656} y={247} w={256} h={170} body={"[Repeatable engine]\nWhat evidence makes you believe this can scale?"} size={25}/>
|
|
88
|
+
<PitchText id="gtm-learning" theme={theme} x={48} y={438} w={850} h={36} body="[One next experiment and the success criterion that earns more investment.]" size={18}/>
|
|
89
|
+
</PitchSlide>
|
|
90
|
+
|
|
91
|
+
<PitchSlide id="alternatives" theme={theme} eyebrow="COMPETITION / ALTERNATIVES" title="Show the trade-off that lets you win." footer="Comparison placeholder: verify alternatives, criteria and dates. Include doing nothing.">
|
|
92
|
+
<PitchText id="alternatives-column" theme={theme} x={48} y={174} w={254} h={27} body="CUSTOMER CHOICE" role="label" size={11}/>
|
|
93
|
+
<PitchText id="alternatives-strength-column" theme={theme} x={348} y={174} w={242} h={27} body="WHY THEY CHOOSE IT" role="label" size={11}/>
|
|
94
|
+
<PitchText id="alternatives-gap-column" theme={theme} x={642} y={174} w={270} h={27} body="WHERE YOU DIFFER" role="label" size={11}/>
|
|
95
|
+
<PitchPanel id="alternatives-current-rule" theme={theme} rule x={48} y={211} w={864} h={1}/>
|
|
96
|
+
<PitchText id="alternatives-current" theme={theme} x={48} y={228} w={254} h={65} body="[Current workaround]" size={23} weight={600}/>
|
|
97
|
+
<PitchText id="alternatives-current-strength" theme={theme} x={348} y={228} w={242} h={65} body="[Its genuine strength]" size={21}/>
|
|
98
|
+
<PitchText id="alternatives-current-gap" theme={theme} x={642} y={228} w={270} h={65} body="[Your relevant advantage]" size={21}/>
|
|
99
|
+
<PitchPanel id="alternatives-direct-rule" theme={theme} rule x={48} y={307} w={864} h={1}/>
|
|
100
|
+
<PitchText id="alternatives-direct" theme={theme} x={48} y={326} w={254} h={65} body="[Direct competitor]" size={23} weight={600}/>
|
|
101
|
+
<PitchText id="alternatives-direct-strength" theme={theme} x={348} y={326} w={242} h={65} body="[Its genuine strength]" size={21}/>
|
|
102
|
+
<PitchText id="alternatives-direct-gap" theme={theme} x={642} y={326} w={270} h={65} body="[Your relevant advantage]" size={21}/>
|
|
103
|
+
<PitchText id="alternatives-durability" theme={theme} x={48} y={429} w={840} h={47} body="[Explain why the advantage can endure as alternatives improve.]" size={22} weight={600}/>
|
|
104
|
+
</PitchSlide>
|
|
105
|
+
|
|
106
|
+
<PitchSlide id="team" theme={theme} eyebrow="THE TEAM" title="Why this team is right for this problem." footer="Team placeholders. Include relevant experience and real roles; use permissioned portraits.">
|
|
107
|
+
<PitchImage id="founder-one-portrait" theme={theme} x={48} y={178} w={178} h={180} label="Founder portrait"/>
|
|
108
|
+
<PitchImage id="founder-two-portrait" theme={theme} x={354} y={178} w={178} h={180} label="Founder portrait"/>
|
|
109
|
+
<PitchText id="founder-one-name" theme={theme} x={48} y={381} w={274} h={42} body="[Name / role]" size={25} weight={600}/>
|
|
110
|
+
<PitchText id="founder-one-fit" theme={theme} x={48} y={428} w={274} h={52} body="[One specific reason this person belongs here.]" size={18}/>
|
|
111
|
+
<PitchText id="founder-two-name" theme={theme} x={354} y={381} w={274} h={42} body="[Name / role]" size={25} weight={600}/>
|
|
112
|
+
<PitchText id="founder-two-fit" theme={theme} x={354} y={428} w={274} h={52} body="[One specific reason this person belongs here.]" size={18}/>
|
|
113
|
+
<PitchPanel id="team-insight-panel" theme={theme} dark x={660} y={178} w={252} h={302}/>
|
|
114
|
+
<PitchText id="team-insight" theme={theme} x={686} y={212} w={200} h={226} body={"[The earned insight]\nWhat have you learned together that others miss?"} size={28} color={theme.paper}/>
|
|
115
|
+
</PitchSlide>
|
|
116
|
+
|
|
117
|
+
<PitchSlide id="financial-position" theme={theme} eyebrow="FINANCIAL POSITION" title="Make the current position easy to understand." footer="Financial placeholders: currency, as-of date, period and basis. Label projections explicitly.">
|
|
118
|
+
<PitchText id="financial-actuals-label" theme={theme} x={48} y={185} w={386} h={26} body="ACTUALS / AS OF [DATE]" role="label" size={12}/>
|
|
119
|
+
<PitchText id="financial-actuals" theme={theme} x={48} y={238} w={386} h={184} body={"[Revenue, if any]\n[Cash and burn]\n[Runway at current plan]"} size={29}/>
|
|
120
|
+
<PitchPanel id="financial-plan-panel" theme={theme} rule x={484} y={177} w={428} h={287}/>
|
|
121
|
+
<PitchText id="financial-plan-label" theme={theme} x={512} y={205} w={372} h={26} body="PLAN / KEY ASSUMPTIONS" role="label" size={12}/>
|
|
122
|
+
<PitchText id="financial-plan" theme={theme} x={512} y={258} w={372} h={149} body={"[What drives the model]\nName the assumptions that matter and the next evidence needed."} size={27}/>
|
|
123
|
+
<PitchText id="financial-detail" theme={theme} x={48} y={441} w={386} h={38} body="Put detailed schedules in an appendix." size={17}/>
|
|
124
|
+
</PitchSlide>
|
|
125
|
+
|
|
126
|
+
<PitchSlide id="funding-ask" theme={theme} eyebrow="THE RAISE" title="Fund the next proof point." footer="Funding placeholders: currency, intended runway, milestone dates and dependencies.">
|
|
127
|
+
<PitchText id="raise-amount" theme={theme} x={48} y={185} w={348} h={120} body={"[Raise\namount]"} role="display" size={48} weight={600}/>
|
|
128
|
+
<PitchText id="raise-purpose" theme={theme} x={48} y={344} w={328} h={112} body={"[Runway / use of funds]\nExplain what this capital allows you to prove."} size={24}/>
|
|
129
|
+
<PitchText id="milestone-product" theme={theme} x={452} y={190} w={460} h={74} body={"01 [Product milestone]\n[Success criterion + target date]"} size={23}/>
|
|
130
|
+
<PitchText id="milestone-market" theme={theme} x={452} y={293} w={460} h={74} body={"02 [Customer milestone]\n[Success criterion + target date]"} size={23}/>
|
|
131
|
+
<PitchText id="milestone-business" theme={theme} x={452} y={396} w={460} h={74} body={"03 [Business milestone]\n[Success criterion + target date]"} size={23}/>
|
|
132
|
+
</PitchSlide>
|
|
133
|
+
|
|
134
|
+
<PitchSlide id="vision" theme={theme} dark eyebrow="THE VISION" footer="[Founder name] / [Email] / [Website]">
|
|
135
|
+
<PitchText id="vision-promise" theme={theme} x={48} y={106} w={822} h={220} body={"If this works,\nwhat becomes possible?"} role="display" size={62} weight={600} color={theme.paper}/>
|
|
136
|
+
<PitchText id="vision-future" theme={theme} x={48} y={347} w={750} h={85} body="[Describe the company you intend to build in five years.]" size={28} color={theme.paper}/>
|
|
137
|
+
<PitchText id="vision-next-step" theme={theme} x={48} y={449} w={800} h={35} body="[Clear next step for the investor]" size={20} color={theme.paper}/>
|
|
138
|
+
</PitchSlide>
|
|
139
|
+
</PitchDeck>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export default Specimen;
|