@openpresentation/opf 0.12.1 → 0.13.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.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/dist/audit.d.ts +9 -130
  3. package/dist/audit.js +5 -5
  4. package/dist/{catalogs-BnI7JKcn.d.ts → catalogs-ywCamd8C.d.ts} +1 -1
  5. package/dist/catalogs.d.ts +2 -2
  6. package/dist/chart-data-Cdr6rRVV.d.ts +177 -0
  7. package/dist/{chunk-6LZK2IZB.js → chunk-7N4VMAT4.js} +11 -7
  8. package/dist/{chunk-4LAM3N6S.js → chunk-7QBCWNWL.js} +424 -18
  9. package/dist/{chunk-SOSOBKQ2.js → chunk-ATGDDJPX.js} +4 -5
  10. package/dist/{chunk-V2537ENL.js → chunk-II5EYKZU.js} +9 -7
  11. package/dist/{chunk-MWPMJE6P.js → chunk-INU7ZNSB.js} +50 -2
  12. package/dist/{chunk-RUC7L5DJ.js → chunk-IS2CPNVJ.js} +1 -1
  13. package/dist/{chunk-JKVKYVWL.js → chunk-IYCJUKWD.js} +90 -471
  14. package/dist/{chunk-HOBSL7AJ.js → chunk-MPM7NRG7.js} +2396 -1408
  15. package/dist/{chunk-AUM5MXBR.js → chunk-RAYB46AB.js} +8 -6
  16. package/dist/{composition-DWbCiMwF.d.ts → composition-D7we69Tr.d.ts} +7 -0
  17. package/dist/composition.d.ts +2 -1
  18. package/dist/composition.js +1 -1
  19. package/dist/convert.d.ts +4 -1
  20. package/dist/convert.js +33 -16
  21. package/dist/data.d.ts +2 -1
  22. package/dist/data.js +3 -1
  23. package/dist/diff.d.ts +1 -1
  24. package/dist/diff.js +8 -7
  25. package/dist/docs.js +32 -26
  26. package/dist/examples.d.ts +1 -1
  27. package/dist/examples.js +102 -57
  28. package/dist/format.js +1 -1
  29. package/dist/index.d.ts +13 -10
  30. package/dist/index.js +8 -8
  31. package/dist/lint-B7azdiuE.d.ts +197 -0
  32. package/dist/lint.d.ts +7 -70
  33. package/dist/lint.js +4 -4
  34. package/dist/markdown.d.ts +7 -5
  35. package/dist/markdown.js +5 -5
  36. package/dist/pagination.d.ts +2 -1
  37. package/dist/pagination.js +4 -4
  38. package/dist/patch.js +4 -4
  39. package/dist/{presentation-DcF-MZcz.d.ts → presentation-mG-IYErQ.d.ts} +187 -14
  40. package/dist/repo-readme.js +1 -1
  41. package/dist/{schemas-BSjlG8-R.d.ts → schemas-BbPonsTz.d.ts} +18 -0
  42. package/dist/schemas.d.ts +1 -1
  43. package/dist/schemas.js +1 -1
  44. package/dist/spec/catalogs/manifest.json +3 -3
  45. package/dist/spec/schemas/opf.schema.json +238 -20
  46. package/dist/types.d.ts +4 -4
  47. package/dist/{validator-DfG9yxba.d.ts → validator-CIylxoIm.d.ts} +3 -3
  48. package/dist/validator.d.ts +4 -4
  49. package/dist/validator.js +3 -3
  50. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  // src/generated/repo-readme.ts
