@hienlh/ppm 0.22.11 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -1
- package/CLAUDE.md +14 -0
- package/THIRD-PARTY-NOTICES.md +1 -1
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/bun.lock +17 -0
- package/dist/web/assets/__vite-browser-external-CHpXvvmW.js +1 -0
- package/dist/web/assets/accounts-settings-section-BR7t8CEk.js +1 -0
- package/dist/web/assets/ai-resource-editor-BFVg2d2a.js +1 -0
- package/dist/web/assets/ai-settings-section-BJw7E_lM.js +1 -0
- package/dist/web/assets/ai-settings-section-CO-i3ghA.js +1 -0
- package/dist/web/assets/angular-html-D-rbk4zq.js +1 -0
- package/dist/web/assets/angular-ts-B_ldKah2.js +1 -0
- package/dist/web/assets/api-client-BgedDTvo.js +1 -0
- package/dist/web/assets/api-client-c8YOpTlT.js +1 -0
- package/dist/web/assets/api-settings-0s1Rfgcu.js +1 -0
- package/dist/web/assets/api-settings-Bnp28Ysw.js +1 -0
- package/dist/web/assets/api-themes-Pp-AZvwV.js +1 -0
- package/dist/web/assets/apl-19Dr02g6.js +1 -0
- package/dist/web/assets/appearance-settings-section-Ck_FPs9g.js +1 -0
- package/dist/web/assets/architecture-PBZL5I3N-B_n8ddB4.js +1 -0
- package/dist/web/assets/astro-1q5o0N64.js +1 -0
- package/dist/web/assets/audio-preview-DXtE1Lpz.js +1 -0
- package/dist/web/assets/blade-BNgXZCCk.js +1 -0
- package/dist/web/assets/branch-review-tab-CNVxMRuo.js +1 -0
- package/dist/web/assets/bsl-C5u8-gEq.js +1 -0
- package/dist/web/assets/button-CBehaXpV.js +1 -0
- package/dist/web/assets/c-Dko4ZphN.js +1 -0
- package/dist/web/assets/cairo-CrhmfCJH.js +1 -0
- package/dist/web/assets/chat-tab-DqLqcBci.js +1 -0
- package/dist/web/assets/chat-tab-MdU9Jr3F.js +15 -0
- package/dist/web/assets/cobol-BgRxrYyZ.js +1 -0
- package/dist/web/assets/code-editor-wEeCvvMR.js +7 -0
- package/dist/web/assets/codex-daily-guard-B21M4m-P.js +1 -0
- package/dist/web/assets/coffee-9hmEOIYs.js +1 -0
- package/dist/web/assets/conflict-editor-Cu-z_LdX.js +19 -0
- package/dist/web/assets/context-menu-CjYTq8DI.js +1 -0
- package/dist/web/assets/cpp-BntsLe3X.js +1 -0
- package/dist/web/assets/createLucideIcon-DBXq3G0e.js +1 -0
- package/dist/web/assets/crystal-CoXN2Gj8.js +1 -0
- package/dist/web/assets/css-DKuKlxIj.js +1 -0
- package/dist/web/assets/csv-preview-DHbBIqUu.js +2 -0
- package/dist/web/assets/data-grid-overlay-editor-2ERlh7_N.js +1 -0
- package/dist/web/assets/data-grid-types-DatI2Wee.js +1 -0
- package/dist/web/assets/database-viewer-_McYjRzc.js +1 -0
- package/dist/web/assets/design-export-client-SWCbGwwU.js +1 -0
- package/dist/web/assets/design-responsive-dialog-CcJETHO2.js +1 -0
- package/dist/web/assets/design-tab-C0TUD5g-.js +33 -0
- package/dist/web/assets/designs-sidebar-panel-XCAwSNtg.js +1 -0
- package/dist/web/assets/dialog-tzBRkGeW.js +1 -0
- package/dist/web/assets/diff-viewer-C4z-_68x.js +4 -0
- package/dist/web/assets/dist-CgtN5c7X.js +1 -0
- package/dist/web/assets/dist-wmDsBD_Z.js +1 -0
- package/dist/web/assets/docx-preview-C-UKGMXR.js +12 -0
- package/dist/web/assets/edge-gf7weBFr.js +1 -0
- package/dist/web/assets/edit-diff-preview-8nIct7kS.js +7 -0
- package/dist/web/assets/editor-language-service-D8hW_eew.js +1 -0
- package/dist/web/assets/elixir-DOEwBYus.js +1 -0
- package/dist/web/assets/elm-7yx1A5qt.js +1 -0
- package/dist/web/assets/erb-Bm_J_rBw.js +1 -0
- package/dist/web/assets/erlang-DgkAVj5y.js +1 -0
- package/dist/web/assets/esm-wquH4IhX.js +2 -0
- package/dist/web/assets/explorer-body-CdxolRQG.js +2 -0
- package/dist/web/assets/explorer-window-content-D1fkI_cL.js +1 -0
- package/dist/web/assets/extension-manager-section-CAaSoAuG.js +1 -0
- package/dist/web/assets/extension-webview-DmBZun_i.js +12 -0
- package/dist/web/assets/file-icons-BlOxPo3P.js +1 -0
- package/dist/web/assets/file-store-CTlJqj2m.js +1 -0
- package/dist/web/assets/files-settings-section-BFIzSuBh.js +1 -0
- package/dist/web/assets/format-date-BMtvCeb9.js +1 -0
- package/dist/web/assets/format-file-meta-DLaHgkdx.js +1 -0
- package/dist/web/assets/fortran-fixed-form-s8lQifxM.js +1 -0
- package/dist/web/assets/fs-api-RVc5RtTA.js +1 -0
- package/dist/web/assets/fsharp-D6bmDjka.js +1 -0
- package/dist/web/assets/gdresource-wPII3GWW.js +1 -0
- package/dist/web/assets/general-settings-section-BLLUvdhX.js +1 -0
- package/dist/web/assets/git-commit-DqLhxK6K.js +1 -0
- package/dist/web/assets/git-log-panel-Lq2Vkm8w.js +1 -0
- package/dist/web/assets/git-rebase-Cy0Mp9W1.js +1 -0
- package/dist/web/assets/git-repo-store-DFTJ5ngK.js +1 -0
- package/dist/web/assets/gitGraph-HDMCJU4V-w1WApLyy.js +1 -0
- package/dist/web/assets/glide-data-grid-CHdKFqis.js +141 -0
- package/dist/web/assets/glimmer-js-CmHFqq4N.js +1 -0
- package/dist/web/assets/glimmer-ts-vLmZC1JJ.js +1 -0
- package/dist/web/assets/glsl-DArPh0ws.js +1 -0
- package/dist/web/assets/graphql-B-_Ilekp.js +1 -0
- package/dist/web/assets/group-chat-tab-D2bluLme.js +1 -0
- package/dist/web/assets/hack-4KVRpwwM.js +1 -0
- package/dist/web/assets/haml-DoK94C5G.js +1 -0
- package/dist/web/assets/handlebars-D0_6yNlK.js +1 -0
- package/dist/web/assets/html-BOqZwhzR.js +1 -0
- package/dist/web/assets/html-derivative-If_2xbJ8.js +1 -0
- package/dist/web/assets/http-B6pQhqN4.js +1 -0
- package/dist/web/assets/hurl-BjW79rql.js +1 -0
- package/dist/web/assets/hxml-B1Yl76u6.js +1 -0
- package/dist/web/assets/icons-CO_II6D-.js +1 -0
- package/dist/web/assets/image-preview-78Fguk1f.js +1 -0
- package/dist/web/assets/index-CzYrKDUF.css +1 -0
- package/dist/web/assets/index-DSbUqWiH.js +52 -0
- package/dist/web/assets/info-3K5VOQVL-Bv1wKdPY.js +1 -0
- package/dist/web/assets/input-CP31LZnN.js +1 -0
- package/dist/web/assets/java-DPqGHyuh.js +1 -0
- package/dist/web/assets/javascript-D8x_R8ev.js +1 -0
- package/dist/web/assets/jinja-DOkXV84k.js +1 -0
- package/dist/web/assets/jira-watcher-section-BOe_ztas.js +1 -0
- package/dist/web/assets/jison-CGzlyBWT.js +1 -0
- package/dist/web/assets/json-kcFjaEWA.js +1 -0
- package/dist/web/assets/jsx-BzlJCumN.js +1 -0
- package/dist/web/assets/julia-CZrbm1Fa.js +1 -0
- package/dist/web/assets/just-bRG6zWI_.js +1 -0
- package/dist/web/assets/keybindings-store-DFPJBiXT.js +1 -0
- package/dist/web/assets/keyboard-shortcuts-section-CJubMhMq.js +1 -0
- package/dist/web/assets/latex-CZHLEkde.js +1 -0
- package/dist/web/assets/lib-KePrAxj7.js +4 -0
- package/dist/web/assets/liquid-Dcfq3Ccc.js +1 -0
- package/dist/web/assets/lua-Ggfu9EYp.js +1 -0
- package/dist/web/assets/markdown-renderer-6oU-L6RN.js +5 -0
- package/dist/web/assets/markdown-renderer-DxSQ4aqW.js +1 -0
- package/dist/web/assets/marko-BUwN_Iax.js +1 -0
- package/dist/web/assets/mdc-CIifdeNY.js +1 -0
- package/dist/web/assets/media-url-GqzhazJS.js +1 -0
- package/dist/web/assets/mobile-bottom-sheet-Cf4kV1hS.js +1 -0
- package/dist/web/assets/mobile-explorer-sheet-D0968cuP.js +1 -0
- package/dist/web/assets/monaco-dotenv-language-COsgiuQg.js +1 -0
- package/dist/web/assets/new-chat-provider-CJx_waY3.js +1 -0
- package/dist/web/assets/new-design-dialog-CbrMbKum.js +1 -0
- package/dist/web/assets/nextflow-DufnRZW1.js +1 -0
- package/dist/web/assets/nginx-DtUJGfad.js +1 -0
- package/dist/web/assets/nim-BeBPwibr.js +1 -0
- package/dist/web/assets/notification-store-BO3RInEL.js +1 -0
- package/dist/web/assets/notifications-settings-section-Bfxqz65i.js +1 -0
- package/dist/web/assets/number-overlay-editor-xzM7GhYV.js +9 -0
- package/dist/web/assets/onboarding-entry-CcvySZ_l.js +1 -0
- package/dist/web/assets/onboarding-quick-orientation-CT4PylG0.js +1 -0
- package/dist/web/assets/overview-panel-DshAIz6C.js +1 -0
- package/dist/web/assets/packet-RMMSAZCW-Scl5HE6U.js +1 -0
- package/dist/web/assets/panel-store-BUQ-CPsd.js +1 -0
- package/dist/web/assets/pdf-preview-BWim6mu1.js +1 -0
- package/dist/web/assets/perl-hV0EoLCp.js +1 -0
- package/dist/web/assets/php-N1YBqBhK.js +1 -0
- package/dist/web/assets/pie-UPGHQEXC-sY83O9qJ.js +1 -0
- package/dist/web/assets/portal-container-context-NFSuymMu.js +1 -0
- package/dist/web/assets/postgres-viewer-HwlL1UTJ.js +3 -0
- package/dist/web/assets/ppmbot-settings-section-CHr2FIDj.js +1 -0
- package/dist/web/assets/pptx-export-D6DOknBD.js +111 -0
- package/dist/web/assets/problems-panel-41z59l78.js +1 -0
- package/dist/web/assets/process-table-CVMEMJqQ.js +1 -0
- package/dist/web/assets/project-framework-store-XxFXcUpb.js +1 -0
- package/dist/web/assets/project-store-C5gJXkvb.js +1 -0
- package/dist/web/assets/proxy-settings-section-B4dkvCCx.js +1 -0
- package/dist/web/assets/pug-IMA1knL7.js +1 -0
- package/dist/web/assets/qml-DuwVuXga.js +1 -0
- package/dist/web/assets/query-audit-section-Cn11xqgz.js +1 -0
- package/dist/web/assets/r-DsXT2lmn.js +1 -0
- package/dist/web/assets/radar-KQ55EAFF-CNhm_kzj.js +1 -0
- package/dist/web/assets/razor-Be4LE-G0.js +1 -0
- package/dist/web/assets/react-CzUPVyyG.js +1 -0
- package/dist/web/assets/regexp-ztLDvplH.js +1 -0
- package/dist/web/assets/remote-desktop-clipboard-notice-Co4vEiiB.js +1 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-Cv4yo7K4.js +2 -0
- package/dist/web/assets/remote-desktop-mobile-view-CcuulHIu.js +1 -0
- package/dist/web/assets/remote-desktop-readiness-gate-ouPRvBlu.js +1 -0
- package/dist/web/assets/remote-desktop-window-content-DmH3jBuG.js +1 -0
- package/dist/web/assets/rolldown-runtime-C5c2KzVm.js +1 -0
- package/dist/web/assets/rst-BdtOZUlL.js +1 -0
- package/dist/web/assets/ruby-DTna6e9n.js +1 -0
- package/dist/web/assets/run-in-terminal-SU9cwoZ4.js +1 -0
- package/dist/web/assets/sas-X50YKLBX.js +1 -0
- package/dist/web/assets/schedules-settings-section-Dy6hARk0.js +1 -0
- package/dist/web/assets/scroll-area-xAtds1T-.js +1 -0
- package/dist/web/assets/scss-cQk9zuqD.js +1 -0
- package/dist/web/assets/send-to-chat-TSKk3fI9.js +1 -0
- package/dist/web/assets/separator-D8SNZI6E.js +1 -0
- package/dist/web/assets/settings-body-CZSwxG0i.js +2 -0
- package/dist/web/assets/settings-store-DXmQug0m.js +2 -0
- package/dist/web/assets/settings-tab-B_WPC-y7.js +1 -0
- package/dist/web/assets/settings-window-content-CSWdwQn1.js +1 -0
- package/dist/web/assets/shaderlab-CSeOcwk6.js +1 -0
- package/dist/web/assets/shellscript-Dtzjnpp9.js +1 -0
- package/dist/web/assets/shellsession-AqADqsjv.js +1 -0
- package/dist/web/assets/soy-DeMex-y3.js +1 -0
- package/dist/web/assets/sparql-CDZTYDwx.js +1 -0
- package/dist/web/assets/sql-BS_vTOM8.js +1 -0
- package/dist/web/assets/sql-query-editor-6Ee_Zn5j.js +1 -0
- package/dist/web/assets/sqlite-viewer-Cj0S_m9V.js +1 -0
- package/dist/web/assets/stata-PkjbLwNy.js +1 -0
- package/dist/web/assets/surrealql-BJ6bKPXV.js +1 -0
- package/dist/web/assets/svelte-D4u1sGpe.js +1 -0
- package/dist/web/assets/system-monitor-body-PQqXdK4a.js +2 -0
- package/dist/web/assets/system-monitor-tab-BEjvgQuQ.js +1 -0
- package/dist/web/assets/system-monitor-window-content-DZwvvN-M.js +1 -0
- package/dist/web/assets/tab-host-window-content-CnV4Z4Yt.js +1 -0
- package/dist/web/assets/tab-store-DqeaGhhE.js +1 -0
- package/dist/web/assets/team-member-sheet-8EVCTM-X.js +2 -0
- package/dist/web/assets/team-member-window-content-Bc0ydBAn.js +1 -0
- package/dist/web/assets/templ-vtFoIgGG.js +1 -0
- package/dist/web/assets/terminal-tab-0b63-txz.js +3 -0
- package/dist/web/assets/tex-o6JLe3Qo.js +1 -0
- package/dist/web/assets/tool-cards-C09WknHl.js +9 -0
- package/dist/web/assets/treemap-KZPCXAKY-CfpX4ULx.js +1 -0
- package/dist/web/assets/ts-tags-DkmPnhIx.js +1 -0
- package/dist/web/assets/tsx-BUq9xm2T.js +1 -0
- package/dist/web/assets/twig-I9ja_Rk_.js +1 -0
- package/dist/web/assets/typescript-CP3RLBKz.js +1 -0
- package/dist/web/assets/use-blob-url-mZfScQdx.js +1 -0
- package/dist/web/assets/use-inline-blame-BuAc9IXE.js +16 -0
- package/dist/web/assets/use-is-mobile-CkO33jqU.js +1 -0
- package/dist/web/assets/use-lsp-DAtq1G0M.js +6 -0
- package/dist/web/assets/use-monaco-theme-Ch_znquJ.js +1 -0
- package/dist/web/assets/use-open-team-member-DHzZiJZw.js +1 -0
- package/dist/web/assets/use-visual-viewport-C307OVeV.js +1 -0
- package/dist/web/assets/use-websocket-DGEOad8p.js +1 -0
- package/dist/web/assets/vendor-markdown-QKPNiWEd.js +291 -0
- package/dist/web/assets/vendor-mermaid-eg2XWIjK.js +2921 -0
- package/dist/web/assets/vendor-ui-BHh12_0v.js +45 -0
- package/dist/web/assets/video-preview-DH3RtwVT.js +1 -0
- package/dist/web/assets/vue-DJf-APPD.js +1 -0
- package/dist/web/assets/vue-html-DUJ89Ycn.js +1 -0
- package/dist/web/assets/vue-vine-CWUFwuRE.js +1 -0
- package/dist/web/assets/window-pip-registry-DH07f_8k.js +1 -0
- package/dist/web/assets/window-store-B4cbZ5rr.js +1 -0
- package/dist/web/assets/ws-auth-B_y5rMfZ.js +1 -0
- package/dist/web/assets/xml-DshhaDKq.js +1 -0
- package/dist/web/assets/xsl-BlRNlmF7.js +1 -0
- package/dist/web/assets/yaml-seUOGdyI.js +1 -0
- package/dist/web/index.html +37 -36
- package/dist/web/sw.js +1 -1
- package/docs/architecture/workspace-and-ui.md +47 -0
- package/docs/project-roadmap.md +16 -0
- package/docs/system-architecture.md +11 -1
- package/package.json +4 -1
- package/scripts/gen-product-icons.ts +10 -0
- package/src/providers/claude-agent-sdk-query-options.ts +68 -1
- package/src/providers/claude-agent-sdk.ts +44 -15
- package/src/providers/codex-app-server/codex-event-mapper.ts +18 -1
- package/src/providers/codex-app-server/codex-jsonrpc-client.ts +4 -3
- package/src/providers/codex-app-server/codex-permission-map.ts +11 -1
- package/src/providers/codex-app-server/codex-protocol.ts +5 -0
- package/src/providers/codex-app-server/codex-provider.ts +32 -15
- package/src/providers/codex-app-server/codex-thread-params.ts +96 -0
- package/src/server/helpers/preview-asset-guard.ts +36 -0
- package/src/server/index.ts +15 -0
- package/src/server/routes/chat.ts +41 -4
- package/src/server/routes/design-check.ts +48 -0
- package/src/server/routes/design-comments.ts +63 -0
- package/src/server/routes/design-export.ts +84 -0
- package/src/server/routes/design-preview.ts +159 -0
- package/src/server/routes/design-route-helpers.ts +25 -0
- package/src/server/routes/design-style.ts +28 -0
- package/src/server/routes/design-tweaks.ts +38 -0
- package/src/server/routes/design-undo.ts +27 -0
- package/src/server/routes/designs.ts +101 -0
- package/src/server/routes/html-preview.ts +4 -24
- package/src/server/routes/project-scoped.ts +2 -0
- package/src/server/ws/chat.ts +8 -1
- package/src/server/ws/global.ts +22 -1
- package/src/services/chat.service.ts +64 -1
- package/src/services/db.service.ts +73 -4
- package/src/services/design/bridge/bridge-anchor-resolve.ts +96 -0
- package/src/services/design/bridge/bridge-core.ts +205 -0
- package/src/services/design/bridge/bridge-element-info.ts +180 -0
- package/src/services/design/bridge/bridge-extract-blocks.ts +115 -0
- package/src/services/design/bridge/bridge-extract-images.ts +96 -0
- package/src/services/design/bridge/bridge-extract-slides.ts +169 -0
- package/src/services/design/bridge/bridge-extract-text.ts +187 -0
- package/src/services/design/bridge/bridge-layout-boxes.ts +137 -0
- package/src/services/design/bridge/bridge-layout-check.ts +99 -0
- package/src/services/design/bridge/bridge-layout-grid.ts +165 -0
- package/src/services/design/bridge/bridge-layout-screenshot.ts +106 -0
- package/src/services/design/bridge/bridge-nav-guard.ts +61 -0
- package/src/services/design/bridge/bridge-picker-overlay.ts +54 -0
- package/src/services/design/bridge/bridge-picker.ts +174 -0
- package/src/services/design/bridge/bridge-pins.ts +157 -0
- package/src/services/design/bridge/bridge-script.ts +104 -0
- package/src/services/design/bridge/bridge-transform-math.ts +104 -0
- package/src/services/design/bridge/bridge-transform-overlay.ts +94 -0
- package/src/services/design/bridge/bridge-transform-style.ts +78 -0
- package/src/services/design/bridge/bridge-transform.ts +201 -0
- package/src/services/design/bridge/bridge-tweaks.ts +118 -0
- package/src/services/design/check/design-canvas-check-broker.ts +77 -0
- package/src/services/design/comments/design-comment-element-context.ts +81 -0
- package/src/services/design/comments/design-comments-store.ts +81 -0
- package/src/services/design/design-comments.service.ts +140 -0
- package/src/services/design/design-edit-undo-journal.ts +125 -0
- package/src/services/design/design-error.ts +19 -0
- package/src/services/design/design-events.ts +46 -0
- package/src/services/design/design-fs.ts +67 -0
- package/src/services/design/design-instructions.ts +97 -0
- package/src/services/design/design-lock.ts +74 -0
- package/src/services/design/design-manifest.ts +92 -0
- package/src/services/design/design-paths.ts +97 -0
- package/src/services/design/design-restore-journal.ts +143 -0
- package/src/services/design/design-restore.service.ts +77 -0
- package/src/services/design/design-safe-walk.ts +114 -0
- package/src/services/design/design-slug.ts +35 -0
- package/src/services/design/design-snapshot-history.ts +159 -0
- package/src/services/design/design-snapshots.service.ts +161 -0
- package/src/services/design/design-starter-template.ts +100 -0
- package/src/services/design/design-store.service.ts +156 -0
- package/src/services/design/design-style-patch.service.ts +83 -0
- package/src/services/design/design-tool-policy.ts +111 -0
- package/src/services/design/design-turn-snapshot.ts +80 -0
- package/src/services/design/design-tweaks-commit.service.ts +138 -0
- package/src/services/design/design-write-rate-limit.ts +51 -0
- package/src/services/design/export/css-url-inline.ts +130 -0
- package/src/services/design/export/design-export-asset-reader.ts +57 -0
- package/src/services/design/export/design-export-entry.ts +33 -0
- package/src/services/design/export/design-standalone-html.ts +167 -0
- package/src/services/design/export/design-zip-export.ts +106 -0
- package/src/services/design/mcp/design-mcp-access.ts +16 -0
- package/src/services/design/mcp/design-mcp-endpoint.ts +118 -0
- package/src/services/design/mcp/design-mcp-tokens.ts +82 -0
- package/src/services/design/mcp/design-mcp-tool.ts +41 -0
- package/src/services/design/preview/design-csp.ts +31 -0
- package/src/services/design/preview/design-preview-html.ts +98 -0
- package/src/services/design/preview/design-preview-scope.ts +66 -0
- package/src/services/design/preview/design-preview-tokens.ts +137 -0
- package/src/services/design/preview/expired-page.ts +30 -0
- package/src/services/design/preview/html-instrument.ts +119 -0
- package/src/services/design/preview/print-view.ts +62 -0
- package/src/services/design/source/css-root-selector.ts +20 -0
- package/src/services/design/source/css-root-vars-patch.ts +202 -0
- package/src/services/design/source/design-source-file.ts +62 -0
- package/src/services/design/source/design-style-sources.ts +101 -0
- package/src/services/design/source/element-source-range.ts +65 -0
- package/src/services/design/source/html-style-blocks.ts +87 -0
- package/src/services/design/source/inline-style-declarations.ts +131 -0
- package/src/services/design/source/inline-style-patch.ts +79 -0
- package/src/services/design/source/tweak-patch-plan.ts +143 -0
- package/src/services/file-watcher/ignore-rules.ts +9 -1
- package/src/services/server-listen-address.ts +25 -0
- package/src/shared/design-bridge-messages-check.ts +44 -0
- package/src/shared/design-bridge-messages-picker.ts +142 -0
- package/src/shared/design-bridge-messages-slides.ts +37 -0
- package/src/shared/design-bridge-messages-transform.ts +121 -0
- package/src/shared/design-bridge-messages-tweaks.ts +65 -0
- package/src/shared/design-bridge-protocol.ts +158 -0
- package/src/shared/design-canvas-check-format.ts +69 -0
- package/src/shared/design-canvas-check.ts +148 -0
- package/src/shared/design-cdn-hosts.ts +17 -0
- package/src/shared/design-comment-types.ts +111 -0
- package/src/shared/design-slide-doc-parse.ts +140 -0
- package/src/shared/design-slide-doc.ts +91 -0
- package/src/shared/design-system-init-prompt.ts +35 -0
- package/src/shared/design-tweaks.ts +175 -0
- package/src/shared/design-types.ts +63 -0
- package/src/shared/untrusted-text.ts +15 -0
- package/src/types/chat.ts +22 -0
- package/src/types/config.ts +1 -1
- package/src/web/components/chat/chat-history-bar.tsx +18 -15
- package/src/web/components/chat/chat-history-panel.tsx +3 -9
- package/src/web/components/chat/chat-tab.tsx +74 -40
- package/src/web/components/chat/message-input.tsx +11 -4
- package/src/web/components/chat/session-history-list.tsx +5 -9
- package/src/web/components/design/canvas/canvas-geometry.ts +47 -0
- package/src/web/components/design/canvas/design-canvas-pane.tsx +192 -0
- package/src/web/components/design/canvas/design-issues-badge.tsx +71 -0
- package/src/web/components/design/canvas/device-frame-presets.ts +37 -0
- package/src/web/components/design/canvas/use-design-bridge.ts +169 -0
- package/src/web/components/design/canvas/use-design-canvas-check.ts +110 -0
- package/src/web/components/design/canvas/use-design-canvas.ts +107 -0
- package/src/web/components/design/canvas/use-design-live-reload.ts +86 -0
- package/src/web/components/design/canvas/use-design-preview-url.ts +74 -0
- package/src/web/components/design/canvas/use-expanded-canvas-escape.ts +29 -0
- package/src/web/components/design/comments/comment-composer.tsx +107 -0
- package/src/web/components/design/comments/comment-overlay-geometry.ts +50 -0
- package/src/web/components/design/comments/comment-pins-overlay.tsx +70 -0
- package/src/web/components/design/comments/comments-panel.tsx +118 -0
- package/src/web/components/design/comments/comments-send-preview.tsx +43 -0
- package/src/web/components/design/comments/design-comments-layer.tsx +73 -0
- package/src/web/components/design/comments/element-action-bar.tsx +105 -0
- package/src/web/components/design/comments/use-comment-pins.ts +118 -0
- package/src/web/components/design/comments/use-design-comments-feature.ts +124 -0
- package/src/web/components/design/comments/use-design-comments.ts +89 -0
- package/src/web/components/design/comments/use-element-picker.ts +87 -0
- package/src/web/components/design/design-chat-pane.tsx +51 -0
- package/src/web/components/design/design-layout-controls.tsx +84 -0
- package/src/web/components/design/design-mobile-layout.tsx +34 -0
- package/src/web/components/design/design-split-layout.tsx +99 -0
- package/src/web/components/design/design-tab-context.ts +44 -0
- package/src/web/components/design/design-tab.tsx +116 -0
- package/src/web/components/design/design-toolbar-list.tsx +36 -0
- package/src/web/components/design/design-toolbar.tsx +200 -0
- package/src/web/components/design/designs-sidebar-panel.tsx +117 -0
- package/src/web/components/design/dialogs/delete-design-dialog.tsx +69 -0
- package/src/web/components/design/dialogs/design-responsive-dialog.tsx +48 -0
- package/src/web/components/design/dialogs/new-design-dialog.tsx +113 -0
- package/src/web/components/design/dialogs/rename-design-dialog.tsx +56 -0
- package/src/web/components/design/export/export-menu.tsx +108 -0
- package/src/web/components/design/export/export-warnings-sheet.tsx +35 -0
- package/src/web/components/design/export/pptx-export.ts +38 -0
- package/src/web/components/design/export/use-design-export.ts +142 -0
- package/src/web/components/design/history/design-history-panel.tsx +119 -0
- package/src/web/components/design/transform/design-undo-stack.ts +90 -0
- package/src/web/components/design/transform/transform-readout.tsx +50 -0
- package/src/web/components/design/transform/use-canvas-transform.ts +181 -0
- package/src/web/components/design/tweaks/tweak-control.tsx +94 -0
- package/src/web/components/design/tweaks/tweaks-panel.tsx +99 -0
- package/src/web/components/design/tweaks/use-design-tweaks.ts +151 -0
- package/src/web/components/design/use-design-auto-check.ts +94 -0
- package/src/web/components/design/use-design-layout.ts +55 -0
- package/src/web/components/design/use-design-summary.ts +63 -0
- package/src/web/components/layout/command-palette-design-commands.tsx +75 -0
- package/src/web/components/layout/command-palette.tsx +12 -4
- package/src/web/components/layout/editor-panel.tsx +4 -10
- package/src/web/components/layout/mobile-drawer.tsx +9 -2
- package/src/web/components/layout/mobile-nav.tsx +3 -2
- package/src/web/components/layout/mobile-tab-switcher-sheet.tsx +4 -5
- package/src/web/components/layout/sidebar.tsx +8 -1
- package/src/web/components/layout/tab-bar.tsx +3 -2
- package/src/web/components/layout/tab-content.tsx +5 -0
- package/src/web/components/layout/tab-pool.tsx +1 -0
- package/src/web/components/onboarding/onboarding-quick-orientation.tsx +1 -0
- package/src/web/hooks/use-chat.ts +8 -4
- package/src/web/hooks/use-design-session-redirect.ts +39 -0
- package/src/web/hooks/use-design-session-state.ts +94 -0
- package/src/web/hooks/use-global-events.ts +4 -1
- package/src/web/hooks/use-session-history.ts +4 -10
- package/src/web/hooks/use-url-sync.ts +10 -2
- package/src/web/lib/design/api-design-comments.ts +42 -0
- package/src/web/lib/design/api-design-edits.ts +62 -0
- package/src/web/lib/design/api-design-tweaks.ts +64 -0
- package/src/web/lib/design/api-designs.ts +81 -0
- package/src/web/lib/design/deliver-to-design-chat.ts +63 -0
- package/src/web/lib/design/design-auto-check-rounds.ts +32 -0
- package/src/web/lib/design/design-change-filter.ts +27 -0
- package/src/web/lib/design/design-comments-prompt.ts +55 -0
- package/src/web/lib/design/design-export-client.ts +101 -0
- package/src/web/lib/design/design-handoff-prompt.ts +48 -0
- package/src/web/lib/design/design-layout-mode.ts +79 -0
- package/src/web/lib/design/design-tab-metadata.ts +41 -0
- package/src/web/lib/design/design-transform-proposal.ts +62 -0
- package/src/web/lib/design/design-tweaks-model.ts +76 -0
- package/src/web/lib/design/design-ui-events.ts +25 -0
- package/src/web/lib/design/design-view-prefs.ts +90 -0
- package/src/web/lib/design/open-design-tab.ts +78 -0
- package/src/web/lib/design/pptx-slide-mapper.ts +118 -0
- package/src/web/lib/feature-badges.ts +2 -0
- package/src/web/lib/fluent-icon.tsx +38 -2
- package/src/web/lib/icons.generated.tsx +17 -1
- package/src/web/lib/patch-tab-metadata.ts +30 -0
- package/src/web/lib/send-to-chat.ts +16 -2
- package/src/web/lib/sidebar-tabs/tab-registry.ts +2 -0
- package/src/web/lib/tab-session-id.ts +16 -0
- package/src/web/lib/tab-type-icons.ts +2 -1
- package/src/web/stores/panel-store.ts +29 -1
- package/src/web/stores/panel-utils.ts +8 -1
- package/src/web/stores/settings-store.ts +2 -2
- package/src/web/stores/tab-store.ts +2 -1
- package/src/web/stores/window-panel-persistence.ts +1 -0
- package/dist/web/assets/accounts-settings-section-BDXYG6tT.js +0 -1
- package/dist/web/assets/ai-resource-editor-C3rKcZKN.js +0 -1
- package/dist/web/assets/ai-settings-section-ArqD8Nlg.js +0 -1
- package/dist/web/assets/ai-settings-section-DeWoAdLc.js +0 -1
- package/dist/web/assets/angular-html-DnrsWZqK.js +0 -1
- package/dist/web/assets/angular-ts-BXEqA9t1.js +0 -1
- package/dist/web/assets/api-client-Jn3njtNw.js +0 -1
- package/dist/web/assets/api-client-rSFnnCj4.js +0 -1
- package/dist/web/assets/api-settings-BZFSteM_.js +0 -1
- package/dist/web/assets/api-themes-CvKtX6Hd.js +0 -1
- package/dist/web/assets/apl-DUQ6Oyth.js +0 -1
- package/dist/web/assets/appearance-settings-section-K5o_Di4V.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-B9M_VqZI.js +0 -1
- package/dist/web/assets/astro-CakOjJ6X.js +0 -1
- package/dist/web/assets/audio-preview-CwCDCN-_.js +0 -1
- package/dist/web/assets/blade-C903KM82.js +0 -1
- package/dist/web/assets/branch-review-tab-BNpYiUhC.js +0 -1
- package/dist/web/assets/bsl-slfcE_kB.js +0 -1
- package/dist/web/assets/button-B9CTrsEf.js +0 -1
- package/dist/web/assets/c-BWO-aeyf.js +0 -1
- package/dist/web/assets/cairo-DRwEaH6w.js +0 -1
- package/dist/web/assets/chat-tab-CC8KANoK.js +0 -15
- package/dist/web/assets/cobol--n4m6b70.js +0 -1
- package/dist/web/assets/code-editor-Ccf0Egrc.js +0 -7
- package/dist/web/assets/codex-daily-guard-CKk2WFlV.js +0 -1
- package/dist/web/assets/coffee-CjyFmw8_.js +0 -1
- package/dist/web/assets/conflict-editor-BCKbdpXy.js +0 -19
- package/dist/web/assets/context-menu-C6pIsf83.js +0 -1
- package/dist/web/assets/cpp-D18jdQPZ.js +0 -1
- package/dist/web/assets/createLucideIcon-DoiEKeJ_.js +0 -1
- package/dist/web/assets/crystal-CySzfH-7.js +0 -1
- package/dist/web/assets/css-Ca_hTmU6.js +0 -1
- package/dist/web/assets/csv-preview-I3a2lGUx.js +0 -2
- package/dist/web/assets/data-grid-overlay-editor-BD9eJweQ.js +0 -1
- package/dist/web/assets/data-grid-types-C6UX8kgh.js +0 -1
- package/dist/web/assets/database-viewer-DCuBR-bZ.js +0 -1
- package/dist/web/assets/dialog-B84_DJQ8.js +0 -1
- package/dist/web/assets/diff-viewer-DGaBe_Ln.js +0 -4
- package/dist/web/assets/dist-BD2gbdy0.js +0 -1
- package/dist/web/assets/docx-preview-CeH6p2Oi.js +0 -12
- package/dist/web/assets/edge-B6b5FHmU.js +0 -1
- package/dist/web/assets/edit-diff-preview-BG5DsLJG.js +0 -7
- package/dist/web/assets/editor-language-service-BaocEaLc.js +0 -1
- package/dist/web/assets/elixir-Dpo1rvn2.js +0 -1
- package/dist/web/assets/elm-D9CNOsWT.js +0 -1
- package/dist/web/assets/erb-sY7Yee1W.js +0 -1
- package/dist/web/assets/erlang-CfyrBxyF.js +0 -1
- package/dist/web/assets/esm-5AhGJcV8.js +0 -2
- package/dist/web/assets/explorer-body-2GYIYmUh.js +0 -2
- package/dist/web/assets/explorer-window-content-CYQSEX-g.js +0 -1
- package/dist/web/assets/extension-manager-section-BFAGdy3G.js +0 -1
- package/dist/web/assets/extension-webview-D5TXIBMf.js +0 -12
- package/dist/web/assets/file-icons-wS-OmEVu.js +0 -1
- package/dist/web/assets/file-store-Ds3qJ4hC.js +0 -1
- package/dist/web/assets/files-settings-section-BE6o-oHu.js +0 -1
- package/dist/web/assets/format-file-meta-eKLstbCL.js +0 -1
- package/dist/web/assets/fortran-fixed-form-N67gM_wp.js +0 -1
- package/dist/web/assets/fs-api-orca76dV.js +0 -1
- package/dist/web/assets/fsharp-Dq0K01wX.js +0 -1
- package/dist/web/assets/gdresource-DkFbszqY.js +0 -1
- package/dist/web/assets/general-settings-section-mQiXM537.js +0 -1
- package/dist/web/assets/git-commit-Ddt_nerD.js +0 -1
- package/dist/web/assets/git-log-panel-DqbcM9eC.js +0 -1
- package/dist/web/assets/git-rebase-CVK5OA7i.js +0 -1
- package/dist/web/assets/git-repo-store-BCEPfUGT.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-D3RB33aA.js +0 -1
- package/dist/web/assets/glide-data-grid-BjEF7M5i.js +0 -141
- package/dist/web/assets/glimmer-js-51jbYnyY.js +0 -1
- package/dist/web/assets/glimmer-ts-C5L1J32J.js +0 -1
- package/dist/web/assets/glsl-BcsfmwJZ.js +0 -1
- package/dist/web/assets/graphql-dv4wuJsK.js +0 -1
- package/dist/web/assets/group-chat-tab-aX2GEnkD.js +0 -1
- package/dist/web/assets/hack-DLE5d3bx.js +0 -1
- package/dist/web/assets/haml-CoKfcM3E.js +0 -1
- package/dist/web/assets/handlebars-Bn0jy8pD.js +0 -1
- package/dist/web/assets/html-DXzY5Cew.js +0 -1
- package/dist/web/assets/html-derivative-DhcVfYuw.js +0 -1
- package/dist/web/assets/http-DepeIWQ1.js +0 -1
- package/dist/web/assets/hurl-CfsP4sCj.js +0 -1
- package/dist/web/assets/hxml-IfVkY3HL.js +0 -1
- package/dist/web/assets/icons-DQjqk0lJ.js +0 -1
- package/dist/web/assets/image-preview-CWncz5iI.js +0 -1
- package/dist/web/assets/index-BoaecXhu.js +0 -52
- package/dist/web/assets/index-aXJy_SvC.css +0 -1
- package/dist/web/assets/info-3K5VOQVL-DDX-2VB7.js +0 -1
- package/dist/web/assets/input-QNG_gTHh.js +0 -1
- package/dist/web/assets/java-JWdrzVo8.js +0 -1
- package/dist/web/assets/javascript-5aQKJRxB.js +0 -1
- package/dist/web/assets/jinja-DcCmNDQ8.js +0 -1
- package/dist/web/assets/jira-watcher-section-BKn3A8zI.js +0 -1
- package/dist/web/assets/jison-Bt-5cKVZ.js +0 -1
- package/dist/web/assets/json-BOq7QblK.js +0 -1
- package/dist/web/assets/jsx-BSLWViGE.js +0 -1
- package/dist/web/assets/julia-DewYVRtE.js +0 -1
- package/dist/web/assets/just-CLT_ggBy.js +0 -1
- package/dist/web/assets/keybindings-store-Brz0qepi.js +0 -1
- package/dist/web/assets/keyboard-shortcuts-section-Ck8KIbJ8.js +0 -1
- package/dist/web/assets/latex-DXmcayW1.js +0 -1
- package/dist/web/assets/lib-BWyA9SvU.js +0 -4
- package/dist/web/assets/liquid-BVcHf0IA.js +0 -1
- package/dist/web/assets/lua-BYupsB1B.js +0 -1
- package/dist/web/assets/markdown-renderer-BGuM2PBI.js +0 -5
- package/dist/web/assets/markdown-renderer-Ddz8tPbb.js +0 -1
- package/dist/web/assets/marko-CsD0R5tv.js +0 -1
- package/dist/web/assets/mdc-DP2tC4Kc.js +0 -1
- package/dist/web/assets/media-url-CVO4m4zr.js +0 -1
- package/dist/web/assets/mobile-bottom-sheet-C3TniEP-.js +0 -1
- package/dist/web/assets/mobile-explorer-sheet-DpKfB6iF.js +0 -1
- package/dist/web/assets/monaco-dotenv-language-DD8_UQG7.js +0 -1
- package/dist/web/assets/nextflow-FQM6iZO2.js +0 -1
- package/dist/web/assets/nginx-Bg0TK_a9.js +0 -1
- package/dist/web/assets/nim-D1kSCHdq.js +0 -1
- package/dist/web/assets/notification-store-ByCdTvCC.js +0 -1
- package/dist/web/assets/notifications-settings-section-C5v8FoH9.js +0 -1
- package/dist/web/assets/number-overlay-editor-Bsr04yCI.js +0 -9
- package/dist/web/assets/onboarding-entry-C81awoR5.js +0 -1
- package/dist/web/assets/onboarding-quick-orientation-Dqmis-E5.js +0 -1
- package/dist/web/assets/overview-panel-9OdBcYJC.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-B0ZSm6VM.js +0 -1
- package/dist/web/assets/panel-store-D20Zuf3i.js +0 -1
- package/dist/web/assets/pdf-preview-DuR07OfN.js +0 -1
- package/dist/web/assets/perl-B6QNc69s.js +0 -1
- package/dist/web/assets/php-Bvwf1t96.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-DKM0oPn7.js +0 -1
- package/dist/web/assets/portal-container-context-BarKmT4S.js +0 -1
- package/dist/web/assets/postgres-viewer-CGf7_g6Z.js +0 -3
- package/dist/web/assets/ppmbot-settings-section-DeTFU1b-.js +0 -1
- package/dist/web/assets/problems-panel-Bgkcge5_.js +0 -1
- package/dist/web/assets/process-table-DH7pnH5I.js +0 -1
- package/dist/web/assets/project-framework-store-ViZgce6y.js +0 -1
- package/dist/web/assets/project-store-hNvwfqX3.js +0 -1
- package/dist/web/assets/proxy-settings-section-DMGMRHH-.js +0 -1
- package/dist/web/assets/pug-I8oitXP4.js +0 -1
- package/dist/web/assets/qml-LKb7CHg-.js +0 -1
- package/dist/web/assets/query-audit-section-CpiXQVcS.js +0 -1
- package/dist/web/assets/r-DHu15BOo.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-DKhtzXmy.js +0 -1
- package/dist/web/assets/razor-CIPT897U.js +0 -1
- package/dist/web/assets/react-Bghu0NUO.js +0 -1
- package/dist/web/assets/regexp-Vdt2OEkk.js +0 -1
- package/dist/web/assets/remote-desktop-clipboard-notice-Bj5FtU0O.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-BhwVrKxv.js +0 -2
- package/dist/web/assets/remote-desktop-mobile-view-B1oAqbjG.js +0 -1
- package/dist/web/assets/remote-desktop-readiness-gate-2LE86aTu.js +0 -1
- package/dist/web/assets/remote-desktop-window-content-u8HwuzyN.js +0 -1
- package/dist/web/assets/rolldown-runtime-FhOqtrmT.js +0 -1
- package/dist/web/assets/rst-BpcmfJFA.js +0 -1
- package/dist/web/assets/ruby-Cx413jgE.js +0 -1
- package/dist/web/assets/run-in-terminal-BFR70TLU.js +0 -1
- package/dist/web/assets/sas-B3ui_NHy.js +0 -1
- package/dist/web/assets/schedules-settings-section-C8XNDdi9.js +0 -1
- package/dist/web/assets/scroll-area-C0fQWNnx.js +0 -1
- package/dist/web/assets/scss-V4NlXnGi.js +0 -1
- package/dist/web/assets/send-to-chat-C8l7AcV4.js +0 -1
- package/dist/web/assets/separator-DwDoQpxS.js +0 -1
- package/dist/web/assets/settings-body-DelxmiKf.js +0 -2
- package/dist/web/assets/settings-store-m6qOXoy4.js +0 -2
- package/dist/web/assets/settings-tab-Cb_dFdA6.js +0 -1
- package/dist/web/assets/settings-window-content-5EQQfC1t.js +0 -1
- package/dist/web/assets/shaderlab-Cf7qZ4DR.js +0 -1
- package/dist/web/assets/shellscript-DRxJLgrx.js +0 -1
- package/dist/web/assets/shellsession-BfA8Fmhb.js +0 -1
- package/dist/web/assets/soy-CGKN9rxg.js +0 -1
- package/dist/web/assets/sparql-CArCsIdI.js +0 -1
- package/dist/web/assets/sql-ljEiM8nf.js +0 -1
- package/dist/web/assets/sql-query-editor-B3wrPR6K.js +0 -1
- package/dist/web/assets/sqlite-viewer-iQXNp0kH.js +0 -1
- package/dist/web/assets/stata-CplvndbA.js +0 -1
- package/dist/web/assets/surrealql-DwX1PCpP.js +0 -1
- package/dist/web/assets/svelte-DYCNmQjy.js +0 -1
- package/dist/web/assets/system-monitor-body-5grJyA7C.js +0 -2
- package/dist/web/assets/system-monitor-tab-CJr797F8.js +0 -1
- package/dist/web/assets/system-monitor-window-content-OGAhFXXo.js +0 -1
- package/dist/web/assets/tab-host-window-content-C-eEo8I7.js +0 -1
- package/dist/web/assets/tab-store-krAuHQ6_.js +0 -1
- package/dist/web/assets/team-member-sheet-CRvJUtdh.js +0 -2
- package/dist/web/assets/team-member-window-content-C97N4RXb.js +0 -1
- package/dist/web/assets/templ-b_h2-Z9l.js +0 -1
- package/dist/web/assets/terminal-tab-eZwpkvEe.js +0 -3
- package/dist/web/assets/tex-022M3-MR.js +0 -1
- package/dist/web/assets/tool-cards-Bg4vjDYu.js +0 -9
- package/dist/web/assets/treemap-KZPCXAKY-CxqsD_6n.js +0 -1
- package/dist/web/assets/ts-tags-BUl0AdO6.js +0 -1
- package/dist/web/assets/tsx-CKaH7SzK.js +0 -1
- package/dist/web/assets/twig-CMzYUcSa.js +0 -1
- package/dist/web/assets/typescript-DZozDFsi.js +0 -1
- package/dist/web/assets/use-blob-url-C0VR6Uhh.js +0 -1
- package/dist/web/assets/use-inline-blame-CzR8CnOZ.js +0 -16
- package/dist/web/assets/use-is-mobile-TkcwP1Gx.js +0 -1
- package/dist/web/assets/use-lsp-BAoOSc-L.js +0 -6
- package/dist/web/assets/use-monaco-theme-Gd8cpt9n.js +0 -1
- package/dist/web/assets/use-open-team-member-y9sVhaNr.js +0 -1
- package/dist/web/assets/use-visual-viewport-Lp878uzs.js +0 -1
- package/dist/web/assets/use-websocket-CDfXkXo3.js +0 -1
- package/dist/web/assets/vendor-markdown-CuWCHIVb.js +0 -291
- package/dist/web/assets/vendor-mermaid-D6lgjvVE.js +0 -2921
- package/dist/web/assets/vendor-ui-DmZ-Mb-H.js +0 -45
- package/dist/web/assets/video-preview-BYJ3aVo1.js +0 -1
- package/dist/web/assets/vue-D83SsURi.js +0 -1
- package/dist/web/assets/vue-html-BGU-OYYb.js +0 -1
- package/dist/web/assets/vue-vine-1sHE1gZn.js +0 -1
- package/dist/web/assets/window-pip-registry-D1oXq-Dq.js +0 -1
- package/dist/web/assets/window-store-UC1jJeLM.js +0 -1
- package/dist/web/assets/ws-auth-CaxV807E.js +0 -1
- package/dist/web/assets/xml-bWQJszMK.js +0 -1
- package/dist/web/assets/xsl-DTMc1Tsm.js +0 -1
- package/dist/web/assets/yaml-4pzZq5KT.js +0 -1
- /package/dist/web/assets/{abap-DrxZXLHj.js → abap-DWbETETF.js} +0 -0
- /package/dist/web/assets/{actionscript-3-DOPR4pRC.js → actionscript-3-C278tgAF.js} +0 -0
- /package/dist/web/assets/{ada-DkqjEnDr.js → ada-C_5J29IC.js} +0 -0
- /package/dist/web/assets/{andromeeda-BSZjevw2.js → andromeeda-Ct0fb9Zo.js} +0 -0
- /package/dist/web/assets/{apache-DYwdQ5F_.js → apache-oMwCqc2o.js} +0 -0
- /package/dist/web/assets/{apex-Dohu7DfB.js → apex-n6XQQudq.js} +0 -0
- /package/dist/web/assets/{applescript-CdfGIVqp.js → applescript-QDMA6blY.js} +0 -0
- /package/dist/web/assets/{apply-theme-CbR31K6I.js → apply-theme-aVoqSG0I.js} +0 -0
- /package/dist/web/assets/{ara-i3_3TMnI.js → ara-D6rg_rTp.js} +0 -0
- /package/dist/web/assets/{asciidoc-DJFM-7vl.js → asciidoc-DVeBWv0S.js} +0 -0
- /package/dist/web/assets/{asm-bMFssizQ.js → asm-DzHQzzqu.js} +0 -0
- /package/dist/web/assets/{aurora-x-CetC7M8b.js → aurora-x-pJESoXa6.js} +0 -0
- /package/dist/web/assets/{awk-FFWx9ZrE.js → awk-BwfK4mzn.js} +0 -0
- /package/dist/web/assets/{ayu-dark-D4ION2wO.js → ayu-dark-CG-9c7ej.js} +0 -0
- /package/dist/web/assets/{ayu-light-BZN99P5A.js → ayu-light-BGUfMG6m.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-B-IpsKiL.js → ayu-mirage-CMD89qy6.js} +0 -0
- /package/dist/web/assets/{ballerina-DhyJcKkq.js → ballerina-CP5gYaiB.js} +0 -0
- /package/dist/web/assets/{bat-GOVQY81F.js → bat-DCRdiK45.js} +0 -0
- /package/dist/web/assets/{beancount-BO749Rhc.js → beancount-DHkDiOKO.js} +0 -0
- /package/dist/web/assets/{berry-CHYYKXmK.js → berry-B6TPldKS.js} +0 -0
- /package/dist/web/assets/{bibtex-BnYiDnxT.js → bibtex-DIor8yh9.js} +0 -0
- /package/dist/web/assets/{bicep-kljgR_G3.js → bicep-BbIdLZZ_.js} +0 -0
- /package/dist/web/assets/{bird2-DnLtJGhV.js → bird2-C76TmOG1.js} +0 -0
- /package/dist/web/assets/{c3-fc_jio6D.js → c3-CqZ77xXr.js} +0 -0
- /package/dist/web/assets/{cadence-DopRCrdB.js → cadence-BlaAb6F6.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-CUW3vVJg.js → can-open-in-ppm-D8T6Xca-.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DL6iCUa8.js → catppuccin-frappe-BuV7Zg67.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-DNF7n3uY.js → catppuccin-latte-B7HXEZf7.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-ByMic_k0.js → catppuccin-macchiato-B0KctcoC.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-DcrJtZtv.js → catppuccin-mocha-Bofr5rzo.js} +0 -0
- /package/dist/web/assets/{clarity-0cRLlvQe.js → clarity-CerfZ3dW.js} +0 -0
- /package/dist/web/assets/{clojure-DPqZAcpI.js → clojure-BCEG1uj6.js} +0 -0
- /package/dist/web/assets/{cmake-Bx26bw5u.js → cmake-CRxSSKSr.js} +0 -0
- /package/dist/web/assets/{codeowners-BpgxIgxr.js → codeowners-BqW6DYSk.js} +0 -0
- /package/dist/web/assets/{codeql-TRoWjo5g.js → codeql-DlnOpgWF.js} +0 -0
- /package/dist/web/assets/{common-lisp-Ctohamsb.js → common-lisp-DgIX9jkq.js} +0 -0
- /package/dist/web/assets/{coq-BO6TJSED.js → coq-CFeLOER-.js} +0 -0
- /package/dist/web/assets/{csharp-DSy4nlrl.js → csharp-BGFGcV8G.js} +0 -0
- /package/dist/web/assets/{csv-DND7YJXD.js → csv-Cx126-fo.js} +0 -0
- /package/dist/web/assets/{csv-parser-DZ_75eCb.js → csv-parser-BXeH-yzY.js} +0 -0
- /package/dist/web/assets/{cue-BUnWK221.js → cue-Cd0PEGFL.js} +0 -0
- /package/dist/web/assets/{cypher-CInm9Etl.js → cypher-QS9S-1Nu.js} +0 -0
- /package/dist/web/assets/{d-BbsB8r6R.js → d-Bx6zK6J7.js} +0 -0
- /package/dist/web/assets/{dark-plus-DkzIiuQX.js → dark-plus-DLqXEd2I.js} +0 -0
- /package/dist/web/assets/{dart-BG2nw7Se.js → dart-BL2C2Z6E.js} +0 -0
- /package/dist/web/assets/{dax-j4h6VhlV.js → dax-ClxUDxvY.js} +0 -0
- /package/dist/web/assets/{desktop-Dg34JDlS.js → desktop-DLEkw1UR.js} +0 -0
- /package/dist/web/assets/{diff-CRrKo-mH.js → diff-Dlp9KQSL.js} +0 -0
- /package/dist/web/assets/{dist-D39GQICe.js → dist-CDpxSUMU.js} +0 -0
- /package/dist/web/assets/{docker-DAtcxZjt.js → docker-DVBsQYb-.js} +0 -0
- /package/dist/web/assets/{dotenv-DNUcgQCn.js → dotenv-DjBB7S8B.js} +0 -0
- /package/dist/web/assets/{dracula-bhhaShNC.js → dracula-Cu055q9D.js} +0 -0
- /package/dist/web/assets/{dracula-soft-CeHAoi-D.js → dracula-soft-BiX_luwV.js} +0 -0
- /package/dist/web/assets/{dream-maker-BMH1JI2G.js → dream-maker-S6ie6kFg.js} +0 -0
- /package/dist/web/assets/{editor-font-D_4aaSCa.js → editor-font-BOjGgYeg.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-BaAYIdWN.js → emacs-lisp-DpOda430.js} +0 -0
- /package/dist/web/assets/{everforest-dark-Cs91gPa_.js → everforest-dark-BAfSXdLG.js} +0 -0
- /package/dist/web/assets/{everforest-light-lTkE6qWA.js → everforest-light-Dp59kp4R.js} +0 -0
- /package/dist/web/assets/{fennel-CmhYEhcM.js → fennel-CNaNUmMo.js} +0 -0
- /package/dist/web/assets/{fish-p1jauFum.js → fish-C8Z04ic7.js} +0 -0
- /package/dist/web/assets/{fluent-BsH-lUh2.js → fluent-Bugk01mf.js} +0 -0
- /package/dist/web/assets/{format-bytes-amUJ8Js8.js → format-bytes-DBBzVCYA.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-CB6SdVKB.js → fortran-free-form-csIz6MQj.js} +0 -0
- /package/dist/web/assets/{gdscript--YoKuvEA.js → gdscript-fdzYQLfk.js} +0 -0
- /package/dist/web/assets/{gdshader-BRtMwf5z.js → gdshader-CfsEtDeZ.js} +0 -0
- /package/dist/web/assets/{genie-wrzVG2Z8.js → genie-CtHN5N2Q.js} +0 -0
- /package/dist/web/assets/{gherkin-HnpURN27.js → gherkin-gSp2ZJTf.js} +0 -0
- /package/dist/web/assets/{github-dark-XlZ3pGhn.js → github-dark-D7O9efii.js} +0 -0
- /package/dist/web/assets/{github-dark-default-D_R0hfJe.js → github-dark-default-Bv2wIhqD.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-BHQgHLnK.js → github-dark-dimmed-BuY_SpCX.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-Pbl4mEFe.js → github-dark-high-contrast-Chv0f5Wu.js} +0 -0
- /package/dist/web/assets/{github-light-0P0VANJn.js → github-light-DV8f-W2f.js} +0 -0
- /package/dist/web/assets/{github-light-default-DTfsnyDq.js → github-light-default-CNBSU3dB.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-DKITR-5Y.js → github-light-high-contrast-sg94tHwU.js} +0 -0
- /package/dist/web/assets/{gleam-refSZtkM.js → gleam-w7270-PJ.js} +0 -0
- /package/dist/web/assets/{gn-BZ9cGckR.js → gn-yo_iE_A_.js} +0 -0
- /package/dist/web/assets/{gnuplot-CMHqDcTW.js → gnuplot-DSBPrzl4.js} +0 -0
- /package/dist/web/assets/{go-bFdCrzvY.js → go-D1S7g97D.js} +0 -0
- /package/dist/web/assets/{groovy-Dvz5tluQ.js → groovy-C7xW-5IV.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-D0Z-pclr.js → gruvbox-dark-hard-BZald7Z_.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-BG6oIRQR.js → gruvbox-dark-medium-v6W4PZne.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-ILJ-3tU6.js → gruvbox-dark-soft-CN5mIGkw.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-Bl95khkz.js → gruvbox-light-hard-D3NIGRxd.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-CdislFOh.js → gruvbox-light-medium-m4ShuCnD.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-CTcEyxlX.js → gruvbox-light-soft-BEEYNyk-.js} +0 -0
- /package/dist/web/assets/{haskell-D9jfkQuH.js → haskell-CgtdXIH3.js} +0 -0
- /package/dist/web/assets/{haxe-Ckfl4osD.js → haxe-D7HQqtIx.js} +0 -0
- /package/dist/web/assets/{hcl-t03N4k5N.js → hcl-C-YHDaXH.js} +0 -0
- /package/dist/web/assets/{hjson-B_TIVRki.js → hjson-BrgEMvJK.js} +0 -0
- /package/dist/web/assets/{hlsl-BBCTeANz.js → hlsl-BsDumu1j.js} +0 -0
- /package/dist/web/assets/{horizon-CRY-xdGU.js → horizon-D9Kre3KQ.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BpUM2C5u.js → horizon-bright-DJq8c_Yq.js} +0 -0
- /package/dist/web/assets/{houston-RVyAGlyS.js → houston-B9tnxzX8.js} +0 -0
- /package/dist/web/assets/{hy-BHFJHuHd.js → hy-DUYVvXOj.js} +0 -0
- /package/dist/web/assets/{image-gallery-DdQblMAe.js → image-gallery-DvAgPQ3L.js} +0 -0
- /package/dist/web/assets/{image-preview-geometry-BFKR37Pj.js → image-preview-geometry-B-SdD7_D.js} +0 -0
- /package/dist/web/assets/{imba-DyG0_0MS.js → imba-CGW-TsRm.js} +0 -0
- /package/dist/web/assets/{ini-CsCTH-_o.js → ini-PqgYiEAV.js} +0 -0
- /package/dist/web/assets/{json5-g3g-IFTV.js → json5-sbkvqHou.js} +0 -0
- /package/dist/web/assets/{jsonc-DQHBJwib.js → jsonc-pnywfpws.js} +0 -0
- /package/dist/web/assets/{jsonl-zFLDm4eB.js → jsonl-ZPOQ0pRn.js} +0 -0
- /package/dist/web/assets/{jsonnet-DgNm2IGn.js → jsonnet-B_Q7j1YF.js} +0 -0
- /package/dist/web/assets/{jssm-BErkU0In.js → jssm-K-xYeQyp.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-Dgymfjca.js → kanagawa-dragon-DAdLBtU8.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-CWZEYd27.js → kanagawa-lotus-5BwvVGu8.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-CQg17ecf.js → kanagawa-wave-C0h9fsDT.js} +0 -0
- /package/dist/web/assets/{kdl-DY4GHmJC.js → kdl-DXSsFcms.js} +0 -0
- /package/dist/web/assets/{kotlin-DeGTz7bl.js → kotlin-BXNIvloo.js} +0 -0
- /package/dist/web/assets/{kusto-BN-OqpQj.js → kusto-wM3eio5V.js} +0 -0
- /package/dist/web/assets/{laserwave-bAqiAiOp.js → laserwave-FcbxdP2A.js} +0 -0
- /package/dist/web/assets/{lean-CAypLWCf.js → lean-RenzGeoM.js} +0 -0
- /package/dist/web/assets/{less-ikHAUlPb.js → less-CcUdtNJi.js} +0 -0
- /package/dist/web/assets/{libesm-cUHvIIuW.js → libesm-DMnQ3WlF.js} +0 -0
- /package/dist/web/assets/{light-plus-BamuTcT9.js → light-plus-BsMoOZJR.js} +0 -0
- /package/dist/web/assets/{llvm-CddObVkW.js → llvm-CyylMBuq.js} +0 -0
- /package/dist/web/assets/{log-CWbfGTTc.js → log-BOi0GB58.js} +0 -0
- /package/dist/web/assets/{logo-AHyhxX3Z.js → logo-BQUr3X2Y.js} +0 -0
- /package/dist/web/assets/{luau-y7she9L3.js → luau-3YZRDIsh.js} +0 -0
- /package/dist/web/assets/{make-DP3sQaP3.js → make-DEkKRDRU.js} +0 -0
- /package/dist/web/assets/{markdown-9Nuxib8a.js → markdown-BmFN0-A1.js} +0 -0
- /package/dist/web/assets/{material-theme-DDpm-uS7.js → material-theme-DqLHjEZ8.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-CHk91wbm.js → material-theme-darker-DhbvULnI.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-LkmOI8KM.js → material-theme-lighter-C_aA4yVe.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-PpkUhB4-.js → material-theme-ocean-Pk5JltJS.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-DZAigXgW.js → material-theme-palenight-DNi3VguV.js} +0 -0
- /package/dist/web/assets/{matlab-CexKVVPc.js → matlab-BqUtv2ml.js} +0 -0
- /package/dist/web/assets/{mdx-BrcepHfI.js → mdx-DFMrnHBn.js} +0 -0
- /package/dist/web/assets/{mermaid-CNFhZZaG.js → mermaid-BpyuE0L_.js} +0 -0
- /package/dist/web/assets/{min-dark-hd3nbDV4.js → min-dark-DVfCMEPW.js} +0 -0
- /package/dist/web/assets/{min-light-AqA5jmks.js → min-light-B96aMADV.js} +0 -0
- /package/dist/web/assets/{mipsasm-B3x4L8Zk.js → mipsasm-DHhEcvKr.js} +0 -0
- /package/dist/web/assets/{mojo-CvfXy3YL.js → mojo-BQ6HsVIQ.js} +0 -0
- /package/dist/web/assets/{monokai-CdxwmnU_.js → monokai-amcXAKGG.js} +0 -0
- /package/dist/web/assets/{moonbit-6Z_VCO0_.js → moonbit-CGSXXQJI.js} +0 -0
- /package/dist/web/assets/{move-B2__B6Po.js → move-BOa4mq0q.js} +0 -0
- /package/dist/web/assets/{narrat-D6vL6wL-.js → narrat-dBYNSnhr.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-L-FBME4e.js → nextflow-groovy-Dm2Y_qgn.js} +0 -0
- /package/dist/web/assets/{night-owl-DjKrkDjv.js → night-owl-Dy9ibYHN.js} +0 -0
- /package/dist/web/assets/{night-owl-light-CeGjPuUQ.js → night-owl-light-DamYjQKi.js} +0 -0
- /package/dist/web/assets/{nix-dr279CcA.js → nix-C1LyoszC.js} +0 -0
- /package/dist/web/assets/{nord-Dxn-_H_Y.js → nord-LtGRYAFI.js} +0 -0
- /package/dist/web/assets/{nushell-DgeAQO7j.js → nushell-BMoOkt47.js} +0 -0
- /package/dist/web/assets/{objective-c-CO0-Pacn.js → objective-c-CILaOZJu.js} +0 -0
- /package/dist/web/assets/{objective-cpp-SkrjegYw.js → objective-cpp-D5Fo-SoM.js} +0 -0
- /package/dist/web/assets/{ocaml-CAihtkib.js → ocaml-D1TCTCEJ.js} +0 -0
- /package/dist/web/assets/{odin-D0XZbUDB.js → odin-CjdYcmpW.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-BUMNMxjX.js → one-dark-pro-GpsZUGZl.js} +0 -0
- /package/dist/web/assets/{one-light-C0Ui69Bx.js → one-light-DlketcS4.js} +0 -0
- /package/dist/web/assets/{openscad-fZ9ggqM-.js → openscad-BoT8wwuI.js} +0 -0
- /package/dist/web/assets/{pascal-DvZm-eun.js → pascal-Cqy403Sf.js} +0 -0
- /package/dist/web/assets/{pkl-CQSIp_z8.js → pkl-D6gRI9qQ.js} +0 -0
- /package/dist/web/assets/{plastic-CMspsouJ.js → plastic-DgvX8DXX.js} +0 -0
- /package/dist/web/assets/{plsql-B_HL7UfT.js → plsql-CTDnCVE3.js} +0 -0
- /package/dist/web/assets/{po-DxAfbdfe.js → po-DDnzm7AQ.js} +0 -0
- /package/dist/web/assets/{poimandres-JGmqmwux.js → poimandres-C4HQwFp-.js} +0 -0
- /package/dist/web/assets/{polar-_mNmplk8.js → polar-WBTQdMzX.js} +0 -0
- /package/dist/web/assets/{postcss-GpU0Sjqc.js → postcss-CWxogTg1.js} +0 -0
- /package/dist/web/assets/{powerquery-B1IP1lCQ.js → powerquery-DVtReIRR.js} +0 -0
- /package/dist/web/assets/{powershell-BiSO9XmG.js → powershell-Cb_RNzSh.js} +0 -0
- /package/dist/web/assets/{prisma-4QqDYSnH.js → prisma-nKLUh3DY.js} +0 -0
- /package/dist/web/assets/{prolog-BNjvyRqT.js → prolog-BD9orEy4.js} +0 -0
- /package/dist/web/assets/{proto-RNOumnkw.js → proto-B-AFoz75.js} +0 -0
- /package/dist/web/assets/{puppet-CDfv5o8f.js → puppet-DDW6wWm4.js} +0 -0
- /package/dist/web/assets/{purescript-YTjSoifd.js → purescript-DXy49AJg.js} +0 -0
- /package/dist/web/assets/{python-Mh7JD25U.js → python-BQnvDlc7.js} +0 -0
- /package/dist/web/assets/{qmldir-Da_ZrqZy.js → qmldir-CboMQXQW.js} +0 -0
- /package/dist/web/assets/{qss-DANVkyhy.js → qss-8XaprLEt.js} +0 -0
- /package/dist/web/assets/{racket-CwPOn4T1.js → racket-ChcVp15M.js} +0 -0
- /package/dist/web/assets/{raku-B04lBsXd.js → raku-dEgEXW0A.js} +0 -0
- /package/dist/web/assets/{red-MW6Zm5pd.js → red-hmwjontD.js} +0 -0
- /package/dist/web/assets/{reg-44SURM-E.js → reg-CIkOufh2.js} +0 -0
- /package/dist/web/assets/{rel-Gu5Erhpm.js → rel-NXKKDiTi.js} +0 -0
- /package/dist/web/assets/{resolve-theme-BNubecVz.js → resolve-theme-B87m6l4i.js} +0 -0
- /package/dist/web/assets/{riscv-DZDP0Ce7.js → riscv-BEIzhPcg.js} +0 -0
- /package/dist/web/assets/{ron-BwLObbl6.js → ron-CW2Bt8rN.js} +0 -0
- /package/dist/web/assets/{rose-pine-Bz6ToXok.js → rose-pine-DhnBfr5a.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-LyFogzAh.js → rose-pine-dawn-Jyj59rVs.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-CpjkefjD.js → rose-pine-moon-BMulxhJC.js} +0 -0
- /package/dist/web/assets/{rosmsg-BldDLaz1.js → rosmsg-DuctJm-Q.js} +0 -0
- /package/dist/web/assets/{rust-74skZ8CC.js → rust-FbJ2fCp9.js} +0 -0
- /package/dist/web/assets/{sass-CitUFDWl.js → sass-Dfxwdu2h.js} +0 -0
- /package/dist/web/assets/{scala-D2kl5ghT.js → scala-ClsSR0wG.js} +0 -0
- /package/dist/web/assets/{scheme-DZqhC9Xs.js → scheme-Jj_Cc-8H.js} +0 -0
- /package/dist/web/assets/{sdbl-D6a8sHP9.js → sdbl-Bi8D_DGN.js} +0 -0
- /package/dist/web/assets/{slack-dark-DrlPLUB_.js → slack-dark-B7gbmJT9.js} +0 -0
- /package/dist/web/assets/{slack-ochin-Djgychog.js → slack-ochin-O7j_c76D.js} +0 -0
- /package/dist/web/assets/{smalltalk-CYQHXftK.js → smalltalk-BD5-U3JK.js} +0 -0
- /package/dist/web/assets/{snazzy-light-BQAdF14K.js → snazzy-light-BbiRB69_.js} +0 -0
- /package/dist/web/assets/{solarized-dark-JDtJfY-g.js → solarized-dark-2OWHYEBu.js} +0 -0
- /package/dist/web/assets/{solarized-light-DHzVPLDD.js → solarized-light-Cew4YqT3.js} +0 -0
- /package/dist/web/assets/{solidity-CYCEiPu1.js → solidity-Bpbne2Tx.js} +0 -0
- /package/dist/web/assets/{splunk-B7RHmJY2.js → splunk-Dq86L1_O.js} +0 -0
- /package/dist/web/assets/{ssh-config-B74-n00O.js → ssh-config-j5hsMvbs.js} +0 -0
- /package/dist/web/assets/{stylus-xlRhcbpN.js → stylus-DWhCIBg0.js} +0 -0
- /package/dist/web/assets/{swift-DTFwWJtu.js → swift-29fG5ztW.js} +0 -0
- /package/dist/web/assets/{synthwave-84-BuCpuX2E.js → synthwave-84-DraIUmiw.js} +0 -0
- /package/dist/web/assets/{system-verilog-CgxJCrOK.js → system-verilog-DqcJAWq_.js} +0 -0
- /package/dist/web/assets/{systemd-D0x7_XYJ.js → systemd-BUPJrx1D.js} +0 -0
- /package/dist/web/assets/{talonscript-B50aQRuc.js → talonscript-BGYbnAKh.js} +0 -0
- /package/dist/web/assets/{tasl-Byv8gHCL.js → tasl-CwbSJqng.js} +0 -0
- /package/dist/web/assets/{tcl-CzMjCzWo.js → tcl-Ba9376wa.js} +0 -0
- /package/dist/web/assets/{terraform-D6GH4CXG.js → terraform-ChSasWu8.js} +0 -0
- /package/dist/web/assets/{tokyo-night-CQ4rTpHY.js → tokyo-night-Bbw1Yguv.js} +0 -0
- /package/dist/web/assets/{toml-D9W-BuJE.js → toml-CYb7zi5B.js} +0 -0
- /package/dist/web/assets/{tsv-BddanT8p.js → tsv-P2eVmwf9.js} +0 -0
- /package/dist/web/assets/{turtle-BddVklvD.js → turtle-DIoQTATC.js} +0 -0
- /package/dist/web/assets/{typespec-D60I2kfB.js → typespec-Dpr1bC2k.js} +0 -0
- /package/dist/web/assets/{typst-Bxvc-9ID.js → typst-D4WMCDMn.js} +0 -0
- /package/dist/web/assets/{utils-Bmf_8h7Y.js → utils-btZ8C8-R.js} +0 -0
- /package/dist/web/assets/{v-kVYZE10o.js → v-B1wY-VFU.js} +0 -0
- /package/dist/web/assets/{vala-B3zj44PV.js → vala-BKqhrirP.js} +0 -0
- /package/dist/web/assets/{vb-CHgWrFTj.js → vb-S9PHCa7-.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-_yyu5n32.js → vendor-xterm-BHKF_Nsf.js} +0 -0
- /package/dist/web/assets/{verilog-zIMuE3hE.js → verilog-CrztYl3V.js} +0 -0
- /package/dist/web/assets/{vesper-BjqPTQr0.js → vesper-C5KfcyFv.js} +0 -0
- /package/dist/web/assets/{vhdl-Q2EtgpQN.js → vhdl-D0qMeIJu.js} +0 -0
- /package/dist/web/assets/{viml-CrtDZkFz.js → viml-Dsv9mRPK.js} +0 -0
- /package/dist/web/assets/{vitesse-black-D2VWO3oN.js → vitesse-black-rJvNN5GN.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-lleZmHBJ.js → vitesse-dark-CYp0WWjf.js} +0 -0
- /package/dist/web/assets/{vitesse-light-utUY298S.js → vitesse-light-BczSAvzE.js} +0 -0
- /package/dist/web/assets/{vyper-LQ1KxOUo.js → vyper-DM7bKz7E.js} +0 -0
- /package/dist/web/assets/{wasm-CJ9U4zWg.js → wasm-BXCHhbrz.js} +0 -0
- /package/dist/web/assets/{wasm-B-mpMVDM.js → wasm-CAJoqhGc.js} +0 -0
- /package/dist/web/assets/{wenyan-LqMyA7px.js → wenyan-NQ8fdbEq.js} +0 -0
- /package/dist/web/assets/{wgsl-eI4U21sm.js → wgsl-C88C7vmC.js} +0 -0
- /package/dist/web/assets/{wikitext-CuWC2dfS.js → wikitext-D92r7uX8.js} +0 -0
- /package/dist/web/assets/{wit-CCPY0MNz.js → wit-DNvTfQjW.js} +0 -0
- /package/dist/web/assets/{wolfram-CXhjyJun.js → wolfram-CNS5lCGj.js} +0 -0
- /package/dist/web/assets/{zenscript-BzHPI08Q.js → zenscript-B_rGi-H_.js} +0 -0
- /package/dist/web/assets/{zig-CBuhKUve.js → zig-BRi9UYQa.js} +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { BridgeApi } from "./bridge-core.ts";
|
|
2
|
+
import type { CommentQuote } from "../../../shared/design-comment-types.ts";
|
|
3
|
+
import type { PickedElement } from "../../../shared/design-bridge-messages-picker.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What the canvas knows about one element: its anchor (id, tag, CSS path, text quote) and,
|
|
7
|
+
* for a picked element, its box, a trimmed copy of its markup and its text.
|
|
8
|
+
*
|
|
9
|
+
* Every function here is shipped into the design frame as source (`toString()`, installed
|
|
10
|
+
* as `ppm.lib.*` by the assembly), so none may reference anything in this module's scope:
|
|
11
|
+
* helpers are written inline, and other lib functions are reached through `ppm.lib`.
|
|
12
|
+
*
|
|
13
|
+
* {@link elementQuote} is also what the server runs over a parse5 tree to re-validate a
|
|
14
|
+
* re-anchor, which is why it walks through a {@link TreeAccess} instead of the DOM API:
|
|
15
|
+
* the quote a pin was stored with and the quote of a candidate must be computed the same
|
|
16
|
+
* way on both sides, or no candidate would ever score as the same element.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export interface TreeAccess<N> {
|
|
20
|
+
parent(node: N): N | null;
|
|
21
|
+
children(node: N): ArrayLike<N>;
|
|
22
|
+
/** The text of a text node; null for anything else. */
|
|
23
|
+
text(node: N): string | null;
|
|
24
|
+
/** The lowercase tag name of an element; null for anything else. */
|
|
25
|
+
tag(node: N): string | null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ElementAnchorInfo {
|
|
29
|
+
ppmId: number | null;
|
|
30
|
+
tag: string;
|
|
31
|
+
cssPath: string;
|
|
32
|
+
quote: CommentQuote;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The element's own text (up to 160 chars) plus up to 32 chars of the text before and after
|
|
37
|
+
* it, whitespace-collapsed. The context is taken from siblings, climbing at most six
|
|
38
|
+
* ancestors and never past `<body>`; script, style, template and noscript text is ignored.
|
|
39
|
+
*/
|
|
40
|
+
export function elementQuote<N>(el: N, acc: TreeAccess<N>): CommentQuote {
|
|
41
|
+
const EXACT = 160;
|
|
42
|
+
const SIDE = 32;
|
|
43
|
+
const skip: Record<string, boolean> = { script: true, style: true, template: true, noscript: true };
|
|
44
|
+
const norm = (s: string): string => s.replace(/\s+/g, " ").trim();
|
|
45
|
+
|
|
46
|
+
// Text of a subtree read from one end, stopping once `want` collapsed chars are in hand.
|
|
47
|
+
function collect(node: N, want: number, fromEnd: boolean): string {
|
|
48
|
+
const t = acc.text(node);
|
|
49
|
+
if (t !== null) {
|
|
50
|
+
const cap = want * 2 + 64;
|
|
51
|
+
return t.length <= cap ? t : fromEnd ? t.slice(-cap) : t.slice(0, cap);
|
|
52
|
+
}
|
|
53
|
+
const tag = acc.tag(node);
|
|
54
|
+
if (tag === null || skip[tag]) return "";
|
|
55
|
+
const kids = acc.children(node);
|
|
56
|
+
let out = "";
|
|
57
|
+
for (let k = 0; k < kids.length; k++) {
|
|
58
|
+
const part = collect(kids[fromEnd ? kids.length - 1 - k : k]!, want, fromEnd);
|
|
59
|
+
out = fromEnd ? part + out : out + part;
|
|
60
|
+
if (norm(out).length >= want) break;
|
|
61
|
+
}
|
|
62
|
+
// Element boundaries read as a space, so a heading and the paragraph after it do not
|
|
63
|
+
// run together; collapsing makes it harmless inside inline markup.
|
|
64
|
+
return " " + out + " ";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function side(before: boolean): string {
|
|
68
|
+
let out = "";
|
|
69
|
+
let cur: N = el;
|
|
70
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
71
|
+
const parent = acc.parent(cur);
|
|
72
|
+
if (parent === null) break;
|
|
73
|
+
const kids = acc.children(parent);
|
|
74
|
+
const at = Array.prototype.indexOf.call(kids, cur);
|
|
75
|
+
if (at < 0) break;
|
|
76
|
+
for (let i = before ? at - 1 : at + 1; before ? i >= 0 : i < kids.length; i += before ? -1 : 1) {
|
|
77
|
+
const part = collect(kids[i]!, SIDE, before);
|
|
78
|
+
out = before ? part + out : out + part;
|
|
79
|
+
if (norm(out).length >= SIDE) break;
|
|
80
|
+
}
|
|
81
|
+
const tag = acc.tag(parent);
|
|
82
|
+
if (norm(out).length >= SIDE || tag === null || tag === "body" || tag === "head" || tag === "html") break;
|
|
83
|
+
cur = parent;
|
|
84
|
+
}
|
|
85
|
+
const n = norm(out);
|
|
86
|
+
return before ? n.slice(-SIDE) : n.slice(0, SIDE);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { exact: norm(collect(el, EXACT, false)).slice(0, EXACT), prefix: side(true), suffix: side(false) };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** A {@link TreeAccess} over the live DOM. */
|
|
93
|
+
export function domTreeAccess(): TreeAccess<Node> {
|
|
94
|
+
return {
|
|
95
|
+
parent: (n) => n.parentNode,
|
|
96
|
+
children: (n) => n.childNodes,
|
|
97
|
+
text: (n) => (n.nodeType === 3 ? n.nodeValue || "" : null),
|
|
98
|
+
tag: (n) => (n.nodeType === 1 ? (n as Element).localName.toLowerCase() : null),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* `#id` when the element (or an ancestor, at most six levels up) has a plain, unique id,
|
|
104
|
+
* otherwise a `tag:nth-of-type(n)` chain from `body`. Used only to break ties.
|
|
105
|
+
*/
|
|
106
|
+
export function cssPathOf(el: Element): string {
|
|
107
|
+
const plainId = /^[A-Za-z][\w-]{0,63}$/;
|
|
108
|
+
const doc = el.ownerDocument;
|
|
109
|
+
const parts: string[] = [];
|
|
110
|
+
let cur: Element | null = el;
|
|
111
|
+
for (let depth = 0; cur && depth < 6; depth++) {
|
|
112
|
+
const tag = cur.localName.toLowerCase();
|
|
113
|
+
if (tag === "html") break;
|
|
114
|
+
const id = cur.getAttribute("id");
|
|
115
|
+
if (id && plainId.test(id) && doc.querySelectorAll("#" + id).length === 1) {
|
|
116
|
+
parts.unshift("#" + id);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
if (tag === "body") {
|
|
120
|
+
parts.unshift("body");
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
let n = 1;
|
|
124
|
+
for (let s = cur.previousElementSibling; s; s = s.previousElementSibling) if (s.localName === cur.localName) n++;
|
|
125
|
+
parts.unshift(tag + ":nth-of-type(" + n + ")");
|
|
126
|
+
cur = cur.parentElement;
|
|
127
|
+
}
|
|
128
|
+
return parts.join(" > ");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The anchor fields of a live element. Ids come from the serve-time `data-ppm-id`. */
|
|
132
|
+
export function anchorOf(el: Element, ppm: BridgeApi): ElementAnchorInfo {
|
|
133
|
+
const raw = el.getAttribute("data-ppm-id");
|
|
134
|
+
const id = raw !== null && /^\d{1,10}$/.test(raw) ? parseInt(raw, 10) : NaN;
|
|
135
|
+
return {
|
|
136
|
+
ppmId: Number.isFinite(id) && id <= 0x7fffffff ? id : null,
|
|
137
|
+
tag: el.localName.toLowerCase(),
|
|
138
|
+
cssPath: ppm.lib.cssPathOf(el),
|
|
139
|
+
quote: ppm.lib.elementQuote<Node>(el, ppm.lib.domTreeAccess()),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Everything the parent shows about a picked element. The markup is a depth-2 copy with
|
|
145
|
+
* long text cut, built in an inert document so copying an `<img>` fetches nothing.
|
|
146
|
+
*/
|
|
147
|
+
export function describeElement(el: Element, ppm: BridgeApi): PickedElement {
|
|
148
|
+
const anchor = ppm.lib.anchorOf(el, ppm);
|
|
149
|
+
const box = el.getBoundingClientRect();
|
|
150
|
+
const inert = ppm.doc.implementation.createHTMLDocument("");
|
|
151
|
+
function copy(node: Node, depth: number): Node {
|
|
152
|
+
if (node.nodeType === 3) {
|
|
153
|
+
const t = node.nodeValue || "";
|
|
154
|
+
return inert.createTextNode(t.length > 80 ? t.slice(0, 80) + "…" : t);
|
|
155
|
+
}
|
|
156
|
+
if (node.nodeType !== 1) return inert.createTextNode("");
|
|
157
|
+
const clone = inert.importNode(node, false) as Element;
|
|
158
|
+
clone.removeAttribute("data-ppm-id");
|
|
159
|
+
const kids = node.childNodes;
|
|
160
|
+
if (depth < 2) {
|
|
161
|
+
for (let i = 0; i < kids.length && i < 20; i++) clone.appendChild(copy(kids[i]!, depth + 1));
|
|
162
|
+
if (kids.length > 20) clone.appendChild(inert.createTextNode("…"));
|
|
163
|
+
} else if (kids.length) {
|
|
164
|
+
clone.appendChild(inert.createTextNode("…"));
|
|
165
|
+
}
|
|
166
|
+
return clone;
|
|
167
|
+
}
|
|
168
|
+
const gen = /^[0-9a-f]{16}$/.test(ppm.boot.gen) ? ppm.boot.gen : null;
|
|
169
|
+
return {
|
|
170
|
+
ppmId: anchor.ppmId,
|
|
171
|
+
gen,
|
|
172
|
+
file: ppm.boot.file,
|
|
173
|
+
tag: anchor.tag,
|
|
174
|
+
rect: { x: box.left, y: box.top, w: box.width, h: box.height },
|
|
175
|
+
cssPath: anchor.cssPath,
|
|
176
|
+
outerHtml: (copy(el, 0) as Element).outerHTML.slice(0, 2000),
|
|
177
|
+
text: (el.textContent || "").replace(/\s+/g, " ").trim().slice(0, 500),
|
|
178
|
+
quote: anchor.quote,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { ExtractedColor, extractTextRuns, mergeTextRuns } from "./bridge-extract-text.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What one laid-out box on a slide turns into for the PowerPoint export, shipped to the frame
|
|
5
|
+
* as `ppm.lib` helpers (each references nothing outside itself; collaborators are parameters).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type SlideBoxPx = { x: number; y: number; w: number; h: number; rotation: number };
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The element's rotation in degrees from its computed `transform` and `rotate`, and whether
|
|
12
|
+
* that is all the transform does. A scale or skew cannot be carried over, so `pure` is false.
|
|
13
|
+
*/
|
|
14
|
+
export function cssRotation(cs: CSSStyleDeclaration): { deg: number; pure: boolean } {
|
|
15
|
+
let deg = 0;
|
|
16
|
+
let pure = true;
|
|
17
|
+
const m = /^matrix\(([^)]+)\)$/.exec(cs.transform || "");
|
|
18
|
+
if (m) {
|
|
19
|
+
const [a, b, c, d] = m[1]!.split(",").map(parseFloat) as [number, number, number, number];
|
|
20
|
+
deg = (Math.atan2(b, a) * 180) / Math.PI;
|
|
21
|
+
if (Math.abs(Math.hypot(a, b) - 1) > 0.01 || Math.abs(Math.hypot(c, d) - 1) > 0.01 || Math.abs(a * d - b * c - 1) > 0.01) pure = false;
|
|
22
|
+
} else if (cs.transform && cs.transform !== "none") pure = false;
|
|
23
|
+
const r = /^(-?[\d.]+)deg$/.exec(cs.rotate || "");
|
|
24
|
+
if (r) deg += parseFloat(r[1]!);
|
|
25
|
+
else if (cs.rotate && cs.rotate !== "none") pure = false;
|
|
26
|
+
if (cs.scale && cs.scale !== "none" && cs.scale !== "1") pure = false;
|
|
27
|
+
return { deg: Math.round((((deg % 360) + 360) % 360) * 100) / 100, pure };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The shape (background and uniform border) and the text box of one non-inline element, in
|
|
32
|
+
* paint order. `opacity` is the element's own times its ancestors', folded into every colour.
|
|
33
|
+
*/
|
|
34
|
+
export function blockItems(
|
|
35
|
+
el: Element,
|
|
36
|
+
win: Window,
|
|
37
|
+
box: SlideBoxPx,
|
|
38
|
+
opacity: number,
|
|
39
|
+
colorOf: (value: string) => ExtractedColor | null,
|
|
40
|
+
note: (label: string) => void,
|
|
41
|
+
text: { extractTextRuns: typeof extractTextRuns; mergeTextRuns: typeof mergeTextRuns },
|
|
42
|
+
): Array<Record<string, unknown>> {
|
|
43
|
+
const cs = win.getComputedStyle(el);
|
|
44
|
+
const items: Array<Record<string, unknown>> = [];
|
|
45
|
+
const px = (v: string): number => parseFloat(v) || 0;
|
|
46
|
+
const fade = (c: ExtractedColor | null): ExtractedColor | null =>
|
|
47
|
+
(c && c.alpha * opacity > 0.01 ? { hex: c.hex, alpha: Math.round(c.alpha * opacity * 1000) / 1000 } : null);
|
|
48
|
+
|
|
49
|
+
if (cs.backgroundImage && cs.backgroundImage !== "none") {
|
|
50
|
+
note(cs.backgroundImage.indexOf("gradient") >= 0 ? "gradient background" : "background image");
|
|
51
|
+
}
|
|
52
|
+
if (cs.boxShadow && cs.boxShadow !== "none") note("box shadow");
|
|
53
|
+
if (cs.filter && cs.filter !== "none") note("CSS filter");
|
|
54
|
+
if (cs.mixBlendMode && cs.mixBlendMode !== "normal") note("blend mode");
|
|
55
|
+
|
|
56
|
+
const sides = ["top", "right", "bottom", "left"].map((s) => ({
|
|
57
|
+
w: px(cs.getPropertyValue("border-" + s + "-width")),
|
|
58
|
+
style: cs.getPropertyValue("border-" + s + "-style"),
|
|
59
|
+
color: cs.getPropertyValue("border-" + s + "-color"),
|
|
60
|
+
}));
|
|
61
|
+
const drawn = sides.filter((s) => s.w > 0 && s.style !== "none" && s.style !== "hidden");
|
|
62
|
+
const uniform = drawn.length === 4 && drawn.every((s) => s.w === drawn[0]!.w && s.color === drawn[0]!.color);
|
|
63
|
+
if (drawn.length && !uniform) note("border on some sides only");
|
|
64
|
+
const fill = fade(colorOf(cs.backgroundColor));
|
|
65
|
+
const borderColor = uniform ? fade(colorOf(drawn[0]!.color)) : null;
|
|
66
|
+
if (fill || borderColor) {
|
|
67
|
+
const shape: Record<string, unknown> = Object.assign({ kind: "shape" }, box);
|
|
68
|
+
if (fill) shape.fill = fill;
|
|
69
|
+
if (borderColor) shape.border = { widthPx: drawn[0]!.w, color: borderColor };
|
|
70
|
+
const radius = cs.borderTopLeftRadius || "";
|
|
71
|
+
const r = radius.slice(-1) === "%" ? (px(radius) * Math.min(box.w, box.h)) / 100 : px(radius);
|
|
72
|
+
if (r > 0) shape.radiusPx = Math.min(r, Math.min(box.w, box.h) / 2);
|
|
73
|
+
items.push(shape);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Text of its own: a text node, or an inline element holding text, directly inside.
|
|
77
|
+
let ownText = false;
|
|
78
|
+
for (let c = el.firstChild; c && !ownText; c = c.nextSibling) {
|
|
79
|
+
if (c.nodeType === 3) ownText = /\S/.test((c as Text).data);
|
|
80
|
+
else if (c.nodeType === 1 && !/^(script|style|template|noscript|img|svg|canvas)$/i.test((c as Element).tagName)) {
|
|
81
|
+
ownText = /^(inline|contents|)$/.test(win.getComputedStyle(c as Element).display) && /\S/.test(c.textContent || "");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (!ownText) return items;
|
|
85
|
+
const runs = text.mergeTextRuns(text.extractTextRuns(el, win, colorOf, note));
|
|
86
|
+
for (const run of runs) if (run.color) run.color = fade(run.color) || { hex: run.color.hex, alpha: 0 };
|
|
87
|
+
if (!runs.length) return items;
|
|
88
|
+
const inset = {
|
|
89
|
+
l: px(cs.borderLeftWidth) + px(cs.paddingLeft), r: px(cs.borderRightWidth) + px(cs.paddingRight),
|
|
90
|
+
t: px(cs.borderTopWidth) + px(cs.paddingTop), b: px(cs.borderBottomWidth) + px(cs.paddingBottom),
|
|
91
|
+
};
|
|
92
|
+
const item: Record<string, unknown> = Object.assign({ kind: "text" }, box, {
|
|
93
|
+
x: box.x + inset.l, y: box.y + inset.t,
|
|
94
|
+
w: Math.max(1, box.w - inset.l - inset.r), h: Math.max(1, box.h - inset.t - inset.b), runs,
|
|
95
|
+
});
|
|
96
|
+
// A flex or grid box that centres its text does it with alignment, not `text-align`;
|
|
97
|
+
// in a column flex box the two axes swap.
|
|
98
|
+
const flex = /flex|grid/.test(cs.display);
|
|
99
|
+
const column = flex && /column/.test(cs.flexDirection);
|
|
100
|
+
const main = flex ? cs.justifyContent : "";
|
|
101
|
+
const cross = flex ? cs.alignItems : "";
|
|
102
|
+
const across = column ? cross : main;
|
|
103
|
+
const down = column ? main : cross;
|
|
104
|
+
const ta = cs.textAlign;
|
|
105
|
+
item.align = ta === "center" || across === "center" ? "center"
|
|
106
|
+
: ta === "right" || (ta === "end" && cs.direction !== "rtl") || /flex-end|^end$/.test(across) ? "right"
|
|
107
|
+
: ta === "justify" ? "justify" : "left";
|
|
108
|
+
item.valign = down === "center" ? "middle" : /flex-end|^end$/.test(down) ? "bottom" : "top";
|
|
109
|
+
if (cs.lineHeight !== "normal" && px(cs.lineHeight) > 0) item.lineHeightPx = px(cs.lineHeight);
|
|
110
|
+
if (el.tagName === "LI" && cs.listStyleType !== "none") {
|
|
111
|
+
item.bullet = el.parentElement && el.parentElement.tagName === "OL" ? "number" : "bullet";
|
|
112
|
+
}
|
|
113
|
+
items.push(item);
|
|
114
|
+
return items;
|
|
115
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image capture for the PowerPoint export, shipped to the frame as a `ppm.lib` helper (so,
|
|
3
|
+
* like every helper, it references nothing outside itself).
|
|
4
|
+
*
|
|
5
|
+
* The answer is always a PNG or JPEG data URL, the two formats every PowerPoint opens:
|
|
6
|
+
* - an image from the design's own files is fetched (the design CSP's `connect-src` allows
|
|
7
|
+
* exactly that source) and kept as-is when it is already PNG/JPEG, else drawn to a canvas;
|
|
8
|
+
* - an image from a CDN cannot be fetched, so it is loaded with `crossOrigin="anonymous"`
|
|
9
|
+
* and drawn — jsDelivr and unpkg send CORS headers, anything that does not taints the
|
|
10
|
+
* canvas, and that image is reported rather than exported;
|
|
11
|
+
* - an inline `<svg>` is serialised and rasterised at twice its on-screen size, so it
|
|
12
|
+
* stays sharp on a projector; a `<canvas>` is read directly.
|
|
13
|
+
* Null means "could not be read", never a partial image.
|
|
14
|
+
*/
|
|
15
|
+
export function imageDataUrl(el: Element, win: Window): Promise<string | null> {
|
|
16
|
+
const doc = win.document;
|
|
17
|
+
const MAX_EDGE = 4096;
|
|
18
|
+
const rect = el.getBoundingClientRect();
|
|
19
|
+
|
|
20
|
+
const draw = (img: HTMLImageElement, w: number, h: number): string | null => {
|
|
21
|
+
if (!(w > 0 && h > 0)) return null;
|
|
22
|
+
const scale = Math.min(1, MAX_EDGE / Math.max(w, h));
|
|
23
|
+
const canvas = doc.createElement("canvas");
|
|
24
|
+
canvas.width = Math.max(1, Math.round(w * scale));
|
|
25
|
+
canvas.height = Math.max(1, Math.round(h * scale));
|
|
26
|
+
const ctx = canvas.getContext("2d");
|
|
27
|
+
if (!ctx) return null;
|
|
28
|
+
try {
|
|
29
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
30
|
+
return canvas.toDataURL("image/png");
|
|
31
|
+
} catch (e) {
|
|
32
|
+
// A tainted canvas (a cross-origin image without CORS) refuses to be read.
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const load = (src: string, cors: boolean): Promise<HTMLImageElement | null> => new Promise((resolve) => {
|
|
38
|
+
const img = new (win as Window & typeof globalThis).Image();
|
|
39
|
+
if (cors) img.crossOrigin = "anonymous";
|
|
40
|
+
img.onload = () => resolve(img);
|
|
41
|
+
img.onerror = () => resolve(null);
|
|
42
|
+
img.src = src;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const fromBlob = (blob: Blob, vector: boolean): Promise<string | null> => {
|
|
46
|
+
if (blob.type === "image/png" || blob.type === "image/jpeg") {
|
|
47
|
+
return new Promise((resolve) => {
|
|
48
|
+
const reader = new FileReader();
|
|
49
|
+
reader.onload = () => resolve(typeof reader.result === "string" ? reader.result : null);
|
|
50
|
+
reader.onerror = () => resolve(null);
|
|
51
|
+
reader.readAsDataURL(blob);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const url = URL.createObjectURL(blob);
|
|
55
|
+
return load(url, false).then((img) => {
|
|
56
|
+
URL.revokeObjectURL(url);
|
|
57
|
+
if (!img) return null;
|
|
58
|
+
// A vector source has no meaningful natural size: draw it at twice its displayed size.
|
|
59
|
+
return vector || !img.naturalWidth
|
|
60
|
+
? draw(img, rect.width * 2, rect.height * 2)
|
|
61
|
+
: draw(img, img.naturalWidth, img.naturalHeight);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const tag = el.tagName.toLowerCase();
|
|
66
|
+
if (tag === "canvas") {
|
|
67
|
+
try {
|
|
68
|
+
return Promise.resolve((el as HTMLCanvasElement).toDataURL("image/png"));
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return Promise.resolve(null);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (tag === "svg") {
|
|
74
|
+
let xml = new XMLSerializer().serializeToString(el);
|
|
75
|
+
if (!/^<svg[^>]*\sxmlns=/.test(xml)) xml = xml.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
|
|
76
|
+
return fromBlob(new Blob([xml], { type: "image/svg+xml" }), true);
|
|
77
|
+
}
|
|
78
|
+
if (tag !== "img") return Promise.resolve(null);
|
|
79
|
+
const src = (el as HTMLImageElement).currentSrc || (el as HTMLImageElement).src;
|
|
80
|
+
if (!src) return Promise.resolve(null);
|
|
81
|
+
if (/^data:image\/(png|jpeg);base64,/.test(src)) return Promise.resolve(src);
|
|
82
|
+
let own = false;
|
|
83
|
+
try {
|
|
84
|
+
const url = new URL(src, doc.baseURI);
|
|
85
|
+
own = url.protocol === "data:" || url.protocol === "blob:" || url.origin === win.location.origin;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return Promise.resolve(null);
|
|
88
|
+
}
|
|
89
|
+
if (own) {
|
|
90
|
+
return fetch(src)
|
|
91
|
+
.then((res) => (res.ok ? res.blob() : null))
|
|
92
|
+
.then((blob) => (blob ? fromBlob(blob, blob.type === "image/svg+xml") : null))
|
|
93
|
+
.catch(() => null);
|
|
94
|
+
}
|
|
95
|
+
return load(src, true).then((img) => (img ? draw(img, img.naturalWidth || rect.width * 2, img.naturalHeight || rect.height * 2) : null));
|
|
96
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { BridgeApi } from "./bridge-core.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The PowerPoint export's measuring pass, run by the bridge inside the live canvas.
|
|
5
|
+
*
|
|
6
|
+
* The browser already rendering the design is the renderer: every position comes from
|
|
7
|
+
* `getBoundingClientRect` and every colour, size and face from `getComputedStyle`, so no
|
|
8
|
+
* headless browser is involved. Slides are the `section.slide` elements (the slide convention
|
|
9
|
+
* the design instructions teach), else `[data-slide]`, else the whole page as one slide.
|
|
10
|
+
* Inside a slide, each laid-out box becomes a shape when it paints a background or a uniform
|
|
11
|
+
* border, a text box when it holds text of its own, and images/SVG/canvas become pictures.
|
|
12
|
+
*
|
|
13
|
+
* What PowerPoint cannot show (gradients, background images, shadows, partial borders,
|
|
14
|
+
* filters, blend modes, transforms other than rotation…) is counted per slide and reported,
|
|
15
|
+
* never silently dropped. Shipped as source, so it references nothing outside itself; the
|
|
16
|
+
* text and image helpers arrive through `ppm.lib`.
|
|
17
|
+
*/
|
|
18
|
+
export function installSlidesExtract(ppm: BridgeApi): void {
|
|
19
|
+
const win = ppm.win as Window & typeof globalThis;
|
|
20
|
+
const doc = ppm.doc;
|
|
21
|
+
const lib = ppm.lib;
|
|
22
|
+
const MAX_ITEMS = 600;
|
|
23
|
+
const MAX_SLIDES = 200;
|
|
24
|
+
const MAX_IMAGE_BYTES = 50 * 1024 * 1024;
|
|
25
|
+
const MAX_EDGE = 5376;
|
|
26
|
+
const SKIP = /^(script|style|template|noscript|head|meta|link|title|br|wbr|option|datalist|ppm-design-overlay|ppm-design-handles)$/i;
|
|
27
|
+
const MEDIA = /^(img|svg|canvas)$/i;
|
|
28
|
+
// An engine that computes no display at all (happy-dom for unstyled tags) means inline.
|
|
29
|
+
const INLINE = /^(inline|contents|)$/;
|
|
30
|
+
type Color = { hex: string; alpha: number };
|
|
31
|
+
type Frame = { left: number; top: number; scale: number; w: number; h: number };
|
|
32
|
+
let probe: CanvasRenderingContext2D | null = null;
|
|
33
|
+
|
|
34
|
+
function colorOf(value: string): Color | null {
|
|
35
|
+
const parsed = lib.parseCssColor(value);
|
|
36
|
+
if (parsed || !value) return parsed;
|
|
37
|
+
// oklch(), lab(), color(): the canvas converts whatever the engine can paint.
|
|
38
|
+
try {
|
|
39
|
+
if (!probe) {
|
|
40
|
+
const c = doc.createElement("canvas");
|
|
41
|
+
c.width = c.height = 1;
|
|
42
|
+
probe = c.getContext("2d", { willReadFrequently: true });
|
|
43
|
+
}
|
|
44
|
+
if (!probe) return null;
|
|
45
|
+
probe.clearRect(0, 0, 1, 1);
|
|
46
|
+
probe.fillStyle = value;
|
|
47
|
+
probe.fillRect(0, 0, 1, 1);
|
|
48
|
+
const d = probe.getImageData(0, 0, 1, 1).data;
|
|
49
|
+
return lib.parseCssColor("rgba(" + d[0] + "," + d[1] + "," + d[2] + "," + d[3]! / 255 + ")");
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** The element's box in slide px; rotated boxes use their layout size around the rect's centre. */
|
|
56
|
+
function boxOf(el: Element, f: Frame, deg: number) {
|
|
57
|
+
const r = el.getBoundingClientRect();
|
|
58
|
+
const he = el as HTMLElement;
|
|
59
|
+
const rotated = deg !== 0 && typeof he.offsetWidth === "number";
|
|
60
|
+
const w = rotated ? he.offsetWidth : r.width * f.scale;
|
|
61
|
+
const h = rotated ? he.offsetHeight : r.height * f.scale;
|
|
62
|
+
const cx = (r.left + r.width / 2 - f.left) * f.scale;
|
|
63
|
+
const cy = (r.top + r.height / 2 - f.top) * f.scale;
|
|
64
|
+
return { x: cx - w / 2, y: cy - h / 2, w, h, rotation: deg };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function extractSlide(root: Element, f: Frame, note: (label: string) => void) {
|
|
68
|
+
const items: Array<Record<string, unknown> | Promise<Record<string, unknown> | null>> = [];
|
|
69
|
+
const onSlide = (b: { x: number; y: number; w: number; h: number }): boolean =>
|
|
70
|
+
b.x < f.w && b.y < f.h && b.x + b.w > 0 && b.y + b.h > 0;
|
|
71
|
+
const stack: Array<{ el: Element; opacity: number }> = [];
|
|
72
|
+
const pushChildren = (el: Element, opacity: number): void => {
|
|
73
|
+
for (let i = el.children.length - 1; i >= 0; i--) stack.push({ el: el.children[i]!, opacity });
|
|
74
|
+
};
|
|
75
|
+
pushChildren(root, 1);
|
|
76
|
+
while (stack.length) {
|
|
77
|
+
const { el, opacity } = stack.pop()!;
|
|
78
|
+
if (SKIP.test(el.tagName)) continue;
|
|
79
|
+
const cs = win.getComputedStyle(el);
|
|
80
|
+
if (cs.display === "none") continue;
|
|
81
|
+
const op = opacity * (parseFloat(cs.opacity) >= 0 ? parseFloat(cs.opacity) : 1);
|
|
82
|
+
if (op <= 0.01) continue;
|
|
83
|
+
const visible = cs.visibility !== "hidden";
|
|
84
|
+
const media = MEDIA.test(el.tagName);
|
|
85
|
+
if (visible && (media || !INLINE.test(cs.display))) {
|
|
86
|
+
const rot = lib.cssRotation(cs);
|
|
87
|
+
if (!rot.pure) note("transform other than rotation");
|
|
88
|
+
const box = boxOf(el, f, rot.deg);
|
|
89
|
+
// An empty box paints nothing: not worth a warning, and never an item.
|
|
90
|
+
if (!(box.w > 0.5 && box.h > 0.5)) { /* nothing to draw */ }
|
|
91
|
+
else if (!onSlide(box)) note("element outside the slide, left out");
|
|
92
|
+
else if (items.length >= MAX_ITEMS) note("element over the per-slide limit, left out");
|
|
93
|
+
else if (media) {
|
|
94
|
+
if (op < 0.99) note("image opacity");
|
|
95
|
+
items.push(lib.imageDataUrl(el, win).then((data) => {
|
|
96
|
+
if (data) return Object.assign({ kind: "image", data }, box);
|
|
97
|
+
note("image that could not be read");
|
|
98
|
+
return null;
|
|
99
|
+
}));
|
|
100
|
+
} else {
|
|
101
|
+
for (const item of lib.blockItems(el, win, box, op, colorOf, note, lib)) items.push(item);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (!media) pushChildren(el, op);
|
|
105
|
+
}
|
|
106
|
+
const resolved = await Promise.all(items);
|
|
107
|
+
return resolved.filter((item): item is Record<string, unknown> => item !== null);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function backgroundOf(el: Element): Color | null {
|
|
111
|
+
for (let node: Element | null = el; node; node = node.parentElement) {
|
|
112
|
+
const c = colorOf(win.getComputedStyle(node).backgroundColor);
|
|
113
|
+
if (c && c.alpha > 0) return c;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function extractDeck() {
|
|
119
|
+
if (doc.fonts && doc.fonts.ready) await doc.fonts.ready;
|
|
120
|
+
let roots = Array.prototype.slice.call(doc.querySelectorAll("section.slide")) as Element[];
|
|
121
|
+
if (!roots.length) roots = Array.prototype.slice.call(doc.querySelectorAll("[data-slide]")) as Element[];
|
|
122
|
+
const warnings: string[] = [];
|
|
123
|
+
const de = doc.documentElement;
|
|
124
|
+
const whole = roots.length === 0;
|
|
125
|
+
const first = (whole ? de : roots[0]) as HTMLElement;
|
|
126
|
+
const width = Math.min(MAX_EDGE, whole ? de.clientWidth : first.offsetWidth);
|
|
127
|
+
const height = Math.min(MAX_EDGE, whole ? de.scrollHeight : first.offsetHeight);
|
|
128
|
+
if (whole && de.scrollHeight > MAX_EDGE) warnings.push("The page is taller than a slide can be; everything below " + MAX_EDGE + "px was left out.");
|
|
129
|
+
if (!whole && win.innerWidth < width * 0.9) warnings.push("The canvas is narrower than the slides; export from the Slide frame for the exact layout.");
|
|
130
|
+
if (roots.length > MAX_SLIDES) warnings.push("Only the first " + MAX_SLIDES + " slides were exported.");
|
|
131
|
+
if (!(width > 0 && height > 0)) throw new Error("The slides have no size on the canvas");
|
|
132
|
+
const slides: Array<Record<string, unknown>> = [];
|
|
133
|
+
let imageBytes = 0;
|
|
134
|
+
const list = whole ? [doc.body || de] : roots.slice(0, MAX_SLIDES);
|
|
135
|
+
for (let i = 0; i < list.length; i++) {
|
|
136
|
+
const root = list[i]!;
|
|
137
|
+
const r = (whole ? de : root).getBoundingClientRect();
|
|
138
|
+
const counts: Record<string, number> = {};
|
|
139
|
+
const note = (label: string): void => { counts[label] = (counts[label] || 0) + 1; };
|
|
140
|
+
const layoutWidth = whole ? width : (root as HTMLElement).offsetWidth;
|
|
141
|
+
if (!(r.width > 0 && layoutWidth > 0)) {
|
|
142
|
+
warnings.push("Slide " + (i + 1) + " is hidden on the canvas, so it was exported empty.");
|
|
143
|
+
slides.push({ items: [] });
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const frame = { left: r.left, top: r.top, scale: layoutWidth / r.width, w: width, h: height };
|
|
147
|
+
const items = await extractSlide(root, frame, note);
|
|
148
|
+
for (const item of items) if (typeof item.data === "string") imageBytes += item.data.length;
|
|
149
|
+
if (imageBytes > MAX_IMAGE_BYTES) throw new Error("The slides' images add up to more than 50 MB");
|
|
150
|
+
const slide: Record<string, unknown> = { items };
|
|
151
|
+
const bg = backgroundOf(root);
|
|
152
|
+
if (bg) slide.background = bg;
|
|
153
|
+
const own = win.getComputedStyle(root).backgroundImage;
|
|
154
|
+
if (own && own !== "none") note(own.indexOf("gradient") >= 0 ? "gradient slide background" : "slide background image");
|
|
155
|
+
for (const label in counts) warnings.push("Slide " + (i + 1) + ": " + label + (counts[label]! > 1 ? " (" + counts[label] + "x)" : ""));
|
|
156
|
+
slides.push(slide);
|
|
157
|
+
}
|
|
158
|
+
return { width, height, slides, warnings: warnings.slice(0, 200) };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
ppm.on("slides-extract", (m) => {
|
|
162
|
+
const requestId = m.requestId;
|
|
163
|
+
if (typeof requestId !== "string" || !/^[A-Za-z0-9_-]{8,64}$/.test(requestId)) return;
|
|
164
|
+
extractDeck().then(
|
|
165
|
+
(deck) => ppm.post("slides-data", { requestId, doc: deck }),
|
|
166
|
+
(e) => ppm.post("slides-error", { requestId, message: String((e && (e as Error).message) || e).slice(0, 300) }),
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
}
|