From a774ac673aef359a4dc3027e28e1f3aac96d1f0c Mon Sep 17 00:00:00 2001 From: upstream-mirror Date: Wed, 23 Sep 2026 16:12:52 +0500 Subject: [PATCH] snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted) --- .agents/skills | 1 + .claude/launch.json | 23 + .claude/settings.json | 53 + .claude/skills | 1 + .cursor-plugin/marketplace.json | 19 + .cursor/skills | 1 + .dockerignore | 74 + .github/ISSUE_TEMPLATE/bug_report.yml | 49 + .github/ISSUE_TEMPLATE/config.yml | 8 + .github/ISSUE_TEMPLATE/example_request.yml | 16 + .github/ISSUE_TEMPLATE/feature_request.yml | 27 + .github/ISSUE_TEMPLATE/task.yml | 13 + .github/actions/deploy-templates/action.yml | 69 + .../actions/discord-fail-notify/action.yml | 32 + .github/actions/setup-playwright/action.yml | 46 + .github/actions/setup/action.yml | 39 + .github/pull_request_template.md | 21 + .github/workflows/bump-versions.yml | 73 + .github/workflows/checks.yml | 112 + .github/workflows/claude.yml | 52 + .github/workflows/close-stale-issues.yml | 37 + .github/workflows/dependabot-dedupe.yml | 41 + .github/workflows/deploy-analytics.yml | 55 + .github/workflows/deploy-bemo.yml | 61 + .github/workflows/deploy-dotcom.yml | 215 + .github/workflows/deploy-grafana.yml | 115 + .github/workflows/deploy-mcp-app.yml | 63 + .github/workflows/deploy-templates.yml | 57 + .github/workflows/e2e-device.yml | 183 + .github/workflows/get-changelog.yml | 35 + .github/workflows/i18n-download-strings.yml | 73 + .github/workflows/i18n-upload-strings.yml | 35 + .github/workflows/issue-triage.yml | 122 + .github/workflows/license-report.yml | 52 + .github/workflows/playwright-dotcom.yml | 129 + .github/workflows/playwright-examples.yml | 106 + .github/workflows/playwright-mermaid.yml | 71 + .github/workflows/playwright-perf.yml | 107 + .../workflows/playwright-update-snapshots.yml | 84 + .github/workflows/post-release-crew.yml | 56 + .github/workflows/post-release-marketing.yml | 57 + .github/workflows/prune-preview-deploys.yml | 64 + .../workflows/publish-editor-extensions.yml | 73 + .github/workflows/publish-templates.yml | 71 + .../workflows/publish-vscode-extension.yml | 70 + .github/workflows/publish.yml | 330 ++ .github/workflows/staging-cleanup-daily.yml | 38 + .github/workflows/staging-e2e.yml | 68 + .github/workflows/trigger-dotcom-hotfix.yml | 69 + .../workflows/trigger-production-build.yml | 118 + .github/workflows/trigger-sdk-hotfix.yml | 70 + .github/workflows/update-release-notes.yml | 160 + .gitignore | 141 + .husky/post-checkout | 15 + .husky/post-merge | 13 + .husky/pre-commit | 31 + .husky/pre-push | 3 + .ignore | 33 + .oxfmtrc.json | 13 + .oxlintrc.json | 460 ++ .prettierignore | 45 + .prettierrc | 9 + .vscode/extensions.json | 3 + ...icrosoft-tsdoc-npm-0.15.1-e24295d9bd.patch | 91 + .yarnrc.yml | 14 + AGENTS.md | 222 + CLA.md | 35 + CLAUDE.md | 1 + CODE_OF_CONDUCT.md | 48 + COMPANY.md | 5 + CONTRIBUTING.md | 13 + FAQ.md | 3 + LICENSE.md | 70 + README.md | 139 + RELEASES.md | 92 + SECURITY.md | 29 + TRADEMARKS.md | 66 + VOICE.md | 807 ++++ apps/analytics-worker/.gitignore | 2 + apps/analytics-worker/package.json | 28 + apps/analytics-worker/src/worker.ts | 117 + apps/analytics-worker/tsconfig.json | 7 + apps/analytics-worker/vitest.config.ts | 15 + apps/analytics-worker/wrangler.toml | 44 + apps/analytics/.gitignore | 2 + apps/analytics/index.html | 40 + apps/analytics/package.json | 27 + .../analytics-services/analytics-service.ts | 48 + apps/analytics/src/analytics-services/ga4.ts | 119 + apps/analytics/src/analytics-services/gtm.ts | 182 + .../src/analytics-services/hubspot.ts | 23 + .../src/analytics-services/posthog.ts | 53 + apps/analytics/src/analytics-services/reo.ts | 39 + .../src/components/CookieConsentBanner.ts | 90 + .../src/components/PrivacySettingsDialog.ts | 132 + apps/analytics/src/constants.ts | 24 + apps/analytics/src/index.ts | 305 ++ .../src/state/cookie-consent-state.ts | 68 + apps/analytics/src/state/state.test.ts | 57 + apps/analytics/src/state/state.ts | 59 + apps/analytics/src/state/theme-state.ts | 47 + apps/analytics/src/styles.css | 297 ++ apps/analytics/src/types.ts | 56 + apps/analytics/src/utils/consent-check.ts | 27 + apps/analytics/src/vite-env.d.ts | 6 + apps/analytics/tsconfig.json | 17 + apps/analytics/vercel.json | 44 + apps/analytics/vite.config.ts | 20 + apps/analytics/vitest.config.ts | 6 + apps/bemo-worker/.gitignore | 2 + apps/bemo-worker/README.md | 60 + apps/bemo-worker/package.json | 42 + apps/bemo-worker/src/BemoDO.ts | 266 ++ apps/bemo-worker/src/makePermissiveSchema.ts | 49 + apps/bemo-worker/src/types.ts | 17 + apps/bemo-worker/src/worker.test.ts | 5 + apps/bemo-worker/src/worker.ts | 91 + apps/bemo-worker/tsconfig.json | 15 + apps/bemo-worker/vitest.config.ts | 15 + apps/bemo-worker/wrangler.toml | 109 + apps/docs/.gitignore | 8 + apps/docs/.prettierignore | 5 + apps/docs/LICENSE.md | 9 + apps/docs/README.md | 167 + apps/docs/app/(docs)/[...slug]/page.tsx | 139 + apps/docs/app/(docs)/layout.tsx | 20 + .../agent-skills/index.json/route.ts | 31 + .../tldraw-migrate.tar.gz/route.ts | 15 + .../tldraw-migrate/SKILL.md/route.ts | 14 + apps/docs/app/analytics.tsx | 114 + apps/docs/app/globals.css | 138 + apps/docs/app/layout.tsx | 102 + apps/docs/app/not-found.tsx | 72 + apps/docs/app/robots.txt | 4 + apps/docs/app/search/layout.tsx | 14 + apps/docs/app/search/page.tsx | 19 + apps/docs/app/sitemap.ts | 20 + apps/docs/components/common/autorefresh.tsx | 30 + .../components/common/back-to-top-button.tsx | 16 + apps/docs/components/common/button.tsx | 88 + apps/docs/components/common/icon/discord.tsx | 13 + apps/docs/components/common/icon/github.tsx | 13 + apps/docs/components/common/icon/index.tsx | 30 + apps/docs/components/common/icon/linkedin.tsx | 13 + apps/docs/components/common/icon/tldraw.tsx | 16 + apps/docs/components/common/icon/twitter.tsx | 13 + apps/docs/components/common/logo.tsx | 46 + apps/docs/components/common/navigation.tsx | 22 + apps/docs/components/common/page-title.tsx | 20 + apps/docs/components/common/theme-switch.tsx | 43 + apps/docs/components/common/tldraw-link.tsx | 69 + apps/docs/components/content/api-heading.tsx | 3 + apps/docs/components/content/bento.tsx | 228 + apps/docs/components/content/blockquote.tsx | 5 + apps/docs/components/content/callout.tsx | 44 + apps/docs/components/content/check-item.tsx | 11 + apps/docs/components/content/code-files.tsx | 82 + apps/docs/components/content/code.tsx | 180 + apps/docs/components/content/copy-button.tsx | 39 + apps/docs/components/content/embed.tsx | 66 + apps/docs/components/content/example.tsx | 23 + apps/docs/components/content/feature.tsx | 23 + apps/docs/components/content/image.tsx | 27 + apps/docs/components/content/index.tsx | 117 + .../content/masked-article-image.tsx | 17 + .../content/parameters-table-description.tsx | 3 + .../content/parameters-table-name.tsx | 3 + .../content/parameters-table-row.tsx | 3 + .../components/content/parameters-table.tsx | 15 + apps/docs/components/content/pre.tsx | 32 + .../content/side-by-side-images.tsx | 10 + .../content/title-with-source-link.tsx | 54 + apps/docs/components/content/video.tsx | 40 + apps/docs/components/content/youtube.tsx | 26 + .../components/docs/copy-markdown-button.tsx | 40 + .../components/docs/docs-article-info.tsx | 31 + .../components/docs/docs-category-menu.tsx | 58 + .../components/docs/docs-feedback-widget.tsx | 142 + apps/docs/components/docs/docs-footer.tsx | 45 + apps/docs/components/docs/docs-header.tsx | 97 + .../components/docs/docs-mobile-sidebar.tsx | 50 + apps/docs/components/docs/docs-search-bar.tsx | 17 + .../components/docs/docs-sidebar-menu.tsx | 93 + .../components/docs/docs-sidebar-menus.tsx | 56 + .../components/docs/docs-sidebar-utils.ts | 53 + apps/docs/components/docs/docs-sidebar.tsx | 25 + .../components/docs/docs-starter-sidebar.tsx | 31 + .../docs/docs-table-of-contents.tsx | 18 + apps/docs/components/navigation/footer.tsx | 93 + apps/docs/components/navigation/header.tsx | 62 + .../components/navigation/headings-menu.tsx | 53 + apps/docs/components/navigation/link.tsx | 47 + .../components/navigation/social-link.tsx | 19 + .../components/search/ContentHighlight.tsx | 129 + .../docs/components/search/FullPageSearch.tsx | 193 + apps/docs/components/search/SearchButton.tsx | 107 + apps/docs/components/search/SearchDialog.tsx | 192 + apps/docs/components/search/index.tsx | 43 + apps/docs/content/community/contributing.mdx | 11 + apps/docs/content/community/dependencies.mdx | 71 + apps/docs/content/community/license.mdx | 61 + apps/docs/content/community/translations.mdx | 13 + apps/docs/content/docs/ai.mdx | 249 ++ apps/docs/content/docs/assets.mdx | 63 + apps/docs/content/docs/collaboration.mdx | 105 + apps/docs/content/docs/commenting.mdx | 141 + apps/docs/content/docs/driver.mdx | 120 + apps/docs/content/docs/editor.mdx | 141 + apps/docs/content/docs/handles.mdx | 271 ++ apps/docs/content/docs/indicators.mdx | 95 + apps/docs/content/docs/llm-docs.mdx | 56 + apps/docs/content/docs/mermaid.mdx | 152 + apps/docs/content/docs/persistence.mdx | 109 + apps/docs/content/docs/shapes.mdx | 205 + apps/docs/content/docs/sync.mdx | 584 +++ apps/docs/content/docs/tools.mdx | 72 + apps/docs/content/docs/user-interface.mdx | 60 + .../content/getting-started/installation.mdx | 211 + .../content/getting-started/quick-start.mdx | 159 + .../docs/content/getting-started/releases.mdx | 76 + .../docs/content/releases/migration-skill.mdx | 109 + apps/docs/content/releases/next.mdx | 145 + apps/docs/content/releases/v2.0.0.mdx | 179 + apps/docs/content/releases/v2.1.0.mdx | 118 + apps/docs/content/releases/v2.2.0.mdx | 127 + apps/docs/content/releases/v2.3.0.mdx | 67 + apps/docs/content/releases/v2.4.0.mdx | 149 + apps/docs/content/releases/v3.0.0.mdx | 133 + apps/docs/content/releases/v3.1.0.mdx | 41 + apps/docs/content/releases/v3.10.0.mdx | 69 + apps/docs/content/releases/v3.11.0.mdx | 63 + apps/docs/content/releases/v3.12.0.mdx | 65 + apps/docs/content/releases/v3.13.0.mdx | 92 + apps/docs/content/releases/v3.14.0.mdx | 75 + apps/docs/content/releases/v3.15.0.mdx | 94 + apps/docs/content/releases/v3.2.0.mdx | 15 + apps/docs/content/releases/v3.3.0.mdx | 74 + apps/docs/content/releases/v3.4.0.mdx | 56 + apps/docs/content/releases/v3.5.0.mdx | 62 + apps/docs/content/releases/v3.6.0.mdx | 58 + apps/docs/content/releases/v3.7.0.mdx | 58 + apps/docs/content/releases/v3.8.0.mdx | 58 + apps/docs/content/releases/v3.9.0.mdx | 39 + apps/docs/content/releases/v4.0.0.mdx | 123 + apps/docs/content/releases/v4.1.0.mdx | 78 + apps/docs/content/releases/v4.2.0.mdx | 100 + apps/docs/content/releases/v4.3.0.mdx | 317 ++ apps/docs/content/releases/v4.4.0.mdx | 205 + apps/docs/content/releases/v4.5.0.mdx | 169 + apps/docs/content/releases/v5.0.0.mdx | 587 +++ apps/docs/content/releases/v5.1.0.mdx | 50 + apps/docs/content/releases/v5.2.0.mdx | 111 + apps/docs/content/releases/v5.3.0.mdx | 127 + apps/docs/content/releases/v5.4.0.mdx | 199 + .../content/sdk-features/accessibility.mdx | 227 + apps/docs/content/sdk-features/actions.mdx | 315 ++ apps/docs/content/sdk-features/animation.mdx | 138 + .../docs/content/sdk-features/arrow-shape.mdx | 160 + apps/docs/content/sdk-features/assets.mdx | 447 ++ .../docs/content/sdk-features/attribution.mdx | 217 + apps/docs/content/sdk-features/bindings.mdx | 234 + apps/docs/content/sdk-features/camera.mdx | 226 + .../content/sdk-features/click-detection.mdx | 148 + apps/docs/content/sdk-features/clipboard.mdx | 173 + .../content/sdk-features/collaboration.mdx | 541 +++ apps/docs/content/sdk-features/commenting.mdx | 715 +++ .../docs/content/sdk-features/coordinates.mdx | 150 + .../content/sdk-features/cross-tab-sync.mdx | 75 + apps/docs/content/sdk-features/culling.mdx | 106 + .../docs/content/sdk-features/cursor-chat.mdx | 210 + apps/docs/content/sdk-features/cursors.mdx | 226 + apps/docs/content/sdk-features/deep-links.mdx | 146 + .../content/sdk-features/default-shapes.mdx | 622 +++ .../content/sdk-features/drag-and-drop.mdx | 265 ++ apps/docs/content/sdk-features/draw-shape.mdx | 209 + .../content/sdk-features/edge-scrolling.mdx | 96 + apps/docs/content/sdk-features/editor.mdx | 464 ++ .../docs/content/sdk-features/embed-shape.mdx | 226 + .../docs/content/sdk-features/environment.mdx | 154 + apps/docs/content/sdk-features/eraser.mdx | 81 + apps/docs/content/sdk-features/errors.mdx | 148 + apps/docs/content/sdk-features/events.mdx | 285 ++ .../content/sdk-features/external-content.mdx | 283 ++ apps/docs/content/sdk-features/focus.mdx | 137 + .../docs/content/sdk-features/frame-shape.mdx | 150 + apps/docs/content/sdk-features/geo-shape.mdx | 355 ++ apps/docs/content/sdk-features/geometry.mdx | 525 +++ apps/docs/content/sdk-features/grid.mdx | 139 + apps/docs/content/sdk-features/groups.mdx | 189 + apps/docs/content/sdk-features/handles.mdx | 267 ++ .../content/sdk-features/highlighting.mdx | 168 + apps/docs/content/sdk-features/history.mdx | 169 + .../content/sdk-features/image-export.mdx | 167 + apps/docs/content/sdk-features/indicators.mdx | 157 + .../content/sdk-features/input-handling.mdx | 190 + .../content/sdk-features/instance-state.mdx | 292 ++ .../sdk-features/internationalization.mdx | 231 + .../docs/content/sdk-features/license-key.mdx | 144 + .../content/sdk-features/locked-shapes.mdx | 124 + apps/docs/content/sdk-features/note-shape.mdx | 139 + apps/docs/content/sdk-features/options.mdx | 404 ++ .../content/sdk-features/overlay-utils.mdx | 266 ++ apps/docs/content/sdk-features/pages.mdx | 167 + apps/docs/content/sdk-features/parenting.mdx | 239 + apps/docs/content/sdk-features/pen-mode.mdx | 82 + .../docs/content/sdk-features/performance.mdx | 251 ++ .../docs/content/sdk-features/persistence.mdx | 425 ++ apps/docs/content/sdk-features/readonly.mdx | 159 + apps/docs/content/sdk-features/rich-text.mdx | 356 ++ apps/docs/content/sdk-features/scribble.mdx | 227 + apps/docs/content/sdk-features/selection.mdx | 217 + .../content/sdk-features/shape-clipping.mdx | 181 + .../content/sdk-features/shape-indexing.mdx | 131 + .../content/sdk-features/shape-transforms.mdx | 146 + apps/docs/content/sdk-features/shapes.mdx | 306 ++ .../content/sdk-features/side-effects.mdx | 127 + apps/docs/content/sdk-features/signals.mdx | 416 ++ apps/docs/content/sdk-features/snapping.mdx | 218 + apps/docs/content/sdk-features/store.mdx | 412 ++ apps/docs/content/sdk-features/styles.mdx | 208 + .../content/sdk-features/text-measurement.mdx | 194 + apps/docs/content/sdk-features/text-shape.mdx | 250 ++ apps/docs/content/sdk-features/themes.mdx | 429 ++ apps/docs/content/sdk-features/ticks.mdx | 127 + apps/docs/content/sdk-features/tools.mdx | 294 ++ .../content/sdk-features/ui-components.mdx | 321 ++ .../content/sdk-features/ui-primitives.mdx | 429 ++ .../content/sdk-features/user-following.mdx | 149 + .../content/sdk-features/user-preferences.mdx | 145 + apps/docs/content/sdk-features/validation.mdx | 173 + apps/docs/content/sdk-features/visibility.mdx | 143 + apps/docs/content/sections.json | 493 +++ apps/docs/content/starter-kits/agent.mdx | 769 ++++ .../content/starter-kits/branching-chat.mdx | 109 + apps/docs/content/starter-kits/chat.mdx | 90 + .../content/starter-kits/image-pipeline.mdx | 135 + .../docs/content/starter-kits/multiplayer.mdx | 254 ++ apps/docs/content/starter-kits/overview.mdx | 136 + apps/docs/content/starter-kits/shader.mdx | 110 + apps/docs/content/starter-kits/workflow.mdx | 162 + apps/docs/next-env.d.ts | 7 + apps/docs/next.config.js | 224 + apps/docs/package.json | 115 + apps/docs/postcss.config.js | 6 + apps/docs/public/apple-touch-icon-152x152.svg | 11 + apps/docs/public/apple-touch-icon-167x167.svg | 11 + apps/docs/public/apple-touch-icon-180x180.svg | 11 + apps/docs/public/apple-touch-icon.png | Bin 0 -> 2085 bytes apps/docs/public/favicon-16x16.svg | 11 + apps/docs/public/favicon-32x32.svg | 11 + apps/docs/public/favicon.ico | Bin 0 -> 15406 bytes apps/docs/public/favicon.svg | 4 + apps/docs/public/images/404.svg | 1 + apps/docs/public/images/multiplayer_mask.png | Bin 0 -> 9627 bytes .../starter-kit-images/agent-starter.avif | Bin 0 -> 56735 bytes .../multiplayer-starter.avif | Bin 0 -> 20949 bytes .../starter-kit-images/shader-starter.avif | Bin 0 -> 109749 bytes .../starter-kit-images/workflow-starter.avif | Bin 0 -> 34133 bytes apps/docs/public/images/with-watermark.png | Bin 0 -> 102076 bytes apps/docs/public/images/without-watermark.png | Bin 0 -> 98481 bytes apps/docs/scripts/check-broken-links.ts | 16 + apps/docs/scripts/check-external-links.ts | 10 + apps/docs/scripts/create-api-markdown.ts | 8 + apps/docs/scripts/create-llms-txt.ts | 11 + apps/docs/scripts/fetch-api-source.ts | 8 + apps/docs/scripts/lib/checkBrokenLinks.ts | 312 ++ apps/docs/scripts/lib/checkExternalLinks.ts | 165 + apps/docs/scripts/lib/connect.ts | 92 + apps/docs/scripts/lib/createApiMarkdown.ts | 98 + apps/docs/scripts/lib/fetchApiSource.ts | 30 + apps/docs/scripts/lib/generateApiContent.ts | 24 + apps/docs/scripts/lib/generateContent.ts | 20 + .../scripts/lib/generateExamplesContent.ts | 45 + apps/docs/scripts/lib/generateLllmsTxt.ts | 139 + apps/docs/scripts/lib/generateSection.ts | 468 ++ apps/docs/scripts/lib/getApiMarkdown.ts | 623 +++ apps/docs/scripts/lib/getArticleKey.ts | 5 + apps/docs/scripts/lib/package-list.ts | 13 + apps/docs/scripts/lib/refreshContent.ts | 31 + apps/docs/scripts/lib/utils.ts | 306 ++ apps/docs/scripts/refresh-content.ts | 7 + apps/docs/scripts/update-algolia-index.ts | 345 ++ apps/docs/tailwind.config.js | 17 + apps/docs/tsconfig.content.json | 6 + apps/docs/tsconfig.json | 28 + apps/docs/types/content-types.ts | 209 + apps/docs/utils/ContentDatabase.ts | 285 ++ apps/docs/utils/TldrawApiModel.ts | 245 + apps/docs/utils/addContent.ts | 167 + apps/docs/utils/agent-skills.test.ts | 83 + apps/docs/utils/agent-skills.ts | 145 + apps/docs/utils/algolia.ts | 53 + apps/docs/utils/asset-url.test.ts | 165 + apps/docs/utils/asset-url.ts | 40 + apps/docs/utils/autoLinkDocs.ts | 73 + apps/docs/utils/cn.ts | 6 + apps/docs/utils/config.ts | 1 + apps/docs/utils/nicelog.ts | 4 + apps/docs/utils/parse-markdown.test.tsx | 425 ++ apps/docs/utils/parse-markdown.tsx | 276 ++ apps/docs/utils/search-api.ts | 6 + .../utils/sitemap-canonical-paths.test.ts | 24 + apps/docs/utils/sitemap-canonical-paths.ts | 36 + apps/docs/utils/storage.ts | 40 + apps/docs/version.ts | 9 + apps/docs/vitest.config.ts | 20 + apps/docs/watcher.ts | 47 + apps/dotcom/.gitignore | 1 + apps/dotcom/README.md | 34 + apps/dotcom/asset-upload-worker/.gitignore | 1 + apps/dotcom/asset-upload-worker/README.md | 27 + apps/dotcom/asset-upload-worker/package.json | 28 + apps/dotcom/asset-upload-worker/src/types.ts | 13 + apps/dotcom/asset-upload-worker/src/worker.ts | 50 + apps/dotcom/asset-upload-worker/tsconfig.json | 7 + .../asset-upload-worker/vitest.config.ts | 10 + apps/dotcom/asset-upload-worker/wrangler.toml | 81 + apps/dotcom/client/.gitignore | 42 + apps/dotcom/client/PRIVACY_POLICY.md | 118 + apps/dotcom/client/README.md | 29 + apps/dotcom/client/TERMS_OF_SERVICE.md | 132 + .../client/assets/icons/icon/icon-avatar.svg | 1 + .../assets/icons/icon/icon-bookmark.svg | 1 + .../client/assets/icons/icon/icon-check.svg | 1 + .../icons/icon/icon-chevron-down-strong.svg | 1 + .../assets/icons/icon/icon-chevron-down.svg | 1 + .../icons/icon/icon-chevron-right-strong.svg | 1 + .../assets/icons/icon/icon-chevron-right.svg | 1 + .../icons/icon/icon-chevron-up-down.svg | 1 + .../icons/icon/icon-chevron-up-strong.svg | 1 + .../assets/icons/icon/icon-chevron-up.svg | 1 + .../assets/icons/icon/icon-close-strong.svg | 1 + .../client/assets/icons/icon/icon-close.svg | 1 + .../client/assets/icons/icon/icon-comment.svg | 1 + .../assets/icons/icon/icon-copy-strong.svg | 1 + .../client/assets/icons/icon/icon-copy.svg | 1 + .../assets/icons/icon/icon-doc-strong.svg | 1 + .../client/assets/icons/icon/icon-doc.svg | 1 + .../icon/icon-dots-horizontal-strong.svg | 1 + .../icons/icon/icon-dots-horizontal.svg | 1 + .../icons/icon/icon-dots-vertical-strong.svg | 1 + .../assets/icons/icon/icon-dots-vertical.svg | 1 + .../client/assets/icons/icon/icon-draw.svg | 1 + .../assets/icons/icon/icon-edit-strong.svg | 1 + .../client/assets/icons/icon/icon-edit.svg | 1 + .../client/assets/icons/icon/icon-export.svg | 1 + .../assets/icons/icon/icon-external.svg | 1 + .../assets/icons/icon/icon-feedback.svg | 1 + .../assets/icons/icon/icon-folder-new.svg | 1 + .../assets/icons/icon/icon-folder-open.svg | 1 + .../client/assets/icons/icon/icon-folder.svg | 1 + .../assets/icons/icon/icon-group-strong.svg | 1 + .../client/assets/icons/icon/icon-group.svg | 1 + .../assets/icons/icon/icon-help-circle.svg | 1 + .../assets/icons/icon/icon-home-strong.svg | 1 + .../client/assets/icons/icon/icon-home.svg | 1 + .../client/assets/icons/icon/icon-import.svg | 1 + .../client/assets/icons/icon/icon-info.svg | 1 + .../client/assets/icons/icon/icon-invite.svg | 1 + .../assets/icons/icon/icon-link-strong.svg | 1 + .../client/assets/icons/icon/icon-link.svg | 1 + .../client/assets/icons/icon/icon-manual.svg | 1 + .../client/assets/icons/icon/icon-more.svg | 1 + .../assets/icons/icon/icon-notification.svg | 1 + .../assets/icons/icon/icon-pin-strong.svg | 1 + .../client/assets/icons/icon/icon-pin.svg | 1 + .../assets/icons/icon/icon-plus-strong.svg | 1 + .../client/assets/icons/icon/icon-plus.svg | 1 + .../client/assets/icons/icon/icon-qr.svg | 1 + .../icons/icon/icon-question-circle.svg | 1 + .../assets/icons/icon/icon-question.svg | 1 + .../client/assets/icons/icon/icon-refresh.svg | 1 + .../client/assets/icons/icon/icon-search.svg | 1 + .../assets/icons/icon/icon-settings.svg | 1 + .../client/assets/icons/icon/icon-share.svg | 1 + .../client/assets/icons/icon/icon-shared.svg | 1 + .../assets/icons/icon/icon-sidebar-strong.svg | 1 + .../client/assets/icons/icon/icon-sidebar.svg | 1 + .../client/assets/icons/icon/icon-sign-in.svg | 1 + .../client/assets/icons/icon/icon-spinner.svg | 1 + .../assets/icons/icon/icon-star-fill.svg | 1 + .../icons/icon/icon-star-strong-fill.svg | 1 + .../assets/icons/icon/icon-star-strong.svg | 1 + .../client/assets/icons/icon/icon-star.svg | 1 + .../client/assets/icons/icon/icon-tick.svg | 1 + .../client/assets/icons/icon/icon-tldraw.svg | 1 + .../client/assets/icons/icon/icon-untick.svg | 1 + .../client/assets/icons/icon/icon-update.svg | 1 + apps/dotcom/client/decs.d.ts | 17 + apps/dotcom/client/e2e/README.md | 32 + apps/dotcom/client/e2e/consts.ts | 7 + apps/dotcom/client/e2e/fixtures/Database.ts | 68 + .../client/e2e/fixtures/DeleteFileDialog.ts | 34 + apps/dotcom/client/e2e/fixtures/Editor.ts | 95 + apps/dotcom/client/e2e/fixtures/ErrorPages.ts | 30 + apps/dotcom/client/e2e/fixtures/HomePage.ts | 103 + .../client/e2e/fixtures/ImportHelper.ts | 51 + apps/dotcom/client/e2e/fixtures/ShareMenu.ts | 169 + apps/dotcom/client/e2e/fixtures/Sidebar.ts | 649 +++ .../client/e2e/fixtures/SignInDialog.ts | 66 + .../e2e/fixtures/WorkspaceInviteDialog.ts | 29 + apps/dotcom/client/e2e/fixtures/helpers.ts | 121 + .../client/e2e/fixtures/scenario-test.ts | 695 +++ .../client/e2e/fixtures/staging-test.ts | 39 + apps/dotcom/client/e2e/fixtures/tla-test.ts | 203 + .../dotcom/client/e2e/global-staging.setup.ts | 49 + apps/dotcom/client/e2e/global.setup.ts | 9 + apps/dotcom/client/e2e/global.teardown.ts | 28 + .../client/e2e/tests/auth.scenario.spec.ts | 35 + .../e2e/tests/client-too-old.scenario.spec.ts | 25 + .../tests/import-download.scenario.spec.ts | 44 + .../e2e/tests/invite-signin.scenario.spec.ts | 60 + .../e2e/tests/legacy-routes.scenario.spec.ts | 86 + .../e2e/tests/sharing-live.scenario.spec.ts | 285 ++ .../e2e/tests/smoke/cookie-consent.spec.ts | 110 + .../client/e2e/tests/smoke/database.spec.ts | 35 + .../client/e2e/tests/smoke/homepage.spec.ts | 162 + .../e2e/tests/smoke/not-logged-in.spec.ts | 47 + .../client/e2e/tests/smoke/sharing.spec.ts | 383 ++ .../tests/smoke/sidebar-dotdev-link.spec.ts | 33 + .../e2e/tests/smoke/signin-dialog.spec.ts | 64 + .../tests/smoke/test-import-download.spec.ts | 117 + .../client/e2e/tests/smoke/workspaces.spec.ts | 513 +++ apps/dotcom/client/e2e/tests/staging.spec.ts | 38 + .../client/e2e/tests/ui.scenario.spec.ts | 379 ++ ...rkspaces-feature-coverage.scenario.spec.ts | 193 + apps/dotcom/client/index.html | 135 + apps/dotcom/client/package.json | 99 + apps/dotcom/client/playwright.config.ts | 129 + .../client/public/.well-known/ai-catalog.json | 23 + .../client/public/.well-known/api-catalog | 28 + ...le-developer-merchantid-domain-association | 1 + apps/dotcom/client/public/404-Sad-tldraw.svg | 5 + .../client/public/android-chrome-192x192.png | Bin 0 -> 2362 bytes .../client/public/android-chrome-512x512.png | Bin 0 -> 6676 bytes .../android-chrome-maskable-192x192.png | Bin 0 -> 1852 bytes .../android-chrome-maskable-512x512.png | Bin 0 -> 5363 bytes .../android-chrome-maskable-beta-512x512.png | Bin 0 -> 66436 bytes .../public/apple-touch-icon-152x152.svg | 11 + .../public/apple-touch-icon-167x167.svg | 11 + .../public/apple-touch-icon-180x180.svg | 11 + .../dotcom/client/public/apple-touch-icon.png | Bin 0 -> 2152 bytes apps/dotcom/client/public/auth.md | 66 + apps/dotcom/client/public/cookies.html | 707 +++ apps/dotcom/client/public/favicon-16x16.png | Bin 0 -> 281 bytes apps/dotcom/client/public/favicon-32x32.png | Bin 0 -> 425 bytes apps/dotcom/client/public/favicon.ico | Bin 0 -> 15406 bytes apps/dotcom/client/public/favicon.svg | 11 + apps/dotcom/client/public/flat.png | Bin 0 -> 6621 bytes apps/dotcom/client/public/legal.html | 707 +++ .../dotcom/client/public/manifest.webmanifest | 38 + apps/dotcom/client/public/privacy.html | 707 +++ apps/dotcom/client/public/reo.html | 20 + apps/dotcom/client/public/robots.txt | 42 + apps/dotcom/client/public/site.webmanifest | 11 + apps/dotcom/client/public/sitemap.txt | 1 + apps/dotcom/client/public/sitemap.xml | 14 + apps/dotcom/client/public/social-og.png | Bin 0 -> 12516 bytes apps/dotcom/client/public/social-twitter.png | Bin 0 -> 26287 bytes .../client/public/staging-favicon-16.png | Bin 0 -> 311 bytes .../client/public/staging-favicon-32.png | Bin 0 -> 541 bytes apps/dotcom/client/public/staging-favicon.svg | 12 + apps/dotcom/client/public/sw.js | 19 + apps/dotcom/client/public/theme-init.js | 32 + .../public/tla/locales-compiled/ar.json | 1989 +++++++++ .../public/tla/locales-compiled/bn.json | 1911 ++++++++ .../public/tla/locales-compiled/ca.json | 1907 ++++++++ .../public/tla/locales-compiled/cs.json | 1941 ++++++++ .../public/tla/locales-compiled/da.json | 1915 ++++++++ .../public/tla/locales-compiled/de.json | 1911 ++++++++ .../public/tla/locales-compiled/el.json | 1931 ++++++++ .../public/tla/locales-compiled/en.json | 1915 ++++++++ .../public/tla/locales-compiled/es.json | 1911 ++++++++ .../public/tla/locales-compiled/fa.json | 1907 ++++++++ .../public/tla/locales-compiled/fi.json | 1911 ++++++++ .../public/tla/locales-compiled/fr.json | 1911 ++++++++ .../public/tla/locales-compiled/gl.json | 1907 ++++++++ .../public/tla/locales-compiled/gu-in.json | 1899 ++++++++ .../public/tla/locales-compiled/he.json | 1941 ++++++++ .../public/tla/locales-compiled/hi-in.json | 1903 ++++++++ .../public/tla/locales-compiled/hr.json | 1922 ++++++++ .../public/tla/locales-compiled/hu.json | 1903 ++++++++ .../public/tla/locales-compiled/id.json | 1891 ++++++++ .../public/tla/locales-compiled/it.json | 1907 ++++++++ .../public/tla/locales-compiled/ja.json | 1859 ++++++++ .../public/tla/locales-compiled/km-kh.json | 1899 ++++++++ .../public/tla/locales-compiled/kn.json | 1903 ++++++++ .../public/tla/locales-compiled/ko-kr.json | 1871 ++++++++ .../public/tla/locales-compiled/ml.json | 1887 ++++++++ .../public/tla/locales-compiled/mr.json | 1899 ++++++++ .../public/tla/locales-compiled/ms.json | 1895 ++++++++ .../public/tla/locales-compiled/ne.json | 1903 ++++++++ .../public/tla/locales-compiled/nl.json | 1911 ++++++++ .../public/tla/locales-compiled/no.json | 1915 ++++++++ .../public/tla/locales-compiled/pa.json | 1903 ++++++++ .../public/tla/locales-compiled/pl.json | 1937 ++++++++ .../public/tla/locales-compiled/pt-br.json | 1907 ++++++++ .../public/tla/locales-compiled/pt-pt.json | 1907 ++++++++ .../public/tla/locales-compiled/ro.json | 1922 ++++++++ .../public/tla/locales-compiled/ru.json | 1949 ++++++++ .../public/tla/locales-compiled/sl.json | 1941 ++++++++ .../public/tla/locales-compiled/so.json | 1903 ++++++++ .../public/tla/locales-compiled/sv.json | 1915 ++++++++ .../public/tla/locales-compiled/ta.json | 1879 ++++++++ .../public/tla/locales-compiled/te.json | 1907 ++++++++ .../public/tla/locales-compiled/th.json | 1887 ++++++++ .../public/tla/locales-compiled/tl.json | 1959 ++++++++ .../public/tla/locales-compiled/tr.json | 1875 ++++++++ .../public/tla/locales-compiled/uk.json | 1937 ++++++++ .../public/tla/locales-compiled/ur.json | 1911 ++++++++ .../public/tla/locales-compiled/vi.json | 1891 ++++++++ .../public/tla/locales-compiled/zh-cn.json | 1903 ++++++++ .../public/tla/locales-compiled/zh-tw.json | 1903 ++++++++ apps/dotcom/client/public/tla/locales/ar.json | 723 +++ apps/dotcom/client/public/tla/locales/bn.json | 723 +++ apps/dotcom/client/public/tla/locales/ca.json | 723 +++ apps/dotcom/client/public/tla/locales/cs.json | 723 +++ apps/dotcom/client/public/tla/locales/da.json | 723 +++ apps/dotcom/client/public/tla/locales/de.json | 723 +++ apps/dotcom/client/public/tla/locales/el.json | 723 +++ apps/dotcom/client/public/tla/locales/en.json | 723 +++ apps/dotcom/client/public/tla/locales/es.json | 723 +++ apps/dotcom/client/public/tla/locales/fa.json | 723 +++ apps/dotcom/client/public/tla/locales/fi.json | 723 +++ apps/dotcom/client/public/tla/locales/fr.json | 723 +++ apps/dotcom/client/public/tla/locales/gl.json | 723 +++ .../client/public/tla/locales/gu-in.json | 723 +++ apps/dotcom/client/public/tla/locales/he.json | 723 +++ .../client/public/tla/locales/hi-in.json | 723 +++ apps/dotcom/client/public/tla/locales/hr.json | 723 +++ apps/dotcom/client/public/tla/locales/hu.json | 723 +++ apps/dotcom/client/public/tla/locales/id.json | 723 +++ apps/dotcom/client/public/tla/locales/it.json | 723 +++ apps/dotcom/client/public/tla/locales/ja.json | 723 +++ .../client/public/tla/locales/km-kh.json | 723 +++ apps/dotcom/client/public/tla/locales/kn.json | 723 +++ .../client/public/tla/locales/ko-kr.json | 723 +++ apps/dotcom/client/public/tla/locales/ml.json | 723 +++ apps/dotcom/client/public/tla/locales/mr.json | 723 +++ apps/dotcom/client/public/tla/locales/ms.json | 723 +++ apps/dotcom/client/public/tla/locales/ne.json | 723 +++ apps/dotcom/client/public/tla/locales/nl.json | 723 +++ apps/dotcom/client/public/tla/locales/no.json | 723 +++ apps/dotcom/client/public/tla/locales/pa.json | 723 +++ apps/dotcom/client/public/tla/locales/pl.json | 723 +++ .../client/public/tla/locales/pt-br.json | 723 +++ .../client/public/tla/locales/pt-pt.json | 723 +++ apps/dotcom/client/public/tla/locales/ro.json | 723 +++ apps/dotcom/client/public/tla/locales/ru.json | 723 +++ apps/dotcom/client/public/tla/locales/sl.json | 723 +++ apps/dotcom/client/public/tla/locales/so.json | 723 +++ apps/dotcom/client/public/tla/locales/sv.json | 723 +++ apps/dotcom/client/public/tla/locales/ta.json | 723 +++ apps/dotcom/client/public/tla/locales/te.json | 723 +++ apps/dotcom/client/public/tla/locales/th.json | 723 +++ apps/dotcom/client/public/tla/locales/tl.json | 723 +++ apps/dotcom/client/public/tla/locales/tr.json | 723 +++ apps/dotcom/client/public/tla/locales/uk.json | 723 +++ apps/dotcom/client/public/tla/locales/ur.json | 723 +++ apps/dotcom/client/public/tla/locales/vi.json | 723 +++ .../client/public/tla/locales/zh-cn.json | 723 +++ .../client/public/tla/locales/zh-tw.json | 723 +++ apps/dotcom/client/public/tla/spinner.svg | 1 + apps/dotcom/client/public/tla/thumbnail-1.png | Bin 0 -> 36910 bytes apps/dotcom/client/public/tla/thumbnail.png | Bin 0 -> 23448 bytes .../client/public/tla/tldraw-logo-2.svg | 9 + .../client/public/tldraw-white-on-black.svg | 15 + apps/dotcom/client/public/tldraw.svg | 11 + .../client/public/tldraw_sidebar_logo.svg | 9 + apps/dotcom/client/public/tos.html | 707 +++ .../client/scripts/browser-run-thumbnail.ts | 298 ++ apps/dotcom/client/scripts/build.ts | 336 ++ apps/dotcom/client/scripts/dev-app.test.ts | 66 + apps/dotcom/client/scripts/dev-app.ts | 86 + apps/dotcom/client/scripts/kill-tree.test.ts | 114 + .../scripts/measure-bundle-size.test.ts | 250 ++ .../client/scripts/measure-bundle-size.ts | 268 ++ .../client/scripts/multiplayer-server-url.ts | 8 + .../client/scripts/vercel-output-config.d.ts | 111 + .../vite-thumbnail-screenshot-plugin.ts | 176 + .../scripts/vite-zod-locale-plugin.d.ts | 7 + .../client/scripts/vite-zod-locale-plugin.js | 40 + .../dotcom/client/scripts/zod-locales-shim.js | 7 + apps/dotcom/client/sentry-release-name.ts | 3 + apps/dotcom/client/sentry.client.config.ts | 58 + apps/dotcom/client/sentry.properties | 4 + apps/dotcom/client/setupTests.js | 9 + .../src/__snapshots__/routes.test.tsx.snap | 86 + apps/dotcom/client/src/app.d.ts | 1 + .../dotcom/client/src/assets/0_merged_tla.svg | 1 + .../BoardHistoryLog/BoardHistoryLog.tsx | 82 + .../src/components/ErrorPage/ErrorPage.tsx | 91 + .../client/src/components/Head/Head.tsx | 30 + .../client/src/components/IFrameProtector.tsx | 76 + .../client/src/components/LocalEditor.tsx | 68 + .../LoginRedirectPage/LoginRedirectPage.tsx | 13 + .../SneakyMermaidHandler.tsx | 73 + .../simpleMermaidStringTest.test.ts | 271 ++ .../simpleMermaidStringTest.ts | 79 + .../src/components/SneakyOnDropOverride.ts | 47 + .../src/components/StoreErrorScreen.tsx | 66 + .../components/ThemeUpdater/ThemeUpdater.tsx | 12 + apps/dotcom/client/src/css.d.ts | 4 + .../client/src/hooks/useLegacyUrlParams.ts | 42 + .../client/src/hooks/useOpenUrlAndTrack.ts | 10 + .../src/hooks/usePerformanceTracking.ts | 153 + .../client/src/hooks/useRoomLoadTracking.ts | 35 + apps/dotcom/client/src/hooks/useUrl.ts | 7 + apps/dotcom/client/src/main.tsx | 60 + .../client/src/pages/admin/AdminButton.tsx | 30 + .../client/src/pages/admin/EffectsSection.tsx | 246 + .../client/src/pages/admin/FileStats.tsx | 193 + .../client/src/pages/admin/FilesSection.tsx | 701 +++ .../client/src/pages/admin/FlagsSection.tsx | 406 ++ .../client/src/pages/admin/SystemSection.tsx | 44 + .../client/src/pages/admin/UsersSection.tsx | 339 ++ .../client/src/pages/admin/admin.module.css | 543 +++ apps/dotcom/client/src/pages/admin/index.tsx | 56 + apps/dotcom/client/src/pages/admin/shared.tsx | 54 + .../src/pages/dev-browser-run-thumbnail.tsx | 124 + .../src/pages/dev-reset-local-state.tsx | 161 + apps/dotcom/client/src/pages/not-found.tsx | 16 + .../client/src/pages/thumbnail-render.test.ts | 138 + .../client/src/pages/thumbnail-render.tsx | 789 ++++ apps/dotcom/client/src/pages/tla-new.tsx | 35 + apps/dotcom/client/src/routeDefs.ts | 94 + apps/dotcom/client/src/routes.test.tsx | 216 + apps/dotcom/client/src/routes.tsx | 160 + .../client/src/thumbnail-render-main.tsx | 55 + .../client/src/tla/app/TldrawApp.test.ts | 219 + apps/dotcom/client/src/tla/app/TldrawApp.ts | 1452 ++++++ .../client/src/tla/app/ZeroLogBuffer.ts | 60 + .../src/tla/app/getMostRecentFileId.test.ts | 165 + .../tla/app/getWorkspaceFilesSorted.test.ts | 61 + .../src/tla/app/msUntilTokenRefresh.test.ts | 34 + .../tla/app/shouldEnableCommenting.test.ts | 57 + .../src/tla/app/uploadTldrFiles.test.ts | 89 + .../components/ExternalLink/ExternalLink.tsx | 18 + .../MaybeForceUserRefresh.module.css | 42 + .../MaybeForceUserRefresh.tsx | 61 + .../TlaAnonDotDevLink.module.css | 113 + .../TlaAnonDotDevLink/TlaAnonDotDevLink.tsx | 61 + .../tla/components/TlaButton/TlaButton.tsx | 75 + .../components/TlaButton/button.module.css | 151 + .../components/TlaCtaButton/TlaCtaButton.tsx | 26 + .../TlaCtaButton/cta-button.module.css | 89 + .../components/TlaEditor/CommentsOnCanvas.tsx | 315 ++ .../tla/components/TlaEditor/SlurpFailure.tsx | 87 + .../src/tla/components/TlaEditor/TlaDebug.tsx | 91 + .../tla/components/TlaEditor/TlaEditor.tsx | 530 +++ .../TlaEditor/TlaEditorTopLeftPanel.tsx | 495 +++ .../TlaEditor/TlaEditorTopRightPanel.tsx | 249 ++ .../components/TlaEditor/TlaEditorWrapper.tsx | 10 + .../TlaEditor/TlaHistorySnapshotEditor.tsx | 47 + .../TlaEditor/TlaLegacyFileEditor.tsx | 138 + .../TlaEditor/TlaLegacySnapshotEditor.tsx | 103 + .../components/TlaEditor/TlaPublishEditor.tsx | 69 + .../TlaEditorErrorFallback.tsx | 6 + .../TlaEditorLegacySharePanel.tsx | 7 + .../editor-components/TlaEditorMenuPanel.tsx | 7 + .../TlaEditorPublishedSharePanel.tsx | 7 + .../editor-components/TlaEditorSharePanel.tsx | 9 + .../editor-components/TlaEditorTopPanel.tsx | 3 + .../components/TlaEditor/editor-messages.ts | 9 + .../components/TlaEditor/editor.module.css | 8 + .../sneaky/SneakyCommentDeepLink.tsx | 72 + .../TlaEditor/sneaky/SneakyDarkModeSync.tsx | 26 + .../TlaEditor/sneaky/SneakyDebugModeToast.tsx | 48 + .../sneaky/SneakyFileDropHandler.tsx | 47 + .../sneaky/SneakyLargeFileHandler.tsx | 93 + .../TlaEditor/sneaky/SneakyLegacyModal.tsx | 97 + .../sneaky/SneakyLegacytSetDocumentTitle.tsx | 15 + .../sneaky/SneakySetDocumentTitle.tsx | 23 + .../TlaEditor/sneaky/SneakyToolSwitcher.tsx | 21 + .../sneaky/sneaky-legacy-modal.module.css | 9 + .../tla/components/TlaEditor/top.module.css | 305 ++ .../TlaEditor/useExtraToolDragIcons.ts | 202 + .../TlaEditor/useFileEditorOverrides.ts | 121 + .../TlaFileError/TlaFileError.module.css | 46 + .../components/TlaFileError/TlaFileError.tsx | 139 + .../components/TlaFileMenu/TlaFileMenu.tsx | 333 ++ .../components/TlaFileShareMenu/QrCode.tsx | 37 + .../Tabs/TlaAnonCopyLinkTab.tsx | 37 + .../TlaFileShareMenu/Tabs/TlaExportTab.tsx | 375 ++ .../TlaFileShareMenu/Tabs/TlaInviteTab.tsx | 154 + .../TlaFileShareMenu/Tabs/TlaPublishTab.tsx | 152 + .../TlaFileShareMenu/TlaFileShareMenu.tsx | 142 + .../file-share-menu-primitives.tsx | 36 + .../file-share-menu.module.css | 66 + .../src/tla/components/TlaIcon/TlaIcon.tsx | 58 + .../tla/components/TlaIcon/icon.module.css | 15 + .../src/tla/components/TlaLogo/TlaLogo.tsx | 29 + .../tla/components/TlaLogo/logo.module.css | 11 + .../tla/components/TlaSidebar/TlaSidebar.tsx | 111 + .../components/TlaSidebarCreateFileButton.tsx | 64 + .../components/TlaSidebarDotDevLink.tsx | 24 + .../components/TlaSidebarFeedbackButton.tsx | 27 + .../components/TlaSidebarFileLink.tsx | 367 ++ .../components/TlaSidebarFileLinkMenu.tsx | 37 + .../components/TlaSidebarFileSection.tsx | 59 + .../components/TlaSidebarInlineInput.tsx | 72 + .../TlaSidebarNotificationsButton.tsx | 56 + .../TlaSidebarNotificationsPanel.tsx | 342 ++ .../components/TlaSidebarRecentFiles.tsx | 128 + .../components/TlaSidebarRenameInline.tsx | 39 + .../components/TlaSidebarSearch.tsx | 126 + .../components/TlaSidebarToggle.tsx | 34 + .../components/TlaSidebarToggleMobile.tsx | 34 + .../components/TlaSidebarUserSettingsMenu.tsx | 103 + .../components/TlaSidebarWorkspaceActions.tsx | 79 + .../components/TlaSidebarWorkspaceLink.tsx | 10 + .../TlaSidebarWorkspaceSwitcher.tsx | 274 ++ .../components/commentNotifications.test.ts | 474 ++ .../components/commentNotifications.ts | 209 + .../components/notifications.module.css | 87 + .../TlaSidebar/components/sidebar-shared.ts | 24 + .../components/TlaSidebar/sidebar.module.css | 1032 +++++ .../tla/components/WorkspaceInviteHandler.tsx | 188 + .../tla/components/dialogs/ConfirmDialog.tsx | 54 + .../dialogs/CreateWorkspaceDialog.tsx | 88 + .../dialogs/SubmitFeedbackDialog.tsx | 203 + .../components/dialogs/TlaCookieConsent.tsx | 130 + .../dialogs/TlaDeleteFileDialog.tsx | 98 + .../dialogs/TlaInviteDialog.module.css | 61 + .../components/dialogs/TlaInviteDialog.tsx | 64 + .../dialogs/TlaInviteExpiredDialog.module.css | 35 + .../dialogs/TlaInviteExpiredDialog.tsx | 32 + .../components/dialogs/TlaLegalAcceptance.tsx | 77 + .../dialogs/TlaManageCookiesDialog.tsx | 74 + .../components/dialogs/TlaSignInDialog.tsx | 468 ++ .../dialogs/TlaTldrawOfflineFileDialog.tsx | 84 + .../dialogs/WorkspaceSettingsDialog.tsx | 558 +++ .../tla/components/dialogs/auth.module.css | 342 ++ .../tla/components/dialogs/dialogs.module.css | 345 ++ .../tla/components/menu-items/menu-items.tsx | 431 ++ .../tla/components/tla-menu/menu.module.css | 410 ++ .../src/tla/components/tla-menu/tla-menu.tsx | 347 ++ .../src/tla/hooks/getIsTldrawStaff.test.ts | 41 + .../src/tla/hooks/useActiveWorkspaceId.ts | 29 + .../src/tla/hooks/useAnalyticsConsent.tsx | 45 + .../client/src/tla/hooks/useAppState.tsx | 149 + .../src/tla/hooks/useCommentTracking.ts | 117 + .../client/src/tla/hooks/useCurrentFileId.ts | 6 + .../client/src/tla/hooks/useDeepLink.tsx | 24 + .../src/tla/hooks/useIsCommentingEnabled.ts | 16 + .../client/src/tla/hooks/useIsFileOwner.tsx | 10 + .../client/src/tla/hooks/useIsFilePinned.tsx | 11 + .../src/tla/hooks/useIsReady.module.css | 20 + .../client/src/tla/hooks/useIsReady.tsx | 43 + .../tla/hooks/useNewRoomCreationTracking.ts | 18 + .../tla/hooks/usePreventAccidentalDrops.ts | 20 + .../src/tla/hooks/useShareLinkOpenTracking.ts | 27 + .../src/tla/hooks/useSignUpTracking.test.ts | 44 + .../client/src/tla/hooks/useSignUpTracking.ts | 71 + .../client/src/tla/hooks/useTldrFileDrop.ts | 59 + .../dotcom/client/src/tla/hooks/useUITheme.ts | 123 + apps/dotcom/client/src/tla/hooks/useUser.tsx | 62 + .../layouts/TlaAnonLayout/TlaAnonLayout.tsx | 13 + .../tla/layouts/TlaAnonLayout/anon.module.css | 15 + .../TlaSidebarLayout/TlaSidebarLayout.tsx | 198 + .../sidebar-layout.module.css | 101 + .../src/tla/pages/file-history-snapshot.tsx | 87 + .../client/src/tla/pages/file-history.tsx | 96 + apps/dotcom/client/src/tla/pages/file.tsx | 61 + apps/dotcom/client/src/tla/pages/import.tsx | 39 + apps/dotcom/client/src/tla/pages/invite.tsx | 27 + .../src/tla/pages/legacy-history-snapshot.tsx | 87 + .../client/src/tla/pages/legacy-history.tsx | 64 + .../src/tla/pages/legacy-readonly-old.tsx | 4 + .../client/src/tla/pages/legacy-readonly.tsx | 4 + .../client/src/tla/pages/legacy-room.tsx | 70 + .../client/src/tla/pages/legacy-snapshot.tsx | 90 + .../client/src/tla/pages/local-file-index.tsx | 62 + .../client/src/tla/pages/local-file.tsx | 33 + apps/dotcom/client/src/tla/pages/local.tsx | 132 + apps/dotcom/client/src/tla/pages/publish.tsx | 32 + .../src/tla/pages/worker-debug-tail.tsx | 61 + .../src/tla/providers/RequireSignedInUser.tsx | 12 + .../src/tla/providers/RequireTldrawStaff.tsx | 14 + .../src/tla/providers/TlaRootProviders.tsx | 387 ++ apps/dotcom/client/src/tla/styles/tla.css | 275 ++ .../dotcom/client/src/tla/themes/ui-themes.ts | 1359 ++++++ .../src/tla/utils/FeatureFlagPoller.test.ts | 95 + .../src/tla/utils/FeatureFlagPoller.tsx | 113 + .../client/src/tla/utils/app-ui-events.tsx | 116 + apps/dotcom/client/src/tla/utils/auth.ts | 11 + apps/dotcom/client/src/tla/utils/copy.ts | 11 + apps/dotcom/client/src/tla/utils/dates.ts | 39 + .../client/src/tla/utils/getCurrentEditor.ts | 5 + .../src/tla/utils/getIsCoarsePointer.tsx | 5 + apps/dotcom/client/src/tla/utils/i18n.tsx | 118 + .../client/src/tla/utils/importFromUrl.ts | 44 + .../src/tla/utils/local-session-state.ts | 170 + .../client/src/tla/utils/notFoundError.ts | 3 + apps/dotcom/client/src/tla/utils/qrcode.ts | 12 + apps/dotcom/client/src/tla/utils/redirect.ts | 17 + .../client/src/tla/utils/session-storage.ts | 5 + .../client/src/tla/utils/slurping.test.ts | 90 + apps/dotcom/client/src/tla/utils/slurping.tsx | 245 + .../src/tla/utils/tldrawOfflineFiles.ts | 38 + apps/dotcom/client/src/utils/analytics.tsx | 427 ++ apps/dotcom/client/src/utils/assetUrls.ts | 35 + apps/dotcom/client/src/utils/config.ts | 30 + .../client/src/utils/consoleBranding.ts | 29 + .../client/src/utils/createAssetFromUrl.ts | 49 + apps/dotcom/client/src/utils/csp.ts | 84 + .../client/src/utils/defineLoader.test.tsx | 77 + apps/dotcom/client/src/utils/defineLoader.tsx | 41 + .../dotcom/client/src/utils/embedShapeUtil.ts | 9 + apps/dotcom/client/src/utils/env.ts | 35 + .../dotcom/client/src/utils/errorReporting.ts | 11 + apps/dotcom/client/src/utils/fetchHistory.ts | 23 + .../dotcom/client/src/utils/firstLoad.test.ts | 320 ++ apps/dotcom/client/src/utils/firstLoad.ts | 449 ++ apps/dotcom/client/src/utils/globalEditor.ts | 6 + apps/dotcom/client/src/utils/iFrame.ts | 16 + .../src/utils/multiplayerAssetStore.test.ts | 200 + .../client/src/utils/multiplayerAssetStore.ts | 150 + .../src/utils/scratch-persistence-key.ts | 27 + .../src/utils/shouldOverrideDocument.tsx | 57 + apps/dotcom/client/src/utils/url.ts | 3 + apps/dotcom/client/styles/globals.css | 300 ++ apps/dotcom/client/thumbnail-render.html | 33 + apps/dotcom/client/tsconfig.json | 35 + apps/dotcom/client/version.ts | 9 + apps/dotcom/client/vite.config.ts | 192 + apps/dotcom/client/vitest.config.ts | 36 + apps/dotcom/image-resize-worker/README.md | 27 + apps/dotcom/image-resize-worker/package.json | 31 + apps/dotcom/image-resize-worker/src/worker.ts | 145 + apps/dotcom/image-resize-worker/tsconfig.json | 11 + .../image-resize-worker/vitest.config.ts | 12 + apps/dotcom/image-resize-worker/wrangler.toml | 37 + apps/dotcom/mcp-server-auth.md | 298 ++ apps/dotcom/process-compose.yaml | 121 + apps/dotcom/restore-state.sh | 138 + apps/dotcom/snapshot-state.sh | 65 + apps/dotcom/sync-worker/.gitignore | 2 + apps/dotcom/sync-worker/README.md | 38 + apps/dotcom/sync-worker/dev.sh | 5 + apps/dotcom/sync-worker/package.json | 49 + apps/dotcom/sync-worker/src/Logger.ts | 45 + .../sync-worker/src/TLFileEffectProcessor.ts | 231 + .../sync-worker/src/TLLoggerDurableObject.ts | 67 + .../src/adminFeatureFlagRoutes.test.ts | 263 ++ apps/dotcom/sync-worker/src/adminRoutes.ts | 1199 +++++ .../sync-worker/src/assetAssociation.test.ts | 115 + .../sync-worker/src/assetAssociation.ts | 86 + .../src/authorizeFileRecord.test.ts | 211 + .../sync-worker/src/authorizeFileRecord.ts | 62 + .../sync-worker/src/commentRows.test.ts | 1203 +++++ apps/dotcom/sync-worker/src/commentRows.ts | 595 +++ apps/dotcom/sync-worker/src/config.ts | 266 ++ .../sync-worker/src/fileEffects.test.ts | 237 + apps/dotcom/sync-worker/src/fileEffects.ts | 64 + apps/dotcom/sync-worker/src/fileStats.test.ts | 342 ++ apps/dotcom/sync-worker/src/fileStats.ts | 274 ++ .../sync-worker/src/healthCheckRoutes.ts | 241 + .../src/mcpClusterIndexStorage.test.ts | 104 + .../sync-worker/src/mcpClusterIndexStorage.ts | 87 + .../sync-worker/src/outboxDrain.test.ts | 326 ++ apps/dotcom/sync-worker/src/outboxDrain.ts | 188 + apps/dotcom/sync-worker/src/postgres.ts | 199 + apps/dotcom/sync-worker/src/r2.ts | 111 + .../sync-worker/src/roomEffectHelpers.test.ts | 107 + .../sync-worker/src/roomEffectHelpers.ts | 92 + .../src/routes/extractBookmarkMetadata.tsx | 30 + .../src/routes/getDocumentNameFromSnapshot.ts | 27 + .../sync-worker/src/routes/getReadonlySlug.ts | 30 + .../src/routes/getRoomHistory.test.ts | 112 + .../sync-worker/src/routes/getRoomHistory.ts | 172 + .../src/routes/getRoomHistorySnapshot.test.ts | 136 + .../src/routes/getRoomHistorySnapshot.ts | 93 + .../sync-worker/src/routes/getRoomSnapshot.ts | 67 + .../src/routes/getSocialPreview.test.ts | 117 + .../src/routes/getSocialPreview.ts | 257 ++ .../src/routes/joinExistingRoom.ts | 26 + .../sync-worker/src/routes/submitFeedback.ts | 224 + .../src/routes/sweepVersionChains.test.ts | 281 ++ .../src/routes/sweepVersionChains.ts | 209 + .../src/routes/tla/acceptInvite.ts | 140 + .../src/routes/tla/boardTools.test.ts | 331 ++ .../sync-worker/src/routes/tla/boardTools.ts | 1068 +++++ .../sync-worker/src/routes/tla/createFiles.ts | 51 + .../src/routes/tla/evalsLocalMcp.test.ts | 160 + .../src/routes/tla/evalsLocalMcp.ts | 249 ++ .../src/routes/tla/forwardRoomRequest.ts | 17 + .../src/routes/tla/getFileSnapshot.ts | 37 + .../src/routes/tla/getInviteInfo.ts | 47 + .../src/routes/tla/getOgImage.test.ts | 468 ++ .../sync-worker/src/routes/tla/getOgImage.ts | 236 + .../src/routes/tla/getPublishedFile.ts | 78 + .../src/routes/tla/getSharedFile.test.ts | 140 + .../src/routes/tla/getSharedFile.ts | 96 + .../routes/tla/getThumbnailSnapshot.test.ts | 332 ++ .../src/routes/tla/getThumbnailSnapshot.ts | 108 + .../sync-worker/src/routes/tla/initUser.ts | 120 + .../src/routes/tla/mcpAuth.test.ts | 450 ++ .../sync-worker/src/routes/tla/mcpAuth.ts | 373 ++ .../src/routes/tla/mcpClusterIndex.test.ts | 211 + .../src/routes/tla/mcpClusterIndex.ts | 126 + .../src/routes/tla/mcpServer.test.ts | 2109 +++++++++ .../sync-worker/src/routes/tla/mcpServer.ts | 1464 ++++++ .../src/routes/tla/mcpServerCard.test.ts | 84 + .../src/routes/tla/mcpServerCard.ts | 88 + .../src/routes/tla/ogImageQueue.test.ts | 1328 ++++++ .../src/routes/tla/ogImageQueue.ts | 500 +++ .../tla/putThumbnailRenderResult.test.ts | 163 + .../routes/tla/putThumbnailRenderResult.ts | 111 + .../src/routes/tla/screenshotTestHelpers.ts | 315 ++ .../src/routes/tla/searchBoards.test.ts | 391 ++ .../src/routes/tla/searchBoards.ts | 330 ++ .../src/routes/tla/thumbnailRender.test.ts | 154 + .../src/routes/tla/thumbnailRender.ts | 928 ++++ .../src/routes/tla/thumbnailShared.test.ts | 204 + .../src/routes/tla/thumbnailShared.ts | 219 + .../sync-worker/src/routes/tla/uploads.ts | 40 + .../src/routes/verifyVersionChain.test.ts | 493 +++ .../src/routes/verifyVersionChain.ts | 258 ++ .../sync-worker/src/snapshotUtils.test.ts | 361 ++ apps/dotcom/sync-worker/src/snapshotUtils.ts | 225 + apps/dotcom/sync-worker/src/test/fakeR2.ts | 66 + apps/dotcom/sync-worker/src/testRoutes.ts | 150 + apps/dotcom/sync-worker/src/types.ts | 358 ++ .../sync-worker/src/undeleteFile.test.ts | 159 + apps/dotcom/sync-worker/src/undeleteFile.ts | 55 + .../dotcom/sync-worker/src/utils/analytics.ts | 34 + .../sync-worker/src/utils/base64.test.ts | 28 + apps/dotcom/sync-worker/src/utils/base64.ts | 41 + .../src/utils/createSupabaseClient.test.ts | 40 + .../src/utils/createSupabaseClient.ts | 26 + .../sync-worker/src/utils/durableObjects.ts | 27 + .../src/utils/featureFlags.test.ts | 430 ++ .../sync-worker/src/utils/featureFlags.ts | 286 ++ .../src/utils/getPublicOrigin.test.ts | 46 + .../sync-worker/src/utils/getPublicOrigin.ts | 31 + .../src/utils/getSnapshotsTable.ts | 10 + apps/dotcom/sync-worker/src/utils/hash.ts | 14 + .../sync-worker/src/utils/loadId.test.ts | 21 + apps/dotcom/sync-worker/src/utils/loadId.ts | 12 + .../src/utils/ogRenderDebounce.test.ts | 186 + .../sync-worker/src/utils/ogRenderDebounce.ts | 57 + .../src/utils/publishSnapshots.test.ts | 182 + .../sync-worker/src/utils/publishSnapshots.ts | 57 + .../dotcom/sync-worker/src/utils/rateLimit.ts | 6 + .../src/utils/renderTokens.test.ts | 638 +++ .../sync-worker/src/utils/renderTokens.ts | 478 ++ .../sync-worker/src/utils/roomIdIsTooLong.ts | 9 + .../sync-worker/src/utils/roomOpenMode.ts | 17 + .../utils/tarStreamReader-fixtures/README.md | 11 + .../directory-only.tar | Bin 0 -> 1536 bytes .../generate-fixtures.sh | 32 + .../tarStreamReader-fixtures/large-body.tar | Bin 0 -> 2560 bytes .../tarStreamReader-fixtures/multi-file.tar | Bin 0 -> 4608 bytes .../tarStreamReader-fixtures/single-file.tar | Bin 0 -> 2048 bytes .../tarStreamReader-fixtures/with-prefix.tar | Bin 0 -> 5632 bytes apps/dotcom/sync-worker/src/utils/throttle.ts | 19 + .../sync-worker/src/utils/tla/getAuth.test.ts | 75 + .../sync-worker/src/utils/tla/getAuth.ts | 198 + .../tla/getJoinableWorkspaceFromInvite.ts | 32 + .../src/utils/tla/getLegacyRoomData.ts | 32 + .../sync-worker/src/utils/tla/getRole.ts | 22 + .../src/utils/tla/hasReadAccessToFile.test.ts | 136 + .../src/utils/tla/hasWriteAccessToFile.ts | 27 + .../sync-worker/src/utils/tla/isTestFile.ts | 3 + .../sync-worker/src/utils/tla/permissions.ts | 7 + .../sync-worker/src/utils/validateSnapshot.ts | 53 + .../sync-worker/src/versionChain.test.ts | 337 ++ apps/dotcom/sync-worker/src/versionChain.ts | 243 + .../sync-worker/src/versionChainCodec.ts | 30 + .../src/versionChainConfig.test.ts | 75 + .../sync-worker/src/versionChainConfig.ts | 49 + .../src/versionChainDelete.test.ts | 25 + .../sync-worker/src/versionChainRead.test.ts | 622 +++ .../sync-worker/src/versionChainRead.ts | 341 ++ .../sync-worker/src/versionChainWrite.test.ts | 428 ++ .../sync-worker/src/versionChainWrite.ts | 172 + .../sync-worker/src/versionDelta.test.ts | 474 ++ apps/dotcom/sync-worker/src/versionDelta.ts | 230 + .../src/welcome/defaultWelcomeSnapshot.ts | 63 + .../welcome/resolveWelcomeSnapshot.test.ts | 126 + .../src/welcome/resolveWelcomeSnapshot.ts | 54 + .../sync-worker/src/welcome/welcome.test.ts | 101 + .../sync-worker/src/worker.exports.test.ts | 19 + apps/dotcom/sync-worker/src/worker.ts | 446 ++ .../sync-worker/src/zero/ZMutationError.ts | 11 + apps/dotcom/sync-worker/tsconfig.json | 19 + apps/dotcom/sync-worker/vitest.config.ts | 24 + apps/dotcom/sync-worker/wrangler.toml | 731 +++ .../tldrawusercontent-worker/.gitignore | 1 + .../tldrawusercontent-worker/package.json | 28 + .../tldrawusercontent-worker/src/types.ts | 22 + .../tldrawusercontent-worker/src/worker.ts | 94 + .../tldrawusercontent-worker/tsconfig.json | 7 + .../tldrawusercontent-worker/wrangler.toml | 88 + apps/dotcom/user-manual.md | 520 +++ apps/dotcom/workspaces-feature.md | 491 ++ apps/dotcom/zero-cache/.env | 12 + apps/dotcom/zero-cache/.gitignore | 12 + apps/dotcom/zero-cache/Dockerfile.template | 14 + .../zero-cache/delete_file_states.test.ts | 256 ++ .../zero-cache/docker/docker-compose.yml | 53 + apps/dotcom/zero-cache/docker/pgbouncer.ini | 21 + .../zero-cache/docker/postgres-logging.conf | 844 ++++ apps/dotcom/zero-cache/docker/userlist.txt | 1 + apps/dotcom/zero-cache/effect_outbox.test.ts | 260 ++ .../flyio-replication-manager.template.toml | 47 + .../flyio-view-syncer.template.toml | 54 + apps/dotcom/zero-cache/flyio.template.toml | 46 + apps/dotcom/zero-cache/migrate.ts | 201 + apps/dotcom/zero-cache/migrationSql.test.ts | 57 + apps/dotcom/zero-cache/migrationSql.ts | 18 + .../dotcom/zero-cache/migrations/000_seed.sql | 72 + .../migrations/001_replicator_boot.sql | 4 + .../zero-cache/migrations/002_add_user_id.sql | 9 + .../003_make_published_slug_unique.sql | 4 + .../004_guest_column_on_file_state.sql | 38 + .../migrations/005_update_file_trigger.sql | 18 + .../migrations/006_add_file_soft_delete.sql | 4 + .../007_update_file_owner_details.sql | 52 + .../zero-cache/migrations/008_add_pinned.sql | 4 + .../009_add_allow_analytics_cookie.sql | 8 + .../migrations/010_add_asset_info.sql | 8 + .../migrations/011_file_creation_column.sql | 5 + .../migrations/012_prevent_deadlocks.sql | 24 + .../migrations/013_add_userid_to_file_key.sql | 17 + .../014_add_publishedSlug_to_file_key.sql | 5 + .../migrations/015_full_replicas.sql | 1 + .../migrations/016_zero_publication.sql | 1 + .../017_associated_users_with_assets.sql | 7 + .../018_file_state_replica_identity_all.sql | 3 + .../019_add_keyboard_shortcuts_pref.sql | 8 + .../020_add_show_ui_labels_pref.sql | 8 + .../021_rename_show_ui_labels_pref.sql | 4 + .../022_add_input_mode_preference.sql | 5 + .../zero-cache/migrations/023_groups.sql | 451 ++ .../zero-cache/migrations/024_add_fairies.sql | 15 + .../migrations/025_fairy_gating.sql | 13 + .../migrations/026_fairy_usage_tracking.sql | 2 + .../migrations/027_add_fairy_messages.sql | 13 + .../027_fairy_invite_description.sql | 3 + .../028_add_paddle_transactions.sql | 21 + .../migrations/029_fairy_weekly_limit.sql | 2 + .../030_add_zoom_direction_preference.sql | 5 + .../migrations/031_group_id_indexes.sql | 2 + .../migrations/032_enable_ddl_detection.sql | 11 + .../033_rename_group_admin_role_to_member.sql | 13 + .../034_fix_unshare_group_file_cleanup.sql | 58 + .../migrations/035_welcome_template.sql | 14 + .../migrations/036_home_group_renameable.sql | 29 + .../037_add_group_invite_link_enabled.sql | 2 + .../038_cleanup_orphan_group_file_links.sql | 65 + .../039_tighten_group_file_association.sql | 37 + .../migrations/040_add_comments.sql | 115 + .../migrations/041_add_comment_read.sql | 20 + .../migrations/042_add_comment_mention.sql | 31 + .../migrations/043_add_comment_reactions.sql | 43 + .../migrations/044_file_visitor.sql | 97 + .../045_add_comment_reaction_user_name.sql | 52 + .../046_stamp_comment_created_at.sql | 24 + .../migrations/047_effect_outbox.sql | 53 + .../migrations/048_effect_outbox_retry_at.sql | 4 + .../049_drop_legacy_sync_tables.sql | 11 + .../050_drop_legacy_owner_columns.sql | 179 + .../051_effect_outbox_last_error.sql | 4 + .../migrations/052_file_search_index.sql | 31 + apps/dotcom/zero-cache/nginx.conf.template | 90 + apps/dotcom/zero-cache/package.json | 33 + .../stamp_comment_created_at.test.ts | 232 + apps/dotcom/zero-cache/start.sh | 38 + apps/dotcom/zero-cache/supervisord.conf | 23 + apps/dotcom/zero-cache/tsconfig.json | 23 + .../validateMigrationFilenames.test.ts | 43 + .../zero-cache/validateMigrationFilenames.ts | 64 + apps/dotcom/zero-cache/vitest.config.ts | 12 + apps/examples/.gitignore | 3 + apps/examples/LICENSE.md | 9 + apps/examples/README.md | 29 + apps/examples/e2e-device/helpers/app.ts | 44 + apps/examples/e2e-device/helpers/pinch.ts | 118 + apps/examples/e2e-device/helpers/stroke.ts | 70 + .../tests/draw-pressure-encoding.e2e.ts | 78 + apps/examples/e2e-device/tests/pinch.e2e.ts | 49 + apps/examples/e2e-device/tsconfig.json | 9 + apps/examples/e2e-device/wdio.android.conf.ts | 22 + apps/examples/e2e-device/wdio.ios.conf.ts | 48 + apps/examples/e2e-device/wdio.shared.conf.ts | 58 + .../examples/e2e/baselines/fps-baselines.json | 146 + .../e2e/fixtures/analytics-reporter.ts | 178 + .../examples/e2e/fixtures/baseline-manager.ts | 261 ++ apps/examples/e2e/fixtures/fixtures.ts | 110 + apps/examples/e2e/fixtures/fps-tracker.ts | 155 + .../e2e/fixtures/heavy-board-generator.ts | 304 ++ .../e2e/fixtures/menus/ActionsMenu.ts | 42 + apps/examples/e2e/fixtures/menus/HelpMenu.ts | 34 + apps/examples/e2e/fixtures/menus/MainMenu.ts | 62 + .../e2e/fixtures/menus/MenuClickCapture.ts | 10 + .../e2e/fixtures/menus/NavigationPanel.ts | 21 + apps/examples/e2e/fixtures/menus/PageMenu.ts | 27 + .../e2e/fixtures/menus/RichTextToolbar.ts | 60 + .../examples/e2e/fixtures/menus/StylePanel.ts | 88 + apps/examples/e2e/fixtures/menus/Toolbar.ts | 45 + apps/examples/e2e/fixtures/perf-utils.ts | 645 +++ apps/examples/e2e/global-setup.ts | 7 + apps/examples/e2e/global-teardown.ts | 8 + .../test-mermaid-readability.spec.ts | 161 + apps/examples/e2e/perf/test-perf.spec.ts | 202 + apps/examples/e2e/playwright.config.ts | 122 + apps/examples/e2e/shared-e2e.ts | 163 + apps/examples/e2e/tests/README-PERFORMANCE.md | 38 + .../tests/export-mermaid-snapshots.spec.ts | 90 + ...wchart-decision-light-1-chromium-linux.png | Bin 0 -> 49792 bytes ...with-class-defs-light-1-chromium-linux.png | Bin 0 -> 32112 bytes ...tom-edge-styles-light-1-chromium-linux.png | Bin 0 -> 25431 bytes ...-with-subgraphs-light-1-chromium-linux.png | Bin 0 -> 28665 bytes ...-diagram-basics-light-1-chromium-linux.png | Bin 0 -> 30487 bytes ...iagram-with-alt-light-1-chromium-linux.png | Bin 0 -> 38580 bytes ...-parallel-lanes-light-1-chromium-linux.png | Bin 0 -> 62222 bytes ...e-diagram-basic-light-1-chromium-linux.png | Bin 0 -> 12620 bytes ...-with-fork-join-light-1-chromium-linux.png | Bin 0 -> 41305 bytes ...th-nested-state-light-1-chromium-linux.png | Bin 0 -> 50290 bytes .../e2e/tests/export-snapshots-data.tsx | 582 +++ .../e2e/tests/export-snapshots.spec.tsx | 1225 +++++ ...hots-Arrows-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 22304 bytes ...snapshots-Arrows-dark-1-chromium-linux.png | Bin 0 -> 22304 bytes ...ots-Arrows-light-1-Mobile-Chrome-linux.png | Bin 0 -> 20385 bytes ...napshots-Arrows-light-1-chromium-linux.png | Bin 0 -> 20385 bytes ...shots-Fills-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 72616 bytes ...-snapshots-Fills-dark-1-chromium-linux.png | Bin 0 -> 72616 bytes ...hots-Fills-light-1-Mobile-Chrome-linux.png | Bin 0 -> 61081 bytes ...snapshots-Fills-light-1-chromium-linux.png | Bin 0 -> 61081 bytes ...shots-Fonts-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 53113 bytes ...-snapshots-Fonts-dark-1-chromium-linux.png | Bin 0 -> 53113 bytes ...hots-Fonts-light-1-Mobile-Chrome-linux.png | Bin 0 -> 49382 bytes ...snapshots-Fonts-light-1-chromium-linux.png | Bin 0 -> 49382 bytes ...ign-objects-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 126307 bytes ...-Foreign-objects-dark-1-chromium-linux.png | Bin 0 -> 127411 bytes ...gn-objects-light-1-Mobile-Chrome-linux.png | Bin 0 -> 124657 bytes ...Foreign-objects-light-1-chromium-linux.png | Bin 0 -> 126040 bytes ...hots-Frames-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 68867 bytes ...snapshots-Frames-dark-1-chromium-linux.png | Bin 0 -> 68499 bytes ...ots-Frames-light-1-Mobile-Chrome-linux.png | Bin 0 -> 65494 bytes ...napshots-Frames-light-1-chromium-linux.png | Bin 0 -> 65366 bytes ...s-Geo-flips-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 120478 bytes ...pshots-Geo-flips-dark-1-chromium-linux.png | Bin 0 -> 120478 bytes ...-Geo-flips-light-1-Mobile-Chrome-linux.png | Bin 0 -> 110744 bytes ...shots-Geo-flips-light-1-chromium-linux.png | Bin 0 -> 110744 bytes ...hots-Images-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 81757 bytes ...snapshots-Images-dark-1-chromium-linux.png | Bin 0 -> 81757 bytes ...ots-Images-light-1-Mobile-Chrome-linux.png | Bin 0 -> 79567 bytes ...napshots-Images-light-1-chromium-linux.png | Bin 0 -> 79567 bytes ...Regressions-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 42246 bytes ...hots-Regressions-dark-1-chromium-linux.png | Bin 0 -> 42246 bytes ...egressions-light-1-Mobile-Chrome-linux.png | Bin 0 -> 38972 bytes ...ots-Regressions-light-1-chromium-linux.png | Bin 0 -> 38972 bytes ...t-alignment-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 42180 bytes ...s-Text-alignment-dark-1-chromium-linux.png | Bin 0 -> 42180 bytes ...-alignment-light-1-Mobile-Chrome-linux.png | Bin 0 -> 35149 bytes ...-Text-alignment-light-1-chromium-linux.png | Bin 0 -> 35149 bytes ...t-rendering-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 79523 bytes ...s-Text-rendering-dark-1-chromium-linux.png | Bin 0 -> 79523 bytes ...-rendering-light-1-Mobile-Chrome-linux.png | Bin 0 -> 69185 bytes ...-Text-rendering-light-1-chromium-linux.png | Bin 0 -> 69185 bytes ...lbow-arrows-dark-1-Mobile-Chrome-linux.png | Bin 0 -> 107773 bytes ...ird-elbow-arrows-dark-1-chromium-linux.png | Bin 0 -> 107773 bytes ...bow-arrows-light-1-Mobile-Chrome-linux.png | Bin 0 -> 99199 bytes ...rd-elbow-arrows-light-1-chromium-linux.png | Bin 0 -> 99199 bytes .../test-a11y-style-panel-navigation.spec.ts | 328 ++ .../e2e/tests/test-actions-menu.spec.ts | 20 + apps/examples/e2e/tests/test-api.spec.ts | 21 + apps/examples/e2e/tests/test-camera.spec.ts | 256 ++ .../e2e/tests/test-canvas-events.spec.ts | 153 + .../e2e/tests/test-clipboard-events.spec.ts | 270 ++ .../examples/e2e/tests/test-clipboard.spec.ts | 104 + .../e2e/tests/test-commenting-a11y.spec.ts | 219 + .../e2e/tests/test-context-menu.spec.ts | 298 ++ apps/examples/e2e/tests/test-dialogs.spec.ts | 134 + apps/examples/e2e/tests/test-focus.spec.ts | 298 ++ .../e2e/tests/test-image-toolbar.spec.ts | 248 ++ apps/examples/e2e/tests/test-kbds.spec.ts | 891 ++++ .../examples/e2e/tests/test-licensing.spec.ts | 182 + .../examples/e2e/tests/test-main-menu.spec.ts | 44 + .../e2e/tests/test-navigation-panel.spec.ts | 33 + .../e2e/tests/test-overlay-snapshots.spec.ts | 261 ++ ...apshots-brush-overlay-1-chromium-linux.png | Bin 0 -> 25869 bytes ...hots-scribble-overlay-1-chromium-linux.png | Bin 0 -> 28155 bytes ...round-multiple-shapes-1-chromium-linux.png | Bin 0 -> 37248 bytes ...eground-rotated-shape-1-chromium-linux.png | Bin 0 -> 44138 bytes ...reground-single-shape-1-chromium-linux.png | Bin 0 -> 30013 bytes ...ndles-arrow-endpoints-1-chromium-linux.png | Bin 0 -> 30149 bytes ...hovered-center-handle-1-chromium-linux.png | Bin 0 -> 27198 bytes ...hovered-center-handle-2-chromium-linux.png | Bin 0 -> 27972 bytes ...es-line-with-vertices-1-chromium-linux.png | Bin 0 -> 28578 bytes ...r-overlay-point-snaps-1-chromium-linux.png | Bin 0 -> 26207 bytes ...ts-zoom-brush-overlay-1-chromium-linux.png | Bin 0 -> 25869 bytes .../examples/e2e/tests/test-page-menu.spec.ts | 685 +++ .../tests/test-paste-text-measurement.spec.ts | 57 + .../e2e/tests/test-pointer-cancel.spec.ts | 163 + .../e2e/tests/test-rich-text-toolbar.spec.ts | 562 +++ .../examples/e2e/tests/test-rich-text.spec.ts | 65 + apps/examples/e2e/tests/test-routes.spec.ts | 44 + .../e2e/tests/test-rtl-text-alignment.spec.ts | 160 + apps/examples/e2e/tests/test-shapes.spec.ts | 158 + apps/examples/e2e/tests/test-smoke.spec.ts | 126 + .../e2e/tests/test-style-panel.spec.ts | 159 + .../e2e/tests/test-text-export-ink.spec.ts | 211 + .../jiffy-italic-export-chromium-linux.png | Bin 0 -> 16891 bytes ...jiffy-italic-svg-export-chromium-linux.png | Bin 0 -> 7805 bytes apps/examples/e2e/tests/test-text.spec.ts | 409 ++ apps/examples/e2e/tests/test-toolbar.spec.ts | 137 + .../e2e/tests/test-video-toolbar.spec.ts | 126 + apps/examples/package.json | 108 + apps/examples/public/ComicMono.woff | Bin 0 -> 14640 bytes apps/examples/public/connect-node.svg | 14 + apps/examples/public/custom-arrow-icon.svg | 4 + apps/examples/public/geo-cross.svg | 3 + apps/examples/public/geo-rounded-rect.svg | 3 + apps/examples/public/glob-icon.svg | 10 + apps/examples/public/heart-icon.svg | 3 + apps/examples/public/icons/discord.svg | 12 + apps/examples/public/icons/github.svg | 3 + apps/examples/public/icons/twitter.svg | 4 + apps/examples/public/man.png | Bin 0 -> 23101 bytes apps/examples/public/node-icon.svg | 4 + apps/examples/public/shadow-man.png | Bin 0 -> 24390 bytes apps/examples/public/speech-bubble.svg | 3 + apps/examples/public/tldraw.png | Bin 0 -> 64367 bytes apps/examples/public/tldraw_dev_dark.png | Bin 0 -> 22845 bytes apps/examples/public/tldraw_dev_dark.svg | 27 + apps/examples/public/tldraw_dev_light.png | Bin 0 -> 23387 bytes apps/examples/public/tldraw_dev_light.svg | 27 + apps/examples/public/tool-screenshot.svg | 5 + apps/examples/src/ExamplePage.tsx | 514 +++ apps/examples/src/ExampleWrapper.tsx | 143 + apps/examples/src/examples.tsx | 67 + .../comment-anchors/CommentAnchorsExample.tsx | 118 + .../collaboration/comment-anchors/README.md | 16 + .../CommentClusteringExample.tsx | 98 + .../comment-clustering/README.md | 16 + .../comment-clustering/comment-clustering.css | 13 + .../CommentDrawingReactionsExample.tsx | 115 + .../comment-drawing-reactions/README.md | 18 + .../comment-drawing-reactions.css | 116 + .../drawing-reactions.tsx | 550 +++ .../comment-history/CommentHistoryExample.tsx | 182 + .../collaboration/comment-history/README.md | 16 + .../comment-history/comment-history.css | 34 + .../CommentNotificationsExample.tsx | 404 ++ .../comment-notifications/README.md | 17 + .../comment-notifications.css | 134 + .../comment-regions/CommentRegionsExample.tsx | 112 + .../collaboration/comment-regions/README.md | 14 + .../CommentShapePrecisionExample.tsx | 133 + .../comment-shape-precision/README.md | 14 + .../comment-shape-precision.css | 11 + .../CommentingMobileExample.tsx | 82 + .../collaboration/commenting-mobile/README.md | 28 + .../CommentingSidebarExample.tsx | 175 + .../commenting-sidebar/README.md | 16 + .../commenting/CommentingExample.tsx | 77 + .../collaboration/commenting/README.md | 16 + .../sync-custom-people-menu/README.md | 26 + .../SyncCustomPeopleMenuExample.tsx | 84 + .../sync-custom-people-menu.css | 73 + .../sync-custom-presence/README.md | 25 + .../SyncCustomPresence.tsx | 71 + .../sync-custom-shape/CounterShape.tsx | 72 + .../collaboration/sync-custom-shape/README.md | 16 + .../SyncDemoShapeExample.tsx | 26 + .../collaboration/sync-custom-shape/ui.tsx | 37 + .../collaboration/sync-demo/README.md | 15 + .../sync-demo/SyncDemoExample.tsx | 12 + .../sync-private-content/README.md | 27 + .../SyncPrivateContentExample.tsx | 173 + .../sync-private-content/Toggle.tsx | 43 + .../sync-private-content/style.css | 24 + .../collaboration/user-presence/README.md | 25 + .../user-presence/UserPresenceExample.tsx | 91 + .../ArrowsPreciseExactExample.tsx | 16 + .../arrows-precise-exact/README.md | 17 + .../asset-props/AssetPropsExample.tsx | 19 + .../configuration/asset-props/README.md | 29 + .../camera-options/CameraOptionsExample.tsx | 505 +++ .../configuration/camera-options/README.md | 27 + .../ConfigureShapeUtilExample.tsx | 15 + .../configure-shape-util/README.md | 25 + .../custom-embed/CustomEmbedExample.tsx | 102 + .../configuration/custom-embed/README.md | 28 + .../custom-options/CustomOptionsExample.tsx | 15 + .../configuration/custom-options/README.md | 14 + .../CustomTextOutlineExample.tsx | 51 + .../custom-text-outline/README.md | 28 + .../deep-links/DeepLinksExample.tsx | 10 + .../configuration/deep-links/README.md | 127 + .../disable-pages/DisablePagesExample.tsx | 10 + .../configuration/disable-pages/README.md | 14 + .../display-options/DisplayOptionsExample.tsx | 76 + .../configuration/display-options/README.md | 16 + .../edge-scrolling/EdgeScrollingExample.tsx | 149 + .../configuration/edge-scrolling/README.md | 19 + .../edge-scrolling/edge-scrolling.css | 44 + .../EmbedPermissionsExample.tsx | 163 + .../configuration/embed-permissions/README.md | 19 + .../EnvironmentDetectionExample.tsx | 73 + .../environment-detection/README.md | 28 + .../environment-detection.css | 7 + .../exploded/ExplodedExample.tsx | 108 + .../examples/configuration/exploded/README.md | 24 + .../frame-colors/FrameColorsExample.tsx | 12 + .../configuration/frame-colors/README.md | 14 + .../only-editor/MicroSelectTool.ts | 92 + .../only-editor/MiniBoxShape.tsx | 62 + .../only-editor/MiniSelectTool.ts | 169 + .../only-editor/OnlyEditorExample.tsx | 56 + .../configuration/only-editor/README.md | 17 + .../persistence-key/PersistenceKeyExample.tsx | 10 + .../configuration/persistence-key/README.md | 17 + .../examples/configuration/readonly/README.md | 23 + .../readonly/ReadOnlyExample.tsx | 15 + .../configuration/reduced-motion/README.md | 29 + .../reduced-motion/ReducedMotionExample.tsx | 141 + .../reduced-motion/reduced-motion.css | 59 + .../configuration/resize-note/README.md | 24 + .../resize-note/ResizeNoteExample.tsx | 12 + .../ClipboardEventsExample.tsx | 275 ++ .../data/assets/clipboard-events/README.md | 18 + .../clipboard-events/clipboard-events.css | 43 + .../CustomAssetTypeExample.tsx | 281 ++ .../data/assets/custom-asset-type/README.md | 14 + .../custom-paste/CustomPasteExample.tsx | 106 + .../data/assets/custom-paste/README.md | 14 + .../custom-records/CustomRecordsExample.tsx | 206 + .../data/assets/custom-records/README.md | 14 + .../assets/custom-records/custom-records.css | 25 + .../ExportCanvasImageExample.tsx | 54 + .../assets/export-canvas-as-image/README.md | 14 + .../ExportCanvasImageSettingsExample.tsx | 177 + .../assets/export-canvas-settings/README.md | 29 + .../ExternalContentSourcesExample.tsx | 110 + .../assets/external-content-sources/README.md | 26 + .../hosted-images/HostedImagesExample.tsx | 61 + .../data/assets/hosted-images/README.md | 26 + .../local-storage/LocalStorageExample.tsx | 103 + .../data/assets/local-storage/README.md | 26 + .../assets/meta-migrations/MetaMigrations.tsx | 78 + .../data/assets/meta-migrations/README.md | 26 + .../data/assets/meta-migrations/snapshot.ts | 57 + .../assets/meta-migrations/ui-overrides.tsx | 55 + .../data/assets/static-assets/README.md | 15 + .../static-assets/StaticAssetsExample.tsx | 33 + .../AlignAndDistributeShapesExample.tsx | 161 + .../align-and-distribute-shapes/README.md | 25 + .../align-and-distribute-shapes.css | 6 + .../examples/editor-api/api/APIExample.tsx | 135 + .../src/examples/editor-api/api/README.md | 14 + .../arrow-labels/ArrowLabelsExample.tsx | 163 + .../editor-api/arrow-labels/README.md | 27 + .../ConditionalCullingExample.tsx | 115 + .../editor-api/conditional-culling/README.md | 16 + .../conditional-culling.css | 27 + .../CoordinateSystemExample.tsx | 167 + .../editor-api/coordinate-system/README.md | 35 + .../coordinate-system/coordinate-system.css | 57 + .../create-arrow/CreateArrowExample.tsx | 137 + .../editor-api/create-arrow/README.md | 26 + .../CircleClipShapeTool.tsx | 21 + .../CircleClipShapeUtil.tsx | 165 + .../custom-clipping-shape/CustomClipping.css | 7 + .../CustomClippingExample.tsx | 169 + .../custom-clipping-shape/README.md | 25 + .../custom-overlay/CustomOverlayExample.tsx | 46 + .../custom-overlay/PointerRingOverlayUtil.ts | 36 + .../editor-api/custom-overlay/README.md | 14 + .../dimensions-hud/DimensionsHudExample.tsx | 40 + .../DimensionsHudOverlayUtil.ts | 190 + .../editor-api/dimensions-hud/README.md | 14 + .../dynamic-tools/DynamicToolsExample.tsx | 170 + .../editor-api/dynamic-tools/README.md | 15 + .../dynamic-tools/dynamic-tools.css | 11 + .../EasterEggStylesExample.tsx | 109 + .../editor-api/easter-egg-styles/README.md | 20 + .../editor-focus/EditorFocusExample.tsx | 67 + .../editor-api/editor-focus/README.md | 14 + .../editor-api/editor-focus/editor-focus.css | 20 + .../focus-mode/FocusModeExample.tsx | 22 + .../examples/editor-api/focus-mode/README.md | 12 + .../hovered-overlay/HoveredOverlayExample.tsx | 68 + .../editor-api/hovered-overlay/README.md | 12 + .../hovered-overlay/hovered-overlay.css | 38 + .../InteractionEndExample.tsx | 72 + .../interaction-end-callback/README.md | 26 + .../lasso-select-tool/LassoOverlayUtil.ts | 52 + .../lasso-select-tool/LassoSelectTool.ts | 155 + .../LassoSelectToolExample.tsx | 88 + .../editor-api/lasso-select-tool/README.md | 29 + .../local-images/LocalImagesExample.tsx | 66 + .../editor-api/local-images/README.md | 14 + .../local-videos/LocalVideosExample.tsx | 47 + .../editor-api/local-videos/README.md | 12 + .../LockCameraZoomExample.tsx | 38 + .../editor-api/lock-camera-zoom/README.md | 25 + .../locked-shapes/LockedShapesExample.tsx | 137 + .../editor-api/locked-shapes/README.md | 29 + .../locked-shapes/locked-shapes.css | 15 + .../PerformanceHooksExample.tsx | 164 + .../editor-api/performance-hooks/README.md | 17 + .../performance-hooks/performance-hooks.css | 46 + .../editor-api/reactive-inputs/README.md | 27 + .../reactive-inputs/ReactiveInputsExample.tsx | 164 + .../reactive-inputs/reactive-inputs.css | 61 + .../DashedBrushOverlayUtil.ts | 20 + .../replace-brush-overlay/README.md | 14 + .../ReplaceBrushOverlayExample.tsx | 32 + .../editor-api/selection-bounds/README.md | 23 + .../SelectionBoundsExample.tsx | 225 + .../selection-bounds/selection-bounds.css | 50 + .../editor-api/shape-animation/README.md | 14 + .../shape-animation/ShapeAnimationExample.tsx | 169 + .../shape-animation/shape-animation.css | 5 + .../examples/editor-api/snapshots/README.md | 27 + .../editor-api/snapshots/SnapshotExample.tsx | 85 + .../editor-api/snapshots/snapshot.json | 1216 +++++ .../editor-api/snapshots/snapshots.css | 23 + .../examples/editor-api/text-search/README.md | 26 + .../text-search/TextSearchExample.tsx | 47 + .../text-search/TextSearchPanel.tsx | 88 + .../editor-api/text-search/text-search.css | 26 + .../src/examples/editor-api/z-order/README.md | 20 + .../editor-api/z-order/ZOrderExample.tsx | 82 + .../examples/editor-api/z-order/z-order.css | 6 + .../editor-api/zoom-to-bounds/README.md | 12 + .../zoom-to-bounds/ZoomToBoundsExample.tsx | 78 + .../zoom-to-bounds/zoom-to-bounds.css | 6 + .../AfterCreateUpdateShapeExample.tsx | 96 + .../after-create-update-shape/README.md | 28 + .../AfterDeleteShapeExample.tsx | 57 + .../events/after-delete-shape/README.md | 27 + .../BeforeCreateUpdateShapeExample.tsx | 72 + .../before-create-update-shape/README.md | 30 + .../BeforeDeleteShapeExample.tsx | 45 + .../events/before-delete-shape/README.md | 27 + .../canvas-events/CanvasEventsExample.tsx | 61 + .../examples/events/canvas-events/README.md | 29 + .../events/canvas-events/canvas-events.css | 22 + .../CustomDoubleClickBehaviorExample.tsx | 52 + .../custom-double-click-behavior/README.md | 37 + .../derived-view/DerivedViewExample.tsx | 122 + .../examples/events/derived-view/README.md | 21 + .../event-blocker/EventBlockerExample.tsx | 55 + .../examples/events/event-blocker/README.md | 18 + .../events/event-blocker/event-blocker.css | 20 + .../OnChangeShapeMetaExample.tsx | 85 + .../examples/events/meta-on-change/README.md | 30 + .../OnCreateShapeMetaExample.tsx | 69 + .../examples/events/meta-on-create/README.md | 18 + .../permissions-2/PermissionsExample2.tsx | 99 + .../examples/events/permissions-2/README.md | 32 + .../events/permissions/PermissionsExample.tsx | 92 + .../src/examples/events/permissions/README.md | 33 + .../PreventInstanceChangeExample.tsx | 22 + .../events/prevent-instance-change/README.md | 29 + .../PreventMultiShapeSelectionExample.tsx | 26 + .../prevent-multi-shape-selection/README.md | 29 + .../PreventShapeChangeExample.tsx | 43 + .../events/prevent-shape-change/README.md | 31 + .../src/examples/events/signals/README.md | 21 + .../events/signals/StateStoreExample.tsx | 78 + .../examples/events/store-events/README.md | 32 + .../store-events/StoreEventsExample.tsx | 98 + .../events/store-events/store-events.css | 21 + .../src/examples/events/ui-events/README.md | 30 + .../events/ui-events/UiEventsExample.tsx | 54 + .../examples/events/ui-events/codeSnippets.ts | 146 + .../examples/events/ui-events/ui-events.css | 26 + .../examples/events/unsaved-changes/README.md | 32 + .../unsaved-changes/UnsavedChangesExample.tsx | 96 + .../getting-started/basic/BasicExample.tsx | 10 + .../examples/getting-started/basic/README.md | 27 + .../layout/external-dialog/ExternalDialog.tsx | 20 + .../examples/layout/external-dialog/README.md | 14 + .../external-dialog/external-dialog.css | 4 + .../ExternalUiContextExample.tsx | 96 + .../layout/external-ui-context/README.md | 27 + .../external-ui-context/external-ui.css | 20 + .../layout/external-ui/ExternalUiExample.tsx | 79 + .../src/examples/layout/external-ui/README.md | 31 + .../layout/external-ui/external-ui.css | 20 + .../examples/layout/image-component/README.md | 26 + .../image-component/TldrawImageExample.tsx | 117 + .../layout/image-component/snapshot.json | 454 ++ .../layout/inline-behavior/InlineBehavior.tsx | 124 + .../examples/layout/inline-behavior/README.md | 33 + .../examples/layout/inline/InlineExample.tsx | 26 + .../src/examples/layout/inline/README.md | 14 + .../inset-canvas/InsetCanvasExample.tsx | 11 + .../examples/layout/inset-canvas/README.md | 14 + .../layout/inset-canvas/inset-canvas.css | 6 + .../examples/layout/inset/InsetExample.tsx | 12 + .../src/examples/layout/inset/README.md | 14 + .../layout/multiple/MultipleExample.tsx | 221 + .../src/examples/layout/multiple/README.md | 14 + .../src/examples/layout/scroll/README.md | 14 + .../examples/layout/scroll/ScrollExample.tsx | 27 + .../tools/ag-grid-shape/DataGridExample.tsx | 129 + .../shapes/tools/ag-grid-shape/README.md | 28 + .../ArrowBindingOptionsExample.tsx | 192 + .../tools/arrow-binding-options/README.md | 28 + .../BoundsSnappingShape.tsx | 63 + .../PlayingCardShape/playing-card-tool.tsx | 15 + .../PlayingCardShape/playing-card-util.tsx | 148 + .../tools/bounds-snapping-shape/README.md | 26 + .../tools/bounds-snapping-shape/snapshot.json | 110 + .../bounds-snapping-shape/ui-overrides.tsx | 51 + .../BezierShapeHandleOverlayUtil.ts | 23 + .../cubic-bezier-shape/CubicBezierShape.tsx | 389 ++ .../CubicBezierShapeExample.tsx | 291 ++ .../shapes/tools/cubic-bezier-shape/README.md | 29 + .../SneakyUndoRedoWhileEditing.tsx | 30 + .../custom-config/CardShape/CardShapeTool.tsx | 14 + .../custom-config/CardShape/CardShapeUtil.tsx | 151 + .../CardShape/card-shape-migrations.ts | 25 + .../CardShape/card-shape-props.ts | 11 + .../custom-config/CustomConfigExample.tsx | 43 + .../shapes/tools/custom-config/README.md | 29 + .../tools/custom-config/ui-overrides.tsx | 61 + .../CustomGeoTypesExample.tsx | 190 + .../shapes/tools/custom-geo-types/README.md | 16 + .../CustomRelativeSnappingExample.tsx | 254 ++ .../tools/custom-relative-snapping/README.md | 27 + .../CustomShapeWrapperExample.tsx | 113 + .../tools/custom-shape-wrapper/README.md | 26 + .../custom-shape-wrapper.css | 3 + .../tools/custom-shape/CustomShapeExample.tsx | 159 + .../shapes/tools/custom-shape/README.md | 26 + .../tools/custom-tool/CustomToolExample.tsx | 81 + .../shapes/tools/custom-tool/README.md | 15 + .../CustomValidatorsExample.tsx | 132 + .../shapes/tools/custom-validators/README.md | 30 + .../drag-and-drop/DragAndDropExample.tsx | 181 + .../shapes/tools/drag-and-drop/README.md | 25 + .../drop-zone-shape/DropZoneShapeExample.tsx | 29 + .../shapes/tools/drop-zone-shape/README.md | 14 + .../drop-zone-shape/drop-zone-shape-util.tsx | 90 + .../tools/drop-zone-shape/drop-zone-shape.css | 25 + .../editable-shape/EditableShapeExample.tsx | 33 + .../editable-shape/EditableShapeUtil.tsx | 132 + .../shapes/tools/editable-shape/README.md | 16 + .../flex-layout/FlexContainerHelpers.tsx | 237 + .../tools/flex-layout/FlexLayoutExample.tsx | 847 ++++ .../shapes/tools/flex-layout/README.md | 16 + .../shapes/tools/flex-layout/flex-layout.css | 49 + .../tools/frame-layouts/BoardLayouts.ts | 161 + .../frame-layouts/FrameLayoutsExample.tsx | 407 ++ .../tools/frame-layouts/MediaCardShapes.tsx | 106 + .../shapes/tools/frame-layouts/README.md | 30 + .../tools/frame-layouts/frame-layouts.css | 67 + .../tools/globs-editor/GlobBindingUtil.tsx | 224 + .../tools/globs-editor/GlobShapeUtil.tsx | 1002 +++++ .../tools/globs-editor/GlobTool/GlobTool.tsx | 356 ++ .../tools/globs-editor/GlobsExample.tsx | 272 ++ .../tools/globs-editor/NodeShapeUtil.tsx | 170 + .../shapes/tools/globs-editor/README.md | 35 + .../shapes/tools/globs-editor/shared.ts | 78 + .../shapes/tools/globs-editor/utils.ts | 96 + .../InteractiveShapeExample.tsx | 29 + .../shapes/tools/interactive-shape/README.md | 27 + .../my-interactive-shape-util.tsx | 120 + .../KeyboardMathInputExample.tsx | 119 + .../tools/keyboard-math-input/MathInput.tsx | 44 + .../keyboard-math-input/MathShapeUtil.tsx | 191 + .../tools/keyboard-math-input/MathTool.ts | 28 + .../tools/keyboard-math-input/README.md | 28 + .../keyboard-math-input.css | 61 + .../tools/keyboard-math-input/shorthand.ts | 48 + .../tools/layout-bindings/LayoutExample.tsx | 424 ++ .../shapes/tools/layout-bindings/README.md | 29 + .../tools/layout-bindings/snapshot.json | 210 + .../outlined-text/OutlinedTextExample.css | 10 + .../outlined-text/OutlinedTextExample.tsx | 152 + .../shapes/tools/outlined-text/README.md | 24 + .../PersistentIframeExample.tsx | 205 + .../tools/persistent-iframe-shape/README.md | 12 + .../shapes/tools/pin-bindings/PinExample.tsx | 436 ++ .../shapes/tools/pin-bindings/README.md | 27 + .../tools/popup-shape/PopupShapeExample.tsx | 26 + .../tools/popup-shape/PopupShapeUtil.tsx | 86 + .../shapes/tools/popup-shape/README.md | 26 + .../shapes/tools/popup-shape/popup-shape.css | 19 + .../tools/portal-shapes/PortalShapeUtil.tsx | 166 + .../portal-shapes/PortalShapesExample.tsx | 80 + .../shapes/tools/portal-shapes/README.md | 14 + .../tools/portal-shapes/companion-cube.json | 167 + .../rich-text-custom-extension/README.md | 26 + .../RichTextCustomExtension.css | 3 + .../RichTextCustomExtension.tsx | 164 + .../FontSizeExtension.ts | 80 + .../tools/rich-text-font-extensions/README.md | 29 + .../RichTextFontExtension.css | 5 + .../RichTextFontExtension.tsx | 194 + .../tools/rich-text-font-extensions/fonts.ts | 92 + .../shapes/tools/screenshot-tool/README.md | 29 + .../ScreenshotTool/ScreenshotTool.ts | 50 + .../ScreenshotTool/childStates/Dragging.ts | 121 + .../ScreenshotTool/childStates/Idle.ts | 17 + .../ScreenshotTool/childStates/Pointing.ts | 36 + .../screenshot-tool/ScreenshotToolExample.tsx | 150 + .../tools/shape-with-custom-styles/README.md | 26 + .../ShapeWithCustomStylesExample.tsx | 193 + .../tools/shape-with-geometry/README.md | 25 + .../shape-with-geometry/ShapeWithGeometry.tsx | 151 + .../tools/shape-with-migrations/README.md | 24 + .../ShapeWithMigrationsExample.tsx | 182 + .../tools/shape-with-migrations/snapshot.json | 91 + .../shape-with-onClick/ClickableShapeUtil.tsx | 101 + .../shapes/tools/shape-with-onClick/README.md | 14 + .../ShapeWithOnClickExample.tsx | 39 + .../shape-with-onDoubleClickEdge/README.md | 14 + .../ResizableShapeUtil.tsx | 83 + .../ShapeWithOnDoubleClickEdgeExample.tsx | 38 + .../tools/shape-with-tldraw-styles/README.md | 25 + .../ShapeWithTldrawStylesExample.tsx | 129 + .../shapes/tools/size-from-dom/README.md | 25 + .../size-from-dom/SizeFromDomExample.tsx | 253 ++ .../shapes/tools/size-from-dom/contents.ts | 18 + .../speech-bubble/CustomShapeWithHandles.tsx | 43 + .../shapes/tools/speech-bubble/README.md | 15 + .../SpeechBubble/SpeechBubbleTool.tsx | 12 + .../SpeechBubble/SpeechBubbleUtil.tsx | 304 ++ .../speech-bubble/SpeechBubble/helpers.tsx | 164 + .../SpeechBubble/ui-overrides.tsx | 77 + .../tools/speech-bubble/customhandles.css | 10 + .../shapes/tools/stamp-tool/README.md | 30 + .../tools/stamp-tool/StampToolExample.tsx | 266 ++ .../shapes/tools/stamp-tool/stamp-tool.css | 25 + .../shapes/tools/sticker-bindings/README.md | 26 + .../tools/sticker-bindings/StickerExample.tsx | 300 ++ .../tools/text-shape-configuration/README.md | 34 + .../TextShapeConfigurationExample.tsx | 122 + .../CustomShapeToSvgExample.tsx | 105 + .../tools/toSvg-method-example/README.md | 25 + .../tools/tool-with-child-states/README.md | 28 + .../ToolWithChildStatesExample.tsx | 238 + .../ActionOverridesExample.tsx | 64 + .../examples/ui/action-overrides/README.md | 25 + .../AddConnectedShapeExample.tsx | 198 + .../examples/ui/add-connected-shape/README.md | 26 + .../add-connected-shape.css | 24 + .../examples/ui/add-tool-to-toolbar/README.md | 26 + .../ToolInToolbarExample.tsx | 118 + .../add-tool-to-toolbar/sticker-tool-util.tsx | 22 + .../ChangingDefaultColorsExample.tsx | 40 + .../ui/changing-default-colors/README.md | 25 + .../ChangingDefaultStyleExample.tsx | 14 + .../ui/changing-default-style/README.md | 14 + .../ui/color-picker/ColorPickerExample.tsx | 568 +++ .../src/examples/ui/color-picker/README.md | 16 + .../examples/ui/color-picker/color-picker.css | 136 + .../ContextualStylePanelExample.tsx | 422 ++ .../ui/contextual-style-panel/README.md | 20 + .../ContextualToolbarExample.tsx | 94 + .../examples/ui/contextual-toolbar/README.md | 23 + .../ui/contextual-toolbar/snapshot.json | 103 + .../CustomComponentsExample.tsx | 29 + .../examples/ui/custom-components/README.md | 24 + .../CustomErrorCaptureExample.tsx | 88 + .../ui/custom-error-capture/README.md | 28 + .../custom-error-capture.css | 30 + .../ui/custom-grid/CustomGridExample.tsx | 121 + .../src/examples/ui/custom-grid/README.md | 24 + .../CustomLanguageTranslationExample.tsx | 93 + .../ui/custom-language-translations/README.md | 25 + .../custom-language-translations.css | 5 + .../ui/custom-menus/CustomMenusExample.tsx | 355 ++ .../src/examples/ui/custom-menus/README.md | 42 + .../ui/custom-renderer/CustomRenderer.tsx | 109 + .../custom-renderer/CustomRendererExample.tsx | 36 + .../src/examples/ui/custom-renderer/README.md | 23 + .../ui/custom-renderer/custom-renderer.css | 4 + .../ui/custom-theme/CustomThemeExample.tsx | 437 ++ .../src/examples/ui/custom-theme/README.md | 14 + .../ui/custom-theme/custom-font/OFL.txt | 93 + .../custom-font/Silkscreen-Bold.ttf | Bin 0 -> 30384 bytes .../custom-font/Silkscreen-Regular.ttf | Bin 0 -> 31960 bytes .../examples/ui/custom-theme/custom-theme.css | 44 + .../examples/ui/custom-ui/CustomUiExample.tsx | 106 + .../src/examples/ui/custom-ui/README.md | 15 + .../src/examples/ui/custom-ui/custom-ui.css | 31 + .../DarkModeToggleExample.tsx | 46 + .../examples/ui/dark-mode-toggle/README.md | 24 + .../examples/ui/dark-mode/DarkModeExample.tsx | 18 + .../src/examples/ui/dark-mode/README.md | 14 + .../DragAndDropTrayExample.tsx | 300 ++ .../examples/ui/drag-and-drop-tray/README.md | 16 + .../drag-and-drop-tray/drag-and-drop-tray.css | 31 + .../ui/drag-and-drop-tray/trayitems.ts | 77 + .../error-boundary/ErrorBoundaryExample.tsx | 43 + .../examples/ui/error-boundary/ErrorShape.ts | 26 + .../src/examples/ui/error-boundary/README.md | 15 + .../EscapeShapeFocusTrap.tsx | 184 + .../ui/escape-shape-focus-trap/README.md | 29 + .../ui/floaty-window/FloatyExample.tsx | 60 + .../src/examples/ui/floaty-window/README.md | 14 + .../force-mobile/ForceBreakpointExample.tsx | 16 + .../src/examples/ui/force-mobile/README.md | 14 + .../src/examples/ui/hide-ui/HideUiExample.tsx | 16 + .../src/examples/ui/hide-ui/README.md | 14 + .../IndicatorsLogicExample.tsx | 70 + .../examples/ui/indicators-logic/README.md | 22 + .../inspector-panel/InspectorPanelExample.tsx | 235 + .../src/examples/ui/inspector-panel/README.md | 30 + .../ui/inspector-panel/inspector-panel.css | 218 + .../KeyboardShortcutsExample.tsx | 51 + .../examples/ui/keyboard-shortcuts/README.md | 20 + .../ui/layer-panel/LayerPanelExample.tsx | 63 + .../src/examples/ui/layer-panel/README.md | 29 + .../src/examples/ui/layer-panel/ShapeList.tsx | 160 + .../examples/ui/layer-panel/layer-panel.css | 54 + .../src/examples/ui/layer-panel/snapshot.json | 1731 ++++++++ .../MenuSystemHoverExample.tsx | 98 + .../examples/ui/menu-system-hover/README.md | 29 + .../menu-system-hover/menu-system-hover.css | 34 + .../multiple-themes/MultipleThemesExample.tsx | 140 + .../src/examples/ui/multiple-themes/README.md | 14 + .../ui/multiple-themes/multiple-themes.css | 9 + .../OverlayThemeColorsExample.tsx | 72 + .../ui/overlay-theme-colors/README.md | 12 + .../ui/page-panel/PagePanelExample.tsx | 199 + .../src/examples/ui/page-panel/README.md | 14 + .../src/examples/ui/page-panel/page-panel.css | 114 + .../src/examples/ui/remove-tool/README.md | 21 + .../ui/remove-tool/RemoveToolExample.tsx | 28 + .../ui/rich-text-on-multiple-shapes/README.md | 28 + .../RichTextFormatOnMultipleShapesExample.tsx | 196 + .../ui/screen-reader-accessibility/README.md | 28 + .../ScreenReaderAccessibilityExample.tsx | 251 ++ .../screen-reader-accessibility.css | 16 + .../ui/selection-color-condition/README.md | 24 + .../SelectionColorConditionExample.tsx | 78 + .../src/examples/ui/selection-ui/README.md | 24 + .../ui/selection-ui/SelectionUiExample.tsx | 145 + .../examples/ui/stroke-size-picker/README.md | 14 + .../StrokeSizePickerExample.tsx | 180 + .../stroke-size-picker/stroke-size-picker.css | 27 + .../ui/text-mass-style-updates/README.md | 16 + .../TextMassStyleUpdates.tsx | 231 + .../OnTheCanvasExample.tsx | 99 + .../ui/things-on-the-canvas/README.md | 25 + .../things-on-the-canvas.css | 20 + .../examples/ui/toasts-and-dialogs/README.md | 25 + .../ToastsDialogsExample.tsx | 273 ++ .../src/examples/ui/toolbar-groups/README.md | 21 + .../toolbar-groups/ToolbarGroupsExample.tsx | 99 + .../ui/ui-components-hidden/README.md | 13 + .../UiComponentsHiddenExample.tsx | 55 + .../src/examples/ui/ui-primitives/README.md | 22 + .../ui/ui-primitives/UiPrimitivesExample.tsx | 307 ++ .../ui/ui-primitives/ui-primitives.css | 84 + .../examples/ui/vertical-toolbar/README.md | 11 + .../VerticalToolbarExample.tsx | 14 + apps/examples/src/examples/ui/zones/README.md | 13 + .../src/examples/ui/zones/ZonesExample.tsx | 63 + .../CustomShapeMermaids.tsx | 169 + .../use-cases/custom-shape-mermaids/README.md | 16 + .../custom-shape-mermaid.css | 47 + .../customMermaidShapeUtil.css | 62 + .../customMermaidShapeUtil.tsx | 156 + .../flowchartSourceGuard.ts | 17 + .../mermaidPipelineBlueprint.ts | 17 + .../mermaidPipelineState.ts | 125 + .../pipelineFromEditor.ts | 69 + .../custom-shape-mermaids/pipelineGraph.ts | 98 + .../use-cases/d3-map/D3MapExample.tsx | 69 + .../src/examples/use-cases/d3-map/README.md | 13 + .../use-cases/d3-map/UsMapShapeUtil.tsx | 147 + .../use-cases/d3-map/UsStateShapeUtil.tsx | 114 + .../src/examples/use-cases/d3-map/d3-map.css | 36 + .../examples/use-cases/d3-map/us-map-data.ts | 114 + .../EducationCanvasExample.tsx | 285 ++ .../use-cases/education-canvas/README.md | 26 + .../education-canvas/education-canvas.css | 292 ++ .../exam-marking/ExamMarkingExample.tsx | 43 + .../use-cases/exam-marking/ExamScoreLabel.tsx | 45 + .../examples/use-cases/exam-marking/README.md | 19 + .../use-cases/exam-marking/add-mark-tool.tsx | 24 + .../use-cases/exam-marking/add-mark-util.tsx | 165 + .../pdf-editor/ExportPdfButton.tsx | 94 + .../exam-marking/pdf-editor/PdfEditor.tsx | 238 + .../exam-marking/pdf-editor/PdfPicker.tsx | 117 + .../exam-marking/pdf-editor/pdf-editor.css | 55 + .../use-cases/exam-marking/ui-overrides.tsx | 60 + .../use-cases/fog-of-war/FogOfWarExample.tsx | 119 + .../examples/use-cases/fog-of-war/README.md | 25 + .../MermaidDiagramsExample.tsx | 201 + .../use-cases/hundred-mermaids/README.md | 16 + .../hundred-mermaids/hundred-mermaids.css | 12 + .../use-cases/hundred-mermaids/mermaids.ts | 1427 ++++++ .../image-annotator/ImageAnnotationEditor.tsx | 219 + .../image-annotator/ImageAnnotatorExample.tsx | 55 + .../use-cases/image-annotator/ImageExport.tsx | 41 + .../use-cases/image-annotator/ImagePicker.tsx | 69 + .../use-cases/image-annotator/README.md | 29 + .../image-annotator/assets/distracted-bf.jpeg | Bin 0 -> 48720 bytes .../assets/expanding-brain.png | Bin 0 -> 80113 bytes .../image-annotator/image-annotator.css | 107 + .../use-cases/image-annotator/types.tsx | 6 + .../many-shapes/ManyShapesExample.tsx | 155 + .../examples/use-cases/many-shapes/README.md | 14 + .../use-cases/map-tiles/MapTilesExample.tsx | 110 + .../examples/use-cases/map-tiles/README.md | 16 + .../use-cases/map-tiles/TileLayer.tsx | 121 + .../use-cases/map-tiles/map-tiles.css | 26 + .../examples/use-cases/map-tiles/mercator.ts | 71 + .../mask-window/MaskWindowExample.tsx | 87 + .../examples/use-cases/mask-window/README.md | 25 + .../use-cases/mask-window/mask-window.css | 9 + .../mermaid-pasting/MermaidPasting.tsx | 135 + .../use-cases/mermaid-pasting/README.md | 25 + .../use-cases/pdf-editor/ExportPdfButton.tsx | 102 + .../use-cases/pdf-editor/PdfEditor.tsx | 214 + .../use-cases/pdf-editor/PdfEditorExample.tsx | 33 + .../use-cases/pdf-editor/PdfPicker.tsx | 118 + .../examples/use-cases/pdf-editor/README.md | 29 + .../use-cases/pdf-editor/pdf-editor.css | 55 + .../src/examples/use-cases/slides/README.md | 27 + .../use-cases/slides/SlideShapeTool.tsx | 7 + .../use-cases/slides/SlideShapeUtil.tsx | 160 + .../use-cases/slides/SlidesExample.tsx | 131 + .../examples/use-cases/slides/SlidesPanel.tsx | 33 + .../src/examples/use-cases/slides/slides.css | 32 + .../examples/use-cases/slides/useSlides.tsx | 31 + .../examples/use-cases/slideshow/README.md | 29 + .../use-cases/slideshow/SlideShowExample.tsx | 260 ++ .../use-cases/slideshow/SlidesManager.tsx | 100 + .../examples/use-cases/snowstorm/README.md | 14 + .../use-cases/snowstorm/SnowStorm.tsx | 245 + .../use-cases/snowstorm/SnowStormExample.tsx | 15 + .../use-cases/snowstorm/snowstorm.css | 13 + .../examples/use-cases/soft-clip/README.md | 30 + .../use-cases/soft-clip/SoftClipExample.tsx | 203 + .../use-cases/soft-clip/soft-clip.css | 66 + .../use-cases/timeline-scrubber/README.md | 28 + .../TimelineScrubberExample.tsx | 147 + .../timeline-scrubber/timeline-scrubber.css | 36 + .../use-cases/tower-defense/README.md | 16 + .../tower-defense/TowerDefenseExample.tsx | 284 ++ .../use-cases/tower-defense/enemy-config.ts | 59 + .../use-cases/tower-defense/game-loop.ts | 278 ++ .../use-cases/tower-defense/game-state.ts | 113 + .../overlays/EnemyOverlayUtil.ts | 143 + .../overlays/ExplosionOverlayUtil.ts | 62 + .../tower-defense/overlays/PathOverlayUtil.ts | 47 + .../overlays/PlacementPreviewOverlayUtil.ts | 116 + .../overlays/ProjectileOverlayUtil.ts | 82 + .../overlays/TowerRangeOverlayUtil.ts | 76 + .../overlays/UpgradeButtonOverlayUtil.ts | 192 + .../examples/use-cases/tower-defense/path.ts | 63 + .../use-cases/tower-defense/sounds.ts | 92 + .../use-cases/tower-defense/tower-config.ts | 92 + .../use-cases/tower-defense/tower-defense.css | 131 + .../use-cases/xkcd-dependency/README.md | 14 + .../xkcd-dependency/XkcdDependencyExample.tsx | 412 ++ .../zoom-into-moby-dick/ContentLayer.tsx | 179 + .../use-cases/zoom-into-moby-dick/README.md | 74 + .../zoom-into-moby-dick/SemanticZoom.tsx | 213 + .../ZoomIntoMobyDickExample.tsx | 50 + .../use-cases/zoom-into-moby-dick/layout.ts | 341 ++ .../zoom-into-moby-dick/navigation.ts | 104 + .../zoom-into-moby-dick/summaries.ts | 718 +++ .../zoom-into-moby-dick.css | 243 + .../AttributionTimelineExample.tsx | 399 ++ .../users/attribution-timeline/README.md | 27 + .../attribution-timeline.css | 101 + .../users/attribution/AttributionExample.tsx | 236 + .../src/examples/users/attribution/README.md | 14 + .../users/attribution/attribution.css | 77 + .../users/custom-user/CustomUserExample.tsx | 155 + .../src/examples/users/custom-user/README.md | 38 + .../users/custom-user/custom-user.css | 71 + .../NoteAttributionComponentExample.tsx | 85 + .../note-attribution-component/README.md | 12 + .../examples/users/sync-custom-user/README.md | 25 + .../users/sync-custom-user/SyncCustomUser.tsx | 84 + apps/examples/src/hooks/useDebugging.tsx | 53 + apps/examples/src/hooks/usePerformance.ts | 23 + apps/examples/src/icons/apple-touch-icon.png | Bin 0 -> 9408 bytes apps/examples/src/icons/icons.tsx | 22 + apps/examples/src/icons/tldraw.svg | 11 + apps/examples/src/index.html | 24 + apps/examples/src/index.tsx | 132 + apps/examples/src/misc/EndToEndApi.tsx | 15 + apps/examples/src/misc/a11y.tsx | 62 + apps/examples/src/misc/develop.tsx | 189 + apps/examples/src/misc/diff.ts | 26 + apps/examples/src/misc/end-to-end.tsx | 217 + apps/examples/src/misc/mermaidReadability.ts | 276 ++ apps/examples/src/styles.css | 848 ++++ apps/examples/src/vite-env.d.ts | 1 + apps/examples/tsconfig.json | 17 + apps/examples/vercel.json | 22 + apps/examples/vite.config.ts | 228 + apps/examples/writing-examples.md | 189 + .../.claude/skills/add-app-to-server/SKILL.md | 431 ++ .../.claude/skills/convert-web-app/SKILL.md | 557 +++ .../.claude/skills/create-mcp-app/SKILL.md | 367 ++ .../.claude/skills/migrate-oai-app/SKILL.md | 170 + apps/mcp-app/.cursor-plugin/marketplace.json | 19 + apps/mcp-app/.gitignore | 7 + apps/mcp-app/LICENSE.md | 9 + apps/mcp-app/README.md | 141 + apps/mcp-app/dev-tunnel.sh | 88 + apps/mcp-app/package.json | 43 + .../tldraw-mcp/.cursor-plugin/plugin.json | 10 + .../plugins/tldraw-mcp/assets/logo.svg | 3 + apps/mcp-app/plugins/tldraw-mcp/mcp.json | 8 + apps/mcp-app/scripts/extract-editor-api.ts | 1374 ++++++ apps/mcp-app/server.json | 21 + apps/mcp-app/src/agents-canary.test.ts | 78 + apps/mcp-app/src/canvas-store.ts | 103 + apps/mcp-app/src/idle-expiry.test.ts | 123 + apps/mcp-app/src/large-payload-smoke.test.ts | 95 + apps/mcp-app/src/logger.ts | 45 + apps/mcp-app/src/next-expiry-time.test.ts | 38 + apps/mcp-app/src/register-tools.ts | 404 ++ apps/mcp-app/src/shared/exec-key.ts | 26 + apps/mcp-app/src/shared/generated-data.ts | 160 + apps/mcp-app/src/shared/pending-requests.ts | 81 + apps/mcp-app/src/shared/types.ts | 130 + apps/mcp-app/src/shared/utils.ts | 132 + apps/mcp-app/src/tools/exec.ts | 224 + .../src/tools/loadCachedCanvasWidgetHtml.ts | 16 + apps/mcp-app/src/tools/search.ts | 150 + apps/mcp-app/src/widget/app-context.tsx | 29 + apps/mcp-app/src/widget/dev-log.tsx | 70 + apps/mcp-app/src/widget/exec-helpers.test.ts | 99 + apps/mcp-app/src/widget/exec-helpers.ts | 279 ++ apps/mcp-app/src/widget/export-tldr.ts | 35 + apps/mcp-app/src/widget/focused/defaults.ts | 141 + .../widget/focused/focused-editor-proxy.ts | 452 ++ apps/mcp-app/src/widget/focused/format.ts | 366 ++ apps/mcp-app/src/widget/focused/to-focused.ts | 258 ++ apps/mcp-app/src/widget/focused/to-tldraw.ts | 572 +++ apps/mcp-app/src/widget/image-guard.tsx | 106 + apps/mcp-app/src/widget/index.html | 33 + apps/mcp-app/src/widget/mcp-app.css | 111 + apps/mcp-app/src/widget/mcp-app.tsx | 871 ++++ apps/mcp-app/src/widget/persistence.ts | 333 ++ apps/mcp-app/src/widget/snapshot.ts | 157 + apps/mcp-app/src/worker.ts | 567 +++ apps/mcp-app/src/wrangler-dev-harness.ts | 134 + apps/mcp-app/tsconfig.json | 23 + apps/mcp-app/vite.config.ts | 13 + apps/mcp-app/vitest.config.ts | 18 + apps/mcp-app/wrangler.toml | 62 + apps/tldraw-new/.gitignore | 1 + apps/tldraw-new/index.html | 15 + apps/tldraw-new/vercel.json | 10 + apps/vscode/DOCS.md | 416 ++ apps/vscode/README.md | 114 + apps/vscode/VS-Code-Extension-1.tldr | 1 + apps/vscode/editor/LICENSE.md | 9 + apps/vscode/editor/README.md | 23 + apps/vscode/editor/package.json | 57 + apps/vscode/editor/public/index.css | 46 + apps/vscode/editor/scripts/build.ts | 58 + apps/vscode/editor/scripts/cli.ts | 58 + apps/vscode/editor/scripts/dev.ts | 77 + apps/vscode/editor/scripts/helpers.ts | 25 + apps/vscode/editor/scripts/path.ts | 16 + apps/vscode/editor/src/ChangeResponder.tsx | 69 + apps/vscode/editor/src/FileOpen.tsx | 44 + apps/vscode/editor/src/FullPageMessage.tsx | 17 + apps/vscode/editor/src/Links.tsx | 41 + apps/vscode/editor/src/app.tsx | 153 + apps/vscode/editor/src/index.tsx | 9 + apps/vscode/editor/src/utils/bookmarks.ts | 70 + .../src/utils/externalUrlContentHandler.ts | 25 + apps/vscode/editor/src/utils/rpc.ts | 63 + apps/vscode/editor/src/utils/url.ts | 8 + apps/vscode/editor/src/utils/vscode.ts | 9 + apps/vscode/editor/tsconfig.json | 26 + apps/vscode/extension/.gitignore | 6 + apps/vscode/extension/.vscode/extensions.json | 5 + apps/vscode/extension/.vscode/launch.json | 23 + apps/vscode/extension/.vscode/settings.json | 11 + apps/vscode/extension/.vscodeignore | 0 apps/vscode/extension/CHANGELOG.md | 1 + apps/vscode/extension/LICENSE.md | 9 + apps/vscode/extension/README.md | 56 + apps/vscode/extension/assets/vscode_open.png | Bin 0 -> 31450 bytes apps/vscode/extension/examples/1.tldr | 168 + apps/vscode/extension/examples/2.tldr | 1026 +++++ apps/vscode/extension/examples/3.tldr | 1104 +++++ .../files-with-erros/invalid-record.tldr | 1 + .../files-with-erros/invalid-tldraw-file.tldr | 1 + .../files-with-erros/version-too-new.tldr | 1 + apps/vscode/extension/examples/v2.tldr | 3941 +++++++++++++++++ apps/vscode/extension/examples/v2a.tldr | 3231 ++++++++++++++ apps/vscode/extension/icon.png | Bin 0 -> 6600 bytes apps/vscode/extension/package.json | 180 + apps/vscode/extension/scripts/build.ts | 42 + apps/vscode/extension/scripts/cli.ts | 58 + apps/vscode/extension/scripts/dev.ts | 60 + apps/vscode/extension/scripts/helpers.ts | 25 + apps/vscode/extension/scripts/package.ts | 38 + apps/vscode/extension/scripts/path.ts | 16 + apps/vscode/extension/scripts/publish.ts | 82 + apps/vscode/extension/src/TldrawDocument.ts | 181 + .../extension/src/TldrawEditorProvider.ts | 153 + .../src/TldrawOfflineFileProvider.ts | 82 + .../extension/src/TldrawWebviewManager.ts | 82 + .../extension/src/WebViewMessageHandler.ts | 221 + apps/vscode/extension/src/extension.ts | 38 + apps/vscode/extension/src/file.ts | 36 + apps/vscode/extension/src/media.ts | 50 + apps/vscode/extension/src/unfurl.ts | 69 + apps/vscode/extension/src/utils.ts | 8 + apps/vscode/extension/tsconfig.json | 25 + apps/vscode/messages.ts | 120 + assets/embed-icons/canva.png | Bin 0 -> 309 bytes assets/embed-icons/codepen.png | Bin 0 -> 2180 bytes assets/embed-icons/codesandbox.png | Bin 0 -> 237 bytes assets/embed-icons/desmos.png | Bin 0 -> 1425 bytes assets/embed-icons/excalidraw.png | Bin 0 -> 846 bytes assets/embed-icons/felt.png | Bin 0 -> 977 bytes assets/embed-icons/figma.png | Bin 0 -> 1299 bytes assets/embed-icons/github_gist.png | Bin 0 -> 1471 bytes assets/embed-icons/google_calendar.png | Bin 0 -> 962 bytes assets/embed-icons/google_maps.png | Bin 0 -> 1902 bytes assets/embed-icons/google_slides.png | Bin 0 -> 1435 bytes assets/embed-icons/observable.png | Bin 0 -> 769 bytes assets/embed-icons/replit.png | Bin 0 -> 526 bytes assets/embed-icons/scratch.png | Bin 0 -> 3716 bytes assets/embed-icons/spotify.png | Bin 0 -> 2261 bytes assets/embed-icons/tldraw.png | Bin 0 -> 625 bytes assets/embed-icons/val_town.png | Bin 0 -> 540 bytes assets/embed-icons/vimeo.png | Bin 0 -> 864 bytes assets/embed-icons/youtube.png | Bin 0 -> 846 bytes assets/fonts/IBMPlexMono-Bold.woff2 | Bin 0 -> 46684 bytes assets/fonts/IBMPlexMono-BoldItalic.woff2 | Bin 0 -> 50624 bytes assets/fonts/IBMPlexMono-Medium.woff2 | Bin 0 -> 46724 bytes assets/fonts/IBMPlexMono-MediumItalic.woff2 | Bin 0 -> 51344 bytes assets/fonts/IBMPlexSans-Bold.woff2 | Bin 0 -> 63012 bytes assets/fonts/IBMPlexSans-BoldItalic.woff2 | Bin 0 -> 66632 bytes assets/fonts/IBMPlexSans-Medium.woff2 | Bin 0 -> 66740 bytes assets/fonts/IBMPlexSans-MediumItalic.woff2 | Bin 0 -> 71204 bytes assets/fonts/IBMPlexSerif-Bold.woff2 | Bin 0 -> 68940 bytes assets/fonts/IBMPlexSerif-BoldItalic.woff2 | Bin 0 -> 73992 bytes assets/fonts/IBMPlexSerif-Medium.woff2 | Bin 0 -> 72604 bytes assets/fonts/IBMPlexSerif-MediumItalic.woff2 | Bin 0 -> 77900 bytes assets/github-hero-dark.png | Bin 0 -> 46992 bytes assets/github-hero-light.png | Bin 0 -> 42384 bytes assets/icons/icon/align-bottom.svg | 3 + assets/icons/icon/align-center-horizontal.svg | 4 + assets/icons/icon/align-center-vertical.svg | 3 + assets/icons/icon/align-left.svg | 4 + assets/icons/icon/align-right.svg | 4 + assets/icons/icon/align-top.svg | 3 + assets/icons/icon/alt.svg | 5 + assets/icons/icon/arrow-arc.svg | 3 + assets/icons/icon/arrow-cycle.svg | 12 + assets/icons/icon/arrow-elbow.svg | 3 + assets/icons/icon/arrow-left.svg | 3 + assets/icons/icon/arrowhead-arrow.svg | 3 + assets/icons/icon/arrowhead-bar.svg | 3 + assets/icons/icon/arrowhead-diamond.svg | 4 + assets/icons/icon/arrowhead-dot.svg | 4 + assets/icons/icon/arrowhead-none.svg | 3 + assets/icons/icon/arrowhead-square.svg | 3 + .../icon/arrowhead-triangle-inverted.svg | 3 + assets/icons/icon/arrowhead-triangle.svg | 3 + assets/icons/icon/blob.svg | 3 + assets/icons/icon/bold.svg | 3 + assets/icons/icon/bookmark.svg | 3 + assets/icons/icon/bring-forward.svg | 3 + assets/icons/icon/bring-to-front.svg | 3 + assets/icons/icon/broken.svg | 5 + assets/icons/icon/bulletList.svg | 12 + assets/icons/icon/check-circle.svg | 4 + assets/icons/icon/check.svg | 3 + assets/icons/icon/chevron-down.svg | 3 + assets/icons/icon/chevron-left.svg | 3 + assets/icons/icon/chevron-right.svg | 3 + assets/icons/icon/chevron-up.svg | 3 + assets/icons/icon/chevrons-ne.svg | 3 + assets/icons/icon/chevrons-sw.svg | 3 + assets/icons/icon/clipboard-copied.svg | 4 + assets/icons/icon/clipboard-copy.svg | 15 + assets/icons/icon/closed.svg | 1 + assets/icons/icon/code.svg | 3 + assets/icons/icon/color.svg | 3 + assets/icons/icon/comment.svg | 3 + assets/icons/icon/corners.svg | 12 + assets/icons/icon/crop.svg | 13 + assets/icons/icon/cross-2.svg | 3 + assets/icons/icon/cross-circle.svg | 4 + assets/icons/icon/dash-dashed.svg | 3 + assets/icons/icon/dash-dotted.svg | 14 + assets/icons/icon/dash-draw.svg | 3 + assets/icons/icon/dash-solid.svg | 3 + assets/icons/icon/disconnected.svg | 4 + assets/icons/icon/discord.svg | 12 + assets/icons/icon/distribute-horizontal.svg | 6 + assets/icons/icon/distribute-vertical.svg | 6 + assets/icons/icon/dot.svg | 3 + assets/icons/icon/dots-horizontal.svg | 5 + assets/icons/icon/dots-vertical.svg | 5 + assets/icons/icon/download.svg | 4 + assets/icons/icon/drag-handle-dots.svg | 8 + assets/icons/icon/duplicate.svg | 3 + assets/icons/icon/edit.svg | 3 + assets/icons/icon/external-link.svg | 3 + assets/icons/icon/fill-fill.svg | 4 + assets/icons/icon/fill-lined-fill.svg | 4 + assets/icons/icon/fill-none.svg | 3 + assets/icons/icon/fill-pattern.svg | 4 + assets/icons/icon/fill-semi.svg | 3 + assets/icons/icon/fill-solid.svg | 4 + assets/icons/icon/follow.svg | 4 + assets/icons/icon/following.svg | 4 + assets/icons/icon/font-draw.svg | 3 + assets/icons/icon/font-mono.svg | 4 + assets/icons/icon/font-sans.svg | 4 + assets/icons/icon/font-serif.svg | 4 + assets/icons/icon/geo-arrow-down.svg | 3 + assets/icons/icon/geo-arrow-left.svg | 3 + assets/icons/icon/geo-arrow-right.svg | 3 + assets/icons/icon/geo-arrow-up.svg | 3 + assets/icons/icon/geo-check-box.svg | 5 + assets/icons/icon/geo-cloud.svg | 3 + assets/icons/icon/geo-diamond.svg | 3 + assets/icons/icon/geo-ellipse.svg | 3 + assets/icons/icon/geo-heart.svg | 3 + assets/icons/icon/geo-hexagon.svg | 3 + assets/icons/icon/geo-octagon.svg | 3 + assets/icons/icon/geo-oval.svg | 3 + assets/icons/icon/geo-pentagon.svg | 3 + assets/icons/icon/geo-rectangle.svg | 3 + assets/icons/icon/geo-rhombus-2.svg | 3 + assets/icons/icon/geo-rhombus.svg | 3 + assets/icons/icon/geo-star.svg | 3 + assets/icons/icon/geo-trapezoid.svg | 3 + assets/icons/icon/geo-triangle.svg | 3 + assets/icons/icon/geo-x-box.svg | 5 + assets/icons/icon/github.svg | 3 + assets/icons/icon/group.svg | 10 + assets/icons/icon/heading.svg | 10 + assets/icons/icon/help-circle.svg | 5 + assets/icons/icon/highlight.svg | 4 + assets/icons/icon/horizontal-align-end.svg | 5 + assets/icons/icon/horizontal-align-middle.svg | 7 + assets/icons/icon/horizontal-align-start.svg | 5 + assets/icons/icon/icon/avatar.svg | 3 + assets/icons/icon/info-circle.svg | 5 + assets/icons/icon/italic.svg | 3 + assets/icons/icon/leading.svg | 4 + assets/icons/icon/link.svg | 4 + assets/icons/icon/list.svg | 3 + assets/icons/icon/lock.svg | 4 + assets/icons/icon/manual.svg | 4 + assets/icons/icon/menu.svg | 5 + assets/icons/icon/minus.svg | 3 + assets/icons/icon/mixed.svg | 11 + assets/icons/icon/pack.svg | 3 + assets/icons/icon/plus.svg | 3 + assets/icons/icon/question-mark-circle.svg | 5 + assets/icons/icon/question-mark.svg | 4 + assets/icons/icon/redo.svg | 3 + assets/icons/icon/reset-zoom.svg | 6 + assets/icons/icon/rotate-ccw.svg | 4 + assets/icons/icon/rotate-cw.svg | 4 + assets/icons/icon/send-backward.svg | 3 + assets/icons/icon/send-to-back.svg | 3 + assets/icons/icon/share-1.svg | 4 + assets/icons/icon/size-extra-large.svg | 4 + assets/icons/icon/size-large.svg | 3 + assets/icons/icon/size-medium.svg | 3 + assets/icons/icon/size-small.svg | 3 + assets/icons/icon/spline-cubic.svg | 3 + assets/icons/icon/spline-line.svg | 3 + assets/icons/icon/stack-horizontal.svg | 3 + assets/icons/icon/stack-vertical.svg | 3 + assets/icons/icon/status-offline.svg | 7 + assets/icons/icon/stretch-horizontal.svg | 5 + assets/icons/icon/stretch-vertical.svg | 4 + assets/icons/icon/strike.svg | 4 + assets/icons/icon/text-align-center.svg | 3 + assets/icons/icon/text-align-left.svg | 3 + assets/icons/icon/text-align-right.svg | 3 + assets/icons/icon/toggle-off.svg | 4 + assets/icons/icon/toggle-on.svg | 4 + assets/icons/icon/tool-arrow.svg | 3 + assets/icons/icon/tool-eraser.svg | 3 + assets/icons/icon/tool-frame.svg | 3 + assets/icons/icon/tool-hand.svg | 3 + assets/icons/icon/tool-highlight.svg | 4 + assets/icons/icon/tool-laser.svg | 6 + assets/icons/icon/tool-line.svg | 3 + assets/icons/icon/tool-media.svg | 4 + assets/icons/icon/tool-note.svg | 4 + assets/icons/icon/tool-pencil.svg | 4 + assets/icons/icon/tool-pointer.svg | 3 + assets/icons/icon/tool-screenshot.svg | 5 + assets/icons/icon/tool-text.svg | 3 + assets/icons/icon/trash.svg | 5 + assets/icons/icon/twitter.svg | 4 + assets/icons/icon/underline.svg | 3 + assets/icons/icon/undo.svg | 3 + assets/icons/icon/ungroup.svg | 9 + assets/icons/icon/unlock.svg | 4 + assets/icons/icon/vertical-align-end.svg | 5 + assets/icons/icon/vertical-align-middle.svg | 7 + assets/icons/icon/vertical-align-start.svg | 5 + assets/icons/icon/warning-triangle.svg | 5 + assets/icons/icon/zoom-in.svg | 6 + assets/icons/icon/zoom-out.svg | 5 + assets/tldraw_sdk_logo_dark.png | Bin 0 -> 24032 bytes assets/tldraw_sdk_logo_light.png | Bin 0 -> 23041 bytes assets/translations/ar.json | 541 +++ assets/translations/bn.json | 540 +++ assets/translations/ca.json | 541 +++ assets/translations/cs.json | 541 +++ assets/translations/da.json | 541 +++ assets/translations/de.json | 541 +++ assets/translations/el.json | 540 +++ assets/translations/en.json | 1 + assets/translations/es.json | 541 +++ assets/translations/fa.json | 541 +++ assets/translations/fi.json | 541 +++ assets/translations/fr.json | 541 +++ assets/translations/gl.json | 540 +++ assets/translations/gu-in.json | 540 +++ assets/translations/he.json | 541 +++ assets/translations/hi-in.json | 541 +++ assets/translations/hr.json | 541 +++ assets/translations/hu.json | 541 +++ assets/translations/id.json | 541 +++ assets/translations/it.json | 541 +++ assets/translations/ja.json | 541 +++ assets/translations/km-kh.json | 540 +++ assets/translations/kn.json | 540 +++ assets/translations/ko-kr.json | 542 +++ assets/translations/ku.json | 93 + assets/translations/languages.json | 198 + assets/translations/main.json | 544 +++ assets/translations/ml.json | 540 +++ assets/translations/mr.json | 540 +++ assets/translations/ms.json | 540 +++ assets/translations/my.json | 112 + assets/translations/ne.json | 541 +++ assets/translations/nl.json | 540 +++ assets/translations/no.json | 540 +++ assets/translations/pa.json | 540 +++ assets/translations/pl.json | 541 +++ assets/translations/pt-br.json | 541 +++ assets/translations/pt-pt.json | 541 +++ assets/translations/ro.json | 541 +++ assets/translations/ru.json | 541 +++ assets/translations/sl.json | 541 +++ assets/translations/so.json | 541 +++ assets/translations/sv.json | 541 +++ assets/translations/ta.json | 540 +++ assets/translations/te.json | 541 +++ assets/translations/th.json | 541 +++ assets/translations/tl.json | 540 +++ assets/translations/tr.json | 541 +++ assets/translations/uk.json | 541 +++ assets/translations/ur.json | 540 +++ assets/translations/vi.json | 541 +++ assets/translations/zh-cn.json | 541 +++ assets/translations/zh-tw.json | 541 +++ assets/watermarks/watermark-desktop.svg | 20 + assets/watermarks/watermark-mobile.svg | 8 + assets/watermarks/watermark-track.svg | 1 + internal/apps-script/.gitignore | 1 + internal/apps-script/README.md | 23 + internal/apps-script/appsscript.json | 33 + internal/apps-script/build-workspace-app.ts | 30 + internal/apps-script/package.json | 47 + internal/apps-script/tsconfig.json | 23 + internal/config/LICENSE.md | 1 + internal/config/api-extractor.json | 406 ++ internal/config/package.json | 15 + internal/config/tsconfig.base.json | 37 + internal/config/tsconfig.json | 6 + internal/config/vitest/node-preset.ts | 51 + internal/config/vitest/setup.ts | 143 + internal/docs/product-stable-ids.md | 83 + internal/grafana/README.md | 77 + .../8451fbba-5835-56e2-b2f5-7f5e44c520b8.yaml | 112 + .../afjn4kz1g4jk0a.yaml | 66 + .../bfjyilovht2pse.yaml | 81 + .../cfjnb1whljcowe.yaml | 72 + .../cfjnbehzmlhxcc.yaml | 72 + .../cfjyl9tbrury8b.yaml | 80 + .../dfjn3qe3l7w8wc.yaml | 69 + .../dfjn9xellhibka.yaml | 72 + .../dotcom-file-do-exceptions.yaml | 94 + .../dotcom-version-chain-verify-failures.yaml | 95 + .../dotcom-version-chain-write-errors.yaml | 85 + .../e75d2f6c-44cf-54bf-8a74-ced2e045fcb6.yaml | 116 + .../eec2ad9e-30b9-5c8f-802f-53e26ab8fdc9.yaml | 110 + .../efjn4hgdlhc00f.yaml | 66 + .../efjnbq9h4iha8a.yaml | 69 + .../adgumkhou3chsd.yaml | 254 ++ ...anthropic-integration-scrape-overview.yaml | 195 + .../edrigjn435v5sf.yaml | 375 ++ .../slow-queries.yaml | 605 +++ .../nivs2rl.yaml | 2334 ++++++++++ .../mcp-server.yaml | 2071 +++++++++ .../mix4slb.yaml | 819 ++++ .../ni7hhgd.yaml | 1164 +++++ .../kotx6wj.yaml | 940 ++++ .../anthropic.yaml | 9 + .../folders.v1.folder.grafana.app/dotcom.yaml | 9 + .../folders.v1.folder.grafana.app/f6hsw6.yaml | 9 + internal/grafana/templates/discord.gotmpl | 22 + internal/grafana/templates/email.gotmpl | 26 + internal/health-worker/.gitignore | 2 + internal/health-worker/README.md | 27 + internal/health-worker/package.json | 23 + internal/health-worker/src/discord.ts | 96 + internal/health-worker/src/index.ts | 69 + internal/health-worker/src/updown_types.ts | 152 + internal/health-worker/tsconfig.json | 11 + internal/health-worker/wrangler.toml | 17 + internal/scripts/api-check.ts | 102 + internal/scripts/benchmark-dict-validator.ts | 292 ++ internal/scripts/benchmark-validators.ts | 379 ++ internal/scripts/build-api.ts | 62 + internal/scripts/build-package.ts | 137 + internal/scripts/bump-versions.ts | 23 + internal/scripts/check-circular-deps.ts | 237 + internal/scripts/check-packages.ts | 618 +++ internal/scripts/check-worker-bundle.ts | 65 + internal/scripts/clean.sh | 41 + internal/scripts/cloudflare/dns-check.ts | 104 + internal/scripts/cloudflare/ssl-cleanup.ts | 142 + internal/scripts/create-docs-reference.ts | 220 + internal/scripts/deploy-analytics.ts | 110 + internal/scripts/deploy-bemo.ts | 123 + internal/scripts/deploy-dotcom.ts | 1093 +++++ internal/scripts/deploy-template.ts | 100 + internal/scripts/dev-template.sh | 45 + internal/scripts/dotcom/cleanup-test-files.ts | 72 + .../dotcom/copy-random-files-to-staging.ts | 182 + internal/scripts/export-template.ts | 170 + internal/scripts/extract-draft-changelog.tsx | 258 ++ internal/scripts/fetch-fly-logs.ts | 126 + internal/scripts/fetch-fly-metrics.ts | 201 + internal/scripts/fetch-screenshot-metrics.ts | 321 ++ internal/scripts/fly-common.ts | 38 + internal/scripts/generate-test-licenses.ts | 257 ++ .../scripts/generate-tldraw-package-docs.ts | 334 ++ internal/scripts/i18n-download-strings.ts | 219 + internal/scripts/i18n-fix-strings.ts | 1480 +++++++ internal/scripts/i18n-upload-strings.ts | 253 ++ internal/scripts/lib/add-extensions.ts | 77 + internal/scripts/lib/deploy.ts | 217 + internal/scripts/lib/didAnyPackageChange.ts | 183 + internal/scripts/lib/discord.ts | 124 + internal/scripts/lib/exec.ts | 76 + internal/scripts/lib/file.ts | 90 + internal/scripts/lib/kill-tree.ts | 40 + internal/scripts/lib/labels.ts | 44 + internal/scripts/lib/makeEnv.ts | 18 + internal/scripts/lib/nicelog.ts | 3 + internal/scripts/lib/posthog.ts | 57 + internal/scripts/lib/pr-info.ts | 64 + internal/scripts/lib/publishing.ts | 295 ++ internal/scripts/lib/skip-ci.ts | 19 + internal/scripts/lib/sort-unions.ts | 42 + internal/scripts/lib/types.ts | 80 + internal/scripts/lib/upload-static-assets.ts | 98 + internal/scripts/lib/worker-externals.ts | 27 + internal/scripts/lib/workspace.ts | 62 + internal/scripts/license-report.ts | 414 ++ internal/scripts/lint-staged.ts | 72 + internal/scripts/lint.ts | 62 + internal/scripts/oxlint/tldraw-plugin.mjs | 1204 +++++ internal/scripts/package.json | 86 + internal/scripts/postpack.sh | 21 + internal/scripts/prepack.ts | 97 + internal/scripts/process-compose-bin.cjs | 97 + internal/scripts/product-manifest.ts | 69 + internal/scripts/profile-tsserver.ts | 483 ++ internal/scripts/profile-typescript.ts | 292 ++ internal/scripts/prune-preview-deploys.ts | 458 ++ internal/scripts/publish-editor-extensions.ts | 143 + internal/scripts/publish-manual.ts | 35 + internal/scripts/publish-new.ts | 147 + internal/scripts/publish-patch.ts | 138 + internal/scripts/publish-prerelease.ts | 30 + internal/scripts/purge-css.ts | 14 + internal/scripts/refresh-assets.ts | 772 ++++ internal/scripts/refresh-create-templates.ts | 44 + internal/scripts/trigger-dotcom-hotfix.ts | 224 + internal/scripts/trigger-sdk-hotfix.ts | 168 + internal/scripts/tsconfig.json | 21 + internal/scripts/typecheck.ts | 150 + internal/scripts/update-pr-template.ts | 70 + internal/scripts/vercel/build-docs.sh | 6 + internal/scripts/vercel/build.sh | 4 + internal/scripts/vercel/install.sh | 4 + .../scripts/vercel/should-build-analytics.sh | 20 + internal/scripts/vercel/should-build-docs.sh | 17 + .../scripts/vercel/should-build-template.sh | 21 + .../scripts/vercel/should-build-tldraw-new.sh | 20 + internal/scripts/workers/dev.ts | 249 ++ lazy.config.ts | 147 + lerna.json | 7 + package.json | 202 + packages/assets/LICENSE.md | 1 + packages/assets/README.md | 33 + packages/assets/api-extractor.json | 4 + packages/assets/imports.d.ts | 2 + packages/assets/imports.js | 364 ++ packages/assets/imports.vite.d.ts | 2 + packages/assets/imports.vite.js | 364 ++ packages/assets/modules.d.ts | 16 + packages/assets/package.json | 67 + packages/assets/selfHosted.d.ts | 2 + packages/assets/selfHosted.js | 281 ++ packages/assets/tsconfig.json | 14 + packages/assets/types.d.ts | 266 ++ packages/assets/urls.d.ts | 2 + packages/assets/urls.js | 350 ++ packages/assets/utils.d.ts | 2 + packages/assets/utils.js | 20 + packages/collaboration/LICENSE.md | 1 + packages/collaboration/README.md | 7 + packages/collaboration/api-extractor.json | 4 + packages/collaboration/api-report.api.md | 12 + packages/collaboration/package.json | 63 + .../collaboration/scripts/copy-css-files.mjs | 25 + packages/collaboration/src/index.ts | 13 + packages/collaboration/tsconfig.json | 24 + packages/collaboration/vitest.config.ts | 6 + packages/commenting/LICENSE.md | 1 + packages/commenting/REACTIONS.md | 219 + packages/commenting/README.md | 9 + packages/commenting/api-extractor.json | 4 + packages/commenting/api-report.api.md | 693 +++ packages/commenting/package.json | 70 + .../commenting/scripts/copy-css-files.mjs | 28 + .../src/canvas/anchor-lifecycle.test.ts | 290 ++ .../commenting/src/canvas/anchor-lifecycle.ts | 190 + .../commenting/src/canvas/canvas-events.ts | 18 + packages/commenting/src/canvas/canvas.css | 557 +++ .../commenting/src/canvas/cluster-badge.tsx | 133 + .../commenting/src/canvas/cluster-fade.ts | 102 + .../src/canvas/cluster-input.test.ts | 365 ++ .../commenting/src/canvas/cluster-input.ts | 115 + .../src/canvas/cluster-model.test.ts | 151 + .../commenting/src/canvas/cluster-model.ts | 416 ++ .../commenting/src/canvas/comment-body.tsx | 21 + .../src/canvas/comment-drafts.test.ts | 55 + .../commenting/src/canvas/comment-drafts.ts | 46 + .../src/canvas/comment-mutations.test.ts | 452 ++ .../src/canvas/comment-mutations.ts | 299 ++ .../src/canvas/comment-reactions.test.ts | 154 + .../src/canvas/comment-reactions.tsx | 246 + .../src/canvas/comment-render.test.ts | 90 + .../commenting/src/canvas/comment-render.ts | 98 + .../commenting/src/canvas/comment-store.ts | 100 + .../src/canvas/comment-tool.test.ts | 267 ++ .../commenting/src/canvas/comment-tool.tsx | 294 ++ .../src/canvas/comments-filter-menu.tsx | 88 + .../src/canvas/comments-menu-item.tsx | 24 + .../src/canvas/comments-overflow-menu.tsx | 60 + .../src/canvas/comments-overlay.test.ts | 43 + .../src/canvas/comments-overlay.tsx | 363 ++ .../src/canvas/comments-sidebar.test.ts | 45 + .../src/canvas/comments-sidebar.tsx | 208 + .../src/canvas/comments-visibility-toggle.tsx | 25 + packages/commenting/src/canvas/context.ts | 48 + packages/commenting/src/canvas/hooks.test.ts | 94 + packages/commenting/src/canvas/hooks.ts | 83 + packages/commenting/src/canvas/license.ts | 17 + .../commenting/src/canvas/mobile-placement.ts | 115 + .../commenting/src/canvas/options.test.ts | 299 ++ packages/commenting/src/canvas/options.ts | 369 ++ .../src/canvas/pending-composer.tsx | 161 + .../src/canvas/pin-stacking.test.ts | 224 + .../commenting/src/canvas/pin-stacking.ts | 103 + packages/commenting/src/canvas/region-box.tsx | 124 + packages/commenting/src/canvas/rich-text.ts | 15 + .../commenting/src/canvas/sidebar-filters.ts | 26 + packages/commenting/src/canvas/state.ts | 151 + packages/commenting/src/canvas/thread-pin.tsx | 409 ++ .../src/canvas/thread-preview.test.ts | 91 + .../commenting/src/canvas/thread-preview.tsx | 294 ++ .../commenting/src/canvas/thread-stack.tsx | 238 + .../src/canvas/thread-state.test.ts | 295 ++ .../commenting/src/canvas/thread-state.ts | 252 ++ .../commenting/src/canvas/thread-view.test.ts | 72 + .../commenting/src/canvas/thread-view.tsx | 612 +++ .../clustering/computeClusterTable.test.ts | 300 ++ .../src/clustering/computeClusterTable.ts | 74 + .../src/clustering/locality.test.ts | 189 + .../commenting/src/clustering/mst.test.ts | 383 ++ packages/commenting/src/clustering/mst.ts | 134 + .../commenting/src/clustering/replay.test.ts | 540 +++ packages/commenting/src/clustering/replay.ts | 412 ++ .../commenting/src/clustering/runtime.test.ts | 850 ++++ packages/commenting/src/clustering/runtime.ts | 304 ++ .../src/clustering/schedule.test.ts | 508 +++ .../commenting/src/clustering/schedule.ts | 184 + .../src/clustering/screen-offsets.test.ts | 171 + packages/commenting/src/clustering/types.ts | 112 + packages/commenting/src/index.ts | 145 + packages/commenting/src/ui/byline.tsx | 35 + packages/commenting/src/ui/comment-card.tsx | 42 + .../commenting/src/ui/comment-composer.tsx | 299 ++ .../commenting/src/ui/comment-extensions.ts | 25 + packages/commenting/src/ui/comment-pin.tsx | 32 + packages/commenting/src/ui/comment-thread.tsx | 63 + .../commenting/src/ui/comments-list.test.ts | 31 + packages/commenting/src/ui/comments-list.tsx | 174 + packages/commenting/src/ui/comments.css | 935 ++++ packages/commenting/src/ui/count-badge.tsx | 16 + .../commenting/src/ui/emoji-picker.test.ts | 25 + packages/commenting/src/ui/emoji-picker.tsx | 80 + packages/commenting/src/ui/empty-state.tsx | 16 + .../commenting/src/ui/format-time.test.ts | 69 + packages/commenting/src/ui/format-time.ts | 67 + packages/commenting/src/ui/icons.tsx | 138 + .../commenting/src/ui/reaction-picker.test.ts | 36 + .../commenting/src/ui/reaction-picker.tsx | 113 + packages/commenting/src/ui/reaction.tsx | 123 + packages/commenting/src/ui/reactions.tsx | 74 + packages/commenting/src/ui/reply-count.ts | 16 + packages/commenting/src/ui/send-button.tsx | 25 + .../commenting/src/ui/visual-viewport.test.ts | 36 + packages/commenting/src/ui/visual-viewport.ts | 27 + packages/commenting/tsconfig.json | 30 + packages/commenting/vitest.config.ts | 6 + packages/create-tldraw/LICENSE.md | 1 + packages/create-tldraw/README.md | 94 + packages/create-tldraw/cli.cjs | 3 + packages/create-tldraw/package.json | 68 + packages/create-tldraw/scripts/build.sh | 12 + packages/create-tldraw/scripts/dev.sh | 10 + packages/create-tldraw/src/group-select.ts | 143 + packages/create-tldraw/src/main.ts | 310 ++ packages/create-tldraw/src/templates.ts | 68 + packages/create-tldraw/src/utils.test.ts | 128 + packages/create-tldraw/src/utils.ts | 129 + packages/create-tldraw/src/wrap-ansi.test.ts | 387 ++ packages/create-tldraw/src/wrap-ansi.ts | 279 ++ packages/create-tldraw/tsconfig.json | 7 + packages/create-tldraw/vitest.config.ts | 14 + packages/dotcom-shared/README.md | 23 + packages/dotcom-shared/package.json | 40 + packages/dotcom-shared/src/capabilities.ts | 13 + .../dotcom-shared/src/commentMentions.test.ts | 66 + packages/dotcom-shared/src/commentMentions.ts | 29 + packages/dotcom-shared/src/constants.ts | 15 + packages/dotcom-shared/src/index.test.ts | 3 + packages/dotcom-shared/src/index.ts | 13 + packages/dotcom-shared/src/license.ts | 4 + packages/dotcom-shared/src/mutators.test.ts | 1585 +++++++ packages/dotcom-shared/src/mutators.ts | 665 +++ packages/dotcom-shared/src/queries.test.ts | 72 + packages/dotcom-shared/src/queries.ts | 261 ++ packages/dotcom-shared/src/roles.test.ts | 59 + packages/dotcom-shared/src/roles.ts | 46 + packages/dotcom-shared/src/routes.ts | 56 + .../dotcom-shared/src/shapeClusters.test.ts | 333 ++ packages/dotcom-shared/src/shapeClusters.ts | 445 ++ .../dotcom-shared/src/thumbnailScreenshot.ts | 84 + packages/dotcom-shared/src/tlaSchema.ts | 551 +++ packages/dotcom-shared/src/types.ts | 516 +++ packages/dotcom-shared/tsconfig.json | 14 + packages/dotcom-shared/vitest.config.ts | 6 + packages/driver/LICENSE.md | 1 + packages/driver/README.md | 125 + packages/driver/api-extractor.json | 4 + packages/driver/api-report.api.md | 78 + packages/driver/package.json | 58 + packages/driver/src/index.ts | 10 + packages/driver/src/lib/Driver.ts | 730 +++ packages/driver/tsconfig.json | 10 + packages/driver/vitest.config.ts | 3 + packages/editor/LICENSE.md | 1 + packages/editor/README.md | 37 + packages/editor/api-extractor.json | 4 + packages/editor/editor.css | 1625 +++++++ packages/editor/modules.d.ts | 4 + packages/editor/package.json | 92 + packages/editor/setupTests.js | 28 + packages/editor/setupVitest.js | 66 + packages/editor/src/index.ts | 526 +++ packages/editor/src/lib/TldrawEditor.tsx | 853 ++++ .../src/lib/components/EditorPortal.tsx | 77 + .../src/lib/components/ErrorBoundary.tsx | 57 + .../src/lib/components/HTMLContainer.tsx | 14 + .../src/lib/components/LiveCollaborators.tsx | 133 + .../src/lib/components/MenuClickCapture.tsx | 259 ++ .../src/lib/components/SVGContainer.tsx | 14 + packages/editor/src/lib/components/Shape.tsx | 283 ++ .../default-components/CanvasOverlays.tsx | 206 + .../default-components/DefaultBackground.tsx | 4 + .../default-components/DefaultCanvas.tsx | 358 ++ .../default-components/DefaultCursor.tsx | 65 + .../DefaultErrorFallback.tsx | 240 + .../default-components/DefaultGrid.tsx | 47 + .../DefaultLoadingScreen.tsx | 11 + .../DefaultShapeErrorFallback.tsx | 10 + .../DefaultShapeWrapper.tsx | 35 + .../default-components/DefaultSpinner.tsx | 23 + .../default-components/DefaultSvgDefs.tsx | 4 + .../src/lib/config/TLEditorSnapshot.test.ts | 244 + .../editor/src/lib/config/TLEditorSnapshot.ts | 107 + .../src/lib/config/TLSessionStateSnapshot.ts | 332 ++ .../src/lib/config/TLUserPreferences.test.ts | 58 + .../src/lib/config/TLUserPreferences.ts | 286 ++ .../src/lib/config/createTLCurrentUser.ts | 57 + .../editor/src/lib/config/createTLStore.ts | 208 + .../editor/src/lib/config/defaultAssets.ts | 19 + .../editor/src/lib/config/defaultBindings.ts | 19 + .../editor/src/lib/config/defaultShapes.ts | 33 + packages/editor/src/lib/constants.ts | 41 + packages/editor/src/lib/editor/Editor.test.ts | 1436 ++++++ .../editor/src/lib/editor/assets/AssetUtil.ts | 85 + .../src/lib/editor/bindings/BindingUtil.ts | 278 ++ .../lib/editor/derivations/bindingsIndex.ts | 110 + .../editor/derivations/notVisibleShapes.ts | 72 + .../editor/derivations/parentsToChildren.ts | 123 + .../derivations/shapeIdsInCurrentPage.ts | 102 + .../ClickManager/ClickManager.test.ts | 410 ++ .../managers/ClickManager/ClickManager.ts | 176 + .../CollaboratorsManager.test.ts | 204 + .../CollaboratorsManager.ts | 134 + .../EdgeScrollManager.test.ts | 421 ++ .../EdgeScrollManager/EdgeScrollManager.ts | 147 + .../lib/editor/managers/EditorManager.test.ts | 82 + .../src/lib/editor/managers/EditorManager.ts | 72 + .../FocusManager/FocusManager.test.ts | 465 ++ .../managers/FocusManager/FocusManager.ts | 89 + .../managers/FontManager/FontManager.test.ts | 406 ++ .../managers/FontManager/FontManager.ts | 267 ++ .../HistoryManager/HistoryManager.test.ts | 910 ++++ .../managers/HistoryManager/HistoryManager.ts | 432 ++ .../InputsManager/InputsManager.test.ts | 257 ++ .../managers/InputsManager/InputsManager.ts | 715 +++ .../PerformanceApiAdapter.ts | 82 + .../PerformanceManager.test.ts | 602 +++ .../PerformanceManager/PerformanceManager.ts | 556 +++ .../managers/PerformanceManager/perf-types.ts | 196 + .../ScribbleManager/ScribbleManager.ts | 581 +++ .../managers/SnapManager/BoundsSnaps.ts | 1264 ++++++ .../managers/SnapManager/HandleSnaps.ts | 298 ++ .../managers/SnapManager/SnapManager.test.ts | 528 +++ .../managers/SnapManager/SnapManager.ts | 111 + .../SpatialIndexManager/RBushIndex.ts | 129 + .../SpatialIndexManager.ts | 335 ++ .../managers/TextManager/TextManager.test.ts | 623 +++ .../managers/TextManager/TextManager.ts | 476 ++ .../ThemeManager/ThemeManager.test.ts | 53 + .../managers/ThemeManager/ThemeManager.ts | 122 + .../managers/ThemeManager/defaultThemes.ts | 619 +++ .../managers/TickManager/TickManager.test.ts | 211 + .../managers/TickManager/TickManager.ts | 60 + .../UserPreferencesManager.test.ts | 731 +++ .../UserPreferencesManager.ts | 187 + .../src/lib/editor/overlays/OverlayManager.ts | 185 + .../src/lib/editor/overlays/OverlayUtil.ts | 148 + .../overlays/getOverlayDisplayValues.ts | 51 + .../editor/overlays/strokeShapeIndicators.ts | 85 + .../lib/editor/shapes/BaseBoxShapeUtil.tsx | 39 + .../editor/shapes/BaseFrameLikeShapeUtil.tsx | 137 + .../editor/src/lib/editor/shapes/ShapeUtil.ts | 1155 +++++ .../editor/shapes/group/DashedOutlineBox.tsx | 37 + .../editor/shapes/group/GroupShapeUtil.tsx | 156 + .../shapes/shared/getPerfectDashProps.ts | 118 + .../src/lib/editor/shapes/shared/resizeBox.ts | 129 + .../lib/editor/shapes/shared/resizeScaled.ts | 61 + .../BaseBoxShapeTool/BaseBoxShapeTool.ts | 18 + .../tools/BaseBoxShapeTool/children/Idle.ts | 18 + .../BaseBoxShapeTool/children/Pointing.ts | 164 + .../editor/src/lib/editor/tools/RootState.ts | 9 + .../src/lib/editor/tools/StateNode.test.ts | 349 ++ .../editor/src/lib/editor/tools/StateNode.ts | 293 ++ .../src/lib/editor/types/SvgExportContext.tsx | 127 + .../src/lib/editor/types/clipboard-types.ts | 12 + .../editor/src/lib/editor/types/emit-types.ts | 31 + .../src/lib/editor/types/event-types.ts | 215 + .../src/lib/editor/types/external-content.ts | 133 + .../src/lib/editor/types/history-types.ts | 27 + .../editor/src/lib/editor/types/misc-types.ts | 261 ++ .../src/lib/editor/types/selection-types.ts | 10 + .../editor/src/lib/exports/ExportDelay.tsx | 62 + .../src/lib/exports/FontEmbedder.test.ts | 99 + .../editor/src/lib/exports/FontEmbedder.ts | 151 + .../editor/src/lib/exports/StyleEmbedder.ts | 364 ++ packages/editor/src/lib/exports/cssRules.ts | 126 + packages/editor/src/lib/exports/domUtils.ts | 71 + packages/editor/src/lib/exports/embedMedia.ts | 94 + .../editor/src/lib/exports/exportToSvg.tsx | 137 + .../editor/src/lib/exports/fetchCache.test.ts | 22 + packages/editor/src/lib/exports/fetchCache.ts | 31 + .../editor/src/lib/exports/getSvgAsImage.ts | 360 ++ .../editor/src/lib/exports/getSvgJsx.test.ts | 905 ++++ packages/editor/src/lib/exports/getSvgJsx.tsx | 554 +++ .../editor/src/lib/exports/parseCss.test.ts | 372 ++ packages/editor/src/lib/exports/parseCss.ts | 112 + .../editor/src/lib/globals/editors.test.ts | 76 + packages/editor/src/lib/globals/editors.ts | 53 + .../editor/src/lib/globals/environment.ts | 109 + packages/editor/src/lib/globals/menus.test.ts | 33 + packages/editor/src/lib/globals/menus.ts | 203 + packages/editor/src/lib/globals/time.ts | 8 + .../src/lib/hooks/EditorComponentsContext.tsx | 37 + .../editor/src/lib/hooks/useCanvasEvents.ts | 303 ++ .../editor/src/lib/hooks/useCoarsePointer.ts | 23 + packages/editor/src/lib/hooks/useColorMode.ts | 17 + .../editor/src/lib/hooks/useContainer.tsx | 28 + packages/editor/src/lib/hooks/useCursor.ts | 86 + packages/editor/src/lib/hooks/useDarkMode.ts | 30 + .../editor/src/lib/hooks/useDocumentEvents.ts | 351 ++ packages/editor/src/lib/hooks/useEditor.tsx | 37 + .../src/lib/hooks/useEditorComponents.tsx | 53 + packages/editor/src/lib/hooks/useEvent.tsx | 73 + .../useFixSafariDoubleTapZoomPencilEvents.ts | 42 + .../editor/src/lib/hooks/useForceUpdate.ts | 7 + .../editor/src/lib/hooks/useGestureEvents.ts | 401 ++ .../src/lib/hooks/useGlobalMenuIsOpen.ts | 63 + packages/editor/src/lib/hooks/useIdentity.tsx | 62 + .../editor/src/lib/hooks/useIsCropping.ts | 9 + packages/editor/src/lib/hooks/useIsEditing.ts | 9 + .../editor/src/lib/hooks/useLocalStore.ts | 93 + .../lib/hooks/usePassThroughWheelEvents.ts | 103 + packages/editor/src/lib/hooks/usePeerIds.ts | 26 + packages/editor/src/lib/hooks/usePresence.ts | 22 + packages/editor/src/lib/hooks/useRefState.ts | 55 + packages/editor/src/lib/hooks/useSafeId.tsx | 62 + .../editor/src/lib/hooks/useScreenBounds.ts | 82 + .../editor/src/lib/hooks/useShapeCulling.tsx | 100 + .../editor/src/lib/hooks/useStateAttribute.ts | 18 + packages/editor/src/lib/hooks/useTLStore.ts | 34 + packages/editor/src/lib/hooks/useTransform.ts | 38 + .../editor/src/lib/hooks/useViewportHeight.ts | 47 + packages/editor/src/lib/hooks/useZoomCss.ts | 27 + .../src/lib/license/LicenseManager.test.ts | 1402 ++++++ .../editor/src/lib/license/LicenseManager.ts | 679 +++ .../src/lib/license/LicenseProvider.test.tsx | 76 + .../src/lib/license/LicenseProvider.tsx | 129 + .../editor/src/lib/license/Watermark.test.tsx | 32 + packages/editor/src/lib/license/Watermark.tsx | 258 ++ .../src/lib/license/useLicenseManagerState.ts | 25 + packages/editor/src/lib/options.ts | 356 ++ .../editor/src/lib/primitives/Box.test.ts | 769 ++++ packages/editor/src/lib/primitives/Box.ts | 703 +++ .../editor/src/lib/primitives/Mat.test.ts | 46 + packages/editor/src/lib/primitives/Mat.ts | 316 ++ .../editor/src/lib/primitives/Vec.test.ts | 397 ++ packages/editor/src/lib/primitives/Vec.ts | 656 +++ packages/editor/src/lib/primitives/easings.ts | 33 + .../src/lib/primitives/geometry/Arc2d.test.ts | 237 + .../src/lib/primitives/geometry/Arc2d.ts | 114 + .../lib/primitives/geometry/Circle2d.test.ts | 207 + .../src/lib/primitives/geometry/Circle2d.ts | 99 + .../primitives/geometry/CubicBezier2d.test.ts | 188 + .../lib/primitives/geometry/CubicBezier2d.ts | 112 + .../primitives/geometry/CubicSpline2d.test.ts | 162 + .../lib/primitives/geometry/CubicSpline2d.ts | 103 + .../lib/primitives/geometry/Edge2d.test.ts | 23 + .../src/lib/primitives/geometry/Edge2d.ts | 73 + .../lib/primitives/geometry/Ellipse2d.test.ts | 245 + .../src/lib/primitives/geometry/Ellipse2d.ts | 130 + .../primitives/geometry/Geometry2d.test.ts | 1035 +++++ .../src/lib/primitives/geometry/Geometry2d.ts | 579 +++ .../lib/primitives/geometry/Group2d.test.ts | 421 ++ .../src/lib/primitives/geometry/Group2d.ts | 295 ++ .../lib/primitives/geometry/Point2d.test.ts | 16 + .../src/lib/primitives/geometry/Point2d.ts | 33 + .../lib/primitives/geometry/Polygon2d.test.ts | 5 + .../src/lib/primitives/geometry/Polygon2d.ts | 15 + .../primitives/geometry/Polyline2d.test.ts | 207 + .../src/lib/primitives/geometry/Polyline2d.ts | 131 + .../primitives/geometry/Rectangle2d.test.ts | 5 + .../lib/primitives/geometry/Rectangle2d.ts | 58 + .../lib/primitives/geometry/Stadium2d.test.ts | 193 + .../src/lib/primitives/geometry/Stadium2d.ts | 126 + .../primitives/geometry/geometry-constants.ts | 7 + .../src/lib/primitives/intersect.test.ts | 946 ++++ .../editor/src/lib/primitives/intersect.ts | 382 ++ .../editor/src/lib/primitives/utils.test.ts | 68 + packages/editor/src/lib/primitives/utils.ts | 495 +++ .../src/lib/test/ContentElementSlot.test.tsx | 201 + .../editor/src/lib/test/EditorPortal.test.tsx | 48 + .../src/lib/test/InFrontOfTheCanvas.test.tsx | 187 + packages/editor/src/lib/test/TestEditor.ts | 31 + .../src/lib/test/preserveFocus.test.tsx | 81 + .../src/lib/test/useCanvasEvents.test.tsx | 74 + .../src/lib/test/useDocumentEvents.test.tsx | 107 + .../test/usePassThroughWheelEvents.test.tsx | 100 + packages/editor/src/lib/test/user.test.ts | 25 + packages/editor/src/lib/utils/EditorAtom.ts | 37 + .../editor/src/lib/utils/SharedStylesMap.ts | 122 + .../src/lib/utils/areShapesContentEqual.ts | 11 + packages/editor/src/lib/utils/assets.ts | 26 + .../src/lib/utils/browserCanvasMaxSize.ts | 171 + .../src/lib/utils/collaborators.test.ts | 34 + .../editor/src/lib/utils/collaborators.ts | 25 + packages/editor/src/lib/utils/debug-flags.ts | 189 + .../editor/src/lib/utils/deepLinks.test.ts | 102 + packages/editor/src/lib/utils/deepLinks.ts | 133 + packages/editor/src/lib/utils/dom.test.ts | 103 + packages/editor/src/lib/utils/dom.ts | 187 + .../src/lib/utils/getHtmlLayerTransform.ts | 22 + .../src/lib/utils/getIncrementedName.ts | 22 + .../editor/src/lib/utils/getPointerInfo.ts | 25 + .../src/lib/utils/getSvgPathFromPoints.ts | 49 + packages/editor/src/lib/utils/keyboard.ts | 10 + packages/editor/src/lib/utils/licensing.ts | 30 + .../src/lib/utils/normalizeWheel.test.ts | 39 + .../editor/src/lib/utils/normalizeWheel.ts | 31 + packages/editor/src/lib/utils/pointer.test.ts | 76 + packages/editor/src/lib/utils/pointer.ts | 42 + .../editor/src/lib/utils/reorderShapes.ts | 297 ++ packages/editor/src/lib/utils/reparenting.ts | 335 ++ packages/editor/src/lib/utils/richText.ts | 78 + packages/editor/src/lib/utils/rotation.ts | 120 + packages/editor/src/lib/utils/runtime.ts | 48 + .../src/lib/utils/sync/LocalIndexedDb.test.ts | 362 ++ .../src/lib/utils/sync/LocalIndexedDb.ts | 343 ++ .../src/lib/utils/sync/StoreWithStatus.ts | 30 + .../lib/utils/sync/TLLocalSyncClient.test.ts | 486 ++ .../src/lib/utils/sync/TLLocalSyncClient.ts | 476 ++ packages/editor/src/lib/utils/sync/alerts.ts | 20 + .../editor/src/lib/utils/sync/hardReset.ts | 21 + packages/editor/src/lib/utils/uniq.ts | 14 + packages/editor/src/lib/watermarks.ts | 8 + packages/editor/src/version.ts | 9 + packages/editor/tsconfig.json | 26 + packages/editor/vitest.config.ts | 26 + packages/mentions/LICENSE.md | 1 + packages/mentions/README.md | 16 + packages/mentions/api-extractor.json | 4 + packages/mentions/api-report.api.md | 92 + packages/mentions/mentions.css | 109 + packages/mentions/package.json | 67 + packages/mentions/src/avatar.tsx | 35 + packages/mentions/src/comment-author.ts | 15 + packages/mentions/src/index.ts | 25 + .../mentions/src/mention-extension.test.ts | 41 + packages/mentions/src/mention-extension.ts | 51 + packages/mentions/src/mention-list.tsx | 98 + .../mentions/src/mention-suggestion.test.ts | 18 + packages/mentions/src/mention-suggestion.tsx | 260 ++ packages/mentions/src/mention.tsx | 9 + packages/mentions/tsconfig.json | 24 + packages/mentions/vitest.config.ts | 6 + packages/mermaid/LICENSE.md | 1 + packages/mermaid/README.md | 214 + packages/mermaid/api-extractor.json | 4 + packages/mermaid/api-report.api.md | 225 + packages/mermaid/package.json | 67 + packages/mermaid/src/blueprint.ts | 132 + packages/mermaid/src/colors.ts | 392 ++ .../mermaid/src/createMermaidDiagram.test.ts | 73 + packages/mermaid/src/createMermaidDiagram.ts | 184 + .../src/defaultMermaidNodeRenderSpec.ts | 109 + packages/mermaid/src/flowchartDiagram.ts | 217 + packages/mermaid/src/index.ts | 30 + packages/mermaid/src/mermaidDiagrams.test.ts | 1896 ++++++++ .../src/mermaidNodeCreateShape.test.ts | 79 + .../mermaid/src/mermaidNodeCreateShape.ts | 96 + packages/mermaid/src/mindmapDiagram.ts | 112 + packages/mermaid/src/renderBlueprint.test.ts | 101 + packages/mermaid/src/renderBlueprint.ts | 322 ++ packages/mermaid/src/sequenceDiagram.ts | 1129 +++++ packages/mermaid/src/stateDiagram.ts | 391 ++ packages/mermaid/src/svgParsing.test.ts | 348 ++ packages/mermaid/src/svgParsing.ts | 392 ++ packages/mermaid/src/utils.ts | 103 + packages/mermaid/tsconfig.json | 7 + packages/mermaid/vitest.config.ts | 11 + packages/namespaced-tldraw/LICENSE.md | 1 + packages/namespaced-tldraw/README.md | 35 + packages/namespaced-tldraw/api-extractor.json | 20 + packages/namespaced-tldraw/api-report.api.md | 12 + packages/namespaced-tldraw/package.json | 73 + .../scripts/copy-css-files.mjs | 30 + packages/namespaced-tldraw/src/index.test.ts | 10 + packages/namespaced-tldraw/src/index.ts | 9 + packages/namespaced-tldraw/tsconfig.json | 7 + packages/namespaced-tldraw/vitest.config.ts | 6 + packages/state-react/DOCS.md | 819 ++++ packages/state-react/LICENSE.md | 9 + packages/state-react/README.md | 33 + packages/state-react/api-extractor.json | 4 + packages/state-react/api-report.api.md | 44 + packages/state-react/package.json | 77 + packages/state-react/src/index.ts | 14 + packages/state-react/src/lib/track.test.tsx | 192 + packages/state-react/src/lib/track.ts | 123 + packages/state-react/src/lib/useAtom.test.tsx | 51 + packages/state-react/src/lib/useAtom.ts | 35 + .../state-react/src/lib/useComputed.test.tsx | 117 + packages/state-react/src/lib/useComputed.ts | 91 + .../src/lib/useQuickReactor.test.tsx | 405 ++ .../state-react/src/lib/useQuickReactor.ts | 54 + .../state-react/src/lib/useReactor.test.tsx | 128 + packages/state-react/src/lib/useReactor.ts | 93 + .../src/lib/useStateTracking.test.tsx | 158 + .../state-react/src/lib/useStateTracking.ts | 85 + .../state-react/src/lib/useValue.test.tsx | 209 + packages/state-react/src/lib/useValue.ts | 108 + packages/state-react/tsconfig.json | 7 + packages/state-react/vitest.config.ts | 6 + packages/state/ARCHITECTURE.md | 298 ++ packages/state/DOCS.md | 564 +++ packages/state/LICENSE.md | 9 + packages/state/README.md | 295 ++ packages/state/SPEC.md | 171 + packages/state/api-extractor.json | 4 + packages/state/api-report.api.md | 207 + packages/state/docs-ordering.json | 5 + packages/state/package.json | 68 + packages/state/src/index.ts | 41 + packages/state/src/lib/ArraySet.ts | 173 + packages/state/src/lib/Atom.ts | 283 ++ packages/state/src/lib/Computed.ts | 659 +++ packages/state/src/lib/EffectScheduler.ts | 407 ++ packages/state/src/lib/HistoryBuffer.ts | 163 + .../state/src/lib/__tests__/ArraySet.test.ts | 240 + .../src/lib/__tests__/EffectScheduler.test.ts | 472 ++ .../src/lib/__tests__/HistoryBuffer.test.ts | 76 + packages/state/src/lib/__tests__/atom.test.ts | 203 + .../state/src/lib/__tests__/capture.test.ts | 359 ++ .../state/src/lib/__tests__/computed.test.ts | 411 ++ .../state/src/lib/__tests__/debug.test.ts | 84 + .../lib/__tests__/deferAsyncEffects.test.ts | 255 ++ .../state/src/lib/__tests__/errors.test.ts | 217 + .../src/lib/__tests__/fuzz.tlstate.test.ts | 464 ++ .../state/src/lib/__tests__/guards.test.ts | 49 + .../state/src/lib/__tests__/helpers.test.ts | 152 + .../state/src/lib/__tests__/history.test.ts | 554 +++ .../lib/__tests__/localStorageAtom.test.ts | 278 ++ .../src/lib/__tests__/propagation.test.ts | 477 ++ .../src/lib/__tests__/transactions.test.ts | 265 ++ packages/state/src/lib/capture.ts | 275 ++ packages/state/src/lib/constants.ts | 7 + packages/state/src/lib/helpers.ts | 115 + packages/state/src/lib/isComputed.ts | 20 + packages/state/src/lib/isSignal.ts | 34 + packages/state/src/lib/localStorageAtom.ts | 94 + packages/state/src/lib/transactions.ts | 416 ++ packages/state/src/lib/types.ts | 228 + packages/state/src/lib/warnings.ts | 50 + packages/state/tsconfig.json | 7 + packages/state/vitest.config.ts | 6 + packages/store/DOCS.md | 790 ++++ packages/store/LICENSE.md | 9 + packages/store/README.md | 366 ++ packages/store/SPEC.md | 243 + packages/store/api-extractor.json | 4 + packages/store/api-report.api.md | 707 +++ packages/store/package.json | 67 + packages/store/setupTests.js | 1 + packages/store/src/index.ts | 77 + packages/store/src/lib/AtomMap.test.ts | 663 +++ packages/store/src/lib/AtomMap.ts | 465 ++ packages/store/src/lib/AtomSet.test.ts | 116 + packages/store/src/lib/AtomSet.ts | 52 + packages/store/src/lib/BaseRecord.test.ts | 32 + packages/store/src/lib/BaseRecord.ts | 136 + packages/store/src/lib/ImmutableMap.test.ts | 179 + packages/store/src/lib/ImmutableMap.ts | 1167 +++++ .../src/lib/IncrementalSetConstructor.test.ts | 116 + .../src/lib/IncrementalSetConstructor.ts | 191 + packages/store/src/lib/RecordType.test.ts | 216 + packages/store/src/lib/RecordType.ts | 379 ++ packages/store/src/lib/RecordsDiff.test.ts | 177 + packages/store/src/lib/RecordsDiff.ts | 347 ++ packages/store/src/lib/Store.test.ts | 767 ++++ packages/store/src/lib/Store.ts | 1467 ++++++ packages/store/src/lib/StoreListeners.test.ts | 516 +++ packages/store/src/lib/StoreQueries.test.ts | 892 ++++ packages/store/src/lib/StoreQueries.ts | 635 +++ packages/store/src/lib/StoreSchema.test.ts | 1109 +++++ packages/store/src/lib/StoreSchema.ts | 813 ++++ .../store/src/lib/StoreSideEffects.test.ts | 725 +++ packages/store/src/lib/StoreSideEffects.ts | 684 +++ packages/store/src/lib/devFreeze.test.ts | 111 + packages/store/src/lib/devFreeze.ts | 52 + packages/store/src/lib/executeQuery.test.ts | 1451 ++++++ packages/store/src/lib/executeQuery.ts | 192 + packages/store/src/lib/isDev.ts | 20 + packages/store/src/lib/migrate.test.ts | 392 ++ packages/store/src/lib/migrate.ts | 557 +++ packages/store/src/lib/setUtils.test.ts | 64 + packages/store/src/lib/setUtils.ts | 87 + .../src/lib/test/recordStoreFuzzing.test.ts | 511 +++ packages/store/src/lib/test/testSchema.v0.ts | 83 + packages/store/src/lib/test/testSchema.v1.ts | 225 + packages/store/tsconfig.json | 7 + packages/store/vitest.config.ts | 14 + packages/sync-collaboration/LICENSE.md | 1 + packages/sync-collaboration/README.md | 5 + .../sync-collaboration/api-extractor.json | 4 + packages/sync-collaboration/api-report.api.md | 55 + packages/sync-collaboration/package.json | 52 + .../src/comment-authorizers.test.ts | 925 ++++ .../src/comment-authorizers.ts | 354 ++ packages/sync-collaboration/src/index.ts | 16 + packages/sync-collaboration/tsconfig.json | 23 + packages/sync-collaboration/vitest.config.ts | 6 + packages/sync-core/DOCS.md | 662 +++ packages/sync-core/LICENSE.md | 1 + packages/sync-core/README.md | 37 + packages/sync-core/SPEC.md | 289 ++ packages/sync-core/api-extractor.json | 4 + packages/sync-core/api-report.api.md | 886 ++++ packages/sync-core/package.json | 83 + packages/sync-core/setupVitest.js | 44 + packages/sync-core/src/index.ts | 93 + .../src/lib/ClientWebSocketAdapter.test.ts | 1001 +++++ .../src/lib/ClientWebSocketAdapter.ts | 765 ++++ .../DurableObjectSqliteSyncWrapper.test.ts | 102 + .../src/lib/DurableObjectSqliteSyncWrapper.ts | 94 + .../src/lib/InMemorySyncStorage.test.ts | 315 ++ .../sync-core/src/lib/InMemorySyncStorage.ts | 452 ++ .../src/lib/MicrotaskNotifier.test.ts | 254 ++ .../sync-core/src/lib/MicrotaskNotifier.ts | 38 + .../src/lib/NodeSqliteWrapper.test.ts | 305 ++ .../sync-core/src/lib/NodeSqliteWrapper.ts | 102 + packages/sync-core/src/lib/RoomSession.ts | 148 + .../src/lib/SQLiteSyncStorage.test.ts | 325 ++ .../sync-core/src/lib/SQLiteSyncStorage.ts | 749 ++++ .../src/lib/ServerSocketAdapter.test.ts | 89 + .../sync-core/src/lib/ServerSocketAdapter.ts | 171 + .../sync-core/src/lib/TLRemoteSyncError.ts | 58 + packages/sync-core/src/lib/TLSocketRoom.ts | 1114 +++++ .../sync-core/src/lib/TLSyncClient.test.ts | 1773 ++++++++ packages/sync-core/src/lib/TLSyncClient.ts | 1027 +++++ packages/sync-core/src/lib/TLSyncRoom.ts | 1700 +++++++ .../sync-core/src/lib/TLSyncStorage.test.ts | 262 ++ packages/sync-core/src/lib/TLSyncStorage.ts | 233 + packages/sync-core/src/lib/chunk.test.ts | 459 ++ packages/sync-core/src/lib/chunk.ts | 216 + packages/sync-core/src/lib/diff.test.ts | 885 ++++ packages/sync-core/src/lib/diff.ts | 402 ++ packages/sync-core/src/lib/interval.test.ts | 43 + packages/sync-core/src/lib/interval.ts | 44 + packages/sync-core/src/lib/protocol.test.ts | 43 + packages/sync-core/src/lib/protocol.ts | 290 ++ packages/sync-core/src/lib/recordDiff.test.ts | 159 + packages/sync-core/src/lib/recordDiff.ts | 73 + packages/sync-core/src/lib/server-types.ts | 52 + packages/sync-core/src/test/FuzzEditor.ts | 406 ++ packages/sync-core/src/test/RandomSource.ts | 46 + .../sync-core/src/test/TLSocketRoom.test.ts | 1852 ++++++++ .../src/test/TLSyncClientRebase.test.ts | 285 ++ .../sync-core/src/test/TLSyncRoom.test.ts | 2493 +++++++++++ packages/sync-core/src/test/TestServer.ts | 56 + packages/sync-core/src/test/TestSocketPair.ts | 128 + .../sync-core/src/test/objectStore.test.ts | 714 +++ .../src/test/storageContractSuite.ts | 719 +++ packages/sync-core/src/test/syncFuzz.test.ts | 310 ++ .../src/test/upgradeDowngrade.test.ts | 1329 ++++++ packages/sync-core/tsconfig.json | 14 + packages/sync-core/vitest.config.ts | 10 + packages/sync/DOCS.md | 637 +++ packages/sync/LICENSE.md | 1 + packages/sync/README.md | 37 + packages/sync/api-extractor.json | 4 + packages/sync/api-report.api.md | 95 + packages/sync/package.json | 78 + packages/sync/setupVitest.js | 3 + packages/sync/src/index.test.ts | 3 + packages/sync/src/index.ts | 20 + packages/sync/src/useSync.test.tsx | 95 + packages/sync/src/useSync.ts | 604 +++ packages/sync/src/useSyncDemo.test.ts | 202 + packages/sync/src/useSyncDemo.ts | 309 ++ packages/sync/tsconfig.json | 13 + packages/sync/vitest.config.ts | 10 + packages/tldraw/LICENSE.md | 1 + packages/tldraw/README.md | 79 + packages/tldraw/api-extractor.json | 4 + packages/tldraw/package.json | 103 + packages/tldraw/scripts/copy-css-files.mjs | 27 + packages/tldraw/setupVitest.js | 194 + packages/tldraw/src/index.ts | 920 ++++ packages/tldraw/src/lib/Tldraw.test.tsx | 325 ++ packages/tldraw/src/lib/Tldraw.tsx | 385 ++ packages/tldraw/src/lib/TldrawImage.tsx | 237 + .../src/lib/assets/BookmarkAssetUtil.ts | 23 + .../src/lib/assets/ImageAssetUtil.test.ts | 116 + .../tldraw/src/lib/assets/ImageAssetUtil.ts | 77 + .../tldraw/src/lib/assets/VideoAssetUtil.ts | 64 + .../lib/bindings/arrow/ArrowBindingUtil.ts | 406 ++ packages/tldraw/src/lib/defaultAssetUtils.ts | 6 + .../tldraw/src/lib/defaultBindingUtils.ts | 4 + .../tldraw/src/lib/defaultEmbedDefinitions.ts | 788 ++++ .../defaultExternalContentHandlers.test.ts | 328 ++ .../src/lib/defaultExternalContentHandlers.ts | 970 ++++ .../tldraw/src/lib/defaultOverlayUtils.ts | 30 + packages/tldraw/src/lib/defaultShapeTools.ts | 20 + packages/tldraw/src/lib/defaultShapeUtils.ts | 28 + packages/tldraw/src/lib/defaultSideEffects.ts | 99 + packages/tldraw/src/lib/defaultTools.ts | 8 + .../overlays/ArrowBindingHintOverlayUtil.ts | 258 ++ .../src/lib/overlays/ArrowHintOverlayUtil.ts | 215 + .../src/lib/overlays/BrushOverlayUtil.ts | 108 + .../overlays/CollaboratorBrushOverlayUtil.ts | 80 + .../overlays/CollaboratorCursorOverlayUtil.ts | 312 ++ .../overlays/CollaboratorHintOverlayUtil.ts | 96 + .../CollaboratorScribbleOverlayUtil.ts | 122 + .../CollaboratorShapeIndicatorOverlayUtil.ts | 85 + .../src/lib/overlays/ScribbleOverlayUtil.ts | 143 + .../SelectionForegroundOverlayUtil.ts | 700 +++ .../lib/overlays/ShapeHandleOverlayUtil.ts | 211 + .../lib/overlays/ShapeIndicatorOverlayUtil.ts | 133 + .../lib/overlays/SnapIndicatorOverlayUtil.ts | 195 + .../src/lib/overlays/ZoomBrushOverlayUtil.ts | 75 + .../tldraw/src/lib/shapes/arrow/ArrowPath.tsx | 73 + .../shapes/arrow/ArrowShapeOptions.test.ts | 305 ++ .../lib/shapes/arrow/ArrowShapeTool.test.ts | 807 ++++ .../src/lib/shapes/arrow/ArrowShapeTool.ts | 14 + .../lib/shapes/arrow/ArrowShapeUtil.test.ts | 1135 +++++ .../src/lib/shapes/arrow/ArrowShapeUtil.tsx | 1281 ++++++ .../src/lib/shapes/arrow/arrow-types.ts | 178 + .../tldraw/src/lib/shapes/arrow/arrowLabel.ts | 324 ++ .../src/lib/shapes/arrow/arrowTargetState.ts | 398 ++ .../tldraw/src/lib/shapes/arrow/arrowheads.ts | 163 + .../src/lib/shapes/arrow/curved-arrow.ts | 484 ++ .../shapes/arrow/elbow/ElbowArrowDebug.tsx | 215 + .../src/lib/shapes/arrow/elbow/definitions.ts | 350 ++ .../arrow/elbow/elbowArrowSnapLines.tsx | 129 + .../arrow/elbow/getElbowArrowInfo.test.ts | 80 + .../shapes/arrow/elbow/getElbowArrowInfo.tsx | 901 ++++ .../src/lib/shapes/arrow/elbow/range.tsx | 81 + .../elbow/routes/ElbowArrowRouteBuilder.ts | 93 + .../routes/ElbowArrowWorkingInfo.test.ts | 44 + .../elbow/routes/ElbowArrowWorkingInfo.ts | 233 + .../arrow/elbow/routes/elbowArrowRoutes.tsx | 403 ++ .../routes/routeArrowWithAutoEdgePicking.tsx | 241 + .../src/lib/shapes/arrow/getArrowInfo.ts | 69 + .../tldraw/src/lib/shapes/arrow/shared.ts | 302 ++ .../src/lib/shapes/arrow/straight-arrow.ts | 284 ++ .../src/lib/shapes/arrow/toolStates/Idle.tsx | 80 + .../lib/shapes/arrow/toolStates/Pointing.tsx | 206 + .../lib/shapes/bookmark/BookmarkShapeUtil.tsx | 258 ++ .../src/lib/shapes/bookmark/bookmarks.ts | 267 ++ .../src/lib/shapes/draw/DrawShapeTool.test.ts | 277 ++ .../src/lib/shapes/draw/DrawShapeTool.ts | 21 + .../src/lib/shapes/draw/DrawShapeUtil.test.ts | 212 + .../src/lib/shapes/draw/DrawShapeUtil.tsx | 404 ++ .../tldraw/src/lib/shapes/draw/getPath.ts | 167 + .../src/lib/shapes/draw/toolStates/Drawing.ts | 792 ++++ .../src/lib/shapes/draw/toolStates/Idle.ts | 22 + .../src/lib/shapes/embed/EmbedShapeUtil.tsx | 470 ++ .../lib/shapes/frame/FrameShapeTool.test.ts | 186 + .../src/lib/shapes/frame/FrameShapeTool.ts | 66 + .../src/lib/shapes/frame/FrameShapeUtil.tsx | 417 ++ .../shapes/frame/components/FrameHeading.tsx | 80 + .../frame/components/FrameLabelInput.tsx | 114 + .../src/lib/shapes/frame/frameHelpers.ts | 121 + .../src/lib/shapes/geo/GeoShapeBody.tsx | 55 + .../src/lib/shapes/geo/GeoShapeTool.test.ts | 268 ++ .../tldraw/src/lib/shapes/geo/GeoShapeTool.ts | 13 + .../src/lib/shapes/geo/GeoShapeUtil.test.tsx | 418 ++ .../src/lib/shapes/geo/GeoShapeUtil.tsx | 1004 +++++ .../src/lib/shapes/geo/getGeoShapePath.ts | 719 +++ .../src/lib/shapes/geo/toolStates/Idle.ts | 27 + .../src/lib/shapes/geo/toolStates/Pointing.ts | 146 + .../highlight/HighlightShapeTool.test.ts | 3 + .../shapes/highlight/HighlightShapeTool.ts | 21 + .../highlight/HighlightShapeUtil.test.ts | 188 + .../shapes/highlight/HighlightShapeUtil.tsx | 357 ++ .../src/lib/shapes/image/ImageAlphaCache.ts | 168 + .../lib/shapes/image/ImageAlphaGeometry.ts | 61 + .../src/lib/shapes/image/ImageShapeUtil.tsx | 655 +++ .../src/lib/shapes/line/LineShapeTool.test.ts | 293 ++ .../src/lib/shapes/line/LineShapeTool.ts | 14 + .../lib/shapes/line/LineShapeUtil.test.tsx | 531 +++ .../src/lib/shapes/line/LineShapeUtil.tsx | 424 ++ .../__snapshots__/LineShapeUtil.test.tsx.snap | 38 + .../src/lib/shapes/line/toolStates/Idle.ts | 20 + .../lib/shapes/line/toolStates/Pointing.ts | 172 + .../note/DefaultNoteShapeAttribution.tsx | 84 + .../src/lib/shapes/note/NoteShapeTool.test.ts | 339 ++ .../src/lib/shapes/note/NoteShapeTool.ts | 13 + .../src/lib/shapes/note/NoteShapeUtil.tsx | 795 ++++ .../src/lib/shapes/note/noteCloning.test.ts | 447 ++ .../tldraw/src/lib/shapes/note/noteHelpers.ts | 291 ++ .../src/lib/shapes/note/toolStates/Idle.ts | 17 + .../lib/shapes/note/toolStates/Pointing.ts | 204 + .../src/lib/shapes/shared/BrokenAssetIcon.tsx | 18 + .../src/lib/shapes/shared/HyperlinkButton.tsx | 40 + .../lib/shapes/shared/PathBuilder.test.tsx | 176 + .../src/lib/shapes/shared/PathBuilder.tsx | 1196 +++++ .../src/lib/shapes/shared/PatternFill.tsx | 56 + .../src/lib/shapes/shared/PlainTextLabel.tsx | 143 + .../src/lib/shapes/shared/RichTextLabel.tsx | 290 ++ .../src/lib/shapes/shared/TextHelpers.ts | 19 + .../shapes/shared/createTextJsxFromSpans.tsx | 98 + packages/tldraw/src/lib/shapes/shared/crop.ts | 762 ++++ .../shapes/shared/default-shape-constants.ts | 63 + .../src/lib/shapes/shared/defaultFills.ts | 11 + .../src/lib/shapes/shared/defaultFonts.tsx | 169 + .../lib/shapes/shared/defaultStyleDefs.tsx | 318 ++ packages/tldraw/src/lib/shapes/shared/flip.ts | 59 + .../src/lib/shapes/shared/freehand/core.ts | 547 +++ .../src/lib/shapes/shared/freehand/fmt.ts | 106 + .../lib/shapes/shared/freehand/getStroke.ts | 23 + .../shared/freehand/getStrokeOutlinePoints.ts | 645 +++ .../shapes/shared/freehand/getStrokePoints.ts | 57 + .../src/lib/shapes/shared/freehand/svg.ts | 101 + .../src/lib/shapes/shared/freehand/svgInk.ts | 341 ++ .../src/lib/shapes/shared/freehand/types.ts | 48 + .../src/lib/shapes/shared/getDisplayValues.ts | 49 + .../src/lib/shapes/shared/icons-editor.ts | 2 + .../lib/shapes/shared/interpolate-props.ts | 49 + .../src/lib/shapes/shared/legacyProps.ts | 26 + .../lib/shapes/shared/rotated-box-shadow.ts | 29 + .../lib/shapes/shared/useEditablePlainText.ts | 177 + .../lib/shapes/shared/useEditableRichText.ts | 62 + .../shared/useEfficientZoomThreshold.ts | 10 + .../shared/useImageOrVideoAsset.test.tsx | 153 + .../lib/shapes/shared/useImageOrVideoAsset.ts | 200 + .../shapes/shared/usePrefersReducedMotion.tsx | 30 + .../src/lib/shapes/text/PlainTextArea.tsx | 62 + .../src/lib/shapes/text/RichTextArea.tsx | 325 ++ .../src/lib/shapes/text/TextShapeTool.test.ts | 328 ++ .../src/lib/shapes/text/TextShapeTool.ts | 13 + .../src/lib/shapes/text/TextShapeUtil.tsx | 409 ++ .../src/lib/shapes/text/toolStates/Idle.ts | 44 + .../lib/shapes/text/toolStates/Pointing.ts | 205 + .../src/lib/shapes/video/VideoShapeUtil.tsx | 245 + packages/tldraw/src/lib/styles.tsx | 170 + .../src/lib/tools/EraserTool/EraserTool.ts | 35 + .../tools/EraserTool/childStates/Erasing.ts | 173 + .../lib/tools/EraserTool/childStates/Idle.ts | 27 + .../tools/EraserTool/childStates/Pointing.ts | 93 + .../tldraw/src/lib/tools/HandTool/HandTool.ts | 36 + .../tools/HandTool/childStates/Dragging.ts | 68 + .../lib/tools/HandTool/childStates/Idle.ts | 17 + .../HandTool/childStates/OneFingerZooming.ts | 89 + .../tools/HandTool/childStates/Pointing.ts | 44 + .../src/lib/tools/LaserTool/LaserTool.ts | 53 + .../lib/tools/LaserTool/childStates/Idle.ts | 18 + .../tools/LaserTool/childStates/Lasering.ts | 45 + .../tools/SelectTool/DragAndDropManager.ts | 253 ++ .../GestureShapeChangeTracker.test.ts | 45 + .../SelectTool/GestureShapeChangeTracker.ts | 76 + .../src/lib/tools/SelectTool/SelectTool.ts | 92 + .../tools/SelectTool/childStates/Brushing.ts | 270 ++ .../tools/SelectTool/childStates/Crop/Crop.ts | 40 + .../childStates/Crop/children/Cropping.ts | 288 ++ .../childStates/Crop/children/Idle.ts | 250 ++ .../childStates/Crop/children/PointingCrop.ts | 51 + .../Crop/children/PointingCropHandle.ts | 112 + .../Crop/children/TranslatingCrop.ts | 134 + .../childStates/Crop/children/crop_helpers.ts | 52 + .../SelectTool/childStates/DraggingHandle.tsx | 376 ++ .../SelectTool/childStates/EditingShape.ts | 248 ++ .../lib/tools/SelectTool/childStates/Idle.ts | 812 ++++ .../childStates/PointingArrowLabel.ts | 188 + .../SelectTool/childStates/PointingCanvas.ts | 59 + .../SelectTool/childStates/PointingHandle.ts | 229 + .../childStates/PointingResizeHandle.ts | 133 + .../childStates/PointingRotateHandle.ts | 111 + .../childStates/PointingSelection.ts | 82 + .../SelectTool/childStates/PointingShape.ts | 288 ++ .../tools/SelectTool/childStates/Resizing.ts | 725 +++ .../tools/SelectTool/childStates/Rotating.ts | 234 + .../childStates/ScribbleBrushing.ts | 201 + .../SelectTool/childStates/Translating.ts | 681 +++ .../src/lib/tools/SelectTool/selectHelpers.ts | 94 + .../tldraw/src/lib/tools/ZoomTool/ZoomTool.ts | 67 + .../lib/tools/ZoomTool/childStates/Idle.ts | 21 + .../tools/ZoomTool/childStates/Pointing.ts | 39 + .../ZoomTool/childStates/ZoomBrushing.ts | 61 + .../tools/ZoomTool/childStates/ZoomQuick.ts | 180 + .../getHitShapeOnCanvasPointerDown.ts | 22 + .../selectOnCanvasPointerUp.ts | 101 + .../lib/tools/selection-logic/selection.tldr | 1041 +++++ .../selection-logic/updateHoveredOverlayId.ts | 41 + .../selection-logic/updateHoveredShapeId.ts | 110 + packages/tldraw/src/lib/ui.css | 2344 ++++++++++ packages/tldraw/src/lib/ui/TldrawUi.tsx | 250 ++ packages/tldraw/src/lib/ui/assetUrls.ts | 58 + .../tldraw/src/lib/ui/components/A11y.tsx | 201 + .../lib/ui/components/AccessibilityMenu.tsx | 20 + .../ActionsMenu/DefaultActionsMenu.tsx | 73 + .../ActionsMenu/DefaultActionsMenuContent.tsx | 146 + .../src/lib/ui/components/ColorSchemeMenu.tsx | 44 + .../ContextMenu/DefaultContextMenu.tsx | 190 + .../ContextMenu/DefaultContextMenuContent.tsx | 50 + .../lib/ui/components/CursorChatBubble.tsx | 206 + .../components/DebugMenu/DefaultDebugMenu.tsx | 50 + .../DebugMenu/DefaultDebugMenuContent.tsx | 292 ++ .../lib/ui/components/DefaultDebugPanel.tsx | 91 + .../components/DefaultFollowingIndicator.tsx | 17 + .../lib/ui/components/DefaultMenuPanel.tsx | 48 + .../tldraw/src/lib/ui/components/Dialogs.tsx | 80 + .../src/lib/ui/components/EditLinkDialog.tsx | 170 + .../src/lib/ui/components/EmbedDialog.tsx | 170 + .../components/HelpMenu/DefaultHelpMenu.tsx | 52 + .../HelpMenu/DefaultHelpMenuContent.tsx | 36 + .../HelperButtons/BackToContent.tsx | 116 + .../HelperButtons/DefaultHelperButtons.tsx | 20 + .../DefaultHelperButtonsContent.tsx | 14 + .../components/HelperButtons/ExitPenMode.tsx | 11 + .../HelperButtons/StopFollowing.tsx | 17 + .../src/lib/ui/components/InputModeMenu.tsx | 55 + .../DefaultKeyboardShortcutsDialog.tsx | 65 + .../DefaultKeyboardShortcutsDialogContent.tsx | 216 + .../src/lib/ui/components/LanguageMenu.tsx | 36 + .../src/lib/ui/components/LoadingScreen.tsx | 7 + .../components/MainMenu/DefaultMainMenu.tsx | 51 + .../MainMenu/DefaultMainMenuContent.tsx | 184 + .../ui/components/Minimap/DefaultMinimap.tsx | 208 + .../ui/components/Minimap/MinimapManager.ts | 289 ++ .../lib/ui/components/MobileStylePanel.tsx | 81 + .../DefaultNavigationPanel.tsx | 83 + .../OfflineIndicator/OfflineIndicator.tsx | 16 + .../components/PageMenu/DefaultPageMenu.tsx | 697 +++ .../ui/components/PageMenu/PageItemInput.tsx | 68 + .../components/PageMenu/PageItemSubmenu.tsx | 103 + .../components/PageMenu/edit-pages-shared.ts | 43 + .../QuickActions/DefaultQuickActions.tsx | 21 + .../DefaultQuickActionsContent.tsx | 71 + .../SharePanel/DefaultPeopleMenu.tsx | 66 + .../SharePanel/DefaultPeopleMenuAvatar.tsx | 23 + .../SharePanel/DefaultPeopleMenuContent.tsx | 29 + .../SharePanel/DefaultPeopleMenuFacePile.tsx | 47 + .../SharePanel/DefaultPeopleMenuItem.tsx | 74 + .../SharePanel/DefaultSharePanel.tsx | 14 + .../SharePanel/DefaultUserPresenceEditor.tsx | 85 + .../SharePanel/UserPresenceColorPicker.tsx | 127 + .../tldraw/src/lib/ui/components/Spinner.tsx | 10 + .../StylePanel/DefaultStylePanel.tsx | 84 + .../StylePanel/DefaultStylePanelContent.tsx | 419 ++ .../StylePanel/StylePanelButtonPicker.tsx | 204 + .../StylePanel/StylePanelContext.tsx | 102 + .../StylePanelDoubleDropdownPicker.tsx | 181 + .../StylePanel/StylePanelDropdownPicker.tsx | 161 + .../StylePanel/StylePanelSubheading.tsx | 9 + .../tldraw/src/lib/ui/components/Toasts.tsx | 106 + .../ui/components/Toolbar/AltTextEditor.tsx | 104 + .../Toolbar/DefaultImageToolbar.tsx | 122 + .../Toolbar/DefaultImageToolbarContent.tsx | 318 ++ .../Toolbar/DefaultRichTextToolbar.tsx | 207 + .../Toolbar/DefaultRichTextToolbarContent.tsx | 134 + .../ui/components/Toolbar/DefaultToolbar.tsx | 106 + .../Toolbar/DefaultToolbarContent.tsx | 245 + .../Toolbar/DefaultVideoToolbar.tsx | 80 + .../Toolbar/DefaultVideoToolbarContent.tsx | 80 + .../lib/ui/components/Toolbar/LinkEditor.tsx | 119 + .../components/Toolbar/OverflowingToolbar.tsx | 363 ++ .../Toolbar/ToggleToolLockedButton.tsx | 50 + .../TopPanel/CenteredTopPanelContainer.tsx | 99 + .../components/ZoomMenu/DefaultZoomMenu.tsx | 80 + .../ZoomMenu/DefaultZoomMenuContent.tsx | 15 + .../src/lib/ui/components/menu-items.tsx | 761 ++++ .../primitives/Button/TldrawUiButton.tsx | 54 + .../primitives/Button/TldrawUiButtonCheck.tsx | 21 + .../primitives/Button/TldrawUiButtonIcon.tsx | 22 + .../primitives/Button/TldrawUiButtonLabel.tsx | 11 + .../Button/TldrawUiButtonSpinner.tsx | 6 + .../primitives/TldrawUiContextualToolbar.tsx | 386 ++ .../components/primitives/TldrawUiDialog.tsx | 85 + .../primitives/TldrawUiDropdownMenu.tsx | 266 ++ .../ui/components/primitives/TldrawUiIcon.tsx | 122 + .../components/primitives/TldrawUiInput.tsx | 206 + .../ui/components/primitives/TldrawUiKbd.tsx | 22 + .../components/primitives/TldrawUiPopover.tsx | 102 + .../components/primitives/TldrawUiSelect.tsx | 213 + .../primitives/TldrawUiSlider.test.tsx | 92 + .../components/primitives/TldrawUiSlider.tsx | 142 + .../components/primitives/TldrawUiToolbar.tsx | 161 + .../components/primitives/TldrawUiTooltip.tsx | 456 ++ .../lib/ui/components/primitives/layout.tsx | 99 + .../menus/TldrawUiMenuActionCheckboxItem.tsx | 21 + .../menus/TldrawUiMenuActionItem.tsx | 15 + .../menus/TldrawUiMenuCheckboxItem.tsx | 112 + .../primitives/menus/TldrawUiMenuContext.tsx | 43 + .../primitives/menus/TldrawUiMenuGroup.tsx | 74 + .../primitives/menus/TldrawUiMenuItem.tsx | 491 ++ .../primitives/menus/TldrawUiMenuSubmenu.tsx | 109 + .../primitives/menus/TldrawUiMenuToolItem.tsx | 15 + packages/tldraw/src/lib/ui/constants.ts | 30 + .../ui/context/TldrawUiContextProvider.tsx | 112 + packages/tldraw/src/lib/ui/context/a11y.tsx | 60 + .../tldraw/src/lib/ui/context/actions.tsx | 1923 ++++++++ .../tldraw/src/lib/ui/context/asset-urls.tsx | 54 + .../tldraw/src/lib/ui/context/breakpoints.tsx | 48 + .../tldraw/src/lib/ui/context/components.tsx | 165 + .../tldraw/src/lib/ui/context/dialogs.tsx | 93 + packages/tldraw/src/lib/ui/context/events.tsx | 191 + packages/tldraw/src/lib/ui/context/toasts.tsx | 90 + packages/tldraw/src/lib/ui/getLocalFiles.ts | 50 + .../src/lib/ui/hooks/clipboard/pasteFiles.ts | 35 + .../src/lib/ui/hooks/clipboard/pasteUrl.ts | 47 + .../ui/hooks/clipboard/putPastedContent.ts | 30 + .../tldraw/src/lib/ui/hooks/menu-hooks.ts | 173 + .../src/lib/ui/hooks/useClipboardEvents.ts | 994 +++++ .../lib/ui/hooks/useCollaborationStatus.ts | 22 + .../src/lib/ui/hooks/useCommentingEnabled.ts | 15 + packages/tldraw/src/lib/ui/hooks/useCopyAs.ts | 27 + .../src/lib/ui/hooks/useEditorEvents.ts | 24 + .../tldraw/src/lib/ui/hooks/useExportAs.ts | 33 + .../tldraw/src/lib/ui/hooks/useFlatten.ts | 225 + .../src/lib/ui/hooks/useGetEmbedDefinition.ts | 20 + .../lib/ui/hooks/useGetEmbedDefinitions.ts | 7 + .../src/lib/ui/hooks/useKeyboardShortcuts.ts | 493 +++ .../src/lib/ui/hooks/useLocalStorageState.ts | 31 + .../tldraw/src/lib/ui/hooks/useMenuIsOpen.ts | 29 + packages/tldraw/src/lib/ui/hooks/usePrint.ts | 230 + .../tldraw/src/lib/ui/hooks/useReadonly.ts | 7 + .../src/lib/ui/hooks/useRelevantStyles.ts | 50 + packages/tldraw/src/lib/ui/hooks/useTools.tsx | 427 ++ .../useTranslation/TLUiTranslationKey.ts | 546 +++ .../useTranslation/defaultTranslation.ts | 558 +++ .../ui/hooks/useTranslation/translations.ts | 76 + .../useTranslation/useTranslation.test.tsx | 72 + .../hooks/useTranslation/useTranslation.tsx | 143 + packages/tldraw/src/lib/ui/icon-types.ts | 335 ++ packages/tldraw/src/lib/ui/kbd-utils.test.ts | 49 + packages/tldraw/src/lib/ui/kbd-utils.ts | 76 + packages/tldraw/src/lib/ui/overrides.ts | 216 + packages/tldraw/src/lib/ui/version.ts | 9 + .../tldraw/src/lib/utils/assets/assets.ts | 100 + .../src/lib/utils/assets/preload-font.ts | 59 + packages/tldraw/src/lib/utils/clipboard.ts | 62 + .../src/lib/utils/embeds/embeds.test.ts | 878 ++++ .../tldraw/src/lib/utils/embeds/embeds.ts | 133 + .../putExcalidrawContent.test.tsx.snap | 1966 ++++++++ .../bound-arrows.json | 107 + .../bound-elbow-arrows.json | 117 + .../excalidraw-test-fixtures/image.json | 45 + .../line-drawing.json | 1274 ++++++ .../excalidraw/putExcalidrawContent.test.tsx | 134 + .../utils/excalidraw/putExcalidrawContent.ts | 550 +++ .../tldraw/src/lib/utils/export/copyAs.ts | 86 + .../tldraw/src/lib/utils/export/export.ts | 59 + .../tldraw/src/lib/utils/export/exportAs.ts | 74 + .../tldraw/src/lib/utils/frames/frames.ts | 137 + .../tldraw/src/lib/utils/shapes/shapes.ts | 55 + .../src/lib/utils/static-assets/assetUrls.ts | 65 + .../src/lib/utils/svg/sanitizeSvg.test.ts | 866 ++++ .../tldraw/src/lib/utils/svg/sanitizeSvg.ts | 692 +++ packages/tldraw/src/lib/utils/test-helpers.ts | 62 + .../src/lib/utils/text/literalTyping.ts | 68 + .../src/lib/utils/text/richText.test.ts | 132 + .../tldraw/src/lib/utils/text/richText.ts | 245 + .../tldraw/src/lib/utils/text/text.test.ts | 11 + packages/tldraw/src/lib/utils/text/text.ts | 86 + .../tldraw/src/lib/utils/text/tiptap.test.ts | 40 + packages/tldraw/src/lib/utils/text/tiptap.ts | 18 + .../src/lib/utils/text/wrapSelection.test.ts | 285 ++ .../src/lib/utils/text/wrapSelection.ts | 226 + .../buildFromV1Document.test.ts.snap | 538 +++ .../utils/tldr/buildFromV1Document.test.ts | 31 + .../src/lib/utils/tldr/buildFromV1Document.ts | 1228 +++++ packages/tldraw/src/lib/utils/tldr/file.ts | 365 ++ .../tldr/test-fixtures/arrow-binding.tldr | 1 + .../test-fixtures/exact-arrow-binding.tldr | 1 + .../incorrect-arrow-binding.tldr | 1 + packages/tldraw/src/test/A11y.test.tsx | 103 + packages/tldraw/src/test/ClickManager.test.ts | 330 ++ packages/tldraw/src/test/Editor.test.tsx | 1033 +++++ packages/tldraw/src/test/EraserTool.test.ts | 704 +++ packages/tldraw/src/test/HandTool.test.ts | 277 ++ .../tldraw/src/test/HighlightShape.test.ts | 25 + .../tldraw/src/test/ImageShapeUtil.test.ts | 244 + packages/tldraw/src/test/LaserTool.test.ts | 478 ++ .../tldraw/src/test/ScribbleManager.test.ts | 441 ++ packages/tldraw/src/test/SelectTool.test.ts | 1698 +++++++ .../src/test/TLSessionStateSnapshot.test.ts | 211 + .../tldraw/src/test/TLUserPreferences.test.ts | 127 + packages/tldraw/src/test/TestEditor.test.ts | 7 + packages/tldraw/src/test/TestEditor.ts | 540 +++ .../tldraw/src/test/TldrawEditor.test.tsx | 872 ++++ .../tldraw/src/test/VideoShapeUtil.test.tsx | 126 + packages/tldraw/src/test/ZoomTool.test.ts | 617 +++ .../test/__snapshots__/drawing.test.ts.snap | 35 + .../test/__snapshots__/groups.test.tsx.snap | 46 + .../test/__snapshots__/resizing.test.ts.snap | 35 + .../src/test/actions-menu-readonly.test.tsx | 37 + .../tldraw/src/test/arrows-megabus.test.tsx | 852 ++++ packages/tldraw/src/test/assets.test.ts | 38 + packages/tldraw/src/test/attribution.test.ts | 345 ++ packages/tldraw/src/test/bindings.test.tsx | 471 ++ .../tldraw/src/test/bindingsIndex.test.tsx | 265 ++ .../tldraw/src/test/bookmark-shapes.test.ts | 671 +++ packages/tldraw/src/test/cleanup.test.ts | 132 + .../tldraw/src/test/commaKeyClick.test.ts | 94 + .../__snapshots__/getSvgString.test.ts.snap | 279 ++ .../__snapshots__/packShapes.test.ts.snap | 367 ++ .../__snapshots__/zoomToFit.test.ts.snap | 12 + .../src/test/commands/alignShapes.test.tsx | 406 ++ .../commands/allShapesCommonBounds.test.ts | 91 + .../src/test/commands/animateShapes.test.ts | 72 + .../src/test/commands/animateToShape.test.ts | 3 + .../src/test/commands/animationSpeed.test.ts | 39 + .../tldraw/src/test/commands/blur.test.ts | 3 + .../src/test/commands/cameraState.test.ts | 424 ++ .../tldraw/src/test/commands/cancel.test.ts | 3 + .../src/test/commands/centerOnPoint.test.ts | 29 + .../src/test/commands/clipboard.test.ts | 518 +++ .../test/commands/clipboardCallbacks.test.ts | 340 ++ .../src/test/commands/clipboardPaste.test.ts | 724 +++ .../tldraw/src/test/commands/complete.test.ts | 3 + .../src/test/commands/createPage.test.ts | 65 + .../src/test/commands/createShape.test.ts | 64 + .../src/test/commands/createShapes.test.ts | 156 + .../src/test/commands/deletePage.test.ts | 162 + .../src/test/commands/deleteShapes.test.ts | 215 + .../test/commands/distributeShapes.test.tsx | 337 ++ .../src/test/commands/duplicatePage.test.ts | 55 + .../src/test/commands/getBaseZoom.test.ts | 89 + .../src/test/commands/getContent.test.ts | 9 + .../commands/getInitialMetaForShape.test.ts | 21 + .../src/test/commands/getInitialZoom.test.ts | 89 + .../src/test/commands/getSvgString.test.ts | 308 ++ .../src/test/commands/groupShapes.test.ts | 42 + packages/tldraw/src/test/commands/guide.md | 12 + .../src/test/commands/interrupt.test.ts | 3 + .../src/test/commands/isShapeOfType.test.ts | 44 + .../src/test/commands/lockShapes.test.ts | 434 ++ .../test/commands/moveShapesToPage.test.ts | 255 ++ .../tldraw/src/test/commands/nudge.test.ts | 375 ++ .../src/test/commands/packShapes.test.ts | 97 + .../src/test/commands/pageToScreen.test.ts | 25 + packages/tldraw/src/test/commands/pan.test.ts | 51 + .../tldraw/src/test/commands/penmode.test.ts | 154 + .../tldraw/src/test/commands/pinch.test.ts | 11 + .../src/test/commands/putContent.test.ts | 191 + .../src/test/commands/reorderShapes.test.ts | 1122 +++++ .../test/commands/reparentShapesById.test.ts | 162 + .../src/test/commands/resetZoom.test.ts | 44 + .../src/test/commands/resizeShape.test.ts | 59 + .../src/test/commands/resizeToBounds.test.tsx | 245 + .../src/test/commands/rotateShapes.test.ts | 132 + .../src/test/commands/screenToPage.test.ts | 246 + .../tldraw/src/test/commands/setBrush.test.ts | 38 + .../src/test/commands/setCamera.test.ts | 1428 ++++++ .../src/test/commands/setCurrentPage.test.ts | 126 + .../src/test/commands/setPageState.test.ts | 9 + .../src/test/commands/setSelectedIds.test.ts | 83 + .../src/test/commands/setSelectedTool.test.ts | 23 + .../src/test/commands/setSettings.test.ts | 9 + .../tldraw/src/test/commands/setStyle.test.ts | 11 + .../src/test/commands/stackShapes.test.ts | 337 ++ .../tldraw/src/test/commands/stretch.test.tsx | 287 ++ .../tldraw/src/test/commands/ungroup.test.ts | 17 + .../src/test/commands/updateShape.test.ts | 67 + .../src/test/commands/updateShapes.test.ts | 208 + .../commands/updateViewportPageBounds.test.ts | 131 + .../tldraw/src/test/commands/zoomIn.test.ts | 78 + .../tldraw/src/test/commands/zoomOut.test.ts | 132 + .../src/test/commands/zoomToBounds.test.ts | 73 + .../src/test/commands/zoomToFit.test.ts | 85 + .../src/test/commands/zoomToSelection.test.ts | 62 + .../tldraw/src/test/createDeepLink.test.tsx | 56 + .../tldraw/src/test/createNShapes.test.ts | 55 + packages/tldraw/src/test/crop.test.ts | 2394 ++++++++++ packages/tldraw/src/test/cropping.test.ts | 1603 +++++++ .../tldraw/src/test/custom-clipping.test.ts | 491 ++ .../tldraw/src/test/customSnapping.test.tsx | 808 ++++ .../defaultHandleExternalFileContent.test.ts | 86 + .../tldraw/src/test/displayValues.test.ts | 309 ++ packages/tldraw/src/test/dragAndDrop.test.ts | 363 ++ .../test/dragDuringCameraAnimation.test.ts | 114 + .../src/test/dragFromToolbar-dom.test.tsx | 150 + .../tldraw/src/test/dragFromToolbar.test.ts | 67 + .../src/test/drawing-shift-keyup.test.ts | 79 + packages/tldraw/src/test/drawing.data.ts | 1006 +++++ packages/tldraw/src/test/drawing.test.ts | 398 ++ packages/tldraw/src/test/duplicate.test.ts | 379 ++ .../src/test/embed-aspect-ratio.test.ts | 254 ++ .../src/test/embed-iframe-paste.test.ts | 211 + packages/tldraw/src/test/flatten.test.ts | 135 + packages/tldraw/src/test/flipShapes.test.ts | 677 +++ packages/tldraw/src/test/frames.test.ts | 2020 +++++++++ .../src/test/freehand/corpus/presets.ts | 71 + .../tldraw/src/test/freehand/corpus/real.ts | 370 ++ .../src/test/freehand/corpus/strokes.ts | 50 + packages/tldraw/src/test/freehand/svg.test.ts | 20 + .../src/test/freehand/wellformed.test.ts | 30 + .../tldraw/src/test/getCulledShapes.test.tsx | 286 ++ .../tldraw/src/test/getShapeAtPoint.test.ts | 288 ++ packages/tldraw/src/test/getSnapLines.ts | 25 + .../src/test/grid-align-on-create.test.ts | 107 + packages/tldraw/src/test/groups.test.tsx | 2156 +++++++++ .../tldraw/src/test/handleDeepLink.test.tsx | 226 + .../src/test/inner-outer-margin.test.ts | 315 ++ .../tldraw/src/test/long-press-create.test.ts | 102 + packages/tldraw/src/test/maxShapes.test.ts | 361 ++ .../src/test/middleMouseButtonPanning.test.ts | 31 + .../tldraw/src/test/minimap-wheel.test.tsx | 48 + packages/tldraw/src/test/modifiers.test.ts | 157 + packages/tldraw/src/test/navigation.test.ts | 1324 ++++++ .../tldraw/src/test/notVisibleShapes.test.ts | 779 ++++ .../test/noteAttributionComponent.test.tsx | 92 + .../src/test/noteAttributionExport.test.tsx | 69 + .../onDragFromToolbarToCreateShape.test.ts | 84 + .../overlays/ArrowHintOverlayUtil.test.ts | 128 + .../test/overlays/BrushOverlayUtil.test.ts | 50 + .../BrushOverlayUtilDisplayValues.test.ts | 97 + .../CollaboratorBrushOverlayUtil.test.ts | 80 + .../CollaboratorCursorOverlayUtil.test.ts | 350 ++ .../CollaboratorHintOverlayUtil.test.ts | 111 + .../CollaboratorScribbleOverlayUtil.test.ts | 100 + .../src/test/overlays/OverlayManager.test.ts | 311 ++ .../test/overlays/ScribbleOverlayUtil.test.ts | 79 + .../SelectionForegroundOverlayUtil.test.ts | 401 ++ .../overlays/ShapeHandleOverlayUtil.test.ts | 271 ++ .../ShapeIndicatorOverlayUtil.test.ts | 36 + .../overlays/SnapIndicatorOverlayUtil.test.ts | 74 + .../overlays/ZoomBrushOverlayUtil.test.ts | 50 + packages/tldraw/src/test/panning.test.ts | 26 + .../test/parentsToChildrenWithIndexes.test.ts | 117 + packages/tldraw/src/test/paste.test.ts | 667 +++ .../src/test/perf/PerformanceMeasurer.ts | 163 + packages/tldraw/src/test/perf/perf.test.ts | 212 + packages/tldraw/src/test/pinch-dom.test.tsx | 170 + packages/tldraw/src/test/pinch.test.ts | 177 + .../src/test/pointercancel-dom.test.tsx | 326 ++ .../test/registerDeepLinkListener.test.tsx | 105 + .../tldraw/src/test/renderingShapes.test.tsx | 201 + packages/tldraw/src/test/resizeBox.test.ts | 106 + .../src/test/resolveAssetsInContent.test.ts | 96 + .../src/test/right-click-context-menu.test.ts | 90 + .../tldraw/src/test/rightClickPanning.test.ts | 53 + packages/tldraw/src/test/rotating.test.ts | 361 ++ packages/tldraw/src/test/roundedBox.ts | 13 + packages/tldraw/src/test/select.test.tsx | 189 + .../tldraw/src/test/selection-omnibus.test.ts | 2413 ++++++++++ .../src/test/shapeIdsInCurrentPage.test.ts | 75 + packages/tldraw/src/test/shapeutils.test.ts | 683 +++ .../tldraw/src/test/spacebarPanning.test.ts | 150 + packages/tldraw/src/test/spatialIndex.test.ts | 532 +++ .../tldraw/src/test/strange-tools.test.ts | 86 + packages/tldraw/src/test/styles2.test.tsx | 209 + packages/tldraw/src/test/styles3.test.ts | 70 + packages/tldraw/src/test/test-jsx.tsx | 328 ++ packages/tldraw/src/test/testutils/pretty.ts | 128 + .../test/testutils/renderTldrawComponent.tsx | 37 + packages/tldraw/src/test/text.test.ts | 269 ++ .../src/test/toolbar-tool-selection.test.tsx | 45 + packages/tldraw/src/test/translating.test.ts | 2591 +++++++++++ .../test/transparent-image-hit-test.test.ts | 361 ++ .../src/test/ui-outside-editor.test.tsx | 74 + .../tldraw/src/test/ui/AltTextEditor.test.tsx | 51 + .../tldraw/src/test/ui/BackToContent.test.tsx | 190 + .../tldraw/src/test/ui/ContextMenu.test.tsx | 362 ++ packages/tldraw/src/test/ui/Dialogs.test.tsx | 256 ++ .../src/test/ui/EditLinkDialog.test.tsx | 77 + .../tldraw/src/test/ui/EditorPortal.test.tsx | 35 + .../test/ui/FrameSelectionMenuItem.test.tsx | 115 + .../tldraw/src/test/ui/ImageToolbar.test.tsx | 58 + .../tldraw/src/test/ui/StylePanel.test.tsx | 77 + .../tldraw/src/test/ui/changePage.test.tsx | 131 + .../src/test/ui/copyHoveredStyles.test.tsx | 154 + .../src/test/ui/keyboardShortcuts.test.tsx | 791 ++++ .../src/test/ui/presenceActivity.test.tsx | 44 + .../tldraw/src/test/ui/unlockAll.test.tsx | 55 + .../src/test/viewport-following.test.ts | 46 + packages/tldraw/src/test/zoomToUser.test.ts | 63 + packages/tldraw/tsconfig.json | 17 + packages/tldraw/vitest.config.ts | 46 + packages/tlschema/DOCS.md | 682 +++ packages/tlschema/LICENSE.md | 9 + packages/tlschema/README.md | 99 + packages/tlschema/api-extractor.json | 4 + packages/tlschema/api-report.api.md | 2041 +++++++++ packages/tlschema/package.json | 71 + packages/tlschema/src/TLStore.test.ts | 657 +++ packages/tlschema/src/TLStore.ts | 570 +++ .../src/__tests__/migrationTestUtils.ts | 58 + packages/tlschema/src/assets/TLBaseAsset.ts | 124 + .../tlschema/src/assets/TLBookmarkAsset.ts | 99 + packages/tlschema/src/assets/TLImageAsset.ts | 155 + packages/tlschema/src/assets/TLVideoAsset.ts | 175 + .../tlschema/src/bindings/TLArrowBinding.ts | 185 + .../tlschema/src/bindings/TLBaseBinding.ts | 189 + .../src/createPresenceStateDerivation.test.ts | 171 + .../src/createPresenceStateDerivation.ts | 154 + packages/tlschema/src/createTLSchema.test.ts | 181 + packages/tlschema/src/createTLSchema.ts | 437 ++ packages/tlschema/src/index.ts | 387 ++ packages/tlschema/src/migrations.test.ts | 2809 ++++++++++++ packages/tlschema/src/misc/TLColor.ts | 72 + packages/tlschema/src/misc/TLCursor.ts | 157 + packages/tlschema/src/misc/TLHandle.ts | 113 + packages/tlschema/src/misc/TLOpacity.ts | 56 + packages/tlschema/src/misc/TLRichText.test.ts | 56 + packages/tlschema/src/misc/TLRichText.ts | 87 + packages/tlschema/src/misc/TLScribble.ts | 146 + packages/tlschema/src/misc/b64Vecs.test.ts | 592 +++ packages/tlschema/src/misc/b64Vecs.ts | 636 +++ packages/tlschema/src/misc/geometry-types.ts | 65 + packages/tlschema/src/misc/id-validator.ts | 33 + packages/tlschema/src/records/TLAsset.ts | 290 ++ packages/tlschema/src/records/TLBinding.ts | 434 ++ packages/tlschema/src/records/TLCamera.ts | 184 + .../tlschema/src/records/TLComment.test.ts | 255 ++ packages/tlschema/src/records/TLComment.ts | 446 ++ .../tlschema/src/records/TLCustomRecord.ts | 297 ++ packages/tlschema/src/records/TLDocument.ts | 224 + packages/tlschema/src/records/TLInstance.ts | 656 +++ packages/tlschema/src/records/TLPage.ts | 192 + packages/tlschema/src/records/TLPageState.ts | 255 ++ packages/tlschema/src/records/TLPointer.ts | 171 + packages/tlschema/src/records/TLPresence.ts | 258 ++ packages/tlschema/src/records/TLRecord.ts | 136 + packages/tlschema/src/records/TLShape.ts | 586 +++ packages/tlschema/src/records/TLUser.ts | 148 + .../tlschema/src/recordsWithProps.test.ts | 188 + packages/tlschema/src/recordsWithProps.ts | 276 ++ packages/tlschema/src/shapes/ShapeWithCrop.ts | 74 + packages/tlschema/src/shapes/TLArrowShape.ts | 472 ++ packages/tlschema/src/shapes/TLBaseShape.ts | 181 + .../tlschema/src/shapes/TLBookmarkShape.ts | 112 + packages/tlschema/src/shapes/TLDrawShape.ts | 291 ++ packages/tlschema/src/shapes/TLEmbedShape.ts | 386 ++ packages/tlschema/src/shapes/TLFrameShape.ts | 106 + packages/tlschema/src/shapes/TLGeoShape.ts | 342 ++ packages/tlschema/src/shapes/TLGroupShape.ts | 64 + .../tlschema/src/shapes/TLHighlightShape.ts | 204 + packages/tlschema/src/shapes/TLImageShape.ts | 207 + packages/tlschema/src/shapes/TLLineShape.ts | 305 ++ packages/tlschema/src/shapes/TLNoteShape.ts | 308 ++ packages/tlschema/src/shapes/TLTextShape.ts | 185 + packages/tlschema/src/shapes/TLVideoShape.ts | 179 + .../tlschema/src/store-migrations.test.ts | 88 + packages/tlschema/src/store-migrations.ts | 156 + packages/tlschema/src/styles/StyleProp.ts | 163 + packages/tlschema/src/styles/TLColorStyle.ts | 101 + packages/tlschema/src/styles/TLDashStyle.ts | 63 + packages/tlschema/src/styles/TLFillStyle.ts | 63 + packages/tlschema/src/styles/TLFontFace.ts | 65 + packages/tlschema/src/styles/TLFontStyle.ts | 137 + .../src/styles/TLHorizontalAlignStyle.ts | 64 + packages/tlschema/src/styles/TLSizeStyle.ts | 63 + .../tlschema/src/styles/TLTextAlignStyle.ts | 61 + packages/tlschema/src/styles/TLTheme.ts | 261 ++ .../src/styles/TLVerticalAlignStyle.ts | 61 + .../tlschema/src/translations/languages.ts | 55 + .../src/translations/translations.test.ts | 386 ++ .../tlschema/src/translations/translations.ts | 220 + packages/tlschema/src/util-types.ts | 52 + packages/tlschema/tsconfig.json | 12 + packages/tlschema/vitest.config.ts | 6 + packages/utils/DOCS.md | 930 ++++ packages/utils/LICENSE.md | 9 + packages/utils/README.md | 31 + packages/utils/api-extractor.json | 4 + packages/utils/api-report.api.md | 573 +++ packages/utils/package.json | 68 + packages/utils/setupTests.js | 3 + packages/utils/setupVitest.js | 3 + packages/utils/src/index.ts | 121 + packages/utils/src/lib/ExecutionQueue.test.ts | 220 + packages/utils/src/lib/ExecutionQueue.ts | 151 + packages/utils/src/lib/LruCache.test.ts | 101 + packages/utils/src/lib/LruCache.ts | 36 + .../utils/src/lib/PerformanceTracker.test.ts | 123 + packages/utils/src/lib/PerformanceTracker.ts | 117 + packages/utils/src/lib/array.test.ts | 339 ++ packages/utils/src/lib/array.ts | 288 ++ packages/utils/src/lib/bind.test.ts | 47 + packages/utils/src/lib/bind.ts | 136 + packages/utils/src/lib/cache.test.ts | 73 + packages/utils/src/lib/cache.ts | 64 + packages/utils/src/lib/control.test.ts | 50 + packages/utils/src/lib/control.ts | 275 ++ packages/utils/src/lib/debounce.test.ts | 128 + packages/utils/src/lib/debounce.ts | 103 + packages/utils/src/lib/error.test.ts | 60 + packages/utils/src/lib/error.ts | 67 + packages/utils/src/lib/file.test.ts | 49 + packages/utils/src/lib/file.ts | 188 + .../utils/src/lib/fractionalIndexing.test.ts | 138 + packages/utils/src/lib/fractionalIndexing.ts | 275 ++ packages/utils/src/lib/function.ts | 43 + packages/utils/src/lib/hash.test.ts | 99 + packages/utils/src/lib/hash.ts | 117 + packages/utils/src/lib/id.test.ts | 32 + packages/utils/src/lib/id.ts | 129 + packages/utils/src/lib/iterable.test.ts | 25 + packages/utils/src/lib/iterable.ts | 20 + packages/utils/src/lib/json-value.ts | 77 + packages/utils/src/lib/media/apng.test.ts | 67 + packages/utils/src/lib/media/apng.ts | 167 + packages/utils/src/lib/media/avif.test.ts | 26 + packages/utils/src/lib/media/avif.ts | 38 + packages/utils/src/lib/media/gif.test.ts | 52 + packages/utils/src/lib/media/gif.ts | 121 + packages/utils/src/lib/media/media.test.ts | 58 + packages/utils/src/lib/media/media.ts | 488 ++ packages/utils/src/lib/media/png.ts | 338 ++ packages/utils/src/lib/media/webp.test.ts | 81 + packages/utils/src/lib/media/webp.ts | 57 + packages/utils/src/lib/network.test.ts | 38 + packages/utils/src/lib/network.ts | 32 + packages/utils/src/lib/number.test.ts | 74 + packages/utils/src/lib/number.ts | 108 + packages/utils/src/lib/object.test.ts | 236 + packages/utils/src/lib/object.ts | 369 ++ packages/utils/src/lib/perf.ts | 141 + packages/utils/src/lib/reordering.test.ts | 168 + packages/utils/src/lib/reordering.ts | 199 + packages/utils/src/lib/retry.test.ts | 77 + packages/utils/src/lib/retry.ts | 77 + packages/utils/src/lib/sort.test.ts | 36 + packages/utils/src/lib/sort.ts | 25 + packages/utils/src/lib/storage.test.ts | 121 + packages/utils/src/lib/storage.tsx | 165 + packages/utils/src/lib/string.test.ts | 80 + packages/utils/src/lib/string.ts | 58 + packages/utils/src/lib/stringEnum.ts | 27 + packages/utils/src/lib/throttle.test.ts | 443 ++ packages/utils/src/lib/throttle.ts | 227 + packages/utils/src/lib/timers.test.ts | 230 + packages/utils/src/lib/timers.ts | 290 ++ packages/utils/src/lib/types.ts | 149 + packages/utils/src/lib/url.test.ts | 44 + packages/utils/src/lib/url.ts | 47 + packages/utils/src/lib/value.test.ts | 102 + packages/utils/src/lib/value.ts | 137 + packages/utils/src/lib/version.test.ts | 537 +++ packages/utils/src/lib/version.ts | 247 ++ packages/utils/src/lib/warn.test.ts | 64 + packages/utils/src/lib/warn.ts | 59 + packages/utils/tsconfig.json | 6 + packages/utils/vitest.config.ts | 10 + packages/validate/DOCS.md | 888 ++++ packages/validate/LICENSE.md | 9 + packages/validate/README.md | 59 + packages/validate/SPEC.md | 140 + packages/validate/api-extractor.json | 4 + packages/validate/api-report.api.md | 260 ++ packages/validate/package.json | 60 + packages/validate/src/index.ts | 18 + packages/validate/src/lib/validation.ts | 2003 +++++++++ packages/validate/src/test/arrays.test.ts | 103 + packages/validate/src/test/dicts.test.ts | 86 + packages/validate/src/test/enums.test.ts | 28 + packages/validate/src/test/errors.test.ts | 124 + packages/validate/src/test/index-key.test.ts | 15 + packages/validate/src/test/json.test.ts | 108 + packages/validate/src/test/model.test.ts | 34 + .../src/test/nullable-optional.test.ts | 75 + packages/validate/src/test/numbers.test.ts | 114 + packages/validate/src/test/objects.test.ts | 137 + packages/validate/src/test/or.test.ts | 13 + packages/validate/src/test/primitives.test.ts | 67 + .../validate/src/test/refine-check.test.ts | 82 + packages/validate/src/test/unions.test.ts | 147 + packages/validate/src/test/urls.test.ts | 59 + .../validate/src/test/validation.fuzz.test.ts | 378 ++ packages/validate/src/test/validator.test.ts | 60 + packages/validate/tsconfig.json | 7 + packages/validate/vitest.config.ts | 6 + packages/worker-shared/DOCS.md | 370 ++ packages/worker-shared/README.md | 27 + packages/worker-shared/package.json | 33 + packages/worker-shared/src/bookmarks.test.ts | 239 + packages/worker-shared/src/bookmarks.ts | 127 + packages/worker-shared/src/env.ts | 49 + packages/worker-shared/src/errors.ts | 76 + packages/worker-shared/src/handleRequest.ts | 252 ++ packages/worker-shared/src/index.test.ts | 3 + packages/worker-shared/src/index.ts | 22 + packages/worker-shared/src/origins.test.ts | 107 + packages/worker-shared/src/origins.ts | 110 + packages/worker-shared/src/sentry.test.ts | 42 + packages/worker-shared/src/sentry.ts | 89 + .../src/userAssetUploads.test.ts | 106 + .../worker-shared/src/userAssetUploads.ts | 229 + packages/worker-shared/tsconfig.json | 7 + packages/worker-shared/vitest.config.ts | 6 + skills/clean-copy/SKILL.md | 46 + skills/commit-changes/SKILL.md | 48 + skills/dotcom-release-crew/SKILL.md | 111 + skills/dotcom-release-marketing/SKILL.md | 186 + skills/issue/SKILL.md | 101 + skills/issue/scripts/set-issue-type.sh | 36 + skills/pr-walkthrough/SKILL.md | 247 ++ skills/pr-walkthrough/references/manifest.md | 138 + .../pr-walkthrough/scripts/generate-audio.sh | 279 ++ skills/pr-walkthrough/scripts/make-video.sh | 89 + skills/pr-walkthrough/video/.gitignore | 6 + skills/pr-walkthrough/video/build.mjs | 793 ++++ skills/pr-walkthrough/video/hyperframes.json | 9 + skills/pr-walkthrough/video/meta.json | 4 + skills/pr-walkthrough/video/render.sh | 160 + skills/pr/SKILL.md | 53 + skills/review-docs/SKILL.md | 386 ++ skills/shared/blog-guide.md | 189 + skills/shared/docs-guide.md | 231 + skills/shared/release-notes-guide.md | 281 ++ skills/shepherd-pr/SKILL.md | 161 + skills/simplify-trace/SKILL.md | 67 + .../simplify-trace/scripts/simplify-trace.mjs | 482 ++ skills/skill-creator/LICENSE.txt | 201 + skills/skill-creator/SKILL.md | 355 ++ .../references/output-patterns.md | 92 + skills/skill-creator/references/workflows.md | 28 + skills/skill-creator/scripts/init-skill.ts | 255 ++ skills/skill-creator/scripts/package-skill.ts | 152 + .../skill-creator/scripts/quick-validate.ts | 152 + skills/spec-driven-tests/SKILL.md | 99 + skills/take/SKILL.md | 111 + skills/tldraw-migrate/.gitignore | 1 + skills/tldraw-migrate/README.md | 82 + skills/tldraw-migrate/SKILL.md | 174 + skills/tldraw-migrate/detect-target.mjs | 34 + skills/tldraw-migrate/detect-versions.mjs | 107 + skills/tldraw-migrate/fetch-release-notes.mjs | 163 + skills/tldraw-migrate/type-errors.md | 75 + skills/update-release-notes/SKILL.md | 238 + .../scripts/fetch-pr-batch.sh | 58 + .../scripts/get-changelog-status.sh | 116 + .../scripts/get-new-prs-from-main.sh | 88 + .../scripts/get-new-prs.sh | 76 + .../scripts/update-draft-release.sh | 84 + skills/write-docs/SKILL.md | 124 + skills/write-e2e-tests/SKILL.md | 288 ++ skills/write-example/SKILL.md | 201 + skills/write-issue/SKILL.md | 123 + skills/write-pr/SKILL.md | 310 ++ skills/write-pr/scripts/example-scenario.mjs | 42 + .../write-pr/scripts/record-interaction.mjs | 139 + skills/write-release-notes/SKILL.md | 137 + skills/write-tbp/SKILL.md | 109 + skills/write-tbp/assets/.gitignore | 5 + skills/write-unit-tests/SKILL.md | 63 + socket.yml | 11 + templates/.gitignore | 1 + templates/agent/.gitignore | 5 + templates/agent/LICENSE.md | 9 + templates/agent/README.md | 796 ++++ templates/agent/client/AgentHelpers.ts | 532 +++ templates/agent/client/App.tsx | 99 + .../client/actions/AddDetailActionUtil.ts | 25 + .../agent/client/actions/AgentActionUtil.ts | 167 + .../agent/client/actions/AlignActionUtil.ts | 32 + .../client/actions/BringToFrontActionUtil.ts | 28 + .../agent/client/actions/ClearActionUtil.ts | 37 + .../client/actions/CountShapesActionUtil.ts | 28 + .../client/actions/CountryInfoActionUtil.ts | 41 + .../agent/client/actions/CreateActionUtil.ts | 230 + .../agent/client/actions/DeleteActionUtil.ts | 36 + .../client/actions/DistributeActionUtil.ts | 32 + .../agent/client/actions/LabelActionUtil.ts | 66 + .../agent/client/actions/MessageActionUtil.ts | 16 + .../agent/client/actions/MoveActionUtil.ts | 128 + .../agent/client/actions/PenActionUtil.ts | 115 + .../agent/client/actions/PlaceActionUtil.ts | 135 + .../agent/client/actions/ResizeActionUtil.ts | 49 + .../agent/client/actions/ReviewActionUtil.ts | 61 + .../agent/client/actions/RotateActionUtil.ts | 35 + .../client/actions/SendToBackActionUtil.ts | 28 + .../client/actions/SetMyViewActionUtil.ts | 42 + .../agent/client/actions/StackActionUtil.ts | 36 + .../agent/client/actions/ThinkActionUtil.ts | 22 + .../agent/client/actions/UnknownActionUtil.ts | 18 + .../agent/client/actions/UpdateActionUtil.ts | 106 + .../actions/UpsertTodoListItemActionUtil.ts | 33 + templates/agent/client/agent/TldrawAgent.ts | 735 +++ .../agent/client/agent/TldrawAgentApp.ts | 83 + .../client/agent/TldrawAgentAppProvider.tsx | 213 + .../agent/managers/AgentActionManager.ts | 159 + .../agent/managers/AgentAppAgentsManager.ts | 162 + .../managers/AgentAppPersistenceManager.ts | 236 + .../client/agent/managers/AgentChatManager.ts | 86 + .../agent/managers/AgentChatOriginManager.ts | 51 + .../agent/managers/AgentContextManager.ts | 219 + .../agent/managers/AgentDebugManager.ts | 81 + .../client/agent/managers/AgentLintManager.ts | 329 ++ .../client/agent/managers/AgentModeManager.ts | 83 + .../agent/managers/AgentModelNameManager.ts | 55 + .../agent/managers/AgentRequestManager.ts | 188 + .../client/agent/managers/AgentTodoManager.ts | 109 + .../agent/managers/AgentUserActionTracker.ts | 132 + .../agent/managers/BaseAgentAppManager.ts | 37 + .../client/agent/managers/BaseAgentManager.ts | 34 + .../agent/client/components/ChatInput.tsx | 149 + .../agent/client/components/ChatPanel.tsx | 58 + .../client/components/ChatPanelFallback.tsx | 15 + .../client/components/ContextItemTag.tsx | 19 + .../client/components/CustomHelperButtons.tsx | 17 + .../client/components/GoToAgentButton.tsx | 108 + .../agent/client/components/PromptTag.tsx | 21 + .../agent/client/components/SelectionTag.tsx | 5 + .../agent/client/components/TodoList.tsx | 51 + .../components/chat-history/ChatHistory.tsx | 90 + .../chat-history/ChatHistoryGroup.tsx | 82 + .../chat-history/ChatHistoryGroupWithDiff.tsx | 122 + .../ChatHistoryGroupWithoutDiff.tsx | 111 + .../chat-history/ChatHistoryPrompt.tsx | 38 + .../chat-history/ChatHistorySection.tsx | 56 + .../chat-history/TldrawDiffViewer.tsx | 135 + .../components/chat-history/TldrawViewer.tsx | 96 + .../components/chat-history/getActionInfo.ts | 27 + templates/agent/client/index.css | 772 ++++ templates/agent/client/main.tsx | 10 + .../agent/client/modes/AgentModeChart.ts | 107 + .../client/modes/AgentModeDefinitions.ts | 194 + .../overlays/AgentHighlightOverlayUtil.ts | 383 ++ .../parts/AgentViewportBoundsPartUtil.ts | 19 + .../client/parts/BlurryShapesPartUtil.ts | 49 + .../agent/client/parts/CanvasLintsPartUtil.ts | 39 + .../agent/client/parts/ChatHistoryPartUtil.ts | 32 + .../client/parts/ContextItemsPartUtil.ts | 23 + templates/agent/client/parts/DataPartUtil.ts | 33 + templates/agent/client/parts/DebugPartUtil.ts | 18 + .../agent/client/parts/MessagesPartUtil.ts | 18 + templates/agent/client/parts/ModePartUtil.ts | 24 + .../agent/client/parts/ModelNamePartUtil.ts | 17 + .../client/parts/PeripheralShapesPartUtil.ts | 48 + .../agent/client/parts/PromptPartUtil.ts | 70 + .../agent/client/parts/ScreenshotPartUtil.ts | 45 + .../client/parts/SelectedShapesPartUtil.ts | 22 + templates/agent/client/parts/TimePartUtil.ts | 15 + .../agent/client/parts/TodoListPartUtil.ts | 17 + .../client/parts/UserActionHistoryPartUtil.ts | 110 + .../parts/UserViewportBoundsPartUtil.ts | 19 + .../agent/client/tools/TargetAreaTool.tsx | 119 + .../agent/client/tools/TargetShapeTool.tsx | 165 + templates/agent/client/vite-env.d.ts | 1 + templates/agent/index.html | 13 + templates/agent/package.json | 60 + templates/agent/public/favicon.ico | Bin 0 -> 15406 bytes .../agent/scripts/vite-zod-locale-plugin.d.ts | 7 + .../agent/scripts/vite-zod-locale-plugin.js | 40 + templates/agent/scripts/zod-locales-shim.js | 7 + templates/agent/shared/format/BlurryShape.ts | 11 + templates/agent/shared/format/FocusedColor.ts | 36 + templates/agent/shared/format/FocusedFill.ts | 31 + .../agent/shared/format/FocusedFontSize.ts | 86 + .../shared/format/FocusedGeoShapeType.ts | 26 + templates/agent/shared/format/FocusedShape.ts | 179 + .../shared/format/PeripheralShapesCluster.ts | 6 + .../convertFocusedShapeToTldrawShape.ts | 817 ++++ .../format/convertTldrawShapeToBlurryShape.ts | 33 + .../convertTldrawShapeToFocusedShape.ts | 315 ++ .../convertTldrawShapesToPeripheralShapes.ts | 54 + templates/agent/shared/icons/AgentIcon.tsx | 39 + templates/agent/shared/icons/AtIcon.tsx | 19 + templates/agent/shared/icons/BrainIcon.tsx | 25 + .../agent/shared/icons/ChevronDownIcon.tsx | 18 + .../agent/shared/icons/ChevronRightIcon.tsx | 18 + templates/agent/shared/icons/CommentIcon.tsx | 18 + templates/agent/shared/icons/CrossIcon.tsx | 19 + templates/agent/shared/icons/CursorIcon.tsx | 18 + templates/agent/shared/icons/EllipsisIcon.tsx | 20 + templates/agent/shared/icons/EyeIcon.tsx | 19 + templates/agent/shared/icons/NoteIcon.tsx | 23 + templates/agent/shared/icons/PencilIcon.tsx | 19 + templates/agent/shared/icons/RefreshIcon.tsx | 21 + templates/agent/shared/icons/SearchIcon.tsx | 19 + templates/agent/shared/icons/SmallSpinner.tsx | 17 + templates/agent/shared/icons/TargetIcon.tsx | 22 + templates/agent/shared/icons/TickIcon.tsx | 18 + templates/agent/shared/icons/TrashIcon.tsx | 22 + templates/agent/shared/models.ts | 145 + .../schema/AgentActionSchemaRegistry.ts | 95 + .../agent/shared/schema/AgentActionSchemas.ts | 385 ++ .../shared/schema/PromptPartDefinitions.ts | 528 +++ .../shared/schema/buildResponseSchema.ts | 45 + templates/agent/shared/types/AgentAction.ts | 113 + .../agent/shared/types/AgentCanvasLint.ts | 8 + templates/agent/shared/types/AgentInput.ts | 21 + templates/agent/shared/types/AgentMessage.ts | 11 + templates/agent/shared/types/AgentPrompt.ts | 24 + templates/agent/shared/types/AgentRequest.ts | 49 + .../agent/shared/types/BaseAgentAction.ts | 6 + .../agent/shared/types/BasePromptPart.ts | 6 + .../agent/shared/types/ChatHistoryInfo.ts | 35 + .../agent/shared/types/ChatHistoryItem.ts | 41 + templates/agent/shared/types/ContextItem.ts | 70 + templates/agent/shared/types/PromptPart.ts | 126 + templates/agent/shared/types/Streaming.ts | 10 + .../shared/types/SystemPromptCategory.ts | 8 + templates/agent/shared/types/TodoItem.ts | 7 + templates/agent/shared/types/ids-schema.ts | 21 + templates/agent/tsconfig.json | 36 + templates/agent/vite.config.ts | 16 + .../agent/worker/do/AgentDurableObject.ts | 80 + templates/agent/worker/do/AgentService.ts | 228 + .../agent/worker/do/closeAndParseJson.ts | 72 + templates/agent/worker/environment.ts | 6 + .../agent/worker/prompt/buildMessages.ts | 98 + .../agent/worker/prompt/buildSystemPrompt.ts | 58 + templates/agent/worker/prompt/getModelName.ts | 23 + .../worker/prompt/getSystemPromptFlags.ts | 81 + .../agent/worker/prompt/sections/flagged.ts | 3 + .../worker/prompt/sections/intro-section.ts | 17 + .../worker/prompt/sections/rules-section.ts | 244 + templates/agent/worker/routes/stream.ts | 25 + templates/agent/worker/worker.ts | 25 + templates/agent/wrangler.toml | 25 + templates/branching-chat/.gitignore | 3 + templates/branching-chat/LICENSE.md | 9 + templates/branching-chat/README.md | 135 + templates/branching-chat/client/App.tsx | 99 + .../client/components/WorkflowToolbar.tsx | 131 + .../client/components/icons/HandleIcon.tsx | 12 + .../client/components/icons/SendIcon.tsx | 12 + .../connection/ConnectionBindingUtil.tsx | 196 + .../ConnectionCenterHandleOverlayUtil.tsx | 124 + .../client/connection/ConnectionShapeUtil.tsx | 339 ++ .../connection/insertNodeWithinConnection.tsx | 207 + .../connection/keepConnectionsAtBottom.tsx | 116 + templates/branching-chat/client/constants.tsx | 9 + .../client/disableTransparency.tsx | 13 + templates/branching-chat/client/index.css | 86 + templates/branching-chat/client/main.tsx | 5 + .../client/nodes/NodeShapeUtil.tsx | 153 + .../branching-chat/client/nodes/nodePorts.tsx | 96 + .../branching-chat/client/nodes/nodeTypes.tsx | 67 + .../client/nodes/types/MessageNode.tsx | 209 + .../client/nodes/types/shared.tsx | 73 + .../client/ports/PointingPort.tsx | 150 + .../branching-chat/client/ports/Port.tsx | 80 + .../client/ports/getPortAtPoint.tsx | 48 + .../branching-chat/client/ports/portState.ts | 24 + templates/branching-chat/index.html | 13 + templates/branching-chat/package.json | 55 + templates/branching-chat/public/favicon.ico | Bin 0 -> 15406 bytes templates/branching-chat/tsconfig.json | 23 + templates/branching-chat/vite.config.ts | 10 + templates/branching-chat/worker/types.ts | 4 + templates/branching-chat/worker/worker.ts | 69 + templates/branching-chat/wrangler.toml | 12 + templates/chat/.gitignore | 36 + templates/chat/LICENSE.md | 9 + templates/chat/README.md | 75 + templates/chat/next.config.mjs | 6 + templates/chat/package.json | 45 + templates/chat/src/app/api/chat/route.ts | 26 + templates/chat/src/app/api/upload/route.ts | 27 + templates/chat/src/app/favicon.ico | Bin 0 -> 15406 bytes templates/chat/src/app/layout.tsx | 14 + templates/chat/src/app/page.tsx | 10 + templates/chat/src/app/styles.css | 615 +++ templates/chat/src/components/Chat.tsx | 201 + templates/chat/src/components/ChatInput.tsx | 212 + .../chat/src/components/ChatInputImage.tsx | 28 + templates/chat/src/components/ChatMessage.tsx | 71 + .../chat/src/components/ClearChatIcon.tsx | 27 + templates/chat/src/components/MessageList.tsx | 18 + .../chat/src/components/WhiteboardModal.tsx | 189 + .../chat/src/components/icons/ImageIcon.tsx | 22 + .../chat/src/components/icons/SendIcon.tsx | 19 + .../chat/src/components/icons/UploadIcon.tsx | 19 + .../src/components/icons/WhiteboardIcon.tsx | 49 + templates/chat/src/components/icons/XIcon.tsx | 13 + templates/chat/src/hooks/useChatInputState.ts | 101 + .../chat/src/hooks/useChatMessageStorage.tsx | 54 + templates/chat/src/hooks/useScrollToBottom.ts | 57 + .../chat/src/utils/uploadMessageContents.ts | 92 + templates/chat/tsconfig.json | 49 + templates/chat/vercel.json | 6 + templates/image-pipeline/README.md | 114 + templates/image-pipeline/index.html | 13 + templates/image-pipeline/package.json | 51 + templates/image-pipeline/src/App.tsx | 136 + .../image-pipeline/src/api/pipelineApi.ts | 181 + .../src/components/ImagePipelineSidebar.tsx | 174 + .../src/components/OnCanvasNodePicker.tsx | 181 + .../src/components/PipelineRegions.tsx | 150 + .../src/components/PipelineToolbar.tsx | 109 + .../src/components/TemplatePicker.tsx | 113 + .../src/components/icons/AddIcon.tsx | 7 + .../src/components/icons/AdjustIcon.tsx | 12 + .../src/components/icons/BlendIcon.tsx | 8 + .../src/components/icons/CaptureIcon.tsx | 13 + .../src/components/icons/ControlNetIcon.tsx | 16 + .../src/components/icons/GenerateIcon.tsx | 14 + .../src/components/icons/GenerateTextIcon.tsx | 17 + .../src/components/icons/IPAdapterIcon.tsx | 16 + .../src/components/icons/IteratorIcon.tsx | 15 + .../src/components/icons/LoadImageIcon.tsx | 15 + .../src/components/icons/ModelIcon.tsx | 20 + .../src/components/icons/NumberIcon.tsx | 13 + .../src/components/icons/PlayIcon.tsx | 7 + .../src/components/icons/PreviewIcon.tsx | 14 + .../src/components/icons/PromptConcatIcon.tsx | 11 + .../src/components/icons/PromptIcon.tsx | 13 + .../src/components/icons/RouterIcon.tsx | 11 + .../src/components/icons/StopIcon.tsx | 7 + .../components/icons/StyleTransferIcon.tsx | 21 + .../src/components/icons/SubtractIcon.tsx | 7 + .../src/components/icons/TemplateIcon.tsx | 19 + .../src/components/icons/UpscaleIcon.tsx | 15 + .../src/connection/ConnectionBindingUtil.tsx | 186 + .../ConnectionCenterHandleOverlayUtil.tsx | 124 + .../src/connection/ConnectionShapeUtil.tsx | 404 ++ .../connection/insertNodeWithinConnection.tsx | 87 + .../connection/keepConnectionsAtBottom.tsx | 95 + templates/image-pipeline/src/constants.tsx | 30 + .../src/disableTransparency.tsx | 17 + .../src/execution/ExecutionGraph.tsx | 166 + .../src/execution/executionState.ts | 38 + templates/image-pipeline/src/index.css | 833 ++++ templates/image-pipeline/src/main.tsx | 5 + .../src/nodes/NodeShapeUtil.tsx | 367 ++ .../image-pipeline/src/nodes/nodePorts.tsx | 212 + .../image-pipeline/src/nodes/nodeTypes.tsx | 138 + .../image-pipeline/src/nodes/resizeNode.ts | 129 + .../src/nodes/types/AdjustNode.tsx | 197 + .../src/nodes/types/BlendNode.tsx | 246 + .../src/nodes/types/CaptureNode.tsx | 144 + .../src/nodes/types/ControlNetNode.tsx | 274 ++ .../src/nodes/types/GenerateNode.tsx | 314 ++ .../src/nodes/types/GenerateTextNode.tsx | 182 + .../src/nodes/types/IPAdapterNode.tsx | 218 + .../src/nodes/types/IteratorNode.tsx | 235 + .../src/nodes/types/LoadImageNode.tsx | 194 + .../src/nodes/types/ModelNode.tsx | 140 + .../src/nodes/types/NumberNode.tsx | 83 + .../src/nodes/types/PreviewNode.tsx | 120 + .../src/nodes/types/PromptConcatNode.tsx | 202 + .../src/nodes/types/PromptNode.tsx | 89 + .../src/nodes/types/RouterNode.tsx | 122 + .../src/nodes/types/StyleTransferNode.tsx | 253 ++ .../src/nodes/types/UpscaleNode.tsx | 194 + .../image-pipeline/src/nodes/types/shared.tsx | 393 ++ .../image-pipeline/src/ports/PointingPort.tsx | 180 + templates/image-pipeline/src/ports/Port.tsx | 93 + .../src/ports/getPortAtPoint.tsx | 42 + .../src/ports/portCompatibility.ts | 22 + .../image-pipeline/src/ports/portState.ts | 29 + .../src/templates/templateActions.ts | 154 + .../src/templates/templateState.ts | 57 + templates/image-pipeline/src/utils.ts | 29 + templates/image-pipeline/src/utils/sleep.ts | 8 + templates/image-pipeline/tsconfig.json | 22 + templates/image-pipeline/vite.config.ts | 8 + .../image-pipeline/worker/providers/index.ts | 18 + .../worker/providers/replicate.ts | 235 + .../image-pipeline/worker/providers/types.ts | 95 + .../image-pipeline/worker/routes/generate.ts | 103 + .../worker/routes/generateText.ts | 116 + .../image-pipeline/worker/routes/images.ts | 68 + .../image-pipeline/worker/routes/ipAdapter.ts | 101 + .../worker/routes/styleTransfer.ts | 119 + .../image-pipeline/worker/routes/upscale.ts | 57 + templates/image-pipeline/worker/worker.ts | 38 + templates/image-pipeline/wrangler.toml | 29 + templates/nextjs/.gitignore | 36 + templates/nextjs/LICENSE.md | 9 + templates/nextjs/README.md | 40 + templates/nextjs/next.config.mjs | 6 + templates/nextjs/package.json | 33 + templates/nextjs/src/app/favicon.ico | Bin 0 -> 15406 bytes templates/nextjs/src/app/globals.css | 7 + templates/nextjs/src/app/layout.tsx | 14 + templates/nextjs/src/app/page.tsx | 12 + templates/nextjs/tsconfig.json | 49 + templates/shader/.gitignore | 3 + templates/shader/LICENSE.md | 9 + templates/shader/README.md | 155 + templates/shader/index.html | 13 + templates/shader/package.json | 42 + templates/shader/public/favicon.ico | Bin 0 -> 15406 bytes templates/shader/src/App.tsx | 65 + templates/shader/src/WebGLCanvas.tsx | 12 + templates/shader/src/WebGLManager.ts | 286 ++ .../shader/src/config-panel/ConfigPanel.tsx | 62 + .../ConfigPanelBooleanControl.tsx | 23 + .../src/config-panel/ConfigPanelLabel.tsx | 3 + .../src/config-panel/ConfigPanelSlider.tsx | 43 + .../shader/src/config-panel/config-panel.md | 239 + .../shader/src/fluid/FluidConfigPanel.tsx | 251 ++ templates/shader/src/fluid/FluidManager.ts | 442 ++ templates/shader/src/fluid/FluidRenderer.tsx | 60 + templates/shader/src/fluid/config.ts | 32 + templates/shader/src/fluid/fluid.md | 125 + templates/shader/src/fluid/fluid.ts | 2024 +++++++++ templates/shader/src/index.css | 7 + templates/shader/src/main.tsx | 11 + .../shader/src/minimal/MinimalConfigPanel.tsx | 52 + .../shader/src/minimal/MinimalRenderer.tsx | 25 + .../src/minimal/MinimalShaderManager.ts | 170 + templates/shader/src/minimal/config.ts | 36 + templates/shader/src/minimal/fragment.glsl | 12 + .../shader/src/minimal/minimal-example.md | 199 + templates/shader/src/minimal/vertex.glsl | 15 + .../shader/src/rainbow/RainbowConfigPanel.tsx | 54 + .../shader/src/rainbow/RainbowRenderer.tsx | 25 + .../src/rainbow/RainbowShaderManager.ts | 299 ++ templates/shader/src/rainbow/config.ts | 38 + templates/shader/src/rainbow/fragment.glsl | 172 + .../shader/src/rainbow/rainbow-example.md | 325 ++ templates/shader/src/rainbow/vertex.glsl | 15 + templates/shader/src/shader.css | 108 + .../shader/src/shadow/ShadowControlPanel.tsx | 53 + .../shader/src/shadow/ShadowRenderer.tsx | 25 + .../shader/src/shadow/ShadowShaderManager.ts | 290 ++ templates/shader/src/shadow/config.ts | 34 + templates/shader/src/shadow/fragment.glsl | 97 + templates/shader/src/shadow/shadow-example.md | 23 + templates/shader/src/shadow/vertex.glsl | 15 + templates/shader/src/vite-env.d.ts | 1 + templates/shader/tsconfig.json | 22 + templates/shader/vercel.json | 6 + templates/shader/vite-env.d.ts | 1 + templates/shader/vite.config.ts | 7 + templates/simple-server-example/.gitignore | 3 + templates/simple-server-example/README.md | 33 + templates/simple-server-example/package.json | 49 + .../simple-server-example/src/client/App.tsx | 98 + .../src/client/index.css | 7 + .../src/client/index.html | 13 + .../simple-server-example/src/client/main.tsx | 10 + .../src/client/vite-env.d.ts | 1 + .../src/server/assets.ts | 15 + .../simple-server-example/src/server/rooms.ts | 47 + .../src/server/server.ts | 83 + .../src/server/unfurl.ts | 14 + templates/simple-server-example/tsconfig.json | 11 + .../simple-server-example/vite.config.mts | 15 + templates/socketio-server-example/.gitignore | 3 + templates/socketio-server-example/README.md | 33 + .../socketio-server-example/package.json | 47 + .../src/client/App.tsx | 176 + .../src/client/index.css | 7 + .../src/client/index.html | 13 + .../src/client/main.tsx | 10 + .../src/client/vite-env.d.ts | 1 + .../src/server/assets.ts | 15 + .../src/server/rooms.ts | 48 + .../src/server/server.ts | 139 + .../src/server/unfurl.ts | 14 + .../socketio-server-example/tsconfig.json | 11 + .../socketio-server-example/vite.config.mts | 15 + templates/sync-cloudflare/.gitignore | 5 + templates/sync-cloudflare/LICENSE.md | 9 + templates/sync-cloudflare/README.md | 119 + .../client/getBookmarkPreview.tsx | 40 + templates/sync-cloudflare/client/index.css | 88 + .../sync-cloudflare/client/localStorage.ts | 21 + templates/sync-cloudflare/client/main.tsx | 23 + .../client/multiplayerAssetStore.tsx | 30 + .../sync-cloudflare/client/pages/Room.tsx | 83 + .../sync-cloudflare/client/pages/Root.tsx | 10 + .../sync-cloudflare/client/vite-env.d.ts | 1 + templates/sync-cloudflare/index.html | 13 + templates/sync-cloudflare/package.json | 55 + templates/sync-cloudflare/public/favicon.ico | Bin 0 -> 15406 bytes templates/sync-cloudflare/tsconfig.json | 27 + templates/sync-cloudflare/vite.config.ts | 10 + .../worker/TldrawDurableObject.ts | 157 + .../sync-cloudflare/worker/assetUploads.ts | 105 + templates/sync-cloudflare/worker/worker.ts | 37 + templates/sync-cloudflare/wrangler.toml | 35 + templates/vite/.gitignore | 3 + templates/vite/LICENSE.md | 9 + templates/vite/README.md | 40 + templates/vite/index.html | 13 + templates/vite/package.json | 41 + templates/vite/public/favicon.ico | Bin 0 -> 15406 bytes templates/vite/src/App.tsx | 11 + templates/vite/src/index.css | 7 + templates/vite/src/main.tsx | 10 + templates/vite/src/vite-env.d.ts | 1 + templates/vite/tsconfig.json | 21 + templates/vite/vite-env.d.ts | 1 + templates/vite/vite.config.ts | 7 + templates/vue/.gitignore | 3 + templates/vue/LICENSE.md | 9 + templates/vue/README.md | 42 + templates/vue/index.html | 13 + templates/vue/package.json | 40 + templates/vue/public/favicon.ico | Bin 0 -> 15406 bytes templates/vue/src/App.vue | 39 + templates/vue/src/TldrawWrapper.tsx | 6 + templates/vue/src/index.css | 14 + templates/vue/src/main.ts | 5 + templates/vue/src/vite-env.d.ts | 7 + templates/vue/tsconfig.json | 21 + templates/vue/vite.config.ts | 9 + templates/workflow/.gitignore | 3 + templates/workflow/LICENSE.md | 9 + templates/workflow/README.md | 78 + templates/workflow/alex-notes.md | 23 + templates/workflow/index.html | 13 + templates/workflow/package.json | 44 + templates/workflow/public/favicon.ico | Bin 0 -> 15406 bytes templates/workflow/src/App.tsx | 108 + .../components/MathematicalToolbarItem.tsx | 54 + .../components/OnCanvasComponentPicker.tsx | 186 + .../src/components/WorkflowRegions.tsx | 174 + .../src/components/WorkflowToolbar.tsx | 141 + .../workflow/src/components/icons/AddIcon.tsx | 22 + .../src/components/icons/ConditionalIcon.tsx | 22 + .../src/components/icons/DivideIcon.tsx | 26 + .../src/components/icons/EarthquakeIcon.tsx | 18 + .../src/components/icons/MathematicalIcon.tsx | 67 + .../src/components/icons/MultiplyIcon.tsx | 18 + .../src/components/icons/PlayIcon.tsx | 22 + .../src/components/icons/SliderIcon.tsx | 28 + .../src/components/icons/StopIcon.tsx | 16 + .../src/components/icons/SubtractIcon.tsx | 7 + .../src/connection/ConnectionBindingUtil.tsx | 198 + .../ConnectionCenterHandleOverlayUtil.tsx | 125 + .../src/connection/ConnectionShapeUtil.tsx | 386 ++ .../connection/insertNodeWithinConnection.tsx | 167 + .../connection/keepConnectionsAtBottom.tsx | 125 + templates/workflow/src/constants.tsx | 12 + .../workflow/src/disableTransparency.tsx | 17 + .../workflow/src/execution/ExecutionGraph.tsx | 172 + .../workflow/src/execution/executionState.ts | 50 + .../workflow/src/hooks/useDragToCreate.ts | 180 + templates/workflow/src/index.css | 322 ++ templates/workflow/src/main.tsx | 5 + .../workflow/src/nodes/NodeShapeUtil.tsx | 165 + templates/workflow/src/nodes/nodePorts.tsx | 157 + templates/workflow/src/nodes/nodeTypes.tsx | 115 + .../workflow/src/nodes/types/AddNode.tsx | 202 + .../src/nodes/types/ConditionalNode.tsx | 219 + .../workflow/src/nodes/types/DivideNode.tsx | 123 + .../src/nodes/types/EarthquakeNode.tsx | 208 + .../workflow/src/nodes/types/MultiplyNode.tsx | 126 + .../workflow/src/nodes/types/SliderNode.tsx | 85 + .../workflow/src/nodes/types/SubtractNode.tsx | 126 + templates/workflow/src/nodes/types/shared.tsx | 258 ++ templates/workflow/src/ports/PointingPort.tsx | 204 + templates/workflow/src/ports/Port.tsx | 88 + .../workflow/src/ports/getPortAtPoint.tsx | 49 + templates/workflow/src/ports/portState.ts | 28 + templates/workflow/src/utils.ts | 85 + templates/workflow/src/utils/sleep.ts | 8 + templates/workflow/tsconfig.json | 22 + templates/workflow/vercel.json | 6 + templates/workflow/vite.config.ts | 7 + tsdoc.json | 15 + vitest.config.ts | 12 + 4541 files changed, 770499 insertions(+) create mode 120000 .agents/skills create mode 100644 .claude/launch.json create mode 100644 .claude/settings.json create mode 120000 .claude/skills create mode 100644 .cursor-plugin/marketplace.json create mode 120000 .cursor/skills create mode 100644 .dockerignore create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/example_request.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/task.yml create mode 100644 .github/actions/deploy-templates/action.yml create mode 100644 .github/actions/discord-fail-notify/action.yml create mode 100644 .github/actions/setup-playwright/action.yml create mode 100644 .github/actions/setup/action.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/bump-versions.yml create mode 100644 .github/workflows/checks.yml create mode 100644 .github/workflows/claude.yml create mode 100644 .github/workflows/close-stale-issues.yml create mode 100644 .github/workflows/dependabot-dedupe.yml create mode 100644 .github/workflows/deploy-analytics.yml create mode 100644 .github/workflows/deploy-bemo.yml create mode 100644 .github/workflows/deploy-dotcom.yml create mode 100644 .github/workflows/deploy-grafana.yml create mode 100644 .github/workflows/deploy-mcp-app.yml create mode 100644 .github/workflows/deploy-templates.yml create mode 100644 .github/workflows/e2e-device.yml create mode 100644 .github/workflows/get-changelog.yml create mode 100644 .github/workflows/i18n-download-strings.yml create mode 100644 .github/workflows/i18n-upload-strings.yml create mode 100644 .github/workflows/issue-triage.yml create mode 100644 .github/workflows/license-report.yml create mode 100644 .github/workflows/playwright-dotcom.yml create mode 100644 .github/workflows/playwright-examples.yml create mode 100644 .github/workflows/playwright-mermaid.yml create mode 100644 .github/workflows/playwright-perf.yml create mode 100644 .github/workflows/playwright-update-snapshots.yml create mode 100644 .github/workflows/post-release-crew.yml create mode 100644 .github/workflows/post-release-marketing.yml create mode 100644 .github/workflows/prune-preview-deploys.yml create mode 100644 .github/workflows/publish-editor-extensions.yml create mode 100644 .github/workflows/publish-templates.yml create mode 100644 .github/workflows/publish-vscode-extension.yml create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/staging-cleanup-daily.yml create mode 100644 .github/workflows/staging-e2e.yml create mode 100644 .github/workflows/trigger-dotcom-hotfix.yml create mode 100644 .github/workflows/trigger-production-build.yml create mode 100644 .github/workflows/trigger-sdk-hotfix.yml create mode 100644 .github/workflows/update-release-notes.yml create mode 100644 .gitignore create mode 100755 .husky/post-checkout create mode 100755 .husky/post-merge create mode 100755 .husky/pre-commit create mode 100755 .husky/pre-push create mode 100644 .ignore create mode 100644 .oxfmtrc.json create mode 100644 .oxlintrc.json create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 .yarn/patches/@microsoft-tsdoc-npm-0.15.1-e24295d9bd.patch create mode 100644 .yarnrc.yml create mode 100644 AGENTS.md create mode 100644 CLA.md create mode 100644 CLAUDE.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 COMPANY.md create mode 100644 CONTRIBUTING.md create mode 100644 FAQ.md create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 RELEASES.md create mode 100644 SECURITY.md create mode 100644 TRADEMARKS.md create mode 100644 VOICE.md create mode 100644 apps/analytics-worker/.gitignore create mode 100644 apps/analytics-worker/package.json create mode 100644 apps/analytics-worker/src/worker.ts create mode 100644 apps/analytics-worker/tsconfig.json create mode 100644 apps/analytics-worker/vitest.config.ts create mode 100644 apps/analytics-worker/wrangler.toml create mode 100644 apps/analytics/.gitignore create mode 100644 apps/analytics/index.html create mode 100644 apps/analytics/package.json create mode 100644 apps/analytics/src/analytics-services/analytics-service.ts create mode 100644 apps/analytics/src/analytics-services/ga4.ts create mode 100644 apps/analytics/src/analytics-services/gtm.ts create mode 100644 apps/analytics/src/analytics-services/hubspot.ts create mode 100644 apps/analytics/src/analytics-services/posthog.ts create mode 100644 apps/analytics/src/analytics-services/reo.ts create mode 100644 apps/analytics/src/components/CookieConsentBanner.ts create mode 100644 apps/analytics/src/components/PrivacySettingsDialog.ts create mode 100644 apps/analytics/src/constants.ts create mode 100644 apps/analytics/src/index.ts create mode 100644 apps/analytics/src/state/cookie-consent-state.ts create mode 100644 apps/analytics/src/state/state.test.ts create mode 100644 apps/analytics/src/state/state.ts create mode 100644 apps/analytics/src/state/theme-state.ts create mode 100644 apps/analytics/src/styles.css create mode 100644 apps/analytics/src/types.ts create mode 100644 apps/analytics/src/utils/consent-check.ts create mode 100644 apps/analytics/src/vite-env.d.ts create mode 100644 apps/analytics/tsconfig.json create mode 100644 apps/analytics/vercel.json create mode 100644 apps/analytics/vite.config.ts create mode 100644 apps/analytics/vitest.config.ts create mode 100644 apps/bemo-worker/.gitignore create mode 100644 apps/bemo-worker/README.md create mode 100644 apps/bemo-worker/package.json create mode 100644 apps/bemo-worker/src/BemoDO.ts create mode 100644 apps/bemo-worker/src/makePermissiveSchema.ts create mode 100644 apps/bemo-worker/src/types.ts create mode 100644 apps/bemo-worker/src/worker.test.ts create mode 100644 apps/bemo-worker/src/worker.ts create mode 100644 apps/bemo-worker/tsconfig.json create mode 100644 apps/bemo-worker/vitest.config.ts create mode 100644 apps/bemo-worker/wrangler.toml create mode 100644 apps/docs/.gitignore create mode 100644 apps/docs/.prettierignore create mode 100644 apps/docs/LICENSE.md create mode 100644 apps/docs/README.md create mode 100644 apps/docs/app/(docs)/[...slug]/page.tsx create mode 100644 apps/docs/app/(docs)/layout.tsx create mode 100644 apps/docs/app/.well-known/agent-skills/index.json/route.ts create mode 100644 apps/docs/app/.well-known/agent-skills/tldraw-migrate.tar.gz/route.ts create mode 100644 apps/docs/app/.well-known/agent-skills/tldraw-migrate/SKILL.md/route.ts create mode 100644 apps/docs/app/analytics.tsx create mode 100644 apps/docs/app/globals.css create mode 100644 apps/docs/app/layout.tsx create mode 100644 apps/docs/app/not-found.tsx create mode 100644 apps/docs/app/robots.txt create mode 100644 apps/docs/app/search/layout.tsx create mode 100644 apps/docs/app/search/page.tsx create mode 100644 apps/docs/app/sitemap.ts create mode 100644 apps/docs/components/common/autorefresh.tsx create mode 100644 apps/docs/components/common/back-to-top-button.tsx create mode 100644 apps/docs/components/common/button.tsx create mode 100644 apps/docs/components/common/icon/discord.tsx create mode 100644 apps/docs/components/common/icon/github.tsx create mode 100644 apps/docs/components/common/icon/index.tsx create mode 100644 apps/docs/components/common/icon/linkedin.tsx create mode 100644 apps/docs/components/common/icon/tldraw.tsx create mode 100644 apps/docs/components/common/icon/twitter.tsx create mode 100644 apps/docs/components/common/logo.tsx create mode 100644 apps/docs/components/common/navigation.tsx create mode 100644 apps/docs/components/common/page-title.tsx create mode 100644 apps/docs/components/common/theme-switch.tsx create mode 100644 apps/docs/components/common/tldraw-link.tsx create mode 100644 apps/docs/components/content/api-heading.tsx create mode 100644 apps/docs/components/content/bento.tsx create mode 100644 apps/docs/components/content/blockquote.tsx create mode 100644 apps/docs/components/content/callout.tsx create mode 100644 apps/docs/components/content/check-item.tsx create mode 100644 apps/docs/components/content/code-files.tsx create mode 100644 apps/docs/components/content/code.tsx create mode 100644 apps/docs/components/content/copy-button.tsx create mode 100644 apps/docs/components/content/embed.tsx create mode 100644 apps/docs/components/content/example.tsx create mode 100644 apps/docs/components/content/feature.tsx create mode 100644 apps/docs/components/content/image.tsx create mode 100644 apps/docs/components/content/index.tsx create mode 100644 apps/docs/components/content/masked-article-image.tsx create mode 100644 apps/docs/components/content/parameters-table-description.tsx create mode 100644 apps/docs/components/content/parameters-table-name.tsx create mode 100644 apps/docs/components/content/parameters-table-row.tsx create mode 100644 apps/docs/components/content/parameters-table.tsx create mode 100644 apps/docs/components/content/pre.tsx create mode 100644 apps/docs/components/content/side-by-side-images.tsx create mode 100644 apps/docs/components/content/title-with-source-link.tsx create mode 100644 apps/docs/components/content/video.tsx create mode 100644 apps/docs/components/content/youtube.tsx create mode 100644 apps/docs/components/docs/copy-markdown-button.tsx create mode 100644 apps/docs/components/docs/docs-article-info.tsx create mode 100644 apps/docs/components/docs/docs-category-menu.tsx create mode 100644 apps/docs/components/docs/docs-feedback-widget.tsx create mode 100644 apps/docs/components/docs/docs-footer.tsx create mode 100644 apps/docs/components/docs/docs-header.tsx create mode 100644 apps/docs/components/docs/docs-mobile-sidebar.tsx create mode 100644 apps/docs/components/docs/docs-search-bar.tsx create mode 100644 apps/docs/components/docs/docs-sidebar-menu.tsx create mode 100644 apps/docs/components/docs/docs-sidebar-menus.tsx create mode 100644 apps/docs/components/docs/docs-sidebar-utils.ts create mode 100644 apps/docs/components/docs/docs-sidebar.tsx create mode 100644 apps/docs/components/docs/docs-starter-sidebar.tsx create mode 100644 apps/docs/components/docs/docs-table-of-contents.tsx create mode 100644 apps/docs/components/navigation/footer.tsx create mode 100644 apps/docs/components/navigation/header.tsx create mode 100644 apps/docs/components/navigation/headings-menu.tsx create mode 100644 apps/docs/components/navigation/link.tsx create mode 100644 apps/docs/components/navigation/social-link.tsx create mode 100644 apps/docs/components/search/ContentHighlight.tsx create mode 100644 apps/docs/components/search/FullPageSearch.tsx create mode 100644 apps/docs/components/search/SearchButton.tsx create mode 100644 apps/docs/components/search/SearchDialog.tsx create mode 100644 apps/docs/components/search/index.tsx create mode 100644 apps/docs/content/community/contributing.mdx create mode 100644 apps/docs/content/community/dependencies.mdx create mode 100644 apps/docs/content/community/license.mdx create mode 100644 apps/docs/content/community/translations.mdx create mode 100644 apps/docs/content/docs/ai.mdx create mode 100644 apps/docs/content/docs/assets.mdx create mode 100644 apps/docs/content/docs/collaboration.mdx create mode 100644 apps/docs/content/docs/commenting.mdx create mode 100644 apps/docs/content/docs/driver.mdx create mode 100644 apps/docs/content/docs/editor.mdx create mode 100644 apps/docs/content/docs/handles.mdx create mode 100644 apps/docs/content/docs/indicators.mdx create mode 100644 apps/docs/content/docs/llm-docs.mdx create mode 100644 apps/docs/content/docs/mermaid.mdx create mode 100644 apps/docs/content/docs/persistence.mdx create mode 100644 apps/docs/content/docs/shapes.mdx create mode 100644 apps/docs/content/docs/sync.mdx create mode 100644 apps/docs/content/docs/tools.mdx create mode 100644 apps/docs/content/docs/user-interface.mdx create mode 100644 apps/docs/content/getting-started/installation.mdx create mode 100644 apps/docs/content/getting-started/quick-start.mdx create mode 100644 apps/docs/content/getting-started/releases.mdx create mode 100644 apps/docs/content/releases/migration-skill.mdx create mode 100644 apps/docs/content/releases/next.mdx create mode 100644 apps/docs/content/releases/v2.0.0.mdx create mode 100644 apps/docs/content/releases/v2.1.0.mdx create mode 100644 apps/docs/content/releases/v2.2.0.mdx create mode 100644 apps/docs/content/releases/v2.3.0.mdx create mode 100644 apps/docs/content/releases/v2.4.0.mdx create mode 100644 apps/docs/content/releases/v3.0.0.mdx create mode 100644 apps/docs/content/releases/v3.1.0.mdx create mode 100644 apps/docs/content/releases/v3.10.0.mdx create mode 100644 apps/docs/content/releases/v3.11.0.mdx create mode 100644 apps/docs/content/releases/v3.12.0.mdx create mode 100644 apps/docs/content/releases/v3.13.0.mdx create mode 100644 apps/docs/content/releases/v3.14.0.mdx create mode 100644 apps/docs/content/releases/v3.15.0.mdx create mode 100644 apps/docs/content/releases/v3.2.0.mdx create mode 100644 apps/docs/content/releases/v3.3.0.mdx create mode 100644 apps/docs/content/releases/v3.4.0.mdx create mode 100644 apps/docs/content/releases/v3.5.0.mdx create mode 100644 apps/docs/content/releases/v3.6.0.mdx create mode 100644 apps/docs/content/releases/v3.7.0.mdx create mode 100644 apps/docs/content/releases/v3.8.0.mdx create mode 100644 apps/docs/content/releases/v3.9.0.mdx create mode 100644 apps/docs/content/releases/v4.0.0.mdx create mode 100644 apps/docs/content/releases/v4.1.0.mdx create mode 100644 apps/docs/content/releases/v4.2.0.mdx create mode 100644 apps/docs/content/releases/v4.3.0.mdx create mode 100644 apps/docs/content/releases/v4.4.0.mdx create mode 100644 apps/docs/content/releases/v4.5.0.mdx create mode 100644 apps/docs/content/releases/v5.0.0.mdx create mode 100644 apps/docs/content/releases/v5.1.0.mdx create mode 100644 apps/docs/content/releases/v5.2.0.mdx create mode 100644 apps/docs/content/releases/v5.3.0.mdx create mode 100644 apps/docs/content/releases/v5.4.0.mdx create mode 100644 apps/docs/content/sdk-features/accessibility.mdx create mode 100644 apps/docs/content/sdk-features/actions.mdx create mode 100644 apps/docs/content/sdk-features/animation.mdx create mode 100644 apps/docs/content/sdk-features/arrow-shape.mdx create mode 100644 apps/docs/content/sdk-features/assets.mdx create mode 100644 apps/docs/content/sdk-features/attribution.mdx create mode 100644 apps/docs/content/sdk-features/bindings.mdx create mode 100644 apps/docs/content/sdk-features/camera.mdx create mode 100644 apps/docs/content/sdk-features/click-detection.mdx create mode 100644 apps/docs/content/sdk-features/clipboard.mdx create mode 100644 apps/docs/content/sdk-features/collaboration.mdx create mode 100644 apps/docs/content/sdk-features/commenting.mdx create mode 100644 apps/docs/content/sdk-features/coordinates.mdx create mode 100644 apps/docs/content/sdk-features/cross-tab-sync.mdx create mode 100644 apps/docs/content/sdk-features/culling.mdx create mode 100644 apps/docs/content/sdk-features/cursor-chat.mdx create mode 100644 apps/docs/content/sdk-features/cursors.mdx create mode 100644 apps/docs/content/sdk-features/deep-links.mdx create mode 100644 apps/docs/content/sdk-features/default-shapes.mdx create mode 100644 apps/docs/content/sdk-features/drag-and-drop.mdx create mode 100644 apps/docs/content/sdk-features/draw-shape.mdx create mode 100644 apps/docs/content/sdk-features/edge-scrolling.mdx create mode 100644 apps/docs/content/sdk-features/editor.mdx create mode 100644 apps/docs/content/sdk-features/embed-shape.mdx create mode 100644 apps/docs/content/sdk-features/environment.mdx create mode 100644 apps/docs/content/sdk-features/eraser.mdx create mode 100644 apps/docs/content/sdk-features/errors.mdx create mode 100644 apps/docs/content/sdk-features/events.mdx create mode 100644 apps/docs/content/sdk-features/external-content.mdx create mode 100644 apps/docs/content/sdk-features/focus.mdx create mode 100644 apps/docs/content/sdk-features/frame-shape.mdx create mode 100644 apps/docs/content/sdk-features/geo-shape.mdx create mode 100644 apps/docs/content/sdk-features/geometry.mdx create mode 100644 apps/docs/content/sdk-features/grid.mdx create mode 100644 apps/docs/content/sdk-features/groups.mdx create mode 100644 apps/docs/content/sdk-features/handles.mdx create mode 100644 apps/docs/content/sdk-features/highlighting.mdx create mode 100644 apps/docs/content/sdk-features/history.mdx create mode 100644 apps/docs/content/sdk-features/image-export.mdx create mode 100644 apps/docs/content/sdk-features/indicators.mdx create mode 100644 apps/docs/content/sdk-features/input-handling.mdx create mode 100644 apps/docs/content/sdk-features/instance-state.mdx create mode 100644 apps/docs/content/sdk-features/internationalization.mdx create mode 100644 apps/docs/content/sdk-features/license-key.mdx create mode 100644 apps/docs/content/sdk-features/locked-shapes.mdx create mode 100644 apps/docs/content/sdk-features/note-shape.mdx create mode 100644 apps/docs/content/sdk-features/options.mdx create mode 100644 apps/docs/content/sdk-features/overlay-utils.mdx create mode 100644 apps/docs/content/sdk-features/pages.mdx create mode 100644 apps/docs/content/sdk-features/parenting.mdx create mode 100644 apps/docs/content/sdk-features/pen-mode.mdx create mode 100644 apps/docs/content/sdk-features/performance.mdx create mode 100644 apps/docs/content/sdk-features/persistence.mdx create mode 100644 apps/docs/content/sdk-features/readonly.mdx create mode 100644 apps/docs/content/sdk-features/rich-text.mdx create mode 100644 apps/docs/content/sdk-features/scribble.mdx create mode 100644 apps/docs/content/sdk-features/selection.mdx create mode 100644 apps/docs/content/sdk-features/shape-clipping.mdx create mode 100644 apps/docs/content/sdk-features/shape-indexing.mdx create mode 100644 apps/docs/content/sdk-features/shape-transforms.mdx create mode 100644 apps/docs/content/sdk-features/shapes.mdx create mode 100644 apps/docs/content/sdk-features/side-effects.mdx create mode 100644 apps/docs/content/sdk-features/signals.mdx create mode 100644 apps/docs/content/sdk-features/snapping.mdx create mode 100644 apps/docs/content/sdk-features/store.mdx create mode 100644 apps/docs/content/sdk-features/styles.mdx create mode 100644 apps/docs/content/sdk-features/text-measurement.mdx create mode 100644 apps/docs/content/sdk-features/text-shape.mdx create mode 100644 apps/docs/content/sdk-features/themes.mdx create mode 100644 apps/docs/content/sdk-features/ticks.mdx create mode 100644 apps/docs/content/sdk-features/tools.mdx create mode 100644 apps/docs/content/sdk-features/ui-components.mdx create mode 100644 apps/docs/content/sdk-features/ui-primitives.mdx create mode 100644 apps/docs/content/sdk-features/user-following.mdx create mode 100644 apps/docs/content/sdk-features/user-preferences.mdx create mode 100644 apps/docs/content/sdk-features/validation.mdx create mode 100644 apps/docs/content/sdk-features/visibility.mdx create mode 100644 apps/docs/content/sections.json create mode 100644 apps/docs/content/starter-kits/agent.mdx create mode 100644 apps/docs/content/starter-kits/branching-chat.mdx create mode 100644 apps/docs/content/starter-kits/chat.mdx create mode 100644 apps/docs/content/starter-kits/image-pipeline.mdx create mode 100644 apps/docs/content/starter-kits/multiplayer.mdx create mode 100644 apps/docs/content/starter-kits/overview.mdx create mode 100644 apps/docs/content/starter-kits/shader.mdx create mode 100644 apps/docs/content/starter-kits/workflow.mdx create mode 100644 apps/docs/next-env.d.ts create mode 100644 apps/docs/next.config.js create mode 100644 apps/docs/package.json create mode 100644 apps/docs/postcss.config.js create mode 100644 apps/docs/public/apple-touch-icon-152x152.svg create mode 100644 apps/docs/public/apple-touch-icon-167x167.svg create mode 100644 apps/docs/public/apple-touch-icon-180x180.svg create mode 100644 apps/docs/public/apple-touch-icon.png create mode 100644 apps/docs/public/favicon-16x16.svg create mode 100644 apps/docs/public/favicon-32x32.svg create mode 100644 apps/docs/public/favicon.ico create mode 100644 apps/docs/public/favicon.svg create mode 100644 apps/docs/public/images/404.svg create mode 100644 apps/docs/public/images/multiplayer_mask.png create mode 100644 apps/docs/public/images/starter-kit-images/agent-starter.avif create mode 100644 apps/docs/public/images/starter-kit-images/multiplayer-starter.avif create mode 100644 apps/docs/public/images/starter-kit-images/shader-starter.avif create mode 100644 apps/docs/public/images/starter-kit-images/workflow-starter.avif create mode 100644 apps/docs/public/images/with-watermark.png create mode 100644 apps/docs/public/images/without-watermark.png create mode 100644 apps/docs/scripts/check-broken-links.ts create mode 100644 apps/docs/scripts/check-external-links.ts create mode 100644 apps/docs/scripts/create-api-markdown.ts create mode 100644 apps/docs/scripts/create-llms-txt.ts create mode 100644 apps/docs/scripts/fetch-api-source.ts create mode 100644 apps/docs/scripts/lib/checkBrokenLinks.ts create mode 100644 apps/docs/scripts/lib/checkExternalLinks.ts create mode 100644 apps/docs/scripts/lib/connect.ts create mode 100644 apps/docs/scripts/lib/createApiMarkdown.ts create mode 100644 apps/docs/scripts/lib/fetchApiSource.ts create mode 100644 apps/docs/scripts/lib/generateApiContent.ts create mode 100644 apps/docs/scripts/lib/generateContent.ts create mode 100644 apps/docs/scripts/lib/generateExamplesContent.ts create mode 100644 apps/docs/scripts/lib/generateLllmsTxt.ts create mode 100644 apps/docs/scripts/lib/generateSection.ts create mode 100644 apps/docs/scripts/lib/getApiMarkdown.ts create mode 100644 apps/docs/scripts/lib/getArticleKey.ts create mode 100644 apps/docs/scripts/lib/package-list.ts create mode 100644 apps/docs/scripts/lib/refreshContent.ts create mode 100644 apps/docs/scripts/lib/utils.ts create mode 100644 apps/docs/scripts/refresh-content.ts create mode 100644 apps/docs/scripts/update-algolia-index.ts create mode 100644 apps/docs/tailwind.config.js create mode 100644 apps/docs/tsconfig.content.json create mode 100644 apps/docs/tsconfig.json create mode 100644 apps/docs/types/content-types.ts create mode 100644 apps/docs/utils/ContentDatabase.ts create mode 100644 apps/docs/utils/TldrawApiModel.ts create mode 100644 apps/docs/utils/addContent.ts create mode 100644 apps/docs/utils/agent-skills.test.ts create mode 100644 apps/docs/utils/agent-skills.ts create mode 100644 apps/docs/utils/algolia.ts create mode 100644 apps/docs/utils/asset-url.test.ts create mode 100644 apps/docs/utils/asset-url.ts create mode 100644 apps/docs/utils/autoLinkDocs.ts create mode 100644 apps/docs/utils/cn.ts create mode 100644 apps/docs/utils/config.ts create mode 100644 apps/docs/utils/nicelog.ts create mode 100644 apps/docs/utils/parse-markdown.test.tsx create mode 100644 apps/docs/utils/parse-markdown.tsx create mode 100644 apps/docs/utils/search-api.ts create mode 100644 apps/docs/utils/sitemap-canonical-paths.test.ts create mode 100644 apps/docs/utils/sitemap-canonical-paths.ts create mode 100644 apps/docs/utils/storage.ts create mode 100644 apps/docs/version.ts create mode 100644 apps/docs/vitest.config.ts create mode 100644 apps/docs/watcher.ts create mode 100644 apps/dotcom/.gitignore create mode 100644 apps/dotcom/README.md create mode 100644 apps/dotcom/asset-upload-worker/.gitignore create mode 100644 apps/dotcom/asset-upload-worker/README.md create mode 100644 apps/dotcom/asset-upload-worker/package.json create mode 100644 apps/dotcom/asset-upload-worker/src/types.ts create mode 100644 apps/dotcom/asset-upload-worker/src/worker.ts create mode 100644 apps/dotcom/asset-upload-worker/tsconfig.json create mode 100644 apps/dotcom/asset-upload-worker/vitest.config.ts create mode 100644 apps/dotcom/asset-upload-worker/wrangler.toml create mode 100644 apps/dotcom/client/.gitignore create mode 100644 apps/dotcom/client/PRIVACY_POLICY.md create mode 100644 apps/dotcom/client/README.md create mode 100644 apps/dotcom/client/TERMS_OF_SERVICE.md create mode 100644 apps/dotcom/client/assets/icons/icon/icon-avatar.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-bookmark.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-check.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-down-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-down.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-right-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-right.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-up-down.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-up-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-chevron-up.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-close-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-close.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-comment.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-copy-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-copy.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-doc-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-doc.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-dots-horizontal-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-dots-horizontal.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-dots-vertical-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-dots-vertical.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-draw.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-edit-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-edit.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-export.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-external.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-feedback.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-folder-new.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-folder-open.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-folder.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-group-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-group.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-help-circle.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-home-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-home.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-import.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-info.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-invite.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-link-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-link.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-manual.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-more.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-notification.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-pin-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-pin.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-plus-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-plus.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-qr.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-question-circle.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-question.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-refresh.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-search.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-settings.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-share.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-shared.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-sidebar-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-sidebar.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-sign-in.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-spinner.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-star-fill.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-star-strong-fill.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-star-strong.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-star.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-tick.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-tldraw.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-untick.svg create mode 100644 apps/dotcom/client/assets/icons/icon/icon-update.svg create mode 100644 apps/dotcom/client/decs.d.ts create mode 100644 apps/dotcom/client/e2e/README.md create mode 100644 apps/dotcom/client/e2e/consts.ts create mode 100644 apps/dotcom/client/e2e/fixtures/Database.ts create mode 100644 apps/dotcom/client/e2e/fixtures/DeleteFileDialog.ts create mode 100644 apps/dotcom/client/e2e/fixtures/Editor.ts create mode 100644 apps/dotcom/client/e2e/fixtures/ErrorPages.ts create mode 100644 apps/dotcom/client/e2e/fixtures/HomePage.ts create mode 100644 apps/dotcom/client/e2e/fixtures/ImportHelper.ts create mode 100644 apps/dotcom/client/e2e/fixtures/ShareMenu.ts create mode 100644 apps/dotcom/client/e2e/fixtures/Sidebar.ts create mode 100644 apps/dotcom/client/e2e/fixtures/SignInDialog.ts create mode 100644 apps/dotcom/client/e2e/fixtures/WorkspaceInviteDialog.ts create mode 100644 apps/dotcom/client/e2e/fixtures/helpers.ts create mode 100644 apps/dotcom/client/e2e/fixtures/scenario-test.ts create mode 100644 apps/dotcom/client/e2e/fixtures/staging-test.ts create mode 100644 apps/dotcom/client/e2e/fixtures/tla-test.ts create mode 100644 apps/dotcom/client/e2e/global-staging.setup.ts create mode 100644 apps/dotcom/client/e2e/global.setup.ts create mode 100644 apps/dotcom/client/e2e/global.teardown.ts create mode 100644 apps/dotcom/client/e2e/tests/auth.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/client-too-old.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/import-download.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/invite-signin.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/legacy-routes.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/sharing-live.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/cookie-consent.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/database.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/homepage.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/not-logged-in.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/sharing.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/sidebar-dotdev-link.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/signin-dialog.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/test-import-download.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/smoke/workspaces.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/staging.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/ui.scenario.spec.ts create mode 100644 apps/dotcom/client/e2e/tests/workspaces-feature-coverage.scenario.spec.ts create mode 100644 apps/dotcom/client/index.html create mode 100644 apps/dotcom/client/package.json create mode 100644 apps/dotcom/client/playwright.config.ts create mode 100644 apps/dotcom/client/public/.well-known/ai-catalog.json create mode 100644 apps/dotcom/client/public/.well-known/api-catalog create mode 100644 apps/dotcom/client/public/.well-known/apple-developer-merchantid-domain-association create mode 100644 apps/dotcom/client/public/404-Sad-tldraw.svg create mode 100644 apps/dotcom/client/public/android-chrome-192x192.png create mode 100644 apps/dotcom/client/public/android-chrome-512x512.png create mode 100644 apps/dotcom/client/public/android-chrome-maskable-192x192.png create mode 100644 apps/dotcom/client/public/android-chrome-maskable-512x512.png create mode 100644 apps/dotcom/client/public/android-chrome-maskable-beta-512x512.png create mode 100644 apps/dotcom/client/public/apple-touch-icon-152x152.svg create mode 100644 apps/dotcom/client/public/apple-touch-icon-167x167.svg create mode 100644 apps/dotcom/client/public/apple-touch-icon-180x180.svg create mode 100644 apps/dotcom/client/public/apple-touch-icon.png create mode 100644 apps/dotcom/client/public/auth.md create mode 100644 apps/dotcom/client/public/cookies.html create mode 100644 apps/dotcom/client/public/favicon-16x16.png create mode 100644 apps/dotcom/client/public/favicon-32x32.png create mode 100644 apps/dotcom/client/public/favicon.ico create mode 100644 apps/dotcom/client/public/favicon.svg create mode 100644 apps/dotcom/client/public/flat.png create mode 100644 apps/dotcom/client/public/legal.html create mode 100644 apps/dotcom/client/public/manifest.webmanifest create mode 100644 apps/dotcom/client/public/privacy.html create mode 100644 apps/dotcom/client/public/reo.html create mode 100644 apps/dotcom/client/public/robots.txt create mode 100644 apps/dotcom/client/public/site.webmanifest create mode 100644 apps/dotcom/client/public/sitemap.txt create mode 100644 apps/dotcom/client/public/sitemap.xml create mode 100644 apps/dotcom/client/public/social-og.png create mode 100644 apps/dotcom/client/public/social-twitter.png create mode 100644 apps/dotcom/client/public/staging-favicon-16.png create mode 100644 apps/dotcom/client/public/staging-favicon-32.png create mode 100644 apps/dotcom/client/public/staging-favicon.svg create mode 100644 apps/dotcom/client/public/sw.js create mode 100644 apps/dotcom/client/public/theme-init.js create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ar.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/bn.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ca.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/cs.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/da.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/de.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/el.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/en.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/es.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/fa.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/fi.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/fr.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/gl.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/gu-in.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/he.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/hi-in.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/hr.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/hu.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/id.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/it.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ja.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/km-kh.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/kn.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ko-kr.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ml.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/mr.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ms.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ne.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/nl.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/no.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/pa.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/pl.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/pt-br.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/pt-pt.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ro.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ru.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/sl.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/so.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/sv.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ta.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/te.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/th.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/tl.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/tr.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/uk.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/ur.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/vi.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/zh-cn.json create mode 100644 apps/dotcom/client/public/tla/locales-compiled/zh-tw.json create mode 100644 apps/dotcom/client/public/tla/locales/ar.json create mode 100644 apps/dotcom/client/public/tla/locales/bn.json create mode 100644 apps/dotcom/client/public/tla/locales/ca.json create mode 100644 apps/dotcom/client/public/tla/locales/cs.json create mode 100644 apps/dotcom/client/public/tla/locales/da.json create mode 100644 apps/dotcom/client/public/tla/locales/de.json create mode 100644 apps/dotcom/client/public/tla/locales/el.json create mode 100644 apps/dotcom/client/public/tla/locales/en.json create mode 100644 apps/dotcom/client/public/tla/locales/es.json create mode 100644 apps/dotcom/client/public/tla/locales/fa.json create mode 100644 apps/dotcom/client/public/tla/locales/fi.json create mode 100644 apps/dotcom/client/public/tla/locales/fr.json create mode 100644 apps/dotcom/client/public/tla/locales/gl.json create mode 100644 apps/dotcom/client/public/tla/locales/gu-in.json create mode 100644 apps/dotcom/client/public/tla/locales/he.json create mode 100644 apps/dotcom/client/public/tla/locales/hi-in.json create mode 100644 apps/dotcom/client/public/tla/locales/hr.json create mode 100644 apps/dotcom/client/public/tla/locales/hu.json create mode 100644 apps/dotcom/client/public/tla/locales/id.json create mode 100644 apps/dotcom/client/public/tla/locales/it.json create mode 100644 apps/dotcom/client/public/tla/locales/ja.json create mode 100644 apps/dotcom/client/public/tla/locales/km-kh.json create mode 100644 apps/dotcom/client/public/tla/locales/kn.json create mode 100644 apps/dotcom/client/public/tla/locales/ko-kr.json create mode 100644 apps/dotcom/client/public/tla/locales/ml.json create mode 100644 apps/dotcom/client/public/tla/locales/mr.json create mode 100644 apps/dotcom/client/public/tla/locales/ms.json create mode 100644 apps/dotcom/client/public/tla/locales/ne.json create mode 100644 apps/dotcom/client/public/tla/locales/nl.json create mode 100644 apps/dotcom/client/public/tla/locales/no.json create mode 100644 apps/dotcom/client/public/tla/locales/pa.json create mode 100644 apps/dotcom/client/public/tla/locales/pl.json create mode 100644 apps/dotcom/client/public/tla/locales/pt-br.json create mode 100644 apps/dotcom/client/public/tla/locales/pt-pt.json create mode 100644 apps/dotcom/client/public/tla/locales/ro.json create mode 100644 apps/dotcom/client/public/tla/locales/ru.json create mode 100644 apps/dotcom/client/public/tla/locales/sl.json create mode 100644 apps/dotcom/client/public/tla/locales/so.json create mode 100644 apps/dotcom/client/public/tla/locales/sv.json create mode 100644 apps/dotcom/client/public/tla/locales/ta.json create mode 100644 apps/dotcom/client/public/tla/locales/te.json create mode 100644 apps/dotcom/client/public/tla/locales/th.json create mode 100644 apps/dotcom/client/public/tla/locales/tl.json create mode 100644 apps/dotcom/client/public/tla/locales/tr.json create mode 100644 apps/dotcom/client/public/tla/locales/uk.json create mode 100644 apps/dotcom/client/public/tla/locales/ur.json create mode 100644 apps/dotcom/client/public/tla/locales/vi.json create mode 100644 apps/dotcom/client/public/tla/locales/zh-cn.json create mode 100644 apps/dotcom/client/public/tla/locales/zh-tw.json create mode 100644 apps/dotcom/client/public/tla/spinner.svg create mode 100644 apps/dotcom/client/public/tla/thumbnail-1.png create mode 100644 apps/dotcom/client/public/tla/thumbnail.png create mode 100644 apps/dotcom/client/public/tla/tldraw-logo-2.svg create mode 100644 apps/dotcom/client/public/tldraw-white-on-black.svg create mode 100644 apps/dotcom/client/public/tldraw.svg create mode 100644 apps/dotcom/client/public/tldraw_sidebar_logo.svg create mode 100644 apps/dotcom/client/public/tos.html create mode 100644 apps/dotcom/client/scripts/browser-run-thumbnail.ts create mode 100644 apps/dotcom/client/scripts/build.ts create mode 100644 apps/dotcom/client/scripts/dev-app.test.ts create mode 100644 apps/dotcom/client/scripts/dev-app.ts create mode 100644 apps/dotcom/client/scripts/kill-tree.test.ts create mode 100644 apps/dotcom/client/scripts/measure-bundle-size.test.ts create mode 100644 apps/dotcom/client/scripts/measure-bundle-size.ts create mode 100644 apps/dotcom/client/scripts/multiplayer-server-url.ts create mode 100644 apps/dotcom/client/scripts/vercel-output-config.d.ts create mode 100644 apps/dotcom/client/scripts/vite-thumbnail-screenshot-plugin.ts create mode 100644 apps/dotcom/client/scripts/vite-zod-locale-plugin.d.ts create mode 100644 apps/dotcom/client/scripts/vite-zod-locale-plugin.js create mode 100644 apps/dotcom/client/scripts/zod-locales-shim.js create mode 100644 apps/dotcom/client/sentry-release-name.ts create mode 100644 apps/dotcom/client/sentry.client.config.ts create mode 100644 apps/dotcom/client/sentry.properties create mode 100644 apps/dotcom/client/setupTests.js create mode 100644 apps/dotcom/client/src/__snapshots__/routes.test.tsx.snap create mode 100644 apps/dotcom/client/src/app.d.ts create mode 100644 apps/dotcom/client/src/assets/0_merged_tla.svg create mode 100644 apps/dotcom/client/src/components/BoardHistoryLog/BoardHistoryLog.tsx create mode 100644 apps/dotcom/client/src/components/ErrorPage/ErrorPage.tsx create mode 100644 apps/dotcom/client/src/components/Head/Head.tsx create mode 100644 apps/dotcom/client/src/components/IFrameProtector.tsx create mode 100644 apps/dotcom/client/src/components/LocalEditor.tsx create mode 100644 apps/dotcom/client/src/components/LoginRedirectPage/LoginRedirectPage.tsx create mode 100644 apps/dotcom/client/src/components/SneakyMermaidHandler/SneakyMermaidHandler.tsx create mode 100644 apps/dotcom/client/src/components/SneakyMermaidHandler/simpleMermaidStringTest.test.ts create mode 100644 apps/dotcom/client/src/components/SneakyMermaidHandler/simpleMermaidStringTest.ts create mode 100644 apps/dotcom/client/src/components/SneakyOnDropOverride.ts create mode 100644 apps/dotcom/client/src/components/StoreErrorScreen.tsx create mode 100644 apps/dotcom/client/src/components/ThemeUpdater/ThemeUpdater.tsx create mode 100644 apps/dotcom/client/src/css.d.ts create mode 100644 apps/dotcom/client/src/hooks/useLegacyUrlParams.ts create mode 100644 apps/dotcom/client/src/hooks/useOpenUrlAndTrack.ts create mode 100644 apps/dotcom/client/src/hooks/usePerformanceTracking.ts create mode 100644 apps/dotcom/client/src/hooks/useRoomLoadTracking.ts create mode 100644 apps/dotcom/client/src/hooks/useUrl.ts create mode 100644 apps/dotcom/client/src/main.tsx create mode 100644 apps/dotcom/client/src/pages/admin/AdminButton.tsx create mode 100644 apps/dotcom/client/src/pages/admin/EffectsSection.tsx create mode 100644 apps/dotcom/client/src/pages/admin/FileStats.tsx create mode 100644 apps/dotcom/client/src/pages/admin/FilesSection.tsx create mode 100644 apps/dotcom/client/src/pages/admin/FlagsSection.tsx create mode 100644 apps/dotcom/client/src/pages/admin/SystemSection.tsx create mode 100644 apps/dotcom/client/src/pages/admin/UsersSection.tsx create mode 100644 apps/dotcom/client/src/pages/admin/admin.module.css create mode 100644 apps/dotcom/client/src/pages/admin/index.tsx create mode 100644 apps/dotcom/client/src/pages/admin/shared.tsx create mode 100644 apps/dotcom/client/src/pages/dev-browser-run-thumbnail.tsx create mode 100644 apps/dotcom/client/src/pages/dev-reset-local-state.tsx create mode 100644 apps/dotcom/client/src/pages/not-found.tsx create mode 100644 apps/dotcom/client/src/pages/thumbnail-render.test.ts create mode 100644 apps/dotcom/client/src/pages/thumbnail-render.tsx create mode 100644 apps/dotcom/client/src/pages/tla-new.tsx create mode 100644 apps/dotcom/client/src/routeDefs.ts create mode 100644 apps/dotcom/client/src/routes.test.tsx create mode 100644 apps/dotcom/client/src/routes.tsx create mode 100644 apps/dotcom/client/src/thumbnail-render-main.tsx create mode 100644 apps/dotcom/client/src/tla/app/TldrawApp.test.ts create mode 100644 apps/dotcom/client/src/tla/app/TldrawApp.ts create mode 100644 apps/dotcom/client/src/tla/app/ZeroLogBuffer.ts create mode 100644 apps/dotcom/client/src/tla/app/getMostRecentFileId.test.ts create mode 100644 apps/dotcom/client/src/tla/app/getWorkspaceFilesSorted.test.ts create mode 100644 apps/dotcom/client/src/tla/app/msUntilTokenRefresh.test.ts create mode 100644 apps/dotcom/client/src/tla/app/shouldEnableCommenting.test.ts create mode 100644 apps/dotcom/client/src/tla/app/uploadTldrFiles.test.ts create mode 100644 apps/dotcom/client/src/tla/components/ExternalLink/ExternalLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/MaybeForceUserRefresh/MaybeForceUserRefresh.module.css create mode 100644 apps/dotcom/client/src/tla/components/MaybeForceUserRefresh/MaybeForceUserRefresh.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaAnonDotDevLink/TlaAnonDotDevLink.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaAnonDotDevLink/TlaAnonDotDevLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaButton/TlaButton.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaButton/button.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaCtaButton/TlaCtaButton.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaCtaButton/cta-button.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/CommentsOnCanvas.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/SlurpFailure.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaDebug.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaEditor.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaEditorTopLeftPanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaEditorTopRightPanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaEditorWrapper.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaHistorySnapshotEditor.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaLegacyFileEditor.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaLegacySnapshotEditor.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/TlaPublishEditor.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorErrorFallback.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorLegacySharePanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorMenuPanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorPublishedSharePanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorSharePanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-components/TlaEditorTopPanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor-messages.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/editor.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyCommentDeepLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyDarkModeSync.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyDebugModeToast.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyFileDropHandler.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyLargeFileHandler.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyLegacyModal.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyLegacytSetDocumentTitle.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakySetDocumentTitle.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/SneakyToolSwitcher.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/sneaky/sneaky-legacy-modal.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/top.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/useExtraToolDragIcons.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaEditor/useFileEditorOverrides.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaFileError/TlaFileError.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaFileError/TlaFileError.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileMenu/TlaFileMenu.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/QrCode.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/Tabs/TlaAnonCopyLinkTab.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/Tabs/TlaExportTab.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/Tabs/TlaInviteTab.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/Tabs/TlaPublishTab.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/TlaFileShareMenu.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/file-share-menu-primitives.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaFileShareMenu/file-share-menu.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaIcon/TlaIcon.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaIcon/icon.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaLogo/TlaLogo.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaLogo/logo.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/TlaSidebar.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarCreateFileButton.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarDotDevLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarFeedbackButton.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarFileLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarFileLinkMenu.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarFileSection.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarInlineInput.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarNotificationsButton.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarNotificationsPanel.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarRecentFiles.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarRenameInline.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarSearch.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarToggle.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarToggleMobile.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarUserSettingsMenu.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarWorkspaceActions.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarWorkspaceLink.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/TlaSidebarWorkspaceSwitcher.tsx create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/commentNotifications.test.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/commentNotifications.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/notifications.module.css create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/components/sidebar-shared.ts create mode 100644 apps/dotcom/client/src/tla/components/TlaSidebar/sidebar.module.css create mode 100644 apps/dotcom/client/src/tla/components/WorkspaceInviteHandler.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/ConfirmDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/CreateWorkspaceDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/SubmitFeedbackDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaCookieConsent.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaDeleteFileDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaInviteDialog.module.css create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaInviteDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaInviteExpiredDialog.module.css create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaInviteExpiredDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaLegalAcceptance.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaManageCookiesDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaSignInDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/TlaTldrawOfflineFileDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/WorkspaceSettingsDialog.tsx create mode 100644 apps/dotcom/client/src/tla/components/dialogs/auth.module.css create mode 100644 apps/dotcom/client/src/tla/components/dialogs/dialogs.module.css create mode 100644 apps/dotcom/client/src/tla/components/menu-items/menu-items.tsx create mode 100644 apps/dotcom/client/src/tla/components/tla-menu/menu.module.css create mode 100644 apps/dotcom/client/src/tla/components/tla-menu/tla-menu.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/getIsTldrawStaff.test.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useActiveWorkspaceId.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useAnalyticsConsent.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useAppState.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useCommentTracking.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useCurrentFileId.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useDeepLink.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useIsCommentingEnabled.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useIsFileOwner.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useIsFilePinned.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useIsReady.module.css create mode 100644 apps/dotcom/client/src/tla/hooks/useIsReady.tsx create mode 100644 apps/dotcom/client/src/tla/hooks/useNewRoomCreationTracking.ts create mode 100644 apps/dotcom/client/src/tla/hooks/usePreventAccidentalDrops.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useShareLinkOpenTracking.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useSignUpTracking.test.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useSignUpTracking.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useTldrFileDrop.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useUITheme.ts create mode 100644 apps/dotcom/client/src/tla/hooks/useUser.tsx create mode 100644 apps/dotcom/client/src/tla/layouts/TlaAnonLayout/TlaAnonLayout.tsx create mode 100644 apps/dotcom/client/src/tla/layouts/TlaAnonLayout/anon.module.css create mode 100644 apps/dotcom/client/src/tla/layouts/TlaSidebarLayout/TlaSidebarLayout.tsx create mode 100644 apps/dotcom/client/src/tla/layouts/TlaSidebarLayout/sidebar-layout.module.css create mode 100644 apps/dotcom/client/src/tla/pages/file-history-snapshot.tsx create mode 100644 apps/dotcom/client/src/tla/pages/file-history.tsx create mode 100644 apps/dotcom/client/src/tla/pages/file.tsx create mode 100644 apps/dotcom/client/src/tla/pages/import.tsx create mode 100644 apps/dotcom/client/src/tla/pages/invite.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-history-snapshot.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-history.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-readonly-old.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-readonly.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-room.tsx create mode 100644 apps/dotcom/client/src/tla/pages/legacy-snapshot.tsx create mode 100644 apps/dotcom/client/src/tla/pages/local-file-index.tsx create mode 100644 apps/dotcom/client/src/tla/pages/local-file.tsx create mode 100644 apps/dotcom/client/src/tla/pages/local.tsx create mode 100644 apps/dotcom/client/src/tla/pages/publish.tsx create mode 100644 apps/dotcom/client/src/tla/pages/worker-debug-tail.tsx create mode 100644 apps/dotcom/client/src/tla/providers/RequireSignedInUser.tsx create mode 100644 apps/dotcom/client/src/tla/providers/RequireTldrawStaff.tsx create mode 100644 apps/dotcom/client/src/tla/providers/TlaRootProviders.tsx create mode 100644 apps/dotcom/client/src/tla/styles/tla.css create mode 100644 apps/dotcom/client/src/tla/themes/ui-themes.ts create mode 100644 apps/dotcom/client/src/tla/utils/FeatureFlagPoller.test.ts create mode 100644 apps/dotcom/client/src/tla/utils/FeatureFlagPoller.tsx create mode 100644 apps/dotcom/client/src/tla/utils/app-ui-events.tsx create mode 100644 apps/dotcom/client/src/tla/utils/auth.ts create mode 100644 apps/dotcom/client/src/tla/utils/copy.ts create mode 100644 apps/dotcom/client/src/tla/utils/dates.ts create mode 100644 apps/dotcom/client/src/tla/utils/getCurrentEditor.ts create mode 100644 apps/dotcom/client/src/tla/utils/getIsCoarsePointer.tsx create mode 100644 apps/dotcom/client/src/tla/utils/i18n.tsx create mode 100644 apps/dotcom/client/src/tla/utils/importFromUrl.ts create mode 100644 apps/dotcom/client/src/tla/utils/local-session-state.ts create mode 100644 apps/dotcom/client/src/tla/utils/notFoundError.ts create mode 100644 apps/dotcom/client/src/tla/utils/qrcode.ts create mode 100644 apps/dotcom/client/src/tla/utils/redirect.ts create mode 100644 apps/dotcom/client/src/tla/utils/session-storage.ts create mode 100644 apps/dotcom/client/src/tla/utils/slurping.test.ts create mode 100644 apps/dotcom/client/src/tla/utils/slurping.tsx create mode 100644 apps/dotcom/client/src/tla/utils/tldrawOfflineFiles.ts create mode 100644 apps/dotcom/client/src/utils/analytics.tsx create mode 100644 apps/dotcom/client/src/utils/assetUrls.ts create mode 100644 apps/dotcom/client/src/utils/config.ts create mode 100644 apps/dotcom/client/src/utils/consoleBranding.ts create mode 100644 apps/dotcom/client/src/utils/createAssetFromUrl.ts create mode 100644 apps/dotcom/client/src/utils/csp.ts create mode 100644 apps/dotcom/client/src/utils/defineLoader.test.tsx create mode 100644 apps/dotcom/client/src/utils/defineLoader.tsx create mode 100644 apps/dotcom/client/src/utils/embedShapeUtil.ts create mode 100644 apps/dotcom/client/src/utils/env.ts create mode 100644 apps/dotcom/client/src/utils/errorReporting.ts create mode 100644 apps/dotcom/client/src/utils/fetchHistory.ts create mode 100644 apps/dotcom/client/src/utils/firstLoad.test.ts create mode 100644 apps/dotcom/client/src/utils/firstLoad.ts create mode 100644 apps/dotcom/client/src/utils/globalEditor.ts create mode 100644 apps/dotcom/client/src/utils/iFrame.ts create mode 100644 apps/dotcom/client/src/utils/multiplayerAssetStore.test.ts create mode 100644 apps/dotcom/client/src/utils/multiplayerAssetStore.ts create mode 100644 apps/dotcom/client/src/utils/scratch-persistence-key.ts create mode 100644 apps/dotcom/client/src/utils/shouldOverrideDocument.tsx create mode 100644 apps/dotcom/client/src/utils/url.ts create mode 100644 apps/dotcom/client/styles/globals.css create mode 100644 apps/dotcom/client/thumbnail-render.html create mode 100644 apps/dotcom/client/tsconfig.json create mode 100644 apps/dotcom/client/version.ts create mode 100644 apps/dotcom/client/vite.config.ts create mode 100644 apps/dotcom/client/vitest.config.ts create mode 100644 apps/dotcom/image-resize-worker/README.md create mode 100644 apps/dotcom/image-resize-worker/package.json create mode 100644 apps/dotcom/image-resize-worker/src/worker.ts create mode 100644 apps/dotcom/image-resize-worker/tsconfig.json create mode 100644 apps/dotcom/image-resize-worker/vitest.config.ts create mode 100644 apps/dotcom/image-resize-worker/wrangler.toml create mode 100644 apps/dotcom/mcp-server-auth.md create mode 100644 apps/dotcom/process-compose.yaml create mode 100755 apps/dotcom/restore-state.sh create mode 100755 apps/dotcom/snapshot-state.sh create mode 100644 apps/dotcom/sync-worker/.gitignore create mode 100644 apps/dotcom/sync-worker/README.md create mode 100755 apps/dotcom/sync-worker/dev.sh create mode 100644 apps/dotcom/sync-worker/package.json create mode 100644 apps/dotcom/sync-worker/src/Logger.ts create mode 100644 apps/dotcom/sync-worker/src/TLFileEffectProcessor.ts create mode 100644 apps/dotcom/sync-worker/src/TLLoggerDurableObject.ts create mode 100644 apps/dotcom/sync-worker/src/adminFeatureFlagRoutes.test.ts create mode 100644 apps/dotcom/sync-worker/src/adminRoutes.ts create mode 100644 apps/dotcom/sync-worker/src/assetAssociation.test.ts create mode 100644 apps/dotcom/sync-worker/src/assetAssociation.ts create mode 100644 apps/dotcom/sync-worker/src/authorizeFileRecord.test.ts create mode 100644 apps/dotcom/sync-worker/src/authorizeFileRecord.ts create mode 100644 apps/dotcom/sync-worker/src/commentRows.test.ts create mode 100644 apps/dotcom/sync-worker/src/commentRows.ts create mode 100644 apps/dotcom/sync-worker/src/config.ts create mode 100644 apps/dotcom/sync-worker/src/fileEffects.test.ts create mode 100644 apps/dotcom/sync-worker/src/fileEffects.ts create mode 100644 apps/dotcom/sync-worker/src/fileStats.test.ts create mode 100644 apps/dotcom/sync-worker/src/fileStats.ts create mode 100644 apps/dotcom/sync-worker/src/healthCheckRoutes.ts create mode 100644 apps/dotcom/sync-worker/src/mcpClusterIndexStorage.test.ts create mode 100644 apps/dotcom/sync-worker/src/mcpClusterIndexStorage.ts create mode 100644 apps/dotcom/sync-worker/src/outboxDrain.test.ts create mode 100644 apps/dotcom/sync-worker/src/outboxDrain.ts create mode 100644 apps/dotcom/sync-worker/src/postgres.ts create mode 100644 apps/dotcom/sync-worker/src/r2.ts create mode 100644 apps/dotcom/sync-worker/src/roomEffectHelpers.test.ts create mode 100644 apps/dotcom/sync-worker/src/roomEffectHelpers.ts create mode 100644 apps/dotcom/sync-worker/src/routes/extractBookmarkMetadata.tsx create mode 100644 apps/dotcom/sync-worker/src/routes/getDocumentNameFromSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getReadonlySlug.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getRoomHistory.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getRoomHistory.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getRoomHistorySnapshot.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getRoomHistorySnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getRoomSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getSocialPreview.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/getSocialPreview.ts create mode 100644 apps/dotcom/sync-worker/src/routes/joinExistingRoom.ts create mode 100644 apps/dotcom/sync-worker/src/routes/submitFeedback.ts create mode 100644 apps/dotcom/sync-worker/src/routes/sweepVersionChains.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/sweepVersionChains.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/acceptInvite.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/boardTools.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/boardTools.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/createFiles.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/evalsLocalMcp.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/evalsLocalMcp.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/forwardRoomRequest.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getFileSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getInviteInfo.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getOgImage.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getOgImage.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getPublishedFile.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getSharedFile.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getSharedFile.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getThumbnailSnapshot.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/getThumbnailSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/initUser.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpAuth.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpAuth.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpClusterIndex.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpClusterIndex.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpServer.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpServer.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpServerCard.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/mcpServerCard.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/ogImageQueue.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/ogImageQueue.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/putThumbnailRenderResult.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/putThumbnailRenderResult.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/screenshotTestHelpers.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/searchBoards.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/searchBoards.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/thumbnailRender.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/thumbnailRender.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/thumbnailShared.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/thumbnailShared.ts create mode 100644 apps/dotcom/sync-worker/src/routes/tla/uploads.ts create mode 100644 apps/dotcom/sync-worker/src/routes/verifyVersionChain.test.ts create mode 100644 apps/dotcom/sync-worker/src/routes/verifyVersionChain.ts create mode 100644 apps/dotcom/sync-worker/src/snapshotUtils.test.ts create mode 100644 apps/dotcom/sync-worker/src/snapshotUtils.ts create mode 100644 apps/dotcom/sync-worker/src/test/fakeR2.ts create mode 100644 apps/dotcom/sync-worker/src/testRoutes.ts create mode 100644 apps/dotcom/sync-worker/src/types.ts create mode 100644 apps/dotcom/sync-worker/src/undeleteFile.test.ts create mode 100644 apps/dotcom/sync-worker/src/undeleteFile.ts create mode 100644 apps/dotcom/sync-worker/src/utils/analytics.ts create mode 100644 apps/dotcom/sync-worker/src/utils/base64.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/base64.ts create mode 100644 apps/dotcom/sync-worker/src/utils/createSupabaseClient.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/createSupabaseClient.ts create mode 100644 apps/dotcom/sync-worker/src/utils/durableObjects.ts create mode 100644 apps/dotcom/sync-worker/src/utils/featureFlags.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/featureFlags.ts create mode 100644 apps/dotcom/sync-worker/src/utils/getPublicOrigin.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/getPublicOrigin.ts create mode 100644 apps/dotcom/sync-worker/src/utils/getSnapshotsTable.ts create mode 100644 apps/dotcom/sync-worker/src/utils/hash.ts create mode 100644 apps/dotcom/sync-worker/src/utils/loadId.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/loadId.ts create mode 100644 apps/dotcom/sync-worker/src/utils/ogRenderDebounce.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/ogRenderDebounce.ts create mode 100644 apps/dotcom/sync-worker/src/utils/publishSnapshots.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/publishSnapshots.ts create mode 100644 apps/dotcom/sync-worker/src/utils/rateLimit.ts create mode 100644 apps/dotcom/sync-worker/src/utils/renderTokens.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/renderTokens.ts create mode 100644 apps/dotcom/sync-worker/src/utils/roomIdIsTooLong.ts create mode 100644 apps/dotcom/sync-worker/src/utils/roomOpenMode.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/README.md create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/directory-only.tar create mode 100755 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/generate-fixtures.sh create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/large-body.tar create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/multi-file.tar create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/single-file.tar create mode 100644 apps/dotcom/sync-worker/src/utils/tarStreamReader-fixtures/with-prefix.tar create mode 100644 apps/dotcom/sync-worker/src/utils/throttle.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/getAuth.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/getAuth.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/getJoinableWorkspaceFromInvite.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/getLegacyRoomData.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/getRole.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/hasReadAccessToFile.test.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/hasWriteAccessToFile.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/isTestFile.ts create mode 100644 apps/dotcom/sync-worker/src/utils/tla/permissions.ts create mode 100644 apps/dotcom/sync-worker/src/utils/validateSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/versionChain.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionChain.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainCodec.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainConfig.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainConfig.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainDelete.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainRead.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainRead.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainWrite.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionChainWrite.ts create mode 100644 apps/dotcom/sync-worker/src/versionDelta.test.ts create mode 100644 apps/dotcom/sync-worker/src/versionDelta.ts create mode 100644 apps/dotcom/sync-worker/src/welcome/defaultWelcomeSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/welcome/resolveWelcomeSnapshot.test.ts create mode 100644 apps/dotcom/sync-worker/src/welcome/resolveWelcomeSnapshot.ts create mode 100644 apps/dotcom/sync-worker/src/welcome/welcome.test.ts create mode 100644 apps/dotcom/sync-worker/src/worker.exports.test.ts create mode 100644 apps/dotcom/sync-worker/src/worker.ts create mode 100644 apps/dotcom/sync-worker/src/zero/ZMutationError.ts create mode 100644 apps/dotcom/sync-worker/tsconfig.json create mode 100644 apps/dotcom/sync-worker/vitest.config.ts create mode 100644 apps/dotcom/sync-worker/wrangler.toml create mode 100644 apps/dotcom/tldrawusercontent-worker/.gitignore create mode 100644 apps/dotcom/tldrawusercontent-worker/package.json create mode 100644 apps/dotcom/tldrawusercontent-worker/src/types.ts create mode 100644 apps/dotcom/tldrawusercontent-worker/src/worker.ts create mode 100644 apps/dotcom/tldrawusercontent-worker/tsconfig.json create mode 100644 apps/dotcom/tldrawusercontent-worker/wrangler.toml create mode 100644 apps/dotcom/user-manual.md create mode 100644 apps/dotcom/workspaces-feature.md create mode 100644 apps/dotcom/zero-cache/.env create mode 100644 apps/dotcom/zero-cache/.gitignore create mode 100644 apps/dotcom/zero-cache/Dockerfile.template create mode 100644 apps/dotcom/zero-cache/delete_file_states.test.ts create mode 100644 apps/dotcom/zero-cache/docker/docker-compose.yml create mode 100644 apps/dotcom/zero-cache/docker/pgbouncer.ini create mode 100644 apps/dotcom/zero-cache/docker/postgres-logging.conf create mode 100644 apps/dotcom/zero-cache/docker/userlist.txt create mode 100644 apps/dotcom/zero-cache/effect_outbox.test.ts create mode 100644 apps/dotcom/zero-cache/flyio-replication-manager.template.toml create mode 100644 apps/dotcom/zero-cache/flyio-view-syncer.template.toml create mode 100644 apps/dotcom/zero-cache/flyio.template.toml create mode 100644 apps/dotcom/zero-cache/migrate.ts create mode 100644 apps/dotcom/zero-cache/migrationSql.test.ts create mode 100644 apps/dotcom/zero-cache/migrationSql.ts create mode 100644 apps/dotcom/zero-cache/migrations/000_seed.sql create mode 100644 apps/dotcom/zero-cache/migrations/001_replicator_boot.sql create mode 100644 apps/dotcom/zero-cache/migrations/002_add_user_id.sql create mode 100644 apps/dotcom/zero-cache/migrations/003_make_published_slug_unique.sql create mode 100644 apps/dotcom/zero-cache/migrations/004_guest_column_on_file_state.sql create mode 100644 apps/dotcom/zero-cache/migrations/005_update_file_trigger.sql create mode 100644 apps/dotcom/zero-cache/migrations/006_add_file_soft_delete.sql create mode 100644 apps/dotcom/zero-cache/migrations/007_update_file_owner_details.sql create mode 100644 apps/dotcom/zero-cache/migrations/008_add_pinned.sql create mode 100644 apps/dotcom/zero-cache/migrations/009_add_allow_analytics_cookie.sql create mode 100644 apps/dotcom/zero-cache/migrations/010_add_asset_info.sql create mode 100644 apps/dotcom/zero-cache/migrations/011_file_creation_column.sql create mode 100644 apps/dotcom/zero-cache/migrations/012_prevent_deadlocks.sql create mode 100644 apps/dotcom/zero-cache/migrations/013_add_userid_to_file_key.sql create mode 100644 apps/dotcom/zero-cache/migrations/014_add_publishedSlug_to_file_key.sql create mode 100644 apps/dotcom/zero-cache/migrations/015_full_replicas.sql create mode 100644 apps/dotcom/zero-cache/migrations/016_zero_publication.sql create mode 100644 apps/dotcom/zero-cache/migrations/017_associated_users_with_assets.sql create mode 100644 apps/dotcom/zero-cache/migrations/018_file_state_replica_identity_all.sql create mode 100644 apps/dotcom/zero-cache/migrations/019_add_keyboard_shortcuts_pref.sql create mode 100644 apps/dotcom/zero-cache/migrations/020_add_show_ui_labels_pref.sql create mode 100644 apps/dotcom/zero-cache/migrations/021_rename_show_ui_labels_pref.sql create mode 100644 apps/dotcom/zero-cache/migrations/022_add_input_mode_preference.sql create mode 100644 apps/dotcom/zero-cache/migrations/023_groups.sql create mode 100644 apps/dotcom/zero-cache/migrations/024_add_fairies.sql create mode 100644 apps/dotcom/zero-cache/migrations/025_fairy_gating.sql create mode 100644 apps/dotcom/zero-cache/migrations/026_fairy_usage_tracking.sql create mode 100644 apps/dotcom/zero-cache/migrations/027_add_fairy_messages.sql create mode 100644 apps/dotcom/zero-cache/migrations/027_fairy_invite_description.sql create mode 100644 apps/dotcom/zero-cache/migrations/028_add_paddle_transactions.sql create mode 100644 apps/dotcom/zero-cache/migrations/029_fairy_weekly_limit.sql create mode 100644 apps/dotcom/zero-cache/migrations/030_add_zoom_direction_preference.sql create mode 100644 apps/dotcom/zero-cache/migrations/031_group_id_indexes.sql create mode 100644 apps/dotcom/zero-cache/migrations/032_enable_ddl_detection.sql create mode 100644 apps/dotcom/zero-cache/migrations/033_rename_group_admin_role_to_member.sql create mode 100644 apps/dotcom/zero-cache/migrations/034_fix_unshare_group_file_cleanup.sql create mode 100644 apps/dotcom/zero-cache/migrations/035_welcome_template.sql create mode 100644 apps/dotcom/zero-cache/migrations/036_home_group_renameable.sql create mode 100644 apps/dotcom/zero-cache/migrations/037_add_group_invite_link_enabled.sql create mode 100644 apps/dotcom/zero-cache/migrations/038_cleanup_orphan_group_file_links.sql create mode 100644 apps/dotcom/zero-cache/migrations/039_tighten_group_file_association.sql create mode 100644 apps/dotcom/zero-cache/migrations/040_add_comments.sql create mode 100644 apps/dotcom/zero-cache/migrations/041_add_comment_read.sql create mode 100644 apps/dotcom/zero-cache/migrations/042_add_comment_mention.sql create mode 100644 apps/dotcom/zero-cache/migrations/043_add_comment_reactions.sql create mode 100644 apps/dotcom/zero-cache/migrations/044_file_visitor.sql create mode 100644 apps/dotcom/zero-cache/migrations/045_add_comment_reaction_user_name.sql create mode 100644 apps/dotcom/zero-cache/migrations/046_stamp_comment_created_at.sql create mode 100644 apps/dotcom/zero-cache/migrations/047_effect_outbox.sql create mode 100644 apps/dotcom/zero-cache/migrations/048_effect_outbox_retry_at.sql create mode 100644 apps/dotcom/zero-cache/migrations/049_drop_legacy_sync_tables.sql create mode 100644 apps/dotcom/zero-cache/migrations/050_drop_legacy_owner_columns.sql create mode 100644 apps/dotcom/zero-cache/migrations/051_effect_outbox_last_error.sql create mode 100644 apps/dotcom/zero-cache/migrations/052_file_search_index.sql create mode 100644 apps/dotcom/zero-cache/nginx.conf.template create mode 100644 apps/dotcom/zero-cache/package.json create mode 100644 apps/dotcom/zero-cache/stamp_comment_created_at.test.ts create mode 100644 apps/dotcom/zero-cache/start.sh create mode 100644 apps/dotcom/zero-cache/supervisord.conf create mode 100644 apps/dotcom/zero-cache/tsconfig.json create mode 100644 apps/dotcom/zero-cache/validateMigrationFilenames.test.ts create mode 100644 apps/dotcom/zero-cache/validateMigrationFilenames.ts create mode 100644 apps/dotcom/zero-cache/vitest.config.ts create mode 100644 apps/examples/.gitignore create mode 100755 apps/examples/LICENSE.md create mode 100755 apps/examples/README.md create mode 100644 apps/examples/e2e-device/helpers/app.ts create mode 100644 apps/examples/e2e-device/helpers/pinch.ts create mode 100644 apps/examples/e2e-device/helpers/stroke.ts create mode 100644 apps/examples/e2e-device/tests/draw-pressure-encoding.e2e.ts create mode 100644 apps/examples/e2e-device/tests/pinch.e2e.ts create mode 100644 apps/examples/e2e-device/tsconfig.json create mode 100644 apps/examples/e2e-device/wdio.android.conf.ts create mode 100644 apps/examples/e2e-device/wdio.ios.conf.ts create mode 100644 apps/examples/e2e-device/wdio.shared.conf.ts create mode 100644 apps/examples/e2e/baselines/fps-baselines.json create mode 100644 apps/examples/e2e/fixtures/analytics-reporter.ts create mode 100644 apps/examples/e2e/fixtures/baseline-manager.ts create mode 100644 apps/examples/e2e/fixtures/fixtures.ts create mode 100644 apps/examples/e2e/fixtures/fps-tracker.ts create mode 100644 apps/examples/e2e/fixtures/heavy-board-generator.ts create mode 100644 apps/examples/e2e/fixtures/menus/ActionsMenu.ts create mode 100644 apps/examples/e2e/fixtures/menus/HelpMenu.ts create mode 100644 apps/examples/e2e/fixtures/menus/MainMenu.ts create mode 100644 apps/examples/e2e/fixtures/menus/MenuClickCapture.ts create mode 100644 apps/examples/e2e/fixtures/menus/NavigationPanel.ts create mode 100644 apps/examples/e2e/fixtures/menus/PageMenu.ts create mode 100644 apps/examples/e2e/fixtures/menus/RichTextToolbar.ts create mode 100644 apps/examples/e2e/fixtures/menus/StylePanel.ts create mode 100644 apps/examples/e2e/fixtures/menus/Toolbar.ts create mode 100644 apps/examples/e2e/fixtures/perf-utils.ts create mode 100644 apps/examples/e2e/global-setup.ts create mode 100644 apps/examples/e2e/global-teardown.ts create mode 100644 apps/examples/e2e/mermaid-readability/test-mermaid-readability.spec.ts create mode 100644 apps/examples/e2e/perf/test-perf.spec.ts create mode 100644 apps/examples/e2e/playwright.config.ts create mode 100644 apps/examples/e2e/shared-e2e.ts create mode 100644 apps/examples/e2e/tests/README-PERFORMANCE.md create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-decision-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-class-defs-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-custom-edge-styles-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-flowchart-with-subgraphs-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-basics-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-alt-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-sequence-diagram-with-parallel-lanes-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-basic-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-fork-join-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-mermaid-snapshots.spec.ts-snapshots/Mermaid-export-snapshots-state-diagram-with-nested-state-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots-data.tsx create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Arrows-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Arrows-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Arrows-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Arrows-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fills-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fills-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fills-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fills-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fonts-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fonts-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fonts-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Fonts-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Foreign-objects-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Foreign-objects-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Foreign-objects-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Foreign-objects-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Frames-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Frames-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Frames-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Frames-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-flips-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-flips-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-flips-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Geo-flips-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Images-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Images-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Images-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Images-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Regressions-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-alignment-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-alignment-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-alignment-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-alignment-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-rendering-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-rendering-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-rendering-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Text-rendering-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Weird-elbow-arrows-dark-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Weird-elbow-arrows-dark-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Weird-elbow-arrows-light-1-Mobile-Chrome-linux.png create mode 100644 apps/examples/e2e/tests/export-snapshots.spec.tsx-snapshots/Export-snapshots-Weird-elbow-arrows-light-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-a11y-style-panel-navigation.spec.ts create mode 100644 apps/examples/e2e/tests/test-actions-menu.spec.ts create mode 100644 apps/examples/e2e/tests/test-api.spec.ts create mode 100644 apps/examples/e2e/tests/test-camera.spec.ts create mode 100644 apps/examples/e2e/tests/test-canvas-events.spec.ts create mode 100644 apps/examples/e2e/tests/test-clipboard-events.spec.ts create mode 100644 apps/examples/e2e/tests/test-clipboard.spec.ts create mode 100644 apps/examples/e2e/tests/test-commenting-a11y.spec.ts create mode 100644 apps/examples/e2e/tests/test-context-menu.spec.ts create mode 100644 apps/examples/e2e/tests/test-dialogs.spec.ts create mode 100644 apps/examples/e2e/tests/test-focus.spec.ts create mode 100644 apps/examples/e2e/tests/test-image-toolbar.spec.ts create mode 100644 apps/examples/e2e/tests/test-kbds.spec.ts create mode 100644 apps/examples/e2e/tests/test-licensing.spec.ts create mode 100644 apps/examples/e2e/tests/test-main-menu.spec.ts create mode 100644 apps/examples/e2e/tests/test-navigation-panel.spec.ts create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-brush-overlay-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-scribble-overlay-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-selection-foreground-multiple-shapes-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-selection-foreground-rotated-shape-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-selection-foreground-single-shape-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-shape-handles-arrow-endpoints-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-shape-handles-line-endpoints-and-hovered-center-handle-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-shape-handles-line-endpoints-and-hovered-center-handle-2-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-shape-handles-line-with-vertices-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-snap-indicator-overlay-point-snaps-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-overlay-snapshots.spec.ts-snapshots/Overlay-snapshots-zoom-brush-overlay-1-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-page-menu.spec.ts create mode 100644 apps/examples/e2e/tests/test-paste-text-measurement.spec.ts create mode 100644 apps/examples/e2e/tests/test-pointer-cancel.spec.ts create mode 100644 apps/examples/e2e/tests/test-rich-text-toolbar.spec.ts create mode 100644 apps/examples/e2e/tests/test-rich-text.spec.ts create mode 100644 apps/examples/e2e/tests/test-routes.spec.ts create mode 100644 apps/examples/e2e/tests/test-rtl-text-alignment.spec.ts create mode 100644 apps/examples/e2e/tests/test-shapes.spec.ts create mode 100644 apps/examples/e2e/tests/test-smoke.spec.ts create mode 100644 apps/examples/e2e/tests/test-style-panel.spec.ts create mode 100644 apps/examples/e2e/tests/test-text-export-ink.spec.ts create mode 100644 apps/examples/e2e/tests/test-text-export-ink.spec.ts-snapshots/jiffy-italic-export-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-text-export-ink.spec.ts-snapshots/jiffy-italic-svg-export-chromium-linux.png create mode 100644 apps/examples/e2e/tests/test-text.spec.ts create mode 100644 apps/examples/e2e/tests/test-toolbar.spec.ts create mode 100644 apps/examples/e2e/tests/test-video-toolbar.spec.ts create mode 100644 apps/examples/package.json create mode 100644 apps/examples/public/ComicMono.woff create mode 100644 apps/examples/public/connect-node.svg create mode 100644 apps/examples/public/custom-arrow-icon.svg create mode 100644 apps/examples/public/geo-cross.svg create mode 100644 apps/examples/public/geo-rounded-rect.svg create mode 100644 apps/examples/public/glob-icon.svg create mode 100644 apps/examples/public/heart-icon.svg create mode 100644 apps/examples/public/icons/discord.svg create mode 100644 apps/examples/public/icons/github.svg create mode 100644 apps/examples/public/icons/twitter.svg create mode 100644 apps/examples/public/man.png create mode 100644 apps/examples/public/node-icon.svg create mode 100644 apps/examples/public/shadow-man.png create mode 100644 apps/examples/public/speech-bubble.svg create mode 100644 apps/examples/public/tldraw.png create mode 100644 apps/examples/public/tldraw_dev_dark.png create mode 100644 apps/examples/public/tldraw_dev_dark.svg create mode 100644 apps/examples/public/tldraw_dev_light.png create mode 100644 apps/examples/public/tldraw_dev_light.svg create mode 100644 apps/examples/public/tool-screenshot.svg create mode 100644 apps/examples/src/ExamplePage.tsx create mode 100644 apps/examples/src/ExampleWrapper.tsx create mode 100644 apps/examples/src/examples.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-anchors/CommentAnchorsExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-anchors/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-clustering/CommentClusteringExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-clustering/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-clustering/comment-clustering.css create mode 100644 apps/examples/src/examples/collaboration/comment-drawing-reactions/CommentDrawingReactionsExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-drawing-reactions/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-drawing-reactions/comment-drawing-reactions.css create mode 100644 apps/examples/src/examples/collaboration/comment-drawing-reactions/drawing-reactions.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-history/CommentHistoryExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-history/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-history/comment-history.css create mode 100644 apps/examples/src/examples/collaboration/comment-notifications/CommentNotificationsExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-notifications/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-notifications/comment-notifications.css create mode 100644 apps/examples/src/examples/collaboration/comment-regions/CommentRegionsExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-regions/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-shape-precision/CommentShapePrecisionExample.tsx create mode 100644 apps/examples/src/examples/collaboration/comment-shape-precision/README.md create mode 100644 apps/examples/src/examples/collaboration/comment-shape-precision/comment-shape-precision.css create mode 100644 apps/examples/src/examples/collaboration/commenting-mobile/CommentingMobileExample.tsx create mode 100644 apps/examples/src/examples/collaboration/commenting-mobile/README.md create mode 100644 apps/examples/src/examples/collaboration/commenting-sidebar/CommentingSidebarExample.tsx create mode 100644 apps/examples/src/examples/collaboration/commenting-sidebar/README.md create mode 100644 apps/examples/src/examples/collaboration/commenting/CommentingExample.tsx create mode 100644 apps/examples/src/examples/collaboration/commenting/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-custom-people-menu/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-custom-people-menu/SyncCustomPeopleMenuExample.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-custom-people-menu/sync-custom-people-menu.css create mode 100644 apps/examples/src/examples/collaboration/sync-custom-presence/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-custom-presence/SyncCustomPresence.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-custom-shape/CounterShape.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-custom-shape/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-custom-shape/SyncDemoShapeExample.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-custom-shape/ui.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-demo/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-demo/SyncDemoExample.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-private-content/README.md create mode 100644 apps/examples/src/examples/collaboration/sync-private-content/SyncPrivateContentExample.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-private-content/Toggle.tsx create mode 100644 apps/examples/src/examples/collaboration/sync-private-content/style.css create mode 100644 apps/examples/src/examples/collaboration/user-presence/README.md create mode 100644 apps/examples/src/examples/collaboration/user-presence/UserPresenceExample.tsx create mode 100644 apps/examples/src/examples/configuration/arrows-precise-exact/ArrowsPreciseExactExample.tsx create mode 100644 apps/examples/src/examples/configuration/arrows-precise-exact/README.md create mode 100644 apps/examples/src/examples/configuration/asset-props/AssetPropsExample.tsx create mode 100644 apps/examples/src/examples/configuration/asset-props/README.md create mode 100644 apps/examples/src/examples/configuration/camera-options/CameraOptionsExample.tsx create mode 100644 apps/examples/src/examples/configuration/camera-options/README.md create mode 100644 apps/examples/src/examples/configuration/configure-shape-util/ConfigureShapeUtilExample.tsx create mode 100644 apps/examples/src/examples/configuration/configure-shape-util/README.md create mode 100644 apps/examples/src/examples/configuration/custom-embed/CustomEmbedExample.tsx create mode 100644 apps/examples/src/examples/configuration/custom-embed/README.md create mode 100644 apps/examples/src/examples/configuration/custom-options/CustomOptionsExample.tsx create mode 100644 apps/examples/src/examples/configuration/custom-options/README.md create mode 100644 apps/examples/src/examples/configuration/custom-text-outline/CustomTextOutlineExample.tsx create mode 100644 apps/examples/src/examples/configuration/custom-text-outline/README.md create mode 100644 apps/examples/src/examples/configuration/deep-links/DeepLinksExample.tsx create mode 100644 apps/examples/src/examples/configuration/deep-links/README.md create mode 100644 apps/examples/src/examples/configuration/disable-pages/DisablePagesExample.tsx create mode 100644 apps/examples/src/examples/configuration/disable-pages/README.md create mode 100644 apps/examples/src/examples/configuration/display-options/DisplayOptionsExample.tsx create mode 100644 apps/examples/src/examples/configuration/display-options/README.md create mode 100644 apps/examples/src/examples/configuration/edge-scrolling/EdgeScrollingExample.tsx create mode 100644 apps/examples/src/examples/configuration/edge-scrolling/README.md create mode 100644 apps/examples/src/examples/configuration/edge-scrolling/edge-scrolling.css create mode 100644 apps/examples/src/examples/configuration/embed-permissions/EmbedPermissionsExample.tsx create mode 100644 apps/examples/src/examples/configuration/embed-permissions/README.md create mode 100644 apps/examples/src/examples/configuration/environment-detection/EnvironmentDetectionExample.tsx create mode 100644 apps/examples/src/examples/configuration/environment-detection/README.md create mode 100644 apps/examples/src/examples/configuration/environment-detection/environment-detection.css create mode 100644 apps/examples/src/examples/configuration/exploded/ExplodedExample.tsx create mode 100644 apps/examples/src/examples/configuration/exploded/README.md create mode 100644 apps/examples/src/examples/configuration/frame-colors/FrameColorsExample.tsx create mode 100644 apps/examples/src/examples/configuration/frame-colors/README.md create mode 100644 apps/examples/src/examples/configuration/only-editor/MicroSelectTool.ts create mode 100644 apps/examples/src/examples/configuration/only-editor/MiniBoxShape.tsx create mode 100644 apps/examples/src/examples/configuration/only-editor/MiniSelectTool.ts create mode 100644 apps/examples/src/examples/configuration/only-editor/OnlyEditorExample.tsx create mode 100644 apps/examples/src/examples/configuration/only-editor/README.md create mode 100644 apps/examples/src/examples/configuration/persistence-key/PersistenceKeyExample.tsx create mode 100644 apps/examples/src/examples/configuration/persistence-key/README.md create mode 100644 apps/examples/src/examples/configuration/readonly/README.md create mode 100644 apps/examples/src/examples/configuration/readonly/ReadOnlyExample.tsx create mode 100644 apps/examples/src/examples/configuration/reduced-motion/README.md create mode 100644 apps/examples/src/examples/configuration/reduced-motion/ReducedMotionExample.tsx create mode 100644 apps/examples/src/examples/configuration/reduced-motion/reduced-motion.css create mode 100644 apps/examples/src/examples/configuration/resize-note/README.md create mode 100644 apps/examples/src/examples/configuration/resize-note/ResizeNoteExample.tsx create mode 100644 apps/examples/src/examples/data/assets/clipboard-events/ClipboardEventsExample.tsx create mode 100644 apps/examples/src/examples/data/assets/clipboard-events/README.md create mode 100644 apps/examples/src/examples/data/assets/clipboard-events/clipboard-events.css create mode 100644 apps/examples/src/examples/data/assets/custom-asset-type/CustomAssetTypeExample.tsx create mode 100644 apps/examples/src/examples/data/assets/custom-asset-type/README.md create mode 100644 apps/examples/src/examples/data/assets/custom-paste/CustomPasteExample.tsx create mode 100644 apps/examples/src/examples/data/assets/custom-paste/README.md create mode 100644 apps/examples/src/examples/data/assets/custom-records/CustomRecordsExample.tsx create mode 100644 apps/examples/src/examples/data/assets/custom-records/README.md create mode 100644 apps/examples/src/examples/data/assets/custom-records/custom-records.css create mode 100644 apps/examples/src/examples/data/assets/export-canvas-as-image/ExportCanvasImageExample.tsx create mode 100644 apps/examples/src/examples/data/assets/export-canvas-as-image/README.md create mode 100644 apps/examples/src/examples/data/assets/export-canvas-settings/ExportCanvasImageSettingsExample.tsx create mode 100644 apps/examples/src/examples/data/assets/export-canvas-settings/README.md create mode 100644 apps/examples/src/examples/data/assets/external-content-sources/ExternalContentSourcesExample.tsx create mode 100644 apps/examples/src/examples/data/assets/external-content-sources/README.md create mode 100644 apps/examples/src/examples/data/assets/hosted-images/HostedImagesExample.tsx create mode 100644 apps/examples/src/examples/data/assets/hosted-images/README.md create mode 100644 apps/examples/src/examples/data/assets/local-storage/LocalStorageExample.tsx create mode 100644 apps/examples/src/examples/data/assets/local-storage/README.md create mode 100644 apps/examples/src/examples/data/assets/meta-migrations/MetaMigrations.tsx create mode 100644 apps/examples/src/examples/data/assets/meta-migrations/README.md create mode 100644 apps/examples/src/examples/data/assets/meta-migrations/snapshot.ts create mode 100644 apps/examples/src/examples/data/assets/meta-migrations/ui-overrides.tsx create mode 100644 apps/examples/src/examples/data/assets/static-assets/README.md create mode 100644 apps/examples/src/examples/data/assets/static-assets/StaticAssetsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/align-and-distribute-shapes/AlignAndDistributeShapesExample.tsx create mode 100644 apps/examples/src/examples/editor-api/align-and-distribute-shapes/README.md create mode 100644 apps/examples/src/examples/editor-api/align-and-distribute-shapes/align-and-distribute-shapes.css create mode 100644 apps/examples/src/examples/editor-api/api/APIExample.tsx create mode 100644 apps/examples/src/examples/editor-api/api/README.md create mode 100644 apps/examples/src/examples/editor-api/arrow-labels/ArrowLabelsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/arrow-labels/README.md create mode 100644 apps/examples/src/examples/editor-api/conditional-culling/ConditionalCullingExample.tsx create mode 100644 apps/examples/src/examples/editor-api/conditional-culling/README.md create mode 100644 apps/examples/src/examples/editor-api/conditional-culling/conditional-culling.css create mode 100644 apps/examples/src/examples/editor-api/coordinate-system/CoordinateSystemExample.tsx create mode 100644 apps/examples/src/examples/editor-api/coordinate-system/README.md create mode 100644 apps/examples/src/examples/editor-api/coordinate-system/coordinate-system.css create mode 100644 apps/examples/src/examples/editor-api/create-arrow/CreateArrowExample.tsx create mode 100644 apps/examples/src/examples/editor-api/create-arrow/README.md create mode 100644 apps/examples/src/examples/editor-api/custom-clipping-shape/CircleClipShapeTool.tsx create mode 100644 apps/examples/src/examples/editor-api/custom-clipping-shape/CircleClipShapeUtil.tsx create mode 100644 apps/examples/src/examples/editor-api/custom-clipping-shape/CustomClipping.css create mode 100644 apps/examples/src/examples/editor-api/custom-clipping-shape/CustomClippingExample.tsx create mode 100644 apps/examples/src/examples/editor-api/custom-clipping-shape/README.md create mode 100644 apps/examples/src/examples/editor-api/custom-overlay/CustomOverlayExample.tsx create mode 100644 apps/examples/src/examples/editor-api/custom-overlay/PointerRingOverlayUtil.ts create mode 100644 apps/examples/src/examples/editor-api/custom-overlay/README.md create mode 100644 apps/examples/src/examples/editor-api/dimensions-hud/DimensionsHudExample.tsx create mode 100644 apps/examples/src/examples/editor-api/dimensions-hud/DimensionsHudOverlayUtil.ts create mode 100644 apps/examples/src/examples/editor-api/dimensions-hud/README.md create mode 100644 apps/examples/src/examples/editor-api/dynamic-tools/DynamicToolsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/dynamic-tools/README.md create mode 100644 apps/examples/src/examples/editor-api/dynamic-tools/dynamic-tools.css create mode 100644 apps/examples/src/examples/editor-api/easter-egg-styles/EasterEggStylesExample.tsx create mode 100644 apps/examples/src/examples/editor-api/easter-egg-styles/README.md create mode 100644 apps/examples/src/examples/editor-api/editor-focus/EditorFocusExample.tsx create mode 100644 apps/examples/src/examples/editor-api/editor-focus/README.md create mode 100644 apps/examples/src/examples/editor-api/editor-focus/editor-focus.css create mode 100644 apps/examples/src/examples/editor-api/focus-mode/FocusModeExample.tsx create mode 100644 apps/examples/src/examples/editor-api/focus-mode/README.md create mode 100644 apps/examples/src/examples/editor-api/hovered-overlay/HoveredOverlayExample.tsx create mode 100644 apps/examples/src/examples/editor-api/hovered-overlay/README.md create mode 100644 apps/examples/src/examples/editor-api/hovered-overlay/hovered-overlay.css create mode 100644 apps/examples/src/examples/editor-api/interaction-end-callback/InteractionEndExample.tsx create mode 100644 apps/examples/src/examples/editor-api/interaction-end-callback/README.md create mode 100644 apps/examples/src/examples/editor-api/lasso-select-tool/LassoOverlayUtil.ts create mode 100644 apps/examples/src/examples/editor-api/lasso-select-tool/LassoSelectTool.ts create mode 100644 apps/examples/src/examples/editor-api/lasso-select-tool/LassoSelectToolExample.tsx create mode 100644 apps/examples/src/examples/editor-api/lasso-select-tool/README.md create mode 100644 apps/examples/src/examples/editor-api/local-images/LocalImagesExample.tsx create mode 100644 apps/examples/src/examples/editor-api/local-images/README.md create mode 100644 apps/examples/src/examples/editor-api/local-videos/LocalVideosExample.tsx create mode 100644 apps/examples/src/examples/editor-api/local-videos/README.md create mode 100644 apps/examples/src/examples/editor-api/lock-camera-zoom/LockCameraZoomExample.tsx create mode 100644 apps/examples/src/examples/editor-api/lock-camera-zoom/README.md create mode 100644 apps/examples/src/examples/editor-api/locked-shapes/LockedShapesExample.tsx create mode 100644 apps/examples/src/examples/editor-api/locked-shapes/README.md create mode 100644 apps/examples/src/examples/editor-api/locked-shapes/locked-shapes.css create mode 100644 apps/examples/src/examples/editor-api/performance-hooks/PerformanceHooksExample.tsx create mode 100644 apps/examples/src/examples/editor-api/performance-hooks/README.md create mode 100644 apps/examples/src/examples/editor-api/performance-hooks/performance-hooks.css create mode 100644 apps/examples/src/examples/editor-api/reactive-inputs/README.md create mode 100644 apps/examples/src/examples/editor-api/reactive-inputs/ReactiveInputsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/reactive-inputs/reactive-inputs.css create mode 100644 apps/examples/src/examples/editor-api/replace-brush-overlay/DashedBrushOverlayUtil.ts create mode 100644 apps/examples/src/examples/editor-api/replace-brush-overlay/README.md create mode 100644 apps/examples/src/examples/editor-api/replace-brush-overlay/ReplaceBrushOverlayExample.tsx create mode 100644 apps/examples/src/examples/editor-api/selection-bounds/README.md create mode 100644 apps/examples/src/examples/editor-api/selection-bounds/SelectionBoundsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/selection-bounds/selection-bounds.css create mode 100644 apps/examples/src/examples/editor-api/shape-animation/README.md create mode 100644 apps/examples/src/examples/editor-api/shape-animation/ShapeAnimationExample.tsx create mode 100644 apps/examples/src/examples/editor-api/shape-animation/shape-animation.css create mode 100644 apps/examples/src/examples/editor-api/snapshots/README.md create mode 100644 apps/examples/src/examples/editor-api/snapshots/SnapshotExample.tsx create mode 100644 apps/examples/src/examples/editor-api/snapshots/snapshot.json create mode 100644 apps/examples/src/examples/editor-api/snapshots/snapshots.css create mode 100644 apps/examples/src/examples/editor-api/text-search/README.md create mode 100644 apps/examples/src/examples/editor-api/text-search/TextSearchExample.tsx create mode 100644 apps/examples/src/examples/editor-api/text-search/TextSearchPanel.tsx create mode 100644 apps/examples/src/examples/editor-api/text-search/text-search.css create mode 100644 apps/examples/src/examples/editor-api/z-order/README.md create mode 100644 apps/examples/src/examples/editor-api/z-order/ZOrderExample.tsx create mode 100644 apps/examples/src/examples/editor-api/z-order/z-order.css create mode 100644 apps/examples/src/examples/editor-api/zoom-to-bounds/README.md create mode 100644 apps/examples/src/examples/editor-api/zoom-to-bounds/ZoomToBoundsExample.tsx create mode 100644 apps/examples/src/examples/editor-api/zoom-to-bounds/zoom-to-bounds.css create mode 100644 apps/examples/src/examples/events/after-create-update-shape/AfterCreateUpdateShapeExample.tsx create mode 100644 apps/examples/src/examples/events/after-create-update-shape/README.md create mode 100644 apps/examples/src/examples/events/after-delete-shape/AfterDeleteShapeExample.tsx create mode 100644 apps/examples/src/examples/events/after-delete-shape/README.md create mode 100644 apps/examples/src/examples/events/before-create-update-shape/BeforeCreateUpdateShapeExample.tsx create mode 100644 apps/examples/src/examples/events/before-create-update-shape/README.md create mode 100644 apps/examples/src/examples/events/before-delete-shape/BeforeDeleteShapeExample.tsx create mode 100644 apps/examples/src/examples/events/before-delete-shape/README.md create mode 100644 apps/examples/src/examples/events/canvas-events/CanvasEventsExample.tsx create mode 100644 apps/examples/src/examples/events/canvas-events/README.md create mode 100644 apps/examples/src/examples/events/canvas-events/canvas-events.css create mode 100644 apps/examples/src/examples/events/custom-double-click-behavior/CustomDoubleClickBehaviorExample.tsx create mode 100644 apps/examples/src/examples/events/custom-double-click-behavior/README.md create mode 100644 apps/examples/src/examples/events/derived-view/DerivedViewExample.tsx create mode 100644 apps/examples/src/examples/events/derived-view/README.md create mode 100644 apps/examples/src/examples/events/event-blocker/EventBlockerExample.tsx create mode 100644 apps/examples/src/examples/events/event-blocker/README.md create mode 100644 apps/examples/src/examples/events/event-blocker/event-blocker.css create mode 100644 apps/examples/src/examples/events/meta-on-change/OnChangeShapeMetaExample.tsx create mode 100644 apps/examples/src/examples/events/meta-on-change/README.md create mode 100644 apps/examples/src/examples/events/meta-on-create/OnCreateShapeMetaExample.tsx create mode 100644 apps/examples/src/examples/events/meta-on-create/README.md create mode 100644 apps/examples/src/examples/events/permissions-2/PermissionsExample2.tsx create mode 100644 apps/examples/src/examples/events/permissions-2/README.md create mode 100644 apps/examples/src/examples/events/permissions/PermissionsExample.tsx create mode 100644 apps/examples/src/examples/events/permissions/README.md create mode 100644 apps/examples/src/examples/events/prevent-instance-change/PreventInstanceChangeExample.tsx create mode 100644 apps/examples/src/examples/events/prevent-instance-change/README.md create mode 100644 apps/examples/src/examples/events/prevent-multi-shape-selection/PreventMultiShapeSelectionExample.tsx create mode 100644 apps/examples/src/examples/events/prevent-multi-shape-selection/README.md create mode 100644 apps/examples/src/examples/events/prevent-shape-change/PreventShapeChangeExample.tsx create mode 100644 apps/examples/src/examples/events/prevent-shape-change/README.md create mode 100644 apps/examples/src/examples/events/signals/README.md create mode 100644 apps/examples/src/examples/events/signals/StateStoreExample.tsx create mode 100644 apps/examples/src/examples/events/store-events/README.md create mode 100644 apps/examples/src/examples/events/store-events/StoreEventsExample.tsx create mode 100644 apps/examples/src/examples/events/store-events/store-events.css create mode 100644 apps/examples/src/examples/events/ui-events/README.md create mode 100644 apps/examples/src/examples/events/ui-events/UiEventsExample.tsx create mode 100644 apps/examples/src/examples/events/ui-events/codeSnippets.ts create mode 100644 apps/examples/src/examples/events/ui-events/ui-events.css create mode 100644 apps/examples/src/examples/events/unsaved-changes/README.md create mode 100644 apps/examples/src/examples/events/unsaved-changes/UnsavedChangesExample.tsx create mode 100644 apps/examples/src/examples/getting-started/basic/BasicExample.tsx create mode 100644 apps/examples/src/examples/getting-started/basic/README.md create mode 100644 apps/examples/src/examples/layout/external-dialog/ExternalDialog.tsx create mode 100644 apps/examples/src/examples/layout/external-dialog/README.md create mode 100644 apps/examples/src/examples/layout/external-dialog/external-dialog.css create mode 100644 apps/examples/src/examples/layout/external-ui-context/ExternalUiContextExample.tsx create mode 100644 apps/examples/src/examples/layout/external-ui-context/README.md create mode 100644 apps/examples/src/examples/layout/external-ui-context/external-ui.css create mode 100644 apps/examples/src/examples/layout/external-ui/ExternalUiExample.tsx create mode 100644 apps/examples/src/examples/layout/external-ui/README.md create mode 100644 apps/examples/src/examples/layout/external-ui/external-ui.css create mode 100644 apps/examples/src/examples/layout/image-component/README.md create mode 100644 apps/examples/src/examples/layout/image-component/TldrawImageExample.tsx create mode 100644 apps/examples/src/examples/layout/image-component/snapshot.json create mode 100644 apps/examples/src/examples/layout/inline-behavior/InlineBehavior.tsx create mode 100644 apps/examples/src/examples/layout/inline-behavior/README.md create mode 100644 apps/examples/src/examples/layout/inline/InlineExample.tsx create mode 100644 apps/examples/src/examples/layout/inline/README.md create mode 100644 apps/examples/src/examples/layout/inset-canvas/InsetCanvasExample.tsx create mode 100644 apps/examples/src/examples/layout/inset-canvas/README.md create mode 100644 apps/examples/src/examples/layout/inset-canvas/inset-canvas.css create mode 100644 apps/examples/src/examples/layout/inset/InsetExample.tsx create mode 100644 apps/examples/src/examples/layout/inset/README.md create mode 100644 apps/examples/src/examples/layout/multiple/MultipleExample.tsx create mode 100644 apps/examples/src/examples/layout/multiple/README.md create mode 100644 apps/examples/src/examples/layout/scroll/README.md create mode 100644 apps/examples/src/examples/layout/scroll/ScrollExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/ag-grid-shape/DataGridExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/ag-grid-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/arrow-binding-options/ArrowBindingOptionsExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/arrow-binding-options/README.md create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/BoundsSnappingShape.tsx create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/PlayingCardShape/playing-card-tool.tsx create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/PlayingCardShape/playing-card-util.tsx create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/snapshot.json create mode 100644 apps/examples/src/examples/shapes/tools/bounds-snapping-shape/ui-overrides.tsx create mode 100644 apps/examples/src/examples/shapes/tools/cubic-bezier-shape/BezierShapeHandleOverlayUtil.ts create mode 100644 apps/examples/src/examples/shapes/tools/cubic-bezier-shape/CubicBezierShape.tsx create mode 100644 apps/examples/src/examples/shapes/tools/cubic-bezier-shape/CubicBezierShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/cubic-bezier-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/cubic-bezier-shape/SneakyUndoRedoWhileEditing.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/CardShape/CardShapeTool.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/CardShape/CardShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/CardShape/card-shape-migrations.ts create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/CardShape/card-shape-props.ts create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/CustomConfigExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-config/ui-overrides.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-geo-types/CustomGeoTypesExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-geo-types/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-relative-snapping/CustomRelativeSnappingExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-relative-snapping/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-shape-wrapper/CustomShapeWrapperExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-shape-wrapper/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-shape-wrapper/custom-shape-wrapper.css create mode 100644 apps/examples/src/examples/shapes/tools/custom-shape/CustomShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-tool/CustomToolExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-tool/README.md create mode 100644 apps/examples/src/examples/shapes/tools/custom-validators/CustomValidatorsExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/custom-validators/README.md create mode 100644 apps/examples/src/examples/shapes/tools/drag-and-drop/DragAndDropExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/drag-and-drop/README.md create mode 100644 apps/examples/src/examples/shapes/tools/drop-zone-shape/DropZoneShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/drop-zone-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/drop-zone-shape/drop-zone-shape-util.tsx create mode 100644 apps/examples/src/examples/shapes/tools/drop-zone-shape/drop-zone-shape.css create mode 100644 apps/examples/src/examples/shapes/tools/editable-shape/EditableShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/editable-shape/EditableShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/editable-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/flex-layout/FlexContainerHelpers.tsx create mode 100644 apps/examples/src/examples/shapes/tools/flex-layout/FlexLayoutExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/flex-layout/README.md create mode 100644 apps/examples/src/examples/shapes/tools/flex-layout/flex-layout.css create mode 100644 apps/examples/src/examples/shapes/tools/frame-layouts/BoardLayouts.ts create mode 100644 apps/examples/src/examples/shapes/tools/frame-layouts/FrameLayoutsExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/frame-layouts/MediaCardShapes.tsx create mode 100644 apps/examples/src/examples/shapes/tools/frame-layouts/README.md create mode 100644 apps/examples/src/examples/shapes/tools/frame-layouts/frame-layouts.css create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/GlobBindingUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/GlobShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/GlobTool/GlobTool.tsx create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/GlobsExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/NodeShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/README.md create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/shared.ts create mode 100644 apps/examples/src/examples/shapes/tools/globs-editor/utils.ts create mode 100644 apps/examples/src/examples/shapes/tools/interactive-shape/InteractiveShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/interactive-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/interactive-shape/my-interactive-shape-util.tsx create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/KeyboardMathInputExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/MathInput.tsx create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/MathShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/MathTool.ts create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/README.md create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/keyboard-math-input.css create mode 100644 apps/examples/src/examples/shapes/tools/keyboard-math-input/shorthand.ts create mode 100644 apps/examples/src/examples/shapes/tools/layout-bindings/LayoutExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/layout-bindings/README.md create mode 100644 apps/examples/src/examples/shapes/tools/layout-bindings/snapshot.json create mode 100644 apps/examples/src/examples/shapes/tools/outlined-text/OutlinedTextExample.css create mode 100644 apps/examples/src/examples/shapes/tools/outlined-text/OutlinedTextExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/outlined-text/README.md create mode 100644 apps/examples/src/examples/shapes/tools/persistent-iframe-shape/PersistentIframeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/persistent-iframe-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/pin-bindings/PinExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/pin-bindings/README.md create mode 100644 apps/examples/src/examples/shapes/tools/popup-shape/PopupShapeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/popup-shape/PopupShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/popup-shape/README.md create mode 100644 apps/examples/src/examples/shapes/tools/popup-shape/popup-shape.css create mode 100644 apps/examples/src/examples/shapes/tools/portal-shapes/PortalShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/portal-shapes/PortalShapesExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/portal-shapes/README.md create mode 100644 apps/examples/src/examples/shapes/tools/portal-shapes/companion-cube.json create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-custom-extension/README.md create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-custom-extension/RichTextCustomExtension.css create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-custom-extension/RichTextCustomExtension.tsx create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-font-extensions/FontSizeExtension.ts create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-font-extensions/README.md create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-font-extensions/RichTextFontExtension.css create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-font-extensions/RichTextFontExtension.tsx create mode 100644 apps/examples/src/examples/shapes/tools/rich-text-font-extensions/fonts.ts create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/README.md create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/ScreenshotTool/ScreenshotTool.ts create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/ScreenshotTool/childStates/Dragging.ts create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/ScreenshotTool/childStates/Idle.ts create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/ScreenshotTool/childStates/Pointing.ts create mode 100644 apps/examples/src/examples/shapes/tools/screenshot-tool/ScreenshotToolExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-custom-styles/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-custom-styles/ShapeWithCustomStylesExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-geometry/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-geometry/ShapeWithGeometry.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-migrations/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-migrations/ShapeWithMigrationsExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-migrations/snapshot.json create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onClick/ClickableShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onClick/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onClick/ShapeWithOnClickExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onDoubleClickEdge/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onDoubleClickEdge/ResizableShapeUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-onDoubleClickEdge/ShapeWithOnDoubleClickEdgeExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-tldraw-styles/README.md create mode 100644 apps/examples/src/examples/shapes/tools/shape-with-tldraw-styles/ShapeWithTldrawStylesExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/size-from-dom/README.md create mode 100644 apps/examples/src/examples/shapes/tools/size-from-dom/SizeFromDomExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/size-from-dom/contents.ts create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/CustomShapeWithHandles.tsx create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/README.md create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/SpeechBubble/SpeechBubbleTool.tsx create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/SpeechBubble/SpeechBubbleUtil.tsx create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/SpeechBubble/helpers.tsx create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/SpeechBubble/ui-overrides.tsx create mode 100644 apps/examples/src/examples/shapes/tools/speech-bubble/customhandles.css create mode 100644 apps/examples/src/examples/shapes/tools/stamp-tool/README.md create mode 100644 apps/examples/src/examples/shapes/tools/stamp-tool/StampToolExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/stamp-tool/stamp-tool.css create mode 100644 apps/examples/src/examples/shapes/tools/sticker-bindings/README.md create mode 100644 apps/examples/src/examples/shapes/tools/sticker-bindings/StickerExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/text-shape-configuration/README.md create mode 100644 apps/examples/src/examples/shapes/tools/text-shape-configuration/TextShapeConfigurationExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/toSvg-method-example/CustomShapeToSvgExample.tsx create mode 100644 apps/examples/src/examples/shapes/tools/toSvg-method-example/README.md create mode 100644 apps/examples/src/examples/shapes/tools/tool-with-child-states/README.md create mode 100644 apps/examples/src/examples/shapes/tools/tool-with-child-states/ToolWithChildStatesExample.tsx create mode 100644 apps/examples/src/examples/ui/action-overrides/ActionOverridesExample.tsx create mode 100644 apps/examples/src/examples/ui/action-overrides/README.md create mode 100644 apps/examples/src/examples/ui/add-connected-shape/AddConnectedShapeExample.tsx create mode 100644 apps/examples/src/examples/ui/add-connected-shape/README.md create mode 100644 apps/examples/src/examples/ui/add-connected-shape/add-connected-shape.css create mode 100644 apps/examples/src/examples/ui/add-tool-to-toolbar/README.md create mode 100644 apps/examples/src/examples/ui/add-tool-to-toolbar/ToolInToolbarExample.tsx create mode 100644 apps/examples/src/examples/ui/add-tool-to-toolbar/sticker-tool-util.tsx create mode 100644 apps/examples/src/examples/ui/changing-default-colors/ChangingDefaultColorsExample.tsx create mode 100644 apps/examples/src/examples/ui/changing-default-colors/README.md create mode 100644 apps/examples/src/examples/ui/changing-default-style/ChangingDefaultStyleExample.tsx create mode 100644 apps/examples/src/examples/ui/changing-default-style/README.md create mode 100644 apps/examples/src/examples/ui/color-picker/ColorPickerExample.tsx create mode 100644 apps/examples/src/examples/ui/color-picker/README.md create mode 100644 apps/examples/src/examples/ui/color-picker/color-picker.css create mode 100644 apps/examples/src/examples/ui/contextual-style-panel/ContextualStylePanelExample.tsx create mode 100644 apps/examples/src/examples/ui/contextual-style-panel/README.md create mode 100644 apps/examples/src/examples/ui/contextual-toolbar/ContextualToolbarExample.tsx create mode 100644 apps/examples/src/examples/ui/contextual-toolbar/README.md create mode 100644 apps/examples/src/examples/ui/contextual-toolbar/snapshot.json create mode 100644 apps/examples/src/examples/ui/custom-components/CustomComponentsExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-components/README.md create mode 100644 apps/examples/src/examples/ui/custom-error-capture/CustomErrorCaptureExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-error-capture/README.md create mode 100644 apps/examples/src/examples/ui/custom-error-capture/custom-error-capture.css create mode 100644 apps/examples/src/examples/ui/custom-grid/CustomGridExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-grid/README.md create mode 100644 apps/examples/src/examples/ui/custom-language-translations/CustomLanguageTranslationExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-language-translations/README.md create mode 100644 apps/examples/src/examples/ui/custom-language-translations/custom-language-translations.css create mode 100644 apps/examples/src/examples/ui/custom-menus/CustomMenusExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-menus/README.md create mode 100644 apps/examples/src/examples/ui/custom-renderer/CustomRenderer.tsx create mode 100644 apps/examples/src/examples/ui/custom-renderer/CustomRendererExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-renderer/README.md create mode 100644 apps/examples/src/examples/ui/custom-renderer/custom-renderer.css create mode 100644 apps/examples/src/examples/ui/custom-theme/CustomThemeExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-theme/README.md create mode 100644 apps/examples/src/examples/ui/custom-theme/custom-font/OFL.txt create mode 100644 apps/examples/src/examples/ui/custom-theme/custom-font/Silkscreen-Bold.ttf create mode 100644 apps/examples/src/examples/ui/custom-theme/custom-font/Silkscreen-Regular.ttf create mode 100644 apps/examples/src/examples/ui/custom-theme/custom-theme.css create mode 100644 apps/examples/src/examples/ui/custom-ui/CustomUiExample.tsx create mode 100644 apps/examples/src/examples/ui/custom-ui/README.md create mode 100644 apps/examples/src/examples/ui/custom-ui/custom-ui.css create mode 100644 apps/examples/src/examples/ui/dark-mode-toggle/DarkModeToggleExample.tsx create mode 100644 apps/examples/src/examples/ui/dark-mode-toggle/README.md create mode 100644 apps/examples/src/examples/ui/dark-mode/DarkModeExample.tsx create mode 100644 apps/examples/src/examples/ui/dark-mode/README.md create mode 100644 apps/examples/src/examples/ui/drag-and-drop-tray/DragAndDropTrayExample.tsx create mode 100644 apps/examples/src/examples/ui/drag-and-drop-tray/README.md create mode 100644 apps/examples/src/examples/ui/drag-and-drop-tray/drag-and-drop-tray.css create mode 100644 apps/examples/src/examples/ui/drag-and-drop-tray/trayitems.ts create mode 100644 apps/examples/src/examples/ui/error-boundary/ErrorBoundaryExample.tsx create mode 100644 apps/examples/src/examples/ui/error-boundary/ErrorShape.ts create mode 100644 apps/examples/src/examples/ui/error-boundary/README.md create mode 100644 apps/examples/src/examples/ui/escape-shape-focus-trap/EscapeShapeFocusTrap.tsx create mode 100644 apps/examples/src/examples/ui/escape-shape-focus-trap/README.md create mode 100644 apps/examples/src/examples/ui/floaty-window/FloatyExample.tsx create mode 100644 apps/examples/src/examples/ui/floaty-window/README.md create mode 100644 apps/examples/src/examples/ui/force-mobile/ForceBreakpointExample.tsx create mode 100644 apps/examples/src/examples/ui/force-mobile/README.md create mode 100644 apps/examples/src/examples/ui/hide-ui/HideUiExample.tsx create mode 100644 apps/examples/src/examples/ui/hide-ui/README.md create mode 100644 apps/examples/src/examples/ui/indicators-logic/IndicatorsLogicExample.tsx create mode 100644 apps/examples/src/examples/ui/indicators-logic/README.md create mode 100644 apps/examples/src/examples/ui/inspector-panel/InspectorPanelExample.tsx create mode 100644 apps/examples/src/examples/ui/inspector-panel/README.md create mode 100644 apps/examples/src/examples/ui/inspector-panel/inspector-panel.css create mode 100644 apps/examples/src/examples/ui/keyboard-shortcuts/KeyboardShortcutsExample.tsx create mode 100644 apps/examples/src/examples/ui/keyboard-shortcuts/README.md create mode 100644 apps/examples/src/examples/ui/layer-panel/LayerPanelExample.tsx create mode 100644 apps/examples/src/examples/ui/layer-panel/README.md create mode 100644 apps/examples/src/examples/ui/layer-panel/ShapeList.tsx create mode 100644 apps/examples/src/examples/ui/layer-panel/layer-panel.css create mode 100644 apps/examples/src/examples/ui/layer-panel/snapshot.json create mode 100644 apps/examples/src/examples/ui/menu-system-hover/MenuSystemHoverExample.tsx create mode 100644 apps/examples/src/examples/ui/menu-system-hover/README.md create mode 100644 apps/examples/src/examples/ui/menu-system-hover/menu-system-hover.css create mode 100644 apps/examples/src/examples/ui/multiple-themes/MultipleThemesExample.tsx create mode 100644 apps/examples/src/examples/ui/multiple-themes/README.md create mode 100644 apps/examples/src/examples/ui/multiple-themes/multiple-themes.css create mode 100644 apps/examples/src/examples/ui/overlay-theme-colors/OverlayThemeColorsExample.tsx create mode 100644 apps/examples/src/examples/ui/overlay-theme-colors/README.md create mode 100644 apps/examples/src/examples/ui/page-panel/PagePanelExample.tsx create mode 100644 apps/examples/src/examples/ui/page-panel/README.md create mode 100644 apps/examples/src/examples/ui/page-panel/page-panel.css create mode 100644 apps/examples/src/examples/ui/remove-tool/README.md create mode 100644 apps/examples/src/examples/ui/remove-tool/RemoveToolExample.tsx create mode 100644 apps/examples/src/examples/ui/rich-text-on-multiple-shapes/README.md create mode 100644 apps/examples/src/examples/ui/rich-text-on-multiple-shapes/RichTextFormatOnMultipleShapesExample.tsx create mode 100644 apps/examples/src/examples/ui/screen-reader-accessibility/README.md create mode 100644 apps/examples/src/examples/ui/screen-reader-accessibility/ScreenReaderAccessibilityExample.tsx create mode 100644 apps/examples/src/examples/ui/screen-reader-accessibility/screen-reader-accessibility.css create mode 100644 apps/examples/src/examples/ui/selection-color-condition/README.md create mode 100644 apps/examples/src/examples/ui/selection-color-condition/SelectionColorConditionExample.tsx create mode 100644 apps/examples/src/examples/ui/selection-ui/README.md create mode 100644 apps/examples/src/examples/ui/selection-ui/SelectionUiExample.tsx create mode 100644 apps/examples/src/examples/ui/stroke-size-picker/README.md create mode 100644 apps/examples/src/examples/ui/stroke-size-picker/StrokeSizePickerExample.tsx create mode 100644 apps/examples/src/examples/ui/stroke-size-picker/stroke-size-picker.css create mode 100644 apps/examples/src/examples/ui/text-mass-style-updates/README.md create mode 100644 apps/examples/src/examples/ui/text-mass-style-updates/TextMassStyleUpdates.tsx create mode 100644 apps/examples/src/examples/ui/things-on-the-canvas/OnTheCanvasExample.tsx create mode 100644 apps/examples/src/examples/ui/things-on-the-canvas/README.md create mode 100644 apps/examples/src/examples/ui/things-on-the-canvas/things-on-the-canvas.css create mode 100644 apps/examples/src/examples/ui/toasts-and-dialogs/README.md create mode 100644 apps/examples/src/examples/ui/toasts-and-dialogs/ToastsDialogsExample.tsx create mode 100644 apps/examples/src/examples/ui/toolbar-groups/README.md create mode 100644 apps/examples/src/examples/ui/toolbar-groups/ToolbarGroupsExample.tsx create mode 100644 apps/examples/src/examples/ui/ui-components-hidden/README.md create mode 100644 apps/examples/src/examples/ui/ui-components-hidden/UiComponentsHiddenExample.tsx create mode 100644 apps/examples/src/examples/ui/ui-primitives/README.md create mode 100644 apps/examples/src/examples/ui/ui-primitives/UiPrimitivesExample.tsx create mode 100644 apps/examples/src/examples/ui/ui-primitives/ui-primitives.css create mode 100644 apps/examples/src/examples/ui/vertical-toolbar/README.md create mode 100644 apps/examples/src/examples/ui/vertical-toolbar/VerticalToolbarExample.tsx create mode 100644 apps/examples/src/examples/ui/zones/README.md create mode 100644 apps/examples/src/examples/ui/zones/ZonesExample.tsx create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/CustomShapeMermaids.tsx create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/README.md create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/custom-shape-mermaid.css create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/customMermaidShapeUtil.css create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/customMermaidShapeUtil.tsx create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/flowchartSourceGuard.ts create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/mermaidPipelineBlueprint.ts create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/mermaidPipelineState.ts create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/pipelineFromEditor.ts create mode 100644 apps/examples/src/examples/use-cases/custom-shape-mermaids/pipelineGraph.ts create mode 100644 apps/examples/src/examples/use-cases/d3-map/D3MapExample.tsx create mode 100644 apps/examples/src/examples/use-cases/d3-map/README.md create mode 100644 apps/examples/src/examples/use-cases/d3-map/UsMapShapeUtil.tsx create mode 100644 apps/examples/src/examples/use-cases/d3-map/UsStateShapeUtil.tsx create mode 100644 apps/examples/src/examples/use-cases/d3-map/d3-map.css create mode 100644 apps/examples/src/examples/use-cases/d3-map/us-map-data.ts create mode 100644 apps/examples/src/examples/use-cases/education-canvas/EducationCanvasExample.tsx create mode 100644 apps/examples/src/examples/use-cases/education-canvas/README.md create mode 100644 apps/examples/src/examples/use-cases/education-canvas/education-canvas.css create mode 100644 apps/examples/src/examples/use-cases/exam-marking/ExamMarkingExample.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/ExamScoreLabel.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/README.md create mode 100644 apps/examples/src/examples/use-cases/exam-marking/add-mark-tool.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/add-mark-util.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/pdf-editor/ExportPdfButton.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/pdf-editor/PdfEditor.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/pdf-editor/PdfPicker.tsx create mode 100644 apps/examples/src/examples/use-cases/exam-marking/pdf-editor/pdf-editor.css create mode 100644 apps/examples/src/examples/use-cases/exam-marking/ui-overrides.tsx create mode 100644 apps/examples/src/examples/use-cases/fog-of-war/FogOfWarExample.tsx create mode 100644 apps/examples/src/examples/use-cases/fog-of-war/README.md create mode 100644 apps/examples/src/examples/use-cases/hundred-mermaids/MermaidDiagramsExample.tsx create mode 100644 apps/examples/src/examples/use-cases/hundred-mermaids/README.md create mode 100644 apps/examples/src/examples/use-cases/hundred-mermaids/hundred-mermaids.css create mode 100644 apps/examples/src/examples/use-cases/hundred-mermaids/mermaids.ts create mode 100644 apps/examples/src/examples/use-cases/image-annotator/ImageAnnotationEditor.tsx create mode 100644 apps/examples/src/examples/use-cases/image-annotator/ImageAnnotatorExample.tsx create mode 100644 apps/examples/src/examples/use-cases/image-annotator/ImageExport.tsx create mode 100644 apps/examples/src/examples/use-cases/image-annotator/ImagePicker.tsx create mode 100644 apps/examples/src/examples/use-cases/image-annotator/README.md create mode 100644 apps/examples/src/examples/use-cases/image-annotator/assets/distracted-bf.jpeg create mode 100644 apps/examples/src/examples/use-cases/image-annotator/assets/expanding-brain.png create mode 100644 apps/examples/src/examples/use-cases/image-annotator/image-annotator.css create mode 100644 apps/examples/src/examples/use-cases/image-annotator/types.tsx create mode 100644 apps/examples/src/examples/use-cases/many-shapes/ManyShapesExample.tsx create mode 100644 apps/examples/src/examples/use-cases/many-shapes/README.md create mode 100644 apps/examples/src/examples/use-cases/map-tiles/MapTilesExample.tsx create mode 100644 apps/examples/src/examples/use-cases/map-tiles/README.md create mode 100644 apps/examples/src/examples/use-cases/map-tiles/TileLayer.tsx create mode 100644 apps/examples/src/examples/use-cases/map-tiles/map-tiles.css create mode 100644 apps/examples/src/examples/use-cases/map-tiles/mercator.ts create mode 100644 apps/examples/src/examples/use-cases/mask-window/MaskWindowExample.tsx create mode 100644 apps/examples/src/examples/use-cases/mask-window/README.md create mode 100644 apps/examples/src/examples/use-cases/mask-window/mask-window.css create mode 100644 apps/examples/src/examples/use-cases/mermaid-pasting/MermaidPasting.tsx create mode 100644 apps/examples/src/examples/use-cases/mermaid-pasting/README.md create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/ExportPdfButton.tsx create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/PdfEditor.tsx create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/PdfEditorExample.tsx create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/PdfPicker.tsx create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/README.md create mode 100644 apps/examples/src/examples/use-cases/pdf-editor/pdf-editor.css create mode 100644 apps/examples/src/examples/use-cases/slides/README.md create mode 100644 apps/examples/src/examples/use-cases/slides/SlideShapeTool.tsx create mode 100644 apps/examples/src/examples/use-cases/slides/SlideShapeUtil.tsx create mode 100644 apps/examples/src/examples/use-cases/slides/SlidesExample.tsx create mode 100644 apps/examples/src/examples/use-cases/slides/SlidesPanel.tsx create mode 100644 apps/examples/src/examples/use-cases/slides/slides.css create mode 100644 apps/examples/src/examples/use-cases/slides/useSlides.tsx create mode 100644 apps/examples/src/examples/use-cases/slideshow/README.md create mode 100644 apps/examples/src/examples/use-cases/slideshow/SlideShowExample.tsx create mode 100644 apps/examples/src/examples/use-cases/slideshow/SlidesManager.tsx create mode 100644 apps/examples/src/examples/use-cases/snowstorm/README.md create mode 100644 apps/examples/src/examples/use-cases/snowstorm/SnowStorm.tsx create mode 100644 apps/examples/src/examples/use-cases/snowstorm/SnowStormExample.tsx create mode 100644 apps/examples/src/examples/use-cases/snowstorm/snowstorm.css create mode 100644 apps/examples/src/examples/use-cases/soft-clip/README.md create mode 100644 apps/examples/src/examples/use-cases/soft-clip/SoftClipExample.tsx create mode 100644 apps/examples/src/examples/use-cases/soft-clip/soft-clip.css create mode 100644 apps/examples/src/examples/use-cases/timeline-scrubber/README.md create mode 100644 apps/examples/src/examples/use-cases/timeline-scrubber/TimelineScrubberExample.tsx create mode 100644 apps/examples/src/examples/use-cases/timeline-scrubber/timeline-scrubber.css create mode 100644 apps/examples/src/examples/use-cases/tower-defense/README.md create mode 100644 apps/examples/src/examples/use-cases/tower-defense/TowerDefenseExample.tsx create mode 100644 apps/examples/src/examples/use-cases/tower-defense/enemy-config.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/game-loop.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/game-state.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/EnemyOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/ExplosionOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/PathOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/PlacementPreviewOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/ProjectileOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/TowerRangeOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/overlays/UpgradeButtonOverlayUtil.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/path.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/sounds.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/tower-config.ts create mode 100644 apps/examples/src/examples/use-cases/tower-defense/tower-defense.css create mode 100644 apps/examples/src/examples/use-cases/xkcd-dependency/README.md create mode 100644 apps/examples/src/examples/use-cases/xkcd-dependency/XkcdDependencyExample.tsx create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/ContentLayer.tsx create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/README.md create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/SemanticZoom.tsx create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/ZoomIntoMobyDickExample.tsx create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/layout.ts create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/navigation.ts create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/summaries.ts create mode 100644 apps/examples/src/examples/use-cases/zoom-into-moby-dick/zoom-into-moby-dick.css create mode 100644 apps/examples/src/examples/users/attribution-timeline/AttributionTimelineExample.tsx create mode 100644 apps/examples/src/examples/users/attribution-timeline/README.md create mode 100644 apps/examples/src/examples/users/attribution-timeline/attribution-timeline.css create mode 100644 apps/examples/src/examples/users/attribution/AttributionExample.tsx create mode 100644 apps/examples/src/examples/users/attribution/README.md create mode 100644 apps/examples/src/examples/users/attribution/attribution.css create mode 100644 apps/examples/src/examples/users/custom-user/CustomUserExample.tsx create mode 100644 apps/examples/src/examples/users/custom-user/README.md create mode 100644 apps/examples/src/examples/users/custom-user/custom-user.css create mode 100644 apps/examples/src/examples/users/note-attribution-component/NoteAttributionComponentExample.tsx create mode 100644 apps/examples/src/examples/users/note-attribution-component/README.md create mode 100644 apps/examples/src/examples/users/sync-custom-user/README.md create mode 100644 apps/examples/src/examples/users/sync-custom-user/SyncCustomUser.tsx create mode 100644 apps/examples/src/hooks/useDebugging.tsx create mode 100644 apps/examples/src/hooks/usePerformance.ts create mode 100644 apps/examples/src/icons/apple-touch-icon.png create mode 100644 apps/examples/src/icons/icons.tsx create mode 100644 apps/examples/src/icons/tldraw.svg create mode 100644 apps/examples/src/index.html create mode 100644 apps/examples/src/index.tsx create mode 100644 apps/examples/src/misc/EndToEndApi.tsx create mode 100644 apps/examples/src/misc/a11y.tsx create mode 100644 apps/examples/src/misc/develop.tsx create mode 100644 apps/examples/src/misc/diff.ts create mode 100644 apps/examples/src/misc/end-to-end.tsx create mode 100644 apps/examples/src/misc/mermaidReadability.ts create mode 100644 apps/examples/src/styles.css create mode 100644 apps/examples/src/vite-env.d.ts create mode 100644 apps/examples/tsconfig.json create mode 100644 apps/examples/vercel.json create mode 100644 apps/examples/vite.config.ts create mode 100644 apps/examples/writing-examples.md create mode 100644 apps/mcp-app/.claude/skills/add-app-to-server/SKILL.md create mode 100644 apps/mcp-app/.claude/skills/convert-web-app/SKILL.md create mode 100644 apps/mcp-app/.claude/skills/create-mcp-app/SKILL.md create mode 100644 apps/mcp-app/.claude/skills/migrate-oai-app/SKILL.md create mode 100644 apps/mcp-app/.cursor-plugin/marketplace.json create mode 100644 apps/mcp-app/.gitignore create mode 100644 apps/mcp-app/LICENSE.md create mode 100644 apps/mcp-app/README.md create mode 100755 apps/mcp-app/dev-tunnel.sh create mode 100644 apps/mcp-app/package.json create mode 100644 apps/mcp-app/plugins/tldraw-mcp/.cursor-plugin/plugin.json create mode 100644 apps/mcp-app/plugins/tldraw-mcp/assets/logo.svg create mode 100644 apps/mcp-app/plugins/tldraw-mcp/mcp.json create mode 100644 apps/mcp-app/scripts/extract-editor-api.ts create mode 100644 apps/mcp-app/server.json create mode 100644 apps/mcp-app/src/agents-canary.test.ts create mode 100644 apps/mcp-app/src/canvas-store.ts create mode 100644 apps/mcp-app/src/idle-expiry.test.ts create mode 100644 apps/mcp-app/src/large-payload-smoke.test.ts create mode 100644 apps/mcp-app/src/logger.ts create mode 100644 apps/mcp-app/src/next-expiry-time.test.ts create mode 100644 apps/mcp-app/src/register-tools.ts create mode 100644 apps/mcp-app/src/shared/exec-key.ts create mode 100644 apps/mcp-app/src/shared/generated-data.ts create mode 100644 apps/mcp-app/src/shared/pending-requests.ts create mode 100644 apps/mcp-app/src/shared/types.ts create mode 100644 apps/mcp-app/src/shared/utils.ts create mode 100644 apps/mcp-app/src/tools/exec.ts create mode 100644 apps/mcp-app/src/tools/loadCachedCanvasWidgetHtml.ts create mode 100644 apps/mcp-app/src/tools/search.ts create mode 100644 apps/mcp-app/src/widget/app-context.tsx create mode 100644 apps/mcp-app/src/widget/dev-log.tsx create mode 100644 apps/mcp-app/src/widget/exec-helpers.test.ts create mode 100644 apps/mcp-app/src/widget/exec-helpers.ts create mode 100644 apps/mcp-app/src/widget/export-tldr.ts create mode 100644 apps/mcp-app/src/widget/focused/defaults.ts create mode 100644 apps/mcp-app/src/widget/focused/focused-editor-proxy.ts create mode 100644 apps/mcp-app/src/widget/focused/format.ts create mode 100644 apps/mcp-app/src/widget/focused/to-focused.ts create mode 100644 apps/mcp-app/src/widget/focused/to-tldraw.ts create mode 100644 apps/mcp-app/src/widget/image-guard.tsx create mode 100644 apps/mcp-app/src/widget/index.html create mode 100644 apps/mcp-app/src/widget/mcp-app.css create mode 100644 apps/mcp-app/src/widget/mcp-app.tsx create mode 100644 apps/mcp-app/src/widget/persistence.ts create mode 100644 apps/mcp-app/src/widget/snapshot.ts create mode 100644 apps/mcp-app/src/worker.ts create mode 100644 apps/mcp-app/src/wrangler-dev-harness.ts create mode 100644 apps/mcp-app/tsconfig.json create mode 100644 apps/mcp-app/vite.config.ts create mode 100644 apps/mcp-app/vitest.config.ts create mode 100644 apps/mcp-app/wrangler.toml create mode 100644 apps/tldraw-new/.gitignore create mode 100644 apps/tldraw-new/index.html create mode 100644 apps/tldraw-new/vercel.json create mode 100644 apps/vscode/DOCS.md create mode 100644 apps/vscode/README.md create mode 100644 apps/vscode/VS-Code-Extension-1.tldr create mode 100644 apps/vscode/editor/LICENSE.md create mode 100644 apps/vscode/editor/README.md create mode 100644 apps/vscode/editor/package.json create mode 100644 apps/vscode/editor/public/index.css create mode 100644 apps/vscode/editor/scripts/build.ts create mode 100644 apps/vscode/editor/scripts/cli.ts create mode 100644 apps/vscode/editor/scripts/dev.ts create mode 100644 apps/vscode/editor/scripts/helpers.ts create mode 100644 apps/vscode/editor/scripts/path.ts create mode 100644 apps/vscode/editor/src/ChangeResponder.tsx create mode 100644 apps/vscode/editor/src/FileOpen.tsx create mode 100644 apps/vscode/editor/src/FullPageMessage.tsx create mode 100644 apps/vscode/editor/src/Links.tsx create mode 100644 apps/vscode/editor/src/app.tsx create mode 100644 apps/vscode/editor/src/index.tsx create mode 100644 apps/vscode/editor/src/utils/bookmarks.ts create mode 100644 apps/vscode/editor/src/utils/externalUrlContentHandler.ts create mode 100644 apps/vscode/editor/src/utils/rpc.ts create mode 100644 apps/vscode/editor/src/utils/url.ts create mode 100644 apps/vscode/editor/src/utils/vscode.ts create mode 100644 apps/vscode/editor/tsconfig.json create mode 100644 apps/vscode/extension/.gitignore create mode 100644 apps/vscode/extension/.vscode/extensions.json create mode 100644 apps/vscode/extension/.vscode/launch.json create mode 100644 apps/vscode/extension/.vscode/settings.json create mode 100644 apps/vscode/extension/.vscodeignore create mode 100644 apps/vscode/extension/CHANGELOG.md create mode 100644 apps/vscode/extension/LICENSE.md create mode 100644 apps/vscode/extension/README.md create mode 100644 apps/vscode/extension/assets/vscode_open.png create mode 100644 apps/vscode/extension/examples/1.tldr create mode 100644 apps/vscode/extension/examples/2.tldr create mode 100644 apps/vscode/extension/examples/3.tldr create mode 100644 apps/vscode/extension/examples/files-with-erros/invalid-record.tldr create mode 100644 apps/vscode/extension/examples/files-with-erros/invalid-tldraw-file.tldr create mode 100644 apps/vscode/extension/examples/files-with-erros/version-too-new.tldr create mode 100644 apps/vscode/extension/examples/v2.tldr create mode 100644 apps/vscode/extension/examples/v2a.tldr create mode 100644 apps/vscode/extension/icon.png create mode 100644 apps/vscode/extension/package.json create mode 100644 apps/vscode/extension/scripts/build.ts create mode 100644 apps/vscode/extension/scripts/cli.ts create mode 100644 apps/vscode/extension/scripts/dev.ts create mode 100644 apps/vscode/extension/scripts/helpers.ts create mode 100644 apps/vscode/extension/scripts/package.ts create mode 100644 apps/vscode/extension/scripts/path.ts create mode 100644 apps/vscode/extension/scripts/publish.ts create mode 100644 apps/vscode/extension/src/TldrawDocument.ts create mode 100644 apps/vscode/extension/src/TldrawEditorProvider.ts create mode 100644 apps/vscode/extension/src/TldrawOfflineFileProvider.ts create mode 100644 apps/vscode/extension/src/TldrawWebviewManager.ts create mode 100644 apps/vscode/extension/src/WebViewMessageHandler.ts create mode 100644 apps/vscode/extension/src/extension.ts create mode 100644 apps/vscode/extension/src/file.ts create mode 100644 apps/vscode/extension/src/media.ts create mode 100644 apps/vscode/extension/src/unfurl.ts create mode 100644 apps/vscode/extension/src/utils.ts create mode 100644 apps/vscode/extension/tsconfig.json create mode 100644 apps/vscode/messages.ts create mode 100644 assets/embed-icons/canva.png create mode 100644 assets/embed-icons/codepen.png create mode 100644 assets/embed-icons/codesandbox.png create mode 100644 assets/embed-icons/desmos.png create mode 100644 assets/embed-icons/excalidraw.png create mode 100644 assets/embed-icons/felt.png create mode 100644 assets/embed-icons/figma.png create mode 100644 assets/embed-icons/github_gist.png create mode 100644 assets/embed-icons/google_calendar.png create mode 100644 assets/embed-icons/google_maps.png create mode 100644 assets/embed-icons/google_slides.png create mode 100644 assets/embed-icons/observable.png create mode 100644 assets/embed-icons/replit.png create mode 100644 assets/embed-icons/scratch.png create mode 100644 assets/embed-icons/spotify.png create mode 100644 assets/embed-icons/tldraw.png create mode 100644 assets/embed-icons/val_town.png create mode 100644 assets/embed-icons/vimeo.png create mode 100644 assets/embed-icons/youtube.png create mode 100644 assets/fonts/IBMPlexMono-Bold.woff2 create mode 100644 assets/fonts/IBMPlexMono-BoldItalic.woff2 create mode 100644 assets/fonts/IBMPlexMono-Medium.woff2 create mode 100644 assets/fonts/IBMPlexMono-MediumItalic.woff2 create mode 100644 assets/fonts/IBMPlexSans-Bold.woff2 create mode 100644 assets/fonts/IBMPlexSans-BoldItalic.woff2 create mode 100644 assets/fonts/IBMPlexSans-Medium.woff2 create mode 100644 assets/fonts/IBMPlexSans-MediumItalic.woff2 create mode 100644 assets/fonts/IBMPlexSerif-Bold.woff2 create mode 100644 assets/fonts/IBMPlexSerif-BoldItalic.woff2 create mode 100644 assets/fonts/IBMPlexSerif-Medium.woff2 create mode 100644 assets/fonts/IBMPlexSerif-MediumItalic.woff2 create mode 100644 assets/github-hero-dark.png create mode 100644 assets/github-hero-light.png create mode 100644 assets/icons/icon/align-bottom.svg create mode 100644 assets/icons/icon/align-center-horizontal.svg create mode 100644 assets/icons/icon/align-center-vertical.svg create mode 100644 assets/icons/icon/align-left.svg create mode 100644 assets/icons/icon/align-right.svg create mode 100644 assets/icons/icon/align-top.svg create mode 100644 assets/icons/icon/alt.svg create mode 100644 assets/icons/icon/arrow-arc.svg create mode 100644 assets/icons/icon/arrow-cycle.svg create mode 100644 assets/icons/icon/arrow-elbow.svg create mode 100644 assets/icons/icon/arrow-left.svg create mode 100644 assets/icons/icon/arrowhead-arrow.svg create mode 100644 assets/icons/icon/arrowhead-bar.svg create mode 100644 assets/icons/icon/arrowhead-diamond.svg create mode 100644 assets/icons/icon/arrowhead-dot.svg create mode 100644 assets/icons/icon/arrowhead-none.svg create mode 100644 assets/icons/icon/arrowhead-square.svg create mode 100644 assets/icons/icon/arrowhead-triangle-inverted.svg create mode 100644 assets/icons/icon/arrowhead-triangle.svg create mode 100644 assets/icons/icon/blob.svg create mode 100644 assets/icons/icon/bold.svg create mode 100644 assets/icons/icon/bookmark.svg create mode 100644 assets/icons/icon/bring-forward.svg create mode 100644 assets/icons/icon/bring-to-front.svg create mode 100644 assets/icons/icon/broken.svg create mode 100644 assets/icons/icon/bulletList.svg create mode 100644 assets/icons/icon/check-circle.svg create mode 100644 assets/icons/icon/check.svg create mode 100644 assets/icons/icon/chevron-down.svg create mode 100644 assets/icons/icon/chevron-left.svg create mode 100644 assets/icons/icon/chevron-right.svg create mode 100644 assets/icons/icon/chevron-up.svg create mode 100644 assets/icons/icon/chevrons-ne.svg create mode 100644 assets/icons/icon/chevrons-sw.svg create mode 100644 assets/icons/icon/clipboard-copied.svg create mode 100644 assets/icons/icon/clipboard-copy.svg create mode 100644 assets/icons/icon/closed.svg create mode 100644 assets/icons/icon/code.svg create mode 100644 assets/icons/icon/color.svg create mode 100644 assets/icons/icon/comment.svg create mode 100644 assets/icons/icon/corners.svg create mode 100644 assets/icons/icon/crop.svg create mode 100644 assets/icons/icon/cross-2.svg create mode 100644 assets/icons/icon/cross-circle.svg create mode 100644 assets/icons/icon/dash-dashed.svg create mode 100644 assets/icons/icon/dash-dotted.svg create mode 100644 assets/icons/icon/dash-draw.svg create mode 100644 assets/icons/icon/dash-solid.svg create mode 100644 assets/icons/icon/disconnected.svg create mode 100644 assets/icons/icon/discord.svg create mode 100644 assets/icons/icon/distribute-horizontal.svg create mode 100644 assets/icons/icon/distribute-vertical.svg create mode 100644 assets/icons/icon/dot.svg create mode 100644 assets/icons/icon/dots-horizontal.svg create mode 100644 assets/icons/icon/dots-vertical.svg create mode 100644 assets/icons/icon/download.svg create mode 100644 assets/icons/icon/drag-handle-dots.svg create mode 100644 assets/icons/icon/duplicate.svg create mode 100644 assets/icons/icon/edit.svg create mode 100644 assets/icons/icon/external-link.svg create mode 100644 assets/icons/icon/fill-fill.svg create mode 100644 assets/icons/icon/fill-lined-fill.svg create mode 100644 assets/icons/icon/fill-none.svg create mode 100644 assets/icons/icon/fill-pattern.svg create mode 100644 assets/icons/icon/fill-semi.svg create mode 100644 assets/icons/icon/fill-solid.svg create mode 100644 assets/icons/icon/follow.svg create mode 100644 assets/icons/icon/following.svg create mode 100644 assets/icons/icon/font-draw.svg create mode 100644 assets/icons/icon/font-mono.svg create mode 100644 assets/icons/icon/font-sans.svg create mode 100644 assets/icons/icon/font-serif.svg create mode 100644 assets/icons/icon/geo-arrow-down.svg create mode 100644 assets/icons/icon/geo-arrow-left.svg create mode 100644 assets/icons/icon/geo-arrow-right.svg create mode 100644 assets/icons/icon/geo-arrow-up.svg create mode 100644 assets/icons/icon/geo-check-box.svg create mode 100644 assets/icons/icon/geo-cloud.svg create mode 100644 assets/icons/icon/geo-diamond.svg create mode 100644 assets/icons/icon/geo-ellipse.svg create mode 100644 assets/icons/icon/geo-heart.svg create mode 100644 assets/icons/icon/geo-hexagon.svg create mode 100644 assets/icons/icon/geo-octagon.svg create mode 100644 assets/icons/icon/geo-oval.svg create mode 100644 assets/icons/icon/geo-pentagon.svg create mode 100644 assets/icons/icon/geo-rectangle.svg create mode 100644 assets/icons/icon/geo-rhombus-2.svg create mode 100644 assets/icons/icon/geo-rhombus.svg create mode 100644 assets/icons/icon/geo-star.svg create mode 100644 assets/icons/icon/geo-trapezoid.svg create mode 100644 assets/icons/icon/geo-triangle.svg create mode 100644 assets/icons/icon/geo-x-box.svg create mode 100644 assets/icons/icon/github.svg create mode 100644 assets/icons/icon/group.svg create mode 100644 assets/icons/icon/heading.svg create mode 100644 assets/icons/icon/help-circle.svg create mode 100644 assets/icons/icon/highlight.svg create mode 100644 assets/icons/icon/horizontal-align-end.svg create mode 100644 assets/icons/icon/horizontal-align-middle.svg create mode 100644 assets/icons/icon/horizontal-align-start.svg create mode 100644 assets/icons/icon/icon/avatar.svg create mode 100644 assets/icons/icon/info-circle.svg create mode 100644 assets/icons/icon/italic.svg create mode 100644 assets/icons/icon/leading.svg create mode 100644 assets/icons/icon/link.svg create mode 100644 assets/icons/icon/list.svg create mode 100644 assets/icons/icon/lock.svg create mode 100644 assets/icons/icon/manual.svg create mode 100644 assets/icons/icon/menu.svg create mode 100644 assets/icons/icon/minus.svg create mode 100644 assets/icons/icon/mixed.svg create mode 100644 assets/icons/icon/pack.svg create mode 100644 assets/icons/icon/plus.svg create mode 100644 assets/icons/icon/question-mark-circle.svg create mode 100644 assets/icons/icon/question-mark.svg create mode 100644 assets/icons/icon/redo.svg create mode 100644 assets/icons/icon/reset-zoom.svg create mode 100644 assets/icons/icon/rotate-ccw.svg create mode 100644 assets/icons/icon/rotate-cw.svg create mode 100644 assets/icons/icon/send-backward.svg create mode 100644 assets/icons/icon/send-to-back.svg create mode 100644 assets/icons/icon/share-1.svg create mode 100644 assets/icons/icon/size-extra-large.svg create mode 100644 assets/icons/icon/size-large.svg create mode 100644 assets/icons/icon/size-medium.svg create mode 100644 assets/icons/icon/size-small.svg create mode 100644 assets/icons/icon/spline-cubic.svg create mode 100644 assets/icons/icon/spline-line.svg create mode 100644 assets/icons/icon/stack-horizontal.svg create mode 100644 assets/icons/icon/stack-vertical.svg create mode 100644 assets/icons/icon/status-offline.svg create mode 100644 assets/icons/icon/stretch-horizontal.svg create mode 100644 assets/icons/icon/stretch-vertical.svg create mode 100644 assets/icons/icon/strike.svg create mode 100644 assets/icons/icon/text-align-center.svg create mode 100644 assets/icons/icon/text-align-left.svg create mode 100644 assets/icons/icon/text-align-right.svg create mode 100644 assets/icons/icon/toggle-off.svg create mode 100644 assets/icons/icon/toggle-on.svg create mode 100644 assets/icons/icon/tool-arrow.svg create mode 100644 assets/icons/icon/tool-eraser.svg create mode 100644 assets/icons/icon/tool-frame.svg create mode 100644 assets/icons/icon/tool-hand.svg create mode 100644 assets/icons/icon/tool-highlight.svg create mode 100644 assets/icons/icon/tool-laser.svg create mode 100644 assets/icons/icon/tool-line.svg create mode 100644 assets/icons/icon/tool-media.svg create mode 100644 assets/icons/icon/tool-note.svg create mode 100644 assets/icons/icon/tool-pencil.svg create mode 100644 assets/icons/icon/tool-pointer.svg create mode 100644 assets/icons/icon/tool-screenshot.svg create mode 100644 assets/icons/icon/tool-text.svg create mode 100644 assets/icons/icon/trash.svg create mode 100644 assets/icons/icon/twitter.svg create mode 100644 assets/icons/icon/underline.svg create mode 100644 assets/icons/icon/undo.svg create mode 100644 assets/icons/icon/ungroup.svg create mode 100644 assets/icons/icon/unlock.svg create mode 100644 assets/icons/icon/vertical-align-end.svg create mode 100644 assets/icons/icon/vertical-align-middle.svg create mode 100644 assets/icons/icon/vertical-align-start.svg create mode 100644 assets/icons/icon/warning-triangle.svg create mode 100644 assets/icons/icon/zoom-in.svg create mode 100644 assets/icons/icon/zoom-out.svg create mode 100644 assets/tldraw_sdk_logo_dark.png create mode 100644 assets/tldraw_sdk_logo_light.png create mode 100644 assets/translations/ar.json create mode 100644 assets/translations/bn.json create mode 100644 assets/translations/ca.json create mode 100644 assets/translations/cs.json create mode 100644 assets/translations/da.json create mode 100644 assets/translations/de.json create mode 100644 assets/translations/el.json create mode 100644 assets/translations/en.json create mode 100644 assets/translations/es.json create mode 100644 assets/translations/fa.json create mode 100644 assets/translations/fi.json create mode 100644 assets/translations/fr.json create mode 100644 assets/translations/gl.json create mode 100644 assets/translations/gu-in.json create mode 100644 assets/translations/he.json create mode 100644 assets/translations/hi-in.json create mode 100644 assets/translations/hr.json create mode 100644 assets/translations/hu.json create mode 100644 assets/translations/id.json create mode 100644 assets/translations/it.json create mode 100644 assets/translations/ja.json create mode 100644 assets/translations/km-kh.json create mode 100644 assets/translations/kn.json create mode 100644 assets/translations/ko-kr.json create mode 100644 assets/translations/ku.json create mode 100644 assets/translations/languages.json create mode 100644 assets/translations/main.json create mode 100644 assets/translations/ml.json create mode 100644 assets/translations/mr.json create mode 100644 assets/translations/ms.json create mode 100644 assets/translations/my.json create mode 100644 assets/translations/ne.json create mode 100644 assets/translations/nl.json create mode 100644 assets/translations/no.json create mode 100644 assets/translations/pa.json create mode 100644 assets/translations/pl.json create mode 100644 assets/translations/pt-br.json create mode 100644 assets/translations/pt-pt.json create mode 100644 assets/translations/ro.json create mode 100644 assets/translations/ru.json create mode 100644 assets/translations/sl.json create mode 100644 assets/translations/so.json create mode 100644 assets/translations/sv.json create mode 100644 assets/translations/ta.json create mode 100644 assets/translations/te.json create mode 100644 assets/translations/th.json create mode 100644 assets/translations/tl.json create mode 100644 assets/translations/tr.json create mode 100644 assets/translations/uk.json create mode 100644 assets/translations/ur.json create mode 100644 assets/translations/vi.json create mode 100644 assets/translations/zh-cn.json create mode 100644 assets/translations/zh-tw.json create mode 100644 assets/watermarks/watermark-desktop.svg create mode 100644 assets/watermarks/watermark-mobile.svg create mode 100644 assets/watermarks/watermark-track.svg create mode 100644 internal/apps-script/.gitignore create mode 100644 internal/apps-script/README.md create mode 100644 internal/apps-script/appsscript.json create mode 100644 internal/apps-script/build-workspace-app.ts create mode 100644 internal/apps-script/package.json create mode 100644 internal/apps-script/tsconfig.json create mode 100644 internal/config/LICENSE.md create mode 100644 internal/config/api-extractor.json create mode 100644 internal/config/package.json create mode 100644 internal/config/tsconfig.base.json create mode 100644 internal/config/tsconfig.json create mode 100644 internal/config/vitest/node-preset.ts create mode 100644 internal/config/vitest/setup.ts create mode 100644 internal/docs/product-stable-ids.md create mode 100644 internal/grafana/README.md create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/8451fbba-5835-56e2-b2f5-7f5e44c520b8.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/afjn4kz1g4jk0a.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/bfjyilovht2pse.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/cfjnb1whljcowe.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/cfjnbehzmlhxcc.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/cfjyl9tbrury8b.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/dfjn3qe3l7w8wc.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/dfjn9xellhibka.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/dotcom-file-do-exceptions.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/dotcom-version-chain-verify-failures.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/dotcom-version-chain-write-errors.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/e75d2f6c-44cf-54bf-8a74-ced2e045fcb6.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/eec2ad9e-30b9-5c8f-802f-53e26ab8fdc9.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/efjn4hgdlhc00f.yaml create mode 100644 internal/grafana/resources/alertrules.v0alpha1.rules.alerting.grafana.app/efjnbq9h4iha8a.yaml create mode 100644 internal/grafana/resources/dashboards.v0alpha1.dashboard.grafana.app/adgumkhou3chsd.yaml create mode 100644 internal/grafana/resources/dashboards.v0alpha1.dashboard.grafana.app/anthropic-integration-scrape-overview.yaml create mode 100644 internal/grafana/resources/dashboards.v0alpha1.dashboard.grafana.app/edrigjn435v5sf.yaml create mode 100644 internal/grafana/resources/dashboards.v0alpha1.dashboard.grafana.app/slow-queries.yaml create mode 100644 internal/grafana/resources/dashboards.v1.dashboard.grafana.app/nivs2rl.yaml create mode 100644 internal/grafana/resources/dashboards.v2.dashboard.grafana.app/mcp-server.yaml create mode 100644 internal/grafana/resources/dashboards.v2.dashboard.grafana.app/mix4slb.yaml create mode 100644 internal/grafana/resources/dashboards.v2.dashboard.grafana.app/ni7hhgd.yaml create mode 100644 internal/grafana/resources/dashboards.v2beta1.dashboard.grafana.app/kotx6wj.yaml create mode 100644 internal/grafana/resources/folders.v1.folder.grafana.app/anthropic.yaml create mode 100644 internal/grafana/resources/folders.v1.folder.grafana.app/dotcom.yaml create mode 100644 internal/grafana/resources/folders.v1.folder.grafana.app/f6hsw6.yaml create mode 100644 internal/grafana/templates/discord.gotmpl create mode 100644 internal/grafana/templates/email.gotmpl create mode 100644 internal/health-worker/.gitignore create mode 100644 internal/health-worker/README.md create mode 100644 internal/health-worker/package.json create mode 100644 internal/health-worker/src/discord.ts create mode 100644 internal/health-worker/src/index.ts create mode 100644 internal/health-worker/src/updown_types.ts create mode 100644 internal/health-worker/tsconfig.json create mode 100644 internal/health-worker/wrangler.toml create mode 100755 internal/scripts/api-check.ts create mode 100644 internal/scripts/benchmark-dict-validator.ts create mode 100644 internal/scripts/benchmark-validators.ts create mode 100644 internal/scripts/build-api.ts create mode 100644 internal/scripts/build-package.ts create mode 100644 internal/scripts/bump-versions.ts create mode 100644 internal/scripts/check-circular-deps.ts create mode 100644 internal/scripts/check-packages.ts create mode 100644 internal/scripts/check-worker-bundle.ts create mode 100755 internal/scripts/clean.sh create mode 100644 internal/scripts/cloudflare/dns-check.ts create mode 100644 internal/scripts/cloudflare/ssl-cleanup.ts create mode 100644 internal/scripts/create-docs-reference.ts create mode 100644 internal/scripts/deploy-analytics.ts create mode 100644 internal/scripts/deploy-bemo.ts create mode 100644 internal/scripts/deploy-dotcom.ts create mode 100644 internal/scripts/deploy-template.ts create mode 100755 internal/scripts/dev-template.sh create mode 100644 internal/scripts/dotcom/cleanup-test-files.ts create mode 100644 internal/scripts/dotcom/copy-random-files-to-staging.ts create mode 100644 internal/scripts/export-template.ts create mode 100644 internal/scripts/extract-draft-changelog.tsx create mode 100644 internal/scripts/fetch-fly-logs.ts create mode 100644 internal/scripts/fetch-fly-metrics.ts create mode 100644 internal/scripts/fetch-screenshot-metrics.ts create mode 100644 internal/scripts/fly-common.ts create mode 100644 internal/scripts/generate-test-licenses.ts create mode 100644 internal/scripts/generate-tldraw-package-docs.ts create mode 100644 internal/scripts/i18n-download-strings.ts create mode 100644 internal/scripts/i18n-fix-strings.ts create mode 100644 internal/scripts/i18n-upload-strings.ts create mode 100644 internal/scripts/lib/add-extensions.ts create mode 100644 internal/scripts/lib/deploy.ts create mode 100644 internal/scripts/lib/didAnyPackageChange.ts create mode 100644 internal/scripts/lib/discord.ts create mode 100644 internal/scripts/lib/exec.ts create mode 100644 internal/scripts/lib/file.ts create mode 100644 internal/scripts/lib/kill-tree.ts create mode 100644 internal/scripts/lib/labels.ts create mode 100644 internal/scripts/lib/makeEnv.ts create mode 100644 internal/scripts/lib/nicelog.ts create mode 100644 internal/scripts/lib/posthog.ts create mode 100644 internal/scripts/lib/pr-info.ts create mode 100644 internal/scripts/lib/publishing.ts create mode 100644 internal/scripts/lib/skip-ci.ts create mode 100644 internal/scripts/lib/sort-unions.ts create mode 100644 internal/scripts/lib/types.ts create mode 100644 internal/scripts/lib/upload-static-assets.ts create mode 100644 internal/scripts/lib/worker-externals.ts create mode 100644 internal/scripts/lib/workspace.ts create mode 100644 internal/scripts/license-report.ts create mode 100644 internal/scripts/lint-staged.ts create mode 100644 internal/scripts/lint.ts create mode 100644 internal/scripts/oxlint/tldraw-plugin.mjs create mode 100644 internal/scripts/package.json create mode 100755 internal/scripts/postpack.sh create mode 100644 internal/scripts/prepack.ts create mode 100755 internal/scripts/process-compose-bin.cjs create mode 100644 internal/scripts/product-manifest.ts create mode 100644 internal/scripts/profile-tsserver.ts create mode 100644 internal/scripts/profile-typescript.ts create mode 100644 internal/scripts/prune-preview-deploys.ts create mode 100644 internal/scripts/publish-editor-extensions.ts create mode 100644 internal/scripts/publish-manual.ts create mode 100644 internal/scripts/publish-new.ts create mode 100644 internal/scripts/publish-patch.ts create mode 100644 internal/scripts/publish-prerelease.ts create mode 100644 internal/scripts/purge-css.ts create mode 100644 internal/scripts/refresh-assets.ts create mode 100644 internal/scripts/refresh-create-templates.ts create mode 100644 internal/scripts/trigger-dotcom-hotfix.ts create mode 100644 internal/scripts/trigger-sdk-hotfix.ts create mode 100644 internal/scripts/tsconfig.json create mode 100644 internal/scripts/typecheck.ts create mode 100644 internal/scripts/update-pr-template.ts create mode 100755 internal/scripts/vercel/build-docs.sh create mode 100755 internal/scripts/vercel/build.sh create mode 100755 internal/scripts/vercel/install.sh create mode 100755 internal/scripts/vercel/should-build-analytics.sh create mode 100755 internal/scripts/vercel/should-build-docs.sh create mode 100755 internal/scripts/vercel/should-build-template.sh create mode 100755 internal/scripts/vercel/should-build-tldraw-new.sh create mode 100644 internal/scripts/workers/dev.ts create mode 100644 lazy.config.ts create mode 100644 lerna.json create mode 100644 package.json create mode 100644 packages/assets/LICENSE.md create mode 100644 packages/assets/README.md create mode 100644 packages/assets/api-extractor.json create mode 100644 packages/assets/imports.d.ts create mode 100644 packages/assets/imports.js create mode 100644 packages/assets/imports.vite.d.ts create mode 100644 packages/assets/imports.vite.js create mode 100644 packages/assets/modules.d.ts create mode 100644 packages/assets/package.json create mode 100644 packages/assets/selfHosted.d.ts create mode 100644 packages/assets/selfHosted.js create mode 100644 packages/assets/tsconfig.json create mode 100644 packages/assets/types.d.ts create mode 100644 packages/assets/urls.d.ts create mode 100644 packages/assets/urls.js create mode 100644 packages/assets/utils.d.ts create mode 100644 packages/assets/utils.js create mode 100644 packages/collaboration/LICENSE.md create mode 100644 packages/collaboration/README.md create mode 100644 packages/collaboration/api-extractor.json create mode 100644 packages/collaboration/api-report.api.md create mode 100644 packages/collaboration/package.json create mode 100644 packages/collaboration/scripts/copy-css-files.mjs create mode 100644 packages/collaboration/src/index.ts create mode 100644 packages/collaboration/tsconfig.json create mode 100644 packages/collaboration/vitest.config.ts create mode 100644 packages/commenting/LICENSE.md create mode 100644 packages/commenting/REACTIONS.md create mode 100644 packages/commenting/README.md create mode 100644 packages/commenting/api-extractor.json create mode 100644 packages/commenting/api-report.api.md create mode 100644 packages/commenting/package.json create mode 100644 packages/commenting/scripts/copy-css-files.mjs create mode 100644 packages/commenting/src/canvas/anchor-lifecycle.test.ts create mode 100644 packages/commenting/src/canvas/anchor-lifecycle.ts create mode 100644 packages/commenting/src/canvas/canvas-events.ts create mode 100644 packages/commenting/src/canvas/canvas.css create mode 100644 packages/commenting/src/canvas/cluster-badge.tsx create mode 100644 packages/commenting/src/canvas/cluster-fade.ts create mode 100644 packages/commenting/src/canvas/cluster-input.test.ts create mode 100644 packages/commenting/src/canvas/cluster-input.ts create mode 100644 packages/commenting/src/canvas/cluster-model.test.ts create mode 100644 packages/commenting/src/canvas/cluster-model.ts create mode 100644 packages/commenting/src/canvas/comment-body.tsx create mode 100644 packages/commenting/src/canvas/comment-drafts.test.ts create mode 100644 packages/commenting/src/canvas/comment-drafts.ts create mode 100644 packages/commenting/src/canvas/comment-mutations.test.ts create mode 100644 packages/commenting/src/canvas/comment-mutations.ts create mode 100644 packages/commenting/src/canvas/comment-reactions.test.ts create mode 100644 packages/commenting/src/canvas/comment-reactions.tsx create mode 100644 packages/commenting/src/canvas/comment-render.test.ts create mode 100644 packages/commenting/src/canvas/comment-render.ts create mode 100644 packages/commenting/src/canvas/comment-store.ts create mode 100644 packages/commenting/src/canvas/comment-tool.test.ts create mode 100644 packages/commenting/src/canvas/comment-tool.tsx create mode 100644 packages/commenting/src/canvas/comments-filter-menu.tsx create mode 100644 packages/commenting/src/canvas/comments-menu-item.tsx create mode 100644 packages/commenting/src/canvas/comments-overflow-menu.tsx create mode 100644 packages/commenting/src/canvas/comments-overlay.test.ts create mode 100644 packages/commenting/src/canvas/comments-overlay.tsx create mode 100644 packages/commenting/src/canvas/comments-sidebar.test.ts create mode 100644 packages/commenting/src/canvas/comments-sidebar.tsx create mode 100644 packages/commenting/src/canvas/comments-visibility-toggle.tsx create mode 100644 packages/commenting/src/canvas/context.ts create mode 100644 packages/commenting/src/canvas/hooks.test.ts create mode 100644 packages/commenting/src/canvas/hooks.ts create mode 100644 packages/commenting/src/canvas/license.ts create mode 100644 packages/commenting/src/canvas/mobile-placement.ts create mode 100644 packages/commenting/src/canvas/options.test.ts create mode 100644 packages/commenting/src/canvas/options.ts create mode 100644 packages/commenting/src/canvas/pending-composer.tsx create mode 100644 packages/commenting/src/canvas/pin-stacking.test.ts create mode 100644 packages/commenting/src/canvas/pin-stacking.ts create mode 100644 packages/commenting/src/canvas/region-box.tsx create mode 100644 packages/commenting/src/canvas/rich-text.ts create mode 100644 packages/commenting/src/canvas/sidebar-filters.ts create mode 100644 packages/commenting/src/canvas/state.ts create mode 100644 packages/commenting/src/canvas/thread-pin.tsx create mode 100644 packages/commenting/src/canvas/thread-preview.test.ts create mode 100644 packages/commenting/src/canvas/thread-preview.tsx create mode 100644 packages/commenting/src/canvas/thread-stack.tsx create mode 100644 packages/commenting/src/canvas/thread-state.test.ts create mode 100644 packages/commenting/src/canvas/thread-state.ts create mode 100644 packages/commenting/src/canvas/thread-view.test.ts create mode 100644 packages/commenting/src/canvas/thread-view.tsx create mode 100644 packages/commenting/src/clustering/computeClusterTable.test.ts create mode 100644 packages/commenting/src/clustering/computeClusterTable.ts create mode 100644 packages/commenting/src/clustering/locality.test.ts create mode 100644 packages/commenting/src/clustering/mst.test.ts create mode 100644 packages/commenting/src/clustering/mst.ts create mode 100644 packages/commenting/src/clustering/replay.test.ts create mode 100644 packages/commenting/src/clustering/replay.ts create mode 100644 packages/commenting/src/clustering/runtime.test.ts create mode 100644 packages/commenting/src/clustering/runtime.ts create mode 100644 packages/commenting/src/clustering/schedule.test.ts create mode 100644 packages/commenting/src/clustering/schedule.ts create mode 100644 packages/commenting/src/clustering/screen-offsets.test.ts create mode 100644 packages/commenting/src/clustering/types.ts create mode 100644 packages/commenting/src/index.ts create mode 100644 packages/commenting/src/ui/byline.tsx create mode 100644 packages/commenting/src/ui/comment-card.tsx create mode 100644 packages/commenting/src/ui/comment-composer.tsx create mode 100644 packages/commenting/src/ui/comment-extensions.ts create mode 100644 packages/commenting/src/ui/comment-pin.tsx create mode 100644 packages/commenting/src/ui/comment-thread.tsx create mode 100644 packages/commenting/src/ui/comments-list.test.ts create mode 100644 packages/commenting/src/ui/comments-list.tsx create mode 100644 packages/commenting/src/ui/comments.css create mode 100644 packages/commenting/src/ui/count-badge.tsx create mode 100644 packages/commenting/src/ui/emoji-picker.test.ts create mode 100644 packages/commenting/src/ui/emoji-picker.tsx create mode 100644 packages/commenting/src/ui/empty-state.tsx create mode 100644 packages/commenting/src/ui/format-time.test.ts create mode 100644 packages/commenting/src/ui/format-time.ts create mode 100644 packages/commenting/src/ui/icons.tsx create mode 100644 packages/commenting/src/ui/reaction-picker.test.ts create mode 100644 packages/commenting/src/ui/reaction-picker.tsx create mode 100644 packages/commenting/src/ui/reaction.tsx create mode 100644 packages/commenting/src/ui/reactions.tsx create mode 100644 packages/commenting/src/ui/reply-count.ts create mode 100644 packages/commenting/src/ui/send-button.tsx create mode 100644 packages/commenting/src/ui/visual-viewport.test.ts create mode 100644 packages/commenting/src/ui/visual-viewport.ts create mode 100644 packages/commenting/tsconfig.json create mode 100644 packages/commenting/vitest.config.ts create mode 100644 packages/create-tldraw/LICENSE.md create mode 100644 packages/create-tldraw/README.md create mode 100755 packages/create-tldraw/cli.cjs create mode 100644 packages/create-tldraw/package.json create mode 100755 packages/create-tldraw/scripts/build.sh create mode 100755 packages/create-tldraw/scripts/dev.sh create mode 100644 packages/create-tldraw/src/group-select.ts create mode 100644 packages/create-tldraw/src/main.ts create mode 100644 packages/create-tldraw/src/templates.ts create mode 100644 packages/create-tldraw/src/utils.test.ts create mode 100644 packages/create-tldraw/src/utils.ts create mode 100644 packages/create-tldraw/src/wrap-ansi.test.ts create mode 100644 packages/create-tldraw/src/wrap-ansi.ts create mode 100644 packages/create-tldraw/tsconfig.json create mode 100644 packages/create-tldraw/vitest.config.ts create mode 100644 packages/dotcom-shared/README.md create mode 100644 packages/dotcom-shared/package.json create mode 100644 packages/dotcom-shared/src/capabilities.ts create mode 100644 packages/dotcom-shared/src/commentMentions.test.ts create mode 100644 packages/dotcom-shared/src/commentMentions.ts create mode 100644 packages/dotcom-shared/src/constants.ts create mode 100644 packages/dotcom-shared/src/index.test.ts create mode 100644 packages/dotcom-shared/src/index.ts create mode 100644 packages/dotcom-shared/src/license.ts create mode 100644 packages/dotcom-shared/src/mutators.test.ts create mode 100644 packages/dotcom-shared/src/mutators.ts create mode 100644 packages/dotcom-shared/src/queries.test.ts create mode 100644 packages/dotcom-shared/src/queries.ts create mode 100644 packages/dotcom-shared/src/roles.test.ts create mode 100644 packages/dotcom-shared/src/roles.ts create mode 100644 packages/dotcom-shared/src/routes.ts create mode 100644 packages/dotcom-shared/src/shapeClusters.test.ts create mode 100644 packages/dotcom-shared/src/shapeClusters.ts create mode 100644 packages/dotcom-shared/src/thumbnailScreenshot.ts create mode 100644 packages/dotcom-shared/src/tlaSchema.ts create mode 100644 packages/dotcom-shared/src/types.ts create mode 100644 packages/dotcom-shared/tsconfig.json create mode 100644 packages/dotcom-shared/vitest.config.ts create mode 100644 packages/driver/LICENSE.md create mode 100644 packages/driver/README.md create mode 100644 packages/driver/api-extractor.json create mode 100644 packages/driver/api-report.api.md create mode 100644 packages/driver/package.json create mode 100644 packages/driver/src/index.ts create mode 100644 packages/driver/src/lib/Driver.ts create mode 100644 packages/driver/tsconfig.json create mode 100644 packages/driver/vitest.config.ts create mode 100644 packages/editor/LICENSE.md create mode 100644 packages/editor/README.md create mode 100644 packages/editor/api-extractor.json create mode 100644 packages/editor/editor.css create mode 100644 packages/editor/modules.d.ts create mode 100644 packages/editor/package.json create mode 100644 packages/editor/setupTests.js create mode 100644 packages/editor/setupVitest.js create mode 100644 packages/editor/src/index.ts create mode 100644 packages/editor/src/lib/TldrawEditor.tsx create mode 100644 packages/editor/src/lib/components/EditorPortal.tsx create mode 100644 packages/editor/src/lib/components/ErrorBoundary.tsx create mode 100644 packages/editor/src/lib/components/HTMLContainer.tsx create mode 100644 packages/editor/src/lib/components/LiveCollaborators.tsx create mode 100644 packages/editor/src/lib/components/MenuClickCapture.tsx create mode 100644 packages/editor/src/lib/components/SVGContainer.tsx create mode 100644 packages/editor/src/lib/components/Shape.tsx create mode 100644 packages/editor/src/lib/components/default-components/CanvasOverlays.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultBackground.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultCanvas.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultCursor.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultErrorFallback.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultGrid.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultLoadingScreen.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultShapeErrorFallback.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultShapeWrapper.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultSpinner.tsx create mode 100644 packages/editor/src/lib/components/default-components/DefaultSvgDefs.tsx create mode 100644 packages/editor/src/lib/config/TLEditorSnapshot.test.ts create mode 100644 packages/editor/src/lib/config/TLEditorSnapshot.ts create mode 100644 packages/editor/src/lib/config/TLSessionStateSnapshot.ts create mode 100644 packages/editor/src/lib/config/TLUserPreferences.test.ts create mode 100644 packages/editor/src/lib/config/TLUserPreferences.ts create mode 100644 packages/editor/src/lib/config/createTLCurrentUser.ts create mode 100644 packages/editor/src/lib/config/createTLStore.ts create mode 100644 packages/editor/src/lib/config/defaultAssets.ts create mode 100644 packages/editor/src/lib/config/defaultBindings.ts create mode 100644 packages/editor/src/lib/config/defaultShapes.ts create mode 100644 packages/editor/src/lib/constants.ts create mode 100644 packages/editor/src/lib/editor/Editor.test.ts create mode 100644 packages/editor/src/lib/editor/assets/AssetUtil.ts create mode 100644 packages/editor/src/lib/editor/bindings/BindingUtil.ts create mode 100644 packages/editor/src/lib/editor/derivations/bindingsIndex.ts create mode 100644 packages/editor/src/lib/editor/derivations/notVisibleShapes.ts create mode 100644 packages/editor/src/lib/editor/derivations/parentsToChildren.ts create mode 100644 packages/editor/src/lib/editor/derivations/shapeIdsInCurrentPage.ts create mode 100644 packages/editor/src/lib/editor/managers/ClickManager/ClickManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/ClickManager/ClickManager.ts create mode 100644 packages/editor/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts create mode 100644 packages/editor/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts create mode 100644 packages/editor/src/lib/editor/managers/EditorManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/EditorManager.ts create mode 100644 packages/editor/src/lib/editor/managers/FocusManager/FocusManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/FocusManager/FocusManager.ts create mode 100644 packages/editor/src/lib/editor/managers/FontManager/FontManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/FontManager/FontManager.ts create mode 100644 packages/editor/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/HistoryManager/HistoryManager.ts create mode 100644 packages/editor/src/lib/editor/managers/InputsManager/InputsManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/InputsManager/InputsManager.ts create mode 100644 packages/editor/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts create mode 100644 packages/editor/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts create mode 100644 packages/editor/src/lib/editor/managers/PerformanceManager/perf-types.ts create mode 100644 packages/editor/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts create mode 100644 packages/editor/src/lib/editor/managers/SnapManager/BoundsSnaps.ts create mode 100644 packages/editor/src/lib/editor/managers/SnapManager/HandleSnaps.ts create mode 100644 packages/editor/src/lib/editor/managers/SnapManager/SnapManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/SnapManager/SnapManager.ts create mode 100644 packages/editor/src/lib/editor/managers/SpatialIndexManager/RBushIndex.ts create mode 100644 packages/editor/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts create mode 100644 packages/editor/src/lib/editor/managers/TextManager/TextManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/TextManager/TextManager.ts create mode 100644 packages/editor/src/lib/editor/managers/ThemeManager/ThemeManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/ThemeManager/ThemeManager.ts create mode 100644 packages/editor/src/lib/editor/managers/ThemeManager/defaultThemes.ts create mode 100644 packages/editor/src/lib/editor/managers/TickManager/TickManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/TickManager/TickManager.ts create mode 100644 packages/editor/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts create mode 100644 packages/editor/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts create mode 100644 packages/editor/src/lib/editor/overlays/OverlayManager.ts create mode 100644 packages/editor/src/lib/editor/overlays/OverlayUtil.ts create mode 100644 packages/editor/src/lib/editor/overlays/getOverlayDisplayValues.ts create mode 100644 packages/editor/src/lib/editor/overlays/strokeShapeIndicators.ts create mode 100644 packages/editor/src/lib/editor/shapes/BaseBoxShapeUtil.tsx create mode 100644 packages/editor/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx create mode 100644 packages/editor/src/lib/editor/shapes/ShapeUtil.ts create mode 100644 packages/editor/src/lib/editor/shapes/group/DashedOutlineBox.tsx create mode 100644 packages/editor/src/lib/editor/shapes/group/GroupShapeUtil.tsx create mode 100644 packages/editor/src/lib/editor/shapes/shared/getPerfectDashProps.ts create mode 100644 packages/editor/src/lib/editor/shapes/shared/resizeBox.ts create mode 100644 packages/editor/src/lib/editor/shapes/shared/resizeScaled.ts create mode 100644 packages/editor/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts create mode 100644 packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Idle.ts create mode 100644 packages/editor/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts create mode 100644 packages/editor/src/lib/editor/tools/RootState.ts create mode 100644 packages/editor/src/lib/editor/tools/StateNode.test.ts create mode 100644 packages/editor/src/lib/editor/tools/StateNode.ts create mode 100644 packages/editor/src/lib/editor/types/SvgExportContext.tsx create mode 100644 packages/editor/src/lib/editor/types/clipboard-types.ts create mode 100644 packages/editor/src/lib/editor/types/emit-types.ts create mode 100644 packages/editor/src/lib/editor/types/event-types.ts create mode 100644 packages/editor/src/lib/editor/types/external-content.ts create mode 100644 packages/editor/src/lib/editor/types/history-types.ts create mode 100644 packages/editor/src/lib/editor/types/misc-types.ts create mode 100644 packages/editor/src/lib/editor/types/selection-types.ts create mode 100644 packages/editor/src/lib/exports/ExportDelay.tsx create mode 100644 packages/editor/src/lib/exports/FontEmbedder.test.ts create mode 100644 packages/editor/src/lib/exports/FontEmbedder.ts create mode 100644 packages/editor/src/lib/exports/StyleEmbedder.ts create mode 100644 packages/editor/src/lib/exports/cssRules.ts create mode 100644 packages/editor/src/lib/exports/domUtils.ts create mode 100644 packages/editor/src/lib/exports/embedMedia.ts create mode 100644 packages/editor/src/lib/exports/exportToSvg.tsx create mode 100644 packages/editor/src/lib/exports/fetchCache.test.ts create mode 100644 packages/editor/src/lib/exports/fetchCache.ts create mode 100644 packages/editor/src/lib/exports/getSvgAsImage.ts create mode 100644 packages/editor/src/lib/exports/getSvgJsx.test.ts create mode 100644 packages/editor/src/lib/exports/getSvgJsx.tsx create mode 100644 packages/editor/src/lib/exports/parseCss.test.ts create mode 100644 packages/editor/src/lib/exports/parseCss.ts create mode 100644 packages/editor/src/lib/globals/editors.test.ts create mode 100644 packages/editor/src/lib/globals/editors.ts create mode 100644 packages/editor/src/lib/globals/environment.ts create mode 100644 packages/editor/src/lib/globals/menus.test.ts create mode 100644 packages/editor/src/lib/globals/menus.ts create mode 100644 packages/editor/src/lib/globals/time.ts create mode 100644 packages/editor/src/lib/hooks/EditorComponentsContext.tsx create mode 100644 packages/editor/src/lib/hooks/useCanvasEvents.ts create mode 100644 packages/editor/src/lib/hooks/useCoarsePointer.ts create mode 100644 packages/editor/src/lib/hooks/useColorMode.ts create mode 100644 packages/editor/src/lib/hooks/useContainer.tsx create mode 100644 packages/editor/src/lib/hooks/useCursor.ts create mode 100644 packages/editor/src/lib/hooks/useDarkMode.ts create mode 100644 packages/editor/src/lib/hooks/useDocumentEvents.ts create mode 100644 packages/editor/src/lib/hooks/useEditor.tsx create mode 100644 packages/editor/src/lib/hooks/useEditorComponents.tsx create mode 100644 packages/editor/src/lib/hooks/useEvent.tsx create mode 100644 packages/editor/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts create mode 100644 packages/editor/src/lib/hooks/useForceUpdate.ts create mode 100644 packages/editor/src/lib/hooks/useGestureEvents.ts create mode 100644 packages/editor/src/lib/hooks/useGlobalMenuIsOpen.ts create mode 100644 packages/editor/src/lib/hooks/useIdentity.tsx create mode 100644 packages/editor/src/lib/hooks/useIsCropping.ts create mode 100644 packages/editor/src/lib/hooks/useIsEditing.ts create mode 100644 packages/editor/src/lib/hooks/useLocalStore.ts create mode 100644 packages/editor/src/lib/hooks/usePassThroughWheelEvents.ts create mode 100644 packages/editor/src/lib/hooks/usePeerIds.ts create mode 100644 packages/editor/src/lib/hooks/usePresence.ts create mode 100644 packages/editor/src/lib/hooks/useRefState.ts create mode 100644 packages/editor/src/lib/hooks/useSafeId.tsx create mode 100644 packages/editor/src/lib/hooks/useScreenBounds.ts create mode 100644 packages/editor/src/lib/hooks/useShapeCulling.tsx create mode 100644 packages/editor/src/lib/hooks/useStateAttribute.ts create mode 100644 packages/editor/src/lib/hooks/useTLStore.ts create mode 100644 packages/editor/src/lib/hooks/useTransform.ts create mode 100644 packages/editor/src/lib/hooks/useViewportHeight.ts create mode 100644 packages/editor/src/lib/hooks/useZoomCss.ts create mode 100644 packages/editor/src/lib/license/LicenseManager.test.ts create mode 100644 packages/editor/src/lib/license/LicenseManager.ts create mode 100644 packages/editor/src/lib/license/LicenseProvider.test.tsx create mode 100644 packages/editor/src/lib/license/LicenseProvider.tsx create mode 100644 packages/editor/src/lib/license/Watermark.test.tsx create mode 100644 packages/editor/src/lib/license/Watermark.tsx create mode 100644 packages/editor/src/lib/license/useLicenseManagerState.ts create mode 100644 packages/editor/src/lib/options.ts create mode 100644 packages/editor/src/lib/primitives/Box.test.ts create mode 100644 packages/editor/src/lib/primitives/Box.ts create mode 100644 packages/editor/src/lib/primitives/Mat.test.ts create mode 100644 packages/editor/src/lib/primitives/Mat.ts create mode 100644 packages/editor/src/lib/primitives/Vec.test.ts create mode 100644 packages/editor/src/lib/primitives/Vec.ts create mode 100644 packages/editor/src/lib/primitives/easings.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Arc2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Arc2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Circle2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Circle2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/CubicBezier2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/CubicBezier2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/CubicSpline2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/CubicSpline2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Edge2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Edge2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Ellipse2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Ellipse2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Geometry2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Geometry2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Group2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Group2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Point2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Point2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Polygon2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Polygon2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Polyline2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Polyline2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Rectangle2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Rectangle2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Stadium2d.test.ts create mode 100644 packages/editor/src/lib/primitives/geometry/Stadium2d.ts create mode 100644 packages/editor/src/lib/primitives/geometry/geometry-constants.ts create mode 100644 packages/editor/src/lib/primitives/intersect.test.ts create mode 100644 packages/editor/src/lib/primitives/intersect.ts create mode 100644 packages/editor/src/lib/primitives/utils.test.ts create mode 100644 packages/editor/src/lib/primitives/utils.ts create mode 100644 packages/editor/src/lib/test/ContentElementSlot.test.tsx create mode 100644 packages/editor/src/lib/test/EditorPortal.test.tsx create mode 100644 packages/editor/src/lib/test/InFrontOfTheCanvas.test.tsx create mode 100644 packages/editor/src/lib/test/TestEditor.ts create mode 100644 packages/editor/src/lib/test/preserveFocus.test.tsx create mode 100644 packages/editor/src/lib/test/useCanvasEvents.test.tsx create mode 100644 packages/editor/src/lib/test/useDocumentEvents.test.tsx create mode 100644 packages/editor/src/lib/test/usePassThroughWheelEvents.test.tsx create mode 100644 packages/editor/src/lib/test/user.test.ts create mode 100644 packages/editor/src/lib/utils/EditorAtom.ts create mode 100644 packages/editor/src/lib/utils/SharedStylesMap.ts create mode 100644 packages/editor/src/lib/utils/areShapesContentEqual.ts create mode 100644 packages/editor/src/lib/utils/assets.ts create mode 100644 packages/editor/src/lib/utils/browserCanvasMaxSize.ts create mode 100644 packages/editor/src/lib/utils/collaborators.test.ts create mode 100644 packages/editor/src/lib/utils/collaborators.ts create mode 100644 packages/editor/src/lib/utils/debug-flags.ts create mode 100644 packages/editor/src/lib/utils/deepLinks.test.ts create mode 100644 packages/editor/src/lib/utils/deepLinks.ts create mode 100644 packages/editor/src/lib/utils/dom.test.ts create mode 100644 packages/editor/src/lib/utils/dom.ts create mode 100644 packages/editor/src/lib/utils/getHtmlLayerTransform.ts create mode 100644 packages/editor/src/lib/utils/getIncrementedName.ts create mode 100644 packages/editor/src/lib/utils/getPointerInfo.ts create mode 100644 packages/editor/src/lib/utils/getSvgPathFromPoints.ts create mode 100644 packages/editor/src/lib/utils/keyboard.ts create mode 100644 packages/editor/src/lib/utils/licensing.ts create mode 100644 packages/editor/src/lib/utils/normalizeWheel.test.ts create mode 100644 packages/editor/src/lib/utils/normalizeWheel.ts create mode 100644 packages/editor/src/lib/utils/pointer.test.ts create mode 100644 packages/editor/src/lib/utils/pointer.ts create mode 100644 packages/editor/src/lib/utils/reorderShapes.ts create mode 100644 packages/editor/src/lib/utils/reparenting.ts create mode 100644 packages/editor/src/lib/utils/richText.ts create mode 100644 packages/editor/src/lib/utils/rotation.ts create mode 100644 packages/editor/src/lib/utils/runtime.ts create mode 100644 packages/editor/src/lib/utils/sync/LocalIndexedDb.test.ts create mode 100644 packages/editor/src/lib/utils/sync/LocalIndexedDb.ts create mode 100644 packages/editor/src/lib/utils/sync/StoreWithStatus.ts create mode 100644 packages/editor/src/lib/utils/sync/TLLocalSyncClient.test.ts create mode 100644 packages/editor/src/lib/utils/sync/TLLocalSyncClient.ts create mode 100644 packages/editor/src/lib/utils/sync/alerts.ts create mode 100644 packages/editor/src/lib/utils/sync/hardReset.ts create mode 100644 packages/editor/src/lib/utils/uniq.ts create mode 100644 packages/editor/src/lib/watermarks.ts create mode 100644 packages/editor/src/version.ts create mode 100644 packages/editor/tsconfig.json create mode 100644 packages/editor/vitest.config.ts create mode 100644 packages/mentions/LICENSE.md create mode 100644 packages/mentions/README.md create mode 100644 packages/mentions/api-extractor.json create mode 100644 packages/mentions/api-report.api.md create mode 100644 packages/mentions/mentions.css create mode 100644 packages/mentions/package.json create mode 100644 packages/mentions/src/avatar.tsx create mode 100644 packages/mentions/src/comment-author.ts create mode 100644 packages/mentions/src/index.ts create mode 100644 packages/mentions/src/mention-extension.test.ts create mode 100644 packages/mentions/src/mention-extension.ts create mode 100644 packages/mentions/src/mention-list.tsx create mode 100644 packages/mentions/src/mention-suggestion.test.ts create mode 100644 packages/mentions/src/mention-suggestion.tsx create mode 100644 packages/mentions/src/mention.tsx create mode 100644 packages/mentions/tsconfig.json create mode 100644 packages/mentions/vitest.config.ts create mode 100644 packages/mermaid/LICENSE.md create mode 100644 packages/mermaid/README.md create mode 100644 packages/mermaid/api-extractor.json create mode 100644 packages/mermaid/api-report.api.md create mode 100644 packages/mermaid/package.json create mode 100644 packages/mermaid/src/blueprint.ts create mode 100644 packages/mermaid/src/colors.ts create mode 100644 packages/mermaid/src/createMermaidDiagram.test.ts create mode 100644 packages/mermaid/src/createMermaidDiagram.ts create mode 100644 packages/mermaid/src/defaultMermaidNodeRenderSpec.ts create mode 100644 packages/mermaid/src/flowchartDiagram.ts create mode 100644 packages/mermaid/src/index.ts create mode 100644 packages/mermaid/src/mermaidDiagrams.test.ts create mode 100644 packages/mermaid/src/mermaidNodeCreateShape.test.ts create mode 100644 packages/mermaid/src/mermaidNodeCreateShape.ts create mode 100644 packages/mermaid/src/mindmapDiagram.ts create mode 100644 packages/mermaid/src/renderBlueprint.test.ts create mode 100644 packages/mermaid/src/renderBlueprint.ts create mode 100644 packages/mermaid/src/sequenceDiagram.ts create mode 100644 packages/mermaid/src/stateDiagram.ts create mode 100644 packages/mermaid/src/svgParsing.test.ts create mode 100644 packages/mermaid/src/svgParsing.ts create mode 100644 packages/mermaid/src/utils.ts create mode 100644 packages/mermaid/tsconfig.json create mode 100644 packages/mermaid/vitest.config.ts create mode 100644 packages/namespaced-tldraw/LICENSE.md create mode 100644 packages/namespaced-tldraw/README.md create mode 100644 packages/namespaced-tldraw/api-extractor.json create mode 100644 packages/namespaced-tldraw/api-report.api.md create mode 100644 packages/namespaced-tldraw/package.json create mode 100644 packages/namespaced-tldraw/scripts/copy-css-files.mjs create mode 100644 packages/namespaced-tldraw/src/index.test.ts create mode 100644 packages/namespaced-tldraw/src/index.ts create mode 100644 packages/namespaced-tldraw/tsconfig.json create mode 100644 packages/namespaced-tldraw/vitest.config.ts create mode 100644 packages/state-react/DOCS.md create mode 100644 packages/state-react/LICENSE.md create mode 100644 packages/state-react/README.md create mode 100644 packages/state-react/api-extractor.json create mode 100644 packages/state-react/api-report.api.md create mode 100644 packages/state-react/package.json create mode 100644 packages/state-react/src/index.ts create mode 100644 packages/state-react/src/lib/track.test.tsx create mode 100644 packages/state-react/src/lib/track.ts create mode 100644 packages/state-react/src/lib/useAtom.test.tsx create mode 100644 packages/state-react/src/lib/useAtom.ts create mode 100644 packages/state-react/src/lib/useComputed.test.tsx create mode 100644 packages/state-react/src/lib/useComputed.ts create mode 100644 packages/state-react/src/lib/useQuickReactor.test.tsx create mode 100644 packages/state-react/src/lib/useQuickReactor.ts create mode 100644 packages/state-react/src/lib/useReactor.test.tsx create mode 100644 packages/state-react/src/lib/useReactor.ts create mode 100644 packages/state-react/src/lib/useStateTracking.test.tsx create mode 100644 packages/state-react/src/lib/useStateTracking.ts create mode 100644 packages/state-react/src/lib/useValue.test.tsx create mode 100644 packages/state-react/src/lib/useValue.ts create mode 100644 packages/state-react/tsconfig.json create mode 100644 packages/state-react/vitest.config.ts create mode 100644 packages/state/ARCHITECTURE.md create mode 100644 packages/state/DOCS.md create mode 100644 packages/state/LICENSE.md create mode 100644 packages/state/README.md create mode 100644 packages/state/SPEC.md create mode 100644 packages/state/api-extractor.json create mode 100644 packages/state/api-report.api.md create mode 100644 packages/state/docs-ordering.json create mode 100644 packages/state/package.json create mode 100644 packages/state/src/index.ts create mode 100644 packages/state/src/lib/ArraySet.ts create mode 100644 packages/state/src/lib/Atom.ts create mode 100644 packages/state/src/lib/Computed.ts create mode 100644 packages/state/src/lib/EffectScheduler.ts create mode 100644 packages/state/src/lib/HistoryBuffer.ts create mode 100644 packages/state/src/lib/__tests__/ArraySet.test.ts create mode 100644 packages/state/src/lib/__tests__/EffectScheduler.test.ts create mode 100644 packages/state/src/lib/__tests__/HistoryBuffer.test.ts create mode 100644 packages/state/src/lib/__tests__/atom.test.ts create mode 100644 packages/state/src/lib/__tests__/capture.test.ts create mode 100644 packages/state/src/lib/__tests__/computed.test.ts create mode 100644 packages/state/src/lib/__tests__/debug.test.ts create mode 100644 packages/state/src/lib/__tests__/deferAsyncEffects.test.ts create mode 100644 packages/state/src/lib/__tests__/errors.test.ts create mode 100644 packages/state/src/lib/__tests__/fuzz.tlstate.test.ts create mode 100644 packages/state/src/lib/__tests__/guards.test.ts create mode 100644 packages/state/src/lib/__tests__/helpers.test.ts create mode 100644 packages/state/src/lib/__tests__/history.test.ts create mode 100644 packages/state/src/lib/__tests__/localStorageAtom.test.ts create mode 100644 packages/state/src/lib/__tests__/propagation.test.ts create mode 100644 packages/state/src/lib/__tests__/transactions.test.ts create mode 100644 packages/state/src/lib/capture.ts create mode 100644 packages/state/src/lib/constants.ts create mode 100644 packages/state/src/lib/helpers.ts create mode 100644 packages/state/src/lib/isComputed.ts create mode 100644 packages/state/src/lib/isSignal.ts create mode 100644 packages/state/src/lib/localStorageAtom.ts create mode 100644 packages/state/src/lib/transactions.ts create mode 100644 packages/state/src/lib/types.ts create mode 100644 packages/state/src/lib/warnings.ts create mode 100644 packages/state/tsconfig.json create mode 100644 packages/state/vitest.config.ts create mode 100644 packages/store/DOCS.md create mode 100644 packages/store/LICENSE.md create mode 100644 packages/store/README.md create mode 100644 packages/store/SPEC.md create mode 100644 packages/store/api-extractor.json create mode 100644 packages/store/api-report.api.md create mode 100644 packages/store/package.json create mode 100644 packages/store/setupTests.js create mode 100644 packages/store/src/index.ts create mode 100644 packages/store/src/lib/AtomMap.test.ts create mode 100644 packages/store/src/lib/AtomMap.ts create mode 100644 packages/store/src/lib/AtomSet.test.ts create mode 100644 packages/store/src/lib/AtomSet.ts create mode 100644 packages/store/src/lib/BaseRecord.test.ts create mode 100644 packages/store/src/lib/BaseRecord.ts create mode 100644 packages/store/src/lib/ImmutableMap.test.ts create mode 100644 packages/store/src/lib/ImmutableMap.ts create mode 100644 packages/store/src/lib/IncrementalSetConstructor.test.ts create mode 100644 packages/store/src/lib/IncrementalSetConstructor.ts create mode 100644 packages/store/src/lib/RecordType.test.ts create mode 100644 packages/store/src/lib/RecordType.ts create mode 100644 packages/store/src/lib/RecordsDiff.test.ts create mode 100644 packages/store/src/lib/RecordsDiff.ts create mode 100644 packages/store/src/lib/Store.test.ts create mode 100644 packages/store/src/lib/Store.ts create mode 100644 packages/store/src/lib/StoreListeners.test.ts create mode 100644 packages/store/src/lib/StoreQueries.test.ts create mode 100644 packages/store/src/lib/StoreQueries.ts create mode 100644 packages/store/src/lib/StoreSchema.test.ts create mode 100644 packages/store/src/lib/StoreSchema.ts create mode 100644 packages/store/src/lib/StoreSideEffects.test.ts create mode 100644 packages/store/src/lib/StoreSideEffects.ts create mode 100644 packages/store/src/lib/devFreeze.test.ts create mode 100644 packages/store/src/lib/devFreeze.ts create mode 100644 packages/store/src/lib/executeQuery.test.ts create mode 100644 packages/store/src/lib/executeQuery.ts create mode 100644 packages/store/src/lib/isDev.ts create mode 100644 packages/store/src/lib/migrate.test.ts create mode 100644 packages/store/src/lib/migrate.ts create mode 100644 packages/store/src/lib/setUtils.test.ts create mode 100644 packages/store/src/lib/setUtils.ts create mode 100644 packages/store/src/lib/test/recordStoreFuzzing.test.ts create mode 100644 packages/store/src/lib/test/testSchema.v0.ts create mode 100644 packages/store/src/lib/test/testSchema.v1.ts create mode 100644 packages/store/tsconfig.json create mode 100644 packages/store/vitest.config.ts create mode 100644 packages/sync-collaboration/LICENSE.md create mode 100644 packages/sync-collaboration/README.md create mode 100644 packages/sync-collaboration/api-extractor.json create mode 100644 packages/sync-collaboration/api-report.api.md create mode 100644 packages/sync-collaboration/package.json create mode 100644 packages/sync-collaboration/src/comment-authorizers.test.ts create mode 100644 packages/sync-collaboration/src/comment-authorizers.ts create mode 100644 packages/sync-collaboration/src/index.ts create mode 100644 packages/sync-collaboration/tsconfig.json create mode 100644 packages/sync-collaboration/vitest.config.ts create mode 100644 packages/sync-core/DOCS.md create mode 100644 packages/sync-core/LICENSE.md create mode 100644 packages/sync-core/README.md create mode 100644 packages/sync-core/SPEC.md create mode 100644 packages/sync-core/api-extractor.json create mode 100644 packages/sync-core/api-report.api.md create mode 100644 packages/sync-core/package.json create mode 100644 packages/sync-core/setupVitest.js create mode 100644 packages/sync-core/src/index.ts create mode 100644 packages/sync-core/src/lib/ClientWebSocketAdapter.test.ts create mode 100644 packages/sync-core/src/lib/ClientWebSocketAdapter.ts create mode 100644 packages/sync-core/src/lib/DurableObjectSqliteSyncWrapper.test.ts create mode 100644 packages/sync-core/src/lib/DurableObjectSqliteSyncWrapper.ts create mode 100644 packages/sync-core/src/lib/InMemorySyncStorage.test.ts create mode 100644 packages/sync-core/src/lib/InMemorySyncStorage.ts create mode 100644 packages/sync-core/src/lib/MicrotaskNotifier.test.ts create mode 100644 packages/sync-core/src/lib/MicrotaskNotifier.ts create mode 100644 packages/sync-core/src/lib/NodeSqliteWrapper.test.ts create mode 100644 packages/sync-core/src/lib/NodeSqliteWrapper.ts create mode 100644 packages/sync-core/src/lib/RoomSession.ts create mode 100644 packages/sync-core/src/lib/SQLiteSyncStorage.test.ts create mode 100644 packages/sync-core/src/lib/SQLiteSyncStorage.ts create mode 100644 packages/sync-core/src/lib/ServerSocketAdapter.test.ts create mode 100644 packages/sync-core/src/lib/ServerSocketAdapter.ts create mode 100644 packages/sync-core/src/lib/TLRemoteSyncError.ts create mode 100644 packages/sync-core/src/lib/TLSocketRoom.ts create mode 100644 packages/sync-core/src/lib/TLSyncClient.test.ts create mode 100644 packages/sync-core/src/lib/TLSyncClient.ts create mode 100644 packages/sync-core/src/lib/TLSyncRoom.ts create mode 100644 packages/sync-core/src/lib/TLSyncStorage.test.ts create mode 100644 packages/sync-core/src/lib/TLSyncStorage.ts create mode 100644 packages/sync-core/src/lib/chunk.test.ts create mode 100644 packages/sync-core/src/lib/chunk.ts create mode 100644 packages/sync-core/src/lib/diff.test.ts create mode 100644 packages/sync-core/src/lib/diff.ts create mode 100644 packages/sync-core/src/lib/interval.test.ts create mode 100644 packages/sync-core/src/lib/interval.ts create mode 100644 packages/sync-core/src/lib/protocol.test.ts create mode 100644 packages/sync-core/src/lib/protocol.ts create mode 100644 packages/sync-core/src/lib/recordDiff.test.ts create mode 100644 packages/sync-core/src/lib/recordDiff.ts create mode 100644 packages/sync-core/src/lib/server-types.ts create mode 100644 packages/sync-core/src/test/FuzzEditor.ts create mode 100644 packages/sync-core/src/test/RandomSource.ts create mode 100644 packages/sync-core/src/test/TLSocketRoom.test.ts create mode 100644 packages/sync-core/src/test/TLSyncClientRebase.test.ts create mode 100644 packages/sync-core/src/test/TLSyncRoom.test.ts create mode 100644 packages/sync-core/src/test/TestServer.ts create mode 100644 packages/sync-core/src/test/TestSocketPair.ts create mode 100644 packages/sync-core/src/test/objectStore.test.ts create mode 100644 packages/sync-core/src/test/storageContractSuite.ts create mode 100644 packages/sync-core/src/test/syncFuzz.test.ts create mode 100644 packages/sync-core/src/test/upgradeDowngrade.test.ts create mode 100644 packages/sync-core/tsconfig.json create mode 100644 packages/sync-core/vitest.config.ts create mode 100644 packages/sync/DOCS.md create mode 100644 packages/sync/LICENSE.md create mode 100644 packages/sync/README.md create mode 100644 packages/sync/api-extractor.json create mode 100644 packages/sync/api-report.api.md create mode 100644 packages/sync/package.json create mode 100644 packages/sync/setupVitest.js create mode 100644 packages/sync/src/index.test.ts create mode 100644 packages/sync/src/index.ts create mode 100644 packages/sync/src/useSync.test.tsx create mode 100644 packages/sync/src/useSync.ts create mode 100644 packages/sync/src/useSyncDemo.test.ts create mode 100644 packages/sync/src/useSyncDemo.ts create mode 100644 packages/sync/tsconfig.json create mode 100644 packages/sync/vitest.config.ts create mode 100644 packages/tldraw/LICENSE.md create mode 100644 packages/tldraw/README.md create mode 100644 packages/tldraw/api-extractor.json create mode 100644 packages/tldraw/package.json create mode 100644 packages/tldraw/scripts/copy-css-files.mjs create mode 100644 packages/tldraw/setupVitest.js create mode 100644 packages/tldraw/src/index.ts create mode 100644 packages/tldraw/src/lib/Tldraw.test.tsx create mode 100644 packages/tldraw/src/lib/Tldraw.tsx create mode 100644 packages/tldraw/src/lib/TldrawImage.tsx create mode 100644 packages/tldraw/src/lib/assets/BookmarkAssetUtil.ts create mode 100644 packages/tldraw/src/lib/assets/ImageAssetUtil.test.ts create mode 100644 packages/tldraw/src/lib/assets/ImageAssetUtil.ts create mode 100644 packages/tldraw/src/lib/assets/VideoAssetUtil.ts create mode 100644 packages/tldraw/src/lib/bindings/arrow/ArrowBindingUtil.ts create mode 100644 packages/tldraw/src/lib/defaultAssetUtils.ts create mode 100644 packages/tldraw/src/lib/defaultBindingUtils.ts create mode 100644 packages/tldraw/src/lib/defaultEmbedDefinitions.ts create mode 100644 packages/tldraw/src/lib/defaultExternalContentHandlers.test.ts create mode 100644 packages/tldraw/src/lib/defaultExternalContentHandlers.ts create mode 100644 packages/tldraw/src/lib/defaultOverlayUtils.ts create mode 100644 packages/tldraw/src/lib/defaultShapeTools.ts create mode 100644 packages/tldraw/src/lib/defaultShapeUtils.ts create mode 100644 packages/tldraw/src/lib/defaultSideEffects.ts create mode 100644 packages/tldraw/src/lib/defaultTools.ts create mode 100644 packages/tldraw/src/lib/overlays/ArrowBindingHintOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/ArrowHintOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/BrushOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/CollaboratorBrushOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/CollaboratorCursorOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/CollaboratorHintOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/CollaboratorScribbleOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/CollaboratorShapeIndicatorOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/ScribbleOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/SelectionForegroundOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/ShapeHandleOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/ShapeIndicatorOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/SnapIndicatorOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/overlays/ZoomBrushOverlayUtil.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowPath.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowShapeOptions.test.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.test.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/ArrowShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/arrow-types.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/arrowLabel.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/arrowTargetState.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/arrowheads.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/curved-arrow.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/definitions.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/getElbowArrowInfo.test.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/getElbowArrowInfo.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/range.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/routes/ElbowArrowRouteBuilder.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/routes/ElbowArrowWorkingInfo.test.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/routes/ElbowArrowWorkingInfo.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/routes/elbowArrowRoutes.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/elbow/routes/routeArrowWithAutoEdgePicking.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/getArrowInfo.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/shared.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/straight-arrow.ts create mode 100644 packages/tldraw/src/lib/shapes/arrow/toolStates/Idle.tsx create mode 100644 packages/tldraw/src/lib/shapes/arrow/toolStates/Pointing.tsx create mode 100644 packages/tldraw/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/bookmark/bookmarks.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/DrawShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/DrawShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/DrawShapeUtil.test.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/DrawShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/draw/getPath.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/toolStates/Drawing.ts create mode 100644 packages/tldraw/src/lib/shapes/draw/toolStates/Idle.ts create mode 100644 packages/tldraw/src/lib/shapes/embed/EmbedShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/frame/FrameShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/frame/FrameShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/frame/FrameShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/frame/components/FrameHeading.tsx create mode 100644 packages/tldraw/src/lib/shapes/frame/components/FrameLabelInput.tsx create mode 100644 packages/tldraw/src/lib/shapes/frame/frameHelpers.ts create mode 100644 packages/tldraw/src/lib/shapes/geo/GeoShapeBody.tsx create mode 100644 packages/tldraw/src/lib/shapes/geo/GeoShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/geo/GeoShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/geo/GeoShapeUtil.test.tsx create mode 100644 packages/tldraw/src/lib/shapes/geo/GeoShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/geo/getGeoShapePath.ts create mode 100644 packages/tldraw/src/lib/shapes/geo/toolStates/Idle.ts create mode 100644 packages/tldraw/src/lib/shapes/geo/toolStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/shapes/highlight/HighlightShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/highlight/HighlightShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/highlight/HighlightShapeUtil.test.ts create mode 100644 packages/tldraw/src/lib/shapes/highlight/HighlightShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/image/ImageAlphaCache.ts create mode 100644 packages/tldraw/src/lib/shapes/image/ImageAlphaGeometry.ts create mode 100644 packages/tldraw/src/lib/shapes/image/ImageShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/line/LineShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/line/LineShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/line/LineShapeUtil.test.tsx create mode 100644 packages/tldraw/src/lib/shapes/line/LineShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap create mode 100644 packages/tldraw/src/lib/shapes/line/toolStates/Idle.ts create mode 100644 packages/tldraw/src/lib/shapes/line/toolStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/shapes/note/DefaultNoteShapeAttribution.tsx create mode 100644 packages/tldraw/src/lib/shapes/note/NoteShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/note/NoteShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/note/NoteShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/note/noteCloning.test.ts create mode 100644 packages/tldraw/src/lib/shapes/note/noteHelpers.ts create mode 100644 packages/tldraw/src/lib/shapes/note/toolStates/Idle.ts create mode 100644 packages/tldraw/src/lib/shapes/note/toolStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/BrokenAssetIcon.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/HyperlinkButton.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/PathBuilder.test.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/PathBuilder.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/PatternFill.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/PlainTextLabel.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/RichTextLabel.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/TextHelpers.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/createTextJsxFromSpans.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/crop.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/default-shape-constants.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/defaultFills.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/defaultFonts.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/defaultStyleDefs.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/flip.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/core.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/fmt.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/getStroke.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/getStrokePoints.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/svg.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/svgInk.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/freehand/types.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/getDisplayValues.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/icons-editor.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/interpolate-props.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/legacyProps.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/rotated-box-shadow.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/useEditablePlainText.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/useEditableRichText.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/useEfficientZoomThreshold.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/useImageOrVideoAsset.test.tsx create mode 100644 packages/tldraw/src/lib/shapes/shared/useImageOrVideoAsset.ts create mode 100644 packages/tldraw/src/lib/shapes/shared/usePrefersReducedMotion.tsx create mode 100644 packages/tldraw/src/lib/shapes/text/PlainTextArea.tsx create mode 100644 packages/tldraw/src/lib/shapes/text/RichTextArea.tsx create mode 100644 packages/tldraw/src/lib/shapes/text/TextShapeTool.test.ts create mode 100644 packages/tldraw/src/lib/shapes/text/TextShapeTool.ts create mode 100644 packages/tldraw/src/lib/shapes/text/TextShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/shapes/text/toolStates/Idle.ts create mode 100644 packages/tldraw/src/lib/shapes/text/toolStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/shapes/video/VideoShapeUtil.tsx create mode 100644 packages/tldraw/src/lib/styles.tsx create mode 100644 packages/tldraw/src/lib/tools/EraserTool/EraserTool.ts create mode 100644 packages/tldraw/src/lib/tools/EraserTool/childStates/Erasing.ts create mode 100644 packages/tldraw/src/lib/tools/EraserTool/childStates/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/EraserTool/childStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/tools/HandTool/HandTool.ts create mode 100644 packages/tldraw/src/lib/tools/HandTool/childStates/Dragging.ts create mode 100644 packages/tldraw/src/lib/tools/HandTool/childStates/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/HandTool/childStates/OneFingerZooming.ts create mode 100644 packages/tldraw/src/lib/tools/HandTool/childStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/tools/LaserTool/LaserTool.ts create mode 100644 packages/tldraw/src/lib/tools/LaserTool/childStates/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/LaserTool/childStates/Lasering.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/DragAndDropManager.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/GestureShapeChangeTracker.test.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/GestureShapeChangeTracker.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/SelectTool.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Brushing.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/Crop.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/EditingShape.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingCanvas.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingHandle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingSelection.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/PointingShape.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Resizing.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Rotating.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/childStates/Translating.ts create mode 100644 packages/tldraw/src/lib/tools/SelectTool/selectHelpers.ts create mode 100644 packages/tldraw/src/lib/tools/ZoomTool/ZoomTool.ts create mode 100644 packages/tldraw/src/lib/tools/ZoomTool/childStates/Idle.ts create mode 100644 packages/tldraw/src/lib/tools/ZoomTool/childStates/Pointing.ts create mode 100644 packages/tldraw/src/lib/tools/ZoomTool/childStates/ZoomBrushing.ts create mode 100644 packages/tldraw/src/lib/tools/ZoomTool/childStates/ZoomQuick.ts create mode 100644 packages/tldraw/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts create mode 100644 packages/tldraw/src/lib/tools/selection-logic/selectOnCanvasPointerUp.ts create mode 100644 packages/tldraw/src/lib/tools/selection-logic/selection.tldr create mode 100644 packages/tldraw/src/lib/tools/selection-logic/updateHoveredOverlayId.ts create mode 100644 packages/tldraw/src/lib/tools/selection-logic/updateHoveredShapeId.ts create mode 100644 packages/tldraw/src/lib/ui.css create mode 100644 packages/tldraw/src/lib/ui/TldrawUi.tsx create mode 100644 packages/tldraw/src/lib/ui/assetUrls.ts create mode 100644 packages/tldraw/src/lib/ui/components/A11y.tsx create mode 100644 packages/tldraw/src/lib/ui/components/AccessibilityMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ColorSchemeMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/CursorChatBubble.tsx create mode 100644 packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/DefaultDebugPanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/DefaultFollowingIndicator.tsx create mode 100644 packages/tldraw/src/lib/ui/components/DefaultMenuPanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Dialogs.tsx create mode 100644 packages/tldraw/src/lib/ui/components/EditLinkDialog.tsx create mode 100644 packages/tldraw/src/lib/ui/components/EmbedDialog.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelpMenu/DefaultHelpMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelpMenu/DefaultHelpMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelperButtons/BackToContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelperButtons/DefaultHelperButtons.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelperButtons/DefaultHelperButtonsContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelperButtons/ExitPenMode.tsx create mode 100644 packages/tldraw/src/lib/ui/components/HelperButtons/StopFollowing.tsx create mode 100644 packages/tldraw/src/lib/ui/components/InputModeMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog.tsx create mode 100644 packages/tldraw/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/LanguageMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/LoadingScreen.tsx create mode 100644 packages/tldraw/src/lib/ui/components/MainMenu/DefaultMainMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Minimap/DefaultMinimap.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Minimap/MinimapManager.ts create mode 100644 packages/tldraw/src/lib/ui/components/MobileStylePanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx create mode 100644 packages/tldraw/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/PageMenu/PageItemInput.tsx create mode 100644 packages/tldraw/src/lib/ui/components/PageMenu/PageItemSubmenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/PageMenu/edit-pages-shared.ts create mode 100644 packages/tldraw/src/lib/ui/components/QuickActions/DefaultQuickActions.tsx create mode 100644 packages/tldraw/src/lib/ui/components/QuickActions/DefaultQuickActionsContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultPeopleMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultSharePanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/DefaultUserPresenceEditor.tsx create mode 100644 packages/tldraw/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Spinner.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/StylePanelContext.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx create mode 100644 packages/tldraw/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toasts.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/AltTextEditor.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultRichTextToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultRichTextToolbarContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultToolbarContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultVideoToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/LinkEditor.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx create mode 100644 packages/tldraw/src/lib/ui/components/TopPanel/CenteredTopPanelContainer.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ZoomMenu/DefaultZoomMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/ZoomMenu/DefaultZoomMenuContent.tsx create mode 100644 packages/tldraw/src/lib/ui/components/menu-items.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/Button/TldrawUiButton.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/Button/TldrawUiButtonCheck.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/Button/TldrawUiButtonIcon.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/Button/TldrawUiButtonLabel.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/Button/TldrawUiButtonSpinner.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiDialog.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiIcon.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiInput.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiKbd.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiPopover.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiSelect.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiSlider.test.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiSlider.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiToolbar.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/TldrawUiTooltip.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/layout.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx create mode 100644 packages/tldraw/src/lib/ui/components/primitives/menus/TldrawUiMenuToolItem.tsx create mode 100644 packages/tldraw/src/lib/ui/constants.ts create mode 100644 packages/tldraw/src/lib/ui/context/TldrawUiContextProvider.tsx create mode 100644 packages/tldraw/src/lib/ui/context/a11y.tsx create mode 100644 packages/tldraw/src/lib/ui/context/actions.tsx create mode 100644 packages/tldraw/src/lib/ui/context/asset-urls.tsx create mode 100644 packages/tldraw/src/lib/ui/context/breakpoints.tsx create mode 100644 packages/tldraw/src/lib/ui/context/components.tsx create mode 100644 packages/tldraw/src/lib/ui/context/dialogs.tsx create mode 100644 packages/tldraw/src/lib/ui/context/events.tsx create mode 100644 packages/tldraw/src/lib/ui/context/toasts.tsx create mode 100644 packages/tldraw/src/lib/ui/getLocalFiles.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/clipboard/pasteFiles.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/clipboard/pasteUrl.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/clipboard/putPastedContent.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/menu-hooks.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useClipboardEvents.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useCollaborationStatus.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useCommentingEnabled.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useCopyAs.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useEditorEvents.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useExportAs.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useFlatten.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useGetEmbedDefinition.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useGetEmbedDefinitions.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useKeyboardShortcuts.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useLocalStorageState.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useMenuIsOpen.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/usePrint.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useReadonly.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useRelevantStyles.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useTools.tsx create mode 100644 packages/tldraw/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useTranslation/defaultTranslation.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useTranslation/translations.ts create mode 100644 packages/tldraw/src/lib/ui/hooks/useTranslation/useTranslation.test.tsx create mode 100644 packages/tldraw/src/lib/ui/hooks/useTranslation/useTranslation.tsx create mode 100644 packages/tldraw/src/lib/ui/icon-types.ts create mode 100644 packages/tldraw/src/lib/ui/kbd-utils.test.ts create mode 100644 packages/tldraw/src/lib/ui/kbd-utils.ts create mode 100644 packages/tldraw/src/lib/ui/overrides.ts create mode 100644 packages/tldraw/src/lib/ui/version.ts create mode 100644 packages/tldraw/src/lib/utils/assets/assets.ts create mode 100644 packages/tldraw/src/lib/utils/assets/preload-font.ts create mode 100644 packages/tldraw/src/lib/utils/clipboard.ts create mode 100644 packages/tldraw/src/lib/utils/embeds/embeds.test.ts create mode 100644 packages/tldraw/src/lib/utils/embeds/embeds.ts create mode 100644 packages/tldraw/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap create mode 100644 packages/tldraw/src/lib/utils/excalidraw/excalidraw-test-fixtures/bound-arrows.json create mode 100644 packages/tldraw/src/lib/utils/excalidraw/excalidraw-test-fixtures/bound-elbow-arrows.json create mode 100644 packages/tldraw/src/lib/utils/excalidraw/excalidraw-test-fixtures/image.json create mode 100644 packages/tldraw/src/lib/utils/excalidraw/excalidraw-test-fixtures/line-drawing.json create mode 100644 packages/tldraw/src/lib/utils/excalidraw/putExcalidrawContent.test.tsx create mode 100644 packages/tldraw/src/lib/utils/excalidraw/putExcalidrawContent.ts create mode 100644 packages/tldraw/src/lib/utils/export/copyAs.ts create mode 100644 packages/tldraw/src/lib/utils/export/export.ts create mode 100644 packages/tldraw/src/lib/utils/export/exportAs.ts create mode 100644 packages/tldraw/src/lib/utils/frames/frames.ts create mode 100644 packages/tldraw/src/lib/utils/shapes/shapes.ts create mode 100644 packages/tldraw/src/lib/utils/static-assets/assetUrls.ts create mode 100644 packages/tldraw/src/lib/utils/svg/sanitizeSvg.test.ts create mode 100644 packages/tldraw/src/lib/utils/svg/sanitizeSvg.ts create mode 100644 packages/tldraw/src/lib/utils/test-helpers.ts create mode 100644 packages/tldraw/src/lib/utils/text/literalTyping.ts create mode 100644 packages/tldraw/src/lib/utils/text/richText.test.ts create mode 100644 packages/tldraw/src/lib/utils/text/richText.ts create mode 100644 packages/tldraw/src/lib/utils/text/text.test.ts create mode 100644 packages/tldraw/src/lib/utils/text/text.ts create mode 100644 packages/tldraw/src/lib/utils/text/tiptap.test.ts create mode 100644 packages/tldraw/src/lib/utils/text/tiptap.ts create mode 100644 packages/tldraw/src/lib/utils/text/wrapSelection.test.ts create mode 100644 packages/tldraw/src/lib/utils/text/wrapSelection.ts create mode 100644 packages/tldraw/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap create mode 100644 packages/tldraw/src/lib/utils/tldr/buildFromV1Document.test.ts create mode 100644 packages/tldraw/src/lib/utils/tldr/buildFromV1Document.ts create mode 100644 packages/tldraw/src/lib/utils/tldr/file.ts create mode 100644 packages/tldraw/src/lib/utils/tldr/test-fixtures/arrow-binding.tldr create mode 100644 packages/tldraw/src/lib/utils/tldr/test-fixtures/exact-arrow-binding.tldr create mode 100644 packages/tldraw/src/lib/utils/tldr/test-fixtures/incorrect-arrow-binding.tldr create mode 100644 packages/tldraw/src/test/A11y.test.tsx create mode 100644 packages/tldraw/src/test/ClickManager.test.ts create mode 100644 packages/tldraw/src/test/Editor.test.tsx create mode 100644 packages/tldraw/src/test/EraserTool.test.ts create mode 100644 packages/tldraw/src/test/HandTool.test.ts create mode 100644 packages/tldraw/src/test/HighlightShape.test.ts create mode 100644 packages/tldraw/src/test/ImageShapeUtil.test.ts create mode 100644 packages/tldraw/src/test/LaserTool.test.ts create mode 100644 packages/tldraw/src/test/ScribbleManager.test.ts create mode 100644 packages/tldraw/src/test/SelectTool.test.ts create mode 100644 packages/tldraw/src/test/TLSessionStateSnapshot.test.ts create mode 100644 packages/tldraw/src/test/TLUserPreferences.test.ts create mode 100644 packages/tldraw/src/test/TestEditor.test.ts create mode 100644 packages/tldraw/src/test/TestEditor.ts create mode 100644 packages/tldraw/src/test/TldrawEditor.test.tsx create mode 100644 packages/tldraw/src/test/VideoShapeUtil.test.tsx create mode 100644 packages/tldraw/src/test/ZoomTool.test.ts create mode 100644 packages/tldraw/src/test/__snapshots__/drawing.test.ts.snap create mode 100644 packages/tldraw/src/test/__snapshots__/groups.test.tsx.snap create mode 100644 packages/tldraw/src/test/__snapshots__/resizing.test.ts.snap create mode 100644 packages/tldraw/src/test/actions-menu-readonly.test.tsx create mode 100644 packages/tldraw/src/test/arrows-megabus.test.tsx create mode 100644 packages/tldraw/src/test/assets.test.ts create mode 100644 packages/tldraw/src/test/attribution.test.ts create mode 100644 packages/tldraw/src/test/bindings.test.tsx create mode 100644 packages/tldraw/src/test/bindingsIndex.test.tsx create mode 100644 packages/tldraw/src/test/bookmark-shapes.test.ts create mode 100644 packages/tldraw/src/test/cleanup.test.ts create mode 100644 packages/tldraw/src/test/commaKeyClick.test.ts create mode 100644 packages/tldraw/src/test/commands/__snapshots__/getSvgString.test.ts.snap create mode 100644 packages/tldraw/src/test/commands/__snapshots__/packShapes.test.ts.snap create mode 100644 packages/tldraw/src/test/commands/__snapshots__/zoomToFit.test.ts.snap create mode 100644 packages/tldraw/src/test/commands/alignShapes.test.tsx create mode 100644 packages/tldraw/src/test/commands/allShapesCommonBounds.test.ts create mode 100644 packages/tldraw/src/test/commands/animateShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/animateToShape.test.ts create mode 100644 packages/tldraw/src/test/commands/animationSpeed.test.ts create mode 100644 packages/tldraw/src/test/commands/blur.test.ts create mode 100644 packages/tldraw/src/test/commands/cameraState.test.ts create mode 100644 packages/tldraw/src/test/commands/cancel.test.ts create mode 100644 packages/tldraw/src/test/commands/centerOnPoint.test.ts create mode 100644 packages/tldraw/src/test/commands/clipboard.test.ts create mode 100644 packages/tldraw/src/test/commands/clipboardCallbacks.test.ts create mode 100644 packages/tldraw/src/test/commands/clipboardPaste.test.ts create mode 100644 packages/tldraw/src/test/commands/complete.test.ts create mode 100644 packages/tldraw/src/test/commands/createPage.test.ts create mode 100644 packages/tldraw/src/test/commands/createShape.test.ts create mode 100644 packages/tldraw/src/test/commands/createShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/deletePage.test.ts create mode 100644 packages/tldraw/src/test/commands/deleteShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/distributeShapes.test.tsx create mode 100644 packages/tldraw/src/test/commands/duplicatePage.test.ts create mode 100644 packages/tldraw/src/test/commands/getBaseZoom.test.ts create mode 100644 packages/tldraw/src/test/commands/getContent.test.ts create mode 100644 packages/tldraw/src/test/commands/getInitialMetaForShape.test.ts create mode 100644 packages/tldraw/src/test/commands/getInitialZoom.test.ts create mode 100644 packages/tldraw/src/test/commands/getSvgString.test.ts create mode 100644 packages/tldraw/src/test/commands/groupShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/guide.md create mode 100644 packages/tldraw/src/test/commands/interrupt.test.ts create mode 100644 packages/tldraw/src/test/commands/isShapeOfType.test.ts create mode 100644 packages/tldraw/src/test/commands/lockShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/moveShapesToPage.test.ts create mode 100644 packages/tldraw/src/test/commands/nudge.test.ts create mode 100644 packages/tldraw/src/test/commands/packShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/pageToScreen.test.ts create mode 100644 packages/tldraw/src/test/commands/pan.test.ts create mode 100644 packages/tldraw/src/test/commands/penmode.test.ts create mode 100644 packages/tldraw/src/test/commands/pinch.test.ts create mode 100644 packages/tldraw/src/test/commands/putContent.test.ts create mode 100644 packages/tldraw/src/test/commands/reorderShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/reparentShapesById.test.ts create mode 100644 packages/tldraw/src/test/commands/resetZoom.test.ts create mode 100644 packages/tldraw/src/test/commands/resizeShape.test.ts create mode 100644 packages/tldraw/src/test/commands/resizeToBounds.test.tsx create mode 100644 packages/tldraw/src/test/commands/rotateShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/screenToPage.test.ts create mode 100644 packages/tldraw/src/test/commands/setBrush.test.ts create mode 100644 packages/tldraw/src/test/commands/setCamera.test.ts create mode 100644 packages/tldraw/src/test/commands/setCurrentPage.test.ts create mode 100644 packages/tldraw/src/test/commands/setPageState.test.ts create mode 100644 packages/tldraw/src/test/commands/setSelectedIds.test.ts create mode 100644 packages/tldraw/src/test/commands/setSelectedTool.test.ts create mode 100644 packages/tldraw/src/test/commands/setSettings.test.ts create mode 100644 packages/tldraw/src/test/commands/setStyle.test.ts create mode 100644 packages/tldraw/src/test/commands/stackShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/stretch.test.tsx create mode 100644 packages/tldraw/src/test/commands/ungroup.test.ts create mode 100644 packages/tldraw/src/test/commands/updateShape.test.ts create mode 100644 packages/tldraw/src/test/commands/updateShapes.test.ts create mode 100644 packages/tldraw/src/test/commands/updateViewportPageBounds.test.ts create mode 100644 packages/tldraw/src/test/commands/zoomIn.test.ts create mode 100644 packages/tldraw/src/test/commands/zoomOut.test.ts create mode 100644 packages/tldraw/src/test/commands/zoomToBounds.test.ts create mode 100644 packages/tldraw/src/test/commands/zoomToFit.test.ts create mode 100644 packages/tldraw/src/test/commands/zoomToSelection.test.ts create mode 100644 packages/tldraw/src/test/createDeepLink.test.tsx create mode 100644 packages/tldraw/src/test/createNShapes.test.ts create mode 100644 packages/tldraw/src/test/crop.test.ts create mode 100644 packages/tldraw/src/test/cropping.test.ts create mode 100644 packages/tldraw/src/test/custom-clipping.test.ts create mode 100644 packages/tldraw/src/test/customSnapping.test.tsx create mode 100644 packages/tldraw/src/test/defaultHandleExternalFileContent.test.ts create mode 100644 packages/tldraw/src/test/displayValues.test.ts create mode 100644 packages/tldraw/src/test/dragAndDrop.test.ts create mode 100644 packages/tldraw/src/test/dragDuringCameraAnimation.test.ts create mode 100644 packages/tldraw/src/test/dragFromToolbar-dom.test.tsx create mode 100644 packages/tldraw/src/test/dragFromToolbar.test.ts create mode 100644 packages/tldraw/src/test/drawing-shift-keyup.test.ts create mode 100644 packages/tldraw/src/test/drawing.data.ts create mode 100644 packages/tldraw/src/test/drawing.test.ts create mode 100644 packages/tldraw/src/test/duplicate.test.ts create mode 100644 packages/tldraw/src/test/embed-aspect-ratio.test.ts create mode 100644 packages/tldraw/src/test/embed-iframe-paste.test.ts create mode 100644 packages/tldraw/src/test/flatten.test.ts create mode 100644 packages/tldraw/src/test/flipShapes.test.ts create mode 100644 packages/tldraw/src/test/frames.test.ts create mode 100644 packages/tldraw/src/test/freehand/corpus/presets.ts create mode 100644 packages/tldraw/src/test/freehand/corpus/real.ts create mode 100644 packages/tldraw/src/test/freehand/corpus/strokes.ts create mode 100644 packages/tldraw/src/test/freehand/svg.test.ts create mode 100644 packages/tldraw/src/test/freehand/wellformed.test.ts create mode 100644 packages/tldraw/src/test/getCulledShapes.test.tsx create mode 100644 packages/tldraw/src/test/getShapeAtPoint.test.ts create mode 100644 packages/tldraw/src/test/getSnapLines.ts create mode 100644 packages/tldraw/src/test/grid-align-on-create.test.ts create mode 100644 packages/tldraw/src/test/groups.test.tsx create mode 100644 packages/tldraw/src/test/handleDeepLink.test.tsx create mode 100644 packages/tldraw/src/test/inner-outer-margin.test.ts create mode 100644 packages/tldraw/src/test/long-press-create.test.ts create mode 100644 packages/tldraw/src/test/maxShapes.test.ts create mode 100644 packages/tldraw/src/test/middleMouseButtonPanning.test.ts create mode 100644 packages/tldraw/src/test/minimap-wheel.test.tsx create mode 100644 packages/tldraw/src/test/modifiers.test.ts create mode 100644 packages/tldraw/src/test/navigation.test.ts create mode 100644 packages/tldraw/src/test/notVisibleShapes.test.ts create mode 100644 packages/tldraw/src/test/noteAttributionComponent.test.tsx create mode 100644 packages/tldraw/src/test/noteAttributionExport.test.tsx create mode 100644 packages/tldraw/src/test/onDragFromToolbarToCreateShape.test.ts create mode 100644 packages/tldraw/src/test/overlays/ArrowHintOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/BrushOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/BrushOverlayUtilDisplayValues.test.ts create mode 100644 packages/tldraw/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/CollaboratorHintOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/OverlayManager.test.ts create mode 100644 packages/tldraw/src/test/overlays/ScribbleOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/SelectionForegroundOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/ShapeHandleOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/SnapIndicatorOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/overlays/ZoomBrushOverlayUtil.test.ts create mode 100644 packages/tldraw/src/test/panning.test.ts create mode 100644 packages/tldraw/src/test/parentsToChildrenWithIndexes.test.ts create mode 100644 packages/tldraw/src/test/paste.test.ts create mode 100644 packages/tldraw/src/test/perf/PerformanceMeasurer.ts create mode 100644 packages/tldraw/src/test/perf/perf.test.ts create mode 100644 packages/tldraw/src/test/pinch-dom.test.tsx create mode 100644 packages/tldraw/src/test/pinch.test.ts create mode 100644 packages/tldraw/src/test/pointercancel-dom.test.tsx create mode 100644 packages/tldraw/src/test/registerDeepLinkListener.test.tsx create mode 100644 packages/tldraw/src/test/renderingShapes.test.tsx create mode 100644 packages/tldraw/src/test/resizeBox.test.ts create mode 100644 packages/tldraw/src/test/resolveAssetsInContent.test.ts create mode 100644 packages/tldraw/src/test/right-click-context-menu.test.ts create mode 100644 packages/tldraw/src/test/rightClickPanning.test.ts create mode 100644 packages/tldraw/src/test/rotating.test.ts create mode 100644 packages/tldraw/src/test/roundedBox.ts create mode 100644 packages/tldraw/src/test/select.test.tsx create mode 100644 packages/tldraw/src/test/selection-omnibus.test.ts create mode 100644 packages/tldraw/src/test/shapeIdsInCurrentPage.test.ts create mode 100644 packages/tldraw/src/test/shapeutils.test.ts create mode 100644 packages/tldraw/src/test/spacebarPanning.test.ts create mode 100644 packages/tldraw/src/test/spatialIndex.test.ts create mode 100644 packages/tldraw/src/test/strange-tools.test.ts create mode 100644 packages/tldraw/src/test/styles2.test.tsx create mode 100644 packages/tldraw/src/test/styles3.test.ts create mode 100644 packages/tldraw/src/test/test-jsx.tsx create mode 100644 packages/tldraw/src/test/testutils/pretty.ts create mode 100644 packages/tldraw/src/test/testutils/renderTldrawComponent.tsx create mode 100644 packages/tldraw/src/test/text.test.ts create mode 100644 packages/tldraw/src/test/toolbar-tool-selection.test.tsx create mode 100644 packages/tldraw/src/test/translating.test.ts create mode 100644 packages/tldraw/src/test/transparent-image-hit-test.test.ts create mode 100644 packages/tldraw/src/test/ui-outside-editor.test.tsx create mode 100644 packages/tldraw/src/test/ui/AltTextEditor.test.tsx create mode 100644 packages/tldraw/src/test/ui/BackToContent.test.tsx create mode 100644 packages/tldraw/src/test/ui/ContextMenu.test.tsx create mode 100644 packages/tldraw/src/test/ui/Dialogs.test.tsx create mode 100644 packages/tldraw/src/test/ui/EditLinkDialog.test.tsx create mode 100644 packages/tldraw/src/test/ui/EditorPortal.test.tsx create mode 100644 packages/tldraw/src/test/ui/FrameSelectionMenuItem.test.tsx create mode 100644 packages/tldraw/src/test/ui/ImageToolbar.test.tsx create mode 100644 packages/tldraw/src/test/ui/StylePanel.test.tsx create mode 100644 packages/tldraw/src/test/ui/changePage.test.tsx create mode 100644 packages/tldraw/src/test/ui/copyHoveredStyles.test.tsx create mode 100644 packages/tldraw/src/test/ui/keyboardShortcuts.test.tsx create mode 100644 packages/tldraw/src/test/ui/presenceActivity.test.tsx create mode 100644 packages/tldraw/src/test/ui/unlockAll.test.tsx create mode 100644 packages/tldraw/src/test/viewport-following.test.ts create mode 100644 packages/tldraw/src/test/zoomToUser.test.ts create mode 100644 packages/tldraw/tsconfig.json create mode 100644 packages/tldraw/vitest.config.ts create mode 100644 packages/tlschema/DOCS.md create mode 100644 packages/tlschema/LICENSE.md create mode 100644 packages/tlschema/README.md create mode 100644 packages/tlschema/api-extractor.json create mode 100644 packages/tlschema/api-report.api.md create mode 100644 packages/tlschema/package.json create mode 100644 packages/tlschema/src/TLStore.test.ts create mode 100644 packages/tlschema/src/TLStore.ts create mode 100644 packages/tlschema/src/__tests__/migrationTestUtils.ts create mode 100644 packages/tlschema/src/assets/TLBaseAsset.ts create mode 100644 packages/tlschema/src/assets/TLBookmarkAsset.ts create mode 100644 packages/tlschema/src/assets/TLImageAsset.ts create mode 100644 packages/tlschema/src/assets/TLVideoAsset.ts create mode 100644 packages/tlschema/src/bindings/TLArrowBinding.ts create mode 100644 packages/tlschema/src/bindings/TLBaseBinding.ts create mode 100644 packages/tlschema/src/createPresenceStateDerivation.test.ts create mode 100644 packages/tlschema/src/createPresenceStateDerivation.ts create mode 100644 packages/tlschema/src/createTLSchema.test.ts create mode 100644 packages/tlschema/src/createTLSchema.ts create mode 100644 packages/tlschema/src/index.ts create mode 100644 packages/tlschema/src/migrations.test.ts create mode 100644 packages/tlschema/src/misc/TLColor.ts create mode 100644 packages/tlschema/src/misc/TLCursor.ts create mode 100644 packages/tlschema/src/misc/TLHandle.ts create mode 100644 packages/tlschema/src/misc/TLOpacity.ts create mode 100644 packages/tlschema/src/misc/TLRichText.test.ts create mode 100644 packages/tlschema/src/misc/TLRichText.ts create mode 100644 packages/tlschema/src/misc/TLScribble.ts create mode 100644 packages/tlschema/src/misc/b64Vecs.test.ts create mode 100644 packages/tlschema/src/misc/b64Vecs.ts create mode 100644 packages/tlschema/src/misc/geometry-types.ts create mode 100644 packages/tlschema/src/misc/id-validator.ts create mode 100644 packages/tlschema/src/records/TLAsset.ts create mode 100644 packages/tlschema/src/records/TLBinding.ts create mode 100644 packages/tlschema/src/records/TLCamera.ts create mode 100644 packages/tlschema/src/records/TLComment.test.ts create mode 100644 packages/tlschema/src/records/TLComment.ts create mode 100644 packages/tlschema/src/records/TLCustomRecord.ts create mode 100644 packages/tlschema/src/records/TLDocument.ts create mode 100644 packages/tlschema/src/records/TLInstance.ts create mode 100644 packages/tlschema/src/records/TLPage.ts create mode 100644 packages/tlschema/src/records/TLPageState.ts create mode 100644 packages/tlschema/src/records/TLPointer.ts create mode 100644 packages/tlschema/src/records/TLPresence.ts create mode 100644 packages/tlschema/src/records/TLRecord.ts create mode 100644 packages/tlschema/src/records/TLShape.ts create mode 100644 packages/tlschema/src/records/TLUser.ts create mode 100644 packages/tlschema/src/recordsWithProps.test.ts create mode 100644 packages/tlschema/src/recordsWithProps.ts create mode 100644 packages/tlschema/src/shapes/ShapeWithCrop.ts create mode 100644 packages/tlschema/src/shapes/TLArrowShape.ts create mode 100644 packages/tlschema/src/shapes/TLBaseShape.ts create mode 100644 packages/tlschema/src/shapes/TLBookmarkShape.ts create mode 100644 packages/tlschema/src/shapes/TLDrawShape.ts create mode 100644 packages/tlschema/src/shapes/TLEmbedShape.ts create mode 100644 packages/tlschema/src/shapes/TLFrameShape.ts create mode 100644 packages/tlschema/src/shapes/TLGeoShape.ts create mode 100644 packages/tlschema/src/shapes/TLGroupShape.ts create mode 100644 packages/tlschema/src/shapes/TLHighlightShape.ts create mode 100644 packages/tlschema/src/shapes/TLImageShape.ts create mode 100644 packages/tlschema/src/shapes/TLLineShape.ts create mode 100644 packages/tlschema/src/shapes/TLNoteShape.ts create mode 100644 packages/tlschema/src/shapes/TLTextShape.ts create mode 100644 packages/tlschema/src/shapes/TLVideoShape.ts create mode 100644 packages/tlschema/src/store-migrations.test.ts create mode 100644 packages/tlschema/src/store-migrations.ts create mode 100644 packages/tlschema/src/styles/StyleProp.ts create mode 100644 packages/tlschema/src/styles/TLColorStyle.ts create mode 100644 packages/tlschema/src/styles/TLDashStyle.ts create mode 100644 packages/tlschema/src/styles/TLFillStyle.ts create mode 100644 packages/tlschema/src/styles/TLFontFace.ts create mode 100644 packages/tlschema/src/styles/TLFontStyle.ts create mode 100644 packages/tlschema/src/styles/TLHorizontalAlignStyle.ts create mode 100644 packages/tlschema/src/styles/TLSizeStyle.ts create mode 100644 packages/tlschema/src/styles/TLTextAlignStyle.ts create mode 100644 packages/tlschema/src/styles/TLTheme.ts create mode 100644 packages/tlschema/src/styles/TLVerticalAlignStyle.ts create mode 100644 packages/tlschema/src/translations/languages.ts create mode 100644 packages/tlschema/src/translations/translations.test.ts create mode 100644 packages/tlschema/src/translations/translations.ts create mode 100644 packages/tlschema/src/util-types.ts create mode 100644 packages/tlschema/tsconfig.json create mode 100644 packages/tlschema/vitest.config.ts create mode 100644 packages/utils/DOCS.md create mode 100644 packages/utils/LICENSE.md create mode 100644 packages/utils/README.md create mode 100644 packages/utils/api-extractor.json create mode 100644 packages/utils/api-report.api.md create mode 100644 packages/utils/package.json create mode 100644 packages/utils/setupTests.js create mode 100644 packages/utils/setupVitest.js create mode 100644 packages/utils/src/index.ts create mode 100644 packages/utils/src/lib/ExecutionQueue.test.ts create mode 100644 packages/utils/src/lib/ExecutionQueue.ts create mode 100644 packages/utils/src/lib/LruCache.test.ts create mode 100644 packages/utils/src/lib/LruCache.ts create mode 100644 packages/utils/src/lib/PerformanceTracker.test.ts create mode 100644 packages/utils/src/lib/PerformanceTracker.ts create mode 100644 packages/utils/src/lib/array.test.ts create mode 100644 packages/utils/src/lib/array.ts create mode 100644 packages/utils/src/lib/bind.test.ts create mode 100644 packages/utils/src/lib/bind.ts create mode 100644 packages/utils/src/lib/cache.test.ts create mode 100644 packages/utils/src/lib/cache.ts create mode 100644 packages/utils/src/lib/control.test.ts create mode 100644 packages/utils/src/lib/control.ts create mode 100644 packages/utils/src/lib/debounce.test.ts create mode 100644 packages/utils/src/lib/debounce.ts create mode 100644 packages/utils/src/lib/error.test.ts create mode 100644 packages/utils/src/lib/error.ts create mode 100644 packages/utils/src/lib/file.test.ts create mode 100644 packages/utils/src/lib/file.ts create mode 100644 packages/utils/src/lib/fractionalIndexing.test.ts create mode 100644 packages/utils/src/lib/fractionalIndexing.ts create mode 100644 packages/utils/src/lib/function.ts create mode 100644 packages/utils/src/lib/hash.test.ts create mode 100644 packages/utils/src/lib/hash.ts create mode 100644 packages/utils/src/lib/id.test.ts create mode 100644 packages/utils/src/lib/id.ts create mode 100644 packages/utils/src/lib/iterable.test.ts create mode 100644 packages/utils/src/lib/iterable.ts create mode 100644 packages/utils/src/lib/json-value.ts create mode 100644 packages/utils/src/lib/media/apng.test.ts create mode 100644 packages/utils/src/lib/media/apng.ts create mode 100644 packages/utils/src/lib/media/avif.test.ts create mode 100644 packages/utils/src/lib/media/avif.ts create mode 100644 packages/utils/src/lib/media/gif.test.ts create mode 100644 packages/utils/src/lib/media/gif.ts create mode 100644 packages/utils/src/lib/media/media.test.ts create mode 100644 packages/utils/src/lib/media/media.ts create mode 100644 packages/utils/src/lib/media/png.ts create mode 100644 packages/utils/src/lib/media/webp.test.ts create mode 100644 packages/utils/src/lib/media/webp.ts create mode 100644 packages/utils/src/lib/network.test.ts create mode 100644 packages/utils/src/lib/network.ts create mode 100644 packages/utils/src/lib/number.test.ts create mode 100644 packages/utils/src/lib/number.ts create mode 100644 packages/utils/src/lib/object.test.ts create mode 100644 packages/utils/src/lib/object.ts create mode 100644 packages/utils/src/lib/perf.ts create mode 100644 packages/utils/src/lib/reordering.test.ts create mode 100644 packages/utils/src/lib/reordering.ts create mode 100644 packages/utils/src/lib/retry.test.ts create mode 100644 packages/utils/src/lib/retry.ts create mode 100644 packages/utils/src/lib/sort.test.ts create mode 100644 packages/utils/src/lib/sort.ts create mode 100644 packages/utils/src/lib/storage.test.ts create mode 100644 packages/utils/src/lib/storage.tsx create mode 100644 packages/utils/src/lib/string.test.ts create mode 100644 packages/utils/src/lib/string.ts create mode 100644 packages/utils/src/lib/stringEnum.ts create mode 100644 packages/utils/src/lib/throttle.test.ts create mode 100644 packages/utils/src/lib/throttle.ts create mode 100644 packages/utils/src/lib/timers.test.ts create mode 100644 packages/utils/src/lib/timers.ts create mode 100644 packages/utils/src/lib/types.ts create mode 100644 packages/utils/src/lib/url.test.ts create mode 100644 packages/utils/src/lib/url.ts create mode 100644 packages/utils/src/lib/value.test.ts create mode 100644 packages/utils/src/lib/value.ts create mode 100644 packages/utils/src/lib/version.test.ts create mode 100644 packages/utils/src/lib/version.ts create mode 100644 packages/utils/src/lib/warn.test.ts create mode 100644 packages/utils/src/lib/warn.ts create mode 100644 packages/utils/tsconfig.json create mode 100644 packages/utils/vitest.config.ts create mode 100644 packages/validate/DOCS.md create mode 100644 packages/validate/LICENSE.md create mode 100644 packages/validate/README.md create mode 100644 packages/validate/SPEC.md create mode 100644 packages/validate/api-extractor.json create mode 100644 packages/validate/api-report.api.md create mode 100644 packages/validate/package.json create mode 100644 packages/validate/src/index.ts create mode 100644 packages/validate/src/lib/validation.ts create mode 100644 packages/validate/src/test/arrays.test.ts create mode 100644 packages/validate/src/test/dicts.test.ts create mode 100644 packages/validate/src/test/enums.test.ts create mode 100644 packages/validate/src/test/errors.test.ts create mode 100644 packages/validate/src/test/index-key.test.ts create mode 100644 packages/validate/src/test/json.test.ts create mode 100644 packages/validate/src/test/model.test.ts create mode 100644 packages/validate/src/test/nullable-optional.test.ts create mode 100644 packages/validate/src/test/numbers.test.ts create mode 100644 packages/validate/src/test/objects.test.ts create mode 100644 packages/validate/src/test/or.test.ts create mode 100644 packages/validate/src/test/primitives.test.ts create mode 100644 packages/validate/src/test/refine-check.test.ts create mode 100644 packages/validate/src/test/unions.test.ts create mode 100644 packages/validate/src/test/urls.test.ts create mode 100644 packages/validate/src/test/validation.fuzz.test.ts create mode 100644 packages/validate/src/test/validator.test.ts create mode 100644 packages/validate/tsconfig.json create mode 100644 packages/validate/vitest.config.ts create mode 100644 packages/worker-shared/DOCS.md create mode 100644 packages/worker-shared/README.md create mode 100644 packages/worker-shared/package.json create mode 100644 packages/worker-shared/src/bookmarks.test.ts create mode 100644 packages/worker-shared/src/bookmarks.ts create mode 100644 packages/worker-shared/src/env.ts create mode 100644 packages/worker-shared/src/errors.ts create mode 100644 packages/worker-shared/src/handleRequest.ts create mode 100644 packages/worker-shared/src/index.test.ts create mode 100644 packages/worker-shared/src/index.ts create mode 100644 packages/worker-shared/src/origins.test.ts create mode 100644 packages/worker-shared/src/origins.ts create mode 100644 packages/worker-shared/src/sentry.test.ts create mode 100644 packages/worker-shared/src/sentry.ts create mode 100644 packages/worker-shared/src/userAssetUploads.test.ts create mode 100644 packages/worker-shared/src/userAssetUploads.ts create mode 100644 packages/worker-shared/tsconfig.json create mode 100644 packages/worker-shared/vitest.config.ts create mode 100644 skills/clean-copy/SKILL.md create mode 100644 skills/commit-changes/SKILL.md create mode 100644 skills/dotcom-release-crew/SKILL.md create mode 100644 skills/dotcom-release-marketing/SKILL.md create mode 100644 skills/issue/SKILL.md create mode 100755 skills/issue/scripts/set-issue-type.sh create mode 100644 skills/pr-walkthrough/SKILL.md create mode 100644 skills/pr-walkthrough/references/manifest.md create mode 100755 skills/pr-walkthrough/scripts/generate-audio.sh create mode 100755 skills/pr-walkthrough/scripts/make-video.sh create mode 100644 skills/pr-walkthrough/video/.gitignore create mode 100644 skills/pr-walkthrough/video/build.mjs create mode 100644 skills/pr-walkthrough/video/hyperframes.json create mode 100644 skills/pr-walkthrough/video/meta.json create mode 100755 skills/pr-walkthrough/video/render.sh create mode 100644 skills/pr/SKILL.md create mode 100644 skills/review-docs/SKILL.md create mode 100644 skills/shared/blog-guide.md create mode 100644 skills/shared/docs-guide.md create mode 100644 skills/shared/release-notes-guide.md create mode 100644 skills/shepherd-pr/SKILL.md create mode 100644 skills/simplify-trace/SKILL.md create mode 100644 skills/simplify-trace/scripts/simplify-trace.mjs create mode 100644 skills/skill-creator/LICENSE.txt create mode 100644 skills/skill-creator/SKILL.md create mode 100644 skills/skill-creator/references/output-patterns.md create mode 100644 skills/skill-creator/references/workflows.md create mode 100644 skills/skill-creator/scripts/init-skill.ts create mode 100644 skills/skill-creator/scripts/package-skill.ts create mode 100644 skills/skill-creator/scripts/quick-validate.ts create mode 100644 skills/spec-driven-tests/SKILL.md create mode 100644 skills/take/SKILL.md create mode 100644 skills/tldraw-migrate/.gitignore create mode 100644 skills/tldraw-migrate/README.md create mode 100644 skills/tldraw-migrate/SKILL.md create mode 100644 skills/tldraw-migrate/detect-target.mjs create mode 100644 skills/tldraw-migrate/detect-versions.mjs create mode 100644 skills/tldraw-migrate/fetch-release-notes.mjs create mode 100644 skills/tldraw-migrate/type-errors.md create mode 100644 skills/update-release-notes/SKILL.md create mode 100755 skills/update-release-notes/scripts/fetch-pr-batch.sh create mode 100755 skills/update-release-notes/scripts/get-changelog-status.sh create mode 100755 skills/update-release-notes/scripts/get-new-prs-from-main.sh create mode 100755 skills/update-release-notes/scripts/get-new-prs.sh create mode 100755 skills/update-release-notes/scripts/update-draft-release.sh create mode 100644 skills/write-docs/SKILL.md create mode 100644 skills/write-e2e-tests/SKILL.md create mode 100644 skills/write-example/SKILL.md create mode 100644 skills/write-issue/SKILL.md create mode 100644 skills/write-pr/SKILL.md create mode 100644 skills/write-pr/scripts/example-scenario.mjs create mode 100644 skills/write-pr/scripts/record-interaction.mjs create mode 100644 skills/write-release-notes/SKILL.md create mode 100644 skills/write-tbp/SKILL.md create mode 100644 skills/write-tbp/assets/.gitignore create mode 100644 skills/write-unit-tests/SKILL.md create mode 100644 socket.yml create mode 100644 templates/.gitignore create mode 100644 templates/agent/.gitignore create mode 100644 templates/agent/LICENSE.md create mode 100644 templates/agent/README.md create mode 100644 templates/agent/client/AgentHelpers.ts create mode 100644 templates/agent/client/App.tsx create mode 100644 templates/agent/client/actions/AddDetailActionUtil.ts create mode 100644 templates/agent/client/actions/AgentActionUtil.ts create mode 100644 templates/agent/client/actions/AlignActionUtil.ts create mode 100644 templates/agent/client/actions/BringToFrontActionUtil.ts create mode 100644 templates/agent/client/actions/ClearActionUtil.ts create mode 100644 templates/agent/client/actions/CountShapesActionUtil.ts create mode 100644 templates/agent/client/actions/CountryInfoActionUtil.ts create mode 100644 templates/agent/client/actions/CreateActionUtil.ts create mode 100644 templates/agent/client/actions/DeleteActionUtil.ts create mode 100644 templates/agent/client/actions/DistributeActionUtil.ts create mode 100644 templates/agent/client/actions/LabelActionUtil.ts create mode 100644 templates/agent/client/actions/MessageActionUtil.ts create mode 100644 templates/agent/client/actions/MoveActionUtil.ts create mode 100644 templates/agent/client/actions/PenActionUtil.ts create mode 100644 templates/agent/client/actions/PlaceActionUtil.ts create mode 100644 templates/agent/client/actions/ResizeActionUtil.ts create mode 100644 templates/agent/client/actions/ReviewActionUtil.ts create mode 100644 templates/agent/client/actions/RotateActionUtil.ts create mode 100644 templates/agent/client/actions/SendToBackActionUtil.ts create mode 100644 templates/agent/client/actions/SetMyViewActionUtil.ts create mode 100644 templates/agent/client/actions/StackActionUtil.ts create mode 100644 templates/agent/client/actions/ThinkActionUtil.ts create mode 100644 templates/agent/client/actions/UnknownActionUtil.ts create mode 100644 templates/agent/client/actions/UpdateActionUtil.ts create mode 100644 templates/agent/client/actions/UpsertTodoListItemActionUtil.ts create mode 100644 templates/agent/client/agent/TldrawAgent.ts create mode 100644 templates/agent/client/agent/TldrawAgentApp.ts create mode 100644 templates/agent/client/agent/TldrawAgentAppProvider.tsx create mode 100644 templates/agent/client/agent/managers/AgentActionManager.ts create mode 100644 templates/agent/client/agent/managers/AgentAppAgentsManager.ts create mode 100644 templates/agent/client/agent/managers/AgentAppPersistenceManager.ts create mode 100644 templates/agent/client/agent/managers/AgentChatManager.ts create mode 100644 templates/agent/client/agent/managers/AgentChatOriginManager.ts create mode 100644 templates/agent/client/agent/managers/AgentContextManager.ts create mode 100644 templates/agent/client/agent/managers/AgentDebugManager.ts create mode 100644 templates/agent/client/agent/managers/AgentLintManager.ts create mode 100644 templates/agent/client/agent/managers/AgentModeManager.ts create mode 100644 templates/agent/client/agent/managers/AgentModelNameManager.ts create mode 100644 templates/agent/client/agent/managers/AgentRequestManager.ts create mode 100644 templates/agent/client/agent/managers/AgentTodoManager.ts create mode 100644 templates/agent/client/agent/managers/AgentUserActionTracker.ts create mode 100644 templates/agent/client/agent/managers/BaseAgentAppManager.ts create mode 100644 templates/agent/client/agent/managers/BaseAgentManager.ts create mode 100644 templates/agent/client/components/ChatInput.tsx create mode 100644 templates/agent/client/components/ChatPanel.tsx create mode 100644 templates/agent/client/components/ChatPanelFallback.tsx create mode 100644 templates/agent/client/components/ContextItemTag.tsx create mode 100644 templates/agent/client/components/CustomHelperButtons.tsx create mode 100644 templates/agent/client/components/GoToAgentButton.tsx create mode 100644 templates/agent/client/components/PromptTag.tsx create mode 100644 templates/agent/client/components/SelectionTag.tsx create mode 100644 templates/agent/client/components/TodoList.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistory.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistoryGroup.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistoryGroupWithDiff.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistoryGroupWithoutDiff.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistoryPrompt.tsx create mode 100644 templates/agent/client/components/chat-history/ChatHistorySection.tsx create mode 100644 templates/agent/client/components/chat-history/TldrawDiffViewer.tsx create mode 100644 templates/agent/client/components/chat-history/TldrawViewer.tsx create mode 100644 templates/agent/client/components/chat-history/getActionInfo.ts create mode 100644 templates/agent/client/index.css create mode 100644 templates/agent/client/main.tsx create mode 100644 templates/agent/client/modes/AgentModeChart.ts create mode 100644 templates/agent/client/modes/AgentModeDefinitions.ts create mode 100644 templates/agent/client/overlays/AgentHighlightOverlayUtil.ts create mode 100644 templates/agent/client/parts/AgentViewportBoundsPartUtil.ts create mode 100644 templates/agent/client/parts/BlurryShapesPartUtil.ts create mode 100644 templates/agent/client/parts/CanvasLintsPartUtil.ts create mode 100644 templates/agent/client/parts/ChatHistoryPartUtil.ts create mode 100644 templates/agent/client/parts/ContextItemsPartUtil.ts create mode 100644 templates/agent/client/parts/DataPartUtil.ts create mode 100644 templates/agent/client/parts/DebugPartUtil.ts create mode 100644 templates/agent/client/parts/MessagesPartUtil.ts create mode 100644 templates/agent/client/parts/ModePartUtil.ts create mode 100644 templates/agent/client/parts/ModelNamePartUtil.ts create mode 100644 templates/agent/client/parts/PeripheralShapesPartUtil.ts create mode 100644 templates/agent/client/parts/PromptPartUtil.ts create mode 100644 templates/agent/client/parts/ScreenshotPartUtil.ts create mode 100644 templates/agent/client/parts/SelectedShapesPartUtil.ts create mode 100644 templates/agent/client/parts/TimePartUtil.ts create mode 100644 templates/agent/client/parts/TodoListPartUtil.ts create mode 100644 templates/agent/client/parts/UserActionHistoryPartUtil.ts create mode 100644 templates/agent/client/parts/UserViewportBoundsPartUtil.ts create mode 100644 templates/agent/client/tools/TargetAreaTool.tsx create mode 100644 templates/agent/client/tools/TargetShapeTool.tsx create mode 100644 templates/agent/client/vite-env.d.ts create mode 100644 templates/agent/index.html create mode 100644 templates/agent/package.json create mode 100644 templates/agent/public/favicon.ico create mode 100644 templates/agent/scripts/vite-zod-locale-plugin.d.ts create mode 100644 templates/agent/scripts/vite-zod-locale-plugin.js create mode 100644 templates/agent/scripts/zod-locales-shim.js create mode 100644 templates/agent/shared/format/BlurryShape.ts create mode 100644 templates/agent/shared/format/FocusedColor.ts create mode 100644 templates/agent/shared/format/FocusedFill.ts create mode 100644 templates/agent/shared/format/FocusedFontSize.ts create mode 100644 templates/agent/shared/format/FocusedGeoShapeType.ts create mode 100644 templates/agent/shared/format/FocusedShape.ts create mode 100644 templates/agent/shared/format/PeripheralShapesCluster.ts create mode 100644 templates/agent/shared/format/convertFocusedShapeToTldrawShape.ts create mode 100644 templates/agent/shared/format/convertTldrawShapeToBlurryShape.ts create mode 100644 templates/agent/shared/format/convertTldrawShapeToFocusedShape.ts create mode 100644 templates/agent/shared/format/convertTldrawShapesToPeripheralShapes.ts create mode 100644 templates/agent/shared/icons/AgentIcon.tsx create mode 100644 templates/agent/shared/icons/AtIcon.tsx create mode 100644 templates/agent/shared/icons/BrainIcon.tsx create mode 100644 templates/agent/shared/icons/ChevronDownIcon.tsx create mode 100644 templates/agent/shared/icons/ChevronRightIcon.tsx create mode 100644 templates/agent/shared/icons/CommentIcon.tsx create mode 100644 templates/agent/shared/icons/CrossIcon.tsx create mode 100644 templates/agent/shared/icons/CursorIcon.tsx create mode 100644 templates/agent/shared/icons/EllipsisIcon.tsx create mode 100644 templates/agent/shared/icons/EyeIcon.tsx create mode 100644 templates/agent/shared/icons/NoteIcon.tsx create mode 100644 templates/agent/shared/icons/PencilIcon.tsx create mode 100644 templates/agent/shared/icons/RefreshIcon.tsx create mode 100644 templates/agent/shared/icons/SearchIcon.tsx create mode 100644 templates/agent/shared/icons/SmallSpinner.tsx create mode 100644 templates/agent/shared/icons/TargetIcon.tsx create mode 100644 templates/agent/shared/icons/TickIcon.tsx create mode 100644 templates/agent/shared/icons/TrashIcon.tsx create mode 100644 templates/agent/shared/models.ts create mode 100644 templates/agent/shared/schema/AgentActionSchemaRegistry.ts create mode 100644 templates/agent/shared/schema/AgentActionSchemas.ts create mode 100644 templates/agent/shared/schema/PromptPartDefinitions.ts create mode 100644 templates/agent/shared/schema/buildResponseSchema.ts create mode 100644 templates/agent/shared/types/AgentAction.ts create mode 100644 templates/agent/shared/types/AgentCanvasLint.ts create mode 100644 templates/agent/shared/types/AgentInput.ts create mode 100644 templates/agent/shared/types/AgentMessage.ts create mode 100644 templates/agent/shared/types/AgentPrompt.ts create mode 100644 templates/agent/shared/types/AgentRequest.ts create mode 100644 templates/agent/shared/types/BaseAgentAction.ts create mode 100644 templates/agent/shared/types/BasePromptPart.ts create mode 100644 templates/agent/shared/types/ChatHistoryInfo.ts create mode 100644 templates/agent/shared/types/ChatHistoryItem.ts create mode 100644 templates/agent/shared/types/ContextItem.ts create mode 100644 templates/agent/shared/types/PromptPart.ts create mode 100644 templates/agent/shared/types/Streaming.ts create mode 100644 templates/agent/shared/types/SystemPromptCategory.ts create mode 100644 templates/agent/shared/types/TodoItem.ts create mode 100644 templates/agent/shared/types/ids-schema.ts create mode 100644 templates/agent/tsconfig.json create mode 100644 templates/agent/vite.config.ts create mode 100644 templates/agent/worker/do/AgentDurableObject.ts create mode 100644 templates/agent/worker/do/AgentService.ts create mode 100644 templates/agent/worker/do/closeAndParseJson.ts create mode 100644 templates/agent/worker/environment.ts create mode 100644 templates/agent/worker/prompt/buildMessages.ts create mode 100644 templates/agent/worker/prompt/buildSystemPrompt.ts create mode 100644 templates/agent/worker/prompt/getModelName.ts create mode 100644 templates/agent/worker/prompt/getSystemPromptFlags.ts create mode 100644 templates/agent/worker/prompt/sections/flagged.ts create mode 100644 templates/agent/worker/prompt/sections/intro-section.ts create mode 100644 templates/agent/worker/prompt/sections/rules-section.ts create mode 100644 templates/agent/worker/routes/stream.ts create mode 100644 templates/agent/worker/worker.ts create mode 100644 templates/agent/wrangler.toml create mode 100644 templates/branching-chat/.gitignore create mode 100644 templates/branching-chat/LICENSE.md create mode 100644 templates/branching-chat/README.md create mode 100644 templates/branching-chat/client/App.tsx create mode 100644 templates/branching-chat/client/components/WorkflowToolbar.tsx create mode 100644 templates/branching-chat/client/components/icons/HandleIcon.tsx create mode 100644 templates/branching-chat/client/components/icons/SendIcon.tsx create mode 100644 templates/branching-chat/client/connection/ConnectionBindingUtil.tsx create mode 100644 templates/branching-chat/client/connection/ConnectionCenterHandleOverlayUtil.tsx create mode 100644 templates/branching-chat/client/connection/ConnectionShapeUtil.tsx create mode 100644 templates/branching-chat/client/connection/insertNodeWithinConnection.tsx create mode 100644 templates/branching-chat/client/connection/keepConnectionsAtBottom.tsx create mode 100644 templates/branching-chat/client/constants.tsx create mode 100644 templates/branching-chat/client/disableTransparency.tsx create mode 100644 templates/branching-chat/client/index.css create mode 100644 templates/branching-chat/client/main.tsx create mode 100644 templates/branching-chat/client/nodes/NodeShapeUtil.tsx create mode 100644 templates/branching-chat/client/nodes/nodePorts.tsx create mode 100644 templates/branching-chat/client/nodes/nodeTypes.tsx create mode 100644 templates/branching-chat/client/nodes/types/MessageNode.tsx create mode 100644 templates/branching-chat/client/nodes/types/shared.tsx create mode 100644 templates/branching-chat/client/ports/PointingPort.tsx create mode 100644 templates/branching-chat/client/ports/Port.tsx create mode 100644 templates/branching-chat/client/ports/getPortAtPoint.tsx create mode 100644 templates/branching-chat/client/ports/portState.ts create mode 100644 templates/branching-chat/index.html create mode 100644 templates/branching-chat/package.json create mode 100644 templates/branching-chat/public/favicon.ico create mode 100644 templates/branching-chat/tsconfig.json create mode 100644 templates/branching-chat/vite.config.ts create mode 100644 templates/branching-chat/worker/types.ts create mode 100644 templates/branching-chat/worker/worker.ts create mode 100644 templates/branching-chat/wrangler.toml create mode 100644 templates/chat/.gitignore create mode 100644 templates/chat/LICENSE.md create mode 100644 templates/chat/README.md create mode 100644 templates/chat/next.config.mjs create mode 100644 templates/chat/package.json create mode 100644 templates/chat/src/app/api/chat/route.ts create mode 100644 templates/chat/src/app/api/upload/route.ts create mode 100644 templates/chat/src/app/favicon.ico create mode 100644 templates/chat/src/app/layout.tsx create mode 100644 templates/chat/src/app/page.tsx create mode 100644 templates/chat/src/app/styles.css create mode 100644 templates/chat/src/components/Chat.tsx create mode 100644 templates/chat/src/components/ChatInput.tsx create mode 100644 templates/chat/src/components/ChatInputImage.tsx create mode 100644 templates/chat/src/components/ChatMessage.tsx create mode 100644 templates/chat/src/components/ClearChatIcon.tsx create mode 100644 templates/chat/src/components/MessageList.tsx create mode 100644 templates/chat/src/components/WhiteboardModal.tsx create mode 100644 templates/chat/src/components/icons/ImageIcon.tsx create mode 100644 templates/chat/src/components/icons/SendIcon.tsx create mode 100644 templates/chat/src/components/icons/UploadIcon.tsx create mode 100644 templates/chat/src/components/icons/WhiteboardIcon.tsx create mode 100644 templates/chat/src/components/icons/XIcon.tsx create mode 100644 templates/chat/src/hooks/useChatInputState.ts create mode 100644 templates/chat/src/hooks/useChatMessageStorage.tsx create mode 100644 templates/chat/src/hooks/useScrollToBottom.ts create mode 100644 templates/chat/src/utils/uploadMessageContents.ts create mode 100644 templates/chat/tsconfig.json create mode 100644 templates/chat/vercel.json create mode 100644 templates/image-pipeline/README.md create mode 100644 templates/image-pipeline/index.html create mode 100644 templates/image-pipeline/package.json create mode 100644 templates/image-pipeline/src/App.tsx create mode 100644 templates/image-pipeline/src/api/pipelineApi.ts create mode 100644 templates/image-pipeline/src/components/ImagePipelineSidebar.tsx create mode 100644 templates/image-pipeline/src/components/OnCanvasNodePicker.tsx create mode 100644 templates/image-pipeline/src/components/PipelineRegions.tsx create mode 100644 templates/image-pipeline/src/components/PipelineToolbar.tsx create mode 100644 templates/image-pipeline/src/components/TemplatePicker.tsx create mode 100644 templates/image-pipeline/src/components/icons/AddIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/AdjustIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/BlendIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/CaptureIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/ControlNetIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/GenerateIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/GenerateTextIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/IPAdapterIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/IteratorIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/LoadImageIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/ModelIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/NumberIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/PlayIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/PreviewIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/PromptConcatIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/PromptIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/RouterIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/StopIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/StyleTransferIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/SubtractIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/TemplateIcon.tsx create mode 100644 templates/image-pipeline/src/components/icons/UpscaleIcon.tsx create mode 100644 templates/image-pipeline/src/connection/ConnectionBindingUtil.tsx create mode 100644 templates/image-pipeline/src/connection/ConnectionCenterHandleOverlayUtil.tsx create mode 100644 templates/image-pipeline/src/connection/ConnectionShapeUtil.tsx create mode 100644 templates/image-pipeline/src/connection/insertNodeWithinConnection.tsx create mode 100644 templates/image-pipeline/src/connection/keepConnectionsAtBottom.tsx create mode 100644 templates/image-pipeline/src/constants.tsx create mode 100644 templates/image-pipeline/src/disableTransparency.tsx create mode 100644 templates/image-pipeline/src/execution/ExecutionGraph.tsx create mode 100644 templates/image-pipeline/src/execution/executionState.ts create mode 100644 templates/image-pipeline/src/index.css create mode 100644 templates/image-pipeline/src/main.tsx create mode 100644 templates/image-pipeline/src/nodes/NodeShapeUtil.tsx create mode 100644 templates/image-pipeline/src/nodes/nodePorts.tsx create mode 100644 templates/image-pipeline/src/nodes/nodeTypes.tsx create mode 100644 templates/image-pipeline/src/nodes/resizeNode.ts create mode 100644 templates/image-pipeline/src/nodes/types/AdjustNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/BlendNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/CaptureNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/ControlNetNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/GenerateNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/GenerateTextNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/IPAdapterNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/IteratorNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/LoadImageNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/ModelNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/NumberNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/PreviewNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/PromptConcatNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/PromptNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/RouterNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/StyleTransferNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/UpscaleNode.tsx create mode 100644 templates/image-pipeline/src/nodes/types/shared.tsx create mode 100644 templates/image-pipeline/src/ports/PointingPort.tsx create mode 100644 templates/image-pipeline/src/ports/Port.tsx create mode 100644 templates/image-pipeline/src/ports/getPortAtPoint.tsx create mode 100644 templates/image-pipeline/src/ports/portCompatibility.ts create mode 100644 templates/image-pipeline/src/ports/portState.ts create mode 100644 templates/image-pipeline/src/templates/templateActions.ts create mode 100644 templates/image-pipeline/src/templates/templateState.ts create mode 100644 templates/image-pipeline/src/utils.ts create mode 100644 templates/image-pipeline/src/utils/sleep.ts create mode 100644 templates/image-pipeline/tsconfig.json create mode 100644 templates/image-pipeline/vite.config.ts create mode 100644 templates/image-pipeline/worker/providers/index.ts create mode 100644 templates/image-pipeline/worker/providers/replicate.ts create mode 100644 templates/image-pipeline/worker/providers/types.ts create mode 100644 templates/image-pipeline/worker/routes/generate.ts create mode 100644 templates/image-pipeline/worker/routes/generateText.ts create mode 100644 templates/image-pipeline/worker/routes/images.ts create mode 100644 templates/image-pipeline/worker/routes/ipAdapter.ts create mode 100644 templates/image-pipeline/worker/routes/styleTransfer.ts create mode 100644 templates/image-pipeline/worker/routes/upscale.ts create mode 100644 templates/image-pipeline/worker/worker.ts create mode 100644 templates/image-pipeline/wrangler.toml create mode 100644 templates/nextjs/.gitignore create mode 100644 templates/nextjs/LICENSE.md create mode 100644 templates/nextjs/README.md create mode 100644 templates/nextjs/next.config.mjs create mode 100644 templates/nextjs/package.json create mode 100644 templates/nextjs/src/app/favicon.ico create mode 100644 templates/nextjs/src/app/globals.css create mode 100644 templates/nextjs/src/app/layout.tsx create mode 100644 templates/nextjs/src/app/page.tsx create mode 100644 templates/nextjs/tsconfig.json create mode 100644 templates/shader/.gitignore create mode 100644 templates/shader/LICENSE.md create mode 100644 templates/shader/README.md create mode 100644 templates/shader/index.html create mode 100644 templates/shader/package.json create mode 100644 templates/shader/public/favicon.ico create mode 100644 templates/shader/src/App.tsx create mode 100644 templates/shader/src/WebGLCanvas.tsx create mode 100644 templates/shader/src/WebGLManager.ts create mode 100644 templates/shader/src/config-panel/ConfigPanel.tsx create mode 100644 templates/shader/src/config-panel/ConfigPanelBooleanControl.tsx create mode 100644 templates/shader/src/config-panel/ConfigPanelLabel.tsx create mode 100644 templates/shader/src/config-panel/ConfigPanelSlider.tsx create mode 100644 templates/shader/src/config-panel/config-panel.md create mode 100644 templates/shader/src/fluid/FluidConfigPanel.tsx create mode 100644 templates/shader/src/fluid/FluidManager.ts create mode 100644 templates/shader/src/fluid/FluidRenderer.tsx create mode 100644 templates/shader/src/fluid/config.ts create mode 100644 templates/shader/src/fluid/fluid.md create mode 100644 templates/shader/src/fluid/fluid.ts create mode 100644 templates/shader/src/index.css create mode 100644 templates/shader/src/main.tsx create mode 100644 templates/shader/src/minimal/MinimalConfigPanel.tsx create mode 100644 templates/shader/src/minimal/MinimalRenderer.tsx create mode 100644 templates/shader/src/minimal/MinimalShaderManager.ts create mode 100644 templates/shader/src/minimal/config.ts create mode 100644 templates/shader/src/minimal/fragment.glsl create mode 100644 templates/shader/src/minimal/minimal-example.md create mode 100644 templates/shader/src/minimal/vertex.glsl create mode 100644 templates/shader/src/rainbow/RainbowConfigPanel.tsx create mode 100644 templates/shader/src/rainbow/RainbowRenderer.tsx create mode 100644 templates/shader/src/rainbow/RainbowShaderManager.ts create mode 100644 templates/shader/src/rainbow/config.ts create mode 100644 templates/shader/src/rainbow/fragment.glsl create mode 100644 templates/shader/src/rainbow/rainbow-example.md create mode 100644 templates/shader/src/rainbow/vertex.glsl create mode 100644 templates/shader/src/shader.css create mode 100644 templates/shader/src/shadow/ShadowControlPanel.tsx create mode 100644 templates/shader/src/shadow/ShadowRenderer.tsx create mode 100644 templates/shader/src/shadow/ShadowShaderManager.ts create mode 100644 templates/shader/src/shadow/config.ts create mode 100644 templates/shader/src/shadow/fragment.glsl create mode 100644 templates/shader/src/shadow/shadow-example.md create mode 100644 templates/shader/src/shadow/vertex.glsl create mode 100644 templates/shader/src/vite-env.d.ts create mode 100644 templates/shader/tsconfig.json create mode 100644 templates/shader/vercel.json create mode 100644 templates/shader/vite-env.d.ts create mode 100644 templates/shader/vite.config.ts create mode 100644 templates/simple-server-example/.gitignore create mode 100644 templates/simple-server-example/README.md create mode 100644 templates/simple-server-example/package.json create mode 100644 templates/simple-server-example/src/client/App.tsx create mode 100644 templates/simple-server-example/src/client/index.css create mode 100644 templates/simple-server-example/src/client/index.html create mode 100644 templates/simple-server-example/src/client/main.tsx create mode 100644 templates/simple-server-example/src/client/vite-env.d.ts create mode 100644 templates/simple-server-example/src/server/assets.ts create mode 100644 templates/simple-server-example/src/server/rooms.ts create mode 100644 templates/simple-server-example/src/server/server.ts create mode 100644 templates/simple-server-example/src/server/unfurl.ts create mode 100644 templates/simple-server-example/tsconfig.json create mode 100644 templates/simple-server-example/vite.config.mts create mode 100644 templates/socketio-server-example/.gitignore create mode 100644 templates/socketio-server-example/README.md create mode 100644 templates/socketio-server-example/package.json create mode 100644 templates/socketio-server-example/src/client/App.tsx create mode 100644 templates/socketio-server-example/src/client/index.css create mode 100644 templates/socketio-server-example/src/client/index.html create mode 100644 templates/socketio-server-example/src/client/main.tsx create mode 100644 templates/socketio-server-example/src/client/vite-env.d.ts create mode 100644 templates/socketio-server-example/src/server/assets.ts create mode 100644 templates/socketio-server-example/src/server/rooms.ts create mode 100644 templates/socketio-server-example/src/server/server.ts create mode 100644 templates/socketio-server-example/src/server/unfurl.ts create mode 100644 templates/socketio-server-example/tsconfig.json create mode 100644 templates/socketio-server-example/vite.config.mts create mode 100644 templates/sync-cloudflare/.gitignore create mode 100644 templates/sync-cloudflare/LICENSE.md create mode 100644 templates/sync-cloudflare/README.md create mode 100644 templates/sync-cloudflare/client/getBookmarkPreview.tsx create mode 100644 templates/sync-cloudflare/client/index.css create mode 100644 templates/sync-cloudflare/client/localStorage.ts create mode 100644 templates/sync-cloudflare/client/main.tsx create mode 100644 templates/sync-cloudflare/client/multiplayerAssetStore.tsx create mode 100644 templates/sync-cloudflare/client/pages/Room.tsx create mode 100644 templates/sync-cloudflare/client/pages/Root.tsx create mode 100644 templates/sync-cloudflare/client/vite-env.d.ts create mode 100644 templates/sync-cloudflare/index.html create mode 100644 templates/sync-cloudflare/package.json create mode 100644 templates/sync-cloudflare/public/favicon.ico create mode 100644 templates/sync-cloudflare/tsconfig.json create mode 100644 templates/sync-cloudflare/vite.config.ts create mode 100644 templates/sync-cloudflare/worker/TldrawDurableObject.ts create mode 100644 templates/sync-cloudflare/worker/assetUploads.ts create mode 100644 templates/sync-cloudflare/worker/worker.ts create mode 100644 templates/sync-cloudflare/wrangler.toml create mode 100644 templates/vite/.gitignore create mode 100644 templates/vite/LICENSE.md create mode 100644 templates/vite/README.md create mode 100644 templates/vite/index.html create mode 100644 templates/vite/package.json create mode 100644 templates/vite/public/favicon.ico create mode 100644 templates/vite/src/App.tsx create mode 100644 templates/vite/src/index.css create mode 100644 templates/vite/src/main.tsx create mode 100644 templates/vite/src/vite-env.d.ts create mode 100644 templates/vite/tsconfig.json create mode 100644 templates/vite/vite-env.d.ts create mode 100644 templates/vite/vite.config.ts create mode 100644 templates/vue/.gitignore create mode 100644 templates/vue/LICENSE.md create mode 100644 templates/vue/README.md create mode 100644 templates/vue/index.html create mode 100644 templates/vue/package.json create mode 100644 templates/vue/public/favicon.ico create mode 100644 templates/vue/src/App.vue create mode 100644 templates/vue/src/TldrawWrapper.tsx create mode 100644 templates/vue/src/index.css create mode 100644 templates/vue/src/main.ts create mode 100644 templates/vue/src/vite-env.d.ts create mode 100644 templates/vue/tsconfig.json create mode 100644 templates/vue/vite.config.ts create mode 100644 templates/workflow/.gitignore create mode 100644 templates/workflow/LICENSE.md create mode 100644 templates/workflow/README.md create mode 100644 templates/workflow/alex-notes.md create mode 100644 templates/workflow/index.html create mode 100644 templates/workflow/package.json create mode 100644 templates/workflow/public/favicon.ico create mode 100644 templates/workflow/src/App.tsx create mode 100644 templates/workflow/src/components/MathematicalToolbarItem.tsx create mode 100644 templates/workflow/src/components/OnCanvasComponentPicker.tsx create mode 100644 templates/workflow/src/components/WorkflowRegions.tsx create mode 100644 templates/workflow/src/components/WorkflowToolbar.tsx create mode 100644 templates/workflow/src/components/icons/AddIcon.tsx create mode 100644 templates/workflow/src/components/icons/ConditionalIcon.tsx create mode 100644 templates/workflow/src/components/icons/DivideIcon.tsx create mode 100644 templates/workflow/src/components/icons/EarthquakeIcon.tsx create mode 100644 templates/workflow/src/components/icons/MathematicalIcon.tsx create mode 100644 templates/workflow/src/components/icons/MultiplyIcon.tsx create mode 100644 templates/workflow/src/components/icons/PlayIcon.tsx create mode 100644 templates/workflow/src/components/icons/SliderIcon.tsx create mode 100644 templates/workflow/src/components/icons/StopIcon.tsx create mode 100644 templates/workflow/src/components/icons/SubtractIcon.tsx create mode 100644 templates/workflow/src/connection/ConnectionBindingUtil.tsx create mode 100644 templates/workflow/src/connection/ConnectionCenterHandleOverlayUtil.tsx create mode 100644 templates/workflow/src/connection/ConnectionShapeUtil.tsx create mode 100644 templates/workflow/src/connection/insertNodeWithinConnection.tsx create mode 100644 templates/workflow/src/connection/keepConnectionsAtBottom.tsx create mode 100644 templates/workflow/src/constants.tsx create mode 100644 templates/workflow/src/disableTransparency.tsx create mode 100644 templates/workflow/src/execution/ExecutionGraph.tsx create mode 100644 templates/workflow/src/execution/executionState.ts create mode 100644 templates/workflow/src/hooks/useDragToCreate.ts create mode 100644 templates/workflow/src/index.css create mode 100644 templates/workflow/src/main.tsx create mode 100644 templates/workflow/src/nodes/NodeShapeUtil.tsx create mode 100644 templates/workflow/src/nodes/nodePorts.tsx create mode 100644 templates/workflow/src/nodes/nodeTypes.tsx create mode 100644 templates/workflow/src/nodes/types/AddNode.tsx create mode 100644 templates/workflow/src/nodes/types/ConditionalNode.tsx create mode 100644 templates/workflow/src/nodes/types/DivideNode.tsx create mode 100644 templates/workflow/src/nodes/types/EarthquakeNode.tsx create mode 100644 templates/workflow/src/nodes/types/MultiplyNode.tsx create mode 100644 templates/workflow/src/nodes/types/SliderNode.tsx create mode 100644 templates/workflow/src/nodes/types/SubtractNode.tsx create mode 100644 templates/workflow/src/nodes/types/shared.tsx create mode 100644 templates/workflow/src/ports/PointingPort.tsx create mode 100644 templates/workflow/src/ports/Port.tsx create mode 100644 templates/workflow/src/ports/getPortAtPoint.tsx create mode 100644 templates/workflow/src/ports/portState.ts create mode 100644 templates/workflow/src/utils.ts create mode 100644 templates/workflow/src/utils/sleep.ts create mode 100644 templates/workflow/tsconfig.json create mode 100644 templates/workflow/vercel.json create mode 100644 templates/workflow/vite.config.ts create mode 100644 tsdoc.json create mode 100644 vitest.config.ts diff --git a/.agents/skills b/.agents/skills new file mode 120000 index 0000000..42c5394 --- /dev/null +++ b/.agents/skills @@ -0,0 +1 @@ +../skills \ No newline at end of file diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..ba34f35 --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,23 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "examples", + "runtimeExecutable": "yarn", + "runtimeArgs": ["dev"], + "port": 5420 + }, + { + "name": "dotcom-app", + "runtimeExecutable": "yarn", + "runtimeArgs": ["dev-app"], + "port": 3000 + }, + { + "name": "docs", + "runtimeExecutable": "yarn", + "runtimeArgs": ["dev-docs"], + "port": 3001 + } + ] +} diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..d5a4a47 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,53 @@ +{ + "spinnerVerbs": { + "mode": "replace", + "verbs": [ + "panning", + "zooming", + "scrolling", + "drawing", + "selecting", + "nudging", + "resizing", + "rotating", + "flipping", + "stretching", + "aligning", + "distributing", + "stacking", + "packing", + "grouping", + "cropping", + "styling", + "embedding", + "scribbling", + "brushing", + "pointing", + "snapping to grid" + ] + }, + "permissions": { + "allow": [ + "WebSearch", + "Bash(gh pr:*)", + "Bash(yarn install)", + "Bash(yarn test:*)", + "Bash(yarn lint:*)", + "Bash(yarn typecheck)", + "Bash(git add:*)" + ] + }, + "hooks": { + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "cd \"$(git rev-parse --show-toplevel)\" && git diff --name-only --diff-filter=ACMR | grep -E '\\.(ts|tsx|js|jsx|json|md)$' | xargs -r yarn run -T prettier --write || true" + } + ] + } + ] + }, + "enabledPlugins": {} +} diff --git a/.claude/skills b/.claude/skills new file mode 120000 index 0000000..42c5394 --- /dev/null +++ b/.claude/skills @@ -0,0 +1 @@ +../skills \ No newline at end of file diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json new file mode 100644 index 0000000..6819d20 --- /dev/null +++ b/.cursor-plugin/marketplace.json @@ -0,0 +1,19 @@ +{ + "name": "tldraw", + "owner": { + "name": "tldraw", + "email": "tim@tldraw.com" + }, + "metadata": { + "description": "Draw and visually collaborate with your agents inside Cursor", + "version": "0.1.0", + "pluginRoot": "apps/mcp-app/plugins" + }, + "plugins": [ + { + "name": "tldraw", + "source": "tldraw-mcp", + "description": "Draw and visually collaborate with your agents inside Cursor" + } + ] +} diff --git a/.cursor/skills b/.cursor/skills new file mode 120000 index 0000000..42c5394 --- /dev/null +++ b/.cursor/skills @@ -0,0 +1 @@ +../skills \ No newline at end of file diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..13d22ee --- /dev/null +++ b/.dockerignore @@ -0,0 +1,74 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +**/node_modules + +.git +**/.git + +dist +dist-cjs +dist-esm +.tsbuild* +.lazy +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# turborepo +.turbo + +coverage + +**/*.env +**/*.tsbuildinfo + +**/*.css.map +**/*.js.map +apps/webdriver/www/index.js +apps/webdriver/www/index.css +apps/dotcom/*-worker/.dev.vars +nohup.out + +packages/*/package +packages/*/*.tgz + +tsconfig.build.json +.vercel + +api-json +api-md + +apps/webdriver/www +!apps/webdriver/www/index.html + +# yarn v2 +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +packages/*/api +apps/examples/www/index.css +apps/examples/www/index.js +.tsbuild diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..c8ab71e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,49 @@ +name: Bug report +description: File a bug report +type: Bug +labels: [] +assignees: [] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Describe the bug and what you expected to happen instead. + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: How can we reproduce the bug? + description: | + Please share the steps to reproduce this bug. A [StackBlitz reproduction](https://stackblitz.com/edit/vitejs-vite-ahoswhus?file=src%2FApp.tsx) or screen recording helps us fix it faster. + validations: + required: false + - type: dropdown + id: browsers + validations: + required: false + attributes: + label: What browsers are you seeing the problem on? + multiple: true + options: + - Firefox + - Chrome + - Safari + - Microsoft Edge + - type: dropdown + id: product + attributes: + label: Where did this happen? + options: + - tldraw SDK (@tldraw/tldraw npm package) + - tldraw.com + - tldraw.dev (documentation site) + - VS Code extension + - Obsidian plugin + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..968485a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Documentation + url: https://tldraw.dev + about: Looking for help with the tldraw SDK? Check out the docs. + - name: Discord + url: https://discord.tldraw.com + about: Chat with the community and get help from other developers. diff --git a/.github/ISSUE_TEMPLATE/example_request.yml b/.github/ISSUE_TEMPLATE/example_request.yml new file mode 100644 index 0000000..0c9f8e1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/example_request.yml @@ -0,0 +1,16 @@ +name: Example request +description: Submit a request for an example +labels: [] +assignees: [] +body: + - type: markdown + attributes: + value: | + Need an example of how to do something with tldraw? We're happy to help! + - type: textarea + id: description + attributes: + label: What's the example? + description: Describe the example or the use case you'd like to see demonstrated. + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..4ec9664 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,27 @@ +name: Feature request +description: Suggest a new feature or improvement +type: Feature +labels: [] +assignees: [] +body: + - type: markdown + attributes: + value: | + Have an idea for a feature or improvement in tldraw? We'd love to hear it! + - type: textarea + id: description + attributes: + label: What's the feature? + description: Describe the feature, the problem it solves, and any examples from other apps. + validations: + required: true + - type: dropdown + id: product + attributes: + label: Where would you like this feature? + options: + - tldraw SDK (@tldraw/tldraw npm package) + - tldraw.com + - makereal.tldraw.com + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/task.yml b/.github/ISSUE_TEMPLATE/task.yml new file mode 100644 index 0000000..099affd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/task.yml @@ -0,0 +1,13 @@ +name: Task +description: Create a task +type: Task +labels: [] +assignees: [] +body: + - type: textarea + id: description + attributes: + label: Description + description: Describe the task. + validations: + required: true diff --git a/.github/actions/deploy-templates/action.yml b/.github/actions/deploy-templates/action.yml new file mode 100644 index 0000000..3375f9d --- /dev/null +++ b/.github/actions/deploy-templates/action.yml @@ -0,0 +1,69 @@ +name: Deploy templates +description: > + Build the starter-kit demos against the checked-out SDK and deploy the cloudflare-hosted ones to + *.templates.tldraw.dev. Shared by deploy-templates.yml (template changes, manual runs) and + publish.yml (releases). Expects the repo to be checked out already; runs the setup action itself. + +# The cloudflare credentials are secrets on the deploy-production environment, so the job using +# this action has to select that environment and pass them in. This is a composite action rather +# than a workflow_call workflow because a called workflow only ever sees the secrets its caller +# hands it, and an `environment:` on a job inside the callee does not add that environment's +# secrets to them — see #10636. +inputs: + license-key: + description: tldraw license key the demos are built with (TEMPLATES_TLDRAW_LICENSE_KEY) + required: true + cloudflare-account-id: + description: Cloudflare account the workers deploy to (CLOUDFLARE_ACCOUNT_ID) + required: true + cloudflare-api-token: + description: Cloudflare API token with workers permissions (CLOUDFLARE_API_TOKEN) + required: true + +runs: + using: composite + steps: + - uses: ./.github/actions/setup + + # most templates run `tsc` as part of their build, which resolves the workspace packages + # through their project references and so needs the declarations built first + - name: Build types + shell: bash + env: + # build-types pulls in refresh-assets, which rewrites the generated version files. in CI it + # exits 1 on any change to a committed asset instead of writing it, which would fail the + # deploy on a release ref whose generated files aren't already in sync. + ALLOW_REFRESH_ASSETS_CHANGES: 1 + run: yarn build-types + + - name: Deploy templates + shell: bash + env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + ALLOW_REFRESH_ASSETS_CHANGES: 1 + TEMPLATES_TLDRAW_LICENSE_KEY: ${{ inputs.license-key }} + CLOUDFLARE_API_TOKEN: ${{ inputs.cloudflare-api-token }} + CLOUDFLARE_ACCOUNT_ID: ${{ inputs.cloudflare-account-id }} + run: | + # the templates import tldraw/tldraw.css, which is generated and gitignored + yarn lazy prebuild + + cd templates + all_templates=$(ls -d */ | cut -f1 -d'/') + cd .. + + # the demos are independent of each other, so deploy them all before failing: one broken + # template shouldn't leave the rest stranded on an old build with no signal about which. + # templates with no `deploy` config in their package.json skip themselves. + failed="" + for template in $all_templates; do + echo "::group::Deploying $template" + yarn tsx ./internal/scripts/deploy-template.ts $template || failed="$failed $template" + echo "::endgroup::" + done + + if [ -n "$failed" ]; then + echo "::error::Failed to deploy templates:$failed" + exit 1 + fi diff --git a/.github/actions/discord-fail-notify/action.yml b/.github/actions/discord-fail-notify/action.yml new file mode 100644 index 0000000..5b5eca1 --- /dev/null +++ b/.github/actions/discord-fail-notify/action.yml @@ -0,0 +1,32 @@ +name: Discord fail notify +description: Post a failure message to the Discord deploy/health channel. + +inputs: + webhook-url: + description: Discord webhook URL + required: true + status: + description: What happened to the workflow, used in the message verb + required: false + default: failed + +runs: + using: composite + steps: + - name: Notify Discord + shell: bash + env: + DISCORD_WEBHOOK_URL: ${{ inputs.webhook-url }} + WORKFLOW: ${{ github.workflow }} + REF: ${{ github.ref_name }} + STATUS: ${{ inputs.status }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + if [ -z "$DISCORD_WEBHOOK_URL" ]; then + echo "::warning::DISCORD_WEBHOOK_URL is empty; skipping Discord notification." + exit 0 + fi + payload=$(jq -nc \ + --arg content "<@&1414904550917144586> ❌ **${WORKFLOW}** ${STATUS} on \`${REF}\`: <${RUN_URL}>" \ + '{content: $content}') + curl -fsS -X POST -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK_URL" diff --git a/.github/actions/setup-playwright/action.yml b/.github/actions/setup-playwright/action.yml new file mode 100644 index 0000000..6a99df7 --- /dev/null +++ b/.github/actions/setup-playwright/action.yml @@ -0,0 +1,46 @@ +name: 'Setup Playwright' +description: 'Install Playwright browsers with version-keyed caching shared across workflows.' + +inputs: + browsers: + description: 'Space-separated Playwright browsers to install and cache.' + required: false + # Only bundled Chromium by default — every e2e project uses `devices['Desktop Chrome']` / + # `['Pixel 5']` with no `channel`, so the branded `chrome` build is never launched. + default: 'chromium' + +runs: + using: 'composite' + steps: + # @playwright/test is hoisted to the root node_modules (it's a devDependency of the e2e + # workspaces), so Node resolves it from the repo root — no per-workspace cwd, nothing written + # to the tree. We also derive a key-safe browser token (spaces -> dashes) so multi-browser + # values like "chromium firefox" don't put a space in the cache key. + - name: Resolve Playwright version and browsers + shell: bash + env: + BROWSERS: ${{ inputs.browsers }} + run: | + echo "PLAYWRIGHT_VERSION=$(node -p "require('@playwright/test/package.json').version")" >> "$GITHUB_ENV" + echo "PLAYWRIGHT_BROWSERS_KEY=$(echo "$BROWSERS" | tr ' ' '-')" >> "$GITHUB_ENV" + + # Keyed on os + arch + version + browsers. The arch matters (ARM vs x64 need different + # binaries); the browser set matters too — without it, adding a browser would be a stale cache + # hit that skips the install and never downloads the new one. + - name: Check for Playwright browsers cache + id: playwright-cache + uses: actions/cache@v5 + with: + path: | + ~/.cache/ms-playwright + key: ${{ runner.os }}-${{ runner.arch }}-playwright-${{ env.PLAYWRIGHT_VERSION }}-${{ env.PLAYWRIGHT_BROWSERS_KEY }} + + # Cache miss only. `--with-deps` also installs the OS libraries the browsers need — a no-op for + # Chromium on GitHub's runner images, but it means adding webkit/firefox via `browsers` later + # just works without extra setup. + - name: Install Playwright browsers + if: steps.playwright-cache.outputs.cache-hit != 'true' + shell: bash + env: + BROWSERS: ${{ inputs.browsers }} + run: npx playwright install --with-deps $BROWSERS diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..e829707 --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,39 @@ +name: Setup tldraw/tldraw +description: Set up node & yarn + +runs: + using: composite + steps: + # see https://github.com/actions/setup-node/issues/899 for one of the reasons why this + # needs to be done before action/setup-node + - name: Enable corepack + run: npm i -g corepack + shell: bash + + - name: Setup Node.js Environment + id: setup-node + uses: actions/setup-node@v6 + with: + node-version: 24.17.0 + + - name: Restore node_modules cache + uses: actions/cache@v5 + id: node-modules-cache + with: + path: | + node_modules + **/node_modules + .yarn/cache + .yarn/unplugged + .yarn/install-state.gz + key: ${{ runner.os }}-${{ runner.arch }}-node-${{ steps.setup-node.outputs.node-version }}-yarn-${{ hashFiles('yarn.lock', '.yarnrc.yml', '.yarn/patches/*') }} + restore-keys: | + ${{ runner.os }}-${{ runner.arch }}-node-${{ steps.setup-node.outputs.node-version }}-yarn- + + - name: Install dependencies + run: yarn install --immutable + shell: bash + env: + # Hardened mode enables --check-resolutions on public PRs, adding ~15s. + # See https://yarnpkg.com/features/security - Yarn recommends disabling in most jobs. + YARN_ENABLE_HARDENED_MODE: 0 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..2f68627 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,21 @@ +Describe what your pull request does. If you can, add GIFs or images showing the before and after of your change. + +### Change type + +- [ ] `bugfix` +- [ ] `improvement` +- [ ] `feature` +- [ ] `api` +- [ ] `other` + +### Test plan + +1. Create a shape... +2. + +- [ ] Unit tests +- [ ] End to end tests + +### Release notes + +- Fixed a bug with… \ No newline at end of file diff --git a/.github/workflows/bump-versions.yml b/.github/workflows/bump-versions.yml new file mode 100644 index 0000000..a7cebb9 --- /dev/null +++ b/.github/workflows/bump-versions.yml @@ -0,0 +1,73 @@ +name: Bump versions to latest tldraw version +# This bumps all package versions to match the latest tldraw version from npm + +# Prevent more than one version bumping job from running at the same time +concurrency: + group: version-bump + +# Only run on main branch +on: + workflow_dispatch: + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + bump_versions: + name: 'Bump package versions to latest tldraw version' + environment: npm deploy + timeout-minutes: 30 + runs-on: ubuntu-latest-16-cores-arm-open + + steps: + - name: Generate GH token + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.HUPPY_APP_ID }} + private_key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - name: Check out code + id: checkout + uses: actions/checkout@v6 + with: + persist-credentials: false + token: ${{ steps.generate_token.outputs.token }} + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - name: Check branch + run: | + if [[ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]]; then + echo "ERROR This workflow only runs on the main branch." + exit 1 + fi + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Bump versions + run: | + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + yarn tsx ./internal/scripts/bump-versions.ts + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + # Preserve the setup action for post-job cleanup when checkout already succeeded. + - name: Check out Discord notify action + if: failure() && steps.checkout.outcome != 'success' + uses: actions/checkout@v6 + with: + sparse-checkout: .github/actions/discord-fail-notify + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 0000000..8bb211e --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,112 @@ +name: Checks + +on: + pull_request: + merge_group: + push: + branches: [main] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +permissions: + contents: read + # update-pr-template reads the repo's label list (octo.issues.listLabelsForRepo). + issues: read + +jobs: + test: + name: 'Tests & checks' + timeout-minutes: 15 + runs-on: ubuntu-latest-16-cores-arm-open # TODO: this should probably run on multiple OSes + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - uses: ./.github/actions/setup + + - name: Check for duplicate dependencies + run: yarn dedupe --check + + - name: Check packages + run: yarn check-packages + + - name: Check circular dependencies + run: yarn check-circular-deps + + - name: Restore build tool caches + uses: actions/cache@v5 + with: + path: | + .lazy + **/.lazy + **/.tsbuild + **/*.tsbuildinfo + key: test-tools-${{ runner.os }}-${{ hashFiles('yarn.lock', '.oxlintrc.json', '.oxfmtrc.json', 'lazy.config.ts') }} + + - name: Typecheck + run: yarn build-types + + - name: Check bundle sizes + run: yarn lazy check-bundle-size + + - name: Check PR template + run: yarn update-pr-template --check + env: + GH_TOKEN: ${{ github.token }} + + - name: Check API declarations and docs work as intended + run: yarn api-check + + - name: Lint + run: yarn lint + + - name: Check dotcom localizations + run: | + yarn build-i18n + git diff --exit-code --quiet ./apps/dotcom/client/public/tla/locales/ ./apps/dotcom/client/public/tla/locales-compiled/ || (echo "Please run yarn build-i18n and commit the changes" && exit 1) + + # vitest's fsModuleCache (~54MB gzipped). Entries are content-hashed, so a stale + # restore is safe - unmatched modules are just re-transformed. Keyed on yarn.lock so + # one entry is reused across commits instead of saving a new copy on every run. + - name: Restore vitest module cache + uses: actions/cache@v5 + with: + path: node_modules/.vitest-cache + key: vitest-cache-${{ runner.os }}-${{ hashFiles('yarn.lock') }} + restore-keys: vitest-cache-${{ runner.os }}- + + - name: Test + run: yarn test-ci + + build: + name: 'Build all projects' + timeout-minutes: 15 + runs-on: ubuntu-latest-16-cores-arm-open + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - uses: ./.github/actions/setup + + - name: Restore build tool caches + uses: actions/cache@v5 + with: + path: | + .lazy + **/.lazy + **/.tsbuild + **/*.tsbuildinfo + key: build-tools-${{ runner.os }}-${{ hashFiles('yarn.lock', 'lazy.config.ts') }} + + - name: Build packages + # the sed pipe makes sure that github annotations come through without + # turbo's prefix + run: "yarn build-package | sed -E 's/^.*? ::/::/'" diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000..54a5e40 --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,52 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +permissions: + contents: read + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it. + # prompt: 'Update the pull request description to include a summary of changes.' + + # Optional: Add claude_args to customize behavior and configuration + # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md + # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options + # claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)' diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml new file mode 100644 index 0000000..e756725 --- /dev/null +++ b/.github/workflows/close-stale-issues.yml @@ -0,0 +1,37 @@ +name: Close inactive issues +on: + workflow_dispatch: + schedule: + - cron: '0 0 1 * *' + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v10 + with: + days-before-issue-stale: 150 + days-before-issue-close: 30 + stale-issue-label: 'stale' + stale-issue-message: > + This issue has been marked as stale because it has been open for 150 days with no activity. + If there's no further discussion, it'll be closed in 30 days time. + If you would like to ensure it stays open, you can comment on the issue and revive the discussion. + Or, you can add the 'keep' label to prevent it from being closed. + close-issue-message: 'This issue was closed because it has been inactive for 30 days since being marked as stale.' + close-issue-reason: 'not_planned' + days-before-pr-stale: -1 + days-before-pr-close: -1 + operations-per-run: 1000 + exempt-issue-labels: keep + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/dependabot-dedupe.yml b/.github/workflows/dependabot-dedupe.yml new file mode 100644 index 0000000..f06521b --- /dev/null +++ b/.github/workflows/dependabot-dedupe.yml @@ -0,0 +1,41 @@ +name: Dedupe Dependabot PRs + +on: + push: + branches: ['dependabot/**'] + +permissions: + contents: write + pull-requests: write + repository-projects: write + +defaults: + run: + shell: bash + +jobs: + dedupe: + name: Dedupe Dependabot PRs + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - uses: ./.github/actions/setup + + - name: Configure Git + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Dedupe dependencies + run: yarn dedupe + + - name: Commit changes + run: | + git add . + git commit -m 'Dedupe' || true + + - name: Push changes + run: git push diff --git a/.github/workflows/deploy-analytics.yml b/.github/workflows/deploy-analytics.yml new file mode 100644 index 0000000..29fd57d --- /dev/null +++ b/.github/workflows/deploy-analytics.yml @@ -0,0 +1,55 @@ +name: Deploy analytics worker +permissions: + contents: read + deployments: write + +on: + pull_request: + paths: + - 'apps/analytics-worker/**' + - 'internal/scripts/deploy-analytics.ts' + - 'internal/scripts/lib/deploy.ts' + - '.github/workflows/deploy-analytics.yml' + - '.github/actions/setup/**' + push: + branches: + - main + - production + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + TLDRAW_ENV: ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} + +defaults: + run: + shell: bash + +jobs: + deploy: + name: Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} + timeout-minutes: 10 + runs-on: ubuntu-latest + environment: ${{ github.ref == 'refs/heads/production' && 'deploy-production' || 'deploy-staging' }} + concurrency: analytics-worker-${{ github.ref == 'refs/heads/production' && 'deploy-production' || github.ref }} + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + submodules: true + + - uses: ./.github/actions/setup + + - name: Build types + run: yarn build-types + + - name: Deploy + run: yarn tsx internal/scripts/deploy-analytics.ts + env: + RELEASE_COMMIT_HASH: ${{ github.sha }} + GH_TOKEN: ${{ github.token }} + + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/deploy-bemo.yml b/.github/workflows/deploy-bemo.yml new file mode 100644 index 0000000..24f6020 --- /dev/null +++ b/.github/workflows/deploy-bemo.yml @@ -0,0 +1,61 @@ +name: Deploy bemo + +# TODO: add some sort of production trigger +on: + pull_request: + push: + branches: + - main + - bemo-production + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + TLDRAW_ENV: ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} +defaults: + run: + shell: bash + +permissions: + contents: read + # createGithubDeployment (internal/scripts/lib/deploy.ts) registers the deployment that + # renders the 'View Deployment' button on the PR. + deployments: write + +jobs: + deploy: + name: Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} + timeout-minutes: 15 + runs-on: ubuntu-latest + environment: ${{ github.ref == 'refs/heads/bemo-production' && 'bemo-production' || 'bemo-canary' }} + concurrency: bemo-${{ github.ref == 'refs/heads/bemo-production' && 'bemo-production' || github.ref }} + + steps: + # - name: Notify initial start + # uses: MineBartekSA/discord-webhook@v2 + # if: github.ref == 'refs/heads/bemo-production' + # with: + # webhook: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + # content: 'Preparing ${{ env.TLDRAW_ENV }} bemo deploy: ${{ github.event.head_commit.message }} by ${{ github.event.head_commit.author.name }}' + + - name: Check out code + uses: actions/checkout@v6 + with: + submodules: true + + - uses: ./.github/actions/setup + + - name: Build types + run: yarn build-types + + - name: Deploy + run: yarn tsx internal/scripts/deploy-bemo.ts + env: + RELEASE_COMMIT_HASH: ${{ github.sha }} + GH_TOKEN: ${{ github.token }} + + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_BEMO_WORKER_DSN: ${{ secrets.SENTRY_BEMO_WORKER_DSN }} diff --git a/.github/workflows/deploy-dotcom.yml b/.github/workflows/deploy-dotcom.yml new file mode 100644 index 0000000..327fc7a --- /dev/null +++ b/.github/workflows/deploy-dotcom.yml @@ -0,0 +1,215 @@ +name: Deploy .com + +on: + pull_request: + types: [opened, synchronize, labeled, unlabeled] + push: + branches: + - main + - production + +permissions: + contents: read + # createGithubDeployment (internal/scripts/lib/deploy.ts) registers the deployment that + # renders the 'View Deployment' button on the PR. + deployments: write + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + TLDRAW_ENV: ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} + +defaults: + run: + shell: bash + +jobs: + deploy: + name: Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} + timeout-minutes: 15 + runs-on: ubuntu-latest-16-cores-arm-open + environment: ${{ github.ref == 'refs/heads/production' && 'deploy-production' || 'deploy-staging' }} + concurrency: dotcom-${{ github.ref == 'refs/heads/production' && 'deploy-production' || github.ref }} + if: | + github.event_name == 'push' || + (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'dotcom-preview-please')) + + steps: + # - name: Notify initial start + # uses: MineBartekSA/discord-webhook@v2 + # if: github.ref == 'refs/heads/production' + # with: + # webhook: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + # content: 'Preparing ${{ env.TLDRAW_ENV }} dotcom deploy: ${{ github.event.head_commit.message }} by ${{ github.event.head_commit.author.name }}' + + - name: Check out code + uses: actions/checkout@v6 + env: + # Abort a stalled fetch so checkout's retry kicks in instead of hanging until the job timeout + GIT_HTTP_LOW_SPEED_LIMIT: 1000 + GIT_HTTP_LOW_SPEED_TIME: 60 + + - uses: ./.github/actions/setup + + - name: Determine zero deploy target + id: deploy_target + env: + GH_TOKEN: ${{ github.token }} + run: | + if [[ "${GITHUB_REF}" == "refs/heads/production" ]]; then + echo "DEPLOY_ZERO=flyio-multinode" >> $GITHUB_ENV + elif [[ "${GITHUB_REF}" == "refs/heads/main" ]]; then + echo "DEPLOY_ZERO=flyio-multinode" >> $GITHUB_ENV + else + echo "DEPLOY_ZERO=flyio" >> $GITHUB_ENV + fi + + - name: Install Supabase CLI + if: github.event_name == 'pull_request' + uses: supabase/setup-cli@ab058987d8d6c725971f6cf9d0b5c98467e30bd1 # v1 + with: + # Pinned: v2.112.0 rejects the Management API's own timestamps, which + # breaks `branches get` and `branches delete`. See supabase/cli#6115. + version: 2.111.0 + + - name: Delete Supabase branch + if: contains(github.event.pull_request.labels.*.name, 'reset-preview-db') + env: + SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} + run: | + supabase branches delete "pr-${{ github.event.number }}" \ + --project-ref "${{ vars.SUPABASE_PREVIEW_PROJECT_ID }}" || echo "::warning::Failed to delete Supabase branch (may not exist yet)" + + - name: Create Supabase preview branch + if: github.event_name == 'pull_request' + env: + SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} + run: | + BRANCH_NAME="pr-${{ github.event.number }}" + PROJECT_REF="${{ vars.SUPABASE_PREVIEW_PROJECT_ID }}" + + # Create branch if it doesn't already exist. + if supabase branches get "$BRANCH_NAME" \ + --project-ref "$PROJECT_REF" > /dev/null 2>&1; then + echo "Branch $BRANCH_NAME already exists." + else + supabase branches create "$BRANCH_NAME" --project-ref "$PROJECT_REF" > /dev/null + echo "Branch $BRANCH_NAME created." + fi + + # Wait for branch to be ready, then extract connection strings. + # Write to a temp file to avoid secrets leaking into CI step output. + BRANCH_JSON=$(mktemp) + for i in $(seq 1 24); do + # While the branch is still provisioning, `branches get` may exit + # non-zero and/or write a non-JSON line to stdout (the newer CLI + # renders an error there). Tolerate both: `|| true` keeps `set -e` + # from aborting on a non-zero get, and the guarded jq below treats + # any non-JSON / missing field as "not ready yet" so the loop retries. + supabase branches get "$BRANCH_NAME" \ + --project-ref "$PROJECT_REF" \ + -o json > "$BRANCH_JSON" 2>/dev/null || true + POSTGRES_URL_TRANSACTION=$(jq -r '.POSTGRES_URL // empty' "$BRANCH_JSON" 2>/dev/null || true) + if [ -n "$POSTGRES_URL_TRANSACTION" ]; then + echo "Branch $BRANCH_NAME is ready." + break + fi + echo "Waiting for branch to be ready ($i/24)..." + sleep 5 + done + POSTGRES_URL_NON_POOLING=$(jq -r '.POSTGRES_URL_NON_POOLING // empty' "$BRANCH_JSON" 2>/dev/null || true) + rm "$BRANCH_JSON" + + if [ -z "$POSTGRES_URL_TRANSACTION" ]; then + echo "::error::Branch not ready after 2 minutes — POSTGRES_URL still empty" + exit 1 + fi + + if [ -z "$POSTGRES_URL_NON_POOLING" ] || [ "$POSTGRES_URL_NON_POOLING" = "null" ]; then + echo "::error::Failed to get POSTGRES_URL_NON_POOLING from branch" + exit 1 + fi + + # Rewrite transaction pooler (port 6543, IPv6-only) to session pooler + # (port 5432, IPv4-compatible) since GitHub Actions runners are IPv4-only. + POSTGRES_URL="${POSTGRES_URL_TRANSACTION/:6543/:5432}" + + echo "::add-mask::$POSTGRES_URL" + echo "::add-mask::$POSTGRES_URL_TRANSACTION" + echo "::add-mask::$POSTGRES_URL_NON_POOLING" + echo "POSTGRES_URL=$POSTGRES_URL" >> "$GITHUB_ENV" + echo "POSTGRES_URL_NON_POOLING=$POSTGRES_URL_NON_POOLING" >> "$GITHUB_ENV" + + - name: Build types + run: yarn build-types + + - name: Setup Fly cli + if: env.DEPLOY_ZERO == 'flyio' || env.DEPLOY_ZERO == 'flyio-multinode' + uses: superfly/flyctl-actions/setup-flyctl@ed8efb33836e8b2096c7fd3ba1c8afe303ebbff1 # 1.6 + + - name: Deploy + run: yarn tsx internal/scripts/deploy-dotcom.ts + env: + RELEASE_COMMIT_HASH: ${{ github.sha }} + GH_TOKEN: ${{ github.token }} + + APP_ORIGIN: ${{ vars.APP_ORIGIN }} + ASSET_UPLOAD: ${{ vars.ASSET_UPLOAD }} + IMAGE_WORKER: ${{ vars.IMAGE_WORKER }} + MULTIPLAYER_SERVER: ${{ vars.MULTIPLAYER_SERVER }} + USER_CONTENT_SENTRY_DSN: ${{ secrets.USER_CONTENT_SENTRY_DSN }} + USER_CONTENT_URL: ${{ vars.USER_CONTENT_URL }} + NEXT_PUBLIC_GOOGLE_CLOUD_PROJECT_NUMBER: ${{ vars.NEXT_PUBLIC_GOOGLE_CLOUD_PROJECT_NUMBER }} + SUPABASE_LITE_URL: ${{ vars.SUPABASE_LITE_URL }} + VERCEL_ORG_ID: ${{ vars.VERCEL_ORG_ID }} + VERCEL_PROJECT_ID: ${{ vars.VERCEL_DOTCOM_PROJECT_ID }} + + ANALYTICS_API_URL: ${{ secrets.ANALYTICS_API_URL }} + ANALYTICS_API_TOKEN: ${{ secrets.ANALYTICS_API_TOKEN }} + ASSET_UPLOAD_SENTRY_DSN: ${{ secrets.ASSET_UPLOAD_SENTRY_DSN }} + BOTCOM_POSTGRES_CONNECTION_STRING: ${{ env.POSTGRES_URL_NON_POOLING || secrets.BOTCOM_POSTGRES_CONNECTION_STRING }} + BOTCOM_POSTGRES_POOLED_CONNECTION_STRING: ${{ env.POSTGRES_URL || secrets.BOTCOM_POSTGRES_POOLED_CONNECTION_STRING }} + CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + MCP_SCREENSHOT_TOKEN_SECRET: ${{ secrets.MCP_SCREENSHOT_TOKEN_SECRET }} + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + DISCORD_FEEDBACK_WEBHOOK_URL: ${{ secrets.DISCORD_FEEDBACK_WEBHOOK_URL }} + PLAIN_API_KEY: ${{ secrets.PLAIN_API_KEY }} + PLAIN_LABEL_TYPE_ID: ${{ secrets.PLAIN_LABEL_TYPE_ID }} + PLAIN_WORKSPACE_ID: ${{ secrets.PLAIN_WORKSPACE_ID }} + DISCORD_HEALTH_WEBHOOK_URL: ${{ secrets.DISCORD_HEALTH_WEBHOOK_URL }} + GC_MAPS_API_KEY: ${{ secrets.GC_MAPS_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + HEALTH_CHECK_BEARER_TOKEN: ${{ secrets.HEALTH_CHECK_BEARER_TOKEN }} + HEALTH_WORKER_UPDOWN_WEBHOOK_PATH: ${{ secrets.HEALTH_WORKER_UPDOWN_WEBHOOK_PATH }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_CSP_REPORT_URI: ${{ secrets.SENTRY_CSP_REPORT_URI }} + SENTRY_DSN: ${{ secrets.SENTRY_DSN }} + SUPABASE_LITE_ANON_KEY: ${{ secrets.SUPABASE_LITE_ANON_KEY }} + TLDRAW_LICENSE: ${{ secrets.TLDRAW_LICENSE }} + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VITE_CLERK_PUBLISHABLE_KEY: ${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }} + VITE_POSTHOG_KEY: ${{ secrets.VITE_POSTHOG_KEY }} + VITE_GA4_MEASUREMENT_ID: ${{ secrets.VITE_GA4_MEASUREMENT_ID }} + WORKER_SENTRY_DSN: ${{ secrets.WORKER_SENTRY_DSN }} + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + ZERO_ADMIN_PASSWORD: ${{ secrets.ZERO_ADMIN_PASSWORD }} + ZERO_R2_ENDPOINT: ${{ secrets.ZERO_R2_ENDPOINT }} + ZERO_R2_BUCKET_NAME: ${{ secrets.ZERO_R2_BUCKET_NAME }} + ZERO_R2_ACCESS_KEY_ID: ${{ secrets.ZERO_R2_ACCESS_KEY_ID }} + ZERO_R2_SECRET_ACCESS_KEY: ${{ secrets.ZERO_R2_SECRET_ACCESS_KEY }} + ZERO_OTEL_EXPORTER_OTLP_ENDPOINT: ${{ secrets.ZERO_OTEL_EXPORTER_OTLP_ENDPOINT }} + ZERO_OTEL_EXPORTER_OTLP_HEADERS: ${{ secrets.ZERO_OTEL_EXPORTER_OTLP_HEADERS }} + + # The deploy script posts its own "Deploy failed" message, but a job timeout + # kills it without running that handler, so cover the cancelled case here. + - name: Notify Discord on cancelled deploy + if: cancelled() && github.event_name == 'push' + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + status: was cancelled (job timeout?) diff --git a/.github/workflows/deploy-grafana.yml b/.github/workflows/deploy-grafana.yml new file mode 100644 index 0000000..c8a807b --- /dev/null +++ b/.github/workflows/deploy-grafana.yml @@ -0,0 +1,115 @@ +name: Deploy grafana resources +permissions: + contents: read + +on: + pull_request: + paths: + - 'internal/grafana/**' + - '.github/workflows/deploy-grafana.yml' + push: + branches: + - main + paths: + - 'internal/grafana/**' + - '.github/workflows/deploy-grafana.yml' + +defaults: + run: + shell: bash + +env: + GCX_VERSION: 1.0.0 + GCX_SHA256: c88c65958d19d83dc3a192a2a5037e08307a9c776019f24249b89f369c9c4d41 + +jobs: + deploy: + name: ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} + # Validate and push both need the Grafana secrets, which fork PRs don't get. + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository + timeout-minutes: 10 + runs-on: ubuntu-latest + concurrency: grafana-deploy-${{ github.event_name == 'push' && 'main' || github.ref }} + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Install gcx + run: | + curl -fsSL -o gcx.tar.gz "https://github.com/grafana/gcx/releases/download/v${GCX_VERSION}/gcx_${GCX_VERSION}_linux_amd64.tar.gz" + echo "${GCX_SHA256} gcx.tar.gz" | sha256sum -c - + tar xzf gcx.tar.gz gcx + sudo mv gcx /usr/local/bin/gcx + gcx --version + + - name: Validate resources + run: gcx resources validate -p internal/grafana/resources + env: + GRAFANA_SERVER: ${{ secrets.GRAFANA_SERVER }} + GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }} + + - name: Dry run + if: github.event_name == 'pull_request' + run: gcx resources push -p internal/grafana/resources --dry-run --on-error abort + env: + GRAFANA_SERVER: ${{ secrets.GRAFANA_SERVER }} + GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }} + + # Everything except alert rules, folders first. Two orderings matter and neither is + # the alphabetical one this glob would otherwise give: folders have to exist before + # anything annotated into them, and alert rules go last (see the step below for why). + # A commit adding a folder and a dashboard inside it lands both in one push, so the + # folder cannot be assumed to already be there. + - name: Push resources + if: github.event_name == 'push' + run: | + shopt -s nullglob + for dir in internal/grafana/resources/*folders*/; do + gcx resources push -p "$dir" --on-error abort + done + for dir in internal/grafana/resources/*/; do + case "$dir" in *folders*|*alertrules*) continue ;; esac + gcx resources push -p "$dir" --on-error abort + done + env: + GRAFANA_SERVER: ${{ secrets.GRAFANA_SERVER }} + GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }} + + # Alert rules are the one resource type that can fail here having passed the PR + # dry run, because alerting has no server-side dry-run — the PR reports them as + # "skipped". A newly created rule carrying group labels is rejected outright + # ("cannot set group when creating a new rule"), so the first time any new rule + # lands, this step is where it surfaces. Kept last and separate so that failure + # costs the rule, not every dashboard in the tree. Still fails the job. + - name: Push alert rules + if: github.event_name == 'push' + run: | + shopt -s nullglob + for dir in internal/grafana/resources/*alertrules*/; do + gcx resources push -p "$dir" --on-error abort + done + env: + GRAFANA_SERVER: ${{ secrets.GRAFANA_SERVER }} + GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }} + + # Notification templates can't go through `gcx resources push` — gcx's discovery + # registry ignores the notifications.alerting.grafana.app API group entirely — so + # template files live in templates/ (not resources/) and go through the classic + # provisioning API. The PUT is idempotent and sets `api` provenance, which locks + # UI edits the same way provisioned resources are locked. + - name: Push notification templates + if: github.event_name == 'push' + run: | + shopt -s nullglob + for f in internal/grafana/templates/*.gotmpl; do + name=$(basename "$f" .gotmpl) + jq -Rs '{template: .}' "$f" | curl -fsS -X PUT \ + "$GRAFANA_SERVER/api/v1/provisioning/templates/$name" \ + -H "Authorization: Bearer $GRAFANA_TOKEN" \ + -H "Content-Type: application/json" \ + -d @- > /dev/null + done + env: + GRAFANA_SERVER: ${{ secrets.GRAFANA_SERVER }} + GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }} diff --git a/.github/workflows/deploy-mcp-app.yml b/.github/workflows/deploy-mcp-app.yml new file mode 100644 index 0000000..24d1799 --- /dev/null +++ b/.github/workflows/deploy-mcp-app.yml @@ -0,0 +1,63 @@ +name: Deploy MCP app + +on: + # Auto-deploy whenever production is updated, keeping the public MCP worker on + # the same commit and SDK build as production dotcom. Only production triggers a + # deploy: there is no staging worker, so a push to main must not overwrite the + # shared `tldraw-mcp-app` worker. + push: + branches: + - production + workflow_dispatch: + inputs: + target: + description: 'Target ref to deploy' + required: true + default: 'production' + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + TLDRAW_ENV: production + TARGET: ${{ github.event.inputs.target || github.ref_name }} + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + deploy: + name: Deploy MCP app to production + timeout-minutes: 10 + runs-on: ubuntu-latest + environment: deploy-production + concurrency: mcp-app-deploy-production + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + ref: ${{ env.TARGET }} + submodules: true + fetch-depth: 0 + + - uses: ./.github/actions/setup + + - name: Build types + run: yarn build-types + + - name: Deploy + run: yarn workspace mcp-app deploy + env: + VITE_TLDRAW_LICENSE_KEY: ${{ secrets.MCP_APP_TLDRAW_LICENSE_KEY }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/deploy-templates.yml b/.github/workflows/deploy-templates.yml new file mode 100644 index 0000000..6eee2b2 --- /dev/null +++ b/.github/workflows/deploy-templates.yml @@ -0,0 +1,57 @@ +name: Deploy templates + +# Deploys the cloudflare-hosted starter kit demos at *.templates.tldraw.dev, which are the live +# embeds on the docs pages. Two things should reach them: a change to a template (so edits go live +# without waiting for a release), and a release (so the demos pick up the new SDK — an SDK bump +# never touches templates/, so the path filter alone would never fire for one). This workflow +# covers the first; publish.yml covers the second with a job of its own, using the same +# .github/actions/deploy-templates steps. +# +# The vercel-hosted demos (chat, shader, workflow) deploy through vercel's own git integration and +# aren't handled here. +on: + push: + branches: + - main + paths: + - 'templates/**' + workflow_dispatch: + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + deploy: + name: Deploy templates + # CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID are secrets on this environment rather than on + # the repository, so the job has to select it to see them at all. + environment: deploy-production + timeout-minutes: 60 + runs-on: ubuntu-latest-16-cores-arm-open + # a release deploy and a template-change deploy can otherwise race each other onto the same + # custom domains, and the loser silently wins. + concurrency: + group: deploy-templates + cancel-in-progress: false + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - uses: ./.github/actions/deploy-templates + with: + license-key: ${{ secrets.TEMPLATES_TLDRAW_LICENSE_KEY }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/e2e-device.yml b/.github/workflows/e2e-device.yml new file mode 100644 index 0000000..b9b3b5d --- /dev/null +++ b/.github/workflows/e2e-device.yml @@ -0,0 +1,183 @@ +name: End to end tests (device) + +# Run-on-request device-realistic e2e tests. +# +# These run real Mobile Safari (iOS Simulator) and real Chrome (Android emulator) +# through the OS input pipeline via Appium + WebdriverIO. Unlike the Playwright +# suite, this exercises the browser's own gesture recogniser and platform +# behaviour, so it can catch regressions that synthetic DOM events (CDP) cannot. +# It currently covers multi-touch gestures (pinch), but the harness is meant to +# grow to other device-specific behaviour (exports, clipboard, shortcuts, etc.) +# and other platforms. +# +# It is slower and a bit flaky by nature, so it is NOT part of the per-PR checks. +# Trigger it on demand: +# +# - Manually from the Actions tab (workflow_dispatch), choosing the platform. +# - By adding the `e2e-device-tests` label to a PR that touches device behaviour. + +on: + workflow_dispatch: + inputs: + platform: + description: Which platform(s) to run + type: choice + default: both + options: [both, ios, android] + ios_device: + description: iOS simulator device name (optional; auto-picks newest iPhone if empty) + type: string + default: '' + pull_request: + types: [labeled] + +env: + CI: 1 + EXAMPLES_PORT: '5420' + +defaults: + run: + shell: bash + +# A new push to a PR (or a re-dispatch) cancels the previous in-flight run. +concurrency: + group: e2e-device-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + ios: + name: iOS Safari + # Run when dispatched with ios/both, or when a PR is labelled `e2e-device-tests`. + if: > + (github.event_name == 'workflow_dispatch' && inputs.platform != 'android') || + (github.event_name == 'pull_request' && github.event.label.name == 'e2e-device-tests') + runs-on: macos-26 # pinned: image version determines Xcode + iOS sim runtimes + timeout-minutes: 40 + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Install Appium and the XCUITest driver + run: | + npm i -g appium@3 + appium driver install xcuitest + + - name: Resolve Xcode version (WDA cache key) + id: xcode + run: echo "version=$(xcodebuild -version | head -1 | awk '{print $2}')" >> "$GITHUB_OUTPUT" + + - name: Cache WebDriverAgent build + # WDA is rebuilt from source on a cold simulator (~3.5 min). Cache its + # DerivedData keyed on the Xcode version so iterating on test fixes reuses + # the prebuilt WDA instead of rebuilding. Bump the trailing -vN to bust. + id: wda-cache + uses: actions/cache@v5 + with: + path: ${{ runner.temp }}/wda-derived + key: wda-${{ runner.os }}-xcode-${{ steps.xcode.outputs.version }}-v1 + + - name: Boot iOS simulator + id: sim + # A fresh iOS simulator's first boot runs slow one-time migration plugins + # that exceed XCUITest's boot-wait. So boot ONE simulator here, wait for it + # to finish (`bootstatus -b`), and hand its UDID to Appium so it attaches to + # the ready device instead of booting its own. The available iPhone models + # depend on the Xcode the runner image ships, so auto-pick rather than + # hardcode a name (an explicit `ios_device` input wins if it matches). + env: + DEVICE_NAME: ${{ inputs.ios_device }} + run: | + xcrun simctl list devices available + SEL=$(xcrun simctl list devices available --json | node -e ' + const data = JSON.parse(require("fs").readFileSync(0, "utf8")); + const want = process.env.DEVICE_NAME || ""; + const runtimes = Object.keys(data.devices).filter(r => r.includes("iOS")).sort().reverse(); + const phones = []; + for (const r of runtimes) for (const d of (data.devices[r] || [])) { + if (d.isAvailable !== false && d.name.startsWith("iPhone")) phones.push(d); + } + const pick = (want && phones.find(d => d.name === want)) || phones[0]; + if (!pick) process.exit(2); + process.stdout.write(pick.udid + "|" + pick.name); + ') || { echo "No available iPhone simulator on this runner"; exit 1; } + UDID="${SEL%%|*}" + NAME="${SEL#*|}" + echo "Using $NAME ($UDID)" + xcrun simctl boot "$UDID" || true + xcrun simctl bootstatus "$UDID" -b + echo "udid=$UDID" >> "$GITHUB_OUTPUT" + echo "name=$NAME" >> "$GITHUB_OUTPUT" + + - name: Serve built examples + run: yarn preview --port "$EXAMPLES_PORT" & + working-directory: apps/examples + + - name: Wait for examples server + run: npx --yes wait-on "http://localhost:$EXAMPLES_PORT/end-to-end" -t 120000 + + - name: Run device tests (iOS) + run: yarn e2e-device-ios + working-directory: apps/examples + env: + APPIUM_DEVICE_NAME: ${{ steps.sim.outputs.name }} + APPIUM_UDID: ${{ steps.sim.outputs.udid }} + # Build WDA into the cached dir; reuse the prebuilt one on a cache hit. + APPIUM_DERIVED_DATA_PATH: ${{ runner.temp }}/wda-derived + APPIUM_USE_PREBUILT_WDA: ${{ steps.wda-cache.outputs.cache-hit }} + + android: + name: Android Chrome + if: > + (github.event_name == 'workflow_dispatch' && inputs.platform != 'ios') || + (github.event_name == 'pull_request' && github.event.label.name == 'e2e-device-tests') + runs-on: ubuntu-latest + timeout-minutes: 40 + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Enable KVM (hardware acceleration for the emulator) + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ + | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Install Appium and the UiAutomator2 driver + run: | + npm i -g appium@3 + appium driver install uiautomator2 + + - name: Serve built examples + run: yarn preview --port "$EXAMPLES_PORT" & + working-directory: apps/examples + + - name: Wait for examples server + run: npx --yes wait-on "http://localhost:$EXAMPLES_PORT/end-to-end" -t 120000 + + - name: Run device tests on emulator + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 34 + arch: x86_64 + target: google_apis + # The emulator's `localhost` is the emulator itself, so forward the host + # dev server into it before running the tests. + script: | + adb reverse tcp:${{ env.EXAMPLES_PORT }} tcp:${{ env.EXAMPLES_PORT }} + cd apps/examples && yarn e2e-device-android diff --git a/.github/workflows/get-changelog.yml b/.github/workflows/get-changelog.yml new file mode 100644 index 0000000..072737e --- /dev/null +++ b/.github/workflows/get-changelog.yml @@ -0,0 +1,35 @@ +name: Get draft changelog + +on: + workflow_dispatch: + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + deploy: + name: 'Get draft changlog' + timeout-minutes: 60 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Extract changelog + run: yarn extract-draft-changelog + + - name: Upload changelog.md to artifacts + uses: actions/upload-artifact@v6 + with: + name: changelog-output + path: changelog.md diff --git a/.github/workflows/i18n-download-strings.yml b/.github/workflows/i18n-download-strings.yml new file mode 100644 index 0000000..dad79fa --- /dev/null +++ b/.github/workflows/i18n-download-strings.yml @@ -0,0 +1,73 @@ +name: i18n download strings +on: + workflow_dispatch: + schedule: + - cron: '0 10 * * 1' + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + download: + name: 'Download latest strings' + runs-on: ubuntu-latest + environment: 'deploy-production' + + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push the + # added or changed files to the repository. + contents: write + pull-requests: write + repository-projects: write + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - uses: ./.github/actions/setup + + - name: Download i18n strings + run: 'yarn i18n-download-strings' + env: + LOKALISE_API_TOKEN: ${{ secrets.LOKALISE_API_TOKEN }} + LOKALISE_PROJECT_ID: ${{ secrets.LOKALISE_PROJECT_ID }} + LOKALISE_TLDRAW_PROJECT_ID: ${{ secrets.LOKALISE_TLDRAW_PROJECT_ID }} + + - name: Compile i18n strings + run: 'yarn build-i18n' + + - name: Validate the strings + run: 'yarn i18n-check -f react-intl --locales ./apps/dotcom/client/public/tla/locales/ --source en --only invalidKeys' + + - name: Commit and push changes + env: + GH_TOKEN: ${{ github.token }} + run: | + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + + # Check if there are any changes to JSON files + if ! git diff --quiet '*.json' || ! git diff --cached --quiet '*.json'; then + echo "Changes detected, creating PR..." + else + echo "No changes to commit" + exit 0 + fi + + # Delete the branch if it already exists + git push origin --delete update-i18n-strings 2>/dev/null || true + + git checkout -b update-i18n-strings + git add "*.json" + git commit --no-verify -m '[automated] update i18n strings' + git push --set-upstream origin update-i18n-strings + gh pr create --title "[automated] update i18n strings" --body "This PR updates the i18n strings. + + ### Change type + - [x] \`other\`" --base main --head update-i18n-strings diff --git a/.github/workflows/i18n-upload-strings.yml b/.github/workflows/i18n-upload-strings.yml new file mode 100644 index 0000000..2ad3187 --- /dev/null +++ b/.github/workflows/i18n-upload-strings.yml @@ -0,0 +1,35 @@ +name: i18n upload strings +on: + workflow_dispatch: + push: + branches: [main] + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + upload: + name: 'Upload latest strings' + runs-on: ubuntu-latest + environment: 'deploy-production' + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - uses: ./.github/actions/setup + + - name: Upload i18n strings + run: 'yarn i18n-upload-strings' + env: + LOKALISE_API_TOKEN: ${{ secrets.LOKALISE_API_TOKEN }} + LOKALISE_PROJECT_ID: ${{ secrets.LOKALISE_PROJECT_ID }} + LOKALISE_TLDRAW_PROJECT_ID: ${{ secrets.LOKALISE_TLDRAW_PROJECT_ID }} + LOKALISE_TEAM_ID: ${{ secrets.LOKALISE_TEAM_ID }} + LOKALISE_CARD_ID: ${{ secrets.LOKALISE_CARD_ID }} diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml new file mode 100644 index 0000000..846b25a --- /dev/null +++ b/.github/workflows/issue-triage.yml @@ -0,0 +1,122 @@ +name: Issue Triage + +on: + issues: + types: [opened] + workflow_dispatch: + inputs: + issue_number: + description: 'Issue number to triage (for testing)' + required: true + type: number + +permissions: + contents: read + +jobs: + triage: + runs-on: ubuntu-latest + permissions: + contents: read + issues: write + id-token: write + env: + ISSUE_NUMBER: ${{ github.event.issue.number || inputs.issue_number }} + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - name: Get issue details + id: issue + env: + GH_TOKEN: ${{ github.token }} + run: | + gh issue view ${{ env.ISSUE_NUMBER }} --json title,body,labels,state > /tmp/issue.json + # Fetch issue type via API (not yet supported in gh CLI) + ISSUE_TYPE=$(gh api repos/${{ github.repository }}/issues/${{ env.ISSUE_NUMBER }} --jq '.type.name // "none"') + # Merge the type into the JSON + jq --arg type "$ISSUE_TYPE" '. + {issueType: $type}' /tmp/issue.json > /tmp/issue_with_type.json + echo "details<> $GITHUB_OUTPUT + cat /tmp/issue_with_type.json >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Triage Issue with Claude + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + prompt: | + You are an issue triage bot for the tldraw repository. Tidy up issue #${{ env.ISSUE_NUMBER }}. + + ## Issue details + ```json + ${{ steps.issue.outputs.details }} + ``` + + ## Tasks + + ### 1. Improve the title (if needed) + - Make sure the title is clear and descriptive + - Use sentence case (capitalize only first word and proper nouns) + - For bugs: describe the symptom (e.g., "Arrow bindings break with rotated shapes") + - For features: use imperative mood (e.g., "Add padding option to zoomToFit") + - If the title is already good, leave it as-is + + ### 2. Improve the body (if needed) + - If the issue is written in a language other than English, add an English translation at the top of the body (keep the original text below) + - Make sure the body has enough context to understand the issue + - If the body is already good, leave it as-is + + To update the title or body: + ```bash + gh issue edit ${{ env.ISSUE_NUMBER }} --title "New title" --body "New body" + ``` + + ### 3. Set the issue type + Determine if this is a: + - **Bug**: Something is broken or not working as designed (crashes, rendering errors, data loss) + - **Feature**: A request for new functionality or enhancements (including UX preferences like "I wish X worked like Y") + - **Task**: Internal team task + - **Example**: Request for a new SDK example + + Important: Distinguish between TRUE bugs and UX preferences disguised as bugs: + - TRUE BUG: "Clicking save crashes the app" or "Text doesn't render correctly" + - NOT A BUG (use Feature): "I don't like the color of the button" or "The menu should be on the left instead of right" + + To set or change the issue type: + ```bash + gh api repos/${{ github.repository }}/issues/${{ env.ISSUE_NUMBER }} -X PATCH -f type="Bug" + ``` + Replace "Bug" with the appropriate type (Bug, Feature, Task, or Example). + + ### 4. Apply appropriate labels + Use these labels as appropriate: + - `sdk` - Affects the tldraw SDK (@tldraw/tldraw package) + - `dotcom` - Related to tldraw.com + - `docs` - Changes only affect documentation + - `examples` - Request for a new SDK example + - `performance` - Performance-related issues + - `a11y` - Accessibility-related issues + - `bugfix` - For confirmed bug fixes + - `feature` - For new features + - `improvement` - For product improvements + - `More Info Needed` - If the issue lacks critical information needed to understand or reproduce + + ### 5. Assign a milestone (if appropriate) + If the issue clearly fits one of these milestones, assign it. Otherwise, leave the milestone empty. + + Available milestones: + - **Improve developer resources**: For examples, documentation, improved code comments, starter kits, and `npm create tldraw` improvements + - **Improve automations**: For GitHub Actions, review bots, CI/CD, and other automation improvements + + To assign a milestone: + ```bash + gh issue edit ${{ env.ISSUE_NUMBER }} --milestone "Milestone Name" + ``` + + Only assign a milestone if there's a clear fit. Most issues won't need a milestone. + + ## Output format + Use the GitHub CLI (`gh`) to make any changes. Do NOT add comments to the issue. + claude_args: '--allowedTools "Bash(gh issue:*),Bash(gh api:*)"' diff --git a/.github/workflows/license-report.yml b/.github/workflows/license-report.yml new file mode 100644 index 0000000..808e1be --- /dev/null +++ b/.github/workflows/license-report.yml @@ -0,0 +1,52 @@ +name: Update license report + +# Skipped on PRs from forks: the push below needs write access to the head branch. + +permissions: + contents: write + +on: + pull_request: + paths: + - '**/package.json' + - 'yarn.lock' + - 'internal/scripts/license-report.ts' + - '.github/workflows/license-report.yml' + +env: + CI: 1 + +defaults: + run: + shell: bash + +jobs: + update: + name: 'Update license report' + if: github.event.pull_request.head.repo.full_name == github.repository + timeout-minutes: 15 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + token: ${{ secrets.GITHUB_TOKEN }} + # `pull_request` checks out a detached merge commit, which we can't push back to. + ref: ${{ github.event.pull_request.head.ref }} + + - uses: ./.github/actions/setup + + - name: Configure Git + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Generate license report + run: yarn license-report --prod + + - name: Commit changes + run: | + git add apps/docs/content/community/dependencies.mdx + git diff --cached --quiet || git commit -m 'Update license report' + git push diff --git a/.github/workflows/playwright-dotcom.yml b/.github/workflows/playwright-dotcom.yml new file mode 100644 index 0000000..642957e --- /dev/null +++ b/.github/workflows/playwright-dotcom.yml @@ -0,0 +1,129 @@ +name: End to end tests (dotcom) + +on: + pull_request: + merge_group: + push: + branches: [main] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + TLDRAW_ENV: 'development' + # process-compose (the dev-app orchestrator) has no TTY in CI — run it headless. + PC_DISABLE_TUI: '1' + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + check: + name: 'Check for relevant changes' + runs-on: ubuntu-latest + if: ${{ github.event.pull_request.head.repo.fork == false }} + outputs: + relevant: ${{ steps.includes.outputs.match == 'true' && steps.nondocs.outputs.match == 'true' }} + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Check for changes to relevant paths + uses: dorny/paths-filter@v3 + id: includes + with: + filters: | + match: + - 'packages/**' + - 'apps/dotcom/**' + - '.github/workflows/playwright-dotcom.yml' + - '.github/actions/**' + - 'yarn.lock' + + - name: Check for any non-doc changes + uses: dorny/paths-filter@v3 + id: nondocs + with: + predicate-quantifier: 'every' + filters: | + match: + - '**' + - '!**/*.md' + - '!**/*.mdx' + + build: + name: 'End to end tests (dotcom)' + needs: check + if: needs.check.outputs.relevant == 'true' + timeout-minutes: 20 + runs-on: ubuntu-latest-8-cores-open + environment: 'e2e-dotcom' + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + # No process-compose install step: `yarn dev-app` (the e2e webServer) calls the `process-compose` + # bin of @tldraw/scripts, which fetches the pinned binary on first use. + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Build dotcom client + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && yarn run -T lazy run build-i18n && cd apps/dotcom/client && yarn build + env: + VITE_CLERK_PUBLISHABLE_KEY: ${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }} + + - name: Run Playwright tests + run: | + echo "CLERK_PUBLISHABLE_KEY=${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }}" > apps/dotcom/sync-worker/.dev.vars + echo "CLERK_SECRET_KEY=${{ secrets.CLERK_SECRET_KEY }}" >> apps/dotcom/sync-worker/.dev.vars + yarn e2e-dotcom + env: + VITE_CLERK_PUBLISHABLE_KEY: ${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }} + CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} + if: ${{!contains(github.event.pull_request.labels.*.name, 'e2e-x10') }} + + - name: Run Playwright tests (x10) + run: | + echo "CLERK_PUBLISHABLE_KEY=${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }}" > apps/dotcom/sync-worker/.dev.vars + echo "CLERK_SECRET_KEY=${{ secrets.CLERK_SECRET_KEY }}" >> apps/dotcom/sync-worker/.dev.vars + yarn e2e-dotcom-x10 + env: + VITE_CLERK_PUBLISHABLE_KEY: ${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }} + CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} + if: contains(github.event.pull_request.labels.*.name, 'e2e-x10') + + - uses: actions/upload-artifact@v6 + if: always() + with: + name: playwright-report + path: apps/dotcom/client/playwright-report + retention-days: 30 + + - uses: shallwefootball/s3-upload-action@0d261a6f15b3b2e209dfebdecace4b100c04f95b # master + # only upload if we have AWS credentials: + env: + HAS_AWS_KEY: ${{ secrets.AWS_S3_SECRET_KEY && '1' || '' }} + if: always() && env.HAS_AWS_KEY == '1' + name: Upload S3 + id: s3 + with: + aws_key_id: ${{ secrets.AWS_S3_KEY_ID }} + aws_secret_access_key: ${{ secrets.AWS_S3_SECRET_KEY}} + aws_bucket: playwright.tldraw.xyz + source_dir: apps/dotcom/client/playwright-report + + - name: Log report to summary + if: always() + run: | + report_url="https://playwright.tldraw.xyz/${{ steps.s3.outputs.object_key }}/index.html" + echo "Report: $report_url" + echo "## Playwright report" >> $GITHUB_STEP_SUMMARY + echo "* $report_url" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/playwright-examples.yml b/.github/workflows/playwright-examples.yml new file mode 100644 index 0000000..fc41be7 --- /dev/null +++ b/.github/workflows/playwright-examples.yml @@ -0,0 +1,106 @@ +name: End to end tests (examples) + +on: + pull_request: + merge_group: + push: + branches: [main] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + check: + name: 'Check for relevant changes' + runs-on: ubuntu-latest + outputs: + relevant: ${{ steps.includes.outputs.match == 'true' && steps.nondocs.outputs.match == 'true' }} + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Check for changes to relevant paths + uses: dorny/paths-filter@v3 + id: includes + with: + filters: | + match: + - 'packages/**' + - 'apps/examples/**' + - '.github/workflows/playwright-examples.yml' + - '.github/actions/**' + - 'yarn.lock' + + - name: Check for any non-doc changes + uses: dorny/paths-filter@v3 + id: nondocs + with: + predicate-quantifier: 'every' + filters: | + match: + - '**' + - '!**/*.md' + - '!**/*.mdx' + + build: + name: 'End to end tests (examples)' + needs: check + if: needs.check.outputs.relevant == 'true' + timeout-minutes: 20 + runs-on: ubuntu-latest-32-cores-open + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Run Playwright tests + run: 'yarn e2e' + working-directory: apps/examples + env: + GITHUB_REF_NAME: ${{ github.ref_name }} + GIT_COMMIT: ${{ github.sha }} + + - uses: actions/upload-artifact@v6 + if: always() + with: + name: playwright-report + path: apps/examples/playwright-report + retention-days: 30 + + - uses: shallwefootball/s3-upload-action@0d261a6f15b3b2e209dfebdecace4b100c04f95b # master + # only upload if we have AWS credentials: + env: + HAS_AWS_KEY: ${{ secrets.AWS_S3_SECRET_KEY && '1' || '' }} + if: always() && env.HAS_AWS_KEY == '1' + name: Upload S3 + id: s3 + with: + aws_key_id: ${{ secrets.AWS_S3_KEY_ID }} + aws_secret_access_key: ${{ secrets.AWS_S3_SECRET_KEY}} + aws_bucket: playwright.tldraw.xyz + source_dir: apps/examples/playwright-report + + - name: Log report to summary + if: always() + run: | + report_url="https://playwright.tldraw.xyz/${{ steps.s3.outputs.object_key }}/index.html" + echo "Report: $report_url" + echo "## Playwright report" >> $GITHUB_STEP_SUMMARY + echo "* $report_url" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/playwright-mermaid.yml b/.github/workflows/playwright-mermaid.yml new file mode 100644 index 0000000..7e4b439 --- /dev/null +++ b/.github/workflows/playwright-mermaid.yml @@ -0,0 +1,71 @@ +name: End to end tests (mermaid readability) + +on: + pull_request: + merge_group: + push: + branches: [main] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +jobs: + check: + name: 'Check for relevant changes' + runs-on: ubuntu-latest + outputs: + relevant: ${{ steps.includes.outputs.match == 'true' }} + steps: + - name: Check out code + uses: actions/checkout@v6 + + # Only mermaid conversion changes can affect these checks, unlike the rest of the e2e suites. + - name: Check for changes to relevant paths + uses: dorny/paths-filter@v3 + id: includes + with: + filters: | + match: + - 'packages/mermaid/**' + - 'apps/examples/src/examples/use-cases/hundred-mermaids/**' + - 'apps/examples/src/misc/mermaidReadability.ts' + - 'apps/examples/e2e/mermaid-readability/**' + - '.github/workflows/playwright-mermaid.yml' + - '.github/actions/**' + - 'yarn.lock' + + build: + name: 'End to end tests (mermaid readability)' + needs: check + if: needs.check.outputs.relevant == 'true' + timeout-minutes: 20 + runs-on: ubuntu-latest-16-cores-open + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Run Playwright tests (mermaid readability) + run: 'yarn e2e-mermaid-readability' + working-directory: apps/examples + + - uses: actions/upload-artifact@v6 + if: always() + with: + name: playwright-report + path: apps/examples/playwright-report + retention-days: 30 diff --git a/.github/workflows/playwright-perf.yml b/.github/workflows/playwright-perf.yml new file mode 100644 index 0000000..448e025 --- /dev/null +++ b/.github/workflows/playwright-perf.yml @@ -0,0 +1,107 @@ +name: End to end tests (perf) + +on: + pull_request: + merge_group: + push: + branches: [main] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + check: + name: 'Check for relevant changes' + runs-on: ubuntu-latest + outputs: + relevant: ${{ steps.includes.outputs.match == 'true' && steps.nondocs.outputs.match == 'true' }} + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Check for changes to relevant paths + uses: dorny/paths-filter@v3 + id: includes + with: + filters: | + match: + - 'packages/**' + - 'apps/examples/**' + - '.github/workflows/playwright-perf.yml' + - '.github/actions/**' + - 'yarn.lock' + + - name: Check for any non-doc changes + uses: dorny/paths-filter@v3 + id: nondocs + with: + predicate-quantifier: 'every' + filters: | + match: + - '**' + - '!**/*.md' + - '!**/*.mdx' + + build: + name: 'End to end tests (perf)' + needs: check + if: needs.check.outputs.relevant == 'true' + timeout-minutes: 20 + runs-on: ubuntu-latest-16-cores-open + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Run Playwright tests (perf) + run: 'yarn e2e-perf' + working-directory: apps/examples + env: + PERFORMANCE_ANALYTICS_ENABLED: true + GITHUB_REF_NAME: ${{ github.ref_name }} + GIT_COMMIT: ${{ github.sha }} + + - uses: actions/upload-artifact@v6 + if: always() + with: + name: playwright-report + path: apps/examples/playwright-report + retention-days: 30 + + - uses: shallwefootball/s3-upload-action@0d261a6f15b3b2e209dfebdecace4b100c04f95b # master + # only upload if we have AWS credentials: + env: + HAS_AWS_KEY: ${{ secrets.AWS_S3_SECRET_KEY && '1' || '' }} + if: always() && env.HAS_AWS_KEY == '1' + name: Upload S3 + id: s3 + with: + aws_key_id: ${{ secrets.AWS_S3_KEY_ID }} + aws_secret_access_key: ${{ secrets.AWS_S3_SECRET_KEY}} + aws_bucket: playwright.tldraw.xyz + source_dir: apps/examples/playwright-report + + - name: Log report to summary + if: always() + run: | + report_url="https://playwright.tldraw.xyz/${{ steps.s3.outputs.object_key }}/index.html" + echo "Report: $report_url" + echo "## Playwright report" >> $GITHUB_STEP_SUMMARY + echo "* $report_url" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/playwright-update-snapshots.yml b/.github/workflows/playwright-update-snapshots.yml new file mode 100644 index 0000000..4f6c09b --- /dev/null +++ b/.github/workflows/playwright-update-snapshots.yml @@ -0,0 +1,84 @@ +# Adapted from https://mmazzarolo.com/blog/2022-09-09-visual-regression-testing-with-playwright-and-github-actions/ + +# This workflow's goal is forcing an update of the reference snapshots used +# by Playwright tests. Add the 'update-snapshots' label to a PR. +# From a high-level perspective, it works like this: +# 1. Because of a GitHub Action limitation, this workflow is triggered on every +# label added to a PR. We manually interrupt it unless the label is +# "update-snapshots". +# 2. Use the GitHub API to grab the information about the branch name and SHA of +# the latest commit of the current pull request. +# 3. Remove the label from the PR. +# 4. Update the Playwright reference snapshots based on the UI of this branch. +# 5. Commit the newly generated Playwright reference snapshots into this branch. +name: Update playwright snapshots + +on: + pull_request: + types: [labeled] + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + update_snapshots: + name: 'Run' + timeout-minutes: 60 + runs-on: ubuntu-latest-8-cores-open + if: github.event.label.name == 'update-snapshots' + + permissions: + # Give the default GITHUB_TOKEN write permission to commit and push the + # added or changed files to the repository. + contents: write + pull-requests: write + + steps: + - name: Remove the update-snapshots label + uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: update-snapshots + + - name: Check out code + uses: actions/checkout@v6 + with: + fetch-depth: 5 + token: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.event.pull_request.head.ref }} + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Build examples + run: yarn run -T lazy refresh-assets && yarn run -T lazy run prebuild && cd apps/examples && yarn build + + - name: Run Playwright tests & update snapshots + run: 'yarn e2e --update-snapshots' + working-directory: 'apps/examples' + + - name: Commit and push changes + if: always() + run: | + set -eux + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + git add -A + if git diff --cached --quiet; then + echo 'No snapshot changes to commit.' + exit 0 + fi + git commit --no-verify -m '[automated] update snapshots' + git add -A && git reset --hard HEAD # we sometimes get a dirty tree because husky makes changes for some reason + git pull --rebase + git push diff --git a/.github/workflows/post-release-crew.yml b/.github/workflows/post-release-crew.yml new file mode 100644 index 0000000..6a54fc8 --- /dev/null +++ b/.github/workflows/post-release-crew.yml @@ -0,0 +1,56 @@ +name: Post release crew to Discord + +# Every Wednesday at 07:07 UTC, post to #development naming the people whose critical +# fixes / significant features are in this week's dotcom release. +# GitHub cron is UTC-only. We use a single fixed UTC time (no BST/GMT adjustment) so +# the job never fires twice: 07:07 UTC is 07:07 in London during winter (GMT) and +# 08:07 during summer (BST). GitHub often starts scheduled runs 15-60 minutes late, +# so this is scheduled early (and off the congested :00/:30 slots) to land before +# the working day ramps up. To change the day, edit the day-of-week field +# (`3` = Wednesday) in the cron line. + +on: + schedule: + - cron: '7 7 * * 3' # Wednesday 07:07 UTC + workflow_dispatch: # allow manual runs + +concurrency: + group: post-release-crew + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + post-release-crew: + name: Post release crew to Discord + timeout-minutes: 20 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Fail fast if the Discord webhook is not configured + run: | + if [ -z "$DISCORD_RELEASE_WEBHOOK_URL" ]; then + echo "::error::DISCORD_RELEASE_WEBHOOK_URL secret is not set — the release crew message cannot be posted." + exit 1 + fi + env: + DISCORD_RELEASE_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} + + - name: Install Claude Code + run: npm install -g @anthropic-ai/claude-code@2.1.206 + + - name: Run dotcom-release-crew skill + run: claude --dangerously-skip-permissions --print "/dotcom-release-crew" + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GH_TOKEN: ${{ github.token }} + DISCORD_RELEASE_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} diff --git a/.github/workflows/post-release-marketing.yml b/.github/workflows/post-release-marketing.yml new file mode 100644 index 0000000..d6b2006 --- /dev/null +++ b/.github/workflows/post-release-marketing.yml @@ -0,0 +1,57 @@ +name: Post release marketing summary to Discord + +# Every Wednesday at 07:07 UTC, post a plain-language summary of what's shipping in +# this week's dotcom release to the marketing team's Discord channel. Same schedule as +# post-release-crew.yml. +# GitHub cron is UTC-only. We use a single fixed UTC time (no BST/GMT adjustment) so +# the job never fires twice: 07:07 UTC is 07:07 in London during winter (GMT) and +# 08:07 during summer (BST). GitHub often starts scheduled runs 15-60 minutes late, +# so this is scheduled early (and off the congested :00/:30 slots) to land before +# the working day ramps up. To change the day, edit the day-of-week field +# (`3` = Wednesday) in the cron line. + +on: + schedule: + - cron: '7 7 * * 3' # Wednesday 07:07 UTC + workflow_dispatch: # allow manual runs + +concurrency: + group: post-release-marketing + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + post-release-marketing: + name: Post release marketing summary to Discord + timeout-minutes: 20 + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Fail fast if the Discord webhook is not configured + run: | + if [ -z "$DISCORD_MARKETING_WEBHOOK_URL" ]; then + echo "::error::DISCORD_MARKETING_WEBHOOK_URL secret is not set — the release marketing summary cannot be posted." + exit 1 + fi + env: + DISCORD_MARKETING_WEBHOOK_URL: ${{ secrets.DISCORD_MARKETING_WEBHOOK_URL }} + + - name: Install Claude Code + run: npm install -g @anthropic-ai/claude-code@2.1.206 + + - name: Run dotcom-release-marketing skill + run: claude --dangerously-skip-permissions --print "/dotcom-release-marketing" + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GH_TOKEN: ${{ github.token }} + DISCORD_MARKETING_WEBHOOK_URL: ${{ secrets.DISCORD_MARKETING_WEBHOOK_URL }} diff --git a/.github/workflows/prune-preview-deploys.yml b/.github/workflows/prune-preview-deploys.yml new file mode 100644 index 0000000..8a4b419 --- /dev/null +++ b/.github/workflows/prune-preview-deploys.yml @@ -0,0 +1,64 @@ +name: Prune preview deploys + +on: + schedule: + # run once per day at midnight or whatever + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + id-token: 'write' + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 +defaults: + run: + shell: bash + +jobs: + deploy: + name: Prune preview deploys + timeout-minutes: 30 + runs-on: ubuntu-latest + environment: deploy-staging + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + submodules: true + fetch-depth: 0 + + - uses: ./.github/actions/setup + + - name: Setup Fly IO + uses: superfly/flyctl-actions/setup-flyctl@ed8efb33836e8b2096c7fd3ba1c8afe303ebbff1 # 1.6 + + - name: Configure AWS credentials using OIDC + uses: aws-actions/configure-aws-credentials@v6 + with: + role-to-assume: arn:aws:iam::571248596162:role/huppy-bot + aws-region: 'eu-north-1' + + - name: Prune preview deploys + run: yarn tsx internal/scripts/prune-preview-deploys.ts + env: + GH_TOKEN: ${{ github.token }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }} + SUPABASE_PREVIEW_PROJECT_ID: ${{ vars.SUPABASE_PREVIEW_PROJECT_ID }} + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + ZERO_R2_ENDPOINT: ${{ secrets.ZERO_R2_ENDPOINT }} + ZERO_R2_BUCKET_NAME: ${{ secrets.ZERO_R2_BUCKET_NAME }} + ZERO_R2_ACCESS_KEY_ID: ${{ secrets.ZERO_R2_ACCESS_KEY_ID }} + ZERO_R2_SECRET_ACCESS_KEY: ${{ secrets.ZERO_R2_SECRET_ACCESS_KEY }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/publish-editor-extensions.yml b/.github/workflows/publish-editor-extensions.yml new file mode 100644 index 0000000..f04122f --- /dev/null +++ b/.github/workflows/publish-editor-extensions.yml @@ -0,0 +1,73 @@ +name: Publish editor extensions + +on: + push: + branches: + - main + - production + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + publish: + name: Publish editor extensions + environment: vsce publish + timeout-minutes: 20 + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: vscode-extension-publish + + steps: + - name: Generate GH token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - name: Check out code + id: checkout + uses: actions/checkout@v6 + with: + persist-credentials: false + submodules: true + token: ${{ steps.generate_token.outputs.token }} + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - uses: ./.github/actions/setup + + - name: Build types + run: yarn build-types + + - name: Publish extension + timeout-minutes: 10 + run: yarn tsx ./internal/scripts/publish-editor-extensions.ts + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + TLDRAW_ENV: ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') }} + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + # Preserve the setup action for post-job cleanup when checkout already succeeded. + - name: Check out Discord notify action + if: failure() && steps.checkout.outcome != 'success' + uses: actions/checkout@v6 + with: + sparse-checkout: .github/actions/discord-fail-notify + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/publish-templates.yml b/.github/workflows/publish-templates.yml new file mode 100644 index 0000000..43e1d0a --- /dev/null +++ b/.github/workflows/publish-templates.yml @@ -0,0 +1,71 @@ +name: Publish templates + +on: + workflow_dispatch: + workflow_call: + secrets: + HUPPY_PRIVATE_KEY: + required: true + HUPPY_APP_ID: + required: true + DISCORD_DEPLOY_WEBHOOK_URL: + required: false + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + ALLOW_REFRESH_ASSETS_CHANGES: 1 + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + publish: + name: Publish templates + timeout-minutes: 60 + runs-on: ubuntu-latest-16-cores-arm-open + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - uses: ./.github/actions/setup + + - name: Generate a token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_PRIVATE_KEY }} + owner: ${{ github.repository_owner }} + + - name: Configure git + run: | + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + + - name: Export templates + env: + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + cd templates + all_templates=$(ls -d */ | cut -f1 -d'/') + cd .. + + for template in $all_templates; do + echo "::group::Exporting $template" + yarn tsx ./internal/scripts/export-template.ts $template + echo "::endgroup::" + done + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/publish-vscode-extension.yml b/.github/workflows/publish-vscode-extension.yml new file mode 100644 index 0000000..d8db88b --- /dev/null +++ b/.github/workflows/publish-vscode-extension.yml @@ -0,0 +1,70 @@ +name: Publish VSCE/OVX + +on: + workflow_dispatch: + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + publish: + name: Publish VSCE/OVX + environment: vsce publish + timeout-minutes: 20 + runs-on: ubuntu-latest + permissions: + contents: write + concurrency: vscode-extension-publish + + steps: + - name: Generate GH token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - name: Check out code + id: checkout + uses: actions/checkout@v6 + with: + persist-credentials: false + submodules: true + token: ${{ steps.generate_token.outputs.token }} + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - uses: ./.github/actions/setup + + - name: Build types + run: yarn build-types + + - name: Publish extension + timeout-minutes: 10 + run: yarn tsx ./internal/scripts/publish-editor-extensions.ts + env: + VSCE_PAT: ${{ secrets.VSCE_PAT }} + OVSX_PAT: ${{ secrets.OVSX_PAT }} + TLDRAW_ENV: production + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + # Preserve the setup action for post-job cleanup when checkout already succeeded. + - name: Check out Discord notify action + if: failure() && steps.checkout.outcome != 'success' + uses: actions/checkout@v6 + with: + sparse-checkout: .github/actions/discord-fail-notify + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..1b88bb5 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,330 @@ +name: Publish SDK packages + +on: + push: + branches: + - main + - production + - 'v*.*.x' + pull_request: + types: [labeled] + workflow_dispatch: + inputs: + publish_type: + type: choice + description: What to publish + required: true + default: manual + options: + - manual + - new + version: + description: Version to republish (manual only) + required: false + bump_type: + type: choice + description: Version bump type (new release only) + required: false + default: minor + options: + - minor + - major + - override + version_override: + type: string + description: Version override (new release only) + required: false + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + remove-label: + name: Remove the publish-packages label + if: | + github.event_name == 'pull_request' && + github.event.label.name == 'publish-packages' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + steps: + - name: Remove the publish-packages label + uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: publish-packages + + publish: + name: Publish SDK packages + if: | + github.event_name != 'pull_request' || + ( + github.event.label.name == 'publish-packages' && + github.event.pull_request.head.repo.full_name == github.repository + ) + environment: npm deploy + timeout-minutes: 60 + runs-on: ubuntu-latest-16-cores-arm-open + concurrency: + group: ${{ (github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/heads/v')) && 'npm-publish' || format('npm-publish-{0}', github.run_id) }} + + permissions: + contents: read + id-token: write + + outputs: + mode: ${{ steps.publish_mode.outputs.mode }} + version: ${{ steps.version.outputs.value }} + is_latest_version: ${{ steps.publish.outputs.is_latest_version }} + + steps: + - name: Determine publish mode + id: publish_mode + env: + EVENT_NAME: ${{ github.event_name }} + EVENT_LABEL_NAME: ${{ github.event.label.name }} + REF: ${{ github.ref }} + REF_NAME: ${{ github.ref_name }} + DISPATCH_PUBLISH_TYPE: ${{ inputs.publish_type }} + DISPATCH_VERSION: ${{ inputs.version }} + DISPATCH_BUMP_TYPE: ${{ inputs.bump_type }} + DISPATCH_VERSION_OVERRIDE: ${{ inputs.version_override }} + run: | + mode= + bemo_url=https://demo.tldraw.xyz + use_huppy=false + + case "$EVENT_NAME" in + push) + if [[ "$REF" == "refs/heads/main" ]]; then + mode=canary + bemo_url=https://canary-demo.tldraw.xyz + elif [[ "$REF" == "refs/heads/production" ]]; then + mode=next + bemo_url=https://canary-demo.tldraw.xyz + elif [[ "$REF_NAME" =~ ^v[0-9]+\.[0-9]+\.x$ ]]; then + mode=patch + use_huppy=true + fi + ;; + pull_request) + if [[ "$EVENT_LABEL_NAME" == "publish-packages" ]]; then + mode=internal + bemo_url=https://canary-demo.tldraw.xyz + fi + ;; + workflow_dispatch) + mode="$DISPATCH_PUBLISH_TYPE" + if [[ "$mode" == "manual" || "$mode" == "new" ]]; then + use_huppy=true + fi + ;; + esac + + if [[ -z "$mode" ]]; then + echo "ERROR Could not determine publish mode for $EVENT_NAME on $REF." + exit 1 + fi + + if [[ "$mode" == "manual" && -z "$DISPATCH_VERSION" ]]; then + echo "ERROR You must provide a version when manually republishing packages." + exit 1 + fi + + if [[ "$mode" == "new" ]]; then + if [[ "$REF_NAME" != "production" ]]; then + echo "ERROR You must be on the production branch to publish a new version." + exit 1 + fi + if [[ "$DISPATCH_BUMP_TYPE" != "minor" && "$DISPATCH_BUMP_TYPE" != "major" && "$DISPATCH_BUMP_TYPE" != "override" ]]; then + echo "ERROR New releases must use a minor, major, or override bump type." + exit 1 + fi + if [[ "$DISPATCH_BUMP_TYPE" != "override" && -n "$DISPATCH_VERSION_OVERRIDE" ]]; then + echo "ERROR You must set the bump type to override if you supply a custom version number override." + exit 1 + fi + if [[ "$DISPATCH_BUMP_TYPE" == "override" && -z "$DISPATCH_VERSION_OVERRIDE" ]]; then + echo "ERROR You must supply a version override when using the override bump type." + exit 1 + fi + fi + + { + echo "mode=$mode" + echo "bemo_url=$bemo_url" + echo "use_huppy=$use_huppy" + } >> "$GITHUB_OUTPUT" + + - name: Generate GH token + id: generate_token + if: steps.publish_mode.outputs.use_huppy == 'true' + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.HUPPY_APP_ID }} + private_key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - name: Check out code + id: checkout + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: ${{ steps.publish_mode.outputs.use_huppy != 'true' }} + token: ${{ (steps.publish_mode.outputs.use_huppy == 'true' && steps.generate_token.outputs.token) || github.token }} + + - name: Configure git credentials + if: steps.publish_mode.outputs.use_huppy == 'true' + run: | + git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Publish + id: publish + env: + GH_TOKEN: ${{ (steps.publish_mode.outputs.use_huppy == 'true' && steps.generate_token.outputs.token) || github.token }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + TLDRAW_BEMO_URL: ${{ steps.publish_mode.outputs.bemo_url }} + TLDRAW_VERSION_STRING: ${{ inputs.version }} + PUBLISH_MODE: ${{ steps.publish_mode.outputs.mode }} + BUMP_TYPE: ${{ inputs.bump_type }} + VERSION_OVERRIDE: ${{ inputs.version_override }} + run: | + case "$PUBLISH_MODE" in + canary | internal | next) + yarn tsx ./internal/scripts/publish-prerelease.ts "$PUBLISH_MODE" + ;; + patch) + yarn tsx ./internal/scripts/publish-patch.ts + ;; + manual) + yarn tsx ./internal/scripts/publish-manual.ts + ;; + new) + bump="${BUMP_TYPE:-minor}" + if [[ "$bump" == "override" ]]; then + bump="$VERSION_OVERRIDE" + fi + yarn tsx ./internal/scripts/publish-new.ts --bump "$bump" + ;; + *) + echo "ERROR Unknown publish mode: $PUBLISH_MODE" + exit 1 + ;; + esac + + - name: Get published version + id: version + run: echo "value=$(jq -r .version ./packages/tldraw/package.json)" >> "$GITHUB_OUTPUT" + + # Tell tldraw-internal to update its pinned SDK version. Fires only on a + # `next` publish — the prerelease channel the internal monorepo tracks. + # The tldraw-internal "Update tldraw" workflow listens for the + # `tldraw-release` repository_dispatch and resolves the latest `next` + # version itself, so the payload version is informational. + - name: Generate tldraw-internal token + if: steps.publish_mode.outputs.mode == 'next' + id: generate_internal_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_PRIVATE_KEY }} + owner: tldraw + repositories: tldraw-internal + + - name: Notify tldraw-internal + if: steps.publish_mode.outputs.mode == 'next' + run: | + curl -X POST \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer ${{ steps.generate_internal_token.outputs.token }}" \ + https://api.github.com/repos/tldraw/tldraw-internal/dispatches \ + -d '{"event_type":"tldraw-release","client_payload":{"version":"${{ steps.version.outputs.value }}","tag":"next"}}' + + # Preserve the setup action for post-job cleanup when checkout already succeeded. + - name: Check out Discord notify action + if: failure() && steps.checkout.outcome != 'success' + uses: actions/checkout@v6 + with: + sparse-checkout: .github/actions/discord-fail-notify + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + + comment: + name: Tell user released version + if: needs.publish.outputs.mode == 'internal' + needs: publish + runs-on: ubuntu-latest + + permissions: + contents: read + pull-requests: write + + steps: + - name: Tell user released version + uses: actions-ecosystem/action-create-comment@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + body: | + Published version ${{ needs.publish.outputs.version }} to npm. + + publish_templates: + name: Publishes code templates to separate repositories + uses: tldraw/tldraw/.github/workflows/publish-templates.yml@main + if: needs.publish.outputs.mode == 'new' || ((needs.publish.outputs.mode == 'patch' || needs.publish.outputs.mode == 'manual') && needs.publish.outputs.is_latest_version == 'true') + secrets: + HUPPY_PRIVATE_KEY: ${{ secrets.HUPPY_PRIVATE_KEY }} + HUPPY_APP_ID: ${{ vars.HUPPY_APP_ID }} + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + needs: publish + + deploy_templates: + name: Deploys the template demos with the new SDK version + if: needs.publish.outputs.mode == 'new' || ((needs.publish.outputs.mode == 'patch' || needs.publish.outputs.mode == 'manual') && needs.publish.outputs.is_latest_version == 'true') + needs: publish + # CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID are secrets on this environment rather than on + # the repository, and a job has to select the environment to see them. Calling deploy-templates.yml + # as a reusable workflow doesn't do it: a called workflow only ever sees the secrets its caller + # hands it, so the v5.4.0 release reached the deploy with both empty (#10636) even though the + # called job selected deploy-production itself. The deploy runs here as a job of its own instead, + # sharing its steps with deploy-templates.yml through the composite action. + environment: deploy-production + timeout-minutes: 60 + runs-on: ubuntu-latest-16-cores-arm-open + # same group as deploy-templates.yml: a release deploy and a template-change deploy can otherwise + # race each other onto the same custom domains, and the loser silently wins. + concurrency: + group: deploy-templates + cancel-in-progress: false + + steps: + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + + - uses: ./.github/actions/deploy-templates + with: + license-key: ${{ secrets.TEMPLATES_TLDRAW_LICENSE_KEY }} + cloudflare-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + cloudflare-api-token: ${{ secrets.CLOUDFLARE_API_TOKEN }} + + - name: Notify Discord on failure + if: failure() + uses: ./.github/actions/discord-fail-notify + with: + webhook-url: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} diff --git a/.github/workflows/staging-cleanup-daily.yml b/.github/workflows/staging-cleanup-daily.yml new file mode 100644 index 0000000..c1bc6b1 --- /dev/null +++ b/.github/workflows/staging-cleanup-daily.yml @@ -0,0 +1,38 @@ +name: Staging E2E Daily Cleanup + +on: + schedule: + - cron: '45 1 * * *' + +permissions: + contents: read + +env: + CI: 1 + +defaults: + run: + shell: bash + +jobs: + cleanup: + name: 'Daily Cleanup of Test Files' + timeout-minutes: 20 + runs-on: ubuntu-latest + environment: 'e2e-dotcom' + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Cleanup test files + run: yarn tsx internal/scripts/dotcom/cleanup-test-files.ts + env: + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + SUPABASE_STAGING_DB_URL: ${{ secrets.SUPABASE_STAGING_DB_URL }} + STAGING_OWNER_ID: ${{ secrets.STAGING_OWNER_ID }} diff --git a/.github/workflows/staging-e2e.yml b/.github/workflows/staging-e2e.yml new file mode 100644 index 0000000..5fc8dd1 --- /dev/null +++ b/.github/workflows/staging-e2e.yml @@ -0,0 +1,68 @@ +name: Staging E2E Tests + +on: + workflow_dispatch: + inputs: + test_files_count: + description: 'Number of test files to copy to staging' + required: false + default: '10' + type: number + +permissions: + contents: read + +env: + CI: 1 + PRINT_GITHUB_ANNOTATIONS: 1 + +defaults: + run: + shell: bash + +jobs: + test: + name: 'Staging E2E Tests' + timeout-minutes: 40 + runs-on: ubuntu-latest-8-cores-open + environment: 'e2e-dotcom' + + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Set up Playwright + uses: ./.github/actions/setup-playwright + + - name: Run cleanup of test files + run: yarn tsx internal/scripts/dotcom/cleanup-test-files.ts + env: + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + SUPABASE_STAGING_DB_URL: ${{ secrets.SUPABASE_STAGING_DB_URL }} + STAGING_OWNER_ID: ${{ secrets.STAGING_OWNER_ID }} + + - name: Copy random files to staging + run: yarn tsx internal/scripts/dotcom/copy-random-files-to-staging.ts + env: + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + R2_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} + R2_ACCESS_KEY_SECRET: ${{ secrets.R2_ACCESS_KEY_SECRET }} + SUPABASE_PRODUCTION_DB_URL: ${{ secrets.SUPABASE_PRODUCTION_DB_URL }} + SUPABASE_STAGING_DB_URL: ${{ secrets.SUPABASE_STAGING_DB_URL }} + STAGING_OWNER_ID: ${{ secrets.STAGING_OWNER_ID }} + STAGING_TEST_FILES_COUNT: ${{ github.event.inputs.test_files_count || '10' }} + + - name: Run staging e2e tests + run: yarn e2e-staging + working-directory: apps/dotcom/client + env: + CLERK_PUBLISHABLE_KEY: ${{ secrets.VITE_CLERK_PUBLISHABLE_KEY }} + CLERK_SECRET_KEY: ${{ secrets.CLERK_SECRET_KEY }} + STAGING_TEST_EMAIL: ${{ secrets.STAGING_TEST_EMAIL }} + STAGING_TEST_PASSWORD: ${{ secrets.STAGING_TEST_PASSWORD }} + STAGING_TESTS: 'true' diff --git a/.github/workflows/trigger-dotcom-hotfix.yml b/.github/workflows/trigger-dotcom-hotfix.yml new file mode 100644 index 0000000..8244512 --- /dev/null +++ b/.github/workflows/trigger-dotcom-hotfix.yml @@ -0,0 +1,69 @@ +name: Trigger dotcom hotfix + +# pull_request_target rather than push/pull_request, for the same reason as +# trigger-sdk-hotfix.yml: release-notes PRs squash-merge with `[skip ci]` in the title, which +# suppresses the push-to-main run entirely, and the `labeled` event fires before the merge so the +# `merged == true` gate rejects it. Neither path ever reached the script. GitHub's skip-ci markers +# do not apply to pull_request_target. `closed` replaces the old push trigger (which ran on every +# merge to main just to check labels), and `labeled` allows re-triggering by re-adding the label to +# an already-merged PR. Secrets exposure is safe here: the job only runs for merged PRs carrying a +# maintainer-applied hotfix label, checkout uses the trusted base branch, and the only PR-derived +# code the script builds is the PR's already-merged commit from main. +on: + pull_request_target: + types: [closed, labeled] + branches: + - main + +defaults: + run: + shell: bash + +permissions: + contents: write + pull-requests: write + +jobs: + trigger: + name: Trigger a dotcom hotfix + runs-on: ubuntu-latest + timeout-minutes: 20 + concurrency: dotcom-hotfix + environment: npm deploy + if: | + github.event.pull_request.merged == true && + ((github.event.action == 'closed' && + contains(github.event.pull_request.labels.*.name, 'dotcom-hotfix-please')) || + (github.event.action == 'labeled' && + github.event.label.name == 'dotcom-hotfix-please')) + + steps: + - name: Generate a token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + persist-credentials: false + token: ${{ steps.generate_token.outputs.token }} + fetch-depth: 0 + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - uses: ./.github/actions/setup + + - name: Maybe trigger dotcom hotfix + run: | + set -e + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + git log --oneline -10 + yarn tsx internal/scripts/trigger-dotcom-hotfix.ts + env: + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/trigger-production-build.yml b/.github/workflows/trigger-production-build.yml new file mode 100644 index 0000000..4f19631 --- /dev/null +++ b/.github/workflows/trigger-production-build.yml @@ -0,0 +1,118 @@ +name: Trigger dotcom release + +on: + push: + branches: + - hotfixes + workflow_dispatch: + inputs: + target: + description: 'Target ref to deploy' + required: true + default: 'main' + +defaults: + run: + shell: bash + +env: + TARGET: ${{ github.event.inputs.target }} + +permissions: + contents: read + +jobs: + trigger: + name: ${{ github.event_name == 'workflow_dispatch' && 'Manual trigger' || 'Hotfix' }} + runs-on: ubuntu-latest + concurrency: trigger-production + + steps: + - name: Generate a token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ vars.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + persist-credentials: false + token: ${{ steps.generate_token.outputs.token }} + ref: refs/heads/production + fetch-depth: 0 + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - name: Get target commit hash (manual dispatch) + if: github.event_name == 'workflow_dispatch' + run: | + set -x + + # if the target exists on its own use that + if git rev-parse "$TARGET" --quiet; then + target_hash=$(git rev-parse "$TARGET") + fi + # if not try prefixed with origin: + if [ -z "$target_hash" ]; then + target_hash=$(git rev-parse "origin/$TARGET") + fi + + echo "SHOULD_DEPLOY=true" >> $GITHUB_ENV + echo "TARGET_HASH=$target_hash" >> $GITHUB_ENV + + - name: Get target commit hash (hotfix) + if: github.event_name == 'push' + run: | + set -x + echo "TARGET_HASH=$GITHUB_SHA" >> $GITHUB_ENV + echo "TARGET=hotfix" >> $GITHUB_ENV + # is the hotfix sha already on production? + if git merge-base --is-ancestor "$GITHUB_SHA" production; then + echo "SHOULD_DEPLOY=false" >> $GITHUB_ENV + else + echo "SHOULD_DEPLOY=true" >> $GITHUB_ENV + fi + + - name: Author setup (manual dispatch) + if: github.event_name == 'workflow_dispatch' + run: | + set -x + git config --global user.name "${{ github.actor }}" + git config --global user.email 'huppy+${{ github.actor }}@tldraw.com' + + - name: Author setup (hotfix) + if: github.event_name == 'push' + run: | + set -x + commit_author_name=$(git log -1 --pretty=format:%cn "$TARGET_HASH") + commit_author_email=$(git log -1 --pretty=format:%ce "$TARGET_HASH") + git config --global user.name "$commit_author_name" + git config --global user.email "$commit_author_email" + + - name: Get target tree hash + run: | + set -x + tree_hash=$(git show --quiet --pretty=format:%T "$TARGET_HASH") + echo "TREE_HASH=$tree_hash" >> $GITHUB_ENV + + - name: Create commit & update production branch + run: | + set -eux + now=$(date -u +"%Y-%m-%dT%H:%M:%SZ") + message="Deploy from $TARGET ($TARGET_HASH) at $now" + current_prod_hash=$(git rev-parse HEAD) + + commit=$(git commit-tree -m "$message" -p "$current_prod_hash" -p "$TARGET_HASH" "$TREE_HASH") + + git update-ref refs/heads/production "$commit" + git checkout production + + - name: Push commit to trigger deployment + if: env.SHOULD_DEPLOY == 'true' + run: | + set -x + git push origin production + # reset hotfixes to the latest production + git push origin production:hotfixes --force diff --git a/.github/workflows/trigger-sdk-hotfix.yml b/.github/workflows/trigger-sdk-hotfix.yml new file mode 100644 index 0000000..3a08032 --- /dev/null +++ b/.github/workflows/trigger-sdk-hotfix.yml @@ -0,0 +1,70 @@ +name: Trigger sdk hotfix + +# pull_request_target rather than push/pull_request: hotfix PRs (e.g. the automated +# release-notes updates) carry `[skip ci]` in their commit messages, which suppresses +# push- and pull_request-triggered workflows entirely — the label had no effect. +# GitHub's skip-ci markers do not apply to pull_request_target. The `closed` event +# replaces the old push-to-main trigger (which ran on every merge just to check +# labels), and `labeled` allows re-triggering a hotfix by re-adding the label to an +# already-merged PR. Secrets exposure is safe here: the job only runs for merged PRs +# carrying a maintainer-applied hotfix label, checkout uses the trusted base branch, +# and the only PR-derived code the script builds is the PR's already-merged commit +# from main. +on: + pull_request_target: + types: [closed, labeled] + branches: + - main + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + trigger: + name: Trigger an SDK hotfix + runs-on: ubuntu-latest + concurrency: npm-publish + environment: npm deploy + if: | + github.event.pull_request.merged == true && + ((github.event.action == 'closed' && + (contains(github.event.pull_request.labels.*.name, 'sdk-hotfix-please') || + contains(github.event.pull_request.labels.*.name, 'docs-hotfix-please'))) || + (github.event.action == 'labeled' && + (github.event.label.name == 'sdk-hotfix-please' || github.event.label.name == 'docs-hotfix-please'))) + + steps: + - name: Generate a token + id: generate_token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.HUPPY_APP_ID }} + private-key: ${{ secrets.HUPPY_APP_PRIVATE_KEY }} + + - uses: actions/checkout@v6 + with: + persist-credentials: false + token: ${{ steps.generate_token.outputs.token }} + fetch-depth: 0 + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - uses: ./.github/actions/setup + + - name: Maybe trigger sdk hotfix + run: | + set -e + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + git log --oneline -10 + yarn tsx internal/scripts/trigger-sdk-hotfix.ts + env: + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} + TLDRAW_BEMO_URL: https://demo.tldraw.xyz + DISCORD_DEPLOY_WEBHOOK_URL: ${{ secrets.DISCORD_DEPLOY_WEBHOOK_URL }} + PR_NUMBER: ${{ github.event.pull_request.number }} diff --git a/.github/workflows/update-release-notes.yml b/.github/workflows/update-release-notes.yml new file mode 100644 index 0000000..da20418 --- /dev/null +++ b/.github/workflows/update-release-notes.yml @@ -0,0 +1,160 @@ +name: Update release notes + +on: + # Update release notes whenever production is updated, keeping next.mdx (and the + # draft GitHub release synced by the skill) in step with each dotcom release — + # the same production push that deploys dotcom and publishes the `next` package. + # Production only: a push to main must not trigger a notes run on every merge. + # Release-notes PR titles carry `[skip ci]` so their squash-merge commits skip main + # push workflows. Branch commits omit the marker so required PR checks run. + push: + branches: + - production + workflow_dispatch: + +concurrency: + group: update-release-notes + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + update-release-notes: + name: 'Update release notes with Claude Code' + timeout-minutes: 30 + runs-on: ubuntu-latest + + steps: + - name: Generate GH token + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.HUPPY_APP_ID }} + private_key: ${{ secrets.HUPPY_PRIVATE_KEY }} + + - name: Check out code + uses: actions/checkout@v6 + with: + persist-credentials: false + fetch-depth: 0 + token: ${{ steps.generate_token.outputs.token }} + + - name: Configure git credentials + run: git config --global url."https://x-access-token:${{ steps.generate_token.outputs.token }}@github.com/".insteadOf "https://github.com/" + + - name: Run our setup + uses: ./.github/actions/setup + + - name: Configure git + run: | + git config --global user.name 'huppy-bot[bot]' + git config --global user.email '128400622+huppy-bot[bot]@users.noreply.github.com' + + - name: Create branch + id: branch + run: | + BRANCH_NAME="release-notes/update-$(date +%Y%m%d-%H%M%S)" + git checkout -b "$BRANCH_NAME" + echo "branch_name=$BRANCH_NAME" >> "$GITHUB_OUTPUT" + + # Recorded before the skill runs so the close step below can tell an + # already-open PR from an earlier run apart from the one this run opens. + - name: Find open release notes PRs + id: existing_prs + run: | + { + echo 'numbers<> "$GITHUB_OUTPUT" + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + - name: Install Claude Code + run: npm install -g @anthropic-ai/claude-code + + - name: Run update-release-notes skill + run: | + claude --dangerously-skip-permissions --print "/update-release-notes" + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + - name: Check for changes + id: changes + run: | + if [ -z "$(git status --porcelain)" ]; then + echo "has_changes=false" >> "$GITHUB_OUTPUT" + else + echo "has_changes=true" >> "$GITHUB_OUTPUT" + fi + + - name: Commit and push + if: steps.changes.outputs.has_changes == 'true' + run: | + git add -A + git commit -m "Update release notes" + git push -u origin "${{ steps.branch.outputs.branch_name }}" + + - name: Create PR + if: steps.changes.outputs.has_changes == 'true' + run: | + gh pr create \ + --title "docs(releases): update release notes [skip ci]" \ + --body "$(cat <<'EOF' + In order to keep the release notes up to date, this PR adds entries for PRs merged since the last update. + + ### Change type + + - [x] `other` + + ### Test plan + + - [ ] Unit tests + - [ ] End to end tests + EOF + )" \ + --base main \ + --head "${{ steps.branch.outputs.branch_name }}" \ + --label "docs-hotfix-please" + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + # Each run regenerates the notes from scratch, so a PR opened by this run + # supersedes any release notes PR left open by an earlier run. The PR may come + # from the step above or from the skill itself, so this compares the currently + # open PRs against the ones recorded before the skill ran rather than relying on + # a single known PR number. When this run opened nothing, the older PR is still + # the pending update and is left alone. + - name: Close superseded PRs + run: | + EXISTING="${{ steps.existing_prs.outputs.numbers }}" + CURRENT=$(gh pr list --state open --base main --limit 100 --json number,headRefName \ + --jq '.[] | select(.headRefName | test("^(release-notes/update-|update-release-notes-)")) | .number') + + NEW_PRS=$(comm -13 <(echo "$EXISTING" | sort) <(echo "$CURRENT" | sort)) + if [ -z "$NEW_PRS" ]; then + echo "This run did not open a release notes PR, nothing to supersede" + exit 0 + fi + + # The new PR is already open at this point, so a failure to tidy up an old + # one is a warning, not a reason to fail the run. + NEWEST=$(echo "$NEW_PRS" | sort -n | tail -n 1) + echo "$EXISTING" | while read -r PR; do + [ -n "$PR" ] || continue + echo "Closing superseded release notes PR #$PR" + gh pr close "$PR" --delete-branch --comment "Superseded by #$NEWEST." \ + || echo "Warning: could not close #$PR" + done + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + + - name: No changes + if: steps.changes.outputs.has_changes == 'false' + run: echo "No release notes updates needed" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..65273fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,141 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +/worktrees + +.rooms + +# Temporary files +*.tmp.ts + +node_modules +dist +dist-cjs +dist-esm +.tsbuild* +.lazy +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# turborepo +.turbo + +coverage + +# vitest reports, attachments and blob output +.vitest + +**/*.env +**/*.tsbuildinfo + +**/*.css.map +**/*.js.map +apps/examples/www/index.js +apps/examples/www/index.css +nohup.out + +packages/*/package +packages/*/*.tgz + +tsconfig.build.json +.vercel + +api-json +api-md + +packages/tldraw/tldraw.css +packages/namespaced-tldraw/tldraw.css +packages/commenting/commenting.css +packages/collaboration/collaboration.css + +packages/assets/embed-icons +packages/assets/fonts +packages/assets/icons +packages/assets/translations +packages/assets/watermarks +packages/commenting/assets +apps/examples/www/embed-icons +apps/examples/www/fonts +apps/examples/www/icons +apps/examples/www/translations + +# yarn v2 +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +packages/*/api/temp +packages/*/api/api.json +packages/*/api/internal.d.ts +packages/*/api/public.d.ts + +apps/examples/www/index.css +apps/examples/www/index.js +.tsbuild + +apps/examples/build.esbuild.json + +test-results +apps/examples/e2e/test-results +apps/examples/playwright-report +apps/dotcom/client/test-results +apps/dotcom/client/playwright-report +apps/dotcom/client/e2e/.auth +apps/dotcom/zero-cache/.schema.js + +apps/docs/content/gen +apps/docs/api + +.dev.vars +.env.local +.env.development.local +.env* + +.wrangler +/vercel.json +license-report*.html +license-report*.md +license-report*.pdf + +.bundle-meta.json +.zed + +.mcp.json + +# TypeScript profiling +.ts-profile + +# ESLint cache +.eslintcache +opencode.json + +# PR walkthrough intermediate files +.claude/worktrees +.claude/settings.local.json +skills/pr-walkthrough/tmp +skills/pr-walkthrough/out +skills/pr-walkthrough/video/node_modules +skills/pr-walkthrough/video/dist +skills/pr-walkthrough/video/public/audio-* +skills/pr-walkthrough/video/public/manifest.json +todo.md diff --git a/.husky/post-checkout b/.husky/post-checkout new file mode 100755 index 0000000..974fab8 --- /dev/null +++ b/.husky/post-checkout @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +. "$(dirname -- "$0")/_/husky.sh" + +set -e + +rm -rf *.tsbuildinfo */*.tsbuildinfo */*/*.tsbuildinfo */*/*/*.tsbuildinfo */*/*/*/*.tsbuildinfo + +# This notifies the user if the yarn.lock file has changed. +CHANGED=$(git diff "$1" "$2" --stat -- ./yarn.lock | wc -l) +if (( CHANGED > 0 )); then + echo + echo "🚨 🚨 🚨 yarn.lock has changed! 🚨 🚨 🚨 " + echo "run 'yarn' to get the latest!" + echo +fi diff --git a/.husky/post-merge b/.husky/post-merge new file mode 100755 index 0000000..d24df76 --- /dev/null +++ b/.husky/post-merge @@ -0,0 +1,13 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +set -e + +# This notifies the user if the yarn.lock file has changed. +CHANGED=$(git diff HEAD@{1} --stat -- ./yarn.lock | wc -l) +if (( CHANGED > 0 )); then + echo + echo "🚨 🚨 🚨 yarn.lock has changed! 🚨 🚨 🚨 " + echo "run 'yarn' to get the latest!" + echo +fi diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..9c1ae2d --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,31 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +# Only run yarn if package.json files have changed +CHANGED_PACKAGE_JSON_FILES=$(git diff --cached --name-only -- ':(glob)**/package.json') +if [ -n "$CHANGED_PACKAGE_JSON_FILES" ]; then + yarn install --immutable +fi + +# Only run build-api for packages with staged changes +CHANGED_PACKAGES=$(git diff --cached --name-only -- packages | cut -d/ -f2 | sort -u) +FILTER_ARGS="" +for pkg in $CHANGED_PACKAGES; do + if [ -f "packages/$pkg/package.json" ] && grep -q '"build-api"' "packages/$pkg/package.json"; then + FILTER_ARGS="$FILTER_ARGS --filter=packages/$pkg" + fi +done +if [ -n "$FILTER_ARGS" ]; then + ONLY_REFRESH_ASSETS_IF_NECESSARY=1 npx lazy run build-api $FILTER_ARGS + git add packages/*/api-report.api.md +fi + +# Only run build-i18n when dotcom client files change +CHANGED_DOTCOM_CLIENT=$(git diff --cached --name-only -- apps/dotcom/client) +if [ -n "$CHANGED_DOTCOM_CLIENT" ]; then + npx lazy run build-i18n --filter=apps/dotcom/client + git add apps/dotcom/client/public/tla/locales + git add apps/dotcom/client/public/tla/locales-compiled +fi + +yarn lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..5f26dc4 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1,3 @@ +#!/bin/sh +command -v git-lfs >/dev/null 2>&1 || { printf >&2 "\n%s\n\n" "This repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks')."; exit 2; } +git lfs pre-push "$@" diff --git a/.ignore b/.ignore new file mode 100644 index 0000000..e73158b --- /dev/null +++ b/.ignore @@ -0,0 +1,33 @@ +dist +.tsbuild-dev +.tsbuild-pub +.tsbuild +node_modules +*.d.ts +**/api-report.md +**/api-report.api.md +**/_archive +**/*.tsbuildinfo +yarn.lock +**/*.tldr +**/*.d.ts +**/*.d.ts.map +**/*.js.map +**/*.css.map +apps/example/www/index.css +**/dist/* +*.cjs +apps/docs/.next + +packages/tldraw/tldraw.css + +**/dist-cjs/**/* +**/dist-esm/**/* +**/*.js.map +**/*.api.json +apps/docs/utils/vector-db +apps/docs/content/releases/**/* +apps/docs/content/reference/**/* +packages/**/api + +**/.clasp.json \ No newline at end of file diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..5390e83 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,13 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "trailingComma": "es5", + "singleQuote": true, + "semi": false, + "printWidth": 100, + "tabWidth": 2, + "useTabs": true, + "sortImports": { + "newlinesBetween": false, + }, + "sortPackageJson": false, +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000..ebc1c5a --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,460 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["unicorn", "react", "typescript", "nextjs"], + "jsPlugins": ["./internal/scripts/oxlint/tldraw-plugin.mjs"], + "categories": { + "correctness": "off" + }, + "options": { + "typeAware": true + }, + "env": { + "builtin": true + }, + "settings": { + "next": { + "rootDir": ["apps/*/", "packages/*/"] + }, + "react": { + "version": "19.2" + } + }, + "ignorePatterns": [ + "skills/**/*", + ".claude/**/*", + ".agents/**/*", + ".cursor/**/*", + "**/node_modules/*", + "**/out/*", + "**/dist/*", + "**/dist-cjs/*", + "**/dist-esm/*", + "**/.tsbuild*", + "**/.lazy/*", + "**/.next/*", + "**/.wrangler/*", + "**/.vercel/*", + "**/*.md", + "**/_archive/*", + "**/*.css.map", + "**/*.js.map", + "**/*.d.ts", + "**/api/*", + "!**/pages/api/*", + "**/*.json", + "**/lazy.config.ts", + "**/next.config.js", + "**/setupTests.js", + "apps/vscode/extension/editor", + "apps/examples/www", + "apps/docs/api-content.json", + "apps/docs/content.json", + "apps/vscode/extension/editor/index.js", + "apps/vscode/extension/editor/tldraw-assets.json", + "**/sentry.server.config.js", + "**/scripts/upload-sourcemaps.js", + "**/scripts/lib/auto-plugin.js", + "**/coverage/**/*", + "apps/docs/postcss.config.js", + "apps/docs/tailwind.config.js", + "apps/dotcom/client/public/sw.js", + "apps/dotcom/client/public/theme-init.js", + "apps/analytics/public/*", + "**/.clasp.json", + "**/*.mjs", + "**/.*.js", + "packages/assets/*", + "packages/create-tldraw/cli.cjs", + "**/*/vitest.config.ts", + "**/*/setupVitest.js", + "**/*/zod-locales-shim.js", + "**/*/scripts/vite-zod-locale-plugin.js" + ], + "rules": { + "no-unexpected-multiline": "error", + "constructor-super": "error", + "for-direction": "error", + "getter-return": "error", + "no-async-promise-executor": "error", + "no-case-declarations": "error", + "no-class-assign": "error", + "no-compare-neg-zero": "error", + "no-cond-assign": "error", + "no-const-assign": "error", + "no-constant-binary-expression": "error", + "no-constant-condition": "error", + "no-control-regex": "error", + "no-debugger": "error", + "no-delete-var": "error", + "no-dupe-class-members": "error", + "no-dupe-else-if": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-empty": "error", + "no-empty-character-class": "error", + "no-empty-pattern": "error", + "no-empty-static-block": "error", + "no-ex-assign": "error", + "no-extra-boolean-cast": "error", + "no-func-assign": "error", + "no-global-assign": "error", + "no-import-assign": "error", + "no-invalid-regexp": "error", + "no-irregular-whitespace": "error", + "no-loss-of-precision": "error", + "no-misleading-character-class": "error", + "no-new-native-nonconstructor": "error", + "no-nonoctal-decimal-escape": "error", + "no-obj-calls": "error", + "no-prototype-builtins": "error", + "no-redeclare": "error", + "no-regex-spaces": "error", + "no-self-assign": "error", + "no-setter-return": "error", + "no-shadow-restricted-names": "error", + "no-sparse-arrays": "error", + "no-this-before-super": "error", + "no-undef": "error", + "no-unreachable": "error", + "no-unsafe-finally": "error", + "no-unsafe-negation": "error", + "no-unsafe-optional-chaining": "error", + "no-unused-labels": "error", + "no-unused-private-class-members": "error", + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_", + "fix": { + "imports": "safe-fix", + "variables": "off" + } + } + ], + "no-useless-backreference": "error", + "no-useless-catch": "error", + "no-useless-escape": "error", + "no-with": "error", + "require-yield": "error", + "use-isnan": "error", + "valid-typeof": "error", + "no-throw-literal": "error", + "no-array-constructor": "error", + "no-unused-expressions": "error", + + "react/jsx-key": "error", + "react/jsx-no-comment-textnodes": "error", + "react/jsx-no-duplicate-props": "error", + "react/jsx-no-target-blank": "error", + "react/jsx-no-undef": "error", + "react/no-children-prop": "error", + "react/no-danger-with-children": "error", + "react/no-direct-mutation-state": "error", + "react/no-find-dom-node": "error", + "react/no-is-mounted": "error", + "react/no-render-return-value": "error", + "react/no-string-refs": "error", + "react/no-unescaped-entities": "error", + "react/no-unknown-property": "error", + "react/require-render-return": "error", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "error", + + "@typescript-eslint/no-duplicate-enum-values": "error", + "@typescript-eslint/no-empty-object-type": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-non-null-asserted-optional-chain": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unnecessary-type-constraint": "error", + "@typescript-eslint/no-unsafe-declaration-merging": "error", + "@typescript-eslint/no-unsafe-function-type": "error", + "@typescript-eslint/no-wrapper-object-types": "error", + "@typescript-eslint/prefer-as-const": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/no-deprecated": "error", + "@typescript-eslint/consistent-type-exports": [ + "error", + { "fixMixedExportsWithInlineTypeSpecifier": true } + ], + "@typescript-eslint/consistent-type-definitions": ["error", "interface"], + + "@next/next/google-font-display": "warn", + "@next/next/google-font-preconnect": "warn", + "@next/next/next-script-for-ga": "warn", + "@next/next/no-async-client-component": "warn", + "@next/next/no-before-interactive-script-outside-document": "warn", + "@next/next/no-css-tags": "warn", + "@next/next/no-head-element": "warn", + "@next/next/no-page-custom-font": "warn", + "@next/next/no-styled-jsx-in-document": "warn", + "@next/next/no-sync-scripts": "error", + "@next/next/no-title-in-document-head": "warn", + "@next/next/no-typos": "warn", + "@next/next/no-unwanted-polyfillio": "warn", + "@next/next/inline-script-id": "error", + "@next/next/no-assign-module-variable": "error", + "@next/next/no-document-import-in-page": "error", + "@next/next/no-duplicate-head": "error", + "@next/next/no-head-import-in-document": "error", + "@next/next/no-script-component-in-head": "error", + + "no-restricted-globals": [ + "error", + { + "name": "structuredClone", + "message": "Use structuredClone from @tldraw/util instead" + } + ], + + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "lodash", + "message": "The main `lodash` package is CommonJS and does not tree-shake. Use a deep import (e.g. `import throttle from 'lodash/throttle'`), `lodash-es`, a per-method package, or inline the helper." + } + ] + } + ], + + "tldraw/no-export-star": "error", + "tldraw/no-internal-imports": "error", + "tldraw/tagged-components": "error", + "tldraw/prefer-class-methods": "error", + "tldraw/tsdoc-param-matching": "error", + "tldraw/no-whilst": "error", + "tldraw/no-tiptap-default-import": "error", + "tldraw/no-setter-getter": "error", + "tldraw/no-direct-storage": "error", + "tldraw/no-path2d-roundrect": "error", + "tldraw/no-exported-arrow-const": "error", + "tldraw/no-focused-tests": "error", + "tldraw/enforce-default-message": ["error", "literal"], + "tldraw/method-signature-style": "error", + "tldraw/claude-agents-pairing": "error" + }, + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"], + "rules": { + "@typescript-eslint/explicit-module-boundary-types": "off", + "no-console": ["error", { "allow": ["warn", "error"] }], + "constructor-super": "off", + "getter-return": "off", + "no-class-assign": "off", + "no-const-assign": "off", + "no-dupe-class-members": "off", + "no-dupe-keys": "off", + "no-func-assign": "off", + "no-import-assign": "off", + "no-new-native-nonconstructor": "off", + "no-obj-calls": "off", + "no-redeclare": "off", + "no-setter-return": "off", + "no-this-before-super": "off", + "no-undef": "off", + "no-unreachable": "off", + "no-unsafe-negation": "off", + "no-with": "off", + "no-var": "error", + "prefer-const": "error", + "prefer-rest-params": "error", + "prefer-spread": "error" + } + }, + { + "files": ["packages/**/*", "apps/**/*", "internal/**/*", "templates/**/*"], + "rules": { + "tldraw/no-undeclared-dependencies": "error" + } + }, + { + "files": ["packages/editor/**/*", "packages/tldraw/**/*", "packages/utils/**/*"], + "rules": { + "no-restricted-globals": [ + "error", + { + "name": "fetch", + "message": "Use the fetch from @tldraw/util instead." + }, + { + "name": "Image", + "message": "Use the Image from @tldraw/util instead." + }, + { + "name": "setTimeout", + "message": "Use the timers from editor.timers instead." + }, + { + "name": "setInterval", + "message": "Use the timers from editor.timers instead." + }, + { + "name": "requestAnimationFrame", + "message": "Use the timers from editor.timers instead." + }, + { + "name": "structuredClone", + "message": "Use structuredClone from @tldraw/util instead" + } + ], + "tldraw/no-restricted-properties": [ + "error", + [ + { + "object": "window", + "property": "fetch", + "message": "Use the fetch from @tldraw/util instead." + }, + { + "object": "window", + "property": "Image", + "message": "Use the Image from @tldraw/util instead." + }, + { + "object": "window", + "property": "setTimeout", + "message": "Use the timers from editor.timers instead." + }, + { + "object": "window", + "property": "setInterval", + "message": "Use the timers from editor.timers instead." + }, + { + "object": "window", + "property": "requestAnimationFrame", + "message": "Use the timers from editor.timers instead." + } + ] + ], + "tldraw/img-referrer-policy": "error" + } + }, + { + "files": ["apps/dotcom/client/**/*"], + "rules": { + "no-restricted-globals": [ + "error", + { + "name": "fetch", + "message": "Use the fetch from @tldraw/util instead." + }, + { + "name": "Image", + "message": "Use the Image from @tldraw/util instead." + }, + { + "name": "structuredClone", + "message": "Use structuredClone from @tldraw/util instead" + } + ], + "tldraw/no-restricted-properties": [ + "error", + [ + { + "object": "window", + "property": "fetch", + "message": "Use the fetch from @tldraw/util instead." + }, + { + "object": "window", + "property": "Image", + "message": "Use the Image from @tldraw/util instead." + }, + { + "object": "crypto", + "property": "randomUUID", + "message": "Please use the makeUUID util instead." + } + ] + ] + } + }, + { + "files": ["apps/dotcom/client/src/tla/**/*"], + "rules": { + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "react-intl", + "message": "Please import useIntl from src/utils/intl instead." + }, + { + "name": "lodash", + "message": "The main `lodash` package is CommonJS and does not tree-shake. Use a deep import (e.g. `import throttle from 'lodash/throttle'`), `lodash-es`, a per-method package, or inline the helper." + } + ] + } + ], + "tldraw/jsx-no-literals": "error" + } + }, + { + "files": ["**/scripts/**/*"], + "rules": { + "@typescript-eslint/no-require-imports": "off" + } + }, + { + "files": ["internal/scripts/**/*"], + "rules": { + "tldraw/no-export-star": "off" + } + }, + { + "files": ["internal/scripts/process-compose-bin.cjs"], + "env": { "node": true }, + "globals": { "fetch": "readonly" } + }, + { + "files": ["apps/mcp-app/**/*"], + "rules": { + "tldraw/no-export-star": "off" + } + }, + { + "files": ["**/*.test.ts", "**/*.test.tsx", "**/*.spec.ts"], + "rules": { + "tldraw/no-restricted-properties": "off", + "no-restricted-globals": "off", + "react/jsx-key": "off", + "react/no-string-refs": "off" + } + }, + { + "files": ["internal/**/*", "templates/simple-server-example/**/*"], + "rules": { + "no-console": "off" + } + }, + { + "files": ["apps/examples/**/*"], + "rules": { + "tldraw/no-setter-getter": "off", + "tldraw/no-direct-storage": "off", + "tldraw/img-referrer-policy": "off" + } + }, + { + "files": ["templates/**/*"], + "rules": { + "tldraw/prefer-class-methods": "off", + "tldraw/no-setter-getter": "off", + "tldraw/no-direct-storage": "off", + "tldraw/img-referrer-policy": "off", + "no-console": "off", + "tldraw/method-signature-style": "off" + } + } + ] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..ad62b24 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,45 @@ +**/node_modules/* +**/out/* +**/dist/* +**/dist-cjs/* +**/dist-esm/* +**/.next/* +**/api/* +!**/app/api/* +!**/pages/api/* +**/.tsbuild* +**/.next/* +**/_archive/* +apps/docs/api-content.json +apps/docs/content.json +apps/vscode/extension/editor/* +apps/examples/www +content.json +apps/docs/utils/vector-db/index.json +**/gen/**/*.md +.github/pull_request_template.md +skills +.agents +.cursor + +**/api-report.md +**/api-report.api.md +**/CHANGELOG.md +apps/docs/content/releases/**/* +apps/docs/content/reference/**/* + +**/.vercel/* +**/.wrangler/* +**/.out/* +**/.temp/* +apps/dotcom/client/public/**/*.* +apps/analytics/public/**/* + +**/.clasp.json + +apps/dotcom/zero-cache/docker/docker-compose.yml + +lerna.json + +internal/scripts/eslint/eslint-plugin.mjs +apps/dotcom/zero-cache/.schema.js \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7fd1df8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "trailingComma": "es5", + "singleQuote": true, + "semi": false, + "printWidth": 100, + "tabWidth": 2, + "useTabs": true, + "plugins": ["prettier-plugin-organize-imports"] +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..9879019 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["oxc.oxc-vscode"] +} diff --git a/.yarn/patches/@microsoft-tsdoc-npm-0.15.1-e24295d9bd.patch b/.yarn/patches/@microsoft-tsdoc-npm-0.15.1-e24295d9bd.patch new file mode 100644 index 0000000..77e161e --- /dev/null +++ b/.yarn/patches/@microsoft-tsdoc-npm-0.15.1-e24295d9bd.patch @@ -0,0 +1,91 @@ +diff --git a/lib-commonjs/emitters/TSDocEmitter.js b/lib-commonjs/emitters/TSDocEmitter.js +index 60535a109e3705baae7cb851e1f7cca6e2b5595b..5aedafa2da8ebcf22ec356d89921a93b33dca7ea 100644 +--- a/lib-commonjs/emitters/TSDocEmitter.js ++++ b/lib-commonjs/emitters/TSDocEmitter.js +@@ -282,6 +282,9 @@ var TSDocEmitter = /** @class */ (function () { + var docPlainText = docNode; + this._writeContent(docPlainText.text); + break; ++ case DocNode_1.DocNodeKind.SoftBreak: ++ this._ensureAtStartOfLine(); ++ break; + } + }; + TSDocEmitter.prototype._renderInlineTag = function (docInlineTagBase, writeInlineTagContent) { +diff --git a/lib-commonjs/transforms/TrimSpacesTransform.js b/lib-commonjs/transforms/TrimSpacesTransform.js +index b5fe0c49a27a8df5b08e9862541c2449c61c1158..1fa36cab07267eaabbb9a0b9d640cfcec116dae4 100644 +--- a/lib-commonjs/transforms/TrimSpacesTransform.js ++++ b/lib-commonjs/transforms/TrimSpacesTransform.js +@@ -20,6 +20,25 @@ var TrimSpacesTransform = /** @class */ (function () { + // We always trim leading whitespace for a paragraph. This flag gets set to true + // as soon as nonempty content is encountered. + var finishedSkippingLeadingSpaces = false; ++ ++ function pushAccumulatedText() { ++ const lines = accumulatedTextChunks.join('').split('\n') ++ for (let i = 0; i < lines.length; i++) { ++ const line = lines[i] ++ transformedNodes.push(new nodes_1.DocPlainText({ ++ configuration: docParagraph.configuration, ++ text: line ++ })); ++ if (i < lines.length - 1) { ++ transformedNodes.push(new nodes_1.DocSoftBreak({ ++ configuration: docParagraph.configuration ++ })); ++ } ++ } ++ accumulatedTextChunks.length = 0; ++ accumulatedNodes.length = 0; ++ } ++ + for (var _i = 0, _a = docParagraph.nodes; _i < _a.length; _i++) { + var node = _a[_i]; + switch (node.kind) { +@@ -46,9 +65,15 @@ var TrimSpacesTransform = /** @class */ (function () { + } + break; + case nodes_1.DocNodeKind.SoftBreak: +- if (finishedSkippingLeadingSpaces) { +- pendingSpace = true; +- } ++ // by default, this transform strips out all soft-breaks and replaces them with ++ // spaces where needed. because we're rendering to markdown and markdown is ++ // whitespace-sensitive, we don't want to do this. instead, we accumulate the ++ // soft-breaks and emit them as normal. ++ ++ // if (finishedSkippingLeadingSpaces) { ++ // pendingSpace = true; ++ // } ++ accumulatedTextChunks.push('\n'); + accumulatedNodes.push(node); + break; + default: +@@ -60,12 +85,7 @@ var TrimSpacesTransform = /** @class */ (function () { + if (accumulatedTextChunks.length > 0) { + // TODO: We should probably track the accumulatedNodes somehow, e.g. so we can map them back to the + // original excerpts. But we need a developer scenario before we can design this API. +- transformedNodes.push(new nodes_1.DocPlainText({ +- configuration: docParagraph.configuration, +- text: accumulatedTextChunks.join('') +- })); +- accumulatedTextChunks.length = 0; +- accumulatedNodes.length = 0; ++ pushAccumulatedText(); + } + transformedNodes.push(node); + finishedSkippingLeadingSpaces = true; +@@ -73,12 +93,7 @@ var TrimSpacesTransform = /** @class */ (function () { + } + // Push the accumulated text + if (accumulatedTextChunks.length > 0) { +- transformedNodes.push(new nodes_1.DocPlainText({ +- configuration: docParagraph.configuration, +- text: accumulatedTextChunks.join('') +- })); +- accumulatedTextChunks.length = 0; +- accumulatedNodes.length = 0; ++ pushAccumulatedText() + } + var transformedParagraph = new nodes_1.DocParagraph({ + configuration: docParagraph.configuration diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..e19deb7 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,14 @@ +compressionLevel: mixed + +enableGlobalCache: false + +# Don't run third-party dependency build/install scripts by default. Packages that +# genuinely need to build are allowlisted via dependenciesMeta..built in package.json. +# This closes the postinstall code-execution vector; see the note in AGENTS.md. +enableScripts: false + +enableInlineBuilds: true + +nodeLinker: node-modules + +npmMinimalAgeGate: '7d' diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..158445c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,222 @@ +# AGENTS.md + +This file provides guidance to AI coding agents working in this repository. + +## Core rules + +- Use `yarn`, not `npm`, for repo commands. This repo uses Yarn workspaces and Yarn 4. +- Run commands from the repo root unless a command explicitly says to run from a workspace. +- Never run bare `tsc`; use `yarn typecheck` from the repo root. +- Prefer targeted checks first. Avoid repo-wide test or e2e runs unless the change needs them. +- Keep changes scoped to the request and the affected package. Do not refactor unrelated code. +- Respect existing worktree changes. Do not revert user changes unless explicitly asked. +- Prefer editing existing files over creating new files. Do not add new documentation files unless requested. +- Use sentence case for headings, titles, labels, and documentation text. + +## Repo overview + +This is the tldraw monorepo, an infinite canvas SDK for React applications. It is organized with Yarn workspaces. + +Core packages: + +- `packages/editor` - foundational infinite canvas editor with no default shapes, tools, or UI +- `packages/tldraw` - complete SDK with default UI, shapes, tools, and interactions +- `packages/store` - reactive client-side database, persistence, and migrations +- `packages/tlschema` - shape, binding, and record type definitions and validators +- `packages/state` - reactive signals library +- `packages/sync` and `packages/sync-core` - multiplayer sync packages +- `packages/utils` and `packages/validate` - shared utilities and validation helpers +- `packages/assets` - icons, fonts, translations, and bundled assets + +Apps and examples: + +- `apps/examples` - SDK examples and demos; the main place for example development +- `apps/docs` - documentation site at tldraw.dev +- `apps/dotcom` - tldraw.com app and workers +- `apps/vscode` - VS Code extension +- `templates` - starter templates for supported frameworks + +## Setup + +Requires Node `>=22.12.0`. Enable Corepack before installing dependencies: + +```bash +npm i -g corepack && yarn +``` + +## Common commands + +Development: + +- `yarn dev` - start the examples app at localhost:5420 +- `yarn dev-app` - start the tldraw.com client app +- `yarn dev-docs` - start the docs site +- `yarn dev-vscode` - start VS Code extension development +- `yarn dev-template