2
- var repoReadmeRaw = '# Open Presentation Format (OPF)\n\n[![npm version](https://img.shields.io/npm/v/@openpresentation/opf?label=npm)](https://www.npmjs.com/package/@openpresentation/opf)\n[![npm downloads](https://img.shields.io/npm/dw/@openpresentation/opf)](https://www.npmjs.com/package/@openpresentation/opf)\n[![license](https://img.shields.io/npm/l/@openpresentation/opf)](./LICENSE)\n\nPublic npm package: [`@openpresentation/opf`](https://www.npmjs.com/package/@openpresentation/opf) (`npm install @openpresentation/opf`).\n\nOpen Presentation Format is the portable, human-readable JSON document format for slide decks.\n\nThis repository is the canonical home for the OPF **spec**, **JSON Schemas**, **catalog presets**, examples, generated developer types, local validation tooling, and integration docs for the render/edit/convert toolkit. OpenPresentation publishes open-source code and documentation only; it does not provide hosted APIs, hosted rendering functions, queues, storage, authentication, jobs, previews, SLAs, telemetry, or managed infrastructure.\n\nFor AI agents, use the [OPF skill set](docs/agent-skills.md) for authoring, layout, presets, editing, export, and schema inspection.\n\nPublished CLI 0.10.0 installs all six skills into your project with `npx @openpresentation/cli@0.10.0 skills install`. It uses local copies, preserves existing instructions and refuses to overwrite customized skills. See the [installation and update guide](docs/agent-skills.md) for personal or agent-specific targets and source development.\n\nFor a fresh Node 24 project that installs **published** packages (not this\ncheckout), follow the [developer quickstart](docs/quickstart.md) and the\n[compatibility matrix](docs/compatibility-matrix.md).\n\nFor LLM authoring, start with [the authoring guide](docs/llm-authoring.md), [dynamic composition](docs/dynamic-composition.md), and [local ecosystem verification](docs/ecosystem-development.md).\n\n## File naming\n\nOpen Presentation Format documents are JSON files. Use `*.opf.json` for complete OPF presentation documents, for example `board-review.opf.json` or `deck.opf.json`.\n\nAvoid using bare `*.opf` for OPF JSON. The `.opf` extension is already used by other document and project formats, while `.opf.json` keeps the OPF identity and still makes the underlying JSON format clear to editors, validators, agents, and version-control tooling.\n\n## Naming and reuse\n\nThe format name is **Open Presentation Format**. The schemas, catalogs, packages, and local tooling in this repository are free and open source under the MIT license, so third-party tools may read, write, validate, render, convert, and describe support for Open Presentation Format without adopting any product-specific branding.\n\n## Why OPF\n\n`.pptx` is a zipped bundle of XML. Humans can\'t diff it, LLMs can\'t read or write it reliably, and git can\'t track it meaningfully. Every change looks like a binary blob.\n\nOPF is plain JSON. A human can open it in an editor. A model can read and write it without guessing at schema-by-example. Decks live in git like the rest of your work.\n\nThat\'s the shift that lets LLMs actually *author* decks. When the format stops fighting them, models can do the work that matters \u2014 narrative structure, persuasive framing, data analysis, chart recommendations, ruthless revision passes \u2014 instead of wrestling with `<p:sp>` tags.\n\nAnd they don\'t start from a blank canvas. [pptx.gallery](https://pptx.gallery) is the human-browsable reference for OPF catalog presets: layouts, themes, color schemes, font schemes, chart types, narratives, audiences, purposes, tones, languages, and social platforms.\n\n## Start in three steps\n\n1. **Install the coordinated published packages** on Node 24. See [the developer quickstart](docs/quickstart.md) for the current pin set: core 0.12.0, renderer 0.12.0, editor 0.11.0, PPTX 0.12.1 and CLI 0.10.0.\n2. **Author, lint, paginate, preview and export.** Copy [`docs/quickstart/developer-quickstart.opf.json`](./docs/quickstart/developer-quickstart.opf.json) and run the commands in that guide. `validatePresentation` / `opf validate` is local schema checking, not visual verification.\n3. **Know the limits.** The [compatibility matrix](docs/compatibility-matrix.md) lists shipped APIs versus renderer issue 24, native PowerPoint issue 87, and other deferred work. Browse presets at [pptx.gallery](https://pptx.gallery).\n\nYour deck can live in git from the first commit. After installing dependencies and supplying referenced assets, these commands run locally without a model provider, account or hosted OPF API.\n\n## JavaScript and TypeScript\n\nThe canonical JavaScript/TypeScript package is published at [`packages/javascript`](./packages/javascript) as [`@openpresentation/opf`](https://www.npmjs.com/package/@openpresentation/opf). The schema is pre-stable (0.x \u2014 expect breaking changes between minor versions until 1.0). Its responsibility is local and format-level only:\n\n- export the canonical schemas from [`spec/`](./spec)\n- export bundled catalog records from [`spec/`](./spec)\n- export a typed raw spec file manifest for package-addressable `spec/` content\n- generate TypeScript types, with `Presentation` as the top-level type\n- validate OPF JSON and catalog records locally\n\nIt does not render `.pptx`, parse `.pptx`, generate content with AI, fetch remote catalogs, call hosted APIs, or provide managed services. Render/edit/convert packages live in separate MIT repos that depend on `@openpresentation/opf`. The format package also exposes pure composition geometry so those packages share layout behavior.\n\n## Toolkit libraries\n\nThe local toolkit lives in sibling repositories. See [ecosystem development](docs/ecosystem-development.md) for coordinated builds and verification, and [dynamic composition](docs/dynamic-composition.md) for portable layout rules.\n\n| Repo | Role | Boundary |\n|---|---|---|\n| `opf-render` | OPF to SVG/PNG/PDF | Local and embeddable rendering library |\n| `opf-editor` | WYSIWYG bindings/components | Headless editor primitives plus optional UI components |\n| `opf-pptx` | OPF to PPTX and PPTX to OPF | Pure local import/export library for browser and server use where supported |\n\nThese repos provide OSS primitives only. Downstream applications own hosting, auth, storage, collaboration, queues, previews, analytics, support, and workflow UX.\n\n## Usage\n\nInstall from npm:\n\n```sh\npnpm add @openpresentation/opf\n# or: npm install @openpresentation/opf\n```\n\nTo work on the package itself, clone this repo and build the workspace:\n\n```sh\npnpm install\npnpm build\n```\n\nUse the format package from JavaScript or TypeScript:\n\n```ts\nimport {\n presentation,\n audiences,\n purposes,\n tones,\n validatePresentation,\n} from "@openpresentation/opf";\n\nimport type { Presentation } from "@openpresentation/opf";\n\nconst deck: Presentation = {\n name: "Quarterly Review",\n slides: [{ title: "Quarterly Review", items: ["Revenue", "Product", "Hiring"] }],\n};\n\nconst result = validatePresentation(deck);\nconsole.log(result.valid); // schema correctness\nconsole.log(result.warnings); // advisory issues, e.g. unknown catalog ids\nconsole.log(audiences.length, purposes.length, tones.length);\n```\n\nUse focused imports when you only need one surface:\n\n```ts\nimport { presentation } from "@openpresentation/opf/schemas";\nimport { audiences, purposes } from "@openpresentation/opf/catalogs";\nimport { specFileEntries } from "@openpresentation/opf/spec-files";\nimport { validate } from "@openpresentation/opf/validator";\nimport type { Presentation } from "@openpresentation/opf/types";\n```\n\nUse raw JSON when an engine or resolver needs package-addressable files:\n\n```ts\nimport presentationSchema from "@openpresentation/opf/spec/schemas/opf.schema.json" with {\n type: "json",\n};\n```\n\nUse the [installable OPF CLI](./packages/cli/README.md) to create, validate, and edit files locally:\n\n```sh\npnpm --filter @openpresentation/cli build\nnode packages/cli/dist/index.js create deck.opf.json --title "Decision brief"\nnode packages/cli/dist/index.js validate deck.opf.json\nnode packages/cli/dist/index.js edit deck.opf.json --patch changes.json --in-place\n```\n\nSee [CSV and JSON data import](./docs/data-import.md) for editable tables and charts in the editor, CLI, and package API, and [content conversions](./docs/conversions.md) for the pure converters (`@openpresentation/opf/convert`) that change a block\'s kind, nest list items, restructure a slide and split or merge slides, and [Markdown and outlines](./docs/markdown.md) for the deterministic Markdown dialect (`@openpresentation/opf/markdown`, `opf from-md`, `opf to-md`) that reads and writes a whole deck as text.\n\nSee [Templates and variables](./docs/templates-and-variables.md) for fillable OPF templates: typed variables, `{{id}}` tokens, `opf fill` and `resolveVariables`.\n\n## Layout\n\n| Path | Contents |\n|---|---|\n| [`spec/schemas/opf.schema.json`](./spec/schemas/opf.schema.json) | Canonical JSON Schema for top-level OPF `Presentation` documents. |\n| [`docs/how-opf-works.md`](./docs/how-opf-works.md) | Conceptual introduction: the document model, content shapes, catalog resolution, and the validation philosophy. Start here. |\n| [`docs/design-resolution.md`](./docs/design-resolution.md) | The design precedence algorithm (slide design \u2192 deck design \u2192 resolved theme \u2192 engine defaults) with worked examples. |\n| [`docs/schema-reference.md`](./docs/schema-reference.md) | Author-facing reference for top-level OPF fields and every presentation schema `$defs` object/type. |\n| [`docs/catalog-schema-reference.md`](./docs/catalog-schema-reference.md) | Author-facing reference for every companion catalog schema. |\n| [`docs/content-payloads.md`](./docs/content-payloads.md) | Author-facing notes for slide and region content payloads, including chart and table object shapes. |\n| [`docs/footnotes-citations-captions.md`](./docs/footnotes-citations-captions.md) | Citations (`cite`), inline footnotes, the deck `references` list, captions on images, charts, tables and videos, and how every engine draws them. |\n| [`docs/examples.md`](./docs/examples.md) | Guide to the expanded scenario-oriented examples under `examples/gallery/`. |\n| [`docs/live-editor.md`](./docs/live-editor.md) | Browser canvas, live OPF editing, font loading, published packages, and current fidelity limits. |\n| [`docs/release-process.md`](./docs/release-process.md) | Maintainer runbook for tagging, trusted npm publishing, verification, and GitHub release notes. |\n| [`spec/schemas/*.schema.json`](./spec/schemas) | Companion schemas for catalog records and sub-objects. |\n| [`spec/catalogs/<catalog-kind>/`](./spec/catalogs) | Canonical bundled catalog records. |\n| [`spec/openapi.yaml`](./spec/openapi.yaml) | Optional reference OpenAPI contract for downstream services that choose to expose OPF over HTTP. OpenPresentation does not host this API. |\n| [`examples/technical/`](./examples/technical) | Focused OPF fixtures for validator, renderer, catalog-resolution, design, content-payload, and region behavior. |\n| [`examples/gallery/`](./examples/gallery) | Broader OPF example decks organized by industry, function, education, government, presentation type, international, and design/media scenarios. |\n| [`packages/javascript/`](./packages/javascript) | Public pre-stable source for `@openpresentation/opf`. |\n| [`packages/cli/`](./packages/cli) | Installable local CLI for creating, validating, editing, and inspecting OPF. |\n| [`legacy/`](./legacy) | Tombstone for service-specific clients, CLIs, tool integrations, and workflows removed from the OpenPresentation OSS repo. |\n\n## OpenPresentation Boundary\n\nOpenPresentation defines the format, bundled presets, local validation, examples, docs, and planned local render/edit/convert libraries. It does not provide hosted functions or managed product surfaces.\n\nFuture non-JavaScript OPF packages should follow the same local-first boundary: Python and Go packages should expose schemas, types/models, catalogs, validation, and package-addressable assets. Future toolkit packages should expose embeddable library APIs with no required network calls, hosted callbacks, hidden telemetry, or managed infrastructure assumptions.\n\nThe published JavaScript package copies package-addressable OPF schemas, catalogs, reference assets, and the optional reference `spec/openapi.yaml` from `spec/`. It intentionally remains `@openpresentation/opf` instead of introducing a separate `@openpresentation/opf-spec` package so downstream imports can advance by semver-pinning one canonical package.\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n';
2
+ var repoReadmeRaw = '# Open Presentation Format (OPF)\n\n[![npm version](https://img.shields.io/npm/v/@openpresentation/opf?label=npm)](https://www.npmjs.com/package/@openpresentation/opf)\n[![npm downloads](https://img.shields.io/npm/dw/@openpresentation/opf)](https://www.npmjs.com/package/@openpresentation/opf)\n[![license](https://img.shields.io/npm/l/@openpresentation/opf)](./LICENSE)\n\nPublic npm package: [`@openpresentation/opf`](https://www.npmjs.com/package/@openpresentation/opf) (`npm install @openpresentation/opf`).\n\nOpen Presentation Format is the portable, human-readable JSON document format for slide decks.\n\nThis repository is the canonical home for the OPF **spec**, **JSON Schemas**, **catalog presets**, examples, generated developer types, local validation tooling, and integration docs for the render/edit/convert toolkit. OpenPresentation publishes open-source code and documentation only; it does not provide hosted APIs, hosted rendering functions, queues, storage, authentication, jobs, previews, SLAs, telemetry, or managed infrastructure.\n\nFor AI agents, use the [OPF skill set](docs/agent-skills.md) for authoring, layout, presets, editing, export, and schema inspection.\n\nPublished CLI 0.10.0 installs all six skills into your project with `npx @openpresentation/cli@0.10.0 skills install`. It uses local copies, preserves existing instructions and refuses to overwrite customized skills. See the [installation and update guide](docs/agent-skills.md) for personal or agent-specific targets and source development.\n\nFor a fresh Node 24 project that installs **published** packages (not this\ncheckout), follow the [developer quickstart](docs/quickstart.md) and the\n[compatibility matrix](docs/compatibility-matrix.md).\n\nFor LLM authoring, start with [the authoring guide](docs/llm-authoring.md), [dynamic composition](docs/dynamic-composition.md), and [local ecosystem verification](docs/ecosystem-development.md).\n\n## File naming\n\nOpen Presentation Format documents are JSON files. Use `*.opf.json` for complete OPF presentation documents, for example `board-review.opf.json` or `deck.opf.json`.\n\nAvoid using bare `*.opf` for OPF JSON. The `.opf` extension is already used by other document and project formats, while `.opf.json` keeps the OPF identity and still makes the underlying JSON format clear to editors, validators, agents, and version-control tooling.\n\n## Naming and reuse\n\nThe format name is **Open Presentation Format**. The schemas, catalogs, packages, and local tooling in this repository are free and open source under the MIT license, so third-party tools may read, write, validate, render, convert, and describe support for Open Presentation Format without adopting any product-specific branding.\n\n## Why OPF\n\n`.pptx` is a zipped bundle of XML. Humans can\'t diff it, LLMs can\'t read or write it reliably, and git can\'t track it meaningfully. Every change looks like a binary blob.\n\nOPF is plain JSON. A human can open it in an editor. A model can read and write it without guessing at schema-by-example. Decks live in git like the rest of your work.\n\nThat\'s the shift that lets LLMs actually *author* decks. When the format stops fighting them, models can do the work that matters \u2014 narrative structure, persuasive framing, data analysis, chart recommendations, ruthless revision passes \u2014 instead of wrestling with `<p:sp>` tags.\n\nAnd they don\'t start from a blank canvas. [pptx.gallery](https://pptx.gallery) is the human-browsable reference for OPF catalog presets: layouts, themes, color schemes, font schemes, chart types, narratives, audiences, purposes, tones, languages, and social platforms.\n\n## Start in three steps\n\n1. **Install the coordinated published packages** on Node 24. See [the developer quickstart](docs/quickstart.md) for the current pin set: core 0.12.1, renderer 0.12.0, editor 0.11.2, PPTX 0.12.3 and CLI 0.10.0.\n2. **Author, lint, paginate, preview and export.** Copy [`docs/quickstart/developer-quickstart.opf.json`](./docs/quickstart/developer-quickstart.opf.json) and run the commands in that guide. `validatePresentation` / `opf validate` is local schema checking, not visual verification.\n3. **Know the limits.** The [compatibility matrix](docs/compatibility-matrix.md) lists shipped APIs versus renderer issue 24, native PowerPoint issue 87, and other deferred work. Browse presets at [pptx.gallery](https://pptx.gallery).\n\nYour deck can live in git from the first commit. After installing dependencies and supplying referenced assets, these commands run locally without a model provider, account or hosted OPF API.\n\n## JavaScript and TypeScript\n\nThe canonical JavaScript/TypeScript package is published at [`packages/javascript`](./packages/javascript) as [`@openpresentation/opf`](https://www.npmjs.com/package/@openpresentation/opf). The schema is pre-stable (0.x \u2014 expect breaking changes between minor versions until 1.0). Its responsibility is local and format-level only:\n\n- export the canonical schemas from [`spec/`](./spec)\n- export bundled catalog records from [`spec/`](./spec)\n- export a typed raw spec file manifest for package-addressable `spec/` content\n- generate TypeScript types, with `Presentation` as the top-level type\n- validate OPF JSON and catalog records locally\n\nIt does not render `.pptx`, parse `.pptx`, generate content with AI, fetch remote catalogs, call hosted APIs, or provide managed services. Render/edit/convert packages live in separate MIT repos that depend on `@openpresentation/opf`. The format package also exposes pure composition geometry so those packages share layout behavior.\n\n## Toolkit libraries\n\nThe local toolkit lives in sibling repositories. See [ecosystem development](docs/ecosystem-development.md) for coordinated builds and verification, and [dynamic composition](docs/dynamic-composition.md) for portable layout rules.\n\n| Repo | Role | Boundary |\n|---|---|---|\n| `opf-render` | OPF to SVG/PNG/PDF | Local and embeddable rendering library |\n| `opf-editor` | WYSIWYG bindings/components | Headless editor primitives plus optional UI components |\n| `opf-pptx` | OPF to PPTX and PPTX to OPF | Pure local import/export library for browser and server use where supported |\n\nThese repos provide OSS primitives only. Downstream applications own hosting, auth, storage, collaboration, queues, previews, analytics, support, and workflow UX.\n\n## Usage\n\nInstall from npm:\n\n```sh\npnpm add @openpresentation/opf\n# or: npm install @openpresentation/opf\n```\n\nTo work on the package itself, clone this repo and build the workspace:\n\n```sh\npnpm install\npnpm build\n```\n\nUse the format package from JavaScript or TypeScript:\n\n```ts\nimport {\n presentation,\n audiences,\n purposes,\n tones,\n validatePresentation,\n} from "@openpresentation/opf";\n\nimport type { Presentation } from "@openpresentation/opf";\n\nconst deck: Presentation = {\n name: "Quarterly Review",\n slides: [{ title: "Quarterly Review", items: ["Revenue", "Product", "Hiring"] }],\n};\n\nconst result = validatePresentation(deck);\nconsole.log(result.valid); // schema correctness\nconsole.log(result.warnings); // advisory issues, e.g. unknown catalog ids\nconsole.log(audiences.length, purposes.length, tones.length);\n```\n\nUse focused imports when you only need one surface:\n\n```ts\nimport { presentation } from "@openpresentation/opf/schemas";\nimport { audiences, purposes } from "@openpresentation/opf/catalogs";\nimport { specFileEntries } from "@openpresentation/opf/spec-files";\nimport { validate } from "@openpresentation/opf/validator";\nimport type { Presentation } from "@openpresentation/opf/types";\n```\n\nUse raw JSON when an engine or resolver needs package-addressable files:\n\n```ts\nimport presentationSchema from "@openpresentation/opf/spec/schemas/opf.schema.json" with {\n type: "json",\n};\n```\n\nUse the [installable OPF CLI](./packages/cli/README.md) to create, validate, and edit files locally:\n\n```sh\npnpm --filter @openpresentation/cli build\nnode packages/cli/dist/index.js create deck.opf.json --title "Decision brief"\nnode packages/cli/dist/index.js validate deck.opf.json\nnode packages/cli/dist/index.js edit deck.opf.json --patch changes.json --in-place\n```\n\nSee [CSV and JSON data import](./docs/data-import.md) for editable tables and charts in the editor, CLI, and package API, and [content conversions](./docs/conversions.md) for the pure converters (`@openpresentation/opf/convert`) that change a block\'s kind, nest list items, restructure a slide and split or merge slides, and [Markdown and outlines](./docs/markdown.md) for the deterministic Markdown dialect (`@openpresentation/opf/markdown`, `opf from-md`, `opf to-md`) that reads and writes a whole deck as text.\n\nSee [Templates and variables](./docs/templates-and-variables.md) for fillable OPF templates: typed variables, `{{id}}` tokens, `opf fill` and `resolveVariables`.\n\n## Layout\n\n| Path | Contents |\n|---|---|\n| [`spec/schemas/opf.schema.json`](./spec/schemas/opf.schema.json) | Canonical JSON Schema for top-level OPF `Presentation` documents. |\n| [`docs/how-opf-works.md`](./docs/how-opf-works.md) | Conceptual introduction: the document model, content shapes, catalog resolution, and the validation philosophy. Start here. |\n| [`docs/design-resolution.md`](./docs/design-resolution.md) | The design precedence algorithm (slide design \u2192 deck design \u2192 resolved theme \u2192 engine defaults) with worked examples. |\n| [`docs/schema-reference.md`](./docs/schema-reference.md) | Author-facing reference for top-level OPF fields and every presentation schema `$defs` object/type. |\n| [`docs/catalog-schema-reference.md`](./docs/catalog-schema-reference.md) | Author-facing reference for every companion catalog schema. |\n| [`docs/content-payloads.md`](./docs/content-payloads.md) | Author-facing notes for slide and region content payloads, including chart and table object shapes. |\n| [`docs/footnotes-citations-captions.md`](./docs/footnotes-citations-captions.md) | Citations (`cite`), inline footnotes, the deck `references` list, captions on images, charts, tables and videos, and how every engine draws them. |\n| [`docs/examples.md`](./docs/examples.md) | Guide to the expanded scenario-oriented examples under `examples/gallery/`. |\n| [`docs/live-editor.md`](./docs/live-editor.md) | Browser canvas, live OPF editing, font loading, published packages, and current fidelity limits. |\n| [`docs/release-process.md`](./docs/release-process.md) | Maintainer runbook for tagging, trusted npm publishing, verification, and GitHub release notes. |\n| [`spec/schemas/*.schema.json`](./spec/schemas) | Companion schemas for catalog records and sub-objects. |\n| [`spec/catalogs/<catalog-kind>/`](./spec/catalogs) | Canonical bundled catalog records. |\n| [`spec/openapi.yaml`](./spec/openapi.yaml) | Optional reference OpenAPI contract for downstream services that choose to expose OPF over HTTP. OpenPresentation does not host this API. |\n| [`examples/technical/`](./examples/technical) | Focused OPF fixtures for validator, renderer, catalog-resolution, design, content-payload, and region behavior. |\n| [`examples/gallery/`](./examples/gallery) | Broader OPF example decks organized by industry, function, education, government, presentation type, international, and design/media scenarios. |\n| [`packages/javascript/`](./packages/javascript) | Public pre-stable source for `@openpresentation/opf`. |\n| [`packages/cli/`](./packages/cli) | Installable local CLI for creating, validating, editing, and inspecting OPF. |\n| [`legacy/`](./legacy) | Tombstone for service-specific clients, CLIs, tool integrations, and workflows removed from the OpenPresentation OSS repo. |\n\n## OpenPresentation Boundary\n\nOpenPresentation defines the format, bundled presets, local validation, examples, docs, and planned local render/edit/convert libraries. It does not provide hosted functions or managed product surfaces.\n\nFuture non-JavaScript OPF packages should follow the same local-first boundary: Python and Go packages should expose schemas, types/models, catalogs, validation, and package-addressable assets. Future toolkit packages should expose embeddable library APIs with no required network calls, hosted callbacks, hidden telemetry, or managed infrastructure assumptions.\n\nThe published JavaScript package copies package-addressable OPF schemas, catalogs, reference assets, and the optional reference `spec/openapi.yaml` from `spec/`. It intentionally remains `@openpresentation/opf` instead of introducing a separate `@openpresentation/opf-spec` package so downstream imports can advance by semver-pinning one canonical package.\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n';
3
3
 
