Full Code of webstudio-is/webstudio for AI

main 6c17a0ec191f cached
2152 files
10.0 MB
2.7M tokens
1665 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (10,915K chars total). Download the full file to get everything.
Repository: webstudio-is/webstudio
Branch: main
Commit: 6c17a0ec191f
Files: 2152
Total size: 10.0 MB

Directory structure:
gitextract_3aga18g3/

├── .devcontainer/
│   ├── .gitignore
│   ├── Dockerfile
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   ├── library-scripts/
│   │   └── docker-in-docker-debian.sh
│   └── postinstall.sh
├── .editorconfig
├── .github/
│   ├── actions/
│   │   ├── add-status/
│   │   │   └── action.yaml
│   │   ├── ci-setup/
│   │   │   └── action.yml
│   │   ├── submodules-checkout/
│   │   │   └── action.yml
│   │   └── vercel/
│   │       └── action.yaml
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── build-figma-tokens.yml
│       ├── check-submodules.yml
│       ├── chromatic.yml
│       ├── cli-r2-static.yaml
│       ├── cli-r2.yaml
│       ├── delete-github-deployments.yml
│       ├── fixtures-test.yml
│       ├── lint-pull-request.yaml
│       ├── main.yml
│       ├── migrate.yaml
│       ├── publish-beta.yml
│       ├── re-create-figma-tokens-branch.yml
│       ├── release.yml
│       ├── vercel-deploy-staging.yml
│       └── vis-reg-tests.yml
├── .gitignore
├── .gitmodules
├── .nvmrc
├── .oxlintrc.json
├── .prettierignore
├── .storybook/
│   ├── main.ts
│   ├── preview-body.html
│   └── preview.tsx
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── @types/
│   ├── canvas-iframe.d.ts
│   ├── content.d.ts
│   ├── css-tree.d.ts
│   ├── navigator.d.ts
│   ├── scroll-timeline.d.ts
│   └── warn-once.d.ts
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── apps/
│   └── builder/
│       ├── .gitignore
│       ├── app/
│       │   ├── auth/
│       │   │   ├── index.client.ts
│       │   │   ├── login.stories.tsx
│       │   │   ├── login.tsx
│       │   │   └── secret-login.tsx
│       │   ├── builder/
│       │   │   ├── builder.css
│       │   │   ├── builder.tsx
│       │   │   ├── features/
│       │   │   │   ├── address-bar.stories.tsx
│       │   │   │   ├── address-bar.tsx
│       │   │   │   ├── assets/
│       │   │   │   │   ├── assets.tsx
│       │   │   │   │   └── index.ts
│       │   │   │   ├── blocking-alerts/
│       │   │   │   │   ├── alert.stories.tsx
│       │   │   │   │   ├── alert.tsx
│       │   │   │   │   ├── blocking-alerts.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   ├── breakpoints/
│       │   │   │   │   ├── breakpoint-editor-utils.test.ts
│       │   │   │   │   ├── breakpoint-editor-utils.ts
│       │   │   │   │   ├── breakpoints-container.tsx
│       │   │   │   │   ├── breakpoints-editor.tsx
│       │   │   │   │   ├── breakpoints-menu.tsx
│       │   │   │   │   ├── breakpoints-selector.stories.tsx
│       │   │   │   │   ├── breakpoints-selector.tsx
│       │   │   │   │   ├── canvas-settings-popover.tsx
│       │   │   │   │   ├── cascade-indicator.tsx
│       │   │   │   │   ├── condition-input.tsx
│       │   │   │   │   ├── confirmation-dialog.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── width-input.tsx
│       │   │   │   ├── builder-mode.stories.tsx
│       │   │   │   ├── builder-mode.tsx
│       │   │   │   ├── clone.tsx
│       │   │   │   ├── command-panel/
│       │   │   │   │   ├── command-panel.stories.tsx
│       │   │   │   │   ├── command-panel.tsx
│       │   │   │   │   ├── command-state.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── breakpoints-group.tsx
│       │   │   │   │   │   ├── commands-group.tsx
│       │   │   │   │   │   ├── components-group.tsx
│       │   │   │   │   │   ├── convert-group.tsx
│       │   │   │   │   │   ├── css-variables-group.tsx
│       │   │   │   │   │   ├── data-variables-group.tsx
│       │   │   │   │   │   ├── duplicate-tokens-group.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── instances-group.tsx
│       │   │   │   │   │   ├── pages-group.tsx
│       │   │   │   │   │   ├── tags-group.tsx
│       │   │   │   │   │   ├── tokens-group.tsx
│       │   │   │   │   │   ├── wrap-group.test.tsx
│       │   │   │   │   │   └── wrap-group.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── shared/
│       │   │   │   │       ├── auto-select.ts
│       │   │   │   │       ├── component-utils.ts
│       │   │   │   │       ├── instance-list.tsx
│       │   │   │   │       ├── instance-path-footer.tsx
│       │   │   │   │       ├── types.ts
│       │   │   │   │       └── usage-utils.ts
│       │   │   │   ├── components/
│       │   │   │   │   ├── components.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── use-draggable.tsx
│       │   │   │   ├── footer/
│       │   │   │   │   ├── breadcrumbs.tsx
│       │   │   │   │   ├── footer.tsx
│       │   │   │   │   └── index.ts
│       │   │   │   ├── help/
│       │   │   │   │   ├── help-center.stories.tsx
│       │   │   │   │   ├── help-center.tsx
│       │   │   │   │   ├── remote-dialog.stories.tsx
│       │   │   │   │   └── remote-dialog.tsx
│       │   │   │   ├── keyboard-shortcuts-dialog/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── keyboard-shortcuts-dialog.stories.tsx
│       │   │   │   │   └── keyboard-shortcuts-dialog.tsx
│       │   │   │   ├── marketplace/
│       │   │   │   │   ├── about.stories.tsx
│       │   │   │   │   ├── about.tsx
│       │   │   │   │   ├── card.stories.tsx
│       │   │   │   │   ├── card.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── marketplace.tsx
│       │   │   │   │   ├── overview.tsx
│       │   │   │   │   ├── templates.tsx
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── menu/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── menu-button.tsx
│       │   │   │   │   ├── menu.stories.tsx
│       │   │   │   │   └── menu.tsx
│       │   │   │   ├── navigator/
│       │   │   │   │   ├── css-preview.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── navigator-tree.tsx
│       │   │   │   │   └── navigator.tsx
│       │   │   │   ├── pages/
│       │   │   │   │   ├── confirmation-dialogs.stories.tsx
│       │   │   │   │   ├── confirmation-dialogs.tsx
│       │   │   │   │   ├── custom-metadata.stories.tsx
│       │   │   │   │   ├── custom-metadata.tsx
│       │   │   │   │   ├── folder-settings.tsx
│       │   │   │   │   ├── form.stories.tsx
│       │   │   │   │   ├── form.tsx
│       │   │   │   │   ├── image-info.stories.tsx
│       │   │   │   │   ├── image-info.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── page-context-menu.tsx
│       │   │   │   │   ├── page-settings.stories.tsx
│       │   │   │   │   ├── page-settings.tsx
│       │   │   │   │   ├── page-utils.test.ts
│       │   │   │   │   ├── page-utils.ts
│       │   │   │   │   ├── pages.tsx
│       │   │   │   │   ├── search-preview.stories.tsx
│       │   │   │   │   ├── search-preview.tsx
│       │   │   │   │   ├── social-preview.stories.tsx
│       │   │   │   │   ├── social-preview.tsx
│       │   │   │   │   ├── social-utils.test.ts
│       │   │   │   │   └── social-utils.ts
│       │   │   │   ├── publish/
│       │   │   │   │   ├── add-domain.tsx
│       │   │   │   │   ├── cname.test.ts
│       │   │   │   │   ├── cname.ts
│       │   │   │   │   ├── collapsible-domain-section.stories.tsx
│       │   │   │   │   ├── collapsible-domain-section.tsx
│       │   │   │   │   ├── domain-checkbox.tsx
│       │   │   │   │   ├── domains.tsx
│       │   │   │   │   ├── entri.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── publish.tsx
│       │   │   │   ├── safe-mode.tsx
│       │   │   │   ├── settings-panel/
│       │   │   │   │   ├── controls/
│       │   │   │   │   │   ├── boolean.tsx
│       │   │   │   │   │   ├── check.tsx
│       │   │   │   │   │   ├── code.tsx
│       │   │   │   │   │   ├── combined.tsx
│       │   │   │   │   │   ├── controls.stories.tsx
│       │   │   │   │   │   ├── file.tsx
│       │   │   │   │   │   ├── json.tsx
│       │   │   │   │   │   ├── number.tsx
│       │   │   │   │   │   ├── radio.tsx
│       │   │   │   │   │   ├── resource-control.tsx
│       │   │   │   │   │   ├── select-asset.tsx
│       │   │   │   │   │   ├── select.tsx
│       │   │   │   │   │   ├── tag-control.tsx
│       │   │   │   │   │   ├── text-content.tsx
│       │   │   │   │   │   ├── text.tsx
│       │   │   │   │   │   └── url.tsx
│       │   │   │   │   ├── curl.test.ts
│       │   │   │   │   ├── curl.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── property-label.tsx
│       │   │   │   │   ├── props-section/
│       │   │   │   │   │   ├── animation/
│       │   │   │   │   │   │   ├── animation-keyframes.tsx
│       │   │   │   │   │   │   ├── animation-panel-content.stories.tsx
│       │   │   │   │   │   │   ├── animation-panel-content.tsx
│       │   │   │   │   │   │   ├── animation-section.tsx
│       │   │   │   │   │   │   ├── animation-transforms.tsx
│       │   │   │   │   │   │   ├── animations-select.tsx
│       │   │   │   │   │   │   ├── keyframe-helpers.test.ts
│       │   │   │   │   │   │   ├── keyframe-helpers.ts
│       │   │   │   │   │   │   ├── new-scroll-animations.ts
│       │   │   │   │   │   │   ├── new-view-animations.ts
│       │   │   │   │   │   │   ├── set-css-property.test.tsx
│       │   │   │   │   │   │   ├── set-css-property.ts
│       │   │   │   │   │   │   └── subject-select.tsx
│       │   │   │   │   │   ├── match-media-breakpoints.test.ts
│       │   │   │   │   │   ├── match-media-breakpoints.ts
│       │   │   │   │   │   ├── props-section.stories.tsx
│       │   │   │   │   │   ├── props-section.tsx
│       │   │   │   │   │   └── use-props-logic.ts
│       │   │   │   │   ├── resource-panel.tsx
│       │   │   │   │   ├── settings-panel.tsx
│       │   │   │   │   ├── settings-section.tsx
│       │   │   │   │   ├── shared.tsx
│       │   │   │   │   ├── variable-popover.tsx
│       │   │   │   │   ├── variables-section.stories.tsx
│       │   │   │   │   └── variables-section.tsx
│       │   │   │   ├── share.tsx
│       │   │   │   ├── style-panel/
│       │   │   │   │   ├── controls/
│       │   │   │   │   │   ├── color/
│       │   │   │   │   │   │   └── color-control.tsx
│       │   │   │   │   │   ├── font-family/
│       │   │   │   │   │   │   └── font-family-control.tsx
│       │   │   │   │   │   ├── font-weight/
│       │   │   │   │   │   │   └── font-weight-control.tsx
│       │   │   │   │   │   ├── image/
│       │   │   │   │   │   │   └── image-control.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── menu/
│       │   │   │   │   │   │   └── menu-control.tsx
│       │   │   │   │   │   ├── position/
│       │   │   │   │   │   │   └── position-control.tsx
│       │   │   │   │   │   ├── select/
│       │   │   │   │   │   │   └── select-control.tsx
│       │   │   │   │   │   ├── text/
│       │   │   │   │   │   │   └── text-control.tsx
│       │   │   │   │   │   ├── toggle/
│       │   │   │   │   │   │   └── toggle-control.tsx
│       │   │   │   │   │   └── toggle-group/
│       │   │   │   │   │       └── toggle-group-control.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── property-label.tsx
│       │   │   │   │   ├── sections/
│       │   │   │   │   │   ├── advanced/
│       │   │   │   │   │   │   ├── advanced.tsx
│       │   │   │   │   │   │   └── stores.ts
│       │   │   │   │   │   ├── backdrop-filter/
│       │   │   │   │   │   │   ├── backdrop-filter.stories.tsx
│       │   │   │   │   │   │   └── backdrop-filter.tsx
│       │   │   │   │   │   ├── backgrounds/
│       │   │   │   │   │   │   ├── background-code-editor.tsx
│       │   │   │   │   │   │   ├── background-content.stories.tsx
│       │   │   │   │   │   │   ├── background-content.tsx
│       │   │   │   │   │   │   ├── background-gradient.tsx
│       │   │   │   │   │   │   ├── background-image.tsx
│       │   │   │   │   │   │   ├── background-position.tsx
│       │   │   │   │   │   │   ├── background-size.test.ts
│       │   │   │   │   │   │   ├── background-size.tsx
│       │   │   │   │   │   │   ├── background-thumbnail.tsx
│       │   │   │   │   │   │   ├── backgrounds.stories.tsx
│       │   │   │   │   │   │   ├── backgrounds.tsx
│       │   │   │   │   │   │   ├── gradient-utils.test.ts
│       │   │   │   │   │   │   └── gradient-utils.ts
│       │   │   │   │   │   ├── borders/
│       │   │   │   │   │   │   ├── border-color.tsx
│       │   │   │   │   │   │   ├── border-property.tsx
│       │   │   │   │   │   │   ├── border-radius.tsx
│       │   │   │   │   │   │   ├── border-style.tsx
│       │   │   │   │   │   │   ├── border-width.tsx
│       │   │   │   │   │   │   ├── borders.stories.tsx
│       │   │   │   │   │   │   ├── borders.tsx
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── box-shadows/
│       │   │   │   │   │   │   ├── box-shadows.stories.tsx
│       │   │   │   │   │   │   └── box-shadows.tsx
│       │   │   │   │   │   ├── filter/
│       │   │   │   │   │   │   ├── filter.stories.tsx
│       │   │   │   │   │   │   └── filter.tsx
│       │   │   │   │   │   ├── flex-child/
│       │   │   │   │   │   │   ├── flex-child.stories.tsx
│       │   │   │   │   │   │   └── flex-child.tsx
│       │   │   │   │   │   ├── grid-child/
│       │   │   │   │   │   │   ├── grid-child.stories.tsx
│       │   │   │   │   │   │   ├── grid-child.test.ts
│       │   │   │   │   │   │   └── grid-child.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── layout/
│       │   │   │   │   │   │   ├── layout.stories.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   └── shared/
│       │   │   │   │   │   │       ├── alignment-ui.stories.tsx
│       │   │   │   │   │   │       ├── alignment-ui.test.ts
│       │   │   │   │   │   │       ├── alignment-ui.tsx
│       │   │   │   │   │   │       ├── constants.ts
│       │   │   │   │   │   │       ├── flex-alignment.tsx
│       │   │   │   │   │   │       ├── grid-alignment.tsx
│       │   │   │   │   │   │       ├── grid-area-picker.test.ts
│       │   │   │   │   │   │       ├── grid-area-picker.tsx
│       │   │   │   │   │   │       ├── grid-areas.test.ts
│       │   │   │   │   │   │       ├── grid-areas.tsx
│       │   │   │   │   │   │       ├── grid-areas.utils.test.ts
│       │   │   │   │   │   │       ├── grid-generator.test.ts
│       │   │   │   │   │   │       ├── grid-generator.tsx
│       │   │   │   │   │   │       ├── grid-position-inputs.tsx
│       │   │   │   │   │   │       ├── grid-settings.tsx
│       │   │   │   │   │   │       ├── grid-utils.test.ts
│       │   │   │   │   │   │       └── grid-utils.ts
│       │   │   │   │   │   ├── list-item.tsx
│       │   │   │   │   │   ├── outline/
│       │   │   │   │   │   │   ├── outline.stories.tsx
│       │   │   │   │   │   │   └── outline.tsx
│       │   │   │   │   │   ├── position/
│       │   │   │   │   │   │   ├── inset-control.stories.tsx
│       │   │   │   │   │   │   ├── inset-control.tsx
│       │   │   │   │   │   │   ├── inset-layout.stories.tsx
│       │   │   │   │   │   │   ├── inset-layout.tsx
│       │   │   │   │   │   │   ├── inset-tooltip.tsx
│       │   │   │   │   │   │   └── position.tsx
│       │   │   │   │   │   ├── sections.ts
│       │   │   │   │   │   ├── shared/
│       │   │   │   │   │   │   ├── align-self.tsx
│       │   │   │   │   │   │   ├── input-popover.tsx
│       │   │   │   │   │   │   ├── keyboard.ts
│       │   │   │   │   │   │   ├── order.tsx
│       │   │   │   │   │   │   ├── scrub.tsx
│       │   │   │   │   │   │   └── value-text.tsx
│       │   │   │   │   │   ├── size/
│       │   │   │   │   │   │   ├── size.stories.tsx
│       │   │   │   │   │   │   └── size.tsx
│       │   │   │   │   │   ├── space/
│       │   │   │   │   │   │   ├── layout.stories.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   ├── properties.ts
│       │   │   │   │   │   │   ├── space.tsx
│       │   │   │   │   │   │   └── tooltip.tsx
│       │   │   │   │   │   ├── text-shadows/
│       │   │   │   │   │   │   ├── text-shadows.stories.tsx
│       │   │   │   │   │   │   └── text-shadows.tsx
│       │   │   │   │   │   ├── transforms/
│       │   │   │   │   │   │   ├── transform-and-perspective-origin.tsx
│       │   │   │   │   │   │   ├── transform-extractors.test.ts
│       │   │   │   │   │   │   ├── transform-extractors.ts
│       │   │   │   │   │   │   ├── transform-rotate.tsx
│       │   │   │   │   │   │   ├── transform-scale.tsx
│       │   │   │   │   │   │   ├── transform-skew.tsx
│       │   │   │   │   │   │   ├── transform-translate.tsx
│       │   │   │   │   │   │   ├── transform-utils.ts
│       │   │   │   │   │   │   ├── transforms.stories.tsx
│       │   │   │   │   │   │   └── transforms.tsx
│       │   │   │   │   │   ├── transitions/
│       │   │   │   │   │   │   ├── transition-content.tsx
│       │   │   │   │   │   │   ├── transition-property.tsx
│       │   │   │   │   │   │   ├── transitions.stories.tsx
│       │   │   │   │   │   │   └── transitions.tsx
│       │   │   │   │   │   └── typography/
│       │   │   │   │   │       ├── typography.stories.tsx
│       │   │   │   │   │       └── typography.tsx
│       │   │   │   │   ├── shared/
│       │   │   │   │   │   ├── color-picker.tsx
│       │   │   │   │   │   ├── css-fragment.test.ts
│       │   │   │   │   │   ├── css-fragment.tsx
│       │   │   │   │   │   ├── css-value-input/
│       │   │   │   │   │   │   ├── convert-units.test.ts
│       │   │   │   │   │   │   ├── convert-units.ts
│       │   │   │   │   │   │   ├── css-value-input-container.tsx
│       │   │   │   │   │   │   ├── css-value-input.stories.tsx
│       │   │   │   │   │   │   ├── css-value-input.tsx
│       │   │   │   │   │   │   ├── evaluate-math.test.ts
│       │   │   │   │   │   │   ├── evaluate-math.ts
│       │   │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   │   ├── parse-intermediate-or-invalid-value.ts
│       │   │   │   │   │   │   ├── parse-intermediate-or-invalid-value.ts.test.ts
│       │   │   │   │   │   │   ├── unit-select-options.ts
│       │   │   │   │   │   │   ├── unit-select.test.ts
│       │   │   │   │   │   │   ├── unit-select.tsx
│       │   │   │   │   │   │   └── value-editor-dialog.tsx
│       │   │   │   │   │   ├── filter-content.tsx
│       │   │   │   │   │   ├── instances-kv.ts
│       │   │   │   │   │   ├── model.tsx
│       │   │   │   │   │   ├── modifier-keys.ts
│       │   │   │   │   │   ├── recent-selectors.ts
│       │   │   │   │   │   ├── repeated-style.test.ts
│       │   │   │   │   │   ├── repeated-style.tsx
│       │   │   │   │   │   ├── scroll-by-pointer.ts
│       │   │   │   │   │   ├── shadow-content.tsx
│       │   │   │   │   │   ├── show-more.stories.tsx
│       │   │   │   │   │   ├── show-more.tsx
│       │   │   │   │   │   ├── style-section.tsx
│       │   │   │   │   │   └── use-style-data.ts
│       │   │   │   │   ├── style-panel.tsx
│       │   │   │   │   ├── style-source/
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── style-source-badge.stories.tsx
│       │   │   │   │   │   ├── style-source-badge.tsx
│       │   │   │   │   │   ├── style-source-control.tsx
│       │   │   │   │   │   ├── style-source-input.stories.tsx
│       │   │   │   │   │   ├── style-source-input.tsx
│       │   │   │   │   │   ├── style-source-menu.tsx
│       │   │   │   │   │   └── use-sortable.tsx
│       │   │   │   │   ├── style-source-section.test.ts
│       │   │   │   │   └── style-source-section.tsx
│       │   │   │   ├── sync-status.tsx
│       │   │   │   ├── view-mode.tsx
│       │   │   │   └── workspace/
│       │   │   │       ├── canvas-iframe.tsx
│       │   │   │       ├── canvas-tools/
│       │   │   │       │   ├── apply-scale.ts
│       │   │   │       │   ├── block-editor-context-menu.tsx
│       │   │   │       │   ├── canvas-instance-context-menu.tsx
│       │   │   │       │   ├── canvas-tools.tsx
│       │   │   │       │   ├── grid-guides.tsx
│       │   │   │       │   ├── index.ts
│       │   │   │       │   ├── media-badge.tsx
│       │   │   │       │   ├── outline/
│       │   │   │       │   │   ├── block-instance-outline.tsx
│       │   │   │       │   │   ├── block-utils.ts
│       │   │   │       │   │   ├── collaborative-instance-outline.tsx
│       │   │   │       │   │   ├── hovered-instance-outline.tsx
│       │   │   │       │   │   ├── index.ts
│       │   │   │       │   │   ├── label.tsx
│       │   │   │       │   │   ├── outline.stories.tsx
│       │   │   │       │   │   ├── outline.tsx
│       │   │   │       │   │   └── selected-instance-outline.tsx
│       │   │   │       │   ├── resize-handles.tsx
│       │   │   │       │   ├── text-toolbar.tsx
│       │   │   │       │   └── use-subscribe-drag-drop-state.ts
│       │   │   │       ├── index.ts
│       │   │   │       └── workspace.tsx
│       │   │   ├── index.client.ts
│       │   │   ├── inspector.tsx
│       │   │   ├── shared/
│       │   │   │   ├── asset-manager/
│       │   │   │   │   ├── asset-filters.tsx
│       │   │   │   │   ├── asset-info.test.ts
│       │   │   │   │   ├── asset-info.tsx
│       │   │   │   │   ├── asset-manager.stories.tsx
│       │   │   │   │   ├── asset-manager.tsx
│       │   │   │   │   ├── asset-sort.tsx
│       │   │   │   │   ├── asset-thumbnail.tsx
│       │   │   │   │   ├── delete-unused-assets.tsx
│       │   │   │   │   ├── image.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── uploading-animation.tsx
│       │   │   │   │   ├── utils.test.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── assets/
│       │   │   │   │   ├── asset-upload.test.ts
│       │   │   │   │   ├── asset-upload.tsx
│       │   │   │   │   ├── asset-utils.test.ts
│       │   │   │   │   ├── asset-utils.ts
│       │   │   │   │   ├── assets-shell.tsx
│       │   │   │   │   ├── delete-assets.ts
│       │   │   │   │   ├── drag-monitor.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── not-found.tsx
│       │   │   │   │   ├── separator.tsx
│       │   │   │   │   ├── types.ts
│       │   │   │   │   ├── upload-assets.test.ts
│       │   │   │   │   ├── upload-assets.tsx
│       │   │   │   │   ├── use-assets.test.ts
│       │   │   │   │   └── use-assets.tsx
│       │   │   │   ├── binding-popover.test.ts
│       │   │   │   ├── binding-popover.tsx
│       │   │   │   ├── calc-canvas-width.test.ts
│       │   │   │   ├── calc-canvas-width.ts
│       │   │   │   ├── client-settings/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── settings.ts
│       │   │   │   ├── collapsible-section.stories.tsx
│       │   │   │   ├── collapsible-section.tsx
│       │   │   │   ├── commands.ts
│       │   │   │   ├── css-editor/
│       │   │   │   │   ├── add-style-input.tsx
│       │   │   │   │   ├── css-editor-context-menu.tsx
│       │   │   │   │   ├── css-editor.stories.tsx
│       │   │   │   │   ├── css-editor.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── parse-style-input.test.ts
│       │   │   │   │   └── parse-style-input.ts
│       │   │   │   ├── css-variable-utils.test.tsx
│       │   │   │   ├── css-variable-utils.tsx
│       │   │   │   ├── data-variable-utils.test.tsx
│       │   │   │   ├── data-variable-utils.tsx
│       │   │   │   ├── expression-editor.stories.tsx
│       │   │   │   ├── expression-editor.test.ts
│       │   │   │   ├── expression-editor.tsx
│       │   │   │   ├── fonts-manager/
│       │   │   │   │   ├── fonts-manager.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── item-menu.tsx
│       │   │   │   │   └── item-utils.ts
│       │   │   │   ├── inert-handlers.ts
│       │   │   │   ├── instance-context-menu.tsx
│       │   │   │   ├── instance-label.tsx
│       │   │   │   ├── loading.stories.tsx
│       │   │   │   ├── loading.tsx
│       │   │   │   ├── nano-states.ts
│       │   │   │   ├── relative-time.stories.tsx
│       │   │   │   ├── relative-time.tsx
│       │   │   │   ├── style-source-actions.tsx
│       │   │   │   ├── topbar-layout.stories.tsx
│       │   │   │   ├── topbar-layout.tsx
│       │   │   │   ├── topbar.tsx
│       │   │   │   ├── url-pattern.test.ts
│       │   │   │   ├── url-pattern.ts
│       │   │   │   └── use-disable-context-menu.ts
│       │   │   └── sidebar-left/
│       │   │       ├── sidebar-left.tsx
│       │   │       ├── sidebar-tabs.tsx
│       │   │       └── types.ts
│       │   ├── canvas/
│       │   │   ├── canvas.tsx
│       │   │   ├── collaborative-instance.ts
│       │   │   ├── elements.tsx
│       │   │   ├── features/
│       │   │   │   ├── build-mode/
│       │   │   │   │   ├── block-template.tsx
│       │   │   │   │   └── block.tsx
│       │   │   │   ├── text-editor/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── interop.test.tsx
│       │   │   │   │   ├── interop.ts
│       │   │   │   │   ├── text-editor.stories.tsx
│       │   │   │   │   ├── text-editor.tsx
│       │   │   │   │   └── toolbar-connector.tsx
│       │   │   │   └── webstudio-component/
│       │   │   │       ├── index.ts
│       │   │   │       ├── webstudio-component.test.tsx
│       │   │   │       └── webstudio-component.tsx
│       │   │   ├── grid-guide-utils.test.ts
│       │   │   ├── grid-guide-utils.ts
│       │   │   ├── index.client.ts
│       │   │   ├── inflator.test.ts
│       │   │   ├── inflator.ts
│       │   │   ├── instance-context-menu.ts
│       │   │   ├── instance-hovering.ts
│       │   │   ├── instance-selected.ts
│       │   │   ├── instance-selection.ts
│       │   │   ├── interceptor.ts
│       │   │   ├── scrollbar-width.ts
│       │   │   ├── shared/
│       │   │   │   ├── commands.ts
│       │   │   │   ├── font-weight-support.ts
│       │   │   │   ├── inert.ts
│       │   │   │   ├── routing-priority.test.ts
│       │   │   │   ├── routing-priority.ts
│       │   │   │   ├── scroll-new-instance-into-view.ts
│       │   │   │   ├── scroll-state.ts
│       │   │   │   ├── styles.test.ts
│       │   │   │   ├── styles.ts
│       │   │   │   ├── use-drag-drop.ts
│       │   │   │   └── use-pointer-outline.ts
│       │   │   └── stores.ts
│       │   ├── dashboard/
│       │   │   ├── dashboard.stories.tsx
│       │   │   ├── dashboard.tsx
│       │   │   ├── index.client.ts
│       │   │   ├── profile-menu.tsx
│       │   │   ├── projects/
│       │   │   │   ├── colors.ts
│       │   │   │   ├── project-card.tsx
│       │   │   │   ├── project-dialogs.tsx
│       │   │   │   ├── project-menu.tsx
│       │   │   │   ├── projects-list.tsx
│       │   │   │   ├── projects.tsx
│       │   │   │   ├── sort.test.ts
│       │   │   │   ├── sort.tsx
│       │   │   │   ├── tags.tsx
│       │   │   │   └── utils.ts
│       │   │   ├── search/
│       │   │   │   ├── nothing-found.tsx
│       │   │   │   ├── search-field.tsx
│       │   │   │   └── search-results.tsx
│       │   │   ├── shared/
│       │   │   │   ├── card.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── spinner.tsx
│       │   │   │   ├── thumbnail.tsx
│       │   │   │   └── types.ts
│       │   │   └── templates/
│       │   │       ├── template-card.tsx
│       │   │       └── templates.tsx
│       │   ├── env/
│       │   │   ├── env.server.ts
│       │   │   ├── env.static.server.ts
│       │   │   ├── env.static.ts
│       │   │   └── vite-env.d.ts
│       │   ├── root.tsx
│       │   ├── routes/
│       │   │   ├── _canvas.canvas.tsx
│       │   │   ├── _canvas.tsx
│       │   │   ├── _ui.$.tsx
│       │   │   ├── _ui.(builder).tsx
│       │   │   ├── _ui.dashboard._index.tsx
│       │   │   ├── _ui.dashboard.search.tsx
│       │   │   ├── _ui.dashboard.templates.tsx
│       │   │   ├── _ui.dashboard.tsx
│       │   │   ├── _ui.error.tsx
│       │   │   ├── _ui.login._index.tsx
│       │   │   ├── _ui.logout.tsx
│       │   │   ├── _ui.tsx
│       │   │   ├── auth.dev.tsx
│       │   │   ├── auth.github.tsx
│       │   │   ├── auth.github_.callback.tsx
│       │   │   ├── auth.google.tsx
│       │   │   ├── auth.google_.callback.tsx
│       │   │   ├── auth.ws.ts
│       │   │   ├── auth.ws_.callback.ts
│       │   │   ├── builder-logout.ts
│       │   │   ├── cgi.asset.$.ts
│       │   │   ├── cgi.empty[.]gif.ts
│       │   │   ├── cgi.image.$.ts
│       │   │   ├── cgi.video.$.ts
│       │   │   ├── dashboard-logout.ts
│       │   │   ├── n8n.$.tsx
│       │   │   ├── oauth.ws.authorize.tsx
│       │   │   ├── oauth.ws.token.ts
│       │   │   ├── rest.assets.tsx
│       │   │   ├── rest.assets_.$name.tsx
│       │   │   ├── rest.build.$buildId.tsx
│       │   │   ├── rest.buildId.$projectId.tsx
│       │   │   ├── rest.data.$projectId.ts
│       │   │   ├── rest.patch.ts
│       │   │   ├── rest.resources-loader.ts
│       │   │   └── trpc.$.ts
│       │   ├── services/
│       │   │   ├── auth-strategy/
│       │   │   │   └── ws.server.ts
│       │   │   ├── auth.server.ts
│       │   │   ├── auth.server.utils.ts
│       │   │   ├── bloom-filter.server.test.ts
│       │   │   ├── bloom-filter.server.ts
│       │   │   ├── builder-access.server.ts
│       │   │   ├── builder-auth.server.ts
│       │   │   ├── builder-session.server.ts
│       │   │   ├── cookie.server.ts
│       │   │   ├── csrf-session.server.ts
│       │   │   ├── destinations.server.ts
│       │   │   ├── logout-router.server.ts
│       │   │   ├── no-cross-origin-cookie.ts
│       │   │   ├── no-store-redirect.ts
│       │   │   ├── session.server.ts
│       │   │   ├── token.server.test.ts
│       │   │   ├── token.server.ts
│       │   │   ├── trcp-router.server.ts
│       │   │   ├── trpc.server.ts
│       │   │   └── user-router.server.ts
│       │   └── shared/
│       │       ├── $resources/
│       │       │   ├── assets.server.ts
│       │       │   ├── current-date.server.ts
│       │       │   └── sitemap.xml.server.ts
│       │       ├── app.css
│       │       ├── array-utils.test.ts
│       │       ├── array-utils.ts
│       │       ├── asset-client.ts
│       │       ├── awareness.test.tsx
│       │       ├── awareness.ts
│       │       ├── breakpoints/
│       │       │   ├── index.ts
│       │       │   ├── select-breakpoint-by-order.ts
│       │       │   └── stores.ts
│       │       ├── breakpoints-utils.test.ts
│       │       ├── breakpoints-utils.ts
│       │       ├── builder-api.ts
│       │       ├── builder-data.ts
│       │       ├── canvas-api.ts
│       │       ├── client-only.ts
│       │       ├── client-supports.ts
│       │       ├── clone-project.tsx
│       │       ├── code-editor-base.tsx
│       │       ├── code-editor.stories.tsx
│       │       ├── code-editor.tsx
│       │       ├── code-highlight.ts
│       │       ├── commands-emitter.ts
│       │       ├── content-model.test.tsx
│       │       ├── content-model.ts
│       │       ├── context.server.ts
│       │       ├── copy-paste/
│       │       │   ├── asset-upload.test.tsx
│       │       │   ├── asset-upload.ts
│       │       │   ├── init-copy-paste.ts
│       │       │   ├── plugin-html.test.tsx
│       │       │   ├── plugin-html.ts
│       │       │   ├── plugin-instance.test.ts
│       │       │   ├── plugin-instance.ts
│       │       │   ├── plugin-markdown.test.tsx
│       │       │   ├── plugin-markdown.ts
│       │       │   └── plugin-webflow/
│       │       │       ├── __generated__/
│       │       │       │   └── style-presets.ts
│       │       │       ├── instances-properties.ts
│       │       │       ├── plugin-webflow.test.tsx
│       │       │       ├── plugin-webflow.ts
│       │       │       ├── schema.ts
│       │       │       ├── style-presets-overrides.ts
│       │       │       ├── style-presets.css
│       │       │       └── styles.ts
│       │       ├── copy-paste.test.tsx
│       │       ├── copy-to-clipboard.stories.tsx
│       │       ├── copy-to-clipboard.tsx
│       │       ├── csrf.client.ts
│       │       ├── data-variables.test.tsx
│       │       ├── data-variables.ts
│       │       ├── db/
│       │       │   ├── canvas.server.ts
│       │       │   ├── index.ts
│       │       │   ├── user-plan-features.server.ts
│       │       │   └── user.server.ts
│       │       ├── debug-track.ts
│       │       ├── debug.ts
│       │       ├── dom-hooks/
│       │       │   ├── index.ts
│       │       │   ├── use-content-editable.ts
│       │       │   └── use-window-resize.ts
│       │       ├── dom-utils.stories.tsx
│       │       ├── dom-utils.test.ts
│       │       ├── dom-utils.ts
│       │       ├── empty.ts
│       │       ├── entri/
│       │       │   └── entri-api.server.ts
│       │       ├── error/
│       │       │   ├── error-boundary.tsx
│       │       │   ├── error-message.client.tsx
│       │       │   ├── error-message.stories.tsx
│       │       │   ├── error-parse.ts
│       │       │   ├── index.ts
│       │       │   └── toast-error.tsx
│       │       ├── event-utils.test.ts
│       │       ├── event-utils.ts
│       │       ├── fetch.client.ts
│       │       ├── form-utils/
│       │       │   ├── index.ts
│       │       │   └── use-ids.ts
│       │       ├── help.tsx
│       │       ├── hook-utils/
│       │       │   ├── effect-event.ts
│       │       │   ├── use-interval.ts
│       │       │   └── use-mount.ts
│       │       ├── html.test.tsx
│       │       ├── html.ts
│       │       ├── instance-utils.test.tsx
│       │       ├── instance-utils.ts
│       │       ├── logout.client.tsx
│       │       ├── marketplace/
│       │       │   ├── db.server.ts
│       │       │   ├── router.server.ts
│       │       │   └── types.ts
│       │       ├── matcher.test.tsx
│       │       ├── matcher.ts
│       │       ├── math-utils.ts
│       │       ├── nano-hash.test.ts
│       │       ├── nano-hash.ts
│       │       ├── nano-states/
│       │       │   ├── breakpoints.ts
│       │       │   ├── canvas.ts
│       │       │   ├── components.ts
│       │       │   ├── index.ts
│       │       │   ├── instances.ts
│       │       │   ├── misc.ts
│       │       │   ├── pages.ts
│       │       │   ├── project-settings.ts
│       │       │   ├── props.test.tsx
│       │       │   ├── props.ts
│       │       │   └── variables.ts
│       │       ├── page-utils.test.tsx
│       │       ├── page-utils.ts
│       │       ├── pages/
│       │       │   ├── index.ts
│       │       │   └── use-switch-page.ts
│       │       ├── project-settings/
│       │       │   ├── image-control.tsx
│       │       │   ├── import-redirects-dialog.stories.tsx
│       │       │   ├── import-redirects-dialog.tsx
│       │       │   ├── index.ts
│       │       │   ├── project-settings.stories.tsx
│       │       │   ├── project-settings.tsx
│       │       │   ├── section-backups.tsx
│       │       │   ├── section-general.tsx
│       │       │   ├── section-marketplace.tsx
│       │       │   ├── section-publish.tsx
│       │       │   ├── section-redirects.test.ts
│       │       │   ├── section-redirects.tsx
│       │       │   ├── utils.test.ts
│       │       │   └── utils.ts
│       │       ├── pubsub/
│       │       │   ├── create.test.ts
│       │       │   ├── create.ts
│       │       │   ├── index.ts
│       │       │   └── raf-queue.ts
│       │       ├── redirects/
│       │       │   ├── README.md
│       │       │   ├── fixtures/
│       │       │   │   ├── apache.htaccess
│       │       │   │   ├── generic.csv
│       │       │   │   ├── generic.json
│       │       │   │   ├── hubspot.csv
│       │       │   │   ├── netlify._redirects
│       │       │   │   ├── shopify.csv
│       │       │   │   └── vercel-nextjs.json
│       │       │   ├── redirect-loop-detection.test.ts
│       │       │   ├── redirect-loop-detection.ts
│       │       │   ├── redirect-parsers.test.ts
│       │       │   └── redirect-parsers.ts
│       │       ├── resource-utils.ts
│       │       ├── resources.test.ts
│       │       ├── resources.ts
│       │       ├── router-utils/
│       │       │   ├── index.ts
│       │       │   ├── is-canvas.ts
│       │       │   ├── origins.ts
│       │       │   └── path-utils.ts
│       │       ├── session/
│       │       │   ├── index.ts
│       │       │   └── use-login-error-message.ts
│       │       ├── share-project/
│       │       │   ├── index.ts
│       │       │   ├── share-project-container.tsx
│       │       │   ├── share-project.stories.tsx
│       │       │   └── share-project.tsx
│       │       ├── shim.test.ts
│       │       ├── shim.ts
│       │       ├── store-utils.test.ts
│       │       ├── store-utils.ts
│       │       ├── string-utils.ts
│       │       ├── style-object-model.test.tsx
│       │       ├── style-object-model.ts
│       │       ├── style-source-utils.test.tsx
│       │       ├── style-source-utils.ts
│       │       ├── sync/
│       │       │   ├── command-queue.ts
│       │       │   ├── data-stores.ts
│       │       │   ├── project-queue.ts
│       │       │   ├── sync-client.ts
│       │       │   └── sync-stores.ts
│       │       ├── sync-client.test.ts
│       │       ├── sync-client.ts
│       │       ├── system.test.ts
│       │       ├── system.ts
│       │       ├── tailwind/
│       │       │   ├── __generated__/
│       │       │   │   └── preflight.ts
│       │       │   ├── preflight-bin.ts
│       │       │   ├── preflight.css
│       │       │   ├── tailwind.test.tsx
│       │       │   └── tailwind.ts
│       │       ├── token-conflict-dialog.tsx
│       │       ├── tree-utils.test.ts
│       │       ├── tree-utils.ts
│       │       ├── trpc/
│       │       │   └── trpc-client.ts
│       │       ├── use-set-features.ts
│       │       ├── visually-hidden.ts
│       │       ├── webstudio-data-migrator.test.ts
│       │       └── webstudio-data-migrator.ts
│       ├── docker-compose.yaml
│       ├── docs/
│       │   └── test-cases.md
│       ├── package.json
│       ├── public/
│       │   └── robots.txt
│       ├── tsconfig.json
│       ├── vite.config.ts
│       └── vitest.config.ts
├── codemod/
│   ├── migrate-css-variables.ts
│   └── migrate-tokens.ts
├── fixtures/
│   ├── README.md
│   ├── react-router-cloudflare/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── entry.server.tsx
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── react-router.config.ts
│   │   ├── tsconfig.json
│   │   ├── vite.config.ts
│   │   ├── workers/
│   │   │   └── app.ts
│   │   └── wrangler.jsonc
│   ├── react-router-docker/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [_image].$.ts
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── react-router-netlify/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── netlify.toml
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── react-router-vercel/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── react-router.config.ts
│   │   ├── tsconfig.json
│   │   ├── vercel.json
│   │   └── vite.config.ts
│   ├── ssg/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   └── constants.mjs
│   │   ├── package.json
│   │   ├── pages/
│   │   │   ├── +config.ts
│   │   │   ├── another-page/
│   │   │   │   ├── +Head.tsx
│   │   │   │   ├── +Page.tsx
│   │   │   │   └── +data.ts
│   │   │   └── index/
│   │   │       ├── +Head.tsx
│   │   │       ├── +Page.tsx
│   │   │       └── +data.ts
│   │   ├── renderer/
│   │   │   ├── +onRenderClient.tsx
│   │   │   └── +onRenderHtml.tsx
│   │   ├── tsconfig.json
│   │   ├── vike.d.ts
│   │   └── vite.config.ts
│   ├── ssg-netlify-by-project-id/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [redirect]._index.server.tsx
│   │   │   │   ├── [redirect]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   └── constants.mjs
│   │   ├── package.json
│   │   ├── pages/
│   │   │   ├── +config.ts
│   │   │   ├── index/
│   │   │   │   ├── +Head.tsx
│   │   │   │   ├── +Page.tsx
│   │   │   │   └── +data.ts
│   │   │   └── redirect/
│   │   │       ├── +Head.tsx
│   │   │       ├── +Page.tsx
│   │   │       └── +data.ts
│   │   ├── renderer/
│   │   │   ├── +onRenderClient.tsx
│   │   │   └── +onRenderHtml.tsx
│   │   ├── tsconfig.json
│   │   ├── vike.d.ts
│   │   └── vite.config.ts
│   ├── webstudio-cloudflare-template/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── WS_CF_README.md
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   └── routes/
│   │   │       ├── [another-page]._index.tsx
│   │   │       ├── [robots.txt].tsx
│   │   │       ├── [sitemap.xml]._index.tsx
│   │   │       └── _index.tsx
│   │   ├── functions/
│   │   │   └── [[path]].ts
│   │   ├── load-context.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   ├── vite.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.toml
│   └── webstudio-features/
│       ├── .gitignore
│       ├── .npmrc
│       ├── .template/
│       │   ├── .npmrc
│       │   ├── app/
│       │   │   └── constants.mjs
│       │   ├── package.json
│       │   ├── tsconfig.json
│       │   └── vite.config.ts
│       ├── .webstudio/
│       │   ├── config.json
│       │   └── data.json
│       ├── README.md
│       ├── app/
│       │   ├── __generated__/
│       │   │   ├── $resources.assets.ts
│       │   │   ├── $resources.sitemap.xml.ts
│       │   │   ├── [_route_with_symbols_]._index.server.tsx
│       │   │   ├── [_route_with_symbols_]._index.tsx
│       │   │   ├── [animations]._index.server.tsx
│       │   │   ├── [animations]._index.tsx
│       │   │   ├── [assets1]._index.server.tsx
│       │   │   ├── [assets1]._index.tsx
│       │   │   ├── [class-names]._index.server.tsx
│       │   │   ├── [class-names]._index.tsx
│       │   │   ├── [content-block]._index.server.tsx
│       │   │   ├── [content-block]._index.tsx
│       │   │   ├── [duration]._index.server.tsx
│       │   │   ├── [duration]._index.tsx
│       │   │   ├── [expressions]._index.server.tsx
│       │   │   ├── [expressions]._index.tsx
│       │   │   ├── [form]._index.server.tsx
│       │   │   ├── [form]._index.tsx
│       │   │   ├── [head-tag]._index.server.tsx
│       │   │   ├── [head-tag]._index.tsx
│       │   │   ├── [heading-with-id]._index.server.tsx
│       │   │   ├── [heading-with-id]._index.tsx
│       │   │   ├── [nested].[nested-page]._index.server.tsx
│       │   │   ├── [nested].[nested-page]._index.tsx
│       │   │   ├── [radix]._index.server.tsx
│       │   │   ├── [radix]._index.tsx
│       │   │   ├── [resources]._index.server.tsx
│       │   │   ├── [resources]._index.tsx
│       │   │   ├── [sitemap.xml]._index.server.tsx
│       │   │   ├── [sitemap.xml]._index.tsx
│       │   │   ├── [text-duration]._index.server.tsx
│       │   │   ├── [text-duration]._index.tsx
│       │   │   ├── _index.server.tsx
│       │   │   ├── _index.tsx
│       │   │   └── index.css
│       │   ├── constants.mjs
│       │   ├── extension.ts
│       │   ├── root.tsx
│       │   ├── routes/
│       │   │   ├── [_route_with_symbols_]._index.tsx
│       │   │   ├── [animations]._index.tsx
│       │   │   ├── [assets1]._index.tsx
│       │   │   ├── [class-names]._index.tsx
│       │   │   ├── [content-block]._index.tsx
│       │   │   ├── [duration]._index.tsx
│       │   │   ├── [expressions]._index.tsx
│       │   │   ├── [form]._index.tsx
│       │   │   ├── [head-tag]._index.tsx
│       │   │   ├── [heading-with-id]._index.tsx
│       │   │   ├── [nested].[nested-page]._index.tsx
│       │   │   ├── [radix]._index.tsx
│       │   │   ├── [resources]._index.tsx
│       │   │   ├── [robots.txt].tsx
│       │   │   ├── [sitemap.xml]._index.tsx
│       │   │   ├── [text-duration]._index.tsx
│       │   │   └── _index.tsx
│       │   └── routes.ts
│       ├── package.json
│       ├── proxy-emulator/
│       │   └── dedupe-meta.ts
│       ├── public/
│       │   └── assets/
│       │       ├── webm-example_2r_6VmRBjhAy3ldaqz0gk.webm
│       │       └── webm-example_zNrAFpO1v78xz91jYpaiE.webm
│       ├── tsconfig.json
│       └── vite.config.ts
├── https/
│   ├── README.md
│   ├── fullchain.pem
│   ├── haproxy.pem
│   ├── haproxy.sh
│   └── privkey.pem
├── lostpixel.config.js
├── package.json
├── packages/
│   ├── asset-uploader/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.ts
│   │   │   ├── clients/
│   │   │   │   ├── fs/
│   │   │   │   │   ├── fs.ts
│   │   │   │   │   └── upload.ts
│   │   │   │   └── s3/
│   │   │   │       ├── s3.ts
│   │   │   │       └── upload.ts
│   │   │   ├── constants.ts
│   │   │   ├── db/
│   │   │   │   ├── index.ts
│   │   │   │   └── load.ts
│   │   │   ├── delete.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── patch.ts
│   │   │   ├── schema.ts
│   │   │   ├── types.ts
│   │   │   ├── upload.ts
│   │   │   └── utils/
│   │   │       ├── font-data.test.ts
│   │   │       ├── font-data.ts
│   │   │       ├── format-asset.test.ts
│   │   │       ├── format-asset.ts
│   │   │       ├── get-asset-data.ts
│   │   │       ├── get-unique-filename.ts
│   │   │       ├── sanitize-s3-key.test.ts
│   │   │       ├── sanitize-s3-key.ts
│   │   │       ├── size-limiter.ts
│   │   │       └── to-bytes.ts
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── authorization-token/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── authorization-token.ts
│   │   │   │   └── index.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   └── trpc/
│   │   │       ├── authorization-tokens-router.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── cli/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── bin.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── args.ts
│   │   │   ├── build-utils.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── build.ts
│   │   │   │   ├── init-flow.ts
│   │   │   │   ├── link.ts
│   │   │   │   ├── sync.ts
│   │   │   │   └── yargs-types.ts
│   │   │   ├── config.ts
│   │   │   ├── config.ts-expect.ts
│   │   │   ├── framework-react-router.ts
│   │   │   ├── framework-remix.ts
│   │   │   ├── framework-vike-ssg.ts
│   │   │   ├── framework.ts
│   │   │   ├── fs-utils.ts
│   │   │   ├── html-to-jsx.test.ts
│   │   │   ├── html-to-jsx.ts
│   │   │   └── prebuild.ts
│   │   ├── templates/
│   │   │   ├── cloudflare/
│   │   │   │   ├── WS_CF_README.md
│   │   │   │   ├── functions/
│   │   │   │   │   └── [[path]].ts
│   │   │   │   ├── load-context.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vite.config.ts
│   │   │   │   ├── worker-configuration.d.ts
│   │   │   │   └── wrangler.toml
│   │   │   ├── defaults/
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   ├── extension.ts
│   │   │   │   │   ├── root.tsx
│   │   │   │   │   ├── route-templates/
│   │   │   │   │   │   ├── default-sitemap.tsx
│   │   │   │   │   │   ├── html.tsx
│   │   │   │   │   │   ├── redirect.tsx
│   │   │   │   │   │   └── xml.tsx
│   │   │   │   │   └── routes/
│   │   │   │   │       └── [robots.txt].tsx
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── internal/
│   │   │   │   ├── .npmrc
│   │   │   │   ├── package.json
│   │   │   │   └── tsconfig.json
│   │   │   ├── react-router/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── app/
│   │   │   │   │   ├── extension.ts
│   │   │   │   │   ├── root.tsx
│   │   │   │   │   ├── route-templates/
│   │   │   │   │   │   ├── default-sitemap.tsx
│   │   │   │   │   │   ├── html.tsx
│   │   │   │   │   │   ├── redirect.tsx
│   │   │   │   │   │   └── xml.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   └── [robots.txt].tsx
│   │   │   │   │   └── routes.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── react-router-cloudflare/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── entry.server.tsx
│   │   │   │   ├── package.json
│   │   │   │   ├── react-router.config.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vite.config.ts
│   │   │   │   ├── workers/
│   │   │   │   │   └── app.ts
│   │   │   │   └── wrangler.jsonc
│   │   │   ├── react-router-docker/
│   │   │   │   ├── .dockerignore
│   │   │   │   ├── Dockerfile
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── routes/
│   │   │   │   │       └── [_image].$.ts
│   │   │   │   └── package.json
│   │   │   ├── react-router-netlify/
│   │   │   │   ├── app/
│   │   │   │   │   └── constants.mjs
│   │   │   │   ├── netlify.toml
│   │   │   │   ├── package.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── react-router-vercel/
│   │   │   │   ├── app/
│   │   │   │   │   └── constants.mjs
│   │   │   │   ├── package.json
│   │   │   │   ├── react-router.config.ts
│   │   │   │   └── vercel.json
│   │   │   ├── saas-helpers/
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── ssg/
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── route-templates/
│   │   │   │   │       └── html/
│   │   │   │   │           ├── +Head.tsx
│   │   │   │   │           ├── +Page.tsx
│   │   │   │   │           └── +data.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── pages/
│   │   │   │   │   └── +config.ts
│   │   │   │   ├── renderer/
│   │   │   │   │   ├── +onRenderClient.tsx
│   │   │   │   │   └── +onRenderHtml.tsx
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vike.d.ts
│   │   │   │   └── vite.config.ts
│   │   │   ├── ssg-netlify/
│   │   │   │   └── app/
│   │   │   │       └── constants.mjs
│   │   │   └── ssg-vercel/
│   │   │       ├── app/
│   │   │       │   └── constants.mjs
│   │   │       └── public/
│   │   │           └── vercel.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── css-data/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── bin/
│   │   │   ├── css-to-ws.ts
│   │   │   ├── css-tree-dist-data.d.ts
│   │   │   ├── html.css.ts
│   │   │   ├── mdn-data.ts
│   │   │   ├── prompts/
│   │   │   │   ├── declarations.prompt.md
│   │   │   │   ├── properties.prompt.md
│   │   │   │   └── pseudo-selectors.prompt.md
│   │   │   └── property-value-descriptions.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── animatable-properties.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── keyword-values.ts
│   │   │   │   ├── properties.ts
│   │   │   │   ├── property-value-descriptions.ts
│   │   │   │   ├── pseudo-classes.ts
│   │   │   │   ├── pseudo-elements.ts
│   │   │   │   ├── pseudo-selector-descriptions.ts
│   │   │   │   ├── shorthand-properties.ts
│   │   │   │   └── units.ts
│   │   │   ├── custom-data.ts
│   │   │   ├── html.css
│   │   │   ├── index.ts
│   │   │   ├── media-condition-simulator.test.ts
│   │   │   ├── media-condition-simulator.ts
│   │   │   ├── parse-css-value.test.ts
│   │   │   ├── parse-css-value.ts
│   │   │   ├── parse-css.test.ts
│   │   │   ├── parse-css.ts
│   │   │   ├── property-parsers/
│   │   │   │   ├── conic-gradient.test.ts
│   │   │   │   ├── conic-gradient.ts
│   │   │   │   ├── gradient-utils.ts
│   │   │   │   ├── grid-template-areas.test.ts
│   │   │   │   ├── grid-template-areas.ts
│   │   │   │   ├── grid-template-tracks.test.ts
│   │   │   │   ├── grid-template-tracks.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── linear-gradient.test.ts
│   │   │   │   ├── linear-gradient.ts
│   │   │   │   ├── radial-gradient.test.ts
│   │   │   │   ├── radial-gradient.ts
│   │   │   │   └── types.ts
│   │   │   ├── selector-validation.test.ts
│   │   │   ├── selector-validation.ts
│   │   │   ├── shorthands.test.ts
│   │   │   └── shorthands.ts
│   │   └── tsconfig.json
│   ├── css-engine/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── types.ts
│   │   │   ├── core/
│   │   │   │   ├── atomic.test.ts
│   │   │   │   ├── atomic.ts
│   │   │   │   ├── compare-media.test.ts
│   │   │   │   ├── compare-media.ts
│   │   │   │   ├── create-style-sheet.ts
│   │   │   │   ├── css-engine.stories.tsx
│   │   │   │   ├── equal-media.test.ts
│   │   │   │   ├── equal-media.ts
│   │   │   │   ├── find-applicable-media.test.ts
│   │   │   │   ├── find-applicable-media.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── match-media.test.ts
│   │   │   │   ├── match-media.ts
│   │   │   │   ├── merger.test.ts
│   │   │   │   ├── merger.ts
│   │   │   │   ├── prefixer.test.ts
│   │   │   │   ├── prefixer.ts
│   │   │   │   ├── rules.test.ts
│   │   │   │   ├── rules.ts
│   │   │   │   ├── style-element.ts
│   │   │   │   ├── style-sheet-regular.test.ts
│   │   │   │   ├── style-sheet-regular.ts
│   │   │   │   ├── style-sheet.ts
│   │   │   │   ├── to-property.test.ts
│   │   │   │   ├── to-property.ts
│   │   │   │   ├── to-value.test.ts
│   │   │   │   └── to-value.ts
│   │   │   ├── css.ts
│   │   │   ├── index.ts
│   │   │   ├── runtime.ts
│   │   │   └── schema.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── dashboard/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── index.ts
│   │   │   │   └── projects.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   └── trpc/
│   │   │       ├── index.ts
│   │   │       └── project-router.ts
│   │   └── tsconfig.json
│   ├── design-system/
│   │   ├── LICENSE
│   │   ├── bin/
│   │   │   └── transform-figma-tokens.ts
│   │   ├── documentation/
│   │   │   └── figma-design-tokens.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── figma-design-tokens.json
│   │   │   │   └── figma-design-tokens.ts
│   │   │   ├── components/
│   │   │   │   ├── __DEPRECATED__/
│   │   │   │   │   ├── list.stories.tsx
│   │   │   │   │   └── list.tsx
│   │   │   │   ├── avatar.stories.tsx
│   │   │   │   ├── avatar.tsx
│   │   │   │   ├── box.tsx
│   │   │   │   ├── button.stories.tsx
│   │   │   │   ├── button.tsx
│   │   │   │   ├── card.stories.tsx
│   │   │   │   ├── card.tsx
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── checkbox.tsx
│   │   │   │   ├── color-picker.stories.tsx
│   │   │   │   ├── color-picker.tsx
│   │   │   │   ├── combobox.stories.tsx
│   │   │   │   ├── combobox.tsx
│   │   │   │   ├── command.stories.tsx
│   │   │   │   ├── command.tsx
│   │   │   │   ├── component-card.stories.tsx
│   │   │   │   ├── component-card.tsx
│   │   │   │   ├── context-menu.stories.tsx
│   │   │   │   ├── context-menu.tsx
│   │   │   │   ├── css-value-list-item.stories.tsx
│   │   │   │   ├── css-value-list-item.tsx
│   │   │   │   ├── dialog.stories.tsx
│   │   │   │   ├── dialog.test.ts
│   │   │   │   ├── dialog.tsx
│   │   │   │   ├── dropdown-menu.stories.tsx
│   │   │   │   ├── dropdown-menu.tsx
│   │   │   │   ├── enhanced-tooltip.stories.tsx
│   │   │   │   ├── enhanced-tooltip.tsx
│   │   │   │   ├── flex.tsx
│   │   │   │   ├── floating-panel.stories.tsx
│   │   │   │   ├── floating-panel.tsx
│   │   │   │   ├── focus-ring.ts
│   │   │   │   ├── gradient-picker.stories.tsx
│   │   │   │   ├── gradient-picker.tsx
│   │   │   │   ├── grid.tsx
│   │   │   │   ├── icon-button.stories.tsx
│   │   │   │   ├── icon-button.tsx
│   │   │   │   ├── input-field.stories.tsx
│   │   │   │   ├── input-field.tsx
│   │   │   │   ├── kbd.stories.tsx
│   │   │   │   ├── kbd.tsx
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── label.tsx
│   │   │   │   ├── link.stories.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── list-position-indicator.stories.tsx
│   │   │   │   ├── list-position-indicator.tsx
│   │   │   │   ├── menu.stories.tsx
│   │   │   │   ├── menu.tsx
│   │   │   │   ├── nested-icon-label.stories.tsx
│   │   │   │   ├── nested-icon-label.tsx
│   │   │   │   ├── nested-input-button.stories.tsx
│   │   │   │   ├── nested-input-button.tsx
│   │   │   │   ├── panel-banner.stories.tsx
│   │   │   │   ├── panel-banner.tsx
│   │   │   │   ├── panel-tabs.stories.tsx
│   │   │   │   ├── panel-tabs.tsx
│   │   │   │   ├── panel-title.stories.tsx
│   │   │   │   ├── panel-title.tsx
│   │   │   │   ├── popover.stories.tsx
│   │   │   │   ├── popover.tsx
│   │   │   │   ├── position-grid.stories.tsx
│   │   │   │   ├── position-grid.tsx
│   │   │   │   ├── primitives/
│   │   │   │   │   ├── arrow-focus.tsx
│   │   │   │   │   ├── create-content-controller.stories.tsx
│   │   │   │   │   ├── create-content-controller.ts
│   │   │   │   │   ├── dnd/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   │   └── geometry-utils.test.ts.snap
│   │   │   │   │   │   ├── canvas.stories.tsx
│   │   │   │   │   │   ├── dom-utils.ts
│   │   │   │   │   │   ├── geometry-utils.test.ts
│   │   │   │   │   │   ├── geometry-utils.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── placement-indicator.tsx
│   │   │   │   │   │   ├── sortable-list.stories.tsx
│   │   │   │   │   │   ├── use-auto-scroll.test.ts
│   │   │   │   │   │   ├── use-auto-scroll.ts
│   │   │   │   │   │   ├── use-drag-cursor.ts
│   │   │   │   │   │   ├── use-drag.ts
│   │   │   │   │   │   ├── use-drop.ts
│   │   │   │   │   │   ├── use-hold.ts
│   │   │   │   │   │   └── use-sortable.tsx
│   │   │   │   │   ├── is-truncated.tsx
│   │   │   │   │   ├── list.tsx
│   │   │   │   │   ├── numeric-gesture-control.stories.tsx
│   │   │   │   │   ├── numeric-gesture-control.ts
│   │   │   │   │   ├── numeric-input-arrow-keys.ts
│   │   │   │   │   ├── small-button.stories.tsx
│   │   │   │   │   ├── small-button.tsx
│   │   │   │   │   └── use-scrub.ts
│   │   │   │   ├── pro-badge.stories.tsx
│   │   │   │   ├── pro-badge.tsx
│   │   │   │   ├── progress.stories.tsx
│   │   │   │   ├── progress.tsx
│   │   │   │   ├── radio.stories.tsx
│   │   │   │   ├── radio.tsx
│   │   │   │   ├── scroll-area.stories.tsx
│   │   │   │   ├── scroll-area.tsx
│   │   │   │   ├── search-field.stories.tsx
│   │   │   │   ├── search-field.tsx
│   │   │   │   ├── section-title.stories.tsx
│   │   │   │   ├── section-title.tsx
│   │   │   │   ├── select-button.stories.tsx
│   │   │   │   ├── select-button.tsx
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── select.tsx
│   │   │   │   ├── separator.stories.tsx
│   │   │   │   ├── separator.tsx
│   │   │   │   ├── small-icon-button.stories.tsx
│   │   │   │   ├── small-icon-button.tsx
│   │   │   │   ├── small-toggle-button.stories.tsx
│   │   │   │   ├── small-toggle-button.tsx
│   │   │   │   ├── storybook.tsx
│   │   │   │   ├── switch.stories.tsx
│   │   │   │   ├── switch.tsx
│   │   │   │   ├── text-area.stories.tsx
│   │   │   │   ├── text-area.tsx
│   │   │   │   ├── text.stories.tsx
│   │   │   │   ├── text.ts
│   │   │   │   ├── toast.stories.tsx
│   │   │   │   ├── toast.tsx
│   │   │   │   ├── toggle-button.stories.tsx
│   │   │   │   ├── toggle-button.tsx
│   │   │   │   ├── toggle-group.stories.tsx
│   │   │   │   ├── toggle-group.tsx
│   │   │   │   ├── toolbar.stories.tsx
│   │   │   │   ├── toolbar.tsx
│   │   │   │   ├── tooltip.stories.tsx
│   │   │   │   ├── tooltip.tsx
│   │   │   │   ├── tree.stories.tsx
│   │   │   │   ├── tree.tsx
│   │   │   │   ├── two-rows-icon-button-container.stories.tsx
│   │   │   │   └── two-rows-icon-button-container.tsx
│   │   │   ├── index.ts
│   │   │   ├── stitches.config.ts
│   │   │   └── utilities.ts
│   │   ├── tsconfig.json
│   │   ├── tsconfig.typecheck.json
│   │   └── vitest.config.ts
│   ├── domain/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── cname-from-user-id.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── validate.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── rdap.ts
│   │   │   └── trpc/
│   │   │       ├── domain.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── feature-flags/
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── feature.ts
│   │   │   ├── flags.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── fonts/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── constants.ts
│   │   │   ├── font-weights.ts
│   │   │   ├── get-font-faces.test.ts
│   │   │   ├── get-font-faces.ts
│   │   │   ├── index.ts
│   │   │   └── schema.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── generate-arg-types/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── arg-types.ts
│   │   │   ├── cli.ts
│   │   │   └── props/
│   │   │       └── add-descriptions.ts
│   │   └── tsconfig.json
│   ├── html-data/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── bin/
│   │   │   ├── aria.ts
│   │   │   ├── attributes.ts
│   │   │   ├── crawler.ts
│   │   │   ├── elements.ts
│   │   │   ├── overrides.ts
│   │   │   └── possible-standard-names.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── aria-jsx-test.tsx
│   │   │   │   ├── aria.ts
│   │   │   │   ├── attributes-jsx-test.tsx
│   │   │   │   ├── attributes.ts
│   │   │   │   └── elements.ts
│   │   │   ├── index.ts
│   │   │   └── pseudo-classes.ts
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── http-client/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.test.ts
│   │   │   └── index.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── icons/
│   │   ├── LICENSE
│   │   ├── generate.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── components.tsx
│   │   │   │   └── svg.ts
│   │   │   ├── index.stories.tsx
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── svg-string.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── image/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── image-dev.stories.tsx
│   │   │   ├── image-loader.test.ts
│   │   │   ├── image-loaders.ts
│   │   │   ├── image-optimize.test.ts
│   │   │   ├── image-optimize.ts
│   │   │   ├── image.tsx
│   │   │   └── index.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── postgrest/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── playground/
│   │   │   ├── domains.ts
│   │   │   └── pnpm-playground
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── db-types.ts
│   │   │   └── index.server.ts
│   │   ├── supabase/
│   │   │   ├── SQL-TESTS-AI.md
│   │   │   └── tests/
│   │   │       ├── cleanup-builds.sql
│   │   │       ├── latest-builds-domains.sql
│   │   │       ├── latest-builds-projects.sql
│   │   │       └── project-domains.sql
│   │   └── tsconfig.json
│   ├── prisma-client/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── migrations-cli/
│   │   │   ├── README.md
│   │   │   ├── TROUBLESHOOTING.md
│   │   │   ├── args.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands.ts
│   │   │   ├── errors.ts
│   │   │   ├── logger.ts
│   │   │   ├── prisma-migrations.ts
│   │   │   └── umzug.ts
│   │   ├── package.json
│   │   ├── prisma/
│   │   │   ├── migrations/
│   │   │   │   ├── 20220601192603_start/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608130924_/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608130959_adduser/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608131719_add_user/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220611090740_/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220611091346_add_email/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220616143541_add_projects/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220616143902_userid_not_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220619163536_userid_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624214305_teams/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624215036_remove_userid/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624235138_users_have_projects/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220714112221_add_assets/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220714114102_remove_size/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220715192633_add_alt/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220716191150_add_more_info_to_asset/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220716192051_make_metadata_not_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220717152939_make_width_and_height_float/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220717193140_make_width_and_height_decimal/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220722131820_remove_path/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220722132445_add_location/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220905153337_noop/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220909124449_builds/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220909124542_builds-data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220909131750_builds-cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220912141854_assets-meta/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220912142938_assets-meta-data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220912150542_assets-meta-cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220915143947_breakpoints-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220915144008_breakpoints-build_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220915145316_breakpoints-build_cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221021172622_asset_format_notnull/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221021172647_lowercase_domains/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221126165439_design-tokens/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221201075120_user-props/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221208123312_remove-assets-from-project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221218211129_tree_text/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221227220622_assets-status/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221230120125_tree_preset_styles/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230106000103_tree_styles/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230106000143_tree_styles_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230115165217_tree_instances/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230115165314_tree_instances_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230119013820_instance-props-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230119181836_tree_props/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230119181858_tree_props_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230120130130_dashboard-project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230120130131_dashboard-project-is-prod/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230123225816_dashboard-project-is-deleted/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230124131218_authorization-tokens/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230127120101_style_sources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230129141714_unused_schema/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230129174218_fill-auth-view-tokens/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230130121014_tree_relations/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130121041_tree_relations_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230130124937_tree_relations_not_null/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130153140_authorization-tokens-fix/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130160827_build_styles/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230202131409_project-created-at/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230202174408_build_breakpoints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230202174456_build_breakpoints_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230202192437_composite_ids/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230213220858_is-deleted-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227142607_build_style_source_selections/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227142622_build_style_source_selections_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230227180214_build_props/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227180250_build_props_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228132402_drop_style_source_tree_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228161419_page_root_instance_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228194425_build_instances/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230228194553_build_instances_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228222541_convert-image-style/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230301101527_drop_page_tree_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230301101856_drop_tree/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230301134408_convert-background-to-layers/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230309142820_link-target/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230412160008_min-width-remove/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230501151815_file/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230501151941_asset-to-file/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230501153024_asset-file-relation/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230515112405_file_uploader_project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230517133730_file_is_deleted/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230517150043_domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230520112258_drop_breakpoints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230529133454_build_version/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230530132921_deployment/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230530155049_drop_unused_asset_fields/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230605174851_domain-updated-at/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230606165920_deployment-project-domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230606234538_latest-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230610111903_button_children/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230611121710_merge_block_text_components/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230611181439_control_labels/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230619131628_build_data_sources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230702002752_form_data_sources/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230831150459_add-administrators/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230911125308_form_action/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20231105075338_add-last-transaction-id/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231108172804_prop_expression/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20231115205820_client-references/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231116173417_product/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231117095612_transaction/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231119153806_transaction-customer-subscription/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231120172840_add-event-type/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231121125755_token-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231129164239_event-data/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231211152313_build_resources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240112011509_folders/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240112155724_nullable-user/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240112155725_user_product_view/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240125182656_calc-domains/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240127230238_project-preview/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240131193159_new_constraints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240131200102_page_meta_expressions/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240227150630_marketplace/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240229133316_add-approval-status/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240308131249_add-token-rights/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240309212641_page_system_variable/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240315173349_add-approved-marketplace-product/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240530162819_marketplace-token/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240723144019_latest-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240723150501_latest-static-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240725003228_clone_project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240730131207_clone_project_preview_imagea/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240731170412_create_production_build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240807000548_deleted-project-free-domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240809220753_tz/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240916143551_time/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240917152817_pgtap/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240918100751_latest-virtual-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240920091253_domain-ordering/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240924174536_cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20241207052014_can-publish/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250322141808_user_publish_count/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250710163439_restore_development_build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250810123401_asset_filename_description/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250913204036_project_tags/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20251129093846_add_updated_at_to_latest_build_virtual/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── migration_lock.toml
│   │   │   │   └── template.txt
│   │   │   └── schema.prisma
│   │   ├── prisma.cjs
│   │   ├── prisma.mjs
│   │   ├── src/
│   │   │   ├── cjs/
│   │   │   │   └── package.json
│   │   │   └── prisma.ts
│   │   └── tsconfig.json
│   ├── project/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── project-domain.ts
│   │   │   │   └── project.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   └── schema.ts
│   │   │   └── trpc/
│   │   │       └── project-router.ts
│   │   └── tsconfig.json
│   ├── project-build/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── build.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── pages.ts
│   │   │   │   ├── style-source-selections.ts
│   │   │   │   └── styles.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   ├── graph-utils.test.ts
│   │   │   │   ├── graph-utils.ts
│   │   │   │   ├── marketplace.ts
│   │   │   │   ├── pages-utils.test.ts
│   │   │   │   └── pages-utils.ts
│   │   │   ├── template.tsx
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── react-sdk/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── placeholder.d.ts
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── standard-attributes.ts
│   │   │   ├── collection-utils.test.ts
│   │   │   ├── collection-utils.ts
│   │   │   ├── component-generator.test.tsx
│   │   │   ├── component-generator.ts
│   │   │   ├── components/
│   │   │   │   └── components-utils.ts
│   │   │   ├── context.tsx
│   │   │   ├── hook.test.ts
│   │   │   ├── hook.ts
│   │   │   ├── index.ts
│   │   │   ├── page-settings-canonical-link.tsx
│   │   │   ├── page-settings-meta.tsx
│   │   │   ├── page-settings-title.tsx
│   │   │   ├── props.test.ts
│   │   │   ├── props.ts
│   │   │   ├── remix.test.ts
│   │   │   ├── remix.ts
│   │   │   ├── runtime.ts
│   │   │   └── variable-state.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── normalize.css.ts
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── normalize.css.ts
│   │   │   │   └── tags.ts
│   │   │   ├── assets.test.ts
│   │   │   ├── assets.ts
│   │   │   ├── core-metas.ts
│   │   │   ├── core-templates.tsx
│   │   │   ├── css.test.tsx
│   │   │   ├── css.ts
│   │   │   ├── expression.test.ts
│   │   │   ├── expression.ts
│   │   │   ├── form-fields.ts
│   │   │   ├── index.ts
│   │   │   ├── instances-utils.test.tsx
│   │   │   ├── instances-utils.ts
│   │   │   ├── normalize.css
│   │   │   ├── page-meta-generator.test.ts
│   │   │   ├── page-meta-generator.ts
│   │   │   ├── page-utils.test.ts
│   │   │   ├── page-utils.ts
│   │   │   ├── resource-loader.test.ts
│   │   │   ├── resource-loader.ts
│   │   │   ├── resources-generator.test.tsx
│   │   │   ├── resources-generator.ts
│   │   │   ├── router-path-test-data.ts
│   │   │   ├── router-paths.test.ts
│   │   │   ├── runtime.ts
│   │   │   ├── schema/
│   │   │   │   ├── animation-schema.ts
│   │   │   │   ├── assets.ts
│   │   │   │   ├── breakpoints.test.ts
│   │   │   │   ├── breakpoints.ts
│   │   │   │   ├── component-meta.ts
│   │   │   │   ├── data-sources.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── instances.ts
│   │   │   │   ├── pages.test.ts
│   │   │   │   ├── pages.ts
│   │   │   │   ├── prop-meta.ts
│   │   │   │   ├── props.ts
│   │   │   │   ├── resources.ts
│   │   │   │   ├── style-source-selections.ts
│   │   │   │   ├── style-sources.ts
│   │   │   │   ├── styles.ts
│   │   │   │   └── webstudio.ts
│   │   │   ├── scope.test.ts
│   │   │   ├── scope.ts
│   │   │   ├── to-string.ts
│   │   │   ├── url-pattern.test.ts
│   │   │   └── url-pattern.ts
│   │   ├── tsconfig.dts.json
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── sdk-cli/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   └── generate-stories.ts
│   │   └── tsconfig.json
│   ├── sdk-components-animation/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── animate-children.props.ts
│   │   │   │   ├── animate-text.props.ts
│   │   │   │   ├── stagger-animation.props.ts
│   │   │   │   └── video-animation.props.ts
│   │   │   ├── animate-children.tsx
│   │   │   ├── animate-children.ws.ts
│   │   │   ├── animate-text.tsx
│   │   │   ├── animate-text.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── hooks.ts
│   │   │   ├── metas.ts
│   │   │   ├── shared/
│   │   │   │   ├── create-progress-animation.tsx
│   │   │   │   ├── meta.ts
│   │   │   │   └── proxy.ts
│   │   │   ├── stagger-animation.tsx
│   │   │   ├── stagger-animation.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── video-animation.template.tsx
│   │   │   ├── video-animation.tsx
│   │   │   └── video-animation.ws.ts
│   │   ├── tsconfig.dts.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.typecheck.json
│   │   ├── vite.config.ts
│   │   └── vitest.config.ts
│   ├── sdk-components-react/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── LICENSE
│   │   │   ├── __generated__/
│   │   │   │   ├── blockquote.props.ts
│   │   │   │   ├── blockquote.stories.tsx
│   │   │   │   ├── body.props.ts
│   │   │   │   ├── bold.props.ts
│   │   │   │   ├── box.props.ts
│   │   │   │   ├── button.props.ts
│   │   │   │   ├── button.stories.tsx
│   │   │   │   ├── checkbox.props.ts
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── code-text.props.ts
│   │   │   │   ├── content-embed.stories.tsx
│   │   │   │   ├── form.props.ts
│   │   │   │   ├── form.stories.tsx
│   │   │   │   ├── fragment.props.ts
│   │   │   │   ├── head-link.props.ts
│   │   │   │   ├── head-meta.props.ts
│   │   │   │   ├── head-slot.props.ts
│   │   │   │   ├── head-title.props.ts
│   │   │   │   ├── heading.props.ts
│   │   │   │   ├── heading.stories.tsx
│   │   │   │   ├── html-embed.props.ts
│   │   │   │   ├── image.props.ts
│   │   │   │   ├── input.props.ts
│   │   │   │   ├── italic.props.ts
│   │   │   │   ├── label.props.ts
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── link.props.ts
│   │   │   │   ├── link.stories.tsx
│   │   │   │   ├── list-item.props.ts
│   │   │   │   ├── list-item.stories.tsx
│   │   │   │   ├── list.props.ts
│   │   │   │   ├── list.stories.tsx
│   │   │   │   ├── markdown-embed.props.ts
│   │   │   │   ├── markdown-embed.stories.tsx
│   │   │   │   ├── option.props.ts
│   │   │   │   ├── paragraph.props.ts
│   │   │   │   ├── paragraph.stories.tsx
│   │   │   │   ├── radio-button.props.ts
│   │   │   │   ├── radio-button.stories.tsx
│   │   │   │   ├── rich-text-link.props.ts
│   │   │   │   ├── select.props.ts
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── separator.props.ts
│   │   │   │   ├── slot.props.ts
│   │   │   │   ├── span.props.ts
│   │   │   │   ├── subscript.props.ts
│   │   │   │   ├── superscript.props.ts
│   │   │   │   ├── text.props.ts
│   │   │   │   ├── text.stories.tsx
│   │   │   │   ├── textarea.props.ts
│   │   │   │   ├── time.props.ts
│   │   │   │   ├── video.props.ts
│   │   │   │   ├── vimeo-play-button.props.ts
│   │   │   │   ├── vimeo-preview-image.props.ts
│   │   │   │   ├── vimeo-spinner.props.ts
│   │   │   │   ├── vimeo.props.ts
│   │   │   │   ├── vimeo.stories.tsx
│   │   │   │   ├── webhook-form.props.ts
│   │   │   │   ├── xml-node.props.ts
│   │   │   │   ├── xml-time.props.ts
│   │   │   │   ├── you-tube.stories.tsx
│   │   │   │   └── youtube.props.ts
│   │   │   ├── blockquote.tsx
│   │   │   ├── blockquote.ws.ts
│   │   │   ├── body.tsx
│   │   │   ├── body.ws.ts
│   │   │   ├── bold.tsx
│   │   │   ├── bold.ws.ts
│   │   │   ├── box.tsx
│   │   │   ├── box.ws.ts
│   │   │   ├── button.tsx
│   │   │   ├── button.ws.ts
│   │   │   ├── checkbox.tsx
│   │   │   ├── checkbox.ws.ts
│   │   │   ├── code-text.tsx
│   │   │   ├── code-text.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── content-embed.template.tsx
│   │   │   ├── form.tsx
│   │   │   ├── form.ws.ts
│   │   │   ├── fragment.tsx
│   │   │   ├── fragment.ws.ts
│   │   │   ├── head-link.tsx
│   │   │   ├── head-link.ws.ts
│   │   │   ├── head-meta.tsx
│   │   │   ├── head-meta.ws.ts
│   │   │   ├── head-slot.template.tsx
│   │   │   ├── head-slot.tsx
│   │   │   ├── head-slot.ws.ts
│   │   │   ├── head-title.tsx
│   │   │   ├── head-title.ws.ts
│   │   │   ├── heading.tsx
│   │   │   ├── heading.ws.ts
│   │   │   ├── hooks.ts
│   │   │   ├── html-embed-patchers.ts
│   │   │   ├── html-embed.test.tsx
│   │   │   ├── html-embed.tsx
│   │   │   ├── html-embed.ws.ts
│   │   │   ├── image.tsx
│   │   │   ├── image.ws.ts
│   │   │   ├── input.tsx
│   │   │   ├── input.ws.ts
│   │   │   ├── italic.tsx
│   │   │   ├── italic.ws.ts
│   │   │   ├── label.tsx
│   │   │   ├── label.ws.ts
│   │   │   ├── link.tsx
│   │   │   ├── link.ws.ts
│   │   │   ├── list-item.tsx
│   │   │   ├── list-item.ws.ts
│   │   │   ├── list.tsx
│   │   │   ├── list.ws.ts
│   │   │   ├── markdown-embed.template.tsx
│   │   │   ├── markdown-embed.tsx
│   │   │   ├── markdown-embed.ws.ts
│   │   │   ├── metas.ts
│   │   │   ├── option.tsx
│   │   │   ├── option.ws.ts
│   │   │   ├── paragraph.tsx
│   │   │   ├── paragraph.ws.ts
│   │   │   ├── radio-button.tsx
│   │   │   ├── radio-button.ws.ts
│   │   │   ├── rich-text-link.tsx
│   │   │   ├── rich-text-link.ws.ts
│   │   │   ├── select.tsx
│   │   │   ├── select.ws.ts
│   │   │   ├── separator.tsx
│   │   │   ├── separator.ws.ts
│   │   │   ├── shared/
│   │   │   │   └── video.ts
│   │   │   ├── slot.tsx
│   │   │   ├── slot.ws.ts
│   │   │   ├── span.tsx
│   │   │   ├── span.ws.ts
│   │   │   ├── subscript.tsx
│   │   │   ├── subscript.ws.ts
│   │   │   ├── superscript.tsx
│   │   │   ├── superscript.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── test-utils/
│   │   │   │   └── cartesian.ts
│   │   │   ├── text.tsx
│   │   │   ├── text.ws.ts
│   │   │   ├── textarea.tsx
│   │   │   ├── textarea.ws.ts
│   │   │   ├── time.test.ts
│   │   │   ├── time.tsx
│   │   │   ├── time.ws.ts
│   │   │   ├── video.tsx
│   │   │   ├── video.ws.ts
│   │   │   ├── vimeo-play-button.tsx
│   │   │   ├── vimeo-play-button.ws.ts
│   │   │   ├── vimeo-preview-image.tsx
│   │   │   ├── vimeo-preview-image.ws.ts
│   │   │   ├── vimeo-spinner.tsx
│   │   │   ├── vimeo-spinner.ws.ts
│   │   │   ├── vimeo.template.tsx
│   │   │   ├── vimeo.tsx
│   │   │   ├── vimeo.ws.ts
│   │   │   ├── webhook-form.template.tsx
│   │   │   ├── webhook-form.tsx
│   │   │   ├── webhook-form.ws.ts
│   │   │   ├── xml-node.stories.tsx
│   │   │   ├── xml-node.tsx
│   │   │   ├── xml-node.ws.ts
│   │   │   ├── xml-time.tsx
│   │   │   ├── xml-time.ws.ts
│   │   │   ├── youtube.template.tsx
│   │   │   ├── youtube.tsx
│   │   │   └── youtube.ws.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-radix/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── accordion.props.ts
│   │   │   │   ├── accordion.stories.tsx
│   │   │   │   ├── checkbox.props.ts
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── collapsible.props.ts
│   │   │   │   ├── collapsible.stories.tsx
│   │   │   │   ├── dialog.props.ts
│   │   │   │   ├── dialog.stories.tsx
│   │   │   │   ├── label.props.ts
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── navigation-menu.props.ts
│   │   │   │   ├── navigation-menu.stories.tsx
│   │   │   │   ├── popover.props.ts
│   │   │   │   ├── popover.stories.tsx
│   │   │   │   ├── radio-group.props.ts
│   │   │   │   ├── radio-group.stories.tsx
│   │   │   │   ├── select.props.ts
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── sheet.stories.tsx
│   │   │   │   ├── switch.props.ts
│   │   │   │   ├── switch.stories.tsx
│   │   │   │   ├── tabs.props.ts
│   │   │   │   ├── tabs.stories.tsx
│   │   │   │   ├── tooltip.props.ts
│   │   │   │   └── tooltip.stories.tsx
│   │   │   ├── accordion.template.tsx
│   │   │   ├── accordion.tsx
│   │   │   ├── accordion.ws.ts
│   │   │   ├── checkbox.template.tsx
│   │   │   ├── checkbox.tsx
│   │   │   ├── checkbox.ws.ts
│   │   │   ├── collapsible.template.tsx
│   │   │   ├── collapsible.tsx
│   │   │   ├── collapsible.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── dialog.template.tsx
│   │   │   ├── dialog.tsx
│   │   │   ├── dialog.ws.ts
│   │   │   ├── hooks.ts
│   │   │   ├── label.template.tsx
│   │   │   ├── label.tsx
│   │   │   ├── label.ws.ts
│   │   │   ├── metas.ts
│   │   │   ├── navigation-menu.template.tsx
│   │   │   ├── navigation-menu.tsx
│   │   │   ├── navigation-menu.ws.ts
│   │   │   ├── popover.template.tsx
│   │   │   ├── popover.tsx
│   │   │   ├── popover.ws.ts
│   │   │   ├── props-descriptions.ts
│   │   │   ├── radio-group.template.tsx
│   │   │   ├── radio-group.tsx
│   │   │   ├── radio-group.ws.ts
│   │   │   ├── select.template.tsx
│   │   │   ├── select.tsx
│   │   │   ├── select.ws.ts
│   │   │   ├── shared/
│   │   │   │   ├── meta.ts
│   │   │   │   ├── preset-styles.ts
│   │   │   │   ├── proxy.ts
│   │   │   │   ├── styles.ts
│   │   │   │   └── theme.ts
│   │   │   ├── sheet.template.tsx
│   │   │   ├── switch.template.tsx
│   │   │   ├── switch.tsx
│   │   │   ├── switch.ws.ts
│   │   │   ├── tabs.template.tsx
│   │   │   ├── tabs.tsx
│   │   │   ├── tabs.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── tooltip.template.tsx
│   │   │   ├── tooltip.tsx
│   │   │   └── tooltip.ws.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-remix/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── body.tsx
│   │   │   ├── components.ts
│   │   │   ├── link.tsx
│   │   │   ├── remix-form.tsx
│   │   │   ├── rich-text-link.tsx
│   │   │   └── webhook-form.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-router/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── body.tsx
│   │   │   ├── components.ts
│   │   │   ├── link.tsx
│   │   │   ├── metas.ts
│   │   │   ├── remix-form.tsx
│   │   │   ├── rich-text-link.tsx
│   │   │   └── webhook-form.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── template/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── css.test.ts
│   │   │   ├── css.ts
│   │   │   ├── index.ts
│   │   │   ├── jsx.test.tsx
│   │   │   ├── jsx.ts
│   │   │   └── template.ts
│   │   └── tsconfig.json
│   ├── trpc-interface/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── authorize/
│   │   │   │   └── project.server.ts
│   │   │   ├── context/
│   │   │   │   ├── context.server.ts
│   │   │   │   ├── errors.server.ts
│   │   │   │   └── router.server.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   ├── client.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── shared-router.ts
│   │   │   │   └── trpc.ts
│   │   │   ├── trpc-caller-link.test.ts
│   │   │   └── trpc-caller-link.ts
│   │   └── tsconfig.json
│   └── tsconfig/
│       ├── README.md
│       ├── base.json
│       └── package.json
├── patches/
│   ├── @radix-ui__react-scroll-area@1.0.5.patch
│   ├── @remix-run__dev.patch
│   └── @stitches__react@1.3.1-1.patch
├── pnpm-workspace.yaml
├── release.sh
├── submodules.sh
├── vercel.json
├── vite.sdk-components.config.ts
└── vitest.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .devcontainer/.gitignore
================================================
.local

================================================
FILE: .devcontainer/Dockerfile
================================================
FROM mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm

ENV PATH=/usr/local/bin:${PATH}
# Install latest pnpm
# RUN npm install -g pnpm@9.0.2

# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
#     && apt-get -y install --no-install-recommends <your-package-list-here>

# [Optional] Uncomment if you want to install an additional version of node using nvm
# ARG EXTRA_NODE_VERSION=10
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"

# [Optional] Uncomment if you want to install more global node modules
# RUN su node -c "npm install -g <your-package-list-here>"

COPY library-scripts/*.sh /tmp/library-scripts/

ENV DOCKER_BUILDKIT=1
RUN apt-get update
RUN /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh


================================================
FILE: .devcontainer/devcontainer.json
================================================
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node-postgres
{
  "name": "Node.js & PostgreSQL",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspaces/webstudio",
  "features": {
    "ghcr.io/robbert229/devcontainer-features/postgresql-client:1": {
      "version": "15"
    }
  },

  // Features to add to the dev container. More info: https://containers.dev/features.
  // "features": {},

  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // This can be used to network with other containers or with the host.
  // "forwardPorts": [3000, 5432],
  "forwardPorts": [5173],

  // Use 'postCreateCommand' to run commands after the container is created.

  "postCreateCommand": ".devcontainer/postinstall.sh",
  // "postStartCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
  "customizations": {
    "vscode": {
      "extensions": [
        "esbenp.prettier-vscode",
        "redhat.vscode-yaml",
        "me-dutour-mathieu.vscode-github-actions",
        "eamodio.gitlens",
        "bradymholt.pgformatter",
        "YoavBls.pretty-ts-errors",
        "typescriptteam.native-preview"
      ]
    }
  }

  // Configure tool-specific properties.
  // "customizations": {},

  // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
  // "remoteUser": "root"
}


================================================
FILE: .devcontainer/docker-compose.yml
================================================
version: "3.8"

services:
  app:
    init: true
    privileged: true
    build:
      context: .
      dockerfile: Dockerfile

    volumes:
      - ..:/workspaces/webstudio:cached
      # preserve history
      - ./.local:/home/node/.local
      - docker-data:/var/lib/docker
      - ${HOME}/.github/instructions:/home/node/.github/instructions

    entrypoint: ["/usr/local/share/docker-init.sh"]
    # Overrides default command so things don't shut down after the process ends.
    command: sleep infinity
    # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
    network_mode: service:db

    depends_on:
      db:
        condition: service_healthy

  db:
    image: ghcr.io/supabase/postgres:15.1.1.55
    # Uncomment to log all queries
    command: ["postgres", "-c", "log_statement=all", "-c", "listen_addresses=*"]
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: webstudio

    ports:
      - ${PGPORT:-5432}:5432
      - 3000:3000

    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d webstudio"]
      interval: 10s
      timeout: 5s
      retries: 25

  rest:
    container_name: supabase-rest
    image: postgrest/postgrest:v12.2.0
    depends_on:
      db:
        # Disable this if you are using an external Postgres database
        condition: service_healthy
    restart: unless-stopped
    environment:
      PGRST_DB_URI: postgresql://postgres:pass@localhost/webstudio
      PGRST_DB_SCHEMAS: ${PGRST_DB_SCHEMAS:-public}
      PGRST_DB_ANON_ROLE: anon
      PGRST_JWT_SECRET: ${JWT_SECRET:-jwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecret}
      PGRST_DB_USE_LEGACY_GUCS: "false"
      PGRST_APP_SETTINGS_JWT_SECRET: ${JWT_SECRET:-jwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecretjwtsecret}
      PGRST_APP_SETTINGS_JWT_EXP: ${JWT_EXPIRY}
    command: "postgrest"

    # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
    network_mode: service:db

volumes:
  postgres-data:
  docker-data:


================================================
FILE: .devcontainer/library-scripts/docker-in-docker-debian.sh
================================================
#!/usr/bin/env bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md
# Maintainer: The Dev Container spec maintainers


DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version
USE_MOBY="${MOBY:-"true"}"
MOBY_BUILDX_VERSION="${MOBYBUILDXVERSION:-"latest"}"
DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"latest"}" #latest, v2 or none
AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}"
DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL:-""}"
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
INSTALL_DOCKER_COMPOSE_SWITCH="${INSTALLDOCKERCOMPOSESWITCH:-"true"}"
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble"
DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal hirsute impish jammy noble"

# Default: Exit on any failure.
set -e

# Clean up
rm -rf /var/lib/apt/lists/*

# Setup STDERR.
err() {
    echo "(!) $*" >&2
}

if [ "$(id -u)" -ne 0 ]; then
    err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
    exit 1
fi

###################
# Helper Functions
# See: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/shared/utils.sh
###################

# Determine the appropriate non-root user
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
    USERNAME=""
    POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
    for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do
        if id -u ${CURRENT_USER} > /dev/null 2>&1; then
            USERNAME=${CURRENT_USER}
            break
        fi
    done
    if [ "${USERNAME}" = "" ]; then
        USERNAME=root
    fi
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
    USERNAME=root
fi

apt_get_update()
{
    if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
        echo "Running apt-get update..."
        apt-get update -y
    fi
}

# Checks if packages are installed and installs them if not
check_packages() {
    if ! dpkg -s "$@" > /dev/null 2>&1; then
        apt_get_update
        apt-get -y install --no-install-recommends "$@"
    fi
}

# Figure out correct version of a three part version number is not passed
find_version_from_git_tags() {
    local variable_name=$1
    local requested_version=${!variable_name}
    if [ "${requested_version}" = "none" ]; then return; fi
    local repository=$2
    local prefix=${3:-"tags/v"}
    local separator=${4:-"."}
    local last_part_optional=${5:-"false"}
    if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then
        local escaped_separator=${separator//./\\.}
        local last_part
        if [ "${last_part_optional}" = "true" ]; then
            last_part="(${escaped_separator}[0-9]+)?"
        else
            last_part="${escaped_separator}[0-9]+"
        fi
        local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$"
        local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)"
        if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then
            declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)"
        else
            set +e
                declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
            set -e
        fi
    fi
    if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then
        err "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2
        exit 1
    fi
    echo "${variable_name}=${!variable_name}"
}

# Use semver logic to decrement a version number then look for the closest match
find_prev_version_from_git_tags() {
    local variable_name=$1
    local current_version=${!variable_name}
    local repository=$2
    # Normally a "v" is used before the version number, but support alternate cases
    local prefix=${3:-"tags/v"}
    # Some repositories use "_" instead of "." for version number part separation, support that
    local separator=${4:-"."}
    # Some tools release versions that omit the last digit (e.g. go)
    local last_part_optional=${5:-"false"}
    # Some repositories may have tags that include a suffix (e.g. actions/node-versions)
    local version_suffix_regex=$6
    # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios.
    set +e
        major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')"
        minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')"
        breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')"

        if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then
            ((major=major-1))
            declare -g ${variable_name}="${major}"
            # Look for latest version from previous major release
            find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}"
        # Handle situations like Go's odd version pattern where "0" releases omit the last part
        elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then
            ((minor=minor-1))
            declare -g ${variable_name}="${major}.${minor}"
            # Look for latest version from previous minor release
            find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}"
        else
            ((breakfix=breakfix-1))
            if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then
                declare -g ${variable_name}="${major}.${minor}"
            else
                declare -g ${variable_name}="${major}.${minor}.${breakfix}"
            fi
        fi
    set -e
}

# Function to fetch the version released prior to the latest version
get_previous_version() {
    local url=$1
    local repo_url=$2
    local variable_name=$3
    prev_version=${!variable_name}

    output=$(curl -s "$repo_url");
    message=$(echo "$output" | jq -r '.message')

    if [[ $message == "API rate limit exceeded"* ]]; then
        echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}"
        echo -e "\nAttempting to find latest version using GitHub tags."
        find_prev_version_from_git_tags prev_version "$url" "tags/v"
        declare -g ${variable_name}="${prev_version}"
    else
        echo -e "\nAttempting to find latest version using GitHub Api."
        version=$(echo "$output" | jq -r '.tag_name')
        declare -g ${variable_name}="${version#v}"
    fi
    echo "${variable_name}=${!variable_name}"
}

get_github_api_repo_url() {
    local url=$1
    echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest"
}

###########################################
# Start docker-in-docker installation
###########################################

# Ensure apt is in non-interactive to avoid prompts
export DEBIAN_FRONTEND=noninteractive


# Source /etc/os-release to get OS info
. /etc/os-release
# Fetch host/container arch.
architecture="$(dpkg --print-architecture)"

# Check if distro is supported
if [ "${USE_MOBY}" = "true" ]; then
    if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
        err "Unsupported  distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
        err "Support distributions include:  ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
        exit 1
    fi
    echo "Distro codename  '${VERSION_CODENAME}'  matched filter  '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'"
else
    if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
        err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution"
        err "Support distributions include:  ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}"
        exit 1
    fi
    echo "Distro codename  '${VERSION_CODENAME}'  matched filter  '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'"
fi

# Install dependencies
check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr wget jq
if ! type git > /dev/null 2>&1; then
    check_packages git
fi

# Swap to legacy iptables for compatibility
if type iptables-legacy > /dev/null 2>&1; then
    update-alternatives --set iptables /usr/sbin/iptables-legacy
    update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
fi



# Set up the necessary apt repos (either Microsoft's or Docker's)
if [ "${USE_MOBY}" = "true" ]; then

    # Name of open source engine/cli
    engine_package_name="moby-engine"
    cli_package_name="moby-cli"

    # Import key safely and import Microsoft apt repo
    curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
    echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
else
    # Name of licensed engine/cli
    engine_package_name="docker-ce"
    cli_package_name="docker-ce-cli"

    # Import key safely and import Docker apt repo
    curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
fi

# Refresh apt lists
apt-get update

# Soft version matching
if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then
    # Empty, meaning grab whatever "latest" is in apt repo
    engine_version_suffix=""
    cli_version_suffix=""
else
    # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...)
    docker_version_dot_escaped="${DOCKER_VERSION//./\\.}"
    docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}"
    # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/
    docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)"
    set +e # Don't exit if finding version fails - will handle gracefully
        cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")"
        engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")"
    set -e
    if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then
        err "No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:"
        apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+'
        exit 1
    fi
    echo "engine_version_suffix ${engine_version_suffix}"
    echo "cli_version_suffix ${cli_version_suffix}"
fi

# Version matching for moby-buildx
if [ "${USE_MOBY}" = "true" ]; then
    if [ "${MOBY_BUILDX_VERSION}" = "latest" ]; then
        # Empty, meaning grab whatever "latest" is in apt repo
        buildx_version_suffix=""
    else
        buildx_version_dot_escaped="${MOBY_BUILDX_VERSION//./\\.}"
        buildx_version_dot_plus_escaped="${buildx_version_dot_escaped//+/\\+}"
        buildx_version_regex="^(.+:)?${buildx_version_dot_plus_escaped}([\\.\\+ ~:-]|$)"
        set +e
            buildx_version_suffix="=$(apt-cache madison moby-buildx | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${buildx_version_regex}")"
        set -e
        if [ -z "${buildx_version_suffix}" ] || [ "${buildx_version_suffix}" = "=" ]; then
            err "No full or partial moby-buildx version match found for \"${MOBY_BUILDX_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:"
            apt-cache madison moby-buildx | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+'
            exit 1
        fi
        echo "buildx_version_suffix ${buildx_version_suffix}"
    fi
fi

# Install Docker / Moby CLI if not already installed
if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then
    echo "Docker / Moby CLI and Engine already installed."
else
    if [ "${USE_MOBY}" = "true" ]; then
        # Install engine
        set +e # Handle error gracefully
            apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx${buildx_version_suffix} moby-engine${engine_version_suffix}
            exit_code=$?
        set -e

        if [ ${exit_code} -ne 0 ]; then
            err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (eg: 'ubuntu-20.04')."
            exit 1
        fi

        # Install compose
        apt-get -y install --no-install-recommends moby-compose || err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping."
    else
        apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix}
        # Install compose
        apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping."
    fi
fi

echo "Finished installing docker / moby!"

docker_home="/usr/libexec/docker"
cli_plugins_dir="${docker_home}/cli-plugins"

# fallback for docker-compose
fallback_compose(){
    local url=$1
    local repo_url=$(get_github_api_repo_url "$url")
    echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..."
    get_previous_version "${url}" "${repo_url}" compose_version
    echo -e "\nAttempting to install v${compose_version}"
    curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path}
}

# If 'docker-compose' command is to be included
if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then
    case "${architecture}" in
        amd64) target_compose_arch=x86_64 ;;
        arm64) target_compose_arch=aarch64 ;;
        *)
            echo "(!) Docker in docker does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine."
            exit 1
    esac

    docker_compose_path="/usr/local/bin/docker-compose"
    if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
        err "The final Compose V1 release, version 1.29.2, was May 10, 2021. These packages haven't received any security updates since then. Use at your own risk."
        INSTALL_DOCKER_COMPOSE_SWITCH="false"

        if [ "${target_compose_arch}" = "x86_64" ]; then
            echo "(*) Installing docker compose v1..."
            curl -fsSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o ${docker_compose_path}
            chmod +x ${docker_compose_path}

            # Download the SHA256 checksum
            DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64.sha256" | awk '{print $1}')"
            echo "${DOCKER_COMPOSE_SHA256}  ${docker_compose_path}" > docker-compose.sha256sum
            sha256sum -c docker-compose.sha256sum --ignore-missing
        elif [ "${VERSION_CODENAME}" = "bookworm" ]; then
            err "Docker compose v1 is unavailable for 'bookworm' on Arm64. Kindly switch to use v2"
            exit 1
        else
            # Use pip to get a version that runs on this architecture
            check_packages python3-minimal python3-pip libffi-dev python3-venv
            echo "(*) Installing docker compose v1 via pip..."
            export PYTHONUSERBASE=/usr/local
            pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation
        fi
    else
        compose_version=${DOCKER_DASH_COMPOSE_VERSION#v}
        docker_compose_url="https://github.com/docker/compose"
        find_version_from_git_tags compose_version "$docker_compose_url" "tags/v"
        echo "(*) Installing docker-compose ${compose_version}..."
        curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || {
            if [[ $DOCKER_DASH_COMPOSE_VERSION == "latest" ]]; then
                fallback_compose "$docker_compose_url"
            else
                echo -e "Error: Failed to install docker-compose v${compose_version}"
            fi
        }

        chmod +x ${docker_compose_path}

        # Download the SHA256 checksum
        DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}.sha256" | awk '{print $1}')"
        echo "${DOCKER_COMPOSE_SHA256}  ${docker_compose_path}" > docker-compose.sha256sum
        sha256sum -c docker-compose.sha256sum --ignore-missing

        mkdir -p ${cli_plugins_dir}
        cp ${docker_compose_path} ${cli_plugins_dir}
    fi
fi

# fallback method for compose-switch
fallback_compose-switch() {
    local url=$1
    local repo_url=$(get_github_api_repo_url "$url")
    echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..."
    get_previous_version "$url" "$repo_url" compose_switch_version
    echo -e "\nAttempting to install v${compose_switch_version}"
    curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch
}

# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation
if [ "${INSTALL_DOCKER_COMPOSE_SWITCH}" = "true" ] && ! type compose-switch > /dev/null 2>&1; then
    if type docker-compose > /dev/null 2>&1; then
        echo "(*) Installing compose-switch..."
        current_compose_path="$(which docker-compose)"
        target_compose_path="$(dirname "${current_compose_path}")/docker-compose-v1"
        compose_switch_version="latest"
        compose_switch_url="https://github.com/docker/compose-switch"
        find_version_from_git_tags compose_switch_version "$compose_switch_url"
        curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch || fallback_compose-switch "$compose_switch_url"
        chmod +x /usr/local/bin/compose-switch
        # TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11
        # Setup v1 CLI as alternative in addition to compose-switch (which maps to v2)
        mv "${current_compose_path}" "${target_compose_path}"
        update-alternatives --install ${docker_compose_path} docker-compose /usr/local/bin/compose-switch 99
        update-alternatives --install ${docker_compose_path} docker-compose "${target_compose_path}" 1
    else
        err "Skipping installation of compose-switch as docker compose is unavailable..."
    fi
fi

# If init file already exists, exit
if [ -f "/usr/local/share/docker-init.sh" ]; then
    echo "/usr/local/share/docker-init.sh already exists, so exiting."
    # Clean up
    rm -rf /var/lib/apt/lists/*
    exit 0
fi
echo "docker-init doesn't exist, adding..."

if ! cat /etc/group | grep -e "^docker:" > /dev/null 2>&1; then
        groupadd -r docker
fi

usermod -aG docker ${USERNAME}

# fallback for docker/buildx
fallback_buildx() {
    local url=$1
    local repo_url=$(get_github_api_repo_url "$url")
    echo -e "\n(!) Failed to fetch the latest artifacts for docker buildx v${buildx_version}..."
    get_previous_version "$url" "$repo_url" buildx_version
    buildx_file_name="buildx-v${buildx_version}.linux-${architecture}"
    echo -e "\nAttempting to install v${buildx_version}"
    wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name}
}

if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then
    buildx_version="latest"
    docker_buildx_url="https://github.com/docker/buildx"
    find_version_from_git_tags buildx_version "$docker_buildx_url" "refs/tags/v"
    echo "(*) Installing buildx ${buildx_version}..."
    buildx_file_name="buildx-v${buildx_version}.linux-${architecture}"

    cd /tmp
    wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} || fallback_buildx "$docker_buildx_url"

    docker_home="/usr/libexec/docker"
    cli_plugins_dir="${docker_home}/cli-plugins"

    mkdir -p ${cli_plugins_dir}
    mv ${buildx_file_name} ${cli_plugins_dir}/docker-buildx
    chmod +x ${cli_plugins_dir}/docker-buildx

    chown -R "${USERNAME}:docker" "${docker_home}"
    chmod -R g+r+w "${docker_home}"
    find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s
fi

tee /usr/local/share/docker-init.sh > /dev/null \
<< EOF
#!/bin/sh
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------

set -e

AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION}
DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL}
EOF

tee -a /usr/local/share/docker-init.sh > /dev/null \
<< 'EOF'
dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} $(cat << 'INNEREOF'
    # explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
    find /run /var/run -iname 'docker*.pid' -delete || :
    find /run /var/run -iname 'container*.pid' -delete || :

    # -- Start: dind wrapper script --
    # Maintained: https://github.com/moby/moby/blob/master/hack/dind

    export container=docker

    if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then
        mount -t securityfs none /sys/kernel/security || {
            echo >&2 'Could not mount /sys/kernel/security.'
            echo >&2 'AppArmor detection and --privileged mode might break.'
        }
    fi

    # Mount /tmp (conditionally)
    if ! mountpoint -q /tmp; then
        mount -t tmpfs none /tmp
    fi

    set_cgroup_nesting()
    {
        # cgroup v2: enable nesting
        if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
            # move the processes from the root group to the /init group,
            # otherwise writing subtree_control fails with EBUSY.
            # An error during moving non-existent process (i.e., "cat") is ignored.
            mkdir -p /sys/fs/cgroup/init
            xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || :
            # enable controllers
            sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
                > /sys/fs/cgroup/cgroup.subtree_control
        fi
    }

    # Set cgroup nesting, retrying if necessary
    retry_cgroup_nesting=0

    until [ "${retry_cgroup_nesting}" -eq "5" ];
    do
        set +e
            set_cgroup_nesting

            if [ $? -ne 0 ]; then
                echo "(*) cgroup v2: Failed to enable nesting, retrying..."
            else
                break
            fi

            retry_cgroup_nesting=`expr $retry_cgroup_nesting + 1`
        set -e
    done

    # -- End: dind wrapper script --

    # Handle DNS
    set +e
        cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' > /dev/null 2>&1
        if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ]
        then
            echo "Setting dockerd Azure DNS."
            CUSTOMDNS="--dns 168.63.129.16"
        else
            echo "Not setting dockerd DNS manually."
            CUSTOMDNS=""
        fi
    set -e

    if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ]
    then
        DEFAULT_ADDRESS_POOL=""
    else
        DEFAULT_ADDRESS_POOL="--default-address-pool $DOCKER_DEFAULT_ADDRESS_POOL"
    fi

    # Start docker/moby engine
    ( dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL > /tmp/dockerd.log 2>&1 ) &
INNEREOF
)"

sudo_if() {
    COMMAND="$*"

    if [ "$(id -u)" -ne 0 ]; then
        sudo $COMMAND
    else
        $COMMAND
    fi
}

retry_docker_start_count=0
docker_ok="false"

until [ "${docker_ok}" = "true"  ] || [ "${retry_docker_start_count}" -eq "5" ];
do
    # Start using sudo if not invoked as root
    if [ "$(id -u)" -ne 0 ]; then
        sudo /bin/sh -c "${dockerd_start}"
    else
        eval "${dockerd_start}"
    fi

    retry_count=0
    until [ "${docker_ok}" = "true"  ] || [ "${retry_count}" -eq "5" ];
    do
        sleep 1s
        set +e
            docker info > /dev/null 2>&1 && docker_ok="true"
        set -e

        retry_count=`expr $retry_count + 1`
    done

    if [ "${docker_ok}" != "true" ] && [ "${retry_docker_start_count}" != "4" ]; then
        echo "(*) Failed to start docker, retrying..."
        set +e
            sudo_if pkill dockerd
            sudo_if pkill containerd
        set -e
    fi

    retry_docker_start_count=`expr $retry_docker_start_count + 1`
done

# Execute whatever commands were passed in (if any). This allows us
# to set this script to ENTRYPOINT while still executing the default CMD.
exec "$@"
EOF

chmod +x /usr/local/share/docker-init.sh
chown ${USERNAME}:root /usr/local/share/docker-init.sh

# Clean up
rm -rf /var/lib/apt/lists/*

echo 'docker-in-docker-debian script has completed!'

================================================
FILE: .devcontainer/postinstall.sh
================================================
#!/bin/bash

echo "Running postinstall.sh"

# Aggressively clean npm and corepack caches
npm cache clean -f
sudo rm -rf /tmp/corepack-cache
sudo rm -rf /usr/local/lib/node_modules/corepack # Manually remove global corepack

# Reinstall corepack globally via npm
npm install -g corepack@latest --force # Install latest corepack version
sudo corepack enable # Re-enable corepack

# Check corepack version after reinstall
corepack --version

# Prepare pnpm (again, after corepack reinstall)
corepack prepare pnpm@9.14.4 --activate

# Go to workspace directory
cd /workspaces/webstudio

# Configure pnpm store directory
pnpm config set store-dir $HOME/.pnpm-store

# Clean up directories (optional)
find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +
find . -name 'lib' -type d -prune -exec rm -rf '{}' +
find . -name 'build' -type d -prune -exec rm -rf '{}' +
find . -name 'dist' -type d -prune -exec rm -rf '{}' +
find . -name '.cache' -type d -prune -exec rm -rf '{}' +
find . -name '.pnpm-store' -type d -prune -exec rm -rf '{}' +

# Install dependencies, build, and migrate
pnpm install
pnpm build
pnpm migrations migrate

# Add git aliases
cat << 'EOF' >> /home/node/.bashrc
alias gitclean="(git remote | xargs git remote prune) && git branch -vv | egrep '('\$(git remote | xargs | sed -e 's/ /|/g')')/.*: gone]' | awk '{print \$1}'  | xargs -r git branch -D"
alias gitrebase="git rebase --interactive main"
EOF

# Symlink workspace GitHub instructions to mounted user instructions (for Copilot)
if [ -d "/home/node/.github/instructions" ]; then
  mkdir -p /workspaces/webstudio/.github
  ln -sfn /home/node/.github/instructions /workspaces/webstudio/.github/instructions
fi


echo "postinstall.sh finished"


================================================
FILE: .editorconfig
================================================
root = true

[*]
end_of_line = lf


================================================
FILE: .github/actions/add-status/action.yaml
================================================
name: Add status to commit
description: Add status to commit
inputs:
  url:
    description: "URL"
    required: true
  title:
    description: "Title"
    required: true
  description:
    description: "Description"
    required: true

runs:
  using: "composite"
  steps:
    - name: Add URL to vercel deployment through *.prs.webstudio.is
      uses: actions/github-script@v7
      with:
        script: |
          const branch = context.payload.pull_request?.head?.ref ?? context.payload.ref?.replace('refs/heads/', '')
          const sha = context.payload.pull_request?.head?.sha ?? context.sha;

          const status = {
            state: 'success',
            target_url: '${{ inputs.url }}',
            description: '${{ inputs.description }}',
            context: '${{ inputs.title }}'
          };

          github.rest.repos.createCommitStatus({
            ...context.repo,
            sha,
            ...status
          });


================================================
FILE: .github/actions/ci-setup/action.yml
================================================
name: CI setup

description: |
  Sets up the CI environment for the project.

runs:
  using: "composite"

  steps:
    - uses: pnpm/action-setup@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: pnpm
    - run: pnpm install --frozen-lockfile --ignore-scripts
      shell: bash


================================================
FILE: .github/actions/submodules-checkout/action.yml
================================================
name: CI setup

description: |
  Sets up the CI environment for the project.

inputs:
  submodules-ssh-key:
    description: "The SSH key to private submodules to use for the checkout"
    required: true

runs:
  using: "composite"

  steps:
    - name: Set up SSH for Git
      if: ${{ inputs.submodules-ssh-key }}
      run: |
        mkdir -p ~/.ssh
        echo "${{ inputs.submodules-ssh-key }}" > ~/.ssh/id_ed25519
        chmod 600 ~/.ssh/id_ed25519
        ssh-keyscan github.com >> ~/.ssh/known_hosts
      shell: bash

    - name: Verify SSH Connection (Optional)
      if: ${{ inputs.submodules-ssh-key }}
      run: |
        ssh -T git@github.com || true
      shell: bash

    - name: Verify SSH Connection (Optional)
      if: ${{ inputs.submodules-ssh-key }}
      run: |
        echo Branch is ${{ github.event.pull_request.head.ref || github.ref_name }}
      shell: bash

    - name: Try checkout submodules to the same branch as main repo
      if: ${{ inputs.submodules-ssh-key }}
      run: |
        ./submodules.sh ${{ github.event.pull_request.head.ref || github.ref_name }}
      shell: bash

    - name: Show main readme
      if: ${{ inputs.submodules-ssh-key }}
      run: |
        cat ./packages/sdk-components-animation/private-src/README.md || echo "No README found"
      shell: bash


================================================
FILE: .github/actions/vercel/action.yaml
================================================
name: "VERCEL BUILD AND DEPLOY"
description: "Builds and deploy vercel project"

inputs:
  vercel-token:
    description: "Vercel token"
    required: true
  vercel-org-id:
    description: "Vercel Organization ID"
    required: true
  vercel-project-id:
    description: "Vercel Project ID"
    required: true
  ref-name:
    description: "Branch"
    required: true
  sha:
    description: "Sha"
    required: true
  environment:
    description: "Sha"
    required: true

outputs:
  domain:
    description: "Domain"
    value: ${{ steps.deploy.outputs.domain }}
  inspect-url:
    description: "Inspect URL"
    value: ${{ steps.deploy.outputs.inspect-url }}
  alias:
    description: "Alias"
    value: ${{ steps.alias.outputs.value }}

runs:
  using: "composite"
  steps:
    - id: branch
      run: |
        CLEAN_NAME="${REF_NAME/.staging/}"
        CLEAN_NAME=$( echo "${CLEAN_NAME}" | sed 's/[^a-zA-Z0-9_-]//g' | tr A-Z a-z | tr _ - | sed 's/-\{2,\}/-/g' )
        echo "value=${CLEAN_NAME}" >> $GITHUB_OUTPUT
      shell: bash
      env:
        REF_NAME: ${{ inputs.ref-name }}

    - id: short_sha
      run: |
        SHORT_SHA=$( echo "value=$(echo ${{ inputs.sha }} | cut -c1-7)" )
        echo "value=${SHORT_SHA}" >> $GITHUB_OUTPUT
      shell: bash

    - name: CREATE VERCEL PROJECT FILE
      run: |
        mkdir -p .vercel
        cat <<"EOF" > .vercel/project.json
        {
          "projectId": "${{ inputs.vercel-project-id }}",
          "orgId": "${{ inputs.vercel-org-id }}",
          "settings": {
            "framework": "remix",
            "devCommand": "pnpm dev",
            "installCommand": "pnpm install",
            "buildCommand": "pnpm --filter=@webstudio-is/http-client build && pnpm --filter=@webstudio-is/builder build",
            "outputDirectory": null,
            "rootDirectory": "apps/builder",
            "directoryListing": false,
            "nodeVersion": "20.x"
          }
        }
        EOF
      shell: bash

    - name: Build
      run: |
        export GITHUB_SHA=${{ inputs.sha }}
        export GITHUB_REF_NAME=${{ inputs.ref-name }}

        pnpx vercel build
      shell: bash

    - name: Patch
      run: |
        # When we deploy on Vercel, it generates a URL like webstudio-saas-mahqcavgo-getwebstudio.vercel.app.
        # We use the alias oauth-wstd-00-staging.vercel.app for routing, which maps to oauth.staging.webstudio.is on the worker.
        # Issue: Vercel proxies also set x-forwarded-host, which overrides our header.
        # We are adding x-forwarded-ws-host on the worker as a workaround, but issues with request.url persist.
        # Remix and the Vercel adapter lack support for header selection https://github.com/vercel/vercel/blob/9d4d4b6deb6294506016106f78e71f1984adcc7f/packages/remix/defaults/server-node.mjs#L44
        # Patching server-node.mjs directly without installing Vercel CLI was unsuccessful, so we are using string replacement instead.

        mapfile -t matching_files < <(grep -rl "req\.headers\['x-forwarded-host'\] || req\.headers\.host" "./apps/builder/build")
        if [ ${#matching_files[@]} -eq 0 ]; then
          echo "No files found containing the specified string."
          exit 1
        fi

        echo "Files containing 'req.headers['x-forwarded-host'] || req.headers.host':"
        printf '%s\n' "${matching_files[@]}"

        find ./apps/builder/build -type f -exec sed -i "s/req\.headers\['x-forwarded-host'\] || req\.headers\.host/req.headers['x-forwarded-ws-host'] || req.headers['x-forwarded-host'] || req.headers.host/g" {} +
      shell: bash

    - name: Deploy
      id: deploy
      run: |
        pnpx vercel deploy \
        --prebuilt \
        --token ${{ inputs.vercel-token }} \
        2> >(tee info.txt >&2) | tee domain.txt

        echo "domain=$(cat ./domain.txt)" >> $GITHUB_OUTPUT
        echo "inspect-url=$(cat info.txt | grep 'Inspect:' | awk '{print $2}')" >> $GITHUB_OUTPUT

      shell: bash

    - name: Set Alias
      id: alias
      run: |
        ALIAS="${{ steps.branch.outputs.value }}"

        pnpx vercel alias set \
        "${{ steps.deploy.outputs.domain }}" \
        "${ALIAS}-wstd-00-${{ inputs.environment }}" \
        --token ${{ inputs.vercel-token }} \
        --scope getwebstudio

        echo "value=${ALIAS}" >> $GITHUB_OUTPUT
      shell: bash


================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot

version: 2
updates:
 - package-ecosystem: "devcontainers"
   directory: "/"
   schedule:
     interval: weekly


================================================
FILE: .github/pull_request_template.md
================================================
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why", not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login: 0000)
- [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file


================================================
FILE: .github/workflows/build-figma-tokens.yml
================================================
name: Build and commit Figma tokens

on:
  push:
    branches:
      - figma-tokens
    paths:
      - packages/design-system/src/__generated__/figma-design-tokens.json

jobs:
  main:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          # We don't need a token to push from an action,
          # but we need it if want the commit to trigger other workflows as normal
          token: ${{ secrets.ACCESS_TOKEN_FOR_FIGMA_TOKENS }}

      - uses: ./.github/actions/ci-setup

      - name: Configure git
        run: |
          git config --global user.name 'Bot (build-figma-tokens.yml)'
          git config --global user.email 'bot@localhost'

      - name: Switch branch
        run: git checkout figma-tokens

      - name: Build tokens
        run: pnpm build-figma-tokens

      - name: Commit and push
        run: |
          [[ -z `git status | grep figma-design-tokens.ts` ]] || git commit -m "Update figma-design-tokens.ts" packages/design-system/src/__generated__/figma-design-tokens.ts
          git push


================================================
FILE: .github/workflows/check-submodules.yml
================================================
name: Check submodules

on:
  pull_request:

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  checks:
    timeout-minutes: 20

    environment:
      name: development

    env:
      DATABASE_URL: postgres://
      AUTH_SECRET: test

    runs-on: ubuntu-24.04-arm

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - name: Check if any submodule branch matches github.ref_name
        run: |
          echo "C ${{ github.workflow }}-${{ github.event.number || github.sha }}"
          # Get the current branch or tag name
          REF_NAME="${{ github.event.pull_request.head.ref || github.ref_name }}"

          echo "Branch is:" $REF_NAME

          # List all submodule paths
          SUBMODULES=$(git submodule status | awk '{print $2}')

          # Check each submodule's branch
          for SUBMODULE in $SUBMODULES; do
            echo "Checking submodule: $SUBMODULE"
            (
              cd "$SUBMODULE"
              # Get the current branch of the submodule
              SUBMODULE_BRANCH=$(git rev-parse --abbrev-ref HEAD)
              echo "Submodule branch: $SUBMODULE_BRANCH"

              # Compare the submodule branch to the ref_name
              if [ "$SUBMODULE_BRANCH" = "$REF_NAME" ]; then
                echo "::error::Submodule '$SUBMODULE' is on branch '$SUBMODULE_BRANCH', which matches the current ref '$REF_NAME'."
                exit 1
              fi
            )
            if [ $? -ne 0 ]; then
              exit 1 # Fail the workflow if any submodule branch matches
            fi
          done

          echo "No submodule is on the same branch as the current ref '$REF_NAME'."


================================================
FILE: .github/workflows/chromatic.yml
================================================
name: Chromatic

on:
  push:
    branches:
      - main
  pull_request:
  pull_request_target:
    types: [labeled]

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  chromatic:
    # Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
    if: |
      github.event_name == 'push' ||
      github.event_name == 'pull_request' ||
      (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
    
    timeout-minutes: 20

    runs-on: ubuntu-latest

    environment:
      name: development

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2 # we need to fetch at least parent commit to satisfy Chromatic
          ref: ${{ github.event.pull_request.head.sha || github.sha }} # HEAD commit instead of merge commit

      # Storybook with submodules
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: ./.github/actions/ci-setup

      - name: Chromatic
        id: chromatic
        uses: chromaui/action@v11.3.0
        with:
          projectToken: bea8dc1981d4
          buildScriptName: storybook:build


================================================
FILE: .github/workflows/cli-r2-static.yaml
================================================
name: CLI R2 SSG

on:
  push:
    branches:
      - "*.staging"

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: vercel-cli-r2-static-${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)
  statuses: write # This is required for the GitHub Script createCommitStatus to work
  packages: write

jobs:
  build:
    env:
      COMPATIBILITY_DATE: 2024-04-10

    environment:
      name: "staging"

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }} # HEAD commit instead of merge commit

      # We need submodules here as this is used for the cloudflare build
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      # TRY FIX cloudlare incident
      - uses: unfor19/install-aws-cli-action@v1
        with:
          version: "2.22.35"
          verbose: false
          arch: amd64

      - name: pnpm instal
        run: pnpm install --ignore-scripts

      - name: pnpm build
        run: pnpm --filter 'ssg^...' run build

      # Ideally, execute 'pnpm deploy --prod', but @remix-run/dev doesn't support this flag.
      # Despite being listed as a dependency, @remix-run/dev does not install the remix cli.
      # TODO: Minimize artefact size due to frequent downloads on each publish.
      - name: pnpm deploy
        run: pnpm --filter 'ssg' deploy "${{ github.workspace }}/../ssg-template"

      - name: Make archive
        run: |
          tar --use-compress-program="zstd -19" -cf ssg-template.tar.zst ssg-template
        working-directory: ${{ github.workspace }}/..

      - name: Copy artifact
        run: |
          # For staging
          aws s3 cp ssg-template.tar.zst "s3://${ARTEFACT_BUCKET_NAME}/public/ssg-template/${{ github.ref_name }}.tar.zst"

          # For production can be cached forever
          aws s3 cp \
          --metadata-directive REPLACE --cache-control "public,max-age=31536102,immutable" \
          ssg-template.tar.zst "s3://${ARTEFACT_BUCKET_NAME}/public/ssg-template/${{ github.sha }}.tar.zst"

        working-directory: ${{ github.workspace }}/..
        env:
          AWS_ENDPOINT_URL_S3: ${{ secrets.AWS_ENDPOINT_URL_S3 }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          ARTEFACT_BUCKET_NAME: ${{ secrets.ARTEFACT_BUCKET_NAME }}

  checks:
    environment:
      name: "staging"

    runs-on: ubuntu-latest

    needs: build

    steps:
      - uses: pnpm/action-setup@v4
        with:
          version: "9"

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Copy atrifact via http
        run: curl -o ssg-template.tar.zst ${{ secrets.ARTEFACT_BUCKET_URL }}/public/ssg-template/${{ github.ref_name }}.tar.zst

      - name: Extract archive
        run: tar --use-compress-program="zstd -d" -xf ssg-template.tar.zst -C .

      - name: Webstudio Build
        run: pnpm webstudio build --template ssg --template internal
        working-directory: ${{ github.workspace }}/ssg-template

      - name: Build
        run: pnpm build
        working-directory: ${{ github.workspace }}/ssg-template


================================================
FILE: .github/workflows/cli-r2.yaml
================================================
name: CLI R2

on:
  push:
    branches:
      - "*.staging"

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: vercel-cli-r2-${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)
  statuses: write # This is required for the GitHub Script createCommitStatus to work
  packages: write
  deployments: write

jobs:
  build:
    env:
      COMPATIBILITY_DATE: 2024-04-10

    environment:
      name: "staging"

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }} # HEAD commit instead of merge commit

      # We need submodules here as this is used for the cloudflare build
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      # TRY FIX cloudlare incident
      - uses: unfor19/install-aws-cli-action@v1
        with:
          version: "2.22.35"
          verbose: false
          arch: amd64

      - name: pnpm instal
        run: pnpm install --ignore-scripts

      - name: pnpm build
        run: pnpm --filter 'webstudio-cloudflare-template^...' run build

      # Ideally, execute 'pnpm deploy --prod', but @remix-run/dev doesn't support this flag.
      # Despite being listed as a dependency, @remix-run/dev does not install the remix cli.
      # TODO: Minimize artefact size due to frequent downloads on each publish.
      - name: pnpm deploy
        run: pnpm --filter 'webstudio-cloudflare-template' deploy "${{ github.workspace }}/../cloudflare-template"

      - name: Make archive
        run: |
          tar --use-compress-program="zstd -19" -cf cloudflare-template.tar.zst cloudflare-template
        working-directory: ${{ github.workspace }}/..

      - name: Copy artifact
        run: |
          # For staging
          aws s3 cp cloudflare-template.tar.zst "s3://${ARTEFACT_BUCKET_NAME}/public/cloudflare-template/${{ github.ref_name }}.tar.zst"

          # For production can be cached forever
          aws s3 cp \
          --metadata-directive REPLACE --cache-control "public,max-age=31536102,immutable" \
          cloudflare-template.tar.zst "s3://${ARTEFACT_BUCKET_NAME}/public/cloudflare-template/${{ github.sha }}.tar.zst"

        working-directory: ${{ github.workspace }}/..
        env:
          AWS_ENDPOINT_URL_S3: ${{ secrets.AWS_ENDPOINT_URL_S3 }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          ARTEFACT_BUCKET_NAME: ${{ secrets.ARTEFACT_BUCKET_NAME }}

  checks:
    environment:
      name: "staging"

    runs-on: ubuntu-latest

    needs: build

    steps:
      - uses: pnpm/action-setup@v4
        with:
          version: "9"

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Copy atrifact via http
        run: curl -o cloudflare-template.tar.zst ${{ secrets.ARTEFACT_BUCKET_URL }}/public/cloudflare-template/${{ github.ref_name }}.tar.zst

      - name: Extract archive
        run: tar --use-compress-program="zstd -d" -xf cloudflare-template.tar.zst -C .

      - name: Webstudio Build
        run: pnpm webstudio build --template internal --template saas-helpers --template cloudflare --assets false
        working-directory: ${{ github.workspace }}/cloudflare-template

      - name: Remix Build
        run: pnpm build
        working-directory: ${{ github.workspace }}/cloudflare-template

      - name: WRANGLER Build
        run: |
          NODE_ENV=production pnpm wrangler deploy \
          --name build \
          --compatibility-date '${COMPATIBILITY_DATE}' \
          --minify true \
          --logpush true \
          --dry-run \
          --outdir dist \
          './functions/[[path]].ts'

        working-directory: ${{ github.workspace }}/cloudflare-template

  delete-github-deployments:
    needs: checks
    uses: ./.github/workflows/delete-github-deployments.yml
    with:
      ref: ${{ github.ref_name }}


================================================
FILE: .github/workflows/delete-github-deployments.yml
================================================
# https://github.com/orgs/community/discussions/36919
name: Delete github deployments

on:
  workflow_call:
    inputs:
      ref:
        type: string
        required: true

permissions:
  deployments: write

jobs:
  delete_github_deployments:
    runs-on: ubuntu-latest
    if: ${{ always() }}
    steps:
      - name: Delete Previous deployments
        uses: actions/github-script@v7
        env:
          REF: ${{ inputs.ref }}
        with:
          script: |
            const { REF } = process.env;

            console.log(REF);

            const deployments = await github.rest.repos.listDeployments({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: REF,
              per_page: 100
            });

            console.log(deployments);

            await Promise.allSettled(
              deployments.data.map(async (deployment) => {
                await github.rest.repos.createDeploymentStatus({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  deployment_id: deployment.id,
                  state: 'inactive'
                });
                return github.rest.repos.deleteDeployment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  deployment_id: deployment.id
                });
              })
            );


================================================
FILE: .github/workflows/fixtures-test.yml
================================================
name: Fixtures tests

on:
  workflow_call:
    inputs:
      builder-url:
        required: true
        type: string
      builder-host:
        required: true
        type: string
      environment:
        required: true
        type: string
    secrets:
      PRIVATE_GITHUB_DEPLOY_TOKEN:
        required: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  checks:
    timeout-minutes: 20

    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]

    runs-on: ${{ matrix.os }}

    environment:
      name: ${{ inputs.environment }}

    env:
      DATABASE_URL: postgres://
      AUTH_SECRET: test
      BUILDER_URL_DEPRECATED: ${{ inputs.builder-url }}
      BUILDER_HOST: ${{ inputs.builder-host }}

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
      # Test that everything is working with submodules
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: ./.github/actions/ci-setup

        # Testing fixtures for vercel template
      - name: Test cli --help flag
        working-directory: ./fixtures/webstudio-features
        run: pnpm cli --help

      - name: Testing cli link command
        run: pnpm --filter='./fixtures/*' --sequential run fixtures:link

      - name: Testing cli sync command
        run: pnpm --filter='./fixtures/*' run --parallel fixtures:sync

      - name: Testing cli build command
        run: pnpm --filter='./fixtures/*' run --parallel fixtures:build

      - name: Prepare for diffing
        shell: bash
        run: |
          find . -type f -path "./fixtures/*/.webstudio/data.json" -exec sed -i 's|"origin": ".*"|"origin": "https://main.development.webstudio.is"|g' {} +

      - name: Test git diff
        # This command will fail if there are uncommitted changes, i.e something has broken
        run: git diff --name-only HEAD --exit-code

      - name: Show changed files and diff
        if: ${{ failure() }}
        run: |
          echo "Changed files are:"
          git diff --name-only HEAD
          git diff HEAD | head -n 1000


================================================
FILE: .github/workflows/lint-pull-request.yaml
================================================
name: "Lint PR"

on:
  pull_request:
    types:
      - opened
      - edited
      - synchronize

  pull_request_target:
    types:
      - opened
      - edited
      - synchronize

permissions:
  pull-requests: write

jobs:
  main:
    name: Validate PR title
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5
        id: lint_pr_title
        with:
          # Configure which types are allowed (newline-delimited).
          # Default: https://github.com/commitizen/conventional-commit-types
          types: |
            feat
            fix
            docs
            style
            refactor
            perf
            test
            build
            ci
            chore
            revert
            experimental
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - if: always() && (steps.lint_pr_title.outputs.error_message != null)
        uses: marocchino/sticky-pull-request-comment@v2
        # When the previous steps fails, the workflow would stop. By adding this
        # condition you can continue the execution with the populated error message.

        with:
          header: pr-title-lint-error
          message: |
            Hey there and thank you for opening this pull request! 👋🏼

            We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.

            Details:

            ```
            ${{ steps.lint_pr_title.outputs.error_message }}
            ```
            <details>
              <summary>Release types</summary>

            - **feat** - A new feature
            - **fix** - A bug fix
            - **docs** - Documentation only changes
            - **style** - Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
            - **refactor** - A code change that neither fixes a bug nor adds a feature
            - **perf** - A code change that improves performance
            - **test** - Adding missing tests or correcting existing tests
            - **build** - Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
            - **ci** - Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
            - **chore** - Other changes that don't modify src or test files
            - **revert** - Reverts a previous commit
            - **experimental** - Flagged feature

            </details>

        # Delete a previous comment when the issue has been resolved
      - if: ${{ steps.lint_pr_title.outputs.error_message == null }}
        uses: marocchino/sticky-pull-request-comment@v2
        with:
          header: pr-title-lint-error
          delete: true


================================================
FILE: .github/workflows/main.yml
================================================
name: Main workflow

on:
  push:
    branches:
      - main
  pull_request:
  pull_request_target:
    types: [labeled]

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  checks:
    # Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
    if: |
      github.event_name == 'push' ||
      github.event_name == 'pull_request' ||
      (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
    
    timeout-minutes: 20

    strategy:
      matrix:
        environment:
          - empty
          - development

    environment:
      name: ${{ matrix.environment }}

    env:
      DATABASE_URL: postgres://
      AUTH_SECRET: test

    runs-on: ubuntu-24.04-arm

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      # Will not checkout submodules on empty environment, and will on development
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - name: Pnpm install
        run: |
          pnpm install

      - uses: actions/cache@v4
        with:
          path: |
            ./node_modules/.cache/prettier/.prettier-cache
          key: checks-${{ github.sha }}
          restore-keys: checks-

      - run: echo ===SHA USED=== ${{ github.event.pull_request.head.sha || github.sha }} # todo: remove after check whats happening on main

      - run: |
          pnpm prettier --cache --check "**/*.{js,md,ts,tsx}"

      - name: Lint
        run: |
          pnpm lint

      - name: Cache Playwright browsers
        uses: actions/cache@v4
        with:
          path: ~/.cache/ms-playwright
          key: playwright-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            playwright-${{ runner.os }}-

      - name: Playwright init
        run: |
          pnpm playwright install
        working-directory: packages/sdk-components-animation

      - name: Test
        run: |
          pnpm -r test

      - name: Typecheck
        run: |
          pnpm -r typecheck

  check-size:
    runs-on: ubuntu-24.04-arm

    environment:
      name: development

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: ./.github/actions/ci-setup

      - run: pnpm --filter "{./fixtures/*}..." build

      - uses: actions/github-script@v7
        with:
          script: |
            const assertSize = async (directory, maxSize) => {
              let result = ''
              await exec.exec('du', ['-sk', directory], {
                silent: true,
                listeners: {
                  stdout: (data) => {
                    result += data.toString()
                  }
                }
              })
              const size = Number.parseInt(result, 10)
              return {
                passed: size <= maxSize,
                size,
                diff: size - maxSize,
                directory,
              }
            }
            const results = [
              await assertSize('./fixtures/ssg/dist/client', 356),
              await assertSize('./fixtures/react-router-netlify/build/client', 376),
              await assertSize('./fixtures/webstudio-features/build/client', 3312),
            ]
            for (const result of results) {
              if (result.passed) {
                console.info(`${result.directory}: ${result.size}kB (${result.diff}kB)`)
              } else {
                console.info('')
                console.error(`${result.directory}: ${result.size}kB (+${result.diff}kB)`)
              }
            }
            if (results.some(result => result.passed === false)) {
              console.error('Some fixtures exceeded limits')
              process.exit(1)
            }


================================================
FILE: .github/workflows/migrate.yaml
================================================
name: Migrate

on:
  push:
    branches:
      - "migrate"
      - "main"
      - "*.staging"
      - "*.migrate"

# Pending if other migration from the same branch is running
concurrency: migrate-${{ github.ref_name }}

permissions:
  contents: read # to fetch code (actions/checkout)
  statuses: write # This is required for the GitHub Script createCommitStatus to work

jobs:
  migrate:
    # This workflow is triggered only on pushes to the `main`, `*.staging` or 'migrate' branches.
    # For `*.staging` and `migrate` it specifically checks if the commit message starts with `::migrate::`,
    # indicating a migration-related change.
    #
    # Example usage:
    #   Execute a commit with a migration flag using:
    #   git commit --allow-empty -m "::migrate::test description"
    # Note:
    #   This setup is a temporary measure. The intention is to transition to a fully automated publish and release process via GitHub Actions in the future.
    if: (github.ref_name == 'main') || ((github.ref_name == 'migrate' || endsWith(github.ref_name, '.migrate') || endsWith(github.ref_name, '.staging')) && startsWith(github.event.head_commit.message, '::migrate::'))

    runs-on: ubuntu-latest

    environment:
      name: ${{ (startsWith(github.ref_name, 'release') && endsWith(github.ref_name, '.staging')) && 'postgres_production' || 'postgres_development' }}

    timeout-minutes: 20

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }} # HEAD commit instead of merge commit

      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - name: pnpm instal
        run: pnpm install --ignore-scripts

      - name: generate prisma
        run: pnpm --filter=@webstudio-is/prisma-client generate

      - name: execute migration
        run: pnpm --filter '@webstudio-is/prisma-client' run migrations migrate
        env:
          DIRECT_URL: ${{ secrets.DIRECT_URL }}

  # Execute db tests (runs after migrations, even if they fail)
  db-tests:
    # Always run tests to see failures on CI, but only after migrate job completes
    if: always()

    needs: [migrate]

    runs-on: ubuntu-latest

    environment:
      name: ${{ (startsWith(github.ref_name, 'release') && endsWith(github.ref_name, '.staging')) && 'postgres_production' || 'postgres_development' }}

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }} # HEAD commit instead of merge commit

      - uses: pnpm/action-setup@v4

      - name: Run database tests
        run: pnpm -r db-test
        env:
          DIRECT_URL: ${{ secrets.DIRECT_URL }}

  # Prints pending migrations
  pending:
    if: always()

    needs: [migrate]

    runs-on: ubuntu-latest

    environment:
      name: ${{ (startsWith(github.ref_name, 'release') && endsWith(github.ref_name, '.staging')) && 'postgres_production' || 'postgres_development' }}

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }} # HEAD commit instead of merge commit

      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm

      - name: pnpm instal
        run: pnpm install --ignore-scripts

      - name: generate prisma
        run: pnpm --filter=@webstudio-is/prisma-client generate

      - name: get pending
        id: pending
        run: |
          echo "value=$(pnpm --filter '@webstudio-is/prisma-client' run migrations pending-count | grep ::pending-count::)" >> $GITHUB_OUTPUT
        env:
          DIRECT_URL: ${{ secrets.DIRECT_URL }}

      - uses: ./.github/actions/add-status
        with:
          title: "⭕ Pending Migrations"
          description: ${{ steps.pending.outputs.value }}
          url: "https://webstudio.is"


================================================
FILE: .github/workflows/publish-beta.yml
================================================
name: Publish beta packages on NPM 📦

on:
  pull_request:
    types:
      - labeled

jobs:
  publish:
    # prevents this action from running on forks
    if: |
      github.repository_owner == 'webstudio-is' &&
      startsWith(github.event.label.name, 'publish:')

    timeout-minutes: 20

    runs-on: ubuntu-latest

    env:
      DATABASE_URL: postgres://
      AUTH_SECRET: test

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }} # HEAD commit instead of merge commit

      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - name: Creating .npmrc
        run: |
          cat << EOF > "$HOME/.npmrc"
            //registry.npmjs.org/:_authToken=$NPM_TOKEN
          EOF
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

      # compute short sha
      - id: short_sha
        run: echo "value=$(echo ${{ github.event.pull_request.head.sha || github.sha }} | cut -c1-7)" >> $GITHUB_OUTPUT

      - id: tag
        run: echo "value=$(echo ${{ github.event.label.name }} | cut -d ':' -f2)" >> $GITHUB_OUTPUT

      - name: bump version to 0.0.0-${{ steps.short_sha.outputs.value }}
        run: |
          pnpx replace-in-files-cli \
            --string="0.0.0-webstudio-version" \
            --replacement="0.0.0-${{ steps.short_sha.outputs.value }}" \
            "**/package.json"

      - run: pnpm install --ignore-scripts
      - run: pnpm --filter="webstudio..." build
      - run: pnpm --filter="webstudio..." dts

      - name: Publishing ${{ steps.tag.outputs.value }} tag with sha ${{ steps.short_sha.outputs.value }}
        run: pnpm -r publish --tag "${{ steps.tag.outputs.value }}" --no-git-checks --access public


================================================
FILE: .github/workflows/re-create-figma-tokens-branch.yml
================================================
name: Re-create branch for Figma tokens

on: delete

permissions:
  contents: write

jobs:
  main:
    runs-on: ubuntu-latest

    # run if figma-tokens was deleted
    if: ${{ github.event.ref == 'figma-tokens'}}

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Re-create branch
        run: |
          git checkout main
          git checkout -b figma-tokens
          git push --set-upstream origin figma-tokens


================================================
FILE: .github/workflows/release.yml
================================================
name: Release

on:
  push:
    tags:
      - '[0-9]+.[0-9]+.[0-9]+'

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
    - uses: actions/github-script@v7
      with:
        script: |
          const latestRelease = await github.rest.repos.getLatestRelease({
            owner: context.repo.owner,
            repo: context.repo.repo,
          })
          const commits = await github.rest.repos.compareCommitsWithBasehead({
            owner: context.repo.owner,
            repo: context.repo.repo,
            basehead: `refs/tags/${latestRelease.data.tag_name}...${context.ref}`,
          })

          const groups = {
            feat: [`## Features\n`],
            fix: [`## Fixes\n`],
            docs: [`## Documentation\n`],
            experimental: [`## Experimental\n`],
            other: [`## Other changes\n`],
          }
          for (const commit of commits.data.commits) {
            const match = commit.commit.message.match(/^(?<type>\w+)\s*:\s*(?<message>.+)\n*/)
            const type = match?.groups?.type
            const message = match?.groups?.message
            if (type && message) {
              const availableType = type in groups ? type : 'other'
              const capitalized = message[0].toLocaleUpperCase() + message.slice(1)
              groups[availableType].push(`- ${capitalized} by @${commit.author.login}`)
            }
          }

          const tag_name = context.ref.slice('refs/tags/'.length)
          const fullChangelog = `**Full Changelog**: https://github.com/${context.repo.owner}/${context.repo.repo}/compare/${latestRelease.data.tag_name}...${tag_name}`
          const changelog = Object.values(groups)
            .filter(lines => lines.length > 1)
            .map(lines => lines.join('\n'))
            .concat(fullChangelog)
            .join('\n\n')
          console.info(changelog)

          await github.rest.repos.createRelease({
            owner: context.repo.owner,
            repo: context.repo.repo,
            tag_name,
            name: tag_name,
            body: changelog,
          })

  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    environment:
      name: development
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.ref }} # tag name
      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - id: version
        run: echo "value=$(echo ${{ github.ref }} | sed 's/refs\/tags\///')" >> $GITHUB_OUTPUT
      - name: bump version to ${{ steps.version.outputs.value }}
        run: |
          pnpx replace-in-files-cli \
            --string="0.0.0-webstudio-version" \
            --replacement="${{ steps.version.outputs.value }}" \
            "**/package.json"

      - name: pnpm instal
        run: pnpm install --ignore-scripts
      - run: pnpm --filter="webstudio..." build
      - run: pnpm --filter="webstudio..." dts

      - name: Creating .npmrc
        run: |
          cat << EOF > "$HOME/.npmrc"
            //registry.npmjs.org/:_authToken=$NPM_TOKEN
          EOF
        env:
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
      - run: pnpm -r publish --access public --no-git-checks


================================================
FILE: .github/workflows/vercel-deploy-staging.yml
================================================
name: Vercel Deploy Staging

on:
  push:
  pull_request_target:
    types: [labeled, synchronize]

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: vercel-deploy-${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)
  statuses: write # This is required for the GitHub Script createCommitStatus to work
  deployments: write
  pull-requests: write # needed to remove labels and comment

jobs:
  # Remove the safe-to-deploy label when new commits are pushed to a PR (requires re-review)
  remove-label-on-update:
    if: github.event_name == 'pull_request_target' && github.event.action == 'synchronize'
    runs-on: ubuntu-latest
    steps:
      - name: Remove safe-to-deploy label
        uses: actions/github-script@v7
        with:
          script: |
            await github.rest.issues.removeLabel({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              name: 'safe-to-deploy'
            }).catch(() => {});
            console.log('Removed safe-to-deploy label due to new commits. Re-review required.');

  deployment:
    # Run on push (for repo branches) OR on labeled event with safe-to-deploy label (for fork PRs)
    if: |
      github.event_name == 'push' ||
      (github.event_name == 'pull_request_target' && github.event.action == 'labeled' && github.event.label.name == 'safe-to-deploy')
    
    # Execute development and staging on staging branches
    # Execute only development on all other branches
    strategy:
      matrix:
        environment:
          - staging
          - development
        is-staging:
          - ${{ github.event_name == 'push' && endsWith(github.ref_name, '.staging') }}
        exclude:
          - environment: staging
            is-staging: false

    environment:
      name: ${{ matrix.environment }}

    timeout-minutes: 20

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }}

      - uses: ./.github/actions/submodules-checkout
        with:
          submodules-ssh-key: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

      - uses: pnpm/action-setup@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - uses: ./.github/actions/vercel
        id: vercel
        name: Deploy to Vercel
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          ref-name: ${{ github.event_name == 'pull_request_target' && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}
          sha: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }}
          environment: ${{ matrix.environment }}

      - name: Debug Vercel Outputs
        run: |
          echo "domain=${{ steps.vercel.outputs.domain }}"
          echo "inspect-url=${{ steps.vercel.outputs.inspect-url }}"
          echo "alias=${{ steps.vercel.outputs.alias }}"

      - uses: ./.github/actions/add-status
        with:
          title: "⏰ [${{ matrix.environment }}] Vercel Inspection"
          description: "[${{ matrix.environment }}] Vercel logs"
          url: "${{ steps.vercel.outputs.inspect-url }}"

      - uses: ./.github/actions/add-status
        with:
          title: "⭐ [${{ matrix.environment }}] Apps Webstudio URL"
          description: "[${{ matrix.environment }}] Site url"
          url: "https://${{ steps.vercel.outputs.alias }}.${{ matrix.environment }}.webstudio.is"

      - name: Comment on PR with deployment URL
        if: github.event_name == 'pull_request_target' && matrix.environment == 'development'
        uses: actions/github-script@v7
        with:
          script: |
            const deployUrl = 'https://${{ steps.vercel.outputs.alias }}.${{ matrix.environment }}.webstudio.is';
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `🚀 **Deployed!**\n\n📍 Preview: ${deployUrl}\n\n_Note: Adding new commits will remove the \`safe-to-deploy\` label and require re-approval._`
            });

    outputs:
      builder-url: "https://${{ steps.vercel.outputs.alias }}.${{ matrix.environment }}.webstudio.is"
      builder-host: "${{ steps.vercel.outputs.alias }}.${{ matrix.environment }}.webstudio.is"

  fixtures-test:
    needs: deployment
    uses: ./.github/workflows/fixtures-test.yml
    with:
      builder-url: ${{ needs.deployment.outputs.builder-url }}
      builder-host: ${{ needs.deployment.outputs.builder-host }}
      environment: development
    secrets:
      # We are not passing the secret here (as it does not exist in the current environment).
      # Instead, this serves as a signal to the calling workflow that it has permission to extract it from the environment.
      PRIVATE_GITHUB_DEPLOY_TOKEN: ${{ secrets.PRIVATE_GITHUB_DEPLOY_TOKEN }}

  delete-github-deployments:
    needs: fixtures-test
    uses: ./.github/workflows/delete-github-deployments.yml
    with:
      ref: ${{ github.event_name == 'pull_request_target' && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}


================================================
FILE: .github/workflows/vis-reg-tests.yml
================================================
name: Visual Regression Tests

on:
  push:
    branches:
      - main
  pull_request:
  pull_request_target:
    types: [labeled]

# cancel in-progress runs on new commits to same PR (gitub.event.number)
concurrency:
  group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
  cancel-in-progress: true

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  lost-pixel:
    # Run on push, regular PR (for repo branches), or labeled PR with safe-to-deploy (for forks)
    if: |
      github.event_name == 'push' ||
      github.event_name == 'pull_request' ||
      (github.event_name == 'pull_request_target' && github.event.label.name == 'safe-to-deploy')
    
    timeout-minutes: 20
    runs-on: ubuntu-latest
    env:
      DATABASE_URL: postgres://
      AUTH_SECRET: test
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha || github.sha }} # HEAD commit instead of merge commit

      - uses: ./.github/actions/ci-setup

      - run: VISUAL_TESTING=true pnpm storybook:build

      - name: Lost Pixel
        uses: lost-pixel/lost-pixel@v3.16.0
        env:
          LOST_PIXEL_API_KEY: 8b76db6c-b9f0-46d1-982f-70900a02690a


================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
.pnp
.pnp.js
yarn.lock

# testing
coverage

# remix
build
_build
.cache
.vercel
.output
.netlify

# misc
.DS_Store
*.pem
!https/*.pem
/.idea

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
# .env
.env.development
.env.local
.env.development.local
.env.test.local
.env.production.local

# data
/data
*.db
*.db-journal

# migrations
**/prisma/migrations/lockfile
**/prisma/migrations/*/client

# builds
packages/**/lib
generated
storybook-static
tsconfig.tsbuildinfo

# to save thunder https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client files
.thunder
.env*.local

# wrangler builds
dist

# should be here otherwise if placed inside prisma-client pnpm deploy doesn't copy it
packages/prisma-client/src/__generated__

.temp
*.timestamp-*.mjs

# copilot instructions
.github/instructions


================================================
FILE: .gitmodules
================================================
[submodule "packages/sdk-components-animation/private-src"]
	path = packages/sdk-components-animation/private-src
	url = git@github.com:webstudio-is/sdk-components-animation.git
	branch = main


================================================
FILE: .nvmrc
================================================
22


================================================
FILE: .oxlintrc.json
================================================
{
  "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
  "plugins": ["react", "unicorn", "typescript"],
  "categories": {
    "correctness": "off"
  },
  "rules": {
    "no-console": [
      "error",
      { "allow": ["info", "warn", "error", "time", "timeEnd"] }
    ],
    "func-style": ["error", "expression", { "allowArrowFunctions": true }],
    "curly": "error",
    "eqeqeq": ["error", "always", { "null": "ignore" }],
    "radix": "error",
    "react/rules-of-hooks": "error",
    "react/exhaustive-deps": "warn",
    "typescript/no-explicit-any": "error",
    "unicorn/filename-case": ["error", { "case": "kebabCase" }],
    "unicorn/prefer-node-protocol": "error"
  },
  "ignorePatterns": [
    "**/*.js",
    "**/*.d.ts",
    "**/__generated__/**",
    "codemod/**",
    "packages/*/lib/**",
    "packages/prisma-client/prisma/migrations/**",
    "packages/cli/templates/**",
    "fixtures/**",
    "packages/sdk-components-animation/private-src/polyfill/**",
    "packages/sdk-components-animation/private-src/perf/**"
  ]
}


================================================
FILE: .prettierignore
================================================
pnpm-lock.yaml
packages/prisma-client/prisma/migrations/*/client
packages/prisma-client/**/*.d.ts

================================================
FILE: .storybook/main.ts
================================================
import * as path from "node:path";
import { existsSync, readdirSync } from "node:fs";
import { defaultClientConditions } from "vite";
import type { StorybookConfig } from "@storybook/react-vite";

const isFolderEmpty = (folderPath: string) => {
  if (!existsSync(folderPath)) {
    return true; // Folder does not exist
  }
  const contents = readdirSync(folderPath);

  return contents.length === 0;
};

const hasPrivateFolders = !isFolderEmpty(
  path.join(__dirname, "../../packages/sdk-components-animation/private-src")
);

const visualTestingStories: StorybookConfig["stories"] = [
  {
    directory: "../apps/builder",
    titlePrefix: "Builder",
    files: "**/*.stories.tsx",
  },
  {
    directory: "../packages/design-system/src/components",
    titlePrefix: "Design system",
    files: "**/*.stories.tsx",
  },
];

export default {
  stories: process.env.VISUAL_TESTING
    ? visualTestingStories
    : [
        ...visualTestingStories,
        {
          directory: "../packages/css-engine/src",
          titlePrefix: "CSS engine",
          files: "**/*.stories.tsx",
        },
        {
          directory: "../packages/image/src",
          titlePrefix: "Image",
          files: "**/*.stories.tsx",
        },
        {
          directory: "../packages/icons",
          titlePrefix: "Icons",
          files: "**/*.stories.tsx",
        },
        {
          directory: "../packages/sdk-components-react",
          titlePrefix: "SDK components React",
          files: "**/*.stories.tsx",
        },
        {
          directory: "../packages/sdk-components-react-radix",
          titlePrefix: "SDK components React Radix",
          files: "**/*.stories.tsx",
        },
        {
          directory: "../packages/sdk-components-animation",
          titlePrefix: "SDK components animation",
          files: "**/*.stories.tsx",
        },
      ],
  framework: {
    name: "@storybook/react-vite",
    options: {},
  },
  addons: [
    "@storybook/addon-controls",
    "@storybook/addon-actions",
    "@storybook/addon-backgrounds",
  ],
  async viteFinal(config) {
    return {
      ...config,
      optimizeDeps: {
        exclude: ["scroll-timeline-polyfill"],
      },

      define: {
        ...config.define,
        // storybook use "util" package internally which is bundled with stories
        // and gives an error that process is undefined
        "process.env.NODE_DEBUG": "undefined",
        "process.env.IS_STROYBOOK": "true",
      },
      resolve: {
        ...config.resolve,
        conditions: hasPrivateFolders
          ? ["webstudio-private", "webstudio", ...defaultClientConditions]
          : ["webstudio", ...defaultClientConditions],

        alias: [
          {
            find: "~",
            replacement: path.resolve("./apps/builder/app"),
          },
        ],
      },
    };
  },
} satisfies StorybookConfig;


================================================
FILE: .storybook/preview-body.html
================================================
<script>
  // for styling radix components
  document.body.setAttribute("data-ws-component", "Body");
</script>


================================================
FILE: .storybook/preview.tsx
================================================
import type { Preview } from "@storybook/react";
import * as React from "react";
import { useEffect } from "react";
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { setEnv } from "../packages/feature-flags/src/index";
import { theme, globalCss } from "../packages/design-system/src/index";
import { color } from "../packages/design-system/src/__generated__/figma-design-tokens";

// this adds <style> tags to the <head> of the document
import "@fontsource-variable/inter";
import "@fontsource-variable/manrope";
import "@fontsource/roboto-mono";

const WaitForFonts = ({ children }) => {
  const [isFontsLoaded, setIsFontsLoaded] = React.useState(false);

  useEffect(() => {
    let isUnsubscribed = false;
    document.fonts.ready.then(() => {
      if (isUnsubscribed === false) {
        setIsFontsLoaded(true);
      }
    });
    return () => {
      isUnsubscribed = true;
    };
  }, []);

  return isFontsLoaded ? (
    children
  ) : (
    <div>
      Waiting for fonts to load ...
      {/* not rendering children initially breaks backgrounds addon,
       * so we always render it */}
      <div style={{ display: "none" }}>{children}</div>
    </div>
  );
};

const globalStyles = globalCss({
  body: {
    color: theme.colors.foregroundMain,
    fontFamily: theme.fonts.sans,
  },
});

export const decorators: Preview["decorators"] = [
  (Story) => {
    globalStyles();
    setEnv("*");
    return (
      // waiting for fonts makes screenshot tests more stable
      <WaitForFonts>
        <TooltipProvider>
          <Story />
        </TooltipProvider>
      </WaitForFonts>
    );
  },
];

const parameters: Preview["parameters"] = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
  backgrounds: {
    default: "White",
    values: [
      { name: "White", value: "#ffffff" },
      { name: "Black", value: "#000000" },
      { name: "Panel", value: color.backgroundPanel },
      { name: "Maintenance Dark", value: color.maintenanceDark },
      { name: "Maintenance Medium", value: color.maintenanceMedium },
      { name: "Maintenance Light", value: color.maintenanceLight },
    ],
  },
};

export default {
  decorators,
  parameters,
} satisfies Preview;


================================================
FILE: .vscode/extensions.json
================================================
{
  "recommendations": ["ms-vscode-remote.remote-containers"]
}


================================================
FILE: .vscode/settings.json
================================================
{
  "typescript.experimental.useTsgo": true,
  // Disable formatting for SQL files
  "[sql]": {
    "editor.formatOnSave": false,
    "editor.formatOnPaste": false,
    "editor.formatOnType": false
  },
  // Disable Prettier for SQL files specifically
  "prettier.enable": true,
  "prettier.ignorePath": ".prettierignore",
  // Exclude SQL files from auto-formatting
  "files.associations": {
    "*.sql": "sql"
  }
}


================================================
FILE: @types/canvas-iframe.d.ts
================================================
declare namespace React {
  interface IframeHTMLAttributes {
    credentialless?: "true";
  }
}


================================================
FILE: @types/content.d.ts
================================================
// CSS Containment
// Specification: https://drafts.csswg.org/css-contain-2/
// Repository: https://github.com/w3c/csswg-drafts/tree/main/css-contain-2

declare var oncontentvisibilityautostatechange: ContentVisibilityAutoStateChangeEvent | null;

interface GlobalEventHandlersEventMap {
  contentvisibilityautostatechange: ContentVisibilityAutoStateChangeEvent;
}


================================================
FILE: @types/css-tree.d.ts
================================================
// Minimal-yet-safe TypeScript typings for css-tree v3.x
// Covers: AST node types, parse/generate, walk/find, List, lexer API,
// value definition syntax helpers, and common utils used in this project.

declare module "css-tree" {
  // -------------------------------------------------
  // Common
  // -------------------------------------------------
  export interface SourceLocation {
    source: string;
    start: { offset: number; line: number; column: number };
    end: { offset: number; line: number; column: number };
  }

  export interface BaseNode {
    type: string;
    loc: SourceLocation | null;
  }

  // Doubly-linked list used by csstree
  export interface ListItem<T> {
    prev: ListItem<T> | null;
    next: ListItem<T> | null;
    data: T;
  }

  export class List<T> implements Iterable<T> {
    static createItem<T>(data: T): ListItem<T>;

    constructor();
    // iteration
    [Symbol.iterator](): IterableIterator<T>;
    // props
    readonly size: number;
    readonly isEmpty: boolean;
    readonly first: T | null;
    readonly last: T | null;
    // traversal helpers
    forEach(
      fn: (data: T, item: ListItem<T>, list: List<T>) => void,
      thisArg?: any
    ): void;
    forEachRight(
      fn: (data: T, item: ListItem<T>, list: List<T>) => void,
      thisArg?: any
    ): void;
    // conversion
    fromArray(items: T[]): this;
    toArray(): T[];
    toJSON(): T[];
    // mutation (minimal surface used by walkers)
    clear(): void;
    remove(item: ListItem<T>): ListItem<T>;
    insert(item: ListItem<T>, before?: ListItem<T> | null): void;
    insertData(data: T, before?: ListItem<T> | null): void;
    append(item: ListItem<T>): void;
    appendData(data: T): void;
    prepend(item: ListItem<T>): void;
    prependData(data: T): void;
    replace(oldItem: ListItem<T>, newItemOrList: ListItem<T> | List<T>): void;
  }

  // -------------------------------------------------
  // AST Nodes (as per docs/ast.md)
  // -------------------------------------------------
  export interface AnPlusB extends BaseNode {
    type: "AnPlusB";
    a: string | null;
    b: string | null;
  }
  export interface Atrule extends BaseNode {
    type: "Atrule";
    name: string;
    prelude: AtrulePrelude | Raw | null;
    block: Block | null;
  }
  export interface AtrulePrelude extends BaseNode {
    type: "AtrulePrelude";
    children: List<CssNode>;
  }
  export interface AttributeSelector extends BaseNode {
    type: "AttributeSelector";
    name: Identifier;
    matcher: string | null;
    value: StringNode | Identifier | null;
    flags: string | null;
  }
  export interface Block extends BaseNode {
    type: "Block";
    children: List<Atrule | Rule | Declaration>;
  }
  export interface Brackets extends BaseNode {
    type: "Brackets";
    children: List<CssNode>;
  }
  export interface CDC extends BaseNode {
    type: "CDC";
  }
  export interface CDO extends BaseNode {
    type: "CDO";
  }
  export interface ClassSelector extends BaseNode {
    type: "ClassSelector";
    name: string;
  }
  export interface Combinator extends BaseNode {
    type: "Combinator";
    name: string;
  }
  export interface Comment extends BaseNode {
    type: "Comment";
    value: string;
  }
  export interface Condition extends BaseNode {
    type: "Condition";
    kind: string;
    children: List<
      | Identifier
      | Feature
      | FeatureFunction
      | FeatureRange
      | SupportsDeclaration
    >;
  }
  export interface Declaration extends BaseNode {
    type: "Declaration";
    important: boolean | string;
    property: string;
    value: Value | Raw;
  }
  export interface DeclarationList extends BaseNode {
    type: "DeclarationList";
    children: List<Declaration | Atrule | Rule>;
  }
  export interface Dimension extends BaseNode {
    type: "Dimension";
    value: string;
    unit: string;
  }
  export interface Feature extends BaseNode {
    type: "Feature";
    kind: string;
    name: string;
    value: Identifier | NumberNode | Dimension | Ratio | FunctionNode | null;
  }
  export interface FeatureFunction extends BaseNode {
    type: "FeatureFunction";
    kind: string;
    feature: string;
    value: Declaration | Selector;
  }
  export interface FeatureRange extends BaseNode {
    type: "FeatureRange";
    kind: string;
    left: Identifier | NumberNode | Dimension | Ratio | FunctionNode;
    leftComparison: string;
    middle: Identifier | NumberNode | Dimension | Ratio | FunctionNode;
    rightComparison: string | null;
    right: Identifier | NumberNode | Dimension | Ratio | FunctionNode | null;
  }
  export interface FunctionNode extends BaseNode {
    type: "Function";
    name: string;
    children: List<CssNode>;
  }
  export interface GeneralEnclosed extends BaseNode {
    type: "GeneralEnclosed";
    kind: string;
    function: string | null;
    children: List<CssNode>;
  }
  export interface Hash extends BaseNode {
    type: "Hash";
    value: string;
  }
  export interface IdSelector extends BaseNode {
    type: "IdSelector";
    name: string;
  }
  export interface Identifier extends BaseNode {
    type: "Identifier";
    name: string;
  }
  export interface Layer extends BaseNode {
    type: "Layer";
    name: string;
  }
  export interface LayerList extends BaseNode {
    type: "LayerList";
    children: List<Layer>;
  }
  export interface MediaQuery extends BaseNode {
    type: "MediaQuery";
    modifier: string | null;
    mediaType: string | null;
    condition: Condition | null;
  }
  export interface MediaQueryList extends BaseNode {
    type: "MediaQueryList";
    children: List<MediaQuery>;
  }
  export interface NestingSelector extends BaseNode {
    type: "NestingSelector";
  }
  export interface Nth extends BaseNode {
    type: "Nth";
    nth: AnPlusB | Identifier;
    selector: SelectorList | null;
  }
  export interface NumberNode extends BaseNode {
    type: "Number";
    value: string;
  }
  export interface Operator extends BaseNode {
    type: "Operator";
    value: string;
  }
  export interface Parentheses extends BaseNode {
    type: "Parentheses";
    children: List<CssNode>;
  }
  export interface Percentage extends BaseNode {
    type: "Percentage";
    value: string;
  }
  export interface PseudoClassSelector extends BaseNode {
    type: "PseudoClassSelector";
    name: string;
    children: List<Raw> | null;
  }
  export interface PseudoElementSelector extends BaseNode {
    type: "PseudoElementSelector";
    name: string;
    children: List<Raw> | null;
  }
  export interface Ratio extends BaseNode {
    type: "Ratio";
    left: NumberNode | FunctionNode;
    right: NumberNode | FunctionNode | null;
  }
  export interface Raw extends BaseNode {
    type: "Raw";
    value: string;
  }
  export interface Rule extends BaseNode {
    type: "Rule";
    prelude: SelectorList | Raw;
    block: Block;
  }
  export interface Scope extends BaseNode {
    type: "Scope";
    root: SelectorList | Raw | null;
    limit: SelectorList | Raw | null;
  }
  export interface Selector extends BaseNode {
    type: "Selector";
    children: List<
      | TypeSelector
      | IdSelector
      | ClassSelector
      | AttributeSelector
      | PseudoClassSelector
      | PseudoElementSelector
      | Combinator
      | NestingSelector
    >;
  }
  export interface SelectorList extends BaseNode {
    type: "SelectorList";
    children: List<Selector | Raw>;
  }
  export interface StringNode extends BaseNode {
    type: "String";
    value: string;
  }
  export interface StyleSheet extends BaseNode {
    type: "StyleSheet";
    children: List<Comment | CDO | CDC | Atrule | Rule | Raw>;
  }
  export interface SupportsDeclaration extends BaseNode {
    type: "SupportsDeclaration";
    declaration: Declaration;
  }
  export interface TypeSelector extends BaseNode {
    type: "TypeSelector";
    name: string;
  }
  export interface UnicodeRange extends BaseNode {
    type: "UnicodeRange";
    value: string;
  }
  export interface Url extends BaseNode {
    type: "Url";
    value: string;
  }
  export interface Value extends BaseNode {
    type: "Value";
    children: List<CssNode>;
  }
  export interface WhiteSpace extends BaseNode {
    type: "WhiteSpace";
    value: string;
  }

  export type CssNode =
    | AnPlusB
    | Atrule
    | AtrulePrelude
    | AttributeSelector
    | Block
    | Brackets
    | CDC
    | CDO
    | ClassSelector
    | Combinator
    | Comment
    | Condition
    | Declaration
    | DeclarationList
    | Dimension
    | Feature
    | FeatureFunction
    | FeatureRange
    | FunctionNode
    | GeneralEnclosed
    | Hash
    | IdSelector
    | Identifier
    | Layer
    | LayerList
    | MediaQuery
    | MediaQueryList
    | NestingSelector
    | Nth
    | NumberNode
    | Operator
    | Parentheses
    | Percentage
    | PseudoClassSelector
    | PseudoElementSelector
    | Ratio
    | Raw
    | Rule
    | Scope
    | Selector
    | SelectorList
    | StringNode
    | StyleSheet
    | SupportsDeclaration
    | TypeSelector
    | UnicodeRange
    | Url
    | Value
    | WhiteSpace;

  // A plain-object form where children are arrays (for JSON, etc.)
  export type CssNodePlain = Omit<CssNode, "children" | "loc"> & {
    children?: CssNodePlain[] | null;
    loc?: SourceLocation | null;
  };

  // -------------------------------------------------
  // Parsing / Generation
  // -------------------------------------------------
  export type ParseContext =
    | "stylesheet"
    | "atrule"
    | "atrulePrelude"
    | "mediaQueryList"
    | "mediaQuery"
    | "rule"
    | "selectorList"
    | "selector"
    | "block"
    | "declarationList"
    | "declaration"
    | "value";

  export interface ParseOptions {
    context?: ParseContext;
    atrule?: string | null;
    positions?: boolean;
    onParseError?: (error: any, fallbackNode?: Raw) => void;
    onComment?: (value: string, loc: SourceLocation | null) => void;
    onToken?:
      | ((type: number, start: number, end: number, index: number) => void)
      | Array<{ type: number; start: number; end: number }>
      | null;
    filename?: string;
    offset?: number;
    line?: number;
    column?: number;
    parseAtrulePrelude?: boolean;
    parseRulePrelude?: boolean;
    parseValue?: boolean;
    parseCustomProperty?: boolean;
  }

  // Strict overloads by context
  export function parse(source: string): StyleSheet;
  export function parse(
    source: string,
    options: ParseOptions & { context?: "stylesheet" }
  ): StyleSheet;
  export function parse(
    source: string,
    options: ParseOptions & { context: "atrule" }
  ): Atrule;
  export function parse(
    source: string,
    options: ParseOptions & { context: "atrulePrelude" }
  ): AtrulePrelude;
  export function parse(
    source: string,
    options: ParseOptions & { context: "mediaQueryList" }
  ): MediaQueryList;
  export function parse(
    source: string,
    options: ParseOptions & { context: "mediaQuery" }
  ): MediaQuery;
  export function parse(
    source: string,
    options: ParseOptions & { context: "rule" }
  ): Rule;
  export function parse(
    source: string,
    options: ParseOptions & { context: "selectorList" }
  ): SelectorList;
  export function parse(
    source: string,
    options: ParseOptions & { context: "selector" }
  ): Selector;
  export function parse(
    source: string,
    options: ParseOptions & { context: "block" }
  ): Block;
  export function parse(
    source: string,
    options: ParseOptions & { context: "declarationList" }
  ): DeclarationList;
  export function parse(
    source: string,
    options: ParseOptions & { context: "declaration" }
  ): Declaration;
  export function parse(
    source: string,
    options: ParseOptions & { context: "value" }
  ): Value;
  // Fallback
  export function parse(source: string, options: ParseOptions): CssNode;

  export function generate(
    ast: CssNode,
    options: {
      sourceMap: true;
      decorator?: (node: CssNode) => any;
      mode?: "spec" | "safe";
    }
  ): { css: string; map: any };
  export function generate(
    ast: CssNode,
    options?: {
      sourceMap?: false;
      decorator?: (node: CssNode) => any;
      mode?: "spec" | "safe";
    }
  ): string;

  // -------------------------------------------------
  // Traversal helpers
  // -------------------------------------------------
  export type WalkHandler = (
    node: CssNode,
    item?: ListItem<CssNode>,
    list?: List<CssNode>
  ) => any;
  export interface WalkOptions {
    enter?: WalkHandler;
    leave?: WalkHandler;
    visit?: CssNode["type"] | null;
    reverse?: boolean;
  }
  export function walk(ast: CssNode, options: WalkOptions | WalkHandler): void;
  export function find(ast: CssNode, fn: WalkHandler): CssNode | null;
  export function findLast(ast: CssNode, fn: WalkHandler): CssNode | null;
  export function findAll(ast: CssNode, fn: WalkHandler): CssNode[];

  // -------------------------------------------------
  // Utils
  // -------------------------------------------------
  export function clone<T extends CssNode>(ast: T): T;
  export function fromPlainObject<T extends { children?: any }>(obj: T): T;
  export function toPlainObject<T extends { children?: any }>(ast: T): T;

  export interface PropertyInfo {
    basename: string;
    name: string;
    hack: string;
    vendor: string;
    prefix: string;
    custom: boolean;
  }
  export function property(name: string): PropertyInfo;

  export interface KeywordInfo {
    basename: string;
    name: string;
    vendor: string;
    prefix: string;
    custom: boolean;
  }
  export function keyword(name: string): KeywordInfo;

  export namespace ident {
    function decode(value: string): string;
    function encode(value: string): string;
  }
  export namespace string {
    function decode(value: string): string;
    function encode(value: string, preferSingleQuotes?: boolean): string;
  }
  export namespace url {
    function decode(value: string): string;
    function encode(value: string): string;
  }

  // -------------------------------------------------
  // Definition syntax (values) sub-API
  // -------------------------------------------------
  export namespace definitionSyntax {
    // AST nodes for definition syntax are intentionally minimal here
    interface Base {
      type: string;
    }
    interface Group extends Base {
      type: "Group";
      terms: Base[];
      combinator: " " | "|" | "||" | "&&";
      disallowEmpty: boolean;
      explicit: boolean;
    }
    interface Keyword extends Base {
      type: "Keyword";
      name: string;
    }
    interface Function extends Base {
      type: "Function";
      name: string;
    }
    interface String extends Base {
      type: "String";
      value: string;
    }
    interface Property extends Base {
      type: "Property";
      name: string;
    }
    interface Type extends Base {
      type: "Type";
      name: string;
      opts: Range | null;
    }
    interface Range extends Base {
      type: "Range";
      min: number | null;
      max: number | null;
    }
    interface Multiplier extends Base {
      type: "Multiplier";
      comma: boolean;
      min: number;
      max: number;
      term: Base;
    }

    type Node =
      | Group
      | Keyword
      | Function
      | String
      | Property
      | Type
      | Range
      | Multiplier
      | Base;

    function parse(source: string): Node;
    function walk(
      node: Node,
      options:
        | { enter?: (n: Node) => void; leave?: (n: Node) => void }
        | ((n: Node) => void),
      context?: any
    ): void;
    function generate(
      node: Node,
      options?: {
        forceBraces?: boolean;
        compact?: boolean;
        decorate?: (content: string, node: Node) => string;
      }
    ): string;
  }

  // -------------------------------------------------
  // Lexer
  // -------------------------------------------------
  export interface AtruleSyntaxConfig {
    prelude?: string | definitionSyntax.Node | ((ref?: any) => any) | null;
    descriptors?: Record<
      string,
      string | definitionSyntax.Node | ((ref?: any) => any)
    > | null;
  }

  export interface LexerConfig {
    generic?: boolean;
    cssWideKeywords?: string[];
    units?: Record<string, string[]>;
    types?: Record<
      string,
      string | definitionSyntax.Node | ((ref?: any) => any)
    >;
    atrules?: Record<string, AtruleSyntaxConfig>;
    properties?: Record<
      string,
      string | definitionSyntax.Node | ((ref?: any) => any)
    >;
  }

  export interface MatchResult {
    matched: any;
    error: Error | null;
    iterations: number;
    isType(node: CssNode | null | undefined, name: string): boolean;
    getTrace(
      node: CssNode | null | undefined
    ): Array<{ type: string; name: string }>;
  }

  export interface FragmentResult {
    parent: List<CssNode>;
    nodes: List<CssNode>;
  }

  export class Lexer {
    constructor(config?: LexerConfig, syntax?: any, structure?: any);

    cssWideKeywords: string[];
    units: Record<string, string[]>;

    checkStructure(
      ast: CssNode
    ): false | Array<{ node: CssNode; message: string }>;

    checkAtruleName(atruleName: string): Error | void;
    checkAtrulePrelude(
      atruleName: string,
      prelude?: string | CssNode | null
    ): Error | void;
    checkAtruleDescriptorName(
      atruleName: string,
      descriptorName: string
    ): Error | void;
    checkPropertyName(propertyName: string): Error | void;

    matchAtrulePrelude(
      atruleName: string,
      prelude?: string | CssNode | null
    ): MatchResult;
    matchAtruleDescriptor(
      atruleName: string,
      descriptorName: string,
      value: string | CssNode
    ): MatchResult;
    matchDeclaration(node: CssNode): MatchResult;
    matchProperty(propertyName: string, value: string | CssNode): MatchResult;
    matchType(typeName: string, value: string | CssNode): MatchResult;
    match(
      syntax: string | definitionSyntax.Node,
      value: string | CssNode
    ): MatchResult;

    findValueFragments(
      propertyName: string,
      value: Value,
      type: string,
      name: string
    ): FragmentResult[];
    findDeclarationValueFragments(
      declaration: Declaration,
      type: string,
      name: string
    ): FragmentResult[];
    findAllFragments(
      ast: CssNode,
      type: string,
      name: string
    ): FragmentResult[];

    // descriptor getters
    getAtrule(atruleName: string, fallbackBasename?: boolean): any | null;
    getAtrulePrelude(
      atruleName: string,
      fallbackBasename?: boolean
    ): any | null;
    getAtruleDescriptor(atruleName: string, name: string): any | null;
    getProperty(propertyName: string, fallbackBasename?: boolean): any | null;
    getType(name: string): any | null;

    validate(): null | {
      errors: string[];
      types: string[];
      properties: string[];
    };
    dump(syntaxAsAst?: boolean, pretty?: boolean): any;
    toString(): string;
  }

  export const lexer: Lexer;
  export function createLexer(config?: LexerConfig): Lexer;

  // -------------------------------------------------
  // Tokenizer / misc exports (lightly typed)
  // -------------------------------------------------
  export const tokenTypes: Record<string, number>;
  export const tokenNames: string[];
  export function tokenize(input: string): IterableIterator<any>;

  // Syntax factory and forking
  export function createSyntax(config: any): any;
  export function fork(ext?: any): any;
}

// Optional subpath module shims to enable tree-shake-style imports
declare module "css-tree/lexer" {
  export * from "css-tree";
}
declare module "css-tree/parser" {
  export type { ParseOptions, CssNode } from "css-tree";
  export { parse as default } from "css-tree";
}
declare module "css-tree/generator" {
  export { generate as default } from "css-tree";
}
declare module "css-tree/walker" {
  export {
    walk,
    find,
    findAll,
    findLast,
    WalkOptions,
    WalkHandler,
  } from "css-tree";
}
declare module "css-tree/definition-syntax" {
  export { definitionSyntax } from "css-tree";
}
declare module "css-tree/utils" {
  export {
    List,
    ListItem,
    clone,
    fromPlainObject,
    toPlainObject,
    property,
    keyword,
    ident,
    string,
    url,
  } from "css-tree";
}


================================================
FILE: @types/navigator.d.ts
================================================
interface Navigator {
  userAgentData?: {
    brands: Array<{ brand: string; version: string }>;
    getHighEntropyValues(hints: string[]): Promise<{
      fullVersionList?: Array<{ brand: string; version: string }>;
    }>;
  };
}


================================================
FILE: @types/scroll-timeline.d.ts
================================================
type ScrollAxis = "block" | "inline" | "x" | "y";

interface ScrollTimelineOptions {
  source?: Element | Document | null;
  axis?: ScrollAxis;
}

declare class ScrollTimeline extends AnimationTimeline {
  constructor(options?: ScrollTimelineOptions);
}

interface ViewTimelineOptions {
  subject?: Element | Document | null;
  axis?: ScrollAxis;
  inset?: string;
}

declare class ViewTimeline extends ScrollTimeline {
  constructor(options?: ViewTimelineOptions);
}


================================================
FILE: @types/warn-once.d.ts
================================================
declare module "warn-once" {
  export default function warnOnce(condition: boolean, message: string): void;
}


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

- The use of sexualized language or imagery, and sexual attention or
  advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
  address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
oleg@webstudio.is.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

================================================
FILE: README.md
================================================
<img width="1512" alt="builder-screenshot" src="https://github.com/webstudio-is/.github/blob/main/assets/builder-screenshot.png?raw=true">
<br /><br />

<section align="center">
  Webstudio is an Open Source Visual Development Platform for developers, designers, and cross-functional teams. You own the data, components, and infrastructure. You can use the hosted version or roll out your own.
</section>
<br /><br />

## Learning Resources

- [Blog](https://webstudio.is/blog)
- [Documentation](https://docs.webstudio.is/)
- [Brand and Product Design](https://docs.webstudio.is/contributing/contributing-for-designers)
- [Contributing Guide for Devs](https://docs.webstudio.is/contributing/contributing-for-developers)
- [Github Discussions](https://github.com/webstudio-is/webstudio-community/discussions)
- [Wishlist](https://github.com/webstudio-is/webstudio-community/discussions/categories/wishlist)
- [Builder Issues Tracker](https://github.com/webstudio-is/webstudio/issues)
- [Roadmap](https://github.com/orgs/webstudio-is/projects/11)

## Social Media

- [Twitter](https://twitter.com/getwebstudio)
- [Youtube](https://www.youtube.com/@getwebstudio)
- [Discord](https://wstd.us/community)

## Thanks

<a href="https://www.lost-pixel.com/"><img src="https://user-images.githubusercontent.com/29632358/168112844-77e76a0d-b96f-4bc8-b753-cd39f4afd428.png" width="50" height="50" alt="Lost Pixel" /></a>

Thanks to [Lost Pixel](https://www.lost-pixel.com/) for providing the visual testing platform that helps us review UI changes and catch visual regressions.

## License

- **Webstudio core** (all functionality in this repository) is free/open-source under AGPL-3.0-or-later.
- **sdk-components-animation** package (optional) is proprietary. You must accept the Webstudio, Inc. EULA located in [sdk-components-animation/LICENSE](./packages/sdk-components-animation/LICENSE) before using it.


================================================
FILE: apps/builder/.gitignore
================================================
.cache
.vercel
.output

/build/
/public/build
/api/index.js
/api/index.js.map
/api/_assets
/public/s/uploads
/public/cgi/asset



================================================
FILE: apps/builder/app/auth/index.client.ts
================================================
export * from "./login";


================================================
FILE: apps/builder/app/auth/login.stories.tsx
================================================
import type { JSX } from "react";
import type { StoryFn } from "@storybook/react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { StorySection } from "@webstudio-is/design-system";
import { Login as LoginComponent } from "./login";

export default {
  title: "Auth",
  component: LoginComponent,
};

const createRouter = (element: JSX.Element) =>
  createBrowserRouter([
    {
      path: "*",
      element,
      loader: () => null,
    },
  ]);

export const Auth: StoryFn<typeof LoginComponent> = () => {
  const router = createRouter(
    <LoginComponent isGoogleEnabled={false} isSecretLoginEnabled />
  );
  return (
    <StorySection title="Auth">
      <RouterProvider router={router} />
    </StorySection>
  );
};


================================================
FILE: apps/builder/app/auth/login.tsx
================================================
import { TooltipProvider } from "@radix-ui/react-tooltip";
import {
  Button,
  Flex,
  globalCss,
  rawTheme,
  Text,
  theme,
} from "@webstudio-is/design-system";
import { GithubIcon, GoogleIcon, WebstudioIcon } from "@webstudio-is/icons";
import { Form } from "@remix-run/react";
import { authPath } from "~/shared/router-utils";
import { SecretLogin } from "./secret-login";

const globalStyles = globalCss({
  body: {
    margin: 0,
    overflow: "hidden",
  },
});

export type LoginProps = {
  errorMessage?: string;
  isGithubEnabled?: boolean;
  isGoogleEnabled?: boolean;
  isSecretLoginEnabled?: boolean;
};

export const Login = ({
  errorMessage,
  isGithubEnabled,
  isGoogleEnabled,
  isSecretLoginEnabled,
}: LoginProps) => {
  globalStyles();
  return (
    <Flex
      align="center"
      justify="center"
      css={{
        height: "100vh",
        background: theme.colors.brandBackgroundDashboard,
      }}
    >
      <Flex
        direction="column"
        align="center"
        gap="6"
        css={{
          width: theme.spacing[35],
          minWidth: theme.spacing[20],
          padding: theme.spacing[17],
          borderRadius: theme.spacing[5],
          [`@media (min-width: ${rawTheme.spacing[35]})`]: {
            backgroundColor: `rgba(255, 255, 255, 0.5)`,
          },
        }}
      >
        <WebstudioIcon size={48} />
        <Text variant="brandSectionTitle" as="h1" align="center">
          Welcome to Webstudio
        </Text>

        <TooltipProvider>
          <Flex direction="column" gap="3" css={{ width: "100%" }}>
            <Form method="post" style={{ display: "contents" }}>
              <Button
                disabled={isGoogleEnabled === false}
                prefix={<GoogleIcon size={22} />}
                color="primary"
                css={{ height: theme.spacing[15] }}
                formAction={authPath({ provider: "google" })}
              >
                Sign in with Google
              </Button>
              <Button
                disabled={isGithubEnabled === false}
                prefix={<GithubIcon size={22} fill="currentColor" />}
                color="ghost"
                css={{
                  border: `1px solid ${theme.colors.borderDark}`,
                  height: theme.spacing[15],
                }}
                formAction={authPath({ provider: "github" })}
              >
                Sign in with GitHub
              </Button>
            </Form>
            {isSecretLoginEnabled && <SecretLogin />}
          </Flex>
        </TooltipProvider>
        {errorMessage ? (
          <Text align="center" color="destructive">
            {errorMessage}
          </Text>
        ) : null}
      </Flex>
    </Flex>
  );
};


================================================
FILE: apps/builder/app/auth/secret-login.tsx
================================================
import { Button, Flex, InputField, theme } from "@webstudio-is/design-system";
import { useState } from "react";
import { authPath } from "~/shared/router-utils";

export const SecretLogin = () => {
  const [show, setShow] = useState(false);
  if (show) {
    return (
      <form
        method="post"
        action={authPath({ provider: "dev" })}
        style={{ display: "contents" }}
      >
        <Flex gap="2">
          <InputField
            name="secret"
            type="text"
            minLength={2}
            required
            autoFocus
            placeholder="Auth secret"
            css={{ flexGrow: 1 }}
          />
          <Button type="submit">Login</Button>
        </Flex>
      </form>
    );
  }

  return (
    <Button
      onClick={() => setShow(true)}
      color="neutral"
      css={{ height: theme.spacing[15] }}
    >
      Login with Secret
    </Button>
  );
};


================================================
FILE: apps/builder/app/builder/builder.css
================================================
html {
  overflow: hidden;
}

body {
  overflow: hidden;
  overscroll-behavior: contain;
  -webkit-font-smoothing: antialiased;
  /* 
    This is the top bar and loading screen color (--colors-backgroundTopbar).
    We are setting it to avoid a white screen flash when opening project from the dashboard.
   */
  background-color: #2d2d2d;
}

[data-radix-scroll-area-viewport] {
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}

[data-radix-scroll-area-viewport]::-webkit-scrollbar {
  display: none;
}

* {
  scrollbar-width: thin;
  scrollbar-color: var(--colors-foregroundScrollBar) transparent;
}


================================================
FILE: apps/builder/app/builder/builder.tsx
================================================
import { useEffect, useMemo, useState, type JSX, type ReactNode } from "react";
import { useStore } from "@nanostores/react";
import { TooltipProvider } from "@radix-ui/react-tooltip";
import {
  theme,
  Box,
  Toaster,
  type CSS,
  Flex,
  Grid,
  rawTheme,
} from "@webstudio-is/design-system";
import type { AuthPermit } from "@webstudio-is/trpc-interface/index.server";
import { initializeClientSync, getSyncClient } from "~/shared/sync/sync-client";
import { usePreventUnload } from "~/shared/sync/project-queue";
import { usePublish, $publisher } from "~/shared/pubsub";
import { Inspector } from "./inspector";
import { Topbar } from "./shared/topbar";
import { Footer } from "./features/footer";
import {
  CanvasIframe,
  CanvasToolsContainer,
  Workspace,
} from "./features/workspace";
import {
  $authPermit,
  $authToken,
  $isPreviewMode,
  $pages,
  $project,
  subscribeResources,
  $authTokenPermissions,
  $isDesignMode,
  $isContentMode,
  $userPlanFeatures,
  subscribeModifierKeys,
  $stagingUsername,
  $stagingPassword,
} from "~/shared/nano-states";
import { $settings, type Settings } from "./shared/client-settings";
import { builderUrl, getCanvasUrl } from "~/shared/router-utils";
import { BlockingAlerts } from "./features/blocking-alerts";
import { useSyncPageUrl } from "~/shared/pages";
import { useMount, useUnmount } from "~/shared/hook-utils/use-mount";
import { subscribeCommands } from "~/builder/shared/commands";
import { ProjectSettings } from "~/shared/project-settings";
import type { UserPlanFeatures } from "~/shared/db/user-plan-features.server";
import {
  $activeSidebarPanel,
  $dataLoadingState,
  $isCloneDialogOpen,
  $loadingState,
} from "./shared/nano-states";
import { CloneProjectDialog } from "~/shared/clone-project";
import type { TokenPermissions } from "@webstudio-is/authorization-token";
import { useToastErrors } from "~/shared/error/toast-error";
import { initBuilderApi } from "~/shared/builder-api";
import { updateWebstudioData } from "~/shared/instance-utils";
import { migrateWebstudioDataMutable } from "~/shared/webstudio-data-migrator";
import { Loading, LoadingBackground } from "./shared/loading";
import { mergeRefs } from "@react-aria/utils";
import { CommandPanel } from "./features/command-panel";
import { DeleteUnusedTokensDialog } from "~/builder/shared/style-source-actions";
import { DeleteUnusedDataVariablesDialog } from "~/builder/shared/data-variable-utils";
import { DeleteUnusedCssVariablesDialog } from "~/builder/shared/css-variable-utils";
import { DeleteUnusedAssetsDialog } from "~/builder/shared/asset-manager/delete-unused-assets";
import { KeyboardShortcutsDialog } from "./features/keyboard-shortcuts-dialog";
import { TokenConflictDialog } from "~/shared/token-conflict-dialog";

import {
  initCopyPaste,
  initCopyPasteForContentEditMode,
} from "~/shared/copy-paste/init-copy-paste";
import { useInertHandlers } from "./shared/inert-handlers";
import { TextToolbar } from "./features/workspace/canvas-tools/text-toolbar";
import { RemoteDialog } from "./features/help/remote-dialog";
import type { SidebarPanelName } from "./sidebar-left/types";
import { SidebarLeft } from "./sidebar-left/sidebar-left";
import { useDisableContextMenu } from "./shared/use-disable-context-menu";

const useSetWindowTitle = () => {
  const project = useStore($project);
  useEffect(() => {
    document.title = `${project?.title} | Webstudio`;
  }, [project?.title]);
};

type SidePanelProps = {
  children: JSX.Element | Array<JSX.Element>;
  isPreviewMode?: boolean;
  css?: CSS;
  gridArea: "inspector" | "sidebar" | "navigator";
};

const SidePanel = ({
  children,
  isPreviewMode = false,
  gridArea,
  css,
}: SidePanelProps) => {
  return (
    <Box
      as="aside"
      css={{
        position: "relative",
        isolation: "isolate",
        gridArea,
        display: isPreviewMode ? "none" : "flex",
        flexDirection: "column",
        px: 0,
        fg: 0,
        // Left sidebar tabs won't be able to pop out to the right if we set overflowX to auto.
        //overflowY: "auto",
        backgroundColor: theme.colors.backgroundPanel,
        height: "100%",
        ...css,
      }}
    >
      {children}
    </Box>
  );
};

const Main = ({ children, css }: { children: ReactNode; css?: CSS }) => (
  <Flex
    as="main"
    direction="column"
    css={{
      gridArea: "main",
      position: "relative",
      isolation: "isolate",
      ...css,
    }}
  >
    {children}
  </Flex>
);

type ChromeWrapperProps = {
  children: Array<JSX.Element | null | false>;
  isPreviewMode: boolean;
  navigatorLayout: Settings["navigatorLayout"];
};

const getChromeLayout = ({
  isPreviewMode,
  navigatorLayout,
  activeSidebarPanel,
  leftSidebarWidth,
}: {
  isPreviewMode: boolean;
  navigatorLayout: Settings["navigatorLayout"];
  activeSidebarPanel?: SidebarPanelName;
  leftSidebarWidth: number;
}) => {
  if (isPreviewMode) {
    return {
      gridTemplateColumns: "auto 1fr",
      gridTemplateAreas: `
            "header header"
            "sidebar main"
            "footer footer"
          `,
    };
  }

  if (navigatorLayout === "undocked" && activeSidebarPanel !== "none") {
    return {
      gridTemplateColumns: `auto ${leftSidebarWidth}px 1fr ${theme.sizes.sidebarWidth}`,
      gridTemplateAreas: `
            "header header header header"
            "sidebar navigator main inspector"
            "footer footer footer footer"
          `,
    };
  }

  return {
    gridTemplateColumns: `auto 1fr ${theme.sizes.sidebarWidth}`,
    gridTemplateAreas: `
          "header header header"
          "sidebar main inspector"
          "footer footer footer"
        `,
  };
};

const defaultSidebarWidth = Number.parseFloat(rawTheme.spacing[30]);

const ChromeWrapper = ({
  children,
  isPreviewMode,
  navigatorLayout,
}: ChromeWrapperProps) => {
  const activeSidebarPanel = useStore($activeSidebarPanel);
  const settings = useStore($settings);
  const leftSidebarWidth =
    activeSidebarPanel === "none"
      ? defaultSidebarWidth
      : (settings.sidebarPanelWidths[activeSidebarPanel] ??
        defaultSidebarWidth);

  const gridLayout = getChromeLayout({
    isPreviewMode,
    navigatorLayout,
    activeSidebarPanel,
    leftSidebarWidth,
  });

  return (
    <Grid
      css={{
        height: "100vh",
        overflow: "hidden",
        display: "grid",
        gridTemplateRows: "auto 1fr auto",
        ...gridLayout,
      }}
    >
      {children}
    </Grid>
  );
};

export type BuilderProps = {
  projectId: string;
  authToken?: string;
  authPermit: AuthPermit;
  authTokenPermissions: TokenPermissions;
  userPlanFeatures: UserPlanFeatures;
  stagingUsername: string;
  stagingPassword: string;
};

export const Builder = ({
  projectId,
  authToken,
  authPermit,
  userPlanFeatures,
  authTokenPermissions,
  stagingUsername,
  stagingPassword,
}: BuilderProps) => {
  useMount(initBuilderApi);

  useMount(() => {
    // additional data stores
    $authPermit.set(authPermit);
    $authToken.set(authToken);
    $userPlanFeatures.set(userPlanFeatures);
    $authTokenPermissions.set(authTokenPermissions);
    $stagingUsername.set(stagingUsername);
    $stagingPassword.set(stagingPassword);

    const controller = new AbortController();

    $dataLoadingState.set("loading");
    initializeClientSync({
      projectId,
      authPermit,
      authToken,
      signal: controller.signal,
      onReady() {
        updateWebstudioData((data) => {
          migrateWebstudioDataMutable(data);
        });

        // render canvas only after all data is loaded
        // so builder is started listening for connect event
        // when canvas is rendered
        $dataLoadingState.set("loaded");

        // @todo make needs error handling and error state? e.g. a toast
      },
    });

    return () => {
      $dataLoadingState.set("idle");
      controller.abort("unmount");
    };
  });

  useToastErrors();
  useEffect(subscribeCommands, []);
  useEffect(subscribeResources, []);
  useDisableContextMenu();

  useUnmount(() => {
    $pages.set(undefined);
  });

  useSyncPageUrl();

  const [publish, publishRef] = usePublish();
  useEffect(() => {
    $publisher.set({ publish });
  }, [publish]);

  const project = useStore($project);

  usePreventUnload();
  const isCloneDialogOpen = useStore($isCloneDialogOpen);
  const isPreviewMode = useStore($isPreviewMode);
  const isDesignMode = useStore($isDesignMode);
  const isContentMode = useStore($isContentMode);

  useSetWindowTitle();

  const iframeRefCallback = useMemo(
    () =>
      mergeRefs((element: HTMLIFrameElement | null) => {
        if (element?.contentWindow) {
          const client = getSyncClient();
          if (client) {
            // added to iframe window and stored in local variable right away to prevent
            // overriding in emebedded scripts on canvas
            element.contentWindow.__webstudioSharedSyncEmitter__ =
              client.emitter;
          }
        }
      }, publishRef),
    [publishRef]
  );

  const { navigatorLayout } = useStore($settings);
  const dataLoadingState = useStore($dataLoadingState);
  const [loadingState, setLoadingState] = useState(() => $loadingState.get());

  useEffect(() => {
    const abortController = new AbortController();

    if (isDesignMode) {
      // We need to initialize this in both canvas and builder,
      // because the events will fire in either one, depending on where the focus is
      // @todo we need to forward the events from canvas to builder and avoid importing this
      // in both places
      initCopyPaste(abortController);
      subscribeModifierKeys({ signal: abortController.signal });
    }

    if (isContentMode) {
      initCopyPasteForContentEditMode(abortController);
      subscribeModifierKeys({ signal: abortController.signal });
    }

    return () => {
      abortController.abort();
    };
  }, [isContentMode, isDesignMode]);

  useEffect(() => {
    const unsubscribe = $loadingState.subscribe((loadingState) => {
      setLoadingState(loadingState);
      // We need to stop updating it once it's ready in case in the future it changes again.
      if (loadingState.state === "ready") {
        unsubscribe();
      }
    });
    return unsubscribe;
  }, []);

  const canvasUrl = getCanvasUrl();

  const inertHandlers = useInertHandlers();

  // Show loading screen if project isn't ready yet
  if (!project || dataLoadingState !== "loaded") {
    return (
      <TooltipProvider>
        <Loading state={loadingState} />
      </TooltipProvider>
    );
  }

  return (
    <TooltipProvider>
      <div
        style={{ display: "contents" }}
        onPointerDown={inertHandlers.onPointerDown}
        onInput={inertHandlers.onInput}
        onKeyDown={inertHandlers.onKeyDown}
      >
        <ChromeWrapper
          isPreviewMode={isPreviewMode}
          navigatorLayout={navigatorLayout}
        >
          <Box
            data-dialog-boundary
            css={{
              gridArea: "sidebar / sidebar / main / inspector",
              pointerEvents: "none",
            }}
          />
          <ProjectSettings />

          {/* Main must be after left sidebar panels because in content mode the Plus button must be above the left sidebar, otherwise it won't be visible when content is full width */}
          <Main>
            <Workspace>
              {dataLoadingState === "loaded" && project && (
                <CanvasIframe
                  ref={iframeRefCallback}
                  src={canvasUrl}
                  title={project.title}
                />
              )}
            </Workspace>
          </Main>
          <Main css={{ pointerEvents: "none" }}>
            <CanvasToolsContainer />
          </Main>
          <SidePanel
            gridArea="sidebar"
            css={{
              order: navigatorLayout === "docked" ? 1 : undefined,
            }}
          >
            <SidebarLeft publish={publish} />
          </SidePanel>

          <SidePanel
            gridArea="inspector"
            isPreviewMode={isPreviewMode}
            css={{
              overflow: "hidden",
              // Drawing border this way to ensure content still has full width, avoid subpixels and give layout round numbers
              "&::after": {
                content: "''",
                position: "absolute",
                top: 0,
                left: 0,
                bottom: 0,
                width: 1,
                background: theme.colors.borderMain,
              },
            }}
          >
            <Inspector navigatorLayout={navigatorLayout} />
          </SidePanel>
          <Main css={{ pointerEvents: "none" }}>
            <CanvasToolsContainer />
          </Main>
          {project ? (
            <Topbar
              project={project}
              css={{ gridArea: "header" }}
              loading={
                <LoadingBackground
                  // Looks nicer when topbar is already visible earlier, so user has more sense of progress.
                  show={
                    loadingState.readyStates.get("dataLoadingState")
                      ? false
                      : true
                  }
                />
              }
            />
          ) : null}
          <Main css={{ pointerEvents: "none" }}>
            <TextToolbar />
          </Main>
          {isPreviewMode === false && <Footer />}
          {project ? (
            <CloneProjectDialog
              isOpen={isCloneDialogOpen}
              onOpenChange={$isCloneDialogOpen.set}
              project={project}
              onCreate={(projectId) => {
                window.location.href = builderUrl({
                  origin: window.origin,
                  projectId: projectId,
                });
              }}
            />
          ) : null}
        </ChromeWrapper>
        <Loading state={loadingState} />
        <BlockingAlerts />
        <CommandPanel />
        <DeleteUnusedTokensDialog />
        <DeleteUnusedDataVariablesDialog />
        <DeleteUnusedCssVariablesDialog />
        <DeleteUnusedAssetsDialog />
        <KeyboardShortcutsDialog />
        <TokenConflictDialog />
        <RemoteDialog />
        <Toaster />
      </div>
    </TooltipProvider>
  );
};


================================================
FILE: apps/builder/app/builder/features/address-bar.stories.tsx
================================================
import { useStore } from "@nanostores/react";
import type { Meta, StoryFn } from "@storybook/react";
import { StorySection, Text } from "@webstudio-is/design-system";
import { ToolbarButton } from "@webstudio-is/design-system";
import { WebstudioIcon } from "@webstudio-is/icons";
import { TopbarLayout } from "~/builder/shared/topbar-layout";
import { AddressBarPopover } from "./address-bar";
import { $dataSources, $pages } from "~/shared/sync/data-stores";
import { registerContainers } from "~/shared/sync/sync-stores";
import { $awareness, $selectedPage } from "~/shared/awareness";
import { $currentSystem } from "~/shared/system";

registerContainers();

$dataSources.set(new Map());

$pages.set({
  folders: [
    {
      id: "rootId",
      name: "",
      slug: "",
      children: ["homeId", "dynamicId"],
    },
  ],
  homePage: {
    id: "homeId",
    path: "",
    name: "",
    title: "",
    meta: {},
    rootInstanceId: "",
  },
  pages: [
    {
      id: "dynamicId",
      path: "/blog/:date/post/:slug",
      name: "",
      title: "",
      meta: {},
      rootInstanceId: "rootInstanceId",
    },
  ],
});

const SystemInspect = () => {
  const system = useStore($currentSystem);
  return (
    <Text variant="mono" css={{ whiteSpace: "pre" }}>
      {JSON.stringify(system, null, 2)}
    </Text>
  );
};

const HistoryInspect = () => {
  const page = useStore($selectedPage);
  return (
    <Text variant="mono" css={{ whiteSpace: "pre" }}>
      {JSON.stringify(page?.history, null, 2)}
    </Text>
  );
};

export default {
  title: "Address Bar",
  component: AddressBarPopover,
} satisfies Meta;

export const AddressBar: StoryFn = () => {
  $awareness.set({ pageId: "dynamicId" });
  return (
    <StorySection title="Address Bar">
      <TopbarLayout
        menu={
          <ToolbarButton aria-label="Menu">
            <WebstudioIcon size={22} />
          </ToolbarButton>
        }
        left={<AddressBarPopover />}
      />
      <SystemInspect />
      <HistoryInspect />
    </StorySection>
  );
};


================================================
FILE: apps/builder/app/builder/features/address-bar.tsx
================================================
import { computed } from "nanostores";
import { useStore } from "@nanostores/react";
import { mergeRefs } from "@react-aria/utils";
import {
  forwardRef,
  useEffect,
  useMemo,
  useRef,
  useState,
  type ComponentProps,
  type RefObject,
} from "react";
import { flushSync } from "react-dom";
import {
  Flex,
  InputField,
  Tooltip,
  theme,
  textVariants,
  InputErrorsTooltip,
  ToolbarButton,
  Popover,
  PopoverTrigger,
  PopoverContent,
  IconButton,
  MenuItemButton,
  MenuList,
} from "@webstudio-is/design-system";
import { CheckMarkIcon, CopyIcon, DynamicPageIcon } from "@webstudio-is/icons";
import { $publishedOrigin } from "~/shared/nano-states";
import {
  compilePathnamePattern,
  isPathnamePattern,
  matchPathnamePattern,
  tokenizePathnamePattern,
} from "~/builder/shared/url-pattern";
import { $selectedPage, $selectedPagePath } from "~/shared/awareness";
import { $currentSystem, updateCurrentSystem } from "~/shared/system";

const $selectedPageHistory = computed(
  $selectedPage,
  (page) => page?.history ?? []
);

const useCopyUrl = (pageUrl: string) => {
  const [copyState, setCopyState] = useState<"copy" | "copied">("copy");
  // reset copied state after 2 seconds
  useEffect(() => {
    if (copyState === "copied") {
      const timeoutId = setTimeout(() => {
        setCopyState("copy");
      }, 2000);
      return () => {
        clearTimeout(timeoutId);
      };
    }
  }, [copyState]);
  let copyIcon = <CopyIcon />;
  if (copyState === "copied") {
    copyIcon = <CheckMarkIcon />;
  }
  const onClick = () => {
    navigator.clipboard.writeText(pageUrl);
    setCopyState("copied");
  };
  return {
    tooltipProps: {
      // keep tooltip open when user just copied
      open: copyState === "copied" ? true : undefined,
      content: copyState === "copied" ? "Copied" : `Copy ${pageUrl}`,
    } satisfies Partial<ComponentProps<typeof Tooltip>>,
    buttonProps: {
      onClick,
      children: copyIcon,
    } satisfies Partial<ComponentProps<"button">>,
  };
};

const moveSelection = (menu: HTMLElement, diff: number) => {
  const options = Array.from(menu.querySelectorAll("[role=option]"));
  const index = options.findIndex((element) => element.ariaSelected === "true");
  const newIndex = Math.max(-1, Math.min(index + diff, options.length - 1));
  if (index >= 0) {
    options[index].ariaSelected = null;
  }
  if (newIndex >= 0) {
    options[newIndex].ariaSelected = "true";
  }
};

/**
 * Suggestions are opened whenever user
 * - types in input
 * - focuses input
 * - press arrow down or arrow up
 *
 * and closed when
 * - input is lost focus
 * - escape or enter are pressed
 *
 * option selection is managed by arrow up, arrow down and hover
 */
const Suggestions = ({
  containerRef,
  options,
  onSelect,
}: {
  containerRef: RefObject<null | HTMLFormElement>;
  options: string[];
  onSelect: (option: string) => void;
}) => {
  const list = options;

  const menuRef = useRef<HTMLDivElement>(null);
  const [isListOpen, setIsListOpen] = useState(false);

  useEffect(() => {
    const container = containerRef.current;
    if (container === null) {
      return;
    }
    const handleInput = () => {
      setIsListOpen(true);
    };
    let frameId: undefined | number;
    const handleFocusIn = () => {
      if (frameId) {
        cancelAnimationFrame(frameId);
      }
      setIsListOpen(true);
    };
    const handleFocusOut = () => {
      frameId = requestAnimationFrame(() => {
        setIsListOpen(false);
      });
    };
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "ArrowDown") {
        // avoid moving cursor to the end
        event.preventDefault();
        // trigger menu with up and down like in chrome
        if (menuRef.current === null) {
          setIsListOpen(true);
          return;
        }
        moveSelection(menuRef.current, +1);
      }
      if (event.key === "ArrowUp") {
        // avoid moving cursor to the start
        event.preventDefault();
        if (menuRef.current === null) {
          setIsListOpen(true);
          return;
        }
        moveSelection(menuRef.current, -1);
      }
      if (event.key === "Escape" && menuRef.current) {
        // avoid closing popovers and dialogs when list is open
        event.stopPropagation();
        setIsListOpen(false);
      }
      if (event.key === "Enter" && menuRef.current) {
        const selected = menuRef.current?.querySelector(
          "[role=option][aria-selected=true]"
        );
        if (selected instanceof HTMLElement) {
          // avoid submitting form when item is selected
          event.preventDefault();
          selected.click();
        }
      }
    };
    container.addEventListener("input", handleInput);
    container.addEventListener("focusin", handleFocusIn);
    container.addEventListener("focusout", handleFocusOut);
    container.addEventListener("keydown", handleKeyDown);
    return () => {
      container.removeEventListener("input", handleInput);
      container.removeEventListener("focusin", handleFocusIn);
      container.removeEventListener("focusout", handleFocusOut);
      container.removeEventListener("keydown", handleKeyDown);
    };
  }, [containerRef]);

  if (isListOpen === false || list.length === 0) {
    return;
  }
  return (
    <MenuList
      ref={menuRef}
      role="listbox"
      css={{
        position: "absolute",
        left: 0,
        top: "calc(100% + 4px)",
        minWidth: "100%",
      }}
      // close after selecting option
      onClick={() => setIsListOpen(false)}
    >
      {list.map((option) => (
        <MenuItemButton
          key={option}
          type="button"
          role="option"
          tabIndex={-1}
          css={{ textTransform: "none", whiteSpace: "nowrap" }}
          onMouseEnter={(event) => {
            // select option on hover
            const options =
              menuRef.current?.querySelectorAll("[role=option]") ?? [];
            for (const element of options) {
              if (element.ariaSelected === "true") {
                element.ariaSelected = null;
              }
              if (element === event.currentTarget) {
                element.ariaSelected = "true";
              }
            }
          }}
          onClick={() => onSelect(option)}
        >
          {option}
        </MenuItemButton>
      ))}
    </MenuList>
  );
};

const AddressBar = forwardRef<
  HTMLFormElement,
  {
    onSubmit: () => void;
  }
>(({ onSubmit }, ref) => {
  const publishedOrigin = useStore($publishedOrigin);
  const path = useStore($selectedPagePath);
  let history = useStore($selectedPageHistory);
  history = useMemo(() => {
    return history.filter((item) => matchPathnamePattern(path, item));
  }, [history, path]);
  const [pathParams, setPathParams] = useState(
    () => $currentSystem.get().params
  );
  const tokens = tokenizePathnamePattern(path);
  const compiledPath = compilePathnamePattern(tokens, pathParams);
  const { tooltipProps, buttonProps } = useCopyUrl(
    `${publishedOrigin}${compiledPath}`
  );

  const errors = new Map<string, string>();
  for (const token of tokens) {
    if (token.type === "param") {
      const value = (pathParams[token.name] ?? "").trim();
      if (value === "" && token.optional === false) {
        errors.set(token.name, `"${token.name}" is required`);
      }
      if (value.includes("/") && token.splat === false) {
        errors.set(
          token.name,
          `"${token.name}" should be splat parameter to contain slashes`
        );
      }
    }
  }

  const containerRef = useRef<HTMLFormElement>(null);

  return (
    <form
      ref={mergeRefs(ref, containerRef)}
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        const params = Object.fromEntries(formData) as Record<string, string>;
        updateCurrentSystem({ params });
        if (errors.size === 0) {
          onSubmit();
        }
      }}
    >
      {/* submit is not triggered when press enter on input without submit button */}
      <button style={{ display: "none" }}>submit</button>
      <Suggestions
        containerRef={containerRef}
        options={history}
        onSelect={(option) => {
          flushSync(() => {
            setPathParams(matchPathnamePattern(path, option) ?? {});
          });
          containerRef.current?.requestSubmit();
        }}
      />
      <InputErrorsTooltip errors={Array.from(errors.values())}>
        <Flex gap={1} css={{ padding: theme.spacing[5] }}>
          <Flex align="center" gap={1} css={textVariants.mono}>
            {tokens.map((token, index) => {
              if (token.type === "fragment") {
                return token.value;
              }
              if (token.type === "param") {
                return (
                  <InputField
                    key={index}
                    name={token.name}
                    fieldSizing="content"
                    autoComplete="off"
                    css={{ minWidth: theme.spacing[15] }}
                    color={errors.has(token.name) ? "error" : undefined}
                    placeholder={token.name}
                    value={pathParams[token.name] ?? ""}
                    onChange={(event) =>
                      setPathParams((prevPathParams) => ({
                        ...prevPathParams,
                        [token.name]: event.target.value,
                      }))
                    }
                  />
                );
              }
              token satisfies never;
            })}
          </Flex>

          <Tooltip {...tooltipProps}>
            <IconButton
              {...buttonProps}
              disabled={errors.size > 0}
              type="button"
            />
          </Tooltip>
        </Flex>
      </InputErrorsTooltip>
    </form>
  );
});

export const AddressBarPopover = () => {
  const [isOpen, setIsOpen] = useState(false);
  const path = useStore($selectedPagePath);
  const publishedOrigin = useStore($publishedOrigin);
  const { tooltipProps, buttonProps } = useCopyUrl(`${publishedOrigin}${path}`);
  const formRef = useRef<HTMLFormElement>(null);

  // show only copy button when path is static
  if (isPathnamePattern(path) === false) {
    return (
      <Tooltip {...tooltipProps}>
        <ToolbarButton
          {...buttonProps}
          aria-label="Copy page URL"
          tabIndex={0}
        />
      </Tooltip>
    );
  }

  return (
    <Popover
      open={isOpen}
      onOpenChange={(newIsOpen) => {
        formRef.current?.requestSubmit();
        setIsOpen(newIsOpen);
      }}
    >
      <PopoverTrigger asChild>
        <ToolbarButton aria-label="Toggle dynamic page address" tabIndex={0}>
          <DynamicPageIcon />
        </ToolbarButton>
      </PopoverTrigger>
      <PopoverContent sideOffset={0} collisionPadding={4} align="start">
        <AddressBar ref={formRef} onSubmit={() => setIsOpen(false)} />
      </PopoverContent>
    </Popover>
  );
};


================================================
FILE: apps/builder/app/builder/features/assets/assets.tsx
================================================
import {
  IconButton,
  PanelTitle,
  Separator,
  Tooltip,
} from "@webstudio-is/design-system";
import { BrushCleaningIcon } from "@webstudio-is/icons";
import { AssetManager } from "~/builder/shared/asset-manager";
import { AssetUpload } from "~/builder/shared/assets";
import { openDeleteUnusedAssetsDialog } from "~/builder/shared/asset-manager/delete-unused-assets";

export const AssetsPanel = (_props: { onClose: () => void }) => {
  return (
    <>
      <PanelTitle
        suffix={
          <>
            <Tooltip content="Delete unused assets">
              <IconButton onClick={openDeleteUnusedAssetsDialog}>
                <BrushCleaningIcon />
              </IconButton>
            </Tooltip>
            <AssetUpload type="file" />
          </>
        }
      >
        Assets
      </PanelTitle>
      <Separator />
      <AssetManager />
    </>
  );
};


================================================
FILE: apps/builder/app/builder/features/assets/index.ts
================================================
export * from "./assets";


================================================
FILE: apps/builder/app/builder/features/blocking-alerts/alert.stories.tsx
================================================
import { StorySection } from "@webstudio-is/design-system";
import { Alert } from "./alert";

export default { title: "Blocking Alerts", component: Alert };

export const BlockingAlerts = () => (
  <StorySection title="Blocking Alerts">
    <Alert
      message={
        "Your browser window is too small. Resize your browser to at least 900px wide to continue building with Webstudio."
      }
    />
  </StorySection>
);


================================================
FILE: apps/builder/app/builder/features/blocking-alerts/alert.tsx
================================================
import { atom } from "nanostores";
import { useStore } from "@nanostores/react";
import type { ReactNode } from "react";
import {
  Button,
  css,
  Flex,
  Popover,
  PopoverContent,
  Text,
  theme,
} from "@webstudio-is/design-system";
import { AlertIcon } from "@webstudio-is/icons";

const containerStyle = css({
  position: "absolute",
  top: theme.spacing[15],
  left: 0,
  width: "100vw",
  height: "100vh",
  background: "rgba(0, 0, 0, 0.9)",
});

const contentStyle = css({
  width: theme.spacing[33],
  color: theme.colors.foregroundDestructive,
});

const $isAlertDismissed = atom(false);

export const Alert = ({
  message,
  isDismissable,
}: {
  message: string | ReactNode;
  isDismissable?: boolean;
}) => {
  const isAlertDismissed = useStore($isAlertDismissed);
  if (isAlertDismissed) {
    return;
  }
  return (
    <Popover open>
      <PopoverContent css={{ zIndex: theme.zIndices.max }}>
        <Flex align="center" justify="center" className={containerStyle()}>
          <Flex
            direction="column"
            align="center"
            gap="2"
            className={contentStyle()}
          >
            <AlertIcon size={22} />
            <Text color="contrast" align="center">
              {message}
            </Text>
            {isDismissable && (
              <Button
                color="destructive"
                onClick={() => $isAlertDismissed.set(true)}
              >
                Dismiss
              </Button>
            )}
          </Flex>
        </Flex>
      </PopoverContent>
    </Popover>
  );
};


================================================
FILE: apps/builder/app/builder/features/blocking-alerts/blocking-alerts.tsx
================================================
import { useEffect, useState, type ReactNode } from "react";
import { Alert } from "./alert";
import { useWindowResizeDebounced } from "~/shared/dom-hooks";
import { isFeatureEnabled } from "@webstudio-is/feature-flags";
import { Link } from "@webstudio-is/design-system";
import { $isPreviewMode } from "~/shared/nano-states";
import { useStore } from "@nanostores/react";
import { $loadingState } from "~/builder/shared/nano-states";

const useTooSmallMessage = () => {
  const [message, setMessage] = useState<string>();
  const check = () => {
    // To have more space for Chrome DevTools, we allow a smaller window size in development
    const minWidth = process.env.NODE_ENV === "production" ? 900 : 700;
    const message =
      window.innerWidth >= minWidth
        ? undefined
        : `Your browser window is too small. Resize your browser to at least ${minWidth}px wide to continue building with Webstudio.`;
    setMessage(message);
  };

  useWindowResizeDebounced(check);
  useEffect(check, []);
  return message;
};

const useUnsupportedBrowser = () => {
  const [message, setMessage] = useState<ReactNode>();
  useEffect(() => {
    if ("chrome" in window || isFeatureEnabled("unsupportedBrowsers")) {
      return;
    }

    setMessage(
      <>
        The Webstudio Builder UI currently supports any{" "}
        <Link
          href="https://en.wikipedia.org/wiki/Chromium_(web_browser)"
          target="_blank"
          color="inherit"
          variant="inherit"
        >
          Chromium-based
        </Link>{" "}
        browsers such as{" "}
        <Link
          href="https://www.google.com/chrome"
          target="_blank"
          color="inherit"
          variant="inherit"
        >
          Google Chrome
        </Link>
        ,{" "}
        <Link
          href="https://www.microsoft.com/en-us/edge"
          target="_blank"
          color="inherit"
          variant="inherit"
        >
          Microsoft Edge
        </Link>
        ,{" "}
        <Link
          href="https://brave.com/"
          target="_blank"
          color="inherit"
          variant="inherit"
        >
          Brave
        </Link>
        ,{" "}
        <Link
          href="https://arc.net/"
          target="_blank"
          color="inherit"
          variant="inherit"
        >
          Arc
        </Link>{" "}
        and many more. We plan to support Firefox and Safari in the near future.
        <br />
        <br />
        The website you&apos;re building should function correctly across all
        browsers!
      </>
    );
  }, []);
  return message;
};

export const BlockingAlerts = () => {
  const isPreviewMode = useStore($isPreviewMode);
  const loadingState = useStore($loadingState);

  const unsupportedBrowsersMessage = useUnsupportedBrowser();
  // Takes the latest message, order matters
  const message = [useTooSmallMessage(), unsupportedBrowsersMessage]
    .filter(Boolean)
    .pop();

  if (
    message =
Download .txt
gitextract_3aga18g3/

├── .devcontainer/
│   ├── .gitignore
│   ├── Dockerfile
│   ├── devcontainer.json
│   ├── docker-compose.yml
│   ├── library-scripts/
│   │   └── docker-in-docker-debian.sh
│   └── postinstall.sh
├── .editorconfig
├── .github/
│   ├── actions/
│   │   ├── add-status/
│   │   │   └── action.yaml
│   │   ├── ci-setup/
│   │   │   └── action.yml
│   │   ├── submodules-checkout/
│   │   │   └── action.yml
│   │   └── vercel/
│   │       └── action.yaml
│   ├── dependabot.yml
│   ├── pull_request_template.md
│   └── workflows/
│       ├── build-figma-tokens.yml
│       ├── check-submodules.yml
│       ├── chromatic.yml
│       ├── cli-r2-static.yaml
│       ├── cli-r2.yaml
│       ├── delete-github-deployments.yml
│       ├── fixtures-test.yml
│       ├── lint-pull-request.yaml
│       ├── main.yml
│       ├── migrate.yaml
│       ├── publish-beta.yml
│       ├── re-create-figma-tokens-branch.yml
│       ├── release.yml
│       ├── vercel-deploy-staging.yml
│       └── vis-reg-tests.yml
├── .gitignore
├── .gitmodules
├── .nvmrc
├── .oxlintrc.json
├── .prettierignore
├── .storybook/
│   ├── main.ts
│   ├── preview-body.html
│   └── preview.tsx
├── .vscode/
│   ├── extensions.json
│   └── settings.json
├── @types/
│   ├── canvas-iframe.d.ts
│   ├── content.d.ts
│   ├── css-tree.d.ts
│   ├── navigator.d.ts
│   ├── scroll-timeline.d.ts
│   └── warn-once.d.ts
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── apps/
│   └── builder/
│       ├── .gitignore
│       ├── app/
│       │   ├── auth/
│       │   │   ├── index.client.ts
│       │   │   ├── login.stories.tsx
│       │   │   ├── login.tsx
│       │   │   └── secret-login.tsx
│       │   ├── builder/
│       │   │   ├── builder.css
│       │   │   ├── builder.tsx
│       │   │   ├── features/
│       │   │   │   ├── address-bar.stories.tsx
│       │   │   │   ├── address-bar.tsx
│       │   │   │   ├── assets/
│       │   │   │   │   ├── assets.tsx
│       │   │   │   │   └── index.ts
│       │   │   │   ├── blocking-alerts/
│       │   │   │   │   ├── alert.stories.tsx
│       │   │   │   │   ├── alert.tsx
│       │   │   │   │   ├── blocking-alerts.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   ├── breakpoints/
│       │   │   │   │   ├── breakpoint-editor-utils.test.ts
│       │   │   │   │   ├── breakpoint-editor-utils.ts
│       │   │   │   │   ├── breakpoints-container.tsx
│       │   │   │   │   ├── breakpoints-editor.tsx
│       │   │   │   │   ├── breakpoints-menu.tsx
│       │   │   │   │   ├── breakpoints-selector.stories.tsx
│       │   │   │   │   ├── breakpoints-selector.tsx
│       │   │   │   │   ├── canvas-settings-popover.tsx
│       │   │   │   │   ├── cascade-indicator.tsx
│       │   │   │   │   ├── condition-input.tsx
│       │   │   │   │   ├── confirmation-dialog.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── width-input.tsx
│       │   │   │   ├── builder-mode.stories.tsx
│       │   │   │   ├── builder-mode.tsx
│       │   │   │   ├── clone.tsx
│       │   │   │   ├── command-panel/
│       │   │   │   │   ├── command-panel.stories.tsx
│       │   │   │   │   ├── command-panel.tsx
│       │   │   │   │   ├── command-state.ts
│       │   │   │   │   ├── groups/
│       │   │   │   │   │   ├── breakpoints-group.tsx
│       │   │   │   │   │   ├── commands-group.tsx
│       │   │   │   │   │   ├── components-group.tsx
│       │   │   │   │   │   ├── convert-group.tsx
│       │   │   │   │   │   ├── css-variables-group.tsx
│       │   │   │   │   │   ├── data-variables-group.tsx
│       │   │   │   │   │   ├── duplicate-tokens-group.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── instances-group.tsx
│       │   │   │   │   │   ├── pages-group.tsx
│       │   │   │   │   │   ├── tags-group.tsx
│       │   │   │   │   │   ├── tokens-group.tsx
│       │   │   │   │   │   ├── wrap-group.test.tsx
│       │   │   │   │   │   └── wrap-group.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── shared/
│       │   │   │   │       ├── auto-select.ts
│       │   │   │   │       ├── component-utils.ts
│       │   │   │   │       ├── instance-list.tsx
│       │   │   │   │       ├── instance-path-footer.tsx
│       │   │   │   │       ├── types.ts
│       │   │   │   │       └── usage-utils.ts
│       │   │   │   ├── components/
│       │   │   │   │   ├── components.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── use-draggable.tsx
│       │   │   │   ├── footer/
│       │   │   │   │   ├── breadcrumbs.tsx
│       │   │   │   │   ├── footer.tsx
│       │   │   │   │   └── index.ts
│       │   │   │   ├── help/
│       │   │   │   │   ├── help-center.stories.tsx
│       │   │   │   │   ├── help-center.tsx
│       │   │   │   │   ├── remote-dialog.stories.tsx
│       │   │   │   │   └── remote-dialog.tsx
│       │   │   │   ├── keyboard-shortcuts-dialog/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── keyboard-shortcuts-dialog.stories.tsx
│       │   │   │   │   └── keyboard-shortcuts-dialog.tsx
│       │   │   │   ├── marketplace/
│       │   │   │   │   ├── about.stories.tsx
│       │   │   │   │   ├── about.tsx
│       │   │   │   │   ├── card.stories.tsx
│       │   │   │   │   ├── card.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── marketplace.tsx
│       │   │   │   │   ├── overview.tsx
│       │   │   │   │   ├── templates.tsx
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── menu/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── menu-button.tsx
│       │   │   │   │   ├── menu.stories.tsx
│       │   │   │   │   └── menu.tsx
│       │   │   │   ├── navigator/
│       │   │   │   │   ├── css-preview.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── navigator-tree.tsx
│       │   │   │   │   └── navigator.tsx
│       │   │   │   ├── pages/
│       │   │   │   │   ├── confirmation-dialogs.stories.tsx
│       │   │   │   │   ├── confirmation-dialogs.tsx
│       │   │   │   │   ├── custom-metadata.stories.tsx
│       │   │   │   │   ├── custom-metadata.tsx
│       │   │   │   │   ├── folder-settings.tsx
│       │   │   │   │   ├── form.stories.tsx
│       │   │   │   │   ├── form.tsx
│       │   │   │   │   ├── image-info.stories.tsx
│       │   │   │   │   ├── image-info.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── page-context-menu.tsx
│       │   │   │   │   ├── page-settings.stories.tsx
│       │   │   │   │   ├── page-settings.tsx
│       │   │   │   │   ├── page-utils.test.ts
│       │   │   │   │   ├── page-utils.ts
│       │   │   │   │   ├── pages.tsx
│       │   │   │   │   ├── search-preview.stories.tsx
│       │   │   │   │   ├── search-preview.tsx
│       │   │   │   │   ├── social-preview.stories.tsx
│       │   │   │   │   ├── social-preview.tsx
│       │   │   │   │   ├── social-utils.test.ts
│       │   │   │   │   └── social-utils.ts
│       │   │   │   ├── publish/
│       │   │   │   │   ├── add-domain.tsx
│       │   │   │   │   ├── cname.test.ts
│       │   │   │   │   ├── cname.ts
│       │   │   │   │   ├── collapsible-domain-section.stories.tsx
│       │   │   │   │   ├── collapsible-domain-section.tsx
│       │   │   │   │   ├── domain-checkbox.tsx
│       │   │   │   │   ├── domains.tsx
│       │   │   │   │   ├── entri.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── publish.tsx
│       │   │   │   ├── safe-mode.tsx
│       │   │   │   ├── settings-panel/
│       │   │   │   │   ├── controls/
│       │   │   │   │   │   ├── boolean.tsx
│       │   │   │   │   │   ├── check.tsx
│       │   │   │   │   │   ├── code.tsx
│       │   │   │   │   │   ├── combined.tsx
│       │   │   │   │   │   ├── controls.stories.tsx
│       │   │   │   │   │   ├── file.tsx
│       │   │   │   │   │   ├── json.tsx
│       │   │   │   │   │   ├── number.tsx
│       │   │   │   │   │   ├── radio.tsx
│       │   │   │   │   │   ├── resource-control.tsx
│       │   │   │   │   │   ├── select-asset.tsx
│       │   │   │   │   │   ├── select.tsx
│       │   │   │   │   │   ├── tag-control.tsx
│       │   │   │   │   │   ├── text-content.tsx
│       │   │   │   │   │   ├── text.tsx
│       │   │   │   │   │   └── url.tsx
│       │   │   │   │   ├── curl.test.ts
│       │   │   │   │   ├── curl.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── property-label.tsx
│       │   │   │   │   ├── props-section/
│       │   │   │   │   │   ├── animation/
│       │   │   │   │   │   │   ├── animation-keyframes.tsx
│       │   │   │   │   │   │   ├── animation-panel-content.stories.tsx
│       │   │   │   │   │   │   ├── animation-panel-content.tsx
│       │   │   │   │   │   │   ├── animation-section.tsx
│       │   │   │   │   │   │   ├── animation-transforms.tsx
│       │   │   │   │   │   │   ├── animations-select.tsx
│       │   │   │   │   │   │   ├── keyframe-helpers.test.ts
│       │   │   │   │   │   │   ├── keyframe-helpers.ts
│       │   │   │   │   │   │   ├── new-scroll-animations.ts
│       │   │   │   │   │   │   ├── new-view-animations.ts
│       │   │   │   │   │   │   ├── set-css-property.test.tsx
│       │   │   │   │   │   │   ├── set-css-property.ts
│       │   │   │   │   │   │   └── subject-select.tsx
│       │   │   │   │   │   ├── match-media-breakpoints.test.ts
│       │   │   │   │   │   ├── match-media-breakpoints.ts
│       │   │   │   │   │   ├── props-section.stories.tsx
│       │   │   │   │   │   ├── props-section.tsx
│       │   │   │   │   │   └── use-props-logic.ts
│       │   │   │   │   ├── resource-panel.tsx
│       │   │   │   │   ├── settings-panel.tsx
│       │   │   │   │   ├── settings-section.tsx
│       │   │   │   │   ├── shared.tsx
│       │   │   │   │   ├── variable-popover.tsx
│       │   │   │   │   ├── variables-section.stories.tsx
│       │   │   │   │   └── variables-section.tsx
│       │   │   │   ├── share.tsx
│       │   │   │   ├── style-panel/
│       │   │   │   │   ├── controls/
│       │   │   │   │   │   ├── color/
│       │   │   │   │   │   │   └── color-control.tsx
│       │   │   │   │   │   ├── font-family/
│       │   │   │   │   │   │   └── font-family-control.tsx
│       │   │   │   │   │   ├── font-weight/
│       │   │   │   │   │   │   └── font-weight-control.tsx
│       │   │   │   │   │   ├── image/
│       │   │   │   │   │   │   └── image-control.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── menu/
│       │   │   │   │   │   │   └── menu-control.tsx
│       │   │   │   │   │   ├── position/
│       │   │   │   │   │   │   └── position-control.tsx
│       │   │   │   │   │   ├── select/
│       │   │   │   │   │   │   └── select-control.tsx
│       │   │   │   │   │   ├── text/
│       │   │   │   │   │   │   └── text-control.tsx
│       │   │   │   │   │   ├── toggle/
│       │   │   │   │   │   │   └── toggle-control.tsx
│       │   │   │   │   │   └── toggle-group/
│       │   │   │   │   │       └── toggle-group-control.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── property-label.tsx
│       │   │   │   │   ├── sections/
│       │   │   │   │   │   ├── advanced/
│       │   │   │   │   │   │   ├── advanced.tsx
│       │   │   │   │   │   │   └── stores.ts
│       │   │   │   │   │   ├── backdrop-filter/
│       │   │   │   │   │   │   ├── backdrop-filter.stories.tsx
│       │   │   │   │   │   │   └── backdrop-filter.tsx
│       │   │   │   │   │   ├── backgrounds/
│       │   │   │   │   │   │   ├── background-code-editor.tsx
│       │   │   │   │   │   │   ├── background-content.stories.tsx
│       │   │   │   │   │   │   ├── background-content.tsx
│       │   │   │   │   │   │   ├── background-gradient.tsx
│       │   │   │   │   │   │   ├── background-image.tsx
│       │   │   │   │   │   │   ├── background-position.tsx
│       │   │   │   │   │   │   ├── background-size.test.ts
│       │   │   │   │   │   │   ├── background-size.tsx
│       │   │   │   │   │   │   ├── background-thumbnail.tsx
│       │   │   │   │   │   │   ├── backgrounds.stories.tsx
│       │   │   │   │   │   │   ├── backgrounds.tsx
│       │   │   │   │   │   │   ├── gradient-utils.test.ts
│       │   │   │   │   │   │   └── gradient-utils.ts
│       │   │   │   │   │   ├── borders/
│       │   │   │   │   │   │   ├── border-color.tsx
│       │   │   │   │   │   │   ├── border-property.tsx
│       │   │   │   │   │   │   ├── border-radius.tsx
│       │   │   │   │   │   │   ├── border-style.tsx
│       │   │   │   │   │   │   ├── border-width.tsx
│       │   │   │   │   │   │   ├── borders.stories.tsx
│       │   │   │   │   │   │   ├── borders.tsx
│       │   │   │   │   │   │   └── utils.ts
│       │   │   │   │   │   ├── box-shadows/
│       │   │   │   │   │   │   ├── box-shadows.stories.tsx
│       │   │   │   │   │   │   └── box-shadows.tsx
│       │   │   │   │   │   ├── filter/
│       │   │   │   │   │   │   ├── filter.stories.tsx
│       │   │   │   │   │   │   └── filter.tsx
│       │   │   │   │   │   ├── flex-child/
│       │   │   │   │   │   │   ├── flex-child.stories.tsx
│       │   │   │   │   │   │   └── flex-child.tsx
│       │   │   │   │   │   ├── grid-child/
│       │   │   │   │   │   │   ├── grid-child.stories.tsx
│       │   │   │   │   │   │   ├── grid-child.test.ts
│       │   │   │   │   │   │   └── grid-child.tsx
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── layout/
│       │   │   │   │   │   │   ├── layout.stories.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   └── shared/
│       │   │   │   │   │   │       ├── alignment-ui.stories.tsx
│       │   │   │   │   │   │       ├── alignment-ui.test.ts
│       │   │   │   │   │   │       ├── alignment-ui.tsx
│       │   │   │   │   │   │       ├── constants.ts
│       │   │   │   │   │   │       ├── flex-alignment.tsx
│       │   │   │   │   │   │       ├── grid-alignment.tsx
│       │   │   │   │   │   │       ├── grid-area-picker.test.ts
│       │   │   │   │   │   │       ├── grid-area-picker.tsx
│       │   │   │   │   │   │       ├── grid-areas.test.ts
│       │   │   │   │   │   │       ├── grid-areas.tsx
│       │   │   │   │   │   │       ├── grid-areas.utils.test.ts
│       │   │   │   │   │   │       ├── grid-generator.test.ts
│       │   │   │   │   │   │       ├── grid-generator.tsx
│       │   │   │   │   │   │       ├── grid-position-inputs.tsx
│       │   │   │   │   │   │       ├── grid-settings.tsx
│       │   │   │   │   │   │       ├── grid-utils.test.ts
│       │   │   │   │   │   │       └── grid-utils.ts
│       │   │   │   │   │   ├── list-item.tsx
│       │   │   │   │   │   ├── outline/
│       │   │   │   │   │   │   ├── outline.stories.tsx
│       │   │   │   │   │   │   └── outline.tsx
│       │   │   │   │   │   ├── position/
│       │   │   │   │   │   │   ├── inset-control.stories.tsx
│       │   │   │   │   │   │   ├── inset-control.tsx
│       │   │   │   │   │   │   ├── inset-layout.stories.tsx
│       │   │   │   │   │   │   ├── inset-layout.tsx
│       │   │   │   │   │   │   ├── inset-tooltip.tsx
│       │   │   │   │   │   │   └── position.tsx
│       │   │   │   │   │   ├── sections.ts
│       │   │   │   │   │   ├── shared/
│       │   │   │   │   │   │   ├── align-self.tsx
│       │   │   │   │   │   │   ├── input-popover.tsx
│       │   │   │   │   │   │   ├── keyboard.ts
│       │   │   │   │   │   │   ├── order.tsx
│       │   │   │   │   │   │   ├── scrub.tsx
│       │   │   │   │   │   │   └── value-text.tsx
│       │   │   │   │   │   ├── size/
│       │   │   │   │   │   │   ├── size.stories.tsx
│       │   │   │   │   │   │   └── size.tsx
│       │   │   │   │   │   ├── space/
│       │   │   │   │   │   │   ├── layout.stories.tsx
│       │   │   │   │   │   │   ├── layout.tsx
│       │   │   │   │   │   │   ├── properties.ts
│       │   │   │   │   │   │   ├── space.tsx
│       │   │   │   │   │   │   └── tooltip.tsx
│       │   │   │   │   │   ├── text-shadows/
│       │   │   │   │   │   │   ├── text-shadows.stories.tsx
│       │   │   │   │   │   │   └── text-shadows.tsx
│       │   │   │   │   │   ├── transforms/
│       │   │   │   │   │   │   ├── transform-and-perspective-origin.tsx
│       │   │   │   │   │   │   ├── transform-extractors.test.ts
│       │   │   │   │   │   │   ├── transform-extractors.ts
│       │   │   │   │   │   │   ├── transform-rotate.tsx
│       │   │   │   │   │   │   ├── transform-scale.tsx
│       │   │   │   │   │   │   ├── transform-skew.tsx
│       │   │   │   │   │   │   ├── transform-translate.tsx
│       │   │   │   │   │   │   ├── transform-utils.ts
│       │   │   │   │   │   │   ├── transforms.stories.tsx
│       │   │   │   │   │   │   └── transforms.tsx
│       │   │   │   │   │   ├── transitions/
│       │   │   │   │   │   │   ├── transition-content.tsx
│       │   │   │   │   │   │   ├── transition-property.tsx
│       │   │   │   │   │   │   ├── transitions.stories.tsx
│       │   │   │   │   │   │   └── transitions.tsx
│       │   │   │   │   │   └── typography/
│       │   │   │   │   │       ├── typography.stories.tsx
│       │   │   │   │   │       └── typography.tsx
│       │   │   │   │   ├── shared/
│       │   │   │   │   │   ├── color-picker.tsx
│       │   │   │   │   │   ├── css-fragment.test.ts
│       │   │   │   │   │   ├── css-fragment.tsx
│       │   │   │   │   │   ├── css-value-input/
│       │   │   │   │   │   │   ├── convert-units.test.ts
│       │   │   │   │   │   │   ├── convert-units.ts
│       │   │   │   │   │   │   ├── css-value-input-container.tsx
│       │   │   │   │   │   │   ├── css-value-input.stories.tsx
│       │   │   │   │   │   │   ├── css-value-input.tsx
│       │   │   │   │   │   │   ├── evaluate-math.test.ts
│       │   │   │   │   │   │   ├── evaluate-math.ts
│       │   │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   │   ├── parse-intermediate-or-invalid-value.ts
│       │   │   │   │   │   │   ├── parse-intermediate-or-invalid-value.ts.test.ts
│       │   │   │   │   │   │   ├── unit-select-options.ts
│       │   │   │   │   │   │   ├── unit-select.test.ts
│       │   │   │   │   │   │   ├── unit-select.tsx
│       │   │   │   │   │   │   └── value-editor-dialog.tsx
│       │   │   │   │   │   ├── filter-content.tsx
│       │   │   │   │   │   ├── instances-kv.ts
│       │   │   │   │   │   ├── model.tsx
│       │   │   │   │   │   ├── modifier-keys.ts
│       │   │   │   │   │   ├── recent-selectors.ts
│       │   │   │   │   │   ├── repeated-style.test.ts
│       │   │   │   │   │   ├── repeated-style.tsx
│       │   │   │   │   │   ├── scroll-by-pointer.ts
│       │   │   │   │   │   ├── shadow-content.tsx
│       │   │   │   │   │   ├── show-more.stories.tsx
│       │   │   │   │   │   ├── show-more.tsx
│       │   │   │   │   │   ├── style-section.tsx
│       │   │   │   │   │   └── use-style-data.ts
│       │   │   │   │   ├── style-panel.tsx
│       │   │   │   │   ├── style-source/
│       │   │   │   │   │   ├── index.ts
│       │   │   │   │   │   ├── style-source-badge.stories.tsx
│       │   │   │   │   │   ├── style-source-badge.tsx
│       │   │   │   │   │   ├── style-source-control.tsx
│       │   │   │   │   │   ├── style-source-input.stories.tsx
│       │   │   │   │   │   ├── style-source-input.tsx
│       │   │   │   │   │   ├── style-source-menu.tsx
│       │   │   │   │   │   └── use-sortable.tsx
│       │   │   │   │   ├── style-source-section.test.ts
│       │   │   │   │   └── style-source-section.tsx
│       │   │   │   ├── sync-status.tsx
│       │   │   │   ├── view-mode.tsx
│       │   │   │   └── workspace/
│       │   │   │       ├── canvas-iframe.tsx
│       │   │   │       ├── canvas-tools/
│       │   │   │       │   ├── apply-scale.ts
│       │   │   │       │   ├── block-editor-context-menu.tsx
│       │   │   │       │   ├── canvas-instance-context-menu.tsx
│       │   │   │       │   ├── canvas-tools.tsx
│       │   │   │       │   ├── grid-guides.tsx
│       │   │   │       │   ├── index.ts
│       │   │   │       │   ├── media-badge.tsx
│       │   │   │       │   ├── outline/
│       │   │   │       │   │   ├── block-instance-outline.tsx
│       │   │   │       │   │   ├── block-utils.ts
│       │   │   │       │   │   ├── collaborative-instance-outline.tsx
│       │   │   │       │   │   ├── hovered-instance-outline.tsx
│       │   │   │       │   │   ├── index.ts
│       │   │   │       │   │   ├── label.tsx
│       │   │   │       │   │   ├── outline.stories.tsx
│       │   │   │       │   │   ├── outline.tsx
│       │   │   │       │   │   └── selected-instance-outline.tsx
│       │   │   │       │   ├── resize-handles.tsx
│       │   │   │       │   ├── text-toolbar.tsx
│       │   │   │       │   └── use-subscribe-drag-drop-state.ts
│       │   │   │       ├── index.ts
│       │   │   │       └── workspace.tsx
│       │   │   ├── index.client.ts
│       │   │   ├── inspector.tsx
│       │   │   ├── shared/
│       │   │   │   ├── asset-manager/
│       │   │   │   │   ├── asset-filters.tsx
│       │   │   │   │   ├── asset-info.test.ts
│       │   │   │   │   ├── asset-info.tsx
│       │   │   │   │   ├── asset-manager.stories.tsx
│       │   │   │   │   ├── asset-manager.tsx
│       │   │   │   │   ├── asset-sort.tsx
│       │   │   │   │   ├── asset-thumbnail.tsx
│       │   │   │   │   ├── delete-unused-assets.tsx
│       │   │   │   │   ├── image.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── uploading-animation.tsx
│       │   │   │   │   ├── utils.test.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── assets/
│       │   │   │   │   ├── asset-upload.test.ts
│       │   │   │   │   ├── asset-upload.tsx
│       │   │   │   │   ├── asset-utils.test.ts
│       │   │   │   │   ├── asset-utils.ts
│       │   │   │   │   ├── assets-shell.tsx
│       │   │   │   │   ├── delete-assets.ts
│       │   │   │   │   ├── drag-monitor.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── not-found.tsx
│       │   │   │   │   ├── separator.tsx
│       │   │   │   │   ├── types.ts
│       │   │   │   │   ├── upload-assets.test.ts
│       │   │   │   │   ├── upload-assets.tsx
│       │   │   │   │   ├── use-assets.test.ts
│       │   │   │   │   └── use-assets.tsx
│       │   │   │   ├── binding-popover.test.ts
│       │   │   │   ├── binding-popover.tsx
│       │   │   │   ├── calc-canvas-width.test.ts
│       │   │   │   ├── calc-canvas-width.ts
│       │   │   │   ├── client-settings/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── settings.ts
│       │   │   │   ├── collapsible-section.stories.tsx
│       │   │   │   ├── collapsible-section.tsx
│       │   │   │   ├── commands.ts
│       │   │   │   ├── css-editor/
│       │   │   │   │   ├── add-style-input.tsx
│       │   │   │   │   ├── css-editor-context-menu.tsx
│       │   │   │   │   ├── css-editor.stories.tsx
│       │   │   │   │   ├── css-editor.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── parse-style-input.test.ts
│       │   │   │   │   └── parse-style-input.ts
│       │   │   │   ├── css-variable-utils.test.tsx
│       │   │   │   ├── css-variable-utils.tsx
│       │   │   │   ├── data-variable-utils.test.tsx
│       │   │   │   ├── data-variable-utils.tsx
│       │   │   │   ├── expression-editor.stories.tsx
│       │   │   │   ├── expression-editor.test.ts
│       │   │   │   ├── expression-editor.tsx
│       │   │   │   ├── fonts-manager/
│       │   │   │   │   ├── fonts-manager.tsx
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── item-menu.tsx
│       │   │   │   │   └── item-utils.ts
│       │   │   │   ├── inert-handlers.ts
│       │   │   │   ├── instance-context-menu.tsx
│       │   │   │   ├── instance-label.tsx
│       │   │   │   ├── loading.stories.tsx
│       │   │   │   ├── loading.tsx
│       │   │   │   ├── nano-states.ts
│       │   │   │   ├── relative-time.stories.tsx
│       │   │   │   ├── relative-time.tsx
│       │   │   │   ├── style-source-actions.tsx
│       │   │   │   ├── topbar-layout.stories.tsx
│       │   │   │   ├── topbar-layout.tsx
│       │   │   │   ├── topbar.tsx
│       │   │   │   ├── url-pattern.test.ts
│       │   │   │   ├── url-pattern.ts
│       │   │   │   └── use-disable-context-menu.ts
│       │   │   └── sidebar-left/
│       │   │       ├── sidebar-left.tsx
│       │   │       ├── sidebar-tabs.tsx
│       │   │       └── types.ts
│       │   ├── canvas/
│       │   │   ├── canvas.tsx
│       │   │   ├── collaborative-instance.ts
│       │   │   ├── elements.tsx
│       │   │   ├── features/
│       │   │   │   ├── build-mode/
│       │   │   │   │   ├── block-template.tsx
│       │   │   │   │   └── block.tsx
│       │   │   │   ├── text-editor/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── interop.test.tsx
│       │   │   │   │   ├── interop.ts
│       │   │   │   │   ├── text-editor.stories.tsx
│       │   │   │   │   ├── text-editor.tsx
│       │   │   │   │   └── toolbar-connector.tsx
│       │   │   │   └── webstudio-component/
│       │   │   │       ├── index.ts
│       │   │   │       ├── webstudio-component.test.tsx
│       │   │   │       └── webstudio-component.tsx
│       │   │   ├── grid-guide-utils.test.ts
│       │   │   ├── grid-guide-utils.ts
│       │   │   ├── index.client.ts
│       │   │   ├── inflator.test.ts
│       │   │   ├── inflator.ts
│       │   │   ├── instance-context-menu.ts
│       │   │   ├── instance-hovering.ts
│       │   │   ├── instance-selected.ts
│       │   │   ├── instance-selection.ts
│       │   │   ├── interceptor.ts
│       │   │   ├── scrollbar-width.ts
│       │   │   ├── shared/
│       │   │   │   ├── commands.ts
│       │   │   │   ├── font-weight-support.ts
│       │   │   │   ├── inert.ts
│       │   │   │   ├── routing-priority.test.ts
│       │   │   │   ├── routing-priority.ts
│       │   │   │   ├── scroll-new-instance-into-view.ts
│       │   │   │   ├── scroll-state.ts
│       │   │   │   ├── styles.test.ts
│       │   │   │   ├── styles.ts
│       │   │   │   ├── use-drag-drop.ts
│       │   │   │   └── use-pointer-outline.ts
│       │   │   └── stores.ts
│       │   ├── dashboard/
│       │   │   ├── dashboard.stories.tsx
│       │   │   ├── dashboard.tsx
│       │   │   ├── index.client.ts
│       │   │   ├── profile-menu.tsx
│       │   │   ├── projects/
│       │   │   │   ├── colors.ts
│       │   │   │   ├── project-card.tsx
│       │   │   │   ├── project-dialogs.tsx
│       │   │   │   ├── project-menu.tsx
│       │   │   │   ├── projects-list.tsx
│       │   │   │   ├── projects.tsx
│       │   │   │   ├── sort.test.ts
│       │   │   │   ├── sort.tsx
│       │   │   │   ├── tags.tsx
│       │   │   │   └── utils.ts
│       │   │   ├── search/
│       │   │   │   ├── nothing-found.tsx
│       │   │   │   ├── search-field.tsx
│       │   │   │   └── search-results.tsx
│       │   │   ├── shared/
│       │   │   │   ├── card.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── spinner.tsx
│       │   │   │   ├── thumbnail.tsx
│       │   │   │   └── types.ts
│       │   │   └── templates/
│       │   │       ├── template-card.tsx
│       │   │       └── templates.tsx
│       │   ├── env/
│       │   │   ├── env.server.ts
│       │   │   ├── env.static.server.ts
│       │   │   ├── env.static.ts
│       │   │   └── vite-env.d.ts
│       │   ├── root.tsx
│       │   ├── routes/
│       │   │   ├── _canvas.canvas.tsx
│       │   │   ├── _canvas.tsx
│       │   │   ├── _ui.$.tsx
│       │   │   ├── _ui.(builder).tsx
│       │   │   ├── _ui.dashboard._index.tsx
│       │   │   ├── _ui.dashboard.search.tsx
│       │   │   ├── _ui.dashboard.templates.tsx
│       │   │   ├── _ui.dashboard.tsx
│       │   │   ├── _ui.error.tsx
│       │   │   ├── _ui.login._index.tsx
│       │   │   ├── _ui.logout.tsx
│       │   │   ├── _ui.tsx
│       │   │   ├── auth.dev.tsx
│       │   │   ├── auth.github.tsx
│       │   │   ├── auth.github_.callback.tsx
│       │   │   ├── auth.google.tsx
│       │   │   ├── auth.google_.callback.tsx
│       │   │   ├── auth.ws.ts
│       │   │   ├── auth.ws_.callback.ts
│       │   │   ├── builder-logout.ts
│       │   │   ├── cgi.asset.$.ts
│       │   │   ├── cgi.empty[.]gif.ts
│       │   │   ├── cgi.image.$.ts
│       │   │   ├── cgi.video.$.ts
│       │   │   ├── dashboard-logout.ts
│       │   │   ├── n8n.$.tsx
│       │   │   ├── oauth.ws.authorize.tsx
│       │   │   ├── oauth.ws.token.ts
│       │   │   ├── rest.assets.tsx
│       │   │   ├── rest.assets_.$name.tsx
│       │   │   ├── rest.build.$buildId.tsx
│       │   │   ├── rest.buildId.$projectId.tsx
│       │   │   ├── rest.data.$projectId.ts
│       │   │   ├── rest.patch.ts
│       │   │   ├── rest.resources-loader.ts
│       │   │   └── trpc.$.ts
│       │   ├── services/
│       │   │   ├── auth-strategy/
│       │   │   │   └── ws.server.ts
│       │   │   ├── auth.server.ts
│       │   │   ├── auth.server.utils.ts
│       │   │   ├── bloom-filter.server.test.ts
│       │   │   ├── bloom-filter.server.ts
│       │   │   ├── builder-access.server.ts
│       │   │   ├── builder-auth.server.ts
│       │   │   ├── builder-session.server.ts
│       │   │   ├── cookie.server.ts
│       │   │   ├── csrf-session.server.ts
│       │   │   ├── destinations.server.ts
│       │   │   ├── logout-router.server.ts
│       │   │   ├── no-cross-origin-cookie.ts
│       │   │   ├── no-store-redirect.ts
│       │   │   ├── session.server.ts
│       │   │   ├── token.server.test.ts
│       │   │   ├── token.server.ts
│       │   │   ├── trcp-router.server.ts
│       │   │   ├── trpc.server.ts
│       │   │   └── user-router.server.ts
│       │   └── shared/
│       │       ├── $resources/
│       │       │   ├── assets.server.ts
│       │       │   ├── current-date.server.ts
│       │       │   └── sitemap.xml.server.ts
│       │       ├── app.css
│       │       ├── array-utils.test.ts
│       │       ├── array-utils.ts
│       │       ├── asset-client.ts
│       │       ├── awareness.test.tsx
│       │       ├── awareness.ts
│       │       ├── breakpoints/
│       │       │   ├── index.ts
│       │       │   ├── select-breakpoint-by-order.ts
│       │       │   └── stores.ts
│       │       ├── breakpoints-utils.test.ts
│       │       ├── breakpoints-utils.ts
│       │       ├── builder-api.ts
│       │       ├── builder-data.ts
│       │       ├── canvas-api.ts
│       │       ├── client-only.ts
│       │       ├── client-supports.ts
│       │       ├── clone-project.tsx
│       │       ├── code-editor-base.tsx
│       │       ├── code-editor.stories.tsx
│       │       ├── code-editor.tsx
│       │       ├── code-highlight.ts
│       │       ├── commands-emitter.ts
│       │       ├── content-model.test.tsx
│       │       ├── content-model.ts
│       │       ├── context.server.ts
│       │       ├── copy-paste/
│       │       │   ├── asset-upload.test.tsx
│       │       │   ├── asset-upload.ts
│       │       │   ├── init-copy-paste.ts
│       │       │   ├── plugin-html.test.tsx
│       │       │   ├── plugin-html.ts
│       │       │   ├── plugin-instance.test.ts
│       │       │   ├── plugin-instance.ts
│       │       │   ├── plugin-markdown.test.tsx
│       │       │   ├── plugin-markdown.ts
│       │       │   └── plugin-webflow/
│       │       │       ├── __generated__/
│       │       │       │   └── style-presets.ts
│       │       │       ├── instances-properties.ts
│       │       │       ├── plugin-webflow.test.tsx
│       │       │       ├── plugin-webflow.ts
│       │       │       ├── schema.ts
│       │       │       ├── style-presets-overrides.ts
│       │       │       ├── style-presets.css
│       │       │       └── styles.ts
│       │       ├── copy-paste.test.tsx
│       │       ├── copy-to-clipboard.stories.tsx
│       │       ├── copy-to-clipboard.tsx
│       │       ├── csrf.client.ts
│       │       ├── data-variables.test.tsx
│       │       ├── data-variables.ts
│       │       ├── db/
│       │       │   ├── canvas.server.ts
│       │       │   ├── index.ts
│       │       │   ├── user-plan-features.server.ts
│       │       │   └── user.server.ts
│       │       ├── debug-track.ts
│       │       ├── debug.ts
│       │       ├── dom-hooks/
│       │       │   ├── index.ts
│       │       │   ├── use-content-editable.ts
│       │       │   └── use-window-resize.ts
│       │       ├── dom-utils.stories.tsx
│       │       ├── dom-utils.test.ts
│       │       ├── dom-utils.ts
│       │       ├── empty.ts
│       │       ├── entri/
│       │       │   └── entri-api.server.ts
│       │       ├── error/
│       │       │   ├── error-boundary.tsx
│       │       │   ├── error-message.client.tsx
│       │       │   ├── error-message.stories.tsx
│       │       │   ├── error-parse.ts
│       │       │   ├── index.ts
│       │       │   └── toast-error.tsx
│       │       ├── event-utils.test.ts
│       │       ├── event-utils.ts
│       │       ├── fetch.client.ts
│       │       ├── form-utils/
│       │       │   ├── index.ts
│       │       │   └── use-ids.ts
│       │       ├── help.tsx
│       │       ├── hook-utils/
│       │       │   ├── effect-event.ts
│       │       │   ├── use-interval.ts
│       │       │   └── use-mount.ts
│       │       ├── html.test.tsx
│       │       ├── html.ts
│       │       ├── instance-utils.test.tsx
│       │       ├── instance-utils.ts
│       │       ├── logout.client.tsx
│       │       ├── marketplace/
│       │       │   ├── db.server.ts
│       │       │   ├── router.server.ts
│       │       │   └── types.ts
│       │       ├── matcher.test.tsx
│       │       ├── matcher.ts
│       │       ├── math-utils.ts
│       │       ├── nano-hash.test.ts
│       │       ├── nano-hash.ts
│       │       ├── nano-states/
│       │       │   ├── breakpoints.ts
│       │       │   ├── canvas.ts
│       │       │   ├── components.ts
│       │       │   ├── index.ts
│       │       │   ├── instances.ts
│       │       │   ├── misc.ts
│       │       │   ├── pages.ts
│       │       │   ├── project-settings.ts
│       │       │   ├── props.test.tsx
│       │       │   ├── props.ts
│       │       │   └── variables.ts
│       │       ├── page-utils.test.tsx
│       │       ├── page-utils.ts
│       │       ├── pages/
│       │       │   ├── index.ts
│       │       │   └── use-switch-page.ts
│       │       ├── project-settings/
│       │       │   ├── image-control.tsx
│       │       │   ├── import-redirects-dialog.stories.tsx
│       │       │   ├── import-redirects-dialog.tsx
│       │       │   ├── index.ts
│       │       │   ├── project-settings.stories.tsx
│       │       │   ├── project-settings.tsx
│       │       │   ├── section-backups.tsx
│       │       │   ├── section-general.tsx
│       │       │   ├── section-marketplace.tsx
│       │       │   ├── section-publish.tsx
│       │       │   ├── section-redirects.test.ts
│       │       │   ├── section-redirects.tsx
│       │       │   ├── utils.test.ts
│       │       │   └── utils.ts
│       │       ├── pubsub/
│       │       │   ├── create.test.ts
│       │       │   ├── create.ts
│       │       │   ├── index.ts
│       │       │   └── raf-queue.ts
│       │       ├── redirects/
│       │       │   ├── README.md
│       │       │   ├── fixtures/
│       │       │   │   ├── apache.htaccess
│       │       │   │   ├── generic.csv
│       │       │   │   ├── generic.json
│       │       │   │   ├── hubspot.csv
│       │       │   │   ├── netlify._redirects
│       │       │   │   ├── shopify.csv
│       │       │   │   └── vercel-nextjs.json
│       │       │   ├── redirect-loop-detection.test.ts
│       │       │   ├── redirect-loop-detection.ts
│       │       │   ├── redirect-parsers.test.ts
│       │       │   └── redirect-parsers.ts
│       │       ├── resource-utils.ts
│       │       ├── resources.test.ts
│       │       ├── resources.ts
│       │       ├── router-utils/
│       │       │   ├── index.ts
│       │       │   ├── is-canvas.ts
│       │       │   ├── origins.ts
│       │       │   └── path-utils.ts
│       │       ├── session/
│       │       │   ├── index.ts
│       │       │   └── use-login-error-message.ts
│       │       ├── share-project/
│       │       │   ├── index.ts
│       │       │   ├── share-project-container.tsx
│       │       │   ├── share-project.stories.tsx
│       │       │   └── share-project.tsx
│       │       ├── shim.test.ts
│       │       ├── shim.ts
│       │       ├── store-utils.test.ts
│       │       ├── store-utils.ts
│       │       ├── string-utils.ts
│       │       ├── style-object-model.test.tsx
│       │       ├── style-object-model.ts
│       │       ├── style-source-utils.test.tsx
│       │       ├── style-source-utils.ts
│       │       ├── sync/
│       │       │   ├── command-queue.ts
│       │       │   ├── data-stores.ts
│       │       │   ├── project-queue.ts
│       │       │   ├── sync-client.ts
│       │       │   └── sync-stores.ts
│       │       ├── sync-client.test.ts
│       │       ├── sync-client.ts
│       │       ├── system.test.ts
│       │       ├── system.ts
│       │       ├── tailwind/
│       │       │   ├── __generated__/
│       │       │   │   └── preflight.ts
│       │       │   ├── preflight-bin.ts
│       │       │   ├── preflight.css
│       │       │   ├── tailwind.test.tsx
│       │       │   └── tailwind.ts
│       │       ├── token-conflict-dialog.tsx
│       │       ├── tree-utils.test.ts
│       │       ├── tree-utils.ts
│       │       ├── trpc/
│       │       │   └── trpc-client.ts
│       │       ├── use-set-features.ts
│       │       ├── visually-hidden.ts
│       │       ├── webstudio-data-migrator.test.ts
│       │       └── webstudio-data-migrator.ts
│       ├── docker-compose.yaml
│       ├── docs/
│       │   └── test-cases.md
│       ├── package.json
│       ├── public/
│       │   └── robots.txt
│       ├── tsconfig.json
│       ├── vite.config.ts
│       └── vitest.config.ts
├── codemod/
│   ├── migrate-css-variables.ts
│   └── migrate-tokens.ts
├── fixtures/
│   ├── README.md
│   ├── react-router-cloudflare/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── entry.server.tsx
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── react-router.config.ts
│   │   ├── tsconfig.json
│   │   ├── vite.config.ts
│   │   ├── workers/
│   │   │   └── app.ts
│   │   └── wrangler.jsonc
│   ├── react-router-docker/
│   │   ├── .dockerignore
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [_image].$.ts
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── react-router-netlify/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── netlify.toml
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── react-router-vercel/
│   │   ├── .gitignore
│   │   ├── .npmrc
│   │   ├── .template/
│   │   │   ├── .npmrc
│   │   │   ├── package.json
│   │   │   └── tsconfig.json
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   ├── routes/
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── [robots.txt].tsx
│   │   │   │   ├── [sitemap.xml]._index.tsx
│   │   │   │   └── _index.tsx
│   │   │   └── routes.ts
│   │   ├── package.json
│   │   ├── react-router.config.ts
│   │   ├── tsconfig.json
│   │   ├── vercel.json
│   │   └── vite.config.ts
│   ├── ssg/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   └── constants.mjs
│   │   ├── package.json
│   │   ├── pages/
│   │   │   ├── +config.ts
│   │   │   ├── another-page/
│   │   │   │   ├── +Head.tsx
│   │   │   │   ├── +Page.tsx
│   │   │   │   └── +data.ts
│   │   │   └── index/
│   │   │       ├── +Head.tsx
│   │   │       ├── +Page.tsx
│   │   │       └── +data.ts
│   │   ├── renderer/
│   │   │   ├── +onRenderClient.tsx
│   │   │   └── +onRenderHtml.tsx
│   │   ├── tsconfig.json
│   │   ├── vike.d.ts
│   │   └── vite.config.ts
│   ├── ssg-netlify-by-project-id/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [redirect]._index.server.tsx
│   │   │   │   ├── [redirect]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   └── constants.mjs
│   │   ├── package.json
│   │   ├── pages/
│   │   │   ├── +config.ts
│   │   │   ├── index/
│   │   │   │   ├── +Head.tsx
│   │   │   │   ├── +Page.tsx
│   │   │   │   └── +data.ts
│   │   │   └── redirect/
│   │   │       ├── +Head.tsx
│   │   │       ├── +Page.tsx
│   │   │       └── +data.ts
│   │   ├── renderer/
│   │   │   ├── +onRenderClient.tsx
│   │   │   └── +onRenderHtml.tsx
│   │   ├── tsconfig.json
│   │   ├── vike.d.ts
│   │   └── vite.config.ts
│   ├── webstudio-cloudflare-template/
│   │   ├── .npmrc
│   │   ├── .webstudio/
│   │   │   ├── config.json
│   │   │   └── data.json
│   │   ├── WS_CF_README.md
│   │   ├── app/
│   │   │   ├── __generated__/
│   │   │   │   ├── $resources.assets.ts
│   │   │   │   ├── $resources.sitemap.xml.ts
│   │   │   │   ├── [another-page]._index.server.tsx
│   │   │   │   ├── [another-page]._index.tsx
│   │   │   │   ├── _index.server.tsx
│   │   │   │   ├── _index.tsx
│   │   │   │   └── index.css
│   │   │   ├── constants.mjs
│   │   │   ├── extension.ts
│   │   │   ├── root.tsx
│   │   │   └── routes/
│   │   │       ├── [another-page]._index.tsx
│   │   │       ├── [robots.txt].tsx
│   │   │       ├── [sitemap.xml]._index.tsx
│   │   │       └── _index.tsx
│   │   ├── functions/
│   │   │   └── [[path]].ts
│   │   ├── load-context.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   ├── vite.config.ts
│   │   ├── worker-configuration.d.ts
│   │   └── wrangler.toml
│   └── webstudio-features/
│       ├── .gitignore
│       ├── .npmrc
│       ├── .template/
│       │   ├── .npmrc
│       │   ├── app/
│       │   │   └── constants.mjs
│       │   ├── package.json
│       │   ├── tsconfig.json
│       │   └── vite.config.ts
│       ├── .webstudio/
│       │   ├── config.json
│       │   └── data.json
│       ├── README.md
│       ├── app/
│       │   ├── __generated__/
│       │   │   ├── $resources.assets.ts
│       │   │   ├── $resources.sitemap.xml.ts
│       │   │   ├── [_route_with_symbols_]._index.server.tsx
│       │   │   ├── [_route_with_symbols_]._index.tsx
│       │   │   ├── [animations]._index.server.tsx
│       │   │   ├── [animations]._index.tsx
│       │   │   ├── [assets1]._index.server.tsx
│       │   │   ├── [assets1]._index.tsx
│       │   │   ├── [class-names]._index.server.tsx
│       │   │   ├── [class-names]._index.tsx
│       │   │   ├── [content-block]._index.server.tsx
│       │   │   ├── [content-block]._index.tsx
│       │   │   ├── [duration]._index.server.tsx
│       │   │   ├── [duration]._index.tsx
│       │   │   ├── [expressions]._index.server.tsx
│       │   │   ├── [expressions]._index.tsx
│       │   │   ├── [form]._index.server.tsx
│       │   │   ├── [form]._index.tsx
│       │   │   ├── [head-tag]._index.server.tsx
│       │   │   ├── [head-tag]._index.tsx
│       │   │   ├── [heading-with-id]._index.server.tsx
│       │   │   ├── [heading-with-id]._index.tsx
│       │   │   ├── [nested].[nested-page]._index.server.tsx
│       │   │   ├── [nested].[nested-page]._index.tsx
│       │   │   ├── [radix]._index.server.tsx
│       │   │   ├── [radix]._index.tsx
│       │   │   ├── [resources]._index.server.tsx
│       │   │   ├── [resources]._index.tsx
│       │   │   ├── [sitemap.xml]._index.server.tsx
│       │   │   ├── [sitemap.xml]._index.tsx
│       │   │   ├── [text-duration]._index.server.tsx
│       │   │   ├── [text-duration]._index.tsx
│       │   │   ├── _index.server.tsx
│       │   │   ├── _index.tsx
│       │   │   └── index.css
│       │   ├── constants.mjs
│       │   ├── extension.ts
│       │   ├── root.tsx
│       │   ├── routes/
│       │   │   ├── [_route_with_symbols_]._index.tsx
│       │   │   ├── [animations]._index.tsx
│       │   │   ├── [assets1]._index.tsx
│       │   │   ├── [class-names]._index.tsx
│       │   │   ├── [content-block]._index.tsx
│       │   │   ├── [duration]._index.tsx
│       │   │   ├── [expressions]._index.tsx
│       │   │   ├── [form]._index.tsx
│       │   │   ├── [head-tag]._index.tsx
│       │   │   ├── [heading-with-id]._index.tsx
│       │   │   ├── [nested].[nested-page]._index.tsx
│       │   │   ├── [radix]._index.tsx
│       │   │   ├── [resources]._index.tsx
│       │   │   ├── [robots.txt].tsx
│       │   │   ├── [sitemap.xml]._index.tsx
│       │   │   ├── [text-duration]._index.tsx
│       │   │   └── _index.tsx
│       │   └── routes.ts
│       ├── package.json
│       ├── proxy-emulator/
│       │   └── dedupe-meta.ts
│       ├── public/
│       │   └── assets/
│       │       ├── webm-example_2r_6VmRBjhAy3ldaqz0gk.webm
│       │       └── webm-example_zNrAFpO1v78xz91jYpaiE.webm
│       ├── tsconfig.json
│       └── vite.config.ts
├── https/
│   ├── README.md
│   ├── fullchain.pem
│   ├── haproxy.pem
│   ├── haproxy.sh
│   └── privkey.pem
├── lostpixel.config.js
├── package.json
├── packages/
│   ├── asset-uploader/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── client.ts
│   │   │   ├── clients/
│   │   │   │   ├── fs/
│   │   │   │   │   ├── fs.ts
│   │   │   │   │   └── upload.ts
│   │   │   │   └── s3/
│   │   │   │       ├── s3.ts
│   │   │   │       └── upload.ts
│   │   │   ├── constants.ts
│   │   │   ├── db/
│   │   │   │   ├── index.ts
│   │   │   │   └── load.ts
│   │   │   ├── delete.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── patch.ts
│   │   │   ├── schema.ts
│   │   │   ├── types.ts
│   │   │   ├── upload.ts
│   │   │   └── utils/
│   │   │       ├── font-data.test.ts
│   │   │       ├── font-data.ts
│   │   │       ├── format-asset.test.ts
│   │   │       ├── format-asset.ts
│   │   │       ├── get-asset-data.ts
│   │   │       ├── get-unique-filename.ts
│   │   │       ├── sanitize-s3-key.test.ts
│   │   │       ├── sanitize-s3-key.ts
│   │   │       ├── size-limiter.ts
│   │   │       └── to-bytes.ts
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── authorization-token/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── authorization-token.ts
│   │   │   │   └── index.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   └── trpc/
│   │   │       ├── authorization-tokens-router.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── cli/
│   │   ├── .gitignore
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── bin.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── args.ts
│   │   │   ├── build-utils.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── build.ts
│   │   │   │   ├── init-flow.ts
│   │   │   │   ├── link.ts
│   │   │   │   ├── sync.ts
│   │   │   │   └── yargs-types.ts
│   │   │   ├── config.ts
│   │   │   ├── config.ts-expect.ts
│   │   │   ├── framework-react-router.ts
│   │   │   ├── framework-remix.ts
│   │   │   ├── framework-vike-ssg.ts
│   │   │   ├── framework.ts
│   │   │   ├── fs-utils.ts
│   │   │   ├── html-to-jsx.test.ts
│   │   │   ├── html-to-jsx.ts
│   │   │   └── prebuild.ts
│   │   ├── templates/
│   │   │   ├── cloudflare/
│   │   │   │   ├── WS_CF_README.md
│   │   │   │   ├── functions/
│   │   │   │   │   └── [[path]].ts
│   │   │   │   ├── load-context.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vite.config.ts
│   │   │   │   ├── worker-configuration.d.ts
│   │   │   │   └── wrangler.toml
│   │   │   ├── defaults/
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   ├── extension.ts
│   │   │   │   │   ├── root.tsx
│   │   │   │   │   ├── route-templates/
│   │   │   │   │   │   ├── default-sitemap.tsx
│   │   │   │   │   │   ├── html.tsx
│   │   │   │   │   │   ├── redirect.tsx
│   │   │   │   │   │   └── xml.tsx
│   │   │   │   │   └── routes/
│   │   │   │   │       └── [robots.txt].tsx
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── internal/
│   │   │   │   ├── .npmrc
│   │   │   │   ├── package.json
│   │   │   │   └── tsconfig.json
│   │   │   ├── react-router/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── app/
│   │   │   │   │   ├── extension.ts
│   │   │   │   │   ├── root.tsx
│   │   │   │   │   ├── route-templates/
│   │   │   │   │   │   ├── default-sitemap.tsx
│   │   │   │   │   │   ├── html.tsx
│   │   │   │   │   │   ├── redirect.tsx
│   │   │   │   │   │   └── xml.tsx
│   │   │   │   │   ├── routes/
│   │   │   │   │   │   └── [robots.txt].tsx
│   │   │   │   │   └── routes.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── react-router-cloudflare/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── entry.server.tsx
│   │   │   │   ├── package.json
│   │   │   │   ├── react-router.config.ts
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vite.config.ts
│   │   │   │   ├── workers/
│   │   │   │   │   └── app.ts
│   │   │   │   └── wrangler.jsonc
│   │   │   ├── react-router-docker/
│   │   │   │   ├── .dockerignore
│   │   │   │   ├── Dockerfile
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── routes/
│   │   │   │   │       └── [_image].$.ts
│   │   │   │   └── package.json
│   │   │   ├── react-router-netlify/
│   │   │   │   ├── app/
│   │   │   │   │   └── constants.mjs
│   │   │   │   ├── netlify.toml
│   │   │   │   ├── package.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── react-router-vercel/
│   │   │   │   ├── app/
│   │   │   │   │   └── constants.mjs
│   │   │   │   ├── package.json
│   │   │   │   ├── react-router.config.ts
│   │   │   │   └── vercel.json
│   │   │   ├── saas-helpers/
│   │   │   │   ├── package.json
│   │   │   │   ├── tsconfig.json
│   │   │   │   └── vite.config.ts
│   │   │   ├── ssg/
│   │   │   │   ├── app/
│   │   │   │   │   ├── constants.mjs
│   │   │   │   │   └── route-templates/
│   │   │   │   │       └── html/
│   │   │   │   │           ├── +Head.tsx
│   │   │   │   │           ├── +Page.tsx
│   │   │   │   │           └── +data.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── pages/
│   │   │   │   │   └── +config.ts
│   │   │   │   ├── renderer/
│   │   │   │   │   ├── +onRenderClient.tsx
│   │   │   │   │   └── +onRenderHtml.tsx
│   │   │   │   ├── tsconfig.json
│   │   │   │   ├── vike.d.ts
│   │   │   │   └── vite.config.ts
│   │   │   ├── ssg-netlify/
│   │   │   │   └── app/
│   │   │   │       └── constants.mjs
│   │   │   └── ssg-vercel/
│   │   │       ├── app/
│   │   │       │   └── constants.mjs
│   │   │       └── public/
│   │   │           └── vercel.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── css-data/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── bin/
│   │   │   ├── css-to-ws.ts
│   │   │   ├── css-tree-dist-data.d.ts
│   │   │   ├── html.css.ts
│   │   │   ├── mdn-data.ts
│   │   │   ├── prompts/
│   │   │   │   ├── declarations.prompt.md
│   │   │   │   ├── properties.prompt.md
│   │   │   │   └── pseudo-selectors.prompt.md
│   │   │   └── property-value-descriptions.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── animatable-properties.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── keyword-values.ts
│   │   │   │   ├── properties.ts
│   │   │   │   ├── property-value-descriptions.ts
│   │   │   │   ├── pseudo-classes.ts
│   │   │   │   ├── pseudo-elements.ts
│   │   │   │   ├── pseudo-selector-descriptions.ts
│   │   │   │   ├── shorthand-properties.ts
│   │   │   │   └── units.ts
│   │   │   ├── custom-data.ts
│   │   │   ├── html.css
│   │   │   ├── index.ts
│   │   │   ├── media-condition-simulator.test.ts
│   │   │   ├── media-condition-simulator.ts
│   │   │   ├── parse-css-value.test.ts
│   │   │   ├── parse-css-value.ts
│   │   │   ├── parse-css.test.ts
│   │   │   ├── parse-css.ts
│   │   │   ├── property-parsers/
│   │   │   │   ├── conic-gradient.test.ts
│   │   │   │   ├── conic-gradient.ts
│   │   │   │   ├── gradient-utils.ts
│   │   │   │   ├── grid-template-areas.test.ts
│   │   │   │   ├── grid-template-areas.ts
│   │   │   │   ├── grid-template-tracks.test.ts
│   │   │   │   ├── grid-template-tracks.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── linear-gradient.test.ts
│   │   │   │   ├── linear-gradient.ts
│   │   │   │   ├── radial-gradient.test.ts
│   │   │   │   ├── radial-gradient.ts
│   │   │   │   └── types.ts
│   │   │   ├── selector-validation.test.ts
│   │   │   ├── selector-validation.ts
│   │   │   ├── shorthands.test.ts
│   │   │   └── shorthands.ts
│   │   └── tsconfig.json
│   ├── css-engine/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── types.ts
│   │   │   ├── core/
│   │   │   │   ├── atomic.test.ts
│   │   │   │   ├── atomic.ts
│   │   │   │   ├── compare-media.test.ts
│   │   │   │   ├── compare-media.ts
│   │   │   │   ├── create-style-sheet.ts
│   │   │   │   ├── css-engine.stories.tsx
│   │   │   │   ├── equal-media.test.ts
│   │   │   │   ├── equal-media.ts
│   │   │   │   ├── find-applicable-media.test.ts
│   │   │   │   ├── find-applicable-media.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── match-media.test.ts
│   │   │   │   ├── match-media.ts
│   │   │   │   ├── merger.test.ts
│   │   │   │   ├── merger.ts
│   │   │   │   ├── prefixer.test.ts
│   │   │   │   ├── prefixer.ts
│   │   │   │   ├── rules.test.ts
│   │   │   │   ├── rules.ts
│   │   │   │   ├── style-element.ts
│   │   │   │   ├── style-sheet-regular.test.ts
│   │   │   │   ├── style-sheet-regular.ts
│   │   │   │   ├── style-sheet.ts
│   │   │   │   ├── to-property.test.ts
│   │   │   │   ├── to-property.ts
│   │   │   │   ├── to-value.test.ts
│   │   │   │   └── to-value.ts
│   │   │   ├── css.ts
│   │   │   ├── index.ts
│   │   │   ├── runtime.ts
│   │   │   └── schema.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── dashboard/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── index.ts
│   │   │   │   └── projects.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   └── trpc/
│   │   │       ├── index.ts
│   │   │       └── project-router.ts
│   │   └── tsconfig.json
│   ├── design-system/
│   │   ├── LICENSE
│   │   ├── bin/
│   │   │   └── transform-figma-tokens.ts
│   │   ├── documentation/
│   │   │   └── figma-design-tokens.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── figma-design-tokens.json
│   │   │   │   └── figma-design-tokens.ts
│   │   │   ├── components/
│   │   │   │   ├── __DEPRECATED__/
│   │   │   │   │   ├── list.stories.tsx
│   │   │   │   │   └── list.tsx
│   │   │   │   ├── avatar.stories.tsx
│   │   │   │   ├── avatar.tsx
│   │   │   │   ├── box.tsx
│   │   │   │   ├── button.stories.tsx
│   │   │   │   ├── button.tsx
│   │   │   │   ├── card.stories.tsx
│   │   │   │   ├── card.tsx
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── checkbox.tsx
│   │   │   │   ├── color-picker.stories.tsx
│   │   │   │   ├── color-picker.tsx
│   │   │   │   ├── combobox.stories.tsx
│   │   │   │   ├── combobox.tsx
│   │   │   │   ├── command.stories.tsx
│   │   │   │   ├── command.tsx
│   │   │   │   ├── component-card.stories.tsx
│   │   │   │   ├── component-card.tsx
│   │   │   │   ├── context-menu.stories.tsx
│   │   │   │   ├── context-menu.tsx
│   │   │   │   ├── css-value-list-item.stories.tsx
│   │   │   │   ├── css-value-list-item.tsx
│   │   │   │   ├── dialog.stories.tsx
│   │   │   │   ├── dialog.test.ts
│   │   │   │   ├── dialog.tsx
│   │   │   │   ├── dropdown-menu.stories.tsx
│   │   │   │   ├── dropdown-menu.tsx
│   │   │   │   ├── enhanced-tooltip.stories.tsx
│   │   │   │   ├── enhanced-tooltip.tsx
│   │   │   │   ├── flex.tsx
│   │   │   │   ├── floating-panel.stories.tsx
│   │   │   │   ├── floating-panel.tsx
│   │   │   │   ├── focus-ring.ts
│   │   │   │   ├── gradient-picker.stories.tsx
│   │   │   │   ├── gradient-picker.tsx
│   │   │   │   ├── grid.tsx
│   │   │   │   ├── icon-button.stories.tsx
│   │   │   │   ├── icon-button.tsx
│   │   │   │   ├── input-field.stories.tsx
│   │   │   │   ├── input-field.tsx
│   │   │   │   ├── kbd.stories.tsx
│   │   │   │   ├── kbd.tsx
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── label.tsx
│   │   │   │   ├── link.stories.tsx
│   │   │   │   ├── link.tsx
│   │   │   │   ├── list-position-indicator.stories.tsx
│   │   │   │   ├── list-position-indicator.tsx
│   │   │   │   ├── menu.stories.tsx
│   │   │   │   ├── menu.tsx
│   │   │   │   ├── nested-icon-label.stories.tsx
│   │   │   │   ├── nested-icon-label.tsx
│   │   │   │   ├── nested-input-button.stories.tsx
│   │   │   │   ├── nested-input-button.tsx
│   │   │   │   ├── panel-banner.stories.tsx
│   │   │   │   ├── panel-banner.tsx
│   │   │   │   ├── panel-tabs.stories.tsx
│   │   │   │   ├── panel-tabs.tsx
│   │   │   │   ├── panel-title.stories.tsx
│   │   │   │   ├── panel-title.tsx
│   │   │   │   ├── popover.stories.tsx
│   │   │   │   ├── popover.tsx
│   │   │   │   ├── position-grid.stories.tsx
│   │   │   │   ├── position-grid.tsx
│   │   │   │   ├── primitives/
│   │   │   │   │   ├── arrow-focus.tsx
│   │   │   │   │   ├── create-content-controller.stories.tsx
│   │   │   │   │   ├── create-content-controller.ts
│   │   │   │   │   ├── dnd/
│   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   │   └── geometry-utils.test.ts.snap
│   │   │   │   │   │   ├── canvas.stories.tsx
│   │   │   │   │   │   ├── dom-utils.ts
│   │   │   │   │   │   ├── geometry-utils.test.ts
│   │   │   │   │   │   ├── geometry-utils.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── placement-indicator.tsx
│   │   │   │   │   │   ├── sortable-list.stories.tsx
│   │   │   │   │   │   ├── use-auto-scroll.test.ts
│   │   │   │   │   │   ├── use-auto-scroll.ts
│   │   │   │   │   │   ├── use-drag-cursor.ts
│   │   │   │   │   │   ├── use-drag.ts
│   │   │   │   │   │   ├── use-drop.ts
│   │   │   │   │   │   ├── use-hold.ts
│   │   │   │   │   │   └── use-sortable.tsx
│   │   │   │   │   ├── is-truncated.tsx
│   │   │   │   │   ├── list.tsx
│   │   │   │   │   ├── numeric-gesture-control.stories.tsx
│   │   │   │   │   ├── numeric-gesture-control.ts
│   │   │   │   │   ├── numeric-input-arrow-keys.ts
│   │   │   │   │   ├── small-button.stories.tsx
│   │   │   │   │   ├── small-button.tsx
│   │   │   │   │   └── use-scrub.ts
│   │   │   │   ├── pro-badge.stories.tsx
│   │   │   │   ├── pro-badge.tsx
│   │   │   │   ├── progress.stories.tsx
│   │   │   │   ├── progress.tsx
│   │   │   │   ├── radio.stories.tsx
│   │   │   │   ├── radio.tsx
│   │   │   │   ├── scroll-area.stories.tsx
│   │   │   │   ├── scroll-area.tsx
│   │   │   │   ├── search-field.stories.tsx
│   │   │   │   ├── search-field.tsx
│   │   │   │   ├── section-title.stories.tsx
│   │   │   │   ├── section-title.tsx
│   │   │   │   ├── select-button.stories.tsx
│   │   │   │   ├── select-button.tsx
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── select.tsx
│   │   │   │   ├── separator.stories.tsx
│   │   │   │   ├── separator.tsx
│   │   │   │   ├── small-icon-button.stories.tsx
│   │   │   │   ├── small-icon-button.tsx
│   │   │   │   ├── small-toggle-button.stories.tsx
│   │   │   │   ├── small-toggle-button.tsx
│   │   │   │   ├── storybook.tsx
│   │   │   │   ├── switch.stories.tsx
│   │   │   │   ├── switch.tsx
│   │   │   │   ├── text-area.stories.tsx
│   │   │   │   ├── text-area.tsx
│   │   │   │   ├── text.stories.tsx
│   │   │   │   ├── text.ts
│   │   │   │   ├── toast.stories.tsx
│   │   │   │   ├── toast.tsx
│   │   │   │   ├── toggle-button.stories.tsx
│   │   │   │   ├── toggle-button.tsx
│   │   │   │   ├── toggle-group.stories.tsx
│   │   │   │   ├── toggle-group.tsx
│   │   │   │   ├── toolbar.stories.tsx
│   │   │   │   ├── toolbar.tsx
│   │   │   │   ├── tooltip.stories.tsx
│   │   │   │   ├── tooltip.tsx
│   │   │   │   ├── tree.stories.tsx
│   │   │   │   ├── tree.tsx
│   │   │   │   ├── two-rows-icon-button-container.stories.tsx
│   │   │   │   └── two-rows-icon-button-container.tsx
│   │   │   ├── index.ts
│   │   │   ├── stitches.config.ts
│   │   │   └── utilities.ts
│   │   ├── tsconfig.json
│   │   ├── tsconfig.typecheck.json
│   │   └── vitest.config.ts
│   ├── domain/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── cname-from-user-id.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── validate.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── rdap.ts
│   │   │   └── trpc/
│   │   │       ├── domain.ts
│   │   │       └── index.ts
│   │   └── tsconfig.json
│   ├── feature-flags/
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── feature.ts
│   │   │   ├── flags.ts
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── fonts/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── constants.ts
│   │   │   ├── font-weights.ts
│   │   │   ├── get-font-faces.test.ts
│   │   │   ├── get-font-faces.ts
│   │   │   ├── index.ts
│   │   │   └── schema.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── generate-arg-types/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── arg-types.ts
│   │   │   ├── cli.ts
│   │   │   └── props/
│   │   │       └── add-descriptions.ts
│   │   └── tsconfig.json
│   ├── html-data/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── bin/
│   │   │   ├── aria.ts
│   │   │   ├── attributes.ts
│   │   │   ├── crawler.ts
│   │   │   ├── elements.ts
│   │   │   ├── overrides.ts
│   │   │   └── possible-standard-names.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── aria-jsx-test.tsx
│   │   │   │   ├── aria.ts
│   │   │   │   ├── attributes-jsx-test.tsx
│   │   │   │   ├── attributes.ts
│   │   │   │   └── elements.ts
│   │   │   ├── index.ts
│   │   │   └── pseudo-classes.ts
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── http-client/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.test.ts
│   │   │   └── index.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── icons/
│   │   ├── LICENSE
│   │   ├── generate.ts
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── components.tsx
│   │   │   │   └── svg.ts
│   │   │   ├── index.stories.tsx
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── svg-string.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── image/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── image-dev.stories.tsx
│   │   │   ├── image-loader.test.ts
│   │   │   ├── image-loaders.ts
│   │   │   ├── image-optimize.test.ts
│   │   │   ├── image-optimize.ts
│   │   │   ├── image.tsx
│   │   │   └── index.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── postgrest/
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── playground/
│   │   │   ├── domains.ts
│   │   │   └── pnpm-playground
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── db-types.ts
│   │   │   └── index.server.ts
│   │   ├── supabase/
│   │   │   ├── SQL-TESTS-AI.md
│   │   │   └── tests/
│   │   │       ├── cleanup-builds.sql
│   │   │       ├── latest-builds-domains.sql
│   │   │       ├── latest-builds-projects.sql
│   │   │       └── project-domains.sql
│   │   └── tsconfig.json
│   ├── prisma-client/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── migrations-cli/
│   │   │   ├── README.md
│   │   │   ├── TROUBLESHOOTING.md
│   │   │   ├── args.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands.ts
│   │   │   ├── errors.ts
│   │   │   ├── logger.ts
│   │   │   ├── prisma-migrations.ts
│   │   │   └── umzug.ts
│   │   ├── package.json
│   │   ├── prisma/
│   │   │   ├── migrations/
│   │   │   │   ├── 20220601192603_start/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608130924_/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608130959_adduser/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220608131719_add_user/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220611090740_/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220611091346_add_email/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220616143541_add_projects/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220616143902_userid_not_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220619163536_userid_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624214305_teams/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624215036_remove_userid/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220624235138_users_have_projects/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220714112221_add_assets/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220714114102_remove_size/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220715192633_add_alt/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220716191150_add_more_info_to_asset/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220716192051_make_metadata_not_mandatory/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220717152939_make_width_and_height_float/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220717193140_make_width_and_height_decimal/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220722131820_remove_path/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220722132445_add_location/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220905153337_noop/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220909124449_builds/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220909124542_builds-data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220909131750_builds-cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220912141854_assets-meta/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220912142938_assets-meta-data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220912150542_assets-meta-cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220915143947_breakpoints-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20220915144008_breakpoints-build_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20220915145316_breakpoints-build_cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221021172622_asset_format_notnull/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221021172647_lowercase_domains/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221126165439_design-tokens/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221201075120_user-props/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221208123312_remove-assets-from-project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221218211129_tree_text/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20221227220622_assets-status/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20221230120125_tree_preset_styles/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230106000103_tree_styles/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230106000143_tree_styles_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230115165217_tree_instances/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230115165314_tree_instances_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230119013820_instance-props-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230119181836_tree_props/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230119181858_tree_props_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230120130130_dashboard-project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230120130131_dashboard-project-is-prod/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230123225816_dashboard-project-is-deleted/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230124131218_authorization-tokens/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230127120101_style_sources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230129141714_unused_schema/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230129174218_fill-auth-view-tokens/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230130121014_tree_relations/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130121041_tree_relations_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230130124937_tree_relations_not_null/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130153140_authorization-tokens-fix/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230130160827_build_styles/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230202131409_project-created-at/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230202174408_build_breakpoints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230202174456_build_breakpoints_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230202192437_composite_ids/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230213220858_is-deleted-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227142607_build_style_source_selections/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227142622_build_style_source_selections_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230227180214_build_props/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230227180250_build_props_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228132402_drop_style_source_tree_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228161419_page_root_instance_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228194425_build_instances/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230228194553_build_instances_data/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230228222541_convert-image-style/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230301101527_drop_page_tree_id/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230301101856_drop_tree/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230301134408_convert-background-to-layers/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230309142820_link-target/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230412160008_min-width-remove/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230501151815_file/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230501151941_asset-to-file/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230501153024_asset-file-relation/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230515112405_file_uploader_project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230517133730_file_is_deleted/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230517150043_domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230520112258_drop_breakpoints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230529133454_build_version/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230530132921_deployment/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230530155049_drop_unused_asset_fields/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230605174851_domain-updated-at/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230606165920_deployment-project-domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230606234538_latest-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230610111903_button_children/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230611121710_merge_block_text_components/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230611181439_control_labels/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230619131628_build_data_sources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230702002752_form_data_sources/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20230831150459_add-administrators/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20230911125308_form_action/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20231105075338_add-last-transaction-id/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231108172804_prop_expression/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20231115205820_client-references/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231116173417_product/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231117095612_transaction/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231119153806_transaction-customer-subscription/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231120172840_add-event-type/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231121125755_token-uniq/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231129164239_event-data/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20231211152313_build_resources/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240112011509_folders/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240112155724_nullable-user/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240112155725_user_product_view/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240125182656_calc-domains/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240127230238_project-preview/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240131193159_new_constraints/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240131200102_page_meta_expressions/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240227150630_marketplace/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240229133316_add-approval-status/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240308131249_add-token-rights/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240309212641_page_system_variable/
│   │   │   │   │   ├── migration.ts
│   │   │   │   │   └── schema.prisma
│   │   │   │   ├── 20240315173349_add-approved-marketplace-product/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240530162819_marketplace-token/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240723144019_latest-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240723150501_latest-static-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240725003228_clone_project/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240730131207_clone_project_preview_imagea/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240731170412_create_production_build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240807000548_deleted-project-free-domain/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240809220753_tz/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240916143551_time/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240917152817_pgtap/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240918100751_latest-virtual-build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240920091253_domain-ordering/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20240924174536_cleanup/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20241207052014_can-publish/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250322141808_user_publish_count/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250710163439_restore_development_build/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250810123401_asset_filename_description/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20250913204036_project_tags/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── 20251129093846_add_updated_at_to_latest_build_virtual/
│   │   │   │   │   └── migration.sql
│   │   │   │   ├── migration_lock.toml
│   │   │   │   └── template.txt
│   │   │   └── schema.prisma
│   │   ├── prisma.cjs
│   │   ├── prisma.mjs
│   │   ├── src/
│   │   │   ├── cjs/
│   │   │   │   └── package.json
│   │   │   └── prisma.ts
│   │   └── tsconfig.json
│   ├── project/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── project-domain.ts
│   │   │   │   └── project.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   └── schema.ts
│   │   │   └── trpc/
│   │   │       └── project-router.ts
│   │   └── tsconfig.json
│   ├── project-build/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── db/
│   │   │   │   ├── build.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── pages.ts
│   │   │   │   ├── style-source-selections.ts
│   │   │   │   └── styles.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   ├── graph-utils.test.ts
│   │   │   │   ├── graph-utils.ts
│   │   │   │   ├── marketplace.ts
│   │   │   │   ├── pages-utils.test.ts
│   │   │   │   └── pages-utils.ts
│   │   │   ├── template.tsx
│   │   │   └── types.ts
│   │   └── tsconfig.json
│   ├── react-sdk/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── placeholder.d.ts
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   └── standard-attributes.ts
│   │   │   ├── collection-utils.test.ts
│   │   │   ├── collection-utils.ts
│   │   │   ├── component-generator.test.tsx
│   │   │   ├── component-generator.ts
│   │   │   ├── components/
│   │   │   │   └── components-utils.ts
│   │   │   ├── context.tsx
│   │   │   ├── hook.test.ts
│   │   │   ├── hook.ts
│   │   │   ├── index.ts
│   │   │   ├── page-settings-canonical-link.tsx
│   │   │   ├── page-settings-meta.tsx
│   │   │   ├── page-settings-title.tsx
│   │   │   ├── props.test.ts
│   │   │   ├── props.ts
│   │   │   ├── remix.test.ts
│   │   │   ├── remix.ts
│   │   │   ├── runtime.ts
│   │   │   └── variable-state.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk/
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── normalize.css.ts
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── normalize.css.ts
│   │   │   │   └── tags.ts
│   │   │   ├── assets.test.ts
│   │   │   ├── assets.ts
│   │   │   ├── core-metas.ts
│   │   │   ├── core-templates.tsx
│   │   │   ├── css.test.tsx
│   │   │   ├── css.ts
│   │   │   ├── expression.test.ts
│   │   │   ├── expression.ts
│   │   │   ├── form-fields.ts
│   │   │   ├── index.ts
│   │   │   ├── instances-utils.test.tsx
│   │   │   ├── instances-utils.ts
│   │   │   ├── normalize.css
│   │   │   ├── page-meta-generator.test.ts
│   │   │   ├── page-meta-generator.ts
│   │   │   ├── page-utils.test.ts
│   │   │   ├── page-utils.ts
│   │   │   ├── resource-loader.test.ts
│   │   │   ├── resource-loader.ts
│   │   │   ├── resources-generator.test.tsx
│   │   │   ├── resources-generator.ts
│   │   │   ├── router-path-test-data.ts
│   │   │   ├── router-paths.test.ts
│   │   │   ├── runtime.ts
│   │   │   ├── schema/
│   │   │   │   ├── animation-schema.ts
│   │   │   │   ├── assets.ts
│   │   │   │   ├── breakpoints.test.ts
│   │   │   │   ├── breakpoints.ts
│   │   │   │   ├── component-meta.ts
│   │   │   │   ├── data-sources.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── instances.ts
│   │   │   │   ├── pages.test.ts
│   │   │   │   ├── pages.ts
│   │   │   │   ├── prop-meta.ts
│   │   │   │   ├── props.ts
│   │   │   │   ├── resources.ts
│   │   │   │   ├── style-source-selections.ts
│   │   │   │   ├── style-sources.ts
│   │   │   │   ├── styles.ts
│   │   │   │   └── webstudio.ts
│   │   │   ├── scope.test.ts
│   │   │   ├── scope.ts
│   │   │   ├── to-string.ts
│   │   │   ├── url-pattern.test.ts
│   │   │   └── url-pattern.ts
│   │   ├── tsconfig.dts.json
│   │   ├── tsconfig.json
│   │   └── tsconfig.typecheck.json
│   ├── sdk-cli/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   └── generate-stories.ts
│   │   └── tsconfig.json
│   ├── sdk-components-animation/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── animate-children.props.ts
│   │   │   │   ├── animate-text.props.ts
│   │   │   │   ├── stagger-animation.props.ts
│   │   │   │   └── video-animation.props.ts
│   │   │   ├── animate-children.tsx
│   │   │   ├── animate-children.ws.ts
│   │   │   ├── animate-text.tsx
│   │   │   ├── animate-text.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── hooks.ts
│   │   │   ├── metas.ts
│   │   │   ├── shared/
│   │   │   │   ├── create-progress-animation.tsx
│   │   │   │   ├── meta.ts
│   │   │   │   └── proxy.ts
│   │   │   ├── stagger-animation.tsx
│   │   │   ├── stagger-animation.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── video-animation.template.tsx
│   │   │   ├── video-animation.tsx
│   │   │   └── video-animation.ws.ts
│   │   ├── tsconfig.dts.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.typecheck.json
│   │   ├── vite.config.ts
│   │   └── vitest.config.ts
│   ├── sdk-components-react/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── LICENSE
│   │   │   ├── __generated__/
│   │   │   │   ├── blockquote.props.ts
│   │   │   │   ├── blockquote.stories.tsx
│   │   │   │   ├── body.props.ts
│   │   │   │   ├── bold.props.ts
│   │   │   │   ├── box.props.ts
│   │   │   │   ├── button.props.ts
│   │   │   │   ├── button.stories.tsx
│   │   │   │   ├── checkbox.props.ts
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── code-text.props.ts
│   │   │   │   ├── content-embed.stories.tsx
│   │   │   │   ├── form.props.ts
│   │   │   │   ├── form.stories.tsx
│   │   │   │   ├── fragment.props.ts
│   │   │   │   ├── head-link.props.ts
│   │   │   │   ├── head-meta.props.ts
│   │   │   │   ├── head-slot.props.ts
│   │   │   │   ├── head-title.props.ts
│   │   │   │   ├── heading.props.ts
│   │   │   │   ├── heading.stories.tsx
│   │   │   │   ├── html-embed.props.ts
│   │   │   │   ├── image.props.ts
│   │   │   │   ├── input.props.ts
│   │   │   │   ├── italic.props.ts
│   │   │   │   ├── label.props.ts
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── link.props.ts
│   │   │   │   ├── link.stories.tsx
│   │   │   │   ├── list-item.props.ts
│   │   │   │   ├── list-item.stories.tsx
│   │   │   │   ├── list.props.ts
│   │   │   │   ├── list.stories.tsx
│   │   │   │   ├── markdown-embed.props.ts
│   │   │   │   ├── markdown-embed.stories.tsx
│   │   │   │   ├── option.props.ts
│   │   │   │   ├── paragraph.props.ts
│   │   │   │   ├── paragraph.stories.tsx
│   │   │   │   ├── radio-button.props.ts
│   │   │   │   ├── radio-button.stories.tsx
│   │   │   │   ├── rich-text-link.props.ts
│   │   │   │   ├── select.props.ts
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── separator.props.ts
│   │   │   │   ├── slot.props.ts
│   │   │   │   ├── span.props.ts
│   │   │   │   ├── subscript.props.ts
│   │   │   │   ├── superscript.props.ts
│   │   │   │   ├── text.props.ts
│   │   │   │   ├── text.stories.tsx
│   │   │   │   ├── textarea.props.ts
│   │   │   │   ├── time.props.ts
│   │   │   │   ├── video.props.ts
│   │   │   │   ├── vimeo-play-button.props.ts
│   │   │   │   ├── vimeo-preview-image.props.ts
│   │   │   │   ├── vimeo-spinner.props.ts
│   │   │   │   ├── vimeo.props.ts
│   │   │   │   ├── vimeo.stories.tsx
│   │   │   │   ├── webhook-form.props.ts
│   │   │   │   ├── xml-node.props.ts
│   │   │   │   ├── xml-time.props.ts
│   │   │   │   ├── you-tube.stories.tsx
│   │   │   │   └── youtube.props.ts
│   │   │   ├── blockquote.tsx
│   │   │   ├── blockquote.ws.ts
│   │   │   ├── body.tsx
│   │   │   ├── body.ws.ts
│   │   │   ├── bold.tsx
│   │   │   ├── bold.ws.ts
│   │   │   ├── box.tsx
│   │   │   ├── box.ws.ts
│   │   │   ├── button.tsx
│   │   │   ├── button.ws.ts
│   │   │   ├── checkbox.tsx
│   │   │   ├── checkbox.ws.ts
│   │   │   ├── code-text.tsx
│   │   │   ├── code-text.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── content-embed.template.tsx
│   │   │   ├── form.tsx
│   │   │   ├── form.ws.ts
│   │   │   ├── fragment.tsx
│   │   │   ├── fragment.ws.ts
│   │   │   ├── head-link.tsx
│   │   │   ├── head-link.ws.ts
│   │   │   ├── head-meta.tsx
│   │   │   ├── head-meta.ws.ts
│   │   │   ├── head-slot.template.tsx
│   │   │   ├── head-slot.tsx
│   │   │   ├── head-slot.ws.ts
│   │   │   ├── head-title.tsx
│   │   │   ├── head-title.ws.ts
│   │   │   ├── heading.tsx
│   │   │   ├── heading.ws.ts
│   │   │   ├── hooks.ts
│   │   │   ├── html-embed-patchers.ts
│   │   │   ├── html-embed.test.tsx
│   │   │   ├── html-embed.tsx
│   │   │   ├── html-embed.ws.ts
│   │   │   ├── image.tsx
│   │   │   ├── image.ws.ts
│   │   │   ├── input.tsx
│   │   │   ├── input.ws.ts
│   │   │   ├── italic.tsx
│   │   │   ├── italic.ws.ts
│   │   │   ├── label.tsx
│   │   │   ├── label.ws.ts
│   │   │   ├── link.tsx
│   │   │   ├── link.ws.ts
│   │   │   ├── list-item.tsx
│   │   │   ├── list-item.ws.ts
│   │   │   ├── list.tsx
│   │   │   ├── list.ws.ts
│   │   │   ├── markdown-embed.template.tsx
│   │   │   ├── markdown-embed.tsx
│   │   │   ├── markdown-embed.ws.ts
│   │   │   ├── metas.ts
│   │   │   ├── option.tsx
│   │   │   ├── option.ws.ts
│   │   │   ├── paragraph.tsx
│   │   │   ├── paragraph.ws.ts
│   │   │   ├── radio-button.tsx
│   │   │   ├── radio-button.ws.ts
│   │   │   ├── rich-text-link.tsx
│   │   │   ├── rich-text-link.ws.ts
│   │   │   ├── select.tsx
│   │   │   ├── select.ws.ts
│   │   │   ├── separator.tsx
│   │   │   ├── separator.ws.ts
│   │   │   ├── shared/
│   │   │   │   └── video.ts
│   │   │   ├── slot.tsx
│   │   │   ├── slot.ws.ts
│   │   │   ├── span.tsx
│   │   │   ├── span.ws.ts
│   │   │   ├── subscript.tsx
│   │   │   ├── subscript.ws.ts
│   │   │   ├── superscript.tsx
│   │   │   ├── superscript.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── test-utils/
│   │   │   │   └── cartesian.ts
│   │   │   ├── text.tsx
│   │   │   ├── text.ws.ts
│   │   │   ├── textarea.tsx
│   │   │   ├── textarea.ws.ts
│   │   │   ├── time.test.ts
│   │   │   ├── time.tsx
│   │   │   ├── time.ws.ts
│   │   │   ├── video.tsx
│   │   │   ├── video.ws.ts
│   │   │   ├── vimeo-play-button.tsx
│   │   │   ├── vimeo-play-button.ws.ts
│   │   │   ├── vimeo-preview-image.tsx
│   │   │   ├── vimeo-preview-image.ws.ts
│   │   │   ├── vimeo-spinner.tsx
│   │   │   ├── vimeo-spinner.ws.ts
│   │   │   ├── vimeo.template.tsx
│   │   │   ├── vimeo.tsx
│   │   │   ├── vimeo.ws.ts
│   │   │   ├── webhook-form.template.tsx
│   │   │   ├── webhook-form.tsx
│   │   │   ├── webhook-form.ws.ts
│   │   │   ├── xml-node.stories.tsx
│   │   │   ├── xml-node.tsx
│   │   │   ├── xml-node.ws.ts
│   │   │   ├── xml-time.tsx
│   │   │   ├── xml-time.ws.ts
│   │   │   ├── youtube.template.tsx
│   │   │   ├── youtube.tsx
│   │   │   └── youtube.ws.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-radix/
│   │   ├── LICENSE
│   │   ├── LICENSE-3RD-PARTY
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── __generated__/
│   │   │   │   ├── accordion.props.ts
│   │   │   │   ├── accordion.stories.tsx
│   │   │   │   ├── checkbox.props.ts
│   │   │   │   ├── checkbox.stories.tsx
│   │   │   │   ├── collapsible.props.ts
│   │   │   │   ├── collapsible.stories.tsx
│   │   │   │   ├── dialog.props.ts
│   │   │   │   ├── dialog.stories.tsx
│   │   │   │   ├── label.props.ts
│   │   │   │   ├── label.stories.tsx
│   │   │   │   ├── navigation-menu.props.ts
│   │   │   │   ├── navigation-menu.stories.tsx
│   │   │   │   ├── popover.props.ts
│   │   │   │   ├── popover.stories.tsx
│   │   │   │   ├── radio-group.props.ts
│   │   │   │   ├── radio-group.stories.tsx
│   │   │   │   ├── select.props.ts
│   │   │   │   ├── select.stories.tsx
│   │   │   │   ├── sheet.stories.tsx
│   │   │   │   ├── switch.props.ts
│   │   │   │   ├── switch.stories.tsx
│   │   │   │   ├── tabs.props.ts
│   │   │   │   ├── tabs.stories.tsx
│   │   │   │   ├── tooltip.props.ts
│   │   │   │   └── tooltip.stories.tsx
│   │   │   ├── accordion.template.tsx
│   │   │   ├── accordion.tsx
│   │   │   ├── accordion.ws.ts
│   │   │   ├── checkbox.template.tsx
│   │   │   ├── checkbox.tsx
│   │   │   ├── checkbox.ws.ts
│   │   │   ├── collapsible.template.tsx
│   │   │   ├── collapsible.tsx
│   │   │   ├── collapsible.ws.ts
│   │   │   ├── components.ts
│   │   │   ├── dialog.template.tsx
│   │   │   ├── dialog.tsx
│   │   │   ├── dialog.ws.ts
│   │   │   ├── hooks.ts
│   │   │   ├── label.template.tsx
│   │   │   ├── label.tsx
│   │   │   ├── label.ws.ts
│   │   │   ├── metas.ts
│   │   │   ├── navigation-menu.template.tsx
│   │   │   ├── navigation-menu.tsx
│   │   │   ├── navigation-menu.ws.ts
│   │   │   ├── popover.template.tsx
│   │   │   ├── popover.tsx
│   │   │   ├── popover.ws.ts
│   │   │   ├── props-descriptions.ts
│   │   │   ├── radio-group.template.tsx
│   │   │   ├── radio-group.tsx
│   │   │   ├── radio-group.ws.ts
│   │   │   ├── select.template.tsx
│   │   │   ├── select.tsx
│   │   │   ├── select.ws.ts
│   │   │   ├── shared/
│   │   │   │   ├── meta.ts
│   │   │   │   ├── preset-styles.ts
│   │   │   │   ├── proxy.ts
│   │   │   │   ├── styles.ts
│   │   │   │   └── theme.ts
│   │   │   ├── sheet.template.tsx
│   │   │   ├── switch.template.tsx
│   │   │   ├── switch.tsx
│   │   │   ├── switch.ws.ts
│   │   │   ├── tabs.template.tsx
│   │   │   ├── tabs.tsx
│   │   │   ├── tabs.ws.ts
│   │   │   ├── templates.ts
│   │   │   ├── tooltip.template.tsx
│   │   │   ├── tooltip.tsx
│   │   │   └── tooltip.ws.ts
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-remix/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── body.tsx
│   │   │   ├── components.ts
│   │   │   ├── link.tsx
│   │   │   ├── remix-form.tsx
│   │   │   ├── rich-text-link.tsx
│   │   │   └── webhook-form.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── sdk-components-react-router/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── body.tsx
│   │   │   ├── components.ts
│   │   │   ├── link.tsx
│   │   │   ├── metas.ts
│   │   │   ├── remix-form.tsx
│   │   │   ├── rich-text-link.tsx
│   │   │   └── webhook-form.tsx
│   │   ├── tsconfig.dts.json
│   │   └── tsconfig.json
│   ├── template/
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── css.test.ts
│   │   │   ├── css.ts
│   │   │   ├── index.ts
│   │   │   ├── jsx.test.tsx
│   │   │   ├── jsx.ts
│   │   │   └── template.ts
│   │   └── tsconfig.json
│   ├── trpc-interface/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── authorize/
│   │   │   │   └── project.server.ts
│   │   │   ├── context/
│   │   │   │   ├── context.server.ts
│   │   │   │   ├── errors.server.ts
│   │   │   │   └── router.server.ts
│   │   │   ├── index.server.ts
│   │   │   ├── index.ts
│   │   │   ├── shared/
│   │   │   │   ├── client.ts
│   │   │   │   ├── deployment.ts
│   │   │   │   ├── domain.ts
│   │   │   │   ├── shared-router.ts
│   │   │   │   └── trpc.ts
│   │   │   ├── trpc-caller-link.test.ts
│   │   │   └── trpc-caller-link.ts
│   │   └── tsconfig.json
│   └── tsconfig/
│       ├── README.md
│       ├── base.json
│       └── package.json
├── patches/
│   ├── @radix-ui__react-scroll-area@1.0.5.patch
│   ├── @remix-run__dev.patch
│   └── @stitches__react@1.3.1-1.patch
├── pnpm-workspace.yaml
├── release.sh
├── submodules.sh
├── vercel.json
├── vite.sdk-components.config.ts
└── vitest.config.ts
Download .txt
SYMBOL INDEX (1665 symbols across 624 files)

FILE: .storybook/main.ts
  method viteFinal (line 77) | async viteFinal(config) {

FILE: @types/canvas-iframe.d.ts
  type IframeHTMLAttributes (line 2) | interface IframeHTMLAttributes {

FILE: @types/content.d.ts
  type GlobalEventHandlersEventMap (line 7) | interface GlobalEventHandlersEventMap {

FILE: @types/css-tree.d.ts
  type SourceLocation (line 9) | interface SourceLocation {
  type BaseNode (line 15) | interface BaseNode {
  type ListItem (line 21) | interface ListItem<T> {
  class List (line 27) | class List<T> implements Iterable<T> {
  type AnPlusB (line 66) | interface AnPlusB extends BaseNode {
  type Atrule (line 71) | interface Atrule extends BaseNode {
  type AtrulePrelude (line 77) | interface AtrulePrelude extends BaseNode {
  type AttributeSelector (line 81) | interface AttributeSelector extends BaseNode {
  type Block (line 88) | interface Block extends BaseNode {
  type Brackets (line 92) | interface Brackets extends BaseNode {
  type CDC (line 96) | interface CDC extends BaseNode {
  type CDO (line 99) | interface CDO extends BaseNode {
  type ClassSelector (line 102) | interface ClassSelector extends BaseNode {
  type Combinator (line 106) | interface Combinator extends BaseNode {
  type Comment (line 110) | interface Comment extends BaseNode {
  type Condition (line 114) | interface Condition extends BaseNode {
  type Declaration (line 125) | interface Declaration extends BaseNode {
  type DeclarationList (line 131) | interface DeclarationList extends BaseNode {
  type Dimension (line 135) | interface Dimension extends BaseNode {
  type Feature (line 140) | interface Feature extends BaseNode {
  type FeatureFunction (line 146) | interface FeatureFunction extends BaseNode {
  type FeatureRange (line 152) | interface FeatureRange extends BaseNode {
  type FunctionNode (line 161) | interface FunctionNode extends BaseNode {
  type GeneralEnclosed (line 166) | interface GeneralEnclosed extends BaseNode {
  type Hash (line 172) | interface Hash extends BaseNode {
  type IdSelector (line 176) | interface IdSelector extends BaseNode {
  type Identifier (line 180) | interface Identifier extends BaseNode {
  type Layer (line 184) | interface Layer extends BaseNode {
  type LayerList (line 188) | interface LayerList extends BaseNode {
  type MediaQuery (line 192) | interface MediaQuery extends BaseNode {
  type MediaQueryList (line 198) | interface MediaQueryList extends BaseNode {
  type NestingSelector (line 202) | interface NestingSelector extends BaseNode {
  type Nth (line 205) | interface Nth extends BaseNode {
  type NumberNode (line 210) | interface NumberNode extends BaseNode {
  type Operator (line 214) | interface Operator extends BaseNode {
  type Parentheses (line 218) | interface Parentheses extends BaseNode {
  type Percentage (line 222) | interface Percentage extends BaseNode {
  type PseudoClassSelector (line 226) | interface PseudoClassSelector extends BaseNode {
  type PseudoElementSelector (line 231) | interface PseudoElementSelector extends BaseNode {
  type Ratio (line 236) | interface Ratio extends BaseNode {
  type Raw (line 241) | interface Raw extends BaseNode {
  type Rule (line 245) | interface Rule extends BaseNode {
  type Scope (line 250) | interface Scope extends BaseNode {
  type Selector (line 255) | interface Selector extends BaseNode {
  type SelectorList (line 268) | interface SelectorList extends BaseNode {
  type StringNode (line 272) | interface StringNode extends BaseNode {
  type StyleSheet (line 276) | interface StyleSheet extends BaseNode {
  type SupportsDeclaration (line 280) | interface SupportsDeclaration extends BaseNode {
  type TypeSelector (line 284) | interface TypeSelector extends BaseNode {
  type UnicodeRange (line 288) | interface UnicodeRange extends BaseNode {
  type Url (line 292) | interface Url extends BaseNode {
  type Value (line 296) | interface Value extends BaseNode {
  type WhiteSpace (line 300) | interface WhiteSpace extends BaseNode {
  type CssNode (line 305) | type CssNode =
  type CssNodePlain (line 357) | type CssNodePlain = Omit<CssNode, "children" | "loc"> & {
  type ParseContext (line 365) | type ParseContext =
  type ParseOptions (line 379) | interface ParseOptions {
  type WalkHandler (line 472) | type WalkHandler = (
  type WalkOptions (line 477) | interface WalkOptions {
  type PropertyInfo (line 495) | interface PropertyInfo {
  type KeywordInfo (line 505) | interface KeywordInfo {
  type Base (line 532) | interface Base {
  type Group (line 535) | interface Group extends Base {
  type Keyword (line 542) | interface Keyword extends Base {
  type Function (line 546) | interface Function extends Base {
  type String (line 550) | interface String extends Base {
  type Property (line 554) | interface Property extends Base {
  type Type (line 558) | interface Type extends Base {
  type Range (line 563) | interface Range extends Base {
  type Multiplier (line 568) | interface Multiplier extends Base {
  type Node (line 576) | type Node =
  type AtruleSyntaxConfig (line 608) | interface AtruleSyntaxConfig {
  type LexerConfig (line 616) | interface LexerConfig {
  type MatchResult (line 631) | interface MatchResult {
  type FragmentResult (line 641) | interface FragmentResult {
  class Lexer (line 646) | class Lexer {

FILE: @types/navigator.d.ts
  type Navigator (line 1) | interface Navigator {

FILE: @types/scroll-timeline.d.ts
  type ScrollAxis (line 1) | type ScrollAxis = "block" | "inline" | "x" | "y";
  type ScrollTimelineOptions (line 3) | interface ScrollTimelineOptions {
  class ScrollTimeline (line 8) | class ScrollTimeline extends AnimationTimeline {
  type ViewTimelineOptions (line 12) | interface ViewTimelineOptions {
  class ViewTimeline (line 18) | class ViewTimeline extends ScrollTimeline {

FILE: apps/builder/app/auth/login.tsx
  type LoginProps (line 22) | type LoginProps = {

FILE: apps/builder/app/builder/builder.tsx
  type SidePanelProps (line 88) | type SidePanelProps = {
  type ChromeWrapperProps (line 139) | type ChromeWrapperProps = {
  type BuilderProps (line 225) | type BuilderProps = {
  method onReady (line 263) | onReady() {

FILE: apps/builder/app/builder/features/breakpoints/breakpoints-editor.tsx
  type BreakpointEditorItemProps (line 29) | type BreakpointEditorItemProps = {
  type BreakpointsEditorProps (line 180) | type BreakpointsEditorProps = {

FILE: apps/builder/app/builder/features/breakpoints/breakpoints-menu.tsx
  type BreakpointsMenuProps (line 20) | type BreakpointsMenuProps = {

FILE: apps/builder/app/builder/features/breakpoints/condition-input.tsx
  constant PREDEFINED_CONDITIONS (line 4) | const PREDEFINED_CONDITIONS = [
  type Condition (line 122) | type Condition = { value: string; label: string; description?: string };
  type ConditionInputProps (line 124) | type ConditionInputProps = {

FILE: apps/builder/app/builder/features/breakpoints/confirmation-dialog.tsx
  type ConfirmationDialogProps (line 13) | type ConfirmationDialogProps = {

FILE: apps/builder/app/builder/features/breakpoints/width-input.tsx
  method onChange (line 64) | onChange() {
  method onKeyDown (line 67) | onKeyDown(event: KeyboardEvent<HTMLInputElement>) {
  method onBlur (line 78) | onBlur() {

FILE: apps/builder/app/builder/features/command-panel/groups/breakpoints-group.tsx
  type BreakpointOption (line 20) | type BreakpointOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/commands-group.tsx
  type CommandOption (line 15) | type CommandOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/components-group.tsx
  type ComponentOption (line 34) | type ComponentOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/convert-group.tsx
  type ConvertOption (line 36) | type ConvertOption = {

FILE: apps/builder/app/builder/features/command-panel/groups/css-variables-group.tsx
  type CssVariableOption (line 34) | type CssVariableOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/data-variables-group.tsx
  type DataVariableOption (line 31) | type DataVariableOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/duplicate-tokens-group.tsx
  type DuplicateTokenOption (line 38) | type DuplicateTokenOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/index.ts
  type Option (line 40) | type Option =
  type OptionByType (line 52) | type OptionByType<T extends Option["type"]> = Extract<
  type GroupComponent (line 92) | type GroupComponent<T extends Option["type"]> = (props: {

FILE: apps/builder/app/builder/features/command-panel/groups/instances-group.tsx
  type InstanceOption (line 22) | type InstanceOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/pages-group.tsx
  type PageOption (line 17) | type PageOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/tags-group.tsx
  type TagOption (line 24) | type TagOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/tokens-group.tsx
  type TokenOption (line 32) | type TokenOption = BaseOption & {

FILE: apps/builder/app/builder/features/command-panel/groups/wrap-group.tsx
  type WrapOption (line 42) | type WrapOption = {

FILE: apps/builder/app/builder/features/command-panel/shared/component-utils.ts
  type ComponentMetaLike (line 20) | type ComponentMetaLike = {

FILE: apps/builder/app/builder/features/command-panel/shared/instance-list.tsx
  type InstanceOption (line 27) | type InstanceOption = {
  type InstanceListProps (line 34) | type InstanceListProps = {

FILE: apps/builder/app/builder/features/command-panel/shared/instance-path-footer.tsx
  type InstancePathFooterProps (line 8) | type InstancePathFooterProps = {

FILE: apps/builder/app/builder/features/command-panel/shared/types.ts
  type BaseOption (line 1) | type BaseOption = {

FILE: apps/builder/app/builder/features/components/components.tsx
  type Meta (line 46) | type Meta = {
  type Groups (line 102) | type Groups = Array<{
  method onMove (line 218) | onMove({ direction }) {

FILE: apps/builder/app/builder/features/components/use-draggable.tsx
  method elementToData (line 101) | elementToData(element) {
  method onStart (line 104) | onStart({ data: componentName }) {
  method onEnd (line 126) | onEnd({ isCanceled }) {

FILE: apps/builder/app/builder/features/keyboard-shortcuts-dialog/keyboard-shortcuts-dialog.tsx
  type ValidCommandName (line 72) | type ValidCommandName = (typeof allShortcuts)[number]["name"];
  type ValidCategory (line 122) | type ValidCategory = keyof typeof groupedCommands;

FILE: apps/builder/app/builder/features/marketplace/card.tsx
  type ThumbnailProps (line 54) | type ThumbnailProps = {
  type CardProps (line 93) | type CardProps = {

FILE: apps/builder/app/builder/features/marketplace/overview.tsx
  method onPress (line 35) | onPress() {

FILE: apps/builder/app/builder/features/marketplace/templates.tsx
  type TemplateData (line 106) | type TemplateData = {

FILE: apps/builder/app/builder/features/navigator/navigator-tree.tsx
  type TreeItemAncestor (line 75) | type TreeItemAncestor =
  type TreeItem (line 83) | type TreeItem = {

FILE: apps/builder/app/builder/features/pages/confirmation-dialogs.tsx
  type DeletePageConfirmationDialogProps (line 13) | type DeletePageConfirmationDialogProps = {
  type DeleteFolderConfirmationDialogProps (line 62) | type DeleteFolderConfirmationDialogProps = {

FILE: apps/builder/app/builder/features/pages/custom-metadata.tsx
  type Meta (line 22) | type Meta = {
  type CustomMetadataProps (line 27) | type CustomMetadataProps = {

FILE: apps/builder/app/builder/features/pages/folder-settings.tsx
  type Values (line 43) | type Values = z.infer<typeof Values>;
  type FieldName (line 45) | type FieldName = keyof Values;
  type Errors (line 47) | type Errors = {

FILE: apps/builder/app/builder/features/pages/image-info.tsx
  type ImageInfoProps (line 18) | type ImageInfoProps = {

FILE: apps/builder/app/builder/features/pages/page-context-menu.tsx
  type PageContextMenuProps (line 10) | type PageContextMenuProps = {

FILE: apps/builder/app/builder/features/pages/page-settings.tsx
  type FieldName (line 140) | type FieldName = (typeof fieldNames)[number];
  type Values (line 142) | type Values = typeof fieldDefaultValues;
  type OnChange (line 144) | type OnChange = (
  type Errors (line 153) | type Errors = {

FILE: apps/builder/app/builder/features/pages/page-utils.test.ts
  function f (line 59) | function f(id: string, slug?: unknown, children?: unknown) {

FILE: apps/builder/app/builder/features/pages/page-utils.ts
  type DropTarget (line 433) | type DropTarget = {
  type TreeDropTarget (line 440) | type TreeDropTarget = {

FILE: apps/builder/app/builder/features/pages/pages.tsx
  type PagesTreeItem (line 145) | type PagesTreeItem =
  type DropTarget (line 167) | type DropTarget = {

FILE: apps/builder/app/builder/features/pages/search-preview.tsx
  type SearchPreviewProps (line 8) | type SearchPreviewProps = {

FILE: apps/builder/app/builder/features/pages/social-preview.tsx
  type SocialPreviewProps (line 5) | type SocialPreviewProps = {

FILE: apps/builder/app/builder/features/publish/add-domain.tsx
  type DomainsAddProps (line 19) | type DomainsAddProps = {

FILE: apps/builder/app/builder/features/publish/domain-checkbox.tsx
  type DomainCheckboxProps (line 17) | interface DomainCheckboxProps {

FILE: apps/builder/app/builder/features/publish/domains.tsx
  type Domain (line 44) | type Domain = Project["domainsVirtual"][number];
  type DomainStatus (line 46) | type DomainStatus = Domain["status"];
  constant PENDING_TIMEOUT (line 59) | const PENDING_TIMEOUT =
  type DomainsProps (line 545) | type DomainsProps = {

FILE: apps/builder/app/builder/features/publish/entri.tsx
  type DnsRecord (line 18) | type DnsRecord = {
  type EntriCloseEvent (line 25) | type EntriCloseEvent = CustomEvent<entri.EntriCloseEventDetail>;
  type WindowEventMap (line 29) | interface WindowEventMap {
  type EntriProps (line 46) | type EntriProps = {

FILE: apps/builder/app/builder/features/publish/publish.tsx
  type ChangeProjectDomainProps (line 89) | type ChangeProjectDomainProps = {
  type DeployTarget (line 994) | type DeployTarget = {
  type DeployTargets (line 1027) | type DeployTargets = keyof typeof deployTargets;
  type PublishProps (line 1208) | type PublishProps = {

FILE: apps/builder/app/builder/features/settings-panel/controls/code.tsx
  type Error (line 71) | type Error = { message: string; value: string; expected?: string };

FILE: apps/builder/app/builder/features/settings-panel/controls/select-asset.tsx
  type AssetControlProps (line 22) | type AssetControlProps = ControlProps<unknown>;
  type Props (line 24) | type Props = {

FILE: apps/builder/app/builder/features/settings-panel/controls/url.tsx
  type UrlControlProps (line 48) | type UrlControlProps = ControlProps<"url">;
  type BaseControlProps (line 50) | type BaseControlProps = {
  type Mode (line 429) | type Mode = keyof typeof modes;

FILE: apps/builder/app/builder/features/settings-panel/curl.ts
  type CurlRequest (line 28) | type CurlRequest = Pick<

FILE: apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx
  type ValidatedCssValueInputProps (line 113) | type ValidatedCssValueInputProps<T> = Omit<
  type AnimationPanelContentProps (line 329) | type AnimationPanelContentProps = {

FILE: apps/builder/app/builder/features/settings-panel/props-section/animation/animation-transforms.tsx
  constant CONTROLS_GAP (line 37) | const CONTROLS_GAP = 4 + 16 + 4;

FILE: apps/builder/app/builder/features/settings-panel/props-section/animation/animations-select.tsx
  type AnimationsSelectProps (line 58) | type AnimationsSelectProps = {

FILE: apps/builder/app/builder/features/settings-panel/props-section/props-section.tsx
  type Item (line 48) | type Item = {
  type PropsSectionProps (line 192) | type PropsSectionProps = {

FILE: apps/builder/app/builder/features/settings-panel/props-section/use-props-logic.ts
  type PropOrName (line 28) | type PropOrName = { prop?: Prop; propName: string };
  type PropAndMeta (line 30) | type PropAndMeta = {
  type UsePropsLogicInput (line 133) | type UsePropsLogicInput = {

FILE: apps/builder/app/builder/features/settings-panel/resource-panel.tsx
  type PanelApi (line 643) | type PanelApi = {
  type BodyType (line 647) | type BodyType = undefined | "text" | "json";

FILE: apps/builder/app/builder/features/settings-panel/shared.tsx
  type PropValue (line 68) | type PropValue =
  type PropMetaByControl (line 85) | type PropMetaByControl<Control> = Control extends string
  type ControlProps (line 88) | type ControlProps<Control> = {
  type LabelProps (line 115) | type LabelProps = ComponentPropsWithoutRef<typeof BaseLabel> & {
  type LayoutProps (line 253) | type LayoutProps = {
  type BindingState (line 378) | type BindingState = {
  type Attribute (line 430) | type Attribute = (typeof ariaAttributes)[number];

FILE: apps/builder/app/builder/features/settings-panel/variable-popover.tsx
  type VariableType (line 178) | type VariableType =
  type PanelApi (line 279) | type PanelApi = {

FILE: apps/builder/app/builder/features/style-panel/controls/font-family/font-family-control.tsx
  type Item (line 19) | type Item = { value: string; label?: string };

FILE: apps/builder/app/builder/features/style-panel/controls/image/image-control.tsx
  type IntermediateValue (line 28) | type IntermediateValue = {

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/background-code-editor.tsx
  type IntermediateValue (line 19) | type IntermediateValue = {
  type BackgroundCodeEditorProps (line 27) | type BackgroundCodeEditorProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/background-content.tsx
  type BackgroundTypeOption (line 64) | type BackgroundTypeOption = {
  type BackgroundTypeToggleProps (line 121) | type BackgroundTypeToggleProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/background-gradient.tsx
  type RadialSizeOption (line 102) | type RadialSizeOption = (typeof radialSizeOptions)[number];
  type GradientEditorApplyFn (line 127) | type GradientEditorApplyFn = (
  type GradientPickerSectionProps (line 304) | type GradientPickerSectionProps = {
  type OtherGradientPropertiesSectionProps (line 392) | type OtherGradientPropertiesSectionProps = {
  type SolidColorControlsProps (line 642) | type SolidColorControlsProps = {
  type GradientStopControlsProps (line 705) | type GradientStopControlsProps = {
  type GradientPositionControlsProps (line 1037) | type GradientPositionControlsProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/background-position.tsx
  type AxisOption (line 37) | type AxisOption =
  type AxisControlProps (line 42) | type AxisControlProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/background-thumbnail.tsx
  type RepeatedProperty (line 124) | type RepeatedProperty = (typeof repeatedProperties)[number];

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/gradient-utils.test.ts
  type IntermediateColorValue (line 613) | type IntermediateColorValue = { type: "intermediate"; value: string };

FILE: apps/builder/app/builder/features/style-panel/sections/backgrounds/gradient-utils.ts
  type GradientType (line 34) | type GradientType = "linear" | "conic" | "radial";
  type PercentUnitValue (line 35) | type PercentUnitValue = UnitValue & { unit: "%" };
  type NormalizedGradient (line 36) | type NormalizedGradient = {
  type IntermediateColorValue (line 40) | type IntermediateColorValue = {
  type AngleUnit (line 76) | type AngleUnit = (typeof angleUnitTokens)[number];
  type CreateDefaultGradient (line 276) | type CreateDefaultGradient = {
  type AngleUnitValue (line 596) | type AngleUnitValue = UnitValue & { unit: AngleUnit };
  type AngleValue (line 597) | type AngleValue = AngleUnitValue | VarValue;
  type ReverseStopsResolution (line 937) | type ReverseStopsResolution<T extends ParsedGradient> =
  type StopPositionUpdateResolution (line 976) | type StopPositionUpdateResolution =
  type StopHintUpdateResolution (line 1011) | type StopHintUpdateResolution =
  type BackgroundType (line 1173) | type BackgroundType =
  type GradientByType (line 1247) | type GradientByType<T extends GradientType> = Extract<

FILE: apps/builder/app/builder/features/style-panel/sections/grid-child/grid-child.tsx
  type PositionMode (line 58) | type PositionMode = "auto" | "area" | "manual";

FILE: apps/builder/app/builder/features/style-panel/sections/layout/layout.tsx
  method onClick (line 105) | onClick(event) {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/alignment-ui.tsx
  type AlignmentVisualProps (line 88) | type AlignmentVisualProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/constants.ts
  constant DEFAULT_GRID_TRACK_COUNT (line 4) | const DEFAULT_GRID_TRACK_COUNT = 2;
  constant DEFAULT_GRID_GAP (line 9) | const DEFAULT_GRID_GAP = 16;

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/grid-area-picker.tsx
  type GridAreaPickerProps (line 176) | type GridAreaPickerProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/grid-areas.tsx
  type AreaEditorProps (line 222) | type AreaEditorProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/grid-generator.tsx
  type GridGeneratorSelectorProps (line 85) | type GridGeneratorSelectorProps = {
  type GridPreset (line 153) | type GridPreset = {
  type GridPresetsPickerProps (line 235) | type GridPresetsPickerProps = {
  type FillGridInput (line 287) | type FillGridInput = {
  type FillGridItem (line 293) | type FillGridItem = {
  type GridGeneratorProps (line 374) | type GridGeneratorProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/grid-position-inputs.tsx
  type GridPosition (line 9) | type GridPosition = {
  type GridPositionValidation (line 16) | type GridPositionValidation = {
  type GridPositionInputsProps (line 53) | type GridPositionInputsProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/layout/shared/grid-settings.tsx
  type GridTrackProperty (line 69) | type GridTrackProperty =
  type TrackItemProps (line 75) | type TrackItemProps = {
  type TrackEditorProps (line 260) | type TrackEditorProps = {
  type GridSettingsProps (line 447) | type GridSettingsProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/position/inset-control.tsx
  type HoverTarget (line 65) | type HoverTarget = {

FILE: apps/builder/app/builder/features/style-panel/sections/position/inset-layout.tsx
  constant RECT_HEIGHT (line 6) | const RECT_HEIGHT = 6;
  constant RECT_WIDTH (line 7) | const RECT_WIDTH = 42;
  constant RECT_BORDER_RADIUS (line 8) | const RECT_BORDER_RADIUS = 1;
  constant OUTER_BORDER_RADIUS (line 9) | const OUTER_BORDER_RADIUS = 3;
  type InsetProperty (line 39) | type InsetProperty = "top" | "right" | "bottom" | "left";
  type InsetLayoutProps (line 41) | type InsetLayoutProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/shared/align-self.tsx
  type AlignSelfControlProps (line 14) | type AlignSelfControlProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/shared/scrub.tsx
  type ScrubStatus (line 15) | type ScrubStatus<P extends string> = {
  type HoverTarget (line 30) | type HoverTarget<P> = {
  method getInitialValue (line 136) | getInitialValue() {
  method onValueInput (line 146) | onValueInput(event) {
  method onValueChange (line 149) | onValueChange(event) {
  method onStatusChange (line 152) | onStatusChange(status) {

FILE: apps/builder/app/builder/features/style-panel/sections/space/layout.tsx
  constant VALUE_WIDTH (line 11) | const VALUE_WIDTH = 36;
  constant VALUE_HEIGHT (line 12) | const VALUE_HEIGHT = 24;
  constant BORDER (line 14) | const BORDER = 1;
  constant INNER_MARGIN (line 15) | const INNER_MARGIN = 3;
  constant MOST_INNER_WIDTH (line 17) | const MOST_INNER_WIDTH = 62;
  constant MOST_INNER_HEIGHT (line 18) | const MOST_INNER_HEIGHT = 6;
  constant INNER_WIDTH (line 20) | const INNER_WIDTH = MOST_INNER_WIDTH + (VALUE_WIDTH + BORDER) * 2;
  constant INNER_HEIGHT (line 21) | const INNER_HEIGHT = MOST_INNER_HEIGHT + (VALUE_HEIGHT + BORDER) * 2;
  constant TOTAL_WIDTH (line 23) | const TOTAL_WIDTH = INNER_WIDTH + (INNER_MARGIN + VALUE_WIDTH + BORDER) ...
  constant TOTAL_HEIGHT (line 24) | const TOTAL_HEIGHT = INNER_HEIGHT + (INNER_MARGIN + VALUE_HEIGHT + BORDE...
  type LayoutProps (line 246) | type LayoutProps = {

FILE: apps/builder/app/builder/features/style-panel/sections/space/properties.ts
  type SpaceStyleProperty (line 14) | type SpaceStyleProperty = (typeof spaceProperties)[number];
  type HoverTarget (line 16) | type HoverTarget = {

FILE: apps/builder/app/builder/features/style-panel/sections/transforms/transform-extractors.ts
  type SkewFunction (line 37) | type SkewFunction = FunctionValue & { args: LayersValue };

FILE: apps/builder/app/builder/features/style-panel/sections/transforms/transform-utils.ts
  type TransformPanel (line 26) | type TransformPanel = (typeof transformPanels)[number];

FILE: apps/builder/app/builder/features/style-panel/sections/transitions/transition-property.tsx
  type AnimatableProperty (line 28) | type AnimatableProperty = (typeof animatableProperties)[number];
  type AnimatableProperties (line 54) | type AnimatableProperties = (typeof animatableProperties)[number];
  type NameAndLabel (line 55) | type NameAndLabel = { name: string; label?: string };
  type TransitionPropertyProps (line 56) | type TransitionPropertyProps = {

FILE: apps/builder/app/builder/features/style-panel/shared/color-picker.tsx
  type ColorPickerProps (line 13) | type ColorPickerProps = {

FILE: apps/builder/app/builder/features/style-panel/shared/css-fragment.tsx
  type ShorthandProperty (line 22) | type ShorthandProperty = (typeof shorthandProperties)[number];
  method keydown (line 99) | keydown(event) {

FILE: apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input-container.tsx
  type CssValueInputContainerProps (line 6) | type CssValueInputContainerProps = Omit<

FILE: apps/builder/app/builder/features/style-panel/shared/css-value-input/css-value-input.tsx
  method getAcceleration (line 196) | getAcceleration() {
  method getInitialValue (line 210) | getInitialValue() {
  method onStart (line 216) | onStart() {
  method onAbort (line 223) | onAbort() {
  method onValueInput (line 235) | onValueInput(event) {
  method onValueChange (line 244) | onValueChange(event) {
  type IntermediateStyleValue (line 279) | type IntermediateStyleValue = {
  type CssValueInputValue (line 285) | type CssValueInputValue = StyleValue | IntermediateStyleValue;
  type Modifiers (line 287) | type Modifiers = {
  type ChangeCompleteEvent (line 292) | type ChangeCompleteEvent = {
  type CssValueInputProps (line 305) | type CssValueInputProps = Pick<
  method onCloseAutoFocus (line 607) | onCloseAutoFocus(event) {

FILE: apps/builder/app/builder/features/style-panel/shared/css-value-input/unit-select.tsx
  type UnitOption (line 17) | type UnitOption =
  type UseUnitSelectType (line 25) | type UseUnitSelectType = {
  type UnitSelectProps (line 90) | type UnitSelectProps = {

FILE: apps/builder/app/builder/features/style-panel/shared/filter-content.tsx
  type FilterContentProps (line 75) | type FilterContentProps = {
  type FilterFunction (line 88) | type FilterFunction = keyof typeof filterFunctions;

FILE: apps/builder/app/builder/features/style-panel/shared/model.tsx
  type Defined (line 142) | type Defined = {

FILE: apps/builder/app/builder/features/style-panel/shared/modifier-keys.ts
  type Modifiers (line 4) | type Modifiers = {

FILE: apps/builder/app/builder/features/style-panel/shared/repeated-style.tsx
  type ItemType (line 90) | type ItemType = "layers" | "tuple";

FILE: apps/builder/app/builder/features/style-panel/shared/scroll-by-pointer.ts
  method onFocus (line 105) | onFocus() {

FILE: apps/builder/app/builder/features/style-panel/shared/shadow-content.tsx
  type ShadowContentProps (line 70) | type ShadowContentProps = {

FILE: apps/builder/app/builder/features/style-panel/shared/use-style-data.ts
  type StyleUpdate (line 16) | type StyleUpdate =
  type StyleUpdateOptions (line 27) | type StyleUpdateOptions = { isEphemeral?: boolean; listed?: boolean };
  type SetValue (line 29) | type SetValue = (
  type SetProperty (line 34) | type SetProperty = (property: CssProperty) => SetValue;
  type DeleteProperty (line 36) | type DeleteProperty = (
  type CreateBatchUpdate (line 41) | type CreateBatchUpdate = () => {

FILE: apps/builder/app/builder/features/style-panel/style-source-section.tsx
  type CommandRegistry (line 43) | interface CommandRegistry {
  type SelectorConfig (line 281) | type SelectorConfig = {
  type StyleSourceInputItem (line 380) | type StyleSourceInputItem = {

FILE: apps/builder/app/builder/features/style-panel/style-source/style-source-control.tsx
  type ItemSource (line 34) | type ItemSource = "token" | "tag" | "local";
  type ItemSelector (line 36) | type ItemSelector = {
  type EditableTextProps (line 41) | type EditableTextProps = {
  type StyleSourceError (line 202) | type StyleSourceError = {
  type StyleSourceControlProps (line 207) | type StyleSourceControlProps = {

FILE: apps/builder/app/builder/features/style-panel/style-source/style-source-input.stories.tsx
  type Item (line 15) | type Item = {

FILE: apps/builder/app/builder/features/style-panel/style-source/style-source-input.tsx
  type IntermediateItem (line 60) | type IntermediateItem = {
  type TextFieldBaseWrapperProps (line 88) | type TextFieldBaseWrapperProps<Item extends IntermediateItem> = Omit<
  type StyleSourceInputProps (line 299) | type StyleSourceInputProps<Item extends IntermediateItem> = {
  method onItemSelect (line 396) | onItemSelect(item) {
  method onChange (line 404) | onChange(label) {
  method onKeyDown (line 410) | onKeyDown(event) {

FILE: apps/builder/app/builder/features/style-panel/style-source/style-source-menu.tsx
  type SelectorConfig (line 30) | type SelectorConfig = {
  type IntermediateItem (line 38) | type IntermediateItem = {
  type MenuAction (line 120) | type MenuAction = keyof typeof menuActionDescriptions;
  type StyleSourceMenuProps (line 225) | type StyleSourceMenuProps = {

FILE: apps/builder/app/builder/features/style-panel/style-source/use-sortable.tsx
  type UseSortable (line 15) | type UseSortable<Item> = {
  method getValidChildren (line 24) | getValidChildren(parent: Element) {
  method elementToData (line 49) | elementToData() {
  method swapDropTarget (line 52) | swapDropTarget() {
  method onDropTargetChange (line 58) | onDropTargetChange(dropTarget) {
  method elementToData (line 86) | elementToData(element) {
  method onStart (line 104) | onStart({ data: itemId }) {
  method onEnd (line 118) | onEnd({ isCanceled }) {

FILE: apps/builder/app/builder/features/workspace/canvas-iframe.tsx
  type CanvasIframeProps (line 25) | type CanvasIframeProps = JSX.IntrinsicElements["iframe"];

FILE: apps/builder/app/builder/features/workspace/canvas-tools/outline/label.tsx
  type LabelPosition (line 10) | type LabelPosition = "top" | "inside" | "bottom";
  type LabelRefCallback (line 11) | type LabelRefCallback = (element: HTMLElement | null) => void;
  type LabelProps (line 94) | type LabelProps = {

FILE: apps/builder/app/builder/features/workspace/canvas-tools/outline/outline.tsx
  type OutlineProps (line 90) | type OutlineProps = {

FILE: apps/builder/app/builder/features/workspace/canvas-tools/resize-handles.tsx
  method getInitialValue (line 107) | getInitialValue() {
  method getValue (line 110) | getValue(state, movement) {
  method onStatusChange (line 119) | onStatusChange(status) {
  method onValueInput (line 130) | onValueInput(event) {

FILE: apps/builder/app/builder/features/workspace/canvas-tools/text-toolbar.tsx
  type ToolbarProps (line 55) | type ToolbarProps = {

FILE: apps/builder/app/builder/features/workspace/workspace.tsx
  type WorkspaceProps (line 93) | type WorkspaceProps = {

FILE: apps/builder/app/builder/inspector.tsx
  type InspectorProps (line 50) | type InspectorProps = {
  type PanelName (line 90) | type PanelName = "style" | "settings";

FILE: apps/builder/app/builder/shared/asset-manager/asset-filters.tsx
  constant CATEGORY_ALL (line 5) | const CATEGORY_ALL = "All" as const;
  constant DISPLAY_CATEGORIES (line 11) | const DISPLAY_CATEGORIES = [
  type DisplayCategory (line 22) | type DisplayCategory = (typeof DISPLAY_CATEGORIES)[number];
  constant EXTENSION_TO_DISPLAY_CATEGORY (line 35) | const EXTENSION_TO_DISPLAY_CATEGORY: Record<
  type AssetFiltersProps (line 108) | type AssetFiltersProps = {

FILE: apps/builder/app/builder/shared/asset-manager/asset-info.tsx
  type AssetUsage (line 83) | type AssetUsage =

FILE: apps/builder/app/builder/shared/asset-manager/asset-manager.tsx
  type AssetManagerProps (line 22) | type AssetManagerProps = {
  method onMove (line 48) | onMove({ direction }) {

FILE: apps/builder/app/builder/shared/asset-manager/asset-sort.tsx
  type AssetSortSelectProps (line 22) | type AssetSortSelectProps = {

FILE: apps/builder/app/builder/shared/asset-manager/asset-thumbnail.tsx
  constant FORMAT_CATEGORIES (line 23) | const FORMAT_CATEGORIES = FILE_EXTENSIONS_BY_CATEGORY;
  constant CATEGORY_ICON_MAP (line 25) | const CATEGORY_ICON_MAP: Partial<Record<MimeCategory, IconComponent>> = {
  type AssetThumbnailProps (line 168) | type AssetThumbnailProps = {

FILE: apps/builder/app/builder/shared/asset-manager/image.tsx
  type ImageProps (line 3) | type ImageProps = {

FILE: apps/builder/app/builder/shared/asset-manager/utils.ts
  type SortField (line 9) | type SortField = "name" | "size" | "createdAt";
  type SortOrder (line 10) | type SortOrder = "asc" | "desc";
  type SortState (line 12) | type SortState = {

FILE: apps/builder/app/builder/shared/assets/asset-upload.tsx
  type AssetUploadProps (line 105) | type AssetUploadProps = {

FILE: apps/builder/app/builder/shared/assets/asset-utils.ts
  type ParsedAssetName (line 193) | type ParsedAssetName = {

FILE: apps/builder/app/builder/shared/assets/assets-shell.tsx
  type AssetsShellProps (line 38) | type AssetsShellProps = {
  constant OVER (line 53) | const OVER = 2;
  type DropTargetState (line 54) | type DropTargetState = typeof IDLE | typeof OVER;

FILE: apps/builder/app/builder/shared/assets/drag-monitor.tsx
  constant IDLE (line 16) | const IDLE = 0;
  constant POTENTIAL (line 17) | const POTENTIAL = 1;
  type ExternalMonitorDragState (line 19) | type ExternalMonitorDragState = typeof IDLE | typeof POTENTIAL;

FILE: apps/builder/app/builder/shared/assets/types.ts
  type PreviewAsset (line 3) | type PreviewAsset = Pick<
  type UploadedAssetContainer (line 8) | type UploadedAssetContainer = {
  type UploadingAssetContainer (line 13) | type UploadingAssetContainer = {
  type AssetContainer (line 22) | type AssetContainer = UploadedAssetContainer | UploadingAssetContainer;
  type AssetActionResponse (line 24) | type AssetActionResponse = {

FILE: apps/builder/app/builder/shared/binding-popover.tsx
  type BindingVariant (line 251) | type BindingVariant = "default" | "bound" | "overwritten";

FILE: apps/builder/app/builder/shared/client-settings/settings.ts
  type Settings (line 13) | type Settings = z.infer<typeof Settings>;

FILE: apps/builder/app/builder/shared/collapsible-section.tsx
  type Label (line 24) | type Label = string;
  type State (line 26) | type State = {
  type HandleOpenState (line 33) | type HandleOpenState = (
  type CollapsibleSectionBaseProps (line 116) | type CollapsibleSectionBaseProps = {
  type CollapsibleSectionProps (line 162) | type CollapsibleSectionProps = Simplify<

FILE: apps/builder/app/builder/shared/commands.ts
  type CommandRegistry (line 17) | interface CommandRegistry {

FILE: apps/builder/app/builder/shared/css-editor/add-style-input.tsx
  type SearchItem (line 42) | type SearchItem = {

FILE: apps/builder/app/builder/shared/css-variable-utils.tsx
  type CssVariableError (line 273) | type CssVariableError =
  type DeleteCssVariableDialogProps (line 475) | type DeleteCssVariableDialogProps = {
  type RenameCssVariableDialogProps (line 524) | type RenameCssVariableDialogProps = {

FILE: apps/builder/app/builder/shared/data-variable-utils.tsx
  type DataVariableError (line 34) | type DataVariableError = {
  type DeleteDataVariableDialogProps (line 57) | type DeleteDataVariableDialogProps = {
  type RenameDataVariableDialogProps (line 198) | type RenameDataVariableDialogProps = {

FILE: apps/builder/app/builder/shared/expression-editor.tsx
  type Scope (line 92) | type Scope = Record<string, unknown>;
  type Aliases (line 94) | type Aliases = Map<string, string>;
  class VariableWidget (line 349) | class VariableWidget extends WidgetType {
    method constructor (line 351) | constructor(text: string) {
    method toDOM (line 355) | toDOM(): HTMLElement {
  method constructor (line 391) | constructor(view: EditorView) {
  method update (line 394) | update(update: ViewUpdate) {

FILE: apps/builder/app/builder/shared/fonts-manager/fonts-manager.tsx
  method onMove (line 38) | onMove({ direction }) {
  type FontsManagerProps (line 106) | type FontsManagerProps = {

FILE: apps/builder/app/builder/shared/fonts-manager/item-menu.tsx
  type ItemMenuProps (line 23) | type ItemMenuProps = {
  type UseMenu (line 98) | type UseMenu = {

FILE: apps/builder/app/builder/shared/fonts-manager/item-utils.ts
  type Item (line 5) | type Item = {

FILE: apps/builder/app/builder/shared/instance-label.tsx
  type InstanceLike (line 75) | type InstanceLike = {
  type Props (line 81) | type Props = {

FILE: apps/builder/app/builder/shared/loading.tsx
  type LoadingState (line 39) | type LoadingState = {

FILE: apps/builder/app/builder/shared/nano-states.ts
  type GridEditingTrack (line 154) | type GridEditingTrack = {
  type GridEditingArea (line 162) | type GridEditingArea = {

FILE: apps/builder/app/builder/shared/style-source-actions.tsx
  type DeleteStyleSourceDialogProps (line 133) | type DeleteStyleSourceDialogProps = {
  type RenameStyleSourceDialogProps (line 182) | type RenameStyleSourceDialogProps = {

FILE: apps/builder/app/builder/shared/topbar-layout.tsx
  type TopbarLayoutProps (line 21) | type TopbarLayoutProps = {

FILE: apps/builder/app/builder/shared/topbar.tsx
  type TopbarProps (line 61) | type TopbarProps = {

FILE: apps/builder/app/builder/shared/url-pattern.ts
  type Token (line 40) | type Token =

FILE: apps/builder/app/builder/sidebar-left/sidebar-left.tsx
  type PanelConfig (line 67) | type PanelConfig = {
  type SidebarLeftProps (line 169) | type SidebarLeftProps = {

FILE: apps/builder/app/builder/sidebar-left/sidebar-tabs.tsx
  type SidebarTabsContentProps (line 135) | type SidebarTabsContentProps = Omit<

FILE: apps/builder/app/builder/sidebar-left/types.ts
  type SidebarPanelName (line 9) | type SidebarPanelName = (typeof sidebarPanelNames)[number] | "none";

FILE: apps/builder/app/canvas/elements.tsx
  type WebstudioComponentProps (line 12) | type WebstudioComponentProps = {

FILE: apps/builder/app/canvas/features/text-editor/interop.ts
  type Refs (line 23) | type Refs = Map<string, string>;

FILE: apps/builder/app/canvas/features/text-editor/text-editor.tsx
  type HandleNextParams (line 799) | type HandleNextParams =
  type SwitchBlockPluginProps (line 808) | type SwitchBlockPluginProps = {
  type ContextMenuParams (line 1007) | type ContextMenuParams = {
  type RichTextContentPluginProps (line 1011) | type RichTextContentPluginProps = {
  type TextEditorProps (line 1438) | type TextEditorProps = {

FILE: apps/builder/app/canvas/features/text-editor/toolbar-connector.tsx
  constant TOGGLE_SPAN_COMMAND (line 28) | const TOGGLE_SPAN_COMMAND = createCommand<void>();
  constant CLEAR_FORMAT_COMMAND (line 29) | const CLEAR_FORMAT_COMMAND = createCommand<void>();

FILE: apps/builder/app/canvas/grid-guide-utils.ts
  constant MAX_TRACKS (line 20) | const MAX_TRACKS = 20;
  constant IMPLICIT_PROBE_SIZE (line 72) | const IMPLICIT_PROBE_SIZE = 1.25;

FILE: apps/builder/app/canvas/inflator.ts
  constant INFLATE_PADDING (line 27) | const INFLATE_PADDING = 75;
  constant MAX_SIZE_TO_USE_OPTIMIZATION (line 200) | const MAX_SIZE_TO_USE_OPTIMIZATION = 50;

FILE: apps/builder/app/canvas/instance-hovering.ts
  type TimeoutId (line 19) | type TimeoutId = undefined | ReturnType<typeof setTimeout>;
  method onScrollStart (line 175) | onScrollStart() {
  method onScrollEnd (line 180) | onScrollEnd() {

FILE: apps/builder/app/canvas/instance-selected.ts
  method onScrollStart (line 306) | onScrollStart() {
  method onScrollEnd (line 309) | onScrollEnd() {
  method onResizeStart (line 315) | onResizeStart() {
  method onResizeEnd (line 318) | onResizeEnd() {

FILE: apps/builder/app/canvas/shared/inert.ts
  constant AUTO_DISPOSE_INERT_TIMEOUT (line 15) | const AUTO_DISPOSE_INERT_TIMEOUT = 1000;
  constant DISPOSE_INERT_TIMEOUT (line 18) | const DISPOSE_INERT_TIMEOUT = 300;
  constant PREVENT_INERT_TIMEOUT (line 20) | const PREVENT_INERT_TIMEOUT = 100;

FILE: apps/builder/app/canvas/shared/routing-priority.ts
  constant STATIC (line 1) | const STATIC = 1;
  constant DYNAMIC (line 2) | const DYNAMIC = 2;
  constant SPREAD (line 3) | const SPREAD = 3;

FILE: apps/builder/app/canvas/shared/scroll-state.ts
  type UseScrollState (line 40) | type UseScrollState = {

FILE: apps/builder/app/canvas/shared/use-drag-drop.ts
  type PubsubMap (line 41) | interface PubsubMap {
  type Origin (line 50) | type Origin = "canvas" | "panel";
  type DragStartPayload (line 52) | type DragStartPayload =
  type DragEndPayload (line 60) | type DragEndPayload = {
  type DragMovePayload (line 64) | type DragMovePayload = { canvasCoordinates: Point };
  method elementToData (line 144) | elementToData(element) {
  method swapDropTarget (line 153) | swapDropTarget(dropTarget) {
  method onDropTargetChange (line 202) | onDropTargetChange(dropTarget) {
  method elementToData (line 218) | elementToData(element) {
  method onStart (line 238) | onStart({ data: dragInstanceSelector }) {
  method onEnd (line 254) | onEnd({ isCanceled }) {

FILE: apps/builder/app/dashboard/projects/project-card.tsx
  type ProjectCardProps (line 53) | type ProjectCardProps = {

FILE: apps/builder/app/dashboard/projects/project-dialogs.tsx
  type DialogType (line 38) | type DialogType = "rename" | "delete" | "share" | "tags" | "settings";
  type DialogProps (line 40) | type DialogProps = {
  method onReady (line 453) | onReady() {
  type ProjectDialogsProps (line 474) | type ProjectDialogsProps = {

FILE: apps/builder/app/dashboard/projects/project-menu.tsx
  type ProjectMenuProps (line 15) | type ProjectMenuProps = {

FILE: apps/builder/app/dashboard/projects/projects-list.tsx
  type ProjectsListItemProps (line 70) | type ProjectsListItemProps = {
  type ProjectsListProps (line 178) | type ProjectsListProps = {

FILE: apps/builder/app/dashboard/projects/projects.tsx
  type ProjectsProps (line 63) | type ProjectsProps = {

FILE: apps/builder/app/dashboard/projects/sort.test.ts
  type LatestBuildVirtual (line 19) | type LatestBuildVirtual = NonNullable<DashboardProject["latestBuildVirtu...

FILE: apps/builder/app/dashboard/projects/sort.tsx
  type SortField (line 21) | type SortField = "createdAt" | "title" | "updatedAt" | "publishedAt";
  type SortOrder (line 22) | type SortOrder = "asc" | "desc";
  type SortState (line 24) | type SortState = {
  type SortSelectProps (line 87) | type SortSelectProps = {

FILE: apps/builder/app/dashboard/projects/tags.tsx
  type DeleteConfirmationDialogProps (line 33) | type DeleteConfirmationDialogProps = {

FILE: apps/builder/app/dashboard/search/search-results.tsx
  type SearchResults (line 12) | type SearchResults = {

FILE: apps/builder/app/dashboard/shared/card.tsx
  type CardProps (line 30) | type CardProps = ComponentProps<"div"> & {

FILE: apps/builder/app/dashboard/shared/types.ts
  type DashboardData (line 5) | type DashboardData = {

FILE: apps/builder/app/dashboard/templates/template-card.tsx
  type TemplateCardProps (line 9) | type TemplateCardProps = {

FILE: apps/builder/app/dashboard/templates/templates.tsx
  type ProjectsProps (line 41) | type ProjectsProps = {

FILE: apps/builder/app/env/env.server.ts
  type ServerEnv (line 77) | type ServerEnv = typeof env;

FILE: apps/builder/app/env/vite-env.d.ts
  type ImportMetaEnv (line 1) | interface ImportMetaEnv {

FILE: apps/builder/app/root.tsx
  function App (line 18) | function App() {

FILE: apps/builder/app/routes/_canvas.tsx
  function CanvasLayout (line 26) | function CanvasLayout() {

FILE: apps/builder/app/routes/_ui.$.tsx
  function NotFound (line 46) | function NotFound() {

FILE: apps/builder/app/routes/_ui.error.tsx
  function Error (line 104) | function Error() {

FILE: apps/builder/app/routes/_ui.logout.tsx
  function Logout (line 80) | function Logout() {

FILE: apps/builder/app/routes/_ui.tsx
  function Layout (line 103) | function Layout() {

FILE: apps/builder/app/routes/auth.dev.tsx
  function Dev (line 9) | function Dev() {

FILE: apps/builder/app/routes/auth.github.tsx
  function GH (line 9) | function GH() {

FILE: apps/builder/app/routes/auth.google.tsx
  function Google (line 12) | function Google() {

FILE: apps/builder/app/routes/rest.patch.ts
  type Change (line 53) | type Change = {
  type PatchData (line 58) | type PatchData = {

FILE: apps/builder/app/routes/trpc.$.ts
  method responseMeta (line 18) | responseMeta(opts) {
  method createContext (line 64) | async createContext(opts) {

FILE: apps/builder/app/services/auth-strategy/ws.server.ts
  type DynamicProps (line 10) | type DynamicProps = "authorizationEndpoint" | "tokenEndpoint" | "redirec...
  type OAuth2StrategyOptionsOverrides (line 12) | type OAuth2StrategyOptionsOverrides = Partial<OAuth2StrategyOptions> &
  class WsStrategy (line 26) | class WsStrategy<
    method constructor (line 31) | constructor(

FILE: apps/builder/app/services/auth.server.utils.ts
  type SessionData (line 1) | type SessionData = {

FILE: apps/builder/app/services/bloom-filter.server.ts
  class BloomFilter (line 19) | class BloomFilter {
    method constructor (line 23) | constructor(maxItems: number, falsePositiveProbability: number) {
    method add (line 42) | add(item: string) {
    method has (line 51) | has(item: string) {
    method #getHashes (line 58) | #getHashes(item: string): number[] {
    method serialize (line 71) | serialize(): string {
    method deserialize (line 78) | static deserialize(serialized: string): BloomFilter {

FILE: apps/builder/app/services/csrf-session.server.ts
  type CsrfSessionData (line 6) | type CsrfSessionData = {

FILE: apps/builder/app/services/destinations.server.ts
  type Destinations (line 1) | type Destinations = RequestDestination | "empty";

FILE: apps/builder/app/services/token.server.ts
  type CodeTokenPayload (line 81) | type CodeTokenPayload = z.infer<typeof CodeTokenPayload>;
  type AccessTokenPayload (line 140) | type AccessTokenPayload = z.infer<typeof AccessTokenPayload>;

FILE: apps/builder/app/services/trcp-router.server.ts
  type AppRouter (line 20) | type AppRouter = typeof appRouter;

FILE: apps/builder/app/services/trpc.server.ts
  constant TRPC_SERVER_URL (line 5) | const TRPC_SERVER_URL = env.TRPC_SERVER_URL ?? "";
  constant TRPC_SERVER_API_TOKEN (line 6) | const TRPC_SERVER_API_TOKEN = env.TRPC_SERVER_API_TOKEN ?? "";
  constant GITHUB_REF_NAME (line 7) | const GITHUB_REF_NAME = staticEnv.GITHUB_REF_NAME;

FILE: apps/builder/app/shared/array-utils.ts
  type Predicate (line 1) | type Predicate<Item> = (value: Item) => boolean;

FILE: apps/builder/app/shared/awareness.ts
  type Awareness (line 18) | type Awareness = {
  type InstancePath (line 113) | type InstancePath = Array<{

FILE: apps/builder/app/shared/builder-api.ts
  type ToastHandler (line 9) | type ToastHandler = (message: string) => void;
  type Window (line 39) | interface Window {

FILE: apps/builder/app/shared/builder-data.ts
  type BuilderData (line 21) | type BuilderData = WebstudioData & {
  type LoadedBuilderData (line 26) | type LoadedBuilderData = BuilderData &

FILE: apps/builder/app/shared/canvas-api.ts
  type Window (line 21) | interface Window {

FILE: apps/builder/app/shared/code-editor-base.tsx
  type EditorApi (line 214) | type EditorApi = {
  type EditorContentProps (line 219) | type EditorContentProps = {
  method run (line 322) | run(view) {
  method run (line 329) | run(view) {
  method blur (line 352) | blur() {
  method cut (line 355) | cut(event) {
  method focus (line 394) | focus() {

FILE: apps/builder/app/shared/commands-emitter.ts
  type CommandMeta (line 5) | type CommandMeta<CommandName extends string> = {
  type CommandHandler (line 33) | type CommandHandler = () => void;
  type Command (line 38) | type Command<CommandName extends string> = CommandMeta<CommandName> & {

FILE: apps/builder/app/shared/content-model.ts
  type Metas (line 14) | type Metas = Map<Instance["component"], WsComponentMeta>;

FILE: apps/builder/app/shared/copy-paste/init-copy-paste.ts
  type Plugin (line 66) | type Plugin = {

FILE: apps/builder/app/shared/copy-paste/plugin-instance.ts
  type InstanceData (line 40) | type InstanceData = z.infer<typeof InstanceData>;

FILE: apps/builder/app/shared/copy-paste/plugin-webflow/schema.ts
  type WfElementNode (line 326) | type WfElementNode = z.infer<typeof WfElementNode>;
  type WfNode (line 334) | type WfNode = z.infer<typeof WfNode>;
  type WfStyle (line 349) | type WfStyle = z.infer<typeof WfStyle>;
  type WfAsset (line 393) | type WfAsset = z.infer<typeof WfAsset>;
  type WfData (line 404) | type WfData = z.infer<typeof WfData>;

FILE: apps/builder/app/shared/copy-paste/plugin-webflow/style-presets-overrides.ts
  type Key (line 19) | type Key = keyof typeof _stylePresets;
  type WfIcons (line 21) | type WfIcons = Record<`w-icon-${string}`, ParsedStyleDecl>;
  type WfStylePresets (line 23) | type WfStylePresets = Record<Key, Array<ParsedStyleDecl>> & WfIcons;

FILE: apps/builder/app/shared/copy-paste/plugin-webflow/styles.ts
  type WfBreakpoint (line 23) | type WfBreakpoint = { minWidth?: number; maxWidth?: number };
  type WfBreakpointName (line 25) | type WfBreakpointName =
  type UnparsedVariants (line 129) | type UnparsedVariants = Map<string, string | Array<ParsedStyleDecl>>;

FILE: apps/builder/app/shared/db/user-plan-features.server.ts
  type UserPlanFeatures (line 4) | type UserPlanFeatures = NonNullable<AppContext["userPlanFeatures"]>;

FILE: apps/builder/app/shared/db/user.server.ts
  type User (line 10) | type User = Omit<
  type ProjectTag (line 115) | type ProjectTag = z.infer<typeof userProjectTagSchema>;

FILE: apps/builder/app/shared/dom-hooks/use-window-resize.ts
  type UseWindowResize (line 36) | type UseWindowResize = {

FILE: apps/builder/app/shared/dom-utils.ts
  type Rect (line 120) | type Rect = {

FILE: apps/builder/app/shared/hook-utils/use-interval.ts
  type Timeout (line 3) | type Timeout = ReturnType<typeof setTimeout>;

FILE: apps/builder/app/shared/html.ts
  type ElementNode (line 32) | type ElementNode = DefaultTreeAdapterMap["element"];
  type NestedClassRule (line 178) | type NestedClassRule = {
  type StyleTagAction (line 543) | type StyleTagAction =

FILE: apps/builder/app/shared/instance-utils.ts
  type Insertable (line 1696) | type Insertable = {

FILE: apps/builder/app/shared/logout.client.tsx
  type LogoutProps (line 8) | type LogoutProps = {
  constant MAX_RETRIES (line 13) | const MAX_RETRIES = 3;
  type LogoutPageProps (line 86) | type LogoutPageProps = {

FILE: apps/builder/app/shared/marketplace/types.ts
  type MarketplaceOverviewItem (line 4) | type MarketplaceOverviewItem = MarketplaceProduct & {

FILE: apps/builder/app/shared/nano-hash.ts
  constant NANOID_DEFAULT_SIZE (line 6) | const NANOID_DEFAULT_SIZE = 21;

FILE: apps/builder/app/shared/nano-states/canvas.ts
  type TextToolbarState (line 8) | type TextToolbarState = {
  type InstanceOutline (line 20) | type InstanceOutline = {
  type BlockChildOutline (line 25) | type BlockChildOutline = {
  type InstanceContextMenu (line 76) | type InstanceContextMenu = {
  type GridCellData (line 189) | type GridCellData = {

FILE: apps/builder/app/shared/nano-states/instances.ts
  type ContextMenuCommand (line 48) | type ContextMenuCommand =

FILE: apps/builder/app/shared/nano-states/misc.ts
  type StyleSourceSelector (line 71) | type StyleSourceSelector = {
  type UploadingFileData (line 127) | type UploadingFileData = Simplify<
  type ConvertibleUnit (line 149) | type ConvertibleUnit = (typeof convertibleUnits)[number];
  type UnitSizes (line 151) | type UnitSizes = Record<ConvertibleUnit, number>;
  type PropertySizes (line 153) | type PropertySizes = Partial<Record<CssProperty, UnitValue>>;
  type BuilderMode (line 311) | type BuilderMode = (typeof builderModes)[number];
  type ItemDropTarget (line 458) | type ItemDropTarget = {
  type DragAndDropState (line 468) | type DragAndDropState = {

FILE: apps/builder/app/shared/nano-states/project-settings.ts
  type SectionName (line 3) | type SectionName =

FILE: apps/builder/app/shared/project-settings/import-redirects-dialog.tsx
  type ImportStep (line 31) | type ImportStep = "input" | "preview";
  type MergeMode (line 32) | type MergeMode = "add" | "replace";
  type ImportRedirectsDialogProps (line 34) | type ImportRedirectsDialogProps = {
  constant ACCEPTED_EXTENSIONS (line 41) | const ACCEPTED_EXTENSIONS = [".csv", ".json", ".txt", ".htaccess"];

FILE: apps/builder/app/shared/project-settings/section-marketplace.tsx
  method submit (line 98) | submit() {
  method unlist (line 109) | unlist() {

FILE: apps/builder/app/shared/project-settings/section-redirects.tsx
  type ValidationResult (line 54) | type ValidationResult = {

FILE: apps/builder/app/shared/pubsub/create.test.ts
  type TestPublishMap (line 4) | type TestPublishMap = {

FILE: apps/builder/app/shared/pubsub/create.ts
  type Window (line 10) | interface Window {
  type Action (line 22) | type Action<Type extends keyof PublishMap> =
  method publish (line 131) | publish<Type extends keyof PublishMap>(action: Action<Type>) {
  method usePublish (line 144) | usePublish() {
  method useSubscribe (line 187) | useSubscribe<Type extends keyof PublishMap>(
  method subscribe (line 198) | subscribe<Type extends keyof PublishMap>(

FILE: apps/builder/app/shared/pubsub/index.ts
  type CommandRegistry (line 6) | interface CommandRegistry {}
  type NamespacedCommands (line 9) | type NamespacedCommands = {
  type PubsubMap (line 13) | interface PubsubMap extends NamespacedCommands {
  type Publish (line 23) | type Publish = typeof publish;
  type UsePublish (line 24) | type UsePublish = typeof usePublish;

FILE: apps/builder/app/shared/pubsub/raf-queue.ts
  type Task (line 1) | type Task = () => void;

FILE: apps/builder/app/shared/redirects/redirect-loop-detection.ts
  constant LOOP_ERROR (line 3) | const LOOP_ERROR = "This redirect would create a loop";
  type LoopedRedirect (line 75) | type LoopedRedirect = {
  type BatchLoopResult (line 80) | type BatchLoopResult = {

FILE: apps/builder/app/shared/redirects/redirect-parsers.ts
  type ParsedRedirect (line 3) | type ParsedRedirect = {
  type SkippedLine (line 9) | type SkippedLine = {
  type ParseResult (line 15) | type ParseResult = {
  constant FROM_KEYS (line 21) | const FROM_KEYS = [
  constant TO_KEYS (line 28) | const TO_KEYS = [
  constant STATUS_KEYS (line 36) | const STATUS_KEYS = ["status", "code", "statuscode"] as const;
  type RawRecord (line 38) | type RawRecord = Record<string, unknown>;

FILE: apps/builder/app/shared/resources.test.ts
  method searchParams (line 187) | get searchParams(): any {

FILE: apps/builder/app/shared/resources.ts
  constant MAX_PENDING_RESOURCES (line 8) | const MAX_PENDING_RESOURCES = 5;

FILE: apps/builder/app/shared/session/use-login-error-message.ts
  constant AUTH_PROVIDERS (line 4) | const AUTH_PROVIDERS = {
  constant LOGIN_ERROR_MESSAGES (line 10) | const LOGIN_ERROR_MESSAGES = {

FILE: apps/builder/app/shared/share-project/share-project-container.tsx
  type ShareButtonProps (line 92) | type ShareButtonProps = {

FILE: apps/builder/app/shared/share-project/share-project.stories.tsx
  constant INITIAL_LINKS (line 48) | const INITIAL_LINKS: LinkOptions[] = [];

FILE: apps/builder/app/shared/share-project/share-project.tsx
  type PermissionProps (line 51) | type PermissionProps = {
  type MenuProps (line 92) | type MenuProps = {
  type Relation (line 380) | type Relation = "viewers" | "editors" | "builders" | "administrators";
  type LinkOptions (line 382) | type LinkOptions = {
  type SharedLinkItemType (line 391) | type SharedLinkItemType = {
  type ShareProjectProps (line 443) | type ShareProjectProps = {

FILE: apps/builder/app/shared/store-utils.test.ts
  type StoreValue (line 5) | type StoreValue<Store extends ReadableAtom> = Readonly<

FILE: apps/builder/app/shared/store-utils.ts
  type StoreValues (line 11) | type StoreValues<Stores extends AnyStore[]> = {
  type Comparable (line 16) | type Comparable = Record<string, any> | any[] | null | undefined;
  type Computed (line 18) | interface Computed {

FILE: apps/builder/app/shared/style-object-model.ts
  type InstanceSelector (line 57) | type InstanceSelector = string[];
  type StyleValueSourceColor (line 59) | type StyleValueSourceColor =
  type StyleValueSource (line 66) | type StyleValueSource = {
  type StyleObjectModel (line 78) | type StyleObjectModel = {
  method enter (line 307) | enter(node, item, list) {
  type ComputedStyleDecl (line 340) | type ComputedStyleDecl = {

FILE: apps/builder/app/shared/style-source-utils.ts
  type TokenConflict (line 110) | type TokenConflict = {
  type RenameStyleSourceError (line 571) | type RenameStyleSourceError =

FILE: apps/builder/app/shared/sync-client.test.ts
  class TestStorage (line 308) | class TestStorage implements SyncStorage {
    method constructor (line 311) | constructor(value: undefined | number) {
    method subscribe (line 315) | subscribe(setState: (state: unknown) => void) {

FILE: apps/builder/app/shared/sync-client.ts
  type Transaction (line 6) | type Transaction<Payload = unknown> = {
  type RevertedTransaction (line 12) | type RevertedTransaction = {
  type SyncStorage (line 17) | interface SyncStorage {
  type SyncObject (line 42) | interface SyncObject {
  class ImmerhinSyncObject (line 54) | class ImmerhinSyncObject implements SyncObject {
    method constructor (line 57) | constructor(name: string, store: Store) {
    method getState (line 61) | getState() {
    method setState (line 68) | setState(state: Map<string, unknown>) {
    method applyTransaction (line 81) | applyTransaction(transaction: Transaction<Change[]>) {
    method revertTransaction (line 84) | revertTransaction(transaction: RevertedTransaction) {
    method subscribe (line 87) | subscribe(
  class NanostoresSyncObject (line 101) | class NanostoresSyncObject implements SyncObject {
    method constructor (line 106) | constructor(name: string, store: WritableAtom<unknown>) {
    method getState (line 110) | getState() {
    method setState (line 113) | setState(state: unknown) {
    method applyTransaction (line 118) | applyTransaction(transaction: Transaction) {
    method revertTransaction (line 131) | revertTransaction(_transaction: RevertedTransaction) {
    method subscribe (line 134) | subscribe(
  class SyncObjectPool (line 149) | class SyncObjectPool implements SyncObject {
    method constructor (line 152) | constructor(objects: SyncObject[]) {
    method getState (line 157) | getState() {
    method setState (line 164) | setState(state: Map<string, unknown>) {
    method applyTransaction (line 172) | applyTransaction(transaction: Transaction) {
    method revertTransaction (line 175) | revertTransaction(transaction: RevertedTransaction) {
    method subscribe (line 178) | subscribe(
  type SyncMessage (line 188) | type SyncMessage =
  type SyncEmitter (line 194) | type SyncEmitter = Emitter<{
  type SyncClientOptions (line 198) | type SyncClientOptions = {
  class SyncClient (line 205) | class SyncClient {
    method constructor (line 213) | constructor(options: SyncClientOptions) {
    method lead (line 220) | lead() {
    method connect (line 229) | connect({ signal, onReady }: { signal: AbortSignal; onReady?: () => vo...

FILE: apps/builder/app/shared/sync/command-queue.ts
  type Command (line 6) | type Command =

FILE: apps/builder/app/shared/sync/project-queue.ts
  constant NEW_ENTRIES_INTERVAL (line 17) | const NEW_ENTRIES_INTERVAL = 1000;
  constant INTERVAL_RECOVERY (line 20) | const INTERVAL_RECOVERY = 2000;
  constant MAX_RETRY_RECOVERY (line 23) | const MAX_RETRY_RECOVERY = 5;
  constant MAX_ALLOWED_API_ERRORS (line 26) | const MAX_ALLOWED_API_ERRORS = 5;
  constant INTERVAL_ERROR (line 29) | const INTERVAL_ERROR = 5000;
  constant MAX_INTERVAL_ERROR (line 30) | const MAX_INTERVAL_ERROR = 2 * 60000;
  type QueueStatus (line 36) | type QueueStatus =
  type TransactionCompleteCallback (line 46) | type TransactionCompleteCallback = (success: boolean) => void;
  class ServerSyncStorage (line 389) | class ServerSyncStorage implements SyncStorage {
    method constructor (line 393) | constructor(projectId: string) {
    method sendTransaction (line 397) | sendTransaction(transaction: Transaction<Change[]>) {
    method subscribe (line 407) | subscribe(setState: (state: unknown) => void, signal: AbortSignal) {

FILE: apps/builder/app/shared/sync/sync-client.ts
  method onReady (line 69) | onReady() {

FILE: apps/builder/app/shared/sync/sync-stores.ts
  type Window (line 162) | interface Window {

FILE: apps/builder/app/shared/tailwind/tailwind.ts
  type StyleDecl (line 43) | type StyleDecl = Omit<ParsedStyleDecl, "selector">;
  type StyleBreakpoint (line 45) | type StyleBreakpoint = {
  type Range (line 51) | type Range = {
  constant UPPER_BOUND (line 66) | const UPPER_BOUND = Number.MAX_SAFE_INTEGER;

FILE: apps/builder/app/shared/token-conflict-dialog.tsx
  type ConflictResolution (line 20) | type ConflictResolution = "ours" | "theirs" | "merge";
  type DialogState (line 22) | type DialogState =

FILE: apps/builder/app/shared/tree-utils.ts
  type InstanceSelector (line 20) | type InstanceSelector = Instance["id"][];
  type DroppableTarget (line 49) | type DroppableTarget = {

FILE: apps/builder/app/shared/trpc/trpc-client.ts
  type Procedures (line 23) | type Procedures<T> = T extends AnyRouter
  type Client (line 51) | type Client = Record<

FILE: apps/builder/vite.config.ts
  method configureServer (line 49) | configureServer(server) {

FILE: fixtures/react-router-cloudflare/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-cloudflare/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-cloudflare/app/entry.server.tsx
  function handleRequest (line 6) | async function handleRequest(

FILE: fixtures/react-router-cloudflare/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: fixtures/react-router-cloudflare/workers/app.ts
  type AppLoadContext (line 4) | interface AppLoadContext {
  method fetch (line 19) | async fetch(request, env, ctx) {

FILE: fixtures/react-router-docker/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-docker/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-docker/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: fixtures/react-router-netlify/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-netlify/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-netlify/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: fixtures/react-router-vercel/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-vercel/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/react-router-vercel/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: fixtures/ssg-netlify-by-project-id/app/__generated__/[redirect]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/ssg-netlify-by-project-id/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/ssg-netlify-by-project-id/vike.d.ts
  type Config (line 6) | interface Config {
  type PageContext (line 11) | interface PageContext {

FILE: fixtures/ssg/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/ssg/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/ssg/vike.d.ts
  type Config (line 6) | interface Config {
  type PageContext (line 11) | interface PageContext {

FILE: fixtures/webstudio-cloudflare-template/app/__generated__/[another-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-cloudflare-template/app/__generated__/_index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-cloudflare-template/app/extension.ts
  type AppLoadContext (line 7) | interface AppLoadContext {

FILE: fixtures/webstudio-cloudflare-template/load-context.ts
  type Cloudflare (line 3) | type Cloudflare = Omit<PlatformProxy<Env>, "dispose">;
  type AppLoadContext (line 6) | interface AppLoadContext {

FILE: fixtures/webstudio-cloudflare-template/worker-configuration.d.ts
  type Env (line 3) | interface Env {}

FILE: fixtures/webstudio-features/app/__generated__/[_route_with_symbols_]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[animations]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[assets1]._index.server.tsx
  type Params (line 39) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[class-names]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[content-block]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[duration]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[expressions]._index.server.tsx
  type Params (line 41) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[form]._index.server.tsx
  type Params (line 39) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[head-tag]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[heading-with-id]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[nested].[nested-page]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[radix]._index.server.tsx
  type Params (line 33) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[resources]._index.server.tsx
  type Params (line 39) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[sitemap.xml]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/[text-duration]._index.server.tsx
  type Params (line 32) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/__generated__/_index.server.tsx
  type Params (line 39) | type Params = Record<string, string | undefined>;

FILE: fixtures/webstudio-features/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: fixtures/webstudio-features/proxy-emulator/dedupe-meta.ts
  method configureServer (line 6) | configureServer(server) {

FILE: packages/asset-uploader/src/client.ts
  type AssetClient (line 3) | type AssetClient = {

FILE: packages/asset-uploader/src/clients/fs/fs.ts
  type FsClientOptions (line 4) | type FsClientOptions = {

FILE: packages/asset-uploader/src/clients/s3/s3.ts
  type S3ClientOptions (line 6) | type S3ClientOptions = {

FILE: packages/asset-uploader/src/constants.ts
  constant MAX_UPLOAD_SIZE (line 2) | const MAX_UPLOAD_SIZE = "4.5";

FILE: packages/asset-uploader/src/types.ts
  type AssetType (line 1) | type AssetType = "image" | "font" | "video" | "file";

FILE: packages/asset-uploader/src/upload.ts
  type UploadData (line 12) | type UploadData = {
  constant UPLOADING_STALE_TIMEOUT (line 19) | const UPLOADING_STALE_TIMEOUT = 1000 * 60 * 30;

FILE: packages/asset-uploader/src/utils/font-data.ts
  type FontDataStatic (line 61) | type FontDataStatic = {
  type FontDataVariable (line 67) | type FontDataVariable = {
  type FontData (line 72) | type FontData = FontDataStatic | FontDataVariable;

FILE: packages/asset-uploader/src/utils/get-asset-data.ts
  type AssetData (line 7) | type AssetData = {
  type BaseAssetOptions (line 19) | type BaseAssetOptions = {
  type AssetOptions (line 25) | type AssetOptions =

FILE: packages/asset-uploader/src/utils/sanitize-s3-key.ts
  constant REPLACE_CHAR (line 19) | const REPLACE_CHAR = "_";

FILE: packages/authorization-token/src/db/authorization-token.ts
  type AuthorizationToken (line 8) | type AuthorizationToken =
  type TokenPermissions (line 88) | type TokenPermissions = typeof tokenDefaultPermissions;

FILE: packages/authorization-token/src/trpc/authorization-tokens-router.ts
  type Relation (line 7) | type Relation =
  type TokenRelation (line 18) | type TokenRelation = z.infer<typeof TokenProjectRelation>;
  type AuthorizationTokensRouter (line 90) | type AuthorizationTokensRouter = typeof authorizationTokenRouter;

FILE: packages/cli/src/args.ts
  type File (line 1) | type File = {
  type Folder (line 8) | type Folder = {
  type ProjectTarget (line 14) | type ProjectTarget = "defaults";

FILE: packages/cli/src/commands/init-flow.ts
  type ProjectTemplates (line 22) | type ProjectTemplates = (typeof PROJECT_TEMPLATES)[number]["value"];
  method validate (line 53) | validate(value) {

FILE: packages/cli/src/commands/yargs-types.ts
  type CommonYargsOptions (line 36) | interface CommonYargsOptions {
  type CommonYargsArgv (line 42) | type CommonYargsArgv = Argv<CommonYargsOptions>;
  type YargvToInterface (line 44) | type YargvToInterface<T> =
  type RemoveIndex (line 48) | type RemoveIndex<T> = {
  type StrictYargsOptionsToInterface (line 60) | type StrictYargsOptionsToInterface<

FILE: packages/cli/src/config.ts
  constant GLOBAL_CONFIG_FOLDER (line 5) | const GLOBAL_CONFIG_FOLDER = envPaths("webstudio").config;
  constant GLOBAL_CONFIG_FILE_NAME (line 6) | const GLOBAL_CONFIG_FILE_NAME = "webstudio-config.json";
  constant GLOBAL_CONFIG_FILE (line 7) | const GLOBAL_CONFIG_FILE = join(
  constant LOCAL_CONFIG_FILE (line 12) | const LOCAL_CONFIG_FILE = ".webstudio/config.json";
  constant LOCAL_DATA_FILE (line 13) | const LOCAL_DATA_FILE = ".webstudio/data.json";
  type LocalConfig (line 19) | type LocalConfig = z.infer<typeof zLocalConfig>;
  type GlobalConfig (line 53) | type GlobalConfig = z.infer<typeof zGlobalConfig>;
  constant PROJECT_TEMPLATES (line 55) | const PROJECT_TEMPLATES = [
  constant INTERNAL_TEMPLATES (line 88) | const INTERNAL_TEMPLATES = [

FILE: packages/cli/src/framework.ts
  type FrameworkTemplateEntry (line 3) | type FrameworkTemplateEntry = {
  type Framework (line 8) | type Framework = {

FILE: packages/cli/src/html-to-jsx.ts
  constant BOOLEAN_ATTRIBUTES (line 8) | const BOOLEAN_ATTRIBUTES = new Set([
  type WalkNode (line 40) | type WalkNode =

FILE: packages/cli/src/prebuild.ts
  type SiteDataByPage (line 68) | type SiteDataByPage = {

FILE: packages/cli/templates/cloudflare/load-context.ts
  type Cloudflare (line 3) | type Cloudflare = Omit<PlatformProxy<Env>, "dispose">;
  type AppLoadContext (line 6) | interface AppLoadContext {

FILE: packages/cli/templates/cloudflare/worker-configuration.d.ts
  type Env (line 3) | interface Env {}

FILE: packages/cli/templates/defaults/app/extension.ts
  type AppLoadContext (line 7) | interface AppLoadContext {

FILE: packages/cli/templates/react-router-cloudflare/app/entry.server.tsx
  function handleRequest (line 6) | async function handleRequest(

FILE: packages/cli/templates/react-router-cloudflare/workers/app.ts
  type AppLoadContext (line 4) | interface AppLoadContext {
  method fetch (line 19) | async fetch(request, env, ctx) {

FILE: packages/cli/templates/react-router/app/extension.ts
  type AppLoadContext (line 4) | interface AppLoadContext {

FILE: packages/cli/templates/ssg/vike.d.ts
  type Config (line 6) | interface Config {
  type PageContext (line 11) | interface PageContext {

FILE: packages/css-data/bin/mdn-data.ts
  type Property (line 29) | type Property = keyof typeof properties;
  type Value (line 30) | type Value = (typeof properties)[Property];
  type FilteredProperties (line 266) | type FilteredProperties = { [property: string]: Value };

FILE: packages/css-data/bin/property-value-descriptions.ts
  function writeFile (line 328) | function writeFile(descriptions: Record<string, unknown>) {
  function generateWithRetry (line 345) | async function generateWithRetry(message: string): Promise<string> {
  function generate (line 382) | async function generate(message: string): Promise<string | [number, stri...
  function grabDescriptions (line 429) | function grabDescriptions(message: string) {
  function toKebabCase (line 439) | function toKebabCase(keyword: string) {

FILE: packages/css-data/src/__generated__/keyword-values.ts
  type KeywordValues (line 4) | type KeywordValues = Record<__HyphenatedProperty, string[]> &

FILE: packages/css-data/src/__generated__/properties.ts
  type UnitGroup (line 7) | type UnitGroup =
  type PropertyData (line 18) | type PropertyData = {
  type Properties (line 24) | type Properties = Record<__HyphenatedProperty, PropertyData> &

FILE: packages/css-data/src/custom-data.ts
  type RawPropertyData (line 4) | type RawPropertyData = {

FILE: packages/css-data/src/parse-css.ts
  type ParsedStyleDecl (line 11) | type ParsedStyleDecl = {
  type Selector (line 95) | type Selector = {
  method enter (line 113) | enter(node) {
  method leave (line 120) | leave(node) {
  type ParsedClassSelector (line 301) | type ParsedClassSelector = {
  type Segment (line 371) | type Segment = {
  type ParsedBreakpoint (line 464) | type ParsedBreakpoint = {

FILE: packages/css-data/src/property-parsers/conic-gradient.test.ts
  type ConicGradient (line 4) | type ConicGradient = NonNullable<ReturnType<typeof parseConicGradient>>;

FILE: packages/css-data/src/property-parsers/conic-gradient.ts
  type GradientPartResult (line 19) | type GradientPartResult =

FILE: packages/css-data/src/property-parsers/grid-template-areas.ts
  type AreaInfo (line 3) | type AreaInfo = {

FILE: packages/css-data/src/property-parsers/grid-template-tracks.ts
  type GridTrack (line 9) | type GridTrack = {
  type Minmax (line 181) | type Minmax = {
  type GridTemplateSupport (line 241) | type GridTemplateSupport =
  type GridAxisMode (line 344) | type GridAxisMode =

FILE: packages/css-data/src/property-parsers/linear-gradient.test.ts
  type LinearGradient (line 4) | type LinearGradient = NonNullable<ReturnType<typeof parseLinearGradient>>;

FILE: packages/css-data/src/property-parsers/radial-gradient.test.ts
  type RadialGradient (line 5) | type RadialGradient = NonNullable<ReturnType<typeof parseRadialGradient>>;

FILE: packages/css-data/src/property-parsers/types.ts
  type GradientColorValue (line 9) | type GradientColorValue =
  type GradientStop (line 15) | type GradientStop = {
  type ParsedGradientBase (line 21) | type ParsedGradientBase = {
  type ParsedLinearGradient (line 26) | type ParsedLinearGradient = ParsedGradientBase & {
  type ParsedConicGradient (line 32) | type ParsedConicGradient = ParsedGradientBase & {
  type ParsedRadialGradient (line 38) | type ParsedRadialGradient = ParsedGradientBase & {
  type ParsedGradient (line 45) | type ParsedGradient =

FILE: packages/css-data/src/selector-validation.ts
  type SelectorValidationResult (line 5) | type SelectorValidationResult =

FILE: packages/css-data/src/shorthands.ts
  type GetProperty (line 198) | type GetProperty = (edge: string) => string;

FILE: packages/css-engine/src/__generated__/types.ts
  type CamelCasedProperty (line 2) | type CamelCasedProperty =
  type HyphenatedProperty (line 376) | type HyphenatedProperty =
  type Unit (line 750) | type Unit =

FILE: packages/css-engine/src/core/atomic.ts
  type Options (line 6) | type Options = {

FILE: packages/css-engine/src/core/rules.ts
  type StyleMap (line 57) | type StyleMap = Map<string, StyleValue>;
  type Declaration (line 80) | type Declaration = {
  type DeclarationKey (line 94) | type DeclarationKey = Omit<Declaration, "value">;
  class MixinRule (line 112) | class MixinRule {
    method isDirtyBreakpoint (line 119) | isDirtyBreakpoint(breakpoint: string) {
    method clearBreakpoints (line 125) | clearBreakpoints() {
    method setDeclaration (line 128) | setDeclaration(declaration: Declaration) {
    method deleteDeclaration (line 134) | deleteDeclaration(declaration: DeclarationKey) {
    method getDeclarations (line 140) | getDeclarations() {
  class NestingRule (line 158) | class NestingRule {
    method constructor (line 170) | constructor(
    method getSelector (line 179) | getSelector() {
    method setSelector (line 182) | setSelector(selector: string) {
    method getDescendantSuffix (line 186) | getDescendantSuffix() {
    method addMixin (line 189) | addMixin(mixin: string) {
    method applyMixins (line 193) | applyMixins(mixins: string[]) {
    method setDeclaration (line 197) | setDeclaration(declaration: Declaration) {
    method deleteDeclaration (line 203) | deleteDeclaration(declaration: DeclarationKey) {
    method #getDeclarations (line 209) | #getDeclarations() {
    method getMergedDeclarations (line 226) | getMergedDeclarations() {
    method toString (line 229) | toString({
  type MediaRuleOptions (line 300) | type MediaRuleOptions = {
  class MediaRule (line 307) | class MediaRule {
    method constructor (line 311) | constructor(name: string, options: MediaRuleOptions = {}) {
    method insertRule (line 316) | insertRule(rule: PlaintextRule) {
    method cssText (line 320) | get cssText() {
    method toString (line 323) | toString() {
    method generateRule (line 326) | generateRule({
  class PlaintextRule (line 375) | class PlaintextRule {
    method constructor (line 377) | constructor(cssText: string) {
    method toString (line 380) | toString() {
  type FontFaceOptions (line 385) | type FontFaceOptions = {
  class FontFaceRule (line 393) | class FontFaceRule {
    method constructor (line 396) | constructor(options: FontFaceOptions) {
    method cssText (line 399) | get cssText() {
    method toString (line 402) | toString() {

FILE: packages/css-engine/src/core/style-element.ts
  class StyleElement (line 1) | class StyleElement {
    method constructor (line 4) | constructor(name = "") {
    method isMounted (line 7) | get isMounted() {
    method mount (line 10) | mount() {
    method unmount (line 17) | unmount() {
    method render (line 23) | render(cssText: string) {
    method setAttribute (line 28) | setAttribute(name: string, value: string) {
    method getAttribute (line 33) | getAttribute(name: string) {
  class FakeStyleElement (line 44) | class FakeStyleElement {
    method isMounted (line 45) | get isMounted() {
    method mount (line 48) | mount() {}
    method unmount (line 49) | unmount() {}
    method render (line 50) | render(_cssText: string) {}
    method setAttribute (line 51) | setAttribute(_name: string, _value: string) {}
    method getAttribute (line 52) | getAttribute(_name: string) {

FILE: packages/css-engine/src/core/style-sheet-regular.ts
  class StyleSheetRegular (line 3) | class StyleSheetRegular extends StyleSheet {}

FILE: packages/css-engine/src/core/style-sheet.ts
  class StyleSheet (line 14) | class StyleSheet {
    method constructor (line 23) | constructor(element: StyleElement | FakeStyleElement) {
    method setTransformer (line 26) | setTransformer(transformValue: TransformValue) {
    method addMediaRule (line 29) | addMediaRule(id: string, options?: MediaRuleOptions) {
    method addPlaintextRule (line 48) | addPlaintextRule(cssText: string) {
    method addMixinRule (line 55) | addMixinRule(name: string) {
    method addNestingRule (line 63) | addNestingRule(selector: string, descendantSuffix: string = "") {
    method addFontFaceRule (line 72) | addFontFaceRule(options: FontFaceOptions) {
    method generateWith (line 75) | generateWith({
    method cssText (line 108) | get cssText() {
    method clear (line 114) | clear() {
    method render (line 121) | render() {
    method unmount (line 125) | unmount() {
    method setAttribute (line 128) | setAttribute(name: string, value: string) {
    method getAttribute (line 131) | getAttribute(name: string) {

FILE: packages/css-engine/src/core/to-value.ts
  type TransformValue (line 4) | type TransformValue = (styleValue: StyleValue) => undefined | StyleValue;

FILE: packages/css-engine/src/schema.ts
  type CustomProperty (line 9) | type CustomProperty = `--${string}`;
  type StyleProperty (line 11) | type StyleProperty = CamelCasedProperty | CustomProperty;
  type CssProperty (line 13) | type CssProperty = HyphenatedProperty | CustomProperty;
  type CssStyleMap (line 15) | type CssStyleMap = Map<CssProperty, StyleValue>;
  type Unit (line 19) | type Unit = z.infer<typeof Unit>;
  type UnitValue (line 28) | type UnitValue = z.infer<typeof UnitValue>;
  type KeywordValue (line 36) | type KeywordValue = z.infer<typeof KeywordValue>;
  type UnparsedValue (line 48) | type UnparsedValue = z.infer<typeof UnparsedValue>;
  type FontFamilyValue (line 55) | type FontFamilyValue = z.infer<typeof FontFamilyValue>;
  type RgbValue (line 65) | type RgbValue = z.infer<typeof RgbValue>;
  type ColorValue (line 90) | type ColorValue = z.infer<typeof ColorValue>;
  type FunctionValue (line 92) | type FunctionValue = z.infer<typeof FunctionValue>;
  type ImageValue (line 118) | type ImageValue = z.infer<typeof ImageValue>;
  type GuaranteedInvalidValue (line 126) | type GuaranteedInvalidValue = z.infer<typeof GuaranteedInvalidValue>;
  type InvalidValue (line 135) | type InvalidValue = z.infer<typeof InvalidValue>;
  type UnsetValue (line 146) | type UnsetValue = z.infer<typeof UnsetValue>;
  type VarFallback (line 155) | type VarFallback = z.infer<typeof VarFallback>;
  type VarValue (line 180) | type VarValue = z.infer<typeof VarValue>;
  type TupleValueItem (line 192) | type TupleValueItem = z.infer<typeof TupleValueItem>;
  type TupleValue (line 200) | type TupleValue = z.infer<typeof TupleValue>;
  type ShadowValue (line 213) | type ShadowValue = z.infer<typeof ShadowValue>;
  type LayerValueItem (line 229) | type LayerValueItem = z.infer<typeof LayerValueItem>;
  type LayersValue (line 239) | type LayersValue = z.infer<typeof LayersValue>;
  type StyleValue (line 259) | type StyleValue = z.infer<typeof StyleValue>;

FILE: packages/dashboard/src/db/projects.ts
  type DomainVirtual (line 6) | type DomainVirtual = {
  type ProjectWithDomains (line 26) | type ProjectWithDomains = T & {
  type DashboardProject (line 77) | type DashboardProject = Awaited<ReturnType<typeof findMany>>[number];

FILE: packages/dashboard/src/trpc/project-router.ts
  type DashboardProjectRouter (line 30) | type DashboardProjectRouter = typeof dashboardProjectRouter;

FILE: packages/design-system/bin/transform-figma-tokens.ts
  constant SOURCE_FILE (line 6) | const SOURCE_FILE = "./src/__generated__/figma-design-tokens.json";
  constant TMP_OUTPUT_FILE (line 7) | const TMP_OUTPUT_FILE = "./src/__generated__/figma-design-tokens.tmp";
  constant OUTPUT_FILE (line 8) | const OUTPUT_FILE = "./src/__generated__/figma-design-tokens.ts";

FILE: packages/design-system/src/components/__DEPRECATED__/list.tsx
  type UseList (line 88) | type UseList<Item = unknown> = {
  method onFocus (line 108) | onFocus(event: FocusEvent) {
  method onMouseEnter (line 115) | onMouseEnter() {
  method onMouseLeave (line 118) | onMouseLeave() {
  method onClick (line 121) | onClick() {
  method onKeyDown (line 129) | onKeyDown(event: KeyboardEvent) {
  method onBlur (line 147) | onBlur(event: FocusEvent) {

FILE: packages/design-system/src/components/avatar.tsx
  type AvatarVariants (line 50) | type AvatarVariants = VariantProps<typeof StyledAvatar>;
  type AvatarPrimitiveProps (line 51) | type AvatarPrimitiveProps = ComponentProps<typeof AvatarPrimitive.Root>;
  type AvatarOwnProps (line 52) | type AvatarOwnProps = AvatarPrimitiveProps &

FILE: packages/design-system/src/components/button.tsx
  type ButtonColor (line 29) | type ButtonColor = (typeof colors)[number];
  type ButtonState (line 31) | type ButtonState = "auto" | "hover" | "focus" | "pressed" | "pending";
  type ButtonProps (line 148) | type ButtonProps = {

FILE: packages/design-system/src/components/checkbox.tsx
  type CheckboxProps (line 43) | type CheckboxProps = ComponentProps<"button"> &
  type AriaChecked (line 46) | type AriaChecked = ComponentProps<typeof Primitive.Checkbox>["aria-check...

FILE: packages/design-system/src/components/color-picker.tsx
  type RgbaColor (line 41) | type RgbaColor = {
  type ColorThumbProps (line 143) | type ColorThumbProps = Omit<
  type IntermediateColorValue (line 209) | type IntermediateColorValue = {
  type ColorPickerValue (line 215) | type ColorPickerValue = StyleValue | IntermediateColorValue;
  type ColorPickerProps (line 217) | type ColorPickerProps = {
  type ColorPickerPopoverProps (line 223) | type ColorPickerPopoverProps = {

FILE: packages/design-system/src/components/combobox.tsx
  type Match (line 214) | type Match<Item> = (
  type ItemToString (line 233) | type ItemToString<Item> = (item: Item | null) => string;
  type UseComboboxProps (line 235) | type UseComboboxProps<Item> = Omit<UseDownshiftComboboxProps<Item>, "ite...
  method onIsOpenChange (line 285) | onIsOpenChange(state) {
  method onInputValueChange (line 349) | onInputValueChange(state) {
  method onSelectedItemChange (line 361) | onSelectedItemChange({ selectedItem, type }) {
  method onHighlightedIndexChange (line 375) | onHighlightedIndexChange({ highlightedIndex }) {
  type ComboboxProps (line 456) | type ComboboxProps<Item> = UseComboboxProps<Item> &

FILE: packages/design-system/src/components/command.tsx
  type CommandProps (line 58) | type CommandProps = ComponentPropsWithoutRef<typeof CommandPrimitive>;
  type CommandAction (line 72) | type CommandAction = {
  type CommandState (line 77) | type CommandState = {
  type CommandGroupProps (line 361) | type CommandGroupProps = Omit<

FILE: packages/design-system/src/components/component-card.tsx
  type ComponentCardProps (line 66) | type ComponentCardProps = {

FILE: packages/design-system/src/components/css-value-list-item.tsx
  type Props (line 91) | type Props = ComponentProps<typeof ItemButton> & {

FILE: packages/design-system/src/components/dialog.tsx
  constant DIALOG_TITLE_HEIGHT (line 28) | const DIALOG_TITLE_HEIGHT = 40;
  type Point (line 138) | type Point = { x: number; y: number };
  type Size (line 139) | type Size = { width: number; height: number };
  type Rect (line 140) | type Rect = Point & Size;
  type Tolerance (line 142) | type Tolerance = {
  type UseDraggableProps (line 314) | type UseDraggableProps = {

FILE: packages/design-system/src/components/enhanced-tooltip.tsx
  constant DEFAULT_DELAY_DURATION (line 20) | const DEFAULT_DELAY_DURATION = 1600;

FILE: packages/design-system/src/components/floating-panel.tsx
  type OffsetOptions (line 19) | type OffsetOptions =
  type FloatingPanelProps (line 110) | type FloatingPanelProps = {

FILE: packages/design-system/src/components/gradient-picker.tsx
  type GradientPickerProps (line 64) | type GradientPickerProps<T extends ParsedGradient = ParsedGradient> = {
  constant THUMB_INTERACTION_DISTANCE (line 74) | const THUMB_INTERACTION_DISTANCE = 12;
  constant DRAG_THRESHOLD (line 75) | const DRAG_THRESHOLD = 3;
  constant SLIDER_HEIGHT (line 76) | const SLIDER_HEIGHT = 16;
  constant THUMB_HEIGHT (line 77) | const THUMB_HEIGHT = 14;

FILE: packages/design-system/src/components/input-field.tsx
  type InputProps (line 199) | type InputProps = Omit<
  type InputFieldProps (line 207) | type InputFieldProps = {

FILE: packages/design-system/src/components/kbd.tsx
  type ShortcutDefinition (line 17) | type ShortcutDefinition = ReadonlyArray<string>;

FILE: packages/design-system/src/components/label.tsx
  type Props (line 122) | type Props = {

FILE: packages/design-system/src/components/list-position-indicator.tsx
  constant CIRCLE_SIZE (line 9) | const CIRCLE_SIZE = 8;
  constant LINE_THICKNESS (line 10) | const LINE_THICKNESS = 2;
  constant OUTLINE_WIDTH (line 11) | const OUTLINE_WIDTH = 1;
  constant OVERLAP (line 15) | const OVERLAP = 2;

FILE: packages/design-system/src/components/menu.stories.tsx
  type Fruit (line 150) | type Fruit = "Apple" | "Banana" | "Orange" | "Peach";

FILE: packages/design-system/src/components/nested-icon-label.tsx
  type Props (line 85) | type Props = ComponentProps<"label"> & {

FILE: packages/design-system/src/components/panel-title.tsx
  type TitleProps (line 15) | type TitleProps = ComponentProps<"div"> & {

FILE: packages/design-system/src/components/position-grid.tsx
  type Position (line 13) | type Position = { y: number; x: number };
  type MixedPosition (line 14) | type MixedPosition = { y: number | string; x: number | string };
  type PositionGridProps (line 120) | type PositionGridProps = {

FILE: packages/design-system/src/components/primitives/arrow-focus.tsx
  type Render (line 8) | type Render = (props: {

FILE: packages/design-system/src/components/primitives/dnd/canvas.stories.tsx
  constant ROOT_ID (line 15) | const ROOT_ID = "root";
  type ItemData (line 17) | type ItemData = {
  method elementToData (line 206) | elementToData(element) {
  method swapDropTarget (line 210) | swapDropTarget(dropTarget) {
  method onDropTargetChange (line 245) | onDropTargetChange(dropTarget) {
  method elementToData (line 263) | elementToData(element) {
  method onStart (line 270) | onStart({ data: id }) {
  method onEnd (line 279) | onEnd({ isCanceled }) {

FILE: packages/design-system/src/components/primitives/dnd/geometry-utils.ts
  type Rect (line 1) | type Rect = {
  type Point (line 8) | type Point = { x: number; y: number };
  type ChildrenOrientation (line 10) | type ChildrenOrientation =
  type Placement (line 14) | type Placement = {
  type Area (line 23) | type Area = "top" | "bottom" | "left" | "right" | "center";

FILE: packages/design-system/src/components/primitives/dnd/placement-indicator.tsx
  type PlacementIndicatorOptions (line 64) | type PlacementIndicatorOptions = {

FILE: packages/design-system/src/components/primitives/dnd/sortable-list.stories.tsx
  type ItemData (line 16) | type ItemData = { id: string; text: string };
  method elementToData (line 82) | elementToData(element) {
  method swapDropTarget (line 85) | swapDropTarget(dropTarget) {
  method onDropTargetChange (line 96) | onDropTargetChange(dropTarget) {
  method elementToData (line 114) | elementToData(element) {
  method onStart (line 118) | onStart({ data }) {
  method onEnd (line 127) | onEnd({ isCanceled }) {

FILE: packages/design-system/src/components/primitives/dnd/use-auto-scroll.ts
  constant FRAME_PERIOD (line 5) | const FRAME_PERIOD = 30;
  type UseAutoScrollProps (line 42) | type UseAutoScrollProps = {
  type UseAutoScrollHandlers (line 54) | type UseAutoScrollHandlers = {
  method handleMove (line 157) | handleMove({ x, y }) {
  method setEnabled (line 187) | setEnabled(newEnabled) {

FILE: packages/design-system/src/components/primitives/dnd/use-drag.ts
  type State (line 4) | type State<Data> = {
  type UseDragProps (line 22) | type UseDragProps<DragItemData> = {
  type UseDragHandlers (line 36) | type UseDragHandlers = {
  method rootRef (line 216) | rootRef(element) {
  method cancelCurrentDrag (line 219) | cancelCurrentDrag() {

FILE: packages/design-system/src/components/primitives/dnd/use-drop.ts
  type PartialDropTarget (line 16) | type PartialDropTarget<Data> = {
  type DropTarget (line 21) | type DropTarget<Data> = PartialDropTarget<Data> & {
  type UseDropProps (line 34) | type UseDropProps<Data> = {
  type UseDropHandlers (line 72) | type UseDropHandlers = {
  method handleMove (line 278) | handleMove(pointerCoordinates) {
  method handleScroll (line 283) | handleScroll() {
  method handleStart (line 287) | handleStart() {
  method handleEnd (line 291) | handleEnd() {
  method rootRef (line 295) | rootRef(rootElement) {
  method handleDomMutation (line 299) | handleDomMutation() {

FILE: packages/design-system/src/components/primitives/dnd/use-hold.ts
  type UseHoldProps (line 3) | type UseHoldProps<Data> = {
  method reset (line 42) | reset() {

FILE: packages/design-system/src/components/primitives/dnd/use-sortable.tsx
  type UseSortable (line 12) | type UseSortable<Item> = {
  method elementToData (line 36) | elementToData() {
  method swapDropTarget (line 39) | swapDropTarget() {
  method onDropTargetChange (line 45) | onDropTargetChange(dropTarget) {
  method elementToData (line 61) | elementToData(element) {
  method onStart (line 74) | onStart({ data }) {
  method onEnd (line 81) | onEnd({ isCanceled }) {

FILE: packages/design-system/src/components/primitives/list.tsx
  type ListProps (line 5) | type ListProps = SlotProps & {
  type ListItemProps (line 23) | type ListItemProps = SlotProps & {
  method onPress (line 46) | onPress(event) {

FILE: packages/design-system/src/components/primitives/numeric-gesture-control.stories.tsx
  method getAcceleration (line 28) | getAcceleration() {

FILE: packages/design-system/src/components/primitives/numeric-gesture-control.ts
  type NumericScrubDirection (line 46) | type NumericScrubDirection = "horizontal" | "vertical";
  type NumericScrubValue (line 48) | type NumericScrubValue = number;
  type NumericScrubEvent (line 50) | type NumericScrubEvent = {
  type NumericScrubCallback (line 57) | type NumericScrubCallback = (event: NumericScrubEvent) => void;
  type NumericScrubOptions (line 59) | type NumericScrubOptions = {
  type NumericScrubState (line 80) | type NumericScrubState = {

FILE: packages/design-system/src/components/primitives/small-button.tsx
  type Props (line 89) | type Props = {

FILE: packages/design-system/src/components/primitives/use-scrub.ts
  method onValueInput (line 50) | onValueInput(event) {
  method onValueChange (line 58) | onValueChange(event) {

FILE: packages/design-system/src/components/scroll-area.tsx
  type ScrollAreaProps (line 68) | type ScrollAreaProps = {

FILE: packages/design-system/src/components/search-field.tsx
  type UseSearchFieldKeys (line 100) | type UseSearchFieldKeys = {

FILE: packages/design-system/src/components/select-button.tsx
  type Props (line 67) | type Props = Omit<ComponentProps<"button">, "prefix"> & {

FILE: packages/design-system/src/components/select.tsx
  type SelectItemProps (line 81) | type SelectItemProps = ComponentProps<typeof StyledItem> & {
  type SelectOption (line 87) | type SelectOption = string;
  type TriggerPassThroughProps (line 149) | type TriggerPassThroughProps = Omit<
  type SelectProps (line 155) | type SelectProps<Option = SelectOption> = {

FILE: packages/design-system/src/components/small-icon-button.tsx
  type Props (line 24) | type Props = {

FILE: packages/design-system/src/components/small-toggle-button.tsx
  type Props (line 13) | type Props = {

FILE: packages/design-system/src/components/text-area.tsx
  type Props (line 94) | type Props = Omit<

FILE: packages/design-system/src/components/text.ts
  type Variant (line 9) | type Variant = keyof typeof typography;
  type VariantStyle (line 10) | type VariantStyle = typeof normalize & (typeof typography)[Variant];

FILE: packages/design-system/src/components/toast.tsx
  constant ANIMATION_SLIDE_LENGTH (line 19) | const ANIMATION_SLIDE_LENGTH = 30;
  type ToastVariant (line 110) | type ToastVariant = React.ComponentProps<typeof ToastVariants>["variant"];
  type Options (line 383) | type Options = Pick<ToastOptions, "duration" | "id" | "icon">;

FILE: packages/design-system/src/components/toggle-button.tsx
  type Props (line 11) | type Props = {

FILE: packages/design-system/src/components/toggle-group.tsx
  type Color (line 18) | type Color = "default" | "preset" | "local" | "remote" | "overwritten";
  type ToggleGroupProps (line 24) | type ToggleGroupProps = ComponentProps<
  type ToggleGroupButtonProps (line 103) | type ToggleGroupButtonProps = ComponentProps<typeof ToggleGroupPrimitive...

FILE: packages/design-system/src/components/toolbar.tsx
  type ToolbarButtonProps (line 91) | type ToolbarButtonProps = SlotProps & {

FILE: packages/design-system/src/components/tooltip.tsx
  type TooltipProps (line 19) | type TooltipProps = ComponentProps<typeof TooltipPrimitive.Root> &

FILE: packages/design-system/src/components/tree.stories.tsx
  type Node (line 18) | type Node = {
  type FlatNode (line 23) | type FlatNode = {
  type DropTarget (line 115) | type DropTarget = {

FILE: packages/design-system/src/components/tree.tsx
  constant ITEM_PADDING_LEFT (line 37) | const ITEM_PADDING_LEFT = 8;
  constant ITEM_PADDING_RIGHT (line 39) | const ITEM_PADDING_RIGHT = 10;
  constant BARS_GAP (line 40) | const BARS_GAP = 16;
  constant EXPAND_WIDTH (line 41) | const EXPAND_WIDTH = 24;
  type TreeDropTarget (line 205) | type TreeDropTarget = {

FILE: packages/design-system/src/stitches.config.ts
  type VariblesValues (line 176) | type VariblesValues = typeof config.theme;
  type VariblesNames (line 178) | type VariblesNames = {
  type CSS (line 201) | type CSS = Stitches.CSS<typeof config>;

FILE: packages/domain/src/db/domain.ts
  type Result (line 13) | type Result = { success: false; error: string } | { success: true };
  type Status (line 212) | type Status = "active" | "pending" | "error";
  type StatusEnum (line 213) | type StatusEnum = Uppercase<Status>;
  type Domain (line 215) | type Domain = Database["public"]["Tables"]["Domain"]["Row"];
  type RefreshResult (line 217) | type RefreshResult =

FILE: packages/domain/src/rdap.ts
  type DNSList (line 1) | interface DNSList {

FILE: packages/domain/src/trpc/domain.ts
  type DomainRouter (line 341) | type DomainRouter = typeof domainRouter;

FILE: packages/feature-flags/src/feature.ts
  type Name (line 5) | type Name = keyof typeof flags;

FILE: packages/fonts/src/constants.ts
  constant SYSTEM_FONTS (line 3) | const SYSTEM_FONTS = new Map([
  constant DEFAULT_FONT_FALLBACK (line 260) | const DEFAULT_FONT_FALLBACK = "sans-serif";
  constant FONT_FORMATS (line 262) | const FONT_FORMATS: Map<FontFormat, string> = new Map([
  constant FONT_MIME_TYPES (line 268) | const FONT_MIME_TYPES = Array.from(FONT_FORMATS.keys())
  constant FONT_STYLES (line 272) | const FONT_STYLES = ["normal", "italic", "oblique"] as const;
  type FontStyle (line 273) | type FontStyle = (typeof FONT_STYLES)[number];

FILE: packages/fonts/src/font-weights.ts
  type FontWeight (line 49) | type FontWeight = keyof typeof fontWeights;

FILE: packages/fonts/src/get-font-faces.ts
  type PartialFontAsset (line 4) | type PartialFontAsset = {
  type FontFace (line 10) | type FontFace = {

FILE: packages/fonts/src/schema.ts
  type FontFormat (line 9) | type FontFormat = z.infer<typeof FontFormat>;
  type VariationAxes (line 38) | type VariationAxes = z.infer<typeof VariationAxes>;
  type FontMetaStatic (line 46) | type FontMetaStatic = z.infer<typeof FontMetaStatic>;
  type FontMeta (line 55) | type FontMeta = z.infer<typeof FontMeta>;

FILE: packages/generate-arg-types/src/arg-types.ts
  type FilterPredicate (line 4) | type FilterPredicate = (prop: PropItem) => boolean;

FILE: packages/generate-arg-types/src/cli.ts
  constant GENERATED_FILES_DIR (line 11) | const GENERATED_FILES_DIR = "__generated__";
  constant CLI_ARGS_OPTIONS (line 18) | const CLI_ARGS_OPTIONS = {
  type ComponentNameType (line 58) | type ComponentNameType = string;
  type CustomDescriptionsType (line 59) | type CustomDescriptionsType = {

FILE: packages/html-data/bin/aria.ts
  type Attribute (line 21) | type Attribute = {

FILE: packages/html-data/bin/attributes.ts
  type Attribute (line 27) | type Attribute = {

FILE: packages/html-data/bin/crawler.ts
  type Document (line 4) | type Document = DefaultTreeAdapterMap["document"];
  type ChildNode (line 6) | type ChildNode = DefaultTreeAdapterMap["childNode"];
  type Node (line 8) | type Node = DefaultTreeAdapterMap["node"];
  type NodeWithChildren (line 10) | type NodeWithChildren = Extract<ChildNode, { childNodes: ChildNode[] }>;
  type Element (line 12) | type Element = DefaultTreeAdapterMap["element"];
  type Attribute (line 14) | type Attribute = Element["attrs"][number];

FILE: packages/html-data/bin/elements.ts
  type Element (line 15) | type Element = {

FILE: packages/html-data/src/__generated__/aria.ts
  type Attribute (line 1) | type Attribute = {

FILE: packages/html-data/src/__generated__/attributes.ts
  type Attribute (line 1) | type Attribute = {

FILE: packages/html-data/src/__generated__/elements.ts
  type Element (line 1) | type Element = {

FILE: packages/http-client/src/index.ts
  type Data (line 17) | type Data = {

FILE: packages/icons/generate.ts
  type GenerateOptions (line 47) | type GenerateOptions = {

FILE: packages/icons/src/types.ts
  type IconProps (line 7) | interface IconProps extends SVGAttributes<SVGElement> {
  type IconComponent (line 13) | type IconComponent = ForwardRefExoticComponent<
  type IconRecord (line 17) | type IconRecord = Record<string, IconComponent>;
  type IconRecords (line 18) | type IconRecords = Record<string, IconRecord>;

FILE: packages/image/src/image-dev.stories.tsx
  type ImageProps (line 16) | type ImageProps = React.ComponentProps<typeof ImagePrimitive>;
  constant USE_CLOUDFLARE_IMAGE_TRANSFORM (line 22) | const USE_CLOUDFLARE_IMAGE_TRANSFORM = false;
  constant REMOTE_SELF_DOMAIN_IMAGE (line 25) | const REMOTE_SELF_DOMAIN_IMAGE = "https://webstudio.is/logo.webp";

FILE: packages/image/src/image-loaders.ts
  constant NON_EXISTING_DOMAIN (line 4) | const NON_EXISTING_DOMAIN = "https://a3cbcbec-cdb1-4ea4-ad60-43c795308dd...
  type VideoLoader (line 64) | type VideoLoader = (options: { src: string }) => string;

FILE: packages/image/src/image-optimize.ts
  type ImageLoader (line 88) | type ImageLoader = (
  constant DEFAULT_SIZES (line 231) | const DEFAULT_SIZES = "(min-width: 1280px) 50vw, 100vw";
  constant DEFAULT_QUALITY (line 233) | const DEFAULT_QUALITY = 80;

FILE: packages/image/src/image.tsx
  type ImageProps (line 10) | type ImageProps = ComponentProps<typeof defaultTag> & {

FILE: packages/postgrest/src/__generated__/db-types.ts
  type Json (line 1) | type Json =
  type Database (line 9) | type Database = {
  type DatabaseWithoutInternals (line 1033) | type DatabaseWithoutInternals = Omit<Database, "__InternalSupabase">;
  type DefaultSchema (line 1035) | type DefaultSchema = DatabaseWithoutInternals[Extract<
  type Tables (line 1040) | type Tables<
  type TablesInsert (line 1069) | type TablesInsert<
  type TablesUpdate (line 1094) | type TablesUpdate<
  type Enums (line 1119) | type Enums<
  type CompositeTypes (line 1136) | type CompositeTypes<

FILE: packages/postgrest/src/index.server.ts
  type Client (line 5) | type Client = PostgrestClient<Database>;

FILE: packages/postgrest/supabase/tests/latest-builds-domains.sql
  type "public" (line 102) | CREATE

FILE: packages/prisma-client/migrations-cli/cli.ts
  constant USAGE (line 11) | const USAGE = `Usage: migrations <command> [--dev]

FILE: packages/prisma-client/migrations-cli/commands.ts
  type StartedMigration (line 25) | type StartedMigration = {
  type Status (line 31) | type Status = {

FILE: packages/prisma-client/migrations-cli/errors.ts
  class UserError (line 3) | class UserError extends Error {}

FILE: packages/prisma-client/migrations-cli/prisma-migrations.ts
  method prisma (line 25) | get prisma() {
  type PrismaMigration (line 66) | type PrismaMigration = {

FILE: packages/prisma-client/migrations-cli/umzug.ts
  method resolve (line 13) | resolve(params) {
  method logMigration (line 60) | logMigration(params) {
  method unlogMigration (line 63) | unlogMigration() {
  method executed (line 67) | async executed() {

FILE: packages/prisma-client/prisma/migrations/20220601192603_start/migration.sql
  type "Project" (line 2) | CREATE TABLE "Project" (
  type "User" (line 15) | CREATE TABLE "User" (
  type "Tree" (line 22) | CREATE TABLE "Tree" (
  type "InstanceProps" (line 30) | CREATE TABLE "InstanceProps" (
  type "Breakpoints" (line 40) | CREATE TABLE "Breakpoints" (
  type "Project" (line 48) | CREATE UNIQUE INDEX "Project_domain_key" ON "Project"("domain")

FILE: packages/prisma-client/prisma/migrations/20220608130924_/migration.sql
  type "User" (line 15) | CREATE UNIQUE INDEX "User_email_key" ON "User"("email")

FILE: packages/prisma-client/prisma/migrations/20220608131719_add_user/migration.sql
  type "User" (line 15) | CREATE UNIQUE INDEX "User_email_key" ON "User"("email")

FILE: packages/prisma-client/prisma/migrations/20220611091346_add_email/migration.sql
  type "User" (line 15) | CREATE UNIQUE INDEX "User_email_key" ON "User"("email")

FILE: packages/prisma-client/prisma/migrations/20220624214305_teams/migration.sql
  type "Team" (line 11) | CREATE TABLE "Team" (

FILE: packages/prisma-client/prisma/migrations/20220714112221_add_assets/migration.sql
  type "Asset" (line 2) | CREATE TABLE "Asset" (

FILE: packages/prisma-client/prisma/migrations/20220909124449_builds/migration.sql
  type "Build" (line 2) | CREATE TABLE "Build" (

FILE: packages/prisma-client/prisma/migrations/20221126165439_design-tokens/migration.sql
  type "DesignTokens" (line 2) | CREATE TABLE "DesignTokens" (

FILE: packages/prisma-client/prisma/migrations/20221201075120_user-props/migration.ts
  type UserDbProp (line 35) | type UserDbProp = z.infer<typeof UserDbProp>;

FILE: packages/prisma-client/prisma/migrations/20221218211129_tree_text/migration.ts
  type PrevInstance (line 3) | type PrevInstance = {
  type Text (line 10) | type Text = {
  type Instance (line 15) | type Instance = {

FILE: packages/prisma-client/prisma/migrations/20230106000143_tree_styles_data/migration.ts
  type StylesItem (line 3) | type StylesItem = {
  type Styles (line 10) | type Styles = StylesItem[];
  type CssRule (line 12) | type CssRule = {
  type Text (line 17) | type Text = {
  type Instance (line 22) | type Instance = {

FILE: packages/prisma-client/prisma/migrations/20230115165314_tree_instances_data/migration.ts
  type Text (line 3) | type Text = {
  type Id (line 8) | type Id = {
  type Instance (line 13) | type Instance = {
  type InstancesItem (line 21) | type InstancesItem = {

FILE: packages/prisma-client/prisma/migrations/20230119013820_instance-props-uniq/migration.sql
  type "InstanceProps" (line 2) | CREATE UNIQUE INDEX "InstanceProps_instanceId_treeId_key" ON "InstancePr...

FILE: packages/prisma-client/prisma/migrations/20230119181858_tree_props_data/migration.ts
  type PropsItem (line 3) | type PropsItem = {

FILE: packages/prisma-client/prisma/migrations/20230120130130_dashboard-project/migration.sql
  type "DashboardProject" (line 2) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20230120130131_dashboard-project-is-prod/migration.sql
  type "DashboardProject" (line 2) | CREATE

FILE: packages/prisma-client/prisma/migrations/20230123225816_dashboard-project-is-deleted/migration.sql
  type "DashboardProject" (line 11) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20230124131218_authorization-tokens/migration.sql
  type "AuthorizationTokens" (line 5) | CREATE TABLE "AuthorizationTokens" (

FILE: packages/prisma-client/prisma/migrations/20230130121041_tree_relations_data/migration.ts
  type TreeId (line 3) | type TreeId = string;
  type BuildId (line 4) | type BuildId = string;
  type ProjectId (line 5) | type ProjectId = string;
  type Page (line 7) | type Page = {
  type Pages (line 16) | type Pages = {

FILE: packages/prisma-client/prisma/migrations/20230130153140_authorization-tokens-fix/migration.sql
  type "AuthorizationToken" (line 11) | CREATE TABLE "AuthorizationToken" (

FILE: packages/prisma-client/prisma/migrations/20230130160827_build_styles/migration.ts
  type InstanceId (line 4) | type InstanceId = string;
  type StyleSourceId (line 5) | type StyleSourceId = string;
  type BuildId (line 6) | type BuildId = string;
  type TreeId (line 7) | type TreeId = string;
  type TreeStyleDecl (line 9) | type TreeStyleDecl = {
  type TreeStyles (line 16) | type TreeStyles = TreeStyleDecl[];
  type StyleDecl (line 18) | type StyleDecl = {
  type Styles (line 25) | type Styles = StyleDecl[];
  type StyleSource (line 27) | type StyleSource = {
  type StyleSources (line 33) | type StyleSources = StyleSource[];
  type StyleSourceSelection (line 35) | type StyleSourceSelection = {
  type StyleSourceSelections (line 40) | type StyleSourceSelections = StyleSourceSelection[];

FILE: packages/prisma-client/prisma/migrations/20230202131409_project-created-at/migration.sql
  type "DashboardProject" (line 11) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20230213220858_is-deleted-uniq/migration.sql
  type "Project" (line 2) | CREATE UNIQUE INDEX "Project_id_isDeleted_key" ON "Project"("id", "isDel...
  type "Project" (line 5) | CREATE UNIQUE INDEX "Project_domain_isDeleted_key" ON "Project"("domain"...

FILE: packages/prisma-client/prisma/migrations/20230227142622_build_style_source_selections_data/migration.ts
  type InstanceId (line 3) | type InstanceId = string;
  type StyleSourceId (line 4) | type StyleSourceId = string;
  type BuildId (line 5) | type BuildId = string;
  type StyleSourceSelection (line 7) | type StyleSourceSelection = {
  type StyleSourceSelections (line 12) | type StyleSourceSelections = StyleSourceSelection[];

FILE: packages/prisma-client/prisma/migrations/20230227180250_build_props_data/migration.ts
  type PropId (line 3) | type PropId = string;
  type InstanceId (line 4) | type InstanceId = string;
  type BuildId (line 5) | type BuildId = string;
  type Prop (line 7) | type Prop = {
  type Props (line 12) | type Props = Prop[];

FILE: packages/prisma-client/prisma/migrations/20230228132402_drop_style_source_tree_id/migration.ts
  type StyleSource (line 3) | type StyleSource = {

FILE: packages/prisma-client/prisma/migrations/20230228161419_page_root_instance_id/migration.ts
  type InstanceId (line 3) | type InstanceId = string;
  type BuildId (line 4) | type BuildId = string;
  type TreeId (line 5) | type TreeId = string;
  type Instance (line 7) | type Instance = {
  type Page (line 11) | type Page = {
  type Pages (line 17) | type Pages = {

FILE: packages/prisma-client/prisma/migrations/20230228194553_build_instances_data/migration.ts
  type InstanceId (line 3) | type InstanceId = string;
  type BuildId (line 4) | type BuildId = string;
  type Child (line 6) | type Child =
  type Instance (line 10) | type Instance = {

FILE: packages/prisma-client/prisma/migrations/20230228222541_convert-image-style/migration.ts
  type Unit (line 6) | type Unit = z.infer<typeof Unit>;
  type UnitValue (line 14) | type UnitValue = z.infer<typeof UnitValue>;
  type KeywordValue (line 21) | type KeywordValue = z.infer<typeof KeywordValue>;
  type FontFamilyValue (line 35) | type FontFamilyValue = z.infer<typeof FontFamilyValue>;
  type RgbValue (line 44) | type RgbValue = z.infer<typeof RgbValue>;
  type ImageValue (line 51) | type ImageValue = z.infer<typeof ImageValue>;
  type InvalidValue (line 59) | type InvalidValue = z.infer<typeof InvalidValue>;
  type UnsetValue (line 65) | type UnsetValue = z.infer<typeof UnsetValue>;
  type ArrayValue (line 71) | type ArrayValue = z.infer<typeof ArrayValue>;
  type ValidStaticStyleValue (line 98) | type ValidStaticStyleValue = z.infer<typeof ValidStaticStyleValue>;
  type VarValue (line 105) | type VarValue = z.infer<typeof VarValue>;
  type StoredStyleDecl (line 140) | type StoredStyleDecl = z.infer<typeof StoredStyleDecl>;

FILE: packages/prisma-client/prisma/migrations/20230301101527_drop_page_tree_id/migration.ts
  type TreeId (line 3) | type TreeId = string;
  type Page (line 5) | type Page = {
  type Pages (line 10) | type Pages = {

FILE: packages/prisma-client/prisma/migrations/20230301134408_convert-background-to-layers/migration.ts
  type Unit (line 6) | type Unit = z.infer<typeof Unit>;
  type UnitValue (line 14) | type UnitValue = z.infer<typeof UnitValue>;
  type KeywordValue (line 21) | type KeywordValue = z.infer<typeof KeywordValue>;
  type FontFamilyValue (line 35) | type FontFamilyValue = z.infer<typeof FontFamilyValue>;
  type RgbValue (line 44) | type RgbValue = z.infer<typeof RgbValue>;
  type ImageValue (line 51) | type ImageValue = z.infer<typeof ImageValue>;
  type InvalidValue (line 59) | type InvalidValue = z.infer<typeof InvalidValue>;
  type UnsetValue (line 65) | type UnsetValue = z.infer<typeof UnsetValue>;
  type ValidStaticStyleValue (line 81) | type ValidStaticStyleValue = z.infer<typeof ValidStaticStyleValue>;
  type VarValue (line 88) | type VarValue = z.infer<typeof VarValue>;
  type StoredStyleDecl (line 126) | type StoredStyleDecl = z.infer<typeof StoredStyleDecl>;

FILE: packages/prisma-client/prisma/migrations/20230501151815_file/migration.sql
  type "File" (line 2) | CREATE TABLE "File" (

FILE: packages/prisma-client/prisma/migrations/20230517150043_domain/migration.sql
  type "Domain" (line 5) | CREATE TABLE "Domain" (
  type "ProjectDomain" (line 17) | CREATE TABLE "ProjectDomain" (
  type "Domain" (line 28) | CREATE UNIQUE INDEX "Domain_domain_key" ON "Domain"("domain")
  type "ProjectDomain" (line 31) | CREATE UNIQUE INDEX "ProjectDomain_txtRecord_key" ON "ProjectDomain"("tx...
  type "ProjectDomain" (line 34) | CREATE INDEX "ProjectDomain_domainId_idx" ON "ProjectDomain"("domainId")
  type "ProjectWithDomain" (line 44) | CREATE VIEW "ProjectWithDomain" AS

FILE: packages/prisma-client/prisma/migrations/20230530132921_deployment/migration.sql
  type "Build" (line 19) | CREATE UNIQUE INDEX "Build_id_key" ON "Build"("id")
  type "Build" (line 21) | CREATE UNIQUE INDEX "Build_dev_index" ON "Build" ("projectId") WHERE "de...
  type "DashboardProject" (line 24) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20230606234538_latest-build/migration.sql
  type "Project" (line 11) | CREATE UNIQUE INDEX "Project_id_domain_key" ON "Project"("id", "domain")
  type "LatestBuildPerProjectDomain" (line 14) | CREATE OR REPLACE VIEW "LatestBuildPerProjectDomain" AS
  type "LatestBuildPerProject" (line 63) | CREATE OR REPLACE VIEW "LatestBuildPerProject" AS

FILE: packages/prisma-client/prisma/migrations/20230610111903_button_children/migration.ts
  type Text (line 3) | type Text = {
  type Id (line 8) | type Id = {
  type Instance (line 13) | type Instance = {
  type InstancesList (line 21) | type InstancesList = Instance[];
  type BaseProp (line 23) | type BaseProp = {
  type Prop (line 30) | type Prop = BaseProp &
  type PropsList (line 43) | type PropsList = Prop[];

FILE: packages/prisma-client/prisma/migrations/20230611121710_merge_block_text_components/migration.ts
  type Text (line 3) | type Text = {
  type Id (line 8) | type Id = {
  type Instance (line 13) | type Instance = {
  type InstancesList (line 21) | type InstancesList = Instance[];

FILE: packages/prisma-client/prisma/migrations/20230611181439_control_labels/migration.ts
  type Text (line 3) | type Text = {
  type Id (line 8) | type Id = {
  type Instance (line 13) | type Instance = {
  type InstancesList (line 21) | type InstancesList = Instance[];

FILE: packages/prisma-client/prisma/migrations/20230702002752_form_data_sources/migration.ts
  type Text (line 13) | type Text = {
  type Id (line 18) | type Id = {
  type Instance (line 23) | type Instance = {
  type InstancesList (line 31) | type InstancesList = Instance[];
  type BaseProp (line 33) | type BaseProp = {
  type Prop (line 40) | type Prop = BaseProp &
  type PropsList (line 51) | type PropsList = Prop[];
  type DataSourceVariableValue (line 53) | type DataSourceVariableValue =
  type DataSource (line 59) | type DataSource =
  type DataSourcesList (line 75) | type DataSourcesList = DataSource[];

FILE: packages/prisma-client/prisma/migrations/20230911125308_form_action/migration.ts
  type Text (line 11) | type Text = {
  type Id (line 16) | type Id = {
  type Instance (line 21) | type Instance = {
  type InstancesList (line 29) | type InstancesList = Instance[];
  type BaseProp (line 31) | type BaseProp = {
  type Prop (line 38) | type Prop = BaseProp &
  type PropsList (line 53) | type PropsList = Prop[];

FILE: packages/prisma-client/prisma/migrations/20231108172804_prop_expression/migration.ts
  type BaseProp (line 3) | type BaseProp = {
  type Prop (line 10) | type Prop = BaseProp &
  type PropsList (line 26) | type PropsList = Prop[];
  type DataSourceVariableValue (line 28) | type DataSourceVariableValue =
  type DataSource (line 35) | type DataSource =
  type DataSourcesList (line 51) | type DataSourcesList = DataSource[];

FILE: packages/prisma-client/prisma/migrations/20231115205820_client-references/migration.sql
  type "ClientReferences" (line 4) | CREATE TABLE "ClientReferences" (
  type "ClientReferences" (line 15) | CREATE UNIQUE INDEX "ClientReferences_userId_service_key" ON "ClientRefe...
  type "ClientReferences" (line 18) | CREATE UNIQUE INDEX "ClientReferences_reference_service_key" ON "ClientR...

FILE: packages/prisma-client/prisma/migrations/20231116173417_product/migration.sql
  type "Product" (line 2) | CREATE TABLE "Product" (

FILE: packages/prisma-client/prisma/migrations/20231117095612_transaction/migration.sql
  type "TransactionLog" (line 10) | CREATE TABLE "TransactionLog" (
  type "TransactionLog" (line 20) | CREATE UNIQUE INDEX "TransactionLog_eventId_productId_key" ON "Transacti...
  type "TransactionLog" (line 23) | CREATE UNIQUE INDEX "TransactionLog_sessionId_productId_key" ON "Transac...

FILE: packages/prisma-client/prisma/migrations/20231120172840_add-event-type/migration.sql
  type "UserProduct" (line 22) | CREATE VIEW "UserProduct" AS

FILE: packages/prisma-client/prisma/migrations/20231121125755_token-uniq/migration.sql
  type "AuthorizationToken" (line 2) | CREATE UNIQUE INDEX "AuthorizationToken_token_key" ON "AuthorizationToke...

FILE: packages/prisma-client/prisma/migrations/20231129164239_event-data/migration.sql
  type "UserProduct" (line 37) | CREATE VIEW "UserProduct" AS

FILE: packages/prisma-client/prisma/migrations/20240112155725_user_product_view/migration.sql
  type "UserProduct" (line 1) | CREATE OR REPLACE VIEW "UserProduct" AS (

FILE: packages/prisma-client/prisma/migrations/20240125182656_calc-domains/migration.sql
  type "ProjectWithDomain" (line 1) | CREATE OR REPLACE VIEW "ProjectWithDomain" AS

FILE: packages/prisma-client/prisma/migrations/20240127230238_project-preview/migration.sql
  type "DashboardProject" (line 18) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20240131200102_page_meta_expressions/migration.ts
  type Folder (line 3) | type Folder = {
  type Page (line 10) | type Page = {
  type ProjectMeta (line 31) | type ProjectMeta = {
  type PageRedirect (line 37) | type PageRedirect = {
  type ProjectSettings (line 42) | type ProjectSettings = {
  type Pages (line 47) | type Pages = {

FILE: packages/prisma-client/prisma/migrations/20240229133316_add-approval-status/migration.sql
  type "DashboardProject" (line 5) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20240309212641_page_system_variable/migration.ts
  type DataSource (line 4) | type DataSource = {
  type Page (line 11) | type Page = {
  type Pages (line 35) | type Pages = {

FILE: packages/prisma-client/prisma/migrations/20240315173349_add-approved-marketplace-product/migration.sql
  type "Build" (line 2) | CREATE INDEX "Build_projectId_createdAt_idx" ON "Build"("projectId", "cr...
  type "Project" (line 6) | CREATE INDEX "Project_isDeleted_marketplaceApprovalStatus_idx" ON "Proje...
  type "ApprovedMarketplaceProduct" (line 9) | CREATE VIEW "ApprovedMarketplaceProduct" AS

FILE: packages/prisma-client/prisma/migrations/20240530162819_marketplace-token/migration.sql
  type "ApprovedMarketplaceProduct" (line 4) | CREATE VIEW "ApprovedMarketplaceProduct" AS

FILE: packages/prisma-client/prisma/migrations/20240723144019_latest-build/migration.sql
  type "LatestBuildPerProject" (line 1) | CREATE OR REPLACE VIEW "LatestBuildPerProject" AS
  type "LatestBuildPerProjectDomain" (line 38) | CREATE OR REPLACE VIEW "LatestBuildPerProjectDomain" AS

FILE: packages/prisma-client/prisma/migrations/20240723150501_latest-static-build/migration.sql
  type "LatestStaticBuildPerProject" (line 2) | CREATE OR REPLACE VIEW "LatestStaticBuildPerProject" AS

FILE: packages/prisma-client/prisma/migrations/20240725003228_clone_project/migration.sql
  function clone_project (line 2) | CREATE FUNCTION clone_project(

FILE: packages/prisma-client/prisma/migrations/20240730131207_clone_project_preview_imagea/migration.sql
  function clone_project (line 2) | CREATE FUNCTION clone_project(

FILE: packages/prisma-client/prisma/migrations/20240731170412_create_production_build/migration.sql
  function create_production_build (line 2) | CREATE FUNCTION create_production_build(

FILE: packages/prisma-client/prisma/migrations/20240809220753_tz/migration.sql
  type "LatestStaticBuildPerProject" (line 9) | CREATE OR REPLACE VIEW "LatestStaticBuildPerProject" AS
  type "LatestBuildPerProject" (line 25) | CREATE OR REPLACE VIEW "LatestBuildPerProject" AS
  type "LatestBuildPerProjectDomain" (line 62) | CREATE OR REPLACE VIEW "LatestBuildPerProjectDomain" AS

FILE: packages/prisma-client/prisma/migrations/20240916143551_time/migration.sql
  type "LatestStaticBuildPerProject" (line 41) | CREATE OR REPLACE VIEW "LatestStaticBuildPerProject" AS
  type "ApprovedMarketplaceProduct" (line 59) | CREATE VIEW "ApprovedMarketplaceProduct" AS
  type "DashboardProject" (line 91) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20240918100751_latest-virtual-build/migration.sql
  type "domainsVirtual" (line 6) | CREATE TABLE "domainsVirtual" (
  function "domainsVirtual" (line 36) | CREATE OR REPLACE FUNCTION "domainsVirtual"("Project")
  type "latestBuildVirtual" (line 74) | CREATE TABLE "latestBuildVirtual" (
  function "latestBuildVirtual" (line 91) | CREATE OR REPLACE FUNCTION "latestBuildVirtual"("Project")
  function "latestBuildVirtual" (line 158) | CREATE OR REPLACE FUNCTION "latestBuildVirtual"("domainsVirtual")

FILE: packages/prisma-client/prisma/migrations/20240920091253_domain-ordering/migration.sql
  function "domainsVirtual" (line 2) | CREATE OR REPLACE FUNCTION "domainsVirtual"("Project")

FILE: packages/prisma-client/prisma/migrations/20240924174536_cleanup/migration.sql
  function "latestProjectDomainBuildVirtual" (line 5) | CREATE OR REPLACE FUNCTION "latestProjectDomainBuildVirtual"("Project")
  function database_cleanup (line 49) | CREATE OR REPLACE FUNCTION database_cleanup(

FILE: packages/prisma-client/prisma/migrations/20250322141808_user_publish_count/migration.sql
  type user_publish_count (line 1) | CREATE OR REPLACE VIEW user_publish_count AS

FILE: packages/prisma-client/prisma/migrations/20250710163439_restore_development_build/migration.sql
  function restore_development_build (line 2) | CREATE FUNCTION restore_development_build(
  type published_builds (line 31) | CREATE VIEW published_builds AS

FILE: packages/prisma-client/prisma/migrations/20250913204036_project_tags/migration.sql
  type "DashboardProject" (line 13) | CREATE VIEW "DashboardProject" AS

FILE: packages/prisma-client/prisma/migrations/20251129093846_add_updated_at_to_latest_build_virtual/migration.sql
  function "latestBuildVirtual" (line 17) | CREATE
  function "latestBuildVirtual" (line 61) | CREATE
  function "latestProjectDomainBuildVirtual" (line 89) | CREATE
  function "latestBuildVirtual" (line 127) | CREATE

FILE: packages/prisma-client/src/prisma.ts
  type PrismaClientOptions (line 36) | type PrismaClientOptions = {

FILE: packages/project-build/src/shared/graph-utils.ts
  type InstanceId (line 3) | type InstanceId = Instance["id"];

FILE: packages/project-build/src/shared/marketplace.ts
  type MarketplaceProduct (line 20) | type MarketplaceProduct = z.infer<typeof MarketplaceProduct>;

FILE: packages/project-build/src/types.ts
  type Build (line 16) | type Build = {
  type CompactBuild (line 35) | type CompactBuild = {

FILE: packages/project/src/db/project-domain.ts
  constant MIN_DOMAIN_LENGTH (line 7) | const MIN_DOMAIN_LENGTH = 10;

FILE: packages/project/src/db/project.ts
  type Project (line 42) | type Project = Awaited<ReturnType<typeof loadById>>;

FILE: packages/project/src/shared/schema.ts
  constant MIN_TITLE_LENGTH (line 3) | const MIN_TITLE_LENGTH = 2;
  type MarketplaceApprovalStatus (line 19) | type MarketplaceApprovalStatus = z.infer<

FILE: packages/project/src/trpc/project-router.ts
  type ProjectRouter (line 198) | type ProjectRouter = typeof projectRouter;

FILE: packages/react-sdk/placeholder.d.ts
  type Params (line 48) | type Params = Record<string, string | undefined>;

FILE: packages/react-sdk/src/components/components-utils.ts
  type AnyComponent (line 3) | type AnyComponent = React.ForwardRefExoticComponent<
  type Components (line 12) | type Components = Map<string, AnyComponent>;
  type WebstudioComponentSystemProps (line 14) | type WebstudioComponentSystemProps = {

FILE: packages/react-sdk/src/context.tsx
  type Params (line 8) | type Params = {

FILE: packages/react-sdk/src/hook.ts
  type InstanceData (line 3) | type InstanceData = {
  type HookContext (line 16) | type HookContext = {
  type InstancePath (line 26) | type InstancePath = InstanceData[];
  type NavigatorEvent (line 28) | type NavigatorEvent = {
  type Hook (line 35) | type Hook = {

FILE: packages/react-sdk/src/page-settings-canonical-link.tsx
  type PageSettingsCanonicalLinkProps (line 4) | type PageSettingsCanonicalLinkProps = {

FILE: packages/react-sdk/src/page-settings-meta.tsx
  type MetaProps (line 5) | type MetaProps = {

FILE: packages/react-sdk/src/page-settings-title.tsx
  type PageSettingsTitleProps (line 4) | type PageSettingsTitleProps = {

FILE: packages/sdk-cli/src/generate-stories.ts
  constant WS_NAMESPACE (line 19) | const WS_NAMESPACE = "ws";
  constant BASE_NAMESPACE (line 20) | const BASE_NAMESPACE = "@webstudio-is/sdk-components-react";

FILE: packages/sdk-components-animation/src/animate-children.tsx
  type ScrollProps (line 6) | type ScrollProps = {

FILE: packages/sdk-components-animation/src/animate-text.tsx
  type AnimateChildrenProps (line 23) | type AnimateChildrenProps = {

FILE: packages/sdk-components-animation/src/shared/create-progress-animation.tsx
  type ProgressAnimationProps (line 4) | type ProgressAnimationProps<T extends Record<string, unknown> = {}> = {

FILE: packages/sdk-components-animation/src/shared/meta.ts
  method get (line 5) | get(_target, prop) {

FILE: packages/sdk-components-animation/src/stagger-animation.tsx
  type StaggerAnimationProps (line 16) | type StaggerAnimationProps = {

FILE: packages/sdk-components-react-radix/src/__generated__/accordion.stories.tsx
  method render (line 90) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/checkbox.stories.tsx
  method render (line 41) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/collapsible.stories.tsx
  method render (line 34) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/dialog.stories.tsx
  method render (line 57) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/label.stories.tsx
  method render (line 17) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/navigation-menu.stories.tsx
  method render (line 215) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/popover.stories.tsx
  method render (line 42) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/radio-group.stories.tsx
  method render (line 75) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/select.stories.tsx
  method render (line 85) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/sheet.stories.tsx
  method render (line 66) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/switch.stories.tsx
  method render (line 19) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/tabs.stories.tsx
  method render (line 49) | render() {

FILE: packages/sdk-components-react-radix/src/__generated__/tooltip.stories.tsx
  method render (line 32) | render() {

FILE: packages/sdk-components-react-radix/src/dialog.tsx
  type Tag (line 189) | type Tag = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

FILE: packages/sdk-components-react-radix/src/shared/meta.ts
  method get (line 5) | get(_target, prop) {

FILE: packages/sdk-components-react-remix/src/link.tsx
  type Props (line 6) | type Props = Omit<ComponentPropsWithoutRef<typeof BaseLink>, "target"> & {

FILE: packages/sdk-components-react-remix/src/webhook-form.tsx
  type State (line 37) | type State = "initial" | "success" | "error";

FILE: packages/sdk-components-react-router/src/link.tsx
  type Props (line 6) | type Props = Omit<ComponentPropsWithoutRef<typeof BaseLink>, "target"> & {

FILE: packages/sdk-components-react-router/src/webhook-form.tsx
  type State (line 37) | type State = "initial" | "success" | "error";

FILE: packages/sdk-components-react/src/__generated__/blockquote.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/button.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/checkbox.stories.tsx
  method render (line 26) | render() {

FILE: packages/sdk-components-react/src/__generated__/content-embed.stories.tsx
  method render (line 21) | render() {

FILE: packages/sdk-components-react/src/__generated__/form.stories.tsx
  method render (line 47) | render() {

FILE: packages/sdk-components-react/src/__generated__/heading.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/label.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/link.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/list-item.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/list.stories.tsx
  method render (line 26) | render() {

FILE: packages/sdk-components-react/src/__generated__/markdown-embed.stories.tsx
  method render (line 21) | render() {

FILE: packages/sdk-components-react/src/__generated__/paragraph.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/radio-button.stories.tsx
  method render (line 26) | render() {

FILE: packages/sdk-components-react/src/__generated__/select.stories.tsx
  method render (line 25) | render() {

FILE: packages/sdk-components-react/src/__generated__/text.stories.tsx
  method render (line 16) | render() {

FILE: packages/sdk-components-react/src/__generated__/vimeo.stories.tsx
  method render (line 51) | render() {

FILE: packages/sdk-components-react/src/__generated__/you-tube.stories.tsx
  method render (line 51) | render() {

FILE: packages/sdk-components-react/src/blockquote.tsx
  type Props (line 9) | type Props = ComponentProps<typeof defaultTag>;

FILE: packages/sdk-components-react/src/box.tsx
  type Props (line 11) | type Props = ComponentProps<typeof defaultTag> & {

FILE: packages/sdk-components-react/src/button.tsx
  type ButtonProps (line 5) | type ButtonProps = ComponentProps<typeof defaultTag>;

FILE: packages/sdk-components-react/src/fragment.tsx
  type Props (line 3) | type Props = {

FILE: packages/sdk-components-react/src/head-link.tsx
  type LinkRel (line 12) | type LinkRel =
  type LinkAs (line 36) | type LinkAs =
  constant PROPS_ORDER (line 50) | const PROPS_ORDER = ["rel", "hrefLang", "href", "type", "as"] as const;

FILE: packages/sdk-components-react/src/head-meta.tsx
  constant PROPS_ORDER (line 12) | const PROPS_ORDER = ["property", "name", "content"] as const;

FILE: packages/sdk-components-react/src/head-title.tsx
  constant PROPS_ORDER (line 12) | const PROPS_ORDER = [] as const;

FILE: packages/sdk-components-react/src/heading.tsx
  type Props (line 15) | type Props = ComponentProps<typeof defaultTag> & {

FILE: packages/sdk-components-react/src/html-embed.test.tsx
  constant SCRIPT_TEST_ID (line 13) | const SCRIPT_TEST_ID = "script-a";
  constant SCRIPT_PROCESSED_TEST_ID (line 14) | const SCRIPT_PROCESSED_TEST_ID = `${scriptTestIdPrefix}${SCRIPT_TEST_ID}`;
  constant FRAGMENT_DIV_ID (line 16) | const FRAGMENT_DIV_ID = "div";

FILE: packages/sdk-components-react/src/html-embed.tsx
  type ScriptTask (line 74) | type ScriptTask = () => Promise<void>;
  type ChildProps (line 128) | type ChildProps = {
  type HtmlEmbedProps (line 214) | type HtmlEmbedProps = {

FILE: packages/sdk-components-react/src/image.tsx
  type Props (line 12) | type Props = Omit<ComponentPropsWithoutRef<typeof WebstudioImage>, "load...

FILE: packages/sdk-components-react/src/link.tsx
  type Props (line 9) | type Props = Omit<ComponentProps<"a">, "target" | "download"> & {

FILE: packages/sdk-components-react/src/list-item.tsx
  type Props (line 5) | type Props = ComponentProps<typeof defaultTag>;

FILE: packages/sdk-components-react/src/list.tsx
  type ListTag (line 15) | type ListTag = typeof unorderedTag | typeof orderedTag;
  type Props (line 17) | type Props = ComponentProps<typeof unorderedTag> &

FILE: packages/sdk-components-react/src/markdown-embed.tsx
  type MarkdownEmbedProps (line 5) | type MarkdownEmbedProps = ComponentProps<"div"> & {

FILE: packages/sdk-components-react/src/separator.tsx
  type Props (line 10) | type Props = ComponentProps<typeof defaultTag>;

FILE: packages/sdk-components-react/src/shared/video.ts
  type PlayerStatus (line 12) | type PlayerStatus = "initial" | "loading" | "ready";

FILE: packages/sdk-components-react/src/slot.tsx
  type Props (line 3) | type Props = {

FILE: packages/sdk-components-react/src/test-utils/cartesian.ts
  function cartesian (line 6) | function cartesian(...a: unknown[][]) {

FILE: packages/sdk-components-react/src/text.tsx
  type Props (line 11) | type Props = ComponentProps<typeof defaultTag> & {

FILE: packages/sdk-components-react/src/time.tsx
  type Language (line 279) | type Language = (typeof languages)[number];
  type Country (line 280) | type Country = (typeof countries)[number];
  type DateStyle (line 281) | type DateStyle = Intl.DateTimeFormatOptions["dateStyle"] | "none";
  type TimeStyle (line 282) | type TimeStyle = Intl.DateTimeFormatOptions["timeStyle"] | "none";
  constant INITIAL_DATE_STRING (line 284) | const INITIAL_DATE_STRING = "dateTime attribute is not set";
  constant INVALID_DATE_STRING (line 285) | const INVALID_DATE_STRING = "";
  constant DEFAULT_LANGUAGE (line 287) | const DEFAULT_LANGUAGE = "en";
  constant DEFAULT_COUNTRY (line 288) | const DEFAULT_COUNTRY = "GB";
  constant DEFAULT_DATE_STYLE (line 289) | const DEFAULT_DATE_STYLE = "medium";
  constant DEFAULT_TIME_STYLE (line 290) | const DEFAULT_TIME_STYLE = "none";
  type TimeProps (line 398) | type TimeProps = Pick<ComponentProps<"time">, "dateTime"> & {

FILE: packages/sdk-components-react/src/video.tsx
  constant READY_STATE (line 17) | const READY_STATE = {

FILE: packages/sdk-components-react/src/vimeo-play-button.tsx
  type Props (line 14) | type Props = ComponentProps<typeof Button>;

FILE: packages/sdk-components-react/src/vimeo-preview-image.tsx
  type Props (line 13) | type Props = ComponentProps<typeof Image>;

FILE: packages/sdk-components-react/src/vimeo-spinner.tsx
  type Props (line 11) | type Props = ComponentProps<typeof defaultTag>;

FILE: packages/sdk-components-react/src/vimeo.tsx
  type VimeoPlayerOptions (line 26) | type VimeoPlayerOptions = {
  constant PLAYER_CDN (line 144) | const PLAYER_CDN = "https://f.vimeocdn.com";
  constant IFRAME_CDN (line 146) | const IFRAME_CDN = "https://player.vimeo.com";
  constant IMAGE_CDN (line 148) | const IMAGE_CDN = "https://i.vimeocdn.com";
  type VimeoOptions (line 201) | type VimeoOptions = Omit<
  type PlayerProps (line 254) | type PlayerProps = Pick<
  type Props (line 347) | type Props = Omit<ComponentProps<typeof defaultTag>, keyof VimeoOptions> &
  type Ref (line 356) | type Ref = ElementRef<typeof defaultTag>;
  method onInitPlayer (line 420) | onInitPlayer() {

FILE: packages/sdk-components-react/src/webhook-form.tsx
  type Props (line 3) | type Props = ComponentProps<"form"> & {

FILE: packages/sdk-components-react/src/xml-node.stories.tsx
  method render (line 32) | render() {

FILE: packages/sdk-components-react/src/xml-node.tsx
  type Props (line 17) | type Props = {

FILE: packages/sdk-components-react/src/xml-time.tsx
  constant DEFAULT_DATE_STYLE (line 4) | const DEFAULT_DATE_STYLE = "short";
  constant INITIAL_DATE_STRING (line 5) | const INITIAL_DATE_STRING = "dateTime attribute is not set";
  constant INVALID_DATE_STRING (line 6) | const INVALID_DATE_STRING = "";
  type XmlTimeProps (line 8) | type XmlTimeProps = {

FILE: packages/sdk-components-react/src/youtube.tsx
  type YouTubePlayerParameters (line 18) | type YouTubePlayerParameters = {
  type YouTubePlayerOptions (line 151) | type YouTubePlayerOptions = {
  constant PLAYER_PRIVACY_ENHANVED_MODE_CDN (line 166) | const PLAYER_PRIVACY_ENHANVED_MODE_CDN = "https://www.youtube-nocookie.c...
  constant PLAYER_ORIGINAL_CDN (line 167) | const PLAYER_ORIGINAL_CDN = "https://www.youtube.com";
  constant IMAGE_CDN (line 169) | const IMAGE_CDN = "https://img.youtube.com";
  type PlayerStatus (line 365) | type PlayerStatus = "initial" | "loading" | "ready";
  type PlayerProps (line 376) | type PlayerProps = Pick<
  type Props (line 462) | type Props = Omit<
  type Ref (line 474) | type Ref = ElementRef<typeof defaultTag>;
  method onInitPlayer (line 525) | onInitPlayer() {

FILE: packages/sdk/src/__generated__/normalize.css.ts
  type StyleDecl (line 3) | type StyleDecl = {

FILE: packages/sdk/src/assets.ts
  constant ALLOWED_FILE_TYPES (line 15) | const ALLOWED_FILE_TYPES = {
  type AllowedFileExtension (line 73) | type AllowedFileExtension = keyof typeof ALLOWED_FILE_TYPES;
  constant ALLOWED_FILE_EXTENSIONS (line 78) | const ALLOWED_FILE_EXTENSIONS: ReadonlySet<AllowedFileExtension> =
  constant MIME_CATEGORIES (line 86) | const MIME_CATEGORIES = [
  type MimeCategory (line 95) | type MimeCategory = (typeof MIME_CATEGORIES)[number];
  constant FILE_EXTENSIONS_BY_CATEGORY (line 100) | const FILE_EXTENSIONS_BY_CATEGORY: Readonly<
  constant IMAGE_EXTENSIONS (line 144) | const IMAGE_EXTENSIONS: readonly AllowedFileExtension[] =
  constant IMAGE_MIME_TYPES (line 150) | const IMAGE_MIME_TYPES: readonly string[] = IMAGE_EXTENSIONS.map(
  constant RESIZABLE_IMAGE_MIME_TYPES (line 162) | const RESIZABLE_IMAGE_MIME_TYPES: readonly string[] = [
  constant VIDEO_EXTENSIONS (line 173) | const VIDEO_EXTENSIONS: readonly AllowedFileExtension[] =
  constant VIDEO_MIME_TYPES (line 179) | const VIDEO_MIME_TYPES: readonly string[] = VIDEO_EXTENSIONS.map(
  constant FONT_EXTENSIONS (line 186) | const FONT_EXTENSIONS: readonly AllowedFileExtension[] =
  type RuntimeAsset (line 442) | type RuntimeAsset = {
  type RuntimeMetadata (line 455) | type RuntimeMetadata = Omit<RuntimeAsset, "url"> | undefined;

FILE: packages/sdk/src/css.ts
  type CssConfig (line 42) | type CssConfig = {

FILE: packages/sdk/src/expression.ts
  constant SYSTEM_VARIABLE_ID (line 12) | const SYSTEM_VARIABLE_ID = ":system";
  type Diagnostic (line 21) | type Diagnostic = {
  type ExpressionVisitor (line 28) | type ExpressionVisitor = {
  method Identifier (line 92) | Identifier(node) {
  method Literal (line 100) | Literal() {}
  method ArrayExpression (line 101) | ArrayExpression() {}
  method ObjectExpression (line 102) | ObjectExpression() {}
  method UnaryExpression (line 103) | UnaryExpression() {}
  method BinaryExpression (line 104) | BinaryExpression() {}
  method LogicalExpression (line 105) | LogicalExpression() {}
  method MemberExpression (line 106) | MemberExpression() {}
  method ConditionalExpression (line 107) | ConditionalExpression() {}
  method TemplateLiteral (line 108) | TemplateLiteral() {}
  method ChainExpression (line 109) | ChainExpression() {}
  method ParenthesizedExpression (line 110) | ParenthesizedExpression() {}
  method AssignmentExpression (line 111) | AssignmentExpression(node) {
  method YieldExpression (line 128) | YieldExpression() {}
  method CallExpression (line 132) | CallExpression(node) {
  method AssignmentExpression (line 229) | AssignmentExpression(node) {
  method AssignmentExpression (line 278) | AssignmentExpression(node) {
  method MemberExpression (line 283) | MemberExpression(node) {
  method CallExpression (line 298) | CallExpression(node) {

FILE: packages/sdk/src/instances-utils.ts
  constant ROOT_INSTANCE_ID (line 5) | const ROOT_INSTANCE_ID = ":root";
  type IndexesWithinAncestors (line 64) | type IndexesWithinAncestors = Map<Instance["id"], number>;

FILE: packages/sdk/src/page-meta-generator.ts
  type PageMeta (line 7) | type PageMeta = {

FILE: packages/sdk/src/page-utils.ts
  constant ROOT_FOLDER_ID (line 5) | const ROOT_FOLDER_ID = "root";

FILE: packages/sdk/src/resource-loader.ts
  constant LOCAL_RESOURCE_PREFIX (line 5) | const LOCAL_RESOURCE_PREFIX = "$resources";

FILE: packages/sdk/src/router-path-test-data.ts
  constant VALID_ROUTER_PATHS (line 18) | const VALID_ROUTER_PATHS = {
  constant INVALID_ROUTER_PATHS (line 140) | const INVALID_ROUTER_PATHS = {
  constant ALL_VALID_PATHS (line 175) | const ALL_VALID_PATHS = Object.values(VALID_ROUTER_PATHS).flat();
  constant ALL_INVALID_PATHS (line 176) | const ALL_INVALID_PATHS = Object.values(INVALID_ROUTER_PATHS).flat();
  constant VALID_URLPATTERN_PATHS (line 180) | const VALID_URLPATTERN_PATHS = [
  constant STATIC_PATHS (line 204) | const STATIC_PATHS = [
  constant PATTERN_PATHS (line 224) | const PATTERN_PATHS = [

FILE: packages/sdk/src/schema/animation-schema.ts
  constant RANGE_UNITS (line 15) | const RANGE_UNITS = [
  constant TIME_UNITS (line 78) | const TIME_UNITS = ["ms", "s"] as const;
  type RangeUnit (line 239) | type RangeUnit = z.infer<typeof rangeUnitSchema>;
  type RangeUnitValue (line 240) | type RangeUnitValue = z.infer<typeof rangeUnitValueSchema>;
  type DurationUnitValue (line 241) | type DurationUnitValue = z.infer<typeof durationUnitValueSchema>;
  type IterationsUnitValue (line 242) | type IterationsUnitValue = z.infer<typeof iterationsUnitValueSchema>;
  type TimeUnit (line 243) | type TimeUnit = z.infer<typeof timeUnitSchema>;
  type KeyframeStyles (line 244) | type KeyframeStyles = z.infer<typeof keyframeStylesSchema>;
  type AnimationKeyframe (line 245) | type AnimationKeyframe = z.infer<typeof animationKeyframeSchema>;
  type ScrollNamedRange (line 246) | type ScrollNamedRange = z.infer<typeof scrollNamedRangeSchema>;
  type ScrollRangeValue (line 247) | type ScrollRangeValue = z.infer<typeof scrollRangeValueSchema>;
  type ViewNamedRange (line 248) | type ViewNamedRange = z.infer<typeof viewNamedRangeSchema>;
  type ViewRangeValue (line 249) | type ViewRangeValue = z.infer<typeof viewRangeValueSchema>;
  type AnimationActionScroll (line 250) | type AnimationActionScroll = z.infer<typeof scrollActionSchema>;
  type AnimationActionView (line 251) | type AnimationActionView = z.infer<typeof viewActionSchema>;
  type AnimationAction (line 252) | type AnimationAction = z.infer<typeof animationActionSchema>;
  type ScrollAnimation (line 253) | type ScrollAnimation = z.infer<typeof scrollAnimationSchema>;
  type ViewAnimation (line 254) | type ViewAnimation = z.infer<typeof viewAnimationSchema>;
  type InsetUnitValue (line 255) | type InsetUnitValue = z.infer<typeof insetUnitValueSchema>;

FILE: packages/sdk/src/schema/assets.ts
  type FontAsset (line 22) | type FontAsset = z.infer<typeof FontAsset>;
  type ImageMeta (line 28) | type ImageMeta = z.infer<typeof ImageMeta>;
  type ImageAsset (line 36) | type ImageAsset = z.infer<typeof ImageAsset>;
  type FileAsset (line 44) | type FileAsset = z.infer<typeof FileAsset>;
  type Asset (line 47) | type Asset = z.infer<typeof Asset>;
  type Assets (line 50) | type Assets = z.infer<typeof Assets>;

FILE: packages/sdk/src/schema/breakpoints.ts
  type Breakpoint (line 32) | type Breakpoint = z.infer<typeof Breakpoint>;
  type Breakpoints (line 36) | type Breakpoints = z.infer<typeof Breakpoints>;

FILE: packages/sdk/src/schema/component-meta.ts
  type PresetStyleDecl (line 14) | type PresetStyleDecl = Simplify<
  type PresetStyle (line 20) | type PresetStyle<Tag extends HtmlTags = HtmlTags> = Partial<
  type ComponentState (line 44) | type ComponentState = z.infer<typeof ComponentState>;
  type ContentModel (line 71) | type ContentModel = z.infer<typeof ContentModel>;
  type WsComponentMeta (line 92) | type WsComponentMeta = Omit<

FILE: packages/sdk/src/schema/data-sources.ts
  type DataSource (line 57) | type DataSource = z.infer<typeof DataSource>;
  type DataSources (line 61) | type DataSources = z.infer<typeof DataSources>;

FILE: packages/sdk/src/schema/deployment.ts
  type Templates (line 12) | type Templates = z.infer<typeof Templates>;
  type Deployment (line 34) | type Deployment = z.infer<typeof Deployment>;

FILE: packages/sdk/src/schema/instances.ts
  type TextChild (line 9) | type TextChild = z.infer<typeof TextChild>;
  type IdChild (line 17) | type IdChild = z.infer<typeof IdChild>;
  type ExpressionChild (line 23) | type ExpressionChild = z.infer<typeof ExpressionChild>;
  type Instance (line 36) | type Instance = z.infer<typeof Instance>;
  type Instances (line 40) | type Instances = z.infer<typeof Instances>;

FILE: packages/sdk/src/schema/pages.ts
  type System (line 3) | type System = {
  constant MIN_TITLE_LENGTH (line 10) | const MIN_TITLE_LENGTH = 2;
  type Folder (line 33) | type Folder = z.infer<typeof Folder>;
  type ProjectMeta (line 162) | type ProjectMeta = z.infer<typeof ProjectMeta>;
  type PageRedirect (line 183) | type PageRedirect = z.infer<typeof PageRedirect>;
  type CompilerSettings (line 189) | type CompilerSettings = z.infer<typeof CompilerSettings>;
  type Page (line 191) | type Page = z.infer<typeof Page>;
  type Pages (line 204) | type Pages = z.infer<typeof Pages>;

FILE: packages/sdk/src/schema/prop-meta.ts
  type PropMeta (line 217) | type PropMeta = z.infer<typeof PropMeta>;

FILE: packages/sdk/src/schema/props.ts
  type Prop (line 91) | type Prop = z.infer<typeof Prop>;
  type Props (line 95) | type Props = z.infer<typeof Props>;

FILE: packages/sdk/src/schema/resources.ts
  type Resource (line 39) | type Resource = z.infer<typeof Resource>;
  type ResourceRequest (line 63) | type ResourceRequest = z.infer<typeof ResourceRequest>;
  type Resources (line 67) | type Resources = z.infer<typeof Resources>;

FILE: packages/sdk/src/schema/style-source-selections.ts
  type StyleSourceSelection (line 12) | type StyleSourceSelection = z.infer<typeof StyleSourceSelection>;
  type StyleSourceSelections (line 16) | type StyleSourceSelections = z.infer<typeof StyleSourceSelections>;

FILE: packages/sdk/src/schema/style-sources.ts
  type StyleSourceToken (line 11) | type StyleSourceToken = z.infer<typeof StyleSourceToken>;
  type StyleSource (line 20) | type StyleSource = z.infer<typeof StyleSource>;
  type StyleSources (line 24) | type StyleSources = z.infer<typeof StyleSources>;

FILE: packages/sdk/src/schema/styles.ts
  type StyleDecl (line 18) | type StyleDecl = Simplify<
  type StyleDeclKey (line 25) | type StyleDeclKey = string;
  type Styles (line 37) | type Styles = Map<string, StyleDecl>;

FILE: packages/sdk/src/schema/webstudio.ts
  type WebstudioFragment (line 33) | type WebstudioFragment = z.infer<typeof WebstudioFragment>;
  type WebstudioData (line 40) | type WebstudioData = {

FILE: packages/sdk/src/scope.ts
  type Scope (line 6) | type Scope = {

FILE: packages/sdk/src/to-string.ts
  method get (line 3) | get(target, prop, receiver) {

FILE: packages/template/src/css.ts
  type TemplateStyleDecl (line 4) | type TemplateStyleDecl = {

FILE: packages/template/src/jsx.ts
  class Token (line 19) | class Token {
    method constructor (line 22) | constructor(name: string, styles: TemplateStyleDecl[]) {
  class Variable (line 32) | class Variable {
    method constructor (line 35) | constructor(name: string, initialValue: unknown) {
  class Parameter (line 41) | class Parameter {
    method constructor (line 43) | constructor(name: string) {
  type ResourceConfig (line 48) | type ResourceConfig = {
  class ResourceValue (line 56) | class ResourceValue {
    method constructor (line 59) | constructor(name: string, config: ResourceConfig) {
  class Expression (line 65) | class Expression {
    method constructor (line 68) | constructor(
  class ActionValue (line 84) | class ActionValue {
    method constructor (line 87) | constructor(args: string[], code: string | Expression) {
  class AssetValue (line 97) | class AssetValue {
    method constructor (line 99) | constructor(assetId: string) {
  class PageValue (line 104) | class PageValue {
    method constructor (line 106) | constructor(pageId: string, instanceId?: string) {
  class PlaceholderValue (line 115) | class PlaceholderValue {
    method constructor (line 117) | constructor(text: string) {
  type ComponentProps (line 530) | type ComponentProps = Record<string, unknown> &
  type Component (line 540) | type Component = { displayName: string } & ((
  method get (line 548) | get(_target, prop) {

FILE: packages/template/src/template.ts
  type TemplateMeta (line 19) | type TemplateMeta = {
  type GeneratedTemplateMeta (line 28) | type GeneratedTemplateMeta = Omit<TemplateMeta, "template"> & {

FILE: packages/trpc-interface/src/authorize/project.server.ts
  type Relation (line 5) | type Relation =
  type AuthPermit (line 8) | type AuthPermit = "view" | "edit" | "build" | "admin" | "own";
  type TokenAuthPermit (line 10) | type TokenAuthPermit = Exclude<AuthPermit, "own">;
  type CheckInput (line 12) | type CheckInput = {
  type AuthInfo (line 81) | type AuthInfo =

FILE: packages/trpc-interface/src/context/context.server.ts
  type AuthorizationContext (line 7) | type AuthorizationContext =
  type DomainContext (line 43) | type DomainContext = {
  type EntriContext (line 48) | type EntriContext = {
  type DeploymentContext (line 57) | type DeploymentContext = {
  type UserPlanFeatures (line 67) | type UserPlanFeatures = {
  type TrpcCache (line 82) | type TrpcCache = {
  type PostgrestContext (line 87) | type PostgrestContext = {
  type AppContext (line 96) | type AppContext = {

FILE: packages/trpc-interface/src/shared/client.ts
  type SharedClientOptions (line 9) | type SharedClientOptions = {

FILE: packages/trpc-interface/src/shared/shared-router.ts
  type SharedRouter (line 11) | type SharedRouter = typeof sharedRouter;
  type TrpcInterfaceClient (line 13) | type TrpcInterfaceClient = ReturnType<

FILE: packages/trpc-interface/src/shared/trpc.ts
  type Context (line 9) | type Context = inferAsyncReturnType<typeof createContext>;

FILE: packages/trpc-interface/src/trpc-caller-link.test.ts
  type Context (line 7) | type Context = {

FILE: packages/trpc-interface/src/trpc-caller-link.ts
  type MemoryLinkOptions (line 5) | type MemoryLinkOptions<TemplateRouter extends AnyRouter> = {
Copy disabled (too large) Download .json
Condensed preview — 2152 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (11,279K chars).
[
  {
    "path": ".devcontainer/.gitignore",
    "chars": 6,
    "preview": ".local"
  },
  {
    "path": ".devcontainer/Dockerfile",
    "chars": 857,
    "preview": "FROM mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm\n\nENV PATH=/usr/local/bin:${PATH}\n# Install latest pnp"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "chars": 1536,
    "preview": "// For format details, see https://aka.ms/devcontainer.json. For config options, see the\n// README at: https://github.co"
  },
  {
    "path": ".devcontainer/docker-compose.yml",
    "chars": 2263,
    "preview": "version: \"3.8\"\n\nservices:\n  app:\n    init: true\n    privileged: true\n    build:\n      context: .\n      dockerfile: Docke"
  },
  {
    "path": ".devcontainer/library-scripts/docker-in-docker-debian.sh",
    "chars": 27187,
    "preview": "#!/usr/bin/env bash\n#---------------------------------------------------------------------------------------------------"
  },
  {
    "path": ".devcontainer/postinstall.sh",
    "chars": 1721,
    "preview": "#!/bin/bash\n\necho \"Running postinstall.sh\"\n\n# Aggressively clean npm and corepack caches\nnpm cache clean -f\nsudo rm -rf "
  },
  {
    "path": ".editorconfig",
    "chars": 34,
    "preview": "root = true\n\n[*]\nend_of_line = lf\n"
  },
  {
    "path": ".github/actions/add-status/action.yaml",
    "chars": 947,
    "preview": "name: Add status to commit\ndescription: Add status to commit\ninputs:\n  url:\n    description: \"URL\"\n    required: true\n  "
  },
  {
    "path": ".github/actions/ci-setup/action.yml",
    "chars": 316,
    "preview": "name: CI setup\n\ndescription: |\n  Sets up the CI environment for the project.\n\nruns:\n  using: \"composite\"\n\n  steps:\n    -"
  },
  {
    "path": ".github/actions/submodules-checkout/action.yml",
    "chars": 1318,
    "preview": "name: CI setup\n\ndescription: |\n  Sets up the CI environment for the project.\n\ninputs:\n  submodules-ssh-key:\n    descript"
  },
  {
    "path": ".github/actions/vercel/action.yaml",
    "chars": 4343,
    "preview": "name: \"VERCEL BUILD AND DEPLOY\"\ndescription: \"Builds and deploy vercel project\"\n\ninputs:\n  vercel-token:\n    description"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 467,
    "preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 754,
    "preview": "## Description\n\n1. What is this PR about (link the issue and add a short description)\n\n## Steps for reproduction\n\n1. cli"
  },
  {
    "path": ".github/workflows/build-figma-tokens.yml",
    "chars": 1061,
    "preview": "name: Build and commit Figma tokens\n\non:\n  push:\n    branches:\n      - figma-tokens\n    paths:\n      - packages/design-s"
  },
  {
    "path": ".github/workflows/check-submodules.yml",
    "chars": 2075,
    "preview": "name: Check submodules\n\non:\n  pull_request:\n\n# cancel in-progress runs on new commits to same PR (gitub.event.number)\nco"
  },
  {
    "path": ".github/workflows/chromatic.yml",
    "chars": 1427,
    "preview": "name: Chromatic\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  pull_request_target:\n    types: [labeled]\n\n# c"
  },
  {
    "path": ".github/workflows/cli-r2-static.yaml",
    "chars": 3581,
    "preview": "name: CLI R2 SSG\n\non:\n  push:\n    branches:\n      - \"*.staging\"\n\n# cancel in-progress runs on new commits to same PR (gi"
  },
  {
    "path": ".github/workflows/cli-r2.yaml",
    "chars": 4320,
    "preview": "name: CLI R2\n\non:\n  push:\n    branches:\n      - \"*.staging\"\n\n# cancel in-progress runs on new commits to same PR (gitub."
  },
  {
    "path": ".github/workflows/delete-github-deployments.yml",
    "chars": 1405,
    "preview": "# https://github.com/orgs/community/discussions/36919\nname: Delete github deployments\n\non:\n  workflow_call:\n    inputs:\n"
  },
  {
    "path": ".github/workflows/fixtures-test.yml",
    "chars": 2222,
    "preview": "name: Fixtures tests\n\non:\n  workflow_call:\n    inputs:\n      builder-url:\n        required: true\n        type: string\n  "
  },
  {
    "path": ".github/workflows/lint-pull-request.yaml",
    "chars": 2882,
    "preview": "name: \"Lint PR\"\n\non:\n  pull_request:\n    types:\n      - opened\n      - edited\n      - synchronize\n\n  pull_request_target"
  },
  {
    "path": ".github/workflows/main.yml",
    "chars": 4429,
    "preview": "name: Main workflow\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  pull_request_target:\n    types: [labeled]\n"
  },
  {
    "path": ".github/workflows/migrate.yaml",
    "chars": 3859,
    "preview": "name: Migrate\n\non:\n  push:\n    branches:\n      - \"migrate\"\n      - \"main\"\n      - \"*.staging\"\n      - \"*.migrate\"\n\n# Pen"
  },
  {
    "path": ".github/workflows/publish-beta.yml",
    "chars": 1813,
    "preview": "name: Publish beta packages on NPM 📦\n\non:\n  pull_request:\n    types:\n      - labeled\n\njobs:\n  publish:\n    # prevents th"
  },
  {
    "path": ".github/workflows/re-create-figma-tokens-branch.yml",
    "chars": 451,
    "preview": "name: Re-create branch for Figma tokens\n\non: delete\n\npermissions:\n  contents: write\n\njobs:\n  main:\n    runs-on: ubuntu-l"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 3439,
    "preview": "name: Release\n\non:\n  push:\n    tags:\n      - '[0-9]+.[0-9]+.[0-9]+'\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    per"
  },
  {
    "path": ".github/workflows/vercel-deploy-staging.yml",
    "chars": 5593,
    "preview": "name: Vercel Deploy Staging\n\non:\n  push:\n  pull_request_target:\n    types: [labeled, synchronize]\n\n# cancel in-progress "
  },
  {
    "path": ".github/workflows/vis-reg-tests.yml",
    "chars": 1227,
    "preview": "name: Visual Regression Tests\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  pull_request_target:\n    types: "
  },
  {
    "path": ".gitignore",
    "chars": 972,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n.pnp\n"
  },
  {
    "path": ".gitmodules",
    "chars": 193,
    "preview": "[submodule \"packages/sdk-components-animation/private-src\"]\n\tpath = packages/sdk-components-animation/private-src\n\turl ="
  },
  {
    "path": ".nvmrc",
    "chars": 3,
    "preview": "22\n"
  },
  {
    "path": ".oxlintrc.json",
    "chars": 1092,
    "preview": "{\n  \"$schema\": \"https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json\",\n  \"plugins"
  },
  {
    "path": ".prettierignore",
    "chars": 97,
    "preview": "pnpm-lock.yaml\npackages/prisma-client/prisma/migrations/*/client\npackages/prisma-client/**/*.d.ts"
  },
  {
    "path": ".storybook/main.ts",
    "chars": 2885,
    "preview": "import * as path from \"node:path\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport { defaultClientConditions }"
  },
  {
    "path": ".storybook/preview-body.html",
    "chars": 112,
    "preview": "<script>\n  // for styling radix components\n  document.body.setAttribute(\"data-ws-component\", \"Body\");\n</script>\n"
  },
  {
    "path": ".storybook/preview.tsx",
    "chars": 2297,
    "preview": "import type { Preview } from \"@storybook/react\";\nimport * as React from \"react\";\nimport { useEffect } from \"react\";\nimpo"
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 64,
    "preview": "{\n  \"recommendations\": [\"ms-vscode-remote.remote-containers\"]\n}\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 418,
    "preview": "{\n  \"typescript.experimental.useTsgo\": true,\n  // Disable formatting for SQL files\n  \"[sql]\": {\n    \"editor.formatOnSave"
  },
  {
    "path": "@types/canvas-iframe.d.ts",
    "chars": 96,
    "preview": "declare namespace React {\n  interface IframeHTMLAttributes {\n    credentialless?: \"true\";\n  }\n}\n"
  },
  {
    "path": "@types/content.d.ts",
    "chars": 365,
    "preview": "// CSS Containment\n// Specification: https://drafts.csswg.org/css-contain-2/\n// Repository: https://github.com/w3c/csswg"
  },
  {
    "path": "@types/css-tree.d.ts",
    "chars": 20411,
    "preview": "// Minimal-yet-safe TypeScript typings for css-tree v3.x\n// Covers: AST node types, parse/generate, walk/find, List, lex"
  },
  {
    "path": "@types/navigator.d.ts",
    "chars": 232,
    "preview": "interface Navigator {\n  userAgentData?: {\n    brands: Array<{ brand: string; version: string }>;\n    getHighEntropyValue"
  },
  {
    "path": "@types/scroll-timeline.d.ts",
    "chars": 468,
    "preview": "type ScrollAxis = \"block\" | \"inline\" | \"x\" | \"y\";\n\ninterface ScrollTimelineOptions {\n  source?: Element | Document | nul"
  },
  {
    "path": "@types/warn-once.d.ts",
    "chars": 110,
    "preview": "declare module \"warn-once\" {\n  export default function warnOnce(condition: boolean, message: string): void;\n}\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5218,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "LICENSE",
    "chars": 34522,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 1899,
    "preview": "<img width=\"1512\" alt=\"builder-screenshot\" src=\"https://github.com/webstudio-is/.github/blob/main/assets/builder-screens"
  },
  {
    "path": "apps/builder/.gitignore",
    "chars": 128,
    "preview": ".cache\n.vercel\n.output\n\n/build/\n/public/build\n/api/index.js\n/api/index.js.map\n/api/_assets\n/public/s/uploads\n/public/cgi"
  },
  {
    "path": "apps/builder/app/auth/index.client.ts",
    "chars": 25,
    "preview": "export * from \"./login\";\n"
  },
  {
    "path": "apps/builder/app/auth/login.stories.tsx",
    "chars": 759,
    "preview": "import type { JSX } from \"react\";\nimport type { StoryFn } from \"@storybook/react\";\nimport { createBrowserRouter, RouterP"
  },
  {
    "path": "apps/builder/app/auth/login.tsx",
    "chars": 2752,
    "preview": "import { TooltipProvider } from \"@radix-ui/react-tooltip\";\nimport {\n  Button,\n  Flex,\n  globalCss,\n  rawTheme,\n  Text,\n "
  },
  {
    "path": "apps/builder/app/auth/secret-login.tsx",
    "chars": 911,
    "preview": "import { Button, Flex, InputField, theme } from \"@webstudio-is/design-system\";\nimport { useState } from \"react\";\nimport "
  },
  {
    "path": "apps/builder/app/builder/builder.css",
    "chars": 644,
    "preview": "html {\n  overflow: hidden;\n}\n\nbody {\n  overflow: hidden;\n  overscroll-behavior: contain;\n  -webkit-font-smoothing: antia"
  },
  {
    "path": "apps/builder/app/builder/builder.tsx",
    "chars": 14342,
    "preview": "import { useEffect, useMemo, useState, type JSX, type ReactNode } from \"react\";\nimport { useStore } from \"@nanostores/re"
  },
  {
    "path": "apps/builder/app/builder/features/address-bar.stories.tsx",
    "chars": 2042,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport type { Meta, StoryFn } from \"@storybook/react\";\nimport { StorySecti"
  },
  {
    "path": "apps/builder/app/builder/features/address-bar.tsx",
    "chars": 11062,
    "preview": "import { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\nimport { mergeRefs } from \"@react-a"
  },
  {
    "path": "apps/builder/app/builder/features/assets/assets.tsx",
    "chars": 881,
    "preview": "import {\n  IconButton,\n  PanelTitle,\n  Separator,\n  Tooltip,\n} from \"@webstudio-is/design-system\";\nimport { BrushCleanin"
  },
  {
    "path": "apps/builder/app/builder/features/assets/index.ts",
    "chars": 26,
    "preview": "export * from \"./assets\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/blocking-alerts/alert.stories.tsx",
    "chars": 424,
    "preview": "import { StorySection } from \"@webstudio-is/design-system\";\nimport { Alert } from \"./alert\";\n\nexport default { title: \"B"
  },
  {
    "path": "apps/builder/app/builder/features/blocking-alerts/alert.tsx",
    "chars": 1575,
    "preview": "import { atom } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\nimport type { ReactNode } from \"react\";"
  },
  {
    "path": "apps/builder/app/builder/features/blocking-alerts/blocking-alerts.tsx",
    "chars": 3281,
    "preview": "import { useEffect, useState, type ReactNode } from \"react\";\nimport { Alert } from \"./alert\";\nimport { useWindowResizeDe"
  },
  {
    "path": "apps/builder/app/builder/features/blocking-alerts/index.tsx",
    "chars": 52,
    "preview": "export { BlockingAlerts } from \"./blocking-alerts\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoint-editor-utils.test.ts",
    "chars": 5862,
    "preview": "import { describe, test, expect } from \"vitest\";\nimport {\n  isConditionBasedBreakpoint,\n  isWidthBasedBreakpoint,\n  isVa"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoint-editor-utils.ts",
    "chars": 2820,
    "preview": "import type { Breakpoint } from \"@webstudio-is/sdk\";\n\n/**\n * Determines if a breakpoint is condition-based (has a custom"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoints-container.tsx",
    "chars": 3332,
    "preview": "import { useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { Flex } from \"@webstudio-is/desi"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoints-editor.tsx",
    "chars": 8249,
    "preview": "import { Fragment, useState, useMemo } from \"react\";\nimport { nanoid } from \"nanoid\";\nimport type { Breakpoint } from \"@"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoints-menu.tsx",
    "chars": 3869,
    "preview": "import { useState } from \"react\";\nimport type { Breakpoint, Breakpoints } from \"@webstudio-is/sdk\";\nimport {\n  Flex,\n  T"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoints-selector.stories.tsx",
    "chars": 894,
    "preview": "import { StorySection } from \"@webstudio-is/design-system\";\nimport { BreakpointsSelector as BreakpointsSelectorComponent"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/breakpoints-selector.tsx",
    "chars": 6938,
    "preview": "import { useCallback, useRef } from \"react\";\nimport type { Breakpoint } from \"@webstudio-is/sdk\";\nimport {\n  Flex,\n  Tex"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/canvas-settings-popover.tsx",
    "chars": 2013,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport {\n  theme,\n  Flex,\n  Label,\n  Popover,\n  PopoverContent,\n  PopoverT"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/cascade-indicator.tsx",
    "chars": 4501,
    "preview": "import { useEffect, useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { css, theme } from \"@"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/condition-input.tsx",
    "chars": 4839,
    "preview": "import { useMemo } from \"react\";\nimport { Combobox } from \"@webstudio-is/design-system\";\n\nconst PREDEFINED_CONDITIONS = "
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/confirmation-dialog.tsx",
    "chars": 1200,
    "preview": "import type { Breakpoint } from \"@webstudio-is/sdk\";\nimport {\n  theme,\n  Button,\n  Flex,\n  Text,\n  Dialog,\n  DialogConte"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/index.ts",
    "chars": 41,
    "preview": "export * from \"./breakpoints-container\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/breakpoints/width-input.tsx",
    "chars": 3801,
    "preview": "import { useState, type KeyboardEvent, useEffect, useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nim"
  },
  {
    "path": "apps/builder/app/builder/features/builder-mode.stories.tsx",
    "chars": 793,
    "preview": "import { StorySection, Toolbar } from \"@webstudio-is/design-system\";\nimport { BuilderModeDropDown } from \"./builder-mode"
  },
  {
    "path": "apps/builder/app/builder/features/builder-mode.tsx",
    "chars": 4208,
    "preview": "import { useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport {\n  ChevronDownIcon,\n  NotebookAn"
  },
  {
    "path": "apps/builder/app/builder/features/clone.tsx",
    "chars": 791,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { buttonStyle, Link } from \"@webstudio-is/design-system\";\nimport { "
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/command-panel.stories.tsx",
    "chars": 1661,
    "preview": "import type { Meta, StoryFn } from \"@storybook/react\";\nimport { useEffect } from \"react\";\nimport { initialBreakpoints, c"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/command-panel.tsx",
    "chars": 2302,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { matchSorter } from \"match-sorter\";\nimport {\n  Command,\n  CommandD"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/command-state.ts",
    "chars": 1402,
    "preview": "import { atom, computed } from \"nanostores\";\nimport type { ReactNode } from \"react\";\n\nconst $commandPanel = atom<\n  | un"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/breakpoints-group.tsx",
    "chars": 3242,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  Text,\n  Kbd,\n} from \"@webstudio-is/design-system\";\nimpo"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/commands-group.tsx",
    "chars": 2201,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  Text,\n  Kbd,\n} from \"@webstudio-is/design-system\";\nimpo"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/components-group.tsx",
    "chars": 4904,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  CommandIcon,\n  Flex,\n  Text,\n} from \"@webstudio-is/desi"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/convert-group.tsx",
    "chars": 5004,
    "preview": "import {\n  CommandGroup,\n  CommandIcon,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandBackButton,\n  CommandFoot"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/css-variables-group.tsx",
    "chars": 5891,
    "preview": "import { useState } from \"react\";\nimport { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\ni"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/data-variables-group.tsx",
    "chars": 5625,
    "preview": "import { useState } from \"react\";\nimport { computed } from \"nanostores\";\nimport {\n  CommandGroup,\n  CommandGroupHeading,"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/duplicate-tokens-group.tsx",
    "chars": 10493,
    "preview": "import { useState } from \"react\";\nimport { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\ni"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/index.ts",
    "chars": 2821,
    "preview": "import { computed } from \"nanostores\";\nimport {\n  $componentOptions,\n  ComponentsGroup,\n  type ComponentOption,\n} from \""
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/instances-group.tsx",
    "chars": 3275,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  Text,\n  useCommandState,\n  useSetFooterContent,\n} from "
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/pages-group.tsx",
    "chars": 2270,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  Text,\n  useSelectedAction,\n} from \"@webstudio-is/design"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/tags-group.tsx",
    "chars": 3664,
    "preview": "import {\n  CommandGroup,\n  CommandGroupHeading,\n  CommandItem,\n  CommandIcon,\n  Flex,\n  Text,\n} from \"@webstudio-is/desi"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/tokens-group.tsx",
    "chars": 5038,
    "preview": "import { useState } from \"react\";\nimport { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\ni"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/wrap-group.test.tsx",
    "chars": 9646,
    "preview": "import { describe, expect, test, beforeEach } from \"vitest\";\nimport { coreMetas, elementComponent } from \"@webstudio-is/"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/groups/wrap-group.tsx",
    "chars": 8329,
    "preview": "import {\n  CommandGroup,\n  CommandIcon,\n  CommandInput,\n  CommandItem,\n  CommandList,\n  CommandBackButton,\n  CommandFoot"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/index.ts",
    "chars": 101,
    "preview": "export { openCommandPanel, $commandSearch } from \"./command-state\";\nexport * from \"./command-panel\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/auto-select.ts",
    "chars": 1312,
    "preview": "import { useEffect, useRef } from \"react\";\n\n/**\n * Auto-selects the first item in a command list when search changes.\n *"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/component-utils.ts",
    "chars": 1194,
    "preview": "import { componentCategories } from \"@webstudio-is/sdk\";\n\n/**\n * Normalizes a component's category, defaulting undefined"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/instance-list.tsx",
    "chars": 4780,
    "preview": "import { useState } from \"react\";\nimport { matchSorter } from \"match-sorter\";\nimport {\n  CommandGroup,\n  CommandFooter,\n"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/instance-path-footer.tsx",
    "chars": 911,
    "preview": "import { useMemo } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { Flex, Text } from \"@webstudio-is"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/types.ts",
    "chars": 65,
    "preview": "export type BaseOption = {\n  terms: string[];\n  type: string;\n};\n"
  },
  {
    "path": "apps/builder/app/builder/features/command-panel/shared/usage-utils.ts",
    "chars": 391,
    "preview": "/**\n * Formats usage count for display\n */\nexport const formatUsageCount = (usages: number): string => {\n  if (usages =="
  },
  {
    "path": "apps/builder/app/builder/features/components/components.tsx",
    "chars": 9240,
    "preview": "import { useState } from \"react\";\nimport { matchSorter } from \"match-sorter\";\nimport { computed } from \"nanostores\";\nimp"
  },
  {
    "path": "apps/builder/app/builder/features/components/index.ts",
    "chars": 30,
    "preview": "export * from \"./components\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/components/use-draggable.tsx",
    "chars": 3888,
    "preview": "import { useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { createPortal } from \"react-dom\""
  },
  {
    "path": "apps/builder/app/builder/features/footer/breadcrumbs.tsx",
    "chars": 1521,
    "preview": "import { Fragment } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { ChevronRightIcon } from \"@webst"
  },
  {
    "path": "apps/builder/app/builder/features/footer/footer.tsx",
    "chars": 461,
    "preview": "import { Flex, theme } from \"@webstudio-is/design-system\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\n\nexport const Fo"
  },
  {
    "path": "apps/builder/app/builder/features/footer/index.ts",
    "chars": 57,
    "preview": "export * from \"./breadcrumbs\";\nexport * from \"./footer\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/help/help-center.stories.tsx",
    "chars": 659,
    "preview": "import { Button, Flex, StorySection } from \"@webstudio-is/design-system\";\nimport { HelpIcon } from \"@webstudio-is/icons\""
  },
  {
    "path": "apps/builder/app/builder/features/help/help-center.tsx",
    "chars": 1606,
    "preview": "import {\n  Button,\n  Flex,\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n  rawTheme,\n  theme,\n} from \"@webstudio-is/des"
  },
  {
    "path": "apps/builder/app/builder/features/help/remote-dialog.stories.tsx",
    "chars": 503,
    "preview": "import { StorySection } from \"@webstudio-is/design-system\";\nimport { $remoteDialog } from \"../../shared/nano-states\";\nim"
  },
  {
    "path": "apps/builder/app/builder/features/help/remote-dialog.tsx",
    "chars": 1427,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { $remoteDialog } from \"../../shared/nano-states\";\nimport {\n  Dialo"
  },
  {
    "path": "apps/builder/app/builder/features/keyboard-shortcuts-dialog/index.ts",
    "chars": 105,
    "preview": "export {\n  KeyboardShortcutsDialog,\n  openKeyboardShortcutsDialog,\n} from \"./keyboard-shortcuts-dialog\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/keyboard-shortcuts-dialog/keyboard-shortcuts-dialog.stories.tsx",
    "chars": 680,
    "preview": "import type { Meta } from \"@storybook/react\";\nimport { useEffect } from \"react\";\nimport { StorySection } from \"@webstudi"
  },
  {
    "path": "apps/builder/app/builder/features/keyboard-shortcuts-dialog/keyboard-shortcuts-dialog.tsx",
    "chars": 7296,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport {\n  Dialog,\n  DialogTitle,\n  DialogContent,\n  Grid,\n  Text,\n  Kbd,\n"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/about.stories.tsx",
    "chars": 1072,
    "preview": "import {\n  Dialog,\n  DialogContent,\n  Flex,\n  StorySection,\n} from \"@webstudio-is/design-system\";\nimport { About as Abou"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/about.tsx",
    "chars": 2693,
    "preview": "import {\n  DialogClose,\n  Flex,\n  Link,\n  PanelTitle,\n  Separator,\n  Text,\n  Tooltip,\n  buttonStyle,\n  theme,\n  truncate"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/card.stories.tsx",
    "chars": 1503,
    "preview": "import {\n  Flex,\n  IconButton,\n  StorySection,\n  Text,\n} from \"@webstudio-is/design-system\";\nimport { EllipsesIcon } fro"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/card.tsx",
    "chars": 3096,
    "preview": "import { forwardRef } from \"react\";\nimport {\n  Flex,\n  Text,\n  theme,\n  focusRingStyle,\n  css,\n  rawTheme,\n} from \"@webs"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/index.ts",
    "chars": 31,
    "preview": "export * from \"./marketplace\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/marketplace.tsx",
    "chars": 2861,
    "preview": "import { SpinnerIcon } from \"@webstudio-is/icons\";\nimport {\n  Flex,\n  PanelTitle,\n  rawTheme,\n  Separator,\n  FloatingPan"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/overview.tsx",
    "chars": 4038,
    "preview": "import { useMemo, useState } from \"react\";\nimport {\n  Flex,\n  IconButton,\n  List,\n  ListItem,\n  PanelTabs,\n  PanelTabsCo"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/templates.tsx",
    "chars": 7863,
    "preview": "import { useMemo } from \"react\";\nimport {\n  Button,\n  Flex,\n  List,\n  ListItem,\n  ScrollArea,\n  Separator,\n  theme,\n  Li"
  },
  {
    "path": "apps/builder/app/builder/features/marketplace/utils.ts",
    "chars": 915,
    "preview": "import {\n  getStyleDeclKey,\n  type Asset,\n  type WebstudioData,\n} from \"@webstudio-is/sdk\";\nimport type { CompactBuild }"
  },
  {
    "path": "apps/builder/app/builder/features/menu/index.ts",
    "chars": 24,
    "preview": "export * from \"./menu\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/menu/menu-button.tsx",
    "chars": 1566,
    "preview": "import {\n  css,\n  DropdownMenuTrigger,\n  rawTheme,\n  ToolbarButton,\n} from \"@webstudio-is/design-system\";\nimport { MenuI"
  },
  {
    "path": "apps/builder/app/builder/features/menu/menu.stories.tsx",
    "chars": 2013,
    "preview": "import { Flex, StorySection, Text, Toolbar } from \"@webstudio-is/design-system\";\nimport { Menu } from \"./menu\";\nimport {"
  },
  {
    "path": "apps/builder/app/builder/features/menu/menu.tsx",
    "chars": 9438,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport {\n  theme,\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuIte"
  },
  {
    "path": "apps/builder/app/builder/features/navigator/css-preview.tsx",
    "chars": 3014,
    "preview": "import { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\nimport {\n  ScrollArea,\n  css,\n  tex"
  },
  {
    "path": "apps/builder/app/builder/features/navigator/index.ts",
    "chars": 63,
    "preview": "export * from \"./navigator\";\nexport * from \"./navigator-tree\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/navigator/navigator-tree.tsx",
    "chars": 24497,
    "preview": "import { useEffect, useRef } from \"react\";\nimport { atom, computed } from \"nanostores\";\nimport { mergeRefs } from \"@reac"
  },
  {
    "path": "apps/builder/app/builder/features/navigator/navigator.tsx",
    "chars": 773,
    "preview": "import { Flex, PanelTitle, Separator } from \"@webstudio-is/design-system\";\nimport { CssPreview } from \"./css-preview\";\ni"
  },
  {
    "path": "apps/builder/app/builder/features/pages/confirmation-dialogs.stories.tsx",
    "chars": 949,
    "preview": "import { StorySection } from \"@webstudio-is/design-system\";\nimport {\n  DeletePageConfirmationDialog,\n  DeleteFolderConfi"
  },
  {
    "path": "apps/builder/app/builder/features/pages/confirmation-dialogs.tsx",
    "chars": 2546,
    "preview": "import {\n  Dialog,\n  DialogContent,\n  DialogTitle,\n  DialogClose,\n  Flex,\n  Text,\n  Button,\n  theme,\n} from \"@webstudio-"
  },
  {
    "path": "apps/builder/app/builder/features/pages/custom-metadata.stories.tsx",
    "chars": 692,
    "preview": "import { Box, StorySection } from \"@webstudio-is/design-system\";\nimport { CustomMetadata as CustomMetadataComponent } fr"
  },
  {
    "path": "apps/builder/app/builder/features/pages/custom-metadata.tsx",
    "chars": 5877,
    "preview": "import { useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport {\n  Button,\n  Grid,\n  InputErrorsToo"
  },
  {
    "path": "apps/builder/app/builder/features/pages/folder-settings.tsx",
    "chars": 11560,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport {\n  Button,\n  DialogClose,\n  DialogTitle,\n  Flex,\n  Grid,\n  InputEr"
  },
  {
    "path": "apps/builder/app/builder/features/pages/form.stories.tsx",
    "chars": 705,
    "preview": "import {\n  Button,\n  Flex,\n  InputField,\n  StorySection,\n  Text,\n} from \"@webstudio-is/design-system\";\nimport { Form as "
  },
  {
    "path": "apps/builder/app/builder/features/pages/form.tsx",
    "chars": 526,
    "preview": "import { forwardRef, type ReactNode } from \"react\";\n\nexport const Form = forwardRef<\n  HTMLFormElement,\n  { onSubmit: ()"
  },
  {
    "path": "apps/builder/app/builder/features/pages/image-info.stories.tsx",
    "chars": 1271,
    "preview": "import { Flex, StorySection, Text } from \"@webstudio-is/design-system\";\nimport { ImageInfo as ImageInfoComponent } from "
  },
  {
    "path": "apps/builder/app/builder/features/pages/image-info.tsx",
    "chars": 2062,
    "preview": "import {\n  IconButton,\n  Text,\n  Grid,\n  theme,\n  Flex,\n} from \"@webstudio-is/design-system\";\nimport {\n  AspectRatioIcon"
  },
  {
    "path": "apps/builder/app/builder/features/pages/index.ts",
    "chars": 25,
    "preview": "export * from \"./pages\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/pages/page-context-menu.tsx",
    "chars": 2346,
    "preview": "import { useState, type ReactNode } from \"react\";\nimport {\n  ContextMenu,\n  ContextMenuContent,\n  ContextMenuItem,\n  Con"
  },
  {
    "path": "apps/builder/app/builder/features/pages/page-settings.stories.tsx",
    "chars": 2754,
    "preview": "import { $pages } from \"~/shared/nano-states/pages\";\nimport { PageSettings as PageSettingsComponent } from \"./page-setti"
  },
  {
    "path": "apps/builder/app/builder/features/pages/page-settings.tsx",
    "chars": 49731,
    "preview": "import { nanoid } from \"nanoid\";\nimport { z } from \"zod\";\nimport {\n  type FocusEventHandler,\n  useState,\n  useCallback,\n"
  },
  {
    "path": "apps/builder/app/builder/features/pages/page-utils.test.ts",
    "chars": 27482,
    "preview": "import { describe, expect, test } from \"vitest\";\nimport { setEnv } from \"@webstudio-is/feature-flags\";\nimport { createDe"
  },
  {
    "path": "apps/builder/app/builder/features/pages/page-utils.ts",
    "chars": 14302,
    "preview": "import { computed } from \"nanostores\";\nimport { nanoid } from \"nanoid\";\nimport { createRootFolder } from \"@webstudio-is/"
  },
  {
    "path": "apps/builder/app/builder/features/pages/pages.tsx",
    "chars": 19938,
    "preview": "import { useEffect, useRef, useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport {\n  Tooltip,\n "
  },
  {
    "path": "apps/builder/app/builder/features/pages/search-preview.stories.tsx",
    "chars": 1241,
    "preview": "import { Box, StorySection } from \"@webstudio-is/design-system\";\nimport { SearchPreview as SearchPreviewComponent } from"
  },
  {
    "path": "apps/builder/app/builder/features/pages/search-preview.tsx",
    "chars": 3953,
    "preview": "import { Box, Flex, Grid } from \"@webstudio-is/design-system\";\nimport { Image, wsImageLoader } from \"@webstudio-is/image"
  },
  {
    "path": "apps/builder/app/builder/features/pages/social-preview.stories.tsx",
    "chars": 1736,
    "preview": "import { Flex, StorySection } from \"@webstudio-is/design-system\";\nimport { SocialPreview as SocialPreviewComponent } fro"
  },
  {
    "path": "apps/builder/app/builder/features/pages/social-preview.tsx",
    "chars": 2507,
    "preview": "import { Box, Grid, Label, css, theme } from \"@webstudio-is/design-system\";\nimport { Image, wsImageLoader } from \"@webst"
  },
  {
    "path": "apps/builder/app/builder/features/pages/social-utils.test.ts",
    "chars": 2771,
    "preview": "/* eslint-disable no-irregular-whitespace */\nimport { expect, test } from \"vitest\";\nimport { truncateByWords, truncate }"
  },
  {
    "path": "apps/builder/app/builder/features/pages/social-utils.ts",
    "chars": 1046,
    "preview": "/**\n * Exact google truncation logic is not known, but this is a close approximation\n */\nexport const truncateByWords = "
  },
  {
    "path": "apps/builder/app/builder/features/publish/add-domain.tsx",
    "chars": 4083,
    "preview": "import {\n  Button,\n  Flex,\n  InputField,\n  Label,\n  Separator,\n  theme,\n  Text,\n  Grid,\n  toast,\n} from \"@webstudio-is/d"
  },
  {
    "path": "apps/builder/app/builder/features/publish/cname.test.ts",
    "chars": 1130,
    "preview": "import { describe, test, expect } from \"vitest\";\n\nimport { extractCname } from \"./cname\";\n\ndescribe(\"extractCname from o"
  },
  {
    "path": "apps/builder/app/builder/features/publish/cname.ts",
    "chars": 77037,
    "preview": "export const extractCname = (domain: string): string => {\n  // Split the domain into parts\n  const parts: string[] = dom"
  },
  {
    "path": "apps/builder/app/builder/features/publish/collapsible-domain-section.stories.tsx",
    "chars": 19830,
    "preview": "import {\n  Flex,\n  Grid,\n  Text,\n  Button,\n  InputField,\n  Label,\n  Separator,\n  SmallIconButton,\n  IconButton,\n  Toolti"
  },
  {
    "path": "apps/builder/app/builder/features/publish/collapsible-domain-section.tsx",
    "chars": 1680,
    "preview": "import {\n  Box,\n  Flex,\n  Label,\n  theme,\n  SectionTitle,\n  Grid,\n} from \"@webstudio-is/design-system\";\nimport { useEffe"
  },
  {
    "path": "apps/builder/app/builder/features/publish/domain-checkbox.tsx",
    "chars": 2350,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport {\n  Flex,\n  Tooltip,\n  Text,\n  theme,\n  Link,\n  buttonStyle,\n  Chec"
  },
  {
    "path": "apps/builder/app/builder/features/publish/domains.tsx",
    "chars": 14873,
    "preview": "import {\n  Button,\n  theme,\n  Text,\n  Tooltip,\n  IconButton,\n  Grid,\n  InputField,\n  styled,\n  Flex,\n  Link,\n  SmallIcon"
  },
  {
    "path": "apps/builder/app/builder/features/publish/entri.tsx",
    "chars": 3799,
    "preview": "import * as entri from \"entrijs\";\nimport { useEffect, useState } from \"react\";\nimport { useStore } from \"@nanostores/rea"
  },
  {
    "path": "apps/builder/app/builder/features/publish/index.ts",
    "chars": 43,
    "preview": "export { PublishButton } from \"./publish\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/publish/publish.tsx",
    "chars": 36543,
    "preview": "import stripIndent from \"strip-indent\";\nimport { computed } from \"nanostores\";\nimport {\n  useEffect,\n  useState,\n  useOp"
  },
  {
    "path": "apps/builder/app/builder/features/safe-mode.tsx",
    "chars": 1512,
    "preview": "import { useState } from \"react\";\nimport { ShieldIcon } from \"@webstudio-is/icons\";\nimport {\n  Popover,\n  PopoverTrigger"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/boolean.tsx",
    "chars": 2045,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { Grid, Switch, theme } from \"@webstudio-is/design-system\";\nimport "
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/check.tsx",
    "chars": 3316,
    "preview": "import { useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { Checkbox, CheckboxAndLabel } from "
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/code.tsx",
    "chars": 6516,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { useState } from \"react\";\nimport {\n  Button,\n  DialogClose,\n  Dial"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/combined.tsx",
    "chars": 5927,
    "preview": "import { TextControl } from \"./text\";\nimport { CodeControl } from \"./code\";\nimport { NumberControl } from \"./number\";\nim"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/controls.stories.tsx",
    "chars": 4520,
    "preview": "import { Flex, StorySection, Text, theme } from \"@webstudio-is/design-system\";\nimport { BooleanControl } from \"./boolean"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/file.tsx",
    "chars": 3047,
    "preview": "import { useStore } from \"@nanostores/react\";\nimport { useId } from \"react\";\nimport { Flex, InputField, theme } from \"@w"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/json.tsx",
    "chars": 2459,
    "preview": "import { useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { isLiteralExpression } from \"@we"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/number.tsx",
    "chars": 2876,
    "preview": "import { useId, useState } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { InputField } from \"@webs"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/radio.tsx",
    "chars": 2893,
    "preview": "import { useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { RadioGroup, Radio, RadioAndLabel }"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/resource-control.tsx",
    "chars": 9233,
    "preview": "import { nanoid } from \"nanoid\";\nimport { computed } from \"nanostores\";\nimport {\n  forwardRef,\n  useId,\n  useMemo,\n  use"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/select-asset.tsx",
    "chars": 1973,
    "preview": "import { useMemo } from \"react\";\nimport { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\nim"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/select.tsx",
    "chars": 2636,
    "preview": "import { useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { Select } from \"@webstudio-is/desig"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/tag-control.tsx",
    "chars": 3732,
    "preview": "import { useState } from \"react\";\nimport { computed } from \"nanostores\";\nimport { useStore } from \"@nanostores/react\";\ni"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/text-content.tsx",
    "chars": 4503,
    "preview": "import { useMemo } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { computed } from \"nanostores\";\nim"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/text.tsx",
    "chars": 2282,
    "preview": "import { useId } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport { TextArea } from \"@webstudio-is/des"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/controls/url.tsx",
    "chars": 13660,
    "preview": "import { type ReactNode, useEffect, useId, useMemo } from \"react\";\nimport { useStore } from \"@nanostores/react\";\nimport "
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/curl.test.ts",
    "chars": 9724,
    "preview": "import { expect, test } from \"vitest\";\nimport { generateCurl, parseCurl, type CurlRequest } from \"./curl\";\n\ntest(\"suppor"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/curl.ts",
    "chars": 4354,
    "preview": "import { tokenizeArgs } from \"args-tokenizer\";\nimport { parse as parseArgs } from \"@bomb.sh/args\";\nimport type { Resourc"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/index.ts",
    "chars": 34,
    "preview": "export * from \"./settings-panel\";\n"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/property-label.tsx",
    "chars": 7221,
    "preview": "import { micromark } from \"micromark\";\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { computed } fr"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animation-keyframes.tsx",
    "chars": 9436,
    "preview": "import { Fragment, useId, useMemo, useRef, useState } from \"react\";\nimport {\n  StyleValue,\n  toValue,\n  type CssProperty"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.stories.tsx",
    "chars": 2312,
    "preview": "import { AnimationPanelContent } from \"./animation-panel-content\";\nimport { StorySection, theme } from \"@webstudio-is/de"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animation-panel-content.tsx",
    "chars": 30762,
    "preview": "import { useState, type ReactNode } from \"react\";\nimport {\n  Box,\n  Grid,\n  InputField,\n  ScrollArea,\n  Select,\n  theme,"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animation-section.tsx",
    "chars": 13831,
    "preview": "import isEqual from \"fast-deep-equal\";\nimport { forwardRef, useState, type ComponentProps } from \"react\";\nimport {\n  Gri"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animation-transforms.tsx",
    "chars": 10277,
    "preview": "import { useState } from \"react\";\nimport {\n  EnhancedTooltip,\n  Grid,\n  SmallToggleButton,\n  theme,\n} from \"@webstudio-i"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/animations-select.tsx",
    "chars": 13474,
    "preview": "import { useState, useMemo, type ReactNode, useRef } from \"react\";\nimport {\n  theme,\n  DropdownMenu,\n  DropdownMenuTrigg"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/keyframe-helpers.test.ts",
    "chars": 5939,
    "preview": "import { describe, test, expect } from \"vitest\";\nimport { calcOffsets, findInsertionIndex, moveItem } from \"./keyframe-h"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/keyframe-helpers.ts",
    "chars": 2707,
    "preview": "const multiplier = 10000;\n\nexport const calcOffsets = (\n  keyframes: { offset?: number | undefined }[]\n): number[] => {\n"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/new-scroll-animations.ts",
    "chars": 1613,
    "preview": "import { parseCssValue } from \"@webstudio-is/css-data\";\nimport type { ScrollAnimation } from \"@webstudio-is/sdk\";\n\nconst"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/new-view-animations.ts",
    "chars": 4965,
    "preview": "import { parseCssValue } from \"@webstudio-is/css-data\";\nimport type { ViewAnimation } from \"@webstudio-is/sdk\";\n\nconst n"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/set-css-property.test.tsx",
    "chars": 2477,
    "preview": "import { createRegularStyleSheet } from \"@webstudio-is/css-engine\";\nimport { ROOT_INSTANCE_ID, type WebstudioData } from"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/set-css-property.ts",
    "chars": 1731,
    "preview": "import { nanoid } from \"nanoid\";\nimport type { CssProperty, StyleValue } from \"@webstudio-is/css-engine\";\nimport {\n  get"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/animation/subject-select.tsx",
    "chars": 4487,
    "preview": "import { Select, toast } from \"@webstudio-is/design-system\";\nimport { nanoid } from \"nanoid\";\nimport { useState } from \""
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/match-media-breakpoints.test.ts",
    "chars": 2270,
    "preview": "import { describe, it, expect } from \"vitest\";\nimport { matchMediaBreakpoints } from \"./match-media-breakpoints\";\nimport"
  },
  {
    "path": "apps/builder/app/builder/features/settings-panel/props-section/match-media-breakpoints.ts",
    "chars": 755,
    "preview": "/**\n * Given an array of [breakpointId, value] tuples and an ordered list of breakpoint IDs,\n * returns the value associ"
  }
]

// ... and 1952 more files (download for full content)

About this extraction

This page contains the full source code of the webstudio-is/webstudio GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2152 files (10.0 MB), approximately 2.7M tokens, and a symbol index with 1665 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!