4
4
  // src/repo-readme.ts
5
5
  var repoReadme = repoReadmeRaw;
@@ -45,6 +45,7 @@ declare const presentation: JsonSchemaDocument & {
45
45
  readonly "ColorVariable": JsonObject;
46
46
  readonly "TextVariable": JsonObject;
47
47
  readonly "NumberVariable": JsonObject;
48
+ readonly "NumberFormat": JsonObject;
48
49
  readonly "DateVariable": JsonObject;
49
50
  readonly "ImageVariable": JsonObject;
50
51
  readonly "UrlVariable": JsonObject;
@@ -80,6 +81,14 @@ declare const presentation: JsonSchemaDocument & {
80
81
  readonly "ChartDataLabels": JsonObject;
81
82
  readonly "Table": JsonObject;
82
83
  readonly "ChartData": JsonObject;
84
+ readonly "DataColumn": JsonObject;
85
+ readonly "DataSourceRef": JsonObject;
86
+ readonly "DatasetId": JsonObject;
87
+ readonly "DatasetFields": JsonObject;
88
+ readonly "Datasets": JsonObject;
89
+ readonly "Dataset": JsonObject;
90
+ readonly "DatasetRef": JsonObject;
91
+ readonly "ChartMapping": JsonObject;
83
92
  readonly "ChartDataSource": JsonObject;
84
93
  readonly "ChartDataCell": JsonObject;
85
94
  readonly "TableCell": JsonObject;
@@ -156,6 +165,7 @@ declare const schemas: {
156
165
  readonly "ColorVariable": JsonObject;
157
166
  readonly "TextVariable": JsonObject;
158
167
  readonly "NumberVariable": JsonObject;
168
+ readonly "NumberFormat": JsonObject;
159
169
  readonly "DateVariable": JsonObject;
160
170
  readonly "ImageVariable": JsonObject;
161
171
  readonly "UrlVariable": JsonObject;
@@ -191,6 +201,14 @@ declare const schemas: {
191
201
  readonly "ChartDataLabels": JsonObject;
192
202
  readonly "Table": JsonObject;
193
203
  readonly "ChartData": JsonObject;
204
+ readonly "DataColumn": JsonObject;
205
+ readonly "DataSourceRef": JsonObject;
206
+ readonly "DatasetId": JsonObject;
207
+ readonly "DatasetFields": JsonObject;
208
+ readonly "Datasets": JsonObject;
209
+ readonly "Dataset": JsonObject;
210
+ readonly "DatasetRef": JsonObject;
211
+ readonly "ChartMapping": JsonObject;
194
212
  readonly "ChartDataSource": JsonObject;
195
213
  readonly "ChartDataCell": JsonObject;
196
214
  readonly "TableCell": JsonObject;
package/dist/schemas.d.ts CHANGED
@@ -1 +1 @@
1
- export { S as SchemaEntry, a as SchemaName, b as audience, c as chartType, d as colorScheme, f as fontScheme, l as language, e as layout, n as narrative, p as presentation, g as purpose, s as schemaEntries, h as schemaNames, i as schemas, j as socialPlatform, t as theme, k as tone } from './schemas-BSjlG8-R.js';
1
+ export { S as SchemaEntry, a as SchemaName, b as audience, c as chartType, d as colorScheme, f as fontScheme, l as language, e as layout, n as narrative, p as presentation, g as purpose, s as schemaEntries, h as schemaNames, i as schemas, j as socialPlatform, t as theme, k as tone } from './schemas-BbPonsTz.js';
package/dist/schemas.js CHANGED
@@ -1 +1 @@
1
- export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-4LAM3N6S.js';
1
+ export { audience, chartType, colorScheme, fontScheme, language, layout, narrative, presentation, purpose, schemaEntries, schemaNames, schemas, socialPlatform, theme, tone } from './chunk-7QBCWNWL.js';
@@ -4,7 +4,7 @@
4
4
  "publisher": "https://www.pptx.gallery",
5
5
  "source": {
6
6
  "repository": "https://github.com/Data-Advantage/pptx-gallery",
7
- "commit": "2c7cc73ee4cfe98d275695977fccd19e027ed5cd",
7
+ "commit": "04792ccce2c0d6764a9513b87ba6790bf1957407",
8
8
  "path": "public"
9
9
  },
10
10
  "kinds": {
@@ -14,7 +14,7 @@
14
14
  "contentSha256": "bfb44226b533a2da04c92077eb39c689dde43181e0b9979fb15c247dfaba1f98",
15
15
  "gallery": {
16
16
  "records": 22,
17
- "contentSha256": "90ab1b5a3c55ff36ec8c05595a2b0f90a18c108af82c959b33f204f077ee4e51"
17
+ "contentSha256": "bfb44226b533a2da04c92077eb39c689dde43181e0b9979fb15c247dfaba1f98"
18
18
  }
19
19
  },
20
20
  "chart-types": {
@@ -59,7 +59,7 @@
59
59
  "contentSha256": "3e58ecdb3fcc2b8db9fc7a974809c16b9a9b06d560d0e8f0316846bc84754a95",
60
60
  "gallery": {
61
61
  "records": 485,
62
- "contentSha256": "70c66e0cbfec9a8827eef1aec4f20c8bda6c404cee3029977808e53117afc931"
62
+ "contentSha256": "f245b0fbcc4197e5533dcb9453d30bbba88015ed1dbc02a43939aadc7cd0cf3e"
63
63
  }
64
64
  },
65
65
  "narratives": {
@@ -213,6 +213,10 @@
213
213
  "description": "Sources that text runs cite with 'cite'. Ids are unique. A cited reference is listed in the footnote area of every slide that cites it, with a marker number assigned per deck in order of first use; a reference no run cites is a lint warning (opf/unused-reference). referencesSlide() turns the cited references into an ordinary list slide.",
214
214
  "examples": [[{ "id": "gartner-2026", "text": "Gartner, Market Guide for Presentation Tooling, 2026", "url": "https://www.gartner.com" }]]
215
215
  },
216
+ "datasets": {
217
+ "$ref": "#/$defs/Datasets",
218
+ "description": "Optional shared data tables, keyed by id. A chart ('chart.data': { \"dataset\": \"<id>\" }) or a table ('table': { \"dataset\": \"<id>\" }) references one instead of holding its own copy; engines inline the reference before composing, rendering or exporting. A dataset nothing references is a lint warning (opf/unused-dataset). See docs/chart-table-data.md."
219
+ },
216
220
  "assets": {
217
221
  "$ref": "#/$defs/Assets",
218
222
  "description": "Optional reusable asset registry for images, data files, videos, documents, fonts, and other resources referenced elsewhere in the deck via 'asset:<id>' strings."
@@ -1588,19 +1592,25 @@
1588
1592
  "description": "Illustrative number shown in fill forms and used when a template is previewed with examples. Never written to output."
1589
1593
  },
1590
1594
  "format": {
1591
- "type": "string",
1592
- "description": "Display pattern used by '{{<id>}}'. A literal prefix, a numeric part of '#', '0', ',' and '.', and a literal suffix. '0' pads digits, '#' is optional, ',' groups thousands, digits after '.' fix the decimals ('0' required, '#' optional), and a '%' in the suffix scales by 100. English separators only. Absent: the shortest decimal form.",
1593
- "examples": [
1594
- "#,##0",
1595
- "0.0",
1596
- "$#,##0.00",
1597
- "0.#%",
1598
- "#,##0.0M"
1599
- ]
1595
+ "$ref": "#/$defs/NumberFormat",
1596
+ "description": "Display pattern used by '{{<id>}}' (the shared NumberFormat syntax). A literal prefix, a numeric part of '#', '0', ',' and '.', and a literal suffix. '0' pads digits, '#' is optional, ',' groups thousands, digits after '.' fix the decimals ('0' required, '#' optional), and a '%' in the suffix scales by 100. English separators only. Absent: the shortest decimal form."
1600
1597
  }
1601
1598
  },
1602
1599
  "description": "A number. '{{<id>}}' inserts it as text using 'format'; 'var:<id>' as a whole field supplies the number itself (chart values, font sizes)."
1603
1600
  },
1601
+ "NumberFormat": {
1602
+ "type": "string",
1603
+ "description": "Number display pattern, shared by NumberVariable.format, data column formats (DataColumn.format) and table cell formats (StyledTableCell.format). An optional literal prefix, a numeric part of '#', '0', ',' and '.', and an optional literal suffix. '0' pads digits, '#' is optional, ',' groups thousands, digits after '.' fix the decimals ('0' required, '#' optional), and a '%' in the prefix or suffix multiplies the value by 100. English separators only. A format applies only to number values; strings, booleans, null and rich runs display unchanged. A column or cell format that is not a valid pattern is a 'number-format-invalid' error. The PPTX export writes it as the equivalent Excel number format code.",
1604
+ "examples": [
1605
+ "#,##0",
1606
+ "0.0",
1607
+ "$#,##0.00",
1608
+ "0.#%",
1609
+ "0%",
1610
+ "#,##0.0M",
1611
+ "#,##0 units"
1612
+ ]
1613
+ },
1604
1614
  "DateVariable": {
1605
1615
  "type": "object",
1606
1616
  "required": [
@@ -3202,9 +3212,14 @@
3202
3212
  "data": {
3203
3213
  "oneOf": [
3204
3214
  { "$ref": "#/$defs/ChartData" },
3205
- { "$ref": "#/$defs/ChartDataSource" }
3215
+ { "$ref": "#/$defs/ChartDataSource" },
3216
+ { "$ref": "#/$defs/DatasetRef" }
3206
3217
  ],
3207
- "description": "Chart data. Inline data uses a tabular columns/rows shape; renderers convert rows to chart series internally."
3218
+ "description": "Chart data. Inline data uses a tabular columns/rows shape; renderers convert rows to chart series internally. A DatasetRef ({ \"dataset\": \"<id>\" }) plots a top-level dataset instead. A ChartDataSource is not resolved by any engine (a 'chart-data-source-unresolved' warning; engines draw a placeholder); prefer inline data with a 'source'."
3219
+ },
3220
+ "mapping": {
3221
+ "$ref": "#/$defs/ChartMapping",
3222
+ "description": "Optional series mapping by column name: which column is the category, which is the X column of a scatter chart, and which columns are plotted, in order. Absent keeps the positional rule (first column the category, then the X column for scatter, every other column a series)."
3208
3223
  },
3209
3224
  "axisTitles": {
3210
3225
  "$ref": "#/$defs/ChartAxisTitles",
@@ -3267,11 +3282,16 @@
3267
3282
  },
3268
3283
  "Table": {
3269
3284
  "type": "object",
3270
- "description": "Table content. Columns are optional; rows are the only required field.",
3285
+ "description": "Table content, inline or dataset-backed. An inline table has 'rows' (required) and optional 'columns'. A dataset-backed table has 'dataset' (required) and optional 'fields', and no 'rows' or 'columns': it takes its headers, rows and column formats from the dataset (per-cell styles need an inline table).",
3271
3286
  "additionalProperties": false,
3272
- "required": [
3273
- "rows"
3274
- ],
3287
+ "if": { "required": ["dataset"] },
3288
+ "then": {
3289
+ "properties": { "rows": false, "columns": false }
3290
+ },
3291
+ "else": {
3292
+ "required": ["rows"],
3293
+ "properties": { "fields": false }
3294
+ },
3275
3295
  "properties": {
3276
3296
  "columns": {
3277
3297
  "type": "array",
@@ -3289,12 +3309,15 @@
3289
3309
  {
3290
3310
  "$ref": "#/$defs/StyledTableCell"
3291
3311
  },
3312
+ {
3313
+ "$ref": "#/$defs/DataColumn"
3314
+ },
3292
3315
  {
3293
3316
  "type": "null"
3294
3317
  }
3295
3318
  ]
3296
3319
  },
3297
- "description": "Optional column labels. Labels may be strings, rich runs or styled cell objects. Null is an empty label or a placeholder covered by a preceding column span.",
3320
+ "description": "Optional column labels. Labels may be strings, rich runs, styled cell objects or DataColumn objects ({ \"name\", \"format\" }). A header's 'format' (DataColumn or StyledTableCell) is the column's number format; a body cell's own format wins. Null is an empty label or a placeholder covered by a preceding column span.",
3298
3321
  "examples": [
3299
3322
  [
3300
3323
  "Region",
@@ -3329,21 +3352,34 @@
3329
3352
  ]
3330
3353
  ]
3331
3354
  ]
3355
+ },
3356
+ "dataset": {
3357
+ "$ref": "#/$defs/DatasetId",
3358
+ "description": "Id of a top-level dataset that supplies this table's headers, rows and column formats. Excludes 'rows' and 'columns'. An unknown id is a 'dataset-unknown' error."
3359
+ },
3360
+ "fields": {
3361
+ "$ref": "#/$defs/DatasetFields",
3362
+ "description": "Dataset tables only: the dataset columns to show, by name and in order. Absent shows every column. An unknown name is a 'dataset-field-unknown' error."
3332
3363
  }
3333
3364
  }
3334
3365
  },
3335
3366
  "ChartData": {
3336
3367
  "type": "object",
3337
- "description": "Inline tabular data driving a chart. The first column usually supplies category/x-axis labels; subsequent columns are plotted measures unless a chart type or renderer maps them differently.",
3368
+ "description": "Inline tabular data driving a chart. The first column usually supplies category/x-axis labels; subsequent columns are plotted measures unless 'chart.mapping' or a chart type maps them differently. Value cells are numbers; a string is read only in strict decimal syntax ('12', '-3.5', '1e6'), and anything else ('12%', '$5', '(5)', '1,234') is a gap and a 'chart-value-not-numeric' warning.",
3338
3369
  "additionalProperties": false,
3339
3370
  "required": ["columns", "rows"],
3340
3371
  "properties": {
3341
3372
  "columns": {
3342
3373
  "type": "array",
3343
- "items": { "type": "string" },
3374
+ "items": {
3375
+ "oneOf": [
3376
+ { "type": "string" },
3377
+ { "$ref": "#/$defs/DataColumn" }
3378
+ ]
3379
+ },
3344
3380
  "minItems": 1,
3345
- "description": "Ordered column labels for the chart data table.",
3346
- "examples": [["Quarter", "Revenue"], ["Quarter", "Revenue", "Costs"]]
3381
+ "description": "Ordered column labels for the chart data table. A label is a string or a DataColumn ({ \"name\", \"format\" }) whose number format the data labels, value axis and exported workbook use.",
3382
+ "examples": [["Quarter", "Revenue"], ["Quarter", "Revenue", "Costs"], ["Quarter", { "name": "Revenue", "format": "$#,##0.0" }, { "name": "Margin", "format": "0%" }]]
3347
3383
  },
3348
3384
  "rows": {
3349
3385
  "type": "array",
@@ -3354,9 +3390,187 @@
3354
3390
  "minItems": 1,
3355
3391
  "description": "Tabular chart rows. Each row aligns by index with columns.",
3356
3392
  "examples": [[["Q1", 12], ["Q2", 18], ["Q3", 24], ["Q4", 31]]]
3393
+ },
3394
+ "source": {
3395
+ "$ref": "#/$defs/DataSourceRef",
3396
+ "description": "Optional provenance: where this inline data came from. Engines never read, fetch or refresh it; they keep it through editing, export and re-import."
3357
3397
  }
3358
3398
  }
3359
3399
  },
3400
+ "DataColumn": {
3401
+ "type": "object",
3402
+ "additionalProperties": false,
3403
+ "required": ["name"],
3404
+ "description": "A named data column with an optional number format. Anywhere a chart or dataset column is a string it may be a DataColumn; the string form is { \"name\": value } with no format. A table column header may also be a DataColumn.",
3405
+ "properties": {
3406
+ "name": {
3407
+ "type": "string",
3408
+ "description": "Column label, used as the series name, the table header and the name 'fields' and 'chart.mapping' address.",
3409
+ "examples": ["Revenue", "Margin"]
3410
+ },
3411
+ "format": {
3412
+ "$ref": "#/$defs/NumberFormat",
3413
+ "description": "Number format of the column's number values (data labels, value axis, table cells, exported workbook). Absent: the General form."
3414
+ }
3415
+ },
3416
+ "examples": [{ "name": "Revenue", "format": "$#,##0.0" }, { "name": "Margin", "format": "0%" }]
3417
+ },
3418
+ "DataSourceRef": {
3419
+ "type": "object",
3420
+ "additionalProperties": false,
3421
+ "required": ["src"],
3422
+ "description": "Provenance of inline data or a dataset: the file, sheet and range it came from and when. Engines never read, fetch or refresh it; they keep it through editing, export and re-import. Re-import the data to update it.",
3423
+ "properties": {
3424
+ "src": {
3425
+ "type": "string",
3426
+ "description": "Where the data came from: an 'asset:<id>' reference, a URL, or a relative or local path.",
3427
+ "examples": ["./data/revenue.csv", "asset:revenue", "https://cdn.acme.com/data/revenue.csv"]
3428
+ },
3429
+ "sheet": {
3430
+ "type": "string",
3431
+ "description": "Sheet or table name inside a spreadsheet source.",
3432
+ "examples": ["Sheet1"]
3433
+ },
3434
+ "range": {
3435
+ "type": "string",
3436
+ "description": "A1-style range inside a spreadsheet source.",
3437
+ "examples": ["A1:D8"]
3438
+ },
3439
+ "fields": {
3440
+ "type": "array",
3441
+ "items": { "type": "string" },
3442
+ "description": "The source fields the data was taken from, in order.",
3443
+ "examples": [["Quarter", "Revenue"]]
3444
+ },
3445
+ "retrieved": {
3446
+ "type": "string",
3447
+ "anyOf": [{ "format": "date" }, { "format": "date-time" }],
3448
+ "description": "When the data was taken from the source: an ISO 8601 date or date-time.",
3449
+ "examples": ["2026-10-05", "2026-10-05T09:30:00Z"]
3450
+ },
3451
+ "description": {
3452
+ "type": "string",
3453
+ "description": "Free-form note about the source.",
3454
+ "examples": ["Finance export, unaudited"]
3455
+ }
3456
+ },
3457
+ "examples": [{ "src": "./data/revenue.csv", "retrieved": "2026-10-05" }]
3458
+ },
3459
+ "DatasetId": {
3460
+ "type": "string",
3461
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$",
3462
+ "description": "Id of an entry in the top-level datasets map (the assets id pattern).",
3463
+ "examples": ["revenue", "pipeline-2026"]
3464
+ },
3465
+ "DatasetFields": {
3466
+ "type": "array",
3467
+ "items": { "type": "string" },
3468
+ "minItems": 1,
3469
+ "uniqueItems": true,
3470
+ "description": "Dataset column names to use, in order, each at most once. Selects and orders the dataset's columns; an unknown name is a 'dataset-field-unknown' error.",
3471
+ "examples": [["Quarter", "Revenue"]]
3472
+ },
3473
+ "Datasets": {
3474
+ "type": "object",
3475
+ "description": "Shared data tables keyed by id (the assets id pattern). Charts reference one with 'chart.data': { \"dataset\": \"<id>\" } and tables with 'table': { \"dataset\": \"<id>\" }.",
3476
+ "propertyNames": { "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]*$" },
3477
+ "additionalProperties": { "$ref": "#/$defs/Dataset" },
3478
+ "examples": [
3479
+ {
3480
+ "revenue": {
3481
+ "title": "Revenue by quarter",
3482
+ "columns": ["Quarter", { "name": "Revenue", "format": "$#,##0.0" }, "Costs"],
3483
+ "rows": [["Q1", 12, 8], ["Q2", 18, 11], ["Q3", 24, 15]],
3484
+ "source": { "src": "./data/revenue.csv", "retrieved": "2026-10-05" }
3485
+ }
3486
+ }
3487
+ ]
3488
+ },
3489
+ "Dataset": {
3490
+ "type": "object",
3491
+ "additionalProperties": false,
3492
+ "required": ["columns", "rows"],
3493
+ "description": "One shared data table: named columns (strings or DataColumn objects with a number format) and rows of scalar cells. Column names are unique ('data-column-duplicate' error). Rich text and styling belong in an inline table.",
3494
+ "properties": {
3495
+ "title": {
3496
+ "type": "string",
3497
+ "description": "Human name of the dataset, shown by editors.",
3498
+ "examples": ["Revenue by quarter"]
3499
+ },
3500
+ "description": {
3501
+ "type": "string",
3502
+ "description": "What the dataset holds.",
3503
+ "examples": ["Quarterly revenue and costs, in $M."]
3504
+ },
3505
+ "columns": {
3506
+ "type": "array",
3507
+ "items": {
3508
+ "oneOf": [
3509
+ { "type": "string" },
3510
+ { "$ref": "#/$defs/DataColumn" }
3511
+ ]
3512
+ },
3513
+ "minItems": 1,
3514
+ "description": "Ordered, uniquely named columns.",
3515
+ "examples": [["Quarter", { "name": "Revenue", "format": "$#,##0.0" }, "Costs"]]
3516
+ },
3517
+ "rows": {
3518
+ "type": "array",
3519
+ "items": {
3520
+ "type": "array",
3521
+ "items": { "$ref": "#/$defs/ChartDataCell" }
3522
+ },
3523
+ "description": "Rows of scalar cells (string, number, boolean, null); each row aligns by index with columns.",
3524
+ "examples": [[["Q1", 12, 8], ["Q2", 18, 11]]]
3525
+ },
3526
+ "source": {
3527
+ "$ref": "#/$defs/DataSourceRef",
3528
+ "description": "Optional provenance. Engines never read, fetch or refresh it."
3529
+ }
3530
+ }
3531
+ },
3532
+ "DatasetRef": {
3533
+ "type": "object",
3534
+ "additionalProperties": false,
3535
+ "required": ["dataset"],
3536
+ "description": "Chart data taken from a top-level dataset. Engines inline it before plotting; 'chart.mapping' names columns after the 'fields' selection.",
3537
+ "properties": {
3538
+ "dataset": {
3539
+ "$ref": "#/$defs/DatasetId",
3540
+ "description": "Id of the dataset. An unknown id is a 'dataset-unknown' error."
3541
+ },
3542
+ "fields": {
3543
+ "$ref": "#/$defs/DatasetFields",
3544
+ "description": "The dataset columns to use, by name and in order. Absent uses every column."
3545
+ }
3546
+ },
3547
+ "examples": [{ "dataset": "revenue" }, { "dataset": "revenue", "fields": ["Quarter", "Revenue"] }]
3548
+ },
3549
+ "ChartMapping": {
3550
+ "type": "object",
3551
+ "additionalProperties": false,
3552
+ "description": "Series mapping by column name (after any 'fields' selection). Mapping only selects and orders columns; pie, doughnut and other single-series constructs still plot one series. An unknown name is a 'chart-mapping-unknown-column' error; a series that repeats the category or X column, and an X column on a chart type without an X axis, are dropped with a 'chart-mapping-adapted' warning.",
3553
+ "properties": {
3554
+ "category": {
3555
+ "type": "string",
3556
+ "description": "The label (category) column. Default: the first column.",
3557
+ "examples": ["Quarter"]
3558
+ },
3559
+ "x": {
3560
+ "type": "string",
3561
+ "description": "The X column of an XY (scatter) chart. Default: the second column (the first, when the category is the second column), and only when there are three or more columns: with two, the second column is the one series, plotted against row numbers. An X that leaves no series is plotted as the series with a 'chart-mapping-adapted' warning.",
3562
+ "examples": ["Spend"]
3563
+ },
3564
+ "series": {
3565
+ "type": "array",
3566
+ "items": { "type": "string" },
3567
+ "minItems": 1,
3568
+ "description": "The plotted columns, in order. Default: every column that is not the category or the X column.",
3569
+ "examples": [["Revenue", "Costs"]]
3570
+ }
3571
+ },
3572
+ "examples": [{ "category": "Quarter", "series": ["Costs", "Revenue"] }, { "category": "Region", "x": "Spend", "series": ["Revenue"] }]
3573
+ },
3360
3574
  "ChartDataSource": {
3361
3575
  "type": "object",
3362
3576
  "description": "Chart data sourced from an asset reference, URL, data URI, relative path, or local path such as CSV, TSV, JSON, or XLSX. The source is interpreted as a table; optional columns select or order fields from that table.",
@@ -3452,6 +3666,10 @@
3452
3666
  "type": "integer",
3453
3667
  "minimum": 1,
3454
3668
  "description": "Number of grid rows covered, starting at this cell. Covered positions must contain null. Header cells cannot span into body rows. Default 1."
3669
+ },
3670
+ "format": {
3671
+ "$ref": "#/$defs/NumberFormat",
3672
+ "description": "Number format. On a body cell it formats that cell's number value (and wins over the column's format); on a header cell (in 'columns') it is the column's format, the same as a DataColumn header. Strings, booleans, null and rich runs display unchanged."
3455
3673
  }
3456
3674
  },
3457
3675
  "description": "A cell with explicit visual style or merged geometry. Its position remains its array column index; use null placeholders for every covered grid position."
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { P as Presentation } from './presentation-DcF-MZcz.js';
2
- export { A as Audience, C as CatalogKind, e as ChartType, f as ColorScheme, F as FontScheme, L as Language, g as Layout, N as Narrative, P as Purpose, S as SocialPlatform, T as Theme, h as Tone } from './catalogs-BnI7JKcn.js';
3
- export { a as SchemaName } from './schemas-BSjlG8-R.js';
4
- export { V as ValidationIssue, e as ValidationResult } from './validator-DfG9yxba.js';
1
+ export { P as Presentation } from './presentation-mG-IYErQ.js';
2
+ export { A as Audience, C as CatalogKind, e as ChartType, f as ColorScheme, F as FontScheme, L as Language, g as Layout, N as Narrative, P as Purpose, S as SocialPlatform, T as Theme, h as Tone } from './catalogs-ywCamd8C.js';
3
+ export { a as SchemaName } from './schemas-BbPonsTz.js';
4
+ export { V as ValidationIssue, e as ValidationResult } from './validator-CIylxoIm.js';
@@ -1,6 +1,6 @@
1
- import { P as Presentation } from './presentation-DcF-MZcz.js';
2
- import { C as CatalogKind } from './catalogs-BnI7JKcn.js';
3
- import { a as SchemaName, m as JsonSchema } from './schemas-BSjlG8-R.js';
1
+ import { P as Presentation } from './presentation-mG-IYErQ.js';
2
+ import { C as CatalogKind } from './catalogs-ywCamd8C.js';
3
+ import { a as SchemaName, m as JsonSchema } from './schemas-BbPonsTz.js';
4
4
 
5
5
  /**
6
6
  * Template variables: typed, named values a deck declares once and uses in many
@@ -1,4 +1,4 @@
1
- import './catalogs-BnI7JKcn.js';
2
- import './schemas-BSjlG8-R.js';
3
- import './presentation-DcF-MZcz.js';
4
- export { O as OPFValidationError, S as SchemaOrKind, d as ValidateOptions, V as ValidationIssue, e as ValidationResult, o as assertValid, p as assertValidCatalogRecord, q as assertValidPresentation, B as promotedRegionKeys, x as validate, y as validateCatalogRecord, z as validatePresentation } from './validator-DfG9yxba.js';
1
+ import './catalogs-ywCamd8C.js';
2
+ import './schemas-BbPonsTz.js';
3
+ import './presentation-mG-IYErQ.js';
4
+ export { O as OPFValidationError, S as SchemaOrKind, d as ValidateOptions, V as ValidationIssue, e as ValidationResult, o as assertValid, p as assertValidCatalogRecord, q as assertValidPresentation, B as promotedRegionKeys, x as validate, y as validateCatalogRecord, z as validatePresentation } from './validator-CIylxoIm.js';
package/dist/validator.js CHANGED
@@ -1,5 +1,5 @@
1
- export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-JKVKYVWL.js';
2
- export { promotedRegionKeys } from './chunk-HOBSL7AJ.js';
1
+ export { OPFValidationError, assertValid, assertValidCatalogRecord, assertValidPresentation, validate, validateCatalogRecord, validatePresentation } from './chunk-IYCJUKWD.js';
2
+ export { promotedRegionKeys } from './chunk-MPM7NRG7.js';
3
3
  import './chunk-S5W34SIJ.js';
4
4
  import './chunk-E34DJ5LL.js';
5
- import './chunk-4LAM3N6S.js';
5
+ import './chunk-7QBCWNWL.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpresentation/opf",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "Canonical Open Presentation Format schemas, catalogs, TypeScript types, and local validation.",
5
5
  "license": "MIT",
6
6
  "author": "Open Presentation",
@@ -128,12 +128,12 @@
128
128
  "package.json"
129
129
  ],
130
130
  "engines": {
131
- "node": "24.x"
131
+ "node": ">=22"
132
132
  },
133
133
  "scripts": {
134
134
  "clean": "rm -rf dist src/generated",
135
135
  "generate": "node scripts/generate.mjs && node scripts/generate-previews.mjs && node scripts/generate-content.mjs",
136
- "build": "pnpm run generate && tsup && node scripts/copy-spec.mjs",
136
+ "build": "node ../../scripts/reuse-build.mjs check || (pnpm run generate && tsup && node scripts/copy-spec.mjs && node ../../scripts/reuse-build.mjs stamp)",
137
137
  "typecheck": "pnpm run generate && node ../../scripts/typecheck.mjs --noEmit",
138
138
  "test": "pnpm run build && node ../../scripts/run-tests.mjs",
139
139
  "test:packed": "node test/packed-install-smoke.mjs",