{
  "version": 3,
  "sources": ["../../../../../node_modules/archy/index.js", "../../../../services/src/generated/typescript/service-runtime/AssetsHelper.ts", "../../../../services/src/generated/typescript/Assets.ts", "../../../../services/src/generated/typescript/service-runtime/ModulesAPIHelper.ts", "../../../../services/src/generated/typescript/ModulesAPI.ts", "../../../../services/src/generated/typescript/service-runtime/UserNotificationsHelper.ts", "../../../../services/src/generated/typescript/UserNotifications.ts", "../../../../services/src/generated/typescript/service-runtime/UserSessionServiceHelper.ts", "../../../../services/src/generated/typescript/UserSessionService.ts", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/CanvasPan.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/CanvasZoom.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/DocumentLoad.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/DrawingShapeCreate.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/DrawingShapeEdit.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/ErrorToast.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/InteractiveLinkCreate.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/InteractivePageConnect.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/InteractiveScrollConnect.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/LayoutFrameHierarchy.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/RulersCreateGuide.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/RulersDeleteGuide.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/RulersMoveGuide.js", "../../../../../node_modules/@framerjs/framer-events/lib/esm/generated/TextCreate.js", "../../src/app/ipc.ts", "../../src/app/trackDocumentLoad.ts", "../../src/document/EngineLoggers.ts", "../../src/document/models/CanvasTree/utils/inspect.ts", "../../src/utils/mouseDidMove.ts", "../../src/document/components/tools/CreateToolHelper.ts", "../../src/document/components/canvas-hud/Overlay.tsx", "../../src/document/components/canvas-hud/GPULayer.tsx", "../../src/document/components/tools/VideoOverlay.styles.ts", "../../src/document/components/tools/VideoOverlay.tsx", "../../src/document/components/tools/CreateCodeComponentTool.ts", "../../src/document/components/tools/CreateFrameTool.ts", "../../src/document/components/tools/CreateShapeTool.ts", "../../src/document/components/tools/CreateTextTool.ts", "../../src/document/components/chrome/insertSidebar/utils/isWireframerOpen.ts", "../../src/document/components/tools/utils/getNudgeDelta.ts", "../../src/document/components/tools/utils/isSelectable.ts", "../../src/document/components/tools/utils/getSelectableTopNodeAtPoint.ts", "../../src/document/components/tools/HighlightTool.ts", "../../src/document/components/tools/Pan.tsx", "../../src/utils/appPointerEvents.ts", "../../src/document/components/tools/utils/mouseActionType.tsx", "../../src/document/components/tools/RadiusTool.ts", "../../src/document/components/tools/ResizeTool.ts", "../../src/document/components/tools/Rotate.tsx", "../../src/document/components/tools/SampleColor.tsx", "../../src/document/components/utils/variableProviderValues.ts", "../../src/document/components/tools/Select.tsx", "../../src/document/components/tools/MouseDrawnRect.tsx", "../../src/document/components/tools/SlotConnectTool.ts", "../../src/document/components/tools/TextEditTool.ts", "../../src/document/components/tools/ZoomSelectTool.ts", "../../src/document/components/tools/Zoom.ts", "../../src/document/components/tools/linkTool/LinkTool.ts", "../../src/document/components/tools/pathEdit/PathToolManager.tsx", "../../src/document/components/tools/ZoomSelect.tsx", "../../src/document/components/tools/pathEdit/PathCurveBend.tsx", "../../src/document/components/tools/pathEdit/PathDefault.tsx", "../../src/document/models/PathSegmentSnapping.ts", "../../src/document/components/tools/pathEdit/PathSegmentMove.ts", "../../src/document/components/tools/pathEdit/PathSegmentSelect.tsx", "../../src/document/components/tools/pathEdit/controls/ProjectedPoint.tsx", "../../src/document/components/tools/pathEdit/PathSegmentAddition.tsx", "../../src/document/components/tools/pathEdit/controls/PathCurvePreview.tsx", "../../src/document/components/tools/pathEdit/controls/PathCurve.tsx", "../../src/document/components/tools/pathEdit/controls/PathSegmentControl.styles.ts", "../../src/document/components/tools/pathEdit/utils/withPathSnapping.tsx", "../../src/document/components/tools/pathEdit/controls/IntersectionTangent.tsx", "../../src/document/components/tools/pathEdit/PathSegmentHandleMove.tsx", "../../src/document/components/tools/pathEdit/PathSegmentAdditionTool.ts", "../../src/document/components/tools/pathEdit/controls/PathCurves.tsx", "../../src/document/components/tools/pathEdit/controls/PathSegmentAnchors.tsx", "../../src/document/components/tools/pathEdit/controls/PathSegmentAnchor.tsx", "../../src/document/components/tools/pathEdit/controls/PathSegmentHandles.tsx", "../../src/document/components/tools/pathEdit/controls/Line.tsx", "../../src/document/components/tools/pathEdit/controls/PathSegmentHandle.tsx", "../../src/document/components/tools/pathEdit/controls/PathShapes.tsx", "../../src/document/components/tools/pathEdit/controls/PathShape.tsx", "../../src/document/components/tools/pathEdit/utils/PathSnapper.ts", "../../src/document/components/tools/AgentSelectTool.ts", "../../src/document/components/tools/AgentPanelTool.ts", "../../src/document/components/canvas/Multiplayer.styles.ts", "../../src/document/components/tools/Chat.tsx", "../../src/document/components/tools/BaseVariableEditTool.ts", "../../src/document/components/tools/CollectionReferenceVariableEditTool.ts", "../../src/document/components/tools/DateVariableEditTool.ts", "../../src/document/components/tools/EnumVariableEditTool.ts", "../../src/feedback/anchorUtils.ts", "../../src/feedback/model.ts", "../../src/document/components/tools/Feedback.tsx", "../../src/document/utils/getSingleSelectedStackNode.ts", "../../src/document/components/chrome/properties/panels/utils/focusPropertyInput.ts", "../../src/document/components/tools/Gap.tsx", "../../src/document/components/tools/GuideMoveTool.ts", "../../src/document/models/CanvasTree/traits/utils/isUserComponent.ts", "../../src/document/components/tools/utils/getTintColor.ts", "../../src/document/components/tools/HighlightStackItem.tsx", "../../src/document/components/tools/LineAnchorMove.ts", "../../src/document/components/tools/LoadingShieldTool.ts", "../../src/document/components/tools/Padding.tsx", "../../src/prosemirror/plugins/fontPreviewPlugin.ts", "../../src/document/components/tools/RichTextEditTool.ts", "../../src/document/components/tools/RichTextVariableEditTool.ts", "../../src/document/components/tools/ScaleTool.ts", "../../src/document/components/tools/StringVariableEditTool.ts", "../../src/document/components/tools/ViewportResize.tsx", "../../src/document/components/tools/gradient/GradientToolManagerTool.tsx", "../../src/document/toolClassFor.ts", "../../src/document/newToolFor.ts", "../../src/document/stores/LoadingStore.ts", "../../src/document/components/chrome/siteSettings/Usage/types.ts", "../../src/utils/urlParams.ts", "../../src/wrappers/ipcRenderer.ts", "../../src/document/EnginePerformance.ts", "../../src/app/ai/kits/screenshots.ts", "../../src/utils/chromeBreakpoints.ts", "../../src/document/LayoutState.ts", "../../src/document/utils/cycleSelection.ts", "../../src/document/components/chrome/properties/panels/utils/textContentComputedValuePopoutId.ts", "../../src/document/components/utils/editActionForNodes.ts", "../../src/document/components/tools/createToolKeyDownHandler.ts", "../../src/utils/guessFrameForNode.ts", "../../src/document/stores/CanvasStore.ts", "agent-evals-browser-entry:/Users/alex/Projects/FramerStudio/src/app/vekter/src/app/browserAgentEvals.ts", "../../src/document/components/chrome/localization/matchingItemsToastKey.ts", "../../src/document/components/chrome/localization/dismissMatchingItemsToast.ts", "../../src/document/utils/newSetByTogglingItem.ts", "../../src/document/stores/ChromeStore.ts", "../../src/utils/translateErrorEvent.ts", "../../src/document/stores/ComponentsStore.ts", "../../src/document/components/chrome/properties/utils/styledText.ts", "../../src/document/stores/CustomFontStore.ts", "../../src/document/stores/DocumentSettingsStore.ts", "../../src/feedback/api.ts", "../../src/feedback/canvasUtils.ts", "../../src/feedback/notificationUtils.ts", "../../src/feedback/utils.ts", "../../src/document/stores/FeedbackStore.ts", "../../src/document/utils/DataStore.ts", "../../src/document/stores/MouseStore.ts", "../../src/document/stores/PersistedUserDefaults.ts", "../../src/document/stores/WebFontStore.ts", "../../src/utils/serviceChannels.ts", "../../src/modules/getModulesAPI.ts", "../../src/document/RemoteUsers.ts", "../../src/utils/CircularBuffer.ts", "../../src/document/components/canvas/CanvasMouseTarget.tsx", "../../src/app/ai/types/AIChatHistory.ts", "../../src/app/ai/orchestrator/dsl.ts", "../../../../../node_modules/yaml/browser/dist/nodes/identity.js", "../../../../../node_modules/yaml/browser/dist/visit.js", "../../../../../node_modules/yaml/browser/dist/doc/directives.js", "../../../../../node_modules/yaml/browser/dist/doc/anchors.js", "../../../../../node_modules/yaml/browser/dist/doc/applyReviver.js", "../../../../../node_modules/yaml/browser/dist/nodes/toJS.js", "../../../../../node_modules/yaml/browser/dist/nodes/Node.js", "../../../../../node_modules/yaml/browser/dist/nodes/Alias.js", "../../../../../node_modules/yaml/browser/dist/nodes/Scalar.js", "../../../../../node_modules/yaml/browser/dist/doc/createNode.js", "../../../../../node_modules/yaml/browser/dist/nodes/Collection.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyComment.js", "../../../../../node_modules/yaml/browser/dist/stringify/foldFlowLines.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyString.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringify.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyPair.js", "../../../../../node_modules/yaml/browser/dist/log.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js", "../../../../../node_modules/yaml/browser/dist/nodes/addPairToJSMap.js", "../../../../../node_modules/yaml/browser/dist/nodes/Pair.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyCollection.js", "../../../../../node_modules/yaml/browser/dist/nodes/YAMLMap.js", "../../../../../node_modules/yaml/browser/dist/schema/common/map.js", "../../../../../node_modules/yaml/browser/dist/nodes/YAMLSeq.js", "../../../../../node_modules/yaml/browser/dist/schema/common/seq.js", "../../../../../node_modules/yaml/browser/dist/schema/common/string.js", "../../../../../node_modules/yaml/browser/dist/schema/common/null.js", "../../../../../node_modules/yaml/browser/dist/schema/core/bool.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyNumber.js", "../../../../../node_modules/yaml/browser/dist/schema/core/float.js", "../../../../../node_modules/yaml/browser/dist/schema/core/int.js", "../../../../../node_modules/yaml/browser/dist/schema/core/schema.js", "../../../../../node_modules/yaml/browser/dist/schema/json/schema.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/float.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/int.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/set.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js", "../../../../../node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js", "../../../../../node_modules/yaml/browser/dist/schema/tags.js", "../../../../../node_modules/yaml/browser/dist/schema/Schema.js", "../../../../../node_modules/yaml/browser/dist/stringify/stringifyDocument.js", "../../../../../node_modules/yaml/browser/dist/doc/Document.js", "../../../../../node_modules/yaml/browser/dist/parse/cst-visit.js", "../../../../../node_modules/yaml/browser/dist/parse/lexer.js", "../../../../../node_modules/yaml/browser/dist/public-api.js", "../../src/app/ai/orchestrator/systemPrompt.ts", "../../src/app/ai/orchestrator/tasks.ts", "../../src/app/ai/orchestrator/streamPlan.ts", "../../src/app/ai/utils/tracking.ts", "../../src/app/ai/workers/generateMessage/utils/promptBuilder.ts", "../../src/app/ai/workers/generateMessage/generateMessage.ts", "../../src/document/components/utils/createWebPage.ts", "../../src/app/ai/sections/collections.ts", "../../src/app/ai/utils/wireframerKit.ts", "../../src/document/utils/SloppyJavaScriptParser.ts", "../../src/document/models/CanvasTree/traits/utils/ContentContainer.ts", "../../src/app/ai/utils/followUpTasks.ts", "../../src/app/ai/workers/generateWebPage/schema.ts", "../../src/app/ai/utils/getNodeProperty.ts", "../../src/document/models/CanvasTree/nodes/utils/setStringValue.ts", "../../src/document/components/utils/propKeyIsTitleLike.ts", "../../src/document/models/CanvasTree/traits/utils/createComputedFormattedDate.ts", "../../src/document/utils/contentCreationTemplates.ts", "../../src/utils/updateLinks.ts", "../../src/app/ai/workers/generateWebPage/utils/collections.ts", "../../src/app/ai/workers/generateWebPage/utils/applyContentToNodes.ts", "../../src/app/ai/workers/generateWebPage/utils/common.ts", "../../src/app/ai/utils/getKitSectionsUsageData.ts", "../../src/app/ai/workers/generateWebPage/utils/prompts/systemPrompt.ts", "../../src/app/ai/workers/generateWebPage/utils/prompts/promptBuilder.ts", "../../src/app/ai/AsyncQueue.ts", "../../src/utils/shuffle.ts", "../../src/app/ai/sections/data/collections.json", "../../src/app/ai/sections/data/controlProps.json", "../../src/app/ai/sections/data/index.ts", "../../src/app/ai/sections/data/vectorSetModuleData.json", "../../src/app/ai/sections/SectionsState.ts", "../../src/document/components/utils/equalHierarchies.ts", "../../src/document/components/utils/generateReplicaOverrides.ts", "../../src/app/ai/kits/clipboardData.ts", "../../src/app/ai/sections/getKitSectionNodeData.ts", "../../src/app/ai/sections/index.ts", "../../src/app/ai/kits/DefaultKit.ts", "../../src/utils/updateDarkModeWithoutDarkModeProvider.ts", "../../src/app/ai/workers/generateWebPage/utils/colorScheme.ts", "../../src/app/ai/workers/generateWebPage/utils/sectionOperations.ts", "../../src/app/ai/workers/generateWebPage/generateWebPage.ts", "../../src/app/ai/workers/generateWebPage/utils/pageOperations.ts", "../../src/app/ai/workers/generateWebPage/actions/createWebPage.ts", "../../src/app/ai/workers/generateWebPage/actions/deleteWebPage.ts", "../../src/app/ai/workers/generateWebPage/actions/modifyWebPage.ts", "../../src/app/ai/workers/generateWebPage/actions/updateDarkMode.ts", "../../src/app/ai/workers/promptSuggestions/utils/promptBuilder.ts", "../../src/app/ai/workers/promptSuggestions/getPromptSuggestions.ts", "../../src/app/ai/workers/resourceSuggestions/utils/systemPrompt.ts", "../../src/app/ai/workers/resourceSuggestions/getResourceSuggestions.ts", "../../src/app/ai/workers/upsertCmsItems/schema.ts", "../../src/app/ai/workers/upsertCmsItems/utils/richText.ts", "../../src/app/ai/workers/upsertCmsItems/utils/cmsItemsOperations.ts", "../../src/app/ai/workers/upsertCmsItems/utils/systemPrompt.ts", "../../src/app/ai/workers/upsertCmsItems/utils/getItemsSampleByTokens.ts", "../../src/app/ai/workers/upsertCmsItems/utils/userPrompt.ts", "../../src/app/ai/workers/upsertCmsItems/upsertCmsItems.ts", "../../src/app/ai/WireframerSession.ts", "../../src/app/ai/utils/generateLLMJSX.ts", "../../src/app/ai/sections/generateSectionCustomizations.ts", "../../src/app/ai/utils/sectionScreenshot.ts", "../../src/app/ai/kits/KitAliasManager.ts", "../../src/app/ai/kits/LocalKit.ts", "../../src/app/ai/sections/types.ts", "../../src/app/ai/kits/RemoteKit.ts", "../../src/document/library/libraryApi.ts", "../../src/document/stores/AIGenerationStore.ts", "../../src/document/stores/AgentStoreStorage.ts", "../../src/document/stores/AgentStore.ts", "../../src/document/stores/AssetStore.ts", "../../src/document/stores/CodeEditorStore.ts", "../../src/document/components/chrome/contentManagement/utils/collectionItemTableStatusColumn.ts", "../../src/document/components/chrome/contentManagement/utils/collectionItemTableFilters.ts", "../../src/document/stores/ContentManagementStore.ts", "../../src/document/stores/EffectStore.ts", "../../src/document/stores/FontPreviewStore.ts", "../../src/document/preview/ChangeTracker.ts", "../../src/document/stores/FullsizePreviewStore.ts", "../../src/document/stores/GuidesStore.ts", "../../src/history/dataProcessing.ts", "../../src/history/utils.ts", "../../src/history/ServerHistoryController.ts", "../../src/document/stores/HistoryStore.ts", "../../src/document/stores/HostnameStore.ts", "../../src/document/stores/InsertSidebarStore.ts", "../../src/document/stores/KitScreenshotStore.ts", "../../src/document/stores/LibraryStore.ts", "../../src/document/stores/LoadedExternalModulesStore.ts", "../../src/document/components/chrome/shared/UpsellModal/utils/aiCreditsUpsell.ts", "../../src/app/ai/translation/stripHTMLAttributes.ts", "../../src/app/ai/translation/prompts.ts", "../../src/document/components/chrome/localization/fixStreamingHTML.ts", "../../src/document/components/chrome/localization/getTranslationSourceType.ts", "../../src/document/components/chrome/localization/glossaryUtils.ts", "../../src/document/components/chrome/localization/getReusableTranslationsByHash.ts", "../../src/document/components/chrome/localization/translationCreditLimit.ts", "../../src/document/components/chrome/localization/BatchTranslation.ts", "../../src/document/components/chrome/localization/automaticTranslationService.ts", "../../src/document/components/chrome/localization/isExpandedSourceGroup.ts", "../../src/document/stores/AdaptiveDeferral.ts", "../../src/document/stores/LocalizationStore.ts", "../../src/document/stores/MouseCursorStore.ts", "../../src/document/stores/OverlayStore.ts", "../../src/document/stores/PaymentsStore.ts", "../../src/plugins/pluginService.ts", "../../src/document/models/CanvasTree/nodes/utils/entityTypeRootNode.ts", "../../src/plugins/utils/collectTopicsFromNodeChanges.ts", "../../src/document/stores/PluginStore.ts", "../../src/document/preview/PreviewItem.ts", "../../src/document/components/chrome/preview/getLabelForComponent.ts", "../../src/document/preview/PreviewRecentList.ts", "../../src/preview-module/utils/deviceConfigForNode.ts", "../../src/preview-module/utils/scaleToFitConfig.ts", "../../src/document/preview/getPresentationMetadata.ts", "../../src/document/stores/PreviewStore.ts", "../../src/document/stores/ProjectStore.ts", "../../src/document/stores/PropertiesPanelStore.ts", "../../src/document/stores/RepeaterStore.ts", "../../src/document/stores/SelectionOutlineTracker.ts", "../../../shared/src/User.ts", "../../src/document/stores/SessionStore.ts", "../../src/document/stores/ShaderFallbackImageStore.ts", "../../src/document/stores/SnapLinesStore.ts", "../../src/document/stores/UndoRedoManager.ts", "../../src/document/stores/VariablesStore.ts", "../../src/document/EngineStores.ts", "../../src/app/headlessApiContext.ts", "../../src/document/getContextsForErrorReporting.ts", "../../src/document/VekterEngineErrorRecovery.ts", "../../src/document/EngineTesting.ts", "../../src/document/RemoteLocks.ts", "../../src/document/crdt/sync/LocalCacheDataBackend.ts", "../../src/document/crdt/sync/LocalCacheMaintenance.ts", "../../src/document/crdt/sync/LocalCacheVerifyRows.ts", "../../src/document/crdt/sync/LocalCache.ts", "../../src/document/RemoteDocument.ts", "../../src/document/VekterEngineScheduler.ts", "../../src/document/components/chrome/shared/ColorPicker/tokenPackages.ts", "../../src/document/components/chrome/siteSettings/CustomCode/utils/deletePageFromCustomCode.ts", "../../src/document/models/CanvasTree/nodes/utils/isModuleBackedScope.ts", "../../src/document/utils/DocumentUpgradeManager.ts", "../../src/document/VekterEngine.ts"],
  "sourcesContent": ["module.exports = function archy (obj, prefix, opts) {\n    if (prefix === undefined) prefix = '';\n    if (!opts) opts = {};\n    var chr = function (s) {\n        var chars = {\n            '\u2502' : '|',\n            '\u2514' : '`',\n            '\u251C' : '+',\n            '\u2500' : '-',\n            '\u252C' : '-'\n        };\n        return opts.unicode === false ? chars[s] : s;\n    };\n    \n    if (typeof obj === 'string') obj = { label : obj };\n    \n    var nodes = obj.nodes || [];\n    var lines = (obj.label || '').split('\\n');\n    var splitter = '\\n' + prefix + (nodes.length ? chr('\u2502') : ' ') + ' ';\n    \n    return prefix\n        + lines.join(splitter) + '\\n'\n        + nodes.map(function (node, ix) {\n            var last = ix === nodes.length - 1;\n            var more = node.nodes && node.nodes.length;\n            var prefix_ = prefix + (last ? ' ' : chr('\u2502')) + ' ';\n            \n            return prefix\n                + (last ? chr('\u2514') : chr('\u251C')) + chr('\u2500')\n                + (more ? chr('\u252C') : chr('\u2500')) + ' '\n                + archy(node, prefix_, opts).slice(prefix.length + 2)\n            ;\n        }).join('')\n    ;\n};\n", "/*\n ****\n ******\n ******\n ******\n ****** \u267B\uFE0F Runtime helper generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n ****** See '../' for service types.\n ******\n ******\n ******\n ****\n */\n\n// The generated service helper may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport {\n\tService,\n\tServiceManager,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../../runtime/index.ts\"\n\nimport type { Assets } from \"../Assets.ts\"\n\nconst { onewayMethodTemplate, voidMethodTemplate, valueMethodTemplate, streamMethodTemplate } = ServiceRuntimePrivate\n\nexport namespace AssetsHelper {\n\ttype Interface = Assets.Interface\n\n\texport const service: Service<Interface> = {\n\t\tid: \"__Assets__\",\n\t\tfingerprint: \"7c96dcbf0bbf33bdaabf686b6cc22eb0\",\n\t\tmethods: {\n\t\t\tassetUpdatesStream: {},\n\t\t},\n\t\tnewOutgoingWrapper: (helper: ServiceMessageHelper): Interface => {\n\t\t\treturn {\n\t\t\t\tassetUpdatesStream: streamMethodTemplate.bind(/* this: */ -1, \"assetUpdatesStream\", helper),\n\t\t\t} as Interface\n\t\t},\n\t}\n}\n", "/*\n **********\n *********\n ********\n *******\n ****** \u267B\uFE0F Generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n *****\n ****\n ***\n **\n */\n\n// The generated namespace may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport type {\n\tService,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../runtime/index.ts\"\nimport { ServiceManager } from \"../../runtime/index.ts\"\n\n// The generated namespace may or may not use some of the global types. For simplicity, we import all of them.\nimport type {\n\tPoint,\n\tSize,\n\tRect,\n\tUser,\n\tColor,\n\tMenuAction,\n\tMenuValidationResult,\n\tMenuDispatchResult,\n\tMenuActionState,\n\tArea,\n\tContextMenu,\n\tMenuOptionIconCrossOrigin,\n\tMenuOptionIcon,\n\tMenuItemOptions,\n\tContextMenuResult,\n} from \"./Global.ts\"\n\n// Import the service implementation\nimport { AssetsHelper } from \"./service-runtime/AssetsHelper.ts\"\n\nimport type { SharedService } from \"./SharedService.ts\"\n\nexport namespace Assets {\n\t/**\n\t * Assets is not documented.\n\t */\n\texport interface Interface {\n\t\tassetUpdatesStream(_?: ServiceStreamOptions): ServiceStream<Assets.AssetUpdateEvent>\n\t}\n\n\t/*\n\t * Using the service\n\t */\n\n\texport const service: Service<Interface> = AssetsHelper.service\n\n\texport function on(channel: ServiceChannel): SharedService<Interface> {\n\t\t// Note: capture the shared service manager here so testing behavior is predictable\n\t\tconst sharedServices = ServiceManager.shared()\n\t\treturn {\n\t\t\texpect: () => sharedServices.expectWithoutDiscovery(service, channel),\n\t\t\tdiscover: options => sharedServices.discover(service, channel, options),\n\t\t\tregister: implementation => sharedServices.register({ channel, service, implementation }),\n\t\t}\n\t}\n\n\texport async function unregister(implementation: Interface): Promise<void> {\n\t\tvoid ServiceManager.shared().unregister(implementation)\n\t}\n\n\t/*\n\t * Types\n\t */\n\n\texport type FontFaceDescriptors = ServiceValue<{\n\t\tweight: integer\n\t\twidth?: float\n\t\titalic: boolean\n\t\toblique: boolean\n\t\tobliqueAngle?: float\n\t}>\n\n\texport type AssetFontPropertiesFontCategory = ServiceValue<\n\t\t\"sans-serif\" | \"serif\" | \"slab\" | \"monospace\" | \"display\" | \"handwriting\"\n\t>\n\n\texport type AssetFontProperties = ServiceValue<{\n\t\tfontFamily: string\n\t\tfontSubFamily: string\n\t\tmetrics?: UnsafeJSON\n\t\topenTypeData?: UnsafeJSON\n\t\tvariationAxes?: UnsafeJSON\n\t\tfaceDescriptors?: Assets.FontFaceDescriptors\n\t\tfontCategory?: \"sans-serif\" | \"serif\" | \"slab\" | \"monospace\" | \"display\" | \"handwriting\"\n\t\tfontVersion?: string\n\t\tfoundryName?: string\n\t}>\n\n\texport type AssetImageProperties = ServiceValue<{\n\t\theight: integer\n\t\twidth: integer\n\t}>\n\n\texport type AssetProperties = ServiceValue<{\n\t\tkind: string\n\t\tfont: Assets.AssetFontProperties\n\t\timage?: Assets.AssetImageProperties\n\t}>\n\n\texport type Asset = ServiceValue<{\n\t\tkey: string\n\t\tname: string\n\t\textension: string\n\t\townerType: string\n\t\tmimeType: string\n\t\tproperties?: Assets.AssetProperties\n\t}>\n\n\texport type AssetUpdateEvent = ServiceValue<{\n\t\tassets?: readonly Assets.Asset[]\n\t}>\n}\n", "/*\n ****\n ******\n ******\n ******\n ****** \u267B\uFE0F Runtime helper generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n ****** See '../' for service types.\n ******\n ******\n ******\n ****\n */\n\n// The generated service helper may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport {\n\tService,\n\tServiceManager,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../../runtime/index.ts\"\n\nimport type { ModulesAPI } from \"../ModulesAPI.ts\"\n\nconst { onewayMethodTemplate, voidMethodTemplate, valueMethodTemplate, streamMethodTemplate } = ServiceRuntimePrivate\n\nexport namespace ModulesAPIHelper {\n\ttype Interface = ModulesAPI.Interface\n\n\texport const service: Service<Interface> = {\n\t\tid: \"__ModulesAPI__\",\n\t\tfingerprint: \"e687bbf35e2e156e22209ac4bba1fc9d\",\n\t\tmethods: {\n\t\t\tcreate: {},\n\t\t\tdelete: {},\n\t\t\trestore: {},\n\t\t\tgetModuleDependencies: {},\n\t\t\tlist: {},\n\t\t\tlistNamespaces: {},\n\t\t\tlistPublishedModules: {},\n\t\t\tlookUpModules: {},\n\t\t\tmoduleEventsStream: {},\n\t\t\tpublish: {},\n\t\t\tsave: {},\n\t\t\tsaveBatch: {},\n\t\t\tupdate: {},\n\t\t\tcreateNamespace: {},\n\t\t\tkits: {},\n\t\t\tenqueueKitScreenshots: {},\n\t\t},\n\t\tnewOutgoingWrapper: (helper: ServiceMessageHelper): Interface => {\n\t\t\treturn {\n\t\t\t\tcreate: valueMethodTemplate.bind(/* this: */ -1, \"create\", /* accepts argument: */ true, helper),\n\t\t\t\tdelete: voidMethodTemplate.bind(/* this: */ -1, \"delete\", /* accepts argument: */ true, helper),\n\t\t\t\trestore: valueMethodTemplate.bind(/* this: */ -1, \"restore\", /* accepts argument: */ true, helper),\n\t\t\t\tgetModuleDependencies: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"getModuleDependencies\",\n\t\t\t\t\t/* accepts argument: */ true,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tlist: valueMethodTemplate.bind(/* this: */ -1, \"list\", /* accepts argument: */ true, helper),\n\t\t\t\tlistNamespaces: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"listNamespaces\",\n\t\t\t\t\t/* accepts argument: */ false,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tlistPublishedModules: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"listPublishedModules\",\n\t\t\t\t\t/* accepts argument: */ true,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tlookUpModules: valueMethodTemplate.bind(/* this: */ -1, \"lookUpModules\", /* accepts argument: */ true, helper),\n\t\t\t\tmoduleEventsStream: streamMethodTemplate.bind(/* this: */ -1, \"moduleEventsStream\", helper),\n\t\t\t\tpublish: valueMethodTemplate.bind(/* this: */ -1, \"publish\", /* accepts argument: */ true, helper),\n\t\t\t\tsave: valueMethodTemplate.bind(/* this: */ -1, \"save\", /* accepts argument: */ true, helper),\n\t\t\t\tsaveBatch: valueMethodTemplate.bind(/* this: */ -1, \"saveBatch\", /* accepts argument: */ true, helper),\n\t\t\t\tupdate: valueMethodTemplate.bind(/* this: */ -1, \"update\", /* accepts argument: */ true, helper),\n\t\t\t\tcreateNamespace: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"createNamespace\",\n\t\t\t\t\t/* accepts argument: */ true,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tkits: valueMethodTemplate.bind(/* this: */ -1, \"kits\", /* accepts argument: */ false, helper),\n\t\t\t\tenqueueKitScreenshots: voidMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"enqueueKitScreenshots\",\n\t\t\t\t\t/* accepts argument: */ true,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t} as Interface\n\t\t},\n\t}\n}\n", "/*\n **********\n *********\n ********\n *******\n ****** \u267B\uFE0F Generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n *****\n ****\n ***\n **\n */\n\n// The generated namespace may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport type {\n\tService,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../runtime/index.ts\"\nimport { ServiceManager } from \"../../runtime/index.ts\"\n\n// The generated namespace may or may not use some of the global types. For simplicity, we import all of them.\nimport type {\n\tPoint,\n\tSize,\n\tRect,\n\tUser,\n\tColor,\n\tMenuAction,\n\tMenuValidationResult,\n\tMenuDispatchResult,\n\tMenuActionState,\n\tArea,\n\tContextMenu,\n\tMenuOptionIconCrossOrigin,\n\tMenuOptionIcon,\n\tMenuItemOptions,\n\tContextMenuResult,\n} from \"./Global.ts\"\n\n// Import the service implementation\nimport { ModulesAPIHelper } from \"./service-runtime/ModulesAPIHelper.ts\"\n\nimport type { SharedService } from \"./SharedService.ts\"\n\nexport namespace ModulesAPI {\n\t/**\n\t * ModulesAPI is not documented.\n\t */\n\texport interface Interface {\n\t\tcreate(_: ModulesAPI.CreateRequest): Promise<ModulesAPI.ModuleWithSave>\n\t\tdelete(_: ModulesAPI.DeleteRequest): Promise<void>\n\t\trestore(_: ModulesAPI.RestoreRequest): Promise<ModulesAPI.ModuleWithSave>\n\t\tgetModuleDependencies(_: ModulesAPI.DependenciesRequest): Promise<ModulesAPI.DependenciesResponse>\n\t\tlist(_: ModulesAPI.ListRequest): Promise<ModulesAPI.ListResponse>\n\t\tlistNamespaces(): Promise<ModulesAPI.ListNamespacesResponse>\n\t\tlistPublishedModules(_: ModulesAPI.ListPublishedModulesRequest): Promise<ModulesAPI.ListPublishedModulesResponse>\n\t\tlookUpModules(_: ModulesAPI.LookupRequest): Promise<ModulesAPI.LookupResponse>\n\t\tmoduleEventsStream(): ServiceStream<ModulesAPI.ModuleEventList>\n\t\tpublish(_: ModulesAPI.PublishRequest): Promise<ModulesAPI.Publish>\n\t\tsave(_: ModulesAPI.SaveRequest): Promise<ModulesAPI.ModuleWithSave>\n\t\tsaveBatch(_: ModulesAPI.SaveBatchRequest): Promise<ModulesAPI.ListResponse>\n\t\tupdate(_: ModulesAPI.UpdateRequest): Promise<ModulesAPI.ModuleWithSave>\n\t\tcreateNamespace(_: ModulesAPI.CreateNamespaceRequest): Promise<ModulesAPI.Namespace>\n\t\tkits(): Promise<ModulesAPI.KitsResponse>\n\t\tenqueueKitScreenshots(_: ModulesAPI.EnqueueKitScreenshotsRequest): Promise<void>\n\t}\n\n\t/*\n\t * Using the service\n\t */\n\n\texport const service: Service<Interface> = ModulesAPIHelper.service\n\n\texport function on(channel: ServiceChannel): SharedService<Interface> {\n\t\t// Note: capture the shared service manager here so testing behavior is predictable\n\t\tconst sharedServices = ServiceManager.shared()\n\t\treturn {\n\t\t\texpect: () => sharedServices.expectWithoutDiscovery(service, channel),\n\t\t\tdiscover: options => sharedServices.discover(service, channel, options),\n\t\t\tregister: implementation => sharedServices.register({ channel, service, implementation }),\n\t\t}\n\t}\n\n\texport async function unregister(implementation: Interface): Promise<void> {\n\t\tvoid ServiceManager.shared().unregister(implementation)\n\t}\n\n\t/*\n\t * Types\n\t */\n\n\texport type ModuleEvent = ServiceValue<\n\t\t| {\n\t\t\t\ttype: \"delete\"\n\t\t\t\tid: string\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"save\"\n\t\t\t\tmodule: ModulesAPI.ModuleWithSave\n\t\t  }\n\t>\n\n\texport type ModuleEventList = ServiceValue<{\n\t\tevents: readonly ModulesAPI.ModuleEvent[]\n\t}>\n\n\texport type PublishInfo = ServiceValue<{\n\t\tnamespaceId: string\n\t\tname: string\n\t\tversion: string\n\t\timportURL: string\n\t}>\n\n\texport type Group = ServiceValue<{\n\t\tid: string\n\t\ttype: string\n\t\tname: string\n\t}>\n\n\texport type ModuleStatus = ServiceValue<{\n\t\tgroup: ModulesAPI.Group\n\t\tupdateSaveId: string\n\t}>\n\n\texport type Imports = ServiceValue<{\n\t\tabsolute: readonly string[]\n\t\trelative: readonly string[]\n\t\tbare: readonly string[]\n\t}>\n\n\texport type ModuleWithSave = ServiceValue<{\n\t\tid: string\n\t\t/** An id that is unique to the owner (but may be the same across multiple owners). */\n\t\tlocalId: string\n\t\townerId: string\n\t\townerType: string\n\t\tcreatedAt: string\n\t\tupdatedAt: string\n\t\ttype: string\n\t\tname: string\n\t\tdeletedAt: string | null\n\t\ttitle: string\n\t\tdescription: string | null\n\t\tsaveId: string\n\t\tuserId: string\n\t\tsavedAt: string\n\t\t/** A map of file type to filename. */\n\t\tfiles: { readonly [_: string]: string }\n\t\t/**\n\t\t * A list of submodule filenames. For backwards compatibility reasons\n\t\t * they are not part of the files map above.\n\t\t */\n\t\tsubmodules: readonly string[]\n\t\t/** Whether the module is using any assets, including images, videos, and files. */\n\t\thasAssets: boolean\n\t\t/**\n\t\t * A list of binary assets. For backwards compatibility reasons they are\n\t\t * not part of the files map above.\n\t\t */\n\t\tbinaryAssets: readonly string[]\n\t\tmetadata: UnsafeJSON\n\t\t/** The dependencies imported by this module. */\n\t\timports: ModulesAPI.Imports\n\t\t/** A list of names exported by the module. */\n\t\texports: readonly string[]\n\t\t/** The modules that were re-exported by this module (export * from \"\u2026\"). */\n\t\treExportedModules: readonly string[]\n\t\tbaseURL: string\n\t\t/** Short import URL, e.g. \"https://framer.com/m/Button-2m3E.js\" */\n\t\timportURL: string\n\t\t/** Information about the last publish of this module. */\n\t\tlastPublish: ModulesAPI.PublishInfo | null\n\t\t/** Module status (such as team, latest version). Only included sometimes for performance reasons. */\n\t\tstatus?: ModulesAPI.ModuleStatus\n\t\t/**\n\t\t * The revision of the source node of the module at the time the source\n\t\t * code was generated.\n\t\t */\n\t\tsourceRevision?: integer\n\t}>\n\n\texport type Save = ServiceValue<{\n\t\tid: string\n\t\tmoduleId: string\n\t\tuserId: string\n\t\tsavedAt: string\n\t\tname: string\n\t\t/** A map of file type to filename. */\n\t\tfiles: { readonly [_: string]: string }\n\t\t/**\n\t\t * A list of submodule filenames. For backwards compatibility reasons\n\t\t * they are not part of the files map above.\n\t\t */\n\t\tsubmodules: readonly string[]\n\t\tmetadata: UnsafeJSON\n\t\t/** The dependencies imported by this module. */\n\t\timports?: ModulesAPI.Imports\n\t\t/** A list of names exported by the module. */\n\t\texports: readonly string[]\n\t\t/** The modules that were re-exported by this module (export * from \"\u2026\"). */\n\t\treExportedModules: readonly string[]\n\t\tbaseURL: string\n\t\tpublished?: readonly ModulesAPI.Publish[]\n\t}>\n\n\texport type ListResponse = ServiceValue<{\n\t\tdata: readonly ModulesAPI.ModuleWithSave[]\n\t}>\n\n\texport type FileUpload = ServiceValue<{\n\t\t/** A single filename (no paths allowed). */\n\t\tname: string\n\t\t/** The purpose of the file (\"module\", \"source\", etc). */\n\t\ttype: string\n\t\t/** For module's content all the relative imports should be replaced with absolute URLs, if possible. */\n\t\tcontent?: string\n\t\t/** For binary files leave content empty and set bytes. */\n\t\tbytes?: Uint8Array<ArrayBuffer>\n\t}>\n\n\texport type CreateRequest = ServiceValue<{\n\t\t/** The module type (\"codeFile\", \"canvas\", etc). */\n\t\ttype: string\n\t\tsaveId: string\n\t\tname: string\n\t\tfiles: readonly ModulesAPI.FileUpload[]\n\t\tmetadata?: UnsafeJSON\n\t\ttitle?: string\n\t\tdescription?: string\n\t\ttransferEncoding?: string\n\t\tassets?: readonly string[]\n\t\t/** The dependencies imported by this module. */\n\t\timports: ModulesAPI.Imports\n\t\t/** The names exported by this module. */\n\t\texports: readonly string[]\n\t\t/** The modules that were re-exported by this module (export * from \"\u2026\"). */\n\t\treExportedModules: readonly string[]\n\t}>\n\n\texport type DeleteRequest = ServiceValue<{\n\t\tmoduleId: string\n\t}>\n\n\texport type RestoreRequest = ServiceValue<{\n\t\tmoduleId: string\n\t\t/** Optional name to restore the module with. If omitted, the original name is used. Useful when the original name is already taken. */\n\t\tname?: string\n\t}>\n\n\texport type DependenciesRequest = ServiceValue<{\n\t\tmoduleId: string\n\t\tsaveId: string\n\t}>\n\n\texport type ImportDependency = ServiceValue<\n\t\t| {\n\t\t\t\ttype: \"local\"\n\t\t\t\tmoduleType: string\n\t\t\t\tmoduleName: string\n\t\t\t\tlocalId: string\n\t\t\t\tmoduleId: string\n\t\t\t\tsaveId: string\n\t\t\t\tfile: string\n\t\t\t\tspecifier: string\n\t\t\t\tnames: readonly string[]\n\t\t\t\timportURL: string\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"external\"\n\t\t\t\tmoduleId: string\n\t\t\t\tsaveId: string\n\t\t\t\tfile: string\n\t\t\t\tspecifier: string\n\t\t\t\tnames: readonly string[]\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"thirdparty\"\n\t\t\t\tspecifier: string\n\t\t\t\tnames: readonly string[]\n\t\t  }\n\t>\n\n\texport type DependenciesResponse = ServiceValue<{\n\t\tassets: readonly string[]\n\t\timports: readonly ModulesAPI.ImportDependency[]\n\t\townerType: string\n\t\townerId: string\n\t}>\n\n\texport type ListRequest = ServiceValue<{\n\t\t/** The module types to get (\"codeFile\", \"canvas\", etc). Leave empty/undefined for all types. */\n\t\ttypes?: readonly string[]\n\t}>\n\n\texport type ListNamespacesResponse = ServiceValue<{\n\t\tdata: readonly ModulesAPI.Namespace[]\n\t}>\n\n\texport type Namespace = ServiceValue<{\n\t\tnamespaceId: string\n\t\townerId: string\n\t\townerType: string\n\t\tname: string\n\t}>\n\n\texport type KitsResponse = ServiceValue<{\n\t\tdata: readonly ModulesAPI.PublishedModuleWithSave[]\n\t}>\n\n\texport type ListPublishedModulesRequest = ServiceValue<{\n\t\t/** The namespace to get published modules for. Can be either the name or the id of the namespace. */\n\t\tnamespace: string\n\t}>\n\n\texport type PublishedModuleWithSave = ServiceValue<{\n\t\tnamespaceId: string\n\t\t/** The namespace that the module is published under. */\n\t\tnamespace: string\n\t\t/** The name that the module is published under. */\n\t\tname: string\n\t\tversion: string\n\t\tuserId: string\n\t\tvisibility: string\n\t\ttimestamp: string\n\t\timportURL: string\n\t\tmodule: ModulesAPI.ModuleWithSave\n\t}>\n\n\texport type ListPublishedModulesResponse = ServiceValue<{\n\t\tdata: readonly ModulesAPI.PublishedModuleWithSave[]\n\t}>\n\n\texport type LookupQuery = ServiceValue<{\n\t\turl?: string\n\t\tmoduleId?: string\n\t\tsaveId?: string\n\t\tnamespace?: string\n\t\tname?: string\n\t\tslug?: string\n\t}>\n\n\texport type LookupRequest = ServiceValue<{\n\t\tqueries: readonly ModulesAPI.LookupQuery[]\n\t\tincludeDependencies?: boolean\n\t\tincludeStatus?: boolean\n\t}>\n\n\texport type DependenciesInfo = ServiceValue<{\n\t\tdependencies?: UnsafeJSON\n\t\timportMap?: UnsafeJSON\n\t\tmoduleId?: string\n\t\tsaveId?: string\n\t}>\n\n\texport type LookupResponse = ServiceValue<{\n\t\tdata: readonly ModulesAPI.ModuleWithSave[]\n\t\t/**\n\t\t * A map of owner type -> owner id -> import map. It's structured this\n\t\t * way so that looking up multiple modules under the same owner doesn't\n\t\t * repeat the import map multiple times.\n\t\t */\n\t\tdependencies?: { readonly [_: string]: { readonly [_: string]: ModulesAPI.DependenciesInfo } }\n\t}>\n\n\texport type SaveRequest = ServiceValue<{\n\t\tmoduleId: string\n\t\t/** A unique 20-character base62 string for identifying this save. */\n\t\tsaveId: string\n\t\t/** Type of the module (should always be the same). */\n\t\ttype: string\n\t\t/** The name of the module (should be unique among modules of the same type). */\n\t\tname: string\n\t\t/** The files to upload. Must be at least \"source\" and \"module\". */\n\t\tfiles: readonly ModulesAPI.FileUpload[]\n\t\t/** Arbitrary metadata that should be associated with the module. */\n\t\tmetadata?: UnsafeJSON\n\t\t/** Set to gzip and compress the content in FileUpload for more efficient uploads. */\n\t\ttransferEncoding?: string\n\t\t/** The asset keys that are used inside this module. */\n\t\tassets?: readonly string[]\n\t\t/** The dependencies imported by this module. */\n\t\timports: ModulesAPI.Imports\n\t\t/** The names exported by this module. */\n\t\texports: readonly string[]\n\t\t/** The modules that were re-exported by this module (export * from \"\u2026\"). */\n\t\treExportedModules: readonly string[]\n\t}>\n\n\texport type BatchSave = ServiceValue<{\n\t\t/** Can also be \"$new\" (to create a new module) or \"$upsertName\" (to create/update module with matching name). */\n\t\tmoduleId: string\n\t\t/** A unique 20-character base62 string for identifying this save. */\n\t\tsaveId: string\n\t\t/** Type of the module (should always be the same). */\n\t\ttype: string\n\t\t/** The name of the module (should be unique among modules of the same type). */\n\t\tname: string\n\t\t/** The files to upload. Must be at least \"source\" and \"module\". */\n\t\tfiles: readonly ModulesAPI.FileUpload[]\n\t\t/** Arbitrary metadata that should be associated with the module. */\n\t\tmetadata?: UnsafeJSON\n\t\t/** Label for the module to show in the UI (e.g., \"Toggle\"). */\n\t\ttitle?: string | null\n\t\t/** A short description for the module (optional). */\n\t\tdescription?: string | null\n\t\t/** Set to a save id to pull in all files and metadata from so they don't have to be uploaded again. */\n\t\tpatchSaveId?: string\n\t\t/** Set to gzip and compress the content in FileUpload for more efficient uploads. */\n\t\ttransferEncoding?: string\n\t\t/** The asset keys that are used inside this module. */\n\t\tassets?: readonly string[]\n\t\t/** The dependencies imported by this module. */\n\t\timports?: ModulesAPI.Imports\n\t\t/** The names exported by this module. */\n\t\texports?: readonly string[]\n\t\t/** The modules that were re-exported by this module (export * from \"\u2026\"). */\n\t\treExportedModules?: readonly string[]\n\t\t/** Whether the save is \"detached\", i.e., should not update the module's \"HEAD\" AKA last save ID. */\n\t\tdetached: boolean\n\t}>\n\n\texport type SaveBatchRequest = ServiceValue<{\n\t\tbatch: readonly ModulesAPI.BatchSave[]\n\t\tcopyOnWrite?: boolean\n\t}>\n\n\texport type Publish = ServiceValue<{\n\t\tnamespaceId: string\n\t\tname: string\n\t\tvisibility: string\n\t\tversion: string\n\t\tuserId: string\n\t\ttimestamp: string\n\t\tmoduleId: string\n\t\tsaveId: string\n\t\timportURL: string\n\t}>\n\n\texport type PublishRequest = ServiceValue<{\n\t\t/** The namespace to publish to. Can be either the name or the id of the namespace. */\n\t\tnamespace: string\n\t\t/** The name under the namespace to publish to. */\n\t\tname: string\n\t\tmoduleId: string\n\t\tsaveId: string\n\t\t/** A version in the 1.2.3 format. Must be higher than the last publish. */\n\t\tversion: string\n\t}>\n\n\texport type UpdateRequest = ServiceValue<{\n\t\tmoduleId: string\n\t\tname?: string\n\t\ttitle?: string | null\n\t\tdescription?: string | null\n\t}>\n\n\texport type CreateNamespaceRequest = ServiceValue<{\n\t\townerId: string\n\t\townerType: string\n\t}>\n\n\texport type EnqueueKitScreenshotsRequest = ServiceValue<{\n\t\tmoduleId: string\n\t\tsaveId?: string\n\t\tids: readonly string[]\n\t\tkitPageContent: string\n\t}>\n}\n", "/*\n ****\n ******\n ******\n ******\n ****** \u267B\uFE0F Runtime helper generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n ****** See '../' for service types.\n ******\n ******\n ******\n ****\n */\n\n// The generated service helper may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport {\n\tService,\n\tServiceManager,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../../runtime/index.ts\"\n\nimport type { UserNotifications } from \"../UserNotifications.ts\"\n\nconst { onewayMethodTemplate, voidMethodTemplate, valueMethodTemplate, streamMethodTemplate } = ServiceRuntimePrivate\n\nexport namespace UserNotificationsHelper {\n\ttype Interface = UserNotifications.Interface\n\n\texport const service: Service<Interface> = {\n\t\tid: \"__UserNotifications__\",\n\t\tfingerprint: \"b12f5fbc25df3b0f5372f8576a9abf8c\",\n\t\tmethods: {\n\t\t\trequestPermission: {},\n\t\t\tgetPermissionStatus: {},\n\t\t\tpost: {},\n\t\t\tcancel: {},\n\t\t},\n\t\tnewOutgoingWrapper: (helper: ServiceMessageHelper): Interface => {\n\t\t\treturn {\n\t\t\t\trequestPermission: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"requestPermission\",\n\t\t\t\t\t/* accepts argument: */ false,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tgetPermissionStatus: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"getPermissionStatus\",\n\t\t\t\t\t/* accepts argument: */ false,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tpost: valueMethodTemplate.bind(/* this: */ -1, \"post\", /* accepts argument: */ true, helper),\n\t\t\t\tcancel: voidMethodTemplate.bind(/* this: */ -1, \"cancel\", /* accepts argument: */ true, helper),\n\t\t\t} as Interface\n\t\t},\n\t}\n}\n", "/*\n **********\n *********\n ********\n *******\n ****** \u267B\uFE0F Generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n *****\n ****\n ***\n **\n */\n\n// The generated namespace may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport type {\n\tService,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../runtime/index.ts\"\nimport { ServiceManager } from \"../../runtime/index.ts\"\n\n// The generated namespace may or may not use some of the global types. For simplicity, we import all of them.\nimport type {\n\tPoint,\n\tSize,\n\tRect,\n\tUser,\n\tColor,\n\tMenuAction,\n\tMenuValidationResult,\n\tMenuDispatchResult,\n\tMenuActionState,\n\tArea,\n\tContextMenu,\n\tMenuOptionIconCrossOrigin,\n\tMenuOptionIcon,\n\tMenuItemOptions,\n\tContextMenuResult,\n} from \"./Global.ts\"\n\n// Import the service implementation\nimport { UserNotificationsHelper } from \"./service-runtime/UserNotificationsHelper.ts\"\n\nimport type { SharedService } from \"./SharedService.ts\"\n\nexport namespace UserNotifications {\n\t/**\n\t * Shows system notifications to the user\n\t */\n\texport interface Interface {\n\t\trequestPermission(): Promise<UserNotifications.RequestPermissionResponse>\n\t\tgetPermissionStatus(): Promise<UserNotifications.GetPermissionStatusResponse>\n\t\tpost(_: UserNotifications.PostRequest): Promise<UserNotifications.PostResponse>\n\t\tcancel(_: UserNotifications.CancelRequest): Promise<void>\n\t}\n\n\t/*\n\t * Using the service\n\t */\n\n\texport const service: Service<Interface> = UserNotificationsHelper.service\n\n\texport function on(channel: ServiceChannel): SharedService<Interface> {\n\t\t// Note: capture the shared service manager here so testing behavior is predictable\n\t\tconst sharedServices = ServiceManager.shared()\n\t\treturn {\n\t\t\texpect: () => sharedServices.expectWithoutDiscovery(service, channel),\n\t\t\tdiscover: options => sharedServices.discover(service, channel, options),\n\t\t\tregister: implementation => sharedServices.register({ channel, service, implementation }),\n\t\t}\n\t}\n\n\texport async function unregister(implementation: Interface): Promise<void> {\n\t\tvoid ServiceManager.shared().unregister(implementation)\n\t}\n\n\t/*\n\t * Types\n\t */\n\n\texport type PermissionStatus = ServiceValue<\"granted\" | \"denied\" | \"notDetermined\">\n\n\texport type RequestPermissionResponse = ServiceValue<{\n\t\tstatus: UserNotifications.PermissionStatus\n\t}>\n\n\texport type GetPermissionStatusResponse = ServiceValue<{\n\t\tstatus: UserNotifications.PermissionStatus\n\t}>\n\n\texport type NotificationShow = ServiceValue<\"always\" | \"backgrounded\">\n\n\texport type Notification = ServiceValue<{\n\t\t/**\n\t\t * Notification ID\n\t\t *\n\t\t * You can use it to cancel the notification, and to replace previous\n\t\t * notification with the same ID.\n\t\t */\n\t\tid: string\n\t\ttitle: string\n\t\tbody?: string\n\t\t/**\n\t\t * Sometimes, it makes sense to only show a notification if the app\n\t\t * is in the background \u2014 most commonly, when there's a dedicated piece\n\t\t * of UI directly in the app that serves similar purpose as the\n\t\t * notification, e.g., unread comments badge.\n\t\t */\n\t\tshow: \"always\" | \"backgrounded\"\n\t}>\n\n\texport type PostRequest = ServiceValue<{\n\t\tnotification: UserNotifications.Notification\n\t}>\n\n\texport type PostResponse = ServiceValue<\n\t\t| {\n\t\t\t\ttype: \"action\"\n\t\t  }\n\t\t| {\n\t\t\t\ttype: \"cancel\"\n\t\t\t\t/**\n\t\t\t\t * Reason for the notification getting canceled\n\t\t\t\t *\n\t\t\t\t * Possible values are:\n\t\t\t\t * - dismissed   - dismissed by user or programmatically via `cancel`\n\t\t\t\t * - unsupported - notification API is not available\n\t\t\t\t * - suppressed  - suppressed due to notification's \"show\" condition\n\t\t\t\t */\n\t\t\t\treason: string\n\t\t  }\n\t>\n\n\texport type CancelRequest = ServiceValue<{\n\t\tnotificationId: string\n\t}>\n}\n", "/*\n ****\n ******\n ******\n ******\n ****** \u267B\uFE0F Runtime helper generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n ****** See '../' for service types.\n ******\n ******\n ******\n ****\n */\n\n// The generated service helper may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport {\n\tService,\n\tServiceManager,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../../runtime/index.ts\"\n\nimport type { UserSessionService } from \"../UserSessionService.ts\"\n\nconst { onewayMethodTemplate, voidMethodTemplate, valueMethodTemplate, streamMethodTemplate } = ServiceRuntimePrivate\n\nexport namespace UserSessionServiceHelper {\n\ttype Interface = UserSessionService.Interface\n\n\texport const service: Service<Interface> = {\n\t\tid: \"__UserSessionService__\",\n\t\tfingerprint: \"5d23eb6d242eea4124ad7a5cf695616d\",\n\t\tmethods: {\n\t\t\tgetSessionIdentity: {},\n\t\t\tpermissionsStream: {},\n\t\t},\n\t\tnewOutgoingWrapper: (helper: ServiceMessageHelper): Interface => {\n\t\t\treturn {\n\t\t\t\tgetSessionIdentity: valueMethodTemplate.bind(\n\t\t\t\t\t/* this: */ -1,\n\t\t\t\t\t\"getSessionIdentity\",\n\t\t\t\t\t/* accepts argument: */ false,\n\t\t\t\t\thelper,\n\t\t\t\t),\n\t\t\t\tpermissionsStream: streamMethodTemplate.bind(/* this: */ -1, \"permissionsStream\", helper),\n\t\t\t} as Interface\n\t\t},\n\t}\n}\n", "/*\n **********\n *********\n ********\n *******\n ****** \u267B\uFE0F Generated by the Services build process from .d.ts. Do not modify. See the Services README for more information.\n *****\n ****\n ***\n **\n */\n\n// The generated namespace may or may not use some of the runtime exports. For simplicity, we import all of them.\nimport type {\n\tService,\n\tServiceChannel,\n\tServiceMessageHelper,\n\tServiceRuntimePrivate,\n\tServiceValue,\n\tServiceStream,\n\tServiceStreamOptions,\n\tUnsafeJSON,\n\tfloat,\n\tinteger,\n\toneway,\n} from \"../../runtime/index.ts\"\nimport { ServiceManager } from \"../../runtime/index.ts\"\n\n// The generated namespace may or may not use some of the global types. For simplicity, we import all of them.\nimport type {\n\tPoint,\n\tSize,\n\tRect,\n\tUser,\n\tColor,\n\tMenuAction,\n\tMenuValidationResult,\n\tMenuDispatchResult,\n\tMenuActionState,\n\tArea,\n\tContextMenu,\n\tMenuOptionIconCrossOrigin,\n\tMenuOptionIcon,\n\tMenuItemOptions,\n\tContextMenuResult,\n} from \"./Global.ts\"\n\n// Import the service implementation\nimport { UserSessionServiceHelper } from \"./service-runtime/UserSessionServiceHelper.ts\"\n\nimport type { SharedService } from \"./SharedService.ts\"\n\nexport namespace UserSessionService {\n\t/**\n\t * UserSessionService is not documented.\n\t */\n\texport interface Interface {\n\t\tgetSessionIdentity(): Promise<UserSessionService.SessionIdentityResponse>\n\t\tpermissionsStream(_?: ServiceStreamOptions): ServiceStream<UserSessionService.PermissionsResponse>\n\t}\n\n\t/*\n\t * Using the service\n\t */\n\n\texport const service: Service<Interface> = UserSessionServiceHelper.service\n\n\texport function on(channel: ServiceChannel): SharedService<Interface> {\n\t\t// Note: capture the shared service manager here so testing behavior is predictable\n\t\tconst sharedServices = ServiceManager.shared()\n\t\treturn {\n\t\t\texpect: () => sharedServices.expectWithoutDiscovery(service, channel),\n\t\t\tdiscover: options => sharedServices.discover(service, channel, options),\n\t\t\tregister: implementation => sharedServices.register({ channel, service, implementation }),\n\t\t}\n\t}\n\n\texport async function unregister(implementation: Interface): Promise<void> {\n\t\tvoid ServiceManager.shared().unregister(implementation)\n\t}\n\n\t/*\n\t * Types\n\t */\n\n\texport type SessionIdentityResponse = ServiceValue<{\n\t\tuser: User\n\t}>\n\n\texport type PermissionsResponse = ServiceValue<{\n\t\tisViewOnly: boolean\n\t}>\n}\n", "import { triggerEvent } from \"../listeners\";\nfunction createCanvasPanEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerCanvasPanEvent instead of createCanvasPanEvent.\");\n  return {\n    ...payload,\n    event: \"canvas_pan\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerCanvasPanEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"canvas_pan\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createCanvasPanEvent,\n  triggerCanvasPanEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createCanvasZoomEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerCanvasZoomEvent instead of createCanvasZoomEvent.\");\n  return {\n    ...payload,\n    event: \"canvas_zoom\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerCanvasZoomEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"canvas_zoom\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createCanvasZoomEvent,\n  triggerCanvasZoomEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createDocumentLoadEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerDocumentLoadEvent instead of createDocumentLoadEvent.\");\n  return {\n    ...payload,\n    event: \"document_load\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerDocumentLoadEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"document_load\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createDocumentLoadEvent,\n  triggerDocumentLoadEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createDrawingShapeCreateEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerDrawingShapeCreateEvent instead of createDrawingShapeCreateEvent.\");\n  return {\n    ...payload,\n    event: \"drawing_shape_create\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerDrawingShapeCreateEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"drawing_shape_create\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createDrawingShapeCreateEvent,\n  triggerDrawingShapeCreateEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createDrawingShapeEditEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerDrawingShapeEditEvent instead of createDrawingShapeEditEvent.\");\n  return {\n    ...payload,\n    event: \"drawing_shape_edit\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerDrawingShapeEditEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"drawing_shape_edit\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createDrawingShapeEditEvent,\n  triggerDrawingShapeEditEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createErrorToastEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerErrorToastEvent instead of createErrorToastEvent.\");\n  return {\n    ...payload,\n    event: \"error_toast\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerErrorToastEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"error_toast\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createErrorToastEvent,\n  triggerErrorToastEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createInteractiveLinkCreateEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerInteractiveLinkCreateEvent instead of createInteractiveLinkCreateEvent.\");\n  return {\n    ...payload,\n    event: \"interactive_link_create\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerInteractiveLinkCreateEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"interactive_link_create\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createInteractiveLinkCreateEvent,\n  triggerInteractiveLinkCreateEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createInteractivePageConnectEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerInteractivePageConnectEvent instead of createInteractivePageConnectEvent.\");\n  return {\n    ...payload,\n    event: \"interactive_page_connect\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerInteractivePageConnectEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"interactive_page_connect\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createInteractivePageConnectEvent,\n  triggerInteractivePageConnectEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createInteractiveScrollConnectEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerInteractiveScrollConnectEvent instead of createInteractiveScrollConnectEvent.\");\n  return {\n    ...payload,\n    event: \"interactive_scroll_connect\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerInteractiveScrollConnectEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"interactive_scroll_connect\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createInteractiveScrollConnectEvent,\n  triggerInteractiveScrollConnectEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createLayoutFrameHierarchyEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerLayoutFrameHierarchyEvent instead of createLayoutFrameHierarchyEvent.\");\n  return {\n    ...payload,\n    event: \"layout_frame_hierarchy\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerLayoutFrameHierarchyEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"layout_frame_hierarchy\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createLayoutFrameHierarchyEvent,\n  triggerLayoutFrameHierarchyEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createRulersCreateGuideEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerRulersCreateGuideEvent instead of createRulersCreateGuideEvent.\");\n  return {\n    ...payload,\n    event: \"rulers_create_guide\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerRulersCreateGuideEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"rulers_create_guide\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createRulersCreateGuideEvent,\n  triggerRulersCreateGuideEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createRulersDeleteGuideEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerRulersDeleteGuideEvent instead of createRulersDeleteGuideEvent.\");\n  return {\n    ...payload,\n    event: \"rulers_delete_guide\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerRulersDeleteGuideEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"rulers_delete_guide\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createRulersDeleteGuideEvent,\n  triggerRulersDeleteGuideEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createRulersMoveGuideEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerRulersMoveGuideEvent instead of createRulersMoveGuideEvent.\");\n  return {\n    ...payload,\n    event: \"rulers_move_guide\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerRulersMoveGuideEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"rulers_move_guide\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createRulersMoveGuideEvent,\n  triggerRulersMoveGuideEvent\n};\n", "import { triggerEvent } from \"../listeners\";\nfunction createTextCreateEvent(payload) {\n  console.warn(\"[DEPRECATED] Use triggerTextCreateEvent instead of createTextCreateEvent.\");\n  return {\n    ...payload,\n    event: \"text_create\"\n  };\n}\nconst meta = {\n  track: true\n};\nfunction triggerTextCreateEvent(payload) {\n  const event = {\n    ...payload,\n    event: \"text_create\"\n  };\n  triggerEvent(event, meta);\n}\nexport {\n  createTextCreateEvent,\n  triggerTextCreateEvent\n};\n", "export const DocumentLoaded = \"DocumentLoaded\"\nexport const ProjectTitleUpdate = \"ProjectTitleUpdate\"\n", "import { getAppStartTime } from \"@framerjs/app-shared\"\nimport type { DocumentLoadLoadingType } from \"@framerjs/framer-events\"\nimport { triggerDocumentLoadEvent } from \"@framerjs/framer-events\"\nimport { record } from \"web/lib/tracker.ts\"\ninterface TrackParameters {\n\treadonly startLoadingTime: number\n\treadonly treeSize: number\n}\n\ninterface DocumentLoadEvent extends TrackParameters {\n\treadonly timestamp: number\n\treadonly loadingType: DocumentLoadLoadingType\n}\n\nconst DocumentLoadTimeout = 20_000\n\n/**\n * Send two different kinds of Document load events.\n * 1. Partial | Normal document loading. It also bundles the Canvas load time.\n * 2. Remaining document\n */\nclass LoadDocumentMetrics {\n\t#canvasLoadTime: number = 0\n\t#firstLoadEvent?: DocumentLoadEvent\n\t#secondLoadEvent?: DocumentLoadEvent\n\t#didSendFirstLoadEvent = false\n\n\ttrackDocumentTimeout = setTimeout(() => {\n\t\tconst documentLoad = !this.#didSendFirstLoadEvent ? this.#firstLoadEvent : this.#secondLoadEvent\n\t\tconst appLoadTime = !documentLoad ? undefined : documentLoad.startLoadingTime - getAppStartTime()\n\n\t\trecord(\"document_load_timeout\", {\n\t\t\tappLoadTime,\n\t\t\tcanvasLoadTime: this.#canvasLoadTime,\n\t\t\tdidSendFirstLoadEvent: this.#didSendFirstLoadEvent,\n\t\t\tloadType: documentLoad?.loadingType,\n\t\t})\n\t}, DocumentLoadTimeout)\n\n\ttrackCanvasLoad(canvasLoadTime: number) {\n\t\tif (this.#canvasLoadTime) return\n\t\tthis.#canvasLoadTime = canvasLoadTime\n\t\tthis.#maybeSendEvent()\n\t}\n\n\ttrackNormalLoad({ startLoadingTime, treeSize }: TrackParameters) {\n\t\tif (this.#firstLoadEvent) return\n\t\tthis.#firstLoadEvent = { loadingType: \"normal\", startLoadingTime, timestamp: Date.now(), treeSize }\n\t\tthis.#maybeSendEvent()\n\t}\n\n\ttrackPartialLoad({ startLoadingTime, treeSize }: TrackParameters) {\n\t\tif (this.#firstLoadEvent) return\n\t\tthis.#firstLoadEvent = { loadingType: \"partial\", startLoadingTime, timestamp: Date.now(), treeSize }\n\t\tthis.#maybeSendEvent()\n\t}\n\n\ttrackRemainingLoad({ startLoadingTime, treeSize }: TrackParameters) {\n\t\tif (this.#secondLoadEvent) return\n\t\tthis.#secondLoadEvent = { loadingType: \"remaining\", startLoadingTime, timestamp: Date.now(), treeSize }\n\t\tthis.#maybeSendEvent()\n\t}\n\n\t#maybeSendEvent() {\n\t\tif (!this.#canvasLoadTime) return\n\t\tconst appStartTime = getAppStartTime()\n\t\tif (!appStartTime) return\n\n\t\tconst documentLoad = !this.#didSendFirstLoadEvent ? this.#firstLoadEvent : this.#secondLoadEvent\n\t\tif (!documentLoad) return\n\n\t\tthis.#didSendFirstLoadEvent = true\n\t\tconst appLoadTime = documentLoad.startLoadingTime - appStartTime\n\n\t\tclearTimeout(this.trackDocumentTimeout)\n\n\t\ttriggerDocumentLoadEvent({\n\t\t\tappLoadTime,\n\t\t\tcanvasLoadTime: this.#canvasLoadTime,\n\t\t\tdocumentLoadTime: documentLoad.timestamp - appStartTime,\n\t\t\ttreeSize: documentLoad.treeSize,\n\t\t\tloadingType: documentLoad.loadingType,\n\t\t})\n\t}\n}\n\nexport const loadDocumentMetrics = new LoadDocumentMetrics()\n", "import { getLogger } from \"@framerjs/shared\"\n\nexport const logScheduler = getLogger(\"scheduler\")\nexport const engineLog = getLogger(\"app\")\nexport const logTracking = getLogger(\"event-tracking\")\n", "import archy from \"archy\"\nimport type { CanvasTree } from \"document/models/CanvasTree/CanvasTree.ts\"\nimport type { ImmutableNode } from \"document/models/CanvasTree/nodes/MutableNode.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { CanvasNode } from \"../nodes/CanvasNode.ts\"\nimport { isTextNode } from \"../nodes/utils/nodeCheck.ts\"\nimport { isMaster } from \"../traits/WithTemplate.ts\"\n\nfunction labelForNode(node: ImmutableNode, filterIds: NodeID[], filterKeys: string[]): string {\n\tif (filterIds.length > 0 && !filterIds.includes(node.id)) {\n\t\treturn node.__class\n\t}\n\tlet mark = \" \"\n\tlet link = \"\"\n\tif (node.replicaInfo) {\n\t\tmark = \"!\"\n\t\tlink = \" master=\" + node.replicaInfo.master\n\t} else if (node instanceof CanvasNode && isMaster(node)) {\n\t\tmark = \"@\"\n\t} else if (node.originalid) {\n\t\tmark = \".\"\n\t}\n\tlet name = \"\"\n\tif (node instanceof CanvasNode && node.name) {\n\t\tname = \" '\" + node.name + \"'\"\n\t}\n\tlet text = \"\"\n\tif (node instanceof CanvasNode && isTextNode(node)) {\n\t\ttext = node.styledText.text\n\t\tif (text.length > 20) {\n\t\t\ttext = text.slice(0, 17) + \"...\"\n\t\t}\n\t\ttext = \" '\" + text + \"'\"\n\t}\n\n\tlet label = `${node.__class}${mark}(${node.id}${name}${link})${text}`\n\tfor (const key in node) {\n\t\tif (key === \"children\" || key === \"id\") {\n\t\t\tcontinue\n\t\t}\n\t\tif (!filterKeys.includes(key)) {\n\t\t\tcontinue\n\t\t}\n\t\tconst value = node[key]\n\t\tlabel += `\\n ${key}: ${value}`\n\t}\n\treturn label\n}\n\nfunction dataForNode(node: ImmutableNode, filterIds: NodeID[], keys: string[]): archy.Data | null {\n\tconst children = node.children || []\n\tconst isFiltered = filterIds.length > 0 && !filterIds.includes(node.id)\n\tconst nodes = children.map(c => dataForNode(c, isFiltered ? filterIds : [], keys)).filter(n => n !== null)\n\tif (isFiltered && nodes.length === 0) {\n\t\treturn null\n\t}\n\treturn {\n\t\tlabel: labelForNode(node, filterIds, keys),\n\t\tnodes: nodes,\n\t}\n}\nexport function inspect(tree: CanvasTree, filterIds: NodeID[] | string = [], keys: string[] = []): string {\n\tif (typeof filterIds === \"string\") {\n\t\tfilterIds = [filterIds]\n\t}\n\tif (typeof keys === \"string\") {\n\t\tkeys = [keys]\n\t}\n\tconst data = dataForNode(tree.root, filterIds, keys)\n\tif (!data) {\n\t\treturn \"No data\"\n\t}\n\treturn archy(data)\n}\n", "import type { Point } from \"library/render/types/Point.ts\"\n\nexport function mouseDidMove(mouseA: Point | null, mouseB: Point | null) {\n\tif (mouseA && mouseB) {\n\t\tconst { x, y } = mouseA\n\t\tconst x2 = mouseB.x\n\t\tconst y2 = mouseB.y\n\t\treturn x2 !== x || y2 !== y\n\t}\n\treturn mouseA !== mouseB\n}\n", "import { translateXYToPoint } from \"canvas-sandbox/layout-measuring/projection.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport {\n\tCanvasNode,\n\ttype CanvasNodeConstructor,\n\ttype CanvasTree,\n\ttype MaybeNodeID,\n\ttype NodeID,\n} from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode, NullID } from \"document/models/CanvasTree/index.ts\"\nimport type { MaybeCanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { insertNodeAccountingForReplicas } from \"document/models/CanvasTree/nodes/utils/insertNodeAccountingForReplicas.ts\"\nimport { isStackOrGridComponent } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { Matrix } from \"document/models/Matrix.ts\"\nimport { snappingThreshold } from \"document/models/Snapping.ts\"\nimport type { InputState } from \"document/stores/MouseStore.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { withShape } from \"library/index.ts\"\nimport type { WithPaths } from \"library/render/traits/Path.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type React from \"react\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\nimport { isSkewedQuadrilateralPoints } from \"../utils/isSkewedQuadrilateralPoints.ts\"\nimport type { CreateTool, UpdatesFinishedCallback } from \"./Create.tsx\"\nimport { SnapTool } from \"./utils/SnapTool.ts\"\nimport { getStackOrGridInsertionIndexAndLine } from \"./utils/stackInsertionHelpers.ts\"\n\nexport interface OverlayComponentProps {\n\tpoints: Point[]\n}\n\nexport class CreateToolHelper {\n\t// FIXME: !s are unsafe; they are assigned in `.update()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tsnappedMouseDown!: Point\n\tsnappedMouse!: Point\n\tparentHighlight?: NodeID // Better as state?\n\tspacebarOffset: Point | null = null\n\n\t// configurable\n\tdragStart?: () => void\n\toverlayShape?: (width: number, height: number) => WithPaths\n\toverlayComponent?: React.ComponentType<OverlayComponentProps>\n\t/** Should be set to the class of the node that the consuming tool is creating, otherwise nodes might be created inside invalid parents */\n\tnodeClass: CanvasNodeConstructor<CanvasNode> = CanvasNode\n\tshowTooltip: boolean = true\n\tshowFrame: boolean = true\n\thighlightParent?: boolean\n\tpoints!: Point[]\n\n\t// Lifecycle\n\n\tstart(tool: CreateTool) {\n\t\tconst engine = tool.engine\n\t\ttool.snapper = new SnapTool(engine, [])\n\t\tengine.stores.treeStore.setHighlight(null)\n\t}\n\n\tstop(tool: CreateTool) {\n\t\tconst engine = tool.engine\n\t\tengine.stores.toolStore.tooltip = undefined\n\t\ttool.snapper.stop()\n\t}\n\n\tstateDidChange = (previous: InputState, nextProps: InputState) => {\n\t\tconst mouseDownChange =\n\t\t\t(!previous.canvasMouseDownPosition && nextProps.canvasMouseDownPosition) ||\n\t\t\t(previous.canvasMouseDownPosition && !nextProps.canvasMouseDownPosition)\n\t\tconst mouseChange = mouseDidMove(nextProps.canvasMousePosition, previous.canvasMousePosition)\n\n\t\tconst spacebarChange = previous.spacebar !== nextProps.spacebar\n\t\tconst modifierDidChange =\n\t\t\tprevious.altKey !== nextProps.altKey ||\n\t\t\tprevious.shiftKey !== nextProps.shiftKey ||\n\t\t\tprevious.cmdKey !== nextProps.cmdKey\n\t\treturn mouseDownChange || mouseChange || spacebarChange || modifierDidChange\n\t}\n\n\tupdate(tool: CreateTool) {\n\t\tconst engine = tool.engine\n\t\tconst { canvasStore, treeStore, scopeStore, selectionStore, persistedUserDefaults, toolStore, mouseStore } =\n\t\t\tengine.stores\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, altKey, shiftKey, cmdKey, spacebar } = mouseStore.latest\n\n\t\tconst previous = mouseStore.previous\n\t\tconst change = this.stateDidChange(previous, mouseStore.latest)\n\t\tif (!change || !canvasMousePosition) {\n\t\t\treturn\n\t\t}\n\n\t\tconst frameNode =\n\t\t\tscopeStore.active.getGroundNodesOfType(FrameNode, node => {\n\t\t\t\treturn Rect.pointDistance(node.rect(null), canvasMousePosition) < snappingThreshold(canvasStore.zoom)\n\t\t\t})[0] || null\n\n\t\t// Temporarily disable snapping for skewed nodes. In the future we will\n\t\t// bring this back with support for drawing lines and snapping the correct\n\t\t// lines for transformed shapes.\n\t\tconst snappingEnabled = !cmdKey && (this.points ? !isSkewedQuadrilateralPoints(this.points) : true)\n\t\tconst frameIds: MaybeNodeID[] = [frameNode ? frameNode.id : NullID]\n\n\t\tthis.snappedMouse = canvasMousePosition\n\t\tif (!spacebar) {\n\t\t\tthis.snappedMouse = tool.snapper.snap(\n\t\t\t\tcanvasMousePosition,\n\t\t\t\tsnappingEnabled,\n\t\t\t\tframeIds,\n\t\t\t\tundefined,\n\t\t\t\tundefined,\n\t\t\t\tthis.snappedMouseDown,\n\t\t\t)\n\t\t}\n\n\t\tif (!previous.canvasMouseDownPosition && canvasMouseDownPosition) {\n\t\t\tif (this.dragStart !== undefined) {\n\t\t\t\tthis.dragStart()\n\t\t\t}\n\t\t\tthis.snappedMouseDown = this.snappedMouse\n\t\t}\n\n\t\tif (!this.snappedMouseDown) {\n\t\t\tif (this.highlightParent) {\n\t\t\t\tthis.parentHighlight = getPotentialParent(\n\t\t\t\t\ttool.engine,\n\t\t\t\t\tcanvasMousePosition,\n\t\t\t\t\tcanvasMousePosition,\n\t\t\t\t\tthis.nodeClass,\n\t\t\t\t)?.id\n\t\t\t}\n\t\t\treturn\n\t\t} // else\n\n\t\tif (spacebar && this.spacebarOffset) {\n\t\t\tconst point = Point.subtract(canvasMousePosition, this.spacebarOffset)\n\t\t\tthis.snappedMouseDown = tool.snapper.snap(point, snappingEnabled, frameIds, undefined, undefined)\n\t\t\tthis.snappedMouse = canvasMousePosition\n\t\t}\n\n\t\tconst halfPixelAligned = tool.enum === Tools.Path\n\t\tconst frame = this.frame(this.snappedMouseDown, this.snappedMouse, shiftKey, altKey && !spacebar, halfPixelAligned)\n\t\tconst parent = getPotentialParent(tool.engine, this.snappedMouseDown, this.snappedMouse, this.nodeClass)\n\t\tconst parentId = parent?.id ?? null\n\t\tconst { rectInParent, indexInParent, points } = this.getRectInParent(\n\t\t\ttool,\n\t\t\ttreeStore.tree,\n\t\t\tparent,\n\t\t\tthis.snappedMouseDown,\n\t\t\tthis.snappedMouse,\n\t\t\tcanvasStore.zoom,\n\t\t\t(anchorPoint, controlPoint) =>\n\t\t\t\tthis.frame(anchorPoint, controlPoint, shiftKey, altKey && !spacebar, halfPixelAligned),\n\t\t)\n\n\t\tthis.points = points\n\n\t\tconst spacebarChangedToDown = spacebar && !previous.spacebar\n\t\tif (spacebarChangedToDown) {\n\t\t\tthis.spacebarOffset = Point.subtract(this.snappedMouse, this.snappedMouseDown)\n\t\t}\n\t\tif (!spacebar) {\n\t\t\tthis.spacebarOffset = null\n\t\t}\n\n\t\tif (canvasMouseDownPosition) {\n\t\t\tif (this.showTooltip !== false) {\n\t\t\t\t// Tooltip shows frame in canvas width / height\n\t\t\t\ttoolStore.tooltip = `${frame.width} \u00D7 ${frame.height}`\n\t\t\t}\n\n\t\t\tif (this.highlightParent && parentId) {\n\t\t\t\tthis.parentHighlight = parentId\n\t\t\t} else {\n\t\t\t\tthis.parentHighlight = undefined\n\t\t\t}\n\t\t} else {\n\t\t\t// mouse is up\n\t\t\tconst newId = randomID()\n\t\t\tconst properties: any = { id: newId }\n\n\t\t\tproperties.aspectRatio = shiftKey ? rectInParent.width / rectInParent.height : null\n\n\t\t\t// position node at origin if there are no other nodes\n\t\t\tconst { displayRulers } = persistedUserDefaults\n\t\t\tconst groundNodes = scopeStore.active.getGroundNodes()\n\t\t\tif (groundNodes.length === 0 && !displayRulers) {\n\t\t\t\tconst delta = Point.reverse(rectInParent)\n\t\t\t\tconst offset = Point.add(canvasStore.offset, delta)\n\t\t\t\tcanvasStore.scrollToTopLeft(offset)\n\n\t\t\t\trectInParent.x = 0\n\t\t\t\trectInParent.y = 0\n\t\t\t}\n\n\t\t\tlet callback: UpdatesFinishedCallback | undefined\n\n\t\t\tconst idToSelect = insertNodeAccountingForReplicas(\n\t\t\t\tengine.tree,\n\t\t\t\tparentId,\n\t\t\t\t(targetParentId, visibilityProps, addingToReplica) => {\n\t\t\t\t\tcallback = tool.create({\n\t\t\t\t\t\tid: newId,\n\t\t\t\t\t\t// Create tools expect parentId to be the initial\n\t\t\t\t\t\t// parent, to allow for differences in behavior when\n\t\t\t\t\t\t// inserting into replicas.\n\t\t\t\t\t\tparentId,\n\t\t\t\t\t\tindexInParent,\n\t\t\t\t\t\trect: rectInParent,\n\t\t\t\t\t\tproperties: { ...properties, ...visibilityProps },\n\t\t\t\t\t\trotation: 0,\n\t\t\t\t\t\toriginalParentId: addingToReplica ? targetParentId : null,\n\t\t\t\t\t})\n\t\t\t\t\treturn newId\n\t\t\t\t},\n\t\t\t)\n\t\t\tselectionStore.set(idToSelect, { switchToLayers: true, switchToProperties: true })\n\n\t\t\tcallback?.()\n\t\t}\n\t}\n\n\t// Helpers\n\n\tframe(\n\t\tanchorPoint: Point,\n\t\tcontrolPoint: Point,\n\t\taspectConstraint: boolean,\n\t\tmirror: boolean,\n\t\thalfPixelAligned: boolean,\n\t) {\n\t\tlet deltaX = Math.round(controlPoint.x - anchorPoint.x)\n\t\tlet deltaY = Math.round(controlPoint.y - anchorPoint.y)\n\t\tif (aspectConstraint) {\n\t\t\tconst shortestSide = Math.min(Math.abs(deltaX), Math.abs(deltaY))\n\t\t\tdeltaX = shortestSide * Math.sign(deltaX)\n\t\t\tdeltaY = shortestSide * Math.sign(deltaY)\n\t\t}\n\t\tlet sizeMultiplier = 1\n\t\tif (mirror) {\n\t\t\tdeltaX = -Math.abs(deltaX)\n\t\t\tdeltaY = -Math.abs(deltaY)\n\t\t\tsizeMultiplier = 2\n\t\t}\n\t\tconst frame = {\n\t\t\tx: Math.min(anchorPoint.x, anchorPoint.x + deltaX),\n\t\t\ty: Math.min(anchorPoint.y, anchorPoint.y + deltaY),\n\t\t\twidth: Math.abs(deltaX * sizeMultiplier),\n\t\t\theight: Math.abs(deltaY * sizeMultiplier),\n\t\t}\n\n\t\t// When editing shapes at high zoom, rounding to a full pixel can give undesired results,\n\t\t// especially when the shape container is aligned to a half pixel.\n\t\treturn halfPixelAligned ? Rect.halfPixelAligned(frame) : Rect.pixelAligned(frame)\n\t}\n\n\tgetRectInParent(\n\t\ttool: CreateTool,\n\t\ttree: CanvasTree,\n\t\tparent: MaybeCanvasNode,\n\t\tmouseEnd: Point,\n\t\tmouseStart: Point,\n\t\tzoom: number,\n\t\tgetFrame: (a: Point, b: Point) => Rect,\n\t): {\n\t\tindexInParent: number\n\t\trectInParent: Rect\n\t\tpoints: Point[]\n\t} {\n\t\t// Determine the points in the potential parent that project to the\n\t\t// mouse start point, and current mouse point. This will be the rect we\n\t\t// use to render the node we create, and will let us define the 4 points\n\t\t// to use to draw a rect in that parent matrix.\n\t\tconst matrix = parent ? tree.transformMatrixToNode(parent) : Matrix.identity()\n\t\tconst anchorPoint = translateXYToPoint(matrix, { x: 0, y: 0 }, mouseEnd)\n\t\tconst controlPoint = translateXYToPoint(matrix, { x: 0, y: 0 }, mouseStart)\n\t\tconst rect = getFrame(anchorPoint, controlPoint)\n\t\tconst points = Matrix.convertPointsWithClipping(matrix, Rect.cornerPoints(rect)).map(p => Point.multiply(p, zoom))\n\n\t\tconst indexInParent = parent ? getStackOrGridIndex(tool.engine, parent, rect) : -1\n\t\treturn { rectInParent: rect, indexInParent, points }\n\t}\n}\n\nfunction getPotentialParent(\n\tengine: VekterEngine,\n\tanchorPoint: Point,\n\tcontrolPoint: Point,\n\tNodeClass: CanvasNodeConstructor<CanvasNode>,\n) {\n\tconst { scopeStore, overlayStore, mouseStore } = engine.stores\n\tconst potentialParents = engine.tree\n\t\t.getPotentialParents(\n\t\t\tscopeStore.active,\n\t\t\toverlayStore.activeOverlays,\n\t\t\t[controlPoint, anchorPoint],\n\t\t\tmouseStore.latest.canvasMousePosition,\n\t\t\tengine.componentLoader,\n\t\t\tnew NodeClass(engine.tree),\n\t\t)\n\t\t// When drawing shapes, don't nest them in other shapes (or boolean nodes).\n\t\t.filter(node => !withShape(node))\n\n\treturn engine.tree.getTopMostChildNode(potentialParents)\n}\n\nfunction getStackOrGridIndex(engine: VekterEngine, parentNode: CanvasNode, canvasRect: Rect): number {\n\t// We only set indexInParent outside or replicas\n\tif (isReplicaOrReplicaChild(parentNode)) {\n\t\treturn -1\n\t}\n\n\tif (!isStackOrGridComponent(parentNode)) {\n\t\treturn -1\n\t}\n\n\tconst { insertionIndex } = getStackOrGridInsertionIndexAndLine(\n\t\tparentNode,\n\t\tengine,\n\t\tRect.center(canvasRect),\n\t\tcanvasRect,\n\t\t{ allowWrapping: false },\n\t)\n\treturn insertionIndex ?? -1\n}\n", "import { assert } from \"@framerjs/shared\"\nimport { Line, Polygon } from \"library/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type React from \"react\"\nimport { useMemo } from \"react\"\nimport { isFunction, isNull } from \"utils/typeChecks.ts\"\nimport { isSkewedQuadrilateralPoints, isStraightRectangle } from \"../utils/isSkewedQuadrilateralPoints.ts\"\nimport { GPULayer } from \"./GPULayer.tsx\"\n\ninterface OverlayLayout {\n\tskewed: boolean\n\trect: Rect\n}\n\ninterface Props {\n\tpoints: Point[]\n\tbackgroundColor?: string\n\tborderWidth: number\n\tborderColor: string\n\t/* When true, draw the outline **around** the rect, instead of in the rect. Defaults to true. */\n\troundToOutside?: boolean\n\tdashed?: boolean\n\toval?: boolean\n\tchildren?: React.ReactNode | ((info: OverlayLayout) => React.ReactNode)\n\topacity?: number\n\tonDoubleClick?: (event: React.MouseEvent<HTMLElement>) => void\n\tonContextMenu?: (event: React.MouseEvent<HTMLElement>) => void\n\tclassName?: string\n\tstyle?: React.CSSProperties\n\ttestId?: string\n\tclippingRect?: Rect\n\t// When the overlay is a rect, you can choose to only render some of the\n\t// edges. The index goes [top, right, bottom, left]. For example, if you\n\t// only want to render the top and right edges, you could pass [true, true,\n\t// false, false].\n\tshowRectEdges?: (points: Point[], skewed: boolean) => [boolean, boolean, boolean, boolean] | undefined\n\t/**\n\t * When true, we will skip large layers completely if we can't render it as GPU lines, for performance reasons.\n\t */\n\tskipLargeLayer?: boolean\n}\n\nfunction useCanvasClippedPolygonPoints(points: Point[], rect: Rect | undefined, clippingEnabled: boolean): Point[] {\n\tconst pointsKey = points.map(p => `${p.x}-${p.y}`).join(\"-\")\n\tconst key = rect ? `${rect.width}-${rect.height}-${rect.x}-${rect.y}-${pointsKey}` : pointsKey\n\n\t// Including rect and points as dependencies will provide no benefit as\n\t// they will never be the same object twice as they are recreated each\n\t// render. To ensure we only clip the polygon when the points or rect\n\t// materially changes, we use a custom key instead. This could be\n\t// JSON.stringify({points, key}) but this is faster.\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: see above\n\treturn useMemo<Point[]>(() => {\n\t\tif (!rect || !clippingEnabled) return points\n\n\t\t// Inflate the canvas rect to be 2x the size of the visible canvas. This\n\t\t// ensures that we have a margin before we start clipping the points so\n\t\t// no one ever sees the clipped points.\n\t\tconst inflatedRect = Rect.inflate(rect, Math.max(rect.width, rect.height))\n\t\tconst clippedPoints = Polygon.clipToRect(points, inflatedRect)\n\t\t// In the case where the polygon clipped in a way that we couldn't draw\n\t\t// an overlay, just use the original points.\n\t\tif (clippedPoints.length < 3) return points\n\t\treturn clippedPoints\n\t}, [key, clippingEnabled])\n}\n\nconst showAllEdges: [boolean, boolean, boolean, boolean] = [true, true, true, true]\nexport const Overlay = ({\n\tpoints,\n\tbackgroundColor = \"transparent\",\n\tborderWidth,\n\tborderColor,\n\tclippingRect,\n\tdashed,\n\topacity,\n\toval,\n\troundToOutside = true,\n\tchildren,\n\tonDoubleClick,\n\tonContextMenu,\n\tclassName,\n\tstyle: externalStyle,\n\tshowRectEdges,\n\ttestId,\n\tskipLargeLayer = true,\n}: Props) => {\n\tconst skewed = isSkewedQuadrilateralPoints(points)\n\tconst complex = oval || (backgroundColor && backgroundColor !== \"transparent\" && backgroundColor !== \"none\")\n\tconst shouldRenderGPULines = !complex && borderWidth > 0\n\tconst clippedPoints = useCanvasClippedPolygonPoints(points, clippingRect, shouldRenderGPULines)\n\tconst roundedPoints = roundToOutside ? roundPointsToOutside(clippedPoints, borderWidth) : clippedPoints\n\n\tconst rect = Rect.boundingRectFromPoints(points)\n\n\tconst minX = rect.x\n\tconst minY = rect.y\n\n\t// Rebase all points coordinates onto the min X/Y points.\n\tconst rebasedPoints = roundedPoints.map(p => ({\n\t\tx: p.x - minX,\n\t\ty: p.y - minY,\n\t}))\n\n\t// A fast path, where the border lines are drawn using GPU layers, not CSS\n\t// borders. This prevents the main div from becoming a huge texture on the GPU.\n\tif (shouldRenderGPULines) {\n\t\tconst lines: React.ReactElement[] = []\n\t\tconst showRectEdgesResult: [boolean, boolean, boolean, boolean] =\n\t\t\tshowRectEdges?.(roundedPoints, skewed) ?? showAllEdges\n\t\trebasedPoints.forEach((point: Point, index: number) => {\n\t\t\tconst nextPoint = rebasedPoints[(index + 1) % rebasedPoints.length]!\n\t\t\tif (showRectEdgesResult[index] === false) return\n\t\t\tlines.push(\n\t\t\t\t<GPULayer\n\t\t\t\t\tkey={`${point.x}-${point.y}-${index}`}\n\t\t\t\t\tcolor={borderColor}\n\t\t\t\t\theight={borderWidth}\n\t\t\t\t\tx={point.x}\n\t\t\t\t\ty={point.y}\n\t\t\t\t\twidth={Point.distance(point, nextPoint)}\n\t\t\t\t\trotation={Point.angleFromX(point, nextPoint)}\n\t\t\t\t\tdashed={dashed}\n\t\t\t\t/>,\n\t\t\t)\n\t\t})\n\t\treturn (\n\t\t\t// biome-ignore lint/nursery/noStaticElementInteractions: hit target outlines\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tbackgroundColor: \"transparent\",\n\t\t\t\t\twidth: `${rect.width}px`,\n\t\t\t\t\theight: `${rect.height}px`,\n\t\t\t\t\topacity,\n\t\t\t\t\twillChange: \"transform, opacity\",\n\t\t\t\t\ttransform: `translateX(${rect.x}px) translateY(${rect.y}px)`,\n\t\t\t\t\t...externalStyle,\n\t\t\t\t}}\n\t\t\t\tonDoubleClick={onDoubleClick}\n\t\t\t\tonContextMenu={onContextMenu}\n\t\t\t\tclassName={className || \"Overlay\"}\n\t\t\t\tdata-testid={testId ?? \"overlay\"}\n\t\t\t>\n\t\t\t\t{lines}\n\t\t\t\t{children && (\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t// The children need a small border offset because of the border model\n\t\t\t\t\t\t\ttop: borderWidth,\n\t\t\t\t\t\t\tleft: borderWidth,\n\t\t\t\t\t\t\tbottom: borderWidth,\n\t\t\t\t\t\t\tright: borderWidth,\n\t\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\t\twillChange: \"transform\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isFunction(children) ? children({ skewed, rect }) : children}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t)\n\t}\n\n\t// If we aren't drawing GPU lines, don't draw slow divs if the area is too\n\t// large. This is an arbitrary number, considering that a desktop breakpoint\n\t// is 1200 x 800 which is about 1m pixels. You could make an argument for it\n\t// to be much higher. It should be safe to drop these outlines as highlight\n\t// and selection outlines (critical) should always use GPU lines.\n\tif (skipLargeLayer && Math.abs(Polygon.signedArea(points)) > 1_000_000) return null\n\n\t// When the polygon is skewed to a line (rect width/height is 0), snap to at least one pixel so that we could\n\t// render a line.\n\tconst width = Math.max(rect.width, 1)\n\tconst height = Math.max(rect.height, 1)\n\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tbackgroundColor: \"transparent\",\n\t\t\t\twidth: `${width}px`,\n\t\t\t\theight: `${height}px`,\n\t\t\t\twillChange: \"transform\",\n\t\t\t\ttransform: `translateX(${rect.x}px) translateY(${rect.y}px)`,\n\t\t\t\toverflow: \"visible\",\n\t\t\t}}\n\t\t>\n\t\t\t<svg\n\t\t\t\tviewBox={`0 0 ${width} ${height}`}\n\t\t\t\tstyle={{ inset: 0, position: \"absolute\" }}\n\t\t\t\t// Avoid lines being cropped because of the viewBox.\n\t\t\t\toverflow=\"visible\"\n\t\t\t>\n\t\t\t\t{oval ? (\n\t\t\t\t\t<ellipse\n\t\t\t\t\t\tcx={rect.width / 2}\n\t\t\t\t\t\tcy={rect.height / 2}\n\t\t\t\t\t\trx={rect.width / 2}\n\t\t\t\t\t\try={rect.height / 2}\n\t\t\t\t\t\tfill={backgroundColor}\n\t\t\t\t\t\tstrokeWidth={borderWidth}\n\t\t\t\t\t\tstrokeDasharray={dashed ? 3 : undefined}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<polygon\n\t\t\t\t\t\tpoints={rebasedPoints.map(point => `${point.x},${point.y}`).join(\" \")}\n\t\t\t\t\t\tfill={backgroundColor}\n\t\t\t\t\t\tstroke={borderColor}\n\t\t\t\t\t\tstrokeWidth={borderWidth}\n\t\t\t\t\t\tstrokeDasharray={dashed ? 3 : undefined}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</svg>\n\t\t\t{isFunction(children) ? children({ skewed, rect }) : children}\n\t\t</div>\n\t)\n}\n\nfunction roundPointsToOutside(points: Point[], borderWidth: number): Point[] {\n\t// If the rectangle edges are parallel to the x & y axes, rounding is straight-forward: we just outset the rectangle\n\t// by its outline width.\n\tif (isStraightRectangle(points)) {\n\t\tconst rect = Rect.boundingRectFromPoints(points)\n\t\tconst roundedRect = Rect.inset(Rect.roundToOutside(rect), -borderWidth + 1) // +1 as we already round the rect to outside\n\t\treturn Rect.cornerPoints(roundedRect)\n\t}\n\n\t// Otherwise, move the outlines outwards by the border width, and find their intersections as the new corner points.\n\tconst edges: Line[] = []\n\tconst pointsLength = points.length\n\tfor (let i = 0; i < pointsLength; i++) {\n\t\tconst point = points[i]!\n\t\tconst nextPoint = points[(i + 1) % pointsLength]!\n\t\tedges.push(Line(point, nextPoint))\n\t}\n\n\t// If the rectangle is skewed to a line, we won't be able to find an intersection. Pick the longest edge and render\n\t// as a line.\n\tif (Math.abs(Polygon.signedArea(points)) < 1) {\n\t\tconst line = findLongestEdge(edges)\n\t\treturn [line.a, line.a, line.b, line.b]\n\t}\n\n\t// A scale:0 frame might lead to null points after rounding. If we can't\n\t// round the points, just use the original points.\n\treturn getIntersectionsOfOffsetEdges(edges, borderWidth) ?? points\n}\n\nfunction getIntersectionsOfOffsetEdges(edges: Line[], offset: number): Point[] | null {\n\tconst offsetEdges = edges.map(edge => Line.offset(edge, offset))\n\tconst edgesLength = offsetEdges.length\n\n\tconst intersections: Point[] = []\n\tfor (let index = 0; index < edgesLength; index++) {\n\t\tconst offsetEdge = offsetEdges[index]!\n\t\t// Maintain the original points order (tl, tr, br, bl in a\n\t\t// quadrilateral), and we start at the top edge.\n\t\tconst prevEdge = offsetEdges[(index - 1 + edgesLength) % edgesLength]!\n\t\tconst intersection = Line.intersection(prevEdge, offsetEdge)\n\t\t// If the points don't intersect, we won't render the overlay, so no\n\t\t// need to calculate further intersections.\n\t\tif (isNull(intersection)) return null\n\t\tintersections.push(intersection)\n\t}\n\treturn intersections\n}\n\nfunction findLongestEdge(edges: Line[]): Line {\n\tlet max: number | undefined = undefined\n\tlet longest: Line | undefined = undefined\n\tfor (const edge of edges) {\n\t\tconst length = Line.distance(edge)\n\t\tif (max === undefined) {\n\t\t\tmax = length\n\t\t\tlongest = edge\n\t\t\tcontinue\n\t\t}\n\n\t\tif (length > max) {\n\t\t\tmax = length\n\t\t\tlongest = edge\n\t\t}\n\t}\n\n\tassert(longest !== undefined, \"Cannot find longest edge\", edges)\n\treturn longest\n}\n", "import type React from \"react\"\n\ninterface GPULayerProps {\n\tx: number\n\ty: number\n\twidth: number\n\theight: number\n\tcolor: string\n\topacity?: number\n\trotation?: number\n\tdashed?: boolean\n}\n\nexport function GPULayer({ x, y, width, height, color, opacity = 1, rotation = 0, dashed }: GPULayerProps) {\n\tif (dashed) {\n\t\tconst style: React.CSSProperties = {\n\t\t\tposition: \"fixed\",\n\t\t\twidth,\n\t\t\theight,\n\t\t\ttransformOrigin: \"0 0\",\n\t\t\topacity,\n\t\t\twillChange: \"transform\",\n\t\t\ttransform: `translateX(${x}px) translateY(${y}px) translateZ(0) rotate(${rotation ? rotation.toFixed(4) : 0}deg)`,\n\t\t}\n\n\t\treturn (\n\t\t\t<div style={style}>\n\t\t\t\t<svg\n\t\t\t\t\trole=\"presentation\"\n\t\t\t\t\tstyle={{ position: \"absolute\" }}\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\theight=\"100%\"\n\t\t\t\t\tviewBox={`0 0 ${width} ${height}`}\n\t\t\t\t>\n\t\t\t\t\t<line x1={0} y1={0} x2={width} y2={0} stroke={color} strokeWidth={2} strokeDasharray={3} />\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t)\n\t}\n\n\tconst style: React.CSSProperties = {\n\t\tposition: \"fixed\",\n\t\t// We use 100px instead of 1px because of https://github.com/framer/company/issues/19505\n\t\t// @TODO: investigate if we can get rid of the workaround.\n\t\twidth: 100,\n\t\theight: 100,\n\t\tbackgroundColor: color,\n\t\ttransformOrigin: \"0 0\",\n\t\topacity,\n\t\twillChange: \"transform\",\n\t\ttransform: `translateX(${x}px) translateY(${y}px) translateZ(0) rotate(${\n\t\t\trotation ? rotation.toFixed(4) : 0\n\t\t}deg) scaleX(${width / 100}) scaleY(${height / 100})`,\n\t}\n\treturn <div style={style} />\n}\n", "import \"VideoOverlay.styles_146dm9o.wyw.css\"; export const videoOverlayWrapper = \"videoOverlayWrapper_v1d1iynd\";", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { Overlay } from \"../canvas-hud/Overlay.tsx\"\nimport type { OverlayComponentProps } from \"./CreateToolHelper.ts\"\nimport * as styles from \"./VideoOverlay.styles.ts\"\n\nfunction VideoIcon() {\n\treturn (\n\t\t<svg\n\t\t\twidth=\"100%\"\n\t\t\theight=\"100%\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\txmlnsXlink=\"http://www.w3.org/1999/xlink\"\n\t\t\tviewBox=\"0 0 64 64\"\n\t\t>\n\t\t\t<g>\n\t\t\t\t<defs>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M 32 0 C 49.673 0 64 14.327 64 32 C 64 49.673 49.673 64 32 64 C 14.327 64 0 49.673 0 32 C 0 14.327 14.327 0 32 0 Z\"\n\t\t\t\t\t\tid=\"a1000z\"\n\t\t\t\t\t></path>\n\t\t\t\t\t<clipPath id=\"a1001z\">\n\t\t\t\t\t\t<use xlinkHref=\"#a1000z\"></use>\n\t\t\t\t\t</clipPath>\n\t\t\t\t</defs>\n\t\t\t\t<use\n\t\t\t\t\txlinkHref=\"#a1000z\"\n\t\t\t\t\tfill=\"rgba(0, 153, 255, 0.1)\"\n\t\t\t\t\tclipPath=\"url(#a1001z)\"\n\t\t\t\t\tstrokeWidth=\"2\"\n\t\t\t\t\tstroke=\"rgb(0, 153, 255)\"\n\t\t\t\t></use>\n\t\t\t</g>\n\t\t\t<path\n\t\t\t\td=\"M 24 19.822 C 24 19.033 24.871 18.554 25.537 18.978 L 44.674 31.156 C 45.292 31.549 45.292 32.451 44.674 32.844 L 25.537 45.022 C 24.871 45.446 24 44.967 24 44.178 Z\"\n\t\t\t\tfill=\"#ffffff\"\n\t\t\t\tstroke=\"rgb(0, 153, 255)\"\n\t\t\t></path>\n\t\t</svg>\n\t)\n}\n\nconst minFrameSizeForIconDisplay = 100\n\nexport function VideoOverlay({ points }: OverlayComponentProps) {\n\tconst { width, height } = Rect.boundingRectFromPoints(points)\n\tconst showIcon = width >= minFrameSizeForIconDisplay && height >= minFrameSizeForIconDisplay\n\n\treturn (\n\t\t<Overlay\n\t\t\tpoints={points}\n\t\t\tbackgroundColor=\"rgba(0, 153, 255, 0.1)\"\n\t\t\tborderWidth={1}\n\t\t\tborderColor={colors.canvasCreatePreviewBorder}\n\t\t\tstyle={{ pointerEvents: \"none\" }}\n\t\t>\n\t\t\t{({ skewed }) => {\n\t\t\t\tif (skewed) return null\n\t\t\t\treturn (\n\t\t\t\t\tshowIcon && (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={styles.videoOverlayWrapper}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div style={{ maxWidth: 64, maxHeight: 64 }}>\n\t\t\t\t\t\t\t\t<VideoIcon />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t}}\n\t\t</Overlay>\n\t)\n}\n", "import { isReactComponentDefinition } from \"@framerjs/framer-runtime\"\nimport { unhandledError } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport CodeComponentNode from \"document/models/CanvasTree/nodes/CodeComponentNode.ts\"\nimport type { ControlProps } from \"document/models/controlProps/ControlProp.ts\"\nimport { prefixControlProps } from \"document/models/controlProps/controlPropKey.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { insertCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { defaultGetVideoModuleIdentifier } from \"../chrome/insertSidebar/dataSources/items/mediaItems.ts\"\nimport type { CreateOptions, CreateTool } from \"./Create.tsx\"\nimport { CreateToolHelper } from \"./CreateToolHelper.ts\"\nimport { VideoOverlay } from \"./VideoOverlay.tsx\"\nimport type { SnapTool } from \"./utils/SnapTool.ts\"\n\nabstract class CreateCodeComponentBaseTool\n\textends withClassDiscriminator(\"CreateCodeComponentBaseTool\", VekterTool)\n\timplements CreateTool\n{\n\tabstract override readonly enum: Tools.CreateVideo\n\toverride readonly wantsAutoscrolling = true\n\n\thelper = new CreateToolHelper()\n\toval = false\n\tdrawingDidStart = false\n\t// FIXME: ! is unsafe; the snapper is assigned externally, not in the constructor,\n\t// so if the external code forgets to do that, we\u2019ll have a runtime error\n\tsnapper!: SnapTool\n\n\tonDragStart = () => {\n\t\tthis.drawingDidStart = true\n\t}\n\n\toverride start() {\n\t\tthis.helper.nodeClass = CodeComponentNode\n\t\tthis.helper.highlightParent = true\n\t\tthis.helper.dragStart = this.onDragStart\n\n\t\tif (this.enum === Tools.CreateVideo) {\n\t\t\tthis.helper.overlayComponent = VideoOverlay\n\t\t}\n\n\t\tthis.helper.start(this)\n\t\tthis.engine.stores.mouseCursorStore.current = insertCursor\n\t}\n\n\toverride stop() {\n\t\tthis.helper.stop(this)\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.snapper.stop()\n\t}\n\n\toverride update() {\n\t\tthis.helper.update(this)\n\t}\n\n\tcreate({\n\t\tid,\n\t\tparentId,\n\t\tindexInParent,\n\t\trect,\n\t\tproperties,\n\t\trotation,\n\t\toriginalParentId,\n\t}: CreateOptions<CodeComponentNode>) {\n\t\tproperties = { ...properties, top: rect.y, left: rect.x, width: rect.width, height: rect.height, rotation }\n\n\t\tif (properties.width === 0 || properties.height === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tlet componentIdentifier: string | undefined = undefined\n\n\t\t// Ensure that scroll components are created with some values that are\n\t\t// different than the default props the component declares. This allows\n\t\t// us to avoid migrating existing components, whose defaults we don't\n\t\t// want to change if they've already been created.\n\t\tconst componentSpecificOverrides: ControlProps = {}\n\t\tswitch (this.enum) {\n\t\t\tcase Tools.CreateVideo: {\n\t\t\t\tconst moduleIdentifier = defaultGetVideoModuleIdentifier()\n\t\t\t\tthis.engine.stores.toolStore.codeComponentInProgressInsertionIndicatorNodeIDs.add(id)\n\n\t\t\t\tif (moduleIdentifier) {\n\t\t\t\t\tthis.engine.stores.loadedExternalModulesStore\n\t\t\t\t\t\t.ensureModuleEvaluatedInSandbox(moduleIdentifier)\n\t\t\t\t\t\t.catch(unhandledError)\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tthis.engine.stores.toolStore.codeComponentInProgressInsertionIndicatorNodeIDs.delete(id)\n\t\t\t\t\t\t})\n\t\t\t\t\tcomponentIdentifier = moduleIdentifier.value\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow Error(`CreateCodeComponent can't handle tool: ${this.enum}`)\n\t\t}\n\n\t\tproperties.codeComponentIdentifier = componentIdentifier\n\t\tconst component = componentIdentifier\n\t\t\t? this.engine.componentLoader.componentForIdentifier(componentIdentifier)\n\t\t\t: undefined\n\t\tif (!component || !isReactComponentDefinition(component)) return\n\n\t\tproperties = {\n\t\t\t...properties,\n\t\t\t...prefixControlProps(componentSpecificOverrides),\n\t\t}\n\n\t\t// When drawing in a replica, the node should be insert into the\n\t\t// original parent.\n\t\tconst targetParentId = originalParentId ?? parentId\n\t\tthis.engine.createNode(CodeComponentNode, properties, targetParentId)\n\n\t\tif (indexInParent !== -1) this.engine.moveNode(id, parentId, indexInParent)\n\n\t\t// return a callback to run when all the updates are done in\n\t\t// CreateToolHelper.update()\n\t\treturn () => {\n\t\t\tthis.engine.exitTool()\n\n\t\t\tswitch (this.enum) {\n\t\t\t\tcase Tools.CreateVideo:\n\t\t\t\t\trecord(\"layout_video\", {\n\t\t\t\t\t\tsource: \"draw\",\n\t\t\t\t\t\twidth: properties.width,\n\t\t\t\t\t\theight: properties.height,\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class CreateVideoTool extends CreateCodeComponentBaseTool {\n\toverride readonly enum = Tools.CreateVideo\n}\n", "import { VekterTool } from \"document/VekterTool.ts\"\nimport { ContextAction } from \"document/components/utils/contextActions.ts\"\nimport type { CanvasNode, MaybeNodeID } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode, NullID, isDrawableNode } from \"document/models/CanvasTree/index.ts\"\nimport type { ReadonlyChildList } from \"document/models/CanvasTree/nodes/ChildList.ts\"\nimport { isNodeId } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { getBreakpointForNode } from \"document/models/CanvasTree/nodes/utils/breakpointHelpers.ts\"\nimport { isDesignPageNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { NonDynamicValueRecord } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport type { WithChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { withFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { getLayoutType, hasColumnMasonryLayout, hasStackLayout } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport { isLockedOrLockedByParent } from \"document/models/CanvasTree/traits/WithLock.ts\"\nimport { paddingDefinedDefaults } from \"document/models/CanvasTree/traits/WithPadding.ts\"\nimport { isBreakpointVariant, isVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport {\n\tcreateRoundedRectangle,\n\tdefaultRoundedRadius,\n} from \"document/models/CanvasTree/traits/utils/basicShape/createShapes.ts\"\nimport { getFramePresetCategory } from \"document/models/CanvasTree/traits/utils/framePresets.ts\"\nimport { isDeviceNode } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifierChecks.ts\"\nimport { positionTypeUpdateForNewParent } from \"document/models/CanvasTree/traits/utils/positionTypeHelpers.ts\"\nimport { guessConstrainedFrame } from \"document/models/ConstraintSolver.ts\"\nimport { shouldGuessPinToBottom } from \"document/models/shouldGuessPinToBottom.ts\"\nimport { shouldGuessPinToRight } from \"document/models/shouldGuessPinToRight.ts\"\nimport { Tools, isLayoutTool } from \"document/stores/ToolStore.ts\"\nimport {\n\tcollectDefaultLayoutProperties,\n\tcreateLayoutWithPlaceHolderFrames,\n\tguessStackOrGridResponsiveLayout,\n\ttoolToDefaultLayout,\n} from \"document/utils/layoutHelpers.ts\"\nimport { DimensionType } from \"library/render/types/Constraints.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type { Size } from \"library/render/types/Size.ts\"\nimport { insertCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { CreateOptions, CreateTool } from \"./Create.tsx\"\nimport { CreateToolHelper } from \"./CreateToolHelper.ts\"\nimport { getNextFrameColor } from \"./utils/FramesHelper.ts\"\nimport type { SnapTool } from \"./utils/SnapTool.ts\"\nimport { inferStackDirectionForChildren, reparentStackChildren } from \"./utils/stackCreateHelper.ts\"\n\nconst defaultGroundFrameColor = \"white\"\nclass CreateFrameBaseTool extends withClassDiscriminator(\"CreateFrameBaseTool\", VekterTool) implements CreateTool {\n\toverride readonly wantsAutoscrolling = true\n\n\thelper = new CreateToolHelper()\n\t// FIXME: ! is unsafe; the snapper is assigned externally, not in the constructor,\n\t// so if the external code forgets to do that, we\u2019ll have a runtime error\n\tsnapper!: SnapTool\n\tdrawingDidStart = false\n\n\tonDragStart = () => {\n\t\tthis.drawingDidStart = true\n\t}\n\n\toverride start() {\n\t\tthis.helper.nodeClass = FrameNode\n\t\tthis.helper.highlightParent = true\n\t\tthis.helper.dragStart = this.onDragStart\n\t\tthis.helper.start(this)\n\t\tif (this.enum === Tools.CreateRounded) {\n\t\t\tthis.helper.overlayShape = createRoundedRectangle\n\t\t}\n\t\tthis.engine.stores.mouseCursorStore.current = insertCursor\n\t}\n\n\toverride stop() {\n\t\tthis.helper.stop(this)\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.snapper.stop()\n\t}\n\n\toverride update() {\n\t\tthis.helper.update(this)\n\t}\n\n\tcreate({ id, parentId, indexInParent, rect, properties, rotation, originalParentId }: CreateOptions<FrameNode>) {\n\t\tconst { tree } = this.engine\n\t\tconst pixelAlignedFrame = Rect.pixelAligned(rect)\n\t\tproperties = {\n\t\t\t...properties,\n\t\t\ttop: pixelAlignedFrame.y,\n\t\t\tleft: pixelAlignedFrame.x,\n\t\t\twidth: pixelAlignedFrame.width,\n\t\t\theight: pixelAlignedFrame.height,\n\t\t\trotation: rotation === 0 ? undefined : rotation,\n\t\t\tgridItemFillCellWidth: true,\n\t\t\tgridItemFillCellHeight: true,\n\t\t}\n\n\t\tif (properties.width === 0 || properties.height === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\t// Collect constraint props and sibling nodes\n\t\t// When drawing in a replica, we still need to use the parentId to\n\t\t// collect props/siblings, but the node should be insert into the\n\t\t// original parent in the end\n\t\tlet siblingNodes: CanvasNode[] | ReadonlyChildList<CanvasNode> = []\n\t\tlet ancestorBreakpoint: CanvasNode | null = null\n\n\t\tif (parentId) {\n\t\t\tconst parentNode = tree.getNode(parentId)\n\t\t\tif (parentNode) {\n\t\t\t\tconst parentSize: Size = tree.getRect(parentNode)\n\t\t\t\tconst constraintProps = guessConstrainedFrame(\n\t\t\t\t\tpixelAlignedFrame,\n\t\t\t\t\t// When creating a frame it can't be using viewport units, so the parentSize used for\n\t\t\t\t\t// calculating size & position should be the same.\n\t\t\t\t\t{\n\t\t\t\t\t\tsizing: parentSize,\n\t\t\t\t\t\tpositioning: parentSize,\n\t\t\t\t\t\tviewport: null,\n\t\t\t\t\t\tlayout: getLayoutType(parentNode),\n\t\t\t\t\t},\n\t\t\t\t\t// Newly created Frame nodes cannot have floating\n\t\t\t\t\t// position values.\n\t\t\t\t\tnull,\n\t\t\t\t\t{\n\t\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, null, parentNode),\n\t\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, null, parentNode),\n\t\t\t\t\t\tshouldGuessWidth100percent: hasStackLayout(parentNode) && isBreakpointVariant(parentNode),\n\t\t\t\t\t},\n\t\t\t\t)\n\n\t\t\t\tancestorBreakpoint = getBreakpointForNode(this.engine.tree, parentNode.id)\n\n\t\t\t\t// Pin to both sides if drawing layout in a breakpoint\n\t\t\t\tif (ancestorBreakpoint && isLayoutTool(this.enum)) {\n\t\t\t\t\tconstraintProps.left = pixelAlignedFrame.x\n\t\t\t\t\tconstraintProps.right = parentSize.width - pixelAlignedFrame.x - pixelAlignedFrame.width\n\t\t\t\t\tproperties.constraintsLocked = true\n\t\t\t\t}\n\n\t\t\t\t// TODO: Once fill height is implemented for masonry grids, we can most likely remove or extend this bit\n\t\t\t\t// depending on the implementation.\n\t\t\t\t// When drawing in a masonry grid, preserve the drawn child height settings\n\t\t\t\tconst masonryChildProps: Partial<NonDynamicValueRecord<FrameNode>> = hasColumnMasonryLayout(parentNode)\n\t\t\t\t\t? {\n\t\t\t\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t\t\t\t\theight: pixelAlignedFrame.height,\n\t\t\t\t\t\t\tgridItemFillCellHeight: undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}\n\n\t\t\t\tproperties = { ...properties, ...constraintProps, ...masonryChildProps }\n\n\t\t\t\tif (withChildren(parentNode)) {\n\t\t\t\t\tsiblingNodes = parentNode.children\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tsiblingNodes = this.engine.stores.scopeStore.active.getGroundNodes()\n\t\t}\n\n\t\t// When drawing in a replica, the node should be insert into the\n\t\t// original parent.\n\t\tconst targetParentId = originalParentId ?? parentId\n\n\t\tconst addingToReplica = isNodeId(originalParentId)\n\t\t// When drawing in a replica, don't wrap containing sibling nodes.\n\t\t// @TODO: (maybe) support wrapping nodes when drawing in a replica.\n\t\tconst potentialChildren = addingToReplica\n\t\t\t? []\n\t\t\t: siblingNodes.filter(siblingNode => this.isPotentialChildren(siblingNode, pixelAlignedFrame))\n\n\t\tthis.collectPropertiesForFrame(properties, parentId, potentialChildren, pixelAlignedFrame)\n\n\t\tconst isStackLikeTool =\n\t\t\tthis.enum === Tools.CreateStack || this.enum === Tools.CreateColumns || this.enum === Tools.CreateRows\n\n\t\tif (\n\t\t\tisStackLikeTool ||\n\t\t\tthis.enum === Tools.CreateGrid ||\n\t\t\tthis.enum === Tools.CreateGridRow ||\n\t\t\tthis.enum === Tools.CreateGridSpan ||\n\t\t\tthis.enum === Tools.CreateMasonry\n\t\t) {\n\t\t\tconst layout = toolToDefaultLayout(this.enum)\n\t\t\t// If there are potential children that will be wrapped with the new node,\n\t\t\t// we skip adding the placeholder children.\n\t\t\tconst skipPlaceholders = potentialChildren.length > 0\n\t\t\tconst stackWithPreset = createLayoutWithPlaceHolderFrames(this.engine, layout, properties, skipPlaceholders)\n\t\t\tthis.engine.stores.scopeStore.insertNode(stackWithPreset, targetParentId)\n\t\t} else {\n\t\t\tthis.engine.createFrame(targetParentId, properties)\n\t\t}\n\n\t\tif (indexInParent !== -1) this.engine.moveNode(id, parentId, indexInParent)\n\n\t\tif (isLayoutTool(this.enum)) {\n\t\t\trecord(\"layout_stack\", { source: \"draw\", layoutType: trackingForLayoutTool(this.enum) })\n\t\t\tif (isStackLikeTool && potentialChildren.length > 0) {\n\t\t\t\treparentStackChildren(this.engine, id, pixelAlignedFrame, potentialChildren, properties.stackDirection)\n\t\t\t} else if (ancestorBreakpoint) {\n\t\t\t\tguessStackOrGridResponsiveLayout(this.engine, id, ancestorBreakpoint.id)\n\t\t\t}\n\t\t} else if (this.enum === Tools.CreateImage) {\n\t\t\t// Note: We do not add any children to the frame in this case.\n\t\t\tconst popoutNavigation = this.engine.floatingWindowPopoutNavigation\n\t\t\tif (popoutNavigation && !popoutNavigation.isPresenting(\"fill\")) {\n\t\t\t\tpopoutNavigation.presentPopout(\"fill\")\n\t\t\t}\n\t\t\trecord(\"layout_image\", {\n\t\t\t\tsource: \"draw\",\n\t\t\t\twidth: properties.width,\n\t\t\t\theight: properties.height,\n\t\t\t})\n\t\t} else {\n\t\t\tconst presetDeviceType = properties.framePreset ?? undefined\n\t\t\trecord(\"layout_frame\", {\n\t\t\t\tsource: \"draw\",\n\t\t\t\twidth: properties.width,\n\t\t\t\theight: properties.height,\n\t\t\t\tpresetDeviceType,\n\t\t\t\tpresetDeviceTypeCategory: getFramePresetCategory(presetDeviceType),\n\t\t\t})\n\n\t\t\t// Drawing over siblings makes them children.\n\t\t\t// NOTE: This assumes the node created can have children\n\t\t\tpotentialChildren.forEach(node => {\n\t\t\t\tconst parentNode = parentId ? (this.engine.tree.getNode(parentId) as CanvasNode & WithChildren) : null\n\t\t\t\tconst newParent = tree.getNode(id) as CanvasNode & WithChildren\n\t\t\t\tconst update = ContextAction.convertNodeToNewParentUpdate(tree, node, parentNode, newParent)\n\t\t\t\tthis.engine.moveNode(node.id, id)\n\t\t\t\t// The update is type safe because it already checks the trait within `convertNodeToNewParentUpdate`\n\t\t\t\tthis.engine.tree.current(node)?.set(update)\n\t\t\t})\n\t\t}\n\n\t\t// return a callback to run when all the updates are done in\n\t\t// CreateToolHelper.update()\n\t\treturn () => {\n\t\t\tthis.engine.exitTool()\n\t\t}\n\t}\n\n\t// Only add sibling nodes that are contained inside the drawn rect.\n\t// Exclude nodes that can't be children (devices, locked nodes, variants).\n\tisPotentialChildren = (siblingNode: CanvasNode, pixelAlignedFrame: Rect) => {\n\t\tif (isDeviceNode(siblingNode)) return false\n\t\tif (isDrawableNode(siblingNode) && isLockedOrLockedByParent(siblingNode)) return false\n\t\tif (isVariant(siblingNode)) return false\n\t\tconst siblingFrame = this.engine.tree.getRect(siblingNode)\n\t\treturn Rect.containsRect(pixelAlignedFrame, siblingFrame)\n\t}\n\n\tprivate setFrameFillColor(properties: Partial<NonDynamicValueRecord<FrameNode>>, parentId: MaybeNodeID) {\n\t\tproperties.fillColor = defaultGroundFrameColor\n\t\tconst defaultFill = this.engine.stores.persistedUserDefaults.frameBackground\n\t\tconst parentNode = parentId && this.engine.tree.getNode(parentId)\n\n\t\tif (!parentNode) {\n\t\t\treturn\n\t\t}\n\n\t\tif (defaultFill) {\n\t\t\tproperties.fillColor = defaultFill\n\t\t\treturn\n\t\t}\n\n\t\tproperties.fillColor = getNextFrameColor()\n\t\tif (withFill(parentNode) && parentNode.fillType === \"color\" && parentNode.fillColor === properties.fillColor) {\n\t\t\tproperties.fillColor = getNextFrameColor()\n\t\t}\n\t}\n\n\tcollectPropertiesForFrame = (\n\t\tproperties: Partial<NonDynamicValueRecord<FrameNode>>,\n\t\tparentId: MaybeNodeID,\n\t\tpotentialChildren: CanvasNode[],\n\t\tpixelAlignedFrame: Rect,\n\t) => {\n\t\tconst isGroundFrame = parentId === NullID\n\t\tconst activeScope = this.engine.stores.scopeStore.active\n\t\tproperties.overflow =\n\t\t\tisGroundFrame || isWebPageNode(activeScope) || isDesignPageNode(activeScope) ? \"clip\" : \"visible\"\n\n\t\t// If there's only one potential children, and it has a position, we\n\t\t// copied the position type to the created frame/stack.\n\t\tif (potentialChildren.length === 1) {\n\t\t\tconst singleChild = potentialChildren[0]\n\t\t\tconst parentNode = parentId ? this.engine.tree.getNode(parentId) : null\n\t\t\tObject.assign(properties, positionTypeUpdateForNewParent(singleChild, parentNode))\n\t\t}\n\n\t\tswitch (this.enum) {\n\t\t\tcase Tools.CreateRounded: {\n\t\t\t\tproperties.radius = defaultRoundedRadius\n\t\t\t\tthis.setFrameFillColor(properties, parentId)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase Tools.CreateFrame: {\n\t\t\t\tthis.setFrameFillColor(properties, parentId)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase Tools.CreateImage:\n\t\t\t\tproperties.fillType = \"image\"\n\t\t\t\tbreak\n\t\t\tcase Tools.CreateScreen:\n\t\t\t\tproperties.fillColor = defaultGroundFrameColor\n\t\t\t\tproperties.isScreen = true\n\t\t\t\tbreak\n\t\t\tcase Tools.CreateStack: {\n\t\t\t\tproperties.layout = \"stack\"\n\t\t\t\tconst stackDirection = inferStackDirectionForChildren(this.engine.tree, potentialChildren, pixelAlignedFrame)\n\t\t\t\tproperties.stackDirection = stackDirection === \"horizontal\" ? \"horizontal\" : \"vertical\"\n\t\t\t\tproperties.stackDistribution = \"center\"\n\t\t\t\tproperties.stackAlignment = \"center\"\n\t\t\t\tObject.assign(properties, paddingDefinedDefaults)\n\n\t\t\t\tif (isGroundFrame) {\n\t\t\t\t\tproperties.fillColor = defaultGroundFrameColor\n\t\t\t\t} else {\n\t\t\t\t\tproperties.fillEnabled = false\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase Tools.CreateRows:\n\t\t\tcase Tools.CreateColumns: {\n\t\t\t\tconst layout = toolToDefaultLayout(this.enum)\n\t\t\t\tproperties.stackDistribution = \"center\"\n\t\t\t\tproperties.stackAlignment = \"center\"\n\t\t\t\tcollectDefaultLayoutProperties(layout, properties)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase Tools.CreateGridRow:\n\t\t\tcase Tools.CreateGridSpan:\n\t\t\tcase Tools.CreateGrid:\n\t\t\tcase Tools.CreateMasonry: {\n\t\t\t\tconst layout = toolToDefaultLayout(this.enum)\n\t\t\t\tcollectDefaultLayoutProperties(layout, properties)\n\t\t\t\tif (this.enum === Tools.CreateMasonry) {\n\t\t\t\t\t// Mark this grid as masonry\n\t\t\t\t\tproperties.gridType = \"columnMasonry\"\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n}\n\nexport type CreateFrameBaseToolType = CreateFrameBaseTool\n\nexport class CreateFrameTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateFrame\n}\n\nexport class CreateRoundedTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateRounded\n}\n\nexport class CreateScreenTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateScreen\n}\n\nexport class CreateStackTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateStack\n}\n\nexport class CreateImageTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateImage\n}\n\nexport class CreateRowsTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateRows\n}\nexport class CreateColumnsTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateColumns\n}\n\nexport class CreateGridTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateGrid\n}\nexport class CreateGridRowTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateGridRow\n}\nexport class CreateGridSpanTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateGridSpan\n}\nexport class CreateMasonryTool extends CreateFrameBaseTool {\n\toverride readonly enum = Tools.CreateMasonry\n}\n\nfunction trackingForLayoutTool(tool: Tools) {\n\tswitch (tool) {\n\t\tcase Tools.CreateRows:\n\t\t\treturn \"rows\"\n\t\tcase Tools.CreateColumns:\n\t\t\treturn \"columns\"\n\t\tcase Tools.CreateGrid:\n\t\t\treturn \"grid\"\n\t\tcase Tools.CreateMasonry:\n\t\t\treturn \"masonry\"\n\t\tcase Tools.CreateGridRow:\n\t\t\treturn \"grid_row\"\n\t\tcase Tools.CreateGridSpan:\n\t\t\treturn \"grid_span\"\n\t\tcase Tools.CreateStack:\n\t\tdefault:\n\t\t\treturn \"stack\"\n\t}\n}\n", "import { triggerDrawingShapeCreateEvent } from \"@framerjs/framer-events\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { OvalShapeNode, PolygonShapeNode, RectangleShapeNode, StarShapeNode } from \"document/models/CanvasTree/index.ts\"\nimport type { ShapeType } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport {\n\tcreateOval,\n\tcreatePolygon,\n\tcreateRectangle,\n\tcreateStar,\n} from \"document/models/CanvasTree/traits/utils/basicShape/createShapes.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport type { WithPaths } from \"library/render/traits/Path.ts\"\nimport { assertNever } from \"library/utils/assert.ts\"\nimport { insertCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { CreateOptions, CreateTool } from \"./Create.tsx\"\nimport { CreateToolHelper } from \"./CreateToolHelper.ts\"\nimport type { SnapTool } from \"./utils/SnapTool.ts\"\n\nabstract class CreateShapeBaseTool\n\textends withClassDiscriminator(\"CreateShapeBaseTool\", VekterTool)\n\timplements CreateTool\n{\n\tabstract override readonly enum:\n\t\t| Tools.CreateRectangleShape\n\t\t| Tools.CreateOvalShape\n\t\t| Tools.CreateStarShape\n\t\t| Tools.CreatePolygonShape\n\toverride readonly wantsAutoscrolling = true\n\n\ttype: ShapeType = \"rectangle\"\n\thelper = new CreateToolHelper()\n\t// FIXME: ! is unsafe; the snapper is assigned externally, not in the constructor,\n\t// so if the external code forgets to do that, we\u2019ll have a runtime error\n\tsnapper!: SnapTool\n\n\toverride start() {\n\t\tlet overlayShape: (width: number, height: number) => WithPaths = createRectangle\n\t\tswitch (this.type) {\n\t\t\tcase \"polygon\":\n\t\t\t\toverlayShape = createPolygon\n\t\t\t\tbreak\n\t\t\tcase \"star\":\n\t\t\t\toverlayShape = createStar\n\t\t\t\tbreak\n\t\t\tcase \"oval\":\n\t\t\t\toverlayShape = createOval\n\t\t\t\tbreak\n\t\t}\n\n\t\tthis.helper.nodeClass = getNodeClassForShapeType(this.type)\n\t\tthis.helper.overlayShape = overlayShape\n\t\tthis.engine.stores.mouseCursorStore.current = insertCursor\n\t\tthis.helper.highlightParent = true\n\t\tthis.helper.start(this)\n\t}\n\n\toverride stop() {\n\t\tthis.helper.stop(this)\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.snapper.stop()\n\t}\n\n\toverride update() {\n\t\tthis.helper.update(this)\n\t}\n\n\tcreate = ({\n\t\tparentId,\n\t\trect,\n\t\tproperties,\n\t\trotation,\n\t\toriginalParentId,\n\t}: CreateOptions<OvalShapeNode | PolygonShapeNode | StarShapeNode | RectangleShapeNode>) => {\n\t\tproperties = { ...properties, y: rect.y, x: rect.x, width: rect.width, height: rect.height, rotation }\n\n\t\tif (properties.width === 0 || properties.height === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\t// When drawing in a replica, the node should be insert into the\n\t\t// original parent.\n\t\tconst targetParentId = originalParentId ?? parentId\n\t\tthis.engine.createShape(this.type, targetParentId, properties)\n\n\t\t// return a callback to run when all the updates are done in\n\t\t// CreateToolHelper.update()\n\t\treturn () => {\n\t\t\tthis.engine.exitTool()\n\t\t\ttriggerDrawingShapeCreateEvent({\n\t\t\t\tshape: this.type,\n\t\t\t})\n\t\t}\n\t}\n}\n\nexport class CreateRectangleShapeTool extends CreateShapeBaseTool {\n\toverride readonly enum = Tools.CreateRectangleShape\n\tconstructor(engine: VekterEngine) {\n\t\tsuper(engine)\n\t\tthis.type = \"rectangle\"\n\t}\n}\n\nexport class CreateOvalShapeTool extends CreateShapeBaseTool {\n\toverride readonly enum = Tools.CreateOvalShape\n\tconstructor(engine: VekterEngine) {\n\t\tsuper(engine)\n\t\tthis.type = \"oval\"\n\t}\n}\n\nexport class CreateStarShapeTool extends CreateShapeBaseTool {\n\toverride readonly enum = Tools.CreateStarShape\n\tconstructor(engine: VekterEngine) {\n\t\tsuper(engine)\n\t\tthis.type = \"star\"\n\t}\n}\n\nexport class CreatePolygonShapeTool extends CreateShapeBaseTool {\n\toverride readonly enum = Tools.CreatePolygonShape\n\tconstructor(engine: VekterEngine) {\n\t\tsuper(engine)\n\t\tthis.type = \"polygon\"\n\t}\n}\n\nfunction getNodeClassForShapeType(\n\tshapeType: ShapeType,\n): typeof RectangleShapeNode | typeof OvalShapeNode | typeof PolygonShapeNode | typeof StarShapeNode {\n\tswitch (shapeType) {\n\t\tcase \"rectangle\":\n\t\t\treturn RectangleShapeNode\n\t\tcase \"oval\":\n\t\t\treturn OvalShapeNode\n\t\tcase \"polygon\":\n\t\t\treturn PolygonShapeNode\n\t\tcase \"star\":\n\t\t\treturn StarShapeNode\n\t\tdefault:\n\t\t\tassertNever(shapeType)\n\t}\n}\n", "import { triggerTextCreateEvent } from \"@framerjs/framer-events\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { RichTextNode } from \"document/models/CanvasTree/index.ts\"\nimport type { TextAlignment } from \"document/models/CanvasTree/traits/WithTextStyle.ts\"\nimport { parseCSSDimension } from \"document/models/CanvasTree/traits/utils/CSSDimension.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { DimensionType } from \"library/render/types/Constraints.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport type { Rect } from \"library/render/types/Rect.ts\"\nimport type { Size } from \"library/render/types/Size.ts\"\nimport { BlockStyles, InlineStyles } from \"prosemirror/styles.ts\"\nimport { insertCursor } from \"utils/cursor.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { CreateOptions, CreateTool } from \"./Create.tsx\"\nimport { CreateToolHelper } from \"./CreateToolHelper.ts\"\nimport type { TextEditToolOptions } from \"./TextEditTool.ts\"\nimport type { SnapTool } from \"./utils/SnapTool.ts\"\n\n// Drag distance required to switch to a text box (instead of a auto sizing box)\nconst minimumDrag = 10\n\nexport class CreateTextTool extends withClassDiscriminator(\"CreateTextTool\", VekterTool) implements CreateTool {\n\toverride readonly enum = Tools.CreateText\n\toverride readonly wantsAutoscrolling = true\n\n\thelper = new CreateToolHelper()\n\t// FIXME: ! is unsafe; the snapper is assigned externally, not in the constructor,\n\t// so if the external code forgets to do that, we\u2019ll have a runtime error\n\tsnapper!: SnapTool\n\n\toverride start() {\n\t\tthis.helper.nodeClass = RichTextNode\n\t\tthis.helper.highlightParent = true\n\t\tthis.helper.start(this)\n\t\tthis.engine.stores.mouseCursorStore.current = \"text\"\n\t}\n\n\toverride stop() {\n\t\tthis.helper.stop(this)\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.snapper.stop()\n\t}\n\n\tcreate = ({\n\t\tid,\n\t\tparentId,\n\t\tindexInParent,\n\t\trect,\n\t\tproperties,\n\t\trotation,\n\t\toriginalParentId,\n\t}: CreateOptions<RichTextNode>) => {\n\t\tconst { tree } = this.engine\n\t\tconst { x, y, width, height } = rect\n\t\tlet textAlignment: TextAlignment | undefined = undefined\n\n\t\tconst isTextBox = this.isTextBox(rect)\n\t\tconst autoSize = !isTextBox\n\t\tif (autoSize) {\n\t\t\t// Put cursor at mouse up point for an auto resizing text layer\n\t\t\t// (Y has small adjustment for the cursor)\n\t\t\trect = { x: x + width, y: y + height, width: 0, height: 0 }\n\t\t}\n\n\t\tproperties = { ...properties, top: rect.y, left: rect.x, width: rect.width, height: rect.height }\n\n\t\tif (!autoSize) {\n\t\t\tproperties.rotation = rotation\n\t\t}\n\n\t\tif (parentId) {\n\t\t\tconst parentNode = tree.getNode(parentId)!\n\t\t\tconst parentSize: Size | null = tree.getRect(parentNode)\n\n\t\t\tif (autoSize) {\n\t\t\t\tconst mouseY = rect.y\n\t\t\t\tconst parentCenterY = parentSize.height / 2\n\t\t\t\tconst centeredY = Math.abs(mouseY - parentCenterY) < 2\n\n\t\t\t\tif (!centeredY && mouseY < parentCenterY) {\n\t\t\t\t\trect.y -= 10\n\t\t\t\t}\n\t\t\t\tif (!centeredY && mouseY > parentCenterY) {\n\t\t\t\t\trect.y += 6\n\t\t\t\t}\n\n\t\t\t\tconst alignmentTolerance = 4\n\t\t\t\tif (Math.abs(x - parentSize.width / 2) < alignmentTolerance) {\n\t\t\t\t\ttextAlignment = \"center\"\n\t\t\t\t\t// We adjusted the rect above but shift it back in this case, to fix the constraint guessing\n\t\t\t\t\trect.x -= width\n\t\t\t\t} else if (x < alignmentTolerance) {\n\t\t\t\t\ttextAlignment = \"left\"\n\t\t\t\t} else if (parentSize.width - x < alignmentTolerance) {\n\t\t\t\t\ttextAlignment = \"right\"\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (autoSize) {\n\t\t\t// correct for cursor, only if there are other existing nodes to make sure the first one is positioned at the origin\n\t\t\tconst groundNodes = this.engine.stores.scopeStore.active.getGroundNodes()\n\t\t\tif (groundNodes.length !== 0 && isNumber(properties.top)) {\n\t\t\t\tproperties.top -= 10\n\t\t\t}\n\t\t}\n\n\t\tconst attributes: Partial<RichTextNode> = {\n\t\t\t...properties,\n\t\t\twidth: rect.width,\n\t\t\theight: rect.height,\n\t\t\twidthType: autoSize ? DimensionType.Auto : DimensionType.FixedNumber,\n\t\t\theightType: autoSize ? DimensionType.Auto : DimensionType.FixedNumber,\n\t\t\tgridItemFillCellWidth: true,\n\t\t\tgridItemFillCellHeight: true,\n\t\t}\n\n\t\tdelete attributes[\"aspectRatio\"]\n\n\t\tconst targetParentId = originalParentId ?? parentId\n\n\t\t// Start an undo group so the RichTextEditTool can undo the creation if\n\t\t// the text layer is empty when exiting the tool.\n\t\tthis.engine.beginUndoGroup()\n\n\t\tconst { font, textColor, fontSize, letterSpacing, lineHeight, ...linkStyleDefaults } =\n\t\t\tthis.engine.stores.documentSettingsStore.defaultTextStyle\n\n\t\tconst p = document.createElement(\"p\")\n\t\tp.innerHTML = '<br class=\"trailing-break\">'\n\n\t\tconst parsedFontSize = parseCSSDimension(fontSize)\n\n\t\t// Set the default styles on the p tag\n\t\tInlineStyles.transforms.font.toCSS(p.style, font)\n\t\tInlineStyles.transforms.textColor.toCSS(p.style, textColor)\n\t\tInlineStyles.transforms.fontSize.toCSS(p.style, parsedFontSize)\n\t\tInlineStyles.transforms.letterSpacing.toCSS(p.style, letterSpacing)\n\t\tBlockStyles.transforms.lineHeight.toCSS(p.style, lineHeight)\n\t\tBlockStyles.transforms.textAlignment.toCSS(p.style, textAlignment ?? \"start\")\n\n\t\tconst [_, unit] = parsedFontSize\n\t\trecord(\"font_size_update\", { unit })\n\n\t\t// Set the initial HTML of the RichTextNode\n\t\tattributes.html = p.outerHTML\n\n\t\t// Set the default text link styles on the RichTextNode\n\t\tObject.assign(attributes, linkStyleDefaults)\n\n\t\tthis.engine.createRichText(targetParentId, attributes)\n\n\t\tif (indexInParent !== -1) this.engine.moveNode(id, targetParentId, indexInParent)\n\n\t\t// return a callback to run when all the updates are done in\n\t\t// CreateToolHelper.update()\n\t\treturn () => {\n\t\t\tconst options: TextEditToolOptions = {\n\t\t\t\tignoreEditIfEmpty: true,\n\t\t\t\tundoGroupExists: true,\n\t\t\t}\n\n\t\t\tthis.engine.scheduler.runBeforeNextFrame(() => {\n\t\t\t\tthis.engine.scheduler.processWhenReady(() => {\n\t\t\t\t\tthis.engine.setTool(Tools.RichTextEdit, options)\n\t\t\t\t})\n\t\t\t})\n\n\t\t\ttriggerTextCreateEvent({ isTextBox })\n\t\t}\n\t}\n\n\toverride update() {\n\t\tconst { mouseCursorStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = mouseStore.latest\n\t\tif (this.pastMinimumDrag(canvasMousePosition, canvasMouseDownPosition)) {\n\t\t\tmouseCursorStore.current = insertCursor\n\t\t} else {\n\t\t\tmouseCursorStore.current = \"text\"\n\t\t}\n\t\tthis.helper.update(this)\n\t}\n\n\tpastMinimumDrag(mouse: Point | null, mouseDown: Point | null) {\n\t\treturn (\n\t\t\tmouse !== null &&\n\t\t\tmouseDown !== null &&\n\t\t\t(Math.abs(mouse.x - mouseDown.x) >= minimumDrag || Math.abs(mouse.y - mouseDown.y) >= minimumDrag)\n\t\t)\n\t}\n\n\tisTextBox(frame: Rect) {\n\t\tconst zoom = this.engine.stores.canvasStore.zoom\n\t\treturn frame.width * zoom >= minimumDrag || frame.height * zoom >= minimumDrag / zoom\n\t}\n}\n", "import type { EngineStores } from \"document/EngineStores.ts\"\nimport { ActiveLeftPanel } from \"document/utils/ActiveEditorType.ts\"\n\nexport function isWireframerVisible(stores: EngineStores) {\n\treturn (\n\t\tstores.chromeStore.leftPanel === ActiveLeftPanel.Insert &&\n\t\tstores.insertSidebarStore.activeCategoryType === \"wireframer\"\n\t)\n}\n", "import type { Point } from \"library/render/types/Point.ts\"\n\ninterface Increments {\n\tsmallNudgeIncrement: number\n\tlargeNudgeIncrement: number\n}\n\nexport function getNudgeIncrement(largeNudge = false, { smallNudgeIncrement, largeNudgeIncrement }: Increments) {\n\treturn largeNudge ? largeNudgeIncrement : smallNudgeIncrement\n}\n\nexport function getNudgeDelta(\n\tkey: string,\n\tshiftKey: boolean,\n\t{ smallNudgeIncrement, largeNudgeIncrement }: Increments,\n): Partial<Point> | undefined {\n\tlet delta: ReturnType<typeof getNudgeDelta>\n\tconst increment = getNudgeIncrement(shiftKey, { smallNudgeIncrement, largeNudgeIncrement })\n\n\tswitch (key) {\n\t\tcase \"ArrowLeft\":\n\t\t\tdelta = { x: -increment }\n\t\t\tbreak\n\t\tcase \"ArrowUp\":\n\t\t\tdelta = { y: -increment }\n\t\t\tbreak\n\t\tcase \"ArrowRight\":\n\t\t\tdelta = { x: increment }\n\t\t\tbreak\n\t\tcase \"ArrowDown\":\n\t\t\tdelta = { y: increment }\n\t\t\tbreak\n\t}\n\n\treturn delta\n}\n\n/**\n * Given a number, getNearestNudgeIncrement returns the nearest increment step.\n * e.g:\n * number is 5, increment is 10, returns 10.\n * number is 15, increment is 10, returns 20.\n */\nexport function getNearestNudgeIncrement(\n\tvalue: number,\n\tshiftKey: boolean,\n\t{ smallNudgeIncrement, largeNudgeIncrement }: Increments,\n): number {\n\tconst increment = getNudgeIncrement(shiftKey, { smallNudgeIncrement, largeNudgeIncrement })\n\n\t// For example, if the increment is 10, then:\n\t// if the number is 3 then round to 10\n\t// if the number is 13, then round the 20\n\t// etc\n\treturn Math.ceil(value / increment) * increment\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { ScopeNode, isVectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { shouldBlockSelectionInOverlayEditMode } from \"document/models/CanvasTree/nodes/utils/overlayHelpers.ts\"\nimport type { WithChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { isLockedOrLockedByParent, withLock } from \"document/models/CanvasTree/traits/WithLock.ts\"\nimport { isRotatedAndNotAxisAligned, withRotation } from \"document/models/CanvasTree/traits/WithRotation.ts\"\nimport { isMasterOrReplicaChild, isReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isReplicaVariantChild, isVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { isSymbolReplica } from \"document/models/CanvasTree/traits/utils/isSymbol.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\n\nexport function isSelectable({\n\tnode,\n\tengine,\n\tcmdKey,\n\tdoubleClick = false,\n\tuseDirectSelect = true,\n}: {\n\tnode: CanvasNode\n\tengine: VekterEngine\n\tcmdKey: boolean\n\tdoubleClick?: boolean\n\tuseDirectSelect?: boolean\n}): boolean {\n\tconst { tree } = engine\n\tif (!node.cache.visible) return false\n\tif (isLockedOrLockedByParent(node)) return false\n\n\tconst { selectionStore, overlayStore } = engine.stores\n\n\t// if (node.isSelected()) return true\n\t// @FIXME: we used to check if the node is selected by looking at the node cache,\n\t// but for selection updates from CanvasEventTarget, the node cache might not be updated in time,\n\t// result in the highlight not being cleared when the selection is changed by double click.\n\t// (for example, when you double click to select a descendant of a shape group)\n\t// We use engine.stores.selectionStore.ids as a temporary solution as the upcoming canvas isolation will probably refactor the cache logic\n\tif (selectionStore.ids.includes(node.id)) return true\n\n\t// ground nodes are not selectable, unless they are empty, rotated, user components, or shape containers\n\tif (tree.isGroundNode(node)) {\n\t\treturn isGroundNodeSelectable(node, useDirectSelect) || cmdKey\n\t}\n\n\t// TODO: we need to change this logic when we implement on canvas editing of slot content.\n\tif (node.cache.slotPropertyAncestorId) return false\n\n\tif (\n\t\tshouldBlockSelectionInOverlayEditMode(overlayStore.activeOverlays, overlayStore.activeRelativeOverlayTriggers, node)\n\t) {\n\t\treturn false\n\t}\n\n\tconst parent = tree.getParent(node.id)\n\n\tif (isVectorNode(node)) {\n\t\tif (!isVectorNodeSelectable(parent, cmdKey, doubleClick)) return false\n\t}\n\n\tif (!useDirectSelect) {\n\t\treturn isSelectableBreadthFirst(node, engine, cmdKey, doubleClick)\n\t}\n\n\tif (selectionStore.isSticky) {\n\t\tif (doubleClick && !cmdKey) {\n\t\t\treturn !!parent && parent.isSelected()\n\t\t}\n\n\t\tfor (const ancestor of node.ancestors()) {\n\t\t\tif (ancestor.isSelected()) return false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunction isSelectableBreadthFirst(\n\tnode: CanvasNode,\n\tengine: VekterEngine,\n\tcmdKey: boolean,\n\tdoubleClick: boolean = false,\n): boolean {\n\tif (cmdKey) return true\n\n\tconst { tree } = engine\n\tconst parent = tree.getParent(node.id)\n\n\tconst { selectionStore } = engine.stores\n\n\tfor (const selectedId of selectionStore.ids) {\n\t\tconst selectedNode = engine.tree.getNode(selectedId)\n\t\tif (!selectedNode) continue\n\t\tfor (const ancestor of selectedNode.ancestors()) {\n\t\t\tif (node.parentid === ancestor.id) return true\n\t\t}\n\n\t\tif (doubleClick) {\n\t\t\tif (node.parentid === selectedNode.id) return true\n\t\t}\n\t}\n\n\tif (\n\t\tparent &&\n\t\tengine.tree.isGroundNode(parent) &&\n\t\t!isRotatedAndNotAxisAligned(parent) &&\n\t\t!selectionStore.ids.includes(parent.id) &&\n\t\t!isMasterOrReplicaChild(node)\n\t) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nexport function isSelectableInRect(\n\tnode: CanvasNode,\n\tdragSelectRect: Rect,\n\tengine: VekterEngine,\n\tselectableNodeCache: Set<NodeID>,\n\tuseDirectSelection: boolean = true,\n) {\n\tconst { tree } = engine\n\tif (!node.isVisible() || (withLock(node) && node.locked)) {\n\t\treturn false\n\t}\n\tconst { overlayStore } = engine.stores\n\n\tif (\n\t\tshouldBlockSelectionInOverlayEditMode(overlayStore.activeOverlays, overlayStore.activeRelativeOverlayTriggers, node)\n\t) {\n\t\treturn false\n\t}\n\n\t// exclude ground frames, unless they are empty, rotated, or completely wrapped in the dragging rect\n\tif (tree.isGroundNode(node)) {\n\t\treturn isGroundNodeSelectable(node, useDirectSelection) || Rect.containsRect(dragSelectRect, tree.getRect(node))\n\t}\n\n\t// don't select descendants of an hidden frame\n\tconst ancestors = tree.getAncestors(node.id).map(ancestorId => {\n\t\treturn tree.getNode(ancestorId)!\n\t})\n\tconst invisibleAncestor = ancestors.find(ancestor => {\n\t\tif (ancestor instanceof ScopeNode) return false\n\t\treturn !ancestor.isVisible()\n\t})\n\tif (invisibleAncestor !== undefined) {\n\t\treturn false\n\t}\n\n\t// disable drag-select for replica descendants\n\tif (isReplicaChild(node) && !isReplicaVariantChild(node)) return false\n\n\t// (when using breadth first selection) allow drag-select everything if cmdKey is down,\n\t// otherwise pick from the selectable nodes.\n\tif (!useDirectSelection && !engine.stores.mouseStore.latest.cmdKey) {\n\t\treturn selectableNodeCache.has(node.id)\n\t}\n\n\treturn true\n}\n\nfunction isGroundNodeSelectable(groundNode: CanvasNode, useDirectSelection: boolean = true): boolean {\n\tif (isVectorNode(groundNode)) return true\n\n\treturn (\n\t\t!groundNode.children ||\n\t\tgroundNode.children.length === 0 ||\n\t\tisSymbolReplica(groundNode) ||\n\t\t(withRotation(groundNode) && groundNode.resolveValue(\"rotation\") !== 0) ||\n\t\t(!useDirectSelection && isVariant(groundNode))\n\t)\n}\n\nfunction isVectorNodeSelectable(parent: (CanvasNode & WithChildren) | null, cmdKey: boolean, doubleClick: boolean) {\n\t// 1. direct select with cmd key is always possible\n\tif (cmdKey) return true\n\n\t// 2. double click should only select one level deeper (by checking is the parent selected)\n\tif (doubleClick && parent && parent.isSelected()) return true\n\n\tif (!parent) return false\n\n\t// 3. top level shapes should be directly selectable, or it has at least one selected sibling\n\treturn !isVectorNode(parent) || descendantInSelection(parent)\n}\n\nfunction descendantInSelection(node: CanvasNode) {\n\tlet inSelection = false\n\tfunction checkChildren(children: Iterable<CanvasNode> | undefined) {\n\t\tif (inSelection || !children) return\n\t\tfor (const child of children) {\n\t\t\tif (child.isSelected()) {\n\t\t\t\tinSelection = true\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcheckChildren(child.children)\n\t\t}\n\t}\n\tcheckChildren(node.children)\n\treturn inSelection\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { getVisuallyOrderedNodes } from \"document/models/CanvasTree/getVisuallyOrderedNodes.ts\"\nimport { type CanvasNode, FrameNode, type NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { MaybeCanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport { isFrameNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { hasLayoutTemplate } from \"document/models/CanvasTree/traits/WithLayoutTemplate.ts\"\nimport { type IsBreakpoint, isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { Polygon } from \"library/index.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport { isSelectable } from \"./isSelectable.ts\"\n\nexport function getSelectableTopNodeAtPoint({\n\tpoint,\n\tengine,\n\tdoubleClick,\n\t// Some tools use this as a precision picker and should ignore the user's canvas selection preference.\n\tuseDirectSelect,\n}: {\n\tpoint: Point\n\tengine: VekterEngine\n\tdoubleClick: boolean\n\tuseDirectSelect?: boolean\n}): MaybeCanvasNode {\n\tconst { tree } = engine\n\tconst { selectionStore, canvasStore, persistedUserDefaults, scopeStore, mouseStore } = engine.stores\n\tconst { cmdKey, shiftKey } = mouseStore.latest\n\tconst visibleCanvasFrame = canvasStore.getCanvasVisibleRect()\n\tconst shouldUseDirectSelect = useDirectSelect ?? persistedUserDefaults.useDirectSelect\n\n\tconst activeScope = scopeStore.active\n\n\tlet nodesAtPoint = tree.getNodesAtPoint(activeScope, point, true, canvasStore.zoom < 4, visibleCanvasFrame)\n\n\tif (shouldUseDirectSelect && shiftKey && cmdKey) {\n\t\t// only select siblings\n\t\tif (selectionStore.ids.length > 0) {\n\t\t\tnodesAtPoint = nodesAtPoint.filter(node => {\n\t\t\t\tconst siblings = tree.getSiblingsIncludingSelf(node)\n\t\t\t\treturn siblings.some(sibling => selectionStore.ids.includes(sibling.id))\n\t\t\t})\n\t\t}\n\t}\n\n\tconst selectableNodes: CanvasNode[] = []\n\tconst overrides: Record<NodeID, CanvasNode[]> = {}\n\tconst nodeForLayoutTemplateSelector = new Map<string, CanvasNode & IsBreakpoint>()\n\tfor (const node of nodesAtPoint) {\n\t\tif (isFrameNode(node) && isBreakpointVariant(node)) {\n\t\t\tconst scope = tree.getScopeNodeFor(node)\n\t\t\tif (hasLayoutTemplate(scope)) {\n\t\t\t\tconst { selectors, pseudoSelectorNodesUnderPoint } = getLayoutTemplateBoxes(node, point)\n\t\t\t\toverrides[node.id] = pseudoSelectorNodesUnderPoint\n\t\t\t\tselectableNodes.push(...pseudoSelectorNodesUnderPoint)\n\t\t\t\tselectors.forEach(s => nodeForLayoutTemplateSelector.set(s, node))\n\t\t\t}\n\t\t}\n\n\t\tif (!isSelectable({ node, engine, cmdKey, useDirectSelect: shouldUseDirectSelect, doubleClick })) continue\n\t\tselectableNodes.push(node)\n\t}\n\n\tconst visuallyOrderedNodes = getVisuallyOrderedNodes(selectableNodes, tree, overrides)\n\tconst topMostChildNode = visuallyOrderedNodes[visuallyOrderedNodes.length - 1]\n\tif (!topMostChildNode) return null\n\tconst layoutTemplateSelectorBreakpoint = nodeForLayoutTemplateSelector.get(topMostChildNode?.id)\n\tconst selectableTopNode = layoutTemplateSelectorBreakpoint ?? topMostChildNode\n\n\tif (shouldUseDirectSelect && cmdKey && selectableTopNode) {\n\t\tconst selectableAncestorId = tree.getAncestors(selectableTopNode.id).find(ancestorId => {\n\t\t\treturn selectableNodes.some(selectableNode => selectableNode.id === ancestorId)\n\t\t})\n\n\t\tconst selectableAncestor = selectableAncestorId ? tree.getNode(selectableAncestorId) : null\n\t\tif (selectableAncestor) return selectableAncestor\n\t}\n\n\treturn selectableTopNode\n}\n\n/**\n * Determine if the cursor is over a fixed layout template layer.\n */\nfunction getLayoutTemplateBoxes(node: CanvasNode & IsBreakpoint, point: Point) {\n\tconst pseudoSelectorNodesUnderPoint: CanvasNode[] = []\n\tconst selectors = new Set<string>()\n\n\tif (!node.cache.layoutTemplateRects) return { pseudoSelectorNodesUnderPoint, selectors }\n\n\tfor (const [selector, info] of node.cache.layoutTemplateRects) {\n\t\tif (!info.canvasCorners) continue\n\n\t\tif (!Polygon.containsPoint(info.canvasCorners, point)) continue\n\n\t\t// LAYOUT_TEMPLATE @TODO - Design a way to sort without needing a CanvasNode type OR\n\t\t// cache it so that we don't have to create / garbage collect it\n\t\t// over and over again.\n\t\tconst nodeAtPoint = new FrameNode({\n\t\t\tzIndex: info.domRect.zIndex,\n\t\t\tid: selector,\n\t\t\tparentid: node.id,\n\t\t})\n\n\t\tselectors.add(selector)\n\t\tpseudoSelectorNodesUnderPoint.push(nodeAtPoint)\n\t}\n\n\treturn {\n\t\tpseudoSelectorNodesUnderPoint,\n\t\tselectors,\n\t}\n}\n", "import { triggerRulersDeleteGuideEvent, triggerRulersMoveGuideEvent } from \"@framerjs/framer-events\"\nimport { dimensions } from \"@framerjs/fresco/tokens\"\nimport { ReadonlySet, isCommandKeyPressed } from \"@framerjs/shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { updateNodeSizeForEach } from \"document/components/utils/dimensions.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { isGridComponent, isStackComponent } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { withFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { hasFloatingPosition } from \"document/models/CanvasTree/traits/WithFloatingPosition.ts\"\nimport type { GuideSelector } from \"document/models/CanvasTree/traits/WithGuides.ts\"\nimport {\n\tclosestGuideInRange,\n\tgetGuideNode,\n\tgetGuides,\n\tgetGuidesKey,\n\tisEqualGuide,\n} from \"document/models/CanvasTree/traits/WithGuides.ts\"\nimport { withOpacity } from \"document/models/CanvasTree/traits/WithOpacity.ts\"\nimport { isPositionRelative } from \"document/models/CanvasTree/traits/utils/positionTypeHelpers.ts\"\nimport { getConstraintsLocked } from \"document/models/CanvasTree/utils/getConstraintsLocked.ts\"\nimport { isTokenCSSVariable } from \"document/models/CanvasTree/utils/tokens.ts\"\nimport { shouldGuessPinToBottom } from \"document/models/shouldGuessPinToBottom.ts\"\nimport { shouldGuessPinToRight } from \"document/models/shouldGuessPinToRight.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { ActiveLeftPanel, ActiveRightPanel } from \"document/utils/ActiveEditorType.ts\"\nimport { ConvertColor } from \"library/render/types/Color/ConvertColor.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type { Size } from \"library/render/types/Size.ts\"\nimport { addCursor } from \"utils/cursor.ts\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\nimport { isNumber, isString } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { isWireframerVisible } from \"../chrome/insertSidebar/utils/isWireframerOpen.ts\"\nimport { isRichTextSource } from \"../chrome/localization/getLocalizationSources.ts\"\nimport { getLocalizationSourcesForNode } from \"../chrome/localization/getLocalizationSourcesForNode.ts\"\nimport { ContextAction, canDeleteOrHideNode } from \"../utils/contextActions.ts\"\nimport type { MoveToolOptions } from \"./MoveTool.ts\"\nimport { getNudgeDelta } from \"./utils/getNudgeDelta.ts\"\nimport { getSelectableTopNodeAtPoint } from \"./utils/getSelectableTopNodeAtPoint.ts\"\n\nconst numberStrings = new Set(\"0123456789\")\n\nexport class HighlightTool extends withClassDiscriminator(\"HighlightTool\", VekterTool) {\n\toverride readonly enum: Tools.Highlight | Tools.DirectSelect = Tools.Highlight\n\n\t// Last number key pressed to support numbers entered in succession\n\tlastNumberKey?: number\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = true\n\toverride displayPaddingHandles = true\n\toverride displayGapHandles = true\n\toverride displayViewportHandle = true\n\toverride cmsBadge: \"visible\" | \"hidden\" | \"disabled\" = \"visible\"\n\n\toverride start() {\n\t\tthis.update()\n\t}\n\n\toverride stop() {}\n\n\toverride update() {\n\t\tconst { mouseCursorStore, treeStore, mouseStore, persistedUserDefaults, scopeStore, canvasStore } =\n\t\t\tthis.engine.stores\n\t\tconst { previous: state, latest } = mouseStore\n\t\tconst { canvasMousePosition, windowMousePosition, canvasMouseDownPosition, spacebar, altKey, cmdKey, shiftKey } =\n\t\t\tlatest\n\t\tconst { windowMiddleMouseButtonDownPosition } = mouseStore\n\n\t\tif (spacebar || windowMiddleMouseButtonDownPosition) {\n\t\t\tthis.engine.setTool(Tools.Pan)\n\t\t\treturn\n\t\t}\n\n\t\t// no mouse change\n\t\tconst isMouseChange =\n\t\t\tmouseDidMove(canvasMousePosition, state.canvasMousePosition) ||\n\t\t\tstate.cmdKey !== cmdKey ||\n\t\t\tstate.altKey !== altKey ||\n\t\t\tstate.canvasMouseDownPosition !== canvasMouseDownPosition ||\n\t\t\tstate.shiftKey !== shiftKey\n\t\tif (!canvasMousePosition || !isMouseChange) return\n\n\t\tconst cmdKeyDown = cmdKey\n\t\tconst cmdKeyUp = !cmdKey\n\t\tif (this.enum === Tools.Highlight && cmdKeyDown) {\n\t\t\tthis.engine.setTool(Tools.DirectSelect)\n\t\t\treturn\n\t\t}\n\t\tif (this.enum === Tools.DirectSelect && cmdKeyUp) {\n\t\t\tthis.engine.setTool(Tools.Highlight)\n\t\t\treturn\n\t\t}\n\n\t\tconst { displayRulers } = persistedUserDefaults\n\t\tif (displayRulers) {\n\t\t\tconst closestGuide = closestGuideInRange(treeStore.tree, scopeStore.active, canvasMousePosition, canvasStore.zoom)\n\n\t\t\tif (closestGuide) {\n\t\t\t\tthis.handleMouseOnGuide(closestGuide)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (this.isMouseOnRulers(windowMousePosition)) {\n\t\t\t\tthis.handleMouseOnRulers()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tmouseCursorStore.clear() // reset cursor from guide\n\n\t\tconst node = getSelectableTopNodeAtPoint({\n\t\t\tpoint: canvasMousePosition,\n\t\t\tengine: this.engine,\n\t\t\tdoubleClick: false,\n\t\t})\n\t\tif (node) {\n\t\t\tthis.handleMouseOnSelectableTopNode(node)\n\t\t\treturn\n\t\t}\n\n\t\tthis.handleMouseOnVoid()\n\t}\n\n\toverride onKeyDown = (event: KeyboardEvent) => {\n\t\tconst engine = this.engine\n\t\tconst { guidesStore, siteSettingsStore, selectionStore } = engine.stores\n\t\tif (getIsViewOnly(engine, \"canDesign\") || siteSettingsStore.isOpen) return\n\t\tconst { displayRulers } = engine.stores.persistedUserDefaults\n\n\t\tif (displayRulers && guidesStore.selected) {\n\t\t\tthis.handleKeyEventOnGuide(event, guidesStore.selected)\n\t\t\treturn\n\t\t}\n\n\t\tthis.handleKeyEventOnNode(event, selectionStore.ids)\n\t}\n\n\tnewOpacity(requestedOpacity: number, currentOpacity?: number) {\n\t\tif (currentOpacity === undefined) {\n\t\t\treturn\n\t\t}\n\t\tlet newOpacity = requestedOpacity\n\t\tif (currentOpacity < 1 && requestedOpacity === 0) {\n\t\t\tnewOpacity = 1 // Toggle\n\t\t}\n\t\treturn newOpacity\n\t}\n\n\tisMouseOnRulers = (mouseRaw: Point) => {\n\t\tconst { layoutState, persistedUserDefaults, mouseStore } = this.engine.stores\n\t\tconst { isMouseOnCanvas } = mouseStore.latest\n\t\tconst { displayRulers } = persistedUserDefaults\n\t\treturn (\n\t\t\tdisplayRulers &&\n\t\t\tisMouseOnCanvas &&\n\t\t\t(mouseRaw.x < layoutState.currentChromeMarginLeft + dimensions.values.rulerWidth ||\n\t\t\t\tmouseRaw.y < layoutState.currentChromeMarginTop + dimensions.values.rulerWidth)\n\t\t)\n\t}\n\n\thandleMouseOnRulers = () => {\n\t\t// Handle view-only mode.\n\t\tif (getIsViewOnly(this.engine, \"canDesign\")) return\n\n\t\tconst { selectionStore, mouseCursorStore, treeStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMouseDownPosition } = mouseStore.latest\n\n\t\tif (canvasMouseDownPosition) {\n\t\t\t// create new guide\n\t\t\tselectionStore.clear()\n\t\t\tthis.selectGuide()\n\t\t\tthis.engine.setTool(Tools.Guide)\n\t\t} else {\n\t\t\tmouseCursorStore.current = addCursor\n\t\t\ttreeStore.setHighlight(null)\n\t\t\tthis.highlightGuide()\n\t\t}\n\t}\n\n\thandleMouseOnGuide = (closestGuide: GuideSelector) => {\n\t\tconst { selectionStore, mouseCursorStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMouseDownPosition } = mouseStore.latest\n\t\t// Handle view-only mode.\n\t\tconst isViewOnly = getIsViewOnly(this.engine, \"canDesign\")\n\n\t\tif (canvasMouseDownPosition) {\n\t\t\t// move an existing guide\n\t\t\tselectionStore.clear()\n\t\t\tthis.selectGuide(closestGuide)\n\t\t\tif (!isViewOnly) this.engine.setTool(Tools.Guide)\n\t\t} else {\n\t\t\tif (!isViewOnly) {\n\t\t\t\tconst cursor = closestGuide.axis === \"x\" ? \"ew-resize\" : \"ns-resize\"\n\t\t\t\tmouseCursorStore.current = cursor\n\t\t\t}\n\t\t\tthis.highlightGuide(closestGuide)\n\t\t}\n\t}\n\n\thandleMouseOnSelectableTopNode = (node: CanvasNode) => {\n\t\tconst { selectionStore, chromeStore, treeStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMouseDownPosition, shiftKey, altKey, cmdKey } = mouseStore.latest\n\t\tconst moveFromAnywhereEnabled = altKey && cmdKey\n\n\t\t// NOTE: This logic used to be in the ToolManager, misses some logic around icons\n\t\tif (canvasMouseDownPosition) {\n\t\t\tif (chromeStore.isPreviewingLocaleOnCanvas) {\n\t\t\t\tselectionStore.set(node.id, { sticky: cmdKey, switchToLayers: true, switchToProperties: true })\n\t\t\t\ttreeStore.setHighlight(null)\n\n\t\t\t\tthis.engine.setTool(Tools.Move, {\n\t\t\t\t\tmoveToolDidExitWithoutMoving: () => {\n\t\t\t\t\t\tconst latestNode = this.engine.tree.current(node)\n\t\t\t\t\t\tif (!latestNode) return\n\n\t\t\t\t\t\tconst sources = getLocalizationSourcesForNode(node, this.engine)\n\t\t\t\t\t\tif (sources.length !== 1) return\n\n\t\t\t\t\t\tconst [source] = sources\n\t\t\t\t\t\tif (!isRichTextSource(source)) return\n\n\t\t\t\t\t\tchromeStore.setOverlay({\n\t\t\t\t\t\t\ttype: \"localization\",\n\t\t\t\t\t\t\tkeyPath: source.keyPath,\n\t\t\t\t\t\t\tsingleColumn: true,\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t})\n\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst id = node.id\n\n\t\t\tlet moveToolDidExitWithoutMoving: MoveToolOptions[\"moveToolDidExitWithoutMoving\"]\n\t\t\tif (!moveFromAnywhereEnabled) {\n\t\t\t\tconst elementPartOfSelection = selectionStore.ids.includes(id)\n\n\t\t\t\tif (shiftKey) {\n\t\t\t\t\tif (elementPartOfSelection) {\n\t\t\t\t\t\t// We postpone toggling the selection because if the\n\t\t\t\t\t\t// user started a drag we don't want to deselect the\n\t\t\t\t\t\t// layer.\n\t\t\t\t\t\tmoveToolDidExitWithoutMoving = () => {\n\t\t\t\t\t\t\tselectionStore.toggle(id, { switchToLayers: true, switchToProperties: true })\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectionStore.toggle(id, { switchToLayers: true, switchToProperties: true })\n\t\t\t\t\t}\n\t\t\t\t} else if (elementPartOfSelection === false) {\n\t\t\t\t\tselectionStore.set(id, { sticky: cmdKey, switchToLayers: true, switchToProperties: true })\n\n\t\t\t\t\ttreeStore.setHighlight(null)\n\t\t\t\t}\n\n\t\t\t\tif (!elementPartOfSelection && !isWireframerVisible(this.engine.stores)) {\n\t\t\t\t\tchromeStore.removePanelOverrides()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Normally we switch back to the properties panel when the selection **changes** in\n\t\t\t// chromeStore.onCanvasSelectionChange. This is an edge case where we still want to\n\t\t\t// switch back to the properties panel when clicking again on a selected layer.\n\t\t\tif (experiments.isOn(\"agent\") && selectionStore.ids.includes(id)) {\n\t\t\t\tchromeStore.onCanvasSelectionChange(selectionStore.ids, false, true)\n\t\t\t}\n\n\t\t\tthis.engine.setTool(Tools.Move, { moveToolDidExitWithoutMoving })\n\t\t} else {\n\t\t\ttreeStore.setHighlight(node.id)\n\t\t}\n\t}\n\n\thandleMouseOnVoid = () => {\n\t\tconst {\n\t\t\tselectionStore,\n\t\t\tchromeStore,\n\t\t\tmouseCursorStore,\n\t\t\tmouseStore,\n\t\t\tscopeStore,\n\t\t\toverlayStore,\n\t\t\ttreeStore,\n\t\t\trepeaterStore,\n\t\t} = this.engine.stores\n\t\tconst { canvasMouseDownPosition, shiftKey, altKey, cmdKey } = mouseStore.latest\n\t\tconst moveFromAnywhereEnabled = altKey && cmdKey\n\n\t\tif (canvasMouseDownPosition) {\n\t\t\tif (moveFromAnywhereEnabled) {\n\t\t\t\tthis.engine.setTool(Tools.Move)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!shiftKey) {\n\t\t\t\tselectionStore.clear()\n\t\t\t\tthis.selectGuide()\n\n\t\t\t\t// Only exit editing modes if the mouse is not over any nodes (canvas backdrop)\n\t\t\t\tconst nodesUnderMouse = this.engine.tree.getNodesAtPoint(scopeStore.active, canvasMouseDownPosition)\n\t\t\t\tif (nodesUnderMouse.length === 0) {\n\t\t\t\t\toverlayStore.hideAll()\n\t\t\t\t\trepeaterStore.exitEditMode(selectionStore)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.engine.setTool(Tools.Select)\n\n\t\t\t// If the left panel is the insert panel and Wireframer is open we don't want to remove the panel overrides\n\t\t\tif (!isWireframerVisible(this.engine.stores)) {\n\t\t\t\tchromeStore.removePanelOverrides()\n\t\t\t}\n\t\t} else {\n\t\t\tmouseCursorStore.clear()\n\t\t\ttreeStore.setHighlight(null)\n\t\t\tthis.highlightGuide()\n\t\t}\n\t}\n\n\thandleKeyEventOnGuide = (event: KeyboardEvent, selectedGuide: GuideSelector) => {\n\t\tif (this.engine.stores.chromeStore.isPreviewingLocaleOnCanvas) return\n\n\t\tconst { key, shiftKey } = event\n\n\t\tif (key === \"Escape\") {\n\t\t\tthis.selectGuide()\n\t\t} else if ((key === \"Backspace\" || key === \"Delete\") && !isCommandKeyPressed(event)) {\n\t\t\tthis.deleteAction()\n\t\t\tevent.preventDefault() // make sure the webview does not navigate back\n\t\t} else if (key === \"ArrowUp\" || key === \"ArrowDown\" || key === \"ArrowLeft\" || key === \"ArrowRight\") {\n\t\t\tconst delta = getNudgeDelta(key, shiftKey, this.engine.stores.persistedUserDefaults)\n\t\t\tif (delta) {\n\t\t\t\tthis.moveSelectedGuide(selectedGuide, delta)\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t}\n\n\t\tevent.stopPropagation()\n\t}\n\n\thandleKeyEventOnNode = (event: KeyboardEvent, selection: string[]) => {\n\t\tconst { key } = event\n\t\tconst engine = this.engine\n\t\tconst { tree } = engine\n\n\t\tconst { overlayStore, chromeStore, selectionStore, persistedUserDefaults, treeStore, mouseStore } = engine.stores\n\t\tconst { cmdKey, shiftKey } = mouseStore.latest\n\n\t\tif (key === \"Enter\" && shiftKey && !cmdKey) {\n\t\t\tContextAction.selectAncestor(engine, selection, \"parent\")\n\t\t\treturn\n\t\t}\n\n\t\tif (key === \"Escape\") {\n\t\t\tif (chromeStore.leftPanel !== ActiveLeftPanel.Canvas || chromeStore.rightPanel !== ActiveRightPanel.Canvas) {\n\t\t\t\tchromeStore.removePanelOverrides()\n\t\t\t\ttreeStore.setHighlight(null)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (ContextAction.selectAncestor(engine, selection, cmdKey ? \"groundNode\" : \"parent\")) return\n\n\t\t\tif (selectionStore.ids.length) {\n\t\t\t\tselectionStore.clear()\n\t\t\t} else if (overlayStore.editModeActive) {\n\t\t\t\toverlayStore.exitEditMode(selectionStore)\n\t\t\t}\n\t\t\ttreeStore.setHighlight(null)\n\t\t}\n\n\t\tif (chromeStore.isPreviewingLocaleOnCanvas) return\n\n\t\tif ((key === \"Backspace\" || key === \"Delete\") && !isCommandKeyPressed(event)) {\n\t\t\tthis.deleteAction()\n\t\t\tevent.preventDefault()\n\t\t}\n\n\t\t// Arrow keys\n\t\tif (key === \"ArrowUp\" || key === \"ArrowDown\" || key === \"ArrowLeft\" || key === \"ArrowRight\") {\n\t\t\tconst delta = getNudgeDelta(key, event.shiftKey, persistedUserDefaults)\n\t\t\tif (delta && !(event.altKey && isCommandKeyPressed(event))) {\n\t\t\t\tconst withoutDescendants = tree.withoutDescendants(tree.getNodes(selection))\n\t\t\t\tif (isCommandKeyPressed(event)) {\n\t\t\t\t\tengine.setEditReason(\"resize\")\n\t\t\t\t\tupdateNodeSizeForEach(engine, withoutDescendants, (currentSize: Size) => {\n\t\t\t\t\t\tconst result: Partial<Size> = {}\n\n\t\t\t\t\t\tif (delta !== undefined) {\n\t\t\t\t\t\t\tif (delta.x !== undefined) {\n\t\t\t\t\t\t\t\tresult.width = currentSize.width + delta.x\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (delta.y !== undefined) {\n\t\t\t\t\t\t\t\tresult.height = currentSize.height + delta.y\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn result\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tconst allNodesArePositionRelativeParentDirected = withoutDescendants.every(node =>\n\t\t\t\t\t\tisPositionRelative(node, engine.tree.getParent(node.id)),\n\t\t\t\t\t)\n\n\t\t\t\t\t// Move items through stack\n\t\t\t\t\tif (allNodesArePositionRelativeParentDirected) {\n\t\t\t\t\t\tconst commonParent = tree.getCommonParent(withoutDescendants)\n\t\t\t\t\t\tconst horizontalLayoutDirection = engine.tree.root.getHorizontalLayoutDirection()\n\t\t\t\t\t\tconst horizontalLayoutDirectionMultiplier = horizontalLayoutDirection === \"ltr\" ? 1 : -1\n\t\t\t\t\t\tconst deltaX = (delta.x ?? 0) * horizontalLayoutDirectionMultiplier\n\t\t\t\t\t\tconst deltaY = delta.y ?? 0\n\t\t\t\t\t\tengine.setEditReason(\"order\")\n\t\t\t\t\t\tif (isStackComponent(commonParent)) {\n\t\t\t\t\t\t\tconst isVertical = commonParent.stackDirection === \"vertical\"\n\t\t\t\t\t\t\tconst direction = isVertical ? deltaY : deltaX\n\n\t\t\t\t\t\t\tif (direction < 0) {\n\t\t\t\t\t\t\t\tContextAction.sendBackward(this.engine, withoutDescendants)\n\t\t\t\t\t\t\t} else if (direction > 0) {\n\t\t\t\t\t\t\t\tContextAction.sendForward(this.engine, withoutDescendants)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (isGridComponent(commonParent)) {\n\t\t\t\t\t\t\tconst direction = deltaX + deltaY\n\n\t\t\t\t\t\t\tif (direction < 0) {\n\t\t\t\t\t\t\t\tContextAction.sendBackward(this.engine, withoutDescendants)\n\t\t\t\t\t\t\t} else if (direction > 0) {\n\t\t\t\t\t\t\t\tContextAction.sendForward(this.engine, withoutDescendants)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tengine.setEditReason(\"nudge\")\n\t\t\t\t\t\twithoutDescendants.forEach(node => {\n\t\t\t\t\t\t\tif (hasFloatingPosition(node)) {\n\t\t\t\t\t\t\t\t// When nudging a relative overlay, directly\n\t\t\t\t\t\t\t\t// apply the delta to the offset instead of\n\t\t\t\t\t\t\t\t// going through `updateForRect`, which can\n\t\t\t\t\t\t\t\t// impact an offset that wasn't nudged due to\n\t\t\t\t\t\t\t\t// alignment and rounding.\n\t\t\t\t\t\t\t\tnode.set({\n\t\t\t\t\t\t\t\t\tfloatingOffsetX: (node.floatingOffsetX ?? 0) + (delta.x ?? 0),\n\t\t\t\t\t\t\t\t\tfloatingOffsetY: (node.floatingOffsetY ?? 0) + (delta.y ?? 0),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst parent = tree.getParent(node.id)\n\t\t\t\t\t\t\t\tconst newRect = Rect.offset(tree.getRect(node), delta)\n\t\t\t\t\t\t\t\tconst nodeUpdate = node.updateForRect({\n\t\t\t\t\t\t\t\t\trect: newRect,\n\t\t\t\t\t\t\t\t\tparentSizeInfo: tree.getParentSizeInfo(node),\n\t\t\t\t\t\t\t\t\tconstraintsLocked: getConstraintsLocked(node),\n\t\t\t\t\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, node),\n\t\t\t\t\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, node, parent),\n\t\t\t\t\t\t\t\t\t// When an element had a percentage width/height and a max-width/height set,\n\t\t\t\t\t\t\t\t\t// by using the arrow keys in the position panel the size would\n\t\t\t\t\t\t\t\t\t// change. This makes sure it does not happen.\n\t\t\t\t\t\t\t\t\tupdateSize: false,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tnode.set(nodeUpdate)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t}\n\n\t\t// All shortcuts below only use shift as a modifier\n\t\tif (isCommandKeyPressed(event)) {\n\t\t\treturn\n\t\t}\n\n\t\t// Number keys\n\t\tlet num: number | undefined\n\t\tif (numberStrings.has(key)) {\n\t\t\tnum = parseInt(key)\n\t\t}\n\t\tif (num !== undefined) {\n\t\t\t// Don't allow holding down a number to set color / opacity\n\t\t\tif (event.repeat) return\n\t\t\t// Also support entering 2 numbers in succession\n\t\t\tlet value = num * 10\n\t\t\tif (this.lastNumberKey !== undefined) {\n\t\t\t\tvalue = this.lastNumberKey * 10 + num\n\t\t\t}\n\t\t\tthis.lastNumberKey = num\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.lastNumberKey = undefined\n\t\t\t}, 300)\n\n\t\t\tif (event.shiftKey) {\n\t\t\t\tengine.setEditReason(\"color\")\n\t\t\t\ttree.getNodesWithTrait(selection, withFill).forEach(node => {\n\t\t\t\t\tif (!isString(node.fillColor) || isTokenCSSVariable(node.fillColor)) return\n\t\t\t\t\tconst newOpacity = this.newOpacity(value / 100, ConvertColor.getAlpha(node.fillColor))\n\t\t\t\t\tif (!isNumber(newOpacity)) return\n\t\t\t\t\tnode.set({ fillColor: ConvertColor.setAlpha(node.fillColor, newOpacity) })\n\t\t\t\t})\n\t\t\t\t// TODO: Should also do it for text colors\n\t\t\t} else {\n\t\t\t\tengine.setEditReason(\"opacity\")\n\t\t\t\tengine.tree.getNodesWithTrait(selection, withOpacity).forEach(node => {\n\t\t\t\t\tif (isDynamicValue(node.opacity)) return\n\n\t\t\t\t\tconst newOpacity = this.newOpacity(value / 100, node.opacity)\n\t\t\t\t\tif (!isNumber(newOpacity)) return\n\n\t\t\t\t\tnode.set({ opacity: newOpacity })\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tevent.stopPropagation()\n\t\t}\n\t}\n\n\toverride canDelete = (): boolean => {\n\t\tconst { guidesStore, selectionStore } = this.engine.stores\n\t\tif (guidesStore.selected) return true\n\t\tconst nodes = this.engine.tree.getNodes(selectionStore.ids)\n\t\treturn nodes.some(n => canDeleteOrHideNode(n))\n\t}\n\n\toverride deleteAction = () => {\n\t\tconst { guidesStore, selectionStore } = this.engine.stores\n\t\tif (guidesStore.selected) return this.deleteSelectedGuide(guidesStore.selected)\n\n\t\tconst engine = this.engine\n\t\tconst selectedNodes = engine.tree.getNodes(selectionStore.ids)\n\t\tthis.engine.setEditReason(\"delete\")\n\t\tContextAction.deleteOrHideNodes(engine, selectedNodes, true)\n\t}\n\n\tselectGuide = (guide: GuideSelector | null = null) => {\n\t\tconst { guidesStore, persistedUserDefaults, selectionStore, treeStore } = this.engine.stores\n\t\tif (!persistedUserDefaults.displayRulers) return\n\n\t\t// cancel frame selection when a guide is selected\n\t\tif (guide) {\n\t\t\tguidesStore.selected = guide\n\t\t\tif (selectionStore.ids.length) selectionStore.clear()\n\t\t\tif (treeStore.highlight) treeStore.setHighlight(null)\n\t\t} else {\n\t\t\tguidesStore.clearSelected()\n\t\t}\n\t}\n\n\thighlightGuide = (guide: GuideSelector | null = null) => {\n\t\tconst { guidesStore, treeStore, persistedUserDefaults } = this.engine.stores\n\t\tconst { displayRulers } = persistedUserDefaults\n\t\tif (!displayRulers) return\n\n\t\tif (guide) {\n\t\t\t// don't highlight the selected one\n\t\t\tif (guidesStore.selected && isEqualGuide(guide, guidesStore.selected)) return\n\t\t\tguidesStore.highlighted = guide\n\t\t\t// clear frame highlight when a guide is highlighted\n\t\t\ttreeStore.setHighlight(null)\n\t\t} else {\n\t\t\tguidesStore.highlighted = undefined\n\t\t}\n\t}\n\n\tdeleteSelectedGuide = (selectedGuide: GuideSelector) => {\n\t\tconst guideNode = getGuideNode(this.engine.tree, selectedGuide)\n\t\tif (!guideNode) return\n\n\t\tthis.engine.setEditReason(\"delete_guide\")\n\t\tconst guides = getGuides(guideNode, selectedGuide.axis)\n\t\tconst nextGuides = [...ReadonlySet.remove(new Set(guides), selectedGuide.offset)]\n\t\tguideNode.set({ [getGuidesKey(selectedGuide.axis)]: nextGuides })\n\n\t\tthis.engine.stores.guidesStore.clearSelected()\n\t\ttriggerRulersDeleteGuideEvent({\n\t\t\tguideSelector: `${guideNode.id}-${selectedGuide.axis}-${selectedGuide.offset}`,\n\t\t\tmethod: \"menu\",\n\t\t})\n\t}\n\n\tmoveSelectedGuide = (selectedGuide: GuideSelector, delta: Partial<Point>) => {\n\t\tthis.engine.setEditReason(\"move_guide\")\n\t\tconst { guidesStore } = this.engine.stores\n\t\tconst guideNode = getGuideNode(this.engine.tree, selectedGuide)\n\t\tconst axisDelta = delta[selectedGuide.axis]\n\t\tif (guideNode && axisDelta) {\n\t\t\tconst guidesKey = getGuidesKey(selectedGuide.axis)\n\t\t\tconst previousGuides = getGuides(guideNode.draftOrCurrent(), selectedGuide.axis)\n\n\t\t\tconst newGuides = new Set(previousGuides)\n\t\t\tconst newOffset = selectedGuide.offset + axisDelta\n\n\t\t\t// if there is a ghost guide on the same place as the selected one,\n\t\t\t// don't delete the selected one.\n\t\t\tif (isEqualGuide(guidesStore.ghost, selectedGuide)) {\n\t\t\t\tnewGuides.add(newOffset)\n\t\t\t\tguidesStore.ghost = undefined\n\t\t\t} else {\n\t\t\t\tnewGuides.delete(selectedGuide.offset)\n\t\t\t\tnewGuides.add(newOffset)\n\t\t\t}\n\n\t\t\tconst nextGuides = Array.from(newGuides).sort((a, b) => a - b)\n\t\t\tguideNode.set({ [guidesKey]: nextGuides })\n\n\t\t\ttriggerRulersMoveGuideEvent({\n\t\t\t\tguideSelector: `${guideNode.id}-${selectedGuide.axis}-${newOffset}`,\n\t\t\t\tmethod: \"keyboard\",\n\t\t\t})\n\n\t\t\tconst newGuide = { ...selectedGuide, offset: newOffset }\n\t\t\tguidesStore.selected = newGuide\n\n\t\t\t// if the selected guide is moving onto an existing guide,\n\t\t\t// we leave a ghost guide at the same position to avoid killing the selected one at the next move before deselecting\n\t\t\tif (previousGuides.includes(newOffset)) {\n\t\t\t\tguidesStore.ghost = newGuide\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport class DirectSelectTool extends HighlightTool {\n\toverride readonly enum = Tools.DirectSelect\n}\n", "import { triggerCanvasPanEvent } from \"@framerjs/framer-events\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { disableAppPointerEvents, enableAppPointerEvents } from \"utils/appPointerEvents.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine } from \"./pathEdit/PathToolManager.tsx\"\n\nexport class PanTool extends withClassDiscriminator(\"PanTool\", VekterTool) {\n\toverride readonly enum = Tools.Pan\n\n\tpathEngine?: VekterPathEngine\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tstartScrollPoint!: Point\n\tstartSpacebar!: boolean\n\tstartMiddleButton!: Point | null\n\n\toverride start() {\n\t\tconst { canvasStore, mouseStore, mouseCursorStore } = this.engine.stores\n\t\tthis.startScrollPoint = canvasStore.offset\n\t\tthis.startSpacebar = mouseStore.spacebar\n\t\tthis.startMiddleButton = mouseStore.windowMiddleMouseButtonDownPosition\n\t\tmouseCursorStore.current = \"-webkit-grab\"\n\t\ttriggerCanvasPanEvent({})\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tenableAppPointerEvents()\n\t}\n\n\toverride update() {\n\t\tconst { mouseStore, mouseCursorStore, canvasStore } = this.engine.stores\n\t\tconst { windowMousePosition, windowMouseDownPosition, spacebar, windowMiddleMouseButtonDownPosition, previous } =\n\t\t\tmouseStore\n\n\t\tif (\n\t\t\t(!windowMouseDownPosition && this.startSpacebar && !spacebar) ||\n\t\t\t(this.startMiddleButton && !windowMiddleMouseButtonDownPosition)\n\t\t) {\n\t\t\tif (this.pathEngine) {\n\t\t\t\tthis.pathEngine.switchToDefault()\n\t\t\t} else {\n\t\t\t\tthis.engine.exitTool()\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\t// mouse up\n\t\tif (!windowMouseDownPosition && previous.windowMouseDownPosition) {\n\t\t\tmouseCursorStore.current = \"-webkit-grab\"\n\t\t}\n\n\t\tconst mouseRawPosition = windowMouseDownPosition || windowMiddleMouseButtonDownPosition\n\t\tif (!windowMousePosition || !mouseRawPosition) {\n\t\t\treturn\n\t\t}\n\n\t\t// mouse down\n\t\tif (windowMiddleMouseButtonDownPosition) {\n\t\t\tmouseCursorStore.current = \"-webkit-grabbing\"\n\t\t}\n\n\t\tif (!previous.windowMouseDownPosition && windowMouseDownPosition) {\n\t\t\tmouseCursorStore.current = \"-webkit-grabbing\"\n\t\t\tthis.startScrollPoint = canvasStore.offset\n\t\t}\n\n\t\tif (windowMouseDownPosition || windowMiddleMouseButtonDownPosition) {\n\t\t\tdisableAppPointerEvents()\n\t\t} else {\n\t\t\tenableAppPointerEvents()\n\t\t}\n\n\t\tconst delta = Point.subtract(windowMousePosition, mouseRawPosition)\n\t\tconst scrollPoint = Point.subtract(this.startScrollPoint, Point.divide(delta, canvasStore.zoom))\n\t\tcanvasStore.scrollToTopLeft(scrollPoint, { live: true })\n\t}\n}\n\nexport class Pan extends React.Component {\n\toverride render() {\n\t\treturn null\n\t}\n}\n", "import { appDisablePointerEvents } from \"./appPointerEvents.styles.ts\"\n\nexport function enableAppPointerEvents() {\n\tdocument.body.classList.remove(appDisablePointerEvents)\n}\n\nexport function disableAppPointerEvents() {\n\tdocument.body.classList.add(appDisablePointerEvents)\n}\n", "import type { Point } from \"library/render/types/Point.ts\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\n\ninterface MouseProps {\n\tcanvasMousePosition: Point | null\n\tcanvasMouseDownPosition: Point | null\n\taltKey?: boolean\n\tcmdKey?: boolean\n\tshiftKey?: boolean\n}\n\ntype MouseEventType = \"mouseDown\" | \"mouseUp\" | \"mouseMove\"\n\nexport const mouseActionType = (nextProps: MouseProps, prevProps: MouseProps): MouseEventType | null => {\n\tif (nextProps.canvasMouseDownPosition && !prevProps.canvasMouseDownPosition) {\n\t\treturn \"mouseDown\"\n\t}\n\tif (!nextProps.canvasMouseDownPosition && prevProps.canvasMouseDownPosition) {\n\t\treturn \"mouseUp\"\n\t}\n\n\tconst mouseChange = mouseDidMove(nextProps.canvasMousePosition, prevProps.canvasMousePosition)\n\tconst altDidChange = nextProps.altKey !== prevProps.altKey\n\tconst cmdDidChange = nextProps.cmdKey !== prevProps.cmdKey\n\tconst shiftDidChange = nextProps.shiftKey !== prevProps.shiftKey\n\tconst modifierDidChange = altDidChange || cmdDidChange || shiftDidChange\n\tif (mouseChange || modifierDidChange) {\n\t\treturn \"mouseMove\"\n\t}\n\n\treturn null\n}\n", "import { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { WithRadius } from \"document/models/CanvasTree/traits/WithRadius.ts\"\nimport { withRadius, withRelativeRadius } from \"document/models/CanvasTree/traits/WithRadius.ts\"\nimport type { WithRadiusPerCorner } from \"document/models/CanvasTree/traits/WithRadiusPerCorner.ts\"\nimport { radiusPerCornerKeys, withRadiusPerCorner } from \"document/models/CanvasTree/traits/WithRadiusPerCorner.ts\"\nimport { convertFrameToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Line } from \"library/render/types/Line.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\nexport class RadiusTool extends withClassDiscriminator(\"RadiusTool\", VekterTool) {\n\toverride readonly enum = Tools.Radius\n\n\tmouseHasChanged = false\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = true\n\n\toverride start() {\n\t\tthis.engine.beginUndoGroup()\n\t\tthis.updateTooltip()\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t}\n\n\toverride stop() {\n\t\tthis.engine.endUndoGroup()\n\t\tthis.engine.stores.toolStore.tooltip = undefined\n\t}\n\n\toverride update() {\n\t\tconst {\n\t\t\ttree,\n\t\t\tstores: { mouseStore },\n\t\t} = this.engine\n\n\t\tconst { latest, previous } = mouseStore\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = latest\n\n\t\tconst node = this.getNode()\n\t\tif (!node) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition) {\n\t\t\tif (mouseStore.canvasDoubleClickPosition) {\n\t\t\t\tconst radius = containerRelativeRadiusForNode(node, tree)\n\n\t\t\t\tif (radius !== null) {\n\t\t\t\t\tnode.set({ radius })\n\t\t\t\t\tthis.updateTooltip(radius)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tif (mouseAction !== \"mouseMove\") {\n\t\t\treturn\n\t\t}\n\n\t\tthis.mouseHasChanged = true\n\t\tthis.displaySelectionHandles = false\n\t\tthis.displaySelectionBox = false\n\n\t\tconst frame = tree.getRect(node)\n\t\tconst maxRadius = Math.min(frame.width / 2, frame.height / 2)\n\n\t\tconst min = { x: 0, y: 0 }\n\t\tconst max = { x: maxRadius, y: maxRadius }\n\n\t\tconst canvasMin = tree.convertPointToCanvas(node, min)\n\t\tconst canvasMax = tree.convertPointToCanvas(node, max)\n\t\tconst line = Line(canvasMin, canvasMax)\n\t\tconst perpendicular = Line.perpendicular(line, canvasMousePosition)\n\n\t\tconst intersection = Line.intersection(line, perpendicular)\n\t\tif (intersection === null) {\n\t\t\treturn\n\t\t}\n\n\t\tconst minDistance = Point.distance(canvasMin, intersection)\n\t\tconst maxDistance = Point.distance(canvasMax, intersection)\n\t\tconst length = Point.distance(canvasMin, canvasMax)\n\n\t\tlet progress = 0\n\n\t\tif (minDistance > length && maxDistance > length) {\n\t\t\tprogress = minDistance < maxDistance ? 0 : 1\n\t\t} else if (minDistance > length) {\n\t\t\tprogress = 1\n\t\t} else if (maxDistance > length) {\n\t\t\tprogress = 0\n\t\t} else {\n\t\t\tprogress = minDistance / length\n\t\t}\n\n\t\tconst newRadius = Math.round(progress * maxRadius)\n\t\tconst update: Partial<WithRadius & WithRadiusPerCorner> = { radius: newRadius }\n\t\t// Also keep per corner radius in sync, if they currently are\n\t\tif (\n\t\t\twithRadiusPerCorner(node) &&\n\t\t\tnode.radiusBottomLeft === node.radius &&\n\t\t\tnode.radiusBottomRight === node.radius &&\n\t\t\tnode.radiusTopLeft === node.radius &&\n\t\t\tnode.radiusTopRight === node.radius\n\t\t) {\n\t\t\tupdate.radiusBottomLeft = newRadius\n\t\t\tupdate.radiusBottomRight = newRadius\n\t\t\tupdate.radiusTopLeft = newRadius\n\t\t\tupdate.radiusTopRight = newRadius\n\t\t}\n\n\t\tnode.set(update)\n\t\tthis.updateTooltip(newRadius)\n\t}\n\n\tgetNode(): (CanvasNode & WithRadius) | null {\n\t\tconst id = this.engine.stores.selectionStore.ids[0]\n\t\tif (!id) return null\n\t\tconst node = this.engine.tree.get(id)\n\t\treturn node && withRadius(node) ? node : null\n\t}\n\n\tupdateTooltip(radius?: number) {\n\t\tconst node = this.getNode()\n\t\tif (!node) return\n\t\tthis.engine.stores.toolStore.tooltip = `${radius !== undefined ? radius : (node.radius ?? 0)}`\n\t}\n}\n\n// Get the radius of the reference corner, accounting for individual radii\nfunction getRadius(node: CanvasNode & WithRadius, closestCornerIndex: number): number | null {\n\tif (!withRadiusPerCorner(node) || !node.radiusPerCorner) {\n\t\treturn isNumber(node.radius) ? node.radius : null\n\t}\n\tconst cornerKey = radiusPerCornerKeys[closestCornerIndex]\n\tif (!cornerKey) return null\n\tconst cornerRadius = node[cornerKey]\n\treturn isNumber(cornerRadius) ? cornerRadius : null\n}\n\n/**\n * Returns a single value for a corner radius that's concentric to the radius of the node's container.\n * Accounts for alignment of the node inside the container, as well as relatively-sized container radius.\n *\n * @param node\n * @param tree\n */\nfunction containerRelativeRadiusForNode(node: CanvasNode, tree: CanvasTree): number | null {\n\tconst container = tree.getAncestorThatMatches(node, withRadius)\n\tif (!container) {\n\t\treturn null\n\t}\n\n\tconst containerRect = convertFrameToCanvas(tree, container)\n\tconst nodeRect = convertFrameToCanvas(tree, node)\n\n\tconst containerCorners = Rect.cornerPoints(containerRect)\n\tconst nodeCorners = Rect.cornerPoints(nodeRect)\n\tconst nodeCenter = Rect.center(nodeRect)\n\n\t// Find the container corner closest to the center of the node to use as a reference for calculating\n\t// the inner radius. This is a rough way to judge alignment. E.g. a small rectangle positioned all\n\t// the way to the left in a bigger container (like in an iOS notification) will pick the top-left\n\t// corner as a reference, while if you move that rectangle all the way to the right, it will pick\n\t// the top-right corner, instead.\n\n\tlet closestCornerIndex = 0\n\tlet closestCornerDistance = Infinity\n\tcontainerCorners.forEach((corner, i) => {\n\t\tconst distance = Point.distance(nodeCenter, corner)\n\t\tif (distance < closestCornerDistance) {\n\t\t\tclosestCornerDistance = distance\n\t\t\tclosestCornerIndex = i\n\t\t}\n\t})\n\n\tconst referenceContainerCorner = containerCorners[closestCornerIndex]\n\tconst referenceNodeCorner = nodeCorners[closestCornerIndex]\n\n\t// The general formula for the inner radius is Inner Radius = Container Radius - Distance from Edge\n\t// Because the horizontal distance might differ from the vertical distance, we'll calculate both\n\t// and pick the smallest, because the smallest usually looks better.\n\tconst hDistance = Point.distance({ x: referenceContainerCorner.x, y: 0 }, { x: referenceNodeCorner.x, y: 0 })\n\tconst vDistance = Point.distance({ y: referenceContainerCorner.y, x: 0 }, { y: referenceNodeCorner.y, x: 0 })\n\n\tlet containerRadius = getRadius(container, closestCornerIndex)\n\tif (!isNumber(containerRadius)) return null\n\n\tif (withRelativeRadius(container) && container.radiusIsRelative) {\n\t\tconst side = hDistance < vDistance ? containerRect.width : containerRect.height\n\t\tcontainerRadius = Math.round((containerRadius / 100) * side)\n\t}\n\n\treturn Math.max(0, containerRadius - Math.min(hDistance, vDistance))\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert } from \"@framerjs/shared\"\nimport { translateXYToPoint } from \"canvas-sandbox/layout-measuring/projection.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { scaleShapeNode } from \"document/components/utils/dimensions.ts\"\nimport type { CanvasNode, CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isVectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { isAnyTextNode } from \"document/models/CanvasTree/nodes/utils/isAnyTextNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisShapeContainerNode,\n\tisStackComponent,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { ScalableVectorStyles } from \"document/models/CanvasTree/traits/ScalableVectorStyles.ts\"\nimport { collectScalableVectorStyles } from \"document/models/CanvasTree/traits/ScalableVectorStyles.ts\"\nimport { withAspectRatio } from \"document/models/CanvasTree/traits/WithAspectRatio.ts\"\nimport { getChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport type { WithFloatingPosition } from \"document/models/CanvasTree/traits/WithFloatingPosition.ts\"\nimport { withFloatingPosition } from \"document/models/CanvasTree/traits/WithFloatingPosition.ts\"\nimport { getLayoutType, hasAnyLayout } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport type { WithPins } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { withPositionType } from \"document/models/CanvasTree/traits/WithPositionType.ts\"\nimport { withRotation } from \"document/models/CanvasTree/traits/WithRotation.ts\"\nimport { withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport type { WithSize } from \"document/models/CanvasTree/traits/WithSize.ts\"\nimport { withSize } from \"document/models/CanvasTree/traits/WithSize.ts\"\nimport type { ConstrainedAxes } from \"document/models/CanvasTree/traits/WithSizeConstraints.ts\"\nimport {\n\tconstrainHeight,\n\tconstrainRect,\n\tconstrainWidth,\n\tconstraintsForNodeRect,\n\tsupportsSizeConstraints,\n} from \"document/models/CanvasTree/traits/WithSizeConstraints.ts\"\nimport { hasViewportHeight, hasViewportWidth } from \"document/models/CanvasTree/traits/WithSizeDimensionType.ts\"\nimport type { WithSizeToFit } from \"document/models/CanvasTree/traits/WithSizeToFit.ts\"\nimport { isFontSize } from \"document/models/CanvasTree/traits/WithTextStyle.ts\"\nimport { createCSSDimension } from \"document/models/CanvasTree/traits/utils/CSSDimension.ts\"\nimport { isAutoSizedOnBothDimensions } from \"document/models/CanvasTree/traits/utils/autoSizeHelpers.ts\"\nimport { getSupportedDimensionType } from \"document/models/CanvasTree/traits/utils/getDimensionOrVariantDimensionType.ts\"\nimport {\n\thasLockedAspectRatio,\n\tlayoutSupportsAspectRatio,\n} from \"document/models/CanvasTree/traits/utils/layoutSupportsAspectRatio.ts\"\nimport { isPositionAbsolute, isPositionFixed } from \"document/models/CanvasTree/traits/utils/positionTypeHelpers.ts\"\nimport { getSizeMinusPadding } from \"document/models/CanvasTree/traits/utils/sizeMinusPadding.ts\"\nimport {\n\tconvertCornerPointsToCanvas,\n\tconvertFramePointsToCanvas,\n\tconvertFrameToCanvas,\n\tgetBoundingFrameForNodes,\n} from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { getConstraintsLocked } from \"document/models/CanvasTree/utils/getConstraintsLocked.ts\"\nimport { ContentEdgeSnap, sizeToFitContent } from \"document/models/CanvasTree/utils/sizeToFitContent.ts\"\nimport type { FramePoints } from \"document/models/FramePoint.ts\"\nimport { FramePoint } from \"document/models/FramePoint.ts\"\nimport { Matrix } from \"document/models/Matrix.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport { shouldGuessPinToBottom } from \"document/models/shouldGuessPinToBottom.ts\"\nimport { shouldGuessPinToRight } from \"document/models/shouldGuessPinToRight.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport * as Immutable from \"immutable\"\nimport { modulate } from \"library/index.ts\"\nimport type { WithPath } from \"library/render/traits/Path.ts\"\nimport type { ConstraintValues } from \"library/render/types/Constraints.ts\"\nimport { DimensionType, isAutoDimensionType } from \"library/render/types/Constraints.ts\"\nimport { Line } from \"library/render/types/Line.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { isFiniteNumber } from \"library/render/utils/isFiniteNumber.ts\"\nimport { roundedNumber } from \"library/render/utils/roundedNumber.ts\"\nimport type { MirroredCursorAxes } from \"utils/constrainedResizingCursor.ts\"\nimport * as Cursor from \"utils/cursor.ts\"\nimport { isNull, isNumber, isUndefined } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { isSkewedQuadrilateralPoints } from \"../utils/isSkewedQuadrilateralPoints.ts\"\nimport {\n\tcollectDescendantShapesAndFlattenRotations,\n\tcollectShapeContainerDescendantShapesAndFlattenRotations,\n\tconvertPathToCanvas,\n} from \"./pathEdit/utils/index.ts\"\nimport { SnapTool, shouldSnapToViewportLine } from \"./utils/SnapTool.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\ninterface ChildBeginState {\n\trect: Rect\n\tcanvasRect: Rect\n\toriginalProps: Partial<ConstraintValues>\n}\n\ninterface BeginState {\n\trect: Rect\n\tcanvasToParentMatrix: DOMMatrixReadOnly | null\n\tcanvasMatrix: DOMMatrixReadOnly\n\tchildren: Immutable.Map<NodeID, ChildBeginState>\n\tdescendantPaths?: Immutable.Map<NodeID, WithPath> // paths are normalized for the canvas\n\tdescendantBasicShapes?: Immutable.Map<NodeID, null | Point[]> // corner points are normalized for the canvas\n\tshapeContainerDescendantPaths?: Immutable.Map<NodeID, WithPath> // paths are normalized for the shape container\n\tshapeContainerDescendantBasicShapes?: Immutable.Map<NodeID, null | Point[]> // corner points are normalized for the shape container\n\tshapeContainerDescendantScalableStyles?: Immutable.Map<NodeID, ScalableVectorStyles>\n}\nexport class ResizeTool extends withClassDiscriminator(\"ResizeTool\", VekterTool) {\n\toverride readonly enum = Tools.Resize\n\toverride readonly wantsAutoscrolling = true\n\toverride readonly cmsBadge = \"visible\"\n\n\t// FIXME: the !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\thandle!: FramePoint\n\tselectedNodes = Immutable.Map<CanvasNode, BeginState>()\n\tstartRect!: Rect\n\tcontextNode: CanvasNode | null = null\n\tcontextNodeStartMatrix: DOMMatrixReadOnly | null = null\n\tcontextNodeStartMatrixInverse: DOMMatrixReadOnly | null = null\n\n\tisSkewed: boolean = true\n\tsnapper!: SnapTool\n\n\tparentDirectedNodeSelected = false\n\n\thasMoved = false\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = true\n\n\t// Lifecycle\n\n\toverride start() {\n\t\tassert(!isNull(this.engine.handle), \"ResizeTool cannot be started if handle is null\")\n\t\tthis.handle = this.engine.handle\n\t\tconst { selectionStore } = this.engine.stores\n\t\tthis.snapper = new SnapTool(this.engine, selectionStore.ids)\n\t\tthis.engine.beginUndoGroup()\n\n\t\tconst { tree } = this.engine\n\n\t\tthis.updateCursor()\n\n\t\tconst frames: Rect[] = []\n\t\tconst selectedNodes: CanvasNode[] = tree.withoutDescendants(tree.getNodes(selectionStore.ids))\n\t\tif (selectedNodes.length === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tselectedNodes.forEach(node => {\n\t\t\tconst rect = tree.getRect(node)\n\t\t\tconst canvasMatrix = node.canvasMatrix()\n\t\t\tthis.parentDirectedNodeSelected =\n\t\t\t\tthis.parentDirectedNodeSelected ||\n\t\t\t\tBoolean(node.cache.parentDirected && !isPositionFixed(node) && !isPositionAbsolute(node))\n\n\t\t\tif (isAnyTextNode(node)) {\n\t\t\t\tnode.cache.resizeHeight = rect.height\n\t\t\t}\n\n\t\t\tlet canvasFrame: Rect\n\n\t\t\tif (withShape(node)) {\n\t\t\t\tconst calculatedPaths = node.calculatedPaths()\n\t\t\t\tconst canvasPath = convertPathToCanvas(tree, node, calculatedPaths)\n\t\t\t\tcanvasFrame = Path.boundingBox(canvasPath)\n\t\t\t} else {\n\t\t\t\tcanvasFrame = convertFrameToCanvas(tree, node)\n\t\t\t}\n\t\t\tframes.push(canvasFrame)\n\n\t\t\tconst { descendantPaths, descendantBasicShapes } = collectDescendantShapesAndFlattenRotations(this.engine, node)\n\t\t\tnode = node.draftOrCurrent()\n\n\t\t\tconst { shapeContainerDescendantPaths, shapeContainerDescendantBasicShapes } =\n\t\t\t\tcollectShapeContainerDescendantShapesAndFlattenRotations(this.engine, node)\n\t\t\tnode = node.draftOrCurrent()\n\n\t\t\tconst shapeContainerDescendantScalableStyles = isShapeContainerNode(node)\n\t\t\t\t? collectScalableVectorStyles(node)\n\t\t\t\t: undefined\n\n\t\t\tlet children = Immutable.Map<NodeID, ChildBeginState>()\n\t\t\tgetChildren(node).forEach(childNode => {\n\t\t\t\tconst childRect = tree.getRect(childNode)\n\t\t\t\tconst childCanvasRect = convertFrameToCanvas(tree, childNode)\n\t\t\t\tlet originalProps = {}\n\t\t\t\tif (isPinnable(childNode)) {\n\t\t\t\t\toriginalProps = childNode.constraintValues()\n\t\t\t\t}\n\t\t\t\tchildren = children.set(childNode.id, {\n\t\t\t\t\trect: childRect,\n\t\t\t\t\tcanvasRect: childCanvasRect,\n\t\t\t\t\toriginalProps,\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tconst parent = tree.getParent(node.id)\n\t\t\tconst canvasToParentMatrix = parent ? parent.canvasMatrix().inverse() : null\n\n\t\t\tthis.selectedNodes = this.selectedNodes.set(node, {\n\t\t\t\trect,\n\t\t\t\tcanvasToParentMatrix,\n\t\t\t\tcanvasMatrix,\n\t\t\t\tchildren,\n\t\t\t\tdescendantPaths,\n\t\t\t\tdescendantBasicShapes,\n\t\t\t\tshapeContainerDescendantPaths,\n\t\t\t\tshapeContainerDescendantBasicShapes,\n\t\t\t\tshapeContainerDescendantScalableStyles,\n\t\t\t})\n\t\t})\n\n\t\tconst singleSelection = selectedNodes.length === 1\n\t\tconst firstNode = selectedNodes[0]?.draftOrCurrent()\n\n\t\tif (singleSelection && firstNode && (withRotation(firstNode) || isShapeContainerNode(firstNode))) {\n\t\t\tthis.contextNode = firstNode\n\t\t\tthis.contextNodeStartMatrix = firstNode.canvasMatrix()\n\t\t\tthis.contextNodeStartMatrixInverse = this.contextNodeStartMatrix.inverse()\n\t\t\tthis.startRect = tree.getRect(this.contextNode)\n\t\t\t// Temporarily disable snapping for skewed nodes. In the future we\n\t\t\t// will bring this back with support for drawing lines and snapping\n\t\t\t// the correct lines for transformed shapes.\n\t\t\tthis.isSkewed = isSkewedQuadrilateralPoints(convertCornerPointsToCanvas(this.engine.tree, this.contextNode))\n\t\t} else {\n\t\t\tthis.startRect = Rect.merge(...frames)\n\t\t}\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.toolStore.tooltip = undefined\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.engine.endUndoGroup()\n\t\tthis.snapper.stop()\n\n\t\t// Clear out any resizeHeight properties we have set in start().\n\t\tthis.selectedNodes.forEach((_, node) => {\n\t\t\tif (node && isAnyTextNode(node)) {\n\t\t\t\tnode.cache.resizeHeight = null\n\t\t\t}\n\t\t})\n\t}\n\n\tkeepChildPositionFixed() {\n\t\tconst { contextNode, engine } = this\n\t\tconst { cmdKey } = engine.stores.mouseStore.latest\n\t\treturn cmdKey || isShapeContainerNode(contextNode)\n\t}\n\n\toverride update() {\n\t\tconst { canvasMouseDownPosition, altKey, shiftKey } = this.engine.stores.mouseStore.latest\n\t\tconst {\n\t\t\tmouseStore,\n\t\t\tselectionStore,\n\t\t\ttreeStore: { tree },\n\t\t\tlayoutCache,\n\t\t\tdocumentSettingsStore,\n\t\t} = this.engine.stores\n\t\tlet { canvasMousePosition } = mouseStore.latest\n\n\t\t// Make sure all the nodes still exist, in multi-user scenarios they might get deleted.\n\t\tthis.selectedNodes = Immutable.Map<CanvasNode, BeginState>(\n\t\t\tthis.selectedNodes.filter((_beginState, node) => tree.has(node?.id)),\n\t\t)\n\n\t\tif (this.selectedNodes.isEmpty()) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst selectedNodes = this.selectedNodes.keySeq().toArray()\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition) {\n\t\t\tif (mouseStore.canvasDoubleClickPosition && selectedNodes.length === 1) {\n\t\t\t\tconst edge = contentEdgeSnapForHandle(this.handle, altKey, shiftKey)\n\t\t\t\tsizeToFitContent(this.engine.tree, this.engine.componentLoader, selectedNodes, layoutCache, edge)\n\t\t\t}\n\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(mouseStore.latest, mouseStore.previous)\n\t\tif (mouseAction !== \"mouseMove\") {\n\t\t\treturn\n\t\t}\n\n\t\tthis.hasMoved = true\n\t\tthis.displaySelectionHandles = false\n\n\t\tconst { startRect, contextNode } = this\n\t\tconst keepChildrenFixed = this.keepChildPositionFixed()\n\n\t\tconst mirror = altKey || this.centeredAutoSizedContextNode()\n\t\tconst snappingEnabled = !this.parentDirectedNodeSelected && !this.isSkewed\n\n\t\tconst aspectRatioEnabled = this.getAspectRatioLock()\n\t\tconst constraint = this.getConstraint(aspectRatioEnabled, snappingEnabled)\n\n\t\tconst includeBoundingBoxes: Rect[] = []\n\t\tselectedNodes.forEach(node => {\n\t\t\tif (!isAnyTextNode(node) || isAutoSizedOnBothDimensions(node)) return\n\n\t\t\tconst size = node.rect(tree.getParentSizeInfo(node), true, this.engine.componentLoader)\n\t\t\tconst textCanvasFrame = convertFrameToCanvas(tree, node, {\n\t\t\t\t...size,\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t})\n\n\t\t\tincludeBoundingBoxes.push(textCanvasFrame)\n\t\t})\n\n\t\tif (keepChildrenFixed) {\n\t\t\tthis.selectedNodes.valueSeq().forEach((beginState: BeginState) => {\n\t\t\t\tbeginState.children.forEach((childState: ChildBeginState) => {\n\t\t\t\t\tincludeBoundingBoxes.push(childState.canvasRect)\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\n\t\tconst isAutoSizedTextNode = Boolean(\n\t\t\tcontextNode && isAnyTextNode(contextNode) && isAutoSizedOnBothDimensions(contextNode),\n\t\t)\n\t\tif (isAutoSizedTextNode) {\n\t\t\tif (constraint) {\n\t\t\t\tconst perpendicularLine = Line.perpendicular(constraint, canvasMousePosition)\n\t\t\t\tconst intersection = Line.intersection(constraint, perpendicularLine)\n\t\t\t\tif (intersection !== null) {\n\t\t\t\t\tcanvasMousePosition = intersection\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst topLevelFrameNodes = tree.getTopLevelFrameNodes(selectedNodes)\n\t\t\tconst uniqueFrameAncestors = Array.from(new Set(topLevelFrameNodes))\n\t\t\tthis.snapper.excludedNodes = selectionStore.ids\n\t\t\tcanvasMousePosition = this.snapper.snap(\n\t\t\t\tcanvasMousePosition,\n\t\t\t\tsnappingEnabled,\n\t\t\t\tuniqueFrameAncestors,\n\t\t\t\tundefined,\n\t\t\t\tconstraint,\n\t\t\t\tundefined,\n\t\t\t\tincludeBoundingBoxes,\n\t\t\t\tshouldSnapToViewportLine(tree, selectionStore.ids),\n\t\t\t)\n\t\t}\n\n\t\t// Calculate start position\n\t\tconst { fx, fy } = this.handle\n\t\tconst startX = startRect.width * fx\n\t\tconst startY = startRect.height * fy\n\n\t\t// Calculate difference Round the delta instead of the resize rect to avoid affecting the\n\t\t// value on the axis that isn't being resized.\n\t\tlet deltaX = 0\n\t\tlet deltaY = 0\n\t\tif (this.contextNodeStartMatrix) {\n\t\t\t// @FIXME - Currently we will try to snap to the mouse position,\n\t\t\t// even if the mouse is not on the orthogonal resize line in the\n\t\t\t// case of rotations. We should be able to instead snap to the point\n\t\t\t// that intersects the orthogonal line that drawn through the center\n\t\t\t// of the node to the handle point.\n\t\t\tconst delta = translateXYToPoint(this.contextNodeStartMatrix, { x: startX, y: startY }, canvasMousePosition)\n\t\t\tdeltaX = roundToFullPixel(delta.x)\n\t\t\tdeltaY = roundToFullPixel(delta.y)\n\t\t} else {\n\t\t\t// Calculate difference\n\t\t\tdeltaX = roundToFullPixel(canvasMousePosition.x - (startX + startRect.x))\n\t\t\tdeltaY = roundToFullPixel(canvasMousePosition.y - (startY + startRect.y))\n\t\t}\n\n\t\tif (mirror) {\n\t\t\tdeltaX = 2 * roundToFullPixel(deltaX)\n\t\t\tdeltaY = 2 * roundToFullPixel(deltaY)\n\t\t}\n\n\t\t// Calculate new frame\n\t\tlet resizeRect = { ...this.startRect }\n\t\tresizeRect.height += (fy * 2 - 1) * deltaY\n\t\tresizeRect.width += (fx * 2 - 1) * deltaX\n\n\t\tlet selectionAspectRatio: number | null = null\n\t\t// Adjust for aspect ratio locking\n\t\tif (aspectRatioEnabled) {\n\t\t\tselectionAspectRatio = startRect.width / startRect.height\n\n\t\t\tif (fx === 0.5) {\n\t\t\t\tresizeRect.width = resizeRect.height * selectionAspectRatio\n\t\t\t} else if (fy === 0.5) {\n\t\t\t\tresizeRect.height = resizeRect.width / selectionAspectRatio\n\t\t\t} else {\n\t\t\t\tconst xSign = Math.sign(resizeRect.width)\n\t\t\t\tconst ySign = Math.sign(resizeRect.height)\n\t\t\t\tconst altWidth = Math.abs(resizeRect.height * selectionAspectRatio)\n\t\t\t\tconst altHeight = Math.abs(resizeRect.width / selectionAspectRatio)\n\t\t\t\tresizeRect.width = Math.min(altWidth, Math.abs(resizeRect.width)) * xSign\n\t\t\t\tresizeRect.height = Math.min(altHeight, Math.abs(resizeRect.height)) * ySign\n\t\t\t}\n\t\t}\n\n\t\tresizeRect.width = roundToFullPixel(resizeRect.width)\n\t\tresizeRect.height = roundToFullPixel(resizeRect.height)\n\n\t\t// Update the cursor with the resizeRect, this helps us determine if the\n\t\t// node is being resized negatively, allowing us to correctly determine\n\t\t// which cursors to use if the resized dimension meets a constraint.\n\t\tthis.updateCursor(resizeRect, selectionAspectRatio)\n\n\t\t// Handle the case of a single node being resized.\n\t\tif (contextNode !== null) {\n\t\t\t// Ensure the resize rect does not exceed the size constraints a\n\t\t\t// node may have.\n\t\t\tresizeRect = constrainRect(resizeRect, contextNode, this.engine.componentLoader, {\n\t\t\t\t...tree.getParentSizeInfo(contextNode),\n\t\t\t\tselectionAspectRatio,\n\t\t\t})\n\t\t\tconst delta = this.resizeDelta(contextNode, resizeRect, fx, fy, mirror)\n\t\t\tif (isUndefined(delta)) return\n\t\t\tdelta.x = roundToFullPixel(delta.x)\n\t\t\tdelta.y = roundToFullPixel(delta.y)\n\t\t\tresizeRect = Rect.offset(resizeRect, delta)\n\n\t\t\tif (isAnyTextNode(contextNode)) {\n\t\t\t\tconst parent = tree.getParent(contextNode.id)\n\t\t\t\tconst lockedUpdate = contextNode.updateForRect({\n\t\t\t\t\trect: resizeRect,\n\t\t\t\t\tparentSizeInfo: tree.getParentSizeInfo(contextNode),\n\t\t\t\t\tconstraintsLocked: true,\n\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, contextNode),\n\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, contextNode, parent),\n\t\t\t\t})\n\n\t\t\t\tadjustUpdateForAutoAndFractionDimensions(this.engine.componentLoader, contextNode, lockedUpdate, false)\n\n\t\t\t\tthis.engine.tree.current(contextNode)?.set(lockedUpdate)\n\n\t\t\t\tconst textNode = this.engine.tree.getNode(contextNode.id)\n\t\t\t\tassert(textNode && isAnyTextNode(textNode), \"Updated node needs to be a TextNode\")\n\n\t\t\t\tconst [fontSize] = textNode.getFontSizes(false)\n\t\t\t\tif (isNumber(fontSize)) {\n\t\t\t\t\tdocumentSettingsStore.defaultTextStyle.fontSize = createCSSDimension(fontSize, \"px\")\n\t\t\t\t} else if (isFontSize(fontSize)) {\n\t\t\t\t\tdocumentSettingsStore.defaultTextStyle.fontSize = createCSSDimension(...fontSize)\n\t\t\t\t}\n\t\t\t} else if (isVectorNode(contextNode)) {\n\t\t\t\tthis.shapeUpdates(tree, contextNode, startRect, resizeRect, false)\n\t\t\t} else {\n\t\t\t\t// don't update fractions and auto dimensions\n\t\t\t\tconst parent = tree.getParent(contextNode.id)\n\t\t\t\tlet parentSizeInfo = tree.getParentSizeInfo(contextNode)\n\t\t\t\tif (isStackComponent(parent) && !isPositionFixed(contextNode) && !isPositionAbsolute(contextNode)) {\n\t\t\t\t\tconst parentSizeMinusPadding = getSizeMinusPadding(tree, parent)\n\t\t\t\t\tparentSizeInfo = {\n\t\t\t\t\t\tsizing: {\n\t\t\t\t\t\t\t// vw/vh node should ignore the padding on that axis.\n\t\t\t\t\t\t\twidth: hasViewportWidth(contextNode)\n\t\t\t\t\t\t\t\t? (parentSizeInfo.sizing?.width ?? parentSizeMinusPadding.width)\n\t\t\t\t\t\t\t\t: parentSizeMinusPadding.width,\n\t\t\t\t\t\t\theight: hasViewportHeight(contextNode)\n\t\t\t\t\t\t\t\t? (parentSizeInfo.sizing?.height ?? parentSizeMinusPadding.height)\n\t\t\t\t\t\t\t\t: parentSizeMinusPadding.height,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpositioning: parentSizeInfo?.positioning ?? parentSizeMinusPadding,\n\t\t\t\t\t\tviewport: null,\n\t\t\t\t\t\tlayout: getLayoutType(parent),\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst update: Partial<WithPins & WithSizeToFit & WithFloatingPosition> = contextNode.updateForRect({\n\t\t\t\t\trect: resizeRect,\n\t\t\t\t\tparentSizeInfo,\n\t\t\t\t\tconstraintsLocked: getConstraintsLocked(contextNode),\n\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, contextNode),\n\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, contextNode, parent),\n\t\t\t\t})\n\n\t\t\t\t// When resizing, never update the offset of relative overlays.\n\t\t\t\t// Only update the Size to ensure that they stay aligned to\n\t\t\t\t// their alignment and placement.\n\t\t\t\tif (withFloatingPosition(contextNode)) {\n\t\t\t\t\tObject.assign(update, {\n\t\t\t\t\t\tfloatingOffsetX: contextNode.floatingOffsetX,\n\t\t\t\t\t\tfloatingOffsetY: contextNode.floatingOffsetY,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tadjustUpdateForAutoAndFractionDimensions(this.engine.componentLoader, contextNode, update, false)\n\n\t\t\t\tif (isShapeContainerNode(contextNode)) {\n\t\t\t\t\tupdate.sizeToFit = false\n\t\t\t\t}\n\n\t\t\t\tthis.engine.tree.current(contextNode)?.set(update)\n\n\t\t\t\tthis.updateChildNodesConstraints(contextNode, resizeRect)\n\t\t\t}\n\t\t} else {\n\t\t\t// Handle the case where many nodes are being resized together in a\n\t\t\t// combined selection rect.\n\t\t\tconst anchorPoints = FramePoint.fromFrame(this.startRect)\n\t\t\tconst transformPoints = FramePoint.fromFrame(resizeRect)\n\t\t\tconst anchorIndex = this.anchorIndex(fx, fy, mirror)\n\t\t\tconst anchorStartPoint = anchorPoints[anchorIndex]\n\t\t\tconst anchorEndPoint = transformPoints[anchorIndex]\n\t\t\tif (isUndefined(anchorStartPoint) || isUndefined(anchorEndPoint)) return\n\n\t\t\tconst anchorStart = Point.add(anchorStartPoint, this.startRect)\n\t\t\tconst anchorEnd = Point.add(anchorEndPoint, resizeRect)\n\t\t\tconst delta = Point.subtract(anchorStart, anchorEnd)\n\n\t\t\tresizeRect = Rect.offset(resizeRect, delta)\n\n\t\t\tthis.selectedNodes.forEach((beginState: BeginState, node: CanvasNode) => {\n\t\t\t\tif (isVectorNode(node)) {\n\t\t\t\t\tthis.shapeUpdates(tree, node, startRect, resizeRect, true)\n\t\t\t\t} else {\n\t\t\t\t\tconst convertedStartRect = projectFrame(beginState.canvasToParentMatrix, this.startRect)\n\t\t\t\t\tconst convertedResizeRect = projectFrame(beginState.canvasToParentMatrix, resizeRect)\n\t\t\t\t\tconst xFromRange: [number, number] = [convertedStartRect.x, convertedStartRect.x + convertedStartRect.width]\n\t\t\t\t\tconst xToRange: [number, number] = [convertedResizeRect.x, convertedResizeRect.x + convertedResizeRect.width]\n\t\t\t\t\tconst yFromRange: [number, number] = [convertedStartRect.y, convertedStartRect.y + convertedStartRect.height]\n\t\t\t\t\tconst yToRange: [number, number] = [convertedResizeRect.y, convertedResizeRect.y + convertedResizeRect.height]\n\n\t\t\t\t\tconst nodeRect = beginState.rect\n\n\t\t\t\t\tconst pointA = {\n\t\t\t\t\t\tx: modulate(nodeRect.x, xFromRange, xToRange, false),\n\t\t\t\t\t\ty: modulate(nodeRect.y, yFromRange, yToRange, false),\n\t\t\t\t\t}\n\t\t\t\t\tlet pointB = {\n\t\t\t\t\t\tx: modulate(nodeRect.x + nodeRect.width, xFromRange, xToRange, false),\n\t\t\t\t\t\ty: modulate(nodeRect.y + nodeRect.height, yFromRange, yToRange, false),\n\t\t\t\t\t}\n\n\t\t\t\t\t// Ensure the second point does not create a rect that\n\t\t\t\t\t// violates the size constraints of the individual node, or\n\t\t\t\t\t// the original aspect ratio if locked via holding the shift\n\t\t\t\t\t// key.\n\t\t\t\t\tconst aspectRatio = aspectRatioEnabled ? nodeRect.width / nodeRect.height : undefined\n\t\t\t\t\tif (supportsSizeConstraints(node)) {\n\t\t\t\t\t\tconst parentSize = tree.getParentSizeInfo(node)\n\t\t\t\t\t\tpointB = {\n\t\t\t\t\t\t\tx:\n\t\t\t\t\t\t\t\tconstrainWidth(node, pointB.x - pointA.x, this.engine.componentLoader, {\n\t\t\t\t\t\t\t\t\t...parentSize,\n\t\t\t\t\t\t\t\t\tselectionAspectRatio: aspectRatio,\n\t\t\t\t\t\t\t\t}) + pointA.x,\n\t\t\t\t\t\t\ty:\n\t\t\t\t\t\t\t\tconstrainHeight(node, pointB.y - pointA.y, this.engine.componentLoader, {\n\t\t\t\t\t\t\t\t\t...parentSize,\n\t\t\t\t\t\t\t\t\tselectionAspectRatio: aspectRatio,\n\t\t\t\t\t\t\t\t}) + pointA.y,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst newRect = Rect.fromTwoPoints(pointA, pointB)\n\t\t\t\t\tconst parent = tree.getParent(node.id)\n\t\t\t\t\tconst update = node.updateForRect({\n\t\t\t\t\t\trect: newRect,\n\t\t\t\t\t\tparentSizeInfo: tree.getParentSizeInfo(node),\n\t\t\t\t\t\tconstraintsLocked: getConstraintsLocked(node),\n\t\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, node),\n\t\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, node, parent),\n\t\t\t\t\t})\n\t\t\t\t\tadjustUpdateForAutoAndFractionDimensions(this.engine.componentLoader, node, update, false)\n\t\t\t\t\tthis.engine.tree.current(node)?.set(update)\n\n\t\t\t\t\tthis.updateChildNodesConstraints(node, newRect)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\t// force the engine to the new state, then set tooltip\n\t\t// TODO: show tooltip after rendering\n\t\t// this.engine.updateTreeState()\n\t\tthis.updateTooltip()\n\t}\n\n\tshapeUpdates = (tree: CanvasTree, shape: CanvasNode, startRect: Rect, resizeRect: Rect, inCanvas: boolean) => {\n\t\tconst beginState = this.selectedNodes.get(shape)\n\t\tif (!beginState) return\n\n\t\tscaleShapeNode(tree, beginState, startRect, resizeRect, inCanvas)\n\t}\n\n\tupdateChildNodesConstraints = (parentNode: CanvasNode, parentRect: Rect) => {\n\t\t// Stacks and grid layout their own children, updating properties here will create a lot of empty overrides.\n\t\tif (hasAnyLayout(parentNode)) return\n\n\t\tconst { tree } = this.engine\n\t\tconst keepChildrenFixed = this.keepChildPositionFixed()\n\t\tconst beginState = this.selectedNodes.get(parentNode)\n\n\t\tlet parentDelta = {\n\t\t\tx: beginState.rect.x - parentRect.x,\n\t\t\ty: beginState.rect.y - parentRect.y,\n\t\t}\n\n\t\tif (withRotation(parentNode)) {\n\t\t\tconst rotation = parentNode.resolveValue(\"rotation\")\n\t\t\tconst matrix = new DOMMatrix().rotateSelf(0, 0, -rotation)\n\t\t\tparentDelta = Matrix.convertPoint(matrix, parentDelta)\n\t\t}\n\n\t\tbeginState.children.forEach((childBeginState: ChildBeginState, childId: NodeID) => {\n\t\t\tconst childNode = tree.getNode(childId)\n\t\t\tif (!childNode) return\n\t\t\tlet childRect = childBeginState.rect\n\t\t\tlet childProps = childBeginState.originalProps\n\t\t\tif (keepChildrenFixed) {\n\t\t\t\tchildRect = Rect.offset(childRect, parentDelta)\n\t\t\t\tconst parentSizeInfo = tree.getParentSizeInfo(childNode, parentNode)\n\t\t\t\tchildProps = childNode.updateForRect({\n\t\t\t\t\trect: childRect,\n\t\t\t\t\tparentSizeInfo: {\n\t\t\t\t\t\tsizing: parentSizeInfo.sizing ?? parentRect,\n\t\t\t\t\t\tpositioning: parentRect,\n\t\t\t\t\t\tviewport: parentSizeInfo.viewport ?? null,\n\t\t\t\t\t\tlayout: getLayoutType(parentNode),\n\t\t\t\t\t},\n\t\t\t\t\tconstraintsLocked: getConstraintsLocked(childNode),\n\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, null, parentNode),\n\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToRight(tree, null, parentNode),\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Only needed for TextNode at the moment\n\t\t\tif (!withAspectRatio(childNode) || !layoutSupportsAspectRatio(childNode)) {\n\t\t\t\tdelete childProps.aspectRatio\n\t\t\t}\n\t\t\tadjustUpdateForAutoAndFractionDimensions(this.engine.componentLoader, childNode, childProps, true)\n\t\t\tchildNode.set(childProps as any)\n\t\t})\n\t}\n\n\tupdateTooltip = () => {\n\t\tconst {\n\t\t\tselectionStore,\n\t\t\ttoolStore,\n\t\t\ttreeStore: { tree },\n\t\t} = this.engine.stores\n\n\t\tlet frame: Rect\n\n\t\tif (selectionStore.ids.length === 1 && selectionStore.ids[0]) {\n\t\t\tconst selected = selectionStore.ids[0]\n\t\t\tif (isUndefined(selected)) return\n\t\t\tconst node = tree.getNode(selected)\n\t\t\tif (!node) return\n\t\t\tif (isAnyTextNode(node) && isAutoSizedOnBothDimensions(node)) {\n\t\t\t\tconst size = node.getFontSizes(false)[0]\n\t\t\t\ttoolStore.tooltip = isFontSize(size) ? size.join(\"\") : undefined\n\t\t\t\treturn\n\t\t\t}\n\t\t\tframe = Rect.round(tree.getRect(node), 2)\n\n\t\t\t// The parent directed rect isn't updated in time\n\t\t\t// Its only updated when the cache is reset\n\t\t\tif (node.cache.parentDirected) {\n\t\t\t\tif (isPinnable(node) && withSize(node)) {\n\t\t\t\t\tconst parent = tree.getParent(node.id)\n\t\t\t\t\tlet parentSize = tree.getParentSizeInfo(node).sizing\n\t\t\t\t\tif (parent && isSizePaddingRelative(node, parent)) {\n\t\t\t\t\t\tparentSize = getSizeMinusPadding(tree, parent)\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (node.widthType) {\n\t\t\t\t\t\tcase DimensionType.FixedNumber:\n\t\t\t\t\t\t\tframe.width = node.width\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase DimensionType.Percentage:\n\t\t\t\t\t\t\tif (parentSize) {\n\t\t\t\t\t\t\t\tframe.width = roundedNumber(node.width * parentSize.width, 0)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tswitch (node.heightType) {\n\t\t\t\t\t\tcase DimensionType.FixedNumber:\n\t\t\t\t\t\t\tframe.height = node.height\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase DimensionType.Percentage:\n\t\t\t\t\t\t\tif (parentSize) {\n\t\t\t\t\t\t\t\tframe.height = roundedNumber(node.height * parentSize.height, 0)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst rect = getBoundingFrameForNodes(tree, tree.getNodes(selectionStore.ids))\n\t\t\tframe = Rect.pixelAligned(rect)\n\t\t}\n\n\t\ttoolStore.tooltip = `${frame.width} \u00D7 ${frame.height}`\n\t}\n\n\t// Helpers\n\n\tupdateCursor(): void\n\tupdateCursor(resizeRect: Rect, selectionAspectRatio: number | null): void\n\tupdateCursor(resizeRect?: Rect, selectionAspectRatio?: number | null): void {\n\t\tconst { selectionStore, mouseCursorStore } = this.engine.stores\n\t\tconst { tree } = this.engine\n\t\tconst singleSelection = selectionStore.ids.length === 1\n\t\tlet framePoints: FramePoints | null = null\n\t\tlet constraints: ConstrainedAxes | null = null\n\t\tconst mirroredAxes: MirroredCursorAxes = {\n\t\t\tx: false,\n\t\t\ty: false,\n\t\t}\n\n\t\tif (singleSelection) {\n\t\t\tconst id = selectionStore.ids[0]\n\t\t\tif (isUndefined(id)) return\n\t\t\tconst node = tree.getNode<CanvasNode>(id)\n\t\t\tif (!node) return\n\n\t\t\tframePoints = convertFramePointsToCanvas(tree, node)\n\t\t\tconstraints = constraintsForNodeRect(node, tree.getRect(node), this.engine.componentLoader, {\n\t\t\t\t...tree.getParentSizeInfo(node),\n\t\t\t\tselectionAspectRatio,\n\t\t\t})\n\n\t\t\tif (resizeRect) {\n\t\t\t\tmirroredAxes.y = resizeRect.width < 0\n\t\t\t\tmirroredAxes.x = resizeRect.height < 0\n\t\t\t}\n\t\t} else {\n\t\t\tconst mergedFrame = selectionStore.ids.reduce((previous: Rect | undefined, id) => {\n\t\t\t\tconst node = tree.getNode<CanvasNode>(id)\n\t\t\t\tif (!node) return previous\n\n\t\t\t\tconst canvasFrame = convertFrameToCanvas(tree, node)\n\t\t\t\treturn previous ? Rect.merge(previous, canvasFrame) : canvasFrame\n\t\t\t}, undefined) as Rect | undefined\n\t\t\tif (mergedFrame) {\n\t\t\t\tframePoints = FramePoint.fromFrame(mergedFrame)\n\t\t\t}\n\t\t}\n\t\tif (framePoints) {\n\t\t\tmouseCursorStore.current = Cursor.resizing(this.handle, framePoints, constraints, mirroredAxes)\n\t\t}\n\t}\n\n\tanchorIndex = (fx: number, fy: number, mirror: boolean): number => {\n\t\tif (mirror) {\n\t\t\treturn 4\n\t\t}\n\t\treturn 8 - (fx * 2 + fy * 6)\n\t}\n\n\tgetConstraint(aspectRatioEnabled: boolean, allowConstraint: boolean): Line | undefined {\n\t\tif (!allowConstraint) return\n\n\t\tconst { selectionStore } = this.engine.stores\n\t\tconst { contextNode, startRect } = this\n\n\t\tif (!startRect) return\n\n\t\tconst isConstrained =\n\t\t\taspectRatioEnabled || this.handle.fx === 0.5 || this.handle.fy === 0.5 || selectionStore.ids.length > 1\n\t\tif (!isConstrained) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (contextNode && this.contextNodeStartMatrix) {\n\t\t\tconst centerPoint = Matrix.convertPoint(this.contextNodeStartMatrix, {\n\t\t\t\tx: startRect.width / 2,\n\t\t\t\ty: startRect.height / 2,\n\t\t\t})\n\t\t\tconst handlePoint = Matrix.convertPoint(this.contextNodeStartMatrix, {\n\t\t\t\tx: this.handle.fx * startRect.width,\n\t\t\t\ty: this.handle.fy * startRect.height,\n\t\t\t})\n\t\t\treturn Line(centerPoint, handlePoint)\n\t\t} else {\n\t\t\tconst centerPoint = Rect.center(startRect)\n\t\t\tconst handlePoint = Point(\n\t\t\t\tstartRect.x + startRect.width * this.handle.fx,\n\t\t\t\tstartRect.y + startRect.height * this.handle.fy,\n\t\t\t)\n\t\t\treturn Line(centerPoint, handlePoint)\n\t\t}\n\t}\n\n\tgetAspectRatioLock(): boolean {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, mouseStore } = this.engine.stores\n\t\tconst { shiftKey } = mouseStore.latest\n\n\t\tif (shiftKey) {\n\t\t\treturn true\n\t\t}\n\t\tif (selectionStore.ids.length > 1) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Else the selection is a single node\n\t\tconst id = selectionStore.ids[0]\n\t\tif (isUndefined(id)) return false\n\t\tconst node = tree.getNode(id) as CanvasNode\n\t\tif (!node) return false\n\n\t\tif (withAspectRatio(node) && layoutSupportsAspectRatio(node)) {\n\t\t\treturn hasLockedAspectRatio(node)\n\t\t} else {\n\t\t\treturn isAnyTextNode(node) && isAutoSizedOnBothDimensions(node)\n\t\t}\n\t}\n\n\tresizeDelta = (node: CanvasNode, newRect: Rect, fx: number, fy: number, mirror: boolean) => {\n\t\tconst index = this.anchorIndex(fx, fy, mirror)\n\t\tconst startFrame = { ...this.startRect }\n\t\tconst startAnchor = FramePoint.fromFrame(startFrame)[index]\n\t\tconst ignoreRotation = isVectorNode(node) || isShapeContainerNode(node)\n\n\t\tif (newRect.width < 0) {\n\t\t\tnewRect.width *= -1\n\t\t\tfx = Math.abs(fx - 1)\n\t\t}\n\n\t\tif (newRect.height < 0) {\n\t\t\tnewRect.height *= -1\n\t\t\tfy = Math.abs(fy - 1)\n\t\t}\n\n\t\tconst endIndex = this.anchorIndex(fx, fy, mirror)\n\t\tconst endAnchor = FramePoint.fromFrame(newRect)[endIndex]\n\t\tif (isUndefined(startAnchor) || isUndefined(endAnchor)) return\n\n\t\tlet n = node\n\n\t\tif (ignoreRotation) {\n\t\t\tn = node.clone({ rotation: 0 })\n\t\t}\n\n\t\tconst startPoint = Matrix.convertPoint(n.originAdjustedMatrix(null, startFrame), startAnchor)\n\t\tconst endPoint = Matrix.convertPoint(n.originAdjustedMatrix(null, newRect), endAnchor)\n\n\t\treturn Point.subtract(startPoint, endPoint)\n\t}\n\n\tcenteredAutoSizedContextNode = () => {\n\t\tconst ctx = this.contextNode\n\t\tif (!ctx) return false\n\n\t\tconst isAutoSizedTextNode = isAnyTextNode(ctx) && isAutoSizedOnBothDimensions(ctx)\n\t\treturn (\n\t\t\tctx &&\n\t\t\tisPinnable(ctx) &&\n\t\t\tisAutoSizedTextNode &&\n\t\t\tctx.top === null &&\n\t\t\tctx.bottom === null &&\n\t\t\tctx.left === null &&\n\t\t\tctx.right === null\n\t\t)\n\t}\n}\n\nfunction isSizePaddingRelative(node: CanvasNode, parent: CanvasNode) {\n\tif (!withPositionType(node) || !hasAnyLayout(parent)) return false\n\treturn node.position === \"sticky\" || isUndefined(node.position)\n}\n\nfunction projectFrame(matrix: DOMMatrixReadOnly | null, frame: Rect) {\n\tif (!matrix) return frame\n\tconst convertedCorners = Matrix.convertPointsWithClipping(matrix, Rect.cornerPoints(frame))\n\treturn Rect.boundingRectFromPoints(convertedCorners)\n}\n\nfunction removeAutoAndFractionFromUpdate(\n\tcomponentLoader: ComponentLoader,\n\tnode: CanvasNode & WithPins,\n\tupdate: Partial<WithPins & WithSize>,\n\tdimension: \"width\" | \"height\",\n) {\n\tconst dimensionType = dimension === \"width\" ? \"widthType\" : \"heightType\"\n\tconst supportedDimensionType = isCodeComponentNode(node)\n\t\t? getSupportedDimensionType(componentLoader, node, dimension)\n\t\t: node[dimensionType]\n\tif (isAutoDimensionType(supportedDimensionType) || supportedDimensionType === DimensionType.FractionOfFreeSpace) {\n\t\tdelete update[dimension]\n\t\tdelete update[dimensionType]\n\t}\n}\n\nfunction adjustUpdateForAutoAndFractionDimensions(\n\tcomponentLoader: ComponentLoader,\n\tnode: CanvasNode,\n\tupdate: Partial<WithPins & WithSize>,\n\tisChildOfResizedNode: boolean,\n) {\n\tif (!isPinnable(node)) return\n\tif (!isCodeComponentNode(node) || isChildOfResizedNode) {\n\t\tremoveAutoAndFractionFromUpdate(componentLoader, node, update, \"width\")\n\t\tremoveAutoAndFractionFromUpdate(componentLoader, node, update, \"height\")\n\t\treturn\n\t}\n\n\t// If the node supports it, set the dimensionType to fixed if we are updating an auto-width node with a finite number\n\tconst variantSize = node.getCurrentVariantSize(componentLoader)\n\tconst supportedLayoutWidthType = getSupportedDimensionType(componentLoader, node, \"width\")\n\tconst supportedLayoutHeightType = getSupportedDimensionType(componentLoader, node, \"height\")\n\tif (\n\t\t(variantSize?.widthType === DimensionType.FixedNumber || supportedLayoutWidthType === DimensionType.FixedNumber) &&\n\t\tisAutoDimensionType(node.widthType) &&\n\t\tisFiniteNumber(update.width)\n\t) {\n\t\tupdate.widthType = DimensionType.FixedNumber\n\t} else {\n\t\tremoveAutoAndFractionFromUpdate(componentLoader, node, update, \"width\")\n\t}\n\n\tif (\n\t\t(variantSize?.heightType === DimensionType.FixedNumber ||\n\t\t\tsupportedLayoutHeightType === DimensionType.FixedNumber) &&\n\t\tisAutoDimensionType(node.heightType) &&\n\t\tisFiniteNumber(update.height)\n\t) {\n\t\tupdate.heightType = DimensionType.FixedNumber\n\t} else {\n\t\tremoveAutoAndFractionFromUpdate(componentLoader, node, update, \"height\")\n\t}\n}\n\nconst contentEdges = [\n\t[ContentEdgeSnap.topLeft, ContentEdgeSnap.top, ContentEdgeSnap.topRight],\n\t[ContentEdgeSnap.left, ContentEdgeSnap.none, ContentEdgeSnap.right],\n\t[ContentEdgeSnap.bottomLeft, ContentEdgeSnap.bottom, ContentEdgeSnap.bottomRight],\n]\n\nconst symmetricalContentEdges = [\n\t[ContentEdgeSnap.none, ContentEdgeSnap.vertical, ContentEdgeSnap.none],\n\t[ContentEdgeSnap.horizontal, ContentEdgeSnap.none, ContentEdgeSnap.horizontal],\n\t[ContentEdgeSnap.none, ContentEdgeSnap.vertical, ContentEdgeSnap.none],\n]\n\nfunction contentEdgeSnapForHandle({ fx, fy }: FramePoint, altKey: boolean, shiftKey: boolean) {\n\tif (shiftKey) {\n\t\treturn ContentEdgeSnap.none\n\t}\n\n\tconst edges = altKey ? symmetricalContentEdges : contentEdges\n\treturn edges[fy * 2]?.[fx * 2] ?? ContentEdgeSnap.none\n}\n\nfunction roundToFullPixel(value: number) {\n\treturn Math.round(value)\n}\n", "import { assert } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { isComputedValue } from \"document/models/CanvasTree/traits/ComputedValue.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport type { WithRotation } from \"document/models/CanvasTree/traits/WithRotation.ts\"\nimport { withRotation } from \"document/models/CanvasTree/traits/WithRotation.ts\"\nimport {\n\tconvertCornerPointsToCanvas,\n\tconvertFramePointsToCanvas,\n\tconvertFrameToCanvas,\n} from \"document/models/CanvasTree/utils/geometry.ts\"\nimport type { FramePoint } from \"document/models/FramePoint.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Polygon } from \"library/render/types/Polygon.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport React from \"react\"\nimport * as Cursor from \"utils/cursor.ts\"\nimport { isNull } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { ToolProps } from \"./props.ts\"\n\nexport class RotateTool extends withClassDiscriminator(\"RotateTool\", VekterTool) {\n\toverride readonly enum = Tools.Rotate\n\n\t// FIXME: the !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\thandle!: FramePoint\n\n\tselectedNode!: Readonly<CanvasNode> & WithRotation\n\tnormalizer!: (value: number) => number\n\tstartRotation!: number\n\tisParentFlipped!: boolean\n\n\toverride displaySelectionBox = true\n\n\t// Lifecycle\n\n\toverride start() {\n\t\tassert(!isNull(this.engine.handle), \"RotateTool cannot be started if handle is null\")\n\t\tthis.handle = this.engine.handle\n\t\tconst { tree } = this.engine\n\n\t\tthis.engine.beginUndoGroup()\n\n\t\tconst id = this.engine.stores.selectionStore.ids[0]\n\t\tconst node = tree.getNode(id)\n\t\tif (!node || !withRotation(node) || isVariableReference(node.rotation) || isComputedValue(node.rotation)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.selectedNode = node\n\t\tthis.normalizer = Point.rotationNormalizer()\n\n\t\tconst parent = tree.getParent(node.id)\n\t\tif (parent) {\n\t\t\tconst corners = convertCornerPointsToCanvas(tree, parent)\n\t\t\tthis.isParentFlipped = !Polygon.isClockwise(corners)\n\t\t}\n\n\t\tconst rotation = node.resolveValue(\"rotation\")\n\t\tthis.normalizer(rotation)\n\t\tthis.startRotation = rotation\n\t\tthis.engine.stores.toolStore.tooltip = `${this.startRotation}\u00B0`\n\t\tthis.updateCursor()\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.toolStore.tooltip = undefined\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.engine.endUndoGroup()\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { latest, previous } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey, altKey } = latest\n\n\t\tif (!canvasMouseDownPosition || !this.selectedNode || !tree.has(this.selectedNode.id)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseMove =\n\t\t\tcanvasMousePosition.x !== previous.canvasMousePosition.x ||\n\t\t\tcanvasMousePosition.y !== previous.canvasMousePosition.y\n\t\tconst modifierChange = altKey !== previous.altKey || shiftKey !== previous.shiftKey\n\n\t\tif (mouseMove || modifierChange) {\n\t\t\tconst center = Rect.center(convertFrameToCanvas(tree, this.selectedNode))\n\n\t\t\tconst angle1 = Math.atan2(canvasMouseDownPosition.y - center.y, canvasMouseDownPosition.x - center.x)\n\t\t\tconst angle2 = Math.atan2(canvasMousePosition.y - center.y, canvasMousePosition.x - center.x)\n\t\t\tlet angle = angle2 - angle1\n\t\t\tangle = (angle * 180) / Math.PI\n\n\t\t\tif (this.isParentFlipped) {\n\t\t\t\tangle = -angle\n\t\t\t}\n\n\t\t\tlet rotation = this.startRotation + angle\n\t\t\trotation = Math.round(this.normalizer(rotation))\n\n\t\t\tif (shiftKey) {\n\t\t\t\tconst times = Math.round(rotation / 15)\n\t\t\t\trotation = times * 15\n\t\t\t}\n\n\t\t\tthis.engine.stores.toolStore.tooltip = `${rotation}\u00B0`\n\t\t\tthis.updateCursor()\n\n\t\t\tconst selectedNode = this.engine.tree.current(this.selectedNode)\n\t\t\tif (!selectedNode || !withRotation(selectedNode)) return\n\t\t\tselectedNode.set({ rotation })\n\t\t}\n\t}\n\n\t// helper\n\tupdateCursor() {\n\t\tconst { tree } = this.engine\n\t\tconst node = tree.getNode(this.selectedNode.id)\n\t\tif (!node) return\n\t\tconst framePoints = convertFramePointsToCanvas(tree, node)\n\t\tif (!framePoints) return\n\t\tthis.engine.stores.mouseCursorStore.current = Cursor.rotating(this.handle, framePoints)\n\t}\n}\n\nexport class Rotate extends React.Component<ToolProps<RotateTool>> {\n\toverride render() {\n\t\treturn null\n\t}\n}\n", "import { List, unhandledError } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { sampleColor } from \"document/components/tools/utils/sampleColor.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { isAnyTextNode } from \"document/models/CanvasTree/nodes/utils/isAnyTextNode.ts\"\nimport { isCodeComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { withBorder } from \"document/models/CanvasTree/traits/WithBorder.ts\"\nimport { supportsBoxShadow } from \"document/models/CanvasTree/traits/WithBoxShadow.ts\"\nimport type { WithFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport {\n\tisGradientFillType,\n\tsupportsGradientProps,\n\twithFill,\n\twithOptionalFill,\n} from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { withShadow } from \"document/models/CanvasTree/traits/WithShadow.ts\"\nimport { withStroke } from \"document/models/CanvasTree/traits/WithStroke.ts\"\nimport { isStylableNode } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifierChecks.ts\"\nimport { conicGradientUpdate, linearGradientUpdate, radialGradientUpdate } from \"document/models/Gradient.ts\"\nimport { getUpdatedShadow } from \"document/models/Shadow.ts\"\nimport type { CollectionControlProp } from \"document/models/controlProps/CollectionControlProp.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport React from \"react\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { setValueInCMS } from \"../utils/variableProviderValues.ts\"\nimport type { GradientFillToolManagerTool, GradientMaskToolManagerTool } from \"./gradient/GradientToolManagerTool.tsx\"\nimport type { VekterPathEngine } from \"./pathEdit/PathToolManager.tsx\"\nimport type { ToolPropsWithManagerProps } from \"./props.ts\"\n\nexport class SampleColorTool extends withClassDiscriminator(\"SampleColorTool\", VekterTool) {\n\toverride readonly enum = Tools.SampleColor\n\n\tpathEngine?: VekterPathEngine\n\tgradientEngine?: GradientFillToolManagerTool | GradientMaskToolManagerTool\n\n\toverride displaySelectionBox = true\n\n\texit() {\n\t\tif (this.pathEngine) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t} else if (this.gradientEngine) {\n\t\t\tthis.gradientEngine.setDefault()\n\t\t} else {\n\t\t\tthis.engine.exitTool()\n\t\t}\n\t}\n\n\toverride update() {}\n\n\toverride stop() {}\n\n\toverride start() {\n\t\tconst { tree } = this.engine\n\n\t\tconst { selectionStore } = this.engine.stores\n\n\t\tif (selectionStore.ids.length === 0) {\n\t\t\tthis.exit()\n\t\t\treturn\n\t\t}\n\n\t\tsampleColor(this.engine)\n\t\t\t.then(color => {\n\t\t\t\tthis.engine.scheduler.processWhenReady(() => {\n\t\t\t\t\tthis.exit()\n\t\t\t\t\tif (color === undefined) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tthis.engine.beginUndoGroup()\n\n\t\t\t\t\ttree.getNodes(selectionStore.ids).forEach(node => {\n\t\t\t\t\t\tconst updater = getColorUpdater(this.engine, node, color)\n\t\t\t\t\t\tif (!updater) {\n\t\t\t\t\t\t\t// This node should not have its color updated at all.\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (updater.oldValue) {\n\t\t\t\t\t\t\tconst value: CollectionControlProp = { type: ControlType.Color, value: color }\n\t\t\t\t\t\t\tif (setValueInCMS(this.engine, updater.oldValue, value)) {\n\t\t\t\t\t\t\t\t// Since the variable provider was updated, don't update the node (below).\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// If we get here then the variable could not be updated.\n\t\t\t\t\t\tupdater.updateNode()\n\t\t\t\t\t})\n\n\t\t\t\t\tthis.engine.endUndoGroup()\n\t\t\t\t})\n\t\t\t})\n\t\t\t.catch(error => {\n\t\t\t\tthis.engine.scheduler.processWhenReady(() => {\n\t\t\t\t\tthis.exit()\n\t\t\t\t})\n\t\t\t\tunhandledError(error)\n\t\t\t})\n\t}\n}\n\ninterface ColorUpdater {\n\t/** Will only matter if it's DynamicValue, otherwise it will be ignored. */\n\toldValue: unknown\n\t/** Called if the variable could not be updated. */\n\tupdateNode(): void\n}\n\nfunction getColorUpdater(engine: VekterEngine, node: CanvasNode, color: string): ColorUpdater | undefined {\n\tif (isAnyTextNode(node)) {\n\t\treturn {\n\t\t\toldValue: node.getTextColors(false)[0],\n\t\t\tupdateNode() {\n\t\t\t\tnode.setTextColor(color, false)\n\t\t\t},\n\t\t}\n\t}\n\n\tconst fillDisabled = withOptionalFill(node) && !node.fillEnabled\n\n\tif (hasActiveGradient(node) && node.fillLinearGradient) {\n\t\tconst index = node.fillLinearGradient.stops.findIndex(\n\t\t\t({ id }) => id === engine.stores.selectionStore.gradientStopId,\n\t\t)\n\t\tconst stops = List.update(node.fillLinearGradient.stops, index, colorStop => colorStop.merge({ value: color }))\n\t\tconst tool = Tools.FillGradient\n\t\treturn {\n\t\t\toldValue: undefined, // We won't update variables for gradients.\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({\n\t\t\t\t\tfillLinearGradient: linearGradientUpdate(node, { stops }, tool),\n\t\t\t\t\tfillRadialGradient: radialGradientUpdate(node, { stops }, tool),\n\t\t\t\t\tfillConicGradient: conicGradientUpdate(node, { stops }, tool),\n\t\t\t\t})\n\t\t\t},\n\t\t}\n\t} else if (isCodeComponentNode(node) && !isStylableNode(node)) {\n\t\tconst component = engine.componentLoader.componentForIdentifier(node.codeComponentIdentifier)\n\t\tif (!component?.properties) return\n\t\tconst firstColorKey = Object.keys(component.properties).find(\n\t\t\tkey => component.properties[key]?.type === ControlType.Color,\n\t\t)\n\t\tif (!firstColorKey) return\n\t\treturn {\n\t\t\toldValue: node.getRawControlProp(firstColorKey)?.value,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.setControlProp(firstColorKey, { type: ControlType.Color, value: color })\n\t\t\t},\n\t\t}\n\t} else if (withFill(node) && !fillDisabled) {\n\t\treturn {\n\t\t\toldValue: node.fillColor,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ fillColor: color })\n\t\t\t},\n\t\t}\n\t} else if (withBorder(node) && node.borderEnabled) {\n\t\treturn {\n\t\t\toldValue: node.borderColor,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ borderColor: color })\n\t\t\t},\n\t\t}\n\t} else if (withStroke(node) && node.strokeEnabled) {\n\t\treturn {\n\t\t\toldValue: node.strokeColor,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ strokeColor: color })\n\t\t\t},\n\t\t}\n\t} else if (withShadow(node) && node.shadows && node.shadows[0]) {\n\t\tconst existingShadow = node.shadows[0]\n\t\tconst shadows = List.replace(node.shadows, 0, getUpdatedShadow(existingShadow, { color }))\n\t\treturn {\n\t\t\toldValue: existingShadow.color,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ shadows })\n\t\t\t},\n\t\t}\n\t} else if (supportsBoxShadow(node) && node.boxShadows && !isDynamicValue(node.boxShadows) && node.boxShadows[0]) {\n\t\tconst existingShadow = node.boxShadows[0]\n\t\tconst boxShadows = List.replace(node.boxShadows, 0, getUpdatedShadow(existingShadow, { color }))\n\t\treturn {\n\t\t\toldValue: existingShadow.color,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ boxShadows })\n\t\t\t},\n\t\t}\n\t} else if (withFill(node) && fillDisabled) {\n\t\treturn {\n\t\t\toldValue: node.fillColor,\n\t\t\tupdateNode() {\n\t\t\t\tengine.tree.current(node)?.set({ fillColor: color, fillEnabled: true })\n\t\t\t},\n\t\t}\n\t}\n}\n\nfunction hasActiveGradient(node: CanvasNode): node is CanvasNode & WithFill {\n\tconst fillEnabled = !withOptionalFill(node) || !!node.fillEnabled\n\tif (!fillEnabled) return false\n\tif (!supportsGradientProps(node)) return false\n\tif (!isGradientFillType(node.fillType)) return false\n\treturn Boolean(\n\t\t(node.fillType === \"linear-gradient\" && node.fillLinearGradient) ||\n\t\t(node.fillType === \"radial-gradient\" && node.fillRadialGradient) ||\n\t\t(node.fillType === \"conic-gradient\" && node.fillConicGradient),\n\t)\n}\n\nexport class SampleColor extends React.Component<ToolPropsWithManagerProps<SampleColorTool>> {\n\toverride render() {\n\t\treturn null\n\t}\n}\n", "import { AnnotationKey } from \"@framerjs/framer-runtime/crossorigin\"\nimport { unhandledError } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CollectionItemNode } from \"document/models/CanvasTree/nodes/CollectionItemNode.ts\"\nimport type { CollectionNode } from \"document/models/CanvasTree/nodes/CollectionNode.ts\"\nimport { isCollectionItemNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isComputedValue, isComputedValueFromFetchData } from \"document/models/CanvasTree/traits/ComputedValue.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { FALLBACK_PROVIDER_ID } from \"document/models/CanvasTree/traits/VariableProvider.ts\"\nimport { withCollectionDataSource } from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport { withVariableProvider } from \"document/models/CanvasTree/traits/WithVariableProvider.ts\"\nimport type { VariableDefinition } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport type { CollectionControlProp } from \"document/models/controlProps/CollectionControlProp.ts\"\nimport type { CollectionControlType } from \"document/models/controlProps/CollectionControlType.ts\"\nimport { getCollectionForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { getFirstRepeaterItemId } from \"utils/getFirstRepeaterItemId.ts\"\n\n// TODO: These functions have names that are useful as of this writing, because\n// they can only apply to CMS values. If, in the future, we can get or set\n// values in other kinds of variable providers, we should make these functions\n// generic to support all of them.\n\n/**\n * If the provided `oldValue` is a variable reference, attempts to update the\n * value inside the provider of the variable. Returns `true` if the update is\n * successful. For now this only applies to collections in the CMS.\n */\nexport function setValueInCMS(engine: VekterEngine, oldValue: unknown, value: CollectionControlProp): boolean {\n\tconst info = getInfo(engine, oldValue, value.type)\n\tif (!info) return false\n\n\tconst { collectionNode, collectionItemNode, variable } = info\n\n\tcollectionItemNode.setControlProp(variable.id, value)\n\tengine.stores.codeGenerationStore.updateComponent(collectionNode.id).catch(unhandledError)\n\n\treturn true\n}\n\ninterface Info {\n\treadonly collectionNode: CollectionNode\n\treadonly collectionItemNode: CollectionItemNode\n\treadonly variable: VariableDefinition\n}\n\nfunction getInfo(engine: VekterEngine, oldValue: unknown, expectedType: CollectionControlType): Info | undefined {\n\tif (!isDynamicValue(oldValue)) return\n\tif (isComputedValueFromFetchData(oldValue)) return\n\n\tconst variableReference = isComputedValue(oldValue) ? oldValue.startValue : oldValue\n\tif (!variableReference.providerId || variableReference.providerId === FALLBACK_PROVIDER_ID) return\n\n\tconst providerNode = engine.tree.get(variableReference.providerId)\n\tif (!providerNode || !withCollectionDataSource(providerNode) || !withVariableProvider(providerNode)) return\n\tif (!providerNode.dataIdentifier) return\n\n\tconst collectionNode = getCollectionForIdentifier(engine.tree, providerNode.dataIdentifier)\n\tif (!collectionNode) return\n\n\tconst variable = collectionNode.getVariable(variableReference.id)\n\tif (!variable || variable.type !== expectedType) return\n\n\tconst data = engine.componentLoader.dataForIdentifier(providerNode.dataIdentifier)\n\tif (!data) return\n\n\tconst idKey = data.annotations?.[AnnotationKey.FramerRecordIdKey]\n\tif (!idKey) return\n\n\tconst collectionItemId = getFirstRepeaterItemId(providerNode, engine.stores.treeStore.sandboxRepeaterData)\n\tconst collectionItemNode = engine.tree.get(collectionItemId)\n\tif (!isCollectionItemNode(collectionItemNode)) return\n\n\treturn { collectionNode, collectionItemNode, variable }\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { intersection, union, without } from \"document/components/utils/list.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { getNodesInRect } from \"document/models/CanvasTree/utils/hitTesting.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport React from \"react\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { MouseDrawnRect } from \"./MouseDrawnRect.tsx\"\nimport type { ToolPropsWithManagerProps } from \"./props.ts\"\nimport { isSelectable, isSelectableInRect } from \"./utils/isSelectable.ts\"\n\nexport class SelectTool extends withClassDiscriminator(\"SelectTool\", VekterTool) {\n\toverride readonly enum: Tools = Tools.Select\n\toverride readonly wantsAutoscrolling = true\n\n\t// FIXME: the !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tselectionAtStart!: NodeID[]\n\tselectableNodeCache: Set<NodeID> = new Set()\n\tcanvasGroundNodes!: CanvasNode[]\n\n\tmouseDidMove = false\n\n\toverride displaySelectionBox = true\n\toverride cmsBadge: \"visible\" | \"hidden\" | \"disabled\" = \"visible\"\n\toverride displayViewportHandle = true\n\n\toverride start() {\n\t\tthis.selectionAtStart = this.engine.stores.selectionStore.ids\n\t\tthis.canvasGroundNodes = this.engine.stores.scopeStore.active.getGroundNodes()\n\t\tif (!this.engine.stores.persistedUserDefaults.useDirectSelect) {\n\t\t\tthis.buildSelectableNodeCache()\n\t\t}\n\t}\n\n\tprivate buildSelectableNodeCache() {\n\t\tconst selectableNodeCache = new Set<NodeID>()\n\t\tfor (const node of this.engine.stores.scopeStore.active.walk()) {\n\t\t\tif (\n\t\t\t\tisSelectable({\n\t\t\t\t\tnode,\n\t\t\t\t\tengine: this.engine,\n\t\t\t\t\tcmdKey: false,\n\t\t\t\t\tuseDirectSelect: false,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tselectableNodeCache.add(node.id)\n\t\t\t}\n\t\t}\n\n\t\tthis.selectableNodeCache = selectableNodeCache\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { latest, previous: state } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, altKey, shiftKey, cmdKey } = latest\n\n\t\tif (!canvasMouseDownPosition) {\n\t\t\tthis.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseChange = mouseDidMove(state.canvasMousePosition, canvasMousePosition)\n\t\tconst altKeyDidChange = state.altKey !== altKey\n\t\tconst shiftKeyDidChange = state.shiftKey !== shiftKey\n\t\tconst cmdKeyDidChange = state.cmdKey !== cmdKey\n\n\t\tif (\n\t\t\tcanvasMouseDownPosition &&\n\t\t\tcanvasMousePosition &&\n\t\t\t(mouseChange || (this.mouseDidMove && (altKeyDidChange || shiftKeyDidChange || cmdKeyDidChange)))\n\t\t) {\n\t\t\tif (!this.mouseDidMove) {\n\t\t\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t\t\t}\n\n\t\t\tthis.mouseDidMove = true\n\n\t\t\tconst dragSelectRect = Rect.fromTwoPoints(canvasMouseDownPosition, canvasMousePosition)\n\t\t\tconst nodes = getNodesInRect(tree, this.engine.stores.scopeStore.active, dragSelectRect, !altKey)\n\n\t\t\tconst selectableNodeIds = this.filterSelectableNodeIds(nodes, dragSelectRect)\n\t\t\tlet ids: NodeID[] = Array.from(selectableNodeIds)\n\t\t\tif (shiftKey) {\n\t\t\t\tconst inBoth = intersection(ids, this.selectionAtStart)\n\t\t\t\tids = union(ids, this.selectionAtStart)\n\t\t\t\tids = without(ids, inBoth)\n\t\t\t}\n\n\t\t\tthis.engine.stores.selectionStore.set(ids, {\n\t\t\t\t// Could be called by the agent (drag) select tool, in which case we don't want to switch to properties.\n\t\t\t\tswitchToProperties: this.enum === Tools.Select,\n\t\t\t})\n\t\t}\n\t}\n\n\tfilterSelectableNodeIds(nodesInRect: CanvasNode[], dragSelectRect: Rect) {\n\t\tconst set = new Set<NodeID>()\n\t\tnodesInRect.forEach(node => {\n\t\t\tif (\n\t\t\t\t!isSelectableInRect(\n\t\t\t\t\tnode,\n\t\t\t\t\tdragSelectRect,\n\t\t\t\t\tthis.engine,\n\t\t\t\t\tthis.selectableNodeCache,\n\t\t\t\t\tthis.engine.stores.persistedUserDefaults.useDirectSelect,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tset.add(node.id)\n\t\t})\n\n\t\treturn set\n\t}\n\n\texitTool() {\n\t\tthis.engine.exitTool()\n\t}\n}\n\nexport class Select extends React.Component<ToolPropsWithManagerProps<SelectTool>> {\n\toverride render() {\n\t\tconst { mouseDown, mouse, zoom } = this.props\n\t\treturn (\n\t\t\t<MouseDrawnRect\n\t\t\t\tmouseDown={mouseDown}\n\t\t\t\tmouse={mouse}\n\t\t\t\tzoom={zoom}\n\t\t\t\tbackgroundColor={colors.canvasSelectionRectBackground}\n\t\t\t\tborderColor={colors.canvasSelectionRectBorder}\n\t\t\t/>\n\t\t)\n\t}\n}\n", "import type { Point } from \"library/index.ts\"\nimport { Rect } from \"library/index.ts\"\nimport { Overlay } from \"../canvas-hud/Overlay.tsx\"\n\ninterface Props {\n\tmouseDown: Point | null\n\tmouse: Point | null\n\tzoom: number\n\tbackgroundColor: string\n\tborderColor: string\n}\n\nexport const MouseDrawnRect = ({ mouseDown, mouse, zoom, backgroundColor, borderColor }: Props) => {\n\tif (!mouse || !mouseDown) {\n\t\treturn null\n\t}\n\n\tconst mouseRect = Rect.fromTwoPoints(mouseDown, mouse)\n\n\treturn (\n\t\t<Overlay\n\t\t\tpoints={Rect.cornerPoints(Rect.multiply(mouseRect, zoom))}\n\t\t\troundToOutside={false}\n\t\t\tbackgroundColor={backgroundColor}\n\t\t\tborderColor={borderColor}\n\t\t\tborderWidth={1}\n\t\t\tskipLargeLayer={false}\n\t\t/>\n\t)\n}\n", "import { triggerInteractivePageConnectEvent, triggerInteractiveScrollConnectEvent } from \"@framerjs/framer-events\"\nimport { assert, List, isEmptyObject, unhandledError } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport type { MenuItemOptions } from \"app/menu.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { FrameNode, MaybeNodeID, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { NullID } from \"document/models/CanvasTree/index.ts\"\nimport type CodeComponentNode from \"document/models/CanvasTree/nodes/CodeComponentNode.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { isCodeComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport {\n\tacceptsMultipleSlotItems,\n\tgetSlotKeyIfOnlyWithItems,\n\tgetSlotKeys,\n\tgetSlotNodeIdsBySlotKey,\n\tgetUniqueSlotNodeIdsFromAllSlots,\n\thasAnySlots,\n\tslotTitleForControlKey,\n} from \"document/models/CanvasTree/nodes/utils/slotUtils.ts\"\nimport { findComponentIn } from \"document/models/CanvasTree/traits/utils/findComponentIn.ts\"\nimport { HardCodedCodeIdentifier } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifiers.ts\"\nimport type { ControlProps } from \"document/models/controlProps/ControlProp.ts\"\nimport { prefixControlProps } from \"document/models/controlProps/controlPropKey.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { addCursor, disconnectCursor } from \"utils/cursor.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { Slot } from \"../chrome/properties/codeComponentRows/utils/Slot.ts\"\n\nexport class SlotConnectTool extends withClassDiscriminator(\"SlotConnectTool\", VekterTool) {\n\toverride readonly enum = Tools.SlotConnect\n\n\tmouseHasBeenUp = false\n\tcanDisconnect = false\n\tactiveSlotKeys: string[] = []\n\n\toverride start() {\n\t\tconst { tree, componentLoader } = this.engine\n\t\tconst { selectionStore } = this.engine.stores\n\t\tconst firstID = selectionStore.ids[0]\n\t\tif (!firstID) return\n\t\tconst node = tree.getNode(firstID)\n\t\tif (!node) return\n\t\tif (!isCodeComponentNode(node)) return\n\n\t\tconst nodeId = node.id\n\t\tconst slotKeys = getSlotKeys(node, componentLoader)\n\n\t\tconst controlsVisibility = this.engine.getControlsVisibility()\n\t\tassert(controlsVisibility, \"Controls visibility not available\")\n\n\t\tcontrolsVisibility\n\t\t\t.getHiddenStateForControlsByNode({\n\t\t\t\t[nodeId]: {\n\t\t\t\t\tcontrolNames: slotKeys,\n\t\t\t\t},\n\t\t\t})\n\t\t\t.then(hiddenSlotsByNodeId => {\n\t\t\t\tconst activeSlotKeys = new Set(slotKeys)\n\t\t\t\tconst hiddenSlotsByNode = hiddenSlotsByNodeId[nodeId]\n\n\t\t\t\tif (hiddenSlotsByNode) {\n\t\t\t\t\tfor (const slotKey in hiddenSlotsByNode) {\n\t\t\t\t\t\tconst hidden = hiddenSlotsByNode[slotKey]\n\t\t\t\t\t\tif (hidden) activeSlotKeys.delete(slotKey)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.activeSlotKeys = Array.from(activeSlotKeys)\n\t\t\t\tconst uniqueSlotItemIds = getUniqueSlotNodeIdsFromAllSlots(this.engine.tree, node, componentLoader)\n\t\t\t\tthis.canDisconnect = uniqueSlotItemIds.size > 0\n\t\t\t})\n\t\t\t.catch(unhandledError)\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t}\n\n\toverride update() {\n\t\tconst { tree, componentLoader } = this.engine\n\t\tconst { selectionStore, mouseStore } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = latest\n\t\tconst { activeSlotKeys } = this\n\t\tconst prevMouseDown = previous.canvasMouseDownPosition\n\n\t\tconst firstID = selectionStore.ids[0]\n\t\tif (!firstID) return this.exitTool()\n\n\t\tconst node = tree.getNode(firstID)\n\n\t\tif (!node || !isCodeComponentNode(node)) return this.exitTool()\n\n\t\tif (!hasAnySlots(node, componentLoader)) return this.exitTool()\n\n\t\tconst oneToManyRelation = acceptsMultipleSlotItems(node, componentLoader, activeSlotKeys)\n\t\tconst minusCursor = oneToManyRelation ? \"\" : disconnectCursor\n\n\t\tconst ancestors = tree.getAncestors(node.id)\n\t\tconst nodesAtPoint = tree.getNodesAtPoint(this.engine.stores.scopeStore.active, canvasMousePosition)\n\t\tlet topLevelFrame = nodesAtPoint.find(nodeAtPoint => {\n\t\t\tif (!Slot.isValidSlotTarget(tree, nodeAtPoint)) return false\n\t\t\tif (ancestors.includes(nodeAtPoint.id)) return false\n\t\t\treturn tree.getParent(nodeAtPoint.id) === null\n\t\t}) as FrameNode | undefined\n\n\t\t// check target frame for cycles back to the current component, that's not allowed\n\t\tif (findComponentIn(tree, node, topLevelFrame, componentLoader)) {\n\t\t\ttopLevelFrame = undefined\n\t\t}\n\n\t\tthis.engine.stores.mouseCursorStore.current =\n\t\t\tnodesAtPoint.length === 0 && this.canDisconnect ? minusCursor : topLevelFrame ? addCursor : undefined\n\n\t\tconst mouseUp = canvasMouseDownPosition === null && prevMouseDown !== null\n\t\tif (mouseUp && (this.mouseHasBeenUp || Point.distance(prevMouseDown, canvasMousePosition) > 4)) {\n\t\t\tswitch (node.codeComponentIdentifier) {\n\t\t\t\tcase HardCodedCodeIdentifier.scroll:\n\t\t\t\t\ttriggerInteractiveScrollConnectEvent({\n\t\t\t\t\t\tsource: \"canvas\",\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t\tcase HardCodedCodeIdentifier.page:\n\t\t\t\t\ttriggerInteractivePageConnectEvent({\n\t\t\t\t\t\tsource: \"canvas\",\n\t\t\t\t\t})\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst linkedId: MaybeNodeID = topLevelFrame ? topLevelFrame.id : NullID\n\n\t\t\tif (linkedId) {\n\t\t\t\tconst linkedNode = this.engine.tree.get(linkedId)\n\t\t\t\tassert(linkedNode, \"Node to link from must exist\")\n\t\t\t\tlinkedNode.linkTo(node.id)\n\t\t\t\tthis.addSlotContent(linkedId, node)\n\t\t\t} else if (nodesAtPoint.length === 0 && !oneToManyRelation) {\n\t\t\t\t// only remove if there are no nodes below cursor\n\t\t\t\tthis.addSlotContent(NullID, node)\n\t\t\t} else {\n\t\t\t\tthis.exitTool()\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\t\tthis.mouseHasBeenUp = this.mouseHasBeenUp || mouseUp\n\t\tthis.engine.stores.treeStore.setHighlight(topLevelFrame ? topLevelFrame.id : null)\n\t}\n\n\taddSlotContent(id: MaybeNodeID, node: CodeComponentNode) {\n\t\tconst { activeSlotKeys } = this\n\t\tconst firstActiveSlotKey = activeSlotKeys[0]\n\n\t\tif (!firstActiveSlotKey) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (activeSlotKeys.length === 1) {\n\t\t\tthis.addSlotContentForKey(id, firstActiveSlotKey, node)\n\t\t\treturn\n\t\t}\n\n\t\tif (!id) {\n\t\t\tconst singleSlotKey = getSlotKeyIfOnlyWithItems(this.engine.tree, node, this.engine.componentLoader)\n\t\t\tif (singleSlotKey) {\n\t\t\t\tthis.addSlotContentForKey(id, singleSlotKey, node)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst nodeIdsForAllSlots = getSlotNodeIdsBySlotKey(this.engine.tree, node, this.engine.componentLoader)\n\n\t\tconst visibleSlots: Record<string, NodeID[]> = {}\n\t\tfor (const slotKey in nodeIdsForAllSlots) {\n\t\t\tconst nodeIds = nodeIdsForAllSlots[slotKey]\n\t\t\tif (nodeIds && activeSlotKeys.includes(slotKey)) visibleSlots[slotKey] = nodeIds\n\t\t}\n\n\t\tif (isEmptyObject(visibleSlots)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.slotSelector(id, visibleSlots, node)\n\t}\n\n\tslotSelector = (id: MaybeNodeID, visibleSlots: { [key: string]: NodeID[] }, node: CodeComponentNode) => {\n\t\tconst slotKeys = Object.keys(visibleSlots)\n\t\tconst { contextMenuStore, mouseStore } = this.engine.stores\n\n\t\tconst options: MenuItemOptions[] = [\n\t\t\t{\n\t\t\t\tlabel: !id ? Dictionary.Disconnect : \"Connect to\u2026\",\n\t\t\t\tenabled: false,\n\t\t\t},\n\t\t]\n\n\t\tfor (const slotKey of slotKeys) {\n\t\t\toptions.push({\n\t\t\t\tlabel: slotTitleForControlKey(node, this.engine.componentLoader, slotKey),\n\t\t\t\tclick: () => {\n\t\t\t\t\tthis.addSlotContentForKey(id, slotKey, node)\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\tcontextMenuStore.show(options, { location: mouseStore.latest.windowMousePosition, onCancel: this.exitTool })\n\t}\n\n\taddSlotContentForKey(reference: MaybeNodeID, slotKey: string, node: CodeComponentNode) {\n\t\tconst componentDefinition = this.engine.componentLoader.componentForIdentifier(node.codeComponentIdentifier)\n\t\tif (!componentDefinition || !componentDefinition.properties) {\n\t\t\treturn this.exitTool()\n\t\t}\n\n\t\tconst control = componentDefinition.properties[slotKey]\n\t\tif (control?.type !== ControlType.Slot) {\n\t\t\treturn this.exitTool()\n\t\t}\n\n\t\tlet update: ControlProps = {}\n\t\tif (control.maxCount === 1) {\n\t\t\tupdate = {\n\t\t\t\t[slotKey]: {\n\t\t\t\t\ttype: ControlType.Slot,\n\t\t\t\t\tvalue: reference ? [{ id: randomID(), reference }] : [],\n\t\t\t\t},\n\t\t\t}\n\t\t} else {\n\t\t\tconst controlProps = node.getControlProps(componentDefinition.properties)\n\t\t\tconst controlProp = controlProps[slotKey]\n\t\t\tassert(controlProp?.type === ControlType.Slot)\n\n\t\t\tconst reachedMaxCount = isNumber(control.maxCount) && controlProp.value.length >= control.maxCount\n\t\t\tif (reachedMaxCount) {\n\t\t\t\tconst slotTitle = slotTitleForControlKey(node, this.engine.componentLoader, slotKey)\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"warning\",\n\t\t\t\t\ttext: `The ${slotTitle} property only supports ${control.maxCount} layer${control.maxCount === 1 ? \"\" : \"s\"}`,\n\t\t\t\t\ticon: \"warning\",\n\t\t\t\t\tduration: 3000,\n\t\t\t\t})\n\t\t\t\treturn this.exitTool()\n\t\t\t}\n\n\t\t\tif (reference) {\n\t\t\t\tupdate = {\n\t\t\t\t\t[slotKey]: {\n\t\t\t\t\t\ttype: ControlType.Slot,\n\t\t\t\t\t\tvalue: List.push(controlProp.value, { id: randomID(), reference }),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdate = {\n\t\t\t\t\t[slotKey]: {\n\t\t\t\t\t\ttype: ControlType.Slot,\n\t\t\t\t\t\tvalue: List.pop(controlProp.value),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst nodeUpdate = prefixControlProps(update)\n\t\tthis.engine.tree.current(node)?.set(nodeUpdate)\n\t\tthis.exitTool()\n\t}\n\n\texitTool = () => {\n\t\tthis.engine.exitTool()\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { NodeID, TextNode } from \"document/models/CanvasTree/index.ts\"\nimport { NullID } from \"document/models/CanvasTree/index.ts\"\nimport { isTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { migrateTextToRichTextNode } from \"document/utils/migrateTextToRichTextNode.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\n\nexport type TextEditEventSource = \"none\" | \"mouse\" | \"keyboard\"\n\nexport interface TextEditToolOptions {\n\t/** Entry point for the tool, either double click, cmd+enter etc. Used to tweak initial state */\n\teventSource?: TextEditEventSource\n\n\t/** If the text is empty when the tool exit it will be deleted. Set this to true if the undo\n\t * entry should not be preserved either. */\n\tignoreEditIfEmpty?: boolean\n\n\t/** Set to true if an undo group was already started by the caller. */\n\tundoGroupExists?: boolean\n}\n\nexport class TextEditTool extends withClassDiscriminator(\"TextEditTool\", VekterTool) {\n\toverride readonly enum = Tools.TextEdit\n\n\t// FIXME: the ! is unsafe; it is assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where this field is undefined\n\tnodeId!: NodeID\n\n\tprivate isLoadingFonts = false\n\tprivate unsubscribeFromFullTreeMigration?: () => void\n\n\tconstructor(\n\t\tengine: VekterEngine,\n\t\tprivate options: TextEditToolOptions = {},\n\t) {\n\t\tsuper(engine)\n\t}\n\n\tget eventSource() {\n\t\treturn this.options.eventSource ?? \"none\"\n\t}\n\n\tmigrateToRichText(textNode: TextNode<any>) {\n\t\tconst engine = this.engine\n\n\t\tconst { selectionStore } = engine.stores\n\n\t\t// Exit the text edit tool first\n\t\tselectionStore.clear()\n\t\tengine.exitTool()\n\n\t\tconst migrationInfo = migrateTextToRichTextNode(engine, textNode)\n\n\t\tif (migrationInfo) {\n\t\t\tselectionStore.set(migrationInfo.idToSelect)\n\t\t}\n\n\t\t// Exit the TextEdit tool and start the RichTextTool instead\n\t\tengine.setTool(Tools.RichTextEdit, this.options)\n\t}\n\n\toverride start() {\n\t\tconst { tree } = this.engine\n\t\tthis.nodeId = this.engine.stores.selectionStore.ids[0]\n\n\t\tif (!this.options.undoGroupExists) {\n\t\t\tthis.engine.beginUndoGroup()\n\t\t}\n\n\t\tconst node = tree.getNode(this.nodeId) as TextNode<any>\n\t\tif (!node) return this.engine.exitTool()\n\n\t\tconst engine = this.engine\n\t\tthis.unsubscribeFromFullTreeMigration?.()\n\t\tif (engine.stores.treeStore.getDataTree()) {\n\t\t\tconst currentNode = engine.tree.current(node)\n\t\t\tif (currentNode) this.migrateToRichText(currentNode)\n\t\t\tthis.unsubscribeFromFullTreeMigration = undefined\n\t\t} else {\n\t\t\tthis.unsubscribeFromFullTreeMigration = engine.runWithFullyLoadedTree(\n\t\t\t\t() => {\n\t\t\t\t\tthis.unsubscribeFromFullTreeMigration = undefined\n\t\t\t\t\tconst currentNode = engine.tree.current(node)\n\t\t\t\t\tif (!currentNode) return\n\t\t\t\t\treturn this.migrateToRichText(currentNode)\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmodalTitle: \"Updating your Text Layer\u2026\",\n\t\t\t\t\tname: \"migrate_text_to_rich_text\",\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t}\n\n\toverride update() {\n\t\tconst { mouseStore, selectionStore } = this.engine.stores\n\t\tconst { latest, previous } = mouseStore\n\t\tif (latest.canvasMouseDownPosition && !previous.canvasMouseDownPosition) {\n\t\t\t// Need to switch to the Select tool instead of exitTool() as the default Highlight tool\n\t\t\t// will clear the current selection.\n\t\t\tthis.engine.setTool(Tools.Select)\n\t\t} else if (selectionStore.ids[0] !== this.nodeId) {\n\t\t\tthis.engine.exitTool()\n\t\t} else {\n\t\t\t// In multi-user scenarios the node might get deleted while editing.\n\t\t\t// Or it might get recreated via the remoteTree. This makes sure we\n\t\t\t// can handle both.\n\t\t\tconst node = this.engine.tree.getNode(this.nodeId) as TextNode<any>\n\t\t\tif (!node) {\n\t\t\t\tthis.engine.exitTool()\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Prevent showing the editor with a FOUT (flash of unstyled text)\n\t\t\tif (!this.isLoadingFonts) {\n\t\t\t\tnode.cache.isEditable = true\n\t\t\t}\n\t\t}\n\t}\n\n\toverride stop() {\n\t\tconst engine = this.engine\n\t\tengine.stores.toolStore.nodeInTextEditorId = NullID\n\n\t\tthis.unsubscribeFromFullTreeMigration?.()\n\t\tthis.unsubscribeFromFullTreeMigration = undefined\n\n\t\tconst node = engine.tree.getNode<TextNode<any>>(this.nodeId)\n\t\tif (isTextNode(node)) {\n\t\t\tconst noText = node?.styledText.text.length === 0\n\t\t\tconst isViewOnly = getIsViewOnly(engine, \"canDesign\")\n\n\t\t\tif (node) {\n\t\t\t\tnode.cache.isEditable = false\n\t\t\t}\n\n\t\t\tif (noText && this.options.ignoreEditIfEmpty && !isViewOnly) {\n\t\t\t\t// If this was a just created text, discard the whole edit via the undo stack.\n\t\t\t\tengine.discardUndoGroup()\n\t\t\t} else if (noText && !isReplicaOrReplicaChild(node) && !isViewOnly) {\n\t\t\t\t// If this was an existing text, delete it, but keep an undo entry.\n\t\t\t\tengine.deleteNode(node.id)\n\t\t\t\tengine.endUndoGroup()\n\t\t\t} else {\n\t\t\t\t// Otherwise just close the undo group.\n\t\t\t\tengine.endUndoGroup()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate fontsLoaded() {\n\t\t// If the tool changed in the mean time, don\u2019t bother\n\t\tif (this.engine.tool !== this) return\n\n\t\tconst node = this.engine.tree.getNode(this.nodeId) as TextNode<any>\n\t\tif (!node) return\n\n\t\tnode.cache.isEditable = true\n\t\tthis.engine.stores.toolStore.nodeInTextEditorId = node.id\n\t}\n}\n", "import { triggerCanvasZoomEvent } from \"@framerjs/framer-events\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { zoomInCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine } from \"./pathEdit/PathToolManager.tsx\"\n\nexport class ZoomSelectTool extends withClassDiscriminator(\"ZoomSelectTool\", VekterTool) {\n\toverride readonly enum = Tools.ZoomSelect\n\toverride readonly wantsAutoscrolling = true\n\n\tpathEngine?: VekterPathEngine\n\n\toverride start() {\n\t\tthis.engine.stores.mouseCursorStore.current = zoomInCursor\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\toverride update() {\n\t\tconst { mouseStore, canvasStore } = this.engine.stores\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = mouseStore.latest\n\t\tconst previous = mouseStore.previous\n\n\t\tif (previous.canvasMouseDownPosition && !canvasMouseDownPosition && canvasMousePosition) {\n\t\t\tconst frame = Rect.fromTwoPoints(previous.canvasMouseDownPosition, canvasMousePosition)\n\t\t\tcanvasStore.zoomToCenter(frame, { snapToZoomSteps: true })\n\t\t\ttriggerCanvasZoomEvent({\n\t\t\t\tsource: \"selection\",\n\t\t\t})\n\n\t\t\tif (this.pathEngine) {\n\t\t\t\tthis.pathEngine.switchToDefault()\n\t\t\t} else {\n\t\t\t\tthis.engine.exitTool()\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { triggerCanvasZoomEvent } from \"@framerjs/framer-events\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { zoomInCursor, zoomOutCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { ZoomSelectTool } from \"./ZoomSelectTool.ts\"\nimport type { VekterPathEngine } from \"./pathEdit/PathToolManager.tsx\"\n\nexport class ZoomTool extends withClassDiscriminator(\"ZoomTool\", VekterTool) {\n\toverride readonly enum = Tools.Zoom\n\toverride readonly wantsAutoscrolling = true\n\n\tpathEngine?: VekterPathEngine\n\n\toverride start() {\n\t\tthis.updateCursor(this.engine.stores.mouseStore.latest.altKey)\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\toverride update() {\n\t\tconst { canvasStore, persistedUserDefaults, mouseStore } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMouseDownPosition, windowMousePosition, windowMouseDownPosition, altKey } = latest\n\n\t\tif (altKey !== previous.altKey) {\n\t\t\tthis.updateCursor(altKey)\n\t\t}\n\n\t\tif (windowMousePosition && windowMouseDownPosition) {\n\t\t\tconst delta = Point.distance(windowMousePosition, windowMouseDownPosition)\n\n\t\t\tif (delta > 10) {\n\t\t\t\tif (this.pathEngine) {\n\t\t\t\t\tthis.pathEngine.setPathTool(new ZoomSelectTool(this.engine))\n\t\t\t\t} else {\n\t\t\t\t\tthis.engine.setTool(Tools.ZoomSelect)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// mouse up\n\t\tif (previous.canvasMouseDownPosition && !canvasMouseDownPosition) {\n\t\t\tif (altKey) {\n\t\t\t\tcanvasStore.zoomOut(previous.canvasMouseDownPosition, {\n\t\t\t\t\tanimated: persistedUserDefaults.animateOnZoom,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tcanvasStore.zoomIn(previous.canvasMouseDownPosition, {\n\t\t\t\t\tanimated: persistedUserDefaults.animateOnZoom,\n\t\t\t\t})\n\t\t\t}\n\t\t\ttriggerCanvasZoomEvent({\n\t\t\t\tsource: \"zoom_tool\",\n\t\t\t})\n\t\t}\n\t}\n\n\texit() {\n\t\tif (this.pathEngine) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t} else {\n\t\t\tthis.engine.exitTool()\n\t\t}\n\t}\n\n\toverride onKeyUp = (event: KeyboardEvent) => {\n\t\tif (event.code === \"KeyZ\") {\n\t\t\tthis.exit()\n\t\t}\n\t}\n\n\tprivate updateCursor(altKey: boolean) {\n\t\tconst { mouseCursorStore } = this.engine.stores\n\t\tif (altKey) {\n\t\t\tmouseCursorStore.current = zoomOutCursor\n\t\t} else {\n\t\t\tmouseCursorStore.current = zoomInCursor\n\t\t}\n\t}\n}\n", "import { triggerInteractiveLinkCreateEvent } from \"@framerjs/framer-events\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { trackActionCreation } from \"document/components/chrome/properties/panels/utils/eventActionTracking.ts\"\nimport { hasEvents } from \"document/models/CanvasTree/actions/actions.ts\"\nimport type {\n\tNavigationAction,\n\tUpdateNavigationTargetOptions,\n} from \"document/models/CanvasTree/actions/navigationActions.ts\"\nimport {\n\tcontainsNavigationActionWithoutTarget,\n\tgetNavigateOptionsFromActionControls,\n\tisNavigationAction,\n\tisNavigationTargetOptions,\n\tupdateNavigationTarget,\n} from \"document/models/CanvasTree/actions/navigationActions.ts\"\nimport type { SetVariantAction, UpdateSetVariantOptions } from \"document/models/CanvasTree/actions/variantActions.ts\"\nimport {\n\tcontainsSetVariantActionWithoutVariant,\n\tgetSetVariantOptionsFromActionControls,\n\tisSetVariantAction,\n\tupdateSetVariantVariant,\n} from \"document/models/CanvasTree/actions/variantActions.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { NullID } from \"document/models/CanvasTree/index.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport type CodeComponentNode from \"document/models/CanvasTree/nodes/CodeComponentNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisFrameNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isLocalSmartComponentInstance } from \"document/models/CanvasTree/nodes/utils/smartComponentInstanceHelpers.ts\"\nimport { withFrameEvents } from \"document/models/CanvasTree/traits/WithFrameEvents.ts\"\nimport { withLock } from \"document/models/CanvasTree/traits/WithLock.ts\"\nimport { isGestureOrGestureVariantChild, isTopLevelVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { withFormInputEvents } from \"document/models/CanvasTree/traits/forms/WithFormInputEvents.ts\"\nimport { isDeviceNode } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifierChecks.ts\"\nimport { isEventAction } from \"document/models/EventAction.ts\"\nimport { prefixControlProps } from \"document/models/controlProps/controlPropKey.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { createAndAssignActionVariableToNode } from \"../utils/createAndAssignActionVariableToNode.ts\"\n\nfunction isValidSource(componentLoader: ComponentLoader, node: CanvasNode): boolean {\n\t// If the platform supports variant editing, a component instance without\n\t// events should be a valid source, so that users could create an action by\n\t// linking.\n\tif (isLocalSmartComponentInstance(node)) return true\n\tif (isGestureOrGestureVariantChild(node)) return false\n\treturn hasEvents(node, componentLoader)\n}\n\nexport type PopoverType = \"action\"\n\nexport class LinkTool extends withClassDiscriminator(\"LinkTool\", VekterTool) {\n\toverride readonly enum = Tools.Link\n\n\treadyForDestinationTarget = false\n\tisVariantLink = false\n\n\tactivePopover: PopoverType | null = null\n\t_linkTargetId: NodeID | null = null\n\t_linkSourceId: NodeID | null = null\n\n\tgetLinkSourceCandidate(): CanvasNode | null {\n\t\tconst selection = this.engine.stores.selectionStore.ids\n\t\tif (selection.length !== 1) return null\n\t\tconst node = this.engine.tree.get(selection[0])\n\t\treturn node && isValidSource(this.engine.componentLoader, node) ? node : null\n\t}\n\n\tgetLinkSource(): CanvasNode | null {\n\t\tif (!this._linkSourceId) return null\n\t\treturn this.engine.tree.getNode(this._linkSourceId)\n\t}\n\n\tgetLinkTarget(): CanvasNode | null {\n\t\tif (!this._linkTargetId) return null\n\t\treturn this.engine.tree.getNode(this._linkTargetId)\n\t}\n\n\toverride start() {\n\t\t// NOTE: The starting happens \u201Cdefensively\u201D. Ideally these checks should\n\t\t// be done beforehand, so there is no attempt to start the link tool\n\t\t// when it would result in it immediately exiting. This requires a bit\n\t\t// of a shortcut handling refactor.\n\t\t// See https://github.com/framer/FramerStudio/pull/14491#pullrequestreview-1455234217\n\t\tconst activeScope = this.engine.stores.scopeStore.active\n\t\tif (isWebPageNode(activeScope) || this.engine.stores.overlayStore.editModeActive) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\t\tconst candidate = this.getLinkSourceCandidate()\n\t\tif (!candidate) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis._linkSourceId = candidate.id\n\t\tthis.isVariantLink = isSmartComponentNode(activeScope)\n\t}\n\n\tisValidTarget(tree: CanvasTree, potentialTarget: CanvasNode | null, source: CanvasNode | undefined): boolean {\n\t\tif (!potentialTarget || !source) return false\n\t\tif (withLock(potentialTarget) && potentialTarget.locked) return false\n\n\t\tif (this.isVariantLink) return isTopLevelVariant(potentialTarget)\n\t\tif (isDeviceNode(potentialTarget)) return false\n\n\t\tconst ancestors = tree.getAncestors(source.id)\n\t\tconst targetIsAncestor = ancestors.find(ancestor => ancestor === potentialTarget.id)\n\n\t\treturn (\n\t\t\t!targetIsAncestor &&\n\t\t\t(isFrameNode(potentialTarget) || isCodeComponentNode(potentialTarget)) &&\n\t\t\tpotentialTarget.id !== source.id &&\n\t\t\ttree.isGroundNode(potentialTarget)\n\t\t)\n\t}\n\n\toverride update() {\n\t\tconst linkSource = this.getLinkSource()\n\n\t\tif (!linkSource) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\t// If the selection has changed, exit tool\n\t\tconst candidate = this.getLinkSourceCandidate()\n\t\tif (!candidate || candidate.id !== linkSource.id) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (this.activePopover) {\n\t\t\treturn\n\t\t}\n\n\t\tconst { tree } = this.engine\n\t\tconst { treeStore, scopeStore, mouseCursorStore, mouseStore } = this.engine.stores\n\t\tconst {\n\t\t\tlatest: { canvasMousePosition, canvasMouseDownPosition },\n\t\t\tprevious,\n\t\t} = mouseStore\n\n\t\tconst linkTarget = tree\n\t\t\t.getNodesAtPoint(scopeStore.active, canvasMousePosition)\n\t\t\t.reverse()\n\t\t\t.find(nodeAtPoint => this.isValidTarget(tree, nodeAtPoint, linkSource))\n\n\t\tthis._linkTargetId = linkTarget?.id ?? null\n\t\tif (linkTarget) {\n\t\t\ttreeStore.setHighlight(linkTarget.id)\n\t\t} else {\n\t\t\ttreeStore.setHighlight(NullID)\n\t\t}\n\n\t\tmouseCursorStore.clear()\n\n\t\tconst prevMouseDown = previous.canvasMouseDownPosition\n\t\tconst isMouseUp = canvasMouseDownPosition === null && prevMouseDown !== null\n\n\t\tif (isMouseUp && (this.readyForDestinationTarget || Point.distance(prevMouseDown, canvasMousePosition) > 4)) {\n\t\t\tif (linkTarget) {\n\t\t\t\tif (this.isVariantLink) {\n\t\t\t\t\tthis.updateVariantTarget(linkSource, linkTarget.id)\n\t\t\t\t} else {\n\t\t\t\t\tthis.activePopover = \"action\"\n\t\t\t\t}\n\t\t\t\ttriggerInteractiveLinkCreateEvent({ linkType: this.isVariantLink ? \"variant\" : \"transition\" })\n\t\t\t} else {\n\t\t\t\tthis.engine.exitTool()\n\t\t\t}\n\t\t}\n\t\tthis.readyForDestinationTarget =\n\t\t\tthis.readyForDestinationTarget || isMouseUp || (linkSource !== null && canvasMouseDownPosition === null)\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t\tthis.engine.stores.mouseStore.setMouseDown(false)\n\t}\n\n\texitTool = () => {\n\t\t// we can't wrap the main function itself because the engine isn't available in time\n\t\tthis.engine.scheduler.wrapHandler(() => {\n\t\t\tthis.engine.exitTool()\n\t\t})()\n\t}\n\n\tpreferredEventKeyForCodeComponent(source: CodeComponentNode, fallbackToFirst = false): string | null {\n\t\tconst component = this.engine.componentLoader.componentForIdentifier(source.codeComponentIdentifier)\n\t\tif (!component || !component.properties) return null\n\n\t\tconst eventKeys = Object.keys(component.properties).filter(key => {\n\t\t\tconst property = component.properties[key]\n\t\t\treturn property && property.type === ControlType.EventHandler\n\t\t})\n\n\t\tif (eventKeys.length === 0) {\n\t\t\treturn null\n\t\t}\n\t\tif (eventKeys.length === 1) {\n\t\t\treturn eventKeys[0]!\n\t\t}\n\n\t\tconst eventKeysWithoutTarget = eventKeys.filter(key => {\n\t\t\tconst actionControlProp = source.getRawControlProp(key)\n\t\t\tif (!actionControlProp || !Array.isArray(actionControlProp.value)) return false\n\t\t\tif (this.isVariantLink) {\n\t\t\t\treturn containsSetVariantActionWithoutVariant(actionControlProp.value)\n\t\t\t} else {\n\t\t\t\treturn containsNavigationActionWithoutTarget(actionControlProp.value)\n\t\t\t}\n\t\t})\n\n\t\tif (eventKeysWithoutTarget.length === 1) {\n\t\t\treturn eventKeysWithoutTarget[0]!\n\t\t}\n\n\t\treturn fallbackToFirst ? eventKeys[0]! : null\n\t}\n\n\t// The function is directly passed in to `displayEventSelectionMenu` handler,\n\t// we need to use a fat arrow function to bind \"this\"\n\tupdateNavigationTargetForSource = (eventKey: string, action?: NavigationAction) => {\n\t\tconst source = this.getLinkSource()\n\t\tif (!source) return this.exitTool()\n\t\tif (!withFrameEvents(source) && !withFormInputEvents(source) && !isCodeComponentNode(source)) {\n\t\t\treturn this.exitTool()\n\t\t}\n\n\t\tconst target = this.getLinkTarget()\n\t\tif (!target) return this.exitTool()\n\n\t\tconst options = action ? getNavigateOptionsFromActionControls(action.controls) : undefined\n\t\tconst { documentSettingsStore } = this.engine.stores\n\t\tconst info = {\n\t\t\t...options,\n\t\t\ttarget: target.id,\n\t\t\ttransition: options?.transition ?? documentSettingsStore.defaultTransition,\n\t\t\tappearsFrom: options?.appearsFrom ?? documentSettingsStore.defaultAppearsFrom,\n\t\t}\n\n\t\tif (isCodeComponentNode(source)) {\n\t\t\tconst eventControl = source.getRawControlProp(eventKey)\n\t\t\tconst actions = updateNavigationTarget(eventKey, eventControl?.value, info, action?.meta)\n\t\t\tconst nodeUpdate = prefixControlProps({\n\t\t\t\t[eventKey]: { type: ControlType.EventHandler, value: actions },\n\t\t\t})\n\t\t\tsource.set(nodeUpdate)\n\t\t} else {\n\t\t\tconst actions = updateNavigationTarget(eventKey, source[eventKey as keyof CanvasNode], info, action?.meta)\n\t\t\tsource.set({ [eventKey]: actions })\n\t\t}\n\n\t\t// We only want to track the action creation when the popover is shown.\n\t\t// Currently, we don't show popover for variant actions, thus we are not tracking it in `updateSetVariantTargetForSource`.\n\t\t// And `updateNavigationTargetForSource` only receives an action if called by the link popover.\n\t\tif (isEventAction(action)) {\n\t\t\ttrackActionCreation({ action, eventKey, node: source })\n\t\t}\n\n\t\tthis.engine.exitTool()\n\t}\n\n\tupdateVariantTarget(source: CanvasNode, variantId: NodeID) {\n\t\tif (!hasEvents(source, this.engine.componentLoader)) {\n\t\t\tif (isLocalSmartComponentInstance(source)) {\n\t\t\t\tconst variantNode = this.engine.tree.getNode(variantId)\n\t\t\t\tif (variantNode) {\n\t\t\t\t\tthis.activePopover = \"action\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\tif (withFrameEvents(source) || withFormInputEvents(source)) {\n\t\t\t// Display popover so the user can easily find the appear trigger\n\t\t\tthis.activePopover = \"action\"\n\t\t\treturn\n\t\t} else if (isCodeComponentNode(source)) {\n\t\t\tconst preferredEvent = this.preferredEventKeyForCodeComponent(source, false)\n\n\t\t\tif (preferredEvent) {\n\t\t\t\tconst eventControl = source.getRawControlProp(preferredEvent)\n\t\t\t\tconst actions = updateSetVariantVariant(eventControl?.value, {\n\t\t\t\t\ttype: \"set\",\n\t\t\t\t\tvariantId,\n\t\t\t\t})\n\t\t\t\tconst nodeUpdate = prefixControlProps({\n\t\t\t\t\t[preferredEvent]: { type: ControlType.EventHandler, value: actions },\n\t\t\t\t})\n\t\t\t\tthis.engine.tree.current(source)?.set(nodeUpdate)\n\t\t\t\tthis.engine.exitTool()\n\t\t\t} else {\n\t\t\t\tthis.activePopover = \"action\"\n\t\t\t}\n\t\t}\n\t}\n\n\t// The function is directly passed in to `displayEventSelectionMenu` handler,\n\t// we need to use a fat arrow function to bind \"this\"\n\tupdateVariantTargetForSource = (eventKey: string, action?: SetVariantAction) => {\n\t\tconst source = this.getLinkSource()\n\t\tif (!source) return this.exitTool()\n\t\tif (!withFrameEvents(source) && !withFormInputEvents(source) && !isCodeComponentNode(source)) {\n\t\t\treturn this.exitTool()\n\t\t}\n\n\t\tconst target = this.getLinkTarget()\n\t\tif (!target) return this.exitTool()\n\n\t\tconst options = action ? getSetVariantOptionsFromActionControls(action.controls) : undefined\n\n\t\tconst info: UpdateSetVariantOptions = {\n\t\t\ttype: options?.type ?? \"set\",\n\t\t\tvariantId: options?.variantId ?? target.id,\n\t\t}\n\n\t\tif (isCodeComponentNode(source)) {\n\t\t\tconst eventControl = source.getRawControlProp(eventKey)\n\t\t\tconst currentActions = eventControl?.value\n\t\t\tconst actions = updateSetVariantVariant(currentActions, info, action?.meta)\n\t\t\tconst nodeUpdate = prefixControlProps({\n\t\t\t\t[eventKey]: { type: ControlType.EventHandler, value: actions },\n\t\t\t})\n\t\t\tsource.set(nodeUpdate)\n\t\t} else {\n\t\t\tconst actions = updateSetVariantVariant(source[eventKey as keyof CanvasNode], info, action?.meta)\n\t\t\tsource.set({ [eventKey]: actions })\n\t\t}\n\n\t\tthis.engine.exitTool()\n\t}\n\n\t// Create a trigger for the smart component,\n\t// and add an action to the selected layer\n\taddEventHandlerToSmartComponentAndAssignAction(\n\t\tsource: CanvasNode,\n\t\ttarget: CanvasNode,\n\t\tlayerId: NodeID,\n\t\teventKey: string,\n\t\taction: NavigationAction | SetVariantAction,\n\t) {\n\t\tif (!isCodeComponentNode(source)) return this.exitTool()\n\n\t\tlet info: UpdateNavigationTargetOptions | UpdateSetVariantOptions | null = null\n\n\t\tconst node = this.engine.tree.getNode(layerId)\n\t\tif (!node) return this.exitTool()\n\n\t\tif (isSetVariantAction(action)) {\n\t\t\tconst setVariantOptions = getSetVariantOptionsFromActionControls(action.controls)\n\t\t\tinfo = { ...setVariantOptions, variantId: target.id }\n\t\t} else if (isNavigationAction(action)) {\n\t\t\tconst navigateOptions = getNavigateOptionsFromActionControls(action.controls)\n\t\t\tinfo = {\n\t\t\t\t...navigateOptions,\n\t\t\t\ttarget: target.id,\n\t\t\t}\n\t\t}\n\t\tif (!info) return this.exitTool()\n\n\t\tconst variableId = createAndAssignActionVariableToNode(\n\t\t\tthis.engine.tree,\n\t\t\tthis.engine.componentLoader,\n\t\t\tnode,\n\t\t\teventKey,\n\t\t\tundefined,\n\t\t\tthis.engine.stores.codeGenerationStore,\n\t\t)\n\t\tif (!variableId) return this.exitTool()\n\t\t// Update component instance\n\t\tconst eventControl = source.getRawControlProp(variableId)\n\t\tconst actions = isNavigationTargetOptions(info)\n\t\t\t? updateNavigationTarget(eventKey, eventControl?.value, info, action.meta)\n\t\t\t: updateSetVariantVariant(eventControl?.value, info, action.meta)\n\n\t\tconst nodeUpdate = prefixControlProps({\n\t\t\t[variableId]: { type: ControlType.EventHandler, value: actions },\n\t\t})\n\n\t\tthis.engine.tree.current(source)?.set(nodeUpdate)\n\t\tthis.exitTool()\n\t}\n}\n", "import * as Logger from \"@framerjs/shared\"\nimport { assert, List, isCommandKeyPressed } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasTree, NodeID, VectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { PathNode, nodeIDFromString } from \"document/models/CanvasTree/index.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport type { ClosestCurve, PathSegmentSelector, SegmentHandleSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType, PointRounding, SegmentHandle } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport type { HandleMirroring, PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { Pan, PanTool } from \"../Pan.tsx\"\nimport { ZoomTool } from \"../Zoom.ts\"\nimport { ZoomSelect } from \"../ZoomSelect.tsx\"\nimport { ZoomSelectTool } from \"../ZoomSelectTool.ts\"\nimport type { SubToolManagerProps } from \"../props.ts\"\nimport { getNudgeDelta } from \"../utils/getNudgeDelta.ts\"\nimport { PathCurveBend, PathCurveBendTool } from \"./PathCurveBend.tsx\"\nimport { PathDefault, PathDefaultTool } from \"./PathDefault.tsx\"\nimport { PathSegmentAddition } from \"./PathSegmentAddition.tsx\"\nimport { PathSegmentAdditionTool } from \"./PathSegmentAdditionTool.ts\"\nimport { PathSegmentHandleMove, PathSegmentHandleMoveTool } from \"./PathSegmentHandleMove.tsx\"\nimport { PathSegmentMoveTool } from \"./PathSegmentMove.ts\"\nimport { PathSegmentSelect, PathSegmentSelectTool } from \"./PathSegmentSelect.tsx\"\nimport { PathCurves } from \"./controls/PathCurves.tsx\"\nimport { PathSegmentAnchors } from \"./controls/PathSegmentAnchors.tsx\"\nimport { PathSegmentHandles } from \"./controls/PathSegmentHandles.tsx\"\nimport { PathShapes } from \"./controls/PathShapes.tsx\"\nimport { PathSnapper } from \"./utils/PathSnapper.ts\"\nimport {\n\tcloneNodeAndUpdatePath,\n\tgenerateSegmentSelection,\n\tclosestCurve as getClosestCurve,\n\tgroupPathSegmentSelectors,\n\thandleUpdate,\n\troundedPoint,\n\tsegmentHandlePoint,\n} from \"./utils/index.ts\"\n\nconst log = Logger.getLogger(\"PathToolManager\")\n\ninterface Props extends SubToolManagerProps<VekterPathEngine> {\n\tsnapConstraint: Line | null\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tsegmentHovered: PathSegmentSelector | null\n\tsegmentHandle: SegmentHandleSelector | null\n\tclosestCurve: ClosestCurve | null\n\tpointRounding: PointRounding\n}\n\nexport interface VekterPathTool extends VekterTool {\n\tpathEngine: VekterPathEngine\n}\n\nexport class VekterPathEngine extends withClassDiscriminator(\"VekterPathEngine\", VekterTool) {\n\toverride readonly enum = Tools.Path\n\n\t// FIXME: the !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tpathTool!: VekterPathTool\n\tsnap!: PathSnapper\n\n\t// we capture the selection that we were working on, so when we stop, we can clean up properly\n\tworkingSelection: NodeID[] = []\n\n\ttree!: CanvasTree\n\tsnapConstraint!: Line | null\n\tsegmentSelection: PathSegmentSelector[] = []\n\tselectionType!: PathSelectionType\n\tsegmentHovered!: PathSegmentSelector | null\n\tsegmentHandle!: SegmentHandleSelector | null\n\tclosestCurve!: ClosestCurve | null\n\tpointRounding: PointRounding = PointRounding.Full\n\n\t// **** store methods proxied ****\n\n\tsetSegmentSelection(segments: PathSegmentSelector[], selectionType = PathSelectionType.Segments) {\n\t\t// if (!this.engine.processingEvents) throw Error(\"state error\")\n\t\tthis.engine.stores.pathSelectionStore.setSegmentSelection(segments, selectionType)\n\t\tthis.updateState()\n\t}\n\n\ttoggleSegmentSelection(segments: PathSegmentSelector[], selectionType = PathSelectionType.Segments) {\n\t\tthis.engine.assertStateMutable()\n\t\tthis.engine.stores.pathSelectionStore.toggleSegmentSelection(segments, selectionType)\n\t\tthis.updateState()\n\t}\n\n\tsetSegmentHandle(handle: SegmentHandleSelector | null) {\n\t\tthis.engine.assertStateMutable()\n\t\tthis.engine.stores.pathSelectionStore.setSegmentHandle(handle)\n\t\tthis.updateState()\n\t}\n\n\tsetHoveredSegment(segment: PathSegmentSelector | null) {\n\t\tthis.engine.assertStateMutable()\n\t\tthis.engine.stores.pathSelectionStore.setHoveredSegment(segment)\n\t\tthis.updateState()\n\t}\n\n\tsetClosestCurve(curve: ClosestCurve | null) {\n\t\t// if (!this.engine.processingEvents) throw Error(\"state error\")\n\t\tthis.engine.stores.pathSelectionStore.setClosestCurve(curve)\n\t\tthis.updateState()\n\t}\n\n\tsetPathConstraint(constraint: null | Line) {\n\t\tthis.engine.assertStateMutable()\n\t\tthis.engine.stores.pathSelectionStore.setPathConstraint(constraint)\n\t\tthis.updateState()\n\t}\n\n\t// **** end ****\n\n\tupdateState() {\n\t\t// TODO this is inefficient, but it speaks to the endgoal, where we want disicpline around this\n\t\tthis.tree = this.engine.tree\n\t\tconst props = this.engine.stores.pathSelectionStore.state\n\t\tthis.snapConstraint = props.snapConstraint\n\t\tthis.segmentSelection = props.segmentSelection\n\t\tthis.selectionType = props.selectionType\n\t\tthis.segmentHovered = props.segmentHovered\n\t\tthis.segmentHandle = props.segmentHandle\n\t\tthis.closestCurve = props.closestCurve\n\t\tthis.pointRounding = props.pointRounding\n\t}\n\n\toverride start() {\n\t\tthis.snap = new PathSnapper(this.engine, this)\n\t\tconst { selectionStore, treeStore } = this.engine.stores\n\n\t\tconst segmentSelection: PathSegmentSelector[] = []\n\t\tconst selectedNodes = selectionStore.ids.map(id => this.engine.tree.getNode(id))\n\t\tconst selectedPathNode = selectedNodes.find(node => node instanceof PathNode)\n\t\tif (selectedPathNode && selectedPathNode.pathSegments.length > 0) {\n\t\t\tsegmentSelection.push({ id: selectedPathNode.id, index: 0 })\n\t\t}\n\n\t\ttreeStore.setHighlight(null)\n\t\tthis.setSegmentSelection(segmentSelection)\n\t\tthis.setClosestCurve(null)\n\t\tthis.setWorkingSelection(selectionStore.ids)\n\t\tthis.setPathTool(new PathDefaultTool(this.engine, this))\n\t\tthis.pathTool.start()\n\t}\n\n\toverride stop() {\n\t\tthis.pathTool.stop()\n\t\tthis.setSegmentSelection([])\n\t\tthis.setClosestCurve(null)\n\t\tthis.setWorkingSelection([])\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.snap.stop()\n\t}\n\n\toverride update() {\n\t\tconst { selectionStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMiddleMouseButtonDownPosition, latest, previous: previousState } = mouseStore\n\t\tconst { spacebar } = latest\n\n\t\tconst ignoreMouse = shouldIgnoreMouseEvents(this.pathTool)\n\n\t\tif (ignoreMouse) {\n\t\t\tthis.setClosestCurve(null)\n\t\t} else if (!isEqual(selectionStore.ids, this.workingSelection)) {\n\t\t\tthis.setWorkingSelection(selectionStore.ids)\n\n\t\t\t// when the selection changes and not all selected things are path nodes, exit the vecter editing tool\n\t\t\tif (\n\t\t\t\tselectionStore.ids.length === 0 ||\n\t\t\t\tselectionStore.ids.filter(id => !(this.engine.tree.getNode(id) instanceof PathNode)).length > 0\n\t\t\t) {\n\t\t\t\tthis.engine.exitTool()\n\t\t\t\treturn\n\t\t\t}\n\t\t} else if (\n\t\t\t((spacebar && !previousState.spacebar) || canvasMiddleMouseButtonDownPosition) &&\n\t\t\t(this.pathTool instanceof PathDefaultTool || this.pathTool instanceof PathSegmentAdditionTool)\n\t\t) {\n\t\t\tthis.setPathTool(new PanTool(this.engine))\n\t\t} else if (!isEqual(latest.canvasMousePosition, previousState.canvasMousePosition)) {\n\t\t\tthis.getClosestCurve()\n\t\t}\n\n\t\tthis.updateState()\n\t\tthis.setActiveTool()\n\t\tthis.snap.update()\n\t\tthis.pathTool.update()\n\t}\n\n\t// for any no longer selected PathNode, we delete it from the document if only 1 segment\n\tsetWorkingSelection(selection: NodeID[]) {\n\t\tconst workingSelection = this.workingSelection\n\t\tthis.workingSelection = selection\n\n\t\tworkingSelection.forEach(id => {\n\t\t\tif (selection.includes(id)) return\n\t\t\tconst node = this.engine.tree.getNode(id)\n\t\t\tif (!(node instanceof PathNode)) return\n\t\t\tif (node.pathSegments.length > 1) return\n\t\t\tthis.deleteNode(node)\n\t\t})\n\n\t\t// make sure segment selection does not retain anything from nodes no longer under edit\n\t\tconst segmentSelection = this.segmentSelection.filter(s => selection.includes(s.id))\n\t\tthis.setClosestCurve(null)\n\t\tthis.setSegmentSelection(segmentSelection, this.selectionType)\n\t\tif (segmentSelection.length === 0) {\n\t\t\tthis.switchToDefault()\n\t\t}\n\t}\n\n\tprivate deleteNode(node: VectorNode) {\n\t\tthis.engine.deleteNode(node.id)\n\t}\n\n\toverride onKeyPress = (event: KeyboardEvent) => {\n\t\tconst hasModifier = event.shiftKey || isCommandKeyPressed(event)\n\t\tif (!hasModifier && event.code === \"KeyZ\") {\n\t\t\tevent.stopPropagation()\n\t\t\tif (this.pathTool instanceof ZoomSelectTool) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.setPathTool(new ZoomTool(this.engine))\n\t\t}\n\t}\n\n\toverride canDelete = () => {\n\t\tconst { selectionType, segmentHandle, segmentSelection } = this\n\t\tif (selectionType === PathSelectionType.Curves) {\n\t\t\treturn segmentSelection.length > 0\n\t\t}\n\t\tif (segmentHandle !== null) return true\n\t\treturn segmentSelection.length > 0\n\t}\n\n\toverride deleteAction = () => {\n\t\tconst { selectionType, segmentHandle } = this\n\t\tif (selectionType === PathSelectionType.Curves) {\n\t\t\tthis.deleteCurves()\n\t\t} else if (segmentHandle !== null) {\n\t\t\tthis.deleteHandle()\n\t\t} else {\n\t\t\tthis.deleteSelectedPathSegments()\n\t\t}\n\t}\n\n\toverride onKeyDown = (event: KeyboardEvent) => {\n\t\tthis.updateState()\n\t\tconst { key } = event\n\t\tconst { tree, segmentHandle } = this\n\n\t\tif (key === \"Backspace\" || key === \"Delete\") {\n\t\t\tthis.deleteAction()\n\t\t\tevent.stopPropagation()\n\t\t\tevent.preventDefault()\n\t\t\treturn\n\t\t}\n\n\t\tif (key === \"Enter\") {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (key === \"Escape\") {\n\t\t\tif (this.pathTool instanceof PathDefaultTool || this.pathTool instanceof PathSegmentAdditionTool) {\n\t\t\t\tif (this.segmentSelection.length === 0) {\n\t\t\t\t\tthis.engine.exitTool()\n\t\t\t\t} else {\n\t\t\t\t\tthis.setSegmentSelection([])\n\t\t\t\t\tthis.setSegmentHandle(null)\n\t\t\t\t}\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\treturn\n\t\t}\n\n\t\tif (key === \"Tab\" && !isCommandKeyPressed(event)) {\n\t\t\tif (this.pathTool instanceof PathDefaultTool || this.pathTool instanceof PathSegmentAdditionTool) {\n\t\t\t\tif (this.segmentSelection.length === 0) {\n\t\t\t\t\tconst lastPathNodeId = this.workingSelection\n\t\t\t\t\t\t.slice(0)\n\t\t\t\t\t\t.reverse()\n\t\t\t\t\t\t.find(id => {\n\t\t\t\t\t\t\tconst node = this.engine.tree.getNode(id)\n\t\t\t\t\t\t\tif (!(node instanceof PathNode)) return false\n\t\t\t\t\t\t\treturn node.pathSegments.length >= 1\n\t\t\t\t\t\t})\n\t\t\t\t\tif (lastPathNodeId) {\n\t\t\t\t\t\tthis.setSegmentSelection([{ id: lastPathNodeId, index: 0 }])\n\t\t\t\t\t\tthis.setSegmentHandle(null)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst lastSegmentSelector = this.segmentSelection.slice(-1)[0]\n\t\t\t\t\tassert(lastSegmentSelector, \"Expected last segment selector from segmentSelection\")\n\t\t\t\t\tconst lastPathNode = this.engine.tree.getNode(lastSegmentSelector.id) as PathNode\n\t\t\t\t\tif (lastPathNode) {\n\t\t\t\t\t\tconst direction = event.shiftKey ? -1 : 1\n\t\t\t\t\t\tlet nextIndex = lastSegmentSelector.index + direction\n\t\t\t\t\t\tnextIndex = nextIndex >= lastPathNode.pathSegments.length ? 0 : nextIndex\n\t\t\t\t\t\tnextIndex = nextIndex < 0 ? lastPathNode.pathSegments.length - 1 : nextIndex\n\t\t\t\t\t\tthis.setSegmentSelection([{ id: lastPathNode.id, index: nextIndex }])\n\t\t\t\t\t\tthis.setSegmentHandle(null)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tevent.preventDefault()\n\t\t\treturn\n\t\t}\n\n\t\tconst delta = getNudgeDelta(key, event.shiftKey, this.engine.stores.persistedUserDefaults)\n\t\tif (delta === undefined) {\n\t\t\treturn\n\t\t}\n\n\t\tif (segmentHandle) {\n\t\t\tconst handlePoint = segmentHandlePoint(tree, segmentHandle)\n\t\t\tif (handlePoint) {\n\t\t\t\tconst newPoint = Point.add(handlePoint, { x: 0, y: 0, ...delta })\n\t\t\t\tconst pathSegments = handleUpdate(tree, segmentHandle, newPoint)\n\t\t\t\tconst node = tree.getNode(segmentHandle.id) as PathNode\n\t\t\t\tif (node && node.pathSegments) {\n\t\t\t\t\tnode.set(node.updateForPath({ pathSegments }))\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.moveSelectedVectorSegments(delta)\n\t\t}\n\n\t\tevent.stopPropagation()\n\t\tevent.preventDefault()\n\t}\n\n\t// Tool Switching\n\tsetPathTool(pathTool: VekterPathTool | (VekterTool & { pathEngine?: VekterPathEngine })) {\n\t\tconst oldName = this.pathTool ? this.pathTool.__class : \"null\"\n\t\tconst newName = pathTool.__class\n\t\tlog.debug(\"VekterPathEngine.setPathTool():\", oldName, \"->\", newName)\n\n\t\tif (this.pathTool) {\n\t\t\tthis.pathTool.stop()\n\t\t}\n\n\t\tthis.pathTool = pathTool as VekterPathTool\n\t\tpathTool.pathEngine = this\n\t\tpathTool.start()\n\t\t// Unclear why, but switching path tools doesn't always guarantee a tool processing.\n\t\t// Manually trigger a snap tool update to ensure the snapping UI stays up-to-date.\n\t\tthis.pathTool.pathEngine.snap.update()\n\t}\n\n\tswitchToDefault() {\n\t\tthis.setPathTool(new PathDefaultTool(this.engine, this))\n\t\tthis.setActiveTool()\n\t}\n\n\t// Helpers\n\n\tsetActiveTool(): void {\n\t\tconst { pathTool } = this\n\t\tconst { tree, segmentSelection, selectionType, closestCurve, snapConstraint } = this\n\n\t\tconst { cmdKey, canvasMouseDownPosition } = this.engine.stores.mouseStore.latest\n\n\t\t// never switch when mouse is down, and only for default tool or addition tool\n\t\tif (canvasMouseDownPosition) return\n\t\tif (!(pathTool instanceof PathDefaultTool || pathTool instanceof PathSegmentAdditionTool)) return\n\n\t\tif (this.engine.stores.selectionStore.ids.length === 0) {\n\t\t\tif (pathTool instanceof PathSegmentAdditionTool) return\n\t\t\tthis.setPathTool(new PathSegmentAdditionTool(this.engine, this))\n\t\t\treturn\n\t\t}\n\n\t\tif (segmentSelection.length === 1 && selectionType === PathSelectionType.Segments) {\n\t\t\tif (closestCurve && !cmdKey && !snapConstraint) {\n\t\t\t\tif (pathTool instanceof PathDefaultTool) return\n\t\t\t\tthis.setPathTool(new PathDefaultTool(this.engine, this))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst segment = segmentSelection[0]\n\t\t\tassert(segment, \"Expected segment after length === 1 check\")\n\t\t\tconst node = tree.getNode(segment.id) as PathNode\n\t\t\tif (node && Path.isEndSegment(node.pathSegments, node.pathClosed, segment.index)) {\n\t\t\t\tif (this.pathTool instanceof PathSegmentAdditionTool) return\n\t\t\t\tthis.setPathTool(new PathSegmentAdditionTool(this.engine, this))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif (this.pathTool instanceof PathDefaultTool) return\n\t\tthis.setPathTool(new PathDefaultTool(this.engine, this))\n\t}\n\n\tdeleteHandle() {\n\t\tconst { tree, segmentHandle } = this\n\t\tif (!segmentHandle) {\n\t\t\treturn\n\t\t}\n\t\tconst node = tree.getNode(segmentHandle.id) as PathNode\n\t\tconst pathSegments = List.update(node.pathSegments, segmentHandle.index, (segment: PathSegment) => {\n\t\t\tconst update: Partial<{\n\t\t\t\thandleMirroring: HandleMirroring\n\t\t\t\thandleOutX: number\n\t\t\t\thandleOutY: number\n\t\t\t\thandleInX: number\n\t\t\t\thandleInY: number\n\t\t\t}> = { handleMirroring: \"disconnected\" }\n\n\t\t\tif (segmentHandle.handle === SegmentHandle.In) {\n\t\t\t\tupdate.handleInX = 0\n\t\t\t\tupdate.handleInY = 0\n\t\t\t\tif (segment.handleOutX === 0 && segment.handleOutY === 0) {\n\t\t\t\t\tupdate.handleMirroring = \"straight\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdate.handleOutX = 0\n\t\t\t\tupdate.handleOutY = 0\n\t\t\t\tif (segment.handleInX === 0 && segment.handleInY === 0) {\n\t\t\t\t\tupdate.handleMirroring = \"straight\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn segment.merge(update)\n\t\t})\n\t\tthis.setSegmentHandle(null)\n\t\tnode.set({ pathSegments })\n\t}\n\n\tdeleteSelectedPathSegments() {\n\t\tconst { selectionStore } = this.engine.stores\n\t\tconst { segmentSelection, tree } = this\n\n\t\tif (segmentSelection.length === 0) return\n\n\t\tconst newSelection: PathSegmentSelector[] = []\n\t\tif (selectionStore.ids.length === 1 && segmentSelection.length === 1) {\n\t\t\tconst segment = segmentSelection[0]\n\t\t\tassert(segment, \"Expected segment after length === 1 check\")\n\t\t\tconst node = tree.getNode(segment.id) as PathNode\n\n\t\t\tif (Path.isFirstSegment(node.pathSegments, node.pathClosed, segment.index)) {\n\t\t\t\tnewSelection.push({ id: node.id, index: 0 })\n\t\t\t} else if (Path.isLastSegment(node.pathSegments, node.pathClosed, segment.index)) {\n\t\t\t\tnewSelection.push({ id: node.id, index: node.pathSegments.length - 2 })\n\t\t\t}\n\t\t}\n\n\t\tconst groupedSegments = groupPathSegmentSelectors(segmentSelection)\n\t\tconst nodes = Object.keys(groupedSegments).map(id => tree.getNode(id)) as PathNode[]\n\t\tfor (const node of nodes) {\n\t\t\tconst indexesToRemove = groupedSegments[node.id]\n\t\t\tassert(indexesToRemove, \"Expected indexes for node.id from groupedSegments\")\n\t\t\tconst pathSegments = node.pathSegments.filter((_, index: number) => !indexesToRemove.includes(index))\n\n\t\t\t// Paths can only exist when made of at least two segments.\n\t\t\tif (pathSegments.length <= 1) {\n\t\t\t\tthis.deleteNode(node)\n\t\t\t\tnewSelection.length = 0\n\t\t\t} else {\n\t\t\t\tnode.set(node.updateForPath({ pathSegments }))\n\t\t\t}\n\t\t}\n\n\t\tthis.setSegmentSelection(newSelection)\n\t\tthis.setClosestCurve(null)\n\t}\n\n\tdeleteCurves() {\n\t\tconst { tree, segmentSelection } = this\n\t\tconst selectedIndexesPerNode = groupPathSegmentSelectors(segmentSelection)\n\t\tconst nodes = tree.getNodes(Object.keys(selectedIndexesPerNode)) as PathNode[]\n\t\tconst selection = [...this.engine.stores.selectionStore.ids]\n\n\t\tfor (const node of nodes) {\n\t\t\tconst selectedCurves = selectedIndexesPerNode[node.id]\n\t\t\tassert(selectedCurves, \"Expected selectedCurves for node.id from selectedIndexesPerNode\")\n\t\t\tconst indexesToDelete = Path.segmentIndexesToDelete(node.pathSegments, node.pathClosed, selectedCurves)\n\n\t\t\tlet linked = node.pathClosed\n\n\t\t\tconst paths: PathSegment[][] = []\n\t\t\tlet bucket: PathSegment[] = []\n\t\t\tpaths.push(bucket)\n\n\t\t\tfor (let i = 0, il = node.pathSegments.length; i < il; i++) {\n\t\t\t\tconst segment = node.pathSegments[i]\n\t\t\t\tassert(segment !== undefined, \"Expected segment at index within loop bounds\")\n\t\t\t\tconst ignore = indexesToDelete[i]\n\t\t\t\tif (ignore) {\n\t\t\t\t\tconst isLast = i === il - 1\n\t\t\t\t\tif (isLast) {\n\t\t\t\t\t\tlinked = false\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbucket.push(segment)\n\t\t\t\tif (!selectedCurves.includes(i)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (bucket.length === 0) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbucket = []\n\t\t\t\tpaths.push(bucket)\n\t\t\t}\n\n\t\t\tif (linked && paths.length > 1) {\n\t\t\t\tconst firstItem = paths[0]\n\t\t\t\tassert(firstItem, \"Expected first item after paths initialization\")\n\t\t\t\tconst lastItem = paths.pop()!\n\t\t\t\tfirstItem.unshift(...lastItem)\n\t\t\t}\n\n\t\t\tconst firstPath = paths[0]\n\t\t\tassert(firstPath, \"Expected first path after paths initialization\")\n\t\t\tif (firstPath.length === 0) {\n\t\t\t\t// TODO: take delete into account for normalizing subtree\n\t\t\t\tthis.engine.deleteNode(node.id)\n\t\t\t\tconst indexToRemove = selection.indexOf(node.id)\n\t\t\t\tif (indexToRemove !== -1) {\n\t\t\t\t\tselection.splice(indexToRemove, 1)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor (let i = 0, il = paths.length; i < il; i++) {\n\t\t\t\t\tconst segmentArray = paths[i]\n\t\t\t\t\tassert(segmentArray !== undefined, \"Expected segmentArray at index within loop bounds\")\n\t\t\t\t\tif (segmentArray.length === 0) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tconst pathSegments = segmentArray\n\t\t\t\t\tconst update = { pathSegments, pathClosed: false }\n\n\t\t\t\t\tif (i === 0) {\n\t\t\t\t\t\tnode.set(node.updateForPath(update))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconst newId = randomID()\n\t\t\t\t\t\t// TODO: take cloning into account for normalizing subtree\n\t\t\t\t\t\tcloneNodeAndUpdatePath(tree, this.engine, node, update, newId)\n\t\t\t\t\t\tselection.push(newId)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.setSegmentSelection([])\n\t\tthis.setClosestCurve(null)\n\t\tthis.engine.stores.selectionStore.set(selection)\n\t}\n\n\tmoveSelectedVectorSegments(delta: Partial<Point>) {\n\t\tconst { engine, pointRounding, selectionType } = this\n\t\tconst tree = engine.tree\n\t\tconst segmentSelection = generateSegmentSelection(tree, this.segmentSelection, selectionType)\n\t\tconst selectedIndexesPerNode = groupPathSegmentSelectors(segmentSelection)\n\t\tconst vectorNodes = Object.keys(selectedIndexesPerNode).map(nodeIDFromString)\n\t\tconst nodes = tree.getNodes(vectorNodes)\n\n\t\tnodes.forEach((pathNode: PathNode) => {\n\t\t\tconst selectedIndexes = selectedIndexesPerNode[pathNode.id]\n\t\t\tconst pathSegments = pathNode.pathSegments.map((segment: PathSegment, index: number) => {\n\t\t\t\tconst partOfSelection = selectedIndexes?.includes(index)\n\t\t\t\tif (partOfSelection) {\n\t\t\t\t\tconst convertedPoint = Point.add(tree.convertPointToCanvas(pathNode, segment), {\n\t\t\t\t\t\tx: 0,\n\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\t...delta,\n\t\t\t\t\t})\n\n\t\t\t\t\t// Only round the axis where changes are made, keep the other axis intact.\n\t\t\t\t\tconst rounded = roundedPoint(convertedPoint, pointRounding)\n\t\t\t\t\tif (delta.x) {\n\t\t\t\t\t\tconvertedPoint.x = rounded.x\n\t\t\t\t\t}\n\t\t\t\t\tif (delta.y) {\n\t\t\t\t\t\tconvertedPoint.y = rounded.y\n\t\t\t\t\t}\n\t\t\t\t\tconst localPoint = tree.convertPointToNode(pathNode, convertedPoint)\n\t\t\t\t\treturn segment.merge(localPoint)\n\t\t\t\t} else {\n\t\t\t\t\treturn segment\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tpathNode.set(pathNode.updateForPath({ pathSegments }))\n\t\t})\n\t}\n\n\toverride selectAll() {\n\t\tconst { selectionStore } = this.engine.stores\n\t\tconst { tree } = this\n\n\t\tconst segmentSelection: PathSegmentSelector[] = []\n\n\t\tfor (let i = 0, il = selectionStore.ids.length; i < il; i++) {\n\t\t\tconst node = tree.getNode(selectionStore.ids[i])\n\t\t\tif (!(node instanceof PathNode)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst id = node.id\n\t\t\tconst segments: PathSegmentSelector[] = Array(node.pathSegments.length)\n\t\t\t\t.fill(null)\n\t\t\t\t.map((_, index) => {\n\t\t\t\t\treturn { id, index }\n\t\t\t\t})\n\t\t\tsegmentSelection.push(...segments)\n\t\t}\n\n\t\tthis.setSegmentHandle(null)\n\t\tthis.setSegmentSelection(segmentSelection)\n\t}\n\n\tgetClosestCurve() {\n\t\tconst { tree } = this.engine\n\n\t\tconst { selectionStore, canvasStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMousePosition } = mouseStore.latest\n\n\t\tif (!canvasMousePosition) return\n\t\tif (\n\t\t\t!canvasMousePosition ||\n\t\t\tthis.pathTool instanceof PathCurveBendTool ||\n\t\t\tthis.pathTool instanceof PathSegmentMoveTool ||\n\t\t\tthis.pathTool instanceof PathSegmentHandleMoveTool\n\t\t) {\n\t\t\treturn\n\t\t}\n\t\tconst vectorNodes = selectionStore.ids.map(id => tree.getNode(id)) as PathNode[]\n\t\tconst distanceThreshold = 12 / canvasStore.zoom\n\t\tlet curve: ClosestCurve | null = null\n\t\tfor (const node of vectorNodes) {\n\t\t\tconst closest = getClosestCurve(tree, node, canvasMousePosition, canvasStore.zoom)\n\t\t\tif (!closest || closest.distance > distanceThreshold) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcurve = closest\n\t\t\tbreak\n\t\t}\n\n\t\tthis.setClosestCurve(curve)\n\t}\n}\n\nexport class PathToolManager extends React.Component<Props> {\n\toverride render() {\n\t\tconst { tree, selection, zoom, myTool } = this.props\n\t\tconst pathTool = myTool.pathTool\n\n\t\tconst pathNodes = selection.map(id => {\n\t\t\treturn tree.getNode(id)\n\t\t}) as PathNode[]\n\n\t\treturn (\n\t\t\t<div style={style(pathTool)}>\n\t\t\t\t<PathShapes tree={tree} selection={selection} zoom={zoom} />\n\t\t\t\t<PathCurves {...this.props} nodes={pathNodes} cmdKey={pathTool.engine.stores.mouseStore.latest.cmdKey} />\n\t\t\t\t{this.activeToolElement()}\n\t\t\t\t<PathSegmentHandles {...this.props} pathTool={pathTool} />\n\t\t\t\t<PathSegmentAnchors {...this.props} pathTool={pathTool} />\n\t\t\t</div>\n\t\t)\n\t}\n\n\tactiveToolElement() {\n\t\tconst tool = this.props.myTool\n\t\tconst pathTool = tool.pathTool\n\t\tswitch (pathTool.constructor) {\n\t\t\tcase PathDefaultTool:\n\t\t\t\treturn <PathDefault pathTool={pathTool as PathDefaultTool} />\n\t\t\tcase PathSegmentAdditionTool:\n\t\t\t\treturn <PathSegmentAddition pathTool={pathTool as PathSegmentAdditionTool} />\n\t\t\tcase PathSegmentSelectTool:\n\t\t\t\treturn <PathSegmentSelect pathTool={pathTool as PathSegmentSelectTool} />\n\t\t\tcase PathSegmentHandleMoveTool:\n\t\t\t\treturn <PathSegmentHandleMove pathTool={pathTool as PathSegmentHandleMoveTool} />\n\t\t\tcase PathCurveBendTool:\n\t\t\t\treturn <PathCurveBend pathTool={pathTool as PathCurveBendTool} />\n\n\t\t\tcase PanTool:\n\t\t\t\treturn <Pan />\n\t\t\tcase ZoomTool:\n\t\t\t\treturn null\n\t\t\tcase ZoomSelectTool:\n\t\t\t\treturn <ZoomSelect myTool={pathTool as ZoomSelectTool} />\n\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n}\n\nfunction shouldIgnoreMouseEvents(tool: VekterPathTool) {\n\treturn tool instanceof PanTool || tool instanceof ZoomTool || tool instanceof ZoomSelectTool\n}\n\nfunction style(tool: VekterPathTool): React.CSSProperties | undefined {\n\tif (shouldIgnoreMouseEvents(tool)) {\n\t\treturn { pointerEvents: \"none\" }\n\t}\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport React from \"react\"\nimport { MouseDrawnRect } from \"./MouseDrawnRect.tsx\"\nimport type { ZoomSelectTool } from \"./ZoomSelectTool.ts\"\nimport type { ToolProps } from \"./props.ts\"\n\nexport class ZoomSelect extends React.Component<ToolProps<ZoomSelectTool>> {\n\toverride render() {\n\t\tconst { canvasStore, mouseStore } = this.props.myTool.engine.stores\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = mouseStore.latest\n\n\t\treturn (\n\t\t\t<MouseDrawnRect\n\t\t\t\tmouseDown={canvasMouseDownPosition}\n\t\t\t\tmouse={canvasMousePosition}\n\t\t\t\tzoom={canvasStore.zoom}\n\t\t\t\tbackgroundColor={colors.selectionBox}\n\t\t\t\tborderColor={colors.selectionBoxOutline}\n\t\t\t/>\n\t\t)\n\t}\n}\n", "import { assert, List } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport type { ClosestCurve } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { isStraightCurve } from \"library/render/traits/Path.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\nimport { convertPathToCanvas } from \"./utils/index.ts\"\n\ninterface Props {\n\tpathTool: PathCurveBendTool\n}\n\nexport class PathCurveBendTool extends withClassDiscriminator(\"PathCurveBendTool\") implements VekterPathTool {\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tnode!: PathNode\n\tnormalizedClosestCurve!: ClosestCurve\n\toriginalBezier!: any\n\tisStraight!: boolean\n\tfromSegmentIndex!: number\n\ttoSegmentIndex!: number\n\n\tstart() {\n\t\tconst { closestCurve, tree } = this.pathEngine\n\t\tif (!closestCurve) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t\treturn\n\t\t}\n\n\t\tthis.engine.stores.mouseCursorStore.current = \"-webkit-grabbing\"\n\t\tthis.engine.beginUndoGroup()\n\n\t\tthis.node = tree.getNode(closestCurve.id) as PathNode\n\n\t\tthis.normalizedClosestCurve = {\n\t\t\t...closestCurve,\n\t\t\tprojectedPoint: tree.convertPointToCanvas(this.node, closestCurve.projectedPoint),\n\t\t\tmidPoint: tree.convertPointToCanvas(this.node, closestCurve.midPoint),\n\t\t}\n\n\t\tconst normalizedPath = convertPathToCanvas(tree, this.node, this.node)\n\t\tconst bezierCurves = Path.toBezierJS(normalizedPath)\n\t\tthis.originalBezier = bezierCurves[closestCurve.segmentIndex]\n\n\t\tthis.fromSegmentIndex = closestCurve.segmentIndex\n\t\tthis.toSegmentIndex = this.normalizedClosestCurve.segmentIndex + 1\n\t\tif (this.normalizedClosestCurve.segmentIndex === this.node.pathSegments.length - 1) {\n\t\t\tthis.toSegmentIndex = 0\n\t\t}\n\n\t\tconst fromSegment = this.node.pathSegments[this.fromSegmentIndex]\n\t\tconst toSegment = this.node.pathSegments[this.toSegmentIndex]\n\t\tassert(fromSegment && toSegment, \"fromSegment and toSegment must be defined\")\n\n\t\tthis.isStraight = isStraightCurve(fromSegment, toSegment)\n\t}\n\n\tstop() {\n\t\tthis.pathEngine.setClosestCurve(null)\n\t\tthis.engine.endUndoGroup()\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\tupdate() {\n\t\tconst { tree } = this.engine\n\t\tconst { previous: previousState, latest } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey } = latest\n\n\t\tconst previousMouseDown = previousState.canvasMouseDownPosition\n\t\tconst previousMouse = previousState.canvasMousePosition\n\t\tconst previousShift = previousState.shiftKey\n\n\t\tif (!canvasMouseDownPosition || !previousMouseDown || !previousMouse || !canvasMousePosition) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t\treturn\n\t\t}\n\n\t\tconst delta = this.delta(canvasMouseDownPosition, canvasMousePosition, shiftKey)\n\t\tconst currentDelta = this.delta(previousMouseDown, previousMouse, previousShift)\n\t\tconst change = currentDelta.x !== delta.x || currentDelta.y !== delta.y\n\t\tif (!change) {\n\t\t\treturn\n\t\t}\n\n\t\tconst node = tree.get<PathNode>(this.node.id)\n\t\tif (!node) return\n\n\t\tconst controlPoints = controlPointsForBend(this.originalBezier, this.normalizedClosestCurve, delta, this.isStraight)\n\n\t\tconst localFrom = tree.convertPointToNode(node, controlPoints.from)\n\t\tconst localTo = tree.convertPointToNode(node, controlPoints.to)\n\n\t\tlet pathSegments = List.update(node.pathSegments, this.fromSegmentIndex, fromSegment => {\n\t\t\tconst newPoint = Point.subtract(localFrom, fromSegment)\n\t\t\treturn updateSegment(fromSegment, newPoint, true)\n\t\t})\n\n\t\tpathSegments = List.update(pathSegments, this.toSegmentIndex, toSegment => {\n\t\t\tconst newPoint = Point.subtract(localTo, toSegment)\n\t\t\treturn updateSegment(toSegment, newPoint, false)\n\t\t})\n\n\t\tnode.set(node.updateForPath({ pathSegments }))\n\t}\n\n\t// TODO: remove repetition\n\tprivate delta(mouseDownPoint: Point, mousePoint: Point, shiftKey: boolean) {\n\t\tconst result = Point.subtract(mousePoint, mouseDownPoint)\n\t\tif (shiftKey) {\n\t\t\tif (Math.abs(result.x) > Math.abs(result.y)) {\n\t\t\t\tresult.y = 0\n\t\t\t} else {\n\t\t\t\tresult.x = 0\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n}\n\nexport class PathCurveBend extends React.Component<Props> {\n\toverride render() {\n\t\treturn null\n\t}\n}\n\nfunction updateSegment(current: PathSegment, newControlPoint: Point, handleOut: boolean) {\n\tconst cp1 = newControlPoint\n\tlet cp2 = handleOut ? PathSegment.handleIn(current) : PathSegment.handleOut(current)\n\n\tif (current.handleMirroring === \"symmetric\") {\n\t\tcp2 = Point.reverse(cp1)\n\t}\n\n\tconst update = {\n\t\thandleOutX: handleOut ? cp1.x : cp2.x,\n\t\thandleOutY: handleOut ? cp1.y : cp2.y,\n\t\thandleInX: handleOut ? cp2.x : cp1.x,\n\t\thandleInY: handleOut ? cp2.y : cp1.y,\n\t\thandleMirroring: current.handleMirroring === \"straight\" ? \"disconnected\" : current.handleMirroring,\n\t}\n\n\treturn current.merge(update)\n}\n\nfunction controlPointsForBend(originalCurve: any, dragPoint: ClosestCurve, delta: Point, isStraight: boolean) {\n\tconst grabAtMidPoint = dragPoint.midPointInRange || isStraight\n\n\tconst t = grabAtMidPoint ? 0.5 : dragPoint.projectedTime\n\n\tconst mt = 1 - t\n\tconst t3 = t * t * t\n\tconst mt3 = mt * mt * mt\n\tconst bottom = t3 + mt3\n\tconst top = bottom - 1\n\tconst ratio = Math.abs(top / bottom)\n\tconst hull = originalCurve.hull(t)\n\tconst A = hull[5]\n\tconst B = originalCurve.get(t)\n\n\tconst oriCP0 = originalCurve.points[0]\n\tconst oriCP3 = originalCurve.points[3]\n\tif (A.x === B.x && A.x === oriCP0.x && A.x === oriCP3.x) {\n\t\toriCP0.x += 0.01\n\t\toriCP3.x += 0.01\n\t}\n\tif (A.y === B.y && A.y === oriCP0.y && A.y === oriCP3.y) {\n\t\toriCP0.y += 0.01\n\t\toriCP3.y += 0.01\n\t}\n\n\tlet oriC = originalCurve.getUtils().lli4(A, B, oriCP0, oriCP3)\n\n\tif (!oriC) {\n\t\t// if the discrimiant is zero, C_ will be false, which leads to NaN, instead we use zero\n\t\toriC = dragPoint.midPoint\n\t}\n\tconst C = oriC\n\n\tconst Bl = hull[7]\n\tconst Br = hull[8]\n\tconst dbl = { x: Bl.x - B.x, y: Bl.y - B.y }\n\tconst dbr = { x: Br.x - B.x, y: Br.y - B.y }\n\tconst points = originalCurve.points\n\n\tconst newB = Point.add(grabAtMidPoint ? dragPoint.midPoint : dragPoint.projectedPoint, delta)\n\tconst newA = {\n\t\tx: newB.x - (C.x - newB.x) / ratio,\n\t\ty: newB.y - (C.y - newB.y) / ratio,\n\t}\n\n\tconst p1 = { x: newB.x + dbl.x, y: newB.y + dbl.y }\n\tconst sc1 = {\n\t\tx: newA.x - (newA.x - p1.x) / (1 - t),\n\t\ty: newA.y - (newA.y - p1.y) / (1 - t),\n\t}\n\n\tconst p2 = { x: newB.x + dbr.x, y: newB.y + dbr.y }\n\tconst sc2 = {\n\t\tx: newA.x + (p2.x - newA.x) / t,\n\t\ty: newA.y + (p2.y - newA.y) / t,\n\t}\n\tconst nc1 = {\n\t\tx: points[0].x + (sc1.x - points[0].x) / t,\n\t\ty: points[0].y + (sc1.y - points[0].y) / t,\n\t}\n\n\tconst nc2 = {\n\t\tx: points[3].x - (points[3].x - sc2.x) / (1 - t),\n\t\ty: points[3].y - (points[3].y - sc2.y) / (1 - t),\n\t}\n\n\treturn {\n\t\tfrom: nc1,\n\t\tto: nc2,\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { PathNode, VectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { withPath } from \"document/models/CanvasTree/traits/WithPath.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport { PathSelectionType } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport React from \"react\"\nimport { pathCurveSplitCursor } from \"utils/cursor.ts\"\nimport { getPathOperator } from \"utils/pathOperator.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { mouseActionType } from \"../utils/mouseActionType.tsx\"\nimport { PathCurveBendTool } from \"./PathCurveBend.tsx\"\nimport { PathSegmentMoveTool } from \"./PathSegmentMove.ts\"\nimport { PathSegmentSelectTool } from \"./PathSegmentSelect.tsx\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\nimport { ProjectedPoint } from \"./controls/ProjectedPoint.tsx\"\nimport { partOfSelection } from \"./utils/index.ts\"\n\ninterface Props {\n\tpathTool: PathDefaultTool\n}\n\nexport class PathDefaultTool extends withClassDiscriminator(\"PathDefaultTool\") implements VekterPathTool {\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\tenum = Tools.Unknown\n\n\tmouseDidMove = false\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\tstart() {\n\t\tthis.updateCursor()\n\t}\n\n\tstop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\tupdate() {\n\t\tconst { previous, latest } = this.engine.stores.mouseStore\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tthis.updateCursor()\n\t\tswitch (mouseAction) {\n\t\t\tcase \"mouseDown\":\n\t\t\t\treturn this.mouseDown()\n\t\t\tcase \"mouseUp\":\n\t\t\t\treturn this.mouseUp()\n\t\t\tcase \"mouseMove\":\n\t\t\t\treturn this.mouseMove()\n\t\t}\n\t}\n\n\tmouseMove() {\n\t\tthis.mouseDidMove = true\n\n\t\tif (this.engine.stores.mouseStore.latest.canvasMouseDownPosition) {\n\t\t\tthis.pathEngine.setSegmentHandle(null)\n\t\t\tthis.pathEngine.setPathTool(new PathSegmentSelectTool(this.engine, this.pathEngine))\n\t\t} else {\n\t\t\tthis.pathEngine.setHoveredSegment(null)\n\t\t}\n\t}\n\n\tmouseUp() {\n\t\tif (this.mouseDidMove) return\n\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMousePosition } = mouseStore.latest\n\n\t\tfor (const id of selectionStore.ids) {\n\t\t\tconst node = tree.getNode(id) as VectorNode\n\t\t\tif (!node || !withPath(node) || !canvasMousePosition) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst localPoint = tree.convertPointToNode(node, canvasMousePosition)\n\t\t\t// Only exit when clicked outside path fill area\n\t\t\tif (getPathOperator().containsPoint(node, localPoint)) {\n\t\t\t\tthis.pathEngine.setSegmentSelection([])\n\t\t\t\tthis.pathEngine.setSegmentHandle(null)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tthis.engine.exitTool()\n\t}\n\n\tmouseDown() {\n\t\tconst { tree } = this.engine\n\t\tconst { canvasMousePosition, altKey, cmdKey, shiftKey } = this.engine.stores.mouseStore.latest\n\t\tconst { closestCurve, segmentSelection } = this.pathEngine\n\t\tthis.mouseDidMove = false\n\t\tif (!closestCurve || !canvasMousePosition) {\n\t\t\treturn\n\t\t}\n\n\t\tif (altKey) {\n\t\t\t// set bending tool\n\t\t\tthis.pathEngine.setClosestCurve(closestCurve)\n\t\t\tthis.pathEngine.setPathTool(new PathCurveBendTool(this.engine, this.pathEngine))\n\t\t} else if (cmdKey || closestCurve.midPointInRange) {\n\t\t\t// split curve, add point\n\t\t\tconst node = tree.getNode(closestCurve.id) as PathNode\n\t\t\tconst time = cmdKey ? closestCurve.projectedTime : 0.5\n\t\t\tconst pathSegments = Path.split(node.pathSegments, node.pathClosed, closestCurve.segmentIndex, time)\n\n\t\t\tnode.set(node.updateForPath({ pathSegments }))\n\n\t\t\tthis.pathEngine.setClosestCurve(null)\n\t\t\tthis.pathEngine.setSegmentSelection([{ id: node.id, index: closestCurve.segmentIndex + 1 }])\n\t\t\tthis.pathEngine.setSegmentHandle(null)\n\t\t\tthis.pathEngine.setPathTool(new PathSegmentMoveTool(this.engine, this.pathEngine))\n\t\t} else {\n\t\t\t// select curve\n\t\t\tconst selector = { id: closestCurve.id, index: closestCurve.segmentIndex }\n\t\t\tlet switchToMoveTool = true\n\n\t\t\tif (shiftKey) {\n\t\t\t\tthis.pathEngine.toggleSegmentSelection([selector], PathSelectionType.Curves)\n\t\t\t\tconst notInSelection = !partOfSelection(segmentSelection, closestCurve.id, closestCurve.segmentIndex)\n\t\t\t\tswitchToMoveTool = notInSelection\n\t\t\t} else {\n\t\t\t\tthis.pathEngine.setSegmentSelection([selector], PathSelectionType.Curves)\n\t\t\t}\n\n\t\t\tthis.pathEngine.setSegmentHandle(null)\n\t\t\tthis.pathEngine.setClosestCurve(null)\n\t\t\tif (!switchToMoveTool) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.pathEngine.setPathTool(new PathSegmentMoveTool(this.engine, this.pathEngine))\n\t\t}\n\t}\n\n\tupdateCursor() {\n\t\tconst { mouseCursorStore, mouseStore } = this.engine.stores\n\t\tconst { altKey, cmdKey } = mouseStore.latest\n\t\tconst { closestCurve } = this.pathEngine\n\t\tif (closestCurve && altKey) {\n\t\t\tmouseCursorStore.current = \"-webkit-grab\"\n\t\t} else if (closestCurve && (cmdKey || closestCurve.midPointInRange)) {\n\t\t\tmouseCursorStore.current = pathCurveSplitCursor\n\t\t} else {\n\t\t\tmouseCursorStore.clear()\n\t\t}\n\t}\n}\n\nexport class PathDefault extends React.Component<Props> {\n\toverride render() {\n\t\tconst { canvasMousePosition } = this.props.pathTool.engine.stores.mouseStore.latest\n\t\tif (!canvasMousePosition) return null\n\t\treturn <ProjectedPoint {...this.props} />\n\t}\n}\n", "import { groupPathSegmentSelectors, roundedPoint } from \"document/components/tools/pathEdit/utils/index.ts\"\nimport type { CanvasTree, LoadedScopeNode, PathNode, RectangleShapeNode } from \"document/models/CanvasTree/index.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { withPath } from \"document/models/CanvasTree/traits/WithPath.ts\"\nimport { withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport type { PathSegmentSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PointRounding } from \"document/stores/PathSelectionStore.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type { Size } from \"library/render/types/Size.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { isFrameNode, isShapeContainerNode } from \"./CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { BasicShape } from \"./CanvasTree/traits/utils/basicShape/index.ts\"\nimport { convertFrameToCanvas } from \"./CanvasTree/utils/geometry.ts\"\nimport { getNodesInRect } from \"./CanvasTree/utils/hitTesting.ts\"\nimport * as Snapping from \"./Snapping.ts\"\n\n// FIXME: Remove unused parameters and sort consumer arguments\nexport function pathSegmentSnap(\n\tcache: Snapping.OrthogonalLines,\n\ttree: CanvasTree,\n\tzoom: number,\n\tselectedNodes: PathNode[],\n\tsegmentSelectors: PathSegmentSelector[],\n\tframe: Point & Partial<Size>,\n\tconstraint: Line | null,\n): [Point, Snapping.OrthogonalLines] {\n\tlet result: Snapping.SnapInfo\n\n\tif (constraint) {\n\t\tresult = Snapping.snapWithConstraint(cache, zoom, frame, constraint, [])\n\t\tconst validX = isNumber(result.point.x) && result.point.x !== constraint.a.x\n\t\tconst validY = isNumber(result.point.y) && result.point.y !== constraint.a.y\n\n\t\tif (!(validX || validY)) {\n\t\t\tresult = { snapLines: { x: new Set<number>(), y: new Set<number>() }, point: {} }\n\t\t}\n\t} else {\n\t\tresult = Snapping.snap(cache, zoom, frame, undefined, undefined)\n\t}\n\n\tif (isNumber(result.point.x)) {\n\t\tframe.x = result.point.x\n\t}\n\tif (isNumber(result.point.y)) {\n\t\tframe.y = result.point.y\n\t}\n\treturn [frame, result.snapLines]\n}\n\nexport function pathSegmentSnappingData(\n\ttree: CanvasTree,\n\tactiveScope: LoadedScopeNode,\n\tpathNodes: PathNode[],\n\tsegmentSelectors: PathSegmentSelector[],\n\tvisibleCanvasFrame: Rect,\n): Snapping.OrthogonalLines {\n\tconst xDirection = new Set<number>()\n\tconst yDirection = new Set<number>()\n\n\tconst topLevelFrameNodesAndParents = activeScope.getGroundNodes(isFrameNode).map(node => node.id)\n\tpathNodes.forEach(pathNode => {\n\t\tconst parent = tree.getParent(pathNode.id)\n\t\tif (!parent) return\n\t\tif (isShapeContainerNode(parent) && parent.sizeToFit) return\n\t\tif (topLevelFrameNodesAndParents.includes(parent.id)) return\n\t\ttopLevelFrameNodesAndParents.push(parent.id)\n\t})\n\n\tconst topLevelFrameBoundingBoxes = tree\n\t\t.getNodes(topLevelFrameNodesAndParents)\n\t\t.map(node => convertFrameToCanvas(tree, node))\n\ttopLevelFrameBoundingBoxes.forEach(box => {\n\t\t// Only snap to visible frames\n\t\tif (!Rect.intersects(visibleCanvasFrame, box)) {\n\t\t\treturn\n\t\t}\n\t\tconst pointRounding = PointRounding.Half\n\t\tconst { x: minX, y: minY } = roundedPoint({ x: box.x, y: box.y }, pointRounding)\n\t\tconst { x: midX, y: midY } = roundedPoint({ x: box.x + box.width / 2, y: box.y + box.height / 2 }, pointRounding)\n\t\tconst { x: maxX, y: maxY } = roundedPoint({ x: box.x + box.width, y: box.y + box.height }, pointRounding)\n\n\t\txDirection.add(minX).add(midX).add(maxX)\n\t\tyDirection.add(minY).add(midY).add(maxY)\n\t})\n\n\tconst selectedIndexesPerNode = groupPathSegmentSelectors(segmentSelectors)\n\tconst selectedPaths = Object.keys(selectedIndexesPerNode)\n\n\tconst nonSelectedVisibleShapes = getNodesInRect(tree, activeScope, visibleCanvasFrame, true).filter(node => {\n\t\tif (!withShape(node) || withChildren(node)) {\n\t\t\treturn false\n\t\t}\n\t\treturn !selectedPaths.includes(node.id)\n\t})\n\n\tnonSelectedVisibleShapes.forEach(node => {\n\t\tlet segments: readonly PathSegment[]\n\t\tif (withPath(node)) {\n\t\t\tsegments = node.pathSegments\n\t\t} else {\n\t\t\tsegments = BasicShape.createPath(node as RectangleShapeNode)[0].pathSegments\n\t\t}\n\n\t\tsegments.forEach((segment: PathSegment) => {\n\t\t\tconst convertedPoint = tree.convertPointToCanvas(node, PathSegment.point(segment))\n\t\t\tconst roundedConvertedPoint = roundedPoint(convertedPoint, PointRounding.Half)\n\n\t\t\txDirection.add(roundedConvertedPoint.x)\n\t\t\tyDirection.add(roundedConvertedPoint.y)\n\t\t})\n\t})\n\n\tpathNodes.forEach(node => {\n\t\tconst selectedIndexes: number[] = selectedIndexesPerNode[node.id] || []\n\n\t\tconst shapeXDirection = new Set<number>()\n\t\tconst shapeYDirection = new Set<number>()\n\n\t\tnode.pathSegments.forEach((point: PathSegment, index: number) => {\n\t\t\tif (!selectedIndexes.includes(index)) {\n\t\t\t\tconst convertedPoint = tree.convertPointToCanvas(node, PathSegment.point(point))\n\t\t\t\tconst roundedConvertedPoint = roundedPoint(convertedPoint, PointRounding.Half)\n\n\t\t\t\tshapeXDirection.add(roundedConvertedPoint.x)\n\t\t\t\tshapeYDirection.add(roundedConvertedPoint.y)\n\t\t\t}\n\t\t})\n\n\t\tconst pointRounding = PointRounding.Half\n\t\tconst { x: minX, y: minY } = roundedPoint(\n\t\t\t{\n\t\t\t\tx: Math.min(...shapeXDirection),\n\t\t\t\ty: Math.min(...shapeYDirection),\n\t\t\t},\n\t\t\tpointRounding,\n\t\t)\n\t\tconst { x: maxX, y: maxY } = roundedPoint(\n\t\t\t{\n\t\t\t\tx: Math.max(...shapeXDirection),\n\t\t\t\ty: Math.max(...shapeYDirection),\n\t\t\t},\n\t\t\tpointRounding,\n\t\t)\n\t\tconst { x: midX, y: midY } = roundedPoint({ x: (minX + maxX) / 2, y: (minY + maxY) / 2 }, pointRounding)\n\n\t\tshapeXDirection.add(midX)\n\t\tshapeYDirection.add(midY)\n\n\t\tif (minX === maxX && minY !== maxY) {\n\t\t\tconst delta = maxY - minY\n\t\t\tif (delta > 3) {\n\t\t\t\txDirection.add(minX - delta).add(minX + delta)\n\t\t\t}\n\t\t} else {\n\t\t\tconst width = maxX - minX\n\t\t\txDirection.add(minX - width).add(maxX + width)\n\t\t}\n\t\tif (minY === maxY && minX !== maxX) {\n\t\t\tconst delta = maxX - minX\n\t\t\tif (delta > 3) {\n\t\t\t\tyDirection.add(minY - delta).add(minY + delta)\n\t\t\t}\n\t\t} else {\n\t\t\tconst height = maxY - minY\n\t\t\tyDirection.add(minY - height).add(maxY + height)\n\t\t}\n\n\t\tfor (const value of shapeXDirection.values()) {\n\t\t\txDirection.add(value)\n\t\t}\n\n\t\tfor (const value of shapeYDirection.values()) {\n\t\t\tyDirection.add(value)\n\t\t}\n\t})\n\n\treturn {\n\t\tx: xDirection,\n\t\ty: yDirection,\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasTree, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { pathSegmentSnap, pathSegmentSnappingData } from \"document/models/PathSegmentSnapping.ts\"\nimport type { OrthogonalLines } from \"document/models/Snapping.ts\"\nimport type { PathSegmentSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport type { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\nimport { generateSegmentSelection, groupPathSegmentSelectors, roundedPoint } from \"./utils/index.ts\"\n\nexport class PathSegmentMoveTool extends withClassDiscriminator(\"PathSegmentMoveTool\") implements VekterPathTool {\n\tenum = Tools.Unknown\n\treadonly wantsAutoscrolling = true\n\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tsegmentSelection!: PathSegmentSelector[]\n\toriginalSegmentAnchorsInCanvas!: { [s: string]: Point }\n\toriginalFrame!: Rect\n\n\t// FIXME: !s are unsafe; they are assigned in `.update()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tsnappingCache!: OrthogonalLines\n\tlastSnappingFrame!: Rect\n\n\tstart() {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionType, segmentSelection } = this.pathEngine\n\t\tthis.segmentSelection = generateSegmentSelection(tree, segmentSelection, selectionType)\n\n\t\tthis.originalSegmentAnchorsInCanvas = {}\n\n\t\tconst convertedPoints = this.segmentSelection.map(segmentSelector => {\n\t\t\tconst node = tree.get(segmentSelector.id) as PathNode\n\t\t\tconst vectorPoint = node.pathSegments[segmentSelector.index]\n\t\t\tconst key = this.originalPointKey(segmentSelector)\n\t\t\tconst canvasAnchor = tree.convertPointToCanvas(node, vectorPoint)\n\t\t\tthis.originalSegmentAnchorsInCanvas[key] = canvasAnchor\n\t\t\treturn canvasAnchor\n\t\t})\n\n\t\tthis.originalFrame = Rect.boundingRectFromPoints(convertedPoints)\n\n\t\tthis.engine.beginUndoGroup()\n\t}\n\n\tstop() {\n\t\tthis.engine.stores.snapLinesStore.clear()\n\t\tthis.engine.endUndoGroup()\n\t}\n\n\tupdate() {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, snapLinesStore, canvasStore, mouseStore } = this.engine.stores\n\t\tconst { latest, previous: previousState } = mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey } = latest\n\t\tconst { pointRounding } = this.pathEngine\n\n\t\t// TODO: remove repetition, code is same as move tool\n\t\tconst currentMouseDown = previousState.canvasMouseDownPosition\n\t\tconst currentMouse = previousState.canvasMousePosition\n\t\tconst currentShift = previousState.shiftKey\n\n\t\tif (!canvasMouseDownPosition) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t\treturn\n\t\t}\n\n\t\tif (!currentMouse) return\n\t\tif (!currentMouseDown) return\n\n\t\tlet delta = this.delta(canvasMouseDownPosition, canvasMousePosition, shiftKey)\n\t\tconst currentDelta = this.delta(currentMouseDown, currentMouse, currentShift)\n\t\tconst change = currentDelta.x !== delta.x || currentDelta.y !== delta.y\n\t\tif (!change) {\n\t\t\treturn\n\t\t}\n\n\t\tconst frame = Rect.offset(this.originalFrame, delta)\n\t\tconst roundedRect = roundedPoint(frame, pointRounding)\n\t\tframe.x = roundedRect.x\n\t\tframe.y = roundedRect.y\n\t\tconst selectedIndexesPerNode = groupPathSegmentSelectors(this.segmentSelection)\n\t\tconst pathNodes = tree.getNodes(selectionStore.ids) as PathNode[]\n\n\t\tthis.updateSnappingCache(tree, pathNodes, this.segmentSelection)\n\t\tconst [, snapLines] = pathSegmentSnap(\n\t\t\tthis.snappingCache,\n\t\t\ttree,\n\t\t\tcanvasStore.zoom,\n\t\t\tpathNodes,\n\t\t\tthis.segmentSelection,\n\t\t\tframe,\n\t\t\tnull,\n\t\t)\n\t\tdelta = Point.subtract(frame, this.originalFrame)\n\n\t\tsnapLinesStore.x = snapLines.x\n\t\tsnapLinesStore.y = snapLines.y\n\n\t\tpathNodes.forEach(pathNode => {\n\t\t\tconst selectedIndexes = selectedIndexesPerNode[pathNode.id] || []\n\n\t\t\tconst pathSegments = pathNode.pathSegments.map((segment: PathSegment, index: number) => {\n\t\t\t\tconst partOfSelection = selectedIndexes.includes(index)\n\t\t\t\tif (!partOfSelection) return segment\n\n\t\t\t\tconst key = this.originalPointKey({ id: pathNode.id, index: index })\n\n\t\t\t\tconst originalPointInCanvas = this.originalSegmentAnchorsInCanvas[key]\n\t\t\t\tconst newPoinInCanvas = Point.add(originalPointInCanvas, delta)\n\t\t\t\tconst convertedPoint = roundedPoint(newPoinInCanvas, pointRounding)\n\t\t\t\tconst newPoint = tree.convertPointToNode(pathNode, convertedPoint)\n\t\t\t\treturn segment.merge(newPoint)\n\t\t\t})\n\n\t\t\tpathNode.set(pathNode.updateForPath({ pathSegments }))\n\t\t})\n\t}\n\n\t// TODO: remove repetition\n\tprivate delta(mouseDownPoint: Point, mousePoint: Point, shiftKey: boolean) {\n\t\tconst result = Point.subtract(mousePoint, mouseDownPoint)\n\t\tif (shiftKey) {\n\t\t\tif (Math.abs(result.x) > Math.abs(result.y)) {\n\t\t\t\tresult.y = 0\n\t\t\t} else {\n\t\t\t\tresult.x = 0\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\tprivate originalPointKey(selector: PathSegmentSelector) {\n\t\treturn `${selector.id} ${selector.index}`\n\t}\n\n\tprivate updateSnappingCache(tree: CanvasTree, pathNodes: PathNode[], segmentSelection: PathSegmentSelector[]) {\n\t\tconst visibleFrame = this.engine.stores.canvasStore.getCanvasVisibleRect()\n\t\tconst frameDidChange = !isEqual(this.lastSnappingFrame, visibleFrame)\n\t\tconst noSnappingCache = !this.snappingCache\n\n\t\tif (frameDidChange || noSnappingCache) {\n\t\t\tthis.snappingCache = pathSegmentSnappingData(\n\t\t\t\ttree,\n\t\t\t\tthis.engine.stores.scopeStore.active,\n\t\t\t\tpathNodes,\n\t\t\t\tsegmentSelection,\n\t\t\t\tvisibleFrame,\n\t\t\t)\n\t\t\tthis.lastSnappingFrame = visibleFrame\n\t\t}\n\t}\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { intersection, union, without } from \"document/components/utils/list.ts\"\nimport { PathNode } from \"document/models/CanvasTree/index.ts\"\nimport type { PathSegmentSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport React from \"react\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { MouseDrawnRect } from \"../MouseDrawnRect.tsx\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\n\ninterface Props {\n\tpathTool: PathSegmentSelectTool\n}\n\nexport class PathSegmentSelectTool extends withClassDiscriminator(\"PathSegmentSelectTool\") implements VekterPathTool {\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\tselectionAtStart: PathSegmentSelector[] = []\n\n\tstart() {\n\t\tif (this.pathEngine.selectionType !== PathSelectionType.Curves) {\n\t\t\tthis.selectionAtStart = [...this.pathEngine.segmentSelection]\n\t\t}\n\t}\n\tstop() {}\n\n\tupdate() {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, mouseStore } = this.engine.stores\n\t\tconst { previous: previousState, latest } = mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey } = latest\n\t\tconst currentMouseDown = previousState.canvasMouseDownPosition\n\t\tconst currentMouse = previousState.canvasMousePosition\n\t\tconst mouseMoveAction = mouseDidMove(currentMouse, canvasMousePosition)\n\t\tconst shiftDidChange = previousState.shiftKey !== shiftKey\n\t\tconst mouseUpAction = !canvasMouseDownPosition && currentMouseDown\n\n\t\tif (mouseUpAction) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t\treturn\n\t\t}\n\n\t\tif ((mouseMoveAction || shiftDidChange) && canvasMouseDownPosition) {\n\t\t\tlet newSelection: PathSegmentSelector[] = []\n\n\t\t\tconst frame = Rect.fromTwoPoints(canvasMouseDownPosition, canvasMousePosition)\n\n\t\t\tconst svgNodes = selectionStore.ids.map(id => tree.getNode(id)).filter(node => node instanceof PathNode)\n\t\t\tsvgNodes.forEach(svgNode => {\n\t\t\t\tsvgNode.pathSegments.forEach((vectorPoint: PathSegment, index: number) => {\n\t\t\t\t\tconst p = tree.convertPointToCanvas(svgNode, PathSegment.point(vectorPoint))\n\t\t\t\t\tconst pointInBounds = Rect.containsPoint(frame, p)\n\n\t\t\t\t\tif (pointInBounds) {\n\t\t\t\t\t\tnewSelection.push({ id: svgNode.id, index: index })\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tif (shiftKey) {\n\t\t\t\tconst inBoth = intersection(newSelection, this.selectionAtStart, equals)\n\t\t\t\tnewSelection = union(newSelection, this.selectionAtStart, equals)\n\t\t\t\tnewSelection = without(newSelection, inBoth, equals)\n\t\t\t}\n\n\t\t\tthis.pathEngine.setSegmentSelection(newSelection)\n\t\t}\n\t}\n}\n\nexport class PathSegmentSelect extends React.Component<Props> {\n\toverride render() {\n\t\tconst { canvasStore, mouseStore } = this.props.pathTool.engine.stores\n\t\tconst { canvasMouseDownPosition, canvasMousePosition } = mouseStore.latest\n\t\treturn (\n\t\t\t<MouseDrawnRect\n\t\t\t\tmouseDown={canvasMouseDownPosition}\n\t\t\t\tmouse={canvasMousePosition}\n\t\t\t\tzoom={canvasStore.zoom}\n\t\t\t\tbackgroundColor={colors.selectionBox}\n\t\t\t\tborderColor={colors.selectionBoxOutline}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction equals(a: PathSegmentSelector, b: PathSegmentSelector) {\n\treturn a.id === b.id && a.index === b.index\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { Overlay } from \"document/components/canvas-hud/Overlay.tsx\"\nimport type { PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { Rect } from \"library/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\n\ninterface Props {\n\tpathTool: VekterPathTool\n}\n\nexport class ProjectedPoint extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst {\n\t\t\ttree,\n\t\t\tstores: { mouseStore, canvasStore },\n\t\t} = this.props.pathTool.engine\n\t\tconst { cmdKey, altKey } = mouseStore.latest\n\t\tconst { closestCurve, snapConstraint } = this.props.pathTool.pathEngine\n\t\tif (!closestCurve || altKey || snapConstraint) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst selectedNode = tree.getNode<PathNode>(closestCurve.id)\n\t\tif (!selectedNode) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst curvePoint = cmdKey ? closestCurve.projectedPoint : closestCurve.midPoint\n\t\tconst midPointWidth = cmdKey || closestCurve.midPointInRange ? 8 : 6\n\t\tconst point = Point.multiply(tree.convertPointToCanvas(selectedNode, curvePoint, true), canvasStore.zoom)\n\n\t\treturn (\n\t\t\t<Overlay\n\t\t\t\tpoints={Rect.cornerPoints({\n\t\t\t\t\tx: point.x - midPointWidth / 2,\n\t\t\t\t\ty: point.y - midPointWidth / 2,\n\t\t\t\t\twidth: midPointWidth,\n\t\t\t\t\theight: midPointWidth,\n\t\t\t\t})}\n\t\t\t\troundToOutside={false}\n\t\t\t\tbackgroundColor={colors.tint}\n\t\t\t\tborderColor=\"white\"\n\t\t\t\tborderWidth={1}\n\t\t\t\toval\n\t\t\t/>\n\t\t)\n\t}\n}\n", "import { Point } from \"library/index.ts\"\nimport React from \"react\"\nimport type { PathSegmentAdditionTool } from \"./PathSegmentAdditionTool.ts\"\nimport { PathCurvePreview } from \"./controls/PathCurvePreview.tsx\"\nimport { pathSegmentDot } from \"./controls/PathSegmentControl.styles.ts\"\nimport { ProjectedPoint } from \"./controls/ProjectedPoint.tsx\"\nimport { withPathSnapping } from \"./utils/withPathSnapping.tsx\"\n\ninterface Props {\n\tpathTool: PathSegmentAdditionTool\n}\n\nclass PathSegmentAddition extends React.Component<Props> {\n\toverride render() {\n\t\tconst { snappedMouse } = this.props.pathTool.pathEngine.snap\n\t\tconst { zoom } = this.props.pathTool.engine.stores.canvasStore\n\n\t\treturn (\n\t\t\t<div>\n\t\t\t\t<PathCurvePreview {...this.props} />\n\t\t\t\t<ProjectedPoint {...this.props} />\n\t\t\t\t<ProjectedMousePoint snappedMouse={snappedMouse} zoom={zoom} />\n\t\t\t</div>\n\t\t)\n\t}\n}\nconst pathSegmentAdditionWithPathSnapping = withPathSnapping(PathSegmentAddition)\nexport { pathSegmentAdditionWithPathSnapping as PathSegmentAddition }\n\nconst ProjectedMousePoint = ({ snappedMouse, zoom }: { snappedMouse: Point | null; zoom: number }) => {\n\tif (!snappedMouse) return null\n\n\tconst zoomed = Point.multiply(snappedMouse, zoom)\n\n\treturn (\n\t\t<div\n\t\t\tstyle={{\n\t\t\t\ttransform: `translate(${zoomed.x}px, ${zoomed.y}px)`,\n\t\t\t}}\n\t\t>\n\t\t\t<div className={pathSegmentDot} />\n\t\t</div>\n\t)\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport type { CanvasTree, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport type { PathSegmentSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { isStraightCurve } from \"library/render/traits/Path.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport { convertSegmentToCanvas, reverseSegment } from \"../utils/index.ts\"\nimport { PathCurve } from \"./PathCurve.tsx\"\ninterface Props {\n\tpathTool: VekterPathTool\n}\n\nexport class PathCurvePreview extends React.Component<Props> {\n\toverride render() {\n\t\tconst { tree, segmentSelection, segmentHovered, snap } = this.props.pathTool.pathEngine\n\t\tconst { canvasStore, mouseStore } = this.props.pathTool.engine.stores\n\t\tconst { zoom } = canvasStore\n\n\t\tif (!mouseStore.latest.isMouseOnCanvas) return null\n\n\t\tconst snapConstraint =\n\t\t\tthis.props.pathTool.pathEngine.snapConstraint || this.props.pathTool.pathEngine.snap.temporaryConstraint\n\n\t\tconst segmentSelector = segmentSelection[0]\n\t\tif (!segmentSelector || snap.snappedMouse === null) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst pathNode = tree.getNode(segmentSelector.id) as PathNode\n\t\tif (!pathNode) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst segment = pathNode.pathSegments[segmentSelector.index]\n\t\tif (!segment) {\n\t\t\treturn null\n\t\t}\n\n\t\tlet fromSegment = convertSegmentToCanvas(tree, pathNode, segment, zoom)\n\t\tif (!Path.isLastSegment(pathNode.pathSegments, pathNode.pathClosed, segmentSelector.index)) {\n\t\t\tfromSegment = reverseSegment(fromSegment)\n\t\t}\n\n\t\tlet endSegment: PathSegment | undefined\n\n\t\tif (!snapConstraint && segmentHovered) {\n\t\t\tconst currentSegment = hoveredEndSegment(segmentHovered, segmentSelector, tree, zoom)\n\t\t\tif (currentSegment === null) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tendSegment = currentSegment\n\t\t}\n\n\t\tif (endSegment === undefined) {\n\t\t\tconst localMouse = Point.multiply(snap.snappedMouse, zoom)\n\t\t\tendSegment = new PathSegment(localMouse)\n\t\t}\n\n\t\tconst straight = isStraightCurve(fromSegment, endSegment)\n\t\tconst isConstrained = snapConstraint && !segmentHovered\n\t\tconst preview = (\n\t\t\t<PathCurve\n\t\t\t\tkey=\"curve-preview\"\n\t\t\t\tfrom={fromSegment}\n\t\t\t\tto={endSegment}\n\t\t\t\tstroke={isConstrained ? colors.snapLine : undefined}\n\t\t\t/>\n\t\t)\n\n\t\tif (isConstrained && !straight) {\n\t\t\treturn (\n\t\t\t\t<div>\n\t\t\t\t\t<PathCurve\n\t\t\t\t\t\tkey=\"curve-preview-straight\"\n\t\t\t\t\t\tfrom={new PathSegment(PathSegment.point(fromSegment))}\n\t\t\t\t\t\tto={endSegment}\n\t\t\t\t\t\tstroke={colors.snapLine}\n\t\t\t\t\t\tstrokeDasharray=\"1 3\"\n\t\t\t\t\t/>\n\t\t\t\t\t{preview}\n\t\t\t\t</div>\n\t\t\t)\n\t\t}\n\n\t\treturn preview\n\t}\n}\n\nfunction hoveredEndSegment(\n\tsegmentHovered: PathSegmentSelector,\n\tselected: PathSegmentSelector,\n\ttree: CanvasTree,\n\tzoom: number,\n) {\n\tconst hoveredNode = tree.getNode(segmentHovered.id) as PathNode\n\n\tif (!hoveredNode) return null\n\n\tconst segment = hoveredNode.pathSegments[segmentHovered.index]\n\tif (!segment) return null\n\n\tconst isOpenEnd = Path.isEndSegment(hoveredNode.pathSegments, hoveredNode.pathClosed, segmentHovered.index)\n\tif (!isOpenEnd) return null\n\n\tif (hoveredNode.id === selected.id && segmentHovered.index === selected.index) {\n\t\treturn null\n\t}\n\n\tlet endSegment = convertSegmentToCanvas(tree, hoveredNode, segment, zoom)\n\tif (Path.isLastSegment(hoveredNode.pathSegments, hoveredNode.pathClosed, segmentHovered.index)) {\n\t\tendSegment = reverseSegment(endSegment)\n\t}\n\treturn endSegment\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { Path } from \"document/models/Path.ts\"\nimport { toSVGPath } from \"library/render/traits/Path.ts\"\nimport type { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport React from \"react\"\n\ninterface Props {\n\tfrom: PathSegment\n\tto: PathSegment\n\tstroke?: string\n\tstrokeWidth?: number\n\tstrokeDasharray?: string\n}\n\nexport class PathCurve extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { from, to, stroke, strokeWidth = 1, strokeDasharray } = this.props\n\t\tif (!from || !to) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst pathSegments = [from, to]\n\t\tconst withPath = { pathSegments, pathClosed: false }\n\t\tconst svgPath = toSVGPath(withPath)\n\t\tconst boundingBox = Path.boundingBox(withPath)\n\n\t\tconst style: React.CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\ttransform: `translate(${boundingBox.x}px, ${boundingBox.y}px)`,\n\t\t}\n\n\t\tconst svgStyle: React.CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\twidth: boundingBox.width,\n\t\t\theight: boundingBox.height,\n\t\t\toverflow: \"visible\",\n\t\t\tfill: \"transparent\",\n\t\t\tstrokeWidth,\n\t\t\tstroke: stroke ? stroke : colors.tint,\n\t\t}\n\n\t\treturn (\n\t\t\t<div style={style}>\n\t\t\t\t<svg\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\theight=\"100%\"\n\t\t\t\t\tstyle={svgStyle}\n\t\t\t\t\tviewBox={`${boundingBox.x} ${boundingBox.y} ${boundingBox.width} ${boundingBox.height}`}\n\t\t\t\t\tstrokeDasharray={strokeDasharray}\n\t\t\t\t>\n\t\t\t\t\t<path d={svgPath} />\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t)\n\t}\n}\n", "import \"PathSegmentControl.styles_r4rihi.wyw.css\"; import { cx } from \"@linaria/core\";\nexport const pathSegmentDot = \"pathSegmentDot_pv9rc06\";\nexport const control = cx(pathSegmentDot, \"control_c1arl1nv\");\nexport const controlHighlighted = \"controlHighlighted_c10dexf1\";\nexport const controlConstrained = \"controlConstrained_c1r3347b\";", "import type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type {\n\tClosestCurve,\n\tPathSegmentSelector,\n\tPathSelectionType,\n\tPointRounding,\n\tSegmentHandleSelector,\n} from \"document/stores/PathSelectionStore.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport { IntersectionTangent } from \"../controls/IntersectionTangent.tsx\"\nimport type { PathTool } from \"../types.ts\"\n\ninterface Props {\n\tchildren?: React.ReactNode\n\n\ttree: CanvasTree\n\tselection: NodeID[]\n\tmouse: Point | null\n\tmouseDown: Point | null\n\tshiftKey: boolean\n\tcmdKey: boolean\n\tzoom: number\n\n\tpathTool: PathTool\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tsegmentHovered: PathSegmentSelector | null\n\tsegmentHandle: SegmentHandleSelector | null\n\tclosestCurve: ClosestCurve | null\n\tpointRounding: PointRounding\n\tsnapConstraint: Line | null\n}\n\ninterface State {\n\tsnappedMouse: Point | null\n\ttemporaryConstraint: Line | null\n\tintersectionTangent: Line | null\n\tsnapX: Set<number> | null\n\tsnapY: Set<number> | null\n}\n\nexport function withPathSnapping<P>(Component: React.ComponentClass<P>): React.ComponentClass<P> {\n\tclass WithPathSnapping extends React.Component<Props & P, State> {\n\t\toverride render() {\n\t\t\tconst pathTool = this.props.pathTool as any as VekterPathTool\n\t\t\tconst engine = pathTool.engine\n\t\t\tconst { zoom } = engine.stores.canvasStore\n\t\t\tconst { intersectionTangent } = pathTool.pathEngine.snap\n\t\t\treturn (\n\t\t\t\t<div>\n\t\t\t\t\t<IntersectionTangent intersectionTangent={intersectionTangent} zoom={zoom} />\n\t\t\t\t\t<Component {...this.props}>{this.props.children}</Component>\n\t\t\t\t</div>\n\t\t\t)\n\t\t}\n\t}\n\n\tWithPathSnapping[\"displayName\"] = `WithPathSnapping(${Component.displayName || Component.name})`\n\treturn WithPathSnapping\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { PathCurve } from \"./PathCurve.tsx\"\n\ninterface Props {\n\tintersectionTangent: Line | null\n\tzoom: number\n}\n\nexport class IntersectionTangent extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { intersectionTangent, zoom } = this.props\n\t\tif (!intersectionTangent) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst fromSegment = new PathSegment(Point.multiply(intersectionTangent.a, zoom))\n\t\tconst toSegment = new PathSegment(Point.multiply(intersectionTangent.b, zoom))\n\n\t\treturn (\n\t\t\t<PathCurve key=\"curve-snap\" strokeDasharray=\"1 3\" from={fromSegment} to={toSegment} stroke={colors.snapLine} />\n\t\t)\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport type { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport React from \"react\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\nimport { handleUpdate } from \"./utils/index.ts\"\nimport { withPathSnapping } from \"./utils/withPathSnapping.tsx\"\n\ninterface Props {\n\tpathTool: PathSegmentHandleMoveTool\n}\n\nexport class PathSegmentHandleMoveTool\n\textends withClassDiscriminator(\"PathSegmentHandleMoveTool\")\n\timplements VekterPathTool\n{\n\treadonly wantsAutoscrolling = true\n\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\toriSegment!: PathSegment\n\n\tdidMove = false\n\n\tstart() {\n\t\tconst { segmentHandle, tree } = this.pathEngine\n\n\t\tif (!segmentHandle) return\n\t\tconst node = tree.getNode(segmentHandle.id) as PathNode\n\t\tthis.oriSegment = node.pathSegments[segmentHandle.index]\n\t\tthis.engine.beginUndoGroup()\n\t\tthis.didMove = false\n\t}\n\n\tstop() {\n\t\tthis.pathEngine.setPathConstraint(null)\n\t\tthis.engine.endUndoGroup()\n\t}\n\n\tupdate() {\n\t\tconst { tree } = this.engine\n\t\tconst { latest, previous: previousState } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, altKey } = latest\n\t\tconst { segmentHandle, snap } = this.pathEngine\n\t\tif (!segmentHandle || !canvasMouseDownPosition || !snap.snappedMouse) {\n\t\t\tthis.pathEngine.switchToDefault()\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.didMove) {\n\t\t\tif (isEqual(canvasMouseDownPosition, canvasMousePosition)) return\n\t\t\tthis.didMove = true\n\t\t}\n\n\t\tif (isEqual(snap.snappedMouse, snap.previousSnappedMouse) && altKey === previousState.altKey) {\n\t\t\treturn\n\t\t}\n\n\t\tconst pathSegments = handleUpdate(tree, segmentHandle, snap.snappedMouse, this.oriSegment, altKey)\n\t\tconst node = tree.getNode<PathNode>(segmentHandle.id)\n\t\tif (!node) return\n\t\tnode.set(node.updateForPath({ pathSegments }))\n\t}\n}\n\nclass PathSegmentHandleMove extends React.Component<Props, {}> {\n\toverride render() {\n\t\treturn null\n\t}\n}\n\nconst exportWithSnapping = withPathSnapping(PathSegmentHandleMove)\nexport { exportWithSnapping as PathSegmentHandleMove }\n", "import { List } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { type MaybeNodeID, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { NullID, isTreeNode } from \"document/models/CanvasTree/index.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { hasAnyLayout } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport type { WithPositionType } from \"document/models/CanvasTree/traits/WithPositionType.ts\"\nimport { withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport { strokeDefaults } from \"document/models/CanvasTree/traits/WithStroke.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport { SegmentHandle } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { pathExtensionCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { mouseActionType } from \"../utils/mouseActionType.tsx\"\nimport { PathSegmentHandleMoveTool } from \"./PathSegmentHandleMove.tsx\"\nimport type { VekterPathEngine, VekterPathTool } from \"./PathToolManager.tsx\"\n\n/** Used for testing if we can create a path node in the target parent */\nconst staticPathNode = new PathNode()\n\nexport class PathSegmentAdditionTool\n\textends withClassDiscriminator(\"PathSegmentAdditionTool\")\n\timplements VekterPathTool\n{\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\tpathEngine: VekterPathEngine\n\n\tconstructor(engine: VekterEngine, pathEngine: VekterPathEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t\tthis.pathEngine = pathEngine\n\t}\n\n\tsegmentAdded = false\n\n\tstart() {\n\t\tthis.engine.stores.mouseCursorStore.current = pathExtensionCursor\n\t}\n\n\tstop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\tupdate() {\n\t\tconst { previous, latest } = this.engine.stores.mouseStore\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tswitch (mouseAction) {\n\t\t\tcase \"mouseDown\":\n\t\t\t\treturn this.mouseDown()\n\t\t\tcase \"mouseMove\":\n\t\t\t\treturn this.mouseMove()\n\t\t}\n\t}\n\n\tmouseMove() {\n\t\tconst { tree } = this.engine\n\t\tconst { canvasMouseDownPosition } = this.engine.stores.mouseStore.latest\n\t\tconst { segmentSelection } = this.pathEngine\n\n\t\tconst segmentSelector = segmentSelection[0]\n\t\tif (this.segmentAdded && canvasMouseDownPosition && segmentSelector) {\n\t\t\tconst activeNode = tree.getNode(segmentSelector.id) as PathNode\n\t\t\tconst isLastSegment = Path.isLastSegment(activeNode.pathSegments, activeNode.pathClosed, segmentSelector.index)\n\t\t\tconst handle = isLastSegment ? SegmentHandle.Out : SegmentHandle.In\n\t\t\tthis.pathEngine.setSegmentHandle({ id: activeNode.id, index: segmentSelector.index, handle })\n\t\t\tthis.pathEngine.setPathTool(new PathSegmentHandleMoveTool(this.engine, this.pathEngine))\n\t\t} else {\n\t\t\tthis.pathEngine.setHoveredSegment(null)\n\t\t}\n\t}\n\n\tmouseDown() {\n\t\tconst { tree, componentLoader } = this.engine\n\t\tconst { mouseStore, selectionStore, overlayStore, scopeStore } = this.engine.stores\n\t\tconst { canvasMousePosition } = mouseStore\n\t\tconst { segmentSelection, snap } = this.pathEngine\n\t\tconst { snappedMouse } = snap\n\t\tif (!canvasMousePosition) return\n\t\tif (!snappedMouse) return\n\n\t\tif (segmentSelection.length === 0) {\n\t\t\t// create new Vector with single point select first point\n\t\t\tconst potentialParents = tree\n\t\t\t\t.getPotentialParents(\n\t\t\t\t\tscopeStore.active,\n\t\t\t\t\toverlayStore.activeOverlays,\n\t\t\t\t\tRect.cornerPoints({ ...canvasMousePosition, width: 1, height: 1 }),\n\t\t\t\t\tcanvasMousePosition,\n\t\t\t\t\tcomponentLoader,\n\t\t\t\t\tstaticPathNode,\n\t\t\t\t)\n\t\t\t\t// When drawing a path, don't nest it in other shapes (or boolean nodes).\n\t\t\t\t.filter(node => !withShape(node))\n\n\t\t\tlet parentId: MaybeNodeID = NullID\n\t\t\tlet point = snappedMouse\n\n\t\t\tconst parentNode = tree.getTopMostChildNode(potentialParents)\n\t\t\tif (parentNode && isTreeNode(parentNode)) {\n\t\t\t\tif (isReplicaOrReplicaChild(parentNode)) return\n\t\t\t\tparentId = parentNode.id\n\t\t\t\tpoint = tree.convertPointToNode(parentNode, point)\n\t\t\t}\n\n\t\t\tconst id = randomID()\n\t\t\tconst position: Partial<WithPositionType> = {\n\t\t\t\tposition: parentNode && hasAnyLayout(parentNode) ? \"absolute\" : undefined,\n\t\t\t}\n\n\t\t\tconst properties = { id, ...point, ...strokeDefaults, ...position, pathSegments: [new PathSegment()] }\n\t\t\tthis.engine.createPath(parentId, properties)\n\t\t\tselectionStore.set(id, { switchToProperties: true })\n\t\t\tthis.pathEngine.setSegmentSelection([{ id: id, index: 0 }])\n\t\t\tthis.segmentAdded = true\n\t\t} else {\n\t\t\t// if first or last point of vector, add point, else, exit\n\t\t\tconst segmentSelector = segmentSelection[0]\n\t\t\tif (!segmentSelector) return\n\n\t\t\tconst activeNode = tree.getNode(segmentSelector.id) as PathNode\n\t\t\tconst isLastSegment = Path.isLastSegment(activeNode.pathSegments, activeNode.pathClosed, segmentSelector.index)\n\t\t\tconst convertedMousePoint = tree.convertPointToNode(activeNode, snappedMouse, true)\n\t\t\tconst newPoint = new PathSegment(convertedMousePoint)\n\t\t\tconst insertionIndex = isLastSegment ? activeNode.pathSegments.length : 0\n\t\t\tconst pathSegments = List.insert(activeNode.pathSegments, insertionIndex, newPoint)\n\n\t\t\tactiveNode.set(activeNode.updateForPath({ pathSegments }))\n\n\t\t\tthis.pathEngine.setSegmentSelection([{ id: activeNode.id, index: insertionIndex }])\n\t\t\tthis.pathEngine.setHoveredSegment(null)\n\t\t\tthis.pathEngine.setClosestCurve(null)\n\t\t\tthis.segmentAdded = true\n\t\t}\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { CanvasTree, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport type { ClosestCurve, PathSegmentSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType } from \"document/stores/PathSelectionStore.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { convertPathToCanvas, groupPathSegmentSelectors } from \"../utils/index.ts\"\nimport { PathCurve } from \"./PathCurve.tsx\"\n\ninterface Props {\n\ttree: CanvasTree\n\tnodes: PathNode[]\n\tmouse: Point | null\n\tcmdKey: boolean\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tclosestCurve: ClosestCurve | null\n\tsnapConstraint: Line | null\n\tzoom: number\n}\n\nexport class PathCurves extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { tree, closestCurve, segmentSelection, snapConstraint, selectionType, zoom, cmdKey } = this.props\n\n\t\tif (snapConstraint) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst curves: JSX.Element[] = []\n\n\t\t// Closest curve\n\n\t\tif (!cmdKey && closestCurve && !closestCurve.midPointInRange) {\n\t\t\tconst node = tree.getNode(closestCurve.id) as PathNode\n\t\t\tif (!node) return null\n\t\t\tconst normalizedPath = convertPathToCanvas(tree, node, node, zoom)[0]\n\t\t\tassert(normalizedPath, \"Expected normalizedPath from convertPathToCanvas[0]\")\n\t\t\tconst segmentCount = normalizedPath.pathSegments.length\n\t\t\tconst nextIndex = closestCurve.segmentIndex + 1 === segmentCount ? 0 : closestCurve.segmentIndex + 1\n\t\t\tconst fromSegment = normalizedPath.pathSegments[closestCurve.segmentIndex]\n\t\t\tconst toSegment = normalizedPath.pathSegments[nextIndex]\n\t\t\tif (fromSegment && toSegment) {\n\t\t\t\tconst curve = <PathCurve key=\"closest\" from={fromSegment} to={toSegment} strokeWidth={2} />\n\t\t\t\tcurves.push(curve)\n\t\t\t}\n\t\t}\n\n\t\t// Selected curves\n\n\t\tif (selectionType === PathSelectionType.Curves) {\n\t\t\tconst groupedSegments = groupPathSegmentSelectors(segmentSelection)\n\t\t\tconst ids = Object.keys(groupedSegments)\n\t\t\tfor (const id of ids) {\n\t\t\t\tconst node = tree.getNode(id) as PathNode\n\t\t\t\tconst normalizedPath = convertPathToCanvas(tree, node, node, zoom)[0]\n\t\t\t\tassert(normalizedPath, \"Expected normalizedPath from convertPathToCanvas[0]\")\n\t\t\t\tconst segmentCount = normalizedPath.pathSegments.length\n\n\t\t\t\tconst selectedCurves = groupedSegments[id]\n\t\t\t\tassert(selectedCurves, \"Expected selectedCurves for id from Object.keys\")\n\t\t\t\tfor (const fromIndex of selectedCurves) {\n\t\t\t\t\tconst nextIndex = fromIndex + 1 === segmentCount ? 0 : fromIndex + 1\n\t\t\t\t\tconst fromSegment = normalizedPath.pathSegments[fromIndex]\n\t\t\t\t\tassert(fromSegment, \"Expected fromSegment at fromIndex\")\n\t\t\t\t\tconst toSegment = normalizedPath.pathSegments[nextIndex]\n\t\t\t\t\tassert(toSegment, \"Expected toSegment at nextIndex\")\n\n\t\t\t\t\tconst curve = (\n\t\t\t\t\t\t<PathCurve key={node.id + \"selected curve\" + fromIndex} from={fromSegment} to={toSegment} strokeWidth={2} />\n\t\t\t\t\t)\n\t\t\t\t\tcurves.push(curve)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn <div>{curves}</div>\n\t}\n}\n", "import type { CanvasTree, NodeID, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport type { PathSegmentSelector, SegmentHandleSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType } from \"document/stores/PathSelectionStore.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport { groupPathSegmentSelectors } from \"../utils/index.ts\"\nimport { PathSegmentAnchor } from \"./PathSegmentAnchor.tsx\"\n\ninterface Props {\n\ttree: CanvasTree\n\tselection: NodeID[]\n\tzoom: number\n\tcmdKey: boolean\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tsegmentHandle: SegmentHandleSelector | null\n\tsnapConstraint: Line | null\n\n\tpathTool: VekterPathTool\n}\n\nexport class PathSegmentAnchors extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { tree, selection, pathTool, segmentSelection, cmdKey, zoom, segmentHandle, selectionType, snapConstraint } =\n\t\t\tthis.props\n\n\t\tconst groupedSegments = groupPathSegmentSelectors(segmentSelection)\n\n\t\tconst anchors: JSX.Element[] = []\n\n\t\tfor (let i = 0, il = selection.length; i < il; i++) {\n\t\t\tconst id = selection[i]\n\t\t\tconst node = tree.getNode(id) as PathNode\n\t\t\tconst selectedIndexes: number[] = groupedSegments[id] || []\n\n\t\t\tfor (let j = 0, jl = node.pathSegments.length; j < jl; j++) {\n\t\t\t\tconst segment = node.pathSegments[j]\n\t\t\t\tconst convertedPoint = tree.convertPointToCanvas(node, PathSegment.point(segment))\n\t\t\t\tconst selected =\n\t\t\t\t\tsegmentHandle === null && selectedIndexes.includes(j) && selectionType === PathSelectionType.Segments\n\n\t\t\t\tconst anchor = (\n\t\t\t\t\t<PathSegmentAnchor\n\t\t\t\t\t\tkey={id + \"anchor\" + j}\n\t\t\t\t\t\ttree={tree}\n\t\t\t\t\t\tnode={node}\n\t\t\t\t\t\tindex={j}\n\t\t\t\t\t\tsegmentHandle={segmentHandle}\n\t\t\t\t\t\tpoint={Point.multiply(convertedPoint, zoom)}\n\t\t\t\t\t\tselected={selected}\n\t\t\t\t\t\tpathTool={pathTool}\n\t\t\t\t\t\tsegmentSelection={segmentSelection}\n\t\t\t\t\t\tselectionType={selectionType}\n\t\t\t\t\t\tsnapConstraint={snapConstraint}\n\t\t\t\t\t\tisEnd={!node.pathClosed && (j === 0 || j === jl - 1)}\n\t\t\t\t\t\tcmdKey={cmdKey}\n\t\t\t\t\t/>\n\t\t\t\t)\n\n\t\t\t\tanchors.push(anchor)\n\t\t\t}\n\t\t}\n\n\t\treturn <div style={{ position: \"absolute\" }}>{anchors}</div>\n\t}\n}\n", "import { assert, List } from \"@framerjs/shared\"\nimport { cx } from \"@linaria/core\"\nimport type { CanvasTree, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport type { PathSegmentSelector, SegmentHandleSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType } from \"document/stores/PathSelectionStore.ts\"\nimport { isStraightCurve } from \"library/render/traits/Path.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { pathClosingCursor, pathExtensionCursor } from \"utils/cursor.ts\"\nimport { PathDefaultTool } from \"../PathDefault.tsx\"\nimport { PathSegmentAdditionTool } from \"../PathSegmentAdditionTool.ts\"\nimport { PathSegmentMoveTool } from \"../PathSegmentMove.ts\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport { joinPaths } from \"../utils/index.ts\"\nimport * as styles from \"./PathSegmentControl.styles.ts\"\n\ninterface Props {\n\ttree: CanvasTree\n\tnode: PathNode\n\tindex: number\n\tcmdKey: boolean\n\tpoint: Point\n\tselected: boolean\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tsegmentHandle: SegmentHandleSelector | null\n\tsnapConstraint: Line | null\n\n\tpathTool: VekterPathTool\n\n\tisEnd: boolean\n}\n\ninterface State {\n\thovered: boolean\n\tconstraintAnchor: boolean\n}\n\nexport function processMouseDown(\n\tpathTool: VekterPathTool,\n\tprops: Props,\n\tevent: MouseEvent | React.MouseEvent<HTMLElement>,\n) {\n\tconst engine = pathTool.engine\n\tconst pathEngine = pathTool.pathEngine\n\tconst { tree } = engine\n\tconst { cmdKey } = engine.stores.mouseStore.latest\n\tconst { segmentSelection, segmentHandle, selectionType, snapConstraint } = pathEngine\n\tconst { node, index, isEnd } = props\n\n\tif (snapConstraint) {\n\t\treturn\n\t}\n\n\tif (pathTool instanceof PathSegmentAdditionTool) {\n\t\tconst segmentSelector = segmentSelection[0]\n\t\tassert(segmentSelector, \"Expected segmentSelector in PathSegmentAdditionTool\")\n\n\t\tif (cmdKey) {\n\t\t\treturn\n\t\t}\n\t\tif (isEnd) {\n\t\t\tif (segmentSelector.id === node.id) {\n\t\t\t\tif (canClosePath(index, segmentSelector, node)) {\n\t\t\t\t\tengine.tree.current(node)?.set(node.updateForPath({ pathClosed: true }))\n\t\t\t\t\tpathEngine.setSegmentSelection([{ id: node.id, index }])\n\t\t\t\t\tpathEngine.setPathTool(new PathSegmentMoveTool(engine, pathEngine))\n\t\t\t\t\tevent.stopPropagation()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst selectedNode = tree.getNode(segmentSelector.id) as PathNode\n\t\t\t\tjoinPaths(tree, engine, selectedNode, segmentSelector, node, { id: node.id, index })\n\t\t\t\tpathEngine.setSegmentSelection([])\n\t\t\t\tpathEngine.setPathTool(new PathDefaultTool(engine, pathEngine))\n\t\t\t\tevent.stopPropagation()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t} else if (!(pathTool instanceof PathDefaultTool)) {\n\t\treturn\n\t}\n\n\tconst selectingSegments = selectionType === PathSelectionType.Segments\n\n\tif (event.shiftKey && selectingSegments) {\n\t\tpathEngine.toggleSegmentSelection([{ id: node.id, index }])\n\t} else {\n\t\tconst inSelection = segmentSelection.find(segment => {\n\t\t\treturn segment.id === node.id && segment.index === index\n\t\t})\n\n\t\tif (!selectingSegments || inSelection === undefined || segmentHandle) {\n\t\t\tpathEngine.setSegmentSelection([{ id: node.id, index }])\n\t\t}\n\t}\n\n\tpathEngine.setSegmentHandle(null)\n\tpathEngine.setPathTool(new PathSegmentMoveTool(engine, pathEngine))\n}\n\nexport class PathSegmentAnchor extends React.Component<Props, State> {\n\toverride state: State = { hovered: false, constraintAnchor: false }\n\n\tmouseDown = (event: React.MouseEvent<HTMLElement>) => {\n\t\tconst pathTool = this.props.pathTool\n\t\tconst engine = pathTool.engine\n\n\t\tengine.scheduler.process(() => {\n\t\t\tprocessMouseDown(pathTool, this.props, event)\n\t\t})\n\t}\n\n\tmouseOver = () => {\n\t\tconst pathTool = this.props.pathTool\n\t\tpathTool.engine.scheduler.process(() => {\n\t\t\tconst { snapConstraint } = this.props\n\t\t\tif (!(pathTool instanceof PathDefaultTool) && !(pathTool instanceof PathSegmentAdditionTool)) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (snapConstraint) {\n\t\t\t\tthis.setState({ constraintAnchor: true })\n\t\t\t}\n\n\t\t\tthis.setState({ hovered: true })\n\t\t\tpathTool.pathEngine.setHoveredSegment({ id: this.props.node.id, index: this.props.index })\n\t\t\tpathTool.pathEngine.setClosestCurve(null)\n\t\t})\n\t}\n\n\tmouseOut = () => {\n\t\tthis.setState({ hovered: false })\n\n\t\tif (this.state.constraintAnchor) {\n\t\t\tthis.setState({ constraintAnchor: false })\n\t\t}\n\t}\n\n\tmouseMove = (event: React.MouseEvent<HTMLElement>) => {\n\t\tconst { pathTool } = this.props\n\t\tif (!(pathTool instanceof PathDefaultTool) && !(pathTool instanceof PathSegmentAdditionTool)) {\n\t\t\treturn\n\t\t}\n\t\tevent.stopPropagation()\n\t}\n\n\tdoubleClick = (event: React.MouseEvent<HTMLElement>) => {\n\t\tevent.stopPropagation()\n\t\tconst { node, index, pathTool, segmentSelection } = this.props\n\t\tif (pathTool instanceof PathSegmentAdditionTool) {\n\t\t\tconst segmentSelector = segmentSelection[0]\n\t\t\tassert(segmentSelector, \"Expected segmentSelector in PathSegmentAdditionTool\")\n\t\t\tif (segmentSelector.id !== node.id && segmentSelector.index !== index) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst pathSegments = List.update(node.pathSegments, index, segment => {\n\t\t\tswitch (segment.handleMirroring) {\n\t\t\t\tcase \"straight\": {\n\t\t\t\t\tconst control1 = PathSegment.curveDefault(node.pathSegments, index)\n\t\t\t\t\tconst control2 = Point.reverse(control1)\n\n\t\t\t\t\tconst newProperties: Partial<PathSegment> = {\n\t\t\t\t\t\thandleMirroring: \"symmetric\",\n\t\t\t\t\t\thandleOutX: control1.x,\n\t\t\t\t\t\thandleOutY: control1.y,\n\t\t\t\t\t\thandleInX: control2.x,\n\t\t\t\t\t\thandleInY: control2.y,\n\t\t\t\t\t}\n\n\t\t\t\t\treturn segment.merge(newProperties)\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn segment.merge({ handleMirroring: \"straight\" })\n\t\t\t}\n\t\t})\n\n\t\tpathTool.engine.scheduler.process(() => {\n\t\t\tpathTool.engine.tree.current(node)?.set(node.updateForPath({ pathSegments }))\n\t\t})\n\t}\n\n\toverride render() {\n\t\tconst { selected, point, cmdKey, snapConstraint, isEnd, pathTool, node, index, segmentSelection } = this.props\n\t\tconst highlighted = selected || this.state.hovered\n\t\tconst constrained = snapConstraint && this.state.constraintAnchor && !selected\n\n\t\tconst style: React.CSSProperties = {\n\t\t\ttop: point.y,\n\t\t\tleft: point.x,\n\t\t}\n\n\t\tif (isEnd) {\n\t\t\tstyle.zIndex = 2\n\t\t}\n\n\t\tif (pathTool instanceof PathSegmentAdditionTool && !snapConstraint) {\n\t\t\tif (isEnd) {\n\t\t\t\tconst segmentSelector = segmentSelection[0]\n\t\t\t\tif (segmentSelector) {\n\t\t\t\t\tconst canClose = segmentSelector.id !== node.id || canClosePath(index, segmentSelector, node)\n\t\t\t\t\tif (canClose) {\n\t\t\t\t\t\tstyle.cursor = pathClosingCursor\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (cmdKey) {\n\t\t\t\tstyle.cursor = pathExtensionCursor\n\t\t\t}\n\t\t}\n\n\t\treturn (\n\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events,jsx-a11y/no-static-element-interactions\n\t\t\t<div\n\t\t\t\tstyle={style}\n\t\t\t\tonMouseDown={this.mouseDown}\n\t\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n\t\t\t\tonMouseOver={this.mouseOver}\n\t\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n\t\t\t\tonMouseOut={this.mouseOut}\n\t\t\t\tonMouseMove={this.mouseMove}\n\t\t\t\tonDoubleClick={this.doubleClick}\n\t\t\t\tclassName={cx(\n\t\t\t\t\tstyles.control,\n\t\t\t\t\thighlighted && styles.controlHighlighted,\n\t\t\t\t\tconstrained && styles.controlConstrained,\n\t\t\t\t)}\n\t\t\t/>\n\t\t)\n\t}\n}\n\nfunction canClosePath(hoveredSegmentIndex: number, selectedSegment: PathSegmentSelector, node: PathNode) {\n\tif (hoveredSegmentIndex === selectedSegment.index) {\n\t\treturn false\n\t}\n\tconst segmentCount = node.pathSegments.length\n\tif (segmentCount !== 2) {\n\t\treturn segmentCount > 2\n\t}\n\t// segment count is 2\n\tconst segment1 = node.pathSegments[0]\n\tassert(segment1, \"Expected segment1 when segmentCount === 2\")\n\tconst segment2 = node.pathSegments[1]\n\tassert(segment2, \"Expected segment2 when segmentCount === 2\")\n\treturn !isStraightCurve(segment1, segment2) || !isStraightCurve(segment2, segment1)\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { assert } from \"@framerjs/shared\"\nimport type { CanvasTree, NodeID, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport type { ClosestCurve, PathSegmentSelector, SegmentHandleSelector } from \"document/stores/PathSelectionStore.ts\"\nimport { PathSelectionType, SegmentHandle } from \"document/stores/PathSelectionStore.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { PathCurveBendTool } from \"../PathCurveBend.tsx\"\nimport { PathSegmentHandleMoveTool } from \"../PathSegmentHandleMove.tsx\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport { groupPathSegmentSelectors } from \"../utils/index.ts\"\nimport { VectorLine } from \"./Line.tsx\"\nimport { PathSegmentHandle } from \"./PathSegmentHandle.tsx\"\n\ninterface Props {\n\ttree: CanvasTree\n\tselection: NodeID[]\n\tzoom: number\n\taltKey: boolean\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tclosestCurve: ClosestCurve | null\n\tsegmentHandle: SegmentHandleSelector | null\n\tsnapConstraint: Line | null\n\n\tpathTool: VekterPathTool\n}\n\nexport class PathSegmentHandles extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { tree, selection, segmentSelection, closestCurve, pathTool, selectionType } = this.props\n\n\t\tif (selectionType === PathSelectionType.Curves) {\n\t\t\treturn null\n\t\t}\n\n\t\tif (!(pathTool instanceof PathSegmentHandleMoveTool) && this.props.pathTool.pathEngine.snapConstraint) {\n\t\t\treturn null\n\t\t}\n\n\t\tconst curveBendingActive = pathTool instanceof PathCurveBendTool\n\n\t\tconst lines: JSX.Element[] = []\n\t\tconst handles: JSX.Element[] = []\n\n\t\tif (curveBendingActive && closestCurve) {\n\t\t\tconst node = tree.getNode<PathNode>(closestCurve.id)\n\t\t\tif (node) {\n\t\t\t\tlet toSegmentIndex = closestCurve.segmentIndex + 1\n\t\t\t\tif (closestCurve.segmentIndex === node.pathSegments.length - 1) {\n\t\t\t\t\ttoSegmentIndex = 0\n\t\t\t\t}\n\n\t\t\t\tthis.handles(node, [closestCurve.segmentIndex, toSegmentIndex], lines, handles)\n\t\t\t}\n\t\t} else {\n\t\t\tconst groupedSegments = groupPathSegmentSelectors(segmentSelection)\n\t\t\tselection.forEach(id => {\n\t\t\t\tconst node = tree.getNode<PathNode>(id)\n\t\t\t\tif (!node) return\n\t\t\t\tconst indexes = groupedSegments[id] || []\n\t\t\t\tthis.handles(node, indexes, lines, handles)\n\t\t\t})\n\t\t}\n\n\t\treturn (\n\t\t\t<div style={{ position: \"absolute\" }}>\n\t\t\t\t{\" \"}\n\t\t\t\t{lines} {handles}{\" \"}\n\t\t\t</div>\n\t\t)\n\t}\n\n\thandles(node: PathNode, segmentIndexes: number[], lines: JSX.Element[], handles: JSX.Element[]) {\n\t\tconst { tree, zoom, pathTool, segmentHandle, altKey, segmentSelection } = this.props\n\t\tconst snapConstraint =\n\t\t\tthis.props.pathTool.pathEngine.snapConstraint || this.props.pathTool.pathEngine.snap.temporaryConstraint\n\n\t\tconst pathSegmentsCount = node.pathSegments.length\n\n\t\tfor (let i = 0; i < pathSegmentsCount; i++) {\n\t\t\tlet ignore = !segmentIndexes.includes(i)\n\t\t\tif (!(pathTool instanceof PathSegmentHandleMoveTool) && altKey) {\n\t\t\t\tignore = false\n\t\t\t}\n\t\t\tif (ignore) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst segment = node.pathSegments[i]\n\t\t\tassert(segment, \"Expected segment at index within loop bounds\")\n\t\t\tif (segment.handleMirroring === \"straight\") {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst anchor = tree.convertPointToCanvas(node, PathSegment.point(segment))\n\t\t\tconst handleOut = tree.convertPointToCanvas(node, PathSegment.calculatedHandleOut(segment))\n\t\t\tconst handleIn = tree.convertPointToCanvas(node, PathSegment.calculatedHandleIn(segment))\n\t\t\tconst handleOutLine = Point.multiply(handleOut, zoom)\n\t\t\tconst handleInLine = Point.multiply(handleIn, zoom)\n\n\t\t\tconst key = node.id + i * 10\n\n\t\t\tconst selected = segmentHandle !== null && segmentHandle.id === node.id && segmentHandle.index === i\n\n\t\t\tif (!(segment.handleInX === 0 && segment.handleInY === 0)) {\n\t\t\t\tconst handleSelected = selected && segmentHandle !== null && segmentHandle.handle === SegmentHandle.In\n\t\t\t\tconst constrained = handleSelected && snapConstraint !== null\n\n\t\t\t\tlines.push(\n\t\t\t\t\t<VectorLine\n\t\t\t\t\t\tkey={key + 1}\n\t\t\t\t\t\tzoom={zoom}\n\t\t\t\t\t\tpointA={handleIn}\n\t\t\t\t\t\tpointB={anchor}\n\t\t\t\t\t\tstroke={constrained ? colors.snapLine : undefined}\n\t\t\t\t\t/>,\n\t\t\t\t)\n\t\t\t\thandles.push(\n\t\t\t\t\t<PathSegmentHandle\n\t\t\t\t\t\tkey={key + 3}\n\t\t\t\t\t\tselected={handleSelected}\n\t\t\t\t\t\tconstrained={constrained}\n\t\t\t\t\t\tpoint={handleInLine}\n\t\t\t\t\t\tpathTool={pathTool}\n\t\t\t\t\t\tselector={{ id: node.id, index: i, handle: SegmentHandle.In }}\n\t\t\t\t\t\tsegmentSelection={segmentSelection}\n\t\t\t\t\t/>,\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!(segment.handleOutX === 0 && segment.handleOutY === 0)) {\n\t\t\t\tconst handleSelected = selected && segmentHandle !== null && segmentHandle.handle === SegmentHandle.Out\n\t\t\t\tconst constrained = handleSelected && snapConstraint !== null\n\n\t\t\t\tlines.push(\n\t\t\t\t\t<VectorLine\n\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\tzoom={zoom}\n\t\t\t\t\t\tpointA={handleOut}\n\t\t\t\t\t\tpointB={anchor}\n\t\t\t\t\t\tstroke={constrained ? colors.snapLine : undefined}\n\t\t\t\t\t/>,\n\t\t\t\t)\n\t\t\t\thandles.push(\n\t\t\t\t\t<PathSegmentHandle\n\t\t\t\t\t\tkey={key + 2}\n\t\t\t\t\t\tselected={handleSelected}\n\t\t\t\t\t\tconstrained={constrained}\n\t\t\t\t\t\tpoint={handleOutLine}\n\t\t\t\t\t\tpathTool={pathTool}\n\t\t\t\t\t\tselector={{ id: node.id, index: i, handle: SegmentHandle.Out }}\n\t\t\t\t\t\tsegmentSelection={segmentSelection}\n\t\t\t\t\t/>,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\n\ninterface Props {\n\tzoom: number\n\tpointA: Point\n\tpointB: Point\n\tstroke?: string\n}\n\nexport class VectorLine extends React.Component<Props> {\n\toverride render() {\n\t\tconst pointA = Point.multiply(this.props.pointA, this.props.zoom)\n\t\tconst pointB = Point.multiply(this.props.pointB, this.props.zoom)\n\t\tconst endPoint = Point.subtract(pointB, pointA)\n\n\t\tconst controlPoint1 = { x: 0, y: 0 }\n\t\tconst controlPoint2 = endPoint\n\n\t\tconst pathData = `M 0 0 C ${controlPoint1.x} ${controlPoint1.y} ${controlPoint2.x} ${controlPoint2.y} ${endPoint.x} ${endPoint.y}`\n\n\t\tconst style: React.CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\ttransform: `translate(${pointA.x}px, ${pointA.y}px)`,\n\t\t\twidth: `${100}px`,\n\t\t\theight: `${100}px`,\n\t\t\toverflow: \"visible\",\n\t\t}\n\n\t\treturn (\n\t\t\t<svg\n\t\t\t\twidth=\"100%\"\n\t\t\t\theight=\"100%\"\n\t\t\t\tstyle={style}\n\t\t\t\tstrokeWidth={1}\n\t\t\t\tstroke={this.props.stroke || colors.tint}\n\t\t\t\tfill=\"transparent\"\n\t\t\t\tviewBox={`${0} ${0} ${100} ${100}`}\n\t\t\t>\n\t\t\t\t<path d={pathData} />\n\t\t\t</svg>\n\t\t)\n\t}\n}\n", "import { cx } from \"@linaria/core\"\nimport { InvalidID } from \"document/models/CanvasTree/index.ts\"\nimport type { PathSegmentSelector, SegmentHandleSelector } from \"document/stores/PathSelectionStore.ts\"\nimport type { Point } from \"library/render/types/Point.ts\"\nimport React from \"react\"\nimport { PathDefaultTool } from \"../PathDefault.tsx\"\nimport { PathSegmentAdditionTool } from \"../PathSegmentAdditionTool.ts\"\nimport { PathSegmentHandleMoveTool } from \"../PathSegmentHandleMove.tsx\"\nimport type { VekterPathTool } from \"../PathToolManager.tsx\"\nimport * as styles from \"./PathSegmentControl.styles.ts\"\n\ninterface Props {\n\tselector: SegmentHandleSelector\n\tpoint: Point\n\tsegmentSelection: PathSegmentSelector[]\n\tselected: boolean\n\tconstrained: boolean\n\n\tpathTool: VekterPathTool\n}\n\ninterface State {\n\thovered: boolean\n}\n\nexport class PathSegmentHandle extends React.Component<Props, State> {\n\toverride state: State = { hovered: false }\n\n\tmouseDown = () => {\n\t\tconst engine = this.props.pathTool.engine\n\t\tconst pathEngine = this.props.pathTool.pathEngine\n\t\tengine.scheduler.process(() => {\n\t\t\tconst { selector, segmentSelection } = this.props\n\t\t\tpathEngine.setSegmentHandle(selector)\n\t\t\tpathEngine.setPathTool(new PathSegmentHandleMoveTool(engine, pathEngine))\n\n\t\t\tconst segmentInSelection =\n\t\t\t\tsegmentSelection.find(segmentSelector => {\n\t\t\t\t\treturn selector.id === segmentSelector.id && selector.index === segmentSelector.index\n\t\t\t\t}) !== undefined\n\t\t\tif (segmentInSelection) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tpathEngine.setSegmentSelection([{ id: selector.id, index: selector.index }])\n\t\t})\n\t}\n\n\tmouseOver = () => {\n\t\tconst engine = this.props.pathTool.engine\n\t\tconst pathEngine = this.props.pathTool.pathEngine\n\t\tengine.scheduler.process(() => {\n\t\t\tthis.setState({ hovered: true })\n\t\t\tpathEngine.setHoveredSegment({ id: InvalidID, index: 0 })\n\t\t\tpathEngine.setClosestCurve(null)\n\t\t})\n\t}\n\n\tmouseOut = () => {\n\t\tthis.setState({ hovered: false })\n\t}\n\n\tmouseMove = (event: React.MouseEvent<HTMLElement>) => {\n\t\tevent.stopPropagation()\n\t}\n\n\tdoubleClick = (event: React.MouseEvent) => {\n\t\tevent.stopPropagation()\n\t}\n\n\toverride render() {\n\t\tconst { pathTool, point, selected, constrained } = this.props\n\t\tconst highlighted = selected || this.state.hovered\n\n\t\tconst style: React.CSSProperties = {\n\t\t\ttop: point.y,\n\t\t\tleft: point.x,\n\t\t}\n\n\t\tif (!(pathTool instanceof PathDefaultTool) && !(pathTool instanceof PathSegmentAdditionTool)) {\n\t\t\tstyle.pointerEvents = \"none\"\n\t\t}\n\n\t\treturn (\n\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events,jsx-a11y/no-static-element-interactions\n\t\t\t<div\n\t\t\t\tstyle={style}\n\t\t\t\tonMouseDown={this.mouseDown}\n\t\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n\t\t\t\tonMouseOver={this.mouseOver}\n\t\t\t\t// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events\n\t\t\t\tonMouseOut={this.mouseOut}\n\t\t\t\tonMouseMove={this.mouseMove}\n\t\t\t\tonDoubleClick={this.doubleClick}\n\t\t\t\tclassName={cx(\n\t\t\t\t\tstyles.control,\n\t\t\t\t\thighlighted && styles.controlHighlighted,\n\t\t\t\t\tconstrained && styles.controlConstrained,\n\t\t\t\t)}\n\t\t\t/>\n\t\t)\n\t}\n}\n", "import type { CanvasTree, NodeID, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport React from \"react\"\nimport { PathShape } from \"./PathShape.tsx\"\n\ninterface Props {\n\ttree: CanvasTree\n\tselection: NodeID[]\n\tzoom: number\n}\n\nexport class PathShapes extends React.Component<Props, {}> {\n\toverride render() {\n\t\tconst { tree, selection, zoom } = this.props\n\t\tconst shapes: JSX.Element[] = []\n\n\t\tfor (let i = 0, il = selection.length; i < il; i++) {\n\t\t\tconst node = tree.getNode(selection[i]) as PathNode\n\t\t\tshapes.push(<PathShape key={node.id + \"shapeBg\"} node={node} tree={tree} zoom={zoom} />)\n\t\t}\n\n\t\treturn <div>{shapes}</div>\n\t}\n}\n", "import type { CanvasTree, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { convertCSSColorVariableToValue } from \"document/models/CanvasTree/nodes/utils/convertCSSColorVariableToValue.ts\"\nimport { withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport { Path } from \"document/models/Path.ts\"\nimport { toSVGPath } from \"library/render/traits/Path.ts\"\nimport { ConvertColor } from \"library/render/types/Color/index.ts\"\nimport React from \"react\"\nimport { convertPathToCanvas } from \"../utils/index.ts\"\n\ninterface Props {\n\ttree: CanvasTree\n\tnode: PathNode\n\tzoom: number\n}\n\nexport class PathShape extends React.Component<Props, object> {\n\toverride render() {\n\t\tconst { tree, node, zoom } = this.props\n\n\t\tconst normalized = convertPathToCanvas(tree, node, node, zoom)\n\t\tconst path = toSVGPath(normalized)\n\t\tconst boundingBox = Path.boundingBox(normalized)\n\n\t\tconst style: React.CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\ttransform: `translate(${boundingBox.x}px, ${boundingBox.y}px)`,\n\t\t}\n\n\t\tconst parentNode = tree.getParent(node.id)\n\t\tconst parentIsShape = parentNode && withShape(parentNode)\n\t\tconst strokeColor = convertCSSColorVariableToValue(node.resolveValue(\"strokeColor\"), tree)\n\n\t\tconst drawStroke =\n\t\t\tparentIsShape ||\n\t\t\tzoom > 4 ||\n\t\t\t!node.strokeEnabled ||\n\t\t\tnode.strokeWidth === 0 ||\n\t\t\t(node.strokeWidth && (node.resolveValue(\"strokeWidth\") ?? 0) > 10) ||\n\t\t\tConvertColor.getAlpha(strokeColor) === 0\n\n\t\tconst svgStyle: React.CSSProperties = {\n\t\t\tposition: \"absolute\",\n\t\t\twidth: boundingBox.width,\n\t\t\theight: boundingBox.height,\n\t\t\toverflow: \"visible\",\n\t\t\tfill: \"transparent\",\n\t\t\tstrokeWidth: 1,\n\t\t\tstroke: drawStroke ? \"rgba(0,0,0,0.25)\" : \"transparent\",\n\t\t}\n\n\t\treturn (\n\t\t\t<div style={style}>\n\t\t\t\t<svg\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\theight=\"100%\"\n\t\t\t\t\tstyle={svgStyle}\n\t\t\t\t\tkey={node.id + \"overlay\"}\n\t\t\t\t\tviewBox={`${boundingBox.x} ${boundingBox.y} ${boundingBox.width} ${boundingBox.height}`}\n\t\t\t\t\tstrokeLinecap={node.lineCap}\n\t\t\t\t\tstrokeLinejoin={node.lineJoin}\n\t\t\t\t>\n\t\t\t\t\t<path d={path} />\n\t\t\t\t</svg>\n\t\t\t</div>\n\t\t)\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasTree, NodeID, PathNode } from \"document/models/CanvasTree/index.ts\"\nimport { pathSegmentSnappingData } from \"document/models/PathSegmentSnapping.ts\"\nimport type { OrthogonalLines } from \"document/models/Snapping.ts\"\nimport { snap } from \"document/models/Snapping.ts\"\nimport type {\n\tClosestCurve,\n\tPathSegmentSelector,\n\tPathSelectionType,\n\tPointRounding,\n\tSegmentHandleSelector,\n} from \"document/stores/PathSelectionStore.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport { Line } from \"library/render/types/Line.ts\"\nimport { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport type { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { VekterPathEngine } from \"../PathToolManager.tsx\"\nimport { convertSegmentToCanvas, curveAngle, curveDerivative, roundedPoint } from \"./index.ts\"\n\ninterface Props {\n\ttree: CanvasTree\n\tselection: NodeID[]\n\tmouse: Point | null\n\tmouseDown: Point | null\n\tshiftKey: boolean\n\tcmdKey: boolean\n\tzoom: number\n\n\tpathToolClass: ClassDiscriminator\n\tsegmentSelection: PathSegmentSelector[]\n\tselectionType: PathSelectionType\n\tsegmentHovered: PathSegmentSelector | null\n\tsegmentHandle: SegmentHandleSelector | null\n\tclosestCurve: ClosestCurve | null\n\tpointRounding: PointRounding\n\tsnapConstraint: Line | null\n}\n\ninterface State {\n\tsnappedMouse: Point | null\n\ttemporaryConstraint: Line | null\n\tintersectionTangent: Line | null\n\tsnapX: Set<number> | null\n\tsnapY: Set<number> | null\n}\n\ntype PossibleConstraints = Line[]\n\nexport class PathSnapper implements Props, State {\n\tconstructor(\n\t\tpublic engine: VekterEngine,\n\t\tpublic pathEngine: VekterPathEngine,\n\t) {}\n\n\t// FIXME: the !s are unsafe; they are assigned in `.update()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\t// props\n\ttree!: CanvasTree\n\tselection!: NodeID[]\n\tmouse!: Point | null\n\tmouseDown!: Point | null\n\tshiftKey!: boolean\n\tcmdKey!: boolean\n\tzoom!: number\n\tpathToolClass!: ClassDiscriminator\n\tsegmentSelection!: PathSegmentSelector[]\n\tselectionType!: PathSelectionType\n\tsegmentHovered!: PathSegmentSelector | null\n\tsegmentHandle!: SegmentHandleSelector | null\n\tclosestCurve!: ClosestCurve | null\n\tpointRounding!: PointRounding\n\tsnapConstraint!: Line | null\n\n\t// state\n\tsnappedMouse: Point | null = null\n\tpreviousSnappedMouse: Point | null = null\n\ttemporaryConstraint: Line | null = null\n\tintersectionTangent: Line | null = null\n\tsnapX: Set<number> | null = null\n\tsnapY: Set<number> | null = null\n\n\t// Cache\n\tpossibleConstraints!: PossibleConstraints\n\torthogonalLines!: OrthogonalLines\n\n\tupdateCache() {\n\t\tthis.possibleConstraints = Constraint.options(this)\n\t\tthis.orthogonalLines = orthogonalLineOptions(this, this.engine)\n\t}\n\n\tshouldUpdateCache() {\n\t\tconst nextPathToolClass = this.pathEngine.pathTool.__class\n\t\tif (this.pathToolClass !== nextPathToolClass) return true\n\t\tif (nextPathToolClass !== \"PathSegmentAdditionTool\") return false\n\n\t\tconst prevSegment = this.segmentSelection[0]\n\t\tconst nextSegment = this.pathEngine.segmentSelection[0]\n\t\tif (prevSegment && nextSegment) {\n\t\t\tconst prevNode = this.tree.getNode(prevSegment.id) as PathNode\n\t\t\tconst nextNode = this.pathEngine.tree.getNode(nextSegment.id) as PathNode\n\t\t\tif (prevNode.id !== nextNode.id) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst differentSegmentCount = prevNode.pathSegments.length !== nextNode.pathSegments.length\n\t\t\tif (differentSegmentCount) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn !isEqual(this.segmentSelection, this.pathEngine.segmentSelection)\n\t}\n\n\tupdateProps() {\n\t\tconst shouldUpdateCache = this.shouldUpdateCache()\n\n\t\tthis.tree = this.engine.tree\n\t\tthis.selection = this.engine.stores.selectionStore.ids\n\t\tthis.mouse = this.engine.stores.mouseStore.latest.canvasMousePosition\n\t\tthis.mouseDown = this.engine.stores.mouseStore.latest.canvasMouseDownPosition\n\t\tthis.shiftKey = this.engine.stores.mouseStore.latest.shiftKey\n\t\tthis.cmdKey = this.engine.stores.mouseStore.latest.cmdKey\n\t\tthis.zoom = this.engine.stores.canvasStore.zoom\n\t\tthis.segmentSelection = this.pathEngine.segmentSelection\n\t\tthis.selectionType = this.pathEngine.selectionType\n\t\tthis.segmentHovered = this.pathEngine.segmentHovered\n\t\tthis.segmentHandle = this.pathEngine.segmentHandle\n\t\tthis.closestCurve = this.pathEngine.closestCurve\n\t\tthis.pointRounding = this.pathEngine.pointRounding\n\t\tthis.snapConstraint = this.pathEngine.snapConstraint\n\t\tthis.pathToolClass = this.pathEngine.pathTool.__class\n\t\tthis.previousSnappedMouse = this.snappedMouse\n\n\t\tif (shouldUpdateCache) {\n\t\t\tthis.updateCache()\n\t\t}\n\t}\n\n\tstop() {\n\t\tthis.engine.stores.snapLinesStore.clear()\n\t}\n\n\tupdate() {\n\t\tthis.updateProps()\n\n\t\t// Update State\n\t\tconst newState = update(this, this.possibleConstraints, this.orthogonalLines)\n\t\tif (!newState) return\n\t\tObject.assign(this, newState)\n\n\t\t// Constraint (un)locking\n\t\tconst { snapLinesStore, mouseStore } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMousePosition, shiftKey } = latest\n\t\tconst { snapConstraint } = this.pathEngine\n\t\tconst shiftKeyDown = shiftKey && !previous.shiftKey\n\n\t\tif (shiftKeyDown && canvasMousePosition) {\n\t\t\tconst closest = Constraint.closest(this.possibleConstraints, canvasMousePosition)\n\t\t\tthis.pathEngine.setPathConstraint(closest.constraint)\n\t\t} else if (!shiftKey && snapConstraint) {\n\t\t\tthis.pathEngine.setPathConstraint(null)\n\t\t}\n\n\t\tsnapLinesStore.clear()\n\n\t\tif (this.snapX) {\n\t\t\tsnapLinesStore.x = this.snapX\n\t\t}\n\n\t\tif (this.snapY) {\n\t\t\tsnapLinesStore.y = this.snapY\n\t\t}\n\t}\n}\n\n// Snapping\n\nconst noOrthogonalLines: OrthogonalLines = { x: new Set<number>(), y: new Set<number>() }\n\nfunction orthogonalLineOptions(props: Props, engine: VekterEngine) {\n\tconst { tree, selection } = props\n\tconst nodes = selection.map(id => {\n\t\treturn tree.getNode(id)\n\t}) as PathNode[]\n\tswitch (props.pathToolClass) {\n\t\tcase \"PathSegmentAdditionTool\": {\n\t\t\tconst frame = engine.stores.canvasStore.getCanvasVisibleRect()\n\t\t\treturn pathSegmentSnappingData(tree, engine.stores.scopeStore.active, nodes, [], frame)\n\t\t}\n\t\tdefault:\n\t\t\treturn noOrthogonalLines\n\t}\n}\n\n// State\n\nfunction update(props: Props, possibleConstraints: Line[], orthogonalLines: OrthogonalLines): Partial<State> | null {\n\tswitch (props.pathToolClass) {\n\t\tcase \"PathSegmentAdditionTool\":\n\t\t\treturn segmentAdditionUpdate(props, possibleConstraints, orthogonalLines)\n\t\tcase \"PathSegmentHandleMoveTool\":\n\t\t\treturn segmentHandleMoveUpdate(props, possibleConstraints)\n\t\tdefault:\n\t\t\treturn null\n\t}\n}\n\nfunction segmentAdditionUpdate(props: Props, possibleConstraints: Line[], orthogonalLines: OrthogonalLines): State {\n\tconst { tree, segmentSelection, closestCurve, segmentHovered, snapConstraint, mouse, pointRounding, zoom, cmdKey } =\n\t\tprops\n\tlet snappedMouse = mouse\n\tlet temporaryConstraint: Line | null = null\n\tlet intersectionTangent: Line | null = null\n\tlet snapX: Set<number> | null = null\n\tlet snapY: Set<number> | null = null\n\n\tconst segmentSelector = segmentSelection[0] as PathSegmentSelector | undefined\n\n\tlet hoveredSnap = false\n\n\tif (closestCurve) {\n\t\tconst closestNode = tree.getNode(closestCurve.id) as PathNode\n\t\tif (closestNode) {\n\t\t\tif (cmdKey) {\n\t\t\t\t// Intersect with closest curve\n\t\t\t\tsnappedMouse = tree.convertPointToCanvas(closestNode, closestCurve.projectedPoint)\n\t\t\t\thoveredSnap = true\n\t\t\t} else if (snapConstraint) {\n\t\t\t\tintersectionTangent = Constraint.curveDerivativeTangent(tree, snapConstraint, closestCurve)\n\t\t\t\tif (intersectionTangent) {\n\t\t\t\t\thoveredSnap = true\n\t\t\t\t\tsnappedMouse = intersectionTangent.a\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (segmentHovered) {\n\t\tconst hoveredNode = tree.getNode(segmentHovered.id) as PathNode\n\t\tif (hoveredNode) {\n\t\t\tconst segment = hoveredNode.pathSegments[segmentHovered.index]\n\t\t\tif (segment) {\n\t\t\t\tsnappedMouse = tree.convertPointToCanvas(hoveredNode, segment)\n\t\t\t\thoveredSnap = true\n\t\t\t\tif (snapConstraint) {\n\t\t\t\t\tconst intersection = Line.projectPoint(snapConstraint, snappedMouse)\n\t\t\t\t\tif (intersection) {\n\t\t\t\t\t\tintersectionTangent = Line(snappedMouse, intersection)\n\t\t\t\t\t\tsnappedMouse = intersection\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\ttemporaryConstraint = Constraint.temporary(possibleConstraints, props.mouse, props.zoom)\n\t}\n\n\tconst constraint = snapConstraint || temporaryConstraint\n\n\tif (!hoveredSnap && mouse) {\n\t\tlet excludePoint: Point | undefined\n\t\tif (segmentSelector) {\n\t\t\tconst node = tree.getNode(segmentSelector.id) as PathNode\n\t\t\tif (node) {\n\t\t\t\tconst segment = node.pathSegments[segmentSelector.index]\n\t\t\t\tif (segment) {\n\t\t\t\t\texcludePoint = tree.convertPointToCanvas(node, PathSegment.point(segment))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst snapInfo = snap(orthogonalLines, zoom, mouse, excludePoint, undefined)\n\n\t\tif (constraint) {\n\t\t\tlet snapped = false\n\t\t\tconst { point } = snapInfo\n\n\t\t\tif (point.x !== undefined) {\n\t\t\t\tconst verticalLine = Line({ x: point.x, y: 0 }, { x: point.x, y: 10 })\n\t\t\t\tconst verticalIntersection = Line.intersection(verticalLine, constraint)\n\t\t\t\tif (verticalIntersection) {\n\t\t\t\t\tsnappedMouse = verticalIntersection\n\t\t\t\t\tsnapX = snapInfo.snapLines.x\n\t\t\t\t\tsnapped = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!snapped && point.y !== undefined) {\n\t\t\t\tconst horizontalLine = Line({ y: point.y, x: 0 }, { y: point.y, x: 10 })\n\t\t\t\tconst horizontalIntersection = Line.intersection(horizontalLine, constraint)\n\t\t\t\tif (horizontalIntersection) {\n\t\t\t\t\tsnappedMouse = horizontalIntersection\n\t\t\t\t\tsnapY = snapInfo.snapLines.y\n\t\t\t\t\tsnapped = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!snapped) {\n\t\t\t\tconst intersection = Line.projectPoint(constraint, mouse)\n\t\t\t\tif (intersection) {\n\t\t\t\t\tsnappedMouse = intersection\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (snappedMouse) {\n\t\t\t// No constraints\n\t\t\tconst { point } = snapInfo\n\t\t\tif (point.x !== undefined) {\n\t\t\t\tsnappedMouse.x = point.x\n\t\t\t\tsnapX = snapInfo.snapLines.x\n\t\t\t}\n\t\t\tif (point.y !== undefined) {\n\t\t\t\tsnappedMouse.y = point.y\n\t\t\t\tsnapY = snapInfo.snapLines.y\n\t\t\t}\n\t\t}\n\t}\n\n\tif (snappedMouse) {\n\t\tsnappedMouse = roundedPoint(snappedMouse, pointRounding)\n\t}\n\n\treturn { snappedMouse, temporaryConstraint, intersectionTangent, snapX, snapY }\n}\n\nfunction segmentHandleMoveUpdate(props: Props, possibleConstraints: Line[]): Partial<State> {\n\tconst { mouse, snapConstraint } = props\n\tlet snappedMouse = mouse\n\n\tlet temporaryConstraint: Line | null = null\n\tif (!snapConstraint) {\n\t\ttemporaryConstraint = Constraint.temporary(possibleConstraints, props.mouse, props.zoom)\n\t}\n\n\tconst constraint = snapConstraint || temporaryConstraint\n\n\tif (constraint && mouse) {\n\t\tconst intersection = Line.projectPoint(constraint, mouse)\n\t\tif (intersection) {\n\t\t\tsnappedMouse = intersection\n\t\t}\n\t}\n\n\treturn { snappedMouse, temporaryConstraint, intersectionTangent: null }\n}\n\n// Constraints\n\nexport namespace Constraint {\n\texport function temporary(constraintOptions: Line[], mouse: Point | null, zoom: number) {\n\t\tif (mouse === null) {\n\t\t\treturn null\n\t\t}\n\t\tconst { constraint, distance } = closest(constraintOptions, mouse)\n\t\tconst outOfRange = distance > 4 / zoom\n\t\tif (outOfRange) {\n\t\t\treturn null\n\t\t}\n\t\treturn constraint\n\t}\n\n\texport function closest(constraints: Line[], mouse: Point) {\n\t\tlet shortestDistance = Infinity\n\t\tlet shortestConstraint = constraints[0] as Line | undefined\n\n\t\tfor (let i = 0, il = constraints.length; i < il; i++) {\n\t\t\tconst constraint = constraints[i]\n\t\t\tconst projectedPoint = Line.projectPoint(constraint, mouse)\n\t\t\tif (projectedPoint === null) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst distance = Point.distance(mouse, projectedPoint)\n\t\t\tif (distance >= shortestDistance) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tshortestDistance = distance\n\t\t\tshortestConstraint = constraint\n\t\t}\n\n\t\treturn { constraint: shortestConstraint || null, distance: shortestDistance }\n\t}\n\n\texport function options(props: Props): Line[] {\n\t\tswitch (props.pathToolClass) {\n\t\t\tcase \"PathSegmentAdditionTool\":\n\t\t\t\treturn segmentAdditionOptions(props)\n\t\t\tcase \"PathSegmentHandleMoveTool\":\n\t\t\t\treturn segmentHandleMoveOptions(props)\n\t\t\tdefault:\n\t\t\t\treturn []\n\t\t}\n\t}\n\n\tfunction segmentAdditionOptions(props: Props) {\n\t\tconst { tree, segmentSelection } = props\n\t\tconst segmentSelector = segmentSelection[0]\n\t\tif (!segmentSelector) {\n\t\t\treturn []\n\t\t}\n\t\tconst node = tree.getNode(segmentSelector.id) as PathNode\n\t\treturn segmentOptions(tree, node, segmentSelector)\n\t}\n\n\tfunction segmentHandleMoveOptions(props: Props) {\n\t\tconst { tree, segmentHandle } = props\n\t\tif (!segmentHandle) {\n\t\t\treturn []\n\t\t}\n\t\tconst node = tree.getNode(segmentHandle.id) as PathNode\n\t\treturn segmentOptions(tree, node, segmentHandle)\n\t}\n\n\texport function standard(position: Point) {\n\t\treturn [\n\t\t\tLine(position, { x: position.x, y: position.y + 1 }),\n\t\t\tLine(position, { y: position.y, x: position.x + 1 }),\n\t\t\tLine(position, { y: position.y + 1, x: position.x + 1 }),\n\t\t\tLine(position, { y: position.y + 1, x: position.x - 1 }),\n\t\t]\n\t}\n\n\tfunction segmentOptions(tree: CanvasTree, node: PathNode, segmentSelector: PathSegmentSelector) {\n\t\tconst segment = node.pathSegments[segmentSelector.index]\n\t\tconst canvasSegment = convertSegmentToCanvas(tree, node, segment)\n\n\t\tconst result = standard(tree.convertPointToCanvas(node, segment))\n\n\t\tlet beforeSegment: PathSegment | undefined = node.pathSegments[segmentSelector.index - 1]\n\t\tlet afterSegment: PathSegment | undefined = node.pathSegments[segmentSelector.index + 1]\n\n\t\tif (node.pathClosed && segmentSelector.index === 0) {\n\t\t\tbeforeSegment = node.pathSegments[node.pathSegments.length - 1]\n\t\t}\n\t\tif (node.pathClosed && segmentSelector.index === node.pathSegments.length - 1) {\n\t\t\tafterSegment = node.pathSegments[0]\n\t\t}\n\n\t\tif (beforeSegment) {\n\t\t\tconst canvasBefore = convertSegmentToCanvas(tree, node, beforeSegment)\n\t\t\tconst angle = curveAngle(canvasBefore, canvasSegment, 1)\n\t\t\tif (angle.x !== 0 && angle.y !== 0) {\n\t\t\t\tconst line = Line(canvasSegment, { x: canvasSegment.x + angle.x, y: canvasSegment.y + angle.y })\n\t\t\t\tconst perp = Line.perpendicular(line, canvasSegment)\n\t\t\t\tresult.push(Line(line.a, line.b), Line(line.a, perp.a))\n\t\t\t}\n\t\t}\n\t\tif (afterSegment) {\n\t\t\tconst canvasAfter = convertSegmentToCanvas(tree, node, afterSegment)\n\t\t\tconst angle = curveAngle(canvasSegment, canvasAfter, 0)\n\t\t\tif (angle.x !== 0 && angle.y !== 0) {\n\t\t\t\tconst line = Line(canvasSegment, { x: canvasSegment.x + angle.x, y: canvasSegment.y + angle.y })\n\t\t\t\tconst perp = Line.perpendicular(line, canvasSegment)\n\t\t\t\tresult.push(Line(line.a, line.b), Line(line.a, perp.a))\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n\texport function curveDerivativeTangent(tree: CanvasTree, constraint: Line, closestCurve: ClosestCurve) {\n\t\tconst derivative = curveDerivative(tree, closestCurve)\n\t\tif (!derivative) {\n\t\t\treturn null\n\t\t}\n\t\tconst intersection = Line.intersection(constraint, derivative)\n\t\tif (!intersection) {\n\t\t\treturn null\n\t\t}\n\t\tconst distance = Point.distance(intersection, constraint.a)\n\t\tif (distance > 2000) {\n\t\t\treturn null\n\t\t}\n\t\treturn Line(intersection, derivative.a)\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { convertFrameToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { Rect } from \"library/index.ts\"\nimport { insertCursor } from \"utils/cursor.ts\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { SelectTool } from \"./Select.tsx\"\nimport { getSelectableTopNodeAtPoint } from \"./utils/getSelectableTopNodeAtPoint.ts\"\nimport { isSelectableInRect } from \"./utils/isSelectable.ts\"\n\ntype AgentSelectionCallback = (nodeIds: NodeID[]) => void\n\nexport interface AgentSelectToolOptions {\n\tselectCallback: AgentSelectionCallback\n}\n\nexport class AgentSelectTool extends withClassDiscriminator(\"AgentSelectTool\", VekterTool) {\n\toverride readonly enum: Tools = Tools.AgentSelect\n\toverride readonly wantsAutoscrolling = true\n\toverride displaySelectionBox = true\n\treadonly selectCallback: AgentSelectionCallback\n\n\tconstructor(engine: VekterEngine, options: AgentSelectToolOptions) {\n\t\tsuper(engine, options)\n\t\tthis.selectCallback = options.selectCallback\n\t}\n\n\toverride start() {\n\t\tthis.engine.stores.mouseCursorStore.current = insertCursor\n\t}\n\n\toverride update() {\n\t\t// AGENT @TODO: In the future double check the behavior when direct selection is off.\n\t\tconst { mouseStore } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMousePosition, canvasMouseDownPosition, spacebar, altKey, cmdKey, shiftKey } = latest\n\t\tconst { windowMiddleMouseButtonDownPosition } = mouseStore\n\n\t\tif (spacebar || windowMiddleMouseButtonDownPosition) {\n\t\t\tthis.engine.setTool(Tools.Pan)\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseMoved = mouseDidMove(canvasMousePosition, previous.canvasMousePosition)\n\n\t\t// no mouse change\n\t\tconst isMouseChange =\n\t\t\tmouseMoved ||\n\t\t\tprevious.cmdKey !== cmdKey ||\n\t\t\tprevious.altKey !== altKey ||\n\t\t\tprevious.canvasMouseDownPosition !== canvasMouseDownPosition ||\n\t\t\tprevious.shiftKey !== shiftKey\n\t\tif (!canvasMousePosition || !isMouseChange) return\n\n\t\t// If we mouse down, and we move -> drag select\n\t\tif (canvasMouseDownPosition && mouseMoved) {\n\t\t\tthis.engine.setTool(Tools.AgentDragSelect, {\n\t\t\t\tselectCallback: this.selectCallback,\n\t\t\t\tfromTool: this.enum,\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst node = getSelectableTopNodeAtPoint({\n\t\t\tpoint: canvasMousePosition,\n\t\t\tengine: this.engine,\n\t\t\tdoubleClick: false,\n\t\t\tuseDirectSelect: true,\n\t\t})\n\n\t\tif (node) {\n\t\t\tthis.handleMouseOnSelectableTopNode(node)\n\t\t\treturn\n\t\t}\n\n\t\tthis.handleMouseOnVoid()\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\thandleMouseOnSelectableTopNode = (node: CanvasNode) => {\n\t\tconst { treeStore, mouseStore } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMouseDownPosition } = latest\n\n\t\tconst mouseUp = previous.canvasMouseDownPosition && !canvasMouseDownPosition\n\t\tif (mouseUp) {\n\t\t\tthis.handleSelection([node.id])\n\t\t\treturn\n\t\t}\n\n\t\ttreeStore.setHighlight(node.id)\n\t}\n\n\thandleMouseOnVoid = () => {\n\t\tconst { treeStore, selectionStore, mouseStore } = this.engine.stores\n\t\tconst { latest } = mouseStore\n\t\tconst { canvasMouseDownPosition } = latest\n\n\t\ttreeStore.setHighlight(null)\n\t\tif (canvasMouseDownPosition) {\n\t\t\tselectionStore.clear()\n\t\t}\n\t}\n\n\thandleSelection = (nodeIds: NodeID[]): void => {\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t\tthis.selectCallback(nodeIds)\n\t}\n}\n\nexport interface AgentDragSelectToolOptions extends AgentSelectToolOptions {\n\tfromTool: Tools\n}\nexport class AgentDragSelectTool extends withClassDiscriminator(\"AgentDragSelectTool\", SelectTool) {\n\toverride readonly enum: Tools = Tools.AgentDragSelect\n\toverride cmsBadge: \"visible\" | \"hidden\" | \"disabled\" = \"hidden\"\n\toverride displayViewportHandle = false\n\treadonly selectCallback: AgentSelectionCallback\n\n\tconstructor(engine: VekterEngine, options: AgentDragSelectToolOptions) {\n\t\tsuper(engine, options)\n\t\tthis.selectCallback = options.selectCallback\n\t\tthis.fromTool = options.fromTool\n\t}\n\n\toverride start() {\n\t\tsuper.start()\n\t\tthis.engine.stores.mouseCursorStore.current = insertCursor\n\t}\n\n\toverride stop() {\n\t\tconst { mouseCursorStore, selectionStore } = this.engine.stores\n\t\tconst selectedIds = selectionStore.ids\n\n\t\tif (selectedIds.length > 0) {\n\t\t\tthis.handleSelection(selectedIds)\n\t\t}\n\n\t\tmouseCursorStore.clear()\n\t}\n\n\toverride exitTool() {\n\t\tswitch (this.fromTool) {\n\t\t\tcase Tools.AgentPanel:\n\t\t\t\tthis.engine.setTool(Tools.AgentPanel)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tthis.engine.exitTool()\n\t\t}\n\t}\n\n\toverride filterSelectableNodeIds(nodesInRect: CanvasNode[], dragSelectRect: Rect) {\n\t\tconst set = new Set<NodeID>()\n\t\tconst nodeHasAncestorSelected: Map<NodeID, boolean> = new Map()\n\n\t\tnodesInRect.forEach(node => {\n\t\t\tif (!isSelectableInRect(node, dragSelectRect, this.engine, this.selectableNodeCache, true)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// nodesInRect goes top-down, so we would validate the parent first, then the children.\n\t\t\t// When encountering a node, determine if we should select the node and demote its\n\t\t\t// parent. AGENT @TODO: This probably doesn't work well with non-direct selection.\n\t\t\tconst parent = this.engine.tree.getParent(node.id)\n\t\t\tif (!parent) {\n\t\t\t\tset.add(node.id)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst hasAncestorSelected = Boolean(set.has(parent.id) || nodeHasAncestorSelected.get(parent.id))\n\t\t\tnodeHasAncestorSelected.set(node.id, hasAncestorSelected)\n\n\t\t\tconst parentCanvasRect = convertFrameToCanvas(this.engine.tree, parent)\n\t\t\t// If the parent is contained in the selection rect, we select the parent (unless an\n\t\t\t// ancestor is selected already) and demote all its children.\n\t\t\tif (Rect.containsRect(dragSelectRect, parentCanvasRect)) {\n\t\t\t\tif (!hasAncestorSelected) {\n\t\t\t\t\t// AGENT @TODO: We should check if the parent is selectable as well.\n\t\t\t\t\tset.add(parent.id)\n\t\t\t\t\tdemoteSubtree(parent, set)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Otherwise, we select the node and demote the parent.\n\t\t\tset.add(node.id)\n\t\t\tset.delete(parent.id)\n\t\t\tnodeHasAncestorSelected.set(node.id, false)\n\t\t})\n\n\t\treturn set\n\t}\n\n\thandleSelection = (nodeIds: NodeID[]): void => {\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t\tthis.selectCallback(nodeIds)\n\t}\n}\n\nfunction demoteSubtree(node: CanvasNode, set: Set<NodeID>) {\n\tif (!withChildren(node)) return\n\n\tnode.children.forEach(child => {\n\t\tset.delete(child.id)\n\t\tdemoteSubtree(child, set)\n\t})\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { ContextAction } from \"../utils/contextActions.ts\"\nimport { AgentSelectTool } from \"./AgentSelectTool.ts\"\n\nexport class AgentPanelTool extends withClassDiscriminator(\"AgentPanelTool\", AgentSelectTool) {\n\toverride readonly enum: Tools = Tools.AgentPanel\n\n\tconstructor(engine: VekterEngine) {\n\t\tsuper(engine, {\n\t\t\tselectCallback: nodeIds => handlePanelSelection(engine, nodeIds),\n\t\t})\n\t}\n}\n\nfunction handlePanelSelection(engine: VekterEngine, nodeIds: NodeID[]): void {\n\tengine.stores.selectionStore.clear()\n\tContextAction.addSelectionToAgent(engine.stores, nodeIds)\n}\n", "import \"Multiplayer.styles_ql2hw7.wyw.css\"; export const multiplayer = \"multiplayer_m131gtz1\";\nexport const cursor = \"cursor_c1ri4zde\";\nexport const cursorGraphic = \"cursorGraphic_c1ycq1zn\";\nexport const label = \"label_lv62knu\";\nexport const placeholder = \"placeholder_p1dw9fw\";", "import { assert } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport * as classes from \"../canvas/Multiplayer.styles.ts\"\n\nconst placeholderText = \"Type to chat\u2026\"\n\nexport class ChatTool extends withClassDiscriminator(\"ChatTool\", VekterTool) {\n\toverride readonly enum = Tools.Chat\n\toverride readonly wantsAutoscrolling = true\n\n\tprivate stopping = false\n\tprivate containerElement: HTMLDivElement | null = null\n\n\toverride start() {\n\t\tassert(!this.stopping, \"Cannot restart the chat tool\")\n\t\tconst { remoteUsers, documentSettingsStore } = this.engine.stores\n\t\t// Container that holds all the elements. Mostly exists to match multiplayer cursor styles.\n\t\tconst container = document.createElement(\"div\")\n\t\tcontainer.className = classes.cursor\n\t\tconst currentUserId = documentSettingsStore.currentUserId\n\t\tconst isDarkMode = remoteUsers.isDarkMode\n\t\tconst color = currentUserId && remoteUsers.getCursor(currentUserId)?.getHexColor(isDarkMode)\n\t\tif (color) {\n\t\t\tcontainer.style.setProperty(\"--color\", color)\n\t\t}\n\t\tthis.containerElement = container\n\n\t\t// Wrapper for placeholder and input.\n\t\tconst textWrapper = document.createElement(\"span\")\n\t\ttextWrapper.className = classes.label\n\n\t\t// The actual element that will receive user input. It's a <span> so it can auto-grow.\n\t\tconst input = document.createElement(\"span\")\n\t\tinput.contentEditable = \"true\"\n\t\tinput.style.borderLeft = \"transparent 0.1px solid\" // This ensures the blinking cursor shows up correctly.\n\t\tinput.style.outline = \"0\"\n\n\t\t// Placeholder element that will show previous text etc.\n\t\tconst placeholder = document.createElement(\"span\")\n\t\tplaceholder.className = classes.placeholder\n\t\tplaceholder.innerText = placeholderText\n\n\t\t// Stop chatting if the chat field loses focus.\n\t\tinput.addEventListener(\n\t\t\t\"blur\",\n\t\t\tthis.engine.scheduler.wrapHandler(() => {\n\t\t\t\tif (this.stopping) return\n\t\t\t\tthis.engine.exitTool()\n\t\t\t}),\n\t\t)\n\n\t\t// Respond to Enter / Escape key presses.\n\t\tinput.addEventListener(\n\t\t\t\"keydown\",\n\t\t\tevent => {\n\t\t\t\tswitch (event.key) {\n\t\t\t\t\tcase \"Enter\":\n\t\t\t\t\tcase \"Return\":\n\t\t\t\t\t\tif (input.innerText === \"\") {\n\t\t\t\t\t\t\tinput.blur()\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.engine.remoteDocument?.scheduleChatTextReset()\n\t\t\t\t\t\t\tplaceholder.innerText = input.innerText\n\t\t\t\t\t\t\tplaceholder.style.display = \"\"\n\t\t\t\t\t\t\tinput.innerText = \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"Escape\":\n\t\t\t\t\t\tinput.blur()\n\t\t\t\t\t\tbreak\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tevent.preventDefault()\n\t\t\t\tevent.stopPropagation()\n\t\t\t},\n\t\t\ttrue,\n\t\t)\n\n\t\t// Respond to content changes.\n\t\tinput.addEventListener(\n\t\t\t\"input\",\n\t\t\tthis.engine.scheduler.wrapHandler(event => {\n\t\t\t\tconst value = input.innerText\n\t\t\t\t// Show the placeholder if the user hasn't written anything.\n\t\t\t\tplaceholder.style.display = value ? \"none\" : \"\"\n\t\t\t\t// Send the text to the multiplayer server.\n\t\t\t\tthis.engine.remoteDocument?.setChatText(value)\n\t\t\t\tevent.stopPropagation()\n\t\t\t}),\n\t\t\ttrue,\n\t\t)\n\n\t\ttextWrapper.appendChild(input)\n\t\ttextWrapper.appendChild(placeholder)\n\t\tcontainer.appendChild(textWrapper)\n\t\tdocument.body.appendChild(container)\n\t\tinput.focus()\n\t}\n\n\toverride stop() {\n\t\tthis.stopping = true\n\t\tthis.engine.remoteDocument?.scheduleChatTextReset()\n\t\tif (this.containerElement?.isConnected) {\n\t\t\tdocument.body.removeChild(this.containerElement)\n\t\t}\n\t\tthis.containerElement = null\n\t}\n\n\toverride update() {\n\t\tconst { windowMiddleMouseButtonDownPosition, latest } = this.engine.stores.mouseStore\n\t\tconst { spacebar, windowMousePosition } = latest\n\t\tif (spacebar || windowMiddleMouseButtonDownPosition) {\n\t\t\tthis.engine.setTool(Tools.Pan)\n\t\t\treturn\n\t\t}\n\t\tif (!this.containerElement) return\n\t\tthis.containerElement.style.left = `${windowMousePosition.x}px`\n\t\tthis.containerElement.style.top = `${windowMousePosition.y}px`\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { VariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport type { CollectionControlProp } from \"document/models/controlProps/CollectionControlProp.ts\"\nimport type { CollectionControlType } from \"document/models/controlProps/CollectionControlType.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { getEditableCollectionVariableInfo } from \"../utils/getEditableCollectionVariableInfo.ts\"\n\nexport interface BaseVariableEditToolOptions {\n\tvariableReference: VariableReference\n}\n\nexport class BaseVariableEditTool<ControlType extends CollectionControlType> extends VekterTool {\n\treadonly controlType!: ControlType\n\n\tprotected variableReference: VariableReference\n\tprotected nodeId?: NodeID\n\n\toverride cmsBadge: \"visible\" | \"hidden\" | \"disabled\" = \"disabled\"\n\n\tconstructor(engine: VekterEngine, options?: BaseVariableEditToolOptions) {\n\t\tsuper(engine)\n\n\t\tassert(options, \"Options are required\")\n\t\tthis.variableReference = options.variableReference\n\t\tthis.nodeId = engine.stores.selectionStore.ids[0]\n\t}\n\n\tgetNode(): CanvasNode | null {\n\t\treturn this.engine.tree.getNode(this.nodeId)\n\t}\n\n\tgetVariableInfo() {\n\t\treturn getEditableCollectionVariableInfo(\n\t\t\tthis.engine.tree,\n\t\t\tthis.engine.componentLoader,\n\t\t\tthis.engine.stores.treeStore.sandboxRepeaterData,\n\t\t\tthis.variableReference,\n\t\t\tthis.controlType,\n\t\t\tundefined,\n\t\t)\n\t}\n\n\tgetControlProp() {\n\t\treturn this.getVariableInfo()?.controlProp\n\t}\n\n\tchangeValue(value: CollectionControlProp<ControlType>[\"value\"]) {\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return\n\n\t\tconst { collectionItemNode, controlProp } = variableInfo\n\t\tif (controlProp.value === value) return\n\n\t\tcollectionItemNode.setControlProp(variableInfo.variableId, {\n\t\t\t...controlProp,\n\t\t\tvalue,\n\t\t})\n\t}\n\n\toverride update() {\n\t\tconst engine = this.engine\n\t\tif (engine.tool !== this) return\n\t\tconst {\n\t\t\tmouseStore: { latest, previous },\n\t\t\tselectionStore,\n\t\t} = engine.stores\n\n\t\tconst node = this.getNode()\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (latest.canvasMouseDownPosition && !previous.canvasMouseDownPosition) {\n\t\t\tengine.setTool(Tools.Select)\n\t\t} else if (!variableInfo || !node || selectionStore.ids[0] !== node.id) {\n\t\t\tengine.exitTool()\n\t\t}\n\t}\n}\n", "import type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { type CanvasNodeWithImageFill, hasImageFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport { getEditableNestedVariableReference } from \"utils/collectionReferenceUtils.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { BaseVariableEditTool, type BaseVariableEditToolOptions } from \"./BaseVariableEditTool.ts\"\n\nexport type CollectionReferenceVariableEditToolOptions = BaseVariableEditToolOptions\n\nexport class CollectionReferenceVariableEditTool extends withClassDiscriminator(\n\t\"CollectionReferenceVariableEditTool\",\n\tBaseVariableEditTool as typeof BaseVariableEditTool<ControlType.CollectionReference>,\n) {\n\toverride readonly enum = Tools.CollectionReferenceVariableEdit\n\toverride readonly controlType = ControlType.CollectionReference\n\toverride readonly cmsBadge = \"visible\"\n\n\toverride getNode(): RichTextNode | CanvasNodeWithImageFill | null {\n\t\treturn (\n\t\t\tthis.engine.tree.getNodeWithTrait(this.nodeId, hasImageFill) ||\n\t\t\tthis.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t\t)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tengine.beginUndoGroup()\n\n\t\tconst node = this.getNode()\n\t\tif (!node) return engine.exitTool()\n\n\t\tconst variableReference = getEditableNestedVariableReference(node)\n\t\tif (!variableReference) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\n\t\tengine.scheduler.process(() => {\n\t\t\tengine.endUndoGroup()\n\t\t})\n\t}\n}\n", "import type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { BaseVariableEditTool, type BaseVariableEditToolOptions } from \"./BaseVariableEditTool.ts\"\n\nexport type DateVariableEditToolOptions = BaseVariableEditToolOptions\n\nexport class DateVariableEditTool extends withClassDiscriminator(\n\t\"DateVariableEditTool\",\n\tBaseVariableEditTool as typeof BaseVariableEditTool<ControlType.Date>,\n) {\n\toverride readonly enum = Tools.DateVariableEdit\n\toverride readonly controlType = ControlType.Date\n\n\toverride getNode(): RichTextNode | null {\n\t\treturn this.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tengine.beginUndoGroup()\n\n\t\tconst richTextNode = this.getNode()\n\t\tif (!richTextNode) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\n\t\trichTextNode.cache.isEditable = true\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\n\t\tconst richTextNode = this.getNode()\n\n\t\tif (richTextNode) {\n\t\t\trichTextNode.cache.isEditable = false\n\t\t}\n\n\t\tengine.scheduler.process(() => {\n\t\t\tengine.endUndoGroup()\n\t\t})\n\t}\n}\n", "import type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { BaseVariableEditTool, type BaseVariableEditToolOptions } from \"./BaseVariableEditTool.ts\"\n\nexport type EnumVariableEditToolOptions = BaseVariableEditToolOptions\n\nexport class EnumVariableEditTool extends withClassDiscriminator(\n\t\"EnumVariableEditTool\",\n\tBaseVariableEditTool as typeof BaseVariableEditTool<ControlType.Enum>,\n) {\n\toverride readonly enum = Tools.EnumVariableEdit\n\toverride readonly controlType = ControlType.Enum\n\n\toverride getNode(): RichTextNode | null {\n\t\treturn this.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tengine.beginUndoGroup()\n\n\t\tconst richTextNode = this.getNode()\n\t\tif (!richTextNode) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\n\t\tengine.scheduler.process(() => {\n\t\t\tengine.endUndoGroup()\n\t\t})\n\t}\n}\n", "import { getFallbackPageId } from \"@framerjs/document-migrations\"\nimport { assert, assertNever } from \"@framerjs/shared\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport type { CanvasTree, ScopeNode } from \"../document/models/CanvasTree/index.ts\"\nimport type { Anchor } from \"./types.ts\"\nimport { Quadrant } from \"./types.ts\"\n\n/**\n * Return the page the anchor should be rendered on.\n */\nexport function anchorToScope(tree: CanvasTree, anchor: Anchor) {\n\tconst scopeId = anchor.pageId ?? getFallbackPageId(tree.root)\n\tif (anchor.type === \"canvas\") return scopeId\n\n\tconst node = tree.getNode(anchor.nodeId)\n\tif (node === null) return scopeId\n\n\tconst scopeNode = tree.getScopeNodeFor(node)\n\tif (scopeNode === null) return scopeId\n\n\treturn scopeNode.id\n}\n\n/**\n * Returns a canvas co-ordinate for the anchor provided. If the type is\n * an \"anchor\" node and the node cannot be found in the CanvasTree then\n * will fallback to the default x/y co-ordinate.\n */\nexport function anchorToPoint(tree: CanvasTree, anchor: Anchor): Point {\n\tswitch (anchor.type) {\n\t\tcase \"canvas\":\n\t\t\treturn { x: anchor.x, y: anchor.y }\n\t\tcase \"node\": {\n\t\t\tconst node = tree.getNode(anchor.nodeId)\n\t\t\tif (node) {\n\t\t\t\tconst [nw, ne, se, sw] = Rect.cornerPoints(node.rect())\n\t\t\t\tassert(nw && ne && se && sw, `A node rect must have all corner points defined: ${nw}, ${ne}, ${se}, ${sw}`)\n\t\t\t\tconst insetCorner = anchor.insetCorner as Quadrant\n\n\t\t\t\tconst point = (() => {\n\t\t\t\t\tswitch (insetCorner) {\n\t\t\t\t\t\tcase Quadrant.NW:\n\t\t\t\t\t\t\treturn Point.add(nw, { x: anchor.insetX, y: anchor.insetY })\n\t\t\t\t\t\tcase Quadrant.NE:\n\t\t\t\t\t\t\treturn Point.add(ne, { x: -anchor.insetX, y: anchor.insetY })\n\t\t\t\t\t\tcase Quadrant.SW:\n\t\t\t\t\t\t\treturn Point.add(sw, { x: anchor.insetX, y: -anchor.insetY })\n\t\t\t\t\t\tcase Quadrant.SE:\n\t\t\t\t\t\t\treturn Point.subtract(se, { x: anchor.insetX, y: anchor.insetY })\n\t\t\t\t\t\tcase Quadrant.Center:\n\t\t\t\t\t\t\treturn Rect.center(node.rect())\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn assertNever(insetCorner)\n\t\t\t\t\t}\n\t\t\t\t})()\n\n\t\t\t\t// Apply any transforms that apply to the node to the anchor\n\t\t\t\t// point (such as rotation).\n\t\t\t\treturn Point.pixelAligned(tree.convertPointToCanvas(node, Point.subtract(point, nw)))\n\t\t\t}\n\t\t\treturn { x: anchor.x, y: anchor.y }\n\t\t}\n\t\tdefault:\n\t\t\treturn assertNever(anchor)\n\t}\n}\n\nexport function anchorFromPoint(tree: CanvasTree, activeScope: ScopeNode, position: Point): Anchor {\n\tlet anchor: Anchor = {\n\t\ttype: \"canvas\",\n\t\tpageId: activeScope.id,\n\t\t...position,\n\t}\n\n\tconst nodes = tree.getNodesAtPoint(activeScope, position)\n\tconst groundNode = nodes.find(n => tree.isGroundNode(n))\n\tif (groundNode) {\n\t\tconst rect = groundNode.rect()\n\t\t// Apply any transforms that apply to the node to the anchor\n\t\t// point (such as rotation).\n\t\tconst converted = Point.pixelAligned(Point.add(rect, tree.convertPointToNode(groundNode, position)))\n\t\tanchor = {\n\t\t\ttype: \"node\",\n\t\t\tpageId: activeScope.id,\n\t\t\tx: position.x,\n\t\t\ty: position.y,\n\t\t\tnodeId: groundNode.id,\n\t\t\t...quadrant(rect, converted),\n\t\t}\n\t}\n\n\treturn anchor\n}\n\nfunction quadrant(rect: Rect, point: Point): { insetX: number; insetY: number; insetCorner: Quadrant } {\n\tconst { minX, midX, maxX, minY, midY, maxY } = Rect.positions(rect)\n\n\tif (Point.isEqual(point, Rect.center(rect))) {\n\t\treturn { insetX: 0, insetY: 0, insetCorner: Quadrant.Center }\n\t} else if (point.x <= midX && point.y <= midY) {\n\t\treturn { insetX: point.x - minX, insetY: point.y - minY, insetCorner: Quadrant.NW }\n\t} else if (point.x > midX && point.y <= midY) {\n\t\treturn { insetX: maxX - point.x, insetY: point.y - minY, insetCorner: Quadrant.NE }\n\t} else if (point.x > midX && point.y > midY) {\n\t\treturn { insetX: maxX - point.x, insetY: maxY - point.y, insetCorner: Quadrant.SE }\n\t} else {\n\t\treturn { insetX: point.x - minX, insetY: maxY - point.y, insetCorner: Quadrant.SW }\n\t}\n}\n", "import { v4 as uuid } from \"uuid\"\n/**\n * Deals with filling in the gaps between the model types and the IPC\n * interface restrictions (no enums or union types).\n */\nimport type { Anchor, ApiComment, ApiThread, Comment, Thread } from \"./types.ts\"\n\nconst DraftThreadId = \"__transient-thread__\"\n\nexport function isDraftThread(threadId: string): boolean {\n\treturn threadId === DraftThreadId\n}\n\nexport function localId() {\n\treturn \"local:\" + uuid()\n}\n\n/** Returns true if the id is for a local optimistic update */\nexport function isLocalId(threadId: string): boolean {\n\treturn threadId.startsWith(\"local:\")\n}\n\nexport function createDraftThread(data: Partial<Thread> & { anchor: Anchor }): Thread {\n\treturn {\n\t\tcomments: [],\n\t\tarchived: false,\n\t\tseenUntil: new Date(\"January 19, 2038\"),\n\t\tupdatedAt: undefined,\n\t\t...data,\n\t\tid: DraftThreadId,\n\t}\n}\n\nexport function toServiceThread(thread: Thread): ApiThread {\n\treturn {\n\t\t...thread,\n\t\tcomments: thread.comments.map(toServiceComment),\n\t\tseenUntil: thread.seenUntil?.toISOString() || null,\n\t\tupdatedAt: thread.updatedAt?.toISOString() || null,\n\t}\n}\n\nexport function toServiceComment(comment: Comment): ApiComment {\n\treturn {\n\t\t...comment,\n\t\tdeletedBy: comment.deletedBy || null,\n\t\tcreatedAt: comment.createdAt.toISOString(),\n\t\tupdatedAt: comment.updatedAt?.toISOString() || null,\n\t}\n}\n\nexport function fromServiceThread(thread: ApiThread): Thread {\n\treturn {\n\t\t...thread,\n\t\tcomments: thread.comments.map(fromServiceComment),\n\t\tseenUntil: parseTimestamp(thread.seenUntil),\n\t\tupdatedAt: parseTimestamp(thread.updatedAt),\n\t}\n}\n\nexport function fromServiceComment({ createdAt, updatedAt, deletedBy, ...common }: ApiComment): Comment {\n\tconst createdAtDate = parseTimestamp(createdAt)\n\tif (!createdAtDate) throw new Error(\"Unable to parse createdAt\")\n\treturn {\n\t\tcreatedAt: createdAtDate,\n\t\tdeletedBy: deletedBy || undefined,\n\t\tupdatedAt: parseTimestamp(updatedAt),\n\t\t...common,\n\t}\n}\n\nfunction parseTimestamp(timestamp: unknown): Date | undefined {\n\tif (typeof timestamp !== \"string\") return undefined\n\tconst time = Date.parse(timestamp)\n\treturn Number.isNaN(time) ? undefined : new Date(time)\n}\n", "import { unhandledError } from \"@framerjs/shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { anchorFromPoint, anchorToPoint } from \"feedback/anchorUtils.ts\"\nimport { isDraftThread } from \"feedback/model.ts\"\nimport { Tab } from \"feedback/types.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { commentCursor, feedbackCursor } from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\n\nexport class FeedbackTool extends withClassDiscriminator(\"FeedbackTool\", VekterTool) {\n\toverride readonly enum = Tools.Comment\n\toverride readonly wantsAutoscrolling = true\n\n\t/** The mouse position when mousedown first occured */\n\tmouseDown: Point | undefined\n\n\t/** The Thread ID that was under the mouse when the mouse was clicked  */\n\tdraggingThreadId: string | undefined\n\n\t/**\n\t * The offset between the x,y of the pin and the actual position of the mousedown\n\t * needed in order to keep this visual offset while dragging\n\t * */\n\tdraggingOffset: Point | undefined\n\tisDragging: boolean = false\n\n\toverride start() {\n\t\t// Was platform.isOn(\"supportsFeedback\")\n\t\tif (environment.isAutomation || environment.isTest) return\n\t\tthis.engine.stores.mouseCursorStore.current = experiments.isOn(\"agent\") ? commentCursor : feedbackCursor\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\n\toverride update() {\n\t\tthis.validateThreadIdUnderMouse()\n\n\t\tconst { windowMiddleMouseButtonDownPosition, latest } = this.engine.stores.mouseStore\n\t\tconst { spacebar } = latest\n\t\tif (spacebar || windowMiddleMouseButtonDownPosition) {\n\t\t\tthis.engine.setTool(Tools.Pan)\n\t\t\treturn\n\t\t}\n\t\tif (latest.canvasMouseDownPosition && !this.mouseDown) {\n\t\t\tthis.mouseDown = latest.canvasMouseDownPosition\n\t\t\tthis.onMouseDown()\n\t\t\treturn\n\t\t}\n\t\tif (!latest.canvasMouseDownPosition && this.mouseDown) {\n\t\t\tthis.mouseDown = undefined\n\t\t\tthis.onMouseUp()\n\t\t\treturn\n\t\t}\n\t\tif (latest.canvasMouseDownPosition) {\n\t\t\tthis.onMouseDownMove()\n\t\t\treturn\n\t\t}\n\t}\n\n\t// TODO: Refactor out threadIdUnderMouseCursor, but for the moment\n\t// we need to do some housekeeping in case the thread in question\n\t// is removed from the canvas without this property being updated.\n\t// e.g. performing actions with only the keyboard such as opening\n\t// and closing the comment editor, archiving a thread.\n\tprivate validateThreadIdUnderMouse() {\n\t\tconst { feedbackStore } = this.engine.stores\n\t\tconst { threadIdUnderMouse, selectionState } = feedbackStore\n\n\t\tif (!threadIdUnderMouse) {\n\t\t\treturn\n\t\t}\n\n\t\tconst thread = feedbackStore.getThread(threadIdUnderMouse)\n\t\tif (thread) {\n\t\t\tif (isDraftThread(thread.id) && feedbackStore.draftThread) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst isArchivedTab = selectionState.tab === Tab.Archived\n\t\t\tif (thread.archived === isArchivedTab) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// We're in an invalid state, reset threadIdUnderMouse\n\t\tfeedbackStore.threadIdUnderMouse = undefined\n\t}\n\n\tprivate onMouseDown() {\n\t\tconst { feedbackStore } = this.engine.stores\n\t\tconst draggingThreadId = feedbackStore.threadIdUnderMouse\n\t\tthis.draggingThreadId = draggingThreadId\n\t\tthis.draggingOffset = this.calcDraggingOffset()\n\t}\n\n\tprivate onMouseDownMove() {\n\t\tif (this.isDragging) {\n\t\t\tthis.onDrag()\n\t\t\treturn\n\t\t}\n\t\tconst mouseDown = this.mouseDown\n\t\tif (!mouseDown) return\n\t\tconst { canvasStore, feedbackStore, mouseStore } = this.engine.stores\n\t\tconst { canvasMousePosition } = mouseStore.latest\n\t\tconst distance = Point.distance(canvasMousePosition, mouseDown) * canvasStore.zoom\n\t\tconst threshold = 5\n\t\tif (distance <= threshold) return\n\t\tfeedbackStore.ignoreNextClick = true\n\t\tthis.onDragStart()\n\t}\n\tprivate onMouseUp() {\n\t\tconst { tool } = this.engine\n\t\tconst { feedbackStore, scopeStore, mouseStore } = this.engine.stores\n\t\tif (this.isDragging) {\n\t\t\tthis.onDragEnd()\n\t\t\treturn\n\t\t}\n\n\t\tif (!mouseStore.latest.isMouseOnCanvas || tool.enum !== Tools.Comment) return\n\n\t\tconst isAgentEnabled = experiments.isOn(\"agent\")\n\t\tif (isAgentEnabled && feedbackStore.ignoreNextClick) {\n\t\t\t// Another UI handler (popover close, drag, etc.) already consumed this click.\n\t\t\tfeedbackStore.ignoreNextClick = false\n\t\t\treturn\n\t\t}\n\n\t\tif (\n\t\t\tfeedbackStore.selectedThread &&\n\t\t\tisDraftThread(feedbackStore.selectedThread.id) &&\n\t\t\tfeedbackStore.threadIdUnderMouse !== feedbackStore.selectedThread.id\n\t\t) {\n\t\t\tfeedbackStore.setThreadAnchor(\n\t\t\t\tfeedbackStore.selectedThread.id,\n\t\t\t\tanchorFromPoint(this.engine.tree, scopeStore.active, mouseStore.latest.canvasMousePosition),\n\t\t\t)\n\t\t\treturn\n\t\t}\n\n\t\t// If there's an active thread, clicking outside should dismiss it first, instead of creating a new thread.\n\t\t// When the mouse is over a pin, let handlePinClick handle the thread switch instead.\n\t\tif (isAgentEnabled && feedbackStore.selectedThread) {\n\t\t\tif (!feedbackStore.threadIdUnderMouse) {\n\t\t\t\tfeedbackStore.clearSelectedThread().catch(unhandledError)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (!feedbackStore.threadIdUnderMouse) {\n\t\t\tfeedbackStore.createDraftThread(\n\t\t\t\tanchorFromPoint(this.engine.tree, scopeStore.active, mouseStore.latest.canvasMousePosition),\n\t\t\t)\n\t\t}\n\t}\n\tprivate onDragStart() {\n\t\tthis.isDragging = true\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t}\n\tprivate onDrag() {\n\t\tconst draggingThreadId = this.draggingThreadId\n\t\tconst draggingOffset = this.draggingOffset\n\t\tif (!draggingOffset || !draggingThreadId) return\n\t\tconst { scopeStore, mouseStore, feedbackStore } = this.engine.stores\n\t\tconst position = Point.subtract(mouseStore.latest.canvasMousePosition, draggingOffset)\n\n\t\tfeedbackStore.setThreadAnchor(draggingThreadId, anchorFromPoint(this.engine.tree, scopeStore.active, position))\n\t}\n\tprivate onDragEnd() {\n\t\tconst { feedbackStore, mouseCursorStore } = this.engine.stores\n\t\tconst draggingThreadId = this.draggingThreadId\n\t\tthis.draggingThreadId = undefined\n\t\tthis.mouseDown = undefined\n\t\tthis.draggingOffset = undefined\n\t\tthis.isDragging = false\n\t\tfeedbackStore.ignoreNextClick = false\n\t\tmouseCursorStore.current = feedbackCursor\n\n\t\tif (!draggingThreadId) return\n\t\tfeedbackStore.persistThreadAnchor(draggingThreadId).catch(unhandledError)\n\t}\n\tprivate calcDraggingOffset(): Point | undefined {\n\t\tconst { feedbackStore, mouseStore } = this.engine.stores\n\t\tconst mouseDown = mouseStore.latest.canvasMouseDownPosition\n\t\tif (!mouseDown) return\n\t\tconst draggingThreadId = this.draggingThreadId\n\t\tif (!draggingThreadId) return undefined\n\t\tconst draggingThread = isDraftThread(draggingThreadId)\n\t\t\t? feedbackStore.draftThread\n\t\t\t: feedbackStore.getThread(draggingThreadId)\n\t\tif (!draggingThread) return undefined\n\t\treturn Point.subtract(mouseDown, anchorToPoint(this.engine.tree, draggingThread.anchor))\n\t}\n}\n", "import type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isStackComponent } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withPadding } from \"document/models/CanvasTree/traits/WithPadding.ts\"\n\nexport function getSingleSelectedStackNode(selection: NodeID[], tree: CanvasTree) {\n\tif (selection.length !== 1 || !selection[0]) return null\n\tconst node = tree.getNode(selection[0])\n\treturn isStackComponent(node) && withPadding(node) ? node : null\n}\n", "import { scrollIntoView } from \"utils/scroll-into-view-if-needed/index.ts\"\n\nexport const enum FocusedPropertyInputId {\n\tGap = \"gap-input\",\n\tPadding = \"padding-input\",\n\tPaddingTop = \"paddingTop-input\",\n\tPaddingBottom = \"paddingBottom-input\",\n\tPaddingLeft = \"paddingLeft-input\",\n\tPaddingRight = \"paddingRight-input\",\n}\n\nexport function focusPropertyInput(property: FocusedPropertyInputId) {\n\tconst input = document.getElementById(property)\n\tif (!input) return\n\n\tscrollIntoView(input, {\n\t\tscrollMode: \"if-needed\",\n\t\tblock: \"center\",\n\t})\n\tinput.focus()\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { StackComponentNode } from \"document/models/CanvasTree/nodes/FrameNode.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport {\n\tgetNumericColumnGapFromShorthand,\n\tgetNumericRowGapFromShorthand,\n} from \"document/models/CanvasTree/traits/NumberShorthand.ts\"\nimport { supportGap } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { getLayoutDirectionValue } from \"document/utils/getLayoutDirectionValue.ts\"\nimport { getSingleSelectedStackNode } from \"document/utils/getSingleSelectedStackNode.ts\"\nimport * as Cursor from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { FocusedPropertyInputId, focusPropertyInput } from \"../chrome/properties/panels/utils/focusPropertyInput.ts\"\nimport { getNearestNudgeIncrement } from \"./utils/getNudgeDelta.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\nexport class GapTool extends withClassDiscriminator(\"GapTool\", VekterTool) {\n\toverride readonly enum = Tools.Gap\n\toverride readonly wantsAutoscrolling = true\n\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tcurrentNode!: StackComponentNode | null\n\n\tinitialGap!: number\n\n\tisVertical!: boolean\n\n\thasMoved = false\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = false\n\toverride displayPaddingHandles = false\n\toverride displayGapHandles = true\n\n\toverride start() {\n\t\tthis.engine.beginUndoGroup()\n\t\tthis.currentNode = getSingleSelectedStackNode(this.engine.stores.selectionStore.ids, this.engine.tree)\n\n\t\tif (!this.currentNode || !supportGap(this.currentNode) || isDynamicValue(this.currentNode.gap)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.isVertical = this.currentNode.resolveValue(\"stackDirection\") === \"vertical\"\n\t\tthis.initialGap = this.isVertical\n\t\t\t? getNumericColumnGapFromShorthand(this.currentNode.gap)\n\t\t\t: getNumericRowGapFromShorthand(this.currentNode.gap)\n\t\tthis.updateCursor()\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { latest, previous } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey } = latest\n\n\t\t// Make sure the node being edited still exists, in multi-user scenarios they might get deleted.\n\t\tif (!this.currentNode || !tree.has(this.currentNode?.id)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tif (mouseAction !== \"mouseMove\") {\n\t\t\treturn\n\t\t}\n\n\t\tthis.hasMoved = true\n\n\t\tconst mouseDownPointInNode = this.engine.tree.convertPointToNode(this.currentNode, canvasMouseDownPosition)\n\t\tconst mousePointInNode = this.engine.tree.convertPointToNode(this.currentNode, canvasMousePosition)\n\n\t\tconst mirror = shouldMirrorGapDrag(this.currentNode, this.engine, this.isVertical)\n\n\t\tconst deltaX = mousePointInNode.x - mouseDownPointInNode.x\n\t\tconst deltaY = mousePointInNode.y - mouseDownPointInNode.y\n\t\tlet delta = (this.isVertical ? deltaY : deltaX) * (mirror ? -1 : 1)\n\t\tlet initialGap = this.initialGap\n\n\t\tif (shiftKey) {\n\t\t\tconst { largeNudgeIncrement, smallNudgeIncrement } = this.engine.stores.persistedUserDefaults\n\n\t\t\tdelta = getNearestNudgeIncrement(delta, true, { smallNudgeIncrement, largeNudgeIncrement })\n\n\t\t\tinitialGap = getNearestNudgeIncrement(initialGap, true, { smallNudgeIncrement, largeNudgeIncrement })\n\t\t}\n\n\t\tconst newGap = Math.max(Math.round(initialGap + delta), 0)\n\t\tthis.updateTooltip(newGap)\n\n\t\tthis.engine.tree.current(this.currentNode)?.set({ gap: newGap })\n\t}\n\n\toverride stop() {\n\t\tconst { toolStore, mouseCursorStore } = this.engine.stores\n\t\ttoolStore.tooltip = undefined\n\t\tmouseCursorStore.clear()\n\t\tthis.engine.endUndoGroup()\n\n\t\tif (!this.hasMoved) {\n\t\t\tfocusPropertyInput(FocusedPropertyInputId.Gap)\n\t\t}\n\t}\n\n\tupdateCursor() {\n\t\tconst cursor = this.isVertical ? \"resize-north-south\" : \"resize-east-west\"\n\t\tthis.engine.stores.mouseCursorStore.current = Cursor.cursorImage(cursor)\n\t}\n\n\tupdateTooltip = (value: number | undefined) => {\n\t\tthis.engine.stores.toolStore.tooltip = value?.toString()\n\t}\n}\n\nfunction shouldMirrorGapDrag(currentNode: StackComponentNode, engine: VekterEngine, isVerticalStack: boolean): boolean {\n\tconst activeLocale = engine.tree.root.getLocale(engine.stores.chromeStore.canvasLocaleId)\n\tconst layoutDirection = getLayoutDirectionValue(activeLocale, engine.tree.root.adaptLayoutToTextDirection)\n\tconst stackDistribution = currentNode.resolveValue(\"stackDistribution\")\n\n\tif (layoutDirection === \"ltr\") {\n\t\treturn stackDistribution === \"end\"\n\t}\n\n\treturn isVerticalStack ? stackDistribution === \"end\" : stackDistribution === \"start\"\n}\n", "import {\n\ttriggerRulersCreateGuideEvent,\n\ttriggerRulersDeleteGuideEvent,\n\ttriggerRulersMoveGuideEvent,\n} from \"@framerjs/framer-events\"\nimport { dimensions } from \"@framerjs/fresco/tokens\"\nimport { List, ReadonlySet } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, CanvasTree, MaybeNodeID } from \"document/models/CanvasTree/index.ts\"\nimport { ScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport type { GuideNode, GuideSelector } from \"document/models/CanvasTree/traits/WithGuides.ts\"\nimport {\n\tgetGuideNode,\n\tgetGuides,\n\tgetGuidesKey,\n\tgetOrthogonalAxis,\n\tgetRelativeOffset,\n\tgetValidGuideNodeAtPoint,\n\twithGuides,\n} from \"document/models/CanvasTree/traits/WithGuides.ts\"\nimport { getAbsoluteOffset } from \"document/models/CanvasTree/traits/utils/getAbsoluteOffset.ts\"\nimport { convertFrameToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport type { OrthogonalLines } from \"document/models/Snapping.ts\"\nimport { snap, snappingData } from \"document/models/Snapping.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { removeCursor } from \"utils/cursor.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\n\nconst mouseMoveThreshold = 5\n\nexport class GuideMoveTool extends withClassDiscriminator(\"GuideMoveTool\", VekterTool) {\n\toverride readonly enum = Tools.Guide\n\tstartGuideSelector?: GuideSelector\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tstartMousePos!: Point\n\taxis: GuideSelector[\"axis\"] = \"x\"\n\tresizeCursor: \"ew-resize\" | \"ns-resize\" = \"ew-resize\"\n\tscope: MaybeNodeID\n\tsnappingLines!: OrthogonalLines\n\thasBeenOnCanvas: boolean = false\n\tdidCancel: boolean = false\n\tdidUpdate: boolean = false\n\tmouseDidMove: boolean = false\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tconst { mouseStore, layoutState, guidesStore, scopeStore } = engine.stores\n\t\tconst { canvasMousePosition, canvasMouseDownPosition, windowMouseDownPosition } = mouseStore\n\t\tif (!canvasMousePosition || !canvasMouseDownPosition || !windowMouseDownPosition) return\n\n\t\tconst { tree } = engine\n\t\tif (guidesStore.selected) {\n\t\t\tthis.startGuideSelector = guidesStore.selected\n\t\t\tthis.axis = guidesStore.selected.axis\n\t\t} else if (windowMouseDownPosition.x < layoutState.currentChromeMarginLeft + dimensions.values.rulerWidth) {\n\t\t\tthis.axis = \"x\"\n\t\t} else if (windowMouseDownPosition.y < layoutState.currentChromeMarginTop + dimensions.values.rulerWidth) {\n\t\t\tthis.axis = \"y\"\n\t\t} else {\n\t\t\tengine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.startMousePos = canvasMousePosition\n\t\tconst ghostGuideOffset = this.startGuideSelector\n\t\t\t? this.startGuideSelector.offset\n\t\t\t: Math.round(canvasMousePosition[this.axis])\n\t\tconst activeScope = scopeStore.active\n\t\tconst scopeWithGuides = withGuides(activeScope) ? activeScope : null\n\t\tconst ghostGuideNode = (this.startGuideSelector && getGuideNode(tree, this.startGuideSelector)) ?? scopeWithGuides\n\t\tif (!ghostGuideNode) {\n\t\t\tengine.exitTool()\n\t\t\treturn\n\t\t}\n\t\tguidesStore.clearSelected()\n\t\tguidesStore.highlighted = undefined\n\t\tguidesStore.ghost = { nodeId: ghostGuideNode.id, axis: this.axis, offset: ghostGuideOffset }\n\n\t\tthis.updateSnapLine(tree, ghostGuideNode)\n\t\tengine.beginUndoGroup()\n\t}\n\n\toverride cancel() {\n\t\tthis.didCancel = true\n\t\tthis.engine.discardUndoGroup()\n\t}\n\n\toverride stop() {\n\t\tconst engine = this.engine\n\t\tconst { tree } = engine\n\t\tconst { scopeStore, guidesStore, mouseCursorStore, toolStore, snapLinesStore, mouseStore } = engine.stores\n\t\tconst { canvasMousePosition } = mouseStore\n\t\tconst activeScope = scopeStore.active\n\n\t\tif (getIsViewOnly(engine, \"canDesign\") || !withGuides(activeScope)) {\n\t\t\t// nothing\n\t\t} else if (this.didCancel) {\n\t\t\tif (this.startGuideSelector) {\n\t\t\t\tconst startGuideNode = getGuideNode(tree, this.startGuideSelector)\n\t\t\t\tif (startGuideNode) {\n\t\t\t\t\tconst { axis, offset } = this.startGuideSelector\n\t\t\t\t\tthis.addGuide(startGuideNode, axis, offset)\n\t\t\t\t}\n\t\t\t}\n\t\t\t// clicked on rulers, create a new guide at mouse position\n\t\t} else if (!this.startGuideSelector && !this.mouseDidMove) {\n\t\t\tconst guideNode = activeScope\n\t\t\tconst axis = getOrthogonalAxis(this.axis)\n\t\t\tconst offset = Math.round(canvasMousePosition[axis])\n\t\t\tif (this.isGuideOnCanvas(axis, offset)) {\n\t\t\t\tthis.addGuide(guideNode, axis, offset)\n\t\t\t\tguidesStore.selected = { nodeId: guideNode.id, axis, offset }\n\t\t\t\ttriggerRulersCreateGuideEvent({\n\t\t\t\t\tguideSelector: `${guideNode.id}-${axis}-${offset}`,\n\t\t\t\t\tmethod: \"click\",\n\t\t\t\t})\n\t\t\t}\n\t\t\t// clicked on a guide, selecte it\n\t\t} else if (this.startGuideSelector && !this.didUpdate) {\n\t\t\tguidesStore.selected = this.startGuideSelector\n\t\t\t// updated an exsiting guide\n\t\t} else if (guidesStore.ghost) {\n\t\t\tconst { axis, offset } = guidesStore.ghost\n\t\t\tconst ghostGuideNode = getGuideNode(engine.tree, guidesStore.ghost)\n\t\t\tif (ghostGuideNode) {\n\t\t\t\tconst absoluteOffset = getAbsoluteOffset(engine.tree, ghostGuideNode, axis, offset)\n\t\t\t\tif (this.isGuideOnCanvas(axis, absoluteOffset)) {\n\t\t\t\t\tthis.addGuide(ghostGuideNode, axis, offset)\n\t\t\t\t\tguidesStore.selected = guidesStore.ghost\n\t\t\t\t\tif (this.startGuideSelector) {\n\t\t\t\t\t\ttriggerRulersMoveGuideEvent({\n\t\t\t\t\t\t\tguideSelector: `${ghostGuideNode.id}-${axis}-${offset}`,\n\t\t\t\t\t\t\tmethod: \"mouse\",\n\t\t\t\t\t\t})\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttriggerRulersCreateGuideEvent({\n\t\t\t\t\t\t\tguideSelector: `${ghostGuideNode.id}-${axis}-${offset}`,\n\t\t\t\t\t\t\tmethod: \"drag\",\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// dragging the ghostGuide out of the canvas\n\t\t\t\t\t// \"removing the guide\" = not adding back the deleted guide (already deleted it on update)\n\t\t\t\t\ttriggerRulersDeleteGuideEvent({\n\t\t\t\t\t\tguideSelector: `${ghostGuideNode.id}-${axis}-${offset}`,\n\t\t\t\t\t\tmethod: \"drag_out\",\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tmouseCursorStore.clear()\n\t\ttoolStore.tooltip = undefined\n\t\tguidesStore.ghost = undefined\n\t\tsnapLinesStore.clear()\n\t\tengine.endUndoGroup()\n\t}\n\n\toverride update() {\n\t\tconst engine = this.engine\n\t\tconst { treeStore, guidesStore, mouseStore, scopeStore, toolStore, mouseCursorStore, canvasStore } = engine.stores\n\t\tconst { canvasMousePosition, canvasMouseDownPosition } = mouseStore\n\t\tconst { active: activeScope } = scopeStore\n\t\tif (!withGuides(activeScope)) {\n\t\t\treturn engine.exitTool()\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition || !guidesStore.ghost) {\n\t\t\treturn engine.exitTool()\n\t\t}\n\n\t\tif (Point.distance(this.startMousePos, canvasMousePosition) * canvasStore.zoom > mouseMoveThreshold) {\n\t\t\tthis.mouseDidMove = true\n\t\t\tthis.resizeCursor = this.axis === \"x\" ? \"ew-resize\" : \"ns-resize\"\n\t\t\tmouseCursorStore.current = this.resizeCursor\n\t\t}\n\n\t\tthis.handleCopy()\n\t\tthis.didUpdate = true\n\n\t\tlet offset = Math.round(canvasMousePosition[this.axis])\n\n\t\tconst guideNode = getValidGuideNodeAtPoint(treeStore.tree, activeScope, canvasMousePosition) ?? activeScope\n\n\t\tif (!this.isGuideOnCanvas(this.axis, offset)) {\n\t\t\t// don't show delete cursor until the guide has been dragged into the canvas\n\t\t\tif (this.hasBeenOnCanvas) {\n\t\t\t\tmouseCursorStore.current = removeCursor\n\t\t\t}\n\n\t\t\ttoolStore.tooltip = undefined\n\t\t} else {\n\t\t\tthis.hasBeenOnCanvas = true\n\n\t\t\tif (guideNode.id !== this.scope) {\n\t\t\t\tthis.updateSnapLine(treeStore.tree, guideNode)\n\t\t\t}\n\n\t\t\tconst snapPosition = this.getSnapPosition(canvasMousePosition)\n\t\t\toffset = isNumber(snapPosition) ? snapPosition : offset\n\n\t\t\tconst relativeOffset = getRelativeOffset(treeStore.tree, guideNode, this.axis, offset)\n\t\t\ttoolStore.tooltip = String(relativeOffset)\n\t\t}\n\n\t\tconst relativeOffset = getRelativeOffset(treeStore.tree, guideNode, this.axis, offset)\n\t\tguidesStore.ghost = { nodeId: guideNode.id, axis: this.axis, offset: relativeOffset }\n\t}\n\n\t// Helpers\n\n\tisGuideOnCanvas = (axis: GuideSelector[\"axis\"], offset: number) => {\n\t\tconst { canvasStore } = this.engine.stores\n\t\tconst visibleRect = canvasStore.getCanvasVisibleRect()\n\t\tconst { zoom } = canvasStore\n\t\tconst canvasLength = axis === \"x\" ? visibleRect.width : visibleRect.height\n\n\t\treturn offset > visibleRect[axis] + dimensions.values.rulerWidth / zoom && offset < visibleRect[axis] + canvasLength\n\t}\n\n\tupdateSnapLine = (tree: CanvasTree, guideNode: GuideNode) => {\n\t\tconst nodes = guideNode instanceof ScopeNode ? guideNode.getGroundNodes() : tree.getSubtreeNodes(guideNode.id)\n\t\tthis.snappingLines = this.getOrthogonalLines(nodes)\n\t\tthis.scope = guideNode.id\n\t}\n\n\tgetOrthogonalLines = (nodes: CanvasNode[]) => {\n\t\tconst { treeStore, canvasStore } = this.engine.stores\n\t\tconst visibleNodes = nodes.filter(node => node.isVisible())\n\t\tconst visibleCanvasRect = canvasStore.getCanvasVisibleRect()\n\t\tconst boundingBoxes = visibleNodes\n\t\t\t.map(node => convertFrameToCanvas(treeStore.tree, node))\n\t\t\t.filter(nodeRect => Rect.intersects(nodeRect, visibleCanvasRect))\n\n\t\treturn snappingData(boundingBoxes, canvasStore.zoom)\n\t}\n\n\tgetSnapPosition = (mouse: Point) => {\n\t\tconst engine = this.engine\n\n\t\tconst { canvasStore, snapLinesStore } = engine.stores\n\t\tconst { zoom } = canvasStore\n\t\tconst snapResult = snap(this.snappingLines, zoom, mouse)\n\n\t\tsnapLinesStore.clear()\n\n\t\tif (this.axis === \"x\") {\n\t\t\tsnapLinesStore.x = snapResult.snapLines.x\n\t\t} else {\n\t\t\tsnapLinesStore.y = snapResult.snapLines.y\n\t\t}\n\n\t\tconst snapPosition = snapResult.point[this.axis]\n\t\treturn isNumber(snapPosition) ? snapPosition : null\n\t}\n\n\thandleCopy = () => {\n\t\tif (!this.startGuideSelector) return\n\n\t\tconst startGuideNode = getGuideNode(this.engine.tree, this.startGuideSelector)\n\t\tif (!startGuideNode) return\n\n\t\tthis.engine.stores.mouseStore.latest.altKey\n\t\t\t? this.createCopy(this.startGuideSelector, startGuideNode)\n\t\t\t: this.deleteCopy(this.startGuideSelector, startGuideNode)\n\t}\n\n\tcreateCopy = (startGuideSelector: GuideSelector, startGuideNode: GuideNode) => {\n\t\tif (containGuide(startGuideNode, startGuideSelector)) return\n\n\t\tconst guides = getGuides(startGuideNode, startGuideSelector.axis)\n\t\tconst nextGuides = List.push(guides, startGuideSelector.offset)\n\n\t\tstartGuideNode.set({\n\t\t\t[getGuidesKey(startGuideSelector.axis)]: List.unique(nextGuides),\n\t\t})\n\t}\n\n\tdeleteCopy = (startGuideSelector: GuideSelector, startGuideNode: GuideNode) => {\n\t\tif (!containGuide(startGuideNode, startGuideSelector)) return\n\n\t\tconst guides = getGuides(startGuideNode, startGuideSelector.axis)\n\t\tconst nextGuides = [...ReadonlySet.remove(new Set(guides), startGuideSelector.offset)]\n\n\t\tstartGuideNode.set({\n\t\t\t[getGuidesKey(startGuideSelector.axis)]: nextGuides,\n\t\t})\n\t}\n\n\taddGuide = (node: GuideNode, axis: GuideSelector[\"axis\"], offset: GuideSelector[\"offset\"]) => {\n\t\tconst guides = getGuides(node, axis)\n\t\tconst guidesKey = getGuidesKey(axis)\n\t\tconst nextGuides = List.push(guides, offset)\n\n\t\tnode.set({ [guidesKey]: List.unique(nextGuides) })\n\t}\n}\n\nfunction containGuide(node: GuideNode, selector: GuideSelector) {\n\tconst scopeNodeSelected = !selector.nodeId && node instanceof ScopeNode\n\tif (selector.nodeId !== node.id && !scopeNodeSelected) return false\n\tconst guides = selector.axis === \"y\" ? node.guidesY : node.guidesX\n\n\treturn guides.includes(selector.offset)\n}\n", "import type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { isMaster, isReplica } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isCodeComponentNode } from \"../../nodes/utils/nodeCheck.ts\"\nimport { isBreakpointVariant, isVariant } from \"../WithVariant.ts\"\n\nexport function isUserComponent(node: CanvasNode) {\n\tconst isMasterOrReplica = isMaster(node) || isReplica(node)\n\tif (isMasterOrReplica) {\n\t\tif (!isVariant(node)) return true\n\t\treturn !isBreakpointVariant(node)\n\t}\n\treturn isUserComponentInstance(node)\n}\n\nexport function isUserComponentInstance(node: CanvasNode) {\n\treturn isCodeComponentNode(node) && !node.isBuiltInComponent() && !node.isVectorInstance\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { isUserComponent } from \"document/models/CanvasTree/traits/utils/isUserComponent.ts\"\n\nexport function getTintColor(fromNode: CanvasNode) {\n\tlet tint = colors.tint\n\n\tif (isUserComponent(fromNode)) {\n\t\ttint = colors.componentTint\n\t}\n\n\treturn tint\n}\n\nexport function getBackgroundTintColor(fromNode: CanvasNode) {\n\tlet tint = colors.selectionBoxBackground\n\n\tif (isUserComponent(fromNode)) {\n\t\ttint = colors.selectionBoxComponentBackground\n\t}\n\n\treturn tint\n}\n", "import { colors } from \"@framerjs/fresco/tokens\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { getCornerPointsOnCanvasWithZoom } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { Overlay } from \"../canvas-hud/Overlay.tsx\"\nimport type { ToolPropsWithManagerProps } from \"./props.ts\"\nimport { getTintColor } from \"./utils/getTintColor.ts\"\n\nexport interface HighlightStackItemToolOptions {\n\tnode?: NodeID\n}\n\nexport class HighlightStackItemTool extends withClassDiscriminator(\"HighlightStackItemTool\", VekterTool) {\n\toverride readonly enum = Tools.HighlightStackItem\n\n\t// Lifecycle\n\toverride displaySelectionBox = false\n\toverride displaySelectionHandles = false\n\n\tconstructor(\n\t\tengine: VekterEngine,\n\t\treadonly options?: HighlightStackItemToolOptions,\n\t) {\n\t\tsuper(engine)\n\t}\n\n\toverride start() {\n\t\tthis.engine.stores.treeStore.setHighlight(null)\n\t}\n}\n\nexport function HighlightStackItem({ myTool, zoom }: ToolPropsWithManagerProps<HighlightStackItemTool>) {\n\tconst { tree } = myTool.engine\n\tconst nodeId = myTool.options?.node\n\tconst singleSelectedNode = tree.get(nodeId)\n\tif (!singleSelectedNode) return null\n\n\tconst tint = getTintColor(singleSelectedNode)\n\n\treturn (\n\t\t<Overlay\n\t\t\tpoints={getCornerPointsOnCanvasWithZoom(tree, singleSelectedNode, zoom)}\n\t\t\tbackgroundColor={colors.highlightsBackground}\n\t\t\tborderWidth={1}\n\t\t\tborderColor={tint}\n\t\t/>\n\t)\n}\n", "import { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { PathNode } from \"document/models/CanvasTree/nodes/shapes/PathNode.ts\"\nimport { isPathNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { pathSegmentSnap, pathSegmentSnappingData } from \"document/models/PathSegmentSnapping.ts\"\nimport type { OrthogonalLines } from \"document/models/Snapping.ts\"\nimport { PointRounding } from \"document/stores/PathSelectionStore.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport type { Line } from \"library/render/types/Line.ts\"\nimport type { PathSegment } from \"library/render/types/PathSegment.ts\"\nimport type { Rect } from \"library/render/types/Rect.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { Constraint } from \"./pathEdit/utils/PathSnapper.ts\"\nimport { roundedPoint } from \"./pathEdit/utils/index.ts\"\n\nexport class LineAnchorMoveTool extends withClassDiscriminator(\"LineAnchorMoveTool\", VekterTool) {\n\toverride readonly enum = Tools.LineAnchorMove\n\n\tlastVisibleFrame: Rect | null = null\n\tsnapConstraint: Line | null = null\n\t// FIXME: ! is unsafe; it is assigned in `.update()`, but not in the constructor,\n\t// so there\u2019s a period of time where this field is undefined\n\tsnappingCache!: OrthogonalLines\n\n\toverride displaySelectionBox = true\n\n\toverride start() {\n\t\tthis.engine.beginUndoGroup()\n\t}\n\n\toverride stop() {\n\t\tthis.engine.endUndoGroup()\n\t\tthis.engine.stores.snapLinesStore.clear()\n\t}\n\n\toverride update() {\n\t\tconst { snapLinesStore, toolStore, selectionStore, mouseStore, canvasStore } = this.engine.stores\n\t\tconst { canvasMouseDownPosition, canvasMousePosition, shiftKey } = mouseStore\n\n\t\tif (!canvasMouseDownPosition) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\t\tconst [node] = selectionStore.nodes\n\t\tif (!isPathNode(node)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst anchorIndex = toolStore.straightLineAnchorIndex\n\n\t\tconst snapMouse = { ...canvasMousePosition }\n\n\t\tthis.updateSnappingCache(this.engine.tree, node, anchorIndex)\n\t\tconst snapOptions = this.snapOptions(node, anchorIndex)\n\t\tif (!shiftKey) {\n\t\t\tthis.snapConstraint = Constraint.temporary(snapOptions, canvasMousePosition, canvasStore.zoom)\n\t\t} else if (shiftKey && !this.snapConstraint) {\n\t\t\tthis.snapConstraint = Constraint.closest(snapOptions, canvasMousePosition).constraint\n\t\t}\n\n\t\tconst [snappedPoint, snapLines] = pathSegmentSnap(\n\t\t\tthis.snappingCache,\n\t\t\tthis.engine.tree,\n\t\t\tcanvasStore.zoom,\n\t\t\t[node],\n\t\t\t[{ id: node.id, index: anchorIndex }],\n\t\t\tcanvasMousePosition,\n\t\t\tthis.snapConstraint,\n\t\t)\n\n\t\tsnapLinesStore.x = snapLines.x\n\t\tsnapLinesStore.y = snapLines.y\n\n\t\tif (isNumber(snappedPoint.x)) {\n\t\t\tsnapMouse.x = snappedPoint.x\n\t\t}\n\t\tif (isNumber(snappedPoint.y)) {\n\t\t\tsnapMouse.y = snappedPoint.y\n\t\t}\n\n\t\tconst roundedMouse = roundedPoint(snapMouse, PointRounding.Half)\n\t\tconst localPoint = this.engine.tree.convertPointToNode(node, roundedMouse)\n\n\t\tconst pathSegments = node.pathSegments.map((segment: PathSegment, index: number) => {\n\t\t\tif (index !== anchorIndex) return segment\n\t\t\treturn segment.merge(localPoint)\n\t\t})\n\n\t\tthis.engine.tree.current(node)?.set(node.updateForPath({ pathSegments }))\n\t}\n\n\tprivate updateSnappingCache(tree: CanvasTree, pathNode: PathNode, anchorIndex: 0 | 1) {\n\t\tconst visibleFrame = this.engine.stores.canvasStore.getCanvasVisibleRect()\n\t\tconst frameDidChange = !isEqual(this.lastVisibleFrame, visibleFrame)\n\t\tconst noSnappingCache = !this.snappingCache\n\n\t\tif (frameDidChange || noSnappingCache) {\n\t\t\tthis.snappingCache = pathSegmentSnappingData(\n\t\t\t\ttree,\n\t\t\t\tthis.engine.stores.scopeStore.active,\n\t\t\t\t[pathNode],\n\t\t\t\t[{ id: pathNode.id, index: anchorIndex }],\n\t\t\t\tvisibleFrame,\n\t\t\t)\n\t\t\tthis.lastVisibleFrame = visibleFrame\n\t\t}\n\t}\n\n\tprivate snapOptions(node: PathNode, anchorIndex: 1 | 0): Line[] {\n\t\tconst oppositeAnchor = node.pathSegments[anchorIndex === 0 ? 1 : 0]\n\t\tif (!oppositeAnchor) return []\n\t\tconst oppositeCanvasPoint = this.engine.tree.convertPointToCanvas(node, oppositeAnchor)\n\t\treturn Constraint.standard(oppositeCanvasPoint)\n\t}\n}\n", "import { VekterTool } from \"document/VekterTool.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\n\n// This is a noop tool to block all other tools when the app is loading an older document in history mode.\nexport class LoadingShieldTool extends withClassDiscriminator(\"LoadingShieldTool\", VekterTool) {\n\toverride readonly enum = Tools.LoadingShield\n\n\toverride update() {\n\t\tconst { engine } = this\n\t\tif (!engine.stores.historyStore.isLoadingDocument) {\n\t\t\tengine.exitTool()\n\t\t}\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport type { StackComponentNode } from \"document/models/CanvasTree/nodes/FrameNode.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport type { WithPadding } from \"document/models/CanvasTree/traits/WithPadding.ts\"\nimport { convertFramePointsToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport type { FramePoint, FramePoints } from \"document/models/FramePoint.ts\"\nimport { Matrix } from \"document/models/Matrix.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { paddingFromNode } from \"document/utils/StackComponent/paddingFromNode.ts\"\nimport { getSingleSelectedStackNode } from \"document/utils/getSingleSelectedStackNode.ts\"\nimport * as Cursor from \"utils/cursor.ts\"\nimport { isNull } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { FocusedPropertyInputId, focusPropertyInput } from \"../chrome/properties/panels/utils/focusPropertyInput.ts\"\nimport { getNearestNudgeIncrement } from \"./utils/getNudgeDelta.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\nexport interface PaddingSize {\n\ttop: number\n\tbottom: number\n\tleft: number\n\tright: number\n}\n\nexport class PaddingTool extends withClassDiscriminator(\"PaddingTool\", VekterTool) {\n\toverride readonly enum = Tools.Padding\n\toverride readonly wantsAutoscrolling = true\n\n\t// FIXME: !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\thandle!: FramePoint\n\tcurrentNode!: StackComponentNode | null\n\tcanvasPointToNodeMatrix!: DOMMatrixReadOnly\n\tinitialPadding!: PaddingSize\n\n\thasMoved = false\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = false\n\toverride displayGapHandles = false\n\toverride displayPaddingHandles = true\n\t// Lifecycle\n\n\toverride start() {\n\t\tassert(!isNull(this.engine.handle), \"PaddingTool cannot be started if handle is null\")\n\t\tthis.handle = this.engine.handle\n\t\tthis.engine.beginUndoGroup()\n\t\tthis.currentNode = getSingleSelectedStackNode(this.engine.stores.selectionStore.ids, this.engine.tree)\n\n\t\tif (!this.currentNode || isDynamicValue(this.currentNode.padding)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.initialPadding = paddingFromNode(this.currentNode)\n\t\tthis.canvasPointToNodeMatrix = this.currentNode.canvasMatrix().inverse()\n\t\tthis.updateCursor()\n\t}\n\n\toverride stop() {\n\t\tconst { toolStore, mouseCursorStore } = this.engine.stores\n\t\ttoolStore.tooltip = undefined\n\t\tmouseCursorStore.clear()\n\t\tthis.engine.endUndoGroup()\n\n\t\t// If the user didn't drag the padding handle, then we want to focus the\n\t\t// padding input in the property panel.\n\t\tif (!this.hasMoved) {\n\t\t\tconst currentNode = this.engine.tree.current(this.currentNode)\n\t\t\tif (!currentNode) return\n\n\t\t\tconst id = getFocusedPropertyIdForPaddingHandle(this.handle, currentNode)\n\t\t\tif (id) focusPropertyInput(id)\n\t\t}\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { latest, previous } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, altKey, shiftKey, canvasMousePosition } = latest\n\n\t\t// Make sure the node being edited still exists, in multi-user scenarios they might get deleted.\n\t\tif (!this.currentNode || !tree.has(this.currentNode?.id)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tif (mouseAction !== \"mouseMove\") {\n\t\t\treturn\n\t\t}\n\n\t\tthis.updateCursor()\n\n\t\tthis.hasMoved = true\n\t\tthis.displaySelectionHandles = false\n\n\t\tconst mouseDownPointInNode = Matrix.convertPoint(this.canvasPointToNodeMatrix, canvasMouseDownPosition)\n\t\tconst mousePointInNode = Matrix.convertPoint(this.canvasPointToNodeMatrix, canvasMousePosition)\n\t\tconst deltaX = mousePointInNode.x - mouseDownPointInNode.x\n\t\tconst deltaY = mousePointInNode.y - mouseDownPointInNode.y\n\n\t\tconst { initialPadding } = this\n\t\tconst initialMirror =\n\t\t\tthis.handle.fx === 0.5\n\t\t\t\t? initialPadding.top === initialPadding.bottom\n\t\t\t\t: initialPadding.left === initialPadding.right\n\t\tconst mirror = shiftKey || altKey ? !initialMirror : initialMirror\n\n\t\tconst nodeUpdate: Partial<WithPadding> = {\n\t\t\tpaddingPerSide: true,\n\t\t\tpaddingTop: this.initialPadding.top,\n\t\t\tpaddingLeft: this.initialPadding.left,\n\t\t\tpaddingRight: this.initialPadding.right,\n\t\t\tpaddingBottom: this.initialPadding.bottom,\n\t\t}\n\n\t\tconst maxMultiplier = 2\n\t\tconst minMultiplier = mirror ? 2 / 3 : maxMultiplier\n\t\tlet multiplier = this.handle.fy === 1 || this.handle.fx === 1 ? minMultiplier : maxMultiplier\n\t\tlet startPadding = getInitialPaddingForHandle(this.handle, mirror, initialPadding)\n\t\tlet delta = this.handle.fx === 0.5 ? deltaY : deltaX\n\n\t\tif (shiftKey) {\n\t\t\t// If shift key is down, then we want to increment the value by the nudge\n\t\t\t// increment from the user settings.\n\t\t\tconst { largeNudgeIncrement, smallNudgeIncrement } = this.engine.stores.persistedUserDefaults\n\n\t\t\t// Round the actual delta to the nearest multiplier of the nudge increment\n\t\t\t// So if the delta is 16 and the nudge increment is 10, then the delta will\n\t\t\t// now be 20.\n\t\t\tdelta = getNearestNudgeIncrement(delta, true, { largeNudgeIncrement, smallNudgeIncrement })\n\n\t\t\t// We also need to perform the same rounding logic for the inital padding value\n\t\t\t// so that we end up with a nice round number when nudging.\n\t\t\tstartPadding = getNearestNudgeIncrement(startPadding, true, { largeNudgeIncrement, smallNudgeIncrement })\n\n\t\t\t// we don't want to multiply the nudge value if shift is down\n\t\t\tmultiplier = 1\n\t\t}\n\n\t\tconst newPadding = Math.max(Math.round(startPadding + delta * multiplier), 0)\n\t\tthis.updateTooltip(newPadding)\n\n\t\tconst shouldUpdateTop = shiftKey || this.handle.fy === 0 || (mirror && this.handle.fy === 1)\n\t\tconst shouldUpdateBottom = shiftKey || this.handle.fy === 1 || (mirror && this.handle.fy === 0)\n\t\tconst shouldUpdateLeft = shiftKey || this.handle.fx === 0 || (mirror && this.handle.fx === 1)\n\t\tconst shouldUpdateRight = shiftKey || this.handle.fx === 1 || (mirror && this.handle.fx === 0)\n\n\t\tif (shouldUpdateTop) {\n\t\t\tnodeUpdate.paddingTop = newPadding\n\t\t}\n\t\tif (shouldUpdateBottom) {\n\t\t\tnodeUpdate.paddingBottom = newPadding\n\t\t}\n\t\tif (shouldUpdateLeft) {\n\t\t\tnodeUpdate.paddingLeft = newPadding\n\t\t}\n\t\tif (shouldUpdateRight) {\n\t\t\tnodeUpdate.paddingRight = newPadding\n\t\t}\n\n\t\tthis.engine.tree.current(this.currentNode)?.set(nodeUpdate)\n\t}\n\n\tupdateTooltip = (value: number | undefined) => {\n\t\tthis.engine.stores.toolStore.tooltip = value?.toString()\n\t}\n\n\t// Helpers\n\n\tupdateCursor() {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, mouseCursorStore } = this.engine.stores\n\t\tconst singleSelection = selectionStore.ids.length === 1\n\t\tlet framePoints: FramePoints | null = null\n\t\tif (singleSelection) {\n\t\t\tconst node = tree.getNode<CanvasNode>(selectionStore.ids[0])\n\t\t\tif (!node) return\n\n\t\t\tframePoints = convertFramePointsToCanvas(tree, node)\n\t\t}\n\t\tif (framePoints) {\n\t\t\tmouseCursorStore.current = Cursor.resizing(this.handle, framePoints, null)\n\t\t}\n\t}\n}\n\nfunction getInitialPaddingForHandle(handle: FramePoint, mirror: boolean, initialPadding: PaddingSize): number {\n\tif (mirror) {\n\t\tif (handle.fy === 0 || handle.fy === 1) {\n\t\t\treturn (initialPadding.top + initialPadding.bottom) / 2\n\t\t} else {\n\t\t\treturn (initialPadding.left + initialPadding.right) / 2\n\t\t}\n\t}\n\tif (handle.fy === 0) {\n\t\treturn initialPadding.top\n\t} else if (handle.fy === 1) {\n\t\treturn initialPadding.bottom\n\t} else if (handle.fx === 0) {\n\t\treturn initialPadding.left\n\t} else if (handle.fx === 1) {\n\t\treturn initialPadding.right\n\t} else {\n\t\treturn 0\n\t}\n}\n\nfunction getFocusedPropertyIdForPaddingHandle(\n\thandle: FramePoint,\n\tnode: CanvasNode & WithPadding,\n): FocusedPropertyInputId | undefined {\n\t// If the padding is not per side, then we want to focus the main padding\n\t// input even if the user has clicked on a 'per side' handle.\n\tif (!node.paddingPerSide) return FocusedPropertyInputId.Padding\n\n\tif (handle.fy === 0) {\n\t\treturn FocusedPropertyInputId.PaddingTop\n\t} else if (handle.fy === 1) {\n\t\treturn FocusedPropertyInputId.PaddingBottom\n\t} else if (handle.fx === 0) {\n\t\treturn FocusedPropertyInputId.PaddingLeft\n\t} else if (handle.fx === 1) {\n\t\treturn FocusedPropertyInputId.PaddingRight\n\t}\n}\n", "import { Plugin, PluginKey } from \"prosemirror-state\"\nimport type { EditorView } from \"prosemirror-view\"\nimport { Decoration, DecorationSet } from \"prosemirror-view\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\nimport { getFontStyleProperties } from \"../../text/index.ts\"\n\nconst fontPreviewPluginKey = new PluginKey<string | null>(\"font-preview\")\n\n/**\n * ProseMirror plugin that applies font preview styles to the current text selection.\n * Used when editing text on the canvas and hovering over fonts in the font popout.\n */\nexport function fontPreviewPlugin() {\n\treturn new Plugin<string | null>({\n\t\tkey: fontPreviewPluginKey,\n\n\t\tstate: {\n\t\t\tinit: () => null,\n\n\t\t\tapply(tr, fontSelector) {\n\t\t\t\tconst newFontSelector = tr.getMeta(fontPreviewPluginKey)\n\t\t\t\treturn isUndefined(newFontSelector) ? fontSelector : newFontSelector\n\t\t\t},\n\t\t},\n\n\t\tprops: {\n\t\t\tdecorations(state) {\n\t\t\t\tconst fontSelector = fontPreviewPluginKey.getState(state)\n\t\t\t\tif (!fontSelector) return undefined\n\n\t\t\t\tconst { from, to } = state.selection\n\t\t\t\tif (from === to) return undefined\n\n\t\t\t\treturn DecorationSet.create(state.doc, [\n\t\t\t\t\tDecoration.inline(from, to, { style: buildFontPreviewCSS(fontSelector) }),\n\t\t\t\t])\n\t\t\t},\n\t\t},\n\t})\n}\n\nfunction buildFontPreviewCSS(fontSelector: string): string {\n\tconst fontStyles = getFontStyleProperties(fontSelector)\n\tconst properties: string[] = []\n\n\tif (!isUndefined(fontStyles.fontFamily)) properties.push(`font-family: ${fontStyles.fontFamily}`)\n\tif (!isUndefined(fontStyles.fontStyle)) properties.push(`font-style: ${fontStyles.fontStyle}`)\n\tif (!isUndefined(fontStyles.fontWeight)) properties.push(`font-weight: ${fontStyles.fontWeight}`)\n\tif (!isUndefined(fontStyles.fontVariationAxes)) {\n\t\tproperties.push(`font-variation-settings: ${fontStyles.fontVariationAxes}`)\n\t}\n\n\treturn properties.join(\"; \")\n}\n\n/**\n * Update the font preview on the current selection.\n * Pass null to clear the preview.\n */\nexport function dispatchFontPreview(view: EditorView, fontSelector: string | null) {\n\tview.dispatch(view.state.tr.setMeta(fontPreviewPluginKey, fontSelector))\n}\n", "import { colors, dimensions } from \"@framerjs/fresco/tokens\"\nimport { assert, unhandledError } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { BaseRichTextEditTool } from \"document/base-engine/BaseRichTextEditTool.ts\"\nimport { type NodeID, WebPageNode } from \"document/models/CanvasTree/index.ts\"\nimport { InlineCodeStylePresetNode } from \"document/models/CanvasTree/nodes/InlineCodeStylePresetNode.ts\"\nimport { TextStylePresetNode } from \"document/models/CanvasTree/nodes/TextStylePresetNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { hasCollectionDataSource } from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport type { RichTextTag } from \"document/models/CanvasTree/traits/WithRichTextTag.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport {\n\tadjustViewBoxHeightIfEnabled,\n\tinitializeTextFitViewBox,\n\tmaybePatchDependentTextFitViewBox,\n\tscaleFontSizeToFitViewBoxIfEnabled,\n\tsyncTextFitViewBoxProseMirrorState,\n} from \"document/models/CanvasTree/traits/utils/textFitHelpers.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { fontStore } from \"library/render/fonts/fontStore.ts\"\nimport codemark from \"prosemirror-codemark\"\nimport type { Node as ProseMirrorNode } from \"prosemirror-model\"\nimport type { Transaction } from \"prosemirror-state\"\nimport {\n\taddLineBreakToStyledBlock,\n\taddLineBreakToUnstyledBlock,\n\tbackspaceListItem,\n\treplaceWithSchemaLineBreak,\n} from \"prosemirror/commands.ts\"\nimport { createEditorState } from \"prosemirror/editorState.ts\"\nimport { bulletedListInputRule, numberedListInputRule } from \"prosemirror/inputRules.ts\"\nimport { importProseMirror } from \"prosemirror/loader.ts\"\nimport { dispatchFontPreview, fontPreviewPlugin } from \"prosemirror/plugins/fontPreviewPlugin.ts\"\nimport { preserveInlineStylesPlugin } from \"prosemirror/plugins/preserveInlineStylesPlugin.ts\"\nimport { canvasSchemaParams, makeSchema } from \"prosemirror/schema/index.ts\"\nimport type { InlineCodeAttrs } from \"prosemirror/schema/inlineCode.ts\"\nimport { isInlineStylesMark } from \"prosemirror/schema/inlineStyles.ts\"\nimport type { TextBlockAttrs } from \"prosemirror/schema/textBlock.ts\"\nimport { isTextBlockNode } from \"prosemirror/schema/textBlock.ts\"\nimport { hasTextStylePreset } from \"prosemirror/schema/utils.ts\"\nimport { serializeRichText } from \"prosemirror/serialization/dom.ts\"\nimport type { Mutable } from \"utils/Mutable.ts\"\nimport { getDefaultInlineCodeStylePreset, insertInlineCodeStylePreset } from \"utils/inlineCodeStylePresetUtils.ts\"\nimport { getDefaultTextStylePreset, insertTextStylePreset } from \"utils/textStylePresetUtils.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport type { TextEditToolOptions } from \"./TextEditTool.ts\"\nimport { getUnloadedFontsForRichTextNode } from \"./getUnloadedFontsForRichTextNode.ts\"\nimport { createRichTextPastePlugin } from \"./richTextEditUtils.ts\"\n\ninterface EditorViewControls {\n\tundo(): void\n\tredo(): void\n\thandleOnFocus(): void\n\thandleOnBlur(): void\n\tsetFontPreview(fontSelector: string | null): void\n}\n\nconst contentNotLinkedToCmsToastKey = \"contentNotLinkedToCmsToast\"\nconst contentNotLinkedToCmsToastDismissedLocalStorageKey = \"contentNotLinkedToCmsToastDismissed\"\n\nexport class RichTextEditTool\n\textends withClassDiscriminator(\"RichTextEditTool\", VekterTool)\n\timplements BaseRichTextEditTool\n{\n\toverride readonly enum = Tools.RichTextEdit\n\tprivate nodeId: NodeID | undefined\n\tprivate controls: EditorViewControls | null = null\n\t/**\n\t * After editing text, we have to check if any of the replicas have fit text\n\t * view boxes that need updating. If they do, we have to run a measurement\n\t * which requires 2 engine frames. To ensure that we include the second\n\t * frame in the same undo group, we have to wait for the measure in the\n\t * stop() method before ending the group.\n\t */\n\tprivate textFitViewBoxUpdatePromise: Promise<void> | null = null\n\tprivate hasTextFitViewBox = false\n\tprivate schema = makeSchema(canvasSchemaParams)\n\n\tconstructor(\n\t\tengine: VekterEngine,\n\t\tprivate options: TextEditToolOptions = {},\n\t) {\n\t\tsuper(engine)\n\t}\n\n\tget eventSource() {\n\t\treturn this.options.eventSource ?? \"none\"\n\t}\n\n\tgetRichTextNode() {\n\t\treturn this.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\n\t\tif (!this.options.undoGroupExists) {\n\t\t\tengine.beginUndoGroup()\n\t\t}\n\n\t\tthis.nodeId = engine.stores.selectionStore.ids[0]\n\n\t\tconst node = this.getRichTextNode()\n\t\tif (node === null) return engine.exitTool()\n\n\t\tengine.scheduler.processWhenReady(() => {\n\t\t\tthis.hasTextFitViewBox = initializeTextFitViewBox(engine.tree, node)\n\t\t})\n\n\t\t// Figure out if the node needs custom fonts from textStyle presets to\n\t\t// be loaded This is necessary because assets are not loaded by the time\n\t\t// we try load the custom-fonts initially\n\t\tconst unloadedFonts = getUnloadedFontsForRichTextNode(engine.tree, node)\n\n\t\tif (unloadedFonts.length > 0) {\n\t\t\tfontStore\n\t\t\t\t.loadFonts(unloadedFonts)\n\t\t\t\t.catch(unhandledError)\n\t\t\t\t.finally(() => {\n\t\t\t\t\tengine.scheduler.process(() => {\n\t\t\t\t\t\tthis.startAsync().catch(error => {\n\t\t\t\t\t\t\tunhandledError(error)\n\t\t\t\t\t\t\tengine.exitTool()\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\t// Trigger a re-rendering of the text without changing it\n\t\t\t\t\t\tengine.tree.current(node)?.set({}, engine.tree)\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t} else {\n\t\t\tthis.startAsync().catch(error => {\n\t\t\t\tunhandledError(error)\n\t\t\t\tthis.engine.exitTool()\n\t\t\t})\n\t\t}\n\n\t\tthis.showContentNotLinkedToCmsToastIfNeeded()\n\t}\n\n\tprivate showContentNotLinkedToCmsToastIfNeeded() {\n\t\tconst isDismissed = localStorage.getItem(contentNotLinkedToCmsToastDismissedLocalStorageKey) === \"true\"\n\t\tif (isDismissed) return\n\n\t\tconst node = this.getRichTextNode()\n\t\tif (node === null) return\n\t\tconst webPageNode = WebPageNode.getFor(this.engine.tree, node)\n\t\tconst isCMSDetailPage = hasCollectionDataSource(webPageNode)\n\n\t\tif (!isCMSDetailPage) return\n\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tprimaryText: \"Edits apply to all pages\",\n\t\t\tsecondaryText: \"of the collection.\",\n\t\t\tvariant: \"info\",\n\t\t\tduration: Infinity,\n\t\t\tshowCloseButton: \"never\",\n\t\t\taction: {\n\t\t\t\ttitle: \"Dismiss\",\n\t\t\t\tonClick: () => {\n\t\t\t\t\tlocalStorage.setItem(contentNotLinkedToCmsToastDismissedLocalStorageKey, \"true\")\n\t\t\t\t\ttoast({\n\t\t\t\t\t\ttype: \"remove\",\n\t\t\t\t\t\tkey: contentNotLinkedToCmsToastKey,\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t},\n\t\t\tkey: contentNotLinkedToCmsToastKey,\n\t\t})\n\t}\n\n\tprivate async startAsync() {\n\t\tconst {\n\t\t\tbaseKeymap,\n\t\t\tchainCommands,\n\t\t\tcreateParagraphNear,\n\t\t\tDecoration,\n\t\t\tDecorationSet,\n\t\t\tdropCursor,\n\t\t\tEditorView,\n\t\t\tellipsis,\n\t\t\temDash,\n\t\t\tgapCursor,\n\t\t\thistory,\n\t\t\tInputRule,\n\t\t\tinputRules,\n\t\t\tkeymap,\n\t\t\tliftEmptyBlock,\n\t\t\tliftListItem,\n\t\t\tnewlineInCode,\n\t\t\tredo,\n\t\t\tsinkListItem,\n\t\t\tsplitBlock,\n\t\t\tsplitListItem,\n\t\t\ttoggleMark,\n\t\t\tundo,\n\t\t\tundoInputRule,\n\t\t} = await importProseMirror()\n\n\t\tconst engine = this.engine\n\t\tif (engine.tool !== this) return\n\n\t\tconst node = this.getRichTextNode()\n\t\tif (node === null) return engine.exitTool()\n\n\t\tconst handleEnter = chainCommands(\n\t\t\tsplitListItem(this.schema.nodes.listItem),\n\t\t\tnewlineInCode,\n\t\t\tcreateParagraphNear,\n\t\t\tliftEmptyBlock,\n\t\t\taddLineBreakToUnstyledBlock(this.schema),\n\t\t\taddLineBreakToStyledBlock(this.schema),\n\t\t\t(state, dispatch) =>\n\t\t\t\tsplitBlock(\n\t\t\t\t\tstate,\n\t\t\t\t\tdispatch &&\n\t\t\t\t\t\t(transaction => {\n\t\t\t\t\t\t\tconst selection = state.selection\n\t\t\t\t\t\t\tconst richTextNode = this.getRichTextNode()\n\t\t\t\t\t\t\tassert(richTextNode, \"RichTextNode not found\")\n\n\t\t\t\t\t\t\tconst blockNode = selection.$from.node(1)\n\t\t\t\t\t\t\tif (!isTextBlockNode(blockNode)) return dispatch(transaction)\n\n\t\t\t\t\t\t\tconst atEndOfLine = selection.$to.parentOffset === selection.$to.parent.content.size\n\t\t\t\t\t\t\tif (!atEndOfLine) return dispatch(transaction)\n\n\t\t\t\t\t\t\tconst attrs: Mutable<TextBlockAttrs> = { ...blockNode.attrs }\n\t\t\t\t\t\t\tconst switchBackToParagraph = hasTextStylePreset(blockNode) && attrs.tag !== \"p\"\n\n\t\t\t\t\t\t\tconst position = transaction.mapping.map(state.selection.to)\n\t\t\t\t\t\t\tconst selectionMarks = state.selection.$from.marks()\n\n\t\t\t\t\t\t\tif (switchBackToParagraph) {\n\t\t\t\t\t\t\t\tconst preset =\n\t\t\t\t\t\t\t\t\trichTextNode.getNodeTextStylePreset(engine.tree, \"p\") ??\n\t\t\t\t\t\t\t\t\tgetDefaultTextStylePreset(engine.tree, \"p\") ??\n\t\t\t\t\t\t\t\t\tTextStylePresetNode.createDefault(\"p\")\n\n\t\t\t\t\t\t\t\tengine.scheduler.processWhenReady(() => {\n\t\t\t\t\t\t\t\t\tinsertTextStylePreset(engine, preset)\n\t\t\t\t\t\t\t\t\trichTextNode.setNodeTextStylePreset(preset)\n\t\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\t\tattrs.textStylePreset = preset.id\n\t\t\t\t\t\t\t\tattrs.tag = \"p\"\n\t\t\t\t\t\t\t\tattrs.inlineStyles = {}\n\t\t\t\t\t\t\t\tattrs.blockStyles = {}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// If at end of line, and not using presets, we preserve the current styling\n\t\t\t\t\t\t\t\tconst mark = selectionMarks.find(isInlineStylesMark)\n\t\t\t\t\t\t\t\tattrs.inlineStyles = { ...attrs.inlineStyles, ...mark?.attrs.inlineStyles }\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// ProseMirror doesn't support empty text nodes so we need to store\n\t\t\t\t\t\t\t// the inline styles on the block node to preserve them in the HTML.\n\t\t\t\t\t\t\ttransaction.setNodeMarkup(position - 1, undefined, attrs)\n\n\t\t\t\t\t\t\t// We can't use the default splitBlockKeepMarks here because\n\t\t\t\t\t\t\t// we need to call setStoredMarks after setNodeMarkup.\n\t\t\t\t\t\t\t// Otherwise, setNodeMarkup will clear the stored marks immediately.\n\t\t\t\t\t\t\ttransaction.setStoredMarks(selectionMarks)\n\t\t\t\t\t\t\tif (switchBackToParagraph) {\n\t\t\t\t\t\t\t\ttransaction.removeStoredMark(this.schema.marks.inlineStyles)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdispatch(transaction)\n\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t)\n\n\t\tconst handleEscape = engine.scheduler.wrapHandler(() => {\n\t\t\tengine.exitTool()\n\t\t\treturn true\n\t\t})\n\n\t\tassert(!isVariableReference(node.htmlContent), \"Can't edit rich text node when htmlContent variable is assigned\")\n\n\t\tassert(!isVariableReference(node.textContent), \"Can't edit rich text node when textContent variable is assigned\")\n\n\t\tconst getInlineCodeStylePreset = () => {\n\t\t\tconst richTextNode = this.getRichTextNode()\n\t\t\tassert(richTextNode, \"RichTextNode not found\")\n\n\t\t\tconst preset =\n\t\t\t\trichTextNode.getNodeInlineCodeStylePreset(engine.tree) ??\n\t\t\t\tgetDefaultInlineCodeStylePreset(engine.tree) ??\n\t\t\t\tnew InlineCodeStylePresetNode()\n\n\t\t\tengine.scheduler.processWhenReady(() => {\n\t\t\t\tinsertInlineCodeStylePreset(engine, preset)\n\t\t\t\trichTextNode.setNodeInlineCodeStylePreset(preset)\n\t\t\t})\n\n\t\t\treturn preset.id\n\t\t}\n\n\t\t// Create ProseMirror state\n\t\tconst state = createEditorState(node.html, this.schema, {\n\t\t\tplugins: [\n\t\t\t\thistory(),\n\n\t\t\t\tkeymap({\n\t\t\t\t\t\"Mod-z\": chainCommands(undoInputRule, undo),\n\t\t\t\t\t\"Mod-Shift-z\": redo,\n\t\t\t\t\t\"Shift-Enter\": replaceWithSchemaLineBreak(this.schema),\n\t\t\t\t\t\"Mod-b\": toggleMark(this.schema.marks.bold),\n\t\t\t\t\t\"Mod-i\": toggleMark(this.schema.marks.italic),\n\t\t\t\t\t\"Shift-Tab\": liftListItem(this.schema.nodes.listItem),\n\t\t\t\t\t// end with return true to prevent tabbing breaking out to\n\t\t\t\t\t// next tab index in case of last step\n\t\t\t\t\tTab: chainCommands(sinkListItem(this.schema.nodes.listItem), () => true),\n\t\t\t\t\tBackspace: chainCommands(undoInputRule, backspaceListItem(this.schema)),\n\t\t\t\t\tEscape: handleEscape,\n\t\t\t\t\tEnter: handleEnter,\n\t\t\t\t\t\"Mod-Shift-c\": toggleMark(this.schema.marks.inlineCode, {\n\t\t\t\t\t\t// We use a getter so the InlineCodeStylePreset is\n\t\t\t\t\t\t// calculated when the mark is toggled. When no\n\t\t\t\t\t\t// preset exists we create a new default preset\n\t\t\t\t\t\t// which we want to also return the next time this\n\t\t\t\t\t\t// function is called.\n\t\t\t\t\t\tget inlineCodeStylePreset() {\n\t\t\t\t\t\t\treturn getInlineCodeStylePreset()\n\t\t\t\t\t\t},\n\t\t\t\t\t} satisfies InlineCodeAttrs),\n\t\t\t\t}),\n\n\t\t\t\tkeymap(baseKeymap),\n\n\t\t\t\tdropCursor({ color: colors.cmsRichTextDropCursor, width: dimensions.values.richTextDropCursor }),\n\n\t\t\t\tgapCursor(),\n\n\t\t\t\tpreserveInlineStylesPlugin(),\n\n\t\t\t\tfontPreviewPlugin(),\n\n\t\t\t\tcreateRichTextPastePlugin({\n\t\t\t\t\tengine: this.engine,\n\t\t\t\t\tschema: this.schema,\n\t\t\t\t\tnodeId: this.nodeId,\n\t\t\t\t\tgetRichTextNode: () => this.getRichTextNode(),\n\t\t\t\t}),\n\n\t\t\t\tinputRules({\n\t\t\t\t\trules: [\n\t\t\t\t\t\t// Turn two dashes -- into em dash\n\t\t\t\t\t\temDash,\n\n\t\t\t\t\t\t// Turn three dots ... into ellipsis\n\t\t\t\t\t\tellipsis,\n\n\t\t\t\t\t\t// Turn hashtag #, ## into heading\n\t\t\t\t\t\tnew InputRule(/^(#{1,6})\\s$/u, (state, match, from, to) => {\n\t\t\t\t\t\t\tconst resolvedFrom = state.doc.resolve(from)\n\n\t\t\t\t\t\t\t// Check if we can replace the current node.\n\t\t\t\t\t\t\tconst blockNode = resolvedFrom.node(1)\n\t\t\t\t\t\t\tconst position = resolvedFrom.before(1)\n\t\t\t\t\t\t\tif (!isTextBlockNode(blockNode)) return null\n\n\t\t\t\t\t\t\tconst transaction = state.tr\n\t\t\t\t\t\t\tconst tag = (\"h\" + (match[1]?.length ?? 1)) as RichTextTag\n\n\t\t\t\t\t\t\tconst richTextNode = this.getRichTextNode()\n\t\t\t\t\t\t\tassert(richTextNode, \"RichTextNode not found\")\n\n\t\t\t\t\t\t\tconst preset =\n\t\t\t\t\t\t\t\trichTextNode.getNodeTextStylePreset(engine.tree, tag) ??\n\t\t\t\t\t\t\t\tgetDefaultTextStylePreset(engine.tree, tag) ??\n\t\t\t\t\t\t\t\tTextStylePresetNode.createDefault(tag)\n\n\t\t\t\t\t\t\tconst textStylePresetId = preset.id\n\n\t\t\t\t\t\t\tengine.scheduler.processWhenReady(() => {\n\t\t\t\t\t\t\t\tinsertTextStylePreset(engine, preset)\n\t\t\t\t\t\t\t\trichTextNode.setNodeTextStylePreset(preset)\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\t// Remove any inline styles if we are adding a new preset.\n\t\t\t\t\t\t\t// If we change the preset we want to keep the overrides.\n\t\t\t\t\t\t\tif (!hasTextStylePreset(blockNode)) {\n\t\t\t\t\t\t\t\ttransaction.removeMark(position, position + blockNode.nodeSize, this.schema.marks.inlineStyles)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Delete the markdown hashtags from the line.\n\t\t\t\t\t\t\ttransaction.delete(from, to)\n\n\t\t\t\t\t\t\t// Change the node markup to the correct heading.\n\t\t\t\t\t\t\ttransaction.setNodeMarkup(position, this.schema.nodes.textBlock, {\n\t\t\t\t\t\t\t\t...blockNode.attrs,\n\t\t\t\t\t\t\t\tblockStyles: textStylePresetId ? {} : blockNode.attrs.blockStyles,\n\t\t\t\t\t\t\t\tinlineStyles: textStylePresetId ? {} : blockNode.attrs.inlineStyles,\n\t\t\t\t\t\t\t\ttextStylePreset: textStylePresetId,\n\t\t\t\t\t\t\t\ttag,\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\treturn transaction\n\t\t\t\t\t\t}),\n\n\t\t\t\t\t\tnumberedListInputRule(this.schema),\n\t\t\t\t\t\tbulletedListInputRule(this.schema),\n\t\t\t\t\t],\n\t\t\t\t}),\n\n\t\t\t\t...codemark({\n\t\t\t\t\tmarkType: this.schema.marks.inlineCode,\n\t\t\t\t\tattrs: {\n\t\t\t\t\t\t// We use a getter so the InlineCodeStylePreset is\n\t\t\t\t\t\t// calculated when the mark is toggled. When no\n\t\t\t\t\t\t// preset exists we create a new default preset\n\t\t\t\t\t\t// which we want to also return the next time this\n\t\t\t\t\t\t// function is called.\n\t\t\t\t\t\tget inlineCodeStylePreset() {\n\t\t\t\t\t\t\treturn getInlineCodeStylePreset()\n\t\t\t\t\t\t},\n\t\t\t\t\t} satisfies InlineCodeAttrs,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\n\t\tlet proseMirrorDocument: ProseMirrorNode | undefined\n\n\t\t// Create ProseMirror view\n\t\tconst view = new EditorView(null, {\n\t\t\tstate,\n\n\t\t\tdispatchTransaction: engine.scheduler.wrapHandler((transaction: Transaction) => {\n\t\t\t\tconst node = this.getRichTextNode()\n\t\t\t\tassert(node, \"Node should not be null\")\n\n\t\t\t\tlet state = view.state.apply(transaction)\n\t\t\t\tview.updateState(state)\n\n\t\t\t\tstate = scaleFontSizeToFitViewBoxIfEnabled(state, view, node, this.schema)\n\n\t\t\t\tengine.stores.toolStore.proseMirrorState = state\n\n\t\t\t\tif (proseMirrorDocument !== state.doc) {\n\t\t\t\t\tconst html = serializeRichText(state.doc, this.schema)\n\n\t\t\t\t\tif (node.html !== html) {\n\t\t\t\t\t\tnode.set({ html })\n\t\t\t\t\t\tadjustViewBoxHeightIfEnabled(node, view)\n\t\t\t\t\t}\n\n\t\t\t\t\tproseMirrorDocument = state.doc\n\n\t\t\t\t\tconst hasText = node?.getTextContent().length > 0\n\t\t\t\t\t// If we have changed the node's html property in any way, and it has text,\n\t\t\t\t\t// ensure that the all localized versions of the current\n\t\t\t\t\t// node and it's replicas with text fit view boxes are\n\t\t\t\t\t// updated to accommodate any changes to size.\n\t\t\t\t\tthis.textFitViewBoxUpdatePromise = hasText\n\t\t\t\t\t\t? maybePatchDependentTextFitViewBox(this.engine, node, node.id)\n\t\t\t\t\t\t: null\n\t\t\t\t}\n\n\t\t\t\t// Update text link and link rect to show tooltip correctly\n\t\t\t\tconst selection = document.getSelection()\n\t\t\t\tif (selection === null) return\n\n\t\t\t\tconst links = node.getLinks(true)\n\t\t\t\tengine.stores.toolStore.textLink = links[0] ?? null\n\t\t\t}),\n\t\t})\n\n\t\tnode.cache.isEditable = true\n\t\tnode.cache.editorView = view\n\n\t\tengine.stores.toolStore.proseMirrorView = view\n\t\tengine.stores.toolStore.proseMirrorState = state\n\n\t\t// Setup a bunch of methods that can manipulate the lazily loaded and async created editor view.\n\t\tthis.controls = {\n\t\t\tundo() {\n\t\t\t\tundo(view.state, view.dispatch)\n\t\t\t},\n\n\t\t\tredo() {\n\t\t\t\tredo(view.state, view.dispatch)\n\t\t\t},\n\n\t\t\t// When focused, we remove any fake selection, proseMirror will sync the editor\n\t\t\t// selection back to the DOM.\n\t\t\thandleOnFocus() {\n\t\t\t\tview.setProps({\n\t\t\t\t\tdecorations() {\n\t\t\t\t\t\treturn undefined\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t},\n\t\t\t// When blurred, we copy the selection to a fake selection. This happens for example when\n\t\t\t// opening the font selector.\n\t\t\thandleOnBlur() {\n\t\t\t\tview.setProps({\n\t\t\t\t\tdecorations(state) {\n\t\t\t\t\t\tconst selection = state.selection\n\t\t\t\t\t\tif (selection.from !== selection.to) {\n\t\t\t\t\t\t\treturn DecorationSet.create(state.doc, [\n\t\t\t\t\t\t\t\tDecoration.inline(selection.from, selection.to, {\n\t\t\t\t\t\t\t\t\tclass: \"selection\",\n\t\t\t\t\t\t\t\t\tnodeName: \"mark\",\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t])\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tsetFontPreview(fontSelector: string | null) {\n\t\t\t\tdispatchFontPreview(view, fontSelector)\n\t\t\t},\n\t\t}\n\t}\n\n\toverride update() {\n\t\tconst engine = this.engine\n\t\tconst { mouseStore, toolStore, selectionStore } = engine.stores\n\t\tconst node = this.getRichTextNode()\n\n\t\tif (mouseStore.latest.canvasMouseDownPosition && !mouseStore.previous.canvasMouseDownPosition) {\n\t\t\t// Need to switch to the Select tool as the default Highlight tool\n\t\t\t// will clear the current selection.\n\t\t\tengine.setTool(Tools.Select)\n\t\t\treturn\n\t\t} else if (node === null || selectionStore.ids[0] !== this.nodeId) {\n\t\t\tengine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!node.textFitViewBoxSize || this.hasTextFitViewBox === true) return\n\n\t\tengine.scheduler.processWhenReady(() => {\n\t\t\tconst state = syncTextFitViewBoxProseMirrorState(engine.tree, node, this.schema)\n\t\t\tif (!state) return\n\t\t\ttoolStore.proseMirrorState = state\n\t\t\tthis.hasTextFitViewBox = true\n\t\t})\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\t\tconst toolStore = engine.stores.toolStore\n\n\t\tconst node = this.getRichTextNode()\n\t\tconst noText = node?.getTextContent().length === 0\n\t\tconst hasText = !noText\n\t\tconst isViewOnly = getIsViewOnly(this.engine, \"canDesign\")\n\n\t\tif (node) {\n\t\t\tnode.cache.isEditable = false\n\t\t\tnode.cache.editorView = null\n\t\t}\n\n\t\tif (hasText) {\n\t\t\tawait this.textFitViewBoxUpdatePromise\n\t\t}\n\n\t\tengine.scheduler.process(() => {\n\t\t\tif (noText && this.options.ignoreEditIfEmpty && !isViewOnly) {\n\t\t\t\t// If this was a just created text, discard the whole edit via the undo stack.\n\t\t\t\tengine.discardUndoGroup()\n\t\t\t} else if (noText && !isReplicaOrReplicaChild(node) && !isViewOnly) {\n\t\t\t\t// If this was an existing text, delete it, but keep an undo entry.\n\t\t\t\tengine.deleteNode(node.id)\n\t\t\t\tengine.endUndoGroup()\n\t\t\t} else {\n\t\t\t\t// Otherwise just close the undo group.\n\t\t\t\tengine.endUndoGroup()\n\t\t\t}\n\n\t\t\ttoolStore.proseMirrorView = null\n\t\t\ttoolStore.proseMirrorState = null\n\t\t\tthis.controls = null\n\n\t\t\t// This is set inside RichTextEditor.tsx\n\t\t\ttoolStore.nodeInTextEditorId = null\n\t\t})\n\n\t\ttoast({\n\t\t\ttype: \"remove\",\n\t\t\tkey: contentNotLinkedToCmsToastKey,\n\t\t})\n\t}\n\n\t// We let the tool do its own undo, that will also prevent the engine from doing its own undo\n\t// behind our backs.\n\toverride undo() {\n\t\tthis.controls?.undo()\n\t}\n\n\toverride redo() {\n\t\tthis.controls?.redo()\n\t}\n\n\t// We also route blur and focus to the editor to render a fake selection.\n\thandleOnFocus = () => {\n\t\tthis.controls?.handleOnFocus()\n\t}\n\n\thandleOnBlur = () => {\n\t\tthis.controls?.handleOnBlur()\n\t}\n\n\tsetFontPreview = (fontSelector: string | null) => {\n\t\tthis.controls?.setFontPreview(fontSelector)\n\t}\n}\n\nexport function isRichTextEditTool(tool: VekterTool): tool is RichTextEditTool {\n\treturn tool instanceof RichTextEditTool\n}\n", "import { assert, unhandledError } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { type ProseMirror, importProseMirror } from \"prosemirror/loader.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { BaseVariableEditTool, type BaseVariableEditToolOptions } from \"./BaseVariableEditTool.ts\"\nimport type { TextEditEventSource } from \"./TextEditTool.ts\"\n\ninterface Controls {\n\tundo(): void\n\tredo(): void\n}\n\nexport interface RichTextVariableEditToolOptions extends BaseVariableEditToolOptions {\n\treadonly eventSource?: TextEditEventSource\n}\n\nexport class RichTextVariableEditTool extends withClassDiscriminator(\n\t\"RichTextVariableEditTool\",\n\tBaseVariableEditTool as typeof BaseVariableEditTool<ControlType.RichText>,\n) {\n\toverride readonly enum = Tools.RichTextVariableEdit\n\toverride readonly controlType = ControlType.RichText\n\n\tprivate resumeCodeGeneration?: () => void\n\n\treadonly eventSource: TextEditEventSource\n\n\tcontrols: Controls | undefined\n\tproseMirror: ProseMirror | undefined\n\n\tconstructor(engine: VekterEngine, options: RichTextVariableEditToolOptions) {\n\t\tsuper(engine, options)\n\t\tthis.eventSource = options?.eventSource ?? \"none\"\n\t}\n\n\toverride getNode(): RichTextNode | null {\n\t\treturn this.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tengine.beginUndoGroup()\n\n\t\tconst richTextNode = this.getNode()\n\t\tif (!richTextNode) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\n\t\t// Pause code generation until exiting the tool as it can be expensive.\n\t\tthis.resumeCodeGeneration = engine.stores.codeGenerationStore.pauseCodeGeneration(variableInfo.collectionNode.id)\n\n\t\tthis.startAsync().catch(error => {\n\t\t\tunhandledError(error)\n\t\t\tengine.exitTool()\n\t\t})\n\t}\n\n\tgetValue() {\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return\n\n\t\tconst { controlProp } = variableInfo\n\t\tassert(controlProp, \"Control prop must exist\")\n\t\tif (isDynamicValue(controlProp.value)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\t\treturn controlProp.value\n\t}\n\n\tprivate async startAsync() {\n\t\tthis.proseMirror = await importProseMirror()\n\n\t\tconst engine = this.engine\n\t\tif (engine.tool !== this) return\n\n\t\tconst richTextNode = this.getNode()\n\t\tif (!richTextNode) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\n\t\trichTextNode.cache.isEditable = true\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\t\tconst toolStore = engine.stores.toolStore\n\n\t\tconst richTextNode = this.getNode()\n\n\t\tif (richTextNode) {\n\t\t\trichTextNode.cache.isEditable = false\n\t\t}\n\n\t\tthis.resumeCodeGeneration?.()\n\n\t\tengine.scheduler.process(() => {\n\t\t\tengine.endUndoGroup()\n\n\t\t\t// This is set inside `RichTextVariableEditor.tsx`.\n\t\t\ttoolStore.nodeInTextEditorId = null\n\t\t})\n\t}\n\n\toverride undo() {\n\t\tthis.controls?.undo()\n\t}\n\n\toverride redo() {\n\t\tthis.controls?.redo()\n\t}\n}\n", "import { assert, assertNever } from \"@framerjs/shared\"\nimport { translateXYToPoint } from \"canvas-sandbox/layout-measuring/projection.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { convertFramePointsToCanvas, convertFrameToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { FramePoint, type FramePointValue, type FramePoints } from \"document/models/FramePoint.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { Point, Rect, type Size, isEqual, roundedNumber } from \"library/index.ts\"\nimport { resizing } from \"utils/cursor.ts\"\nimport { isNull, isUndefined } from \"utils/typeChecks.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { type ScaleNodesInitialState, getScaleNodesInitialState, scaleNodes } from \"../utils/scaleToolUtils.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\nexport function isScaleTool(tool: VekterTool): tool is ScaleTool {\n\treturn tool instanceof ScaleTool\n}\n\nexport const MULT_SYMBOL = \"\u00D7\"\nexport const MIN_ABSOLUTE_SCALE_FACTOR = 0.01\n\nconst defaultAnchor: Point = { x: 0.5, y: 0.5 }\n\ninterface ScaleUndoEntry {\n\tselectedNodeIds: NodeID[]\n\tinitialNodeState: ScaleNodesInitialState\n\tanchor: Point\n\tbaseScaleFactor: number\n\trelativeScaleFactor: number\n\tstartRect: Rect\n\tlastScaleResetStateToken: number | null\n\tlastUpdatedTimestamp: number\n\tcontextNode: CanvasNode | null\n\tcontextNodeStartMatrix: DOMMatrixReadOnly | null\n\tsource: \"scaleInput\" | \"dimensionInput\" | \"handle\" | null\n}\n\nexport class ScaleTool extends withClassDiscriminator(\"ScaleTool\", VekterTool) {\n\toverride readonly enum = Tools.Scale\n\toverride readonly wantsAutoscrolling = true\n\n\tselectedNodeIds: NodeID[] = []\n\tselectedNodes: CanvasNode[] = []\n\t// FIXME: the !s are unsafe; they are assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where these fields are undefined\n\tinitialDimensions!: Size\n\tanchor!: Point\n\t/**\n\t * This particular flag helps with the Scale Panel, where there are complex cases with the combo box that sets the\n\t * scale factor. If the user types a value and hits `enter`, we wish to exit the Scale Tool immediately.\n\t */\n\texitAfterUpdate = false\n\n\t// Event tracking\n\tprivate startMs!: number\n\tprivate hasScaledWithHandle = false\n\tprivate hasScaledWithScaleInput = false\n\tprivate hasScaledWithDimensionInput = false\n\tprivate currentScaleSource!: \"scaleInput\" | \"dimensionInput\" | \"handle\" | null\n\n\tprivate startRect!: Rect\n\tprivate contextNode!: CanvasNode | null\n\tprivate contextNodeStartMatrix!: DOMMatrixReadOnly | null\n\tprivate initialNodeState!: ScaleNodesInitialState\n\t/** The last absoluteScaleFactor used for the scale operation */\n\tprivate lastAbsoluteScaleFactor!: number\n\t/** The scale factor of at the point initialNodeState was generated, used to calculate the absolute scale factor */\n\tprivate baseScaleFactor!: number\n\t/** The scale factor relative to baseScaleFactor */\n\tprivate relativeScaleFactor!: number\n\tprivate isCancelled = false\n\tprivate lastScaleResetStateToken: number | null = null\n\n\t// undo/redo\n\tprivate undoBuffer: ScaleUndoEntry[] = []\n\tprivate redoBuffer: ScaleUndoEntry[] = []\n\tprivate lastChange: ScaleUndoEntry | null = null\n\tprivate applyingUndoRedoChanges = false\n\n\toverride displaySelectionBox = true\n\toverride displaySelectionHandles = true\n\toverride displayPaddingHandles = false\n\toverride displayGapHandles = false\n\n\t/**\n\t * Get the absolute scale factor from the initial state to the current state. Used to scale the\n\t * nodes as well as to display the currently applied scale factor on the tooltip.\n\t */\n\tget absoluteScaleFactor() {\n\t\treturn this.relativeScaleFactor * this.baseScaleFactor\n\t}\n\n\t/**\n\t * Set the absolute scale factor from the initial state to the current state. The scale factor\n\t * needed to accomplish that scale will be calculated implicitly. The next tool update will scale\n\t * using the calculated value.\n\t *\n\t * @param newScaleFactor - The new absolute scale factor to set. It is used to calculate `relativeScaleFactor`.\n\t */\n\tsetAbsoluteScaleFactorForNextUpdate(newScaleFactor: number, source: \"scaleInput\" | \"dimensionInput\") {\n\t\tthis.currentScaleSource = source\n\t\tthis.relativeScaleFactor = Math.max(MIN_ABSOLUTE_SCALE_FACTOR, newScaleFactor) / this.baseScaleFactor\n\t}\n\n\t/**\n\t * Get the bounding frame rect of the selected nodes.\n\t *\n\t * If there is a context node, which only has one selected node, then we get the rect of that node.\n\t * Otherwise, we merge the frames of all selected nodes.\n\t */\n\tgetCurrentBoundingFrame(): Rect {\n\t\tassert(\n\t\t\t!isNull(this.contextNode) || this.selectedNodes.length > 0,\n\t\t\t\"Tool state must be initialized before accessing bounding frame\",\n\t\t)\n\t\tif (this.contextNode) {\n\t\t\tconst currentContextNode = this.engine.tree.current(this.contextNode)\n\t\t\tassert(!isNull(currentContextNode), \"Context node must be non-null\")\n\t\t\t// We need to get the parent size info as there is a bug when one dimension is percentage or viewport.\n\t\t\t// Without parent size info, the value goes to the default value of 200. If we simply get the rect with\n\t\t\t// `getBoundingFrameForNodes() or convertFrameToCanvas() for 1 node`, then it does not calculate the\n\t\t\t// correct rect for transformed frames.\n\t\t\tconst parentSizeInfo = this.engine.tree.getParentSizeInfo(\n\t\t\t\tcurrentContextNode,\n\t\t\t\tthis.engine.tree.getParent(currentContextNode.id),\n\t\t\t)\n\t\t\t// Because we are not rounding the rect on our own, sometimes, the value shown in the Scale Panel HUD\n\t\t\t// might not reflect the aspect ratio of the node. However, because other parts of the Canvas show pixels\n\t\t\t// in pixel aligned way, although the values might change in the Scale Panel, the node will still be scaling\n\t\t\t// correctly. If there is a desire to change this, then `pixelAlign` can be `false` in the `rect` call, and\n\t\t\t// the tool can round the rect as it wishes.\n\t\t\treturn currentContextNode.rect(parentSizeInfo)\n\t\t}\n\t\tconst frames = this.selectedNodes.map(node => convertFrameToCanvas(this.engine.tree, node))\n\t\treturn Rect.merge(...frames)\n\t}\n\n\toverride start() {\n\t\tconst { tree } = this.engine\n\n\t\tthis.engine.beginUndoGroup()\n\t\tconst selectedNodes: CanvasNode[] = tree.getNodes(this.engine.stores.selectionStore.ids)\n\t\tif (selectedNodes.length === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (selectedNodes.some(n => isBreakpointVariant(n))) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.initializeToolState(selectedNodes)\n\t}\n\n\toverride cancel() {\n\t\tthis.isCancelled = true\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.toolStore.tooltip = undefined\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\n\t\tif (this.isCancelled) {\n\t\t\tthis.recordTrackingEvent(\"cancel\")\n\t\t\tthis.engine.discardUndoGroup()\n\t\t} else if (this.lastScaleResetStateToken) {\n\t\t\t// only if state has been initialized, then we record the tracking event\n\t\t\tthis.recordTrackingEvent(\"apply\")\n\t\t\tthis.engine.endUndoGroup()\n\t\t}\n\t}\n\n\t/**\n\t * Unlike other tools that involve handles, the Scale Tool is always active. Since `update()` runs on every tick,\n\t * it must accommodate changes made via the canvas/handles and via the Scale Panel UI.\n\t */\n\toverride update() {\n\t\tconst { tree, handle } = this.engine\n\n\t\tconst { selectionStore, mouseCursorStore, toolStore, selectionOutlineTracker, mouseStore } = this.engine.stores\n\n\t\tconst { canvasMouseDownPosition, canvasMousePosition } = mouseStore.latest\n\n\t\tconst selectedNodes: CanvasNode[] = tree.getNodes(selectionStore.ids)\n\t\tif (selectedNodes.length === 0) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (selectedNodes.some(n => isBreakpointVariant(n))) {\n\t\t\t// We do not want to allow scaling on breakpoint variants. This discards the changes that have been made.\n\t\t\tthis.engine.cancelTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.applyingUndoRedoChanges && !isEqual(selectionStore.ids, this.selectedNodeIds, true)) {\n\t\t\t// When the selection changes, we don't want the outline to be hidden. Triggering here instead of the UI\n\t\t\t// prevents a quick flicker.\n\t\t\tselectionOutlineTracker.forceEnableSelectionOutline()\n\n\t\t\t// Current scale is implicitly applied by reinitializing the state\n\t\t\tthis.recordTrackingEvent(\"apply\")\n\n\t\t\t// Reset state if tool is active and another set of node(s) is selected. Switching over would keep the tool\n\t\t\t// open and keep changes that have been made.\n\t\t\tif (!isNull(this.lastScaleResetStateToken)) {\n\t\t\t\tthis.updateUndoBuffer()\n\t\t\t}\n\t\t\tthis.initializeToolState(selectedNodes)\n\t\t\treturn\n\t\t}\n\n\t\tif (!canvasMouseDownPosition && handle) {\n\t\t\t// The mouse has been released after dragging a handle, so we reset the handle.\n\t\t\ttoolStore.tooltip = undefined\n\t\t\tmouseCursorStore.clear()\n\t\t\tthis.displaySelectionHandles = true\n\t\t\tthis.engine.setToolWithHandle(Tools.Scale, null, false)\n\t\t\treturn\n\t\t} else if (canvasMouseDownPosition && !handle) {\n\t\t\t// A click on the canvas without a handle means we want to exit the tool with our changes committed.\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(mouseStore.latest, mouseStore.previous)\n\n\t\tthis.initializeResetStateIfNeeded()\n\n\t\tif (!isNull(handle) && mouseAction === \"mouseMove\") {\n\t\t\t// Since `baseScaleFactor` updates after each handle pull, we must bound whatever we get from the mouse,\n\t\t\t// which is based on the last `startRect` and the `resizeRect` to ensure the new absolute min scale factor\n\t\t\t// never falls below the absolute min scale factor.\n\t\t\tconst newScaleFactor = this.getRelativeScaleFactorFromMouse(handle, canvasMousePosition)\n\t\t\tthis.relativeScaleFactor = Math.max(MIN_ABSOLUTE_SCALE_FACTOR / this.baseScaleFactor, newScaleFactor)\n\t\t\tthis.updateCursor()\n\t\t\tthis.currentScaleSource = \"handle\"\n\t\t}\n\n\t\tif (this.absoluteScaleFactor === this.lastAbsoluteScaleFactor) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.updateUndoBuffer()\n\t\tthis.scaleNodes()\n\t\tthis.updateScaleSourcesForTracking()\n\n\t\tthis.updateTooltip()\n\n\t\tthis.lastAbsoluteScaleFactor = this.absoluteScaleFactor\n\n\t\tif (this.exitAfterUpdate) {\n\t\t\tthis.engine.exitTool()\n\t\t}\n\t}\n\n\tprivate updateCursor(): void {\n\t\tconst { handle, tree } = this.engine\n\t\tconst { selectionStore, mouseCursorStore } = this.engine.stores\n\t\tconst singleSelection = selectionStore.ids.length === 1\n\t\tlet framePoints: FramePoints | null = null\n\n\t\tif (singleSelection) {\n\t\t\tconst id = selectionStore.ids[0]\n\t\t\tif (isUndefined(id)) return\n\t\t\tconst node = tree.getNode<CanvasNode>(id)\n\t\t\tif (!node) return\n\n\t\t\tframePoints = convertFramePointsToCanvas(tree, node)\n\t\t} else {\n\t\t\tconst mergedFrame = selectionStore.ids.reduce((previous: Rect | undefined, id) => {\n\t\t\t\tconst node = tree.getNode<CanvasNode>(id)\n\t\t\t\tif (!node) return previous\n\n\t\t\t\tconst canvasFrame = convertFrameToCanvas(tree, node)\n\t\t\t\treturn previous ? Rect.merge(previous, canvasFrame) : canvasFrame\n\t\t\t}, undefined)\n\t\t\tif (mergedFrame) {\n\t\t\t\tframePoints = FramePoint.fromFrame(mergedFrame)\n\t\t\t}\n\t\t}\n\n\t\tif (framePoints && handle) {\n\t\t\tmouseCursorStore.current = resizing(handle, framePoints, { x: {}, y: {} }, { x: false, y: false })\n\t\t}\n\t}\n\n\t/**\n\t * Initializes the tool state. This occurs when the tool starts and when another selection of node(s) are made. This\n\t * is necessary in both cases as the tool is active without the handles, and the user can select new node(s) without\n\t * exiting the tool via the Layers panel.\n\t */\n\tprivate initializeToolState(selectedNodes: CanvasNode[]) {\n\t\tthis.baseScaleFactor = 1\n\t\tthis.relativeScaleFactor = 1\n\t\tthis.lastAbsoluteScaleFactor = 1\n\n\t\tthis.anchor = defaultAnchor\n\n\t\tthis.selectedNodes = selectedNodes\n\t\tthis.selectedNodeIds = this.engine.stores.selectionStore.ids\n\t\tthis.initialNodeState = getScaleNodesInitialState(this.engine, this.selectedNodes)\n\n\t\t// For shape containers we can't set the token at the same time as we get the initial state https://github.com/framer/company/issues/32156\n\t\tthis.lastScaleResetStateToken = null\n\n\t\tconst withoutDescendants = this.engine.tree.withoutDescendants(this.selectedNodes)\n\n\t\t// Set up context node for single selection or a selection of a parent and its children\n\t\t// We need to check without descendants to ensure the proper bounding box, but we want to use\n\t\t// all selected nodes for `this.selectedNodes` to include overlays when the scaling is applied.\n\t\tif (withoutDescendants.length === 1 && withoutDescendants[0]) {\n\t\t\tthis.contextNode = withoutDescendants[0]\n\t\t\tthis.contextNodeStartMatrix = this.contextNode.canvasMatrix()\n\t\t} else {\n\t\t\tthis.contextNode = null\n\t\t\tthis.contextNodeStartMatrix = null\n\t\t}\n\n\t\tthis.startRect = this.getCurrentBoundingFrame()\n\t\tthis.initialDimensions = {\n\t\t\twidth: this.startRect.width,\n\t\t\theight: this.startRect.height,\n\t\t}\n\n\t\t// tracking\n\t\tthis.startMs = performance.now()\n\t\tthis.hasScaledWithDimensionInput = false\n\t\tthis.hasScaledWithScaleInput = false\n\t\tthis.hasScaledWithHandle = false\n\t\t// undo/redo (we don't reset the buffers because we can undo across selection changes)\n\t\tthis.lastChange = null\n\t}\n\n\t/**\n\t * Reset state can't be initialized until the first scale operation is occurring otherwise we may reset too far\n\t * back and break scaling of certain shapes. https://github.com/framer/company/issues/32156\n\t */\n\tprivate initializeResetStateIfNeeded() {\n\t\tif (!isNull(this.lastScaleResetStateToken)) return\n\t\tif (this.absoluteScaleFactor === this.lastAbsoluteScaleFactor && isNull(this.engine.handle)) return\n\n\t\tthis.lastScaleResetStateToken = this.engine.getStateToken()\n\t\t// ensure the last \"change\" is the initial state\n\t\tthis.lastChange = this.getNewUndoEntry({\n\t\t\tanchor: defaultAnchor,\n\t\t\trelativeScaleFactor: 1,\n\t\t\tbaseScaleFactor: 1,\n\t\t})\n\t}\n\n\tprivate getRelativeScaleFactorFromMouse(handle: FramePoint, mouse: Point): number {\n\t\tthis.displaySelectionHandles = false\n\n\t\t// Calculate scale factor based on mouse position\n\t\tconst { fx, fy } = handle\n\n\t\t// sets opposite of the handle position\n\t\tconst prevAnchor = this.anchor\n\t\tthis.anchor = { x: Math.abs(fx - 1), y: Math.abs(fy - 1) }\n\n\t\tif (!Point.isEqual(prevAnchor, this.anchor)) {\n\t\t\tthis.updateStateAfterHandleChange()\n\t\t}\n\n\t\tconst { startRect } = this\n\t\tconst startX = startRect.width * fx\n\t\tconst startY = startRect.height * fy\n\n\t\t// Calculate difference\n\t\tlet deltaX = 0\n\t\tlet deltaY = 0\n\t\tif (this.contextNodeStartMatrix) {\n\t\t\t// @FIXME - Currently we will try to snap to the mouse position,\n\t\t\t// even if the mouse is not on the orthogonal resize line in the\n\t\t\t// case of rotations. We should be able to instead snap to the point\n\t\t\t// that intersects the orthogonal line that drawn through the center\n\t\t\t// of the node to the handle point.\n\t\t\tconst delta = translateXYToPoint(this.contextNodeStartMatrix, { x: startX, y: startY }, mouse)\n\t\t\tdeltaX = delta.x\n\t\t\tdeltaY = delta.y\n\t\t} else {\n\t\t\t// Calculate difference\n\t\t\tdeltaX = mouse.x - (startX + startRect.x)\n\t\t\tdeltaY = mouse.y - (startY + startRect.y)\n\t\t}\n\n\t\t// Calculate new frame\n\t\tconst resizeRect = { ...this.startRect }\n\t\tresizeRect.height = Math.round(resizeRect.height + (fy * 2 - 1) * deltaY)\n\t\tresizeRect.width = Math.round(resizeRect.width + (fx * 2 - 1) * deltaX)\n\n\t\treturn this.calculateRelativeScaleFactorFromMouse(resizeRect, fx, fy)\n\t}\n\n\t/**\n\t * Unlike other tools the scale tool lives for various multiple handle moves, so when the user switches from dragging\n\t * one handle to dragging another we need to track the state of the nodes at the end of the last handle drag.\n\t * If we don't track this state then the scaled nodes will jump back to the initial position instead of scaling\n\t * consistently with the new handle drag.\n\t *\n\t * This strategy avoids having to reapply a series of scale instructions, since scaling to 1.5x from the top left point,\n\t * then a further 0.5x (to 2x) from the bottom right point would have a different result than scaling 2x from the\n\t * bottom right point. Instead we always scale from the last time the anchor was changed.\n\t */\n\tprivate updateStateAfterHandleChange() {\n\t\tthis.lastScaleResetStateToken = this.engine.getStateToken()\n\t\tthis.initialNodeState = getScaleNodesInitialState(this.engine, this.engine.stores.selectionStore.nodes)\n\t\tthis.lastAbsoluteScaleFactor = this.absoluteScaleFactor\n\t\tthis.baseScaleFactor = this.absoluteScaleFactor\n\t\tthis.relativeScaleFactor = 1\n\n\t\tif (this.contextNode) {\n\t\t\tthis.contextNodeStartMatrix = this.contextNode.canvasMatrix()\n\t\t}\n\n\t\tthis.startRect = this.getCurrentBoundingFrame()\n\t}\n\n\tprivate calculateRelativeScaleFactorFromMouse(resizeRect: Rect, fx: FramePointValue, fy: FramePointValue): number {\n\t\tconst scaleFactorX = resizeRect.width / this.startRect.width\n\t\tconst scaleFactorY = resizeRect.height / this.startRect.height\n\n\t\t// Vertical\n\t\tif (fx === 0.5 && fy !== 0.5) return scaleFactorY\n\t\t// Horizontal\n\t\tif (fy === 0.5 && fx !== 0.5) return scaleFactorX\n\t\t// Corner\n\t\tconst aspectPreservingScale = (scaleFactorX + scaleFactorY) / 2\n\t\treturn aspectPreservingScale\n\t}\n\n\tprivate scaleNodes() {\n\t\tassert(this.lastScaleResetStateToken !== null, \"Last scale reset state token must be initialized\")\n\n\t\tthis.engine.setEditReason(\"ScalePanel\")\n\t\tthis.engine.resetTreeAndSelectionWithToken(this.lastScaleResetStateToken)\n\n\t\tthis.selectedNodes = this.engine.tree.getNodes(this.engine.stores.selectionStore.ids)\n\n\t\tscaleNodes(this.engine, this.selectedNodes, this.relativeScaleFactor, this.initialNodeState, this.anchor)\n\t}\n\n\tprivate updateTooltip = () => {\n\t\tconst {\n\t\t\tstores: { toolStore },\n\t\t\thandle,\n\t\t} = this.engine\n\n\t\tif (!this.startRect) return\n\t\tif (!handle) return\n\n\t\ttoolStore.tooltip = `${roundedNumber(this.absoluteScaleFactor, 2)}${MULT_SYMBOL}`\n\t}\n\n\tprivate updateScaleSourcesForTracking() {\n\t\tthis.hasScaledWithDimensionInput ||= this.currentScaleSource === \"dimensionInput\"\n\t\tthis.hasScaledWithScaleInput ||= this.currentScaleSource === \"scaleInput\"\n\t\tthis.hasScaledWithHandle ||= this.currentScaleSource === \"handle\"\n\t\tthis.currentScaleSource = null\n\t}\n\n\tprivate recordTrackingEvent(eventType: \"apply\" | \"cancel\") {\n\t\tconst openDurationMs = Math.round(performance.now() - this.startMs)\n\t\tswitch (eventType) {\n\t\t\tcase \"apply\":\n\t\t\t\trecord(\"scale_tool_apply\", {\n\t\t\t\t\tanchorX: this.anchor.x,\n\t\t\t\t\tanchorY: this.anchor.y,\n\t\t\t\t\topenDurationMs,\n\t\t\t\t\tselectionCount: this.selectedNodeIds.length,\n\t\t\t\t\tscaleFactor: roundedNumber(this.absoluteScaleFactor, 2),\n\t\t\t\t\twithHandle: this.hasScaledWithHandle,\n\t\t\t\t\twithScaleInput: this.hasScaledWithScaleInput,\n\t\t\t\t\twithDimensionInput: this.hasScaledWithDimensionInput,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\tcase \"cancel\":\n\t\t\t\trecord(\"scale_tool_cancel\", {\n\t\t\t\t\tselectionCount: this.selectedNodeIds.length,\n\t\t\t\t\topenDurationMs,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tassertNever(eventType)\n\t\t}\n\t}\n\n\t/**\n\t * To keep the state in sync after undo/redo we need to keep track of the undo/redo steps ourselves. This method\n\t * will be called by the engine when undoing and the standard undo/redo logic will not be executed. Other benefits\n\t * of this approach are: anchor is set correctly after undo/redo, state is tracked correctly across different selections,\n\t * and undoing when the buffer is empty will cancel the tool.\n\t *\n\t * Undo/redo works as follows:\n\t * - The last change is stored at `this.lastChange`\n\t * - If the current change is considered a new change (not part of a continuous handle move or dimension input change)\n\t *   then `this.lastChange` is pushed into the undo buffer\n\t * - If it is not a new change then `this.lastChange` is updated to the current change\n\t * - On undo we take the current state and push it into the redo buffer, then apply the changes from the undo buffer\n\t * - On redo we take the current state and push it into the undo buffer, then apply the changes from the redo buffer\n\t * - When applying changes from either buffer we set `this.applyingUndoRedoChanges` to avoid confusing `this.lastChange`\n\t */\n\toverride undo() {\n\t\tconst entry = this.undoBuffer.pop()\n\t\tif (!entry) {\n\t\t\tthis.engine.cancelTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst redoEntry = this.lastChange ?? this.getNewUndoEntry()\n\t\tthis.applyUndoRedoChanges(entry)\n\n\t\tthis.redoBuffer.push(redoEntry)\n\t}\n\n\toverride redo() {\n\t\tconst entry = this.redoBuffer.pop()\n\t\tif (!entry) return\n\n\t\tconst undoEntry = this.lastChange ?? this.getNewUndoEntry()\n\t\tthis.applyUndoRedoChanges(entry)\n\n\t\tthis.undoBuffer.push(undoEntry)\n\t}\n\n\tprivate applyUndoRedoChanges(entry: ScaleUndoEntry) {\n\t\tconst { selectionOutlineTracker, selectionStore } = this.engine.stores\n\t\tselectionOutlineTracker.forceEnableSelectionOutline()\n\t\tif (!isEqual(this.selectedNodeIds, entry.selectedNodeIds, true)) {\n\t\t\tthis.selectedNodeIds = entry.selectedNodeIds\n\t\t\tselectionStore.set(this.selectedNodeIds)\n\t\t}\n\n\t\tthis.anchor = entry.anchor\n\t\tthis.baseScaleFactor = entry.baseScaleFactor\n\t\tthis.relativeScaleFactor = entry.relativeScaleFactor\n\t\tthis.startRect = entry.startRect\n\t\tthis.lastScaleResetStateToken = entry.lastScaleResetStateToken\n\t\tthis.contextNode = entry.contextNode\n\t\tthis.contextNodeStartMatrix = entry.contextNodeStartMatrix\n\t\tthis.selectedNodeIds = entry.selectedNodeIds\n\t\tthis.initialNodeState = entry.initialNodeState\n\n\t\tthis.applyingUndoRedoChanges = true\n\t\t// overwrite the source so that it will get pushed onto the undo buffer immediately\n\t\t// with the next action\n\t\tthis.lastChange = { ...entry, source: null }\n\t}\n\n\tprivate getNewUndoEntry(overrides: Partial<ScaleUndoEntry> = {}): ScaleUndoEntry {\n\t\tassert(this.lastScaleResetStateToken !== null, \"Last scale reset state token must be initialized\")\n\n\t\treturn {\n\t\t\tanchor: this.anchor,\n\t\t\tbaseScaleFactor: this.baseScaleFactor,\n\t\t\trelativeScaleFactor: this.relativeScaleFactor,\n\t\t\tinitialNodeState: this.initialNodeState,\n\t\t\tlastScaleResetStateToken: this.lastScaleResetStateToken,\n\t\t\tlastUpdatedTimestamp: performance.now(),\n\t\t\tcontextNode: this.contextNode,\n\t\t\tcontextNodeStartMatrix: this.contextNodeStartMatrix,\n\t\t\tselectedNodeIds: this.selectedNodeIds,\n\t\t\tstartRect: this.startRect,\n\t\t\tsource: this.currentScaleSource,\n\t\t\t...overrides,\n\t\t}\n\t}\n\n\t/**\n\t * Update state required to manage the undo/redo buffers. We make a best effort to merge\n\t * changes that are likely to be from one continuous user interaction into a single undo entry, for example\n\t * a single drag of a handle, or a multiple nudges in the dimension inputs.\n\t */\n\tprivate updateUndoBuffer() {\n\t\tif (this.applyingUndoRedoChanges) {\n\t\t\tthis.applyingUndoRedoChanges = false\n\t\t\treturn\n\t\t}\n\n\t\tconst currentChange = this.getNewUndoEntry()\n\n\t\tif (shouldPushUndoEntry(this.lastChange, currentChange)) {\n\t\t\tthis.undoBuffer.push(this.lastChange)\n\t\t}\n\n\t\tthis.lastChange = currentChange\n\t\tthis.redoBuffer.length = 0\n\t}\n}\n\nconst dimensionInputChangeTimeout = 500\n/**\n * Determine if the current change is a continuation of the last change or if we should push to the undo buffer\n */\nfunction shouldPushUndoEntry(\n\tlastChange: ScaleUndoEntry | null,\n\tcurrentChange: ScaleUndoEntry,\n): lastChange is ScaleUndoEntry {\n\tif (!lastChange) return false\n\t// scale input always creates a new undo entry\n\tif (currentChange.source === \"scaleInput\") return true\n\tif (!Point.isEqual(lastChange.anchor, currentChange.anchor)) return true\n\tif (\n\t\tcurrentChange.source === \"dimensionInput\" &&\n\t\tcurrentChange.lastUpdatedTimestamp - lastChange.lastUpdatedTimestamp > dimensionInputChangeTimeout\n\t) {\n\t\treturn true\n\t}\n\tif (!isEqual(lastChange.selectedNodeIds, currentChange.selectedNodeIds, true)) return true\n\n\treturn false\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { RichTextNode } from \"document/models/CanvasTree/nodes/RichTextNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { BaseVariableEditTool, type BaseVariableEditToolOptions } from \"./BaseVariableEditTool.ts\"\nimport type { TextEditEventSource } from \"./TextEditTool.ts\"\n\nexport interface StringVariableEditToolOptions extends BaseVariableEditToolOptions {\n\treadonly eventSource?: TextEditEventSource\n}\n\nexport class StringVariableEditTool extends withClassDiscriminator(\n\t\"StringVariableEditTool\",\n\tBaseVariableEditTool as typeof BaseVariableEditTool<ControlType.String>,\n) {\n\toverride readonly enum = Tools.StringVariableEdit\n\toverride readonly controlType = ControlType.String\n\n\tprivate resumeCodeGeneration?: () => void\n\n\treadonly eventSource: TextEditEventSource\n\n\tconstructor(engine: VekterEngine, options: StringVariableEditToolOptions) {\n\t\tsuper(engine, options)\n\t\tthis.eventSource = options?.eventSource ?? \"none\"\n\t}\n\n\tget supportsMultiline() {\n\t\tconst variableInfo = this.getVariableInfo()\n\t\treturn variableInfo?.variableDefinition.options?.displayTextArea\n\t}\n\n\toverride getNode(): RichTextNode | null {\n\t\treturn this.engine.tree.getNodeWithTrait(this.nodeId, isRichTextNode)\n\t}\n\n\toverride start() {\n\t\tconst engine = this.engine\n\t\tengine.beginUndoGroup()\n\n\t\tconst richTextNode = this.getNode()\n\t\tif (!richTextNode) return engine.exitTool()\n\n\t\tconst variableInfo = this.getVariableInfo()\n\t\tif (!variableInfo) return engine.exitTool()\n\n\t\t// Pause code generation until exiting the tool as it can be expensive.\n\t\tthis.resumeCodeGeneration = engine.stores.codeGenerationStore.pauseCodeGeneration(variableInfo.collectionNode.id)\n\n\t\trichTextNode.cache.isEditable = true\n\t}\n\n\toverride async stop() {\n\t\tconst engine = this.engine\n\t\tconst toolStore = engine.stores.toolStore\n\n\t\tconst richTextNode = this.getNode()\n\n\t\tif (richTextNode) {\n\t\t\trichTextNode.cache.isEditable = false\n\t\t}\n\n\t\tthis.resumeCodeGeneration?.()\n\n\t\tengine.scheduler.process(() => {\n\t\t\tengine.endUndoGroup()\n\n\t\t\t// This is set inside `StringVariableEditor.tsx`.\n\t\t\ttoolStore.nodeInTextEditorId = null\n\t\t})\n\t}\n\n\tgetValue() {\n\t\tconst controlProp = this.getControlProp()\n\t\tif (!controlProp) return\n\n\t\treturn controlProp.value\n\t}\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, MaybeNodeID, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport type { WithViewport } from \"document/models/CanvasTree/traits/WithViewport.ts\"\nimport {\n\tcanNodeProvideViewportRect,\n\tgetViewportHeight,\n} from \"document/models/CanvasTree/traits/utils/viewportHelpers.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { DimensionType } from \"library/render/types/Constraints.ts\"\nimport * as Cursor from \"utils/cursor.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { mouseActionType } from \"./utils/mouseActionType.tsx\"\n\nexport interface ViewportResizeToolOptions {\n\tvariantNodeId: MaybeNodeID\n\tattachToNode: NodeID | undefined\n}\n\n/**\n * Manage resizing the viewport height of a web page breakpoint.\n *\n * The viewportHeight of a web page has no impact on the generated code, but\n * allows visualizing how fixed position elements will appear in the published\n * site when pinned to the bottom of the viewport.\n */\nexport class ViewportResizeTool extends withClassDiscriminator(\"ViewportResizeTool\", VekterTool) {\n\toverride readonly enum = Tools.ViewportResize\n\n\tvariantNodeId: MaybeNodeID\n\tattachToNode: boolean\n\n\t// FIXME: the ! is unsafe; it is assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where this field is undefined\n\tinitialViewportHeight!: number\n\n\toverride displaySelectionBox = false\n\toverride displaySelectionHandles = false\n\toverride displayViewportHandle = true\n\toverride displayViewportLabel = false\n\n\t/**\n\t * Track the delta to inform whether to send a viewport resize tracking\n\t * update.\n\t */\n\tdelta: number = 0\n\n\tconstructor(engine: VekterEngine, { variantNodeId, attachToNode }: ViewportResizeToolOptions) {\n\t\tsuper(engine)\n\t\tthis.variantNodeId = variantNodeId\n\t\tthis.attachToNode = !!attachToNode\n\t}\n\n\toverride start() {\n\t\tif (!this.variantNodeId) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst variantNode = this.engine.tree.getNode(this.variantNodeId)\n\t\tif (!variantNode || !this.engine.tree.isGroundNode(variantNode) || !canNodeProvideViewportRect(variantNode)) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.engine.beginUndoGroup()\n\n\t\t// When the viewport resize handle is attached to the node bottom (when the selection is vh nodes), always use\n\t\t// the absolute viewport height, as the screen height may depend on the node's height.\n\t\tthis.initialViewportHeight = getViewportHeight(\n\t\t\tvariantNode,\n\t\t\tthis.engine.tree.getRect(variantNode),\n\t\t\t!this.attachToNode,\n\t\t)\n\t\tthis.displayViewportLabel = true\n\t\tthis.updateCursor()\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { previous, latest } = this.engine.stores.mouseStore\n\t\tconst { canvasMouseDownPosition, canvasMousePosition } = latest\n\n\t\t// Make sure the node being edited still exists, in multi-user scenarios they might get deleted.\n\t\tconst variantNode = tree.get(this.variantNodeId)\n\t\tif (!this.variantNodeId || !variantNode) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || !canvasMousePosition) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst mouseAction = mouseActionType(latest, previous)\n\t\tif (mouseAction !== \"mouseMove\") return\n\n\t\tconst delta = canvasMousePosition.y - canvasMouseDownPosition.y\n\t\tconst autoHeight = isPinnable(variantNode) && variantNode.heightType === DimensionType.Auto\n\t\tconst maxHeight = isBreakpointVariant(variantNode) && !autoHeight ? tree.getRect(variantNode).height : Infinity\n\t\tconst newViewportHeight = Math.max(Math.round(this.initialViewportHeight + delta), 0)\n\n\t\tconst nodeUpdate: Partial<WithViewport> = {\n\t\t\t// Do not exceed the height of the webpage.\n\t\t\tviewportHeight: Math.min(newViewportHeight, maxHeight),\n\t\t}\n\n\t\tthis.delta = nodeUpdate.viewportHeight ?? 0\n\t\tthis.engine.tree.get<CanvasNode & WithViewport>(this.variantNodeId)?.set(nodeUpdate)\n\t}\n\n\toverride async stop() {\n\t\tthis.engine.stores.mouseCursorStore.clear()\n\t\tthis.engine.endUndoGroup()\n\t\tif (this.delta > 0) record(\"site_viewport_height_update\", {})\n\t}\n\n\tupdateCursor() {\n\t\tthis.engine.stores.mouseCursorStore.current = Cursor.cursorImage(\"resize-north-south\")\n\t}\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { VekterTool } from \"document/VekterTool.ts\"\nimport type { CanvasNode, RichTextNode } from \"document/models/CanvasTree/index.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withColorable } from \"document/models/CanvasTree/traits/WithColorable.ts\"\nimport type { WithFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport {\n\thasActiveGradientFill,\n\tisGradientFillType,\n\tsupportsGradient,\n\tsupportsGradientProps,\n\twithFill,\n} from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport type { WithMasks } from \"document/models/CanvasTree/traits/WithMasks.ts\"\nimport {\n\tisGradientMaskType,\n\tsupportsMaskGradientProps,\n\twithMasks,\n} from \"document/models/CanvasTree/traits/WithMasks.ts\"\nimport type { MasksByNodeId } from \"document/models/CanvasTree/traits/utils/reduceMasks.ts\"\nimport type { Gradient, GradientTool } from \"document/models/Gradient.ts\"\nimport {\n\tconicGradientUpdate,\n\tgetActiveGradient,\n\tgetNodeMaskForMaskId,\n\tlinearGradientUpdate,\n\tradialGradientUpdate,\n\tupdateMaskGradientForNode,\n} from \"document/models/Gradient.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { isSelectable } from \"../utils/isSelectable.ts\"\nimport type { VekterGradientTool } from \"./types.ts\"\nimport type { GradientCoordinates } from \"./utils.ts\"\nimport { gradientCoordinates, gradientInRange } from \"./utils.ts\"\n\nconst log = getLogger(\"GradientToolManager\")\n\ntype GradientNode = (CanvasNode & (WithFill | WithMasks)) | RichTextNode\n\nabstract class GradientToolManagerTool extends withClassDiscriminator(\"GradientToolManagerTool\", VekterTool) {\n\tconstructor(\n\t\tengine: VekterEngine,\n\t\treadonly maskIds: MasksByNodeId | null = null,\n\t) {\n\t\tsuper(engine)\n\t}\n\n\tabstract override readonly enum: Tools.FillGradient | Tools.MaskGradient\n\ttool: VekterGradientTool | null = null\n\t// FIXME: ! is unsafe; it is assigned in `.start()`, but not in the constructor,\n\t// so there\u2019s a period of time where this field is undefined\n\tcoordinates!: GradientCoordinates\n\t/**\n\t * Old RichTextNode's might have gradient fills without data-stopids. This\n\t * means that on selection a lookup by id will fail, in those cases we can\n\t * fallback to the index.\n\t */\n\tfallbackGradientStopIndex: number | null = null\n\n\tselectFirstStop(gradient: Gradient | null) {\n\t\tif (!gradient) return undefined\n\t\tthis.engine.scheduler.processWhenReady(() => {\n\t\t\tthis.engine.stores.selectionStore.gradientStopId = gradient.stops[0]?.id\n\t\t})\n\t}\n\n\t#lastGradientNode: GradientNode | null = null\n\tget gradientNode(): GradientNode | null {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore } = this.engine.stores\n\n\t\tfor (const selectedNodeId of selectionStore.ids) {\n\t\t\tconst node = tree.getNode(selectedNodeId)\n\t\t\tif (!node) continue\n\t\t\tif (withColorable(node) && !node.colorable) continue\n\t\t\tconst maskId = this.maskIds?.[node.id]\n\n\t\t\tif (\n\t\t\t\tisRichTextNode(node) ||\n\t\t\t\t(supportsGradientProps(node) && isGradientFillType(node.fillType)) ||\n\t\t\t\t(supportsMaskGradientProps(node) &&\n\t\t\t\t\tmaskId &&\n\t\t\t\t\tisGradientMaskType(getNodeMaskForMaskId(node, maskId)?.value.maskType))\n\t\t\t) {\n\t\t\t\tif (this.#lastGradientNode?.id !== node.id) this.selectFirstStop(getActiveGradient(node, this))\n\t\t\t\treturn (this.#lastGradientNode = node)\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n\n\toverride start() {\n\t\tconst gradientNode = this.gradientNode\n\t\tconst gradient = getActiveGradient(gradientNode, this)\n\n\t\tif (!gradientNode || !gradient) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst coordinates = gradientCoordinates(this.engine.tree, gradientNode, gradient)\n\t\tif (!coordinates) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tthis.coordinates = coordinates\n\t}\n\n\toverride stop() {\n\t\tthis.engine.stores.toolStore.tooltip = undefined\n\t\tif (this.tool) {\n\t\t\tthis.tool.stop()\n\t\t}\n\t}\n\n\toverride onKeyDown = (event: KeyboardEvent) => {\n\t\tswitch (event.key) {\n\t\t\tcase \"Delete\":\n\t\t\tcase \"Backspace\":\n\t\t\t\tif (this.canDelete()) this.deleteAction()\n\t\t\t\tbreak\n\t\t\tcase \"ArrowUp\":\n\t\t\tcase \"ArrowDown\":\n\t\t\t\tthis.moveStop(event.key === \"ArrowUp\", event.shiftKey)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\tmoveStop(increase: boolean, shift: boolean) {\n\t\tconst node = this.gradientNode\n\t\tconst { gradientStopId: stopId } = this.engine.stores.selectionStore\n\t\tif (!node || !stopId) return\n\n\t\tconst gradient = getActiveGradient(node, this)\n\t\tif (!gradient) return\n\n\t\tconst stopIndex = gradient.stops.findIndex(stop => stop.id === stopId)\n\t\tconst stop = gradient.stops[stopIndex]\n\t\tif (!stop) return\n\n\t\tconst stops = [...gradient.stops]\n\n\t\tlet increment = increase ? 0.01 : -0.01\n\t\tif (shift) increment *= 5\n\n\t\tlet position = stop.position + increment\n\t\tif (shift) position = Math.round(position / 0.05) * 0.05\n\n\t\tstops.splice(stopIndex, 1, stop.merge({ position }))\n\n\t\tconst type = this.enum\n\t\tif (isRichTextNode(node) && type === Tools.FillGradient) {\n\t\t\tnode.setFill(gradient.updated({ stops }))\n\t\t\treturn\n\t\t}\n\t\tif (type === Tools.FillGradient && withFill(node)) {\n\t\t\tnode.set({\n\t\t\t\tfillLinearGradient: linearGradientUpdate(node, { stops }, type),\n\t\t\t\tfillRadialGradient: radialGradientUpdate(node, { stops }, type),\n\t\t\t\tfillConicGradient: conicGradientUpdate(node, { stops }, type),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif (type === Tools.MaskGradient && withMasks(node)) {\n\t\t\tconst maskId = this.maskIds?.[node.id]\n\t\t\tif (maskId) {\n\t\t\t\tupdateMaskGradientForNode(node, maskId, {\n\t\t\t\t\tmaskLinearGradient: { stops },\n\t\t\t\t\tmaskRadialGradient: { stops },\n\t\t\t\t\tmaskConicGradient: { stops },\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\toverride deleteAction(): void {\n\t\tconst node = this.gradientNode\n\t\tconst { gradientStopId: stopId } = this.engine.stores.selectionStore\n\t\tif (!node || !stopId) return\n\n\t\tconst type = this.enum\n\t\tconst gradient = getActiveGradient(node, this)\n\t\tif (!gradient) return\n\n\t\tconst stops = [...gradient.stops]\n\t\tconst deletingStopIndex = stops.findIndex(stop => stop.id === stopId)\n\t\tconst nextAvailableStopIndex = deletingStopIndex >= stops.length - 1 ? 0 : deletingStopIndex\n\n\t\tstops.splice(deletingStopIndex, 1)\n\n\t\tconst nextGradient = gradient.updated({ stops })\n\t\tif (!nextGradient) return\n\n\t\tif (isRichTextNode(node) && type === Tools.FillGradient) {\n\t\t\tnode.setFill(nextGradient)\n\t\t} else if (type === Tools.FillGradient && withFill(node)) {\n\t\t\tnode.set({\n\t\t\t\tfillLinearGradient: linearGradientUpdate(node, { stops }, type),\n\t\t\t\tfillRadialGradient: radialGradientUpdate(node, { stops }, type),\n\t\t\t\tfillConicGradient: conicGradientUpdate(node, { stops }, type),\n\t\t\t})\n\t\t} else if (type === Tools.MaskGradient && withMasks(node)) {\n\t\t\tconst maskId = this.maskIds?.[node.id]\n\t\t\tif (maskId) {\n\t\t\t\tupdateMaskGradientForNode(node, maskId, {\n\t\t\t\t\tmaskLinearGradient: { stops },\n\t\t\t\t\tmaskRadialGradient: { stops },\n\t\t\t\t\tmaskConicGradient: { stops },\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst nextAvailableStop = stops[nextAvailableStopIndex]\n\t\tthis.engine.stores.selectionStore.gradientStopId = nextAvailableStop?.id\n\t}\n\n\toverride canDelete(): boolean {\n\t\tconst gradient = getActiveGradient(this.gradientNode, this)\n\t\treturn Boolean(this.engine.stores.selectionStore.gradientStopId && gradient && gradient.stops.length > 2)\n\t}\n\n\t/**\n\t * Update the coordinates of the gradient tool. This should be called by child tools that the tool manager orchestrates when\n\t * the child tools change the coordinates of the gradient,\n\t */\n\tupdateCoordinates() {\n\t\tconst gradientNode = this.gradientNode\n\t\tconst gradient = getActiveGradient(gradientNode, this)\n\t\tif (!gradientNode || !gradient) return\n\t\tconst coordinates = gradientCoordinates(this.engine.tree, gradientNode, gradient)\n\t\tif (!coordinates) return\n\t\tthis.coordinates = coordinates\n\t}\n\n\toverride update() {\n\t\tconst { tree } = this.engine\n\t\tconst { selectionStore, mouseStore, treeStore, scopeStore, canvasStore, persistedUserDefaults } = this.engine.stores\n\t\tconst { previous, latest } = mouseStore\n\t\tconst { canvasMouseDownPosition, cmdKey, shiftKey } = latest\n\t\tconst node = this.gradientNode\n\n\t\tif (!node) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst type = this.enum\n\t\tconst nodeCanBeGradient = nodeSupportsGradient(node, type)\n\t\tconst nodeGradient = nodeHasActiveGradient(node, type)\n\n\t\tif (!node || !nodeCanBeGradient || !nodeGradient) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tif (this.tool) {\n\t\t\tthis.tool.update()\n\t\t}\n\n\t\tif (!canvasMouseDownPosition || previous.canvasMouseDownPosition) {\n\t\t\treturn\n\t\t}\n\n\t\tconst gradient = getActiveGradient(node, this)\n\t\tif (!gradient) return\n\n\t\tconst coordinates = this.coordinates\n\t\tif (!coordinates) return\n\n\t\tif (gradientInRange(coordinates, gradient.stops, canvasMouseDownPosition, 30 / canvasStore.zoom)) return\n\n\t\tconst nodesAtPoint = tree.getNodesAtPoint(scopeStore.active, canvasMouseDownPosition, true, canvasStore.zoom < 4)\n\t\tconst selectableNodes = nodesAtPoint.filter(nodeItem => {\n\t\t\treturn isSelectable({\n\t\t\t\tnode: nodeItem,\n\t\t\t\tengine: this.engine,\n\t\t\t\tcmdKey,\n\t\t\t\tuseDirectSelect: persistedUserDefaults.useDirectSelect,\n\t\t\t})\n\t\t})\n\n\t\tconst selectableTopNode = tree.getTopMostChildNode(selectableNodes)\n\n\t\tif (!selectableTopNode) {\n\t\t\tselectionStore.clear()\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst id = selectableTopNode.id\n\t\tconst elementPartOfSelection = selectableTopNode.isSelected()\n\n\t\tif (shiftKey) {\n\t\t\tif (elementPartOfSelection && selectionStore.ids.length === 1) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tselectionStore.toggle(id)\n\t\t\tthis.updateCoordinates()\n\t\t} else if (!elementPartOfSelection) {\n\t\t\tselectionStore.set(id)\n\t\t\ttreeStore.setHighlight(null)\n\t\t\tthis.updateCoordinates()\n\t\t}\n\t}\n\n\t// FIXME: accept Tools enum type for `tool` instead of an initialized tool\n\tsetTool(tool: VekterGradientTool | VekterTool | null) {\n\t\tconst oldName = this.tool ? this.tool.__class : \"null\"\n\t\tconst newName = tool?.__class\n\t\tlog.debug(\"GradientToolManagerTool.setTool():\", oldName, \"->\", newName)\n\n\t\tif (this.tool) {\n\t\t\tthis.tool.stop()\n\t\t}\n\n\t\tthis.tool = tool as VekterGradientTool\n\t\tif (!this.tool) return\n\n\t\tthis.tool.gradientEngine = this\n\t\tthis.tool.start()\n\t}\n\n\tsetDefault() {\n\t\tthis.setTool(null)\n\t}\n}\n\nexport class GradientMaskToolManagerTool extends GradientToolManagerTool {\n\toverride readonly enum = Tools.MaskGradient\n}\n\nexport class GradientFillToolManagerTool extends GradientToolManagerTool {\n\toverride readonly enum = Tools.FillGradient\n}\n\nexport type GradientToolManagerToolType = GradientFillToolManagerTool | GradientMaskToolManagerTool\n\nfunction nodeSupportsGradient(node: CanvasNode, type: GradientTool) {\n\tif (type === Tools.FillGradient) {\n\t\treturn (withFill(node) || isRichTextNode(node)) && supportsGradient(node)\n\t} else {\n\t\treturn withMasks(node) && supportsMaskGradientProps(node)\n\t}\n}\n\nfunction nodeHasActiveGradient(node: CanvasNode, type: GradientTool) {\n\tif (type === Tools.FillGradient) {\n\t\treturn (withFill(node) || isRichTextNode(node)) && hasActiveGradientFill(node)\n\t} else {\n\t\treturn withMasks(node) && supportsMaskGradientProps(node)\n\t}\n}\n", "import { assertNever } from \"@framerjs/shared\"\nimport { CreateVideoTool } from \"document/components/tools/CreateCodeComponentTool.ts\"\nimport {\n\tCreateColumnsTool,\n\tCreateFrameTool,\n\tCreateGridRowTool,\n\tCreateGridSpanTool,\n\tCreateGridTool,\n\tCreateImageTool,\n\tCreateMasonryTool,\n\tCreateRoundedTool,\n\tCreateRowsTool,\n\tCreateScreenTool,\n\tCreateStackTool,\n} from \"document/components/tools/CreateFrameTool.ts\"\nimport {\n\tCreateOvalShapeTool,\n\tCreatePolygonShapeTool,\n\tCreateRectangleShapeTool,\n\tCreateStarShapeTool,\n} from \"document/components/tools/CreateShapeTool.ts\"\nimport { CreateTextTool } from \"document/components/tools/CreateTextTool.ts\"\nimport { DirectSelectTool, HighlightTool } from \"document/components/tools/HighlightTool.ts\"\nimport { MoveTool } from \"document/components/tools/MoveTool.ts\"\nimport { PanTool } from \"document/components/tools/Pan.tsx\"\nimport { RadiusTool } from \"document/components/tools/RadiusTool.ts\"\nimport { ResizeTool } from \"document/components/tools/ResizeTool.ts\"\nimport { RotateTool } from \"document/components/tools/Rotate.tsx\"\nimport { SampleColorTool } from \"document/components/tools/SampleColor.tsx\"\nimport { SelectTool } from \"document/components/tools/Select.tsx\"\nimport { SlotConnectTool } from \"document/components/tools/SlotConnectTool.ts\"\nimport { TextEditTool } from \"document/components/tools/TextEditTool.ts\"\nimport { ZoomTool } from \"document/components/tools/Zoom.ts\"\nimport { ZoomSelectTool } from \"document/components/tools/ZoomSelectTool.ts\"\nimport { LinkTool } from \"document/components/tools/linkTool/LinkTool.ts\"\nimport { VekterPathEngine } from \"document/components/tools/pathEdit/PathToolManager.tsx\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport type { VekterToolClass } from \"./VekterTool.ts\"\nimport { AgentPanelTool } from \"./components/tools/AgentPanelTool.ts\"\nimport { AgentDragSelectTool, AgentSelectTool } from \"./components/tools/AgentSelectTool.ts\"\nimport { ChatTool } from \"./components/tools/Chat.tsx\"\nimport { CollectionReferenceVariableEditTool } from \"./components/tools/CollectionReferenceVariableEditTool.ts\"\nimport { DateVariableEditTool } from \"./components/tools/DateVariableEditTool.ts\"\nimport { EnumVariableEditTool } from \"./components/tools/EnumVariableEditTool.ts\"\nimport { FeedbackTool } from \"./components/tools/Feedback.tsx\"\nimport { GapTool } from \"./components/tools/Gap.tsx\"\nimport { GuideMoveTool } from \"./components/tools/GuideMoveTool.ts\"\nimport { HighlightStackItemTool } from \"./components/tools/HighlightStackItem.tsx\"\nimport { LineAnchorMoveTool } from \"./components/tools/LineAnchorMove.ts\"\nimport { LoadingShieldTool } from \"./components/tools/LoadingShieldTool.ts\"\nimport { PaddingTool } from \"./components/tools/Padding.tsx\"\nimport { RichTextEditTool } from \"./components/tools/RichTextEditTool.ts\"\nimport { RichTextVariableEditTool } from \"./components/tools/RichTextVariableEditTool.ts\"\nimport { ScaleTool } from \"./components/tools/ScaleTool.ts\"\nimport { StringVariableEditTool } from \"./components/tools/StringVariableEditTool.ts\"\nimport { ViewportResizeTool } from \"./components/tools/ViewportResize.tsx\"\nimport {\n\tGradientFillToolManagerTool,\n\tGradientMaskToolManagerTool,\n} from \"./components/tools/gradient/GradientToolManagerTool.tsx\"\n\nexport function toolClassFor(tool: Tools): VekterToolClass | null {\n\tswitch (tool) {\n\t\tcase Tools.AgentPanel:\n\t\t\treturn AgentPanelTool\n\t\tcase Tools.AgentDragSelect:\n\t\t\treturn AgentDragSelectTool\n\t\tcase Tools.AgentSelect:\n\t\t\treturn AgentSelectTool\n\t\tcase Tools.Move:\n\t\t\treturn MoveTool\n\t\tcase Tools.Resize:\n\t\t\treturn ResizeTool\n\t\tcase Tools.Scale:\n\t\t\treturn ScaleTool\n\t\tcase Tools.Padding:\n\t\t\treturn PaddingTool\n\t\tcase Tools.Gap:\n\t\t\treturn GapTool\n\t\tcase Tools.ViewportResize:\n\t\t\treturn ViewportResizeTool\n\t\tcase Tools.Rotate:\n\t\t\treturn RotateTool\n\t\tcase Tools.CollectionReferenceVariableEdit:\n\t\t\treturn CollectionReferenceVariableEditTool\n\t\tcase Tools.CreateRounded:\n\t\t\treturn CreateRoundedTool\n\t\tcase Tools.CreateFrame:\n\t\t\treturn CreateFrameTool\n\t\tcase Tools.CreateImage:\n\t\t\treturn CreateImageTool\n\t\tcase Tools.CreateVideo:\n\t\t\treturn CreateVideoTool\n\t\tcase Tools.CreateScreen:\n\t\t\treturn CreateScreenTool\n\t\tcase Tools.CreateStack:\n\t\t\treturn CreateStackTool\n\t\tcase Tools.CreateRows:\n\t\t\treturn CreateRowsTool\n\t\tcase Tools.CreateColumns:\n\t\t\treturn CreateColumnsTool\n\t\tcase Tools.CreateGrid:\n\t\t\treturn CreateGridTool\n\t\tcase Tools.CreateGridRow:\n\t\t\treturn CreateGridRowTool\n\t\tcase Tools.CreateGridSpan:\n\t\t\treturn CreateGridSpanTool\n\t\tcase Tools.CreateMasonry:\n\t\t\treturn CreateMasonryTool\n\t\tcase Tools.Guide:\n\t\t\treturn GuideMoveTool\n\t\tcase Tools.Highlight:\n\t\t\treturn HighlightTool\n\t\tcase Tools.DirectSelect:\n\t\t\treturn DirectSelectTool\n\t\tcase Tools.Select:\n\t\t\treturn SelectTool\n\t\tcase Tools.Path:\n\t\t\treturn VekterPathEngine\n\t\tcase Tools.Pan:\n\t\t\treturn PanTool\n\t\tcase Tools.Zoom:\n\t\t\treturn ZoomTool\n\t\tcase Tools.ZoomSelect:\n\t\t\treturn ZoomSelectTool\n\t\tcase Tools.Radius:\n\t\t\treturn RadiusTool\n\t\tcase Tools.SampleColor:\n\t\t\treturn SampleColorTool\n\t\tcase Tools.FillGradient:\n\t\t\treturn GradientFillToolManagerTool\n\t\tcase Tools.MaskGradient:\n\t\t\treturn GradientMaskToolManagerTool\n\t\tcase Tools.TextEdit:\n\t\t\treturn TextEditTool\n\t\tcase Tools.RichTextEdit:\n\t\t\treturn RichTextEditTool\n\t\tcase Tools.RichTextVariableEdit:\n\t\t\treturn RichTextVariableEditTool\n\t\tcase Tools.DateVariableEdit:\n\t\t\treturn DateVariableEditTool\n\t\tcase Tools.EnumVariableEdit:\n\t\t\treturn EnumVariableEditTool\n\t\tcase Tools.StringVariableEdit:\n\t\t\treturn StringVariableEditTool\n\t\tcase Tools.CreateText:\n\t\t\treturn CreateTextTool\n\t\tcase Tools.CreateRectangleShape:\n\t\t\treturn CreateRectangleShapeTool\n\t\tcase Tools.CreateOvalShape:\n\t\t\treturn CreateOvalShapeTool\n\t\tcase Tools.CreatePolygonShape:\n\t\t\treturn CreatePolygonShapeTool\n\t\tcase Tools.CreateStarShape:\n\t\t\treturn CreateStarShapeTool\n\t\tcase Tools.SlotConnect:\n\t\t\treturn SlotConnectTool\n\t\tcase Tools.Link:\n\t\t\treturn LinkTool\n\t\tcase Tools.LoadingShield:\n\t\t\treturn LoadingShieldTool\n\t\tcase Tools.Chat:\n\t\t\treturn ChatTool\n\t\tcase Tools.Comment:\n\t\t\treturn FeedbackTool\n\t\tcase Tools.LineAnchorMove:\n\t\t\treturn LineAnchorMoveTool\n\t\tcase Tools.HighlightStackItem:\n\t\t\treturn HighlightStackItemTool\n\t\tcase Tools.Unknown:\n\t\t\treturn null\n\t\tdefault:\n\t\t\treturn assertNever(tool)\n\t}\n}\n", "import type { VekterEngine } from \"./VekterEngine.ts\"\nimport type { VekterTool } from \"./VekterTool.ts\"\nimport type { Tools } from \"./stores/ToolEnum.ts\"\nimport { toolClassFor } from \"./toolClassFor.ts\"\n\nexport function newToolFor(engine: VekterEngine, tool: Tools, arg?: unknown): VekterTool {\n\tconst cls = toolClassFor(tool)\n\tif (!cls) throw Error(\"call with a known tool\")\n\tif (arg) {\n\t\treturn new cls(engine, arg)\n\t}\n\treturn new cls(engine)\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\nimport { environment } from \"environment/index.ts\"\n\ntype State = \"loading\" | \"loaded\" | { failedWith: Error }\n\n/**\n * Three-state load tracking.\n *\n * Closed set of states: still loading, successfully loaded, or finished\n * loading with an error.\n * Must be constructed via `LoadingState.loading`, `LoadingState.loaded`, or `LoadingState.failed(error)`, and\n * is immutable after construction. Consumers can check the state via the `isLoaded`, `isFinished`, and `failure` getters.\n */\nexport class LoadingState {\n\tprivate constructor(private readonly state: State) {}\n\n\tstatic readonly loading: LoadingState = new LoadingState(\"loading\")\n\tstatic readonly loaded: LoadingState = new LoadingState(\"loaded\")\n\tstatic failed(error: Error): LoadingState {\n\t\treturn new LoadingState({ failedWith: error })\n\t}\n\n\t/** `true` only on successful load. */\n\tget isLoaded(): boolean {\n\t\treturn this.state === \"loaded\"\n\t}\n\n\t/** `true` on either successful or errored load; `false` only while still loading. */\n\tget isFinished(): boolean {\n\t\treturn this.state !== \"loading\"\n\t}\n\n\t/** The captured `Error` if the load finished with a failure, otherwise `undefined`. */\n\tget failure(): Error | undefined {\n\t\treturn typeof this.state === \"object\" ? this.state.failedWith : undefined\n\t}\n}\n\nexport class LoadingStore extends EngineStore {\n\t/** Indicates an error has occurred while loading the document. */\n\thasError = false\n\n\t/** True when there should be a connection with the server, but it isn't fully established yet. */\n\tbusyReconnecting = false\n\n\t/** True when we are loading the document and have not even decoded any scopes. */\n\tbusyLoadingFirstData = false\n\n\t/** True when we are loading the document. */\n\tbusyLoadingFullData = false\n\n\t// True when the user has an invalid subscription and cannot edit the project.\n\tblockedDueToInvalidSubscription = false\n\n\t/** Indicates we have loaded enough of the document data to edit. Can go back to false when we\n\t * have to reload the document. */\n\tget hasMinimalEditableData() {\n\t\treturn this.documentLoaded && !this.busyLoadingFirstData && !this.hasError\n\t}\n\n\t/** Indicates we have loaded all the document data. */\n\tget hasFullDocumentData() {\n\t\treturn this.hasMinimalEditableData && !this.busyLoadingFullData\n\t}\n\n\t/** Indicates the document has loaded editable data and is connected to the server (or explicitly offline).\n\t * Can go back to false if the network reconnects, or we have to download a new document, etc.\n\t * Does not take user permissions into consideration. */\n\tget isReady() {\n\t\treturn this.hasMinimalEditableData && !this.busyReconnecting && !this.blockedDueToInvalidSubscription\n\t}\n\n\t// Indicates if the initial tree did load\n\t// Tests currently don't call VekterEngine.didLoad so we need to fake it\n\tdocumentLoaded: boolean = environment.isTest\n\t// Indicates if the asset map is initialized\n\tassetMapLoaded: boolean = environment.isAutomation\n\t// Indicates if the sandbox iframe did load\n\tcanvasSandboxLoadingState: LoadingState = environment.isTest ? LoadingState.loaded : LoadingState.loading\n\t// Indicates if the sandbox finished loading resources for the initial\n\t// scope. Late images, scope switches, code-component module loads and\n\t// fonts are tracked separately and not reflected here.\n\t// See also resetCanvasSandboxLoadingState().\n\t// TODO: rename to something like `canvasInitialSandboxRenderFinished`,\n\t// or fold the other trackers in so the flag matches its name.\n\tcanvasSandboxResourcesLoadingState: LoadingState = environment.isTest ? LoadingState.loaded : LoadingState.loading\n\t// Indicates if the initial web fonts did load\n\twebFontsLoaded: boolean = false\n\t// Indicates the initial modules have all been loaded and evaluated in eager mode.\n\tallModulesLoadedAndEvaluated: boolean = false\n\t// Indicates the ModulesRuntime is loading modules to render a scope for the first time.\n\tisLoadingModules: boolean = false\n\n\t/** Indicates we have at least once loaded some parts of the user document. */\n\tget isDocumentLoaded() {\n\t\treturn this.documentLoaded\n\t}\n\n\tget isUserInteractionsDisabled() {\n\t\treturn !this.documentLoaded || !this.canvasSandboxLoadingState.isLoaded\n\t}\n\n\t/** Reset `canvasSandboxLoadingState` to its bring-up baseline. */\n\tresetCanvasSandboxLoadingState() {\n\t\t// Defer via `processWhenReady` because the typical caller path\n\t\t// (`CanvasSandboxController.createSandbox`) runs synchronously during\n\t\t// the initial render of `CanvasSandboxRenderer`, where store writes\n\t\t// would trip the `Cannot change store state while rendering` guard.\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t// Match the initial value when the store is constructed\n\t\t\tthis.canvasSandboxLoadingState = environment.isTest ? LoadingState.loaded : LoadingState.loading\n\t\t})\n\t}\n}\n", "import type { AIFeatureCategory } from \"app/ai/features.ts\"\nimport type { LanguageModel } from \"app/ai/languageModels.ts\"\n\nexport type UsageType = \"bandwidth\" | \"agents\"\n\nexport function isUsageType(value: string): value is UsageType {\n\treturn value === \"bandwidth\" || value === \"agents\"\n}\n\nexport type UsageFilterOption = \"assetPath\" | \"projectId\" | \"userId\" | \"feature\" | \"model\"\n\ninterface UsageFilter {\n\tvalue: string\n\tvalueLabel: string\n}\n\nexport type UsageFilters = {\n\t[K in UsageFilterOption]?: UsageFilter\n}\n\ninterface UsageState {\n\tshowProjectedLine: boolean\n\tmonth: number\n\tyear: number\n}\nexport interface UsageSummary {\n\ttotalUsage: number\n\tplanLimit: number | null\n\toverage: number\n}\nexport interface BandwidthDailyTotal {\n\tdate: string\n\ttotalBytes: number\n}\n\ninterface BandwidthUsageAsset {\n\tassetPath: string\n\ttotalBytes: number\n\tassetUrl: string\n}\n\ninterface BandwidthUsageAssetCategory {\n\tcategory: string\n\ttotalBytes: number\n}\n\nexport interface BandwidthUsageTopAsset {\n\tassetPath: string\n\ttotalBytes: number\n\tassetUrl?: string\n}\nexport type BandwidthUsageTopAssets = readonly BandwidthUsageTopAsset[]\n\nexport interface UsageTopCategory {\n\tcategory: string\n\ttotalBytes: number\n}\nexport type BandwidthUsageTopCategories = readonly UsageTopCategory[]\n\nexport interface BandwidthUsageState extends UsageState {\n\tdailyTotals: BandwidthDailyTotal[]\n\tindividualAssets: BandwidthUsageAsset[]\n\tassetCategories: BandwidthUsageAssetCategory[]\n\thasSharedHostnames?: boolean\n}\n\nexport interface AgentsUsageDailyTotal {\n\ttimestamp: string\n\tcredits: number\n}\n\nexport interface AgentsUsagePerUser {\n\tvalue: string\n\tfirstName: string\n\tlastName: string\n\tavatar: string\n\tcredits: number\n\tpercentage: number\n}\n\nexport interface AgentsUsagePerModel {\n\tvalue: LanguageModel\n\tcredits: number\n\tpercentage: number\n}\n\nexport interface AgentsUsagePerFeature {\n\tvalue: AIFeatureCategory\n\tcredits: number\n\tpercentage: number\n}\n\nexport interface AgentsUsagePerProject {\n\tvalue: string\n\ttitle: string\n\tcredits: number\n\tpercentage: number\n}\n\nexport type AgentsUsageState = UsageState & {\n\tstats: AgentsUsageDailyTotal[]\n\tuserId: AgentsUsagePerUser[]\n\tmodel: AgentsUsagePerModel[]\n\tfeature: AgentsUsagePerFeature[]\n\tproject?: AgentsUsagePerProject[]\n}\n\ntype UsageContentState = { status: \"loading\" } | { status: \"error\"; message: string }\n\nexport interface UsageDailyTotal {\n\tdate: string\n\tusage: number\n}\n\nexport type BandwidthContentState =\n\t| UsageContentState\n\t| {\n\t\t\tstatus: \"success\"\n\t\t\tusage: readonly UsageDailyTotal[]\n\t\t\tsummary: UsageSummary | null\n\t\t\ttopAssets: BandwidthUsageTopAssets\n\t\t\ttopCategories: BandwidthUsageTopCategories\n\t\t\tmonth: number\n\t\t\tyear: number\n\t\t\thasSharedHostnames: boolean\n\t\t\tshowProjectedLine: boolean\n\t\t\tisUpdating: boolean\n\t  }\n\nexport type AgentsContentState =\n\t| UsageContentState\n\t| {\n\t\t\tstatus: \"success\"\n\t\t\tusage: readonly UsageDailyTotal[]\n\t\t\tsummary: UsageSummary | null\n\t\t\ttopModels: readonly AgentsUsagePerModel[]\n\t\t\ttopFeatures: readonly AgentsUsagePerFeature[]\n\t\t\ttopUsers: readonly AgentsUsagePerUser[]\n\t\t\ttopProjects: readonly AgentsUsagePerProject[]\n\t\t\tmonth: number\n\t\t\tyear: number\n\t\t\tshowProjectedLine: boolean\n\t\t\tisUpdating: boolean\n\t  }\n\nexport type AgentsUsageViewState = \"none\" | \"limited\" | \"full\"\n", "import type { LocalModuleId } from \"@framerjs/shared\"\nimport { asLocalId } from \"@framerjs/shared\"\nimport { isUpsellFeature } from \"document/components/chrome/siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { isUsageType } from \"document/components/chrome/siteSettings/Usage/types.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { AnalyticsTab } from \"document/stores/AnalyticsStore.ts\"\nimport { AnalyticsTabNames, isAnalyticsTabName } from \"document/stores/AnalyticsStore.ts\"\nimport type { SiteSettingsTab } from \"document/stores/SiteSettingsStore.ts\"\nimport { SiteSettingsTabNames, isSiteSettingsTabName } from \"document/stores/SiteSettingsStore.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\n\n// TODO: Deprecate this key.\nconst activeNodeIdKey = \"node\"\nconst activeViewKey = \"view\"\nconst viewSettingsKey = \"settings:\"\nconst analyticsKey = \"analytics:\"\nconst tutorialKey = \"tutorial\"\nconst localeKey = \"locale\"\nconst fullscreenKey = \"fullscreen\"\nconst collectionItemInCanvasIdKey = \"item\"\n\ninterface ViewParams {\n\tcodeModuleLocalId?: LocalModuleId | null\n\tcollectionItemInCanvasId?: NodeID | null\n\tnodeId?: NodeID | null\n\tlocaleId?: LocaleId | null\n\tsiteSettingsTab?: SiteSettingsTab | null\n\tanalyticsTab?: AnalyticsTab | null\n\ttutorialId?: string | null\n\tfullscreen?: string | null\n\tmainView?: ActiveMainView | undefined\n\tpublishModal?: boolean | undefined\n}\n\nexport function getViewParamsFromURL(params: URLSearchParams): ViewParams {\n\tconst viewValue = params.get(activeViewKey)\n\tconst codeModuleLocalId = viewValue?.startsWith(\"code:\") ? asLocalId(viewValue.substring(5)) : null\n\tconst fullscreen = params.get(fullscreenKey)\n\t// Check if the view is set to 'localizations'\n\tlet mainView: ActiveMainView | undefined = undefined\n\n\tswitch (viewValue) {\n\t\tcase \"localizations\":\n\t\t\tmainView = ActiveMainView.Localizations\n\t\t\tbreak\n\t\tcase \"preview\":\n\t\t\tmainView = ActiveMainView.Preview\n\t\t\tbreak\n\t}\n\n\tlet siteSettingsTab: SiteSettingsTab | null = null\n\tif (viewValue?.startsWith(viewSettingsKey)) {\n\t\tconst sitesSettingsParam = viewValue.substring(viewSettingsKey.length)\n\t\tconst [tab, id, ...rest] = sitesSettingsParam.split(\":\")\n\n\t\tif (isSiteSettingsTabName(tab)) {\n\t\t\tif (tab === SiteSettingsTabNames.page) {\n\t\t\t\tif (id) siteSettingsTab = { tab, id }\n\t\t\t} else if (tab === SiteSettingsTabNames.versions) {\n\t\t\t\tconst showDeploymentIssues = rest[0] === \"issues\"\n\t\t\t\tsiteSettingsTab = { tab, id, showDeploymentIssues }\n\t\t\t} else if (tab === SiteSettingsTabNames.plans && id && isUpsellFeature(id)) {\n\t\t\t\tsiteSettingsTab = { tab, upsellFeature: id }\n\t\t\t} else if (tab === SiteSettingsTabNames.usage) {\n\t\t\t\tsiteSettingsTab = { tab, usageType: id && isUsageType(id) ? id : \"bandwidth\" }\n\t\t\t} else {\n\t\t\t\tsiteSettingsTab = { tab }\n\t\t\t}\n\t\t}\n\t}\n\n\tlet analyticsTab: AnalyticsTab | null = null\n\tif (viewValue?.startsWith(analyticsKey)) {\n\t\tconst analyticsParam = viewValue.slice(analyticsKey.length)\n\t\tconst [tab, id] = analyticsParam.split(\":\")\n\n\t\tif (isAnalyticsTabName(tab)) {\n\t\t\tif (tab === AnalyticsTabNames.funnel || tab === AnalyticsTabNames.abtest) {\n\t\t\t\tif (id) analyticsTab = { tab, id }\n\t\t\t} else {\n\t\t\t\tanalyticsTab = { tab }\n\t\t\t}\n\t\t}\n\t}\n\n\tconst publishModal = viewValue === \"publish\"\n\n\treturn {\n\t\tcollectionItemInCanvasId: params.get(collectionItemInCanvasIdKey),\n\t\tnodeId: params.get(activeNodeIdKey),\n\t\ttutorialId: params.get(tutorialKey),\n\t\tlocaleId: params.get(localeKey),\n\t\tcodeModuleLocalId,\n\t\tsiteSettingsTab,\n\t\tanalyticsTab,\n\t\tmainView,\n\t\tfullscreen,\n\t\tpublishModal,\n\t}\n}\n\nexport function setViewParamsInURL(\n\turl: URL,\n\t{\n\t\tcodeModuleLocalId,\n\t\tcollectionItemInCanvasId,\n\t\tnodeId,\n\t\tlocaleId,\n\t\tmainView,\n\t\tfullscreen,\n\t\tsiteSettingsTab,\n\t\tanalyticsTab,\n\t}: ViewParams,\n) {\n\t// TODO: Support ?view=node:<nodeId1>,<nodeId2>;code:<localId> so we can\n\t// have multiselections and multiple views can be opened at once.\n\tif (nodeId) {\n\t\turl.searchParams.set(activeNodeIdKey, nodeId)\n\t} else {\n\t\turl.searchParams.delete(activeNodeIdKey)\n\t}\n\tif (localeId) {\n\t\turl.searchParams.set(localeKey, localeId)\n\t} else {\n\t\turl.searchParams.delete(localeKey)\n\t}\n\tif (collectionItemInCanvasId) {\n\t\turl.searchParams.set(collectionItemInCanvasIdKey, collectionItemInCanvasId)\n\t} else {\n\t\turl.searchParams.delete(collectionItemInCanvasIdKey)\n\t}\n\n\t/** Remove the fullscreen param if it is set. */\n\turl.searchParams.delete(fullscreenKey)\n\n\tif (mainView === ActiveMainView.Localizations) {\n\t\turl.searchParams.set(activeViewKey, \"localizations\")\n\t} else if (mainView === ActiveMainView.Preview) {\n\t\turl.searchParams.set(activeViewKey, \"preview\")\n\t\tif (fullscreen) url.searchParams.set(fullscreenKey, fullscreen)\n\t} else if (mainView === ActiveMainView.Analytics && analyticsTab) {\n\t\tconst id = \"id\" in analyticsTab ? `:${analyticsTab.id}` : \"\"\n\t\turl.searchParams.set(activeViewKey, `${analyticsKey}${analyticsTab.tab}${id ? id : \"\"}`)\n\t} else if (codeModuleLocalId) {\n\t\turl.searchParams.set(activeViewKey, `code:${codeModuleLocalId}`)\n\t} else if (mainView === ActiveMainView.SiteSettings && siteSettingsTab) {\n\t\tlet id = \"\"\n\t\tif (siteSettingsTab.tab === SiteSettingsTabNames.usage) {\n\t\t\tid = `:${siteSettingsTab.usageType}`\n\t\t} else if (\"id\" in siteSettingsTab && siteSettingsTab.tab !== SiteSettingsTabNames.versions) {\n\t\t\t// At this time, purely for scope-cutting reasons, the versions deep link to a specific version is meant to\n\t\t\t// work one-way only, on the initial open, so let's prevent it from being persisted in the URL.\n\t\t\tid = `:${siteSettingsTab.id}`\n\t\t}\n\t\turl.searchParams.set(activeViewKey, `${viewSettingsKey}${siteSettingsTab.tab}${id}`)\n\t} else {\n\t\turl.searchParams.delete(activeViewKey)\n\t}\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport { environment } from \"environment/index.ts\"\nimport { EventEmitter } from \"eventemitter3\"\n\nconst log = getLogger(\"ipcRenderer\")\n\ninterface WindowWithBridge extends Window {\n\t_bridge?: (channel: string, ...args: any[]) => void\n\t_ipc?: IpcRenderer\n\t_onBridge?: (e: Event | null, ...args: any[]) => void\n\t_onBridgeRaw?: (e: Event | null, ...args: any[]) => void\n}\n\nconst windowWithBridge = window as WindowWithBridge\n\nclass IpcRenderer extends EventEmitter {\n\tprivate _sendBacklog: any[] = []\n\n\tsend(channel: string, ...args: any[]) {\n\t\t// This property must be defined by the \u2018browser\u2019 loading this document.\n\t\t// In the case of WebKit in a native app, this can be done by adding a\n\t\t// message handler (see WKUserContentController)\n\t\tif (windowWithBridge._bridge && this._sendBacklog.length === 0) {\n\t\t\twindowWithBridge._bridge(channel, ...args)\n\t\t} else if (environment.isDebugBuild) {\n\t\t\tlog.warn(\"IPC message could not be sent\", channel, args)\n\t\t}\n\t\tif (!windowWithBridge._bridge || this._sendBacklog.length > 0) {\n\t\t\tthis._sendBacklog.push({ channel, args })\n\t\t\tif (this._sendBacklog.length <= 1) {\n\t\t\t\tthis.waitForBridge()\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate waitForBridge() {\n\t\tsetTimeout(() => {\n\t\t\tif (!windowWithBridge._bridge) {\n\t\t\t\treturn this.waitForBridge()\n\t\t\t}\n\n\t\t\tconst backlog = this._sendBacklog\n\t\t\tthis._sendBacklog = []\n\n\t\t\tif (environment.isDebugBuild) {\n\t\t\t\tlog.debug(\"Bridge connected\u2026 sending\", backlog.length, \"older messages\")\n\t\t\t}\n\n\t\t\tbacklog.forEach(message => {\n\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: _bridge existence checked above\n\t\t\t\twindowWithBridge._bridge!(message.channel, ...message.args)\n\t\t\t})\n\t\t}, 100)\n\t}\n}\n\nconst ipc: IpcRenderer = new IpcRenderer()\n\n// Only expose it if we\u2019re not using Electron\nif (typeof window !== \"undefined\") {\n\twindowWithBridge._ipc = ipc\n}\n\nfunction onBridge(e: Event | null, ...args: any[]) {\n\tif (!args) return\n\tconst method = args[0]\n\tconst args2 = args.slice(1)\n\tipc.emit(method, ...args2)\n}\n\nfunction onBridgeRaw(e: Event | null, ...args: any[]) {\n\tif (!args) return\n\tconst method = args[0]\n\tconst argsRaw = args.slice(1)\n\tconst args2 = argsRaw !== null ? JSON.parse(\"[\" + argsRaw + \"]\") : argsRaw\n\tipc.emit(method, ...args2)\n}\n\nexport const getIpcRenderer = () => {\n\treturn ipc\n}\n\nfunction main() {\n\tif (windowWithBridge._bridge) {\n\t\twindowWithBridge._onBridge = onBridge\n\t\twindowWithBridge._onBridgeRaw = onBridgeRaw\n\t\treturn\n\t}\n}\n\nmain()\n", "import type { DebugStore } from \"document/stores/DebugStore.ts\"\nimport React from \"react\"\n\n/*\nNote, to enable tracking all react renders, run the following command on the terminal:\n```\ncd src/app/vekter\npatch build/scripts/react-dom/react-dom.development.js <<EOF\n2704a2705\n> window.ReactDebugCurrentFiber = ReactDebugCurrentFiber\nEOF\n```\n*/\n\nexport type EnginePerformanceReporter = (perf?: EnginePerformance) => void\n\nexport class EnginePerformance {\n\t_update = -1\n\n\t_nodeUpdated = 0\n\t_cacheReset = 0\n\t_cacheUpdated = 0\n\t_nodeGetProps = 0\n\t_nodeCreateElement = 0\n\t_nodeRender = 0\n\n\t_layerPanelItem = 0\n\n\t_reactCreateElement = 0\n\t_reactRender = 0\n\n\t// to uninstall\n\tdebugStore?: DebugStore\n\toriginalReactCreateElement: any\n\toriginalReactSetCurrentPhase: any\n\tgui: any\n\n\treporter: EnginePerformanceReporter | null\n\n\tconstructor(reporter: EnginePerformanceReporter | null = null) {\n\t\tthis.reporter = reporter\n\t}\n\n\treportAndReset(update: number, _start: number) {\n\t\tif (this.reporter) {\n\t\t\tthis.reporter()\n\t\t}\n\t\tthis.reset(update)\n\t}\n\n\treport = () => {\n\t\t// biome-ignore lint/suspicious/noConsole: <explanation>\n\t\tconsole.log(\n\t\t\t\"update: \" +\n\t\t\t\tthis._update +\n\t\t\t\t\"\\nnodes updated: \" +\n\t\t\t\tthis._nodeUpdated +\n\t\t\t\t\"\\ncaches reset: \" +\n\t\t\t\tthis._cacheReset +\n\t\t\t\t\"\\ncaches updated: \" +\n\t\t\t\tthis._cacheUpdated +\n\t\t\t\t\"\\nnode getProps: \" +\n\t\t\t\tthis._nodeGetProps +\n\t\t\t\t\"\\nnode createElement: \" +\n\t\t\t\tthis._nodeCreateElement +\n\t\t\t\t\"\\nnode render: \" +\n\t\t\t\tthis._nodeRender +\n\t\t\t\t\"\\nreact createElement: \" +\n\t\t\t\tthis._reactCreateElement +\n\t\t\t\t\"\\nreact render: \" +\n\t\t\t\tthis._reactRender,\n\t\t)\n\t}\n\n\treset(update = -1) {\n\t\tthis._update = update\n\t\tthis._nodeUpdated = 0\n\t\tthis._cacheReset = 0\n\t\tthis._cacheUpdated = 0\n\t\tthis._nodeGetProps = 0\n\t\tthis._nodeCreateElement = 0\n\t\tthis._nodeRender = 0\n\n\t\tthis._layerPanelItem = 0\n\n\t\tthis._reactCreateElement = 0\n\t\tthis._reactRender = 0\n\t}\n\n\tnodeUpdated(n = 1) {\n\t\tthis._nodeUpdated += n\n\t}\n\tcacheReset() {\n\t\tthis._cacheReset += 1\n\t}\n\tcacheUpdated() {\n\t\tthis._cacheUpdated += 1\n\t}\n\tnodeGetProps() {\n\t\tthis._nodeGetProps += 1\n\t}\n\tnodeCreateElement() {\n\t\tthis._nodeCreateElement += 1\n\t}\n\tnodeRender() {\n\t\tthis._nodeRender += 1\n\t}\n\n\tlayerPanelItem() {\n\t\tthis._layerPanelItem += 1\n\t}\n\n\tinstall(debugStore: DebugStore): this {\n\t\twindow[\"perf\"] = this\n\t\tthis.debugStore = debugStore\n\n\t\t// capture reactCreateElement\n\t\tconst self = this\n\t\tconst originalReactCreateElement = React.createElement\n\t\tthis.originalReactCreateElement = originalReactCreateElement\n\t\t// @ts-ignore We are overriding `createElement` to add performance reporting\n\t\tReact.createElement = function (...args: unknown[]) {\n\t\t\tself._reactCreateElement += 1\n\t\t\treturn originalReactCreateElement.apply(this, args)\n\t\t}\n\n\t\t// capture React render()s.\n\t\t// Note this is only available when patching react-dom.development.js, see above.\n\t\tconst ReactDebugCurrentFiber = window[\"ReactDebugCurrentFiber\"]\n\t\tif (ReactDebugCurrentFiber) {\n\t\t\tconst originalReactSetCurrentPhase = ReactDebugCurrentFiber.setCurrentPhase\n\t\t\tthis.originalReactSetCurrentPhase = originalReactSetCurrentPhase\n\t\t\tReactDebugCurrentFiber.setCurrentPhase = function (phase: string) {\n\t\t\t\tif (phase === \"render\") {\n\t\t\t\t\tself._reactRender += 1\n\t\t\t\t}\n\t\t\t\treturn originalReactSetCurrentPhase(phase)\n\t\t\t}\n\t\t}\n\n\t\t// create a test UI\n\t\tconst dat = window[\"dat\"]\n\t\tif (dat) {\n\t\t\tthis.gui = new dat.GUI()\n\t\t\tthis.gui.add(debugStore, \"hideArrows\")\n\t\t\tthis.gui.add(debugStore, \"hideTitles\")\n\t\t\tthis.gui.add(debugStore, \"reportToConsole\")\n\t\t}\n\n\t\treturn this\n\t}\n\n\tuninstall() {\n\t\twindow[\"perf\"] = undefined\n\t\tthis.debugStore?.reset()\n\n\t\t// @ts-ignore We are restoring the original createElement when uninstalling perf reporting\n\t\tReact.createElement = this.originalReactCreateElement\n\n\t\tconst ReactDebugCurrentFiber = window[\"ReactDebugCurrentFiber\"]\n\t\tif (ReactDebugCurrentFiber) {\n\t\t\tReactDebugCurrentFiber.setCurrentPhase = this.originalReactSetCurrentPhase\n\t\t}\n\n\t\tif (this.gui) {\n\t\t\tthis.gui.destroy()\n\t\t}\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, ModuleType, assertNever } from \"@framerjs/shared\"\nimport type { BaseEngineScheduler } from \"document/base-engine/BaseEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isKitPageNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isCustomizable } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { withKitSectionHash } from \"document/models/CanvasTree/traits/WithKitSectionHash.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { DebugStore } from \"document/stores/DebugStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { PublishStore } from \"document/stores/PublishStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { generateHTML } from \"export/exportToHTML.ts\"\n\n/** Requests screenshots for every kit page in the project, for the most recent save. */\nexport async function requestLocalKitScreenshots(\n\tcomponentLoader: ComponentLoader,\n\ttreeStore: TreeStore,\n\tmodulesStore: ModulesStore,\n\tcodeGenerationStore: CodeGenerationStore,\n\tdebugStore: DebugStore,\n\tpublishStore: PublishStore,\n\tprojectStore: ProjectStore,\n\tassetStore: AssetStore,\n\tscheduler: BaseEngineScheduler,\n\toptions: {\n\t\tpageID?: NodeID\n\t\tdraft?: boolean\n\t\tforce?: boolean\n\t} = {},\n) {\n\tconst { pageID, draft = false } = options\n\tfor (const node of treeStore.tree.root.children) {\n\t\tif (!isKitPageNode(node) || !node.isLoaded()) continue\n\t\tif (pageID && node.id !== pageID) continue\n\n\t\tconst sectionIds = new Set<NodeID>()\n\t\tfor (const section of node.getPrimaryVariant().children) {\n\t\t\tif (!isCustomizable(section)) continue\n\t\t\tif (!withKitSectionHash(section)) continue\n\t\t\tsectionIds.add(section.id)\n\t\t}\n\n\t\tlet kitPageHtml = await generateScreenshotHTML(\n\t\t\tcomponentLoader,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tcodeGenerationStore,\n\t\t\tdebugStore,\n\t\t\tpublishStore,\n\t\t\tprojectStore,\n\t\t\tassetStore,\n\t\t\tscheduler,\n\t\t\tnode.id,\n\t\t)\n\t\tif (!kitPageHtml) continue\n\n\t\t// If we are forcing a regeneration, we need to modify the page content to avoid deduplication.\n\t\t// Use with caution.\n\t\tif (options.force) {\n\t\t\tkitPageHtml += `<!-- Forced: ${Date.now()} -->`\n\t\t}\n\n\t\tawait modulesStore.enqueueKitScreenshots(kitPageHtml, sectionIds, draft)\n\t\tif (pageID) return\n\t}\n\n\tif (pageID) throw new Error(\"Specified kit page for screenshot not found or empty\")\n}\n\n/** Gets the rendered HTML for a kit page for screenshots. */\nexport async function generateScreenshotHTML(\n\tcomponentLoader: ComponentLoader,\n\ttreeStore: TreeStore,\n\tmodulesStore: ModulesStore,\n\tcodeGenerationStore: CodeGenerationStore,\n\tdebugStore: DebugStore,\n\tpublishStore: PublishStore,\n\tprojectStore: ProjectStore,\n\tassetStore: AssetStore,\n\tscheduler: BaseEngineScheduler,\n\tpageID: NodeID,\n) {\n\tconst node = treeStore.tree.get(pageID)\n\tassert(node, \"pageID should exist in the tree\")\n\tassert(isWebPageNode(node), \"node must be a web page node\")\n\n\t// Get the LoadedWebPageNode for rendering.\n\tconst kitPage = node.isLoaded() ? node : await node.load()\n\tassert(kitPage, \"Could not load kit page\")\n\tassert(kitPage.kitPage, \"node must be a kit page\")\n\n\t// Only continue if we find at least one usable section on this page.\n\tlet hasSections = false\n\tfor (const section of kitPage.getPrimaryVariant().children) {\n\t\tif (isCustomizable(section)) {\n\t\t\thasSections = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif (!hasSections) return\n\n\t// KITS @TODO - This needs some optimizations to not generate unnecessary content beyond the desired kit page.\n\tconst html = await generateHTML({\n\t\tcomponentLoader,\n\t\tmodulesStore,\n\t\tcodeGenerationStore,\n\t\tdebugStore,\n\t\ttreeStore,\n\t\tpublishStore,\n\t\tprojectStore,\n\t\tassetStore,\n\t\tscheduler,\n\t\toverrides: {\n\t\t\tentryScreenNodeId: kitPage.id,\n\t\t\t// The search index URL is a random hash normally. For stable output we need to set it to an empty string.\n\t\t\tsearchIndexURL: \"\",\n\t\t\tsearchIndexFallbackURL: \"\",\n\t\t\t// The initial route is the kit page.\n\t\t\t// KITS @TODO - We need to set the path variables for detail pages.\n\t\t\tinitialRoute: { routeId: kitPage.id },\n\t\t\t// The import map changes frequently, so we need to filter out the types that are not\n\t\t\t// needed for the kit page to reduce unnecessary screenshots.\n\t\t\timportMapModuleTypeFilter: filter,\n\t\t},\n\t})\n\n\treturn html.html\n}\nfunction filter(type: ModuleType) {\n\tswitch (type) {\n\t\tcase ModuleType.WebPageMetadata:\n\t\tcase ModuleType.SiteMetadata:\n\t\tcase ModuleType.Snippets:\n\t\tcase ModuleType.Screen:\n\t\tcase ModuleType.LayoutTemplate:\n\t\tcase ModuleType.Localization:\n\t\tcase ModuleType.Kit:\n\t\t\treturn true\n\t\tcase ModuleType.Code:\n\t\tcase ModuleType.Canvas:\n\t\tcase ModuleType.Collection:\n\t\tcase ModuleType.DraftCollection:\n\t\tcase ModuleType.ComponentPresets:\n\t\tcase ModuleType.Config:\n\t\tcase ModuleType.Prototype:\n\t\tcase ModuleType.Vector:\n\t\tcase ModuleType.VectorSet:\n\t\tcase ModuleType.Design:\n\t\tcase ModuleType.CSS:\n\t\tcase ModuleType.Shader:\n\t\t\treturn false\n\t\tdefault:\n\t\t\tassertNever(type)\n\t}\n}\n", "/*\n * Where certain parts of the UI require the same breakpoint (whatever it may be); create a reference here\n */\n\nimport { breakpoints } from \"@framerjs/fresco/tokens\"\n\n/** The UI collapses into a more sparse view, with side panels moved behind menus */\nexport const collapsedViewBreakpoint = breakpoints.tabletSmall\n", "import { dimensions } from \"@framerjs/fresco/tokens\"\nimport { agentDimensionTokenOverrides } from \"app/agent/utils/dimensions.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { collapsedViewBreakpoint } from \"utils/chromeBreakpoints.ts\"\nimport type { EngineChanges } from \"./EngineChanges.ts\"\nimport { EngineChange } from \"./EngineChanges.ts\"\nimport { NavigationBehavior } from \"./components/chrome/insertSidebar/types.ts\"\nimport type { ChromeStore } from \"./stores/ChromeStore.ts\"\nimport type { CodeEditorStore } from \"./stores/CodeEditorStore.ts\"\nimport type { InsertSidebarStore } from \"./stores/InsertSidebarStore.ts\"\nimport type { ScopeStore } from \"./stores/ScopeStore.ts\"\nimport { ActiveLeftPanel, ActiveMainView, ActiveRightPanel, CanvasPanelTab } from \"./utils/ActiveEditorType.ts\"\n\nconst canvasZoomInsertOverlapWindowWidthThreshold = 1300\nexport class LayoutState {\n\tprivate windowWidth = window.innerWidth\n\n\tget defaultTabContentWidth(): number {\n\t\treturn dimensions.values.panelMinWidth\n\t}\n\n\tminWidth = this.defaultTabContentWidth\n\n\tget maxWidth() {\n\t\treturn Math.min(500, Math.max(this.minWidth, this.windowWidth))\n\t}\n\n\tconstructor(\n\t\tprivate changes: EngineChanges,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly insertSidebarStore: InsertSidebarStore,\n\t\treadonly codeEditorStore: CodeEditorStore,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\t// Extract initial values from stores that we depend on so they can be compared in the change observer below.\n\t\tlet { chromeIsVisible, statusBarIsVisible, floatingToolbarWidth, leftPanel } = chromeStore\n\t\tlet breadcrumbBarIsVisible = scopeStore.onIsolatedCanvas || chromeStore.mainView === ActiveMainView.CodeEditor\n\t\tlet rightPanelIsVisible = chromeStore.rightPanel !== ActiveRightPanel.None\n\t\tlet rightPanelUsesEvaluationsWidth = this.rightPanelUsesEvaluationsWidth\n\t\tchanges.observe(chromeStore, scopeStore, () => {\n\t\t\t// Extract new state from the upstream stores.\n\t\t\tconst {\n\t\t\t\tchromeIsVisible: newChromeIsVisible,\n\t\t\t\tstatusBarIsVisible: newStatusBarIsVisible,\n\t\t\t\trightPanel,\n\t\t\t\tfloatingToolbarWidth: newFloatingToolbarWidth,\n\t\t\t\tleftPanel: newLeftPanel,\n\t\t\t} = chromeStore\n\t\t\tconst newRightPanelIsVisible = rightPanel !== ActiveRightPanel.None\n\t\t\tconst newRightPanelUsesEvaluationsWidth = this.rightPanelUsesEvaluationsWidth\n\t\t\tconst newBreadcrumbBarIsVisible =\n\t\t\t\tscopeStore.onCollectionPage || scopeStore.onIsolatedCanvas || chromeStore.mainView === ActiveMainView.CodeEditor\n\t\t\t// Don't change anything if everything we care about is still the same.\n\t\t\tif (\n\t\t\t\tchromeIsVisible === newChromeIsVisible &&\n\t\t\t\tstatusBarIsVisible === newStatusBarIsVisible &&\n\t\t\t\tbreadcrumbBarIsVisible === newBreadcrumbBarIsVisible &&\n\t\t\t\trightPanelIsVisible === newRightPanelIsVisible &&\n\t\t\t\trightPanelUsesEvaluationsWidth === newRightPanelUsesEvaluationsWidth &&\n\t\t\t\tfloatingToolbarWidth === newFloatingToolbarWidth &&\n\t\t\t\tleftPanel === newLeftPanel\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Update our store change tracking variables.\n\t\t\tchromeIsVisible = newChromeIsVisible\n\t\t\tstatusBarIsVisible = newStatusBarIsVisible\n\t\t\tbreadcrumbBarIsVisible = newBreadcrumbBarIsVisible\n\t\t\trightPanelIsVisible = newRightPanelIsVisible\n\t\t\trightPanelUsesEvaluationsWidth = newRightPanelUsesEvaluationsWidth\n\t\t\tfloatingToolbarWidth = newFloatingToolbarWidth\n\t\t\tleftPanel = newLeftPanel\n\t\t\t// Update the CSS layout variables.\n\t\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t\t})\n\n\t\twindow.addEventListener(\"resize\", () => this.handleWindowResize(), { signal: abortSignal })\n\t}\n\n\tprivate getConstrainedTabContentWidth = (width: number): number => {\n\t\treturn Math.min(Math.max(this.minWidth, width), this.maxWidth)\n\t}\n\n\tprivate _targetTabContentWidth = window[\"UserDefaultsTabContentWidth\"] || this.defaultTabContentWidth\n\tprivate _constrainedTabContentWidth = 0\n\n\tprivate _targetPropertyPanelWidth = this.defaultTabContentWidth\n\tprivate _constrainedPropertyPanelWidth = 0\n\tprivate _targetEvaluationsPanelWidth = this.defaultEvaluationsPanelWidth\n\n\tprivate get defaultEvaluationsPanelWidth(): number {\n\t\treturn Math.max(this.minWidth, Math.floor(window.innerWidth * 0.5))\n\t}\n\n\tprivate getConstrainedEvaluationsPanelWidth = (width: number): number => {\n\t\treturn Math.min(Math.max(this.minWidth, width), Math.max(this.minWidth, window.innerWidth))\n\t}\n\n\tgetCurrentTabContentWidth = (): number => {\n\t\treturn this.chromeStore.chromeIsVisible ? this.getConstrainedTabContentWidth(this._targetTabContentWidth) : 0\n\t}\n\n\tgetCurrentPropertyPanelWidth = (): number => {\n\t\treturn this.chromeStore.chromeIsVisible ? this.getConstrainedTabContentWidth(this._targetPropertyPanelWidth) : 0\n\t}\n\n\tgetCurrentEvaluationsPanelWidth = (): number => {\n\t\tif (!this.chromeStore.chromeIsVisible) return 0\n\t\treturn this.getConstrainedEvaluationsPanelWidth(this._targetEvaluationsPanelWidth)\n\t}\n\n\tget tabOverlapOnCanvas(): number {\n\t\treturn this.chromeStore.chromeIsVisible ? this.getConstrainedTabContentWidth(this._targetTabContentWidth) : 0\n\t}\n\n\tget responsiveLeftPanelOverlapOnCanvas(): number {\n\t\treturn this.getConstrainedTabContentWidth(this._targetTabContentWidth)\n\t}\n\n\tget propertyPanelOverlapOnCanvas(): number {\n\t\treturn this.chromeStore.chromeIsVisible ? this.getConstrainedTabContentWidth(this._targetPropertyPanelWidth) : 0\n\t}\n\n\tget evaluationsPanelOverlapOnCanvas(): number {\n\t\treturn this.getCurrentEvaluationsPanelWidth()\n\t}\n\n\tprivate get rightPanelUsesEvaluationsWidth(): boolean {\n\t\treturn (\n\t\t\tthis.chromeStore.rightPanel === ActiveRightPanel.Evaluations ||\n\t\t\t(this.chromeStore.isEvaluationsModeActive &&\n\t\t\t\tthis.chromeStore.rightPanel === ActiveRightPanel.Canvas &&\n\t\t\t\tthis.chromeStore.activeRightPanelTab === CanvasPanelTab.Chat)\n\t\t)\n\t}\n\n\tsetTabContentWidth = (width: number) => {\n\t\tthis._targetTabContentWidth = width\n\t\tthis.changes.addChanges(EngineChange.TabContentWidth)\n\n\t\tconst constrainedWidth = this.getConstrainedTabContentWidth(width)\n\t\tif (constrainedWidth !== this._constrainedTabContentWidth) {\n\t\t\tthis._constrainedTabContentWidth = constrainedWidth\n\t\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t\t}\n\t}\n\n\tsetPropertyPanelWidth = (width: number) => {\n\t\tthis._targetPropertyPanelWidth = width\n\t\tthis.changes.addChanges(EngineChange.PropertyPanelWidth)\n\n\t\tconst constrainedWidth = this.getConstrainedTabContentWidth(width)\n\t\tif (constrainedWidth !== this._constrainedPropertyPanelWidth) {\n\t\t\tthis._constrainedPropertyPanelWidth = constrainedWidth\n\t\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t\t}\n\t}\n\n\tsetEvaluationsPanelWidth = (width: number) => {\n\t\tthis._targetEvaluationsPanelWidth = this.getConstrainedEvaluationsPanelWidth(width)\n\t\tthis.changes.addChanges(EngineChange.PropertyPanelWidth)\n\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t}\n\n\tget currentToolbarHeight(): number {\n\t\t// This used to be platform.isOn(\"supportsProjectBar\")\n\t\tif (!(environment.isAutomation || environment.isTest)) {\n\t\t\tconst isAgentOn = experiments.is(\"agent\", \"on\")\n\t\t\treturn (isAgentOn ? agentDimensionTokenOverrides.webBarHeight : dimensions.values.webBarHeight) + 1 // account for 1px bottom border\n\t\t}\n\t\treturn this.chromeStore.chromeIsVisible ? this._toolsHeight : 0\n\t}\n\n\tget currentChromeMarginTop(): number {\n\t\tif (\n\t\t\t(this.scopeStore.onIsolatedCanvas || this.scopeStore.onCollectionPage) &&\n\t\t\tthis.chromeStore.chromeIsVisible &&\n\t\t\tthis.chromeStore.mainView === ActiveMainView.Canvas\n\t\t) {\n\t\t\tconst isAgentOn = experiments.is(\"agent\", \"on\")\n\t\t\tconst sitesPanelHeaderHeight = isAgentOn\n\t\t\t\t? agentDimensionTokenOverrides.sitesPanelHeaderHeight\n\t\t\t\t: dimensions.values.sitesPanelHeaderHeight\n\t\t\treturn this.currentToolbarHeight + sitesPanelHeaderHeight\n\t\t}\n\t\treturn this.currentToolbarHeight\n\t}\n\n\tget currentChromeMarginRight(): number {\n\t\tif (this.chromeStore.rightPanel === ActiveRightPanel.None) return 0\n\t\tif (this.rightPanelUsesEvaluationsWidth) return this.evaluationsPanelOverlapOnCanvas\n\t\treturn this.chromeStore.chromeIsVisible ? this.propertyPanelOverlapOnCanvas : 0\n\t}\n\n\tget currentChromeMarginLeft(): number {\n\t\tif (!this.chromeStore.chromeIsVisible) return 0\n\t\treturn this.tabOverlapOnCanvas\n\t}\n\n\tget currentCanvasOverlapLeft(): number {\n\t\t// Ignore canvas overlap on smaller windows\n\t\tif (this.windowWidth < canvasZoomInsertOverlapWindowWidthThreshold) return 0\n\n\t\tconst isChromeVisible = this.chromeStore.chromeIsVisible\n\t\tif (!isChromeVisible) return 0\n\t\tconst isInsertVisible = this.chromeStore.leftPanel === ActiveLeftPanel.Insert\n\t\tif (!isInsertVisible) return 0\n\n\t\tconst { categories, activeCategoryType } = this.insertSidebarStore\n\t\tconst isInsertCategoryExpanded = Boolean(\n\t\t\tactiveCategoryType &&\n\t\t\tcategories?.some(\n\t\t\t\tcategory => category.type === activeCategoryType && category.navigationBehavior === NavigationBehavior.Push,\n\t\t\t),\n\t\t)\n\t\treturn isInsertCategoryExpanded ? dimensions.values.panelMinWidth : 0\n\t}\n\n\tget currentChromeMarginBottom(): number {\n\t\treturn (\n\t\t\tthis._tutorialHeight +\n\t\t\tthis._debugBarHeight +\n\t\t\t(this.chromeStore.statusBarIsVisible ? dimensions.values.statusBarHeight : 0)\n\t\t)\n\t}\n\n\t/** Margin bottom without status bar; use when status bar is hidden (e.g. during loading). */\n\tget currentChromeMarginBottomWithoutStatusBar(): number {\n\t\treturn this._tutorialHeight + this._debugBarHeight\n\t}\n\n\tget currentTutorialBottom(): number {\n\t\treturn this.chromeStore.statusBarIsVisible ? dimensions.values.statusBarHeight : 0\n\t}\n\n\tprivate _toolsHeight: number = dimensions.values.panelHeaderHeight\n\n\tprivate _tutorialHeight: number = 0\n\tsetTutorialHeight(height: number) {\n\t\tif (this._tutorialHeight === height) return\n\t\tthis._tutorialHeight = height\n\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t}\n\n\tget floatingToolbarBottom() {\n\t\tconst marginBottom = this.currentChromeMarginBottom\n\t\t// A rough value to make sure the floating toolbar doesn't overlay on top of the tutorial play button\n\t\treturn marginBottom + (this._tutorialHeight ? 20 : 0) + this.floatingToolbarMarginBottom\n\t}\n\n\tget floatingToolbarMarginBottom() {\n\t\tconst isAgentOn = experiments.isOn(\"agent\")\n\t\treturn isAgentOn\n\t\t\t? agentDimensionTokenOverrides.floatingToolbarMarginBottom\n\t\t\t: dimensions.values.floatingToolbarMarginBottom\n\t}\n\n\tget floatingToolbarTop() {\n\t\treturn this.floatingToolbarBottom + dimensions.values.floatingToolbarHeight\n\t}\n\n\tprivate _debugBarHeight = 0\n\tsetDebugBarHeight(height: number) {\n\t\tif (this._debugBarHeight === height) return\n\t\tthis._debugBarHeight = height\n\t\tthis.updateLayoutStyleElement(this.styleElement)\n\t}\n\n\tsaveToUserDefaults = () => {\n\t\t// TODO: Store the sidepanel width in user preferences.\n\t}\n\n\tprivate styleElement: HTMLStyleElement | null = null\n\tupdateLayoutStyleElement(element: HTMLStyleElement | null) {\n\t\tthis.styleElement = element\n\t\tif (element) {\n\t\t\telement.innerHTML = this.cssText()\n\t\t}\n\t}\n\n\tcssText(): string {\n\t\tconst responsiveLeftPanelOverlapOnCanvas = this.responsiveLeftPanelOverlapOnCanvas\n\n\t\treturn `:root { --framerInternalUI-tabContentWidth: ${Math.max(\n\t\t\t1,\n\t\t\tthis.tabOverlapOnCanvas,\n\t\t)}px; --framerInternalUI-propertyPanelWidth: ${Math.max(\n\t\t\t1,\n\t\t\tthis.propertyPanelOverlapOnCanvas,\n\t\t)}px; --framerInternalUI-rightPanelWidth: ${Math.max(\n\t\t\t1,\n\t\t\tthis.currentChromeMarginRight,\n\t\t)}px; --framerInternalUI-chromeToolbarHeight: ${this.currentToolbarHeight}px; --framerInternalUI-chromeMarginTop: ${\n\t\t\tthis.currentChromeMarginTop\n\t\t}px; --framerInternalUI-chromeMarginRight: ${\n\t\t\tthis.currentChromeMarginRight\n\t\t}px; --framerInternalUI-chromeMarginLeft: ${\n\t\t\tthis.currentChromeMarginLeft\n\t\t}px; --framerInternalUI-chromeMarginBottom: ${\n\t\t\tthis.currentChromeMarginBottom\n\t\t}px; --framerInternalUI-chromeMarginBottomWithoutStatusBar: ${\n\t\t\tthis.currentChromeMarginBottomWithoutStatusBar\n\t\t}px; --framerInternalUI-tutorialBottom: ${\n\t\t\tthis.currentTutorialBottom\n\t\t}px; --framerInternalUI-floatingToolbarBottom: ${\n\t\t\tthis.floatingToolbarBottom\n\t\t}px; --framerInternalUI-floatingToolbarTop: ${\n\t\t\tthis.floatingToolbarTop\n\t\t}px; --framerInternalUI-floatingToolbarWidth: ${\n\t\t\tthis.chromeStore.floatingToolbarWidth\n\t\t}px; --framerInternalUI-responsiveLeftPanel: ${\n\t\t\tresponsiveLeftPanelOverlapOnCanvas\n\t\t}px; --framerInternalUI-responsiveLeftOffset: ${responsiveLeftPanelOverlapOnCanvas}px; @media (max-width: ${\n\t\t\tcollapsedViewBreakpoint\n\t\t}px) {--framerInternalUI-responsiveLeftOffset: 0; --framerInternalUI-responsiveLeftPanel: 100%;}\n    }`\n\t}\n\n\thandleWindowResize = () => {\n\t\tthis.windowWidth = window.innerWidth\n\t\tthis.setTabContentWidth(this._targetTabContentWidth)\n\t\tthis.setPropertyPanelWidth(this._targetPropertyPanelWidth)\n\t\tthis.setEvaluationsPanelWidth(this._targetEvaluationsPanelWidth)\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode, MaybeNodeID, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isNodeId } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { hasItemsOrderOverride } from \"document/models/CanvasTree/traits/WithItemsOrder.ts\"\nimport { hasAnyLayout } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport { isArray, isDefined, isNull } from \"utils/typeChecks.ts\"\n\ninterface CycleSelectionProps {\n\tengine: VekterEngine\n\tisForward?: boolean\n}\n\n/**\n * `cycleSelection` cycles the selection through the siblings of each node in the current selection. First, all selected\n * nodes are grouped by their parent. Then, for each parent group, the function will cycle through the siblings of each\n * node. Subsequent calls to the function will move the pointer onwards to the next sibling within each parent group.\n * @param engine The VekterEngine instance\n * @param isForward Whether to cycle forwards or backwards\n * @returns void\n */\nexport function cycleSelection({ engine, isForward = true }: CycleSelectionProps) {\n\tconst { selectionStore } = engine.stores\n\tif (selectionStore.ids.length === 0) return\n\n\tconst selectedNodesPerParent: Record<NodeID, NodeID[]> = {}\n\n\t// Group the selected nodes by their parent\n\tfor (const node of selectionStore.nodes) {\n\t\tconst parentId = node.parentid\n\t\tif (!parentId) continue\n\n\t\tconst parent = engine.tree.getNode(parentId)\n\t\tassert(!isNull(parent), \"Parent must exist\")\n\n\t\tselectedNodesPerParent[parentId] ??= []\n\t\tselectedNodesPerParent[parentId].push(node.id)\n\t}\n\n\t// We check the next selection based on each parent group separately, as we need to have one resulting selection\n\t// per parent.\n\tconst selectionIds: NodeID[] = []\n\tfor (const curParentId in selectedNodesPerParent) {\n\t\tconst parent = engine.tree.getNode(curParentId)\n\t\tassert(!isNull(parent) && parent.children, \"Parent with children must exist\")\n\n\t\tconst curParentNodeIds = selectedNodesPerParent[curParentId]\n\t\tassert(isArray(curParentNodeIds), \"curParentNodeIds must be an array\")\n\n\t\tconst parentHasLayout = hasAnyLayout(parent)\n\t\tconst selectableChildrenIds = getSelectableChildren(parent)\n\n\t\t// If there are no other selectable siblings, then there is nothing to cycle through, so we want to keep the\n\t\t// selection the same for this parent.\n\t\tif (!selectableChildrenIds || selectableChildrenIds.length === 0) {\n\t\t\tselectionIds.push(...curParentNodeIds)\n\t\t\tcontinue\n\t\t}\n\n\t\t// When the selection contains multiple nodes for a particular parent, we set the selection to the first or last\n\t\t// selectable child inside of this parent.\n\t\tif (curParentNodeIds.length > 1) {\n\t\t\tconst { firstNodeId, lastNodeId } = getSelectionBoundaryNodes(selectableChildrenIds, curParentNodeIds)\n\t\t\tif (!isNodeId(firstNodeId)) continue\n\n\t\t\tselectionIds.push(parentHasLayout ? firstNodeId : lastNodeId)\n\t\t\tcontinue\n\t\t}\n\n\t\t// By now, we know the current selection within this parent is a single node, so we must cycle through the other\n\t\t// siblings. We need to find out the current index we have cycled to by finding the index of the first matching\n\t\t// node in the selection against the array of other children IDs.\n\t\tconst currentNodeId = curParentNodeIds[0]\n\t\tassert(isDefined(currentNodeId), \"Current node ID must exist\")\n\t\tconst currentIndex = selectableChildrenIds.indexOf(currentNodeId)\n\n\t\t// If the parent doesn't have a layout, then forward/backwards are inverted so we go from bottom to top.\n\t\tconst appliedIsForward = parentHasLayout ? isForward : !isForward\n\t\tconst nextSelection = getNextSingleSelection(currentIndex, selectableChildrenIds, appliedIsForward)\n\n\t\tselectionIds.push(nextSelection)\n\t}\n\n\tselectionStore.set(selectionIds)\n}\n\n/**\n * isSelectable returns true if the node is a candidate\n * for cycling through with Tab / Shift + Tab.\n * A node is selectable if it's visible.\n * @param node A CanvasNode\n * @returns A boolean indicating whether the node is selectable\n */\nfunction isSelectable(node: CanvasNode): boolean {\n\treturn !!node.cache.visible\n}\n\nfunction getSelectableChildren(parent: CanvasNode): NodeID[] | undefined {\n\tconst children = hasItemsOrderOverride(parent) ? parent.getChildrenInVisualOrder() : parent.children\n\tif (!children) return\n\n\t// We only want to cycle through the selectable children. Some children may be locked for editing,\n\t// or hidden altogether, so it doesn't make sense to be able to tab to them\n\tconst selectableChildren: NodeID[] = []\n\tfor (const node of children) {\n\t\tif (!isSelectable(node)) continue\n\t\tselectableChildren.push(node.id)\n\t}\n\treturn selectableChildren\n}\n\nfunction getSelectionBoundaryNodes(\n\tselectableChildrenIds: NodeID[],\n\tselectedIds: NodeID[],\n): { firstNodeId: MaybeNodeID; lastNodeId: NodeID } {\n\tconst selectedIdsSet = new Set(selectedIds)\n\n\t// We try to find the first selectable child that *is* present in the selection. If there is no match, then we fall\n\t// back to the first selectable child.\n\tlet firstNodeId: MaybeNodeID\n\tfor (let i = 0; i < selectableChildrenIds.length; i++) {\n\t\tconst id = selectableChildrenIds[i]\n\t\tif (!id || !selectedIdsSet.has(id)) continue\n\n\t\tfirstNodeId = id\n\t\tbreak\n\t}\n\tfirstNodeId = firstNodeId || selectableChildrenIds[0]\n\n\t// Similarly, we try to find the last selectable child that *is* present in the selection. Otherwise, we fall back\n\t// to the last selectable child.\n\tlet lastNodeId: MaybeNodeID\n\tfor (let i = selectableChildrenIds.length - 1; i >= 0; i -= 1) {\n\t\tconst id = selectableChildrenIds[i]\n\t\tif (!id || !selectedIdsSet.has(id)) continue\n\n\t\tlastNodeId = id\n\t\tbreak\n\t}\n\n\tassert(lastNodeId, \"lastNodeId is undefined\")\n\n\treturn { firstNodeId, lastNodeId }\n}\n\nfunction getNextSingleSelection(currentIndex: number, selectableChildrenIds: NodeID[], isForward: boolean) {\n\tconst length = selectableChildrenIds.length\n\tconst nextIndex = ((isForward ? currentIndex + 1 : currentIndex - 1) + length) % length\n\n\tconst nextSelection = selectableChildrenIds[nextIndex]\n\tassert(nextSelection, \"nextSelection is undefined\")\n\treturn nextSelection\n}\n", "export const textContentComputedValuePopoutId = \"text-content\"\n", "import { triggerDrawingShapeEditEvent } from \"@framerjs/framer-events\"\nimport { assert, isExternalModuleIdentifier, isLocalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport { isOnlyVisibleInCurrentVariant } from \"code-generation/utils/isOnlyVisibleInCurrentVariant.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { TextEditToolOptions } from \"document/components/tools/TextEditTool.ts\"\nimport { ContextAction } from \"document/components/utils/contextActions.ts\"\nimport type { CanvasNode, FrameNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { ExternalModuleNode } from \"document/models/CanvasTree/nodes/ExternalModuleNode.ts\"\nimport { TemplateHelper, generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport { getPageNodeIdForPrototype } from \"document/models/CanvasTree/nodes/utils/getPageNodeIdForPrototype.ts\"\nimport { isAnyTextNode } from \"document/models/CanvasTree/nodes/utils/isAnyTextNode.ts\"\nimport {\n\tisBooleanShapeNode,\n\tisCodeComponentNode,\n\tisFrameNode,\n\tisRichTextNode,\n\tisSVGNode,\n\tisShaderNode,\n\tisShapeContainerNode,\n\tisShapeGroupNode,\n\tisStackComponent,\n\tisTextNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { ComputedValue } from \"document/models/CanvasTree/traits/ComputedValue.ts\"\nimport { isComputedValue } from \"document/models/CanvasTree/traits/ComputedValue.ts\"\nimport type { VariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { hasImageFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport {\n\tactiveLayoutTemplateBreakpoint,\n\tgetLayoutTemplateForBreakpoint,\n\thasLayoutTemplate,\n} from \"document/models/CanvasTree/traits/WithLayoutTemplate.ts\"\nimport { paddingDefinedDefaults } from \"document/models/CanvasTree/traits/WithPadding.ts\"\nimport { withPath } from \"document/models/CanvasTree/traits/WithPath.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport { isReplica, isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport {\n\tisBreakpointVariant,\n\tisReplicaVariantOrReplicaVariantChild,\n} from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { HardCodedCodeIdentifier } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifiers.ts\"\nimport { Tools } from \"document/stores/ToolEnum.ts\"\nimport { ActiveContentPanelTab } from \"document/utils/ActiveEditorType.ts\"\nimport { DimensionType } from \"library/render/types/Constraints.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { getEditableNestedVariableReference, isNestedVariableId } from \"utils/collectionReferenceUtils.ts\"\nimport { editVariable } from \"utils/editVariable.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { dispatchAction } from \"../actions/ActionResponder.tsx\"\nimport { isCanvasLocalizationScope } from \"../chrome/QuickActions/utils/LocalizationScope.ts\"\nimport { isRichTextSource } from \"../chrome/localization/getLocalizationSources.ts\"\nimport { getLocalizationSourcesForNode } from \"../chrome/localization/getLocalizationSourcesForNode.ts\"\nimport { PanelElementId, highlightPanel } from \"../chrome/properties/panels/utils/highlightPanel.ts\"\nimport { textContentComputedValuePopoutId } from \"../chrome/properties/panels/utils/textContentComputedValuePopoutId.ts\"\nimport { PopoutNavigationId } from \"../chrome/shared/PopoutNavigationId.ts\"\nimport { flattenEnabled, flattenShapes } from \"../tools/pathEdit/utils/index.ts\"\nimport { editActionForCodeComponent, goToLocalSourceNode } from \"./editActionForCodeComponent.ts\"\nimport { getEditableCollectionVariableInfo } from \"./getEditableCollectionVariableInfo.ts\"\n\ntype EventSource = \"none\" | \"mouse\" | \"keyboard\"\n\nexport function createEditVariableAction(\n\tengine: VekterEngine,\n\tnode: CanvasNode,\n\tvariable: VariableReference,\n): () => void {\n\tconst variableId = variable.id\n\tconst providerId = variable.providerId ?? engine.tree.getScopeNodeFor(node)?.id\n\treturn () => {\n\t\tif (!providerId) return\n\t\teditVariable(engine, variableId, providerId)\n\t}\n}\n\nfunction createEditRichTextVariableAction(\n\tengine: VekterEngine,\n\tvariableReference: VariableReference,\n\teventSource: EventSource,\n) {\n\tconst variableInfo = getEditableCollectionVariableInfo(\n\t\tengine.tree,\n\t\tengine.componentLoader,\n\t\tengine.stores.treeStore.sandboxRepeaterData,\n\t\tvariableReference,\n\t\tControlType.RichText,\n\t\tundefined,\n\t)\n\tif (!variableInfo) return\n\n\treturn () => {\n\t\tengine.setTool(Tools.RichTextVariableEdit, {\n\t\t\teventSource,\n\t\t\tvariableReference,\n\t\t})\n\t}\n}\n\nfunction createEditDateVariableActionTool(engine: VekterEngine, computedValue: ComputedValue) {\n\tconst variableReference = computedValue.startValue\n\tif (!isVariableReference(variableReference)) return\n\n\tconst variableInfo = getEditableCollectionVariableInfo(\n\t\tengine.tree,\n\t\tengine.componentLoader,\n\t\tengine.stores.treeStore.sandboxRepeaterData,\n\t\tvariableReference,\n\t\tControlType.Date,\n\t\tundefined,\n\t)\n\tif (!variableInfo) return\n\n\treturn () => {\n\t\tengine.setTool(Tools.DateVariableEdit, {\n\t\t\tvariableReference,\n\t\t})\n\t}\n}\n\nfunction createEditEnumVariableActionTool(engine: VekterEngine, computedValue: ComputedValue) {\n\tconst variableReference = computedValue.startValue\n\tif (!isVariableReference(variableReference)) return\n\n\tconst variableInfo = getEditableCollectionVariableInfo(\n\t\tengine.tree,\n\t\tengine.componentLoader,\n\t\tengine.stores.treeStore.sandboxRepeaterData,\n\t\tvariableReference,\n\t\tControlType.Enum,\n\t\tundefined,\n\t)\n\tif (!variableInfo) return\n\n\treturn () => {\n\t\tengine.setTool(Tools.EnumVariableEdit, {\n\t\t\tvariableReference,\n\t\t})\n\t}\n}\n\nfunction createEditCollectionReferenceVariableActionTool(engine: VekterEngine, variableReference: VariableReference) {\n\tif (!isNestedVariableId(variableReference.id)) {\n\t\treturn\n\t}\n\n\treturn () => {\n\t\tengine.setTool(Tools.CollectionReferenceVariableEdit, {\n\t\t\tvariableReference,\n\t\t})\n\t}\n}\n\nfunction createEditStringVariableAction(\n\tengine: VekterEngine,\n\tvariableReference: VariableReference,\n\teventSource: EventSource,\n) {\n\tconst variableInfo = getEditableCollectionVariableInfo(\n\t\tengine.tree,\n\t\tengine.componentLoader,\n\t\tengine.stores.treeStore.sandboxRepeaterData,\n\t\tvariableReference,\n\t\tControlType.String,\n\t\tundefined,\n\t)\n\tif (!variableInfo) return\n\n\treturn () => {\n\t\tengine.setTool(Tools.StringVariableEdit, {\n\t\t\teventSource,\n\t\t\tvariableReference,\n\t\t})\n\t}\n}\n\nexport function editActionForNodes(\n\tengine: VekterEngine,\n\tnodeIds: NodeID[],\n\teventSource: EventSource = \"none\",\n): () => void {\n\tconst { tree, componentLoader, tool } = engine\n\n\tlet action: () => void = () => {}\n\tif (tool.enum !== Tools.Highlight && tool.enum !== Tools.Move) {\n\t\treturn action\n\t}\n\n\tif (nodeIds.length === 0) {\n\t\treturn action\n\t}\n\n\tconst maybeAction = maybeGraphicsActionForSelection(engine, nodeIds)\n\tif (maybeAction) {\n\t\taction = maybeAction\n\t}\n\n\tif (!maybeAction && eventSource === \"keyboard\") {\n\t\t// Default to selecting all children of the selection\n\t\taction = () => dispatchAction(\"selectChildren\")\n\t}\n\n\tif (nodeIds.length > 1) return action\n\n\tconst node = tree.getNode(nodeIds[0])\n\tif (!node) return action\n\n\t// Handle WebPage nodes with layout templates\n\tif (isWebPageNode(node) && hasLayoutTemplate(node) && node.isLoaded()) {\n\t\tconst identifier = node.layoutTemplateIdentifier\n\t\tconst primaryVariant = node.getPrimaryVariant()\n\t\tconst activeVariant = activeLayoutTemplateBreakpoint(identifier, componentLoader, primaryVariant.width)\n\n\t\treturn () =>\n\t\t\tgoToLocalSourceNode(parseModuleIdentifier(identifier).localIdName, engine, activeVariant, {\n\t\t\t\tkeepHistory: true,\n\t\t\t\tactivateContentPanel: ActiveContentPanelTab.Layers,\n\t\t\t})\n\t}\n\n\tif (isBreakpointVariant(node) && isPinnable(node)) {\n\t\tconst identifier = getLayoutTemplateForBreakpoint(tree, node)\n\t\tif (identifier) {\n\t\t\tconst activeVariant = activeLayoutTemplateBreakpoint(identifier, componentLoader, node.width)\n\n\t\t\treturn () =>\n\t\t\t\tgoToLocalSourceNode(parseModuleIdentifier(identifier).localIdName, engine, activeVariant, {\n\t\t\t\t\tkeepHistory: true,\n\t\t\t\t\tactivateContentPanel: ActiveContentPanelTab.Layers,\n\t\t\t\t})\n\t\t}\n\t}\n\n\tif (isCodeComponentNode(node)) {\n\t\tconst parsedId = parseModuleIdentifier(node.codeComponentIdentifier)\n\t\tconst externalModuleNode = isExternalModuleIdentifier(parsedId)\n\t\t\t? engine.tree.getNode<ExternalModuleNode>(parsedId.moduleId)\n\t\t\t: null\n\n\t\tif (node.codeComponentIdentifier === HardCodedCodeIdentifier.prototype) {\n\t\t\tconst pageNodeId = getPageNodeIdForPrototype(node, componentLoader)\n\t\t\tif (pageNodeId) {\n\t\t\t\taction = () => engine.stores.scopeStore.select(pageNodeId, { keepHistory: false })\n\t\t\t}\n\t\t} else {\n\t\t\taction =\n\t\t\t\teditActionForCodeComponent(node, engine, {\n\t\t\t\t\texternalModuleType: externalModuleNode?.type,\n\t\t\t\t\tactivateContentPanel: ActiveContentPanelTab.Layers,\n\t\t\t\t}) ?? (() => highlightPanel({ id: PanelElementId.CodeComponentPanel, flash: true }))\n\t\t}\n\t} else if (isShaderNode(node)) {\n\t\tconst isViewOnly = getIsViewOnly(engine, \"canDesign\")\n\t\tif (isViewOnly) return action\n\n\t\tconst parsedIdentifier = parseModuleIdentifier(node.shaderModuleIdentifier)\n\t\tif (isLocalModuleIdentifier(parsedIdentifier)) {\n\t\t\tconst entry = engine.stores.modulesStore.getModuleEntryByLocalId(parsedIdentifier.localId)\n\t\t\tif (entry?.name) {\n\t\t\t\taction = () => engine.stores.codeEditorStore.editFile(entry.name)\n\t\t\t}\n\t\t}\n\t} else if (engine.stores.chromeStore.isPreviewingLocaleOnCanvas) {\n\t\treturn () => {\n\t\t\tconst activeScope = engine.stores.scopeStore.active\n\t\t\tif (!isCanvasLocalizationScope(activeScope)) return\n\n\t\t\tconst sources = getLocalizationSourcesForNode(node, engine)\n\t\t\tif (sources.length !== 1) return\n\n\t\t\tconst [source] = sources\n\t\t\tif (!source || !isRichTextSource(source)) return\n\n\t\t\tengine.stores.chromeStore.setOverlay({ type: \"localization\", keyPath: source.keyPath, singleColumn: true })\n\t\t}\n\t}\n\n\tif (isShapeContainerNode(node)) {\n\t\taction = () => dispatchAction(\"selectChildren\")\n\t}\n\n\tif (getIsViewOnly(engine, \"canDesign\")) {\n\t\treturn action\n\t}\n\n\t// Can edit\n\n\tconst editableNestedVariable = getEditableNestedVariableReference(node)\n\tif (editableNestedVariable) {\n\t\tconst action = createEditCollectionReferenceVariableActionTool(engine, editableNestedVariable)\n\t\tif (action) return action\n\t}\n\n\tif (hasImageFill(node) && isVariableReference(node.fillImage)) {\n\t\tconst variableInfo = getEditableCollectionVariableInfo(\n\t\t\tengine.tree,\n\t\t\tengine.componentLoader,\n\t\t\tengine.stores.treeStore.sandboxRepeaterData,\n\t\t\tnode.fillImage,\n\t\t\tControlType.Image,\n\t\t\tundefined,\n\t\t)\n\n\t\tif (variableInfo) {\n\t\t\treturn () => {\n\t\t\t\tconst popoutNavigation = engine.floatingWindowPopoutNavigation\n\t\t\t\tif (popoutNavigation && !popoutNavigation.isPresenting(PopoutNavigationId.FillValueTransform)) {\n\t\t\t\t\tpopoutNavigation.presentPopout(PopoutNavigationId.FillValueTransform)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// show the cms overlay as before\n\t\treturn createEditVariableAction(engine, node, node.fillImage)\n\t}\n\n\tif (isTextNode(node) || isRichTextNode(node)) {\n\t\tif (isRichTextNode(node) && isVariableReference(node.htmlContent)) {\n\t\t\taction =\n\t\t\t\tcreateEditRichTextVariableAction(engine, node.htmlContent, eventSource) ??\n\t\t\t\tcreateEditVariableAction(engine, node, node.htmlContent)\n\t\t} else if (isComputedValue(node.textContent)) {\n\t\t\tconst variableEditToolAction =\n\t\t\t\tcreateEditDateVariableActionTool(engine, node.textContent) ||\n\t\t\t\tcreateEditEnumVariableActionTool(engine, node.textContent)\n\t\t\tif (variableEditToolAction) {\n\t\t\t\taction = variableEditToolAction\n\t\t\t} else {\n\t\t\t\taction = () => {\n\t\t\t\t\tengine.stores.chromeStore.hideOverlay()\n\t\t\t\t\tengine.floatingWindowPopoutNavigation?.presentPopout(textContentComputedValuePopoutId)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (isVariableReference(node.textContent)) {\n\t\t\taction =\n\t\t\t\tcreateEditStringVariableAction(engine, node.textContent, eventSource) ??\n\t\t\t\tcreateEditVariableAction(engine, node, node.textContent)\n\t\t} else {\n\t\t\taction = isTextNode(node)\n\t\t\t\t? () => engine.setTool(Tools.TextEdit, { eventSource })\n\t\t\t\t: () => engine.setTool(Tools.RichTextEdit, { eventSource })\n\t\t}\n\t} else if (isSVGNode(node)) {\n\t\taction = () => {\n\t\t\tContextAction.convertSVGToShape(engine, node)\n\t\t}\n\t} else if (isFrameNode(node)) {\n\t\tif (node.fillEnabled && node.fillType === \"image\") {\n\t\t\taction = () => {\n\t\t\t\tconst popoutNavigation = engine.floatingWindowPopoutNavigation\n\t\t\t\tif (popoutNavigation && !popoutNavigation.isPresenting(\"fill\")) {\n\t\t\t\t\tpopoutNavigation.presentPopout(\"fill\")\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tconst noChildren = node.children.length === 0\n\t\t\tconst firstChild = node.children.length === 1 ? node.children.at(0) : null\n\t\t\tconst singleTextChild = isAnyTextNode(firstChild)\n\t\t\tif (noChildren || singleTextChild) {\n\t\t\t\taction = addTextAction(engine, node, eventSource)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn action\n}\n\nfunction maybeGraphicsActionForSelection(engine: VekterEngine, nodeIds: NodeID[]) {\n\tif (nodeIds.length === 0) return null\n\n\tlet allNodesAreShapeNodes = true\n\tlet allNodesArePathNodes = true\n\tlet someNodesWithShapeChildren = false\n\n\tconst nodes: CanvasNode[] = []\n\tfor (const nodeId of nodeIds) {\n\t\tconst node = engine.tree.getNode(nodeId)\n\t\tif (!node) continue\n\n\t\tallNodesAreShapeNodes = allNodesAreShapeNodes && withShape(node)\n\t\tallNodesArePathNodes = allNodesArePathNodes && withPath(node)\n\t\tsomeNodesWithShapeChildren = someNodesWithShapeChildren || isBooleanShapeNode(node) || isShapeGroupNode(node)\n\n\t\tnodes.push(node)\n\t}\n\n\tif (!allNodesAreShapeNodes) return null\n\n\tif (allNodesArePathNodes) {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return null\n\n\t\treturn () => {\n\t\t\ttriggerDrawingShapeEditEvent({})\n\t\t\tengine.setTool(Tools.Path)\n\t\t}\n\t} else if (someNodesWithShapeChildren) {\n\t\t// select all deepest children, basic shapes and paths\n\t\treturn () => {\n\t\t\tconst newSelection: NodeID[] = []\n\n\t\t\tfunction addToSelection(canvasNodes: Iterable<CanvasNode>) {\n\t\t\t\tfor (const node of canvasNodes) {\n\t\t\t\t\tif (withChildren(node)) {\n\t\t\t\t\t\taddToSelection(node.children)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Add basic shapes and paths\n\t\t\t\t\t\tnewSelection.push(node.id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taddToSelection(nodes)\n\t\t\tengine.stores.selectionStore.set(newSelection)\n\t\t}\n\t} else if (flattenEnabled(engine, nodes)) {\n\t\treturn () => {\n\t\t\tflattenShapes(engine, nodes, true)\n\t\t}\n\t}\n\n\treturn null\n}\n\nfunction addTextAction(engine: VekterEngine, node: FrameNode, eventSource: \"none\" | \"mouse\" | \"keyboard\") {\n\treturn () => {\n\t\tconst latestNode = engine.tree.getNode(node.id)\n\t\tif (!latestNode || !isFrameNode(latestNode)) return\n\t\tif (isStackComponent(latestNode)) return\n\t\tif (!latestNode.cache.visible) return\n\n\t\tconst textToolOptions: TextEditToolOptions = { eventSource }\n\n\t\tconst nodeRect = engine.tree.getRect(latestNode)\n\t\tconst nodeCenterLocal = Rect.center(Rect.atOrigin(nodeRect))\n\t\tconst nodeCenterCanvas = engine.tree.convertPointToCanvas(latestNode, nodeCenterLocal)\n\t\tconst visibleCanvasRect = engine.stores.canvasStore.getCanvasVisibleRectTakingOverlaysIntoAccount()\n\t\tconst nodeCenterIsVisibleInViewport = Rect.containsPoint(visibleCanvasRect, nodeCenterCanvas)\n\t\tif (!nodeCenterIsVisibleInViewport) return\n\n\t\tconst childCount = latestNode.children.length\n\t\tif (childCount === 0) {\n\t\t\tlet originalParent: CanvasNode | null = latestNode\n\t\t\tlet insertIntoReplicaVariant: boolean = false\n\t\t\tlet shouldHideOriginal = false\n\n\t\t\tif (isReplicaOrReplicaChild(latestNode)) {\n\t\t\t\tif (isReplicaVariantOrReplicaVariantChild(latestNode)) {\n\t\t\t\t\toriginalParent = engine.tree.getNode(latestNode.originalid)\n\t\t\t\t\tassert(originalParent, \"Failed to add text to variant: the original parent should exist\")\n\t\t\t\t\tinsertIntoReplicaVariant = true\n\t\t\t\t\tshouldHideOriginal = !isOnlyVisibleInCurrentVariant(engine.tree, latestNode)\n\t\t\t\t} else {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(isFrameNode(originalParent))\n\t\t\toriginalParent.set({\n\t\t\t\t...paddingDefinedDefaults,\n\t\t\t\tlayout: \"stack\",\n\t\t\t\tstackAlignment: \"center\",\n\t\t\t\tstackDirection: nodeRect.width > nodeRect.height ? \"horizontal\" : \"vertical\",\n\t\t\t\tstackDistribution: \"center\",\n\t\t\t\tgap: 10,\n\t\t\t})\n\t\t\tconst text = engine.createRichText(originalParent.id, {\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\twidthType: DimensionType.Auto,\n\t\t\t\theightType: DimensionType.Auto,\n\t\t\t\tvisible: !shouldHideOriginal,\n\t\t\t})\n\n\t\t\tlet idToSelect = text.id\n\n\t\t\tif (insertIntoReplicaVariant) {\n\t\t\t\tconst replicaRoot = TemplateHelper.getReplicaForTemplateNode(engine.tree, latestNode)\n\t\t\t\tassert(replicaRoot && isReplica(replicaRoot), \"Failed to find replica root \")\n\t\t\t\tidToSelect = generateReplicaChildId(replicaRoot.id, text.id)\n\t\t\t\tTemplateHelper.replicaWithChanges(engine.tree, replicaRoot.draftOrCurrent())\n\t\t\t\t// Unhide the node in replica\n\t\t\t\tif (shouldHideOriginal) {\n\t\t\t\t\tconst nodeToMakeVisible = engine.tree.getNode(idToSelect)\n\t\t\t\t\tassert(nodeToMakeVisible, \"Should find variant text node to make it visible\")\n\t\t\t\t\tnodeToMakeVisible.set({ visible: true })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tengine.stores.selectionStore.set(idToSelect)\n\n\t\t\ttextToolOptions.ignoreEditIfEmpty = true\n\t\t\tengine.setTool(Tools.RichTextEdit, textToolOptions)\n\t\t} else if (childCount === 1) {\n\t\t\tconst textNode = node.children.at(0)\n\t\t\tassert(isAnyTextNode(textNode), \"Node child should be a text node\")\n\t\t\tif (!textNode.cache.visible) return\n\t\t\tengine.stores.selectionStore.set(textNode.id)\n\t\t\tengine.setTool(isTextNode(textNode) ? Tools.TextEdit : Tools.RichTextEdit, textToolOptions)\n\t\t}\n\t}\n}\n", "import { assert, isAppleDevice } from \"@framerjs/shared\"\nimport { MetricsInteractionViews } from \"app/metrics.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { ContextAction } from \"document/components/utils/contextActions.ts\"\nimport { isDesignPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { Tools } from \"document/stores/ToolStore.ts\"\nimport { cycleSelection } from \"document/utils/cycleSelection.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { editActionForNodes } from \"../utils/editActionForNodes.ts\"\nimport { ScaleTool } from \"./ScaleTool.ts\"\n\nconst keyRepeatAllowed = Symbol(\"allowKeyRepeat\")\nconst modifierKeys = new Set([\"Alt\", \"Control\", \"Meta\", \"Shift\"])\n\nconst alternativePathShortcut = \"V\"\n\ninterface KeyRepeatCallback {\n\t(): void\n\t[keyRepeatAllowed]: true\n}\n\ninterface KeyMap {\n\t[key: string]: () => void\n}\n\n/** General tool manager key handling. */\nexport function createToolKeyDownHandler(engine: VekterEngine) {\n\treturn (event: KeyboardEvent) => {\n\t\tnew ToolManagerMenu(engine).onKeyDown(event)\n\t}\n}\n\n/**\n * allowKeyRepeat allows a handler to be enabled when `event.repeat` is true\n * (e.g., when a key is held down). Otherwise, the handler will not be executed.\n */\nfunction allowKeyRepeat(callback: () => void): KeyRepeatCallback {\n\tconst repeatableCallback = callback as KeyRepeatCallback\n\trepeatableCallback[keyRepeatAllowed] = true\n\treturn repeatableCallback\n}\n\nfunction isKeyRepeatedCallback(callback: unknown): callback is KeyRepeatCallback {\n\treturn typeof callback === \"function\" && keyRepeatAllowed in callback && callback[keyRepeatAllowed] === true\n}\n\nclass ToolManagerMenu {\n\tprivate _keyMap: KeyMap | undefined\n\n\tprivate getKeyMap() {\n\t\tif (!this._keyMap) {\n\t\t\tthis._keyMap = {\n\t\t\t\tEscape: this.cancelTool,\n\t\t\t\t// TODO: this action should by handled by the main menu but something is preventing it\n\t\t\t\t\"Meta+Enter\": this.createFrame,\n\t\t\t\t\"Meta+Alt+Enter\": this.createStack,\n\t\t\t\tEnter: this.openOrEditAction,\n\t\t\t\tF: this.frame,\n\t\t\t\tK: this.scale,\n\t\t\t\tL: this.link,\n\t\t\t\tS: this.screen,\n\t\t\t\tT: this.text,\n\t\t\t\tP: this.path,\n\t\t\t\t[alternativePathShortcut]: this.path,\n\t\t\t\tO: this.oval,\n\t\t\t\t\"Shift+S\": this.stack,\n\t\t\t\tR: this.rectangle,\n\t\t\t\tTab: this.cycleSelection,\n\t\t\t\t\"Shift+Tab\": this.decycleSelection,\n\t\t\t}\n\t\t}\n\t\treturn this._keyMap\n\t}\n\n\tconstructor(public engine: VekterEngine) {}\n\n\tprivate event: KeyboardEvent | undefined\n\n\tonKeyDown = (event: KeyboardEvent) => {\n\t\tassert(!this.event, \"this instance can only be used once, for a single operation\")\n\t\tthis.event = event\n\t\tconst shortcut = keyDownToShortcut(event)\n\t\tconst keyMap = this.getKeyMap()\n\t\tif (!keyMap) return\n\t\tconst action = keyMap[shortcut]\n\n\t\tif (!action) return\n\t\tif (event.repeat && !isKeyRepeatedCallback(action)) return\n\n\t\taction()\n\t}\n\n\tprivate get toolIsViewOnly() {\n\t\tif (getIsViewOnly(this.engine, \"canDesign\")) return true\n\t\tif (this.engine.stores.chromeStore.isPreviewingLocaleOnCanvas) return true\n\t\treturn false\n\t}\n\n\tprivate text = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateText)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateText\" })\n\t}\n\n\tprivate rectangle = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateRectangleShape)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateRectangleShapeeate\" })\n\t}\n\n\tprivate oval = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateOvalShape)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateOvalShape\" })\n\t}\n\n\tprivate path = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.stores.selectionStore.clear()\n\t\tthis.engine.setTool(Tools.Path)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-Path\" })\n\t}\n\n\tprivate screen = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateScreen)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateScreen\" })\n\t}\n\n\tprivate stack = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateStack)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateStackComponent\" })\n\t}\n\n\tprivate link = () => {\n\t\tif (this.toolIsViewOnly) return\n\t\tif (isDesignPageNode(this.engine.stores.scopeStore.active)) return\n\n\t\tthis.engine.setTool(Tools.Link)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-NavigationLink\" })\n\t}\n\n\tprivate frame = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tthis.engine.setTool(Tools.CreateFrame)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-CreateFrame\" })\n\t}\n\n\tprivate scale = () => {\n\t\tif (this.toolIsViewOnly) return\n\t\tif (this.engine.stores.selectionStore.ids.length === 0) return\n\t\tif (this.engine.stores.selectionStore.nodes.some(n => isBreakpointVariant(n))) return\n\t\tif (this.engine.tool.enum === Tools.Scale) return // if the tool is already active, do not restart it\n\n\t\tthis.engine.setTool(Tools.Scale)\n\t\trecord(\"ui_interaction\", { page: MetricsInteractionViews.MAIN_MENU, id: \"tool-Scale\" })\n\t}\n\n\tprivate openOrEditAction = () => {\n\t\tconst nodeIds = this.engine.stores.selectionStore.ids\n\t\tif (nodeIds.length === 0) return\n\n\t\tconst { activeElement, body } = document\n\n\t\t// Input components from fresco already prevent default for 'Enter' keydown to ensure\n\t\t// that global listeners for the same keypress are not executed (such as this one).\n\t\t// This code remains as a defensive check to ensure that the edit action is not\n\t\t// executed for any future inputs that may be added that do not use the design system\n\t\t// and therefore don't perform the special default prevention logic.\n\t\tif (activeElement && activeElement !== body) return\n\n\t\t// commit changes from scale tool\n\t\tif (this.engine.tool instanceof ScaleTool) {\n\t\t\tthis.engine.exitTool()\n\t\t\treturn\n\t\t}\n\n\t\tconst editAction = editActionForNodes(this.engine, nodeIds, \"keyboard\")\n\t\tif (editAction) {\n\t\t\teditAction()\n\t\t\tassert(this.event, \"editAction() can only be called after onKeyDown()\")\n\t\t\tthis.event.preventDefault()\n\t\t}\n\t}\n\n\tprivate cycleSelection = allowKeyRepeat(() => {\n\t\tcycleSelection({ engine: this.engine })\n\t\tassert(this.event, \"cycleSelection() can only be called after onKeyDown()\")\n\t\tthis.event.preventDefault()\n\t})\n\n\tprivate decycleSelection = allowKeyRepeat(() => {\n\t\tcycleSelection({ engine: this.engine, isForward: false })\n\t\tassert(this.event, \"decycleSelection() can only be called after onKeyDown()\")\n\t\tthis.event.preventDefault()\n\t})\n\n\tprivate createFrame = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tconst frameId = ContextAction.addFrame(this.engine, this.engine.stores.selectionStore.nodes)\n\t\tconst node = this.engine.tree.getNode(String(frameId))\n\n\t\tif (!node) return\n\n\t\tconst { width, height } = this.engine.tree.getRect(node)\n\t\trecord(\"layout_frame\", {\n\t\t\tsource: \"keyboard\",\n\t\t\twidth,\n\t\t\theight,\n\t\t})\n\t\tassert(this.event, \"createFrame() can only be called after onKeyDown()\")\n\t\tthis.event.preventDefault()\n\t}\n\n\tprivate createStack = () => {\n\t\tif (this.toolIsViewOnly) return\n\n\t\tContextAction.addStack(this.engine, this.engine.stores.selectionStore.nodes)\n\t\t// Metrics.push({ type: MetricEventType.LAYOUT_CREATE_FRAME, source: \"keyboard\" })\n\t\tassert(this.event, \"createStack() can only be called after onKeyDown()\")\n\t\tthis.event.preventDefault()\n\t}\n\n\tprivate cancelTool = () => {\n\t\tif (this.engine.tool.enum === Tools.Highlight) return\n\t\tif (this.engine.tool.enum === Tools.Path) return\n\n\t\tthis.engine.cancelTool()\n\t\tassert(this.event, \"cancelTool() can only be called after onKeyDown()\")\n\t\tthis.event.preventDefault()\n\t\tthis.event.stopPropagation()\n\t}\n}\n\nfunction keyDownToShortcut(e: KeyboardEvent) {\n\tconst sb: string[] = []\n\t// To support Windows, we swap the Control and Meta keys.\n\tif (isAppleDevice()) {\n\t\tif (e.ctrlKey) sb.push(\"Control\")\n\t\t// eslint-disable-next-line no-restricted-syntax -- Used only for formatting\n\t\tif (e.metaKey) sb.push(\"Meta\")\n\t\tif (e.altKey) sb.push(\"Alt\")\n\t\tif (e.shiftKey) sb.push(\"Shift\")\n\t} else {\n\t\t// eslint-disable-next-line no-restricted-syntax -- Used only for formatting\n\t\tif (e.metaKey) sb.push(\"Control\")\n\t\tif (e.ctrlKey) sb.push(\"Meta\")\n\t\tif (e.altKey) sb.push(\"Alt\")\n\t\tif (e.shiftKey) sb.push(\"Shift\")\n\t}\n\tif (!modifierKeys.has(e.key)) {\n\t\tif (e.key === \" \") {\n\t\t\tsb.push(\"Space\")\n\t\t} else if (e.key.length === 1) {\n\t\t\t// Convert e.g., \"p\" to \"P\".\n\t\t\tsb.push(e.key.toUpperCase())\n\t\t} else {\n\t\t\t// The remaining keys will be special, e.g., \"Escape\" or Unicode.\n\t\t\tsb.push(e.key)\n\t\t}\n\t}\n\treturn sb.join(\"+\")\n}\n", "import type { CanvasNode, CanvasTree, LoadedScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode } from \"document/models/CanvasTree/index.ts\"\nimport { isSmartComponentNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { convertFrameToCanvas } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport { DimensionType } from \"library/index.ts\"\nimport type { Rect } from \"library/render/types/Rect.ts\"\n\n/** Get the size of a node before rendering. Some nodes have a static size, but some nodes are auto\n * sized, and normally depend on dom rendering. Here we guess their size. First via the sizeHint\n * property, otherwise with a heuristic. */\nexport function guessFrameForNode(tree: CanvasTree, node: CanvasNode): Readonly<Rect> {\n\tconst frame = convertFrameToCanvas(tree, node)\n\n\t// TODO use sizeHint when available\n\n\t// If the node is not pinnable we should know its size.\n\tif (!isPinnable(node)) return frame\n\n\t// If neither width nor height is auto, we should know its size.\n\tif (node.widthType !== DimensionType.Auto && node.heightType !== DimensionType.Auto) return frame\n\n\t// A breakpoint variants is a page of a webpage scope, guess that those are heigher than wide.\n\tif (isBreakpointVariant(node) && node.widthType !== DimensionType.Auto) {\n\t\tconst height = frame.width * 5\n\t\treturn { ...frame, height }\n\t}\n\n\t// Otherwise assume a 16:9 aspect ratio.\n\tif (node.widthType !== DimensionType.Auto) {\n\t\tconst height = (frame.width / 16) * 9\n\t\treturn { ...frame, height }\n\t}\n\n\tif (node.heightType !== DimensionType.Auto) {\n\t\tconst width = (frame.height / 9) * 16\n\t\treturn { ...frame, width }\n\t}\n\n\t// Otherwise guess the size is 1280x720.\n\treturn { ...frame, width: 1280, height: 720 }\n}\n\n/** Returns a ground node that can be considered the main node for a scope. Basically returns the\n * primary variant, otherwise the first frame, or first anything. */\nexport function guessMainNodeForScope(scope: LoadedScopeNode): CanvasNode | undefined {\n\tif (isWebPageNode(scope) || isSmartComponentNode(scope)) {\n\t\tlet node: CanvasNode | undefined = scope.getPrimaryVariant()\n\t\tif (!node.isVisible()) {\n\t\t\tnode = scope.getTopLevelReplicaVariants().find(n => n.isVisible())\n\t\t}\n\t\tif (node) return node\n\t}\n\n\t// Otherwise use the first frame we can find.\n\tfor (const child of scope.children) {\n\t\tif (!child.isVisible()) continue\n\t\tif (child instanceof FrameNode) return child\n\t}\n\n\t// Otherwise return the first child.\n\tfor (const child of scope.children) {\n\t\tif (!child.isVisible()) continue\n\t\treturn child\n\t}\n}\n", "import { chromeMainVersion } from \"@framerjs/shared/src/environment.ts\"\nimport type { EngineChanges } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { LayoutState } from \"document/LayoutState.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport {\n\ttype CanvasNode,\n\ttype CanvasTree,\n\ttype ScopeNode,\n\tisCanvasScopeNode,\n\tisDrawableNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { VECTOR_SET_COLUMNS } from \"document/models/CanvasTree/nodes/VectorSetNode.ts\"\nimport {\n\tisCanvasPageNode,\n\tisCollectionItemNode,\n\tisCollectionNode,\n\tisDesignPageNode,\n\tisVectorSetNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isVectorSetItem } from \"document/models/CanvasTree/traits/WithVectorSetItem.ts\"\nimport { getBoundingFrameForNodes } from \"document/models/CanvasTree/utils/geometry.ts\"\nimport type { DocumentSettingsStore } from \"document/stores/DocumentSettingsStore.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { Rect } from \"library/render/types/Rect.ts\"\nimport { Size } from \"library/render/types/Size.ts\"\nimport { guessFrameForNode, guessMainNodeForScope } from \"utils/guessFrameForNode.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { MouseStore } from \"./MouseStore.ts\"\nimport type { PersistedUserDefaults } from \"./PersistedUserDefaults.ts\"\nimport type { PluginStore } from \"./PluginStore.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst runningUnderTest = process.env.NODE_ENV === \"test\"\n\nconst zoomMin: number = 0.01\nconst zoomMax: number = 32\nconst zoomSteps = [zoomMin, 0.025, 0.05, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, zoomMax]\nconst mouseMoveThreshold = 3\n\ninterface Insets {\n\ttop: number\n\tright: number\n\tbottom: number\n\tleft: number\n}\n\nexport enum UpdateType {\n\t// Immediately reflect transform values, in the canvas renderer as well as app UI\n\tImmediate,\n\t// Animate to transform values in the canvas renderer, only updating app UI after the animation finishes\n\tAnimated,\n\t// Immediately reflect transform values in the canvas renderer, but delay app UI updates\n\tLive,\n}\n\nexport class CanvasStore {\n\t// Some tests can't deal with the async nature of animated zoom and depend on the default 800x800 container size\n\tprivate isConfiguredForTest = false\n\n\t// Viewport element size\n\tcontainerSize = Size(800, 800)\n\tprivate didSetContainerSizeOnce = false\n\n\t/** Unrounded real actual canvas zoom value. */\n\tprivate unroundedZoom: number = 1\n\n\t/** Unrounded real actual canvas scroll offset value. */\n\tprivate unroundedOffset: Readonly<Point> = Point(0, 0)\n\n\t// Canvas content (model/target values). Always use updateCanvas() to set. These values are rounded.\n\tinteractiveOffset: Readonly<Point> = Point(0, 0) // Placed at viewport top left\n\tinteractiveZoom = 1\n\n\t// Canvas content (live values). These values are rounded.\n\tprivate liveOffset?: Readonly<Point>\n\tliveZoom?: number\n\n\t// Return either the live offset, or the interactive offset, both are always rounded.\n\tget offset(): Readonly<Point> {\n\t\treturn this.liveOffset || this.interactiveOffset\n\t}\n\n\t// Return either the live zoom, or the interactive zoom, both are always rounded.\n\tget zoom(): number {\n\t\treturn this.liveZoom || this.interactiveZoom\n\t}\n\n\tcontentOutOfView?: boolean\n\n\tprivate liveAnimation?: {\n\t\tduration: number\n\t\tstartTime: number\n\t\tstartRect: Rect\n\t\tendRect: Rect\n\t\tcurrentRect: Rect\n\t}\n\n\tprivate autoscrolling?: {\n\t\tvelocity: { x: number; y: number }\n\t\tlastAnimationTick?: number\n\t}\n\n\t// In non-interactive mode, canvas components should do no or minimal rendering for optimal performance\n\t// May only be set in `updateCanvas`, `animateCanvas` and `endLiveTransform`\n\tisInteractive = true\n\n\t// For components that want to be explicit about suppressing rendering while the canvas is non-interactive\n\treadonly assertInteractive = environment.isDebugBuild\n\t\t? () => {\n\t\t\t\tif (!this.isInteractive) {\n\t\t\t\t\t// biome-ignore lint/suspicious/noConsole: <explanation>\n\t\t\t\t\tconsole.warn(\"Canvas is live (non-interactive) and should not cause re-renders\", new Error())\n\t\t\t\t}\n\t\t\t}\n\t\t: () => {}\n\n\t// other; TODO probably best to move these to tool store and/or server store\n\tcolorSamplerActive = false\n\n\tconstructor(\n\t\tprivate readonly taskScheduler: VekterEngineScheduler,\n\t\tprivate readonly engineStores: {\n\t\t\tlayoutState: LayoutState // TODO: resolve this circular dependency\n\t\t},\n\t\tprivate readonly pluginStore: PluginStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly mouseStore: MouseStore,\n\t\tprivate readonly persistedUserDefaults: PersistedUserDefaults,\n\t\tprivate readonly selectionStore: SelectionStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly documentSettingsStore: DocumentSettingsStore,\n\t\tprivate readonly changes: EngineChanges,\n\t\tprivate readonly getActiveScope: () => ScopeNode,\n\t\tprivate readonly selectScope: (scope: ScopeNode) => void,\n\t) {\n\t\tthis.endLiveTransformWrapped = this.taskScheduler.wrapHandler(this.endLiveTransform)\n\t\tthis.animateCanvasWrapped = this.taskScheduler.wrapHandler(this.animateCanvas)\n\t\tthis.endMagnification = this.taskScheduler.wrapHandler(() => {\n\t\t\tthis.updateCanvas(this.unroundedOffset, this.unroundedZoom)\n\t\t})\n\t\tthis.endMagnificationAfterInactiveDelay = this.taskScheduler.debounce(this.endMagnification, 150)\n\t}\n\n\tsetColorSamplerActive(colorSamplerActive: boolean): void {\n\t\tthis.colorSamplerActive = colorSamplerActive\n\t\tthis.changes.addChanges(EngineChange.CanvasStore)\n\t}\n\n\tsetContainerSize(width: number, height: number) {\n\t\tconst { width: oldWidth, height: oldHeight } = this.containerSize\n\t\tthis.containerSize = { width, height }\n\t\tif (this.didSetContainerSizeOnce) {\n\t\t\tconst delta = Point.divide(Point((oldWidth - width) / 2, (oldHeight - height) / 2), this.unroundedZoom)\n\t\t\tthis.updateCanvas(Point.add(this.unroundedOffset, delta), this.unroundedZoom)\n\t\t}\n\t\tthis.didSetContainerSizeOnce = true\n\t\tthis.changes.addChanges(EngineChange.CanvasStore)\n\t}\n\n\tprivate getContainerCenter(): Point {\n\t\treturn Rect.center(this.getContainerInteractiveRect())\n\t}\n\n\tprivate getCanvasOverlayInsets(): Insets {\n\t\tconst insets: Insets = {\n\t\t\ttop: 0,\n\t\t\tright: 0,\n\t\t\tbottom: 0,\n\t\t\tleft: this.engineStores.layoutState.currentCanvasOverlapLeft,\n\t\t}\n\n\t\tconst activePlugin = this.pluginStore.activePlugin\n\t\tif (!activePlugin) return insets\n\t\tconst windowState = activePlugin.windowState.getState()\n\t\tif (!windowState.visible) return insets\n\t\tconst floatingWindow = activePlugin.floatingWindowRef.current\n\t\tif (!floatingWindow) return insets\n\n\t\tconst floatingWindowContainer = floatingWindow.containerRef.current\n\t\tconst floatingWindowElement = floatingWindow.contentWrapperRef.current\n\t\tif (!floatingWindowContainer || !floatingWindowElement) return insets\n\n\t\tconst floatingWindowContainerBounds = floatingWindowContainer.getBoundingClientRect()\n\t\tconst floatingWindowBounds = floatingWindowElement.getBoundingClientRect()\n\n\t\tconst offsetLeft = floatingWindowBounds.left - floatingWindowContainerBounds.left\n\t\tconst offsetRight = floatingWindowContainerBounds.right - floatingWindowBounds.right\n\t\tconst offsetTop = floatingWindowBounds.top - floatingWindowContainerBounds.top\n\t\tconst offsetBottom = floatingWindowContainerBounds.bottom - floatingWindowBounds.bottom\n\n\t\tconst halfWidth = floatingWindowContainerBounds.width / 2\n\t\tconst halfHeight = floatingWindowContainerBounds.height / 2\n\n\t\tconst fullSizeThreshold = 20\n\t\tconst coveringFullHeight = offsetTop < fullSizeThreshold && offsetBottom < fullSizeThreshold\n\t\tconst coveringFullWidth = offsetLeft < fullSizeThreshold && offsetRight < fullSizeThreshold\n\n\t\tif (offsetLeft === 0 && coveringFullHeight && offsetRight > halfWidth) {\n\t\t\tinsets.left = floatingWindowBounds.right - floatingWindowBounds.left\n\t\t} else if (offsetRight === 0 && coveringFullHeight && offsetLeft > halfWidth) {\n\t\t\tinsets.right = floatingWindowBounds.right - floatingWindowBounds.left\n\t\t}\n\n\t\tif (offsetTop === 0 && coveringFullWidth && offsetBottom > halfHeight) {\n\t\t\tinsets.top = floatingWindowBounds.bottom - floatingWindowBounds.top\n\t\t} else if (offsetBottom === 0 && coveringFullWidth && offsetTop > halfHeight) {\n\t\t\tinsets.bottom = floatingWindowBounds.bottom - floatingWindowBounds.top\n\t\t}\n\n\t\treturn insets\n\t}\n\n\tprivate getContainerInteractiveRect(): Rect {\n\t\tconst { containerSize } = this\n\n\t\tif (this.isConfiguredForTest) {\n\t\t\treturn { x: 0, y: 0, ...containerSize }\n\t\t}\n\n\t\tif (!this.chromeStore.chromeIsVisible) {\n\t\t\treturn {\n\t\t\t\tx: 0,\n\t\t\t\ty: this.engineStores.layoutState.currentChromeMarginTop,\n\t\t\t\twidth: containerSize.width,\n\t\t\t\theight: containerSize.height - this.engineStores.layoutState.currentChromeMarginTop,\n\t\t\t}\n\t\t}\n\n\t\tconst overlayInsets = this.getCanvasOverlayInsets()\n\n\t\tconst insets = {\n\t\t\ttop: this.engineStores.layoutState.currentChromeMarginTop + overlayInsets.top,\n\t\t\tbottom: this.engineStores.layoutState.currentChromeMarginBottom + overlayInsets.bottom,\n\t\t\tleft: this.engineStores.layoutState.getCurrentTabContentWidth() + overlayInsets.left,\n\t\t\tright: this.engineStores.layoutState.getCurrentPropertyPanelWidth() + overlayInsets.right,\n\t\t}\n\n\t\treturn {\n\t\t\tx: insets.left,\n\t\t\ty: insets.top,\n\t\t\twidth: containerSize.width - insets.left - insets.right,\n\t\t\theight: containerSize.height - insets.top - insets.bottom,\n\t\t}\n\t}\n\n\tgetCanvasCenter(): Point {\n\t\treturn this.convertContainerPointToCanvas(this.getContainerCenter())\n\t}\n\n\tgetCanvasVisibleRect(): Rect {\n\t\tconst { containerSize, offset, zoom } = this\n\t\tconst chromeMarginLeft = this.engineStores.layoutState.currentChromeMarginLeft\n\t\tconst chromeMarginRight = this.engineStores.layoutState.currentChromeMarginRight\n\t\tconst chromeMarginTop = this.engineStores.layoutState.currentChromeMarginTop\n\t\tconst chromeMarginBottom = this.engineStores.layoutState.currentChromeMarginBottom\n\n\t\treturn {\n\t\t\tx: offset.x + chromeMarginLeft / zoom,\n\t\t\ty: offset.y + chromeMarginTop / zoom,\n\t\t\twidth: (containerSize.width - chromeMarginLeft - chromeMarginRight) / zoom,\n\t\t\theight: (containerSize.height - chromeMarginTop - chromeMarginBottom) / zoom,\n\t\t}\n\t}\n\n\tgetCanvasVisibleRectTakingOverlaysIntoAccount(): Rect {\n\t\tconst { containerSize, offset, zoom } = this\n\t\tconst overlayInsets = this.getCanvasOverlayInsets()\n\t\tconst chromeMarginLeft = this.engineStores.layoutState.currentChromeMarginLeft + overlayInsets.left\n\t\tconst chromeMarginRight = this.engineStores.layoutState.currentChromeMarginRight + overlayInsets.right\n\t\tconst chromeMarginTop = this.engineStores.layoutState.currentChromeMarginTop + overlayInsets.top\n\t\tconst chromeMarginBottom = this.engineStores.layoutState.currentChromeMarginBottom + overlayInsets.bottom\n\n\t\treturn {\n\t\t\tx: offset.x + chromeMarginLeft / zoom,\n\t\t\ty: offset.y + chromeMarginTop / zoom,\n\t\t\twidth: (containerSize.width - chromeMarginLeft - chromeMarginRight) / zoom,\n\t\t\theight: (containerSize.height - chromeMarginTop - chromeMarginBottom) / zoom,\n\t\t}\n\t}\n\n\tgetViewportCenter(): Point {\n\t\treturn Rect.center(this.getCanvasVisibleRect())\n\t}\n\n\tgetViewportCenterTakingOverlaysIntoAccount(): Point {\n\t\treturn Rect.center(this.getCanvasVisibleRectTakingOverlaysIntoAccount())\n\t}\n\n\tconvertContainerPointToCanvas = (containerPoint: Point): Point => {\n\t\tconst { zoom, offset } = this\n\t\treturn {\n\t\t\tx: containerPoint.x / zoom + offset.x,\n\t\t\ty: containerPoint.y / zoom + offset.y,\n\t\t}\n\t}\n\n\tprivate convertContainerRectToCanvas = (containerRect: Rect): Rect => {\n\t\tconst { zoom, offset } = this\n\t\treturn {\n\t\t\tx: containerRect.x / zoom + offset.x,\n\t\t\ty: containerRect.y / zoom + offset.y,\n\t\t\twidth: containerRect.width / zoom,\n\t\t\theight: containerRect.height / zoom,\n\t\t}\n\t}\n\n\tconvertCanvasPointToContainer(canvasPoint: Point): Point {\n\t\tconst { offset, zoom } = this\n\t\treturn {\n\t\t\tx: (canvasPoint.x - offset.x) * zoom,\n\t\t\ty: (canvasPoint.y - offset.y) * zoom,\n\t\t}\n\t}\n\n\tprivate getUnroundedCanvasCenter(): Point {\n\t\treturn this.unroundedConvertContainerPointToCanvas(this.getContainerCenter())\n\t}\n\n\tprivate unroundedConvertContainerPointToCanvas = (containerPoint: Point): Point => {\n\t\tconst { unroundedZoom: zoom, unroundedOffset: offset } = this\n\t\treturn {\n\t\t\tx: containerPoint.x / zoom + offset.x,\n\t\t\ty: containerPoint.y / zoom + offset.y,\n\t\t}\n\t}\n\n\tprivate unroundedConvertCanvasPointToContainer(canvasPoint: Point): Point {\n\t\tconst { unroundedZoom: zoom, unroundedOffset: offset } = this\n\t\treturn {\n\t\t\tx: (canvasPoint.x - offset.x) * zoom,\n\t\t\ty: (canvasPoint.y - offset.y) * zoom,\n\t\t}\n\t}\n\n\tprivate isInvalidUntilNextRender = false\n\tprivate liveTransformTimeout = 0\n\n\tinvalidateTransformUntilRendered(task: () => void) {\n\t\tthis.isInvalidUntilNextRender = true\n\t\tthis.updateCanvas(this.unroundedOffset, this.unroundedZoom)\n\n\t\t// Wait for the app to entire live transform mode, then perform the task\n\t\t// FIXME: would be great if we could force a (partial) render here and make the entire method synchronous; then\n\t\t// ScopeStore could automatically use this API from changeActive.\n\t\tthis.taskScheduler.runBeforeNextFrame(() => {\n\t\t\tthis.taskScheduler.wrapHandler(task)()\n\t\t\tthis.isInvalidUntilNextRender = false\n\t\t\tthis.endLiveTransformWrapped()\n\t\t})\n\t}\n\n\tprivate startLiveTransformIfNeeded() {\n\t\tif (this.liveTransformTimeout) clearTimeout(this.liveTransformTimeout)\n\t\tthis.liveTransformTimeout = window.setTimeout(this.endLiveTransformWrapped, 250)\n\t}\n\n\tendLiveTransform = () => {\n\t\tif (this.isInvalidUntilNextRender) return\n\n\t\tif (this.liveZoom && this.liveOffset) {\n\t\t\t// Copy the live values to become the interactive values.\n\t\t\tthis.interactiveZoom = this.liveZoom\n\t\t\tthis.interactiveOffset = this.liveOffset\n\t\t}\n\n\t\t// End the live transform session\n\t\tthis.isInteractive = true\n\t\tthis.liveZoom = undefined\n\t\tthis.liveOffset = undefined\n\t\tthis.liveAnimation = undefined\n\n\t\tif (this.liveTransformTimeout) {\n\t\t\tclearTimeout(this.liveTransformTimeout)\n\t\t\tthis.liveTransformTimeout = 0\n\t\t}\n\n\t\tthis.changes.addChanges(EngineChange.CanvasZoom, EngineChange.CanvasStore)\n\t}\n\n\tupdateCanvas(newOffset: Readonly<Point>, newZoom: number, type: UpdateType = UpdateType.Immediate) {\n\t\tconst { containerSize, isConfiguredForTest } = this\n\t\tconst animated = type === UpdateType.Animated\n\t\tconst live = this.isInvalidUntilNextRender || type === UpdateType.Live\n\n\t\t// If the zoom changes, we will use more precision for the zoom and offset. That helps\n\t\t// jumpiness when zooming. While it prevents repaints while scrolling.\n\t\tconst zooming = type !== UpdateType.Immediate && this.unroundedZoom !== newZoom\n\n\t\t// Keeps track of the precise values\n\t\tconst oldZoom = this.unroundedZoom\n\t\tconst oldOffset = this.unroundedOffset\n\t\tthis.unroundedZoom = newZoom\n\t\tthis.unroundedOffset = newOffset\n\n\t\t// Live transforming\n\t\tif (live) {\n\t\t\tthis.liveZoom = zooming ? quantizeZoomLive(newZoom) : quantizeZoom(newZoom)\n\t\t\tthis.liveOffset = zooming\n\t\t\t\t? quantizeOffsetLive(newOffset, this.liveZoom)\n\t\t\t\t: quantizeOffset(newOffset, this.liveZoom)\n\n\t\t\t// If we are still interactive, signal one last regular zoom change.\n\t\t\tif (this.isInteractive) {\n\t\t\t\tthis.changes.addChanges(EngineChange.CanvasZoom, EngineChange.CanvasStore)\n\t\t\t}\n\t\t\tthis.isInteractive = false\n\t\t\tthis.liveAnimation = undefined\n\t\t\tthis.startLiveTransformIfNeeded()\n\n\t\t\t// Updates while live take the most optimized path.\n\t\t\tthis.changes.addChanges(EngineChange.CanvasLiveTransform)\n\t\t\treturn\n\t\t}\n\n\t\t// If there is no change, don't do anything.\n\t\tif (Point.isEqual(oldOffset, newOffset) && areNumbersEqual(oldZoom, newZoom)) {\n\t\t\treturn\n\t\t}\n\n\t\tthis.interactiveZoom = zooming ? quantizeZoomLive(newZoom) : quantizeZoom(newZoom)\n\t\tthis.interactiveOffset = zooming\n\t\t\t? quantizeOffsetLive(newOffset, this.interactiveZoom)\n\t\t\t: quantizeOffset(newOffset, this.interactiveZoom)\n\n\t\tif (!animated || isConfiguredForTest) {\n\t\t\tthis.endLiveTransform()\n\t\t} else {\n\t\t\tconst startRect = this.liveAnimation\n\t\t\t\t? this.liveAnimation.currentRect\n\t\t\t\t: {\n\t\t\t\t\t\tx: oldOffset.x,\n\t\t\t\t\t\ty: oldOffset.y,\n\t\t\t\t\t\twidth: containerSize.width / oldZoom,\n\t\t\t\t\t\theight: containerSize.height / oldZoom,\n\t\t\t\t\t}\n\t\t\tconst endRect = {\n\t\t\t\tx: newOffset.x,\n\t\t\t\ty: newOffset.y,\n\t\t\t\twidth: containerSize.width / newZoom,\n\t\t\t\theight: containerSize.height / newZoom,\n\t\t\t}\n\n\t\t\t// Use a slower animation when panning the canvas for a smoother transition.\n\t\t\tlet duration = this.interactiveZoom === newZoom ? 150 : 100\n\t\t\t{\n\t\t\t\tlet factor = endRect.width / startRect.width\n\t\t\t\tif (factor < 1) factor = 1 / factor\n\t\t\t\tfactor = (0.5 * factor) ** 0.1\n\t\t\t\tduration *= factor\n\t\t\t}\n\n\t\t\tthis.liveAnimation = {\n\t\t\t\tduration,\n\t\t\t\tstartTime: Date.now(),\n\t\t\t\tstartRect,\n\t\t\t\tendRect,\n\t\t\t\tcurrentRect: startRect,\n\t\t\t}\n\n\t\t\tthis.isInteractive = false\n\t\t\tthis.animateCanvas()\n\t\t}\n\t}\n\n\tprivate animateCanvas = () => {\n\t\tif (runningUnderTest) return\n\n\t\tconst { liveAnimation, containerSize } = this\n\n\t\tif (!liveAnimation) {\n\t\t\t// Animate autoscroll (only while the canvas is interactive)\n\t\t\tconst { isInteractive, autoscrolling } = this\n\t\t\tif (!isInteractive || !autoscrolling) return\n\n\t\t\tconst tick = Date.now()\n\t\t\tif (!autoscrolling.lastAnimationTick) {\n\t\t\t\tautoscrolling.lastAnimationTick = tick\n\t\t\t} else {\n\t\t\t\tconst timeElapsed = (tick - autoscrolling.lastAnimationTick) / 1000\n\t\t\t\tif (timeElapsed > 0) {\n\t\t\t\t\tconst delta = Point.multiply(autoscrolling.velocity, timeElapsed / this.unroundedZoom)\n\t\t\t\t\tif (delta.x !== 0 || delta.y !== 0) {\n\t\t\t\t\t\tconst mouseStore = this.mouseStore\n\t\t\t\t\t\tconst containerPoint = this.convertCanvasPointToContainer(mouseStore.canvasMousePosition)\n\t\t\t\t\t\tthis.updateCanvas(Point.add(this.unroundedOffset, delta), this.unroundedZoom)\n\t\t\t\t\t\tmouseStore.setMousePosition(\n\t\t\t\t\t\t\tthis.convertContainerPointToCanvas(containerPoint),\n\t\t\t\t\t\t\tmouseStore.windowMousePosition,\n\t\t\t\t\t\t\tmouseStore.altKey,\n\t\t\t\t\t\t\tmouseStore.cmdKey,\n\t\t\t\t\t\t\tmouseStore.shiftKey,\n\t\t\t\t\t\t\tmouseStore.ctrlKey,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tautoscrolling.lastAnimationTick = tick\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.taskScheduler.runBeforeNextFrame(this.animateCanvasWrapped)\n\t\t\treturn\n\t\t}\n\n\t\t// Animate live zoom\n\t\tconst { startTime, duration, startRect, endRect } = liveAnimation\n\t\tconst progress = Math.min(1, (Date.now() - startTime) / duration)\n\n\t\t// While the animation is going, interpolate between the start viewport rect and the end viewport rect\n\t\tconst rect = {\n\t\t\tx: startRect.x + progress * (endRect.x - startRect.x),\n\t\t\ty: startRect.y + progress * (endRect.y - startRect.y),\n\t\t\twidth: startRect.width + progress * (endRect.width - startRect.width),\n\t\t\theight: startRect.height + progress * (endRect.height - startRect.height),\n\t\t}\n\n\t\tliveAnimation.currentRect = rect\n\t\tthis.unroundedZoom = containerSize.width / rect.width\n\t\tthis.unroundedOffset = rect\n\t\tthis.liveZoom = quantizeZoomLive(this.unroundedZoom)\n\t\tthis.liveOffset = quantizeOffsetLive(this.unroundedOffset, this.liveZoom)\n\t\tthis.changes.addChanges(EngineChange.CanvasLiveTransform)\n\n\t\t// When the animation is done, clear all the live values\n\t\tif (progress >= 1) {\n\t\t\tthis.taskScheduler.runBeforeNextFrame(this.endLiveTransformWrapped)\n\t\t} else {\n\t\t\tthis.taskScheduler.runBeforeNextFrame(this.animateCanvasWrapped)\n\t\t}\n\t}\n\n\tprivate readonly endLiveTransformWrapped: () => void\n\tprivate readonly animateCanvasWrapped: () => void\n\n\tTEST_assign(partial: Partial<CanvasStore>) {\n\t\tObject.assign(this, partial)\n\t}\n\n\tTEST_configureForTest(test: boolean) {\n\t\tthis.isConfiguredForTest = test\n\t}\n\n\tscroll(containerDeltaX: number, containerDeltaY: number, type: UpdateType = UpdateType.Immediate) {\n\t\tconst { unroundedOffset: offset, unroundedZoom: zoom } = this\n\t\tthis.updateCanvas(Point(offset.x + containerDeltaX / zoom, offset.y + containerDeltaY / zoom), zoom, type)\n\t}\n\n\tscrollToTopLeft(canvasPoint: Point, { animate = false, live = false } = {}): void {\n\t\tlet type = UpdateType.Immediate\n\t\tif (animate) {\n\t\t\ttype = UpdateType.Animated\n\t\t} else if (live) {\n\t\t\ttype = UpdateType.Live\n\t\t}\n\t\tthis.updateCanvas(canvasPoint, this.unroundedZoom, type)\n\t}\n\n\tscrollToCenter(canvasPoint: Point, { animate = false, zoom = this.unroundedZoom } = {}): void {\n\t\tthis.updateZoom({\n\t\t\tzoom,\n\t\t\tcenter: canvasPoint,\n\t\t\tscrollToCenter: true,\n\t\t\ttype: animate ? UpdateType.Animated : UpdateType.Immediate,\n\t\t})\n\t}\n\n\tscrollToVisible(canvasRect: Rect, secondaryCanvasRect?: Rect): void {\n\t\t// Require the secondary rect to be inside the main rect\n\t\tif (secondaryCanvasRect) {\n\t\t\tsecondaryCanvasRect = Rect.intersects(canvasRect, secondaryCanvasRect)\n\t\t\t\t? Rect.intersection(canvasRect, secondaryCanvasRect)\n\t\t\t\t: undefined\n\t\t}\n\n\t\t// Delta needed to make [min...max] visible within [0...available]\n\t\tfunction deltaOnAxis(minEdge: number, maxEdge: number, available: number): number {\n\t\t\tif (minEdge > 0 && maxEdge > available) {\n\t\t\t\treturn Math.min(minEdge, maxEdge - available)\n\t\t\t} else if (minEdge < 0 && maxEdge < available) {\n\t\t\t\treturn -Math.min(available - maxEdge, -minEdge)\n\t\t\t}\n\t\t\treturn 0\n\t\t}\n\n\t\t// Delta needed to make a whole rect visible in the usable canvas area\n\t\tconst interactiveRect = this.convertContainerRectToCanvas(this.getContainerInteractiveRect())\n\t\tfunction deltaForRect(rect: Rect): Point {\n\t\t\treturn {\n\t\t\t\tx: deltaOnAxis(\n\t\t\t\t\tRect.minX(rect) - Rect.minX(interactiveRect),\n\t\t\t\t\tRect.maxX(rect) - Rect.minX(interactiveRect),\n\t\t\t\t\tinteractiveRect.width,\n\t\t\t\t),\n\t\t\t\ty: deltaOnAxis(\n\t\t\t\t\tRect.minY(rect) - Rect.minY(interactiveRect),\n\t\t\t\t\tRect.maxY(rect) - Rect.minY(interactiveRect),\n\t\t\t\t\tinteractiveRect.height,\n\t\t\t\t),\n\t\t\t}\n\t\t}\n\n\t\tconst mainDelta = deltaForRect(canvasRect)\n\n\t\tinteractiveRect.x += mainDelta.x\n\t\tinteractiveRect.y += mainDelta.y\n\t\tconst secondaryDelta = secondaryCanvasRect ? deltaForRect(secondaryCanvasRect) : Point(0, 0)\n\n\t\tconst delta = Point.add(mainDelta, secondaryDelta)\n\t\tif (Math.abs(delta.x) > 1 || Math.abs(delta.y) > 1) {\n\t\t\tthis.updateCanvas(Point.add(this.unroundedOffset, delta), this.unroundedZoom)\n\t\t}\n\t}\n\n\tprivate autoscrollLevel = 0\n\n\tisAutoScrolling() {\n\t\treturn this.autoscrollLevel > 0\n\t}\n\n\tbeginAutoscrolling() {\n\t\tthis.autoscrollLevel++\n\t}\n\n\tendAutoscrolling() {\n\t\tthis.autoscrollLevel--\n\t}\n\n\tautoscrollIfNeeded() {\n\t\tif (!this.isAutoScrolling()) {\n\t\t\tthis.autoscrolling = undefined\n\t\t\treturn\n\t\t}\n\n\t\tconst { windowMousePosition, windowMouseDownPosition } = this.mouseStore.latest\n\t\t// if the mouse is down and the distance between the mouse down and the current mouse position is small,\n\t\t// prevent the starting of the autoscroll\n\t\t// otherwise, autoscroll can start on a click near the edge of the canvas\n\t\tif (\n\t\t\t!this.autoscrolling &&\n\t\t\twindowMouseDownPosition &&\n\t\t\tPoint.distance(windowMouseDownPosition, windowMousePosition) < mouseMoveThreshold\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\tconst bounds = Rect.inset(this.getContainerInteractiveRect(), 20)\n\t\tfunction overdragOnAxis(t: number, min: number, max: number) {\n\t\t\tif (t < min) {\n\t\t\t\treturn t - min\n\t\t\t} else if (t > max) {\n\t\t\t\treturn t - max\n\t\t\t} else {\n\t\t\t\treturn 0 // No autoscroll\n\t\t\t}\n\t\t}\n\n\t\tconst velocity = {\n\t\t\tx: 3 * overdragOnAxis(windowMousePosition.x, Rect.minX(bounds), Rect.maxX(bounds)),\n\t\t\ty: 3 * overdragOnAxis(windowMousePosition.y, Rect.minY(bounds), Rect.maxY(bounds)),\n\t\t}\n\n\t\tif (velocity.x || velocity.y) {\n\t\t\tif (this.autoscrolling) {\n\t\t\t\tthis.autoscrolling.velocity = velocity\n\t\t\t} else {\n\t\t\t\tthis.autoscrolling = { velocity }\n\t\t\t\tthis.animateCanvas()\n\t\t\t}\n\t\t} else {\n\t\t\tthis.autoscrolling = undefined\n\t\t}\n\t}\n\n\tprivate updateZoom(options: { zoom: number; center?: Point; scrollToCenter?: boolean; type?: UpdateType }): void {\n\t\tconst zoom = Math.max(zoomMin, Math.min(zoomMax, options.zoom))\n\t\tconst canvasAnchor = options.center || this.getUnroundedCanvasCenter()\n\t\tconst containerAnchor = options.scrollToCenter\n\t\t\t? this.getContainerCenter()\n\t\t\t: this.unroundedConvertCanvasPointToContainer(canvasAnchor)\n\n\t\tthis.updateCanvas(\n\t\t\t// The new zoom/offset should be such that canvasAnchor == convertContainerPointToCanvas(containerAnchor)\n\t\t\t{ x: canvasAnchor.x - containerAnchor.x / zoom, y: canvasAnchor.y - containerAnchor.y / zoom },\n\t\t\tzoom,\n\t\t\toptions.type,\n\t\t)\n\t}\n\n\tsetZoom(zoom: number, { animated }: { animated?: boolean } = {}): void {\n\t\tthis.updateZoom({\n\t\t\tzoom: this.floorZoom(zoom),\n\t\t\ttype: animated ? UpdateType.Animated : UpdateType.Immediate,\n\t\t})\n\t}\n\n\tzoomIn(canvasPoint?: Point, { animated = false }: { animated?: boolean } = {}): void {\n\t\tconst targetPoint = canvasPoint ?? this.getZoomTarget()\n\t\tthis.updateZoom({\n\t\t\tzoom: this.zoomStep(true),\n\t\t\tcenter: targetPoint,\n\t\t\tscrollToCenter: !canvasPoint,\n\t\t\ttype: animated ? UpdateType.Animated : UpdateType.Immediate,\n\t\t})\n\t}\n\n\tzoomOut(canvasPoint?: Point, { animated = false }: { animated?: boolean } = {}): void {\n\t\tconst targetPoint = canvasPoint ?? this.getZoomTarget()\n\t\tthis.updateZoom({\n\t\t\tzoom: this.zoomStep(false),\n\t\t\tcenter: targetPoint,\n\t\t\tscrollToCenter: !canvasPoint,\n\t\t\ttype: animated ? UpdateType.Animated : UpdateType.Immediate,\n\t\t})\n\t}\n\n\tprivate getZoomTarget(): Point | undefined {\n\t\tif (!this.persistedUserDefaults.keyboardZoomsToSelection) return undefined\n\t\treturn this.selectionStore.nodes.length > 0\n\t\t\t? Rect.center(getBoundingFrameForNodes(this.treeStore.tree, this.selectionStore.nodes))\n\t\t\t: undefined\n\t}\n\n\tzoomToNode(node: CanvasNode) {\n\t\tconst rect = getBoundingFrameForNodes(this.treeStore.tree, [node])\n\n\t\tif (rect.width > 0 && rect.height > 0) {\n\t\t\tthis.zoomToCenter(rect, {\n\t\t\t\tmaxZoom: 1,\n\t\t\t})\n\t\t}\n\t}\n\n\tzoomToCenter(\n\t\tcanvasRect: Rect,\n\t\t{\n\t\t\tzoom,\n\t\t\tmaxZoom,\n\t\t\tminZoom,\n\t\t\tsnapToZoomSteps,\n\t\t\tanimated = false,\n\t\t}: { zoom?: number; maxZoom?: number; minZoom?: number; animated?: boolean; snapToZoomSteps?: boolean } = {},\n\t): void {\n\t\t// either we snap to the nearest zoom step or we must consider the toolbar placement in our calculations\n\t\tconst snap = snapToZoomSteps ?? false\n\t\tconst padding = snap ? 0 : 32\n\t\tconst toolbarHeight = snap ? 0 : 94\n\n\t\tif (!zoom) {\n\t\t\tconst containerSize = this.getContainerInteractiveRect() as Size\n\t\t\tconst heightWithOffsets = containerSize.height - toolbarHeight - padding * 2\n\t\t\tconst heightRatio = heightWithOffsets / canvasRect.height\n\t\t\tconst widthRatio = (containerSize.width - 64) / canvasRect.width\n\t\t\tzoom = Math.min(heightRatio, widthRatio)\n\n\t\t\tif (snap) {\n\t\t\t\tzoom = this.zoomStep(false, zoom)\n\t\t\t}\n\t\t}\n\n\t\tif (maxZoom) {\n\t\t\tzoom = Math.min(zoom, maxZoom)\n\t\t}\n\n\t\tif (minZoom) {\n\t\t\tzoom = Math.max(zoom, minZoom)\n\t\t}\n\n\t\tconst center = Rect.center(canvasRect)\n\t\tif (toolbarHeight) {\n\t\t\tconst toolbarOffsetProjected = (toolbarHeight - padding) / (2 * zoom)\n\t\t\tcenter.y = center.y + toolbarOffsetProjected\n\t\t}\n\t\tthis.updateZoom({\n\t\t\tzoom,\n\t\t\tcenter,\n\t\t\tscrollToCenter: true,\n\t\t\ttype: animated ? UpdateType.Animated : UpdateType.Immediate,\n\t\t})\n\t}\n\n\tprivate zoomStep(zoomIn: boolean, zoom?: number): number {\n\t\tlet currentZoom = zoom ?? this.unroundedZoom\n\n\t\tif (zoomIn) {\n\t\t\tcurrentZoom =\n\t\t\t\tzoomSteps.find(zoomFactor => {\n\t\t\t\t\treturn zoomFactor > currentZoom\n\t\t\t\t}) || zoomMax\n\t\t} else {\n\t\t\tcurrentZoom =\n\t\t\t\tzoomSteps\n\t\t\t\t\t.slice(0)\n\t\t\t\t\t.reverse()\n\t\t\t\t\t.find(zoomFactor => {\n\t\t\t\t\t\treturn zoomFactor < currentZoom\n\t\t\t\t\t}) || zoomMin\n\t\t}\n\n\t\treturn currentZoom\n\t}\n\n\t// Round zoom level down if necessary\n\tprivate floorZoom(zoom: number): number {\n\t\tif (zoomSteps.includes(zoom)) {\n\t\t\treturn zoom\n\t\t} else {\n\t\t\treturn this.zoomStep(false, zoom)\n\t\t}\n\t}\n\n\t/**\n\t * Updates the zoom based on the pixel delta and target scaling factor. Using a scaling factor ensures\n\t * that zooming in and out is consistent, one turn of the wheel, or equivalent trackpad interaction will\n\t * zoom in or out by the same amount\n\t * @param delta The pixel delta of the zoom event\n\t * @param containerPoint The target point of the zoom event\n\t * @param scalingFactor A scaling factor that controls the exponential zooming, should be a decimal between 1 and 1.2\n\t * depending on the sensitivity of the source delta\n\t */\n\tchangeExponentialZoomBy(delta: number, containerPoint: Point, scalingFactor: number) {\n\t\tlet newZoom = this.unroundedZoom * scalingFactor ** delta\n\t\tif (newZoom < zoomMin) newZoom = zoomMin\n\t\tif (newZoom > zoomMax) newZoom = zoomMax\n\t\tif (newZoom === this.unroundedZoom) return\n\n\t\tthis.updateZoom({\n\t\t\tzoom: newZoom,\n\t\t\tcenter: this.convertContainerPointToCanvas(containerPoint),\n\t\t\ttype: UpdateType.Live,\n\t\t})\n\n\t\tthis.endMagnificationAfterInactiveDelay()\n\t}\n\n\tprivate endMagnification: () => void\n\n\tprivate endMagnificationAfterInactiveDelay: () => void\n\n\tprivate zoomToFitScope(tree: CanvasTree, scope: ScopeNode) {\n\t\tconst frame = getBoundingFrameForNodes(\n\t\t\ttree,\n\t\t\tscope.children.filter(n => n.isVisible()),\n\t\t)\n\t\tif (frame.width <= 0 || frame.height <= 0) {\n\t\t\tthis.updateCanvas({ x: 0, y: 0 }, 1)\n\t\t\treturn\n\t\t}\n\t\tthis.zoomToCenter(frame, { maxZoom: 1, animated: false })\n\t}\n\n\tzoomToFitAll() {\n\t\tconst { treeStore, persistedUserDefaults } = this\n\t\tconst rect = this.getActiveScope().getBoundingFrame(treeStore.tree)\n\t\tif (rect.width > 0 && rect.height > 0) {\n\t\t\tthis.zoomToCenter(rect, {\n\t\t\t\tmaxZoom: 1,\n\t\t\t\tanimated: persistedUserDefaults.animateOnZoom,\n\t\t\t})\n\t\t}\n\t}\n\n\t/** Zooms and selects the ground node of what was linked via the url or other mechanisms.\n\t * Otherwise zooms the same as scopeStore.select().\n\t *\n\t * Note: we first switch and zoom to a scope during loading. Quickly after we call this after\n\t * all diffs have loaded. This is to ensure that we zoom to the latest version of the scope and\n\t * to the correct node.\n\t */\n\tzoomToActiveNode = () => {\n\t\tconst { documentSettingsStore, selectionStore } = this\n\t\tconst activeNodeId = documentSettingsStore.activeNode?.id\n\t\tconst node = this.treeStore.tree.get(activeNodeId)\n\n\t\tif (node === null) {\n\t\t\tif (documentSettingsStore.activeNode?.deepLinked) {\n\t\t\t\trecord(\"open_primary_component_fail\", {})\n\t\t\t}\n\t\t\treturn this.zoomAfterScopeSwitch(this.treeStore.tree, this.getActiveScope())\n\t\t}\n\n\t\tconst groundNode = this.treeStore.tree.getGroundNodeFor(node)\n\t\tconst scopeNode = this.treeStore.tree.getScopeNodeFor(groundNode)\n\t\tif (!scopeNode) return\n\n\t\tconst drawableNode = isDrawableNode(groundNode) ? groundNode : undefined\n\n\t\t// This can happen if diffs have created the active node, but the scope itself hasn't fully\n\t\t// loaded during partial document loading, because it could not find the node, thus not its\n\t\t// scope.\n\t\tif (!scopeNode.isValid()) return\n\n\t\t// Switch to the relevant scope\n\t\tthis.selectScope(scopeNode)\n\n\t\tif (isCanvasScopeNode(scopeNode)) {\n\t\t\t// Set the selection to be the ground node.\n\t\t\tselectionStore.set(groundNode.id)\n\t\t\treturn this.zoomAfterScopeSwitch(this.treeStore.tree, scopeNode, drawableNode)\n\t\t} else if (isCollectionNode(node) || isCollectionItemNode(node)) {\n\t\t\tselectionStore.set(node)\n\t\t}\n\t}\n\n\tzoomAfterScopeSwitch(tree: CanvasTree, scope: ScopeNode, node?: CanvasNode) {\n\t\t// If a node was passed in, use its ground node, but only if visible.\n\t\tif (node) {\n\t\t\tnode = tree.getGroundNodeFor(node)\n\t\t\tif (!node.isVisible()) {\n\t\t\t\tnode = undefined\n\t\t\t}\n\t\t}\n\n\t\t// If we are switching to a canvas page, and have nothing to zoom, use zoom to fit all.\n\t\tif (isCanvasPageNode(scope) && !node) {\n\t\t\tthis.zoomToFitScope(tree, scope)\n\t\t\treturn\n\t\t}\n\n\t\t// If we are switching to a Vector Set, and have nothing to zoom, use zoom to fit the first\n\t\t// 5 items.\n\t\tif (isVectorSetNode(scope) && !node) {\n\t\t\tconst items: CanvasNode[] = []\n\t\t\tfor (const child of scope.children) {\n\t\t\t\tif (!isVectorSetItem(child)) continue\n\t\t\t\titems.push(child)\n\t\t\t\tif (items.length >= VECTOR_SET_COLUMNS) break\n\t\t\t}\n\n\t\t\tif (items.length) {\n\t\t\t\tthis.zoomToCenter(getBoundingFrameForNodes(tree, items), {\n\t\t\t\t\tanimated: false,\n\t\t\t\t\tsnapToZoomSteps: true,\n\t\t\t\t\tminZoom: 0.1,\n\t\t\t\t\tmaxZoom: 4,\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// When switching to a design page node, zoom to fit all, but only if the \"all\" selection is\n\t\t// smaller than 5000x5000 (arbitrary threshold) for performance reasons.\n\t\tif (isDesignPageNode(scope) && !node) {\n\t\t\tconst frame = getBoundingFrameForNodes(\n\t\t\t\ttree,\n\t\t\t\tscope.children.filter(n => n.isVisible()),\n\t\t\t)\n\t\t\tif (frame.width > 0 && frame.height > 0 && frame.width <= 5000 && frame.height <= 5000) {\n\t\t\t\tthis.zoomToCenter(frame, { maxZoom: 1, animated: false })\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// If we still don't have a node, guess which node to use.\n\t\tif (!node) {\n\t\t\tif (!scope.isLoaded()) return\n\t\t\tnode = guessMainNodeForScope(scope)\n\t\t}\n\n\t\t// If there is no content use a default offset and zoom.\n\t\tif (!node) {\n\t\t\tthis.updateCanvas({ x: 0, y: 0 }, 1)\n\t\t\treturn\n\t\t}\n\n\t\t// Guess the rendered frame for the ground node.\n\t\tconst frame = guessFrameForNode(tree, node)\n\n\t\t// Using the width, zoom to as much of the groundNode as fits on the canvas.\n\t\tconst canvasSize = this.getContainerInteractiveRect()\n\t\tconst canvasRatio = canvasSize.height / canvasSize.width\n\t\tconst heightOnCanvas = frame.width * canvasRatio\n\n\t\tlet frameOnCanvas: Rect\n\t\tif (frame.height * 1.1 > heightOnCanvas) {\n\t\t\t// If we are zooming to a partial frame, give a bit of padding on the top.\n\t\t\tframeOnCanvas = { ...frame, y: frame.y - 100, height: heightOnCanvas }\n\t\t} else {\n\t\t\tframeOnCanvas = frame\n\t\t}\n\n\t\t// Add a bit of padding all around.\n\t\tframeOnCanvas = Rect.inflate(frameOnCanvas, 30)\n\n\t\t// Will zoom to the provided frame zooming out in fixed steps if needed.\n\t\tthis.zoomToCenter(frameOnCanvas, { maxZoom: 1, animated: false, snapToZoomSteps: true })\n\t}\n}\n\n// For Chrome version 112 up to 118 we need a lower precision for zoom and offset values, because\n// that minimizes the impact of a bug that has chrome resize layers by 1px due to rounding. Note we\n// can remove this when electron releases a stable version based on chrome 119.\nconst chromeVersion = chromeMainVersion()\nconst workaroundChrome1pxResizeBug = chromeVersion >= 112 && chromeVersion <= 118\n\nfunction quantize(n: number, factor: number) {\n\treturn Math.round(n * factor) / factor\n}\n\n/** We cap the precision of the zoom value to nice binary numbers. Basically using N of the 52\n * mantissa bits of a 64 bit float. */\nfunction quantizeZoom(zoom: number) {\n\tif (workaroundChrome1pxResizeBug) return quantizeZoomChrome118(zoom)\n\n\tif (zoom > 32) return quantize(zoom, 1 << 3)\n\tif (zoom > 16) return quantize(zoom, 1 << 4)\n\tif (zoom > 8) return quantize(zoom, 1 << 5)\n\tif (zoom > 4) return quantize(zoom, 1 << 6)\n\tif (zoom > 2) return quantize(zoom, 1 << 7)\n\tif (zoom > 1) return quantize(zoom, 1 << 8)\n\tif (zoom > 1 / 2) return quantize(zoom, 1 << 9)\n\tif (zoom > 1 / 4) return quantize(zoom, 1 << 10)\n\tif (zoom > 1 / 8) return quantize(zoom, 1 << 11)\n\tif (zoom > 1 / 16) return quantize(zoom, 1 << 12)\n\tif (zoom > 1 / 32) return quantize(zoom, 1 << 13)\n\tif (zoom > 1 / 64) return quantize(zoom, 1 << 14)\n\tif (zoom > 1 / 128) return quantize(zoom, 1 << 15)\n\tif (zoom > 1 / 256) return quantize(zoom, 1 << 16)\n\treturn quantize(zoom, 1 << 17)\n}\n\nfunction quantizeZoomLive(zoom: number) {\n\tif (workaroundChrome1pxResizeBug) return quantizeZoomLiveChrome118(zoom)\n\n\tif (zoom > 32) return quantize(zoom, 1 << 5)\n\tif (zoom > 16) return quantize(zoom, 1 << 6)\n\tif (zoom > 8) return quantize(zoom, 1 << 7)\n\tif (zoom > 4) return quantize(zoom, 1 << 8)\n\tif (zoom > 2) return quantize(zoom, 1 << 9)\n\tif (zoom > 1) return quantize(zoom, 1 << 10)\n\tif (zoom > 1 / 2) return quantize(zoom, 1 << 11)\n\tif (zoom > 1 / 4) return quantize(zoom, 1 << 12)\n\tif (zoom > 1 / 8) return quantize(zoom, 1 << 13)\n\tif (zoom > 1 / 16) return quantize(zoom, 1 << 14)\n\tif (zoom > 1 / 32) return quantize(zoom, 1 << 15)\n\tif (zoom > 1 / 64) return quantize(zoom, 1 << 16)\n\tif (zoom > 1 / 128) return quantize(zoom, 1 << 17)\n\tif (zoom > 1 / 256) return quantize(zoom, 1 << 18)\n\treturn quantize(zoom, 1 << 19)\n}\n\n/** Depending on the zoom level, we cap the precision of the offset. */\nfunction quantizeOffset(offset: Point, zoom: number) {\n\t// First scale sub pixel precision to the zoom so ground nodes are placed on pixel boundaries.\n\tconst x = quantize(offset.x, zoom)\n\tconst y = quantize(offset.y, zoom)\n\n\t// Then round it to nice binary numbers depending on zoom.\n\tif (zoom > 16) return Point(quantize(x, 8), quantize(y, 8))\n\tif (zoom > 8) return Point(quantize(x, 4), quantize(y, 4))\n\tif (zoom > 4) return Point(quantize(x, 2), quantize(y, 2))\n\treturn Point(quantize(x, 1), quantize(y, 1))\n}\n\nfunction quantizeOffsetLive(offset: Point, zoom: number) {\n\tif (workaroundChrome1pxResizeBug) return quantizeOffsetLiveChrome118(offset, zoom)\n\n\t// When live zooming, allow more resolution, to reduce jumpiness.\n\tconst x = quantize(offset.x, zoom * 2)\n\tconst y = quantize(offset.y, zoom * 2)\n\t// Then round it to nice binary numbers depending on zoom.\n\tif (zoom > 16) return Point(quantize(x, 256), quantize(y, 256))\n\tif (zoom > 8) return Point(quantize(x, 128), quantize(y, 128))\n\tif (zoom > 4) return Point(quantize(x, 64), quantize(y, 64))\n\tif (zoom > 2) return Point(quantize(x, 32), quantize(y, 32))\n\tif (zoom > 1) return Point(quantize(x, 16), quantize(y, 16))\n\tif (zoom > 0) return Point(quantize(x, 8), quantize(y, 8))\n\tif (zoom > 0.5) return Point(quantize(x, 4), quantize(y, 4))\n\treturn Point(quantize(x, 2), quantize(y, 2))\n}\n\nfunction quantizeZoomChrome118(zoom: number) {\n\tif (zoom > 32) return quantize(zoom, 1 << 1)\n\tif (zoom > 16) return quantize(zoom, 1 << 2)\n\tif (zoom > 8) return quantize(zoom, 1 << 3)\n\tif (zoom > 4) return quantize(zoom, 1 << 4)\n\tif (zoom > 2) return quantize(zoom, 1 << 5)\n\tif (zoom > 1) return quantize(zoom, 1 << 6)\n\tif (zoom > 1 / 2) return quantize(zoom, 1 << 7)\n\tif (zoom > 1 / 4) return quantize(zoom, 1 << 8)\n\tif (zoom > 1 / 8) return quantize(zoom, 1 << 9)\n\tif (zoom > 1 / 16) return quantize(zoom, 1 << 10)\n\tif (zoom > 1 / 32) return quantize(zoom, 1 << 11)\n\tif (zoom > 1 / 64) return quantize(zoom, 1 << 12)\n\tif (zoom > 1 / 128) return quantize(zoom, 1 << 13)\n\tif (zoom > 1 / 256) return quantize(zoom, 1 << 14)\n\treturn quantize(zoom, 1 << 15)\n}\n\nfunction quantizeZoomLiveChrome118(zoom: number) {\n\tif (zoom > 32) return quantize(zoom, 1 << 3)\n\tif (zoom > 16) return quantize(zoom, 1 << 4)\n\tif (zoom > 8) return quantize(zoom, 1 << 5)\n\tif (zoom > 4) return quantize(zoom, 1 << 6)\n\tif (zoom > 2) return quantize(zoom, 1 << 7)\n\tif (zoom > 1) return quantize(zoom, 1 << 8)\n\tif (zoom > 1 / 2) return quantize(zoom, 1 << 9)\n\tif (zoom > 1 / 4) return quantize(zoom, 1 << 10)\n\tif (zoom > 1 / 8) return quantize(zoom, 1 << 11)\n\tif (zoom > 1 / 16) return quantize(zoom, 1 << 12)\n\tif (zoom > 1 / 32) return quantize(zoom, 1 << 13)\n\tif (zoom > 1 / 64) return quantize(zoom, 1 << 14)\n\tif (zoom > 1 / 128) return quantize(zoom, 1 << 15)\n\tif (zoom > 1 / 256) return quantize(zoom, 1 << 16)\n\treturn quantize(zoom, 1 << 17)\n}\n\nfunction quantizeOffsetLiveChrome118(offset: Point, zoom: number) {\n\t// When live zooming, allow more resolution, to reduce jumpiness.\n\tconst x = quantize(offset.x, zoom * 2)\n\tconst y = quantize(offset.y, zoom * 2)\n\t// Then round it to nice binary numbers depending on zoom.\n\tif (zoom > 16) return Point(quantize(x, 128), quantize(y, 128))\n\tif (zoom > 8) return Point(quantize(x, 64), quantize(y, 64))\n\tif (zoom > 4) return Point(quantize(x, 32), quantize(y, 32))\n\tif (zoom > 2) return Point(quantize(x, 16), quantize(y, 16))\n\tif (zoom > 1) return Point(quantize(x, 8), quantize(y, 8))\n\tif (zoom > 0) return Point(quantize(x, 4), quantize(y, 4))\n\tif (zoom > 0.5) return Point(quantize(x, 2), quantize(y, 2))\n\treturn Point(quantize(x, 2), quantize(y, 1))\n}\n\nfunction areNumbersEqual(x: number, y: number) {\n\treturn Math.abs(x - y) < Number.EPSILON\n}\n", "\nexport const browserAgentEvalsEnabled = true\nexport const browserAgentEvalsBuildEnabled = true\nexport const browserAgentEvalsGlobal = {\n\trun: options => import(\"document/components/chrome/evaluations/evalRunner.ts\").then(module =>\n\t\tmodule.runAgentHarnessEvaluationsFromGlobal(options),\n\t),\n}\n\t\t\t\t", "export const matchingItemsToastKey = \"apply-identical-translations\"\n", "import { toast } from \"web/lib/toaster.ts\"\nimport { matchingItemsToastKey } from \"./matchingItemsToastKey.ts\"\n\n// This can't be in the same file as `showMatchingItemsToast` because of\n// circular dependencies. The `chromeStore` depends on this file so it can't\n// depend on the engine.\n\nexport function dismissMatchingItemsToast() {\n\ttoast({ type: \"remove\", key: matchingItemsToastKey })\n}\n", "export function newSetByTogglingItem<T, S extends Set<T> | ReadonlySet<T>>(set: S, item: T): S {\n\tconst result = new Set<T>(set)\n\tif (result.has(item)) {\n\t\tresult.delete(item)\n\t} else {\n\t\tresult.add(item)\n\t}\n\treturn result as S\n}\n", "import type { WindowWithCurrentUser } from \"@framerjs/app-shared\"\nimport { UserSessionService, localChannel } from \"@framerjs/framer-services\"\nimport { assert, getLogger, isLocalUrl } from \"@framerjs/shared\"\nimport { browserAgentEvalsBuildEnabled } from \"app/browserAgentEvals.ts\"\nimport { employeesOnlySettings } from \"app/employeesOnlySettings.ts\"\nimport { projectFeatures } from \"app/projectFeatures.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { QuickActionsCategoryType } from \"document/components/chrome/QuickActions/types.ts\"\nimport { dismissMatchingItemsToast } from \"document/components/chrome/localization/dismissMatchingItemsToast.ts\"\nimport type { MaybeNodeID, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { defaultLocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport {\n\tActiveAssetsPanelTab,\n\tActiveContentPanelTab,\n\tActiveLeftPanel,\n\tActiveMainView,\n\tActiveRightPanel,\n\tCanvasPanelTab,\n\tCollectionPanelTab,\n\tLocalizationPanelTab,\n\ttype ActiveOverlay,\n} from \"document/utils/ActiveEditorType.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { ToastKey } from \"document/utils/ToastKey.ts\"\nimport type { OverlayStackElement } from \"document/utils/contentManagementOverlayStack.ts\"\nimport { postProcessOverlayStack } from \"document/utils/contentManagementOverlayStack.ts\"\nimport { newSetByTogglingItem } from \"document/utils/newSetByTogglingItem.ts\"\nimport { ScopeType } from \"document/utils/scopeType.ts\"\nimport { getFramerRelease } from \"environment/getFramerRelease.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport type { LoadingStore } from \"./LoadingStore.ts\"\nimport type { ModalStore } from \"./ModalStore.ts\"\nimport type { PersistedUserDefaults } from \"./PersistedUserDefaults.ts\"\nimport type { Selection } from \"./SelectionStore.ts\"\nimport { Tools } from \"./ToolEnum.ts\"\n\nconst log = getLogger(\"ChromeStore\")\n\nexport class ChromeStore extends EngineStore {\n\t// FIXME: Use release info from server to see if user is *not* on the stable channels.\n\t#isOnBeta = window.location.hostname.endsWith(\"beta.framer.com\")\n\t#isOnBetaChannel = getFramerRelease(window)?.channel === \"beta\"\n\n\tchromeIsVisible = !environment.isPhone\n\thasReceivedUserPermissions = false\n\tisTutorialActive = false\n\thasTutorialPlayed = false\n\thasCompletedOwnershipTransfer = false\n\thideGeneratePageButton = false\n\tfloatingWindowInFront: \"plugin\" | \"popout\" = \"popout\"\n\tisIntercomMessengerVisible = false\n\n\tprivate _canvasLocaleId: LocaleId = defaultLocaleId\n\n\tget canvasLocaleId() {\n\t\treturn this._canvasLocaleId\n\t}\n\n\tset canvasLocaleId(value: LocaleId) {\n\t\tthis._canvasLocaleId = value\n\t\tthis.hideInsertSidebar()\n\t}\n\n\t// FIXME: this is a temporary solution to improve auto detaching insert items from showing a\n\t// purple selection box that becomes blue when detaching is finished. This should be removed\n\t// once inserting no longer requires these temporary nodes.\n\tautoDetachingNodeId: MaybeNodeID = null\n\n\t// TODO: Move this into a SessionStore or some such.\n\t#currentUser = (window as WindowWithCurrentUser)?.framerUser\n\tuserIsEmployee = this.#currentUser?.isFramerEmployee === true\n\tuserIsViewer = employeesOnlySettings.isOn(\"userIsViewer\")\n\tuserIsAccountSharing = false\n\t#isDetachedEditableMode = false\n\tisViewingBranchFromOtherUser = false\n\tisPreviewingFeaturedTemplate: boolean | undefined = undefined\n\tdebugOverrideUserIsViewer = false\n\tstatusBarIsVisible =\n\t\tthis.chromeIsVisible &&\n\t\t(!this.userIsEmployee || employeesOnlySettings.isOn(\"showStatusBar\")) &&\n\t\t(this.userIsEmployee || this.#isOnBeta || this.#isOnBetaChannel)\n\n\t_aiGenerationInProgress = 0\n\t#aiGeneratedAt: number | null = null\n\tprivate canGenerateWithAI = () => {\n\t\tif (this.#aiGeneratedAt === null) return true\n\t\tif (performance.now() - this.#aiGeneratedAt < 10_000) return false\n\t\treturn true\n\t}\n\n\tgenerateWithAI() {\n\t\tif (!this.canGenerateWithAI()) return false\n\t\tthis.#aiGeneratedAt = performance.now()\n\t\treturn true\n\t}\n\n\tunblockGeneratingWithAI() {\n\t\tthis.#aiGeneratedAt = null\n\t}\n\n\tisProjectMenuOpen = false\n\n\tconstructor(\n\t\tprivate persistedUserDefaults: PersistedUserDefaults,\n\t\tprivate loadingStore: LoadingStore,\n\t\tprivate modalStore: ModalStore,\n\t\tprivate onLocalizationsHide: () => void,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\tsuper()\n\n\t\t// This used to be platform.isOn(\"supportsViewOnlyMode\")\n\t\tif (!(environment.isAutomation || environment.isTest)) {\n\t\t\tlet cancelStream: (() => Promise<void>) | undefined\n\t\t\tlet aborted = false\n\n\t\t\tabortSignal?.addEventListener(\n\t\t\t\t\"abort\",\n\t\t\t\t() => {\n\t\t\t\t\taborted = true\n\t\t\t\t\tvoid cancelStream?.()\n\t\t\t\t},\n\t\t\t\t{ once: true },\n\t\t\t)\n\n\t\t\tUserSessionService.on(localChannel)\n\t\t\t\t.discover()\n\t\t\t\t.then(userSessionService => {\n\t\t\t\t\tif (aborted) return\n\t\t\t\t\tconst stream = userSessionService.permissionsStream({ replay: \"latest\" })\n\t\t\t\t\tcancelStream = () => stream.cancel()\n\t\t\t\t\treturn stream\n\t\t\t\t\t\t.read(async event => {\n\t\t\t\t\t\t\tthis.hasReceivedUserPermissions = true\n\t\t\t\t\t\t\tif (this.debugOverrideUserIsViewer || this.#isDetachedEditableMode) return\n\n\t\t\t\t\t\t\tthis.userIsViewer = employeesOnlySettings.isOn(\"userIsViewer\") || event.isViewOnly\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((error: unknown) => log.error(\"Couldn't set view only mode:\", error))\n\t\t\t\t})\n\t\t\t\t.catch((error: unknown) => log.error(\"Listening user session permissions failed:\", error))\n\t\t}\n\t}\n\n\t#previousMainView: ActiveMainView | undefined\n\n\tpostProcess(engine: VekterEngine) {\n\t\tconst tree = engine.tree\n\n\t\tconst activeCanvasLocale = tree.root.getLocale(this.canvasLocaleId)\n\n\t\t// Reset canvas locale if it no longer exists\n\t\tif (activeCanvasLocale.id !== this.canvasLocaleId) {\n\t\t\tthis.canvasLocaleId = defaultLocaleId\n\t\t}\n\n\t\t// Close insert sidebar when the plugin menu is opened\n\t\tif (\n\t\t\t(this.#leftPanelOverride === ActiveLeftPanel.Insert ||\n\t\t\t\tthis.#leftPanelOverride === ActiveLeftPanel.ContentManagement) &&\n\t\t\tengine.stores.modalStore.active.type === ModalType.QuickActions &&\n\t\t\tengine.stores.modalStore.active.initialCategory?.type === QuickActionsCategoryType.Plugins\n\t\t) {\n\t\t\tthis.#leftPanelOverride = null\n\t\t\tthis.calculateEditorState()\n\t\t}\n\n\t\tif (!this._overlay || this._overlay.type === \"collectionItem\") {\n\t\t\tconst stack = postProcessOverlayStack(engine, this._overlay?.stack)\n\n\t\t\tif (stack.length > 0) {\n\t\t\t\tthis._overlay = {\n\t\t\t\t\ttype: \"collectionItem\",\n\t\t\t\t\tstack,\n\t\t\t\t}\n\t\t\t\tthis._overlayAnimationEnabled = true\n\t\t\t} else {\n\t\t\t\tthis._overlay = null\n\t\t\t}\n\t\t}\n\n\t\tif (this._mainView !== this.#previousMainView) {\n\t\t\tthis.#previousMainView = this._mainView\n\t\t\tif (this._overlayAnimationEnabled) {\n\t\t\t\tthis._overlayAnimationEnabled = false\n\t\t\t}\n\t\t}\n\t}\n\n\tget isPreviewingLocaleOnCanvas(): boolean {\n\t\treturn this.mainView === ActiveMainView.Canvas && this.canvasLocaleId !== defaultLocaleId\n\t}\n\n\tprivate _floatingToolbarWidth = 0\n\tget floatingToolbarWidth() {\n\t\treturn this._floatingToolbarWidth\n\t}\n\n\tset floatingToolbarWidth(width: number) {\n\t\tif (width === this._floatingToolbarWidth) return\n\t\tthis._floatingToolbarWidth = width\n\t}\n\n\t/**\n\t * Hide any panels and reset to the canvas.\n\t */\n\treset() {\n\t\tthis._fullScreenPreviewVisible = false\n\t\tthis._codeEditorPreviewVisible = false\n\t\tthis._isHistoryModeActive = false\n\t\tthis.#leftPanelOverride = null\n\t\tthis.#rightPanelOverride = null\n\t\tthis.#currentCodeFileId = undefined\n\t\tthis.#overlayOverride = null\n\t\tthis.#siteSettingsVisible = false\n\t\tthis.#analyticsVisible = false\n\t\tthis.#analyticsRightPanelVisible = false\n\t\tthis.#localizationsVisible = false\n\t\tthis.#isEvaluationsModeActive = false\n\t\tthis.calculateEditorState()\n\t}\n\n\tprivate _mainView: ActiveMainView = ActiveMainView.Canvas\n\tprivate _leftPanel: ActiveLeftPanel = ActiveLeftPanel.Canvas\n\tprivate _leftPanelOpenOnMobile = false\n\tprivate _rightPanel: ActiveRightPanel = ActiveRightPanel.Canvas\n\tprivate _overlay: ActiveOverlay | null = null\n\tprivate _overlayAnimationEnabled = false\n\tprivate _fullScreenPreviewVisible = false\n\tprivate _codeEditorPreviewVisible = false\n\tprivate _isHistoryModeActive = false\n\tprivate _displayMinimalUI = environment.isPhone\n\n\t/** Maintain a map of the nodes that currently have an in-flight upload\n\t *  of a tiling background pattern (inserted via the insert menu)\n\t */\n\tprivate _uploadingTilingImageMap: Set<NodeID> = new Set()\n\n\tnotifyTilingImageUploadStarted(nodeId: NodeID) {\n\t\tthis._uploadingTilingImageMap.add(nodeId)\n\t}\n\n\tnotifyTilingImageUploadFinished(nodeId: NodeID) {\n\t\tthis._uploadingTilingImageMap.delete(nodeId)\n\t}\n\n\tget uploadingTilingImageMap() {\n\t\treturn this._uploadingTilingImageMap\n\t}\n\n\tget mainView() {\n\t\treturn this._mainView\n\t}\n\n\tget leftPanel() {\n\t\treturn this._leftPanel\n\t}\n\n\tget isLeftPanelOpenOnMobile() {\n\t\treturn this._leftPanelOpenOnMobile\n\t}\n\n\tget rightPanel() {\n\t\treturn this._rightPanel\n\t}\n\n\tget isHistoryModeActive() {\n\t\treturn this._isHistoryModeActive\n\t}\n\n\tset isHistoryModeActive(historyModeActive: boolean) {\n\t\tthis._isHistoryModeActive = historyModeActive\n\t\tthis.calculateEditorState()\n\t}\n\n\tget displayMinimalUI() {\n\t\treturn this._displayMinimalUI\n\t}\n\n\tget aiGenerationInProgress(): boolean {\n\t\treturn this._aiGenerationInProgress > 0\n\t}\n\n\tget shouldShowGeneratePageButton(): boolean {\n\t\treturn (\n\t\t\t!this.hideGeneratePageButton &&\n\t\t\tthis.mainView === ActiveMainView.Canvas &&\n\t\t\t!this.aiGenerationInProgress &&\n\t\t\t(!this.isTutorialActive || this.hasTutorialPlayed)\n\t\t)\n\t}\n\n\tget overlay() {\n\t\treturn this._overlay\n\t}\n\n\tget overlayAnimationEnabled() {\n\t\treturn this._overlayAnimationEnabled\n\t}\n\n\tget contentManagementOverlayStack(): readonly OverlayStackElement[] {\n\t\tif (this._overlay?.type === \"collectionItem\") return this._overlay.stack\n\t\treturn contentManagementOverlayStackFallback\n\t}\n\n\tdebugOverrideSetUserIsViewer(userIsViewer: boolean) {\n\t\tthis.debugOverrideUserIsViewer = true\n\t\tthis.userIsViewer = userIsViewer\n\t}\n\n\tenableDetachedEditableMode() {\n\t\t// Detached engines, such as eval replay runtimes, are not backed by project collaboration state.\n\t\t// They still need normal edit guards to treat their local tree as writable.\n\t\tthis.#isDetachedEditableMode = true\n\t\tthis.hasReceivedUserPermissions = true\n\t\tthis.userIsViewer = false\n\t\tthis.userIsAccountSharing = false\n\t}\n\n\tget isDetachedEditableMode() {\n\t\treturn this.#isDetachedEditableMode\n\t}\n\n\t#insertHasBeenVisible = false\n\t#siteSettingsVisible = false\n\t#analyticsVisible = false\n\t/** Hide the right panel on the overview screen */\n\t#analyticsRightPanelVisible = false\n\t#localizationsVisible = false\n\t#isEvaluationsModeActive = browserAgentEvalsBuildEnabled\n\t#leftPanelOverride: ActiveLeftPanel | null = null\n\t#rightPanelOverride: ActiveRightPanel | null = null\n\t#overlayOverride: ActiveOverlay | null = null\n\t#currentCodeFileId: string | undefined\n\t#scopeType: ScopeType = ScopeType.CanvasPage\n\n\trightPanelTabs: CanvasPanelTab[] = [CanvasPanelTab.Chat, CanvasPanelTab.Properties]\n\t_activeRightPanelTab: CanvasPanelTab = CanvasPanelTab.Chat\n\n\t_activeCollectionPanelTab: CollectionPanelTab = CollectionPanelTab.Collections\n\t_activeLocalizationPanelTab: LocalizationPanelTab = LocalizationPanelTab.Locales\n\n\tchatInputHasContent = false\n\tagentQuestionKeyboardActive = false\n\n\tget activeRightPanelTab(): CanvasPanelTab {\n\t\tif (this.rightPanelTabs.includes(this._activeRightPanelTab)) {\n\t\t\treturn this._activeRightPanelTab\n\t\t}\n\n\t\tassert(this.rightPanelTabs[0], \"Must have at least one right panel tab\")\n\t\treturn this.rightPanelTabs[0]\n\t}\n\n\tset activeRightPanelTab(tab: CanvasPanelTab) {\n\t\tthis._activeRightPanelTab = tab\n\t}\n\n\tget activeCollectionPanelTab(): CollectionPanelTab {\n\t\treturn this._activeCollectionPanelTab\n\t}\n\tset activeCollectionPanelTab(tab: CollectionPanelTab) {\n\t\tthis._activeCollectionPanelTab = tab\n\t}\n\n\tget activeLocalizationPanelTab(): LocalizationPanelTab {\n\t\treturn this._activeLocalizationPanelTab\n\t}\n\tset activeLocalizationPanelTab(tab: LocalizationPanelTab) {\n\t\tthis._activeLocalizationPanelTab = tab\n\t}\n\n\tcalculateEditorState() {\n\t\t// prioritize site settings over preview, so if anything opens the site settings within the preview (e.g.\n\t\t// publish popover), we update the main view correctly\n\t\tif (this.#siteSettingsVisible) {\n\t\t\tthis._mainView = ActiveMainView.SiteSettings\n\t\t\tthis._leftPanel = ActiveLeftPanel.SiteSettings\n\t\t\tthis._rightPanel = ActiveRightPanel.None\n\t\t\tthis._overlay = null\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#analyticsVisible) {\n\t\t\tthis._mainView = ActiveMainView.Analytics\n\t\t\tthis._leftPanel = ActiveLeftPanel.Analytics\n\t\t\tthis._rightPanel = this.#analyticsRightPanelVisible ? ActiveRightPanel.Analytics : ActiveRightPanel.None\n\t\t\tthis._overlay = null\n\t\t\treturn\n\t\t}\n\n\t\tif (this._fullScreenPreviewVisible) {\n\t\t\tthis._mainView = ActiveMainView.Preview\n\t\t\tthis._leftPanel = ActiveLeftPanel.None\n\t\t\tthis._rightPanel = ActiveRightPanel.None\n\t\t\tthis._overlay = null\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#localizationsVisible) {\n\t\t\tthis._mainView = ActiveMainView.Localizations\n\t\t\tthis._leftPanel = ActiveLeftPanel.None\n\t\t\tthis._rightPanel = ActiveRightPanel.None\n\n\t\t\tif (this.#overlayOverride?.type === \"localization\") {\n\t\t\t\tthis._overlay = this.#overlayOverride\n\t\t\t} else {\n\t\t\t\tthis._overlay = null\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#isEvaluationsModeActive) {\n\t\t\tthis._mainView = ActiveMainView.Canvas\n\t\t\tthis._leftPanel = this.#leftPanelOverride ?? ActiveLeftPanel.Canvas\n\t\t\tthis._rightPanel = this._isHistoryModeActive ? ActiveRightPanel.History : ActiveRightPanel.Canvas\n\t\t\tthis._overlay = this.#overlayOverride\n\t\t\treturn\n\t\t}\n\n\t\tconst isCodeEditorOpen = Boolean(this.#currentCodeFileId)\n\n\t\tif (isCodeEditorOpen) {\n\t\t\tthis._mainView = ActiveMainView.CodeEditor\n\t\t\tthis._leftPanel = ActiveLeftPanel.Canvas\n\t\t\tthis._rightPanel = ActiveRightPanel.None\n\t\t\tthis._overlay = null\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#scopeType === ScopeType.ContentManagement) {\n\t\t\tthis._mainView = ActiveMainView.ContentManagement\n\t\t\tthis._leftPanel = ActiveLeftPanel.ContentManagement\n\t\t\tthis._rightPanel = ActiveRightPanel.None\n\n\t\t\tif (this.#overlayOverride?.type === \"collectionItem\") {\n\t\t\t\tthis._overlay = this.#overlayOverride\n\t\t\t} else {\n\t\t\t\tthis._overlay = null\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tthis._mainView = ActiveMainView.Canvas\n\t\tthis._rightPanel = this.#rightPanelOverride ?? ActiveRightPanel.Canvas\n\t\tthis._overlay = this.#overlayOverride\n\t\tif (this._isHistoryModeActive) {\n\t\t\tthis._rightPanel = ActiveRightPanel.History\n\t\t}\n\n\t\tthis._leftPanel = this.#leftPanelOverride ?? ActiveLeftPanel.Canvas\n\t}\n\n\tsetPreviewVisible = (visible: boolean) => {\n\t\tif (this.mainView === ActiveMainView.CodeEditor) {\n\t\t\tthis._codeEditorPreviewVisible = visible\n\t\t} else {\n\t\t\tthis._fullScreenPreviewVisible = visible\n\t\t}\n\t\tthis.calculateEditorState()\n\t}\n\n\tsetLocalizationsVisible = (visible: boolean, onComplete?: () => void) => {\n\t\tassert(projectFeatures.isOn(\"sites\"), \"Sites must be on for localizations\")\n\n\t\tconst update = () => {\n\t\t\tthis.#localizationsVisible = visible\n\t\t\tthis.calculateEditorState()\n\t\t\tif (!visible) {\n\t\t\t\tdismissMatchingItemsToast()\n\t\t\t\tthis.onLocalizationsHide()\n\t\t\t}\n\t\t\tif (onComplete) onComplete()\n\t\t}\n\n\t\tupdate()\n\t}\n\n\tget isEvaluationsModeActive() {\n\t\treturn this.#isEvaluationsModeActive\n\t}\n\n\tenterEvaluationsMode = () => {\n\t\tthis.#isEvaluationsModeActive = true\n\t\tthis._activeRightPanelTab = CanvasPanelTab.Chat\n\t\tthis.calculateEditorState()\n\t}\n\n\texitEvaluationsMode = () => {\n\t\tthis.#isEvaluationsModeActive = false\n\t\tthis.calculateEditorState()\n\t}\n\n\tonChangeSiteSettingsVisible(visible: boolean) {\n\t\tthis.#siteSettingsVisible = visible\n\t\tthis.calculateEditorState()\n\t}\n\n\tonChangeAnalyticsVisible(visible: boolean, rightPanelVisible: boolean) {\n\t\tthis.#analyticsVisible = visible\n\t\tthis.#analyticsRightPanelVisible = rightPanelVisible\n\t\tthis.calculateEditorState()\n\t}\n\n\tget insertSidebarHasBeenVisible() {\n\t\treturn this.#insertHasBeenVisible\n\t}\n\n\trunAIGeneration<R>(task: () => Promise<R>): Promise<R> {\n\t\tconst promise = task()\n\t\tthis.trackAIGeneration(promise)\n\t\treturn promise\n\t}\n\n\ttrackAIGeneration<R>(promise: Promise<R>): void {\n\t\tthis._aiGenerationInProgress += 1\n\t\tthis.calculateEditorState()\n\t\tvoid promise.finally(() => {\n\t\t\tthis._aiGenerationInProgress -= 1\n\t\t\tthis.calculateEditorState()\n\t\t})\n\t}\n\n\tshowInsertSidebar() {\n\t\tif (this.isPreviewingLocaleOnCanvas) return\n\t\tthis.#insertHasBeenVisible = true\n\t\tthis.#leftPanelOverride = ActiveLeftPanel.Insert\n\t\tthis.#rightPanelOverride = null\n\t\tthis.calculateEditorState()\n\t}\n\n\thideInsertSidebar() {\n\t\tif (this.#leftPanelOverride !== ActiveLeftPanel.Insert) {\n\t\t\treturn\n\t\t}\n\t\tthis.#leftPanelOverride = null\n\t\tthis.calculateEditorState()\n\t}\n\n\tshowAiSidebar() {\n\t\tthis.#leftPanelOverride = ActiveLeftPanel.Ai\n\t\tthis.#rightPanelOverride = null\n\t\tthis.calculateEditorState()\n\t}\n\n\thideAiSidebar() {\n\t\tif (this.#leftPanelOverride !== ActiveLeftPanel.Ai) {\n\t\t\treturn\n\t\t}\n\t\tthis.#leftPanelOverride = null\n\t\tthis.calculateEditorState()\n\t}\n\n\ttoggleAiSidebar() {\n\t\tif (this.#leftPanelOverride === ActiveLeftPanel.Ai) {\n\t\t\tthis.hideAiSidebar()\n\t\t} else {\n\t\t\tthis.showAiSidebar()\n\t\t}\n\t}\n\n\ttoggleInsertSidebar() {\n\t\tif (this.#leftPanelOverride === ActiveLeftPanel.Insert) {\n\t\t\tthis.hideInsertSidebar()\n\t\t} else {\n\t\t\tthis.showInsertSidebar()\n\t\t}\n\t}\n\n\tsetLeftPanelOpenOnMobile(setAsOverlay: boolean) {\n\t\tthis._leftPanelOpenOnMobile = setAsOverlay\n\t}\n\n\ttoggleLeftPanelOpenOnMobile() {\n\t\tthis._leftPanelOpenOnMobile = !this._leftPanelOpenOnMobile\n\t}\n\n\tsetOverlay(overlay: ActiveOverlay) {\n\t\tthis.#overlayOverride = overlay\n\t\tthis._overlayAnimationEnabled = true\n\t\tthis.calculateEditorState()\n\t}\n\n\tsetContentManagementOverlayStack(stack: readonly OverlayStackElement[]) {\n\t\tif (stack.length === 0) {\n\t\t\tthis.hideOverlay()\n\t\t\treturn\n\t\t}\n\n\t\tthis.setOverlay({\n\t\t\ttype: \"collectionItem\",\n\t\t\tstack,\n\t\t})\n\t}\n\n\thideOverlay() {\n\t\tthis.#overlayOverride = null\n\t\tthis.calculateEditorState()\n\t}\n\n\tonCanvasSelectionChange(selection: Selection, switchToLayers: boolean, switchToProperties: boolean) {\n\t\tif (selection.length === 0) {\n\t\t\tthis._activeRightPanelTab = CanvasPanelTab.Chat\n\t\t\treturn\n\t\t}\n\n\t\tif (\n\t\t\tswitchToLayers &&\n\t\t\tthis.persistedUserDefaults.autoSwitchToLayers &&\n\t\t\tthis.#scopeType !== ScopeType.ContentManagement\n\t\t) {\n\t\t\tthis.contentPanelTab = ActiveContentPanelTab.Layers\n\t\t}\n\n\t\tif (switchToProperties && this._activeRightPanelTab !== CanvasPanelTab.Properties) {\n\t\t\tif (!(this._activeRightPanelTab === CanvasPanelTab.Chat && this.chatInputHasContent)) {\n\t\t\t\tthis._activeRightPanelTab = CanvasPanelTab.Properties\n\t\t\t}\n\t\t}\n\t}\n\n\tremovePanelOverrides() {\n\t\tif (this.#leftPanelOverride || this.#rightPanelOverride) {\n\t\t\tthis.#leftPanelOverride = null\n\t\t\tthis.#rightPanelOverride = null\n\t\t\tthis.calculateEditorState()\n\t\t}\n\t}\n\n\tonChangeCodeFile(currentCodeFileId: string | undefined) {\n\t\tthis.#currentCodeFileId = currentCodeFileId\n\t\tthis.calculateEditorState()\n\t}\n\n\tonChangeScopeType(scopeType: ScopeType) {\n\t\tthis.#scopeType = scopeType\n\t\tthis.#overlayOverride = null\n\n\t\t// When going to the CMS and back to the canvas we don't want the left panel to keep showing the CMS or insert panel\n\t\tif (scopeType === ScopeType.ContentManagement) {\n\t\t\tthis.#siteSettingsVisible = false\n\t\t\tthis.#analyticsVisible = false\n\t\t\tthis.#leftPanelOverride = null\n\t\t\tthis.#rightPanelOverride = null\n\t\t\ttoast({ key: ToastKey.InsertedExternalDataSourceToastKey, type: \"remove\" })\n\t\t}\n\n\t\tthis.calculateEditorState()\n\t}\n\n\tonToolChange(tool: Tools) {\n\t\tconst hasOverride = this.#leftPanelOverride || this.#rightPanelOverride\n\n\t\tif (hasOverride && shouldRemovePanelOverride(tool)) {\n\t\t\tthis.removePanelOverrides()\n\t\t}\n\t}\n\n\tget codeEditorPreviewVisible() {\n\t\treturn this.mainView === ActiveMainView.CodeEditor && this._codeEditorPreviewVisible\n\t}\n\n\tcodeEditorPreviewWidth = 0\n\n\t/**\n\t * @deprecated\n\t * Prefer using `useIsViewOnly` and `getIsViewOnly` instead\n\t *\n\t * Returns a boolean indicating if the app is in ViewOnly mode.\n\t * It depends on either if the network is connected, if the user has view-only access or\n\t * if the (partial) document is still loading\n\t */\n\tget isViewOnly() {\n\t\tif (!this.loadingStore.isReady) return true\n\t\tif (this.#isDetachedEditableMode) return false\n\t\treturn this.userIsViewer\n\t}\n\n\t/**\n\t * Returns a string representing a status bar type\n\t */\n\tget statusBarType() {\n\t\tif (this.userIsEmployee) {\n\t\t\treturn \"employee\"\n\t\t}\n\t\tif (this.#isOnBetaChannel) {\n\t\t\treturn \"betaChannel\"\n\t\t}\n\t\tif (this.#isOnBeta) {\n\t\t\treturn \"beta\"\n\t\t}\n\t\treturn undefined\n\t}\n\n\t// The dehydrated version of Vekter always has userIsViewer set to false\n\t// Make sure that it is set to true by default when we support view only mode (in Web)\n\t// Because platform.isOn(\"supportsViewOnlyMode\") only returns the correct value at runtime\n\t// and not during SSR, we cannot use it to set the userIsViewer default value\n\tinitializeUserIsViewer() {\n\t\tif (this.hasReceivedUserPermissions) {\n\t\t\t// When we already have received permissions,\n\t\t\t// we do not need to set the default anymore\n\t\t\treturn\n\t\t}\n\n\t\t// When served from localhost, we assume it is some kind of development,\n\t\t// and we default to a read-write mode.\n\t\tconst devMode = isLocalUrl(window.location.href)\n\t\t// This used to be platform.isOn(\"supportsViewOnlyMode\")\n\t\tconst supportsViewOnlyMode = !(environment.isAutomation || environment.isTest)\n\t\tthis.userIsViewer = employeesOnlySettings.isOn(\"userIsViewer\") || (supportsViewOnlyMode && !devMode)\n\t}\n\n\t// Content panel\n\n\tassetsPanelTab: ActiveAssetsPanelTab = ActiveAssetsPanelTab.Components\n\n\tcontentPanelTab: ActiveContentPanelTab = ActiveContentPanelTab.Pages\n\n\tisContentPanelSearchFocused = false\n\n\t// Registered by `AgentChatInput` while it is mounted; call to focus the input. Function-typed\n\t// fields are excluded from store snapshots, so writes do not trigger React re-renders.\n\tfocusAgentChatInput: (() => void) | undefined = undefined\n\n\t// Set when the chat tab is opened but the input isn't mounted yet (e.g. \u2318J while the panel\n\t// is on another tab). `AgentChatInput` checks this on mount and auto-focuses.\n\tpendingAgentChatInputFocus = false\n\n\tsitesPagesExpanded = true\n\tcmsPagesExpanded = true\n\tcanvasPagesExpanded = true\n\tdesignPagesExpanded = true\n\tkitPagesExpanded = true\n\tlayoutTemplatesExpanded = true\n\tvectorSetsExpanded = true\n\tcomponentsExpanded = true\n\tstylesExpanded = true\n\tcodeFilesExpanded = true\n\tshadersExpanded = true\n\n\tpagesExpanded = true\n\tlayersExpanded = true\n\tassetsExpanded = document.documentElement.clientHeight >= 900\n\n\tassetPanelTextStylePresetsExpanded = true\n\tassetPanelLinkStylePresetsExpanded = true\n\tassetPanelBlockquoteStylePresetsExpanded = true\n\tassetPanelInlineCodeStylePresetsExpanded = true\n\tassetPanelColorStyleTokensExpanded = true\n\tassetPanelCmsPresetsExpanded = true\n\n\texpandedRouteSegments: ReadonlySet<NodeID> = new Set()\n\n\ttoggleCanvasPages = () => (this.canvasPagesExpanded = !this.canvasPagesExpanded)\n\ttoggleDesignPages = () => (this.designPagesExpanded = !this.designPagesExpanded)\n\ttoggleKitPages = () => (this.kitPagesExpanded = !this.kitPagesExpanded)\n\ttoggleLayoutTemplates = () => (this.layoutTemplatesExpanded = !this.layoutTemplatesExpanded)\n\ttoggleVectorSets = () => (this.vectorSetsExpanded = !this.vectorSetsExpanded)\n\ttoggleComponents = () => (this.componentsExpanded = !this.componentsExpanded)\n\ttoggleStyles = () => (this.stylesExpanded = !this.stylesExpanded)\n\ttoggleCodeFiles = () => (this.codeFilesExpanded = !this.codeFilesExpanded)\n\ttoggleShaders = () => (this.shadersExpanded = !this.shadersExpanded)\n\n\ttoggleAssetStylesText = () => (this.assetPanelTextStylePresetsExpanded = !this.assetPanelTextStylePresetsExpanded)\n\ttoggleAssetStylesLinks = () => (this.assetPanelLinkStylePresetsExpanded = !this.assetPanelLinkStylePresetsExpanded)\n\ttoggleAssetStylesBlockquotes = () =>\n\t\t(this.assetPanelBlockquoteStylePresetsExpanded = !this.assetPanelBlockquoteStylePresetsExpanded)\n\ttoggleAssetStylesCode = () =>\n\t\t(this.assetPanelInlineCodeStylePresetsExpanded = !this.assetPanelInlineCodeStylePresetsExpanded)\n\ttoggleAssetStylesColors = () => (this.assetPanelColorStyleTokensExpanded = !this.assetPanelColorStyleTokensExpanded)\n\ttoggleAssetStylesCMS = () => (this.assetPanelCmsPresetsExpanded = !this.assetPanelCmsPresetsExpanded)\n\n\tisExpandedRouteSegment = (nodeId: NodeID) => this.expandedRouteSegments.has(nodeId)\n\texpandRouteSegment = (segmentIds: NodeID | ReadonlySet<NodeID>) => {\n\t\tconst newExpandedRouteSegments = new Set(this.expandedRouteSegments)\n\t\tif (typeof segmentIds === \"string\") {\n\t\t\tnewExpandedRouteSegments.add(segmentIds)\n\t\t} else {\n\t\t\tsegmentIds.forEach(id => newExpandedRouteSegments.add(id))\n\t\t}\n\t\tthis.expandedRouteSegments = newExpandedRouteSegments\n\t}\n\tcollapseRouteSegment = (nodeId: NodeID) => {\n\t\tconst newExpandedRouteSegments = new Set(this.expandedRouteSegments)\n\t\tnewExpandedRouteSegments.delete(nodeId)\n\t\tthis.expandedRouteSegments = newExpandedRouteSegments\n\t}\n\tcollapseAllRouteSegments() {\n\t\tthis.expandedRouteSegments = new Set<NodeID>()\n\t}\n\ttoggleRouteSegmentRow(nodeId: NodeID) {\n\t\tthis.expandedRouteSegments = newSetByTogglingItem(this.expandedRouteSegments, nodeId)\n\t}\n\n\tdocumentDidLoad() {\n\t\tthis.pagesExpanded = true\n\t}\n\n\t// Using a readonly private set to avoid broadcasting expanded asset entity\n\t// ids changes to the UI. All public fields changes trigger UI changes.\n\t// Changes are distinct between the asset list used in pop-outs, and\n\t// elsewhere.\n\tprivate _expandedAssetEntityIds: ReadonlySet<NodeID> = new Set([])\n\tprivate _popoutExpandedAssetEntityIds: ReadonlySet<NodeID> = new Set([])\n\n\texpandedAssetEntityIds(popout: boolean) {\n\t\treturn popout ? this._popoutExpandedAssetEntityIds : this._expandedAssetEntityIds\n\t}\n\n\tprivate updateExpandedAssetEntityIds(set: ReadonlySet<NodeID>, popout: boolean) {\n\t\tif (popout) {\n\t\t\tthis._popoutExpandedAssetEntityIds = set\n\t\t\treturn\n\t\t}\n\t\tthis._expandedAssetEntityIds = set\n\t}\n\n\tisExpandedAssetEntityItem(itemId: string, popout: boolean) {\n\t\treturn this.expandedAssetEntityIds(popout).has(itemId)\n\t}\n\n\ttoggleAssetEntityItem(itemId: string, popout: boolean) {\n\t\tthis.updateExpandedAssetEntityIds(newSetByTogglingItem(this.expandedAssetEntityIds(popout), itemId), popout)\n\t}\n\n\texpandAssetEntityItem(itemId: string, popout: boolean) {\n\t\tconst expandedAssetEntityItems = new Set(this.expandedAssetEntityIds(popout))\n\t\texpandedAssetEntityItems.add(itemId)\n\t\tthis.updateExpandedAssetEntityIds(expandedAssetEntityItems, popout)\n\t}\n\n\texpandAssetEntityItems(itemIds: Set<string>, popout: boolean) {\n\t\tconst expandedAssetEntityItems = new Set(this.expandedAssetEntityIds(popout))\n\t\titemIds.forEach(id => expandedAssetEntityItems.add(id))\n\t\tthis.updateExpandedAssetEntityIds(expandedAssetEntityItems, popout)\n\t}\n\n\tcollapseAssetEntityItem(itemId: string, popout: boolean) {\n\t\tconst expandedAssetEntityItems = new Set(this.expandedAssetEntityIds(popout))\n\t\texpandedAssetEntityItems.delete(itemId)\n\t\tthis.updateExpandedAssetEntityIds(expandedAssetEntityItems, popout)\n\t}\n\n\tcollapseAllAssetEntityItems(popout: boolean) {\n\t\tconst expandedAssetEntityItems = new Set<NodeID>()\n\t\tthis.updateExpandedAssetEntityIds(expandedAssetEntityItems, popout)\n\t}\n}\n\nfunction shouldRemovePanelOverride(tool: Tools): boolean {\n\tswitch (tool) {\n\t\tcase Tools.CollectionReferenceVariableEdit:\n\t\tcase Tools.CreateFrame:\n\t\tcase Tools.CreateRounded:\n\t\tcase Tools.CreateImage:\n\t\tcase Tools.CreateVideo:\n\t\tcase Tools.CreateScreen:\n\t\tcase Tools.CreateText:\n\t\tcase Tools.CreateOvalShape:\n\t\tcase Tools.CreateRectangleShape:\n\t\tcase Tools.CreatePolygonShape:\n\t\tcase Tools.CreateStarShape:\n\t\tcase Tools.CreateStack:\n\t\tcase Tools.CreateRows:\n\t\tcase Tools.CreateColumns:\n\t\tcase Tools.CreateGrid:\n\t\tcase Tools.CreateGridRow:\n\t\tcase Tools.CreateGridSpan:\n\t\tcase Tools.CreateMasonry:\n\t\tcase Tools.Comment:\n\t\tcase Tools.TextEdit:\n\t\tcase Tools.RichTextEdit:\n\t\tcase Tools.RichTextVariableEdit:\n\t\tcase Tools.StringVariableEdit:\n\t\tcase Tools.DateVariableEdit:\n\t\tcase Tools.EnumVariableEdit:\n\t\tcase Tools.Resize:\n\t\tcase Tools.Scale:\n\t\tcase Tools.Guide:\n\t\tcase Tools.Link:\n\t\tcase Tools.Radius:\n\t\tcase Tools.SampleColor:\n\t\tcase Tools.FillGradient:\n\t\tcase Tools.MaskGradient:\n\t\tcase Tools.Path:\n\t\tcase Tools.LineAnchorMove:\n\t\tcase Tools.Padding:\n\t\tcase Tools.Gap:\n\t\tcase Tools.SlotConnect:\n\t\tcase Tools.Rotate:\n\t\t\treturn true\n\n\t\tcase Tools.AgentPanel:\n\t\tcase Tools.AgentDragSelect:\n\t\tcase Tools.AgentSelect:\n\t\tcase Tools.Zoom:\n\t\tcase Tools.ZoomSelect:\n\t\tcase Tools.Highlight:\n\t\tcase Tools.HighlightStackItem:\n\t\tcase Tools.DirectSelect:\n\t\tcase Tools.Select:\n\t\tcase Tools.Pan:\n\t\tcase Tools.Move:\n\t\tcase Tools.Chat:\n\t\tcase Tools.Unknown:\n\t\tcase Tools.ViewportResize:\n\t\tcase Tools.LoadingShield:\n\t\t\treturn false\n\t}\n}\n\nconst contentManagementOverlayStackFallback: readonly OverlayStackElement[] = []\n", "import type { ProjectBundleGlobalEnvironment } from \"@framerjs/framer-runtime/sandbox\"\nimport { assert } from \"@framerjs/shared\"\n\ninterface ErrorStackElement {\n\tfileName: string\n\tfunctionName: string\n\tlineNumber: number\n\tcolNumber: number\n\tuserCode: boolean // if the stack element originated in code we compiled for the user\n}\n\nexport interface ComponentEvalError {\n\tmessage: string\n\tfileName: string\n\tlineNumber: number\n\tcolNumber: number\n\tstack?: ErrorStackElement[]\n}\n\ninterface SourceMap {\n\tfile: string\n\tsources: string[]\n\tmappings: string\n}\n\ninterface Mapping {\n\tencoded: string\n\tline: number\n\tmap?: SourceMap\n}\n\ninterface ComponentFileMappings {\n\tscript: string\n\tmaps: Mapping[]\n}\n\n// globals\nlet componentScript: string | null = null\nlet componentSrc: string | null = null\nlet componentMappings: ComponentFileMappings | null = null\n\nfunction updateErrorGlobals() {\n\tconst w: ProjectBundleGlobalEnvironment = window as any\n\tcomponentScript = w.componentScript || null\n\tcomponentSrc = w.componentSrc || null\n}\n\n// implementation\n\nconst sourceMapString = \"//# framerSourceMap=\"\n\nconst charToUInt6: { [key: number]: number } = {}\nconst chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\"\n\nfor (let i = 0; i < chars.length; i++) {\n\tcharToUInt6[chars.charCodeAt(i)] = i\n}\n\n// translates line numbers using the `mappings` field of a source map\nfunction translateUsingMappings(mappings: string, line: number, column: number): [number, number] {\n\tlet currentLine = 0\n\tlet currentColumn = 0\n\tlet origLine = 0\n\tlet origColumn = 0\n\tlet field = 0\n\tlet shift = 0\n\tlet value = 0\n\tfor (let i = 0, il = mappings.length; i < il; i++) {\n\t\tconst c = mappings.charCodeAt(i)\n\n\t\tif (c === 44) {\n\t\t\t// \",\" means a new column range\n\t\t\tfield = 0\n\t\t} else if (c === 59) {\n\t\t\t// \";\" means the next line\n\t\t\tif (currentLine >= line) return [origLine + 1, origColumn + 1]\n\t\t\tcurrentLine += 1\n\t\t\tcurrentColumn = 0\n\t\t\tfield = 0\n\t\t} else {\n\t\t\t// decode variable length quantity\n\t\t\tconst uint6 = charToUInt6[c]\n\t\t\tif (uint6 === undefined) continue\n\n\t\t\tvalue |= (uint6 & 0b001_1111) << shift\n\n\t\t\tif (uint6 & 0b010_0000) {\n\t\t\t\tshift += 5\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// have the complete value, finalize\n\t\t\tconst shouldNegate = value & 1\n\t\t\tvalue >>= 1\n\t\t\tconst num = shouldNegate ? -value : value\n\n\t\t\t// decode per field\n\t\t\tif (field === 0) {\n\t\t\t\tcurrentColumn += num\n\t\t\t\tif (currentLine >= line && currentColumn > column) {\n\t\t\t\t\treturn [origLine + 1, origColumn + 1]\n\t\t\t\t}\n\t\t\t} else if (field === 1) {\n\t\t\t\t// file index, unused\n\t\t\t} else if (field === 2) {\n\t\t\t\torigLine += num\n\t\t\t} else if (field === 3) {\n\t\t\t\torigColumn += num\n\t\t\t} else if (field === 4) {\n\t\t\t\t// name index, unused\n\t\t\t}\n\n\t\t\t// setup for next field\n\t\t\tfield++\n\t\t\tvalue = 0\n\t\t\tshift = 0\n\t\t}\n\t}\n\treturn [-1, 0]\n}\n\nfunction getComponentMappings(script: string): ComponentFileMappings {\n\tif (componentMappings && componentMappings.script === script) return componentMappings\n\n\tcomponentMappings = { script, maps: [] }\n\tlet at = 0\n\tlet lineno = 1\n\tfor (;;) {\n\t\tconst nextAt = script.indexOf(\"\\n\", at)\n\t\tif (nextAt === -1) return componentMappings\n\n\t\t// look for //# framerSourceMap=eyJ2ZXJzaW9u...\n\t\tif (script[at + 2] === \"#\" && script[at + 4] === \"f\") {\n\t\t\tconst line = script.slice(at, nextAt)\n\t\t\tif (line.startsWith(sourceMapString)) {\n\t\t\t\tconst encoded = line.slice(sourceMapString.length)\n\t\t\t\tcomponentMappings.maps.push({ encoded, line: lineno + 1, map: undefined })\n\t\t\t}\n\t\t}\n\t\tlineno += 1\n\t\tat = nextAt + 1\n\t}\n}\n\nexport function errorFromFramerComponentScript(\n\tscript: string,\n\tlineNumber: number,\n\tcolNumber: number,\n\tfunctionName: string,\n\tfileName: string,\n): ErrorStackElement | undefined {\n\tconst mappings = getComponentMappings(script)\n\tlet sourceMap: Mapping | undefined\n\tfor (const candidate of mappings.maps) {\n\t\tif (candidate.line > lineNumber) break\n\t\tsourceMap = candidate\n\t}\n\n\tif (!sourceMap) return { functionName, lineNumber, colNumber, fileName, userCode: false }\n\n\tif (!sourceMap.map) {\n\t\tsourceMap.map = JSON.parse(atob(sourceMap.encoded))\n\t}\n\n\tconst map = sourceMap.map\n\tif (!map) throw Error(\"assert\")\n\n\tfileName = map.sources[0] || map.file || fileName\n\tconst relativeLineNumber = lineNumber - sourceMap.line\n\tconst [l, c] = translateUsingMappings(map.mappings, relativeLineNumber, colNumber)\n\tif (l >= 0) {\n\t\tlineNumber = l\n\t\tcolNumber = c\n\t}\n\n\treturn { functionName, lineNumber, colNumber, fileName, userCode: true }\n}\n\nfunction isComponentBuildFile(fileName: string): boolean {\n\treturn fileName === componentSrc || fileName === \"index/build.js\" || fileName === \"undefined\"\n}\n\nfunction parseStackElementInfo(stackElement: string) {\n\tconst info = { functionName: \"\", fileName: \"\", lineNumber: 0, colNumber: 0 }\n\tlet match = /^\\s*(?<functionName>[^@]+)@(?<fileName>.*):(?<lineNumber>\\d+):(?<colNumber>\\d+)$/u.exec(stackElement)\n\tif (match?.groups) {\n\t\tconst { functionName, fileName, lineNumber, colNumber } = match.groups\n\t\tassert(functionName && fileName && lineNumber && colNumber, `Invalid stack element: ${stackElement}`)\n\t\tinfo.functionName = functionName.trim()\n\t\tinfo.fileName = fileName.trim()\n\t\tinfo.lineNumber = parseInt(lineNumber)\n\t\tinfo.colNumber = parseInt(colNumber)\n\t\treturn info\n\t}\n\tmatch = /^\\s*at (?<functionName>[^(]+)\\((?<fileName>.*):(?<lineNumber>\\d+):(?<colNumber>\\d+)\\)$/u.exec(stackElement)\n\tif (match?.groups) {\n\t\tconst { functionName, fileName, lineNumber, colNumber } = match.groups\n\t\tassert(functionName && fileName && lineNumber && colNumber, `Invalid stack element: ${stackElement}`)\n\t\tinfo.functionName = functionName.trim()\n\t\tinfo.fileName = fileName.trim()\n\t\tinfo.lineNumber = parseInt(lineNumber)\n\t\tinfo.colNumber = parseInt(colNumber)\n\t\treturn info\n\t}\n\tmatch = /^\\s*at (?<fileName>.*):(?<lineNumber>\\d+):(?<colNumber>\\d+)$/u.exec(stackElement)\n\tif (match?.groups) {\n\t\tconst { fileName, lineNumber, colNumber } = match.groups\n\t\tassert(fileName && lineNumber && colNumber, `Invalid stack element: ${stackElement}`)\n\t\tinfo.fileName = fileName.trim()\n\t\tinfo.lineNumber = parseInt(lineNumber)\n\t\tinfo.colNumber = parseInt(colNumber)\n\t\treturn info\n\t}\n\tmatch = /^\\sat (?<functionName>.*)$/u.exec(stackElement)\n\tif (match?.groups) {\n\t\tconst { functionName } = match.groups\n\t\tassert(functionName, `Invalid stack element: ${stackElement}`)\n\t\tinfo.functionName = functionName.trim()\n\t\treturn info\n\t}\n\tinfo.functionName = stackElement.trim()\n\treturn info\n}\n\nfunction parseStackElement(stackElement: string): ErrorStackElement | null {\n\tconst info = parseStackElementInfo(stackElement)\n\tconst { lineNumber, colNumber, functionName } = info\n\tlet { fileName } = info\n\n\tif (isComponentBuildFile(fileName)) {\n\t\tconst script = componentScript\n\t\tif (typeof script === \"string\") {\n\t\t\tconst r = errorFromFramerComponentScript(script, lineNumber, colNumber, functionName, fileName)\n\t\t\tif (r) {\n\t\t\t\tfileName = r.fileName\n\t\t\t\tif (fileName.startsWith(\"../code/\")) {\n\t\t\t\t\tfileName = fileName.slice(\"../code/\".length)\n\t\t\t\t} else if (fileName.startsWith(\"./code\")) {\n\t\t\t\t\tfileName = fileName.slice(\"./code\".length)\n\t\t\t\t} else if (fileName.startsWith(\"./\")) {\n\t\t\t\t\tfileName = fileName.slice(\"./\".length)\n\t\t\t\t}\n\t\t\t\treturn { ...r, fileName }\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { functionName, fileName, lineNumber, colNumber, userCode: false }\n}\n\nfunction parseStack(stack?: string): ErrorStackElement[] | null {\n\tif (!stack) return null\n\tupdateErrorGlobals()\n\treturn stack\n\t\t.split(\"\\n\")\n\t\t.map(parseStackElement)\n\t\t.filter(e => e) as ErrorStackElement[]\n}\n\nexport function parseError(error: Error, errorEvent?: ErrorEvent): ComponentEvalError {\n\tlet message = error.name ? error.name + \": \" + error.message : error.message\n\tmessage = message.split(\"\\n\")[0].trim()\n\tconst stack = parseStack(error.stack)\n\n\tif (stack && stack[0]) {\n\t\tconst first = stack.find(s => s.userCode) || stack[0]\n\t\treturn {\n\t\t\tmessage,\n\t\t\tfileName: first.fileName,\n\t\t\tlineNumber: first.lineNumber,\n\t\t\tcolNumber: first.colNumber,\n\t\t\tstack,\n\t\t}\n\t}\n\n\tif (errorEvent) {\n\t\tconst fileName = errorEvent.filename\n\t\tconst lineNumber = errorEvent.lineno\n\t\tconst colNumber = errorEvent.colno\n\t\treturn {\n\t\t\tmessage,\n\t\t\tfileName,\n\t\t\tlineNumber,\n\t\t\tcolNumber,\n\t\t}\n\t}\n\n\treturn {\n\t\tmessage,\n\t\tfileName: \"\",\n\t\tlineNumber: -1,\n\t\tcolNumber: -1,\n\t}\n}\n\nexport function translateErrorEvent(errorEvent: ErrorEvent): ComponentEvalError {\n\t// The `errorEvent` passed to this function will sometimes come from\n\t// external sources (e.g., the window error handler), so we do defensive\n\t// checks and fallbacks that protect us from actual, real cases of\n\t// ill-shaped objects.\n\tif (!errorEvent.error) {\n\t\treturn {\n\t\t\tmessage: errorEvent.message || \"Unknown error\",\n\t\t\tfileName: errorEvent.filename || \"unknown\",\n\t\t\tlineNumber: errorEvent.lineno || 0,\n\t\t\tcolNumber: errorEvent.colno || 0,\n\t\t}\n\t}\n\n\treturn parseError(errorEvent.error, errorEvent)\n}\n\nexport function getCodeFileBaseNameFromError(error: ComponentEvalError): string {\n\tconst fileName = error.fileName\n\n\tif (fileName.startsWith(\"../code/\")) {\n\t\treturn fileName.slice(\"../code/\".length)\n\t} else if (fileName.startsWith(\"./code/\")) {\n\t\treturn fileName.slice(\"./code/\".length)\n\t} else if (fileName.startsWith(\"./\")) {\n\t\treturn fileName.slice(\"./\".length)\n\t}\n\n\treturn fileName\n}\n", "import type { ComponentLoader, EntityDefinition } from \"@framerjs/framer-runtime\"\nimport { getLogger } from \"@framerjs/shared\"\nimport type { EngineChanges } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport type { SandboxComponentLoaderDefinition } from \"utils/rpc/shared/sandboxComponentLoader.ts\"\nimport type { ComponentEvalError } from \"utils/translateErrorEvent.ts\"\nimport { getCodeFileBaseNameFromError } from \"utils/translateErrorEvent.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport class ComponentsStore implements SandboxComponentLoaderDefinition {\n\tprivate _scriptErrorsByFileName = new Map<string, ComponentEvalError[]>()\n\n\tprivate _deferredProcessing: (() => void) | undefined\n\tprivate _deferredProcessingRetryTimerId: number | undefined\n\n\t/** The modules revision the modules runtime in the sandbox has loaded. */\n\tmodulesRevision = -1\n\n\tconstructor(\n\t\tprivate readonly scheduler: VekterEngineScheduler,\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly selectionStore: SelectionStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly changes: EngineChanges,\n\t\tprivate readonly waitingForSync: () => boolean,\n\t) {\n\t\t// Wait for the code editor to close to process a _deferredProcessing if there is one\n\t\tchanges.observe(EngineChange.DocumentSettings, this.maybeProcessDeferredUpdate)\n\n\t\t// ModulesStore contains module revision, which is a part of pendingBundleHash.\n\t\tchanges.observe(this.modulesStore, () => this.changes.addChanges(EngineChange.PendingBundle))\n\n\t\tthis.debouncedCalculate = this.scheduler.debounce(() => {\n\t\t\tthis.treeStore.updateConnectedScreens(this.selectionStore.ids)\n\t\t\tthis.treeStore.updateVariableProviderInfo(this.selectionStore.ids)\n\t\t}, 200)\n\t}\n\n\tget activeBundleHash(): string {\n\t\treturn this.componentLoader.activeBundleHash ?? \"null\"\n\t}\n\n\tpublic get scriptErrorsByFileName(): ReadonlyMap<string, ComponentEvalError[] | undefined> {\n\t\treturn this._scriptErrorsByFileName\n\t}\n\n\t// Update arrows when external components are loaded in a debounced manner.\n\tprivate readonly debouncedCalculate: () => void\n\n\tpublic update(\n\t\tentitiesToUpdate: readonly EntityDefinition[],\n\t\tentitiesToDelete: readonly string[],\n\t\tmodulesRevision: number,\n\t\tlazyModulesRevision: number,\n\t) {\n\t\tgetLogger(\"componentLoader\").info(\"update\", entitiesToUpdate.length, entitiesToDelete.length)\n\n\t\tfor (const identifier of entitiesToDelete) {\n\t\t\tthis.componentLoader.deleteEntity(identifier)\n\t\t}\n\n\t\tfor (const entity of entitiesToUpdate) {\n\t\t\tthis.componentLoader.updateEntity(entity.identifier, entity)\n\t\t}\n\n\t\tthis.changes.addChanges(EngineChange.ActiveBundle)\n\t\tthis.componentLoader.setModuleRevision(modulesRevision, lazyModulesRevision)\n\t\tthis.treeStore.updateCodeComponents()\n\t\tthis.debouncedCalculate()\n\t}\n\n\t/**\n\t * Returns a componentDefinition for a code file\n\t *\n\t * @param file - file path relative to the projects `/code` folder\n\t */\n\tpublic componentDefinitionForFile(file: string): EntityDefinition | null {\n\t\tif (!file.startsWith(\"./\")) {\n\t\t\tfile = \"./\" + file\n\t\t}\n\n\t\tlet hasFile = false\n\t\tlet component: EntityDefinition | null = null\n\n\t\tfor (const definition of this.componentLoader.getAllEntities()) {\n\t\t\tif (definition.file === file) {\n\t\t\t\tif (definition.type !== \"component\") {\n\t\t\t\t\thasFile = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (file.endsWith(\"/\" + definition.name + \".tsx\")) {\n\t\t\t\t\t// if an exact match, always take it\n\t\t\t\t\tcomponent = definition\n\t\t\t\t} else if (!component) {\n\t\t\t\t\t// if only a match based on filename, take it if this is the first\n\t\t\t\t\tcomponent = definition\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!component && !hasFile) {\n\t\t\tcomponent = this.componentLoader.errorForIdentifier(file)\n\t\t}\n\n\t\treturn component\n\t}\n\n\tpublic updateScriptErrors(error: ComponentEvalError) {\n\t\tconst fileName = getCodeFileBaseNameFromError(error)\n\n\t\tlet scriptErrors = this._scriptErrorsByFileName.get(fileName)\n\t\tif (!scriptErrors) {\n\t\t\tscriptErrors = []\n\t\t\tthis._scriptErrorsByFileName.set(fileName, scriptErrors)\n\t\t}\n\n\t\t// ignore duplicate errors\n\t\tif (scriptErrors.find(e => e.lineNumber === error.lineNumber && e.message === error.message)) return\n\n\t\tscriptErrors.push(error)\n\t\tthis.changes.addChanges(EngineChange.ScriptErrors)\n\t}\n\n\tprivate maybeProcessDeferredUpdate = () => {\n\t\tif (!this._deferredProcessing) return\n\t\tif (this.chromeStore.mainView === ActiveMainView.CodeEditor) return\n\t\tif (this.waitingForSync()) {\n\t\t\tthis.scheduleDeferredUpdate()\n\t\t\treturn\n\t\t}\n\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tconst update = this._deferredProcessing\n\t\t\tthis._deferredProcessing = undefined\n\t\t\tif (update) update()\n\t\t})\n\t}\n\n\tprivate scheduleDeferredUpdate() {\n\t\tif (this._deferredProcessingRetryTimerId !== undefined) clearTimeout(this._deferredProcessingRetryTimerId)\n\t\tthis._deferredProcessingRetryTimerId = window.setTimeout(this.maybeProcessDeferredUpdate, 500)\n\t}\n}\n", "import type { AnyTextNode } from \"document/models/CanvasTree/nodes/utils/isAnyTextNode.ts\"\n\nexport function shouldUpdateDefaultStyle(nodes: AnyTextNode[]): boolean {\n\tif (nodes.length !== 1) return true\n\treturn !nodes[0].cache.isEditable\n}\n", "import { experiments } from \"app/experiments.ts\"\nimport type { EngineChanges } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { EnsureSync } from \"document/VekterEngine.ts\"\nimport type { RunWithFullyLoadedTreeOptions } from \"document/base-engine/BaseEngine.ts\"\nimport { shouldUpdateDefaultStyle } from \"document/components/chrome/properties/utils/styledText.ts\"\nimport { TextNode } from \"document/models/CanvasTree/index.ts\"\nimport { fontStore } from \"library/render/fonts/fontStore.ts\"\nimport type { ReadonlyFontFamily } from \"library/render/fonts/types.ts\"\nimport type { AssetStore } from \"./AssetStore.ts\"\nimport type { DocumentSettingsStore } from \"./DocumentSettingsStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport class CustomFontStore {\n\tconstructor(\n\t\tprivate assetStore: AssetStore,\n\t\tprivate treeStore: TreeStore,\n\t\tprivate documentSettings: DocumentSettingsStore,\n\t\tprivate changes: EngineChanges,\n\t\tprivate runWithFullyLoadedTree: (task: EnsureSync<VoidFunction>, options: RunWithFullyLoadedTreeOptions) => void,\n\t) {\n\t\tthis.initialize()\n\t\tthis.importFonts()\n\t}\n\n\tassetKeyToDelete: string | undefined = undefined\n\n\tgetAssetKeyFromFontFamily(fontFamily: ReadonlyFontFamily): string | undefined {\n\t\t// Get the first font from the family to look up its asset by selector\n\t\tconst firstFont = fontFamily.fonts[0]\n\t\tif (!firstFont) return undefined\n\t\treturn firstFont.assetKey\n\t}\n\n\tprivate initialize() {\n\t\tthis.changes.observe(EngineChange.AssetMap, () => {\n\t\t\tthis.importFonts()\n\t\t\tthis.changes.addChanges(EngineChange.CustomFontStore)\n\t\t})\n\t}\n\n\tprivate importFonts() {\n\t\tfontStore.importCustomFonts(this.assetStore.assetMap.items(), experiments.isOn(\"customFontGrouping\"))\n\t}\n\n\t// TODO: this does not respect any mixed fonts, see: https://github.com/framer/FramerStudio/pull/9173#issuecomment-866082339\n\tdetectMissingFonts(fontFamilies: ReadonlyFontFamily[]) {\n\t\tif (!this.treeStore.tree) return\n\n\t\tconst apply = () => {\n\t\t\tfor (const node of this.treeStore.query().whereClass(TextNode).iterate()) {\n\t\t\t\tfor (const selector of node.getFonts(false)) {\n\t\t\t\t\tif (fontFamilies.some(fontFamily => fontFamily.fonts.some(font => font.selector === selector))) {\n\t\t\t\t\t\tnode.setFont(selector, false)\n\n\t\t\t\t\t\tif (shouldUpdateDefaultStyle([node])) {\n\t\t\t\t\t\t\tthis.documentSettings.defaultTextStyle.font = selector\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.treeStore.getDataTree()) {\n\t\t\tapply()\n\t\t} else {\n\t\t\tthis.runWithFullyLoadedTree(apply, { name: \"detectMissingFonts\" })\n\t\t}\n\t}\n}\n", "import type { Space } from \"@framerjs/app-shared\"\nimport type { NavigateActionAppearsFrom, NavigateActionTransitionType } from \"@framerjs/framer-runtime\"\nimport { navigateActionDefaults } from \"@framerjs/framer-runtime\"\nimport type { LocalModuleId } from \"@framerjs/shared\"\nimport type { ErrorTags } from \"@framerjs/shared/src/logger.ts\"\nimport type { EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { WithLinkStyle } from \"document/models/CanvasTree/traits/WithLinkStyle.ts\"\nimport { linkStyleDefaults } from \"document/models/CanvasTree/traits/WithLinkStyle.ts\"\nimport type { LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type {\n\tFontSizeCSSDimension,\n\tLetterSpacing,\n\tWithTextStyle,\n} from \"document/models/CanvasTree/traits/WithTextStyle.ts\"\nimport { textStyleDefaults } from \"document/models/CanvasTree/traits/WithTextStyle.ts\"\nimport type * as monaco from \"monaco-editor\"\nimport type { ViewStateManager } from \"utils/monaco-editor/viewStateManager.ts\"\nimport { isFramerEmployee } from \"web/lib/isFramerEmployee.ts\"\n\nexport interface ActiveNode {\n\tid: string\n\tlocaleId?: LocaleId\n\t/** Whether the active node is set through deep-linking */\n\tdeepLinked?: boolean\n}\n\nexport interface CrashData {\n\tmessage: string\n\terrorRef: string\n\ttags: ErrorTags\n\tstack: string | undefined\n\tsentryErrorId: string | undefined\n}\n\n/**\n * Manages default properties for the current user session.\n */\nexport class DocumentSettingsStore implements ViewStateManager {\n\t// FIXME: these properties need to find a better place, they don't have listeners\n\tdefaultTextStyle: Pick<WithTextStyle, \"textColor\" | \"lineHeight\"> & {\n\t\tfontSize: FontSizeCSSDimension\n\t\tletterSpacing: LetterSpacing\n\t\tfont: string\n\t} & WithLinkStyle = {\n\t\tfont: textStyleDefaults.font,\n\t\ttextColor: textStyleDefaults.textColor,\n\t\tfontSize: textStyleDefaults.fontSize,\n\t\tletterSpacing: textStyleDefaults.letterSpacing,\n\t\tlineHeight: textStyleDefaults.lineHeight,\n\t\t...linkStyleDefaults,\n\t\tlinkTextDecoration: \"underline\",\n\t\tlinkTextColor: \"#09F\",\n\t}\n\tdefaultTransition: NavigateActionTransitionType = navigateActionDefaults.transition\n\tdefaultAppearsFrom: NavigateActionAppearsFrom = navigateActionDefaults.appearsFrom\n\tlastDuplicationMap: Map<NodeID, NodeID> | null = null\n\tisNewlyCreatedProject = false\n\n\tconstructor(private addChanges: EngineChangeSignal) {}\n\n\tprivate _activeNode: ActiveNode | null = null\n\n\tget activeNode() {\n\t\treturn this._activeNode\n\t}\n\n\tset activeNode(value: ActiveNode | null) {\n\t\tif (value?.id === this._activeNode?.id) return\n\t\tthis._activeNode = value\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\t#hasDarkAppearance = false\n\n\t/** @deprecated Use `useDarkMode` instead. */\n\tget hasDarkAppearance() {\n\t\treturn this.#hasDarkAppearance\n\t}\n\n\t/**\n\t * @deprecated This should only be used inside `EditorContainer.tsx`. Use\n\t * `useDarkMode` to change the theme instead.\n\t */\n\tsyncDarkAppearance(hasDarkAppearance: boolean) {\n\t\tif (this.#hasDarkAppearance === hasDarkAppearance) return\n\t\tthis.#hasDarkAppearance = hasDarkAppearance\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\t// Crash message\n\n\tprivate _crashData: CrashData | null = null\n\n\tget crashData() {\n\t\treturn this._crashData\n\t}\n\n\tset crashData(value) {\n\t\tif (this._crashData === value) return\n\t\tthis._crashData = value\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\tprivate _spaces: Space[] | null = null\n\n\tget spaces() {\n\t\treturn this._spaces\n\t}\n\n\tset spaces(value: Space[] | null) {\n\t\tif (this._spaces === value) return\n\t\tthis._spaces = value\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\t// Current User Info\n\tprivate _currentUserId: string | null = null\n\n\tget currentUserId() {\n\t\treturn this._currentUserId\n\t}\n\n\tset currentUserId(value: string | null) {\n\t\tif (this._currentUserId === value) return\n\t\tthis._currentUserId = value\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\tprivate _currentUserEmail: string | null = null\n\n\tget currentUserEmail() {\n\t\treturn this._currentUserEmail\n\t}\n\n\tset currentUserEmail(value: string | null) {\n\t\tif (this._currentUserEmail === value) return\n\t\tthis._currentUserEmail = value\n\t\tthis.addChanges(EngineChange.DocumentSettings)\n\t}\n\n\t// TODO: Get the current user session and use its isFramerEmployee property.\n\tget isFramerTeam(): boolean {\n\t\tif (!this._currentUserEmail) return false\n\t\treturn isFramerEmployee(this._currentUserEmail)\n\t}\n\n\t// Editor Settings\n\n\tprivate editorViewStates: Map<LocalModuleId, monaco.editor.ICodeEditorViewState> = new Map()\n\taddEditorViewState(localId: LocalModuleId, fileState: monaco.editor.ICodeEditorViewState | null) {\n\t\tif (!fileState) {\n\t\t\treturn\n\t\t}\n\t\tthis.editorViewStates.set(localId, fileState)\n\t}\n\n\tgetEditorViewState(localId: LocalModuleId): monaco.editor.ICodeEditorViewState | undefined {\n\t\treturn this.editorViewStates.get(localId)\n\t}\n}\n", "import type { Anchor, ApiComment, ApiThread, Mention, Thread } from \"feedback/types.ts\"\nimport type { Team, TeamMember } from \"web/lib/TeamSettings.ts\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\n\nexport async function getThreads(\n\tprojectId: string,\n\t{ archived = false } = {},\n): Promise<Readonly<{ threads: readonly ApiThread[] }>> {\n\treturn apiFetcher.get(`/web/projects/${projectId}/threads/?archived=${archived ? \"true\" : \"false\"}`)\n}\nexport async function createThread(\n\tprojectId: string,\n\tbody: { anchor: Anchor; text: string; mentions: Mention[] },\n): Promise<ApiThread> {\n\treturn apiFetcher.post(`/web/projects/${projectId}/threads/`, body)\n}\nexport async function updateThread(projectId: string, body: { id: string } & Partial<Thread>): Promise<ApiThread> {\n\tconst { id, ...rest } = body\n\treturn apiFetcher.post(`/web/projects/${projectId}/threads/${id}`, rest)\n}\nexport async function deleteThread(\n\tprojectId: string,\n\t{ threadId, ...body }: { threadId: string; deletedBy: string },\n): Promise<ApiThread> {\n\treturn apiFetcher.delete(`/web/projects/${projectId}/threads/${threadId}`, body)\n}\nexport async function markAsSeen(\n\tprojectId: string,\n\t{ threadId, ...body }: { threadId: string; lastSeenCommentId: string },\n): Promise<ApiThread> {\n\treturn apiFetcher.post(`/web/projects/${projectId}/threads/${threadId}/seen`, body)\n}\nexport async function createComment(\n\tprojectId: string,\n\t{ threadId, ...body }: { threadId: string; text: string; mentions: Mention[] },\n): Promise<ApiComment> {\n\treturn apiFetcher.post(`/web/projects/${projectId}/threads/${threadId}/comments/`, body)\n}\nexport async function updateComment(\n\tprojectId: string,\n\tbody: { id: string; threadId: string; text: string; mentions: Mention[] },\n): Promise<ApiComment> {\n\tconst { id, threadId, text, mentions } = body\n\treturn apiFetcher.post(`/web/projects/${projectId}/threads/${threadId}/comments/${id}`, { text, mentions })\n}\nexport async function deleteComment(projectId: string, body: { id: string; threadId: string }): Promise<ApiComment> {\n\tconst { id, threadId } = body\n\treturn apiFetcher.delete(`/web/projects/${projectId}/threads/${threadId}/comments/${id}`)\n}\n// TODO: build new endpoint to only fetch team members\nexport async function fetchTeam(teamId: string): Promise<TeamMember[]> {\n\tconst team: Team = await apiFetcher.get(`/account/teams/${teamId}`)\n\treturn team.members\n}\n", "import { experiments } from \"app/experiments.ts\"\nimport type { EngineStores } from \"document/EngineStores.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport type { Rect } from \"library/render/types/Rect.ts\"\nimport { anchorToPoint, anchorToScope } from \"./anchorUtils.ts\"\nimport { isDraftThread } from \"./model.ts\"\nimport type { Anchor, Thread } from \"./types.ts\"\n\n/**\n * Returns a point to scroll the canvas to for the given anchor.\n *\n * This isn't always the anchor point itself. For comments anchored to a node,\n * this might be the center point of the node, if the node fits on the canvas in\n * its entirety.\n */\nfunction scrollPointForAnchor(tree: CanvasTree, anchor: Anchor, willFitOnCanvas: (rect: Rect) => boolean) {\n\tconst anchorPoint = anchorToPoint(tree, anchor)\n\n\tif (anchor.type !== \"node\") {\n\t\treturn anchorPoint\n\t}\n\n\tconst node = tree.getNode(anchor.nodeId)\n\tif (!node) {\n\t\treturn anchorPoint\n\t}\n\n\tconst nodeRect = node.rect()\n\tif (!willFitOnCanvas(nodeRect)) {\n\t\treturn anchorPoint\n\t}\n\n\tconst nodeCenterRelativeToNode = { x: nodeRect.width / 2, y: nodeRect.height / 2 }\n\tconst nodeCenterRelativeToCanvas = tree.convertPointToCanvas(node, nodeCenterRelativeToNode)\n\treturn Point.pixelAligned(nodeCenterRelativeToCanvas)\n}\n\n/**\n * Scrolls and zooms the canvas on the given anchor. (Or the anchor's node.)\n *\n * Under the agent experiment the zoom level is preserved \u2014 only the scroll\n * position changes \u2014 because threads are selected by clicking pins directly.\n */\nfunction scrollCanvasToAnchor({ canvasStore, scopeStore, treeStore }: EngineStores, anchor: Anchor) {\n\tconst isAgent = experiments.isOn(\"agent\")\n\n\tconst pageForAnchor = anchorToScope(treeStore.tree, anchor)\n\tscopeStore.select(pageForAnchor, { keepHistory: false })\n\n\tconst visibleCanvas = canvasStore.getCanvasVisibleRectTakingOverlaysIntoAccount()\n\n\tif (isAgent) {\n\t\tconst willFitOnCanvas = (rect: Rect) => rect.width <= visibleCanvas.width && rect.height <= visibleCanvas.height\n\t\tconst scrollPoint = scrollPointForAnchor(treeStore.tree, anchor, willFitOnCanvas)\n\t\tcanvasStore.scrollToCenter(scrollPoint)\n\t} else {\n\t\tconst newZoom = 1\n\t\tconst zoomChange = canvasStore.zoom / newZoom\n\t\tconst postZoomCanvasWidth = visibleCanvas.width * zoomChange\n\t\tconst postZoomCanvasHeight = visibleCanvas.height * zoomChange\n\t\tconst willFitOnCanvas = (rect: Rect) => rect.width <= postZoomCanvasWidth && rect.height <= postZoomCanvasHeight\n\t\tconst scrollPoint = scrollPointForAnchor(treeStore.tree, anchor, willFitOnCanvas)\n\t\tcanvasStore.scrollToCenter(scrollPoint, { zoom: newZoom, animate: true })\n\t}\n}\n\nexport type SelectedThreadViewportUpdater = (\n\tfeedbackState: {\n\t\tselectedThread: Thread | undefined\n\t\tthreadIdUnderMouse: string | undefined\n\t},\n\tonViewportNeedsUpdate: (anchor: Anchor) => void,\n) => void\n\n/**\n * Creates a function that takes in current feedback state relevant to thread\n * selection, and notifies the callback if the viewport needs to be updated to\n * focus on the given anchor.\n */\nexport function createSelectedThreadViewportUpdater(): SelectedThreadViewportUpdater {\n\tlet previousSelectedThreadId: string | undefined\n\n\tconst handleUpdate = (\n\t\t{\n\t\t\tselectedThread,\n\t\t\tthreadIdUnderMouse,\n\t\t}: {\n\t\t\tselectedThread: Thread | undefined\n\t\t\tthreadIdUnderMouse: string | undefined\n\t\t},\n\t\tonViewportNeedsUpdate: (anchor: Anchor) => void,\n\t) => {\n\t\tif (selectedThread) {\n\t\t\tconst didSelectThread = selectedThread.id !== previousSelectedThreadId\n\t\t\tconst selectedViaAnchorClick = threadIdUnderMouse === selectedThread.id\n\n\t\t\tif (didSelectThread && !selectedViaAnchorClick && !isDraftThread(selectedThread.id)) {\n\t\t\t\tonViewportNeedsUpdate(selectedThread.anchor)\n\t\t\t}\n\t\t}\n\t\tpreviousSelectedThreadId = selectedThread && selectedThread.id\n\t}\n\n\treturn handleUpdate\n}\n\n/**\n * Installs an observer on the Vekter engine to keep the canvas focused on the\n * currently-selected thread.\n */\nexport function installSelectedThreadViewportUpdater(engine: VekterEngine) {\n\tconst handleUpdate = createSelectedThreadViewportUpdater()\n\tengine.scheduler.changes.observe(engine.stores.feedbackStore, () => {\n\t\tconst { selectedThread, threadIdUnderMouse } = engine.stores.feedbackStore\n\t\thandleUpdate({ selectedThread, threadIdUnderMouse }, anchor => {\n\t\t\t// Scrolling the canvas makes it non-interactive, which prevents\n\t\t\t// renders, so do it after everything else had a chance to render.\n\t\t\t//\n\t\t\t// XXX: This doesn't fix all of the \"Canvas is live (non-interactive)\n\t\t\t// and should not cause re-renders\" errors/warnings a project via\n\t\t\t// comment permalink => I guess there must be more renders happening\n\t\t\t// in subsequent frames? But it still goes down from ~10 errors to ~2.\n\t\t\tengine.scheduler.runAtEndOfFrame(() => scrollCanvasToAnchor(engine.stores, anchor))\n\t\t})\n\t})\n}\n", "import type { UserNotifications } from \"@framerjs/framer-services\"\nimport type { Comment } from \"./types.ts\"\n\nexport function createUnreadCommentNotification(threadId: string, comment: Comment): UserNotifications.Notification {\n\treturn {\n\t\tid: `unread-comment-${comment.id}`,\n\t\ttitle: `New comment from ${comment.author.name}`,\n\t\tbody: comment.text,\n\t\tshow: \"backgrounded\",\n\t}\n}\n\nexport function createUnreadSummaryNotification(unreadCount: number): UserNotifications.Notification {\n\treturn {\n\t\tid: \"unread-comments-summary\",\n\t\ttitle: unreadCount === 1 ? `You have ${unreadCount} new comments` : \"You have 1 new comment\",\n\t\tshow: \"backgrounded\",\n\t}\n}\n\nexport class CommentNotificationsTracker {\n\tprivate notifiedCommentIds = new Set<string>()\n\n\tpublic wasNotified(commentId: string) {\n\t\treturn this.notifiedCommentIds.has(commentId)\n\t}\n\n\tpublic markNotified(commentId: string) {\n\t\tthis.notifiedCommentIds.add(commentId)\n\t}\n}\n", "import type { Comment, CommentMetadataMap, Thread } from \"./types.ts\"\n\n/** Returns the time of the most recent comment on the thread, 0 if empty */\nexport function getThreadTimestamp({ comments }: { comments: readonly Comment[] }): number {\n\tconst lastComment = comments[comments.length - 1]\n\treturn lastComment?.createdAt.getTime() || 0\n}\n\nexport function getThreadPermalink(\n\t{ threadId, commentId }: { threadId: string; commentId?: string },\n\t{ href }: { href: string } = typeof window !== \"undefined\" ? window.top!.location : { href: \"\" },\n): string {\n\tconst permalink = new URL(href)\n\tconst token = commentId ? `${threadId}:${commentId}` : threadId\n\tpermalink.searchParams.set(\"t\", token)\n\treturn permalink.toString()\n}\n\n/**\n * Returns true if there are unread comments in the thread (ignoring\n * any updates to the comments). Assumes all comments are sorted in\n * ascending order by createdAt date.\n */\nexport function isUnread({\n\tseenUntil,\n\tcomments,\n}: {\n\tseenUntil: Date | undefined\n\tcomments: readonly Comment[]\n}): boolean {\n\tif (!seenUntil) return true\n\tconst timestamp = getThreadTimestamp({ comments })\n\treturn timestamp > seenUntil.getTime()\n}\n\nexport function getUnreadCommentsForThread(\n\t{ seenUntil, comments }: { seenUntil: Date | undefined; comments: readonly Comment[] },\n\toptions?: { createdAfter?: Date },\n): Comment[] {\n\tconst unreadFilter = seenUntil ? (comment: Comment) => comment.createdAt > seenUntil : () => true\n\n\tconst createdAfter = options?.createdAfter\n\tconst createdAfterFilter = createdAfter ? (comment: Comment) => comment.createdAt > createdAfter : () => true\n\n\treturn comments.filter(c => unreadFilter(c) && createdAfterFilter(c))\n}\n\nexport function getUnreadCommentsForThreads(\n\tthreads: readonly Thread[],\n\toptions?: { createdAfter?: Date },\n): { threadId: string; comment: Comment }[] {\n\tconst createdAfter = options?.createdAfter\n\treturn threads.reduce((unreadComments, thread) => {\n\t\tconst unreadCommentsForThread = getUnreadCommentsForThread(thread, { createdAfter })\n\t\tfor (const comment of unreadCommentsForThread) {\n\t\t\tunreadComments.push({ threadId: thread.id, comment: comment })\n\t\t}\n\t\treturn unreadComments\n\t}, new Array<{ threadId: string; comment: Comment }>())\n}\n\nexport function isEditing(comment: Comment, commentMetadata: CommentMetadataMap) {\n\tconst metadata = commentMetadata.get(comment.id)\n\treturn metadata?.isEditing\n}\n\nexport function hasSendError(comment: Comment, commentMetadata: CommentMetadataMap) {\n\tconst metadata = commentMetadata.get(comment.id)\n\treturn metadata?.hasSendError\n}\n\n/** Query String in the form \"<threadId>:<commentId>\" used to launch a specific thread */\nconst ThreadQueryParam = \"t\"\n\nexport function getThreadFromURL(\n\tlocation: Location = window.location,\n): { threadId: string; commentId?: string } | null {\n\tconst query = new URLSearchParams(location.search)\n\tconst param = query.get(ThreadQueryParam)\n\tif (param) {\n\t\tconst [threadId, commentId] = param.split(\":\")\n\t\treturn { threadId, commentId }\n\t}\n\treturn null\n}\n", "import type { InviteACLEntry, UserACLEntry } from \"@framerjs/app-shared\"\nimport { ACLEntryKind } from \"@framerjs/app-shared\"\nimport { UserNotifications, UserSessionService, handleServiceError, localChannel } from \"@framerjs/framer-services\"\nimport { assert, getLogger, unhandledError } from \"@framerjs/shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { environment } from \"environment/index.ts\"\nimport {\n\tcreateComment,\n\tcreateThread,\n\tdeleteComment,\n\tdeleteThread,\n\tfetchTeam,\n\tgetThreads,\n\tmarkAsSeen,\n\tupdateComment,\n\tupdateThread,\n} from \"feedback/api.ts\"\nimport { installSelectedThreadViewportUpdater } from \"feedback/canvasUtils.ts\"\nimport {\n\tcreateDraftThread,\n\tfromServiceComment,\n\tfromServiceThread,\n\tisDraftThread,\n\tisLocalId,\n\tlocalId,\n} from \"feedback/model.ts\"\nimport {\n\tCommentNotificationsTracker,\n\tcreateUnreadCommentNotification,\n\tcreateUnreadSummaryNotification,\n} from \"feedback/notificationUtils.ts\"\nimport type {\n\tAnchor,\n\tComment,\n\tCommentMetadataMap,\n\tMention,\n\tMentionableUser,\n\tSelectionState,\n\tThread,\n\tUser,\n} from \"feedback/types.ts\"\nimport { Tab } from \"feedback/types.ts\"\nimport { getThreadTimestamp, getUnreadCommentsForThreads, isUnread } from \"feedback/utils.ts\"\nimport { Map as ImmutableMap, List } from \"immutable\"\nimport { isEqual } from \"library/index.ts\"\nimport type { TeamMember } from \"web/lib/TeamSettings.ts\"\nimport type { VekterEngine } from \"../VekterEngine.ts\"\nimport { DataStore } from \"../utils/DataStore.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { ProjectStore } from \"./ProjectStore.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { ToolStore } from \"./ToolStore.ts\"\n\nconst log = getLogger(\"FeedbackStore\")\n\n// For pre-loaded archived threads.\nconst EmptyList: readonly Thread[] = []\n\nclass ThreadNotFoundError extends Error {}\n\nexport class FeedbackStore extends EngineStore {\n\tprivate userSessionService: Promise<UserSessionService.Interface | undefined>\n\tprivate userNotifications: Promise<UserNotifications.Interface | undefined>\n\tprivate pollTimerId: ReturnType<Window[\"setTimeout\"]> | null = null\n\n\t// Time intervals for feedback polling\n\tprivate readonly pollInterval = {\n\t\t/** When Feedback is closed */\n\t\tIdle: 120 * 1000,\n\t\t/** When Feedback is active */\n\t\tActive: 5 * 1000,\n\t\t/** When a thread is open */\n\t\tThread: 1000,\n\t}\n\n\tconstructor(\n\t\tprivate readonly toolStore: ToolStore,\n\t\tprivate readonly selectionStore: SelectionStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly withTestMocks: boolean = false,\n\t) {\n\t\tsuper()\n\t\tif (!(environment.isAutomation || environment.isTest) || this.withTestMocks) {\n\t\t\tthis.userNotifications = UserNotifications.on(localChannel).discover().catch(handleServiceError)\n\t\t\tthis.userSessionService = UserSessionService.on(localChannel).discover().catch(handleServiceError)\n\t\t} else {\n\t\t\tthis.userNotifications = Promise.resolve(undefined)\n\t\t\tthis.userSessionService = Promise.resolve(undefined)\n\t\t}\n\n\t\tconst initialMap = ImmutableMap<string, Thread>()\n\t\tthis.threadMap = new DataStore(initialMap, _info => {\n\t\t\t// This handles the async transaction commits which all need to be\n\t\t\t// processed by the engine.\n\t\t\tvoid this.scheduler.processWhenReadyAsync(() => {\n\t\t\t\tthis.generateDerivedData()\n\n\t\t\t\tthis.hasUnreadFeedback = this.checkUnreadFeedback()\n\n\t\t\t\tthis.postUnreadNotifications().catch(unhandledError)\n\t\t\t})\n\t\t})\n\t\tthis.generateDerivedData()\n\t\tthis._hasUnreadFeedback = this.checkUnreadFeedback()\n\t\tthis._lastAclReference = this.projectStore.acl\n\t}\n\n\t// Track ACL and members changes for mentionable users cache invalidation\n\tprivate _lastAclReference: (UserACLEntry | InviteACLEntry)[]\n\tprivate _lastTeamMembersReference: TeamMember[] | null = null\n\tprivate _cachedMentionableUsers: readonly MentionableUser[] = []\n\tprivate setMentionableUsers() {\n\t\tconst currentAcl = this.projectStore.acl\n\t\tconst currentTeamMembers = this._teamMembers\n\n\t\tconst aclChanged = this._lastAclReference !== currentAcl\n\t\tconst teamMembersChanged = this._lastTeamMembersReference !== currentTeamMembers\n\t\tif (aclChanged || teamMembersChanged || this._cachedMentionableUsers.length === 0) {\n\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\tthis._cachedMentionableUsers = getMentionableUsers(currentAcl, currentTeamMembers)\n\t\t\t\tthis._lastAclReference = currentAcl\n\t\t\t\tthis._lastTeamMembersReference = currentTeamMembers\n\t\t\t})\n\t\t}\n\t}\n\n\tget mentionableUsers(): readonly MentionableUser[] {\n\t\treturn this._cachedMentionableUsers\n\t}\n\n\tsetFeedbackModeActive(active: boolean) {\n\t\tif (this.toolStore.feedbackModeActive === active) return\n\t\tthis.toolStore.feedbackModeActive = active\n\t\tthis.handleFeedbackModeChange()\n\n\t\tif (active) {\n\t\t\tthis.chromeStore.layersExpanded = true\n\t\t\tthis.chromeStore.chromeIsVisible = true\n\t\t\t// In feedback mode, selection is following the frame that the\n\t\t\t// currently-viewed thread is anchored to, so let's clear current\n\t\t\t// selection.\n\t\t\tthis.selectionStore.clear()\n\t\t\tthis.setMentionableUsers()\n\t\t} else {\n\t\t\tthis.clearSelectedThread().catch(unhandledError)\n\t\t}\n\t}\n\n\tprivate didFetchInitialThreads = false\n\tprivate isDocumentLoaded = false\n\tprivate isCanvasSandboxLoaded = false\n\n\tprivate _teamMembers: TeamMember[] = []\n\n\tasync initialize(engine: VekterEngine) {\n\t\t// Was platform.isOn(\"supportsFeedback\")\n\t\tif (environment.isAutomation) return\n\t\tconst project = await this.projectStore.getProject()\n\t\tconst projectId = project.id\n\n\t\tconst [{ threads }, { user }] = await Promise.all([\n\t\t\tgetThreads(projectId, { archived: false }),\n\t\t\tthis.userSessionService.then(async service => {\n\t\t\t\tif (!service) return { user: undefined }\n\t\t\t\treturn service.getSessionIdentity()\n\t\t\t}),\n\t\t])\n\t\tlet teamMembers: TeamMember[] = []\n\t\tif (project.space?.scope === \"organization\") {\n\t\t\ttry {\n\t\t\t\tteamMembers = await fetchTeam(project.space.ownerId)\n\t\t\t} catch {\n\t\t\t\t// Ignore errors, we always want mentions and commenting to work.\n\t\t\t\t// There's even a valid state for this failing: the requesting user is not a member of the team.\n\t\t\t\t// @TODO: consider adding a flag to the project to indicate that the user is not a member of the team.\n\t\t\t}\n\t\t}\n\n\t\t// We need to register the updateThreads call with the engine.\n\t\tawait this.scheduler.processWhenReadyAsync(() => {\n\t\t\tthis.updateThreads(threads.map(fromServiceThread))\n\t\t\tthis._currentUser = user\n\t\t\tthis._teamMembers = teamMembers\n\t\t\tthis.startPolling()\n\t\t})\n\n\t\tthis.didFetchInitialThreads = true\n\t\tthis.maybeFinishInitializing(engine)\n\t}\n\n\tasync openThread(threadId: string, commentId?: string): Promise<void> {\n\t\ttry {\n\t\t\tawait this.setSelectedThread(threadId, commentId)\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof ThreadNotFoundError)) {\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tif (!this._hasArchiveLoaded) {\n\t\t\t\t// The thread may have been archived, load the archive and\n\t\t\t\t// re-try.\n\t\t\t\tawait this.loadArchivedThreads()\n\t\t\t\t// Before we re-try, make sure we're not gonna go into an\n\t\t\t\t// infinite loop in case loadArchivedThreads didn't set the\n\t\t\t\t// _hasArchivedLoaded flag.\n\t\t\t\tassert(this._hasArchiveLoaded)\n\t\t\t\tawait this.openThread(threadId, commentId)\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\t// Didn't find the thread, not even in the archive. No reason to\n\t\t\t\t// crash the app, maybe the query param got mangled?\n\t\t\t\tlog.warn(error)\n\t\t\t}\n\t\t}\n\t\tthis.setFeedbackModeActive(true)\n\t}\n\n\tprivate async openAllThreads() {\n\t\tawait this.setSelectedSidebarTab(Tab.All)\n\t\tawait this.clearSelectedThread()\n\t\tthis.setFeedbackModeActive(true)\n\t}\n\n\tdocumentDidLoad(engine: VekterEngine) {\n\t\tthis.isDocumentLoaded = true\n\t\tthis.maybeFinishInitializing(engine)\n\t}\n\n\tcanvasSandboxDidLoad(engine: VekterEngine) {\n\t\tthis.isCanvasSandboxLoaded = true\n\t\tthis.maybeFinishInitializing(engine)\n\t}\n\n\tprivate maybeFinishInitializing(engine: VekterEngine) {\n\t\t// Was platform.isOn(\"supportsFeedback\")\n\t\tif (environment.isAutomation || environment.isTest) return\n\t\tif (!this.didFetchInitialThreads || !this.isDocumentLoaded || !this.isCanvasSandboxLoaded) return\n\n\t\tinstallSelectedThreadViewportUpdater(engine)\n\t}\n\n\thandleFeedbackModeChange() {\n\t\tthis.startPolling()\n\t}\n\n\t/**\n\t * Called by VekterEngine during interactive post processing as a way\n\t * to update the currently highlighted frame.\n\t */\n\tpostProcess(setHighlight: (id: string | null) => void): void {\n\t\tconst { selectedThread } = this\n\t\tconst highlightNodeId =\n\t\t\tselectedThread && selectedThread.anchor.type === \"node\" ? selectedThread.anchor.nodeId : null\n\t\tsetHighlight(highlightNodeId)\n\t}\n\n\t/**\n\t * Stores two representations of the Thread data, a \"remote\" version that\n\t * represents the current server state and a \"local\" version. Only\n\t * the local version can be accessed via the interface and the\n\t * remote version can be periodically updated via the\n\t * `updateRemote()` method. Local transformations can be registered\n\t * to be applied to the server data to create the local\n\t * representation.\n\t */\n\tprivate threadMap: DataStore<ImmutableMap<string, Thread>>\n\n\tprivate _derivedData: {\n\t\tthreads: readonly Thread[]\n\t\tarchived: readonly Thread[]\n\t\tframesWithThreads: ReadonlySet<string>\n\t} = {\n\t\tthreads: [],\n\t\tarchived: [],\n\t\tframesWithThreads: new Set(),\n\t}\n\tprivate _hasArchiveLoaded = false\n\tprivate _draftThread: Thread | undefined\n\tprivate _currentUser: User | undefined\n\tprivate _selectionState: SelectionState = {\n\t\ttab: Tab.All,\n\t\tthreadId: undefined,\n\t\tcommentId: undefined,\n\t\tseenUntil: undefined,\n\t}\n\tprivate _commentMetadata: CommentMetadataMap = ImmutableMap()\n\n\tignoreNextClick: boolean = false\n\n\tget commentMetadata(): CommentMetadataMap {\n\t\treturn this._commentMetadata\n\t}\n\n\tget selectionState(): Readonly<SelectionState> {\n\t\treturn this._selectionState\n\t}\n\n\tasync setSelectedSidebarTab(tab: Tab) {\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tif (this._selectionState.tab !== tab) {\n\t\t\t\tthis._selectionState = { ...this._selectionState, tab }\n\t\t\t}\n\t\t})\n\t}\n\n\tget currentUser(): User | undefined {\n\t\treturn this._currentUser\n\t}\n\n\tgetThread(id: string): Thread | undefined {\n\t\tif (isDraftThread(id) && this.draftThread) {\n\t\t\treturn this.draftThread\n\t\t}\n\t\treturn this.threadMap.get(id, undefined)\n\t}\n\n\tget selectedThreadId(): string | undefined {\n\t\treturn this._selectionState.threadId\n\t}\n\n\tget selectedThread(): Thread | undefined {\n\t\tif (!this._selectionState.threadId) return undefined\n\t\treturn this.getThread(this._selectionState.threadId)\n\t}\n\n\tasync setSelectedThread(threadId: string, commentId?: string) {\n\t\tif (this.selectedThreadId === threadId) return\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tconst previousThread = this.selectedThread\n\t\t\tif (previousThread && isDraftThread(previousThread.id)) {\n\t\t\t\tthis._draftThread = undefined\n\t\t\t}\n\n\t\t\tconst nextThread = this.getThread(threadId)\n\t\t\tif (!nextThread) throw new ThreadNotFoundError(`Cannot find thread with id: ${threadId}`)\n\n\t\t\tthis._selectionState = {\n\t\t\t\t...this._selectionState,\n\t\t\t\tthreadId,\n\t\t\t\tcommentId: commentId || undefined,\n\t\t\t\tseenUntil: nextThread.seenUntil,\n\t\t\t}\n\n\t\t\tif (threadId) {\n\t\t\t\tthis.updateSelectedTab(threadId)\n\t\t\t}\n\n\t\t\tif (threadId && isUnread(nextThread)) {\n\t\t\t\tthis.markThreadAsSeen(threadId).catch(unhandledError)\n\t\t\t}\n\n\t\t\tthis.startPolling()\n\n\t\t\t// When a thread is opened (likely to reply), refresh mentionable users\n\t\t\tthis.setMentionableUsers()\n\t\t})\n\t}\n\n\tprivate updateSelectedTab(threadId: string) {\n\t\tconst thread = this.getThread(threadId)\n\t\tconst currentTab = this._selectionState.tab\n\n\t\tif (!thread && !this._hasArchiveLoaded) {\n\t\t\t// Archived threads are not yet loaded, this often happens on\n\t\t\t// first load when a permalink points to an archived thread.\n\t\t\tthis.loadArchivedThreads()\n\t\t\t\t.then(() => {\n\t\t\t\t\tif (this.selectedThreadId === threadId && currentTab === this._selectionState.tab) {\n\t\t\t\t\t\tthis.updateSelectedTab(threadId)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(unhandledError)\n\t\t} else if (thread && !thread.archived && currentTab === Tab.Archived) {\n\t\t\tthis._selectionState = { ...this._selectionState, tab: Tab.All }\n\t\t} else if (thread && thread.archived && currentTab !== Tab.Archived) {\n\t\t\tthis._selectionState = { ...this._selectionState, tab: Tab.Archived }\n\t\t}\n\t}\n\n\tasync clearSelectedThread() {\n\t\tif (!this.selectedThreadId) return\n\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tthis._selectionState = {\n\t\t\t\t...this._selectionState,\n\t\t\t\tthreadId: undefined,\n\t\t\t\tcommentId: undefined,\n\t\t\t}\n\t\t\tthis._threadIdUnderMouse = undefined\n\n\t\t\tif (this.draftThread) {\n\t\t\t\tthis._draftThread = undefined\n\t\t\t}\n\n\t\t\tthis.startPolling()\n\t\t})\n\t}\n\n\tasync loadArchivedThreads() {\n\t\tconst projectId = this.projectStore.projectId\n\n\t\tconst { threads } = await getThreads(projectId, { archived: true })\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tthis._hasArchiveLoaded = true\n\t\t\tthis.updateThreads(threads.map(fromServiceThread))\n\t\t})\n\t}\n\n\tcreateDraftThread(anchor: Anchor): void {\n\t\tthis._draftThread = createDraftThread({ anchor })\n\t\tthis._selectionState = { ...this._selectionState, threadId: this._draftThread.id }\n\t\t// Ensure mentionable users are fresh when user starts a new comment\n\t\tthis.setMentionableUsers()\n\t}\n\n\tasync markThreadAsSeen(threadId: string) {\n\t\tif (isDraftThread(threadId) || isLocalId(threadId)) return\n\n\t\t// Optimistic update:\n\t\tconst thread = this.getThread(threadId)\n\t\tif (!thread) return\n\n\t\tconst lastComment = thread.comments[thread.comments.length - 1]\n\t\tif (!lastComment) return\n\t\tconst { createdAt: seenUntil, id: lastSeenCommentId } = lastComment\n\n\t\tawait this.threadMap.beginTransaction(threadId, {\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\tconst updatedThread = await markAsSeen(projectId, {\n\t\t\t\t\tthreadId,\n\t\t\t\t\tlastSeenCommentId,\n\t\t\t\t})\n\t\t\t\treturn prev => latestThread(prev, fromServiceThread(updatedThread))\n\t\t\t},\n\t\t\toptimistic: prev => ({ ...prev, seenUntil }),\n\t\t})\n\t}\n\n\tcreateComment({\n\t\tthreadId,\n\t\ttext,\n\t\tmentions,\n\t}: {\n\t\tthreadId: string\n\t\ttext: string\n\t\tmentions: Mention[]\n\t}): Promise<{ thread: Thread; comment: Comment }> {\n\t\tconst thread = this.getThread(threadId)\n\t\tconst author = this.currentUser\n\t\tif (!author) {\n\t\t\tthrow new Error(`Current user not defined`)\n\t\t}\n\t\tif (!thread) {\n\t\t\tthrow new Error(`Unable to find thread in store: ${threadId}`)\n\t\t}\n\n\t\t// TODO: We need better handling of this in the UI.\n\t\tif (isLocalId(thread.id)) {\n\t\t\tthrow new Error(\"Attempting to add a comment to a local thread\")\n\t\t}\n\n\t\tif (isDraftThread(thread.id)) {\n\t\t\tthis._draftThread = undefined\n\t\t\treturn this.createThread({ anchor: thread.anchor, author, text, mentions })\n\t\t}\n\n\t\treturn this.addCommentToThread({ thread, author, text, mentions })\n\t}\n\n\tprivate async createThread({\n\t\tauthor,\n\t\tanchor,\n\t\ttext,\n\t\tmentions,\n\t}: {\n\t\tauthor: User\n\t\tanchor: Anchor\n\t\ttext: string\n\t\tmentions: Mention[]\n\t}): Promise<{ thread: Thread; comment: Comment }> {\n\t\tconst isAgent = experiments.isOn(\"agent\")\n\n\t\t// Only clear selection for non-agent; agent keeps selection on the draft/local thread\n\t\tif (!isAgent) this._selectionState = { ...this._selectionState, threadId: undefined }\n\n\t\tconst localThreadId = localId()\n\t\tconst localCommentId = localId()\n\t\tconst localCreatedAt = new Date()\n\n\t\tlet createdThreadId = \"\"\n\n\t\tif (isAgent) {\n\t\t\tthis._selectionState = { ...this._selectionState, threadId: localThreadId }\n\t\t\tthis._threadIdUnderMouse = localThreadId\n\t\t}\n\n\t\tawait this.threadMap.beginTransaction({\n\t\t\toptimistic: prev =>\n\t\t\t\tprev.set(localThreadId, {\n\t\t\t\t\tid: localThreadId,\n\t\t\t\t\tanchor: anchor,\n\t\t\t\t\tarchived: false,\n\t\t\t\t\tupdatedAt: undefined,\n\t\t\t\t\tseenUntil: localCreatedAt,\n\t\t\t\t\tcomments: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: localCommentId,\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\tauthor,\n\t\t\t\t\t\t\tcreatedAt: localCreatedAt,\n\t\t\t\t\t\t\tupdatedAt: undefined,\n\t\t\t\t\t\t\tdeletedBy: undefined,\n\t\t\t\t\t\t\tmentions,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\tconst thread = await createThread(projectId, { anchor, text, mentions })\n\n\t\t\t\tcreatedThreadId = thread.id\n\n\t\t\t\t// Remove the old key and insert the new one.\n\t\t\t\treturn prev => prev.remove(localThreadId).set(thread.id, fromServiceThread(thread))\n\t\t\t},\n\t\t\tonError: (_error, { retry, cancel }) => {\n\t\t\t\tvoid this.scheduler.processWhenReadyAsync(() => {\n\t\t\t\t\tthis._commentMetadata = this._commentMetadata.update(localCommentId, prev => ({\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\thasSendError: true,\n\t\t\t\t\t}))\n\t\t\t\t\tthis.commentErrorHandles.set(localCommentId, { retry, cancel })\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\n\t\tif (this.selectedThreadId === localThreadId) {\n\t\t\tif (isAgent) this.threadIdUnderMouse = createdThreadId\n\t\t\tawait this.setSelectedThread(createdThreadId)\n\t\t}\n\n\t\tconst thread = this.getThread(createdThreadId)\n\t\tif (!thread) throw new Error(\"Invariant\")\n\t\tconst comment = thread.comments[0]\n\t\tassert(comment, \"A thread should have at least one comment\")\n\t\t// Move the comment metadata under the persistent id, but remember its\n\t\t// local id to keep React component keys consistent.\n\t\tthis._commentMetadata = this._commentMetadata\n\t\t\t.set(comment.id, { ...this._commentMetadata.get(localCommentId), localId: localCommentId })\n\t\t\t.delete(localCommentId)\n\n\t\treturn { thread, comment }\n\t}\n\n\tprivate async addCommentToThread({\n\t\tthread,\n\t\tauthor,\n\t\ttext,\n\t\tmentions,\n\t}: {\n\t\tthread: Thread\n\t\tauthor: User\n\t\ttext: string\n\t\tmentions: Mention[]\n\t}): Promise<{ thread: Thread; comment: Comment }> {\n\t\tconst localCommentId = localId()\n\t\t// NOTE: There's a risk of clocks being out of sync here and seeing\n\t\t// unwanted unread states\n\t\tconst localCreatedAt = new Date()\n\t\tconst req = this.threadMap.beginTransaction(thread.id, {\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\tconst newComment = await createComment(projectId, { threadId: thread.id, text, mentions }).then(c =>\n\t\t\t\t\tfromServiceComment(c),\n\t\t\t\t)\n\n\t\t\t\treturn prev =>\n\t\t\t\t\tlatestThread(prev, {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tseenUntil: newComment.createdAt,\n\t\t\t\t\t\tcomments: [...prev.comments, newComment],\n\t\t\t\t\t})\n\t\t\t},\n\t\t\toptimistic: t => ({\n\t\t\t\t...t,\n\t\t\t\tseenUntil: localCreatedAt,\n\t\t\t\tcomments: [\n\t\t\t\t\t...t.comments,\n\t\t\t\t\t{\n\t\t\t\t\t\tid: localCommentId,\n\t\t\t\t\t\ttext,\n\t\t\t\t\t\tauthor: author,\n\t\t\t\t\t\tcreatedAt: localCreatedAt,\n\t\t\t\t\t\tupdatedAt: undefined,\n\t\t\t\t\t\tdeletedBy: undefined,\n\t\t\t\t\t\tmentions,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t\tonError: (_error, { retry, cancel }) => {\n\t\t\t\tvoid this.scheduler.processWhenReadyAsync(() => {\n\t\t\t\t\tthis._commentMetadata = this._commentMetadata.update(localCommentId, prev => ({\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\thasSendError: true,\n\t\t\t\t\t}))\n\t\t\t\t\tthis.commentErrorHandles.set(localCommentId, { retry, cancel })\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\n\t\t// Update selection for optimistic comment...\n\t\tconst optimisticThread = this.getThread(thread.id)\n\t\tif (!optimisticThread) throw new Error(\"Invariant\")\n\t\tthis.updateSeenStateForCreatedComment(optimisticThread)\n\n\t\tconst newThread = await req\n\t\tconst newComment = newThread.comments[newThread.comments.length - 1]\n\t\tassert(newComment, \"A thread must have at least one comment\")\n\t\tawait this.scheduler.processWhenReadyAsync(() => {\n\t\t\tthis.updateSeenStateForCreatedComment(newThread)\n\n\t\t\t// Move the comment metadata under the persistent id, but remember its\n\t\t\t// local id to keep React component keys consistent.\n\t\t\tthis._commentMetadata = this._commentMetadata\n\t\t\t\t.set(newComment.id, { ...this._commentMetadata.get(localCommentId), localId: localCommentId })\n\t\t\t\t.delete(localCommentId)\n\t\t})\n\n\t\treturn { thread: newThread, comment: newComment }\n\t}\n\n\tprivate updateSeenStateForCreatedComment(thread: Thread) {\n\t\tconst newComment = thread.comments[thread.comments.length - 1]\n\t\tif (!newComment) return\n\n\t\tif (this.selectedThreadId === thread.id) {\n\t\t\tthis._selectionState = { ...this._selectionState, seenUntil: newComment.createdAt }\n\t\t}\n\t}\n\n\tasync setCommentEditable(commentId: string) {\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\t// Set current comment to editing\n\t\t\tconst metadata = this._commentMetadata.get(commentId)\n\t\t\tif (!metadata?.isEditing) {\n\t\t\t\tthis._commentMetadata = this._commentMetadata.set(commentId, { ...metadata, isEditing: true })\n\t\t\t}\n\n\t\t\t// Set all other comments to not editing\n\t\t\tthis._commentMetadata = this._commentMetadata.withMutations(mutable => {\n\t\t\t\tthis._commentMetadata.forEach((metadata, id) => {\n\t\t\t\t\tif (id && commentId !== id && metadata?.isEditing) {\n\t\t\t\t\t\tmutable.set(id, { ...metadata, isEditing: false })\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\n\t\t\t// Refresh mentionable users when a user starts editing (may mention in edits)\n\t\t\tthis.setMentionableUsers()\n\t\t})\n\t}\n\n\tasync clearCommentEditable(commentId: string) {\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tconst metadata = this._commentMetadata.get(commentId)\n\t\t\tif (metadata?.isEditing) {\n\t\t\t\tthis._commentMetadata = this._commentMetadata.set(commentId, { ...metadata, isEditing: false })\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate getComment({ threadId, commentId }: { threadId: string; commentId: string }): Comment | null {\n\t\tconst thread = this.getThread(threadId)\n\t\tif (!thread) return null\n\n\t\treturn thread.comments.find(({ id }) => id === commentId) || null\n\t}\n\n\tasync updateComment({\n\t\tthreadId,\n\t\tcommentId,\n\t\ttext,\n\t\tmentions,\n\t}: {\n\t\tthreadId: string\n\t\tcommentId: string\n\t\ttext: string\n\t\tmentions: Mention[]\n\t}) {\n\t\t// Optimistic Update\n\t\tconst currentComment = this.getComment({ threadId, commentId })\n\t\tif (!currentComment) throw new Error(\"Unable to find comment with id: \" + commentId)\n\n\t\tif (currentComment && text === currentComment.text) {\n\t\t\treturn currentComment\n\t\t}\n\n\t\tawait this.threadMap.beginTransaction(threadId, {\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\tconst comment = await updateComment(projectId, { id: commentId, threadId, text, mentions })\n\t\t\t\treturn prev => updateThreadWithCommentResponse(prev, fromServiceComment(comment))\n\t\t\t},\n\t\t\toptimistic: prev =>\n\t\t\t\tupdateThreadWithCommentResponse(prev, {\n\t\t\t\t\t...currentComment,\n\t\t\t\t\ttext,\n\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\tmentions,\n\t\t\t\t}),\n\t\t})\n\t}\n\n\tasync deleteComment({ threadId, commentId }: { threadId: string; commentId: string }) {\n\t\t// Optimistic Update\n\t\tconst currentComment = this.getComment({ threadId, commentId })\n\t\tif (!currentComment || currentComment.deletedBy) return\n\n\t\tawait this.threadMap.beginTransaction(threadId, {\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\tconst comment = await deleteComment(projectId, { id: commentId, threadId })\n\t\t\t\treturn prev => updateThreadWithCommentResponse(prev, fromServiceComment(comment))\n\t\t\t},\n\t\t\toptimistic: prev => {\n\t\t\t\tif (!this.currentUser) {\n\t\t\t\t\tthrow new Error(`Current user not defined`)\n\t\t\t\t}\n\t\t\t\treturn updateThreadWithCommentResponse(prev, {\n\t\t\t\t\t...currentComment,\n\t\t\t\t\tdeletedBy: this.currentUser,\n\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\ttext: \"\",\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate commentErrorHandles = new Map<string, { retry: () => void; cancel: () => void }>()\n\n\tresendComment({ commentId }: { commentId: string }) {\n\t\tconst handle = this.commentErrorHandles.get(commentId)\n\t\thandle && handle.retry()\n\n\t\t// Invalidate the handle\n\t\tthis.commentErrorHandles.delete(commentId)\n\n\t\t// Reset the error state\n\t\tthis._commentMetadata = this._commentMetadata.update(commentId, prev => ({ ...prev, hasSendError: false }))\n\t}\n\n\tsetThreadAnchor(threadId: string, anchor: Anchor): Thread | undefined {\n\t\tif (isDraftThread(threadId)) {\n\t\t\tthis._draftThread = createDraftThread({ ...this._draftThread, anchor })\n\t\t\treturn this._draftThread\n\t\t} else {\n\t\t\treturn this.threadMap.update(threadId, t => ({ ...t, anchor }))\n\t\t}\n\t}\n\n\tasync persistThreadAnchor(threadId: string) {\n\t\tif (isDraftThread(threadId) || isLocalId(threadId)) return\n\n\t\tconst projectId = this.projectStore.projectId\n\n\t\tconst thread = this.getThread(threadId)\n\t\tif (!thread) return\n\t\tconst res = await updateThread(projectId, { id: threadId, anchor: thread.anchor })\n\t\tawait this.scheduler.processWhenReadyAsync(() => {\n\t\t\tthis.threadMap.update(threadId, () => fromServiceThread(res))\n\t\t})\n\t}\n\n\tasync archiveThread(threadId: string) {\n\t\tif (isLocalId(threadId)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst current = this.getThread(threadId)\n\t\tif (!current || current.archived) return\n\n\t\tawait this.threadMap.beginTransaction(threadId, {\n\t\t\ttransaction: async () => {\n\t\t\t\t// Ensure archived threads are enabled.\n\t\t\t\tif (!this._hasArchiveLoaded) {\n\t\t\t\t\tthis._hasArchiveLoaded = true\n\t\t\t\t\t// Ensure the archived thread list is populated.\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait this.loadArchivedThreads()\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Ignore errors\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst projectId = this.projectStore.projectId\n\n\t\t\t\t// Update with response from server...\n\t\t\t\tconst thread = await updateThread(projectId, { id: threadId, archived: true })\n\t\t\t\treturn prev => latestThread(prev, fromServiceThread(thread))\n\t\t\t},\n\t\t\toptimistic: t => (t.archived ? t : { ...t, archived: true }),\n\t\t})\n\t}\n\n\tasync unarchiveThread(threadId: string) {\n\t\tif (isLocalId(threadId)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst current = this.getThread(threadId)\n\t\tif (!current || !current.archived) return\n\n\t\tawait this.threadMap.beginTransaction(threadId, {\n\t\t\ttransaction: async () => {\n\t\t\t\tconst projectId = this.projectStore.projectId\n\t\t\t\t// Update with response from server...\n\t\t\t\tconst thread = await updateThread(projectId, { id: threadId, archived: false })\n\t\t\t\treturn prev => latestThread(prev, fromServiceThread(thread))\n\t\t\t},\n\t\t\toptimistic: t => (!t.archived ? t : { ...t, archived: false }),\n\t\t})\n\t}\n\n\tasync deleteThread(threadId: string) {\n\t\tconst projectId = this.projectStore.projectId\n\n\t\tconst currentUserId = this.currentUser?.id\n\t\tassert(currentUserId, \"Current user must be defined\")\n\n\t\tif (!isDraftThread(threadId)) {\n\t\t\tawait this.threadMap.beginTransaction({\n\t\t\t\ttransaction: async () => {\n\t\t\t\t\t// Update with response from server...\n\t\t\t\t\tawait deleteThread(projectId, { threadId, deletedBy: currentUserId })\n\t\t\t\t\treturn prev => prev.delete(threadId)\n\t\t\t\t},\n\t\t\t\toptimistic: prev => prev.delete(threadId),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tthis.threadMap.update(t => t.delete(threadId))\n\n\t\tif (this.selectedThreadId === threadId) {\n\t\t\tthis._selectionState = { ...this._selectionState, threadId: undefined }\n\t\t}\n\t}\n\n\tget threads(): readonly Thread[] {\n\t\treturn this._derivedData.threads\n\t}\n\n\tget archivedThreads(): readonly Thread[] {\n\t\treturn this._hasArchiveLoaded ? this._derivedData.archived : EmptyList\n\t}\n\n\tget draftThread(): Thread | undefined {\n\t\treturn this._draftThread\n\t}\n\n\t/** Returns an object/map */\n\tget framesWithThreads(): ReadonlySet<string> {\n\t\treturn this._derivedData.framesWithThreads\n\t}\n\n\tprivate generateDerivedData(): void {\n\t\tconst threads: Thread[] = []\n\t\tconst archived: Thread[] = []\n\t\tconst framesWithThreads = new Set<string>()\n\n\t\tthis.threadMap.forEach((t: Thread) => {\n\t\t\tif (t.archived) {\n\t\t\t\tarchived.push(t)\n\t\t\t} else {\n\t\t\t\tthreads.push(t)\n\t\t\t}\n\n\t\t\tif (!t.archived && t.anchor.type === \"node\") {\n\t\t\t\tframesWithThreads.add(t.anchor.nodeId)\n\t\t\t}\n\t\t})\n\t\tthis._derivedData = {\n\t\t\tthreads: sortThreads(threads),\n\t\t\tarchived: sortThreads(archived),\n\t\t\tframesWithThreads,\n\t\t}\n\t}\n\n\t// Tracks which comments we've already notified the user about in this\n\t// session. Combined with the \"maxAge\" filter below, this should be Good\n\t// Enough for now to avoid notifying the user multiple times about the same\n\t// unread comments.\n\tprivate commentNotificationsTracker = new CommentNotificationsTracker()\n\n\tprivate async postUnreadNotifications() {\n\t\t// Since we don't *persistently* track which comments we've already\n\t\t// notified the user about, let's only show notifications for the most\n\t\t// fresh comments. This way, if they reload the app and\n\t\t// CommentNotificationsTracker gets reset, we won't possibly spam them\n\t\t// with notifications they may have already seen and dismissed.\n\t\t//\n\t\t// All of this problem should go away when we switch to real-time\n\t\t// updates, because we'll only ever notify the user when the server\n\t\t// pushes the new comment to us.\n\t\tconst maxAgeSeconds = 60\n\t\tconst unreadComments = getUnreadCommentsForThreads(this.threads, {\n\t\t\tcreatedAfter: new Date(Date.now() - maxAgeSeconds * 1000),\n\t\t})\n\t\tconst userNotifications = await this.userNotifications\n\t\tassert(userNotifications, \"User Notification Service not initialized correctly\")\n\t\tconst commentsToNotify = unreadComments\n\t\t\t.filter(({ comment }) => this.currentUser && this.currentUser.id !== comment.author.id)\n\t\t\t.filter(({ comment }) => {\n\t\t\t\tif (this.commentNotificationsTracker.wasNotified(comment.id)) {\n\t\t\t\t\treturn false\n\t\t\t\t} else {\n\t\t\t\t\tthis.commentNotificationsTracker.markNotified(comment.id)\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t})\n\n\t\tif (commentsToNotify.length === 1) {\n\t\t\tconst c = commentsToNotify[0]\n\t\t\tassert(c, \"Comment to notify must be defined\")\n\t\t\tconst notification = createUnreadCommentNotification(c.threadId, c.comment)\n\t\t\treturn userNotifications.post({ notification }).then(res => {\n\t\t\t\tif (res.type === \"action\") {\n\t\t\t\t\treturn this.openThread(c.threadId, c.comment.id)\n\t\t\t\t}\n\t\t\t})\n\t\t} else if (commentsToNotify.length > 1) {\n\t\t\tconst notification = createUnreadSummaryNotification(commentsToNotify.length)\n\t\t\treturn userNotifications.post({ notification }).then(res => {\n\t\t\t\tif (res.type === \"action\") {\n\t\t\t\t\treturn this.openAllThreads()\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Updates the _threads and _archived Lists with new Threads, should be\n\t * used when receiving new models from the network.\n\t */\n\tprivate updateThreads(newThreads: List<Thread> | readonly Thread[]): void {\n\t\tthis.threadMap.update(t => mergeThreads(t, newThreads))\n\t}\n\n\tprivate _hasUnreadFeedback = false\n\tget hasUnreadFeedback() {\n\t\treturn this._hasUnreadFeedback\n\t}\n\tset hasUnreadFeedback(value: boolean) {\n\t\tif (this.hasUnreadFeedback === value) return\n\t\tthis._hasUnreadFeedback = value\n\t}\n\tprivate checkUnreadFeedback(): boolean {\n\t\treturn this.threads.some((t: Thread) => isUnread(t))\n\t}\n\n\tprivate _threadIdUnderMouse: string | undefined\n\tpublic get threadIdUnderMouse(): string | undefined {\n\t\treturn this._threadIdUnderMouse\n\t}\n\tpublic set threadIdUnderMouse(value: string | undefined) {\n\t\tif (this._threadIdUnderMouse === value) return\n\t\tthis._threadIdUnderMouse = value\n\t}\n\n\tpublic __currentPollLoopForTest: Promise<void> | undefined\n\n\tprivate async fetchPollUpdate() {\n\t\tconst projectId = this.projectStore.projectId\n\n\t\tconst prevVersion = this.threadMap.remoteHashCode()\n\t\tconst { threads } = await getThreads(projectId, { archived: false })\n\n\t\tawait this.scheduler.processWhenReadyAsync(() => {\n\t\t\t// Drop this update if something has changed in the mean time\n\t\t\t// as a cheap way of avoiding blowing away local changes.\n\t\t\tif (this.threadMap.remoteHashCode() === prevVersion) {\n\t\t\t\t// We merge in archived threads too.\n\t\t\t\tconst newThreads = threads.map(fromServiceThread).concat(this.archivedThreads)\n\t\t\t\tthis.threadMap.update(() => ImmutableMap(newThreads.map(t => [t.id, t])))\n\t\t\t\tthis._hasUnreadFeedback = this.checkUnreadFeedback()\n\t\t\t}\n\n\t\t\t// Ensure that we mark the current thread as read.\n\t\t\t// TODO: This should take into account window visibility and\n\t\t\t// very likely be driven by the view layer rather than the store.\n\t\t\tif (this.selectedThread && isUnread(this.selectedThread)) {\n\t\t\t\tthis.markThreadAsSeen(this.selectedThread.id).catch(unhandledError)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate startPolling() {\n\t\t// Because this code uses promises it's non-trivial to test in the\n\t\t// unit tests so we expose it via __currentPollLoopForTest so the\n\t\t// test is able to wait for the loop to run.\n\t\tconst run = () => {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-use-before-define\n\t\t\tthis.__currentPollLoopForTest = this.fetchPollUpdate().then(scheduleNextPollUpdate).catch(unhandledError)\n\t\t}\n\n\t\tconst scheduleNextPollUpdate = () => {\n\t\t\tthis.stopPolling()\n\t\t\tthis.pollTimerId = window.setTimeout(run, this.currentPollInterval())\n\t\t}\n\n\t\tscheduleNextPollUpdate()\n\t}\n\n\tprivate stopPolling() {\n\t\tthis.pollTimerId && window.clearTimeout(this.pollTimerId)\n\t\t// Need to also reset this otherwise restarting polling will trigger\n\t\t// an immidate run of the poll loop.\n\t\tthis.pollTimerId = null\n\t}\n\n\tprivate currentPollInterval(): number {\n\t\tif (!this.toolStore.feedbackModeActive) {\n\t\t\treturn this.pollInterval.Idle\n\t\t}\n\n\t\tif (this.selectedThreadId) {\n\t\t\treturn this.pollInterval.Thread\n\t\t}\n\n\t\treturn this.pollInterval.Active\n\t}\n}\n\n/** Updates the `threads` property with a new batch */\nfunction mergeThreads(\n\tcurrent: ImmutableMap<string, Thread>,\n\tnext: List<Thread> | readonly Thread[],\n): ImmutableMap<string, Thread> {\n\tlet didChange = false\n\tconst map: { [id: string]: Thread } = {}\n\n\t// Build the initial map.\n\tcurrent.forEach((t: Thread) => (map[t.id] = t))\n\n\t// Apply changes if needed.\n\tnext.forEach((nextThread: Thread) => {\n\t\tconst currentThread = map[nextThread.id]\n\t\tmap[nextThread.id] = latestThread(currentThread, nextThread)\n\t\tif (nextThread === map[nextThread.id]) {\n\t\t\tdidChange = true\n\t\t}\n\t})\n\n\tif (!didChange) {\n\t\treturn current\n\t}\n\n\treturn ImmutableMap(map)\n}\n\nfunction latestThread(currentThread: Thread | undefined, nextThread: Thread): Thread {\n\t// Add new threads and update old ones.\n\tif (\n\t\t!currentThread ||\n\t\tNumber(currentThread.updatedAt || getThreadTimestamp(currentThread)) <\n\t\t\tNumber(nextThread.updatedAt || getThreadTimestamp(nextThread)) ||\n\t\tcurrentThread.seenUntil !== nextThread.seenUntil\n\t) {\n\t\treturn nextThread\n\t}\n\treturn currentThread\n}\n\nfunction sortThreads(threads: Thread[]) {\n\t// Use Immutable sort as it's guarenteed to be stable.\n\treturn List(threads)\n\t\t.sort((a, b) => {\n\t\t\tconst isAUnread = isUnread(a)\n\t\t\tconst isBUnread = isUnread(b)\n\n\t\t\tif (isAUnread && !isBUnread) return -1\n\t\t\tif (!isAUnread && isBUnread) return 1\n\n\t\t\treturn getThreadTimestamp(b) - getThreadTimestamp(a)\n\t\t})\n\t\t.toArray()\n}\n\nfunction getMentionableUsers(acl: (UserACLEntry | InviteACLEntry)[], teamMembers: TeamMember[]): MentionableUser[] {\n\tlet mentionableUsersMap = new Map<string, MentionableUser>()\n\n\tfor (const aclEntry of acl) {\n\t\tif (aclEntry.kind === ACLEntryKind.User) {\n\t\t\tmentionableUsersMap = mentionableUsersMap.set(aclEntry.user.id, {\n\t\t\t\t...aclEntry.user,\n\t\t\t\tisProjectMember: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tfor (const teamMember of teamMembers) {\n\t\tif (mentionableUsersMap.has(teamMember.userId)) {\n\t\t\tcontinue\n\t\t}\n\t\tconst user: MentionableUser = {\n\t\t\tid: teamMember.userId,\n\t\t\tname: `${teamMember.firstName} ${teamMember.lastName}`,\n\t\t\tinitials: `${teamMember.firstName.charAt(0)}${teamMember.lastName.charAt(0)}`.toUpperCase(),\n\t\t\tavatar: teamMember.avatar,\n\t\t\tisProjectMember: false,\n\t\t}\n\t\tmentionableUsersMap.set(teamMember.userId, user)\n\t}\n\treturn Array.from(mentionableUsersMap.values())\n}\n\nfunction updateThreadWithCommentResponse(thread: Thread, updated: Comment) {\n\tconst comments = thread.comments.slice()\n\tlet hasChanged = false\n\n\tfor (let idx = 0; idx < comments.length; idx += 1) {\n\t\tconst current = comments[idx]\n\t\tif (!current) continue\n\t\tif (current.id !== updated.id) continue\n\t\tif (!isEqual(updated, current)) {\n\t\t\tcomments[idx] = { ...current, ...updated }\n\t\t\thasChanged = true\n\t\t}\n\t\tbreak\n\t}\n\n\treturn hasChanged ? { ...thread, comments: comments } : thread\n}\n", "import type { Map as ImmutableMap } from \"immutable\"\nimport { OrderedMap as ImmutableOrderedMap } from \"immutable\"\n\ntype Transform<T> = (prev: T) => T\ntype KeyTransform<T> = (prev: InferValue<T>) => InferValue<T>\n\ntype TransactionResult<T> = T | Transform<T>\ntype KeyTransactionResult<T> = InferValue<T> | KeyTransform<T>\n\ntype Transaction<T> = () => Promise<TransactionResult<T>>\ntype KeyTransaction<T> = () => Promise<KeyTransactionResult<T>>\n\n// biome-ignore lint/suspicious/noExplicitAny: @TODO add explanation\ntype TransactionError = any\ntype ErrorHandler = (error: TransactionError, actions: { retry: () => void; cancel: () => void }) => void\n\ninterface Update<T> {\n\ttransaction: Transaction<T>\n\toptimistic?: Transform<T>\n\tonError?: ErrorHandler\n}\n\ninterface KeyUpdate<T> {\n\ttransaction: KeyTransaction<T>\n\toptimistic?: KeyTransform<T>\n\tonError?: ErrorHandler\n}\n\ninterface ChangeInfo<T> {\n\tdata: T\n\thasLocalChanges: boolean\n\tdidRemoteChange: boolean\n}\n\n/**\n * This is a first pass at an optimistic update manager for the store state to\n * allow local changes to easily be applied and reverted.\n *\n * It tracks a list of transformations to an underlying \"remote\" datasource.\n *\n * Transformations can be applied to create a \"local\" representation via the\n * `addTransform()` method. The transformation can be cleared by calling\n * the returned `reset()` function.\n *\n * It's designed to mimic the Immutable Map API and provides methods for\n * fetching and iterating over values that share the Immutable API.\n *\n * The onChange() handler will be called anytime the underlying data changes.\n */\nexport class DataStore<T extends ImmutableMap<string, InferValue<T>>> {\n\t/** The latest known remote state. */\n\tprivate remote: T\n\t/** Local state which represents `this.remote` with `this.transforms` applied. */\n\tprivate local: T\n\t/** Local transforms that represent not yet committed to server changes to `this.remote` */\n\tprivate transforms = ImmutableOrderedMap<number, (prev: T) => T>()\n\tprivate counter = 0\n\n\tconstructor(\n\t\tinitial: T,\n\t\tprivate onChange: (info: ChangeInfo<T>) => void,\n\t) {\n\t\tthis.remote = this.local = initial\n\t}\n\n\tpublic remoteHashCode(): number {\n\t\treturn this.local.hashCode()\n\t}\n\n\tpublic get: T[\"get\"] = (...args) => this.local.get(...args)\n\n\tpublic forEach: T[\"forEach\"] = (...args) => this.local.forEach(...args)\n\n\tpublic update(fn: Transform<T>): void\n\tpublic update(key: string, fn: KeyTransform<T>): InferValue<T>\n\tpublic update(...args: [fn: Transform<T>] | [key: string, fn: KeyTransform<T>]): unknown {\n\t\tconst prev = this.remote\n\t\t// This looks a bit odd, but:\n\t\t// - The ternary works around a TypeScript limitation.\n\t\t//   https://github.com/microsoft/TypeScript/issues/49802\n\t\t// - The `as T` works around the fact that update returns a new type,\n\t\t//   but we know it's going to match our input type.\n\t\tthis.remote = (args.length === 1 ? this.remote.update(args[0]) : this.remote.update(...args)) as T\n\t\tif (this.remote !== prev) {\n\t\t\tconst hasLocalChanges = this.applyTransforms()\n\t\t\tthis.onChange({ data: this.local, hasLocalChanges, didRemoteChange: true })\n\t\t}\n\t\tif (typeof args[0] === \"string\") {\n\t\t\treturn this.get(args[0])\n\t\t}\n\t}\n\n\tpublic hasLocalChanges(): boolean {\n\t\treturn this.local !== this.remote\n\t}\n\n\t/**\n\t * Executes the `update`'s transaction.\n\t *\n\t * The `reset` param should be used to reset the optimistic update when the\n\t * transaction completes successfully or gets canceled.\n\t *\n\t * The `commit` param should be used to commit the result of the transaction\n\t * to the data store.\n\t *\n\t * If transaction completes successfully, will resolve with the value\n\t * returned from `commit`.\n\t *\n\t * If transaction fails, will either:\n\t * - call the `update`'s `onError` handler, with an option to retry or\n\t *   cancel the update\n\t * - if there's no `onError` handler, will immediately cancel the update\n\t *\n\t * When canceled, will reject the returned promise with the latest error\n\t * thrown by the transaction.\n\t */\n\tprivate doUpdate<S>(\n\t\tupdate: Update<T> | KeyUpdate<T>,\n\t\treset: () => void,\n\t\tcommit: (r: TransactionResult<T> | KeyTransactionResult<T>) => S,\n\t): Promise<S> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst performTransaction = () => update.transaction()\n\n\t\t\tconst successHandler = (result: TransactionResult<T> | KeyTransactionResult<T>) => {\n\t\t\t\tconst resolveValue = commit(result)\n\t\t\t\treset()\n\t\t\t\tresolve(resolveValue)\n\t\t\t}\n\t\t\tconst errorHandler = (error: TransactionError) => {\n\t\t\t\tconst actions = {\n\t\t\t\t\tretry: () => {\n\t\t\t\t\t\tperformTransaction().then(successHandler, errorHandler)\n\t\t\t\t\t},\n\t\t\t\t\tcancel: () => {\n\t\t\t\t\t\treset()\n\t\t\t\t\t\treject(error)\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\tupdate.onError ? update.onError(error, actions) : actions.cancel()\n\t\t\t}\n\n\t\t\tperformTransaction().then(successHandler, errorHandler)\n\t\t})\n\t}\n\n\tprivate performUpdate(update: Update<T>): Promise<void> {\n\t\tconst reset = update.optimistic ? this.addTransform(update.optimistic) : () => {}\n\n\t\tconst commit = (result: TransactionResult<T>) => {\n\t\t\tconst value = typeof result === \"function\" ? result(this.remote) : result\n\t\t\tthis.update(() => value)\n\t\t}\n\n\t\treturn this.doUpdate(update, reset, commit)\n\t}\n\n\tprivate performKeyUpdate(key: string, update: KeyUpdate<T>): Promise<InferValue<T>> {\n\t\tconst reset = update.optimistic ? this.addTransform(key, update.optimistic) : () => {}\n\n\t\tconst commit = (result: KeyTransactionResult<T>) => {\n\t\t\tconst prev = this.remote.get(key)\n\t\t\t// TypeScript can't distinguish the result here, I assume\n\t\t\t// because it's possible to have a function as a value...\n\t\t\tconst value = typeof result === \"function\" ? (result as KeyTransform<T>)(prev) : result\n\t\t\tthis.update(key, () => value)\n\n\t\t\treturn value\n\t\t}\n\n\t\treturn this.doUpdate(update, reset, commit)\n\t}\n\n\t/**\n\t * Immediately applies `optimistic` update function if present while triggering `onChange` listeners on the store.\n\t * Then executes the `transaction`.\n\t * If transaction completes successfully, will resolve successfully.\n\t * If transaction fails, will either:\n\t * - call the `update`'s `onError` handler, with an option to retry or\n\t *   cancel the update\n\t * - if there's no `onError` handler, will immediately cancel the update.\n\t *\n\t * When canceled, will reject the returned promise with the latest error\n\t * thrown by the transaction.\n\t */\n\tasync beginTransaction(update: Update<T>): Promise<void>\n\tasync beginTransaction(key: string, update?: KeyUpdate<T>): Promise<InferValue<T>>\n\tasync beginTransaction(\n\t\t...args: [update: Update<T>] | [key: string, update?: KeyUpdate<T>]\n\t): Promise<void | InferValue<T>> {\n\t\tif (typeof args[0] === \"string\") {\n\t\t\tconst [key, update] = args\n\t\t\tif (!update) throw new Error(\"Invariant\")\n\t\t\treturn this.performKeyUpdate(key, update)\n\t\t} else {\n\t\t\tconst update = args[0]\n\t\t\treturn this.performUpdate(update)\n\t\t}\n\t}\n\n\t/**\n\t * Applies the transform and returns the function that reverts the transform.\n\t */\n\tprivate addTransform(fn: Transform<T>): () => void\n\tprivate addTransform(key: string, fn: KeyTransform<T>): () => void\n\tprivate addTransform(keyOrFn: string | Transform<T>, fn?: KeyTransform<T>): () => void {\n\t\tconst id = (this.counter += 1)\n\n\t\tlet transform: (prev: T) => T\n\t\tif (typeof keyOrFn === \"string\") {\n\t\t\tif (!fn) throw new Error(\"Invariant\")\n\t\t\ttransform = (prev: T) => prev.update(keyOrFn, fn) as T\n\t\t} else {\n\t\t\ttransform = keyOrFn\n\t\t}\n\n\t\tthis.transforms = this.transforms.set(id, transform)\n\n\t\tif (this.applyTransforms()) {\n\t\t\tthis.onChange({ data: this.local, hasLocalChanges: true, didRemoteChange: false })\n\t\t}\n\n\t\treturn () => {\n\t\t\tconst prevLocal = this.local\n\t\t\tconst prevTransforms = this.transforms\n\t\t\tthis.transforms = this.transforms.remove(id)\n\t\t\tif (this.transforms === prevTransforms) return\n\n\t\t\tconst hasLocalChanges = this.applyTransforms()\n\t\t\t// If reverting transform results in the same local state, don't trigger `onChange`.\n\t\t\tif (this.local === prevLocal) return\n\n\t\t\tthis.onChange({ data: this.local, hasLocalChanges, didRemoteChange: false })\n\t\t}\n\t}\n\n\t/**\n\t * Applies the local transforms and assigns the result of the application to `this.local`.\n\t * Returns `true` if with the transforms applied `this.local` is not equal to `this.remote`, i.e. there are local changes.\n\t */\n\tprivate applyTransforms(): boolean {\n\t\tlet result = this.remote\n\t\tthis.transforms.forEach((fn: (prev: T) => T) => (result = fn(result)))\n\t\tthis.local = result\n\n\t\tif (this.remote !== result) {\n\t\t\treturn true\n\t\t}\n\n\t\treturn false\n\t}\n}\n\ntype InferValue<P> = P extends ImmutableMap<unknown, infer T> ? T : never\n", "import { dragSessionActive } from \"@framerjs/fresco/layout-transitions\"\nimport { assert, isAppleDevice, isCommandKeyPressed } from \"@framerjs/shared\"\nimport type { EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { VekterTool } from \"document/VekterTool.ts\"\nimport type { BaseMouseStore } from \"document/base-engine/BaseMouseStore.ts\"\nimport type { SelectionOutlineTracker } from \"document/stores/SelectionOutlineTracker.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\n\nexport interface InputState {\n\tcanvasMousePosition: Point\n\tcanvasMouseDownPosition: Point | null\n\twindowMousePosition: Point\n\twindowMouseDownPosition: Point | null\n\taltKey: boolean\n\tcmdKey: boolean\n\tctrlKey: boolean\n\tshiftKey: boolean\n\tspacebar: boolean\n\tisMouseOnCanvas: boolean\n}\n\n/**\n * This store keeps track of the mouse state, keyboard modifier state, and is\n * the entry point for key events. This is all in service of the document as\n * we edit it on the canvas.\n *\n * Note that React components like buttons and input fields in places like the\n * property panel should handle their own mouse and key events.\n */\n\nexport class MouseStore implements BaseMouseStore, InputState {\n\tcanvasMousePosition: Point = Point(0, 0)\n\twindowMousePosition: Point = Point(0, 0)\n\tcanvasMouseDownPosition: Point | null = null\n\twindowMouseDownPosition: Point | null = null\n\tisMouseOnCanvas: boolean = false\n\tcanvasMiddleMouseButtonDownPosition: Point | null = null\n\twindowMiddleMouseButtonDownPosition: Point | null = null\n\tcanvasDoubleClickPosition: Point | null = null\n\n\t// modifier keys\n\tcmdKey: boolean = false\n\tctrlKey: boolean = false\n\t// UNSAFE__ctrlKey is used to track whether the ctrl key is really pressed\n\t// regardless of cross-platform support. We use it to determine whether the\n\t// user is pinch zooming (see CanvasEventTarget). It should not be used as a modifier key for\n\t// other purposes.\n\tUNSAFE__ctrlKey = false\n\taltKey: boolean = false\n\tshiftKey: boolean = false\n\tspacebar: boolean = false\n\n\treadonly latest: InputState = {\n\t\tcanvasMousePosition: Point(0, 0),\n\t\tcanvasMouseDownPosition: null,\n\t\twindowMousePosition: Point(0, 0),\n\t\twindowMouseDownPosition: null,\n\t\taltKey: false,\n\t\tcmdKey: false,\n\t\tctrlKey: false,\n\t\tshiftKey: false,\n\t\tspacebar: false,\n\t\tisMouseOnCanvas: false,\n\t}\n\n\treadonly previous: InputState = {\n\t\tcanvasMousePosition: Point(0, 0),\n\t\tcanvasMouseDownPosition: null,\n\t\twindowMousePosition: Point(0, 0),\n\t\twindowMouseDownPosition: null,\n\t\taltKey: false,\n\t\tcmdKey: false,\n\t\tctrlKey: false,\n\t\tshiftKey: false,\n\t\tspacebar: false,\n\t\tisMouseOnCanvas: false,\n\t}\n\n\tprivate isDown: boolean = false\n\n\tconstructor(\n\t\tprivate addChanges: EngineChangeSignal,\n\t\tprivate selectionOutlineTracker: SelectionOutlineTracker,\n\t\tprivate getTool: () => VekterTool | null,\n\t\tprivate setZoomTool: () => void,\n\t\tprivate toolManagerKeyDownHandler: (event: KeyboardEvent) => void,\n\t) {}\n\n\tsetMouseDown(down: boolean) {\n\t\tthis.isDown = down\n\t\tthis.canvasMouseDownPosition = this.isDown ? this.canvasMousePosition : null\n\t\tthis.windowMouseDownPosition = this.isDown ? this.windowMousePosition : null\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetMiddleButtonDown(down: boolean) {\n\t\tthis.isDown = down\n\t\tthis.canvasMiddleMouseButtonDownPosition = this.isDown ? this.canvasMousePosition : null\n\t\tthis.windowMiddleMouseButtonDownPosition = this.isDown ? this.windowMousePosition : null\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetDoubleClick(didDoubleClick: boolean) {\n\t\tthis.canvasDoubleClickPosition = didDoubleClick ? this.canvasMousePosition : null\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tresetMouse() {\n\t\tconst zeroPoint = Point(0, 0)\n\t\tthis.setMousePosition(zeroPoint, zeroPoint, false, false, false, false)\n\t\tthis.setMouseDown(false)\n\t\tthis.setDoubleClick(false)\n\t\tthis.latest.canvasMousePosition = Point(0, 0)\n\t\tthis.latest.canvasMouseDownPosition = null\n\t\tthis.latest.windowMousePosition = Point(0, 0)\n\t\tthis.latest.windowMouseDownPosition = null\n\t}\n\n\tupdateInputState() {\n\t\tthis.previous.canvasMousePosition = this.latest.canvasMousePosition\n\t\tthis.previous.canvasMouseDownPosition = this.latest.canvasMouseDownPosition\n\t\tthis.previous.windowMousePosition = this.latest.windowMousePosition\n\t\tthis.previous.windowMouseDownPosition = this.latest.windowMouseDownPosition\n\t\tthis.previous.altKey = this.latest.altKey\n\t\tthis.previous.cmdKey = this.latest.cmdKey\n\t\tthis.previous.ctrlKey = this.latest.ctrlKey\n\t\tthis.previous.shiftKey = this.latest.shiftKey\n\t\tthis.previous.spacebar = this.latest.spacebar\n\t\tthis.previous.isMouseOnCanvas = this.latest.isMouseOnCanvas\n\n\t\tthis.latest.altKey = this.altKey\n\t\tthis.latest.cmdKey = this.cmdKey\n\t\tthis.latest.ctrlKey = this.ctrlKey\n\t\tthis.latest.shiftKey = this.shiftKey\n\t\tthis.latest.spacebar = this.spacebar\n\t\tthis.latest.isMouseOnCanvas = this.isMouseOnCanvas\n\t\tthis.latest.canvasMousePosition = this.canvasMousePosition\n\t\tthis.latest.windowMousePosition = this.windowMousePosition\n\n\t\tif (this.canvasMouseDownPosition) {\n\t\t\tthis.latest.canvasMouseDownPosition = this.canvasMouseDownPosition\n\t\t\tthis.latest.windowMouseDownPosition = this.windowMouseDownPosition\n\t\t} else {\n\t\t\tthis.latest.canvasMouseDownPosition = null\n\t\t\tthis.latest.windowMouseDownPosition = null\n\t\t}\n\t}\n\n\tsetMousePosition(\n\t\tmouse: Point,\n\t\tmouseRaw: Point,\n\t\taltKey: boolean,\n\t\tcmdKey: boolean,\n\t\tshiftKey: boolean,\n\t\tctrlKey: boolean,\n\t) {\n\t\tassert(isNumber(mouse.x))\n\t\tassert(isNumber(mouse.y))\n\t\tassert(isNumber(mouseRaw.x))\n\t\tassert(isNumber(mouseRaw.y))\n\t\tthis.canvasMousePosition = mouse\n\t\tthis.windowMousePosition = mouseRaw\n\t\tthis.altKey = altKey\n\t\tthis.cmdKey = cmdKey\n\t\tthis.shiftKey = shiftKey\n\t\tthis.ctrlKey = ctrlKey\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetRawMousePosition(mouseRaw: Point) {\n\t\tthis.windowMousePosition = mouseRaw\n\t\tthis.windowMouseDownPosition = this.isDown ? mouseRaw : null\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetMouseOnCanvas(onCanvas: boolean) {\n\t\tthis.isMouseOnCanvas = onCanvas\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetSpacebarDown(keyDown: boolean) {\n\t\tif (this.spacebar === keyDown) return\n\t\tthis.spacebar = keyDown\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tsetModifiers(event: KeyboardEvent) {\n\t\t// eslint-disable-next-line no-restricted-syntax -- Intentional for symmetry\n\t\tconst cmdKey = isAppleDevice() ? event.metaKey : event.ctrlKey\n\t\t// eslint-disable-next-line no-restricted-syntax -- Intentional for symmetry\n\t\tconst ctrlKey = isAppleDevice() ? event.ctrlKey : event.metaKey\n\t\tconst UNSAFE__ctrlKey = event.ctrlKey\n\t\tconst altKey = event.altKey\n\t\tconst shiftKey = event.shiftKey\n\n\t\tlet changed = false\n\t\tif (this.cmdKey !== cmdKey) {\n\t\t\tthis.cmdKey = cmdKey\n\t\t\tchanged = true\n\t\t}\n\t\tif (this.ctrlKey !== ctrlKey) {\n\t\t\tthis.ctrlKey = ctrlKey\n\t\t\tchanged = true\n\t\t}\n\t\tif (this.altKey !== altKey) {\n\t\t\tthis.altKey = altKey\n\t\t\tchanged = true\n\t\t}\n\t\tif (this.shiftKey !== shiftKey) {\n\t\t\tthis.shiftKey = shiftKey\n\t\t\tchanged = true\n\t\t}\n\n\t\tif (this.UNSAFE__ctrlKey !== UNSAFE__ctrlKey) {\n\t\t\tthis.UNSAFE__ctrlKey = UNSAFE__ctrlKey\n\t\t\tchanged = true\n\t\t}\n\n\t\tif (!changed) return\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n\n\tonKeyDown(event: KeyboardEvent) {\n\t\tif (dragSessionActive()) return\n\n\t\tif (event.key === \" \") {\n\t\t\t// prevent default which would cause the active scroll panel to scroll\n\t\t\t// down if it is not at the bottom. This code path will not be called in\n\t\t\t// cases where an input is focused, but we need to allow default in the button case\n\t\t\tif (!(event.target instanceof HTMLButtonElement)) {\n\t\t\t\tevent.preventDefault()\n\t\t\t}\n\t\t\tthis.setSpacebarDown(true)\n\t\t}\n\n\t\tthis.setModifiers(event)\n\n\t\tconst tool = this.getTool()\n\t\tif (!tool) return\n\n\t\t// Re-enable the outline on the selected node.\n\t\tif (!isArrowKey(event) && !isNumberKey(event)) {\n\t\t\tthis.selectionOutlineTracker.forceEnableSelectionOutline()\n\t\t}\n\n\t\t// Zoom tool. Use event.code instead of event.key so that the shortcut\n\t\t// works regardless of modifier keys (e.g. Option+Z produces \"\u03A9\" on macOS).\n\t\tconst hasModifierKey = event.shiftKey || isCommandKeyPressed(event)\n\t\tif (!hasModifierKey && event.code === \"KeyZ\") {\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopPropagation()\n\t\t\tthis.setZoomTool()\n\t\t\treturn\n\t\t}\n\n\t\t// Per-tool key handling.\n\t\tif (tool.onKeyDown) {\n\t\t\ttool.onKeyDown(event)\n\t\t\tif (event.defaultPrevented) return\n\t\t}\n\n\t\tthis.toolManagerKeyDownHandler(event)\n\t}\n\n\tonKeyUp(event: KeyboardEvent) {\n\t\tthis.setModifiers(event)\n\n\t\t// Space bar key up isn't fired while modifier keys are still down\n\t\t// To prevent the space bar being stuck we always unset it in key up\n\t\tthis.setSpacebarDown(false)\n\n\t\tconst tool = this.getTool()\n\t\tif (!tool) return\n\t\tif (tool.onKeyUp) {\n\t\t\ttool.onKeyUp(event)\n\t\t\tif (event.defaultPrevented) return\n\t\t}\n\t}\n\n\tonKeyPress(event: KeyboardEvent) {\n\t\tconst tool = this.getTool()\n\t\tif (!tool) return\n\t\tif (tool.onKeyPress) {\n\t\t\ttool.onKeyPress(event)\n\t\t\tif (event.defaultPrevented) return\n\t\t}\n\t}\n\n\tclearKeys() {\n\t\tconst anyKey = this.cmdKey || this.ctrlKey || this.UNSAFE__ctrlKey || this.altKey || this.shiftKey || this.spacebar\n\t\tif (!anyKey) return\n\n\t\tthis.cmdKey = false\n\t\tthis.ctrlKey = false\n\t\tthis.UNSAFE__ctrlKey = false\n\t\tthis.altKey = false\n\t\tthis.shiftKey = false\n\t\tthis.spacebar = false\n\t\tthis.addChanges(EngineChange.MouseStore)\n\t}\n}\n\nconst numberStrings = new Set(\"0123456789\")\n\nfunction isNumberKey(event: KeyboardEvent) {\n\treturn numberStrings.has(event.key)\n}\n\nfunction isArrowKey(event: KeyboardEvent) {\n\treturn event.key === \"ArrowUp\" || event.key === \"ArrowDown\" || event.key === \"ArrowLeft\" || event.key === \"ArrowRight\"\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport { defaultContourOverride, resolveContourOverride, type ContourOverride } from \"app/ai/contourOverride.ts\"\nimport { isLanguageModel, type LanguageModel } from \"app/ai/languageModels.ts\"\nimport { type AgentReasoningEffort, isAgentModelEfforts } from \"app/ai/models.ts\"\nimport type { EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type { TransitionExportType } from \"document/components/chrome/properties/panels/types.ts\"\nimport {\n\tCSSExportType,\n\tSVGExportType,\n\tisCSSExportType,\n\tisSVGExportType,\n} from \"document/components/chrome/properties/panels/types.ts\"\nimport type { ColorModel } from \"document/components/chrome/shared/ColorPicker/types.ts\"\nimport { isColorModel } from \"document/components/chrome/shared/ColorPicker/types.ts\"\nimport type { GradientColorStop } from \"document/models/GradientColorStop.ts\"\nimport { isBoolean, isNumber, isString } from \"utils/typeChecks.ts\"\n\nconst log = getLogger(\"PersistedUserDefaults\")\n\nconst storageKey = \"VekterUserDefaults\"\n\ntype SerializableValue =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| ContourOverride\n\t| Record<string, unknown>\n\t| GradientColorStop\n\t| readonly SerializableValue[]\n\ninterface PersistedUserDefaultsState {\n\talignToParent: boolean\n\tshowHandoff: boolean\n\tshowPixelGrid: boolean\n\tdisplayAllLinks: boolean\n\teditorFontSize: number\n\tframeBackground: string | null\n\tcolorModel: ColorModel\n\tdisplayRulers: boolean\n\tdisplayGrids: boolean\n\texportCSSType: CSSExportType\n\texportSVGType: SVGExportType\n\texportShowAllProps: boolean\n\tsmallNudgeIncrement: number\n\tlargeNudgeIncrement: number\n\tlayoutGap: number\n\tuseDirectSelect: boolean\n\tautoSwitchToLayers: boolean\n\tanimateOnZoom: boolean\n\treverseZoomDirection: boolean\n\tfastZoom: boolean\n\tkeyboardZoomsToSelection: boolean\n\tbannerScrollFeatures: boolean\n\tbannerStickyScroll: boolean\n\tperformanceMode: boolean\n\tcanvasPage: boolean\n\tdisplayPluginDeveloperTools: boolean\n\t/** Show a toast to scroll back to content when the canvas is empty. */\n\tshowScrollToContentToast: boolean\n\tnewContentAsDraft: boolean\n\tp3: boolean\n\texitCanvasOnDoubleClick: boolean\n\ttemplatesModalOnNewProject: boolean\n\tagentSelectedModel: LanguageModel | null\n\tagentSelectedReasoningByModel: Partial<Record<LanguageModel, AgentReasoningEffort>>\n\tagentFollowMode: boolean\n\tcontourOverride: ContourOverride\n}\n\ntype PersistedUserDefaultKey = keyof PersistedUserDefaultsState\n\nexport class PersistedUserDefaults implements PersistedUserDefaultsState {\n\t// Alignment\n\n\tprivate _alignToParent = false\n\n\tget alignToParent(): boolean {\n\t\treturn this._alignToParent\n\t}\n\n\tset alignToParent(newValue: boolean) {\n\t\tthis._alignToParent = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Show Pixel Grid\n\n\tprivate _showPixelGrid = false\n\n\tget showPixelGrid(): boolean {\n\t\treturn this._showPixelGrid\n\t}\n\n\tset showPixelGrid(newValue: boolean) {\n\t\tthis._showPixelGrid = newValue\n\t\tthis.didChange()\n\t}\n\n\t// handoff\n\tprivate _showHandoff = false\n\n\tget showHandoff(): boolean {\n\t\treturn this._showHandoff\n\t}\n\n\tset showHandoff(newValue: boolean) {\n\t\tthis._showHandoff = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Display All Links\n\n\tprivate _displayAllLinks = false\n\n\tget displayAllLinks(): boolean {\n\t\treturn this._displayAllLinks\n\t}\n\n\tset displayAllLinks(newValue: boolean) {\n\t\tthis._displayAllLinks = newValue\n\t\tthis.didChange()\n\t}\n\n\t// displayRulers\n\n\tprivate _displayRulers = false\n\n\tget displayRulers(): boolean {\n\t\treturn this._displayRulers\n\t}\n\n\tset displayRulers(newValue: boolean) {\n\t\tthis._displayRulers = newValue\n\t\tthis.didChange()\n\t}\n\n\t// displayGrids\n\n\tprivate _displayGrids: boolean = false\n\n\tget displayGrids(): boolean {\n\t\treturn this._displayGrids\n\t}\n\n\tset displayGrids(newValue: boolean) {\n\t\tthis._displayGrids = newValue\n\t\tthis.didChange()\n\t}\n\n\t// editor font size\n\n\treadonly editorDefaultFontSize = 12\n\tprivate _editorFontSize = this.editorDefaultFontSize\n\n\tget editorFontSize(): number {\n\t\treturn this._editorFontSize\n\t}\n\n\tset editorFontSize(newValue: number) {\n\t\tconst minSize = 9\n\t\tconst maxSize = 40\n\t\tif (newValue < minSize) {\n\t\t\tnewValue = minSize\n\t\t} else if (newValue > maxSize) {\n\t\t\tnewValue = maxSize\n\t\t}\n\t\tif (this._editorFontSize === newValue) return\n\n\t\tthis._editorFontSize = newValue\n\t\tthis.didChange()\n\t}\n\n\teditorFontSizeIncrease() {\n\t\tthis.editorFontSize += 1\n\t}\n\n\teditorFontSizeDecrease() {\n\t\tthis.editorFontSize -= 1\n\t}\n\n\teditorFontSizeReset() {\n\t\tthis.editorFontSize = this.editorDefaultFontSize\n\t}\n\n\t// Frame fill\n\n\tprivate _frameBackground: string | null = null\n\n\tget frameBackground(): string | null {\n\t\treturn this._frameBackground\n\t}\n\n\tset frameBackground(newValue: string | null) {\n\t\tthis._frameBackground = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Color Model\n\n\tprivate _colorModel: ColorModel = \"HEX\"\n\n\tget colorModel(): ColorModel {\n\t\treturn this._colorModel\n\t}\n\n\tset colorModel(newValue: ColorModel) {\n\t\tthis._colorModel = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Nudge Increments\n\tprivate _smallNudgeIncrement = 1\n\tget smallNudgeIncrement() {\n\t\treturn this._smallNudgeIncrement\n\t}\n\n\tset smallNudgeIncrement(value: number) {\n\t\tthis._smallNudgeIncrement = value\n\t\tthis.didChange()\n\t}\n\n\tprivate _largeNudgeIncrement = 10\n\tget largeNudgeIncrement() {\n\t\treturn this._largeNudgeIncrement\n\t}\n\n\tset largeNudgeIncrement(value: number) {\n\t\tthis._largeNudgeIncrement = value\n\t\tthis.didChange()\n\t}\n\n\t// Layout Gap\n\tprivate _layoutGap = 10\n\n\tget layoutGap(): number {\n\t\treturn this._layoutGap\n\t}\n\n\tset layoutGap(newValue: number) {\n\t\tthis._layoutGap = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Handoff Code Settings\n\n\tprivate _exportCSSType: CSSExportType = CSSExportType.CSS\n\n\tget exportCSSType() {\n\t\treturn this._exportCSSType\n\t}\n\n\tset exportCSSType(type: CSSExportType) {\n\t\tthis._exportCSSType = type\n\t\tthis.didChange()\n\t}\n\n\tprivate _exportSVGType: SVGExportType = SVGExportType.SVG\n\tget exportSVGType() {\n\t\treturn this._exportSVGType\n\t}\n\n\tset exportSVGType(type: SVGExportType) {\n\t\tthis._exportSVGType = type\n\t\tthis.didChange()\n\t}\n\n\tprivate _exportShowAllProps: boolean = true\n\tget exportShowAllProps() {\n\t\treturn this._exportShowAllProps\n\t}\n\n\tset exportShowAllProps(value: boolean) {\n\t\tthis._exportShowAllProps = value\n\t\tthis.didChange()\n\t}\n\n\t// Handoff motion settings\n\n\tprivate _exportTransitionType?: TransitionExportType\n\tget exportTransitionType() {\n\t\treturn this._exportTransitionType\n\t}\n\n\tset exportTransitionType(type: TransitionExportType | undefined) {\n\t\tthis._exportTransitionType = type\n\t\tthis.didChange()\n\t}\n\n\t// Selection Model\n\n\tprivate _useDirectSelect: boolean = true\n\tget useDirectSelect() {\n\t\treturn this._useDirectSelect\n\t}\n\n\tset useDirectSelect(value: boolean) {\n\t\tthis._useDirectSelect = value\n\t\tthis.didChange()\n\t}\n\n\t// Auto Switch to Layers\n\n\tprivate _autoSwitchToLayers: boolean = false\n\tget autoSwitchToLayers() {\n\t\treturn this._autoSwitchToLayers\n\t}\n\n\tset autoSwitchToLayers(value: boolean) {\n\t\tthis._autoSwitchToLayers = value\n\t\tthis.didChange()\n\t}\n\n\t// Reverse zoom direction\n\n\tprivate _reverseZoomDirection = false\n\tget reverseZoomDirection() {\n\t\treturn this._reverseZoomDirection\n\t}\n\n\tset reverseZoomDirection(newValue: boolean) {\n\t\tthis._reverseZoomDirection = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Fast zoom\n\n\tprivate _fastZoom = false\n\tget fastZoom() {\n\t\treturn this._fastZoom\n\t}\n\n\tset fastZoom(newValue: boolean) {\n\t\tthis._fastZoom = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Animate on zoom\n\n\tprivate _animateOnZoom = true\n\tget animateOnZoom() {\n\t\treturn this._animateOnZoom\n\t}\n\n\tset animateOnZoom(newValue: boolean) {\n\t\tthis._animateOnZoom = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Zoom to selection\n\n\tprivate _keyboardZoomsToSelection = false\n\tget keyboardZoomsToSelection() {\n\t\treturn this._keyboardZoomsToSelection\n\t}\n\n\tset keyboardZoomsToSelection(newValue: boolean) {\n\t\tthis._keyboardZoomsToSelection = newValue\n\t\tthis.didChange()\n\t}\n\n\tprivate _bannerScrollFeatures = true\n\n\tget bannerScrollFeatures() {\n\t\treturn this._bannerScrollFeatures\n\t}\n\n\tset bannerScrollFeatures(newValue: boolean) {\n\t\tthis._bannerScrollFeatures = newValue\n\t\tthis.didChange()\n\t}\n\n\tprivate _bannerStickyScroll = true\n\n\tget bannerStickyScroll() {\n\t\treturn this._bannerStickyScroll\n\t}\n\n\tset bannerStickyScroll(newValue: boolean) {\n\t\tthis._bannerStickyScroll = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Outline view\n\n\tprivate _performanceMode = false\n\n\tget performanceMode() {\n\t\treturn this._performanceMode\n\t}\n\n\tset performanceMode(newValue) {\n\t\tthis._performanceMode = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Canvas page\n\n\tprivate _canvasPage = false\n\tget canvasPage() {\n\t\treturn this._canvasPage\n\t}\n\n\tset canvasPage(newValue: boolean) {\n\t\tthis._canvasPage = newValue\n\t\tthis.didChange()\n\t}\n\n\tprivate _showScrollToContentToast = true\n\n\tget showScrollToContentToast() {\n\t\treturn this._showScrollToContentToast\n\t}\n\n\tset showScrollToContentToast(newValue) {\n\t\tthis._showScrollToContentToast = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Drafts\n\n\tprivate _newContentAsDraft = true\n\n\tget newContentAsDraft() {\n\t\treturn this._newContentAsDraft\n\t}\n\n\tset newContentAsDraft(newValue) {\n\t\tthis._newContentAsDraft = newValue\n\t\tthis.didChange()\n\t}\n\n\t// P3\n\tprivate _p3 = false\n\tget p3() {\n\t\treturn this._p3\n\t}\n\tset p3(newValue: boolean) {\n\t\tthis._p3 = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Plugins\n\n\tprivate _displayPluginDeveloperTools = false\n\n\tget displayPluginDeveloperTools() {\n\t\treturn this._displayPluginDeveloperTools\n\t}\n\n\tset displayPluginDeveloperTools(newValue: boolean) {\n\t\tthis._displayPluginDeveloperTools = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Close Canvas on Double Click\n\n\tprivate _exitCanvasOnDoubleClick = false\n\n\tget exitCanvasOnDoubleClick() {\n\t\treturn this._exitCanvasOnDoubleClick\n\t}\n\n\tset exitCanvasOnDoubleClick(newValue: boolean) {\n\t\tthis._exitCanvasOnDoubleClick = newValue\n\t\tthis.didChange()\n\t}\n\t// Close Canvas on Double Click\n\n\tprivate _templatesModalOnNewProject = true\n\n\tget templatesModalOnNewProject() {\n\t\treturn this._templatesModalOnNewProject\n\t}\n\n\tset templatesModalOnNewProject(newValue: boolean) {\n\t\tthis._templatesModalOnNewProject = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Agent Model\n\n\tprivate _agentSelectedModel: LanguageModel | null = null\n\n\tget agentSelectedModel(): LanguageModel | null {\n\t\treturn this._agentSelectedModel\n\t}\n\n\tset agentSelectedModel(newValue: LanguageModel | null) {\n\t\tthis._agentSelectedModel = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Agent reasoning effort by model\n\n\tprivate _agentReasoningByModel: Partial<Record<LanguageModel, AgentReasoningEffort>> = {}\n\n\tget agentSelectedReasoningByModel(): Partial<Record<LanguageModel, AgentReasoningEffort>> {\n\t\treturn this._agentReasoningByModel\n\t}\n\n\tset agentSelectedReasoningByModel(newValue: Partial<Record<LanguageModel, AgentReasoningEffort>>) {\n\t\tthis._agentReasoningByModel = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Agent follow mode\n\n\tprivate _agentFollowMode = false\n\n\tget agentFollowMode(): boolean {\n\t\treturn this._agentFollowMode\n\t}\n\n\tset agentFollowMode(newValue: boolean) {\n\t\tthis._agentFollowMode = newValue\n\t\tthis.didChange()\n\t}\n\n\t// Configure the exact Contour model release from the debug bar\n\n\tprivate _contourOverride = resolveContourOverride(defaultContourOverride)\n\n\tget contourOverride(): ContourOverride {\n\t\treturn this._contourOverride\n\t}\n\n\tset contourOverride(newValue: ContourOverride) {\n\t\tthis._contourOverride = resolveContourOverride(newValue)\n\t\tthis.didChange()\n\t}\n\n\t// Store functionality\n\n\tprivate skipDidChange = false\n\n\tconstructor(\n\t\tprivate addChanges: EngineChangeSignal,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\tthis.loadStateFromStorage()\n\t\t// Keep settings synchronized with other tabs.\n\t\tglobalThis.addEventListener(\n\t\t\t\"storage\",\n\t\t\t() => {\n\t\t\t\tthis.loadStateFromStorage()\n\t\t\t\tthis.addChanges(EngineChange.UserDefaultsStore)\n\t\t\t},\n\t\t\t{ signal: abortSignal },\n\t\t)\n\t}\n\n\t/**\n\t * Save changes to storage and notify the engine (unless skipDidChange is\n\t * true).\n\t */\n\tprivate didChange() {\n\t\tif (this.skipDidChange) return\n\t\tlocalStorage[storageKey] = JSON.stringify(this.toJSON())\n\t\tthis.addChanges(EngineChange.UserDefaultsStore)\n\t}\n\n\ttoJSON(): Readonly<PersistedUserDefaultsState> {\n\t\treturn {\n\t\t\talignToParent: this._alignToParent,\n\t\t\tshowPixelGrid: this._showPixelGrid,\n\t\t\tshowHandoff: this._showHandoff,\n\t\t\tdisplayAllLinks: this._displayAllLinks,\n\t\t\tframeBackground: this._frameBackground,\n\t\t\tcolorModel: this._colorModel,\n\t\t\teditorFontSize: this._editorFontSize,\n\t\t\tdisplayRulers: this._displayRulers,\n\t\t\tdisplayGrids: this._displayGrids,\n\t\t\texportCSSType: this._exportCSSType,\n\t\t\texportSVGType: this._exportSVGType,\n\t\t\texportShowAllProps: this._exportShowAllProps,\n\t\t\tsmallNudgeIncrement: this._smallNudgeIncrement,\n\t\t\tlargeNudgeIncrement: this._largeNudgeIncrement,\n\t\t\tlayoutGap: this._layoutGap,\n\t\t\tuseDirectSelect: this._useDirectSelect,\n\t\t\tautoSwitchToLayers: this._autoSwitchToLayers,\n\t\t\tanimateOnZoom: this._animateOnZoom,\n\t\t\treverseZoomDirection: this._reverseZoomDirection,\n\t\t\tfastZoom: this._fastZoom,\n\t\t\tkeyboardZoomsToSelection: this._keyboardZoomsToSelection,\n\t\t\tbannerScrollFeatures: this._bannerScrollFeatures,\n\t\t\tbannerStickyScroll: this._bannerStickyScroll,\n\t\t\tperformanceMode: this._performanceMode,\n\t\t\tcanvasPage: this._canvasPage,\n\t\t\tdisplayPluginDeveloperTools: this._displayPluginDeveloperTools,\n\t\t\tshowScrollToContentToast: this._showScrollToContentToast,\n\t\t\tnewContentAsDraft: this._newContentAsDraft,\n\t\t\tp3: this._p3,\n\t\t\texitCanvasOnDoubleClick: this._exitCanvasOnDoubleClick,\n\t\t\ttemplatesModalOnNewProject: this._templatesModalOnNewProject,\n\t\t\tagentSelectedModel: this._agentSelectedModel,\n\t\t\tagentSelectedReasoningByModel: this._agentReasoningByModel,\n\t\t\tagentFollowMode: this._agentFollowMode,\n\t\t\tcontourOverride: this._contourOverride,\n\t\t}\n\t}\n\n\t/** Load the settings from `localStorage`. Note that this won't emit any changes. */\n\tprivate loadStateFromStorage() {\n\t\tthis.skipDidChange = true\n\t\ttry {\n\t\t\tconst state: unknown = JSON.parse(localStorage[storageKey] || \"{}\")\n\t\t\tif (!this.isPersistedStateObject(state)) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tfor (const key of Object.keys(state)) {\n\t\t\t\tif (!isValidKey(key)) continue\n\t\t\t\tthis.setValue(key, state[key])\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.reportError(error)\n\t\t\tlog.warn(\"Failed to load settings:\", error)\n\t\t} finally {\n\t\t\tthis.skipDidChange = false\n\t\t}\n\t}\n\n\tprivate isPersistedStateObject(state: unknown): state is PersistedUserDefaultsState {\n\t\treturn typeof state === \"object\" && state !== null\n\t}\n\n\tprivate setValue(key: PersistedUserDefaultKey, value: SerializableValue) {\n\t\tswitch (key) {\n\t\t\tcase \"alignToParent\":\n\t\t\tcase \"showPixelGrid\":\n\t\t\tcase \"showHandoff\":\n\t\t\tcase \"displayAllLinks\":\n\t\t\tcase \"displayRulers\":\n\t\t\tcase \"displayGrids\":\n\t\t\tcase \"exportShowAllProps\":\n\t\t\tcase \"useDirectSelect\":\n\t\t\tcase \"autoSwitchToLayers\":\n\t\t\tcase \"animateOnZoom\":\n\t\t\tcase \"reverseZoomDirection\":\n\t\t\tcase \"fastZoom\":\n\t\t\tcase \"keyboardZoomsToSelection\":\n\t\t\tcase \"bannerScrollFeatures\":\n\t\t\tcase \"bannerStickyScroll\":\n\t\t\tcase \"performanceMode\":\n\t\t\tcase \"canvasPage\":\n\t\t\tcase \"displayPluginDeveloperTools\":\n\t\t\tcase \"showScrollToContentToast\":\n\t\t\tcase \"newContentAsDraft\":\n\t\t\tcase \"p3\":\n\t\t\tcase \"exitCanvasOnDoubleClick\":\n\t\t\tcase \"templatesModalOnNewProject\":\n\t\t\tcase \"agentFollowMode\":\n\t\t\t\tif (isBoolean(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"editorFontSize\":\n\t\t\tcase \"smallNudgeIncrement\":\n\t\t\tcase \"largeNudgeIncrement\":\n\t\t\tcase \"layoutGap\":\n\t\t\t\tif (isNumber(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"frameBackground\":\n\t\t\t\tif (isString(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"colorModel\":\n\t\t\t\tif (isColorModel(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"exportCSSType\":\n\t\t\t\tif (isCSSExportType(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"exportSVGType\":\n\t\t\t\tif (isSVGExportType(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"agentSelectedModel\":\n\t\t\t\tif (isLanguageModel(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\tcase \"agentSelectedReasoningByModel\": {\n\t\t\t\tif (isAgentModelEfforts(value)) this[key] = value\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase \"contourOverride\":\n\t\t\t\tthis[key] = resolveContourOverride(value)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\thandleUnknownUserDefaultKey(key)\n\t\t}\n\t}\n}\n\nfunction isValidKey(key: string): key is keyof PersistedUserDefaultsState {\n\t// Cast the key to the safe type even if it might not be safe so we can rely\n\t// on exhaustive checking. We still handle unknown keys in the default case.\n\tconst typedKey = key as PersistedUserDefaultKey\n\tswitch (typedKey) {\n\t\tcase \"alignToParent\":\n\t\tcase \"showPixelGrid\":\n\t\tcase \"showHandoff\":\n\t\tcase \"displayAllLinks\":\n\t\tcase \"displayRulers\":\n\t\tcase \"displayGrids\":\n\t\tcase \"editorFontSize\":\n\t\tcase \"frameBackground\":\n\t\tcase \"colorModel\":\n\t\tcase \"exportCSSType\":\n\t\tcase \"exportSVGType\":\n\t\tcase \"exportShowAllProps\":\n\t\tcase \"smallNudgeIncrement\":\n\t\tcase \"largeNudgeIncrement\":\n\t\tcase \"layoutGap\":\n\t\tcase \"useDirectSelect\":\n\t\tcase \"autoSwitchToLayers\":\n\t\tcase \"animateOnZoom\":\n\t\tcase \"reverseZoomDirection\":\n\t\tcase \"fastZoom\":\n\t\tcase \"keyboardZoomsToSelection\":\n\t\tcase \"bannerScrollFeatures\":\n\t\tcase \"bannerStickyScroll\":\n\t\tcase \"performanceMode\":\n\t\tcase \"canvasPage\":\n\t\tcase \"displayPluginDeveloperTools\":\n\t\tcase \"showScrollToContentToast\":\n\t\tcase \"newContentAsDraft\":\n\t\tcase \"p3\":\n\t\tcase \"exitCanvasOnDoubleClick\":\n\t\tcase \"templatesModalOnNewProject\":\n\t\tcase \"agentSelectedModel\":\n\t\tcase \"agentSelectedReasoningByModel\":\n\t\tcase \"agentFollowMode\":\n\t\tcase \"contourOverride\":\n\t\t\treturn true\n\t\tdefault:\n\t\t\thandleUnknownUserDefaultKey(typedKey)\n\t\t\treturn false\n\t}\n}\n\nfunction handleUnknownUserDefaultKey(key: never) {\n\tlog.warn(\"Unknown user default key:\", key)\n}\n", "import type { Asset } from \"@framerjs/assets\"\nimport { environment } from \"@framerjs/framer-environment\"\nimport { getLogger, unhandledError } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { TextNode } from \"document/models/CanvasTree/index.ts\"\nimport { PresetsListNode } from \"document/models/CanvasTree/nodes/PresetsListNode.ts\"\nimport { isAnyTextNode } from \"document/models/CanvasTree/nodes/utils/isAnyTextNode.ts\"\nimport type { FontshareFont } from \"library/render/fonts/FontshareSource.ts\"\nimport type { GoogleWebFontFamily, GoogleWebFontFamilyWithAxes } from \"library/render/fonts/GoogleFontSource.ts\"\nimport { fontStore } from \"library/render/fonts/fontStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst log = getLogger(\"app:webFontStore\")\n\nexport class WebFontStore extends EngineStore {\n\tgoogleWebFonts: { staticFonts: GoogleWebFontFamily[]; variableFonts: GoogleWebFontFamilyWithAxes[] } | undefined\n\tfontshareFonts: FontshareFont[] | undefined\n\tbuiltinFonts: Asset[] | undefined\n\n\tconstructor(private readonly treeStore: TreeStore) {\n\t\tsuper()\n\t}\n\n\t/**\n\t * This \u201Cloads\u201D fonts = actually loads the font files for the browser to\n\t * use. Note (TODO?): while the difference between \u201Cimport\u201D/\u201Cload\u201D is\n\t * confusing, the methods are named this way to aligns with the library,\n\t * which we can\u2019t rename easily.\n\t * https://github.com/framer/FramerStudio/pull/15778#discussion_r1395118062\n\t */\n\tasync loadFontsFromTree() {\n\t\tconst loadFontsPromises: Promise<unknown>[] = []\n\t\tconst nodeIdsToUpdate: string[] = []\n\n\t\tconst tree = this.treeStore.tree\n\t\ttree.beginAllowPartialScopeAccess()\n\t\tfor (const node of tree.root.walk()) {\n\t\t\tif (isAnyTextNode(node)) {\n\t\t\t\tconst fontSelectors = node.getFontsForLoading()\n\t\t\t\tconst promise = fontStore\n\t\t\t\t\t.loadFonts(fontSelectors)\n\t\t\t\t\t.then(({ newlyLoadedFontCount }) => {\n\t\t\t\t\t\tif (newlyLoadedFontCount > 0) nodeIdsToUpdate.push(node.id)\n\t\t\t\t\t})\n\t\t\t\t\t.catch(unhandledError)\n\n\t\t\t\tloadFontsPromises.push(promise)\n\t\t\t}\n\t\t}\n\n\t\tconst listNode = PresetsListNode.get(this.treeStore.tree)\n\t\tif (listNode) {\n\t\t\tconst presets = listNode.getTextStylePresets()\n\t\t\tif (presets.length > 0) {\n\t\t\t\tconst fonts = presets.map(preset => preset.font)\n\t\t\t\tconst promise = fontStore.loadFonts(fonts).catch(unhandledError)\n\t\t\t\tloadFontsPromises.push(promise)\n\t\t\t}\n\t\t}\n\t\ttree.endAllowPartialScopeAccess()\n\n\t\tawait Promise.all(loadFontsPromises)\n\n\t\tTextNode.updateNodes?.(nodeIdsToUpdate)\n\t}\n\n\t/**\n\t * This \u201Cimports\u201D fonts = tells Framer about all Google and Fontshare fonts\n\t * that exist, but doesn\u2019t necessarily load them. Note (TODO?): while the\n\t * difference between \u201Cimport\u201D/\u201Cload\u201D is confusing, the methods are named\n\t * this way to aligns with the library, which we can\u2019t rename easily.\n\t * https://github.com/framer/FramerStudio/pull/15778#discussion_r1395118062\n\t */\n\tasync importFonts() {\n\t\tconst loadGoogleAndFontshareFonts = async () => {\n\t\t\tif (!this.fontshareFonts) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.fontshareFonts = await fontStore.importFontshareFonts()\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (!environment.isTest) log.reportError(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!this.googleWebFonts) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.googleWebFonts = await fontStore.importGoogleFonts()\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (!environment.isTest) log.reportError(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst loadBuiltInFonts = async () => {\n\t\t\tif (!this.builtinFonts) {\n\t\t\t\ttry {\n\t\t\t\t\tthis.builtinFonts = await fontStore.importBuiltInFonts()\n\t\t\t\t} catch (e) {\n\t\t\t\t\t// Don't log errors in test env because this is fine to fail\n\t\t\t\t\t// silently in some tests, but logging errors will make them\n\t\t\t\t\t// fail.\n\t\t\t\t\tif (!environment.isTest) log.reportError(e)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tawait Promise.all([loadGoogleAndFontshareFonts(), loadBuiltInFonts()])\n\t}\n}\n", "import { channelToParentFrame, localChannel } from \"@framerjs/framer-services\"\nimport { environment } from \"environment/index.ts\"\n\nexport const channelToElectron = channelToParentFrame\n// In an automation session, this channel goes to the automation \"controller\",\n// i.e., the code outside the browser that steers the automation session. See\n// for example, EditorSession.ts => loadEditor, which registers some services on\n// this channel.\nexport const channelToWebOrAutomation = environment.isAutomation ? channelToParentFrame : localChannel\n", "import { ModulesAPI, handleServiceError } from \"@framerjs/framer-services\"\nimport { getModulesAPIStub } from \"../utils/modulesService.ts\"\nimport { channelToWebOrAutomation } from \"../utils/serviceChannels.ts\"\n\nexport async function getModulesAPI(): Promise<ModulesAPI.Interface | undefined> {\n\tif (process.env.NODE_ENV === \"test\") {\n\t\treturn getModulesAPIStub()\n\t}\n\n\treturn ModulesAPI.on(channelToWebOrAutomation).discover().catch(handleServiceError)\n}\n", "import type { ACLEntry, UserACLEntry } from \"@framerjs/app-shared\"\nimport { ACLEntryKind, getMultiplayerColor } from \"@framerjs/app-shared\"\nimport { MAIN_BRANCH_ID } from \"@framerjs/crdtree2\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport { motionValue } from \"framer-motion\"\nimport { isEqual } from \"library/index.ts\"\nimport type { PreviewNodeUserState, UserStateData } from \"socket/types.ts\"\nimport { EngineChange, type EngineChanges } from \"./EngineChanges.ts\"\nimport type { RemoteDocumentConnection } from \"./RemoteDocumentHandler.ts\"\nimport type { CanvasStore } from \"./stores/CanvasStore.ts\"\nimport type { MouseStore } from \"./stores/MouseStore.ts\"\nimport type { ScopeStore } from \"./stores/ScopeStore.ts\"\nimport type { TreeStore } from \"./stores/TreeStore.ts\"\n\nexport class RemoteCursor {\n\tid: string\n\tlastActive = -Infinity\n\tlastChange = 0\n\tisIdle = true\n\n\tx = motionValue(0)\n\ty = motionValue(0)\n\tzoom = 1\n\tscroll = { x: 0, y: 0 }\n\tpreviewNode: PreviewNodeUserState | null = null\n\n\tchat = \"\"\n\tpageId = \"\"\n\tbranchId = MAIN_BRANCH_ID\n\n\tuserName = \"\"\n\tshortUserName = \"\"\n\tcolor = 0\n\n\tconstructor(readonly userId: string) {\n\t\tthis.id = userId + Math.floor(Math.random() * 1000)\n\t}\n\n\tgetHexColor(isDarkMode: boolean): string {\n\t\treturn getMultiplayerColor(this.color, isDarkMode)\n\t}\n\n\thandleCursorUpdate(data: UserStateData, now: number) {\n\t\tthis.lastActive = now\n\n\t\t// We don't signal changes if only x or y changed, because they are motion values and will\n\t\t// re-render automatically and cheaply when set.\n\t\tif (data.x !== undefined && data.x !== this.x.get()) {\n\t\t\tthis.x.set(data.x)\n\t\t}\n\t\tif (data.y !== undefined && data.y !== this.y.get()) {\n\t\t\tthis.y.set(data.y)\n\t\t}\n\n\t\t// Any other change will have to trigger an engine cycle.\n\t\tlet changed = false\n\n\t\tif (this.isIdle) {\n\t\t\tthis.isIdle = false\n\t\t\tchanged = true\n\t\t}\n\n\t\tif (data.pageId !== undefined && data.pageId !== this.pageId) {\n\t\t\tchanged = true\n\t\t\tthis.pageId = data.pageId\n\t\t}\n\t\tif (data.branchId !== undefined && data.branchId !== this.branchId) {\n\t\t\tchanged = true\n\t\t\tthis.branchId = data.branchId\n\t\t}\n\t\tif (data.chat !== undefined && this.chat !== data.chat) {\n\t\t\tchanged = true\n\t\t\tthis.chat = data.chat\n\t\t}\n\t\tif (data.zoom !== undefined && this.zoom !== data.zoom) {\n\t\t\tchanged = true\n\t\t\tthis.zoom = data.zoom\n\t\t}\n\t\tif (data.scroll !== undefined && this.scroll !== data.scroll) {\n\t\t\tchanged = true\n\t\t\tthis.scroll = data.scroll\n\t\t}\n\t\tif (data.previewNode !== undefined && data.previewNode !== this.previewNode) {\n\t\t\tchanged = true\n\t\t\tthis.previewNode = data.previewNode\n\t\t}\n\n\t\tif (!changed) return\n\n\t\tthis.lastChange = now\n\t}\n\n\thandleUserUpdate(data: UserACLEntry, now: number) {\n\t\tlet changed = false\n\t\tif (data.user.name && data.user.name !== this.userName) {\n\t\t\tchanged = true\n\t\t\tthis.userName = data.user.name\n\t\t\tthis.shortUserName = this.userName.split(\" \")[0]\n\t\t}\n\t\tif (data.color && data.color !== this.color) {\n\t\t\tchanged = true\n\t\t\tthis.color = data.color\n\t\t}\n\n\t\tif (!changed) return\n\n\t\tthis.lastChange = now\n\t}\n\n\tclearIdle() {\n\t\tconst now = performance.now()\n\t\tthis.lastActive = now\n\t\tthis.lastChange = now\n\t\tthis.isIdle = false\n\t}\n\n\tupdateIdle(now: number): void {\n\t\tconst isIdle = now - this.lastActive > 5000\n\t\tif (this.isIdle !== isIdle) {\n\t\t\tthis.isIdle = isIdle\n\t\t\tthis.lastChange = now\n\t\t}\n\t}\n}\n\n/** Tracks remote user data and cursors. Will only signal changes if any data actually changed. */\nexport class RemoteUsers {\n\tprivate lastChange = 0\n\tprivate cursorMap = new Map<string, RemoteCursor>()\n\tprivate localUserId = \"\"\n\n\t/** Current list of remote cursors. */\n\tcursors: RemoteCursor[] = []\n\n\t/** If the UI is in dark mode or not. Which changes the remote user rgb color value. */\n\tisDarkMode = false\n\n\tconstructor(\n\t\tprivate readonly scheduler: VekterEngineScheduler,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly canvasStore: CanvasStore,\n\t\tprivate readonly mouseStore: MouseStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly changes: EngineChanges,\n\t\tprivate readonly getRemoteConnectionManager: () => RemoteDocumentConnection | null,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\tthis.changes.observe(\n\t\t\tEngineChange.CanvasStore,\n\t\t\tEngineChange.CanvasLiveTransform,\n\t\t\tEngineChange.CanvasZoom,\n\t\t\tEngineChange.MouseStore,\n\t\t\tEngineChange.TreeStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.handleUserStateChange,\n\t\t)\n\n\t\tconst tickIntervalId = setInterval(() => {\n\t\t\tthis.tick()\n\t\t}, 500)\n\t\tabortSignal?.addEventListener(\"abort\", () => clearInterval(tickIntervalId))\n\t}\n\n\tprivate onChange() {\n\t\t// All the changes happening are either timers or socket messages. So we have to use\n\t\t// processWhenReady.\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tthis.changes.addChanges(EngineChange.RemoteUsersStore)\n\t\t\tthis.changes.addChanges(EngineChange.MouseStore)\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tgetRemoteUserCount(): number {\n\t\t// Count only remote editors.\n\t\treturn this.cursorMap.size - (this.cursorMap.has(this.localUserId) ? 1 : 0)\n\t}\n\n\tsetLocalUserId(userId: string) {\n\t\tthis.localUserId = userId\n\t}\n\n\t/** Returns a cursor for the current user, if any. */\n\tgetCursor(userId: string): RemoteCursor | undefined {\n\t\treturn this.cursorMap.get(userId)\n\t}\n\n\tprivate updateCursorList() {\n\t\tthis.cursors = Array.from(this.cursorMap.values())\n\t\tthis.onChange()\n\t}\n\n\tsetDarkMode(isDarkMode: boolean) {\n\t\tif (this.isDarkMode === isDarkMode) return\n\t\tthis.isDarkMode = isDarkMode\n\t\tthis.onChange()\n\t}\n\n\t/** Called at a regular interval to update cursors that are idle. */\n\tprivate tick(): void {\n\t\tconst now = performance.now()\n\t\tfor (const cursor of this.cursorMap.values()) {\n\t\t\tcursor.updateIdle(now)\n\t\t\tif (cursor.lastChange === now) {\n\t\t\t\tthis.lastChange = now\n\t\t\t}\n\t\t}\n\n\t\tif (this.lastChange === now) {\n\t\t\tthis.updateCursorList()\n\t\t}\n\t}\n\n\thandleLeave(userId: string) {\n\t\tthis.cursorMap.delete(userId)\n\t\tthis.lastChange = performance.now()\n\t\tthis.updateCursorList()\n\t}\n\n\thandleCursorUpdate(userId: string, data: UserStateData) {\n\t\tif (userId === this.localUserId) return\n\n\t\tlet cursor = this.cursorMap.get(userId)\n\t\tif (!cursor) {\n\t\t\tcursor = new RemoteCursor(userId)\n\t\t\tthis.cursorMap.set(userId, cursor)\n\t\t}\n\t\tconst now = performance.now()\n\t\tcursor.handleCursorUpdate(data, now)\n\n\t\tif (cursor.lastChange === now) {\n\t\t\tthis.lastChange = now\n\t\t\tthis.updateCursorList()\n\t\t}\n\t}\n\n\tprivate handleUserUpdate(userId: string, update: UserACLEntry, now: number) {\n\t\tlet cursor = this.cursorMap.get(userId)\n\t\tif (!cursor) {\n\t\t\tcursor = new RemoteCursor(userId)\n\t\t\tthis.cursorMap.set(userId, cursor)\n\t\t}\n\n\t\tcursor.handleUserUpdate(update, now)\n\t\tif (cursor.lastChange === now) {\n\t\t\tthis.lastChange = now\n\t\t}\n\t}\n\n\thandleUserUpdates(updates: Record<string, ACLEntry | undefined>) {\n\t\tconst now = performance.now()\n\t\tfor (const userId in updates) {\n\t\t\tconst update = updates[userId]\n\t\t\tif (update?.kind !== ACLEntryKind.User) continue\n\t\t\tthis.handleUserUpdate(userId, update, now)\n\t\t}\n\n\t\tif (this.lastChange === now) {\n\t\t\tthis.updateCursorList()\n\t\t}\n\t}\n\n\t/** Spectates a specific user. */\n\tsetSpectatedUser(userId: string) {\n\t\tconst cursor = this.getCursor(userId)\n\t\tif (!cursor) return\n\n\t\tconst { pageId, scroll, zoom = 1 } = cursor\n\t\tif (!pageId) return\n\n\t\t// Make sure the cursor is showing up even if the user is actually idle.\n\t\tcursor.clearIdle()\n\n\t\t// For now we just take the current user to the specified user's location in the project.\n\t\t// TODO: Keep following the spectated user's viewport, indicating to both users what's going on.\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tif (this.scopeStore.active?.id === pageId) {\n\t\t\t\tif (!scroll) return\n\t\t\t\t// Already on the page, animate to it.\n\t\t\t\tthis.canvasStore.scrollToCenter(scroll, { animate: true, zoom })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Different page, switch to it (instantly setting scroll and zoom).\n\t\t\ttry {\n\t\t\t\tthis.scopeStore.select(pageId, { keepHistory: false })\n\t\t\t\tif (!scroll) return\n\t\t\t\tthis.canvasStore.scrollToCenter(scroll, { zoom })\n\t\t\t} catch {\n\t\t\t\t// Scope did not exist.\n\t\t\t\treturn\n\t\t\t}\n\t\t})\n\t}\n\n\t#lastUserState?: Pick<UserStateData, \"x\" | \"y\" | \"pageId\" | \"branchId\" | \"scroll\" | \"zoom\">\n\t#lastUserStateTime = 0\n\t#updateUserStateTimerId: number | undefined\n\tprivate handleUserStateChange = () => {\n\t\t// Don't compete with other tabs.\n\t\tif (window.document.hidden) return\n\n\t\tconst connectionManager = this.getRemoteConnectionManager()\n\t\tif (!connectionManager) return\n\n\t\tconst pageId = this.scopeStore.activeId\n\t\tconst branchId = this.treeStore.branchId\n\t\tlet { x, y } = this.mouseStore.canvasMousePosition\n\t\t// Round numeric values both to reduce diffs and so that their JSON representation is smaller.\n\t\tx = Math.round(x * 100) / 100\n\t\ty = Math.round(y * 100) / 100\n\t\tlet { zoom } = this.canvasStore\n\t\tzoom = Math.round(zoom * 100) / 100\n\t\tconst scroll = this.canvasStore.getViewportCenter()\n\t\tscroll.x = Math.round(scroll.x * 10) / 10\n\t\tscroll.y = Math.round(scroll.y * 10) / 10\n\n\t\t// If the state didn't change since last time, don't try to send it (in case we got here because of other reasons).\n\t\tconst newState = { x, y, pageId, branchId, scroll, zoom }\n\t\tif (isEqual(newState, this.#lastUserState, true)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (this.#updateUserStateTimerId) {\n\t\t\twindow.clearTimeout(this.#updateUserStateTimerId)\n\t\t}\n\t\t// Send cursor updates less often as latency increases.\n\t\tconst now = performance.now()\n\t\tconst timeSinceLastSend = now - this.#lastUserStateTime\n\t\tconst singleTripTime = Math.max(50, connectionManager.rtt() / 2)\n\t\tif (timeSinceLastSend < singleTripTime) {\n\t\t\tthis.#updateUserStateTimerId = window.setTimeout(\n\t\t\t\tthis.handleUpdateUserStateTimer,\n\t\t\t\tsingleTripTime - timeSinceLastSend,\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tthis.#updateUserStateTimerId = undefined\n\t\tthis.#lastUserState = newState\n\t\tthis.#lastUserStateTime = now\n\t\t// Send the cursor information. We don't need to worry about sending repetitive data, it will get optimized.\n\t\tconnectionManager.updateUserState(newState)\n\t}\n\n\tprivate handleUpdateUserStateTimer = () => {\n\t\tif (!this.#updateUserStateTimerId) return\n\t\tthis.#updateUserStateTimerId = undefined\n\t\tthis.handleUserStateChange()\n\t}\n}\n", "/**\n * Simple array-backed circular buffer implementation. It will only hold up to `capacity` number of items\n * after which newer items will overwrite older ones.\n *\n * Example:\n *\n * const buffer = new CircularBuffer<string>(3)\n *\n * buffer.add(\"a\")\n * buffer.add(\"b\")\n * buffer.add(\"c\")  // buffer is now [\"a\", \"b\", \"c\"]\n * buffer.add(\"d\")  // buffer is now [\"b\", \"c\", \"d\"]\n *\n * buffer.get(-1)   // last element - \"d\"\n * buffer.get(0)    // first element - \"b\"\n *\n */\n\nexport class CircularBuffer<T> {\n\tprivate cursor: number = 0\n\tprivate buffer: T[] = []\n\n\tconstructor(private capacity: number) {}\n\n\tadd(item: T) {\n\t\tthis.buffer[this.cursor] = item\n\t\tthis.cursor = (this.cursor + 1) % this.capacity\n\t}\n\n\tget(index: number): T | undefined {\n\t\tif (index < 0) {\n\t\t\tindex += this.buffer.length\n\t\t}\n\n\t\tif (index < 0 || index > this.buffer.length) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (this.buffer.length < this.capacity) {\n\t\t\treturn this.buffer[index]\n\t\t}\n\n\t\treturn this.buffer[(this.cursor + index) % this.capacity]\n\t}\n\n\tclear() {\n\t\tthis.buffer = []\n\t\tthis.cursor = 0\n\t}\n\n\ttoArray() {\n\t\treturn this.buffer.slice(this.cursor).concat(this.buffer.slice(0, this.cursor))\n\t}\n}\n", "import { Events } from \"@framerjs/fresco/layout-transitions\"\nimport { isAppleDevice, isFirefox } from \"@framerjs/shared\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport type { CanvasStore } from \"document/stores/CanvasStore.ts\"\nimport type { MouseStore } from \"document/stores/MouseStore.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport type React from \"react\"\nimport { CircularBuffer } from \"utils/CircularBuffer.ts\"\nimport { disableAppPointerEvents, enableAppPointerEvents } from \"utils/appPointerEvents.ts\"\nimport { mouseDidMove } from \"utils/mouseDidMove.ts\"\n\nconst mouseMoveThreshold = 3\nconst doubleClickTimeout = 300 // ms\n\nexport class CanvasMouseTarget {\n\tprivate clientPointForMouseMoveThreshold: Point | null = null\n\tprivate lastMouseUpTimestamp = 0\n\tprivate lastMouseUpPosition: Point | null = null\n\tprivate recentMouseDownPositions = new CircularBuffer<Point>(2)\n\n\tconstructor(\n\t\tprivate readonly scheduler: VekterEngineScheduler,\n\t\tprivate readonly canvasStore: CanvasStore,\n\t\tprivate readonly mouseStore: MouseStore,\n\t) {}\n\n\tgetPointsFromEvent(event: MouseEvent): [Point, Point] {\n\t\tconst canvasPoint = this.canvasStore.convertContainerPointToCanvas({\n\t\t\tx: event.pageX,\n\t\t\ty: event.pageY,\n\t\t})\n\t\tconst clientPoint = {\n\t\t\tx: event.clientX,\n\t\t\ty: event.clientY,\n\t\t}\n\t\treturn [canvasPoint, clientPoint]\n\t}\n\n\thandleMouseDown(event: React.MouseEvent, type: \"mousedown\" | \"autoscroll\") {\n\t\tconst isMiddleMouseClick = Events.isMiddleMouseClick(event)\n\t\tif (!Events.isLeftMouseClick(event) && !isMiddleMouseClick) return\n\n\t\tconst mouse = this.mouseStore\n\t\tconst [canvasPoint, clientPoint] = this.getPointsFromEvent(event.nativeEvent)\n\t\t// eslint-disable-next-line no-restricted-syntax -- Intentional for symmetry\n\t\tconst metaOrCtrl = isAppleDevice() ? event.metaKey : event.ctrlKey\n\t\t// eslint-disable-next-line no-restricted-syntax -- Intentional for symmetry\n\t\tconst ctrlOrMeta = isAppleDevice() ? event.ctrlKey : event.metaKey\n\n\t\t// On windows 10, in what looks like rare cases, event.pageX/Y and .clientX/Y seem to be\n\t\t// missing. Simply ignore those events for mouse position handling.\n\t\tif (Number.isFinite(canvasPoint.x) && Number.isFinite(canvasPoint.y)) {\n\t\t\tthis.clientPointForMouseMoveThreshold = clientPoint\n\t\t\tmouse.setMousePosition(canvasPoint, clientPoint, event.altKey, metaOrCtrl, event.shiftKey, ctrlOrMeta)\n\t\t\tthis.recentMouseDownPositions.add(canvasPoint)\n\t\t}\n\n\t\tmouse.setDoubleClick(false)\n\n\t\tif (type === \"mousedown\") {\n\t\t\tif (isMiddleMouseClick) {\n\t\t\t\tmouse.setMiddleButtonDown(true)\n\t\t\t} else {\n\t\t\t\tmouse.setMouseDown(true)\n\t\t\t}\n\t\t} else {\n\t\t\tthis.canvasStore.beginAutoscrolling()\n\t\t}\n\n\t\t// While the mouse is down, we can get a move listener (only on documentElement) to produce events outside the window, allowing for a much better autoscrolling and path adjustment experience\n\t\tthis.addDocumentElementMouseMoveHandler()\n\t}\n\n\thandleMouseUp(event: React.MouseEvent) {\n\t\tthis.removeDocumentElementMouseMoveHandler()\n\t\tthis.clientPointForMouseMoveThreshold = null\n\n\t\tif (this.canvasStore.isAutoScrolling()) {\n\t\t\tthis.canvasStore.endAutoscrolling()\n\t\t}\n\n\t\t// Mouse events from outside the window will have button and buttons be undefined.\n\t\tconst mouse = this.mouseStore\n\t\tif (\n\t\t\tevent.button === undefined ||\n\t\t\tEvents.isLeftMouseButton(event) ||\n\t\t\t// In macOS Firefox Ctrl+LMB is reported as RMB no matter what\n\t\t\t(isAppleDevice() && isFirefox() && event.ctrlKey && Events.isRightMouseButton(event))\n\t\t) {\n\t\t\tmouse.setMouseDown(false)\n\t\t}\n\t\tif (event.button === undefined || Events.isMiddleMouseClick(event)) {\n\t\t\tmouse.setMiddleButtonDown(false)\n\t\t}\n\t\tenableAppPointerEvents()\n\n\t\tthis.handleSyntheticDoubleClick(event)\n\t}\n\n\thandleSyntheticDoubleClick(event: React.MouseEvent) {\n\t\tconst [mouseUpPosition] = this.getPointsFromEvent(event.nativeEvent)\n\t\tthis.lastMouseUpPosition = mouseUpPosition\n\n\t\tconst now = performance.now()\n\t\tconst mouse = this.mouseStore\n\t\tconst firstClickMouseDown = this.recentMouseDownPositions.get(-2)\n\t\tconst timeBetweeenMouseUps = now - this.lastMouseUpTimestamp\n\n\t\t// For an event to be qualified as a synthetic double click, it needs to:\n\t\t// 1) be a mouse up event that happened within 300 ms of another mouse up event\n\t\t// 2) be at the same position as the mouse down before the last mouse down,\n\t\t// indicating that the mouse didn't move or drag between mouse down and second mouse up\n\t\tif (\n\t\t\tfirstClickMouseDown &&\n\t\t\tthis.lastMouseUpPosition &&\n\t\t\t!mouseDidMove(firstClickMouseDown, this.lastMouseUpPosition) &&\n\t\t\ttimeBetweeenMouseUps <= doubleClickTimeout\n\t\t) {\n\t\t\tmouse.setDoubleClick(true)\n\n\t\t\t// prevents triple clicks\n\t\t\tthis.lastMouseUpTimestamp = 0\n\t\t} else {\n\t\t\tthis.lastMouseUpTimestamp = now\n\t\t\tmouse.setDoubleClick(false)\n\t\t}\n\t}\n\n\thandleMouseMove(event: React.MouseEvent) {\n\t\tthis.handleNativeMouseMove(event.nativeEvent)\n\t}\n\n\tprivate handleDocumentElementMouseMove = (moveEvent: MouseEvent) => {\n\t\tthis.scheduler.process(() => {\n\t\t\tmoveEvent.stopPropagation()\n\t\t\tthis.handleNativeMouseMove(moveEvent)\n\t\t})\n\t}\n\n\tprivate handleNativeMouseMove = (nativeEvent: MouseEvent) => {\n\t\tconst [canvasPoint, clientPoint] = this.getPointsFromEvent(nativeEvent)\n\t\tconst mouse = this.mouseStore\n\n\t\tif (this.clientPointForMouseMoveThreshold) {\n\t\t\tif (Point.distance(clientPoint, this.clientPointForMouseMoveThreshold) < mouseMoveThreshold) {\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\tdisableAppPointerEvents()\n\t\t\t\tthis.clientPointForMouseMoveThreshold = null\n\t\t\t}\n\t\t}\n\n\t\tconst metaOrCtrl = isAppleDevice() ? nativeEvent.metaKey : nativeEvent.ctrlKey\n\t\tconst ctrlOrMeta = isAppleDevice() ? nativeEvent.ctrlKey : nativeEvent.metaKey\n\t\tmouse.setMousePosition(canvasPoint, clientPoint, nativeEvent.altKey, metaOrCtrl, nativeEvent.shiftKey, ctrlOrMeta)\n\t\tmouse.setDoubleClick(false)\n\t}\n\n\tprivate hasDocumentElementMouseMoveHandler = false\n\n\tprivate addDocumentElementMouseMoveHandler() {\n\t\tif (!this.hasDocumentElementMouseMoveHandler) {\n\t\t\tthis.hasDocumentElementMouseMoveHandler = true\n\t\t\tdocument.documentElement.addEventListener(\"mousemove\", this.handleDocumentElementMouseMove)\n\t\t}\n\t}\n\n\tprivate removeDocumentElementMouseMoveHandler() {\n\t\tif (this.hasDocumentElementMouseMoveHandler) {\n\t\t\tdocument.documentElement.removeEventListener(\"mousemove\", this.handleDocumentElementMouseMove)\n\t\t\tthis.hasDocumentElementMouseMoveHandler = false\n\t\t}\n\t}\n}\n", "import type { AssistantModelMessage, SystemModelMessage, UserModelMessage } from \"ai\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport z from \"zod\"\nimport type { Command } from \"../orchestrator/dsl.ts\"\n\nexport enum StepStatus {\n\tPending,\n\tLoading,\n\tDone,\n\tError,\n}\n\nexport interface Step {\n\tdescription: string\n\tstatus: StepStatus\n}\n\nexport const SuggestionVariant = z.enum([\"prompt\", \"resource\"])\nexport type SuggestionVariant = z.infer<typeof SuggestionVariant>\n\nexport const PromptSuggestion = z.object({\n\tvariant: z.literal(SuggestionVariant.enum.prompt).describe(\"The type of suggestion. Should be literal 'prompt'.\"),\n\ttext: z.string().describe(\"Concise one-liner summary of the suggestion. Maximum 30 characters.\"),\n\tprompt: z\n\t\t.string()\n\t\t.describe(\n\t\t\t\"Detailed description of the suggestion, which will be used as the new user prompt to follow up this response.\",\n\t\t),\n})\n\nexport type PromptSuggestion = z.infer<typeof PromptSuggestion>\n\nexport const ResourceSuggestion = z.object({\n\tvariant: z.literal(SuggestionVariant.enum.resource).describe(\"The type of suggestion. Should be literal 'resource'.\"),\n\ttext: z\n\t\t.string()\n\t\t.describe(\n\t\t\t\"Concise one-liner title of the suggested resource. Maximum 3 words. Rewrite the title if it's too long.\",\n\t\t),\n\turl: z.string().describe(\"The url of the suggested resource.\"),\n})\n\nexport type ResourceSuggestion = z.infer<typeof ResourceSuggestion>\n\nexport type Suggestion = PromptSuggestion | ResourceSuggestion\n\nexport interface AssistantContent {\n\tmultiStepPlan?: boolean\n\tmessage: string\n\tsteps?: Step[]\n\t/** The raw DSL commands returned by the orchestrator. Used to maintain DSL format in conversation history. */\n\tdslCommands?: Command[]\n\tsuggestions?: {\n\t\toptions: Suggestion[]\n\t\t// If the suggestions are tied to a specific page, we will only render them on that page.\n\t\ttargetPageId?: NodeID\n\t}\n}\n\ninterface AIChatMessageBase {\n\ttimestamp: number\n}\n\nexport interface AIAssistantMessage\n\textends AIChatMessageBase, Omit<AssistantModelMessage, \"providerOptions\" | \"content\"> {\n\tcontent: AssistantContent\n}\n\nexport function isAssistantMessage(message: AIChatMessage): message is AIAssistantMessage {\n\treturn message.role === \"assistant\"\n}\n\ninterface AISystemMessage extends AIChatMessageBase, Omit<SystemModelMessage, \"providerOptions\"> {}\n\nexport interface AIUserMessage extends AIChatMessageBase, Omit<UserModelMessage, \"providerOptions\" | \"content\"> {\n\tcontent: string\n\tisSuggestion: boolean\n\tsource: \"query_parameters\" | \"panel\"\n}\n\nexport type AIChatMessage = AIAssistantMessage | AIUserMessage | AISystemMessage\n\nexport type AIChatHistory = AIChatMessage[]\n", "import { assert, isEmptyObject } from \"@framerjs/shared\"\nimport { isArray, isUndefined } from \"utils/typeChecks.ts\"\nimport z from \"zod\"\n\nexport const COMMAND_SEPARATOR = \";\"\n\n/**\n * Command types\n */\nexport enum CommandType {\n\tAddCMSItems = \"ADD_CMS_ITEMS\",\n\tCreateCMSCollectionWithItems = \"CREATE_CMS_COLLECTION_WITH_ITEMS\",\n\tCreateCMSPage = \"CREATE_CMS_PAGE\",\n\tCreatePage = \"CREATE_PAGE\",\n\tDeletePage = \"DELETE_PAGE\",\n\tPlan = \"PLAN\",\n\tReject = \"REJECT\",\n\tThemePage = \"THEME_PAGE\",\n\tUpdateCMSItems = \"UPDATE_CMS_ITEMS\",\n\tUpdatePage = \"UPDATE_PAGE\",\n}\n\nexport enum PageMode {\n\tLight = \"LIGHT\",\n\tDark = \"DARK\",\n}\n\nconst commandTypesSet = new Set<string>(Object.values(CommandType))\nconst whitespaceSeparatorRegex = /\\s+/\n\nconst PlanCommandSchema = z.object({\n\ttype: z.literal(CommandType.Plan),\n})\n\nconst CreatePageCommandSchema = z.object({\n\ttype: z.literal(CommandType.CreatePage),\n\tattributes: z.object({\n\t\tpath: z.string(),\n\t\tname: z.string(),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\nconst CreateCMSPageCommandSchema = z.object({\n\ttype: z.literal(CommandType.CreateCMSPage),\n\tattributes: z.object({\n\t\tpath: z.string(),\n\t\tname: z.string(),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\n\nconst UpdatePageCommandSchema = z.object({\n\ttype: z.literal(CommandType.UpdatePage),\n\tattributes: z.object({\n\t\tpath: z.string(),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\n\nconst DeletePageCommandSchema = z.object({\n\ttype: z.literal(CommandType.DeletePage),\n\tattributes: z.object({\n\t\tpath: z.string(),\n\t\tdescription: z.string(),\n\t}),\n})\n\nconst PageModeSchema = z.enum([PageMode.Light, PageMode.Dark])\n\nconst ThemePageCommandSchema = z.object({\n\ttype: z.literal(CommandType.ThemePage),\n\tattributes: z.object({\n\t\tpath: z.string(),\n\t\tmode: PageModeSchema,\n\t\tdescription: z.string(),\n\t}),\n})\n\nconst CreateCMSCollectionWithItemsCommandSchema = z.object({\n\ttype: z.literal(CommandType.CreateCMSCollectionWithItems),\n\tattributes: z.object({\n\t\tname: z.string(),\n\t\tfrom_template: z.string(),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\n\nconst AddCMSItemsCommandSchema = z.object({\n\ttype: z.literal(CommandType.AddCMSItems),\n\tattributes: z.object({\n\t\tcollection: z.string(),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\n\nconst UpdateCMSItemsCommandSchema = z.object({\n\ttype: z.literal(CommandType.UpdateCMSItems),\n\tattributes: z.object({\n\t\tcollection: z.string(),\n\t\tslugs: z\n\t\t\t.string()\n\t\t\t.transform(value =>\n\t\t\t\tvalue\n\t\t\t\t\t.split(\",\")\n\t\t\t\t\t.map(item => item.trim())\n\t\t\t\t\t.filter(Boolean),\n\t\t\t)\n\t\t\t.refine(arr => arr.length > 0, \"Expected at least one value\"),\n\t\tdescription: z.string(),\n\t\tinstructions: z.string(),\n\t}),\n})\n\nconst RejectCommandSchema = z.object({\n\ttype: z.literal(CommandType.Reject),\n\tattributes: z.object({\n\t\treason: z.string(),\n\t}),\n})\n\nconst CommandSchema = z.discriminatedUnion(\"type\", [\n\tAddCMSItemsCommandSchema,\n\tCreateCMSCollectionWithItemsCommandSchema,\n\tCreateCMSPageCommandSchema,\n\tCreatePageCommandSchema,\n\tDeletePageCommandSchema,\n\tPlanCommandSchema,\n\tRejectCommandSchema,\n\tThemePageCommandSchema,\n\tUpdateCMSItemsCommandSchema,\n\tUpdatePageCommandSchema,\n])\n\nexport type Command = z.infer<typeof CommandSchema>\n\n/**\n * Example commands for each command type - exhaustively covers all Command types\n */\nconst exampleCommands: { [K in Command[\"type\"]]: Extract<Command, { type: K }> } = {\n\t[CommandType.Plan]: { type: CommandType.Plan },\n\t[CommandType.Reject]: {\n\t\ttype: CommandType.Reject,\n\t\tattributes: {\n\t\t\treason: \"<Reason for rejecting the request>\",\n\t\t},\n\t},\n\t[CommandType.CreatePage]: {\n\t\ttype: CommandType.CreatePage,\n\t\tattributes: {\n\t\t\tpath: \"/<page-path>\",\n\t\t\tname: \"<New Page Name>\",\n\t\t\tdescription: \"<Add Page Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n\t[CommandType.CreateCMSPage]: {\n\t\ttype: CommandType.CreateCMSPage,\n\t\tattributes: {\n\t\t\tpath: \"/<page-path>/:slug\",\n\t\t\tname: \"<New Page Name>\",\n\t\t\tdescription: \"<Add Page Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n\t[CommandType.UpdatePage]: {\n\t\ttype: CommandType.UpdatePage,\n\t\tattributes: {\n\t\t\tpath: \"/<page-path>\",\n\t\t\tdescription: \"<Update Page Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n\t[CommandType.DeletePage]: {\n\t\ttype: CommandType.DeletePage,\n\t\tattributes: {\n\t\t\tpath: \"/<page-path>\",\n\t\t\tdescription: \"<Delete Page Description>\",\n\t\t},\n\t},\n\t[CommandType.ThemePage]: {\n\t\ttype: CommandType.ThemePage,\n\t\tattributes: {\n\t\t\tpath: \"/<page-path>\",\n\t\t\tmode: \"<DARK | LIGHT>\" as PageMode,\n\t\t\tdescription: \"<Theme Page Description>\",\n\t\t},\n\t},\n\t[CommandType.CreateCMSCollectionWithItems]: {\n\t\ttype: CommandType.CreateCMSCollectionWithItems,\n\t\tattributes: {\n\t\t\tname: \"<New Collection Name>\",\n\t\t\tfrom_template: \"<collection-template-name>\",\n\t\t\tdescription: \"<Add Items Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n\t[CommandType.AddCMSItems]: {\n\t\ttype: CommandType.AddCMSItems,\n\t\tattributes: {\n\t\t\tcollection: \"<Collection Name>\",\n\t\t\tdescription: \"<Add Items Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n\t[CommandType.UpdateCMSItems]: {\n\t\ttype: CommandType.UpdateCMSItems,\n\t\tattributes: {\n\t\t\tcollection: \"<Collection Name>\",\n\t\t\tslugs: [\"<slug-1>\", \"<slug-2>\", \"<slug-3>\"],\n\t\t\tdescription: \"<Update Items Description>\",\n\t\t\tinstructions: \"<Instructions (max 50 words)>\",\n\t\t},\n\t},\n}\n\n/**\n * Format command attributes as DSL string\n */\nfunction formatAttributes(attributes: Record<string, string | string[]>): string {\n\treturn Object.entries(attributes)\n\t\t.filter(([_, value]) => !isUndefined(value))\n\t\t.map(([key, value]) => (isArray(value) ? `${key}=\"${value.join(\",\")}\"` : `${key}=\"${value}\"`))\n\t\t.join(\" \")\n}\n\nexport function formatCommand(command: Command): string {\n\tswitch (command.type) {\n\t\tcase CommandType.Plan:\n\t\t\treturn \"PLAN;\"\n\t\tdefault:\n\t\t\treturn `${command.type} ${formatAttributes(command.attributes)};`\n\t}\n}\n\n/**\n * List of all available commands with formatted examples\n */\nexport function availableCommands(filter?: Record<CommandType, boolean>) {\n\treturn Object.values(exampleCommands)\n\t\t.filter(cmd => !filter || filter[cmd.type] !== false)\n\t\t.map(cmd => formatCommand(cmd))\n\t\t.join(\"\\n\")\n}\n\n// Match: key=[\"']value[\"'] where the closing quote is followed by:\n// - Optional whitespace\n// - Then either: another key=, semicolon, or end of string\nconst attributeRegex = /(\\w+)=([\"'])((?:(?!\\2\\s*(?:\\w+=|;|$))[\\s\\S])*)\\2/gm\n\n/**\n * Parses a single command string into a Command object\n */\nexport function parseCommand(commandStr: string): Command {\n\tconst trimmed = commandStr.trim()\n\tassert(trimmed, \"Empty command\")\n\n\t// Extract command type and attributes\n\tconst parts = trimmed.split(whitespaceSeparatorRegex)\n\tconst type = parts[0] as CommandType\n\n\t// Validate command type\n\tassert(commandTypesSet.has(type), `Unknown command type: ${type}`)\n\n\t// PLAN command has no attributes\n\tif (type === CommandType.Plan) return CommandSchema.parse({ type })\n\n\t// Parse attributes (key=\"value\" pairs)\n\tconst attributes: Record<string, string> = {}\n\tconst matches = trimmed.matchAll(attributeRegex)\n\n\tfor (const match of matches) {\n\t\tconst key = match[1]\n\t\tassert(!isUndefined(key), \"Invalid attribute key\")\n\t\tconst value = match[3]\n\t\tassert(!isUndefined(value), \"Invalid attribute value\")\n\t\tattributes[key] = value\n\t}\n\n\t// Validate with Zod\n\treturn CommandSchema.parse({\n\t\ttype,\n\t\tattributes: !isEmptyObject(attributes) ? attributes : undefined,\n\t})\n}\n", "const ALIAS = Symbol.for('yaml.alias');\nconst DOC = Symbol.for('yaml.document');\nconst MAP = Symbol.for('yaml.map');\nconst PAIR = Symbol.for('yaml.pair');\nconst SCALAR = Symbol.for('yaml.scalar');\nconst SEQ = Symbol.for('yaml.seq');\nconst NODE_TYPE = Symbol.for('yaml.node.type');\nconst isAlias = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === ALIAS;\nconst isDocument = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === DOC;\nconst isMap = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === MAP;\nconst isPair = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === PAIR;\nconst isScalar = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === SCALAR;\nconst isSeq = (node) => !!node && typeof node === 'object' && node[NODE_TYPE] === SEQ;\nfunction isCollection(node) {\n    if (node && typeof node === 'object')\n        switch (node[NODE_TYPE]) {\n            case MAP:\n            case SEQ:\n                return true;\n        }\n    return false;\n}\nfunction isNode(node) {\n    if (node && typeof node === 'object')\n        switch (node[NODE_TYPE]) {\n            case ALIAS:\n            case MAP:\n            case SCALAR:\n            case SEQ:\n                return true;\n        }\n    return false;\n}\nconst hasAnchor = (node) => (isScalar(node) || isCollection(node)) && !!node.anchor;\n\nexport { ALIAS, DOC, MAP, NODE_TYPE, PAIR, SCALAR, SEQ, hasAnchor, isAlias, isCollection, isDocument, isMap, isNode, isPair, isScalar, isSeq };\n", "import { isDocument, isNode, isPair, isCollection, isMap, isSeq, isScalar, isAlias } from './nodes/identity.js';\n\nconst BREAK = Symbol('break visit');\nconst SKIP = Symbol('skip children');\nconst REMOVE = Symbol('remove node');\n/**\n * Apply a visitor to an AST node or document.\n *\n * Walks through the tree (depth-first) starting from `node`, calling a\n * `visitor` function with three arguments:\n *   - `key`: For sequence values and map `Pair`, the node's index in the\n *     collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.\n *     `null` for the root node.\n *   - `node`: The current node.\n *   - `path`: The ancestry of the current node.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this node, continue with next\n *     sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current node, then continue with the next one\n *   - `Node`: Replace the current node, then continue by visiting it\n *   - `number`: While iterating the items of a sequence or map, set the index\n *     of the next step. This is useful especially if the index of the current\n *     node has changed.\n *\n * If `visitor` is a single function, it will be called with all values\n * encountered in the tree, including e.g. `null` values. Alternatively,\n * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,\n * `Alias` and `Scalar` node. To define the same visitor function for more than\n * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)\n * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most\n * specific defined one will be used for each node.\n */\nfunction visit(node, visitor) {\n    const visitor_ = initVisitor(visitor);\n    if (isDocument(node)) {\n        const cd = visit_(null, node.contents, visitor_, Object.freeze([node]));\n        if (cd === REMOVE)\n            node.contents = null;\n    }\n    else\n        visit_(null, node, visitor_, Object.freeze([]));\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisit.BREAK = BREAK;\n/** Do not visit the children of the current node */\nvisit.SKIP = SKIP;\n/** Remove the current node */\nvisit.REMOVE = REMOVE;\nfunction visit_(key, node, visitor, path) {\n    const ctrl = callVisitor(key, node, visitor, path);\n    if (isNode(ctrl) || isPair(ctrl)) {\n        replaceNode(key, path, ctrl);\n        return visit_(key, ctrl, visitor, path);\n    }\n    if (typeof ctrl !== 'symbol') {\n        if (isCollection(node)) {\n            path = Object.freeze(path.concat(node));\n            for (let i = 0; i < node.items.length; ++i) {\n                const ci = visit_(i, node.items[i], visitor, path);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    node.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n        }\n        else if (isPair(node)) {\n            path = Object.freeze(path.concat(node));\n            const ck = visit_('key', node.key, visitor, path);\n            if (ck === BREAK)\n                return BREAK;\n            else if (ck === REMOVE)\n                node.key = null;\n            const cv = visit_('value', node.value, visitor, path);\n            if (cv === BREAK)\n                return BREAK;\n            else if (cv === REMOVE)\n                node.value = null;\n        }\n    }\n    return ctrl;\n}\n/**\n * Apply an async visitor to an AST node or document.\n *\n * Walks through the tree (depth-first) starting from `node`, calling a\n * `visitor` function with three arguments:\n *   - `key`: For sequence values and map `Pair`, the node's index in the\n *     collection. Within a `Pair`, `'key'` or `'value'`, correspondingly.\n *     `null` for the root node.\n *   - `node`: The current node.\n *   - `path`: The ancestry of the current node.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `Promise`: Must resolve to one of the following values\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this node, continue with next\n *     sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current node, then continue with the next one\n *   - `Node`: Replace the current node, then continue by visiting it\n *   - `number`: While iterating the items of a sequence or map, set the index\n *     of the next step. This is useful especially if the index of the current\n *     node has changed.\n *\n * If `visitor` is a single function, it will be called with all values\n * encountered in the tree, including e.g. `null` values. Alternatively,\n * separate visitor functions may be defined for each `Map`, `Pair`, `Seq`,\n * `Alias` and `Scalar` node. To define the same visitor function for more than\n * one node type, use the `Collection` (map and seq), `Value` (map, seq & scalar)\n * and `Node` (alias, map, seq & scalar) targets. Of all these, only the most\n * specific defined one will be used for each node.\n */\nasync function visitAsync(node, visitor) {\n    const visitor_ = initVisitor(visitor);\n    if (isDocument(node)) {\n        const cd = await visitAsync_(null, node.contents, visitor_, Object.freeze([node]));\n        if (cd === REMOVE)\n            node.contents = null;\n    }\n    else\n        await visitAsync_(null, node, visitor_, Object.freeze([]));\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisitAsync.BREAK = BREAK;\n/** Do not visit the children of the current node */\nvisitAsync.SKIP = SKIP;\n/** Remove the current node */\nvisitAsync.REMOVE = REMOVE;\nasync function visitAsync_(key, node, visitor, path) {\n    const ctrl = await callVisitor(key, node, visitor, path);\n    if (isNode(ctrl) || isPair(ctrl)) {\n        replaceNode(key, path, ctrl);\n        return visitAsync_(key, ctrl, visitor, path);\n    }\n    if (typeof ctrl !== 'symbol') {\n        if (isCollection(node)) {\n            path = Object.freeze(path.concat(node));\n            for (let i = 0; i < node.items.length; ++i) {\n                const ci = await visitAsync_(i, node.items[i], visitor, path);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    node.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n        }\n        else if (isPair(node)) {\n            path = Object.freeze(path.concat(node));\n            const ck = await visitAsync_('key', node.key, visitor, path);\n            if (ck === BREAK)\n                return BREAK;\n            else if (ck === REMOVE)\n                node.key = null;\n            const cv = await visitAsync_('value', node.value, visitor, path);\n            if (cv === BREAK)\n                return BREAK;\n            else if (cv === REMOVE)\n                node.value = null;\n        }\n    }\n    return ctrl;\n}\nfunction initVisitor(visitor) {\n    if (typeof visitor === 'object' &&\n        (visitor.Collection || visitor.Node || visitor.Value)) {\n        return Object.assign({\n            Alias: visitor.Node,\n            Map: visitor.Node,\n            Scalar: visitor.Node,\n            Seq: visitor.Node\n        }, visitor.Value && {\n            Map: visitor.Value,\n            Scalar: visitor.Value,\n            Seq: visitor.Value\n        }, visitor.Collection && {\n            Map: visitor.Collection,\n            Seq: visitor.Collection\n        }, visitor);\n    }\n    return visitor;\n}\nfunction callVisitor(key, node, visitor, path) {\n    if (typeof visitor === 'function')\n        return visitor(key, node, path);\n    if (isMap(node))\n        return visitor.Map?.(key, node, path);\n    if (isSeq(node))\n        return visitor.Seq?.(key, node, path);\n    if (isPair(node))\n        return visitor.Pair?.(key, node, path);\n    if (isScalar(node))\n        return visitor.Scalar?.(key, node, path);\n    if (isAlias(node))\n        return visitor.Alias?.(key, node, path);\n    return undefined;\n}\nfunction replaceNode(key, path, node) {\n    const parent = path[path.length - 1];\n    if (isCollection(parent)) {\n        parent.items[key] = node;\n    }\n    else if (isPair(parent)) {\n        if (key === 'key')\n            parent.key = node;\n        else\n            parent.value = node;\n    }\n    else if (isDocument(parent)) {\n        parent.contents = node;\n    }\n    else {\n        const pt = isAlias(parent) ? 'alias' : 'scalar';\n        throw new Error(`Cannot replace node with ${pt} parent`);\n    }\n}\n\nexport { visit, visitAsync };\n", "import { isNode } from '../nodes/identity.js';\nimport { visit } from '../visit.js';\n\nconst escapeChars = {\n    '!': '%21',\n    ',': '%2C',\n    '[': '%5B',\n    ']': '%5D',\n    '{': '%7B',\n    '}': '%7D'\n};\nconst escapeTagName = (tn) => tn.replace(/[!,[\\]{}]/g, ch => escapeChars[ch]);\nclass Directives {\n    constructor(yaml, tags) {\n        /**\n         * The directives-end/doc-start marker `---`. If `null`, a marker may still be\n         * included in the document's stringified representation.\n         */\n        this.docStart = null;\n        /** The doc-end marker `...`.  */\n        this.docEnd = false;\n        this.yaml = Object.assign({}, Directives.defaultYaml, yaml);\n        this.tags = Object.assign({}, Directives.defaultTags, tags);\n    }\n    clone() {\n        const copy = new Directives(this.yaml, this.tags);\n        copy.docStart = this.docStart;\n        return copy;\n    }\n    /**\n     * During parsing, get a Directives instance for the current document and\n     * update the stream state according to the current version's spec.\n     */\n    atDocument() {\n        const res = new Directives(this.yaml, this.tags);\n        switch (this.yaml.version) {\n            case '1.1':\n                this.atNextDocument = true;\n                break;\n            case '1.2':\n                this.atNextDocument = false;\n                this.yaml = {\n                    explicit: Directives.defaultYaml.explicit,\n                    version: '1.2'\n                };\n                this.tags = Object.assign({}, Directives.defaultTags);\n                break;\n        }\n        return res;\n    }\n    /**\n     * @param onError - May be called even if the action was successful\n     * @returns `true` on success\n     */\n    add(line, onError) {\n        if (this.atNextDocument) {\n            this.yaml = { explicit: Directives.defaultYaml.explicit, version: '1.1' };\n            this.tags = Object.assign({}, Directives.defaultTags);\n            this.atNextDocument = false;\n        }\n        const parts = line.trim().split(/[ \\t]+/);\n        const name = parts.shift();\n        switch (name) {\n            case '%TAG': {\n                if (parts.length !== 2) {\n                    onError(0, '%TAG directive should contain exactly two parts');\n                    if (parts.length < 2)\n                        return false;\n                }\n                const [handle, prefix] = parts;\n                this.tags[handle] = prefix;\n                return true;\n            }\n            case '%YAML': {\n                this.yaml.explicit = true;\n                if (parts.length !== 1) {\n                    onError(0, '%YAML directive should contain exactly one part');\n                    return false;\n                }\n                const [version] = parts;\n                if (version === '1.1' || version === '1.2') {\n                    this.yaml.version = version;\n                    return true;\n                }\n                else {\n                    const isValid = /^\\d+\\.\\d+$/.test(version);\n                    onError(6, `Unsupported YAML version ${version}`, isValid);\n                    return false;\n                }\n            }\n            default:\n                onError(0, `Unknown directive ${name}`, true);\n                return false;\n        }\n    }\n    /**\n     * Resolves a tag, matching handles to those defined in %TAG directives.\n     *\n     * @returns Resolved tag, which may also be the non-specific tag `'!'` or a\n     *   `'!local'` tag, or `null` if unresolvable.\n     */\n    tagName(source, onError) {\n        if (source === '!')\n            return '!'; // non-specific tag\n        if (source[0] !== '!') {\n            onError(`Not a valid tag: ${source}`);\n            return null;\n        }\n        if (source[1] === '<') {\n            const verbatim = source.slice(2, -1);\n            if (verbatim === '!' || verbatim === '!!') {\n                onError(`Verbatim tags aren't resolved, so ${source} is invalid.`);\n                return null;\n            }\n            if (source[source.length - 1] !== '>')\n                onError('Verbatim tags must end with a >');\n            return verbatim;\n        }\n        const [, handle, suffix] = source.match(/^(.*!)([^!]*)$/s);\n        if (!suffix)\n            onError(`The ${source} tag has no suffix`);\n        const prefix = this.tags[handle];\n        if (prefix) {\n            try {\n                return prefix + decodeURIComponent(suffix);\n            }\n            catch (error) {\n                onError(String(error));\n                return null;\n            }\n        }\n        if (handle === '!')\n            return source; // local tag\n        onError(`Could not resolve tag: ${source}`);\n        return null;\n    }\n    /**\n     * Given a fully resolved tag, returns its printable string form,\n     * taking into account current tag prefixes and defaults.\n     */\n    tagString(tag) {\n        for (const [handle, prefix] of Object.entries(this.tags)) {\n            if (tag.startsWith(prefix))\n                return handle + escapeTagName(tag.substring(prefix.length));\n        }\n        return tag[0] === '!' ? tag : `!<${tag}>`;\n    }\n    toString(doc) {\n        const lines = this.yaml.explicit\n            ? [`%YAML ${this.yaml.version || '1.2'}`]\n            : [];\n        const tagEntries = Object.entries(this.tags);\n        let tagNames;\n        if (doc && tagEntries.length > 0 && isNode(doc.contents)) {\n            const tags = {};\n            visit(doc.contents, (_key, node) => {\n                if (isNode(node) && node.tag)\n                    tags[node.tag] = true;\n            });\n            tagNames = Object.keys(tags);\n        }\n        else\n            tagNames = [];\n        for (const [handle, prefix] of tagEntries) {\n            if (handle === '!!' && prefix === 'tag:yaml.org,2002:')\n                continue;\n            if (!doc || tagNames.some(tn => tn.startsWith(prefix)))\n                lines.push(`%TAG ${handle} ${prefix}`);\n        }\n        return lines.join('\\n');\n    }\n}\nDirectives.defaultYaml = { explicit: false, version: '1.2' };\nDirectives.defaultTags = { '!!': 'tag:yaml.org,2002:' };\n\nexport { Directives };\n", "import { isScalar, isCollection } from '../nodes/identity.js';\nimport { visit } from '../visit.js';\n\n/**\n * Verify that the input string is a valid anchor.\n *\n * Will throw on errors.\n */\nfunction anchorIsValid(anchor) {\n    if (/[\\x00-\\x19\\s,[\\]{}]/.test(anchor)) {\n        const sa = JSON.stringify(anchor);\n        const msg = `Anchor must not contain whitespace or control characters: ${sa}`;\n        throw new Error(msg);\n    }\n    return true;\n}\nfunction anchorNames(root) {\n    const anchors = new Set();\n    visit(root, {\n        Value(_key, node) {\n            if (node.anchor)\n                anchors.add(node.anchor);\n        }\n    });\n    return anchors;\n}\n/** Find a new anchor name with the given `prefix` and a one-indexed suffix. */\nfunction findNewAnchor(prefix, exclude) {\n    for (let i = 1; true; ++i) {\n        const name = `${prefix}${i}`;\n        if (!exclude.has(name))\n            return name;\n    }\n}\nfunction createNodeAnchors(doc, prefix) {\n    const aliasObjects = [];\n    const sourceObjects = new Map();\n    let prevAnchors = null;\n    return {\n        onAnchor: (source) => {\n            aliasObjects.push(source);\n            prevAnchors ?? (prevAnchors = anchorNames(doc));\n            const anchor = findNewAnchor(prefix, prevAnchors);\n            prevAnchors.add(anchor);\n            return anchor;\n        },\n        /**\n         * With circular references, the source node is only resolved after all\n         * of its child nodes are. This is why anchors are set only after all of\n         * the nodes have been created.\n         */\n        setAnchors: () => {\n            for (const source of aliasObjects) {\n                const ref = sourceObjects.get(source);\n                if (typeof ref === 'object' &&\n                    ref.anchor &&\n                    (isScalar(ref.node) || isCollection(ref.node))) {\n                    ref.node.anchor = ref.anchor;\n                }\n                else {\n                    const error = new Error('Failed to resolve repeated object (this should not happen)');\n                    error.source = source;\n                    throw error;\n                }\n            }\n        },\n        sourceObjects\n    };\n}\n\nexport { anchorIsValid, anchorNames, createNodeAnchors, findNewAnchor };\n", "/**\n * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,\n * in section 24.5.1.1 \"Runtime Semantics: InternalizeJSONProperty\" of the\n * 2021 edition: https://tc39.es/ecma262/#sec-json.parse\n *\n * Includes extensions for handling Map and Set objects.\n */\nfunction applyReviver(reviver, obj, key, val) {\n    if (val && typeof val === 'object') {\n        if (Array.isArray(val)) {\n            for (let i = 0, len = val.length; i < len; ++i) {\n                const v0 = val[i];\n                const v1 = applyReviver(reviver, val, String(i), v0);\n                // eslint-disable-next-line @typescript-eslint/no-array-delete\n                if (v1 === undefined)\n                    delete val[i];\n                else if (v1 !== v0)\n                    val[i] = v1;\n            }\n        }\n        else if (val instanceof Map) {\n            for (const k of Array.from(val.keys())) {\n                const v0 = val.get(k);\n                const v1 = applyReviver(reviver, val, k, v0);\n                if (v1 === undefined)\n                    val.delete(k);\n                else if (v1 !== v0)\n                    val.set(k, v1);\n            }\n        }\n        else if (val instanceof Set) {\n            for (const v0 of Array.from(val)) {\n                const v1 = applyReviver(reviver, val, v0, v0);\n                if (v1 === undefined)\n                    val.delete(v0);\n                else if (v1 !== v0) {\n                    val.delete(v0);\n                    val.add(v1);\n                }\n            }\n        }\n        else {\n            for (const [k, v0] of Object.entries(val)) {\n                const v1 = applyReviver(reviver, val, k, v0);\n                if (v1 === undefined)\n                    delete val[k];\n                else if (v1 !== v0)\n                    val[k] = v1;\n            }\n        }\n    }\n    return reviver.call(obj, key, val);\n}\n\nexport { applyReviver };\n", "import { hasAnchor } from './identity.js';\n\n/**\n * Recursively convert any node or its contents to native JavaScript\n *\n * @param value - The input value\n * @param arg - If `value` defines a `toJSON()` method, use this\n *   as its first argument\n * @param ctx - Conversion context, originally set in Document#toJS(). If\n *   `{ keep: true }` is not set, output should be suitable for JSON\n *   stringification.\n */\nfunction toJS(value, arg, ctx) {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n    if (Array.isArray(value))\n        return value.map((v, i) => toJS(v, String(i), ctx));\n    if (value && typeof value.toJSON === 'function') {\n        // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n        if (!ctx || !hasAnchor(value))\n            return value.toJSON(arg, ctx);\n        const data = { aliasCount: 0, count: 1, res: undefined };\n        ctx.anchors.set(value, data);\n        ctx.onCreate = res => {\n            data.res = res;\n            delete ctx.onCreate;\n        };\n        const res = value.toJSON(arg, ctx);\n        if (ctx.onCreate)\n            ctx.onCreate(res);\n        return res;\n    }\n    if (typeof value === 'bigint' && !ctx?.keep)\n        return Number(value);\n    return value;\n}\n\nexport { toJS };\n", "import { applyReviver } from '../doc/applyReviver.js';\nimport { NODE_TYPE, isDocument } from './identity.js';\nimport { toJS } from './toJS.js';\n\nclass NodeBase {\n    constructor(type) {\n        Object.defineProperty(this, NODE_TYPE, { value: type });\n    }\n    /** Create a copy of this node.  */\n    clone() {\n        const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /** A plain JavaScript representation of this node. */\n    toJS(doc, { mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {\n        if (!isDocument(doc))\n            throw new TypeError('A document argument is required');\n        const ctx = {\n            anchors: new Map(),\n            doc,\n            keep: true,\n            mapAsMap: mapAsMap === true,\n            mapKeyWarned: false,\n            maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100\n        };\n        const res = toJS(this, '', ctx);\n        if (typeof onAnchor === 'function')\n            for (const { count, res } of ctx.anchors.values())\n                onAnchor(res, count);\n        return typeof reviver === 'function'\n            ? applyReviver(reviver, { '': res }, '', res)\n            : res;\n    }\n}\n\nexport { NodeBase };\n", "import { anchorIsValid } from '../doc/anchors.js';\nimport { visit } from '../visit.js';\nimport { ALIAS, isAlias, isCollection, isPair, hasAnchor } from './identity.js';\nimport { NodeBase } from './Node.js';\nimport { toJS } from './toJS.js';\n\nclass Alias extends NodeBase {\n    constructor(source) {\n        super(ALIAS);\n        this.source = source;\n        Object.defineProperty(this, 'tag', {\n            set() {\n                throw new Error('Alias nodes cannot have tags');\n            }\n        });\n    }\n    /**\n     * Resolve the value of this alias within `doc`, finding the last\n     * instance of the `source` anchor before this node.\n     */\n    resolve(doc, ctx) {\n        let nodes;\n        if (ctx?.aliasResolveCache) {\n            nodes = ctx.aliasResolveCache;\n        }\n        else {\n            nodes = [];\n            visit(doc, {\n                Node: (_key, node) => {\n                    if (isAlias(node) || hasAnchor(node))\n                        nodes.push(node);\n                }\n            });\n            if (ctx)\n                ctx.aliasResolveCache = nodes;\n        }\n        let found = undefined;\n        for (const node of nodes) {\n            if (node === this)\n                break;\n            if (node.anchor === this.source)\n                found = node;\n        }\n        return found;\n    }\n    toJSON(_arg, ctx) {\n        if (!ctx)\n            return { source: this.source };\n        const { anchors, doc, maxAliasCount } = ctx;\n        const source = this.resolve(doc, ctx);\n        if (!source) {\n            const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;\n            throw new ReferenceError(msg);\n        }\n        let data = anchors.get(source);\n        if (!data) {\n            // Resolve anchors for Node.prototype.toJS()\n            toJS(source, null, ctx);\n            data = anchors.get(source);\n        }\n        /* istanbul ignore if */\n        if (data?.res === undefined) {\n            const msg = 'This should not happen: Alias anchor was not resolved?';\n            throw new ReferenceError(msg);\n        }\n        if (maxAliasCount >= 0) {\n            data.count += 1;\n            if (data.aliasCount === 0)\n                data.aliasCount = getAliasCount(doc, source, anchors);\n            if (data.count * data.aliasCount > maxAliasCount) {\n                const msg = 'Excessive alias count indicates a resource exhaustion attack';\n                throw new ReferenceError(msg);\n            }\n        }\n        return data.res;\n    }\n    toString(ctx, _onComment, _onChompKeep) {\n        const src = `*${this.source}`;\n        if (ctx) {\n            anchorIsValid(this.source);\n            if (ctx.options.verifyAliasOrder && !ctx.anchors.has(this.source)) {\n                const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;\n                throw new Error(msg);\n            }\n            if (ctx.implicitKey)\n                return `${src} `;\n        }\n        return src;\n    }\n}\nfunction getAliasCount(doc, node, anchors) {\n    if (isAlias(node)) {\n        const source = node.resolve(doc);\n        const anchor = anchors && source && anchors.get(source);\n        return anchor ? anchor.count * anchor.aliasCount : 0;\n    }\n    else if (isCollection(node)) {\n        let count = 0;\n        for (const item of node.items) {\n            const c = getAliasCount(doc, item, anchors);\n            if (c > count)\n                count = c;\n        }\n        return count;\n    }\n    else if (isPair(node)) {\n        const kc = getAliasCount(doc, node.key, anchors);\n        const vc = getAliasCount(doc, node.value, anchors);\n        return Math.max(kc, vc);\n    }\n    return 1;\n}\n\nexport { Alias };\n", "import { SCALAR } from './identity.js';\nimport { NodeBase } from './Node.js';\nimport { toJS } from './toJS.js';\n\nconst isScalarValue = (value) => !value || (typeof value !== 'function' && typeof value !== 'object');\nclass Scalar extends NodeBase {\n    constructor(value) {\n        super(SCALAR);\n        this.value = value;\n    }\n    toJSON(arg, ctx) {\n        return ctx?.keep ? this.value : toJS(this.value, arg, ctx);\n    }\n    toString() {\n        return String(this.value);\n    }\n}\nScalar.BLOCK_FOLDED = 'BLOCK_FOLDED';\nScalar.BLOCK_LITERAL = 'BLOCK_LITERAL';\nScalar.PLAIN = 'PLAIN';\nScalar.QUOTE_DOUBLE = 'QUOTE_DOUBLE';\nScalar.QUOTE_SINGLE = 'QUOTE_SINGLE';\n\nexport { Scalar, isScalarValue };\n", "import { Alias } from '../nodes/Alias.js';\nimport { isNode, isPair, MAP, SEQ, isDocument } from '../nodes/identity.js';\nimport { Scalar } from '../nodes/Scalar.js';\n\nconst defaultTagPrefix = 'tag:yaml.org,2002:';\nfunction findTagObject(value, tagName, tags) {\n    if (tagName) {\n        const match = tags.filter(t => t.tag === tagName);\n        const tagObj = match.find(t => !t.format) ?? match[0];\n        if (!tagObj)\n            throw new Error(`Tag ${tagName} not found`);\n        return tagObj;\n    }\n    return tags.find(t => t.identify?.(value) && !t.format);\n}\nfunction createNode(value, tagName, ctx) {\n    if (isDocument(value))\n        value = value.contents;\n    if (isNode(value))\n        return value;\n    if (isPair(value)) {\n        const map = ctx.schema[MAP].createNode?.(ctx.schema, null, ctx);\n        map.items.push(value);\n        return map;\n    }\n    if (value instanceof String ||\n        value instanceof Number ||\n        value instanceof Boolean ||\n        (typeof BigInt !== 'undefined' && value instanceof BigInt) // not supported everywhere\n    ) {\n        // https://tc39.es/ecma262/#sec-serializejsonproperty\n        value = value.valueOf();\n    }\n    const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;\n    // Detect duplicate references to the same object & use Alias nodes for all\n    // after first. The `ref` wrapper allows for circular references to resolve.\n    let ref = undefined;\n    if (aliasDuplicateObjects && value && typeof value === 'object') {\n        ref = sourceObjects.get(value);\n        if (ref) {\n            ref.anchor ?? (ref.anchor = onAnchor(value));\n            return new Alias(ref.anchor);\n        }\n        else {\n            ref = { anchor: null, node: null };\n            sourceObjects.set(value, ref);\n        }\n    }\n    if (tagName?.startsWith('!!'))\n        tagName = defaultTagPrefix + tagName.slice(2);\n    let tagObj = findTagObject(value, tagName, schema.tags);\n    if (!tagObj) {\n        if (value && typeof value.toJSON === 'function') {\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n            value = value.toJSON();\n        }\n        if (!value || typeof value !== 'object') {\n            const node = new Scalar(value);\n            if (ref)\n                ref.node = node;\n            return node;\n        }\n        tagObj =\n            value instanceof Map\n                ? schema[MAP]\n                : Symbol.iterator in Object(value)\n                    ? schema[SEQ]\n                    : schema[MAP];\n    }\n    if (onTagObj) {\n        onTagObj(tagObj);\n        delete ctx.onTagObj;\n    }\n    const node = tagObj?.createNode\n        ? tagObj.createNode(ctx.schema, value, ctx)\n        : typeof tagObj?.nodeClass?.from === 'function'\n            ? tagObj.nodeClass.from(ctx.schema, value, ctx)\n            : new Scalar(value);\n    if (tagName)\n        node.tag = tagName;\n    else if (!tagObj.default)\n        node.tag = tagObj.tag;\n    if (ref)\n        ref.node = node;\n    return node;\n}\n\nexport { createNode };\n", "import { createNode } from '../doc/createNode.js';\nimport { isNode, isPair, isCollection, isScalar } from './identity.js';\nimport { NodeBase } from './Node.js';\n\nfunction collectionFromPath(schema, path, value) {\n    let v = value;\n    for (let i = path.length - 1; i >= 0; --i) {\n        const k = path[i];\n        if (typeof k === 'number' && Number.isInteger(k) && k >= 0) {\n            const a = [];\n            a[k] = v;\n            v = a;\n        }\n        else {\n            v = new Map([[k, v]]);\n        }\n    }\n    return createNode(v, undefined, {\n        aliasDuplicateObjects: false,\n        keepUndefined: false,\n        onAnchor: () => {\n            throw new Error('This should not happen, please report a bug.');\n        },\n        schema,\n        sourceObjects: new Map()\n    });\n}\n// Type guard is intentionally a little wrong so as to be more useful,\n// as it does not cover untypable empty non-string iterables (e.g. []).\nconst isEmptyPath = (path) => path == null ||\n    (typeof path === 'object' && !!path[Symbol.iterator]().next().done);\nclass Collection extends NodeBase {\n    constructor(type, schema) {\n        super(type);\n        Object.defineProperty(this, 'schema', {\n            value: schema,\n            configurable: true,\n            enumerable: false,\n            writable: true\n        });\n    }\n    /**\n     * Create a copy of this collection.\n     *\n     * @param schema - If defined, overwrites the original's schema\n     */\n    clone(schema) {\n        const copy = Object.create(Object.getPrototypeOf(this), Object.getOwnPropertyDescriptors(this));\n        if (schema)\n            copy.schema = schema;\n        copy.items = copy.items.map(it => isNode(it) || isPair(it) ? it.clone(schema) : it);\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /**\n     * Adds a value to the collection. For `!!map` and `!!omap` the value must\n     * be a Pair instance or a `{ key, value }` object, which may not have a key\n     * that already exists in the map.\n     */\n    addIn(path, value) {\n        if (isEmptyPath(path))\n            this.add(value);\n        else {\n            const [key, ...rest] = path;\n            const node = this.get(key, true);\n            if (isCollection(node))\n                node.addIn(rest, value);\n            else if (node === undefined && this.schema)\n                this.set(key, collectionFromPath(this.schema, rest, value));\n            else\n                throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n        }\n    }\n    /**\n     * Removes a value from the collection.\n     * @returns `true` if the item was found and removed.\n     */\n    deleteIn(path) {\n        const [key, ...rest] = path;\n        if (rest.length === 0)\n            return this.delete(key);\n        const node = this.get(key, true);\n        if (isCollection(node))\n            return node.deleteIn(rest);\n        else\n            throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n    }\n    /**\n     * Returns item at `key`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    getIn(path, keepScalar) {\n        const [key, ...rest] = path;\n        const node = this.get(key, true);\n        if (rest.length === 0)\n            return !keepScalar && isScalar(node) ? node.value : node;\n        else\n            return isCollection(node) ? node.getIn(rest, keepScalar) : undefined;\n    }\n    hasAllNullValues(allowScalar) {\n        return this.items.every(node => {\n            if (!isPair(node))\n                return false;\n            const n = node.value;\n            return (n == null ||\n                (allowScalar &&\n                    isScalar(n) &&\n                    n.value == null &&\n                    !n.commentBefore &&\n                    !n.comment &&\n                    !n.tag));\n        });\n    }\n    /**\n     * Checks if the collection includes a value with the key `key`.\n     */\n    hasIn(path) {\n        const [key, ...rest] = path;\n        if (rest.length === 0)\n            return this.has(key);\n        const node = this.get(key, true);\n        return isCollection(node) ? node.hasIn(rest) : false;\n    }\n    /**\n     * Sets a value in this collection. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    setIn(path, value) {\n        const [key, ...rest] = path;\n        if (rest.length === 0) {\n            this.set(key, value);\n        }\n        else {\n            const node = this.get(key, true);\n            if (isCollection(node))\n                node.setIn(rest, value);\n            else if (node === undefined && this.schema)\n                this.set(key, collectionFromPath(this.schema, rest, value));\n            else\n                throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);\n        }\n    }\n}\n\nexport { Collection, collectionFromPath, isEmptyPath };\n", "/**\n * Stringifies a comment.\n *\n * Empty comment lines are left empty,\n * lines consisting of a single space are replaced by `#`,\n * and all other lines are prefixed with a `#`.\n */\nconst stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, '#');\nfunction indentComment(comment, indent) {\n    if (/^\\n+$/.test(comment))\n        return comment.substring(1);\n    return indent ? comment.replace(/^(?! *$)/gm, indent) : comment;\n}\nconst lineComment = (str, indent, comment) => str.endsWith('\\n')\n    ? indentComment(comment, indent)\n    : comment.includes('\\n')\n        ? '\\n' + indentComment(comment, indent)\n        : (str.endsWith(' ') ? '' : ' ') + comment;\n\nexport { indentComment, lineComment, stringifyComment };\n", "const FOLD_FLOW = 'flow';\nconst FOLD_BLOCK = 'block';\nconst FOLD_QUOTED = 'quoted';\n/**\n * Tries to keep input at up to `lineWidth` characters, splitting only on spaces\n * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are\n * terminated with `\\n` and started with `indent`.\n */\nfunction foldFlowLines(text, indent, mode = 'flow', { indentAtStart, lineWidth = 80, minContentWidth = 20, onFold, onOverflow } = {}) {\n    if (!lineWidth || lineWidth < 0)\n        return text;\n    if (lineWidth < minContentWidth)\n        minContentWidth = 0;\n    const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length);\n    if (text.length <= endStep)\n        return text;\n    const folds = [];\n    const escapedFolds = {};\n    let end = lineWidth - indent.length;\n    if (typeof indentAtStart === 'number') {\n        if (indentAtStart > lineWidth - Math.max(2, minContentWidth))\n            folds.push(0);\n        else\n            end = lineWidth - indentAtStart;\n    }\n    let split = undefined;\n    let prev = undefined;\n    let overflow = false;\n    let i = -1;\n    let escStart = -1;\n    let escEnd = -1;\n    if (mode === FOLD_BLOCK) {\n        i = consumeMoreIndentedLines(text, i, indent.length);\n        if (i !== -1)\n            end = i + endStep;\n    }\n    for (let ch; (ch = text[(i += 1)]);) {\n        if (mode === FOLD_QUOTED && ch === '\\\\') {\n            escStart = i;\n            switch (text[i + 1]) {\n                case 'x':\n                    i += 3;\n                    break;\n                case 'u':\n                    i += 5;\n                    break;\n                case 'U':\n                    i += 9;\n                    break;\n                default:\n                    i += 1;\n            }\n            escEnd = i;\n        }\n        if (ch === '\\n') {\n            if (mode === FOLD_BLOCK)\n                i = consumeMoreIndentedLines(text, i, indent.length);\n            end = i + indent.length + endStep;\n            split = undefined;\n        }\n        else {\n            if (ch === ' ' &&\n                prev &&\n                prev !== ' ' &&\n                prev !== '\\n' &&\n                prev !== '\\t') {\n                // space surrounded by non-space can be replaced with newline + indent\n                const next = text[i + 1];\n                if (next && next !== ' ' && next !== '\\n' && next !== '\\t')\n                    split = i;\n            }\n            if (i >= end) {\n                if (split) {\n                    folds.push(split);\n                    end = split + endStep;\n                    split = undefined;\n                }\n                else if (mode === FOLD_QUOTED) {\n                    // white-space collected at end may stretch past lineWidth\n                    while (prev === ' ' || prev === '\\t') {\n                        prev = ch;\n                        ch = text[(i += 1)];\n                        overflow = true;\n                    }\n                    // Account for newline escape, but don't break preceding escape\n                    const j = i > escEnd + 1 ? i - 2 : escStart - 1;\n                    // Bail out if lineWidth & minContentWidth are shorter than an escape string\n                    if (escapedFolds[j])\n                        return text;\n                    folds.push(j);\n                    escapedFolds[j] = true;\n                    end = j + endStep;\n                    split = undefined;\n                }\n                else {\n                    overflow = true;\n                }\n            }\n        }\n        prev = ch;\n    }\n    if (overflow && onOverflow)\n        onOverflow();\n    if (folds.length === 0)\n        return text;\n    if (onFold)\n        onFold();\n    let res = text.slice(0, folds[0]);\n    for (let i = 0; i < folds.length; ++i) {\n        const fold = folds[i];\n        const end = folds[i + 1] || text.length;\n        if (fold === 0)\n            res = `\\n${indent}${text.slice(0, end)}`;\n        else {\n            if (mode === FOLD_QUOTED && escapedFolds[fold])\n                res += `${text[fold]}\\\\`;\n            res += `\\n${indent}${text.slice(fold + 1, end)}`;\n        }\n    }\n    return res;\n}\n/**\n * Presumes `i + 1` is at the start of a line\n * @returns index of last newline in more-indented block\n */\nfunction consumeMoreIndentedLines(text, i, indent) {\n    let end = i;\n    let start = i + 1;\n    let ch = text[start];\n    while (ch === ' ' || ch === '\\t') {\n        if (i < start + indent) {\n            ch = text[++i];\n        }\n        else {\n            do {\n                ch = text[++i];\n            } while (ch && ch !== '\\n');\n            end = i;\n            start = i + 1;\n            ch = text[start];\n        }\n    }\n    return end;\n}\n\nexport { FOLD_BLOCK, FOLD_FLOW, FOLD_QUOTED, foldFlowLines };\n", "import { Scalar } from '../nodes/Scalar.js';\nimport { foldFlowLines, FOLD_FLOW, FOLD_QUOTED, FOLD_BLOCK } from './foldFlowLines.js';\n\nconst getFoldOptions = (ctx, isBlock) => ({\n    indentAtStart: isBlock ? ctx.indent.length : ctx.indentAtStart,\n    lineWidth: ctx.options.lineWidth,\n    minContentWidth: ctx.options.minContentWidth\n});\n// Also checks for lines starting with %, as parsing the output as YAML 1.1 will\n// presume that's starting a new document.\nconst containsDocumentMarker = (str) => /^(%|---|\\.\\.\\.)/m.test(str);\nfunction lineLengthOverLimit(str, lineWidth, indentLength) {\n    if (!lineWidth || lineWidth < 0)\n        return false;\n    const limit = lineWidth - indentLength;\n    const strLen = str.length;\n    if (strLen <= limit)\n        return false;\n    for (let i = 0, start = 0; i < strLen; ++i) {\n        if (str[i] === '\\n') {\n            if (i - start > limit)\n                return true;\n            start = i + 1;\n            if (strLen - start <= limit)\n                return false;\n        }\n    }\n    return true;\n}\nfunction doubleQuotedString(value, ctx) {\n    const json = JSON.stringify(value);\n    if (ctx.options.doubleQuotedAsJSON)\n        return json;\n    const { implicitKey } = ctx;\n    const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;\n    const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');\n    let str = '';\n    let start = 0;\n    for (let i = 0, ch = json[i]; ch; ch = json[++i]) {\n        if (ch === ' ' && json[i + 1] === '\\\\' && json[i + 2] === 'n') {\n            // space before newline needs to be escaped to not be folded\n            str += json.slice(start, i) + '\\\\ ';\n            i += 1;\n            start = i;\n            ch = '\\\\';\n        }\n        if (ch === '\\\\')\n            switch (json[i + 1]) {\n                case 'u':\n                    {\n                        str += json.slice(start, i);\n                        const code = json.substr(i + 2, 4);\n                        switch (code) {\n                            case '0000':\n                                str += '\\\\0';\n                                break;\n                            case '0007':\n                                str += '\\\\a';\n                                break;\n                            case '000b':\n                                str += '\\\\v';\n                                break;\n                            case '001b':\n                                str += '\\\\e';\n                                break;\n                            case '0085':\n                                str += '\\\\N';\n                                break;\n                            case '00a0':\n                                str += '\\\\_';\n                                break;\n                            case '2028':\n                                str += '\\\\L';\n                                break;\n                            case '2029':\n                                str += '\\\\P';\n                                break;\n                            default:\n                                if (code.substr(0, 2) === '00')\n                                    str += '\\\\x' + code.substr(2);\n                                else\n                                    str += json.substr(i, 6);\n                        }\n                        i += 5;\n                        start = i + 1;\n                    }\n                    break;\n                case 'n':\n                    if (implicitKey ||\n                        json[i + 2] === '\"' ||\n                        json.length < minMultiLineLength) {\n                        i += 1;\n                    }\n                    else {\n                        // folding will eat first newline\n                        str += json.slice(start, i) + '\\n\\n';\n                        while (json[i + 2] === '\\\\' &&\n                            json[i + 3] === 'n' &&\n                            json[i + 4] !== '\"') {\n                            str += '\\n';\n                            i += 2;\n                        }\n                        str += indent;\n                        // space after newline needs to be escaped to not be folded\n                        if (json[i + 2] === ' ')\n                            str += '\\\\';\n                        i += 1;\n                        start = i + 1;\n                    }\n                    break;\n                default:\n                    i += 1;\n            }\n    }\n    str = start ? str + json.slice(start) : json;\n    return implicitKey\n        ? str\n        : foldFlowLines(str, indent, FOLD_QUOTED, getFoldOptions(ctx, false));\n}\nfunction singleQuotedString(value, ctx) {\n    if (ctx.options.singleQuote === false ||\n        (ctx.implicitKey && value.includes('\\n')) ||\n        /[ \\t]\\n|\\n[ \\t]/.test(value) // single quoted string can't have leading or trailing whitespace around newline\n    )\n        return doubleQuotedString(value, ctx);\n    const indent = ctx.indent || (containsDocumentMarker(value) ? '  ' : '');\n    const res = \"'\" + value.replace(/'/g, \"''\").replace(/\\n+/g, `$&\\n${indent}`) + \"'\";\n    return ctx.implicitKey\n        ? res\n        : foldFlowLines(res, indent, FOLD_FLOW, getFoldOptions(ctx, false));\n}\nfunction quotedString(value, ctx) {\n    const { singleQuote } = ctx.options;\n    let qs;\n    if (singleQuote === false)\n        qs = doubleQuotedString;\n    else {\n        const hasDouble = value.includes('\"');\n        const hasSingle = value.includes(\"'\");\n        if (hasDouble && !hasSingle)\n            qs = singleQuotedString;\n        else if (hasSingle && !hasDouble)\n            qs = doubleQuotedString;\n        else\n            qs = singleQuote ? singleQuotedString : doubleQuotedString;\n    }\n    return qs(value, ctx);\n}\n// The negative lookbehind avoids a polynomial search,\n// but isn't supported yet on Safari: https://caniuse.com/js-regexp-lookbehind\nlet blockEndNewlines;\ntry {\n    blockEndNewlines = new RegExp('(^|(?<!\\n))\\n+(?!\\n|$)', 'g');\n}\ncatch {\n    blockEndNewlines = /\\n+(?!\\n|$)/g;\n}\nfunction blockString({ comment, type, value }, ctx, onComment, onChompKeep) {\n    const { blockQuote, commentString, lineWidth } = ctx.options;\n    // 1. Block can't end in whitespace unless the last line is non-empty.\n    // 2. Strings consisting of only whitespace are best rendered explicitly.\n    if (!blockQuote || /\\n[\\t ]+$/.test(value)) {\n        return quotedString(value, ctx);\n    }\n    const indent = ctx.indent ||\n        (ctx.forceBlockIndent || containsDocumentMarker(value) ? '  ' : '');\n    const literal = blockQuote === 'literal'\n        ? true\n        : blockQuote === 'folded' || type === Scalar.BLOCK_FOLDED\n            ? false\n            : type === Scalar.BLOCK_LITERAL\n                ? true\n                : !lineLengthOverLimit(value, lineWidth, indent.length);\n    if (!value)\n        return literal ? '|\\n' : '>\\n';\n    // determine chomping from whitespace at value end\n    let chomp;\n    let endStart;\n    for (endStart = value.length; endStart > 0; --endStart) {\n        const ch = value[endStart - 1];\n        if (ch !== '\\n' && ch !== '\\t' && ch !== ' ')\n            break;\n    }\n    let end = value.substring(endStart);\n    const endNlPos = end.indexOf('\\n');\n    if (endNlPos === -1) {\n        chomp = '-'; // strip\n    }\n    else if (value === end || endNlPos !== end.length - 1) {\n        chomp = '+'; // keep\n        if (onChompKeep)\n            onChompKeep();\n    }\n    else {\n        chomp = ''; // clip\n    }\n    if (end) {\n        value = value.slice(0, -end.length);\n        if (end[end.length - 1] === '\\n')\n            end = end.slice(0, -1);\n        end = end.replace(blockEndNewlines, `$&${indent}`);\n    }\n    // determine indent indicator from whitespace at value start\n    let startWithSpace = false;\n    let startEnd;\n    let startNlPos = -1;\n    for (startEnd = 0; startEnd < value.length; ++startEnd) {\n        const ch = value[startEnd];\n        if (ch === ' ')\n            startWithSpace = true;\n        else if (ch === '\\n')\n            startNlPos = startEnd;\n        else\n            break;\n    }\n    let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);\n    if (start) {\n        value = value.substring(start.length);\n        start = start.replace(/\\n+/g, `$&${indent}`);\n    }\n    const indentSize = indent ? '2' : '1'; // root is at -1\n    // Leading | or > is added later\n    let header = (startWithSpace ? indentSize : '') + chomp;\n    if (comment) {\n        header += ' ' + commentString(comment.replace(/ ?[\\r\\n]+/g, ' '));\n        if (onComment)\n            onComment();\n    }\n    if (!literal) {\n        const foldedValue = value\n            .replace(/\\n+/g, '\\n$&')\n            .replace(/(?:^|\\n)([\\t ].*)(?:([\\n\\t ]*)\\n(?![\\n\\t ]))?/g, '$1$2') // more-indented lines aren't folded\n            //                ^ more-ind. ^ empty     ^ capture next empty lines only at end of indent\n            .replace(/\\n+/g, `$&${indent}`);\n        let literalFallback = false;\n        const foldOptions = getFoldOptions(ctx, true);\n        if (blockQuote !== 'folded' && type !== Scalar.BLOCK_FOLDED) {\n            foldOptions.onOverflow = () => {\n                literalFallback = true;\n            };\n        }\n        const body = foldFlowLines(`${start}${foldedValue}${end}`, indent, FOLD_BLOCK, foldOptions);\n        if (!literalFallback)\n            return `>${header}\\n${indent}${body}`;\n    }\n    value = value.replace(/\\n+/g, `$&${indent}`);\n    return `|${header}\\n${indent}${start}${value}${end}`;\n}\nfunction plainString(item, ctx, onComment, onChompKeep) {\n    const { type, value } = item;\n    const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;\n    if ((implicitKey && value.includes('\\n')) ||\n        (inFlow && /[[\\]{},]/.test(value))) {\n        return quotedString(value, ctx);\n    }\n    if (/^[\\n\\t ,[\\]{}#&*!|>'\"%@`]|^[?-]$|^[?-][ \\t]|[\\n:][ \\t]|[ \\t]\\n|[\\n\\t ]#|[\\n\\t :]$/.test(value)) {\n        // not allowed:\n        // - '-' or '?'\n        // - start with an indicator character (except [?:-]) or /[?-] /\n        // - '\\n ', ': ' or ' \\n' anywhere\n        // - '#' not preceded by a non-space char\n        // - end with ' ' or ':'\n        return implicitKey || inFlow || !value.includes('\\n')\n            ? quotedString(value, ctx)\n            : blockString(item, ctx, onComment, onChompKeep);\n    }\n    if (!implicitKey &&\n        !inFlow &&\n        type !== Scalar.PLAIN &&\n        value.includes('\\n')) {\n        // Where allowed & type not set explicitly, prefer block style for multiline strings\n        return blockString(item, ctx, onComment, onChompKeep);\n    }\n    if (containsDocumentMarker(value)) {\n        if (indent === '') {\n            ctx.forceBlockIndent = true;\n            return blockString(item, ctx, onComment, onChompKeep);\n        }\n        else if (implicitKey && indent === indentStep) {\n            return quotedString(value, ctx);\n        }\n    }\n    const str = value.replace(/\\n+/g, `$&\\n${indent}`);\n    // Verify that output will be parsed as a string, as e.g. plain numbers and\n    // booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'),\n    // and others in v1.1.\n    if (actualString) {\n        const test = (tag) => tag.default && tag.tag !== 'tag:yaml.org,2002:str' && tag.test?.test(str);\n        const { compat, tags } = ctx.doc.schema;\n        if (tags.some(test) || compat?.some(test))\n            return quotedString(value, ctx);\n    }\n    return implicitKey\n        ? str\n        : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx, false));\n}\nfunction stringifyString(item, ctx, onComment, onChompKeep) {\n    const { implicitKey, inFlow } = ctx;\n    const ss = typeof item.value === 'string'\n        ? item\n        : Object.assign({}, item, { value: String(item.value) });\n    let { type } = item;\n    if (type !== Scalar.QUOTE_DOUBLE) {\n        // force double quotes on control characters & unpaired surrogates\n        if (/[\\x00-\\x08\\x0b-\\x1f\\x7f-\\x9f\\u{D800}-\\u{DFFF}]/u.test(ss.value))\n            type = Scalar.QUOTE_DOUBLE;\n    }\n    const _stringify = (_type) => {\n        switch (_type) {\n            case Scalar.BLOCK_FOLDED:\n            case Scalar.BLOCK_LITERAL:\n                return implicitKey || inFlow\n                    ? quotedString(ss.value, ctx) // blocks are not valid inside flow containers\n                    : blockString(ss, ctx, onComment, onChompKeep);\n            case Scalar.QUOTE_DOUBLE:\n                return doubleQuotedString(ss.value, ctx);\n            case Scalar.QUOTE_SINGLE:\n                return singleQuotedString(ss.value, ctx);\n            case Scalar.PLAIN:\n                return plainString(ss, ctx, onComment, onChompKeep);\n            default:\n                return null;\n        }\n    };\n    let res = _stringify(type);\n    if (res === null) {\n        const { defaultKeyType, defaultStringType } = ctx.options;\n        const t = (implicitKey && defaultKeyType) || defaultStringType;\n        res = _stringify(t);\n        if (res === null)\n            throw new Error(`Unsupported default string type ${t}`);\n    }\n    return res;\n}\n\nexport { stringifyString };\n", "import { anchorIsValid } from '../doc/anchors.js';\nimport { isPair, isAlias, isNode, isScalar, isCollection } from '../nodes/identity.js';\nimport { stringifyComment } from './stringifyComment.js';\nimport { stringifyString } from './stringifyString.js';\n\nfunction createStringifyContext(doc, options) {\n    const opt = Object.assign({\n        blockQuote: true,\n        commentString: stringifyComment,\n        defaultKeyType: null,\n        defaultStringType: 'PLAIN',\n        directives: null,\n        doubleQuotedAsJSON: false,\n        doubleQuotedMinMultiLineLength: 40,\n        falseStr: 'false',\n        flowCollectionPadding: true,\n        indentSeq: true,\n        lineWidth: 80,\n        minContentWidth: 20,\n        nullStr: 'null',\n        simpleKeys: false,\n        singleQuote: null,\n        trailingComma: false,\n        trueStr: 'true',\n        verifyAliasOrder: true\n    }, doc.schema.toStringOptions, options);\n    let inFlow;\n    switch (opt.collectionStyle) {\n        case 'block':\n            inFlow = false;\n            break;\n        case 'flow':\n            inFlow = true;\n            break;\n        default:\n            inFlow = null;\n    }\n    return {\n        anchors: new Set(),\n        doc,\n        flowCollectionPadding: opt.flowCollectionPadding ? ' ' : '',\n        indent: '',\n        indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : '  ',\n        inFlow,\n        options: opt\n    };\n}\nfunction getTagObject(tags, item) {\n    if (item.tag) {\n        const match = tags.filter(t => t.tag === item.tag);\n        if (match.length > 0)\n            return match.find(t => t.format === item.format) ?? match[0];\n    }\n    let tagObj = undefined;\n    let obj;\n    if (isScalar(item)) {\n        obj = item.value;\n        let match = tags.filter(t => t.identify?.(obj));\n        if (match.length > 1) {\n            const testMatch = match.filter(t => t.test);\n            if (testMatch.length > 0)\n                match = testMatch;\n        }\n        tagObj =\n            match.find(t => t.format === item.format) ?? match.find(t => !t.format);\n    }\n    else {\n        obj = item;\n        tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);\n    }\n    if (!tagObj) {\n        const name = obj?.constructor?.name ?? (obj === null ? 'null' : typeof obj);\n        throw new Error(`Tag not resolved for ${name} value`);\n    }\n    return tagObj;\n}\n// needs to be called before value stringifier to allow for circular anchor refs\nfunction stringifyProps(node, tagObj, { anchors, doc }) {\n    if (!doc.directives)\n        return '';\n    const props = [];\n    const anchor = (isScalar(node) || isCollection(node)) && node.anchor;\n    if (anchor && anchorIsValid(anchor)) {\n        anchors.add(anchor);\n        props.push(`&${anchor}`);\n    }\n    const tag = node.tag ?? (tagObj.default ? null : tagObj.tag);\n    if (tag)\n        props.push(doc.directives.tagString(tag));\n    return props.join(' ');\n}\nfunction stringify(item, ctx, onComment, onChompKeep) {\n    if (isPair(item))\n        return item.toString(ctx, onComment, onChompKeep);\n    if (isAlias(item)) {\n        if (ctx.doc.directives)\n            return item.toString(ctx);\n        if (ctx.resolvedAliases?.has(item)) {\n            throw new TypeError(`Cannot stringify circular structure without alias nodes`);\n        }\n        else {\n            if (ctx.resolvedAliases)\n                ctx.resolvedAliases.add(item);\n            else\n                ctx.resolvedAliases = new Set([item]);\n            item = item.resolve(ctx.doc);\n        }\n    }\n    let tagObj = undefined;\n    const node = isNode(item)\n        ? item\n        : ctx.doc.createNode(item, { onTagObj: o => (tagObj = o) });\n    tagObj ?? (tagObj = getTagObject(ctx.doc.schema.tags, node));\n    const props = stringifyProps(node, tagObj, ctx);\n    if (props.length > 0)\n        ctx.indentAtStart = (ctx.indentAtStart ?? 0) + props.length + 1;\n    const str = typeof tagObj.stringify === 'function'\n        ? tagObj.stringify(node, ctx, onComment, onChompKeep)\n        : isScalar(node)\n            ? stringifyString(node, ctx, onComment, onChompKeep)\n            : node.toString(ctx, onComment, onChompKeep);\n    if (!props)\n        return str;\n    return isScalar(node) || str[0] === '{' || str[0] === '['\n        ? `${props} ${str}`\n        : `${props}\\n${ctx.indent}${str}`;\n}\n\nexport { createStringifyContext, stringify };\n", "import { isCollection, isNode, isScalar, isSeq } from '../nodes/identity.js';\nimport { Scalar } from '../nodes/Scalar.js';\nimport { stringify } from './stringify.js';\nimport { lineComment, indentComment } from './stringifyComment.js';\n\nfunction stringifyPair({ key, value }, ctx, onComment, onChompKeep) {\n    const { allNullValues, doc, indent, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;\n    let keyComment = (isNode(key) && key.comment) || null;\n    if (simpleKeys) {\n        if (keyComment) {\n            throw new Error('With simple keys, key nodes cannot have comments');\n        }\n        if (isCollection(key) || (!isNode(key) && typeof key === 'object')) {\n            const msg = 'With simple keys, collection cannot be used as a key value';\n            throw new Error(msg);\n        }\n    }\n    let explicitKey = !simpleKeys &&\n        (!key ||\n            (keyComment && value == null && !ctx.inFlow) ||\n            isCollection(key) ||\n            (isScalar(key)\n                ? key.type === Scalar.BLOCK_FOLDED || key.type === Scalar.BLOCK_LITERAL\n                : typeof key === 'object'));\n    ctx = Object.assign({}, ctx, {\n        allNullValues: false,\n        implicitKey: !explicitKey && (simpleKeys || !allNullValues),\n        indent: indent + indentStep\n    });\n    let keyCommentDone = false;\n    let chompKeep = false;\n    let str = stringify(key, ctx, () => (keyCommentDone = true), () => (chompKeep = true));\n    if (!explicitKey && !ctx.inFlow && str.length > 1024) {\n        if (simpleKeys)\n            throw new Error('With simple keys, single line scalar must not span more than 1024 characters');\n        explicitKey = true;\n    }\n    if (ctx.inFlow) {\n        if (allNullValues || value == null) {\n            if (keyCommentDone && onComment)\n                onComment();\n            return str === '' ? '?' : explicitKey ? `? ${str}` : str;\n        }\n    }\n    else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {\n        str = `? ${str}`;\n        if (keyComment && !keyCommentDone) {\n            str += lineComment(str, ctx.indent, commentString(keyComment));\n        }\n        else if (chompKeep && onChompKeep)\n            onChompKeep();\n        return str;\n    }\n    if (keyCommentDone)\n        keyComment = null;\n    if (explicitKey) {\n        if (keyComment)\n            str += lineComment(str, ctx.indent, commentString(keyComment));\n        str = `? ${str}\\n${indent}:`;\n    }\n    else {\n        str = `${str}:`;\n        if (keyComment)\n            str += lineComment(str, ctx.indent, commentString(keyComment));\n    }\n    let vsb, vcb, valueComment;\n    if (isNode(value)) {\n        vsb = !!value.spaceBefore;\n        vcb = value.commentBefore;\n        valueComment = value.comment;\n    }\n    else {\n        vsb = false;\n        vcb = null;\n        valueComment = null;\n        if (value && typeof value === 'object')\n            value = doc.createNode(value);\n    }\n    ctx.implicitKey = false;\n    if (!explicitKey && !keyComment && isScalar(value))\n        ctx.indentAtStart = str.length + 1;\n    chompKeep = false;\n    if (!indentSeq &&\n        indentStep.length >= 2 &&\n        !ctx.inFlow &&\n        !explicitKey &&\n        isSeq(value) &&\n        !value.flow &&\n        !value.tag &&\n        !value.anchor) {\n        // If indentSeq === false, consider '- ' as part of indentation where possible\n        ctx.indent = ctx.indent.substring(2);\n    }\n    let valueCommentDone = false;\n    const valueStr = stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));\n    let ws = ' ';\n    if (keyComment || vsb || vcb) {\n        ws = vsb ? '\\n' : '';\n        if (vcb) {\n            const cs = commentString(vcb);\n            ws += `\\n${indentComment(cs, ctx.indent)}`;\n        }\n        if (valueStr === '' && !ctx.inFlow) {\n            if (ws === '\\n' && valueComment)\n                ws = '\\n\\n';\n        }\n        else {\n            ws += `\\n${ctx.indent}`;\n        }\n    }\n    else if (!explicitKey && isCollection(value)) {\n        const vs0 = valueStr[0];\n        const nl0 = valueStr.indexOf('\\n');\n        const hasNewline = nl0 !== -1;\n        const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;\n        if (hasNewline || !flow) {\n            let hasPropsLine = false;\n            if (hasNewline && (vs0 === '&' || vs0 === '!')) {\n                let sp0 = valueStr.indexOf(' ');\n                if (vs0 === '&' &&\n                    sp0 !== -1 &&\n                    sp0 < nl0 &&\n                    valueStr[sp0 + 1] === '!') {\n                    sp0 = valueStr.indexOf(' ', sp0 + 1);\n                }\n                if (sp0 === -1 || nl0 < sp0)\n                    hasPropsLine = true;\n            }\n            if (!hasPropsLine)\n                ws = `\\n${ctx.indent}`;\n        }\n    }\n    else if (valueStr === '' || valueStr[0] === '\\n') {\n        ws = '';\n    }\n    str += ws + valueStr;\n    if (ctx.inFlow) {\n        if (valueCommentDone && onComment)\n            onComment();\n    }\n    else if (valueComment && !valueCommentDone) {\n        str += lineComment(str, ctx.indent, commentString(valueComment));\n    }\n    else if (chompKeep && onChompKeep) {\n        onChompKeep();\n    }\n    return str;\n}\n\nexport { stringifyPair };\n", "function debug(logLevel, ...messages) {\n    if (logLevel === 'debug')\n        console.log(...messages);\n}\nfunction warn(logLevel, warning) {\n    if (logLevel === 'debug' || logLevel === 'warn') {\n        console.warn(warning);\n    }\n}\n\nexport { debug, warn };\n", "import { isScalar, isAlias, isSeq, isMap } from '../../nodes/identity.js';\nimport { Scalar } from '../../nodes/Scalar.js';\n\n// If the value associated with a merge key is a single mapping node, each of\n// its key/value pairs is inserted into the current mapping, unless the key\n// already exists in it. If the value associated with the merge key is a\n// sequence, then this sequence is expected to contain mapping nodes and each\n// of these nodes is merged in turn according to its order in the sequence.\n// Keys in mapping nodes earlier in the sequence override keys specified in\n// later mapping nodes. -- http://yaml.org/type/merge.html\nconst MERGE_KEY = '<<';\nconst merge = {\n    identify: value => value === MERGE_KEY ||\n        (typeof value === 'symbol' && value.description === MERGE_KEY),\n    default: 'key',\n    tag: 'tag:yaml.org,2002:merge',\n    test: /^<<$/,\n    resolve: () => Object.assign(new Scalar(Symbol(MERGE_KEY)), {\n        addToJSMap: addMergeToJSMap\n    }),\n    stringify: () => MERGE_KEY\n};\nconst isMergeKey = (ctx, key) => (merge.identify(key) ||\n    (isScalar(key) &&\n        (!key.type || key.type === Scalar.PLAIN) &&\n        merge.identify(key.value))) &&\n    ctx?.doc.schema.tags.some(tag => tag.tag === merge.tag && tag.default);\nfunction addMergeToJSMap(ctx, map, value) {\n    value = ctx && isAlias(value) ? value.resolve(ctx.doc) : value;\n    if (isSeq(value))\n        for (const it of value.items)\n            mergeValue(ctx, map, it);\n    else if (Array.isArray(value))\n        for (const it of value)\n            mergeValue(ctx, map, it);\n    else\n        mergeValue(ctx, map, value);\n}\nfunction mergeValue(ctx, map, value) {\n    const source = ctx && isAlias(value) ? value.resolve(ctx.doc) : value;\n    if (!isMap(source))\n        throw new Error('Merge sources must be maps or map aliases');\n    const srcMap = source.toJSON(null, ctx, Map);\n    for (const [key, value] of srcMap) {\n        if (map instanceof Map) {\n            if (!map.has(key))\n                map.set(key, value);\n        }\n        else if (map instanceof Set) {\n            map.add(key);\n        }\n        else if (!Object.prototype.hasOwnProperty.call(map, key)) {\n            Object.defineProperty(map, key, {\n                value,\n                writable: true,\n                enumerable: true,\n                configurable: true\n            });\n        }\n    }\n    return map;\n}\n\nexport { addMergeToJSMap, isMergeKey, merge };\n", "import { warn } from '../log.js';\nimport { isMergeKey, addMergeToJSMap } from '../schema/yaml-1.1/merge.js';\nimport { createStringifyContext } from '../stringify/stringify.js';\nimport { isNode } from './identity.js';\nimport { toJS } from './toJS.js';\n\nfunction addPairToJSMap(ctx, map, { key, value }) {\n    if (isNode(key) && key.addToJSMap)\n        key.addToJSMap(ctx, map, value);\n    // TODO: Should drop this special case for bare << handling\n    else if (isMergeKey(ctx, key))\n        addMergeToJSMap(ctx, map, value);\n    else {\n        const jsKey = toJS(key, '', ctx);\n        if (map instanceof Map) {\n            map.set(jsKey, toJS(value, jsKey, ctx));\n        }\n        else if (map instanceof Set) {\n            map.add(jsKey);\n        }\n        else {\n            const stringKey = stringifyKey(key, jsKey, ctx);\n            const jsValue = toJS(value, stringKey, ctx);\n            if (stringKey in map)\n                Object.defineProperty(map, stringKey, {\n                    value: jsValue,\n                    writable: true,\n                    enumerable: true,\n                    configurable: true\n                });\n            else\n                map[stringKey] = jsValue;\n        }\n    }\n    return map;\n}\nfunction stringifyKey(key, jsKey, ctx) {\n    if (jsKey === null)\n        return '';\n    // eslint-disable-next-line @typescript-eslint/no-base-to-string\n    if (typeof jsKey !== 'object')\n        return String(jsKey);\n    if (isNode(key) && ctx?.doc) {\n        const strCtx = createStringifyContext(ctx.doc, {});\n        strCtx.anchors = new Set();\n        for (const node of ctx.anchors.keys())\n            strCtx.anchors.add(node.anchor);\n        strCtx.inFlow = true;\n        strCtx.inStringifyKey = true;\n        const strKey = key.toString(strCtx);\n        if (!ctx.mapKeyWarned) {\n            let jsonStr = JSON.stringify(strKey);\n            if (jsonStr.length > 40)\n                jsonStr = jsonStr.substring(0, 36) + '...\"';\n            warn(ctx.doc.options.logLevel, `Keys with collection values will be stringified due to JS Object restrictions: ${jsonStr}. Set mapAsMap: true to use object keys.`);\n            ctx.mapKeyWarned = true;\n        }\n        return strKey;\n    }\n    return JSON.stringify(jsKey);\n}\n\nexport { addPairToJSMap };\n", "import { createNode } from '../doc/createNode.js';\nimport { stringifyPair } from '../stringify/stringifyPair.js';\nimport { addPairToJSMap } from './addPairToJSMap.js';\nimport { NODE_TYPE, PAIR, isNode } from './identity.js';\n\nfunction createPair(key, value, ctx) {\n    const k = createNode(key, undefined, ctx);\n    const v = createNode(value, undefined, ctx);\n    return new Pair(k, v);\n}\nclass Pair {\n    constructor(key, value = null) {\n        Object.defineProperty(this, NODE_TYPE, { value: PAIR });\n        this.key = key;\n        this.value = value;\n    }\n    clone(schema) {\n        let { key, value } = this;\n        if (isNode(key))\n            key = key.clone(schema);\n        if (isNode(value))\n            value = value.clone(schema);\n        return new Pair(key, value);\n    }\n    toJSON(_, ctx) {\n        const pair = ctx?.mapAsMap ? new Map() : {};\n        return addPairToJSMap(ctx, pair, this);\n    }\n    toString(ctx, onComment, onChompKeep) {\n        return ctx?.doc\n            ? stringifyPair(this, ctx, onComment, onChompKeep)\n            : JSON.stringify(this);\n    }\n}\n\nexport { Pair, createPair };\n", "import { isNode, isPair } from '../nodes/identity.js';\nimport { stringify } from './stringify.js';\nimport { lineComment, indentComment } from './stringifyComment.js';\n\nfunction stringifyCollection(collection, ctx, options) {\n    const flow = ctx.inFlow ?? collection.flow;\n    const stringify = flow ? stringifyFlowCollection : stringifyBlockCollection;\n    return stringify(collection, ctx, options);\n}\nfunction stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, flowChars, itemIndent, onChompKeep, onComment }) {\n    const { indent, options: { commentString } } = ctx;\n    const itemCtx = Object.assign({}, ctx, { indent: itemIndent, type: null });\n    let chompKeep = false; // flag for the preceding node's status\n    const lines = [];\n    for (let i = 0; i < items.length; ++i) {\n        const item = items[i];\n        let comment = null;\n        if (isNode(item)) {\n            if (!chompKeep && item.spaceBefore)\n                lines.push('');\n            addCommentBefore(ctx, lines, item.commentBefore, chompKeep);\n            if (item.comment)\n                comment = item.comment;\n        }\n        else if (isPair(item)) {\n            const ik = isNode(item.key) ? item.key : null;\n            if (ik) {\n                if (!chompKeep && ik.spaceBefore)\n                    lines.push('');\n                addCommentBefore(ctx, lines, ik.commentBefore, chompKeep);\n            }\n        }\n        chompKeep = false;\n        let str = stringify(item, itemCtx, () => (comment = null), () => (chompKeep = true));\n        if (comment)\n            str += lineComment(str, itemIndent, commentString(comment));\n        if (chompKeep && comment)\n            chompKeep = false;\n        lines.push(blockItemPrefix + str);\n    }\n    let str;\n    if (lines.length === 0) {\n        str = flowChars.start + flowChars.end;\n    }\n    else {\n        str = lines[0];\n        for (let i = 1; i < lines.length; ++i) {\n            const line = lines[i];\n            str += line ? `\\n${indent}${line}` : '\\n';\n        }\n    }\n    if (comment) {\n        str += '\\n' + indentComment(commentString(comment), indent);\n        if (onComment)\n            onComment();\n    }\n    else if (chompKeep && onChompKeep)\n        onChompKeep();\n    return str;\n}\nfunction stringifyFlowCollection({ items }, ctx, { flowChars, itemIndent }) {\n    const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;\n    itemIndent += indentStep;\n    const itemCtx = Object.assign({}, ctx, {\n        indent: itemIndent,\n        inFlow: true,\n        type: null\n    });\n    let reqNewline = false;\n    let linesAtValue = 0;\n    const lines = [];\n    for (let i = 0; i < items.length; ++i) {\n        const item = items[i];\n        let comment = null;\n        if (isNode(item)) {\n            if (item.spaceBefore)\n                lines.push('');\n            addCommentBefore(ctx, lines, item.commentBefore, false);\n            if (item.comment)\n                comment = item.comment;\n        }\n        else if (isPair(item)) {\n            const ik = isNode(item.key) ? item.key : null;\n            if (ik) {\n                if (ik.spaceBefore)\n                    lines.push('');\n                addCommentBefore(ctx, lines, ik.commentBefore, false);\n                if (ik.comment)\n                    reqNewline = true;\n            }\n            const iv = isNode(item.value) ? item.value : null;\n            if (iv) {\n                if (iv.comment)\n                    comment = iv.comment;\n                if (iv.commentBefore)\n                    reqNewline = true;\n            }\n            else if (item.value == null && ik?.comment) {\n                comment = ik.comment;\n            }\n        }\n        if (comment)\n            reqNewline = true;\n        let str = stringify(item, itemCtx, () => (comment = null));\n        reqNewline || (reqNewline = lines.length > linesAtValue || str.includes('\\n'));\n        if (i < items.length - 1) {\n            str += ',';\n        }\n        else if (ctx.options.trailingComma) {\n            if (ctx.options.lineWidth > 0) {\n                reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) +\n                    (str.length + 2) >\n                    ctx.options.lineWidth);\n            }\n            if (reqNewline) {\n                str += ',';\n            }\n        }\n        if (comment)\n            str += lineComment(str, itemIndent, commentString(comment));\n        lines.push(str);\n        linesAtValue = lines.length;\n    }\n    const { start, end } = flowChars;\n    if (lines.length === 0) {\n        return start + end;\n    }\n    else {\n        if (!reqNewline) {\n            const len = lines.reduce((sum, line) => sum + line.length + 2, 2);\n            reqNewline = ctx.options.lineWidth > 0 && len > ctx.options.lineWidth;\n        }\n        if (reqNewline) {\n            let str = start;\n            for (const line of lines)\n                str += line ? `\\n${indentStep}${indent}${line}` : '\\n';\n            return `${str}\\n${indent}${end}`;\n        }\n        else {\n            return `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`;\n        }\n    }\n}\nfunction addCommentBefore({ indent, options: { commentString } }, lines, comment, chompKeep) {\n    if (comment && chompKeep)\n        comment = comment.replace(/^\\n+/, '');\n    if (comment) {\n        const ic = indentComment(commentString(comment), indent);\n        lines.push(ic.trimStart()); // Avoid double indent on first line\n    }\n}\n\nexport { stringifyCollection };\n", "import { stringifyCollection } from '../stringify/stringifyCollection.js';\nimport { addPairToJSMap } from './addPairToJSMap.js';\nimport { Collection } from './Collection.js';\nimport { MAP, isPair, isScalar } from './identity.js';\nimport { Pair, createPair } from './Pair.js';\nimport { isScalarValue } from './Scalar.js';\n\nfunction findPair(items, key) {\n    const k = isScalar(key) ? key.value : key;\n    for (const it of items) {\n        if (isPair(it)) {\n            if (it.key === key || it.key === k)\n                return it;\n            if (isScalar(it.key) && it.key.value === k)\n                return it;\n        }\n    }\n    return undefined;\n}\nclass YAMLMap extends Collection {\n    static get tagName() {\n        return 'tag:yaml.org,2002:map';\n    }\n    constructor(schema) {\n        super(MAP, schema);\n        this.items = [];\n    }\n    /**\n     * A generic collection parsing method that can be extended\n     * to other node classes that inherit from YAMLMap\n     */\n    static from(schema, obj, ctx) {\n        const { keepUndefined, replacer } = ctx;\n        const map = new this(schema);\n        const add = (key, value) => {\n            if (typeof replacer === 'function')\n                value = replacer.call(obj, key, value);\n            else if (Array.isArray(replacer) && !replacer.includes(key))\n                return;\n            if (value !== undefined || keepUndefined)\n                map.items.push(createPair(key, value, ctx));\n        };\n        if (obj instanceof Map) {\n            for (const [key, value] of obj)\n                add(key, value);\n        }\n        else if (obj && typeof obj === 'object') {\n            for (const key of Object.keys(obj))\n                add(key, obj[key]);\n        }\n        if (typeof schema.sortMapEntries === 'function') {\n            map.items.sort(schema.sortMapEntries);\n        }\n        return map;\n    }\n    /**\n     * Adds a value to the collection.\n     *\n     * @param overwrite - If not set `true`, using a key that is already in the\n     *   collection will throw. Otherwise, overwrites the previous value.\n     */\n    add(pair, overwrite) {\n        let _pair;\n        if (isPair(pair))\n            _pair = pair;\n        else if (!pair || typeof pair !== 'object' || !('key' in pair)) {\n            // In TypeScript, this never happens.\n            _pair = new Pair(pair, pair?.value);\n        }\n        else\n            _pair = new Pair(pair.key, pair.value);\n        const prev = findPair(this.items, _pair.key);\n        const sortEntries = this.schema?.sortMapEntries;\n        if (prev) {\n            if (!overwrite)\n                throw new Error(`Key ${_pair.key} already set`);\n            // For scalars, keep the old node & its comments and anchors\n            if (isScalar(prev.value) && isScalarValue(_pair.value))\n                prev.value.value = _pair.value;\n            else\n                prev.value = _pair.value;\n        }\n        else if (sortEntries) {\n            const i = this.items.findIndex(item => sortEntries(_pair, item) < 0);\n            if (i === -1)\n                this.items.push(_pair);\n            else\n                this.items.splice(i, 0, _pair);\n        }\n        else {\n            this.items.push(_pair);\n        }\n    }\n    delete(key) {\n        const it = findPair(this.items, key);\n        if (!it)\n            return false;\n        const del = this.items.splice(this.items.indexOf(it), 1);\n        return del.length > 0;\n    }\n    get(key, keepScalar) {\n        const it = findPair(this.items, key);\n        const node = it?.value;\n        return (!keepScalar && isScalar(node) ? node.value : node) ?? undefined;\n    }\n    has(key) {\n        return !!findPair(this.items, key);\n    }\n    set(key, value) {\n        this.add(new Pair(key, value), true);\n    }\n    /**\n     * @param ctx - Conversion context, originally set in Document#toJS()\n     * @param {Class} Type - If set, forces the returned collection type\n     * @returns Instance of Type, Map, or Object\n     */\n    toJSON(_, ctx, Type) {\n        const map = Type ? new Type() : ctx?.mapAsMap ? new Map() : {};\n        if (ctx?.onCreate)\n            ctx.onCreate(map);\n        for (const item of this.items)\n            addPairToJSMap(ctx, map, item);\n        return map;\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        for (const item of this.items) {\n            if (!isPair(item))\n                throw new Error(`Map items must all be pairs; found ${JSON.stringify(item)} instead`);\n        }\n        if (!ctx.allNullValues && this.hasAllNullValues(false))\n            ctx = Object.assign({}, ctx, { allNullValues: true });\n        return stringifyCollection(this, ctx, {\n            blockItemPrefix: '',\n            flowChars: { start: '{', end: '}' },\n            itemIndent: ctx.indent || '',\n            onChompKeep,\n            onComment\n        });\n    }\n}\n\nexport { YAMLMap, findPair };\n", "import { isMap } from '../../nodes/identity.js';\nimport { YAMLMap } from '../../nodes/YAMLMap.js';\n\nconst map = {\n    collection: 'map',\n    default: true,\n    nodeClass: YAMLMap,\n    tag: 'tag:yaml.org,2002:map',\n    resolve(map, onError) {\n        if (!isMap(map))\n            onError('Expected a mapping for this tag');\n        return map;\n    },\n    createNode: (schema, obj, ctx) => YAMLMap.from(schema, obj, ctx)\n};\n\nexport { map };\n", "import { createNode } from '../doc/createNode.js';\nimport { stringifyCollection } from '../stringify/stringifyCollection.js';\nimport { Collection } from './Collection.js';\nimport { SEQ, isScalar } from './identity.js';\nimport { isScalarValue } from './Scalar.js';\nimport { toJS } from './toJS.js';\n\nclass YAMLSeq extends Collection {\n    static get tagName() {\n        return 'tag:yaml.org,2002:seq';\n    }\n    constructor(schema) {\n        super(SEQ, schema);\n        this.items = [];\n    }\n    add(value) {\n        this.items.push(value);\n    }\n    /**\n     * Removes a value from the collection.\n     *\n     * `key` must contain a representation of an integer for this to succeed.\n     * It may be wrapped in a `Scalar`.\n     *\n     * @returns `true` if the item was found and removed.\n     */\n    delete(key) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            return false;\n        const del = this.items.splice(idx, 1);\n        return del.length > 0;\n    }\n    get(key, keepScalar) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            return undefined;\n        const it = this.items[idx];\n        return !keepScalar && isScalar(it) ? it.value : it;\n    }\n    /**\n     * Checks if the collection includes a value with the key `key`.\n     *\n     * `key` must contain a representation of an integer for this to succeed.\n     * It may be wrapped in a `Scalar`.\n     */\n    has(key) {\n        const idx = asItemIndex(key);\n        return typeof idx === 'number' && idx < this.items.length;\n    }\n    /**\n     * Sets a value in this collection. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     *\n     * If `key` does not contain a representation of an integer, this will throw.\n     * It may be wrapped in a `Scalar`.\n     */\n    set(key, value) {\n        const idx = asItemIndex(key);\n        if (typeof idx !== 'number')\n            throw new Error(`Expected a valid index, not ${key}.`);\n        const prev = this.items[idx];\n        if (isScalar(prev) && isScalarValue(value))\n            prev.value = value;\n        else\n            this.items[idx] = value;\n    }\n    toJSON(_, ctx) {\n        const seq = [];\n        if (ctx?.onCreate)\n            ctx.onCreate(seq);\n        let i = 0;\n        for (const item of this.items)\n            seq.push(toJS(item, String(i++), ctx));\n        return seq;\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        return stringifyCollection(this, ctx, {\n            blockItemPrefix: '- ',\n            flowChars: { start: '[', end: ']' },\n            itemIndent: (ctx.indent || '') + '  ',\n            onChompKeep,\n            onComment\n        });\n    }\n    static from(schema, obj, ctx) {\n        const { replacer } = ctx;\n        const seq = new this(schema);\n        if (obj && Symbol.iterator in Object(obj)) {\n            let i = 0;\n            for (let it of obj) {\n                if (typeof replacer === 'function') {\n                    const key = obj instanceof Set ? it : String(i++);\n                    it = replacer.call(obj, key, it);\n                }\n                seq.items.push(createNode(it, undefined, ctx));\n            }\n        }\n        return seq;\n    }\n}\nfunction asItemIndex(key) {\n    let idx = isScalar(key) ? key.value : key;\n    if (idx && typeof idx === 'string')\n        idx = Number(idx);\n    return typeof idx === 'number' && Number.isInteger(idx) && idx >= 0\n        ? idx\n        : null;\n}\n\nexport { YAMLSeq };\n", "import { isSeq } from '../../nodes/identity.js';\nimport { YAMLSeq } from '../../nodes/YAMLSeq.js';\n\nconst seq = {\n    collection: 'seq',\n    default: true,\n    nodeClass: YAMLSeq,\n    tag: 'tag:yaml.org,2002:seq',\n    resolve(seq, onError) {\n        if (!isSeq(seq))\n            onError('Expected a sequence for this tag');\n        return seq;\n    },\n    createNode: (schema, obj, ctx) => YAMLSeq.from(schema, obj, ctx)\n};\n\nexport { seq };\n", "import { stringifyString } from '../../stringify/stringifyString.js';\n\nconst string = {\n    identify: value => typeof value === 'string',\n    default: true,\n    tag: 'tag:yaml.org,2002:str',\n    resolve: str => str,\n    stringify(item, ctx, onComment, onChompKeep) {\n        ctx = Object.assign({ actualString: true }, ctx);\n        return stringifyString(item, ctx, onComment, onChompKeep);\n    }\n};\n\nexport { string };\n", "import { Scalar } from '../../nodes/Scalar.js';\n\nconst nullTag = {\n    identify: value => value == null,\n    createNode: () => new Scalar(null),\n    default: true,\n    tag: 'tag:yaml.org,2002:null',\n    test: /^(?:~|[Nn]ull|NULL)?$/,\n    resolve: () => new Scalar(null),\n    stringify: ({ source }, ctx) => typeof source === 'string' && nullTag.test.test(source)\n        ? source\n        : ctx.options.nullStr\n};\n\nexport { nullTag };\n", "import { Scalar } from '../../nodes/Scalar.js';\n\nconst boolTag = {\n    identify: value => typeof value === 'boolean',\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,\n    resolve: str => new Scalar(str[0] === 't' || str[0] === 'T'),\n    stringify({ source, value }, ctx) {\n        if (source && boolTag.test.test(source)) {\n            const sv = source[0] === 't' || source[0] === 'T';\n            if (value === sv)\n                return source;\n        }\n        return value ? ctx.options.trueStr : ctx.options.falseStr;\n    }\n};\n\nexport { boolTag };\n", "function stringifyNumber({ format, minFractionDigits, tag, value }) {\n    if (typeof value === 'bigint')\n        return String(value);\n    const num = typeof value === 'number' ? value : Number(value);\n    if (!isFinite(num))\n        return isNaN(num) ? '.nan' : num < 0 ? '-.inf' : '.inf';\n    let n = Object.is(value, -0) ? '-0' : JSON.stringify(value);\n    if (!format &&\n        minFractionDigits &&\n        (!tag || tag === 'tag:yaml.org,2002:float') &&\n        /^\\d/.test(n)) {\n        let i = n.indexOf('.');\n        if (i < 0) {\n            i = n.length;\n            n += '.';\n        }\n        let d = minFractionDigits - (n.length - i - 1);\n        while (d-- > 0)\n            n += '0';\n    }\n    return n;\n}\n\nexport { stringifyNumber };\n", "import { Scalar } from '../../nodes/Scalar.js';\nimport { stringifyNumber } from '../../stringify/stringifyNumber.js';\n\nconst floatNaN = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^(?:[-+]?\\.(?:inf|Inf|INF)|\\.nan|\\.NaN|\\.NAN)$/,\n    resolve: str => str.slice(-3).toLowerCase() === 'nan'\n        ? NaN\n        : str[0] === '-'\n            ? Number.NEGATIVE_INFINITY\n            : Number.POSITIVE_INFINITY,\n    stringify: stringifyNumber\n};\nconst floatExp = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'EXP',\n    test: /^[-+]?(?:\\.[0-9]+|[0-9]+(?:\\.[0-9]*)?)[eE][-+]?[0-9]+$/,\n    resolve: str => parseFloat(str),\n    stringify(node) {\n        const num = Number(node.value);\n        return isFinite(num) ? num.toExponential() : stringifyNumber(node);\n    }\n};\nconst float = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^[-+]?(?:\\.[0-9]+|[0-9]+\\.[0-9]*)$/,\n    resolve(str) {\n        const node = new Scalar(parseFloat(str));\n        const dot = str.indexOf('.');\n        if (dot !== -1 && str[str.length - 1] === '0')\n            node.minFractionDigits = str.length - dot - 1;\n        return node;\n    },\n    stringify: stringifyNumber\n};\n\nexport { float, floatExp, floatNaN };\n", "import { stringifyNumber } from '../../stringify/stringifyNumber.js';\n\nconst intIdentify = (value) => typeof value === 'bigint' || Number.isInteger(value);\nconst intResolve = (str, offset, radix, { intAsBigInt }) => (intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix));\nfunction intStringify(node, radix, prefix) {\n    const { value } = node;\n    if (intIdentify(value) && value >= 0)\n        return prefix + value.toString(radix);\n    return stringifyNumber(node);\n}\nconst intOct = {\n    identify: value => intIdentify(value) && value >= 0,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'OCT',\n    test: /^0o[0-7]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 8, opt),\n    stringify: node => intStringify(node, 8, '0o')\n};\nconst int = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    test: /^[-+]?[0-9]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),\n    stringify: stringifyNumber\n};\nconst intHex = {\n    identify: value => intIdentify(value) && value >= 0,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'HEX',\n    test: /^0x[0-9a-fA-F]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),\n    stringify: node => intStringify(node, 16, '0x')\n};\n\nexport { int, intHex, intOct };\n", "import { map } from '../common/map.js';\nimport { nullTag } from '../common/null.js';\nimport { seq } from '../common/seq.js';\nimport { string } from '../common/string.js';\nimport { boolTag } from './bool.js';\nimport { floatNaN, floatExp, float } from './float.js';\nimport { intOct, int, intHex } from './int.js';\n\nconst schema = [\n    map,\n    seq,\n    string,\n    nullTag,\n    boolTag,\n    intOct,\n    int,\n    intHex,\n    floatNaN,\n    floatExp,\n    float\n];\n\nexport { schema };\n", "import { Scalar } from '../../nodes/Scalar.js';\nimport { map } from '../common/map.js';\nimport { seq } from '../common/seq.js';\n\nfunction intIdentify(value) {\n    return typeof value === 'bigint' || Number.isInteger(value);\n}\nconst stringifyJSON = ({ value }) => JSON.stringify(value);\nconst jsonScalars = [\n    {\n        identify: value => typeof value === 'string',\n        default: true,\n        tag: 'tag:yaml.org,2002:str',\n        resolve: str => str,\n        stringify: stringifyJSON\n    },\n    {\n        identify: value => value == null,\n        createNode: () => new Scalar(null),\n        default: true,\n        tag: 'tag:yaml.org,2002:null',\n        test: /^null$/,\n        resolve: () => null,\n        stringify: stringifyJSON\n    },\n    {\n        identify: value => typeof value === 'boolean',\n        default: true,\n        tag: 'tag:yaml.org,2002:bool',\n        test: /^true$|^false$/,\n        resolve: str => str === 'true',\n        stringify: stringifyJSON\n    },\n    {\n        identify: intIdentify,\n        default: true,\n        tag: 'tag:yaml.org,2002:int',\n        test: /^-?(?:0|[1-9][0-9]*)$/,\n        resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),\n        stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)\n    },\n    {\n        identify: value => typeof value === 'number',\n        default: true,\n        tag: 'tag:yaml.org,2002:float',\n        test: /^-?(?:0|[1-9][0-9]*)(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,\n        resolve: str => parseFloat(str),\n        stringify: stringifyJSON\n    }\n];\nconst jsonError = {\n    default: true,\n    tag: '',\n    test: /^/,\n    resolve(str, onError) {\n        onError(`Unresolved plain scalar ${JSON.stringify(str)}`);\n        return str;\n    }\n};\nconst schema = [map, seq].concat(jsonScalars, jsonError);\n\nexport { schema };\n", "import { Scalar } from '../../nodes/Scalar.js';\nimport { stringifyString } from '../../stringify/stringifyString.js';\n\nconst binary = {\n    identify: value => value instanceof Uint8Array, // Buffer inherits from Uint8Array\n    default: false,\n    tag: 'tag:yaml.org,2002:binary',\n    /**\n     * Returns a Buffer in node and an Uint8Array in browsers\n     *\n     * To use the resulting buffer as an image, you'll want to do something like:\n     *\n     *   const blob = new Blob([buffer], { type: 'image/jpeg' })\n     *   document.querySelector('#photo').src = URL.createObjectURL(blob)\n     */\n    resolve(src, onError) {\n        if (typeof atob === 'function') {\n            // On IE 11, atob() can't handle newlines\n            const str = atob(src.replace(/[\\n\\r]/g, ''));\n            const buffer = new Uint8Array(str.length);\n            for (let i = 0; i < str.length; ++i)\n                buffer[i] = str.charCodeAt(i);\n            return buffer;\n        }\n        else {\n            onError('This environment does not support reading binary tags; either Buffer or atob is required');\n            return src;\n        }\n    },\n    stringify({ comment, type, value }, ctx, onComment, onChompKeep) {\n        if (!value)\n            return '';\n        const buf = value; // checked earlier by binary.identify()\n        let str;\n        if (typeof btoa === 'function') {\n            let s = '';\n            for (let i = 0; i < buf.length; ++i)\n                s += String.fromCharCode(buf[i]);\n            str = btoa(s);\n        }\n        else {\n            throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required');\n        }\n        type ?? (type = Scalar.BLOCK_LITERAL);\n        if (type !== Scalar.QUOTE_DOUBLE) {\n            const lineWidth = Math.max(ctx.options.lineWidth - ctx.indent.length, ctx.options.minContentWidth);\n            const n = Math.ceil(str.length / lineWidth);\n            const lines = new Array(n);\n            for (let i = 0, o = 0; i < n; ++i, o += lineWidth) {\n                lines[i] = str.substr(o, lineWidth);\n            }\n            str = lines.join(type === Scalar.BLOCK_LITERAL ? '\\n' : ' ');\n        }\n        return stringifyString({ comment, type, value: str }, ctx, onComment, onChompKeep);\n    }\n};\n\nexport { binary };\n", "import { isSeq, isPair, isMap } from '../../nodes/identity.js';\nimport { createPair, Pair } from '../../nodes/Pair.js';\nimport { Scalar } from '../../nodes/Scalar.js';\nimport { YAMLSeq } from '../../nodes/YAMLSeq.js';\n\nfunction resolvePairs(seq, onError) {\n    if (isSeq(seq)) {\n        for (let i = 0; i < seq.items.length; ++i) {\n            let item = seq.items[i];\n            if (isPair(item))\n                continue;\n            else if (isMap(item)) {\n                if (item.items.length > 1)\n                    onError('Each pair must have its own sequence indicator');\n                const pair = item.items[0] || new Pair(new Scalar(null));\n                if (item.commentBefore)\n                    pair.key.commentBefore = pair.key.commentBefore\n                        ? `${item.commentBefore}\\n${pair.key.commentBefore}`\n                        : item.commentBefore;\n                if (item.comment) {\n                    const cn = pair.value ?? pair.key;\n                    cn.comment = cn.comment\n                        ? `${item.comment}\\n${cn.comment}`\n                        : item.comment;\n                }\n                item = pair;\n            }\n            seq.items[i] = isPair(item) ? item : new Pair(item);\n        }\n    }\n    else\n        onError('Expected a sequence for this tag');\n    return seq;\n}\nfunction createPairs(schema, iterable, ctx) {\n    const { replacer } = ctx;\n    const pairs = new YAMLSeq(schema);\n    pairs.tag = 'tag:yaml.org,2002:pairs';\n    let i = 0;\n    if (iterable && Symbol.iterator in Object(iterable))\n        for (let it of iterable) {\n            if (typeof replacer === 'function')\n                it = replacer.call(iterable, String(i++), it);\n            let key, value;\n            if (Array.isArray(it)) {\n                if (it.length === 2) {\n                    key = it[0];\n                    value = it[1];\n                }\n                else\n                    throw new TypeError(`Expected [key, value] tuple: ${it}`);\n            }\n            else if (it && it instanceof Object) {\n                const keys = Object.keys(it);\n                if (keys.length === 1) {\n                    key = keys[0];\n                    value = it[key];\n                }\n                else {\n                    throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);\n                }\n            }\n            else {\n                key = it;\n            }\n            pairs.items.push(createPair(key, value, ctx));\n        }\n    return pairs;\n}\nconst pairs = {\n    collection: 'seq',\n    default: false,\n    tag: 'tag:yaml.org,2002:pairs',\n    resolve: resolvePairs,\n    createNode: createPairs\n};\n\nexport { createPairs, pairs, resolvePairs };\n", "import { isScalar, isPair } from '../../nodes/identity.js';\nimport { toJS } from '../../nodes/toJS.js';\nimport { YAMLMap } from '../../nodes/YAMLMap.js';\nimport { YAMLSeq } from '../../nodes/YAMLSeq.js';\nimport { resolvePairs, createPairs } from './pairs.js';\n\nclass YAMLOMap extends YAMLSeq {\n    constructor() {\n        super();\n        this.add = YAMLMap.prototype.add.bind(this);\n        this.delete = YAMLMap.prototype.delete.bind(this);\n        this.get = YAMLMap.prototype.get.bind(this);\n        this.has = YAMLMap.prototype.has.bind(this);\n        this.set = YAMLMap.prototype.set.bind(this);\n        this.tag = YAMLOMap.tag;\n    }\n    /**\n     * If `ctx` is given, the return type is actually `Map<unknown, unknown>`,\n     * but TypeScript won't allow widening the signature of a child method.\n     */\n    toJSON(_, ctx) {\n        if (!ctx)\n            return super.toJSON(_);\n        const map = new Map();\n        if (ctx?.onCreate)\n            ctx.onCreate(map);\n        for (const pair of this.items) {\n            let key, value;\n            if (isPair(pair)) {\n                key = toJS(pair.key, '', ctx);\n                value = toJS(pair.value, key, ctx);\n            }\n            else {\n                key = toJS(pair, '', ctx);\n            }\n            if (map.has(key))\n                throw new Error('Ordered maps must not include duplicate keys');\n            map.set(key, value);\n        }\n        return map;\n    }\n    static from(schema, iterable, ctx) {\n        const pairs = createPairs(schema, iterable, ctx);\n        const omap = new this();\n        omap.items = pairs.items;\n        return omap;\n    }\n}\nYAMLOMap.tag = 'tag:yaml.org,2002:omap';\nconst omap = {\n    collection: 'seq',\n    identify: value => value instanceof Map,\n    nodeClass: YAMLOMap,\n    default: false,\n    tag: 'tag:yaml.org,2002:omap',\n    resolve(seq, onError) {\n        const pairs = resolvePairs(seq, onError);\n        const seenKeys = [];\n        for (const { key } of pairs.items) {\n            if (isScalar(key)) {\n                if (seenKeys.includes(key.value)) {\n                    onError(`Ordered maps must not include duplicate keys: ${key.value}`);\n                }\n                else {\n                    seenKeys.push(key.value);\n                }\n            }\n        }\n        return Object.assign(new YAMLOMap(), pairs);\n    },\n    createNode: (schema, iterable, ctx) => YAMLOMap.from(schema, iterable, ctx)\n};\n\nexport { YAMLOMap, omap };\n", "import { Scalar } from '../../nodes/Scalar.js';\n\nfunction boolStringify({ value, source }, ctx) {\n    const boolObj = value ? trueTag : falseTag;\n    if (source && boolObj.test.test(source))\n        return source;\n    return value ? ctx.options.trueStr : ctx.options.falseStr;\n}\nconst trueTag = {\n    identify: value => value === true,\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,\n    resolve: () => new Scalar(true),\n    stringify: boolStringify\n};\nconst falseTag = {\n    identify: value => value === false,\n    default: true,\n    tag: 'tag:yaml.org,2002:bool',\n    test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,\n    resolve: () => new Scalar(false),\n    stringify: boolStringify\n};\n\nexport { falseTag, trueTag };\n", "import { Scalar } from '../../nodes/Scalar.js';\nimport { stringifyNumber } from '../../stringify/stringifyNumber.js';\n\nconst floatNaN = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^(?:[-+]?\\.(?:inf|Inf|INF)|\\.nan|\\.NaN|\\.NAN)$/,\n    resolve: (str) => str.slice(-3).toLowerCase() === 'nan'\n        ? NaN\n        : str[0] === '-'\n            ? Number.NEGATIVE_INFINITY\n            : Number.POSITIVE_INFINITY,\n    stringify: stringifyNumber\n};\nconst floatExp = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'EXP',\n    test: /^[-+]?(?:[0-9][0-9_]*)?(?:\\.[0-9_]*)?[eE][-+]?[0-9]+$/,\n    resolve: (str) => parseFloat(str.replace(/_/g, '')),\n    stringify(node) {\n        const num = Number(node.value);\n        return isFinite(num) ? num.toExponential() : stringifyNumber(node);\n    }\n};\nconst float = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    test: /^[-+]?(?:[0-9][0-9_]*)?\\.[0-9_]*$/,\n    resolve(str) {\n        const node = new Scalar(parseFloat(str.replace(/_/g, '')));\n        const dot = str.indexOf('.');\n        if (dot !== -1) {\n            const f = str.substring(dot + 1).replace(/_/g, '');\n            if (f[f.length - 1] === '0')\n                node.minFractionDigits = f.length;\n        }\n        return node;\n    },\n    stringify: stringifyNumber\n};\n\nexport { float, floatExp, floatNaN };\n", "import { stringifyNumber } from '../../stringify/stringifyNumber.js';\n\nconst intIdentify = (value) => typeof value === 'bigint' || Number.isInteger(value);\nfunction intResolve(str, offset, radix, { intAsBigInt }) {\n    const sign = str[0];\n    if (sign === '-' || sign === '+')\n        offset += 1;\n    str = str.substring(offset).replace(/_/g, '');\n    if (intAsBigInt) {\n        switch (radix) {\n            case 2:\n                str = `0b${str}`;\n                break;\n            case 8:\n                str = `0o${str}`;\n                break;\n            case 16:\n                str = `0x${str}`;\n                break;\n        }\n        const n = BigInt(str);\n        return sign === '-' ? BigInt(-1) * n : n;\n    }\n    const n = parseInt(str, radix);\n    return sign === '-' ? -1 * n : n;\n}\nfunction intStringify(node, radix, prefix) {\n    const { value } = node;\n    if (intIdentify(value)) {\n        const str = value.toString(radix);\n        return value < 0 ? '-' + prefix + str.substr(1) : prefix + str;\n    }\n    return stringifyNumber(node);\n}\nconst intBin = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'BIN',\n    test: /^[-+]?0b[0-1_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 2, opt),\n    stringify: node => intStringify(node, 2, '0b')\n};\nconst intOct = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'OCT',\n    test: /^[-+]?0[0-7_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 1, 8, opt),\n    stringify: node => intStringify(node, 8, '0')\n};\nconst int = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    test: /^[-+]?[0-9][0-9_]*$/,\n    resolve: (str, _onError, opt) => intResolve(str, 0, 10, opt),\n    stringify: stringifyNumber\n};\nconst intHex = {\n    identify: intIdentify,\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'HEX',\n    test: /^[-+]?0x[0-9a-fA-F_]+$/,\n    resolve: (str, _onError, opt) => intResolve(str, 2, 16, opt),\n    stringify: node => intStringify(node, 16, '0x')\n};\n\nexport { int, intBin, intHex, intOct };\n", "import { isMap, isPair, isScalar } from '../../nodes/identity.js';\nimport { Pair, createPair } from '../../nodes/Pair.js';\nimport { YAMLMap, findPair } from '../../nodes/YAMLMap.js';\n\nclass YAMLSet extends YAMLMap {\n    constructor(schema) {\n        super(schema);\n        this.tag = YAMLSet.tag;\n    }\n    add(key) {\n        let pair;\n        if (isPair(key))\n            pair = key;\n        else if (key &&\n            typeof key === 'object' &&\n            'key' in key &&\n            'value' in key &&\n            key.value === null)\n            pair = new Pair(key.key, null);\n        else\n            pair = new Pair(key, null);\n        const prev = findPair(this.items, pair.key);\n        if (!prev)\n            this.items.push(pair);\n    }\n    /**\n     * If `keepPair` is `true`, returns the Pair matching `key`.\n     * Otherwise, returns the value of that Pair's key.\n     */\n    get(key, keepPair) {\n        const pair = findPair(this.items, key);\n        return !keepPair && isPair(pair)\n            ? isScalar(pair.key)\n                ? pair.key.value\n                : pair.key\n            : pair;\n    }\n    set(key, value) {\n        if (typeof value !== 'boolean')\n            throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);\n        const prev = findPair(this.items, key);\n        if (prev && !value) {\n            this.items.splice(this.items.indexOf(prev), 1);\n        }\n        else if (!prev && value) {\n            this.items.push(new Pair(key));\n        }\n    }\n    toJSON(_, ctx) {\n        return super.toJSON(_, ctx, Set);\n    }\n    toString(ctx, onComment, onChompKeep) {\n        if (!ctx)\n            return JSON.stringify(this);\n        if (this.hasAllNullValues(true))\n            return super.toString(Object.assign({}, ctx, { allNullValues: true }), onComment, onChompKeep);\n        else\n            throw new Error('Set items must all have null values');\n    }\n    static from(schema, iterable, ctx) {\n        const { replacer } = ctx;\n        const set = new this(schema);\n        if (iterable && Symbol.iterator in Object(iterable))\n            for (let value of iterable) {\n                if (typeof replacer === 'function')\n                    value = replacer.call(iterable, value, value);\n                set.items.push(createPair(value, null, ctx));\n            }\n        return set;\n    }\n}\nYAMLSet.tag = 'tag:yaml.org,2002:set';\nconst set = {\n    collection: 'map',\n    identify: value => value instanceof Set,\n    nodeClass: YAMLSet,\n    default: false,\n    tag: 'tag:yaml.org,2002:set',\n    createNode: (schema, iterable, ctx) => YAMLSet.from(schema, iterable, ctx),\n    resolve(map, onError) {\n        if (isMap(map)) {\n            if (map.hasAllNullValues(true))\n                return Object.assign(new YAMLSet(), map);\n            else\n                onError('Set items must all have null values');\n        }\n        else\n            onError('Expected a mapping for this tag');\n        return map;\n    }\n};\n\nexport { YAMLSet, set };\n", "import { stringifyNumber } from '../../stringify/stringifyNumber.js';\n\n/** Internal types handle bigint as number, because TS can't figure it out. */\nfunction parseSexagesimal(str, asBigInt) {\n    const sign = str[0];\n    const parts = sign === '-' || sign === '+' ? str.substring(1) : str;\n    const num = (n) => asBigInt ? BigInt(n) : Number(n);\n    const res = parts\n        .replace(/_/g, '')\n        .split(':')\n        .reduce((res, p) => res * num(60) + num(p), num(0));\n    return (sign === '-' ? num(-1) * res : res);\n}\n/**\n * hhhh:mm:ss.sss\n *\n * Internal types handle bigint as number, because TS can't figure it out.\n */\nfunction stringifySexagesimal(node) {\n    let { value } = node;\n    let num = (n) => n;\n    if (typeof value === 'bigint')\n        num = n => BigInt(n);\n    else if (isNaN(value) || !isFinite(value))\n        return stringifyNumber(node);\n    let sign = '';\n    if (value < 0) {\n        sign = '-';\n        value *= num(-1);\n    }\n    const _60 = num(60);\n    const parts = [value % _60]; // seconds, including ms\n    if (value < 60) {\n        parts.unshift(0); // at least one : is required\n    }\n    else {\n        value = (value - parts[0]) / _60;\n        parts.unshift(value % _60); // minutes\n        if (value >= 60) {\n            value = (value - parts[0]) / _60;\n            parts.unshift(value); // hours\n        }\n    }\n    return (sign +\n        parts\n            .map(n => String(n).padStart(2, '0'))\n            .join(':')\n            .replace(/000000\\d*$/, '') // % 60 may introduce error\n    );\n}\nconst intTime = {\n    identify: value => typeof value === 'bigint' || Number.isInteger(value),\n    default: true,\n    tag: 'tag:yaml.org,2002:int',\n    format: 'TIME',\n    test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/,\n    resolve: (str, _onError, { intAsBigInt }) => parseSexagesimal(str, intAsBigInt),\n    stringify: stringifySexagesimal\n};\nconst floatTime = {\n    identify: value => typeof value === 'number',\n    default: true,\n    tag: 'tag:yaml.org,2002:float',\n    format: 'TIME',\n    test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*$/,\n    resolve: str => parseSexagesimal(str, false),\n    stringify: stringifySexagesimal\n};\nconst timestamp = {\n    identify: value => value instanceof Date,\n    default: true,\n    tag: 'tag:yaml.org,2002:timestamp',\n    // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part\n    // may be omitted altogether, resulting in a date format. In such a case, the time part is\n    // assumed to be 00:00:00Z (start of day, UTC).\n    test: RegExp('^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})' + // YYYY-Mm-Dd\n        '(?:' + // time is optional\n        '(?:t|T|[ \\\\t]+)' + // t | T | whitespace\n        '([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\\\.[0-9]+)?)' + // Hh:Mm:Ss(.ss)?\n        '(?:[ \\\\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?' + // Z | +5 | -03:30\n        ')?$'),\n    resolve(str) {\n        const match = str.match(timestamp.test);\n        if (!match)\n            throw new Error('!!timestamp expects a date, starting with yyyy-mm-dd');\n        const [, year, month, day, hour, minute, second] = match.map(Number);\n        const millisec = match[7] ? Number((match[7] + '00').substr(1, 3)) : 0;\n        let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);\n        const tz = match[8];\n        if (tz && tz !== 'Z') {\n            let d = parseSexagesimal(tz, false);\n            if (Math.abs(d) < 30)\n                d *= 60;\n            date -= 60000 * d;\n        }\n        return new Date(date);\n    },\n    stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\\.000Z$/, '') ?? ''\n};\n\nexport { floatTime, intTime, timestamp };\n", "import { map } from '../common/map.js';\nimport { nullTag } from '../common/null.js';\nimport { seq } from '../common/seq.js';\nimport { string } from '../common/string.js';\nimport { binary } from './binary.js';\nimport { trueTag, falseTag } from './bool.js';\nimport { floatNaN, floatExp, float } from './float.js';\nimport { intBin, intOct, int, intHex } from './int.js';\nimport { merge } from './merge.js';\nimport { omap } from './omap.js';\nimport { pairs } from './pairs.js';\nimport { set } from './set.js';\nimport { intTime, floatTime, timestamp } from './timestamp.js';\n\nconst schema = [\n    map,\n    seq,\n    string,\n    nullTag,\n    trueTag,\n    falseTag,\n    intBin,\n    intOct,\n    int,\n    intHex,\n    floatNaN,\n    floatExp,\n    float,\n    binary,\n    merge,\n    omap,\n    pairs,\n    set,\n    intTime,\n    floatTime,\n    timestamp\n];\n\nexport { schema };\n", "import { map } from './common/map.js';\nimport { nullTag } from './common/null.js';\nimport { seq } from './common/seq.js';\nimport { string } from './common/string.js';\nimport { boolTag } from './core/bool.js';\nimport { floatNaN, floatExp, float } from './core/float.js';\nimport { intOct, intHex, int } from './core/int.js';\nimport { schema } from './core/schema.js';\nimport { schema as schema$1 } from './json/schema.js';\nimport { binary } from './yaml-1.1/binary.js';\nimport { merge } from './yaml-1.1/merge.js';\nimport { omap } from './yaml-1.1/omap.js';\nimport { pairs } from './yaml-1.1/pairs.js';\nimport { schema as schema$2 } from './yaml-1.1/schema.js';\nimport { set } from './yaml-1.1/set.js';\nimport { timestamp, intTime, floatTime } from './yaml-1.1/timestamp.js';\n\nconst schemas = new Map([\n    ['core', schema],\n    ['failsafe', [map, seq, string]],\n    ['json', schema$1],\n    ['yaml11', schema$2],\n    ['yaml-1.1', schema$2]\n]);\nconst tagsByName = {\n    binary,\n    bool: boolTag,\n    float,\n    floatExp,\n    floatNaN,\n    floatTime,\n    int,\n    intHex,\n    intOct,\n    intTime,\n    map,\n    merge,\n    null: nullTag,\n    omap,\n    pairs,\n    seq,\n    set,\n    timestamp\n};\nconst coreKnownTags = {\n    'tag:yaml.org,2002:binary': binary,\n    'tag:yaml.org,2002:merge': merge,\n    'tag:yaml.org,2002:omap': omap,\n    'tag:yaml.org,2002:pairs': pairs,\n    'tag:yaml.org,2002:set': set,\n    'tag:yaml.org,2002:timestamp': timestamp\n};\nfunction getTags(customTags, schemaName, addMergeTag) {\n    const schemaTags = schemas.get(schemaName);\n    if (schemaTags && !customTags) {\n        return addMergeTag && !schemaTags.includes(merge)\n            ? schemaTags.concat(merge)\n            : schemaTags.slice();\n    }\n    let tags = schemaTags;\n    if (!tags) {\n        if (Array.isArray(customTags))\n            tags = [];\n        else {\n            const keys = Array.from(schemas.keys())\n                .filter(key => key !== 'yaml11')\n                .map(key => JSON.stringify(key))\n                .join(', ');\n            throw new Error(`Unknown schema \"${schemaName}\"; use one of ${keys} or define customTags array`);\n        }\n    }\n    if (Array.isArray(customTags)) {\n        for (const tag of customTags)\n            tags = tags.concat(tag);\n    }\n    else if (typeof customTags === 'function') {\n        tags = customTags(tags.slice());\n    }\n    if (addMergeTag)\n        tags = tags.concat(merge);\n    return tags.reduce((tags, tag) => {\n        const tagObj = typeof tag === 'string' ? tagsByName[tag] : tag;\n        if (!tagObj) {\n            const tagName = JSON.stringify(tag);\n            const keys = Object.keys(tagsByName)\n                .map(key => JSON.stringify(key))\n                .join(', ');\n            throw new Error(`Unknown custom tag ${tagName}; use one of ${keys}`);\n        }\n        if (!tags.includes(tagObj))\n            tags.push(tagObj);\n        return tags;\n    }, []);\n}\n\nexport { coreKnownTags, getTags };\n", "import { MAP, SCALAR, SEQ } from '../nodes/identity.js';\nimport { map } from './common/map.js';\nimport { seq } from './common/seq.js';\nimport { string } from './common/string.js';\nimport { getTags, coreKnownTags } from './tags.js';\n\nconst sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0;\nclass Schema {\n    constructor({ compat, customTags, merge, resolveKnownTags, schema, sortMapEntries, toStringDefaults }) {\n        this.compat = Array.isArray(compat)\n            ? getTags(compat, 'compat')\n            : compat\n                ? getTags(null, compat)\n                : null;\n        this.name = (typeof schema === 'string' && schema) || 'core';\n        this.knownTags = resolveKnownTags ? coreKnownTags : {};\n        this.tags = getTags(customTags, this.name, merge);\n        this.toStringOptions = toStringDefaults ?? null;\n        Object.defineProperty(this, MAP, { value: map });\n        Object.defineProperty(this, SCALAR, { value: string });\n        Object.defineProperty(this, SEQ, { value: seq });\n        // Used by createMap()\n        this.sortMapEntries =\n            typeof sortMapEntries === 'function'\n                ? sortMapEntries\n                : sortMapEntries === true\n                    ? sortMapEntriesByKey\n                    : null;\n    }\n    clone() {\n        const copy = Object.create(Schema.prototype, Object.getOwnPropertyDescriptors(this));\n        copy.tags = this.tags.slice();\n        return copy;\n    }\n}\n\nexport { Schema };\n", "import { isNode } from '../nodes/identity.js';\nimport { createStringifyContext, stringify } from './stringify.js';\nimport { indentComment, lineComment } from './stringifyComment.js';\n\nfunction stringifyDocument(doc, options) {\n    const lines = [];\n    let hasDirectives = options.directives === true;\n    if (options.directives !== false && doc.directives) {\n        const dir = doc.directives.toString(doc);\n        if (dir) {\n            lines.push(dir);\n            hasDirectives = true;\n        }\n        else if (doc.directives.docStart)\n            hasDirectives = true;\n    }\n    if (hasDirectives)\n        lines.push('---');\n    const ctx = createStringifyContext(doc, options);\n    const { commentString } = ctx.options;\n    if (doc.commentBefore) {\n        if (lines.length !== 1)\n            lines.unshift('');\n        const cs = commentString(doc.commentBefore);\n        lines.unshift(indentComment(cs, ''));\n    }\n    let chompKeep = false;\n    let contentComment = null;\n    if (doc.contents) {\n        if (isNode(doc.contents)) {\n            if (doc.contents.spaceBefore && hasDirectives)\n                lines.push('');\n            if (doc.contents.commentBefore) {\n                const cs = commentString(doc.contents.commentBefore);\n                lines.push(indentComment(cs, ''));\n            }\n            // top-level block scalars need to be indented if followed by a comment\n            ctx.forceBlockIndent = !!doc.comment;\n            contentComment = doc.contents.comment;\n        }\n        const onChompKeep = contentComment ? undefined : () => (chompKeep = true);\n        let body = stringify(doc.contents, ctx, () => (contentComment = null), onChompKeep);\n        if (contentComment)\n            body += lineComment(body, '', commentString(contentComment));\n        if ((body[0] === '|' || body[0] === '>') &&\n            lines[lines.length - 1] === '---') {\n            // Top-level block scalars with a preceding doc marker ought to use the\n            // same line for their header.\n            lines[lines.length - 1] = `--- ${body}`;\n        }\n        else\n            lines.push(body);\n    }\n    else {\n        lines.push(stringify(doc.contents, ctx));\n    }\n    if (doc.directives?.docEnd) {\n        if (doc.comment) {\n            const cs = commentString(doc.comment);\n            if (cs.includes('\\n')) {\n                lines.push('...');\n                lines.push(indentComment(cs, ''));\n            }\n            else {\n                lines.push(`... ${cs}`);\n            }\n        }\n        else {\n            lines.push('...');\n        }\n    }\n    else {\n        let dc = doc.comment;\n        if (dc && chompKeep)\n            dc = dc.replace(/^\\n+/, '');\n        if (dc) {\n            if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')\n                lines.push('');\n            lines.push(indentComment(commentString(dc), ''));\n        }\n    }\n    return lines.join('\\n') + '\\n';\n}\n\nexport { stringifyDocument };\n", "import { Alias } from '../nodes/Alias.js';\nimport { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';\nimport { NODE_TYPE, DOC, isNode, isCollection, isScalar } from '../nodes/identity.js';\nimport { Pair } from '../nodes/Pair.js';\nimport { toJS } from '../nodes/toJS.js';\nimport { Schema } from '../schema/Schema.js';\nimport { stringifyDocument } from '../stringify/stringifyDocument.js';\nimport { anchorNames, findNewAnchor, createNodeAnchors } from './anchors.js';\nimport { applyReviver } from './applyReviver.js';\nimport { createNode } from './createNode.js';\nimport { Directives } from './directives.js';\n\nclass Document {\n    constructor(value, replacer, options) {\n        /** A comment before this Document */\n        this.commentBefore = null;\n        /** A comment immediately after this Document */\n        this.comment = null;\n        /** Errors encountered during parsing. */\n        this.errors = [];\n        /** Warnings encountered during parsing. */\n        this.warnings = [];\n        Object.defineProperty(this, NODE_TYPE, { value: DOC });\n        let _replacer = null;\n        if (typeof replacer === 'function' || Array.isArray(replacer)) {\n            _replacer = replacer;\n        }\n        else if (options === undefined && replacer) {\n            options = replacer;\n            replacer = undefined;\n        }\n        const opt = Object.assign({\n            intAsBigInt: false,\n            keepSourceTokens: false,\n            logLevel: 'warn',\n            prettyErrors: true,\n            strict: true,\n            stringKeys: false,\n            uniqueKeys: true,\n            version: '1.2'\n        }, options);\n        this.options = opt;\n        let { version } = opt;\n        if (options?._directives) {\n            this.directives = options._directives.atDocument();\n            if (this.directives.yaml.explicit)\n                version = this.directives.yaml.version;\n        }\n        else\n            this.directives = new Directives({ version });\n        this.setSchema(version, options);\n        // @ts-expect-error We can't really know that this matches Contents.\n        this.contents =\n            value === undefined ? null : this.createNode(value, _replacer, options);\n    }\n    /**\n     * Create a deep copy of this Document and its contents.\n     *\n     * Custom Node values that inherit from `Object` still refer to their original instances.\n     */\n    clone() {\n        const copy = Object.create(Document.prototype, {\n            [NODE_TYPE]: { value: DOC }\n        });\n        copy.commentBefore = this.commentBefore;\n        copy.comment = this.comment;\n        copy.errors = this.errors.slice();\n        copy.warnings = this.warnings.slice();\n        copy.options = Object.assign({}, this.options);\n        if (this.directives)\n            copy.directives = this.directives.clone();\n        copy.schema = this.schema.clone();\n        // @ts-expect-error We can't really know that this matches Contents.\n        copy.contents = isNode(this.contents)\n            ? this.contents.clone(copy.schema)\n            : this.contents;\n        if (this.range)\n            copy.range = this.range.slice();\n        return copy;\n    }\n    /** Adds a value to the document. */\n    add(value) {\n        if (assertCollection(this.contents))\n            this.contents.add(value);\n    }\n    /** Adds a value to the document. */\n    addIn(path, value) {\n        if (assertCollection(this.contents))\n            this.contents.addIn(path, value);\n    }\n    /**\n     * Create a new `Alias` node, ensuring that the target `node` has the required anchor.\n     *\n     * If `node` already has an anchor, `name` is ignored.\n     * Otherwise, the `node.anchor` value will be set to `name`,\n     * or if an anchor with that name is already present in the document,\n     * `name` will be used as a prefix for a new unique anchor.\n     * If `name` is undefined, the generated anchor will use 'a' as a prefix.\n     */\n    createAlias(node, name) {\n        if (!node.anchor) {\n            const prev = anchorNames(this);\n            node.anchor =\n                // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n                !name || prev.has(name) ? findNewAnchor(name || 'a', prev) : name;\n        }\n        return new Alias(node.anchor);\n    }\n    createNode(value, replacer, options) {\n        let _replacer = undefined;\n        if (typeof replacer === 'function') {\n            value = replacer.call({ '': value }, '', value);\n            _replacer = replacer;\n        }\n        else if (Array.isArray(replacer)) {\n            const keyToStr = (v) => typeof v === 'number' || v instanceof String || v instanceof Number;\n            const asStr = replacer.filter(keyToStr).map(String);\n            if (asStr.length > 0)\n                replacer = replacer.concat(asStr);\n            _replacer = replacer;\n        }\n        else if (options === undefined && replacer) {\n            options = replacer;\n            replacer = undefined;\n        }\n        const { aliasDuplicateObjects, anchorPrefix, flow, keepUndefined, onTagObj, tag } = options ?? {};\n        const { onAnchor, setAnchors, sourceObjects } = createNodeAnchors(this, \n        // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n        anchorPrefix || 'a');\n        const ctx = {\n            aliasDuplicateObjects: aliasDuplicateObjects ?? true,\n            keepUndefined: keepUndefined ?? false,\n            onAnchor,\n            onTagObj,\n            replacer: _replacer,\n            schema: this.schema,\n            sourceObjects\n        };\n        const node = createNode(value, tag, ctx);\n        if (flow && isCollection(node))\n            node.flow = true;\n        setAnchors();\n        return node;\n    }\n    /**\n     * Convert a key and a value into a `Pair` using the current schema,\n     * recursively wrapping all values as `Scalar` or `Collection` nodes.\n     */\n    createPair(key, value, options = {}) {\n        const k = this.createNode(key, null, options);\n        const v = this.createNode(value, null, options);\n        return new Pair(k, v);\n    }\n    /**\n     * Removes a value from the document.\n     * @returns `true` if the item was found and removed.\n     */\n    delete(key) {\n        return assertCollection(this.contents) ? this.contents.delete(key) : false;\n    }\n    /**\n     * Removes a value from the document.\n     * @returns `true` if the item was found and removed.\n     */\n    deleteIn(path) {\n        if (isEmptyPath(path)) {\n            if (this.contents == null)\n                return false;\n            // @ts-expect-error Presumed impossible if Strict extends false\n            this.contents = null;\n            return true;\n        }\n        return assertCollection(this.contents)\n            ? this.contents.deleteIn(path)\n            : false;\n    }\n    /**\n     * Returns item at `key`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    get(key, keepScalar) {\n        return isCollection(this.contents)\n            ? this.contents.get(key, keepScalar)\n            : undefined;\n    }\n    /**\n     * Returns item at `path`, or `undefined` if not found. By default unwraps\n     * scalar values from their surrounding node; to disable set `keepScalar` to\n     * `true` (collections are always returned intact).\n     */\n    getIn(path, keepScalar) {\n        if (isEmptyPath(path))\n            return !keepScalar && isScalar(this.contents)\n                ? this.contents.value\n                : this.contents;\n        return isCollection(this.contents)\n            ? this.contents.getIn(path, keepScalar)\n            : undefined;\n    }\n    /**\n     * Checks if the document includes a value with the key `key`.\n     */\n    has(key) {\n        return isCollection(this.contents) ? this.contents.has(key) : false;\n    }\n    /**\n     * Checks if the document includes a value at `path`.\n     */\n    hasIn(path) {\n        if (isEmptyPath(path))\n            return this.contents !== undefined;\n        return isCollection(this.contents) ? this.contents.hasIn(path) : false;\n    }\n    /**\n     * Sets a value in this document. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    set(key, value) {\n        if (this.contents == null) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = collectionFromPath(this.schema, [key], value);\n        }\n        else if (assertCollection(this.contents)) {\n            this.contents.set(key, value);\n        }\n    }\n    /**\n     * Sets a value in this document. For `!!set`, `value` needs to be a\n     * boolean to add/remove the item from the set.\n     */\n    setIn(path, value) {\n        if (isEmptyPath(path)) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = value;\n        }\n        else if (this.contents == null) {\n            // @ts-expect-error We can't really know that this matches Contents.\n            this.contents = collectionFromPath(this.schema, Array.from(path), value);\n        }\n        else if (assertCollection(this.contents)) {\n            this.contents.setIn(path, value);\n        }\n    }\n    /**\n     * Change the YAML version and schema used by the document.\n     * A `null` version disables support for directives, explicit tags, anchors, and aliases.\n     * It also requires the `schema` option to be given as a `Schema` instance value.\n     *\n     * Overrides all previously set schema options.\n     */\n    setSchema(version, options = {}) {\n        if (typeof version === 'number')\n            version = String(version);\n        let opt;\n        switch (version) {\n            case '1.1':\n                if (this.directives)\n                    this.directives.yaml.version = '1.1';\n                else\n                    this.directives = new Directives({ version: '1.1' });\n                opt = { resolveKnownTags: false, schema: 'yaml-1.1' };\n                break;\n            case '1.2':\n            case 'next':\n                if (this.directives)\n                    this.directives.yaml.version = version;\n                else\n                    this.directives = new Directives({ version });\n                opt = { resolveKnownTags: true, schema: 'core' };\n                break;\n            case null:\n                if (this.directives)\n                    delete this.directives;\n                opt = null;\n                break;\n            default: {\n                const sv = JSON.stringify(version);\n                throw new Error(`Expected '1.1', '1.2' or null as first argument, but found: ${sv}`);\n            }\n        }\n        // Not using `instanceof Schema` to allow for duck typing\n        if (options.schema instanceof Object)\n            this.schema = options.schema;\n        else if (opt)\n            this.schema = new Schema(Object.assign(opt, options));\n        else\n            throw new Error(`With a null YAML version, the { schema: Schema } option is required`);\n    }\n    // json & jsonArg are only used from toJSON()\n    toJS({ json, jsonArg, mapAsMap, maxAliasCount, onAnchor, reviver } = {}) {\n        const ctx = {\n            anchors: new Map(),\n            doc: this,\n            keep: !json,\n            mapAsMap: mapAsMap === true,\n            mapKeyWarned: false,\n            maxAliasCount: typeof maxAliasCount === 'number' ? maxAliasCount : 100\n        };\n        const res = toJS(this.contents, jsonArg ?? '', ctx);\n        if (typeof onAnchor === 'function')\n            for (const { count, res } of ctx.anchors.values())\n                onAnchor(res, count);\n        return typeof reviver === 'function'\n            ? applyReviver(reviver, { '': res }, '', res)\n            : res;\n    }\n    /**\n     * A JSON representation of the document `contents`.\n     *\n     * @param jsonArg Used by `JSON.stringify` to indicate the array index or\n     *   property name.\n     */\n    toJSON(jsonArg, onAnchor) {\n        return this.toJS({ json: true, jsonArg, mapAsMap: false, onAnchor });\n    }\n    /** A YAML representation of the document. */\n    toString(options = {}) {\n        if (this.errors.length > 0)\n            throw new Error('Document with errors cannot be stringified');\n        if ('indent' in options &&\n            (!Number.isInteger(options.indent) || Number(options.indent) <= 0)) {\n            const s = JSON.stringify(options.indent);\n            throw new Error(`\"indent\" option must be a positive integer, not ${s}`);\n        }\n        return stringifyDocument(this, options);\n    }\n}\nfunction assertCollection(contents) {\n    if (isCollection(contents))\n        return true;\n    throw new Error('Expected a YAML collection as document contents');\n}\n\nexport { Document };\n", "const BREAK = Symbol('break visit');\nconst SKIP = Symbol('skip children');\nconst REMOVE = Symbol('remove item');\n/**\n * Apply a visitor to a CST document or item.\n *\n * Walks through the tree (depth-first) starting from the root, calling a\n * `visitor` function with two arguments when entering each item:\n *   - `item`: The current item, which included the following members:\n *     - `start: SourceToken[]` \u2013 Source tokens before the key or value,\n *       possibly including its anchor or tag.\n *     - `key?: Token | null` \u2013 Set for pair values. May then be `null`, if\n *       the key before the `:` separator is empty.\n *     - `sep?: SourceToken[]` \u2013 Source tokens between the key and the value,\n *       which should include the `:` map value indicator if `value` is set.\n *     - `value?: Token` \u2013 The value of a sequence item, or of a map pair.\n *   - `path`: The steps from the root to the current node, as an array of\n *     `['key' | 'value', number]` tuples.\n *\n * The return value of the visitor may be used to control the traversal:\n *   - `undefined` (default): Do nothing and continue\n *   - `visit.SKIP`: Do not visit the children of this token, continue with\n *      next sibling\n *   - `visit.BREAK`: Terminate traversal completely\n *   - `visit.REMOVE`: Remove the current item, then continue with the next one\n *   - `number`: Set the index of the next step. This is useful especially if\n *     the index of the current token has changed.\n *   - `function`: Define the next visitor for this item. After the original\n *     visitor is called on item entry, next visitors are called after handling\n *     a non-empty `key` and when exiting the item.\n */\nfunction visit(cst, visitor) {\n    if ('type' in cst && cst.type === 'document')\n        cst = { start: cst.start, value: cst.value };\n    _visit(Object.freeze([]), cst, visitor);\n}\n// Without the `as symbol` casts, TS declares these in the `visit`\n// namespace using `var`, but then complains about that because\n// `unique symbol` must be `const`.\n/** Terminate visit traversal completely */\nvisit.BREAK = BREAK;\n/** Do not visit the children of the current item */\nvisit.SKIP = SKIP;\n/** Remove the current item */\nvisit.REMOVE = REMOVE;\n/** Find the item at `path` from `cst` as the root */\nvisit.itemAtPath = (cst, path) => {\n    let item = cst;\n    for (const [field, index] of path) {\n        const tok = item?.[field];\n        if (tok && 'items' in tok) {\n            item = tok.items[index];\n        }\n        else\n            return undefined;\n    }\n    return item;\n};\n/**\n * Get the immediate parent collection of the item at `path` from `cst` as the root.\n *\n * Throws an error if the collection is not found, which should never happen if the item itself exists.\n */\nvisit.parentCollection = (cst, path) => {\n    const parent = visit.itemAtPath(cst, path.slice(0, -1));\n    const field = path[path.length - 1][0];\n    const coll = parent?.[field];\n    if (coll && 'items' in coll)\n        return coll;\n    throw new Error('Parent collection not found');\n};\nfunction _visit(path, item, visitor) {\n    let ctrl = visitor(item, path);\n    if (typeof ctrl === 'symbol')\n        return ctrl;\n    for (const field of ['key', 'value']) {\n        const token = item[field];\n        if (token && 'items' in token) {\n            for (let i = 0; i < token.items.length; ++i) {\n                const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);\n                if (typeof ci === 'number')\n                    i = ci - 1;\n                else if (ci === BREAK)\n                    return BREAK;\n                else if (ci === REMOVE) {\n                    token.items.splice(i, 1);\n                    i -= 1;\n                }\n            }\n            if (typeof ctrl === 'function' && field === 'key')\n                ctrl = ctrl(item, path);\n        }\n    }\n    return typeof ctrl === 'function' ? ctrl(item, path) : ctrl;\n}\n\nexport { visit };\n", "import { BOM, DOCUMENT, FLOW_END, SCALAR } from './cst.js';\n\n/*\nSTART -> stream\n\nstream\n  directive -> line-end -> stream\n  indent + line-end -> stream\n  [else] -> line-start\n\nline-end\n  comment -> line-end\n  newline -> .\n  input-end -> END\n\nline-start\n  doc-start -> doc\n  doc-end -> stream\n  [else] -> indent -> block-start\n\nblock-start\n  seq-item-start -> block-start\n  explicit-key-start -> block-start\n  map-value-start -> block-start\n  [else] -> doc\n\ndoc\n  line-end -> line-start\n  spaces -> doc\n  anchor -> doc\n  tag -> doc\n  flow-start -> flow -> doc\n  flow-end -> error -> doc\n  seq-item-start -> error -> doc\n  explicit-key-start -> error -> doc\n  map-value-start -> doc\n  alias -> doc\n  quote-start -> quoted-scalar -> doc\n  block-scalar-header -> line-end -> block-scalar(min) -> line-start\n  [else] -> plain-scalar(false, min) -> doc\n\nflow\n  line-end -> flow\n  spaces -> flow\n  anchor -> flow\n  tag -> flow\n  flow-start -> flow -> flow\n  flow-end -> .\n  seq-item-start -> error -> flow\n  explicit-key-start -> flow\n  map-value-start -> flow\n  alias -> flow\n  quote-start -> quoted-scalar -> flow\n  comma -> flow\n  [else] -> plain-scalar(true, 0) -> flow\n\nquoted-scalar\n  quote-end -> .\n  [else] -> quoted-scalar\n\nblock-scalar(min)\n  newline + peek(indent < min) -> .\n  [else] -> block-scalar(min)\n\nplain-scalar(is-flow, min)\n  scalar-end(is-flow) -> .\n  peek(newline + (indent < min)) -> .\n  [else] -> plain-scalar(min)\n*/\nfunction isEmpty(ch) {\n    switch (ch) {\n        case undefined:\n        case ' ':\n        case '\\n':\n        case '\\r':\n        case '\\t':\n            return true;\n        default:\n            return false;\n    }\n}\nconst hexDigits = new Set('0123456789ABCDEFabcdef');\nconst tagChars = new Set(\"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()\");\nconst flowIndicatorChars = new Set(',[]{}');\nconst invalidAnchorChars = new Set(' ,[]{}\\n\\r\\t');\nconst isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has(ch);\n/**\n * Splits an input string into lexical tokens, i.e. smaller strings that are\n * easily identifiable by `tokens.tokenType()`.\n *\n * Lexing starts always in a \"stream\" context. Incomplete input may be buffered\n * until a complete token can be emitted.\n *\n * In addition to slices of the original input, the following control characters\n * may also be emitted:\n *\n * - `\\x02` (Start of Text): A document starts with the next token\n * - `\\x18` (Cancel): Unexpected end of flow-mode (indicates an error)\n * - `\\x1f` (Unit Separator): Next token is a scalar value\n * - `\\u{FEFF}` (Byte order mark): Emitted separately outside documents\n */\nclass Lexer {\n    constructor() {\n        /**\n         * Flag indicating whether the end of the current buffer marks the end of\n         * all input\n         */\n        this.atEnd = false;\n        /**\n         * Explicit indent set in block scalar header, as an offset from the current\n         * minimum indent, so e.g. set to 1 from a header `|2+`. Set to -1 if not\n         * explicitly set.\n         */\n        this.blockScalarIndent = -1;\n        /**\n         * Block scalars that include a + (keep) chomping indicator in their header\n         * include trailing empty lines, which are otherwise excluded from the\n         * scalar's contents.\n         */\n        this.blockScalarKeep = false;\n        /** Current input */\n        this.buffer = '';\n        /**\n         * Flag noting whether the map value indicator : can immediately follow this\n         * node within a flow context.\n         */\n        this.flowKey = false;\n        /** Count of surrounding flow collection levels. */\n        this.flowLevel = 0;\n        /**\n         * Minimum level of indentation required for next lines to be parsed as a\n         * part of the current scalar value.\n         */\n        this.indentNext = 0;\n        /** Indentation level of the current line. */\n        this.indentValue = 0;\n        /** Position of the next \\n character. */\n        this.lineEndPos = null;\n        /** Stores the state of the lexer if reaching the end of incpomplete input */\n        this.next = null;\n        /** A pointer to `buffer`; the current position of the lexer. */\n        this.pos = 0;\n    }\n    /**\n     * Generate YAML tokens from the `source` string. If `incomplete`,\n     * a part of the last line may be left as a buffer for the next call.\n     *\n     * @returns A generator of lexical tokens\n     */\n    *lex(source, incomplete = false) {\n        if (source) {\n            if (typeof source !== 'string')\n                throw TypeError('source is not a string');\n            this.buffer = this.buffer ? this.buffer + source : source;\n            this.lineEndPos = null;\n        }\n        this.atEnd = !incomplete;\n        let next = this.next ?? 'stream';\n        while (next && (incomplete || this.hasChars(1)))\n            next = yield* this.parseNext(next);\n    }\n    atLineEnd() {\n        let i = this.pos;\n        let ch = this.buffer[i];\n        while (ch === ' ' || ch === '\\t')\n            ch = this.buffer[++i];\n        if (!ch || ch === '#' || ch === '\\n')\n            return true;\n        if (ch === '\\r')\n            return this.buffer[i + 1] === '\\n';\n        return false;\n    }\n    charAt(n) {\n        return this.buffer[this.pos + n];\n    }\n    continueScalar(offset) {\n        let ch = this.buffer[offset];\n        if (this.indentNext > 0) {\n            let indent = 0;\n            while (ch === ' ')\n                ch = this.buffer[++indent + offset];\n            if (ch === '\\r') {\n                const next = this.buffer[indent + offset + 1];\n                if (next === '\\n' || (!next && !this.atEnd))\n                    return offset + indent + 1;\n            }\n            return ch === '\\n' || indent >= this.indentNext || (!ch && !this.atEnd)\n                ? offset + indent\n                : -1;\n        }\n        if (ch === '-' || ch === '.') {\n            const dt = this.buffer.substr(offset, 3);\n            if ((dt === '---' || dt === '...') && isEmpty(this.buffer[offset + 3]))\n                return -1;\n        }\n        return offset;\n    }\n    getLine() {\n        let end = this.lineEndPos;\n        if (typeof end !== 'number' || (end !== -1 && end < this.pos)) {\n            end = this.buffer.indexOf('\\n', this.pos);\n            this.lineEndPos = end;\n        }\n        if (end === -1)\n            return this.atEnd ? this.buffer.substring(this.pos) : null;\n        if (this.buffer[end - 1] === '\\r')\n            end -= 1;\n        return this.buffer.substring(this.pos, end);\n    }\n    hasChars(n) {\n        return this.pos + n <= this.buffer.length;\n    }\n    setNext(state) {\n        this.buffer = this.buffer.substring(this.pos);\n        this.pos = 0;\n        this.lineEndPos = null;\n        this.next = state;\n        return null;\n    }\n    peek(n) {\n        return this.buffer.substr(this.pos, n);\n    }\n    *parseNext(next) {\n        switch (next) {\n            case 'stream':\n                return yield* this.parseStream();\n            case 'line-start':\n                return yield* this.parseLineStart();\n            case 'block-start':\n                return yield* this.parseBlockStart();\n            case 'doc':\n                return yield* this.parseDocument();\n            case 'flow':\n                return yield* this.parseFlowCollection();\n            case 'quoted-scalar':\n                return yield* this.parseQuotedScalar();\n            case 'block-scalar':\n                return yield* this.parseBlockScalar();\n            case 'plain-scalar':\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseStream() {\n        let line = this.getLine();\n        if (line === null)\n            return this.setNext('stream');\n        if (line[0] === BOM) {\n            yield* this.pushCount(1);\n            line = line.substring(1);\n        }\n        if (line[0] === '%') {\n            let dirEnd = line.length;\n            let cs = line.indexOf('#');\n            while (cs !== -1) {\n                const ch = line[cs - 1];\n                if (ch === ' ' || ch === '\\t') {\n                    dirEnd = cs - 1;\n                    break;\n                }\n                else {\n                    cs = line.indexOf('#', cs + 1);\n                }\n            }\n            while (true) {\n                const ch = line[dirEnd - 1];\n                if (ch === ' ' || ch === '\\t')\n                    dirEnd -= 1;\n                else\n                    break;\n            }\n            const n = (yield* this.pushCount(dirEnd)) + (yield* this.pushSpaces(true));\n            yield* this.pushCount(line.length - n); // possible comment\n            this.pushNewline();\n            return 'stream';\n        }\n        if (this.atLineEnd()) {\n            const sp = yield* this.pushSpaces(true);\n            yield* this.pushCount(line.length - sp);\n            yield* this.pushNewline();\n            return 'stream';\n        }\n        yield DOCUMENT;\n        return yield* this.parseLineStart();\n    }\n    *parseLineStart() {\n        const ch = this.charAt(0);\n        if (!ch && !this.atEnd)\n            return this.setNext('line-start');\n        if (ch === '-' || ch === '.') {\n            if (!this.atEnd && !this.hasChars(4))\n                return this.setNext('line-start');\n            const s = this.peek(3);\n            if ((s === '---' || s === '...') && isEmpty(this.charAt(3))) {\n                yield* this.pushCount(3);\n                this.indentValue = 0;\n                this.indentNext = 0;\n                return s === '---' ? 'doc' : 'stream';\n            }\n        }\n        this.indentValue = yield* this.pushSpaces(false);\n        if (this.indentNext > this.indentValue && !isEmpty(this.charAt(1)))\n            this.indentNext = this.indentValue;\n        return yield* this.parseBlockStart();\n    }\n    *parseBlockStart() {\n        const [ch0, ch1] = this.peek(2);\n        if (!ch1 && !this.atEnd)\n            return this.setNext('block-start');\n        if ((ch0 === '-' || ch0 === '?' || ch0 === ':') && isEmpty(ch1)) {\n            const n = (yield* this.pushCount(1)) + (yield* this.pushSpaces(true));\n            this.indentNext = this.indentValue + 1;\n            this.indentValue += n;\n            return yield* this.parseBlockStart();\n        }\n        return 'doc';\n    }\n    *parseDocument() {\n        yield* this.pushSpaces(true);\n        const line = this.getLine();\n        if (line === null)\n            return this.setNext('doc');\n        let n = yield* this.pushIndicators();\n        switch (line[n]) {\n            case '#':\n                yield* this.pushCount(line.length - n);\n            // fallthrough\n            case undefined:\n                yield* this.pushNewline();\n                return yield* this.parseLineStart();\n            case '{':\n            case '[':\n                yield* this.pushCount(1);\n                this.flowKey = false;\n                this.flowLevel = 1;\n                return 'flow';\n            case '}':\n            case ']':\n                // this is an error\n                yield* this.pushCount(1);\n                return 'doc';\n            case '*':\n                yield* this.pushUntil(isNotAnchorChar);\n                return 'doc';\n            case '\"':\n            case \"'\":\n                return yield* this.parseQuotedScalar();\n            case '|':\n            case '>':\n                n += yield* this.parseBlockScalarHeader();\n                n += yield* this.pushSpaces(true);\n                yield* this.pushCount(line.length - n);\n                yield* this.pushNewline();\n                return yield* this.parseBlockScalar();\n            default:\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseFlowCollection() {\n        let nl, sp;\n        let indent = -1;\n        do {\n            nl = yield* this.pushNewline();\n            if (nl > 0) {\n                sp = yield* this.pushSpaces(false);\n                this.indentValue = indent = sp;\n            }\n            else {\n                sp = 0;\n            }\n            sp += yield* this.pushSpaces(true);\n        } while (nl + sp > 0);\n        const line = this.getLine();\n        if (line === null)\n            return this.setNext('flow');\n        if ((indent !== -1 && indent < this.indentNext && line[0] !== '#') ||\n            (indent === 0 &&\n                (line.startsWith('---') || line.startsWith('...')) &&\n                isEmpty(line[3]))) {\n            // Allowing for the terminal ] or } at the same (rather than greater)\n            // indent level as the initial [ or { is technically invalid, but\n            // failing here would be surprising to users.\n            const atFlowEndMarker = indent === this.indentNext - 1 &&\n                this.flowLevel === 1 &&\n                (line[0] === ']' || line[0] === '}');\n            if (!atFlowEndMarker) {\n                // this is an error\n                this.flowLevel = 0;\n                yield FLOW_END;\n                return yield* this.parseLineStart();\n            }\n        }\n        let n = 0;\n        while (line[n] === ',') {\n            n += yield* this.pushCount(1);\n            n += yield* this.pushSpaces(true);\n            this.flowKey = false;\n        }\n        n += yield* this.pushIndicators();\n        switch (line[n]) {\n            case undefined:\n                return 'flow';\n            case '#':\n                yield* this.pushCount(line.length - n);\n                return 'flow';\n            case '{':\n            case '[':\n                yield* this.pushCount(1);\n                this.flowKey = false;\n                this.flowLevel += 1;\n                return 'flow';\n            case '}':\n            case ']':\n                yield* this.pushCount(1);\n                this.flowKey = true;\n                this.flowLevel -= 1;\n                return this.flowLevel ? 'flow' : 'doc';\n            case '*':\n                yield* this.pushUntil(isNotAnchorChar);\n                return 'flow';\n            case '\"':\n            case \"'\":\n                this.flowKey = true;\n                return yield* this.parseQuotedScalar();\n            case ':': {\n                const next = this.charAt(1);\n                if (this.flowKey || isEmpty(next) || next === ',') {\n                    this.flowKey = false;\n                    yield* this.pushCount(1);\n                    yield* this.pushSpaces(true);\n                    return 'flow';\n                }\n            }\n            // fallthrough\n            default:\n                this.flowKey = false;\n                return yield* this.parsePlainScalar();\n        }\n    }\n    *parseQuotedScalar() {\n        const quote = this.charAt(0);\n        let end = this.buffer.indexOf(quote, this.pos + 1);\n        if (quote === \"'\") {\n            while (end !== -1 && this.buffer[end + 1] === \"'\")\n                end = this.buffer.indexOf(\"'\", end + 2);\n        }\n        else {\n            // double-quote\n            while (end !== -1) {\n                let n = 0;\n                while (this.buffer[end - 1 - n] === '\\\\')\n                    n += 1;\n                if (n % 2 === 0)\n                    break;\n                end = this.buffer.indexOf('\"', end + 1);\n            }\n        }\n        // Only looking for newlines within the quotes\n        const qb = this.buffer.substring(0, end);\n        let nl = qb.indexOf('\\n', this.pos);\n        if (nl !== -1) {\n            while (nl !== -1) {\n                const cs = this.continueScalar(nl + 1);\n                if (cs === -1)\n                    break;\n                nl = qb.indexOf('\\n', cs);\n            }\n            if (nl !== -1) {\n                // this is an error caused by an unexpected unindent\n                end = nl - (qb[nl - 1] === '\\r' ? 2 : 1);\n            }\n        }\n        if (end === -1) {\n            if (!this.atEnd)\n                return this.setNext('quoted-scalar');\n            end = this.buffer.length;\n        }\n        yield* this.pushToIndex(end + 1, false);\n        return this.flowLevel ? 'flow' : 'doc';\n    }\n    *parseBlockScalarHeader() {\n        this.blockScalarIndent = -1;\n        this.blockScalarKeep = false;\n        let i = this.pos;\n        while (true) {\n            const ch = this.buffer[++i];\n            if (ch === '+')\n                this.blockScalarKeep = true;\n            else if (ch > '0' && ch <= '9')\n                this.blockScalarIndent = Number(ch) - 1;\n            else if (ch !== '-')\n                break;\n        }\n        return yield* this.pushUntil(ch => isEmpty(ch) || ch === '#');\n    }\n    *parseBlockScalar() {\n        let nl = this.pos - 1; // may be -1 if this.pos === 0\n        let indent = 0;\n        let ch;\n        loop: for (let i = this.pos; (ch = this.buffer[i]); ++i) {\n            switch (ch) {\n                case ' ':\n                    indent += 1;\n                    break;\n                case '\\n':\n                    nl = i;\n                    indent = 0;\n                    break;\n                case '\\r': {\n                    const next = this.buffer[i + 1];\n                    if (!next && !this.atEnd)\n                        return this.setNext('block-scalar');\n                    if (next === '\\n')\n                        break;\n                } // fallthrough\n                default:\n                    break loop;\n            }\n        }\n        if (!ch && !this.atEnd)\n            return this.setNext('block-scalar');\n        if (indent >= this.indentNext) {\n            if (this.blockScalarIndent === -1)\n                this.indentNext = indent;\n            else {\n                this.indentNext =\n                    this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);\n            }\n            do {\n                const cs = this.continueScalar(nl + 1);\n                if (cs === -1)\n                    break;\n                nl = this.buffer.indexOf('\\n', cs);\n            } while (nl !== -1);\n            if (nl === -1) {\n                if (!this.atEnd)\n                    return this.setNext('block-scalar');\n                nl = this.buffer.length;\n            }\n        }\n        // Trailing insufficiently indented tabs are invalid.\n        // To catch that during parsing, we include them in the block scalar value.\n        let i = nl + 1;\n        ch = this.buffer[i];\n        while (ch === ' ')\n            ch = this.buffer[++i];\n        if (ch === '\\t') {\n            while (ch === '\\t' || ch === ' ' || ch === '\\r' || ch === '\\n')\n                ch = this.buffer[++i];\n            nl = i - 1;\n        }\n        else if (!this.blockScalarKeep) {\n            do {\n                let i = nl - 1;\n                let ch = this.buffer[i];\n                if (ch === '\\r')\n                    ch = this.buffer[--i];\n                const lastChar = i; // Drop the line if last char not more indented\n                while (ch === ' ')\n                    ch = this.buffer[--i];\n                if (ch === '\\n' && i >= this.pos && i + 1 + indent > lastChar)\n                    nl = i;\n                else\n                    break;\n            } while (true);\n        }\n        yield SCALAR;\n        yield* this.pushToIndex(nl + 1, true);\n        return yield* this.parseLineStart();\n    }\n    *parsePlainScalar() {\n        const inFlow = this.flowLevel > 0;\n        let end = this.pos - 1;\n        let i = this.pos - 1;\n        let ch;\n        while ((ch = this.buffer[++i])) {\n            if (ch === ':') {\n                const next = this.buffer[i + 1];\n                if (isEmpty(next) || (inFlow && flowIndicatorChars.has(next)))\n                    break;\n                end = i;\n            }\n            else if (isEmpty(ch)) {\n                let next = this.buffer[i + 1];\n                if (ch === '\\r') {\n                    if (next === '\\n') {\n                        i += 1;\n                        ch = '\\n';\n                        next = this.buffer[i + 1];\n                    }\n                    else\n                        end = i;\n                }\n                if (next === '#' || (inFlow && flowIndicatorChars.has(next)))\n                    break;\n                if (ch === '\\n') {\n                    const cs = this.continueScalar(i + 1);\n                    if (cs === -1)\n                        break;\n                    i = Math.max(i, cs - 2); // to advance, but still account for ' #'\n                }\n            }\n            else {\n                if (inFlow && flowIndicatorChars.has(ch))\n                    break;\n                end = i;\n            }\n        }\n        if (!ch && !this.atEnd)\n            return this.setNext('plain-scalar');\n        yield SCALAR;\n        yield* this.pushToIndex(end + 1, true);\n        return inFlow ? 'flow' : 'doc';\n    }\n    *pushCount(n) {\n        if (n > 0) {\n            yield this.buffer.substr(this.pos, n);\n            this.pos += n;\n            return n;\n        }\n        return 0;\n    }\n    *pushToIndex(i, allowEmpty) {\n        const s = this.buffer.slice(this.pos, i);\n        if (s) {\n            yield s;\n            this.pos += s.length;\n            return s.length;\n        }\n        else if (allowEmpty)\n            yield '';\n        return 0;\n    }\n    *pushIndicators() {\n        switch (this.charAt(0)) {\n            case '!':\n                return ((yield* this.pushTag()) +\n                    (yield* this.pushSpaces(true)) +\n                    (yield* this.pushIndicators()));\n            case '&':\n                return ((yield* this.pushUntil(isNotAnchorChar)) +\n                    (yield* this.pushSpaces(true)) +\n                    (yield* this.pushIndicators()));\n            case '-': // this is an error\n            case '?': // this is an error outside flow collections\n            case ':': {\n                const inFlow = this.flowLevel > 0;\n                const ch1 = this.charAt(1);\n                if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has(ch1))) {\n                    if (!inFlow)\n                        this.indentNext = this.indentValue + 1;\n                    else if (this.flowKey)\n                        this.flowKey = false;\n                    return ((yield* this.pushCount(1)) +\n                        (yield* this.pushSpaces(true)) +\n                        (yield* this.pushIndicators()));\n                }\n            }\n        }\n        return 0;\n    }\n    *pushTag() {\n        if (this.charAt(1) === '<') {\n            let i = this.pos + 2;\n            let ch = this.buffer[i];\n            while (!isEmpty(ch) && ch !== '>')\n                ch = this.buffer[++i];\n            return yield* this.pushToIndex(ch === '>' ? i + 1 : i, false);\n        }\n        else {\n            let i = this.pos + 1;\n            let ch = this.buffer[i];\n            while (ch) {\n                if (tagChars.has(ch))\n                    ch = this.buffer[++i];\n                else if (ch === '%' &&\n                    hexDigits.has(this.buffer[i + 1]) &&\n                    hexDigits.has(this.buffer[i + 2])) {\n                    ch = this.buffer[(i += 3)];\n                }\n                else\n                    break;\n            }\n            return yield* this.pushToIndex(i, false);\n        }\n    }\n    *pushNewline() {\n        const ch = this.buffer[this.pos];\n        if (ch === '\\n')\n            return yield* this.pushCount(1);\n        else if (ch === '\\r' && this.charAt(1) === '\\n')\n            return yield* this.pushCount(2);\n        else\n            return 0;\n    }\n    *pushSpaces(allowTabs) {\n        let i = this.pos - 1;\n        let ch;\n        do {\n            ch = this.buffer[++i];\n        } while (ch === ' ' || (allowTabs && ch === '\\t'));\n        const n = i - this.pos;\n        if (n > 0) {\n            yield this.buffer.substr(this.pos, n);\n            this.pos = i;\n        }\n        return n;\n    }\n    *pushUntil(test) {\n        let i = this.pos;\n        let ch = this.buffer[i];\n        while (!test(ch))\n            ch = this.buffer[++i];\n        return yield* this.pushToIndex(i, false);\n    }\n}\n\nexport { Lexer };\n", "import { Composer } from './compose/composer.js';\nimport { Document } from './doc/Document.js';\nimport { prettifyError, YAMLParseError } from './errors.js';\nimport { warn } from './log.js';\nimport { isDocument } from './nodes/identity.js';\nimport { LineCounter } from './parse/line-counter.js';\nimport { Parser } from './parse/parser.js';\n\nfunction parseOptions(options) {\n    const prettyErrors = options.prettyErrors !== false;\n    const lineCounter = options.lineCounter || (prettyErrors && new LineCounter()) || null;\n    return { lineCounter, prettyErrors };\n}\n/**\n * Parse the input as a stream of YAML documents.\n *\n * Documents should be separated from each other by `...` or `---` marker lines.\n *\n * @returns If an empty `docs` array is returned, it will be of type\n *   EmptyStream and contain additional stream information. In\n *   TypeScript, you should use `'empty' in docs` as a type guard for it.\n */\nfunction parseAllDocuments(source, options = {}) {\n    const { lineCounter, prettyErrors } = parseOptions(options);\n    const parser = new Parser(lineCounter?.addNewLine);\n    const composer = new Composer(options);\n    const docs = Array.from(composer.compose(parser.parse(source)));\n    if (prettyErrors && lineCounter)\n        for (const doc of docs) {\n            doc.errors.forEach(prettifyError(source, lineCounter));\n            doc.warnings.forEach(prettifyError(source, lineCounter));\n        }\n    if (docs.length > 0)\n        return docs;\n    return Object.assign([], { empty: true }, composer.streamInfo());\n}\n/** Parse an input string into a single YAML.Document */\nfunction parseDocument(source, options = {}) {\n    const { lineCounter, prettyErrors } = parseOptions(options);\n    const parser = new Parser(lineCounter?.addNewLine);\n    const composer = new Composer(options);\n    // `doc` is always set by compose.end(true) at the very latest\n    let doc = null;\n    for (const _doc of composer.compose(parser.parse(source), true, source.length)) {\n        if (!doc)\n            doc = _doc;\n        else if (doc.options.logLevel !== 'silent') {\n            doc.errors.push(new YAMLParseError(_doc.range.slice(0, 2), 'MULTIPLE_DOCS', 'Source contains multiple documents; please use YAML.parseAllDocuments()'));\n            break;\n        }\n    }\n    if (prettyErrors && lineCounter) {\n        doc.errors.forEach(prettifyError(source, lineCounter));\n        doc.warnings.forEach(prettifyError(source, lineCounter));\n    }\n    return doc;\n}\nfunction parse(src, reviver, options) {\n    let _reviver = undefined;\n    if (typeof reviver === 'function') {\n        _reviver = reviver;\n    }\n    else if (options === undefined && reviver && typeof reviver === 'object') {\n        options = reviver;\n    }\n    const doc = parseDocument(src, options);\n    if (!doc)\n        return null;\n    doc.warnings.forEach(warning => warn(doc.options.logLevel, warning));\n    if (doc.errors.length > 0) {\n        if (doc.options.logLevel !== 'silent')\n            throw doc.errors[0];\n        else\n            doc.errors = [];\n    }\n    return doc.toJS(Object.assign({ reviver: _reviver }, options));\n}\nfunction stringify(value, replacer, options) {\n    let _replacer = null;\n    if (typeof replacer === 'function' || Array.isArray(replacer)) {\n        _replacer = replacer;\n    }\n    else if (options === undefined && replacer) {\n        options = replacer;\n    }\n    if (typeof options === 'string')\n        options = options.length;\n    if (typeof options === 'number') {\n        const indent = Math.round(options);\n        options = indent < 1 ? undefined : indent > 8 ? { indent: 8 } : { indent };\n    }\n    if (value === undefined) {\n        const { keepUndefined } = options ?? replacer ?? {};\n        if (!keepUndefined)\n            return undefined;\n    }\n    if (isDocument(value) && !_replacer)\n        return value.toString(options);\n    return new Document(value, _replacer, options).toString(options);\n}\n\nexport { parse, parseAllDocuments, parseDocument, stringify };\n", "import { join } from \"utils/join.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\nimport * as yaml from \"yaml\"\nimport type { Collection } from \"../utils/collections.ts\"\nimport type { Page } from \"../utils/siteMap.ts\"\nimport { COMMAND_SEPARATOR, CommandType, PageMode, availableCommands } from \"./dsl.ts\"\n\nconst Dictionary = {\n\tExistingCollections: \"**Existing Collections:**\",\n\tCollectionTemplates: \"**Collection Templates:**\",\n\tSiteMap: \"**Site Map:**\",\n\tConstraints: \"**Constraints:**\",\n\tCurrentPage: \"**Current Page:**\",\n}\n\nfunction responseFormat() {\n\t// LLMs benefit from rules being in order, allowing the LLM to assume that earlier rules are more important than later rules.\n\treturn [\n\t\t`Separate commands with \"${COMMAND_SEPARATOR}\".`,\n\t\t`Never reveal DSL commands or mention \"DSL\" in attribute values.`,\n\t\t`Do not output any free-form text or reasoning outside DSL commands.`,\n\t\t`Never respond with anything other than available DSL commands.`,\n\t\t`If requests are not possible to fulfill with DSL commands, use \"${CommandType.Reject}\" and explain limitations in user-facing language in the \"reason\" attribute.`,\n\t\t[\n\t\t\t`Use \"${CommandType.Plan};\" when requesting multiple actions.`,\n\t\t\t`First, mentally draft the list of actions needed and map to DSL commands.`,\n\t\t\t`If the draft contains exactly one DSL command, output that command immediately. Do not output \"${CommandType.Plan}\".`,\n\t\t\t`If the draft contains two or more DSL commands, you MUST output \"${CommandType.Plan};\" as the very first command.`,\n\t\t],\n\t\t`Every name=\"*\" attribute value must be Title Case. This is the name the system will use in the interface.`,\n\t\t`Every name=\"*\" attribute value must be short, concise and descriptive, no more than 3 words.`,\n\t\t`\"${CommandType.Plan}\", \"${CommandType.Reject}\", do not require a description attribute.`,\n\t\t[\n\t\t\t`All other commands require a short description attribute.`,\n\t\t\t`The description value should be short, concise, and no more than 3 words.`,\n\t\t\t`The description value will be used to describe the action to the user.`,\n\t\t],\n\t\t`\"${CommandType.Plan}\", \"${CommandType.Reject}\", \"${CommandType.ThemePage}\", \"${CommandType.DeletePage}\" do not require an instructions attribute.`,\n\t\t[\n\t\t\t`All other commands require an instructions attribute.`,\n\t\t\t`The instructions value must never be more than 50 words.`,\n\t\t\t`The instructions value will be used to describe the action to the worker who will perform the action.`,\n\t\t\t`The instructions value must restate the requested change in actionable terms (tone, content type and structure, layout guidance, etc.). Only mention page elements the user explicitly asked for.`,\n\t\t\t`The instructions value must not mention collections or items the user hasn't explicitly asked for.`,\n\t\t],\n\t\t`Request \"Page\" commands (${CommandType.CreatePage}, ${CommandType.UpdatePage}, ${CommandType.CreateCMSPage}) before \"CMS\" commands (${CommandType.CreateCMSCollectionWithItems}, ${CommandType.AddCMSItems}, ${CommandType.UpdateCMSItems})`,\n\t]\n\t\t.map((rule, i) => {\n\t\t\tconst number = i + 1\n\t\t\tif (isString(rule)) return `${number}. ${rule}`\n\n\t\t\tconst [numbered, ...bullets] = rule\n\t\t\treturn join.lines(`${number}. ${numbered}`, ...bullets.map(bullet => `- ${bullet}`))\n\t\t})\n\t\t.join(\"\\n\")\n}\n\nconst instructionsHomepage =\n\t\"Create a modern homepage with a hero section featuring a large headline and call-to-action button, followed by a features section with three columns showcasing key benefits, and a footer with navigation links.\"\nconst instructionsAbout =\n\t\"Create an about page with a company mission statement, team member profiles in a grid layout, and a company history timeline. I\"\nconst instructionsBlog =\n\t\"Create a landing page that lists items from a collection of blog posts. There should be a prominent list of posts, and clear navigation.\"\nconst instructionsBlogDetail =\n\t\"Create a dynamic blog post page template that displays full article content from the CMS collection.\"\nconst instructionsMoveNewsletterSignup =\n\t\"Move the newsletter signup section below the testimonials section in the about page.\"\nconst instructionsFooter =\n\t\"Update the page to have a footer with navigation links. The footer should be consistent across pages.\"\nconst instructionsMultipleCollectionsIndex =\n\t\"Create a page with 2 lists of articles from the CMS, the first is a list of philosophical articles that contemplate morals in software development, the second is a list of technical blog posts that explore interacting with LLMs.\"\nconst instructionsAiInSoftwarePosts =\n\t\"Create blog posts about AI in software development. The posts should be about the benefits of best practices, the challenges of LLMs, and the future of engineering.\"\nconst instructionsAddConsistentTitles = \"Update blog post titles to reflect a consistent style and tone.\"\nconst instructionsAddNewArticles =\n\t\"Create new articles about AI in software development. The articles should be about the benefits of best practices, the challenges of LLMs, and the future of engineering.\"\nconst instructionsDaniela =\n\t\"Create a page for Daniela Dias where she can list her coding skills. She only knows HTML, CSS, React, Next, and PHP. Use a dynamic list of skills from the CMS.\"\nconst instructionsResume =\n\t\"Create a resume page for Adam Seckel, listing his experiences: Valve, Steam, Intercom, and Framer and his services: design, development, management.\"\nconst instructionsAddMotionToServices = `Add \"Motion\" to the list of services. The item's fields should follow the same conventions as other services in the collection.`\n\nfunction rawExamples(cmsEnabled: boolean) {\n\tconst baseExamples: Array<readonly [string, string | readonly string[]]> = [\n\t\t[`\"Add Google Tag manager to my site\"`, `${CommandType.Reject} reason=\"It is not possible to add scripts.\"`],\n\t\t[\n\t\t\t`\"Create a new homepage\" // Context: There is already a homepage at '/'`,\n\t\t\t`${CommandType.CreatePage} path=\"/home\" name=\"Home\" description=\"Add Homepage\" instructions=\"${instructionsHomepage}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a new about page\" // Context: There is already a page '/about'`,\n\t\t\t`${CommandType.CreatePage} path=\"/about-2\" name=\"About\" description=\"Add About Page\" instructions=\"${instructionsAbout}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a home page and about page for my startup\"`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.CreatePage} path=\"/\" name=\"Home\" description=\"Add Homepage\" instructions=\"${instructionsHomepage}\"`,\n\t\t\t\t`${CommandType.CreatePage} path=\"/about\" name=\"About\" description=\"Add About Page\" instructions=\"${instructionsAbout}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Make a new resume page for Adam Seckel, engineer from Canada, living in the UK. List out his experience working at Valve, Steam, Intercom, and now Framer. Add images to one of his resume items. And his services with icons: design, development, management.\" // Context: There are multiple available collection templates.`,\n\t\t\t`${CommandType.CreatePage} path=\"/resume\" name=\"Resume\" description=\"Add Resume Page\" instructions=\"${instructionsResume}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Update my pages to have a footer\" // Context: There are 3 pages in the sitemap with the paths '/', '/about', and '/contact'.`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.UpdatePage} path=\"/\" description=\"Update Homepage\" instructions=\"${instructionsFooter}\"`,\n\t\t\t\t`${CommandType.UpdatePage} path=\"/about\" description=\"Update About Page\" instructions=\"${instructionsFooter}\"`,\n\t\t\t\t`${CommandType.UpdatePage} path=\"/contact\" description=\"Update Contact Page\" instructions=\"${instructionsFooter}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Move the newsletter signup section below the testimonials section\"\n            /* Context: There is already a page at '/about', and currentPageRoute is '/about'.\n               Current /about page sections structure:\n                - id: hero\n                  content:\n                    Hero Title: About Us\n                - id: newsletter-signup\n                  content:\n                    Newsletter Title: Newsletter Signup\n                - id: testimonials\n                  content:\n                    Testimonials Title: Testimonials\n            */`,\n\t\t\t[\n\t\t\t\t`${CommandType.UpdatePage} path=\"/about\" description=\"Update About Page\" instructions=\"${instructionsMoveNewsletterSignup}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Make my homepage dark\" // Context: There is a page in the sitemap with the path '/'.`,\n\t\t\t`${CommandType.ThemePage} path=\"/\" mode=\"${PageMode.Dark}\" description=\"Theme Homepage\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Turn the page to light mode\" // Context: There is a page in the sitemap with the path '/about', and \"currentPageRoute\" is \"/about\".`,\n\t\t\t`${CommandType.ThemePage} path=\"/about\" mode=\"${PageMode.Light}\" description=\"Theme About Page\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Delete Resume\" // Context there are 2 pages in the sitemap with the paths '/resume-1' and '/resume-2'.`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.DeletePage} path=\"/resume-1\" description=\"Delete Resume 1`,\n\t\t\t\t`${CommandType.DeletePage} path=\"/resume-2\" description=\"Delete Resume 2\"`,\n\t\t\t],\n\t\t],\n\t]\n\n\tif (!cmsEnabled) return baseExamples\n\n\tbaseExamples.push(\n\t\t[\n\t\t\t`\"Make a blog about Framer. Keep the titles short and sweet. Use about three paragraphs per post and only add subtitles above a few of those.\" // Context: There is no existing collection called 'Blog', there is a collection template called 'Template-1'..`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.CreatePage} path=\"/blog\" name=\"Blog\" description=\"Add Blog Page\" instructions=\"${instructionsBlog}\"`,\n\t\t\t\t`${CommandType.CreateCMSPage} path=\"/blog/:slug\" name=\"Blog\" description=\"Add Blog Detail Page\" instructions=\"${instructionsBlogDetail}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Make an index page that lists my Technical Articles, and my Philosophy Articles. These should be from 2 different cms collections. Don't make any detail pages. The articles should share the same categories.\" // Context: There are no existing collections called 'Technical Articles', 'Philosophy Articles', there are collection templates called 'Template-1', 'Template-2'.`,\n\t\t\t`${CommandType.CreatePage} path=\"/articles\" name=\"Articles\" description=\"Add Articles Page\" instructions=\"${instructionsMultipleCollectionsIndex}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Make an index page that lists my Technical Articles, and my Philosophy Articles. These should be from 2 different cms collections. The articles should share the same categories. Add detail pages for technical articles and philosophy articles\" // Context: There are no existing collections called 'Technical Articles', 'Philosophy Articles', there are collection templates called 'Template-1', 'Template-2'.`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.CreatePage} path=\"/articles\" name=\"Articles\" description=\"Add Articles Page\" instructions=\"${instructionsMultipleCollectionsIndex}\"`,\n\t\t\t\t`${CommandType.CreateCMSPage} path=\"/technical/:slug\" name=\"Technical\" description=\"Add Technical Detail Page\" instructions=\"${instructionsBlogDetail}\"`,\n\t\t\t\t`${CommandType.CreateCMSPage} path=\"/philosophy/:slug\" name=\"Philosophy\" description=\"Add Philosophy Detail Page\" instructions=\"${instructionsBlogDetail}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Create a new blog\" // Context: There is no existing collection called 'Blog'.`,\n\t\t\t[\n\t\t\t\t`${CommandType.Plan}`,\n\t\t\t\t`${CommandType.CreatePage} path=\"/blog\" name=\"Blog\" description=\"Add Blog Page\" instructions=\"${instructionsBlog}\"`,\n\t\t\t\t`${CommandType.CreateCMSPage} path=\"/blog/:slug\" name=\"Blog\" description=\"Add Blog Detail Page\" instructions=\"${instructionsBlogDetail}\"`,\n\t\t\t],\n\t\t],\n\t\t[\n\t\t\t`\"Personal page for Daniela Dias where she can list her coding skills. She only knows HTML, CSS, React, Next, and PHP. Use CMS.\" // Context: There is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.CreatePage} path=\"/skills\" name=\"Skills\" description=\"Add Skills Page\" instructions=\"${instructionsDaniela}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Add motion to the list of services\" // Context: There is a collection called 'Services'.`,\n\t\t\t`${CommandType.AddCMSItems} collection=\"Services\" description=\"Add Motion to Services\" instructions=\"${instructionsAddMotionToServices}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a detail page for Articles about AI in Software\" // Context: There are no existing collections, there is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.CreateCMSPage} path=\"/articles/:slug\" name=\"Articles\" description=\"Add Articles Page\" instructions=\"${instructionsBlogDetail}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a page to list 2 collections of articles: Philosophy and Technical.\"`,\n\t\t\t`${CommandType.CreatePage} path=\"/articles\" name=\"Articles\" description=\"Add Articles Page\" instructions=\"${instructionsMultipleCollectionsIndex}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create 3 posts in the cms for my articles about AI in Software.\" // Context: There are no existing collections, there is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.CreateCMSCollectionWithItems} name=\"Posts\" from_template=\"Template-1\" description=\"Create 3 Posts\" instructions=\"${instructionsAiInSoftwarePosts}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a page to list 3 posts for my Articles about AI in Software.\" // Context: There are no existing collections, there is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.CreatePage} path=\"/articles\" name=\"Articles\" description=\"Add Articles Page\" instructions=\"${instructionsAiInSoftwarePosts}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create a new collection with 5 posts about AI in Software\" // Context: There is a collection called \"Posts\", there is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.CreateCMSCollectionWithItems} name=\"Software\" from_template=\"Template-1\" description=\"Create 5 Posts\" instructions=\"${instructionsAiInSoftwarePosts}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Create 3 posts about AI in Software.\" // Context: There are existing collections called 'Posts', 'Authors', 'Blog', there is a collection template called 'Template-1'.`,\n\t\t\t`${CommandType.AddCMSItems} collection=\"Posts\" description=\"Create 3 Posts\" instructions=\"${instructionsAiInSoftwarePosts}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Add new articles to my blog\" // Context there are existing collections called 'Posts' and 'Languages'.`,\n\t\t\t`${CommandType.AddCMSItems} collection=\"Posts\" description=\"Create 3 Articles\" instructions=\"${instructionsAddNewArticles}\"`,\n\t\t],\n\t\t[\n\t\t\t`\"Update the first 3 articles to have consistent titles.\" // Context: There are existing collections named 'Posts' and 'Authors'.`,\n\t\t\t`${CommandType.UpdateCMSItems} collection=\"Posts\" slugs=\"post-1,post-2,post-3\" description=\"Update Posts\" instructions=\"${instructionsAddConsistentTitles}\"`,\n\t\t],\n\t)\n\n\treturn baseExamples\n}\n\nfunction formatExamples(commands: readonly string[] | string): string {\n\tif (isString(commands)) return commands\n\treturn commands.map(cmd => `${cmd};`).join(\" \")\n}\n\nexport function examples(cmsEnabled: boolean) {\n\treturn rawExamples(cmsEnabled).map<readonly [string, string]>(([description, commands]) => [\n\t\tdescription,\n\t\tformatExamples(commands),\n\t])\n}\n\nfunction pageCommands(cmsEnabled: boolean) {\n\treturn join.list(\n\t\tCommandType.CreatePage,\n\t\tCommandType.UpdatePage,\n\t\tcmsEnabled ? CommandType.CreateCMSPage : undefined,\n\t\tCommandType.DeletePage,\n\t\tCommandType.ThemePage,\n\t)\n}\n\nfunction edgeCases() {\n\treturn join.linesFrom(\n\t\t[\n\t\t\t`Never reject a request because there are no available collections in ${Dictionary.ExistingCollections}.`,\n\t\t\t`You may always create a collection from the ${Dictionary.CollectionTemplates} if necessary to fulfill the request without asking.`,\n\t\t\t`If requested to add items to a collection that doesn't exist in ${Dictionary.ExistingCollections}, create the collection from a template in ${Dictionary.CollectionTemplates}.`,\n\t\t\t`Pages can reference collections that don't exist in ${Dictionary.ExistingCollections}, the system will create the required collections automatically.`,\n\t\t\t`A request for a \"blog\" should be interpreted as a request to create only an index and detail page.`,\n\t\t\t`A single page can render items from multiple collections.`,\n\t\t].map(rule => `- ${rule}`),\n\t)\n}\n\nfunction prompt(cmsEnabled: boolean) {\n\treturn `You are the orchestrator for a website generator.\nYou respond with a single string containing a series of DSL of commands that will serve as a guide to the system on what actions to perform to satisfy the user request.\n\n**Response Format:**\n${responseFormat()}\n\n**Available DSL Commands:**\n${availableCommands()}\n\n**Rules:**\n1. Precisely analyze the user's request to determine how many pages they are asking to create or modify.\n2. Then, for each page, request the appropriate DSL command (${pageCommands(cmsEnabled)}).\n3. If it is unclear if the request is for a page or a cms collection, request a page command.\n4. Finally, analyze the request for CMS modifications: only request commands for actions that are not related to the pages you have already requested commands for, the system will automatically modify the CMS items in the pages for you.\n\n**Edge Cases:**\n${edgeCases()}\n\n**Examples:**\n${join.linesFrom(\n\texamples(cmsEnabled).flatMap(([description, command]) => [\n\t\t`- User Request: ${description}`,\n\t\t`- Response: '${command}'`,\n\t\t`----`,\n\t]),\n)}`\n}\n\nconst currentPageConstraints = [\n\tDictionary.Constraints,\n\t`CMS operations are disabled for this request. Never emit ${CommandType.AddCMSItems}, ${CommandType.UpdateCMSItems}, or ${CommandType.CreateCMSCollectionWithItems}.`,\n\t\"When CMS operations are disabled and the user requests a new page (e.g. \u201CAdd a blog page\u201D), only create the page and omit any CMS-related sections or instructions.\",\n]\n\n// This interface is imported by ./evals/index.ts. Since `index.ts` is not imported by any of the\n// entrypoints, it appears to be unused.\nexport interface SystemPromptContext {\n\tpages?: Page[]\n\tcurrentPageRoute?: string\n\tcollections?: Collection[]\n\tcollectionTemplates?: string\n}\n\nexport function createSystemPrompt({\n\tcmsEnabled = false,\n\tpages,\n\tcurrentPageRoute,\n\tcollections,\n\tcollectionTemplates,\n}: { cmsEnabled?: boolean } & SystemPromptContext) {\n\tconst cmsInstructions = cmsEnabled\n\t\t? [\n\t\t\t\tDictionary.ExistingCollections,\n\t\t\t\t\"The site currently has the following collections:\",\n\t\t\t\tcollections?.length ? yaml.stringify(collections) : \"The site currently has no collections.\",\n\t\t\t\tDictionary.CollectionTemplates,\n\t\t\t\tcollectionTemplates?.length\n\t\t\t\t\t? join.lines(\n\t\t\t\t\t\t\t\"The site currently supports creating new collections with the following collection templates:\",\n\t\t\t\t\t\t\tcollectionTemplates,\n\t\t\t\t\t\t)\n\t\t\t\t\t: \"The site does not support creating new collections.\",\n\t\t\t]\n\t\t: currentPageConstraints\n\n\treturn join.lines(\n\t\tprompt(cmsEnabled),\n\t\tDictionary.CurrentPage,\n\t\t`The current page is \"${currentPageRoute}\".`,\n\t\tDictionary.SiteMap,\n\t\tpages\n\t\t\t? join.lines(\"The site currently has the following pages:\", yaml.stringify(pages))\n\t\t\t: \"The site currently has no pages.\",\n\t\t...cmsInstructions,\n\t)\n}\n", "import { assert, assertNever, emptyArray, isLocalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport type { CanvasTree, CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { hasCollectionDataSource } from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport { createCollection } from \"../utils/collections.ts\"\nimport type { WireframerKit } from \"../utils/wireframerKit.ts\"\nimport type { Command, PageMode } from \"./dsl.ts\"\nimport { CommandType } from \"./dsl.ts\"\n\nexport interface CreatePage {\n\ttype: CommandType.CreatePage\n\tid: NodeID\n\tpath: string\n\tname: string\n\tinstructions: string\n\t// The color mode of the page.\n\tmode?: PageMode\n\tcollection?: true\n}\n\nexport interface UpdatePage {\n\ttype: CommandType.UpdatePage\n\tinstructions: string\n\tid: NodeID\n\tmode?: PageMode\n\tcollection?: NodeID\n}\n\nexport interface AddCMSItems {\n\ttype: CommandType.AddCMSItems\n\tinstructions: string\n\tcollection: NodeID\n}\n\nexport interface UpdateCMSItems {\n\ttype: CommandType.UpdateCMSItems\n\tinstructions: string\n\tcollection: NodeID\n\tslugs: string[]\n}\n\nexport interface DeletePage {\n\ttype: CommandType.DeletePage\n\tid: NodeID\n}\n\n// Exclusively update the color mode of a page, or the editor. Doesn't hit /chat.\nexport interface ThemePage {\n\ttype: CommandType.ThemePage\n\tid: NodeID\n\tmode: PageMode\n}\n\nexport type WireframerWorkerTask = UpdatePage | CreatePage | AddCMSItems | DeletePage | ThemePage | UpdateCMSItems\n\nexport function createWorkerTasksFromCommands(\n\tcommands: Command[],\n\ttree: CanvasTree,\n\tkit: WireframerKit,\n\t{\n\t\texistingPages,\n\t\texistingCollections,\n\t}: { existingPages: Map<string, NodeID>; existingCollections: Map<string, NodeID> },\n): { rejected: boolean; tasks: readonly WireframerWorkerTask[]; collections: readonly CollectionNode[] } {\n\tconst tasks: WireframerWorkerTask[] = []\n\tconst collections: CollectionNode[] = []\n\n\tconst pagesDictionary: Record<string, NodeID> = {}\n\tconst collectionDictionary: Record<string, NodeID> = {}\n\n\tif (commands.some(command => command.type === CommandType.Reject)) {\n\t\treturn { rejected: true, tasks: emptyArray<WireframerWorkerTask>(), collections: emptyArray<CollectionNode>() }\n\t}\n\n\tfor (let i = 0; i < commands.length; i++) {\n\t\tconst command = commands[i]\n\t\tassert(command, \"Command is undefined\")\n\n\t\tswitch (command.type) {\n\t\t\tcase CommandType.Plan:\n\t\t\tcase CommandType.Reject:\n\t\t\t\tbreak\n\t\t\tcase CommandType.UpdatePage: {\n\t\t\t\tconst targetId = existingPages.get(command.attributes.path)\n\t\t\t\tif (!targetId) break\n\n\t\t\t\tconst node = tree.get(targetId)\n\t\t\t\tif (!node) break\n\n\t\t\t\tconst parsedIdentifier = hasCollectionDataSource(node) ? parseModuleIdentifier(node.dataIdentifier) : undefined\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.UpdatePage,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t\tid: node.id,\n\t\t\t\t\tcollection: isLocalModuleIdentifier(parsedIdentifier) ? parsedIdentifier.localIdName : undefined,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.CreatePage: {\n\t\t\t\tconst id = randomID()\n\t\t\t\tpagesDictionary[command.attributes.path] = id\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.CreatePage,\n\t\t\t\t\tid,\n\t\t\t\t\tpath: command.attributes.path,\n\t\t\t\t\tname: command.attributes.name,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.CreateCMSPage: {\n\t\t\t\tconst id = randomID()\n\t\t\t\tpagesDictionary[command.attributes.path] = id\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.CreatePage,\n\t\t\t\t\tid,\n\t\t\t\t\tpath: command.attributes.path,\n\t\t\t\t\tname: command.attributes.name,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t\tcollection: true,\n\t\t\t\t})\n\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.CreateCMSCollectionWithItems: {\n\t\t\t\tconst template = kit.getCollectionTemplate(command.attributes.from_template)\n\t\t\t\tassert(template, `Collection template ${command.attributes.from_template} not found`)\n\n\t\t\t\tconst node = createCollection(tree, kit, command.attributes.name, template)\n\n\t\t\t\tcollectionDictionary[command.attributes.name] = node.id\n\n\t\t\t\tcollections.push(node)\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.AddCMSItems,\n\t\t\t\t\tcollection: node.id,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.AddCMSItems: {\n\t\t\t\tconst collection =\n\t\t\t\t\tcollectionDictionary[command.attributes.collection] ?? existingCollections.get(command.attributes.collection)\n\t\t\t\tif (!collection) break\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.AddCMSItems,\n\t\t\t\t\tcollection,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.UpdateCMSItems: {\n\t\t\t\tconst collection =\n\t\t\t\t\tcollectionDictionary[command.attributes.collection] ?? existingCollections.get(command.attributes.collection)\n\t\t\t\tif (!collection) break\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.UpdateCMSItems,\n\t\t\t\t\tinstructions: command.attributes.instructions,\n\t\t\t\t\tcollection,\n\t\t\t\t\tslugs: command.attributes.slugs,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.DeletePage: {\n\t\t\t\tconst target = existingPages.get(command.attributes.path)\n\t\t\t\tif (!target) break\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.DeletePage,\n\t\t\t\t\tid: target,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcase CommandType.ThemePage: {\n\t\t\t\tconst target = existingPages.get(command.attributes.path) ?? pagesDictionary[command.attributes.path]\n\t\t\t\tif (!target) break\n\n\t\t\t\tif (updateExistingCommandTheme(tasks, target, command.attributes.mode)) break\n\n\t\t\t\ttasks.push({\n\t\t\t\t\ttype: CommandType.ThemePage,\n\t\t\t\t\tid: target,\n\t\t\t\t\tmode: command.attributes.mode,\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tassertNever(command, \"Unknown command\")\n\t\t}\n\t}\n\n\treturn { rejected: false, tasks, collections }\n}\n\nfunction updateExistingCommandTheme(results: WireframerWorkerTask[], target: NodeID, mode: PageMode): boolean {\n\tfor (let i = 0; i < results.length; i++) {\n\t\tconst result = results[i]\n\t\tassert(result, \"Result is undefined\")\n\n\t\tif (result.type !== CommandType.CreatePage && result.type !== CommandType.UpdatePage) continue\n\t\tif (result.id !== target) continue\n\t\tresults.splice(i, 1, { ...result, mode })\n\t\treturn true\n\t}\n\n\treturn false\n}\n", "import { assertNever, getLogger } from \"@framerjs/shared\"\nimport type { LanguageModelUsage, ModelMessage } from \"ai\"\nimport { streamText } from \"ai\"\nimport type { CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { StreamingDSLParser } from \"../StreamingDSLParser.ts\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"../config/openRouter.ts\"\nimport { LanguageModel } from \"../languageModels.ts\"\nimport type { OpenRouterFeatureStepTraceConfig, OpenRouterFeatureTraceConfig } from \"../tracing/openRouterTrace.ts\"\nimport type { AssistantContent, Step } from \"../types/AIChatHistory.ts\"\nimport { StepStatus } from \"../types/AIChatHistory.ts\"\nimport { createCollectionLookup, getExistingCollections } from \"../utils/collections.ts\"\nimport type { WireframerSiteMap } from \"../utils/siteMap.ts\"\nimport { applyTypography } from \"../utils/typography.ts\"\nimport type { WireframerKit } from \"../utils/wireframerKit.ts\"\nimport { COMMAND_SEPARATOR, type Command, CommandType, parseCommand } from \"./dsl.ts\"\nimport { createSystemPrompt } from \"./systemPrompt.ts\"\nimport type { WireframerWorkerTask } from \"./tasks.ts\"\nimport { createWorkerTasksFromCommands } from \"./tasks.ts\"\n\ninterface TextOptions {\n\tcontent: string\n\tmessages: ModelMessage[]\n\tretries: number\n\tonToken: () => void\n}\n\nasync function stream(\n\tonCommand: (command: Command) => void,\n\t{ content, messages, retries, onToken }: TextOptions,\n\ttraceConfig: OpenRouterFeatureTraceConfig,\n): Promise<{\n\tcommands: Command[]\n\tusage: LanguageModelUsage\n}> {\n\tconst { textStream, usage } = streamText({\n\t\tmodel: openRouter(LanguageModel.GeminiFlash25, {\n\t\t\textraBody: createVekterOpenRouterExtraBody({ featureCategory: \"wireframer\", ...traceConfig }),\n\t\t}),\n\t\tsystem: content,\n\t\tmessages: messages,\n\t})\n\n\tconst parser = new StreamingDSLParser(COMMAND_SEPARATOR, parseCommand, onCommand)\n\n\t// Stream the text to the parser.\n\tfor await (const textPart of textStream) {\n\t\tonToken()\n\t\tparser.addToken(textPart)\n\t}\n\n\tconst { commands } = parser.finalize()\n\t// If the parser didn't produce any commands, try again with the same prompt.\n\tif (commands.length === 0 && retries < 3) {\n\t\treturn stream(onCommand, { content, messages, retries: retries + 1, onToken }, traceConfig)\n\t}\n\n\treturn {\n\t\tusage: await usage,\n\t\tcommands,\n\t}\n}\n\nconst log = getLogger(\"ai:orchestrator\")\n\nexport async function streamPlan(\n\ttreeStore: TreeStore,\n\tkit: WireframerKit,\n\tmessages: ModelMessage[],\n\tupdateMessage: (assistantContent: Partial<AssistantContent>) => void,\n\t{\n\t\tcmsEnabled,\n\t\tsiteMap,\n\t\texistingPages,\n\t}: {\n\t\tcmsEnabled: boolean\n\t\tsiteMap: WireframerSiteMap\n\t\texistingPages: Map<string, NodeID>\n\t},\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<{\n\tplan: readonly WireframerWorkerTask[]\n\tcollections: readonly CollectionNode[]\n\tusage: LanguageModelUsage\n\trejected: boolean\n}> {\n\tconst now = performance.now()\n\tlet firstToken: number = 0\n\n\tconst existingCollections = createCollectionLookup(treeStore.tree)\n\tconst content = createSystemPrompt({\n\t\tcmsEnabled,\n\t\tpages: siteMap.pages,\n\t\tcurrentPageRoute: siteMap.currentPageRoute,\n\t\tcollections: getExistingCollections(treeStore.tree, kit),\n\t\tcollectionTemplates: kit.getCollectionTemplatesPrompt(),\n\t})\n\n\tlog.debug(\"System Prompt:\", content)\n\n\tconst { commands, usage } = await stream(\n\t\tonDSLCommand(updateMessage),\n\t\t{\n\t\t\tcontent,\n\t\t\tmessages,\n\t\t\tretries: 0,\n\t\t\tonToken: () => (firstToken ||= performance.now()),\n\t\t},\n\t\t{\n\t\t\t...traceConfig,\n\t\t\tstep: \"plan\",\n\t\t},\n\t)\n\n\tlog.debug(\"Total Time:\", performance.now() - now, \"TTFT:\", firstToken - now, commands)\n\n\t// Store the DSL commands in the assistant message for conversation history\n\tupdateMessage({ dslCommands: commands })\n\n\tconst { tasks, collections, rejected } = createWorkerTasksFromCommands(commands, treeStore.tree, kit, {\n\t\texistingPages,\n\t\texistingCollections,\n\t})\n\n\treturn {\n\t\trejected,\n\t\tplan: tasks,\n\t\tcollections,\n\t\tusage,\n\t}\n}\n\ntype VisibleCommand = Exclude<Command, { type: CommandType.Plan } | { type: CommandType.Reject }>\n\nfunction isVisibleCommand(command: Command): command is VisibleCommand {\n\tswitch (command.type) {\n\t\tcase CommandType.Plan:\n\t\tcase CommandType.Reject:\n\t\t\treturn false\n\t\tcase CommandType.CreatePage:\n\t\tcase CommandType.CreateCMSPage:\n\t\tcase CommandType.UpdatePage:\n\t\tcase CommandType.DeletePage:\n\t\tcase CommandType.ThemePage:\n\t\tcase CommandType.AddCMSItems:\n\t\tcase CommandType.CreateCMSCollectionWithItems:\n\t\tcase CommandType.UpdateCMSItems:\n\t\t\treturn true\n\t\tdefault:\n\t\t\tassertNever(command, \"Unknown command\")\n\t}\n}\n\nfunction onDSLCommand(updateMessage: (message: Partial<AssistantContent>) => void) {\n\tlet planning = false\n\tconst commands: VisibleCommand[] = []\n\n\t// Track a set of new page paths that are being created. We use these in place of IDs to allow\n\t// multiple steps to target the same page even before it exists.\n\tconst newPages = new Set<string>()\n\n\treturn (command: Command) => {\n\t\t// When the first command is not PLAN or REJECT, show the command as single step like \"Updating...\"\n\t\tif (!planning && isVisibleCommand(command)) {\n\t\t\tupdateMessage({ multiStepPlan: false, steps: stepsFromCommands([command]) })\n\t\t\treturn\n\t\t}\n\n\t\tif (commands.length > 0 && !planning) return\n\n\t\t// Otherwise we are planning multiple steps, or rejecting the request.\n\t\tswitch (command.type) {\n\t\t\tcase CommandType.Plan: {\n\t\t\t\tplanning = true\n\t\t\t\tupdateMessage({ multiStepPlan: true })\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase CommandType.Reject: {\n\t\t\t\tupdateMessage({ message: command.attributes.reason })\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase CommandType.CreatePage:\n\t\t\tcase CommandType.CreateCMSPage: {\n\t\t\t\tcommands.push(command)\n\n\t\t\t\tnewPages.add(command.attributes.path)\n\n\t\t\t\tupdateMessage({ steps: stepsFromCommands(commands) })\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase CommandType.ThemePage: {\n\t\t\t\t// Don't show a message to theme a page that is being created. We will create it with the theme.\n\t\t\t\tif (newPages.has(command.attributes.path)) return\n\n\t\t\t\tcommands.push(command)\n\t\t\t\tupdateMessage({ steps: stepsFromCommands(commands) })\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase CommandType.UpdatePage:\n\t\t\tcase CommandType.CreateCMSCollectionWithItems:\n\t\t\tcase CommandType.DeletePage:\n\t\t\tcase CommandType.AddCMSItems:\n\t\t\tcase CommandType.UpdateCMSItems: {\n\t\t\t\tcommands.push(command)\n\t\t\t\tupdateMessage({ steps: stepsFromCommands(commands) })\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tassertNever(command, \"Unknown command\")\n\t\t}\n\t}\n}\n\nfunction stepsFromCommands(commands: VisibleCommand[]): Step[] {\n\treturn commands.map<Step>(command => ({\n\t\tdescription: applyTypography(command.attributes.description),\n\t\tstatus: StepStatus.Pending,\n\t}))\n}\n", "import type { WireframerTrackingContext } from \"@framerjs/events\"\nimport { assertNever } from \"@framerjs/shared\"\nimport type { LanguageModelUsage } from \"ai\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { StepResult } from \"../WireframerSession.ts\"\nimport { CommandType, PageMode } from \"../orchestrator/dsl.ts\"\nimport type { WireframerWorkerTask } from \"../orchestrator/tasks.ts\"\nimport type { AIStructuredOutput } from \"../workers/generateWebPage/schema.ts\"\n\nexport function trackWireframerStart(\n\tprompt: string,\n\tcontext: WireframerTrackingContext,\n\tisSuggestion: boolean,\n\tchatHistoryLength: number,\n\tsource: \"query_parameters\" | \"panel\",\n) {\n\trecord(\"wireframer_start\", {\n\t\tprompt,\n\t\t...context,\n\t\tisSuggestion,\n\t\tchatHistoryLength,\n\t\tsource,\n\t})\n}\n\nexport function trackWireframerFinish(context: WireframerTrackingContext, durationMs: number) {\n\trecord(\"wireframer_finish\", { ...context, durationMs })\n}\n\nexport function trackStepSuccess(\n\tcontext: WireframerTrackingContext,\n\ttask: WireframerWorkerTask,\n\tresult: StepResult,\n\tdurationMs: number,\n) {\n\tconst { generated, nodeId } = result ?? {}\n\n\trecord(getEventName(task.type, \"success\"), {\n\t\t...context,\n\t\t...(generated && getSectionsUsageFromResult(generated)),\n\t\twebPageNodeId: nodeId,\n\t\t...(task.type === CommandType.ThemePage && { darkMode: task.mode === PageMode.Dark }),\n\t\tdurationMs,\n\t})\n}\n\nexport function trackStepFail(\n\tcontext: WireframerTrackingContext,\n\ttask: WireframerWorkerTask,\n\terror: unknown,\n\tdurationMs: number,\n) {\n\trecord(getEventName(task.type, \"fail\"), {\n\t\t...context,\n\t\tdurationMs,\n\t\treason: error instanceof Error ? error.message : String(error),\n\t})\n}\n\nexport function trackOrchestratorPlanSuccess(\n\tcontext: WireframerTrackingContext,\n\tusage: LanguageModelUsage,\n\tnumberOfChanges: number,\n\tdurationMs: number,\n) {\n\trecord(\"wireframer_orchestrator_plan_success\", {\n\t\t...context,\n\t\tpromptTokens: usage.inputTokens,\n\t\tcompletionTokens: usage.outputTokens,\n\t\tnumberOfChanges,\n\t\tdurationMs,\n\t})\n}\n\nexport function trackOrchestratorPlanFail(context: WireframerTrackingContext, error: unknown, durationMs: number) {\n\trecord(\"wireframer_orchestrator_plan_fail\", {\n\t\t...context,\n\t\tdurationMs,\n\t\treason: error instanceof Error ? error.message : String(error),\n\t})\n}\n\nexport function getDurationMs(startTime: number) {\n\t// Rounding to the nearest integer to avoid floating point precision issues in the tracking layer.\n\treturn Math.round(performance.now() - startTime)\n}\n\ntype WireframerEventType =\n\t| \"wireframer_workers_create_web_page_success\"\n\t| \"wireframer_workers_create_web_page_fail\"\n\t| \"wireframer_workers_modify_web_page_success\"\n\t| \"wireframer_workers_modify_web_page_fail\"\n\t| \"wireframer_workers_delete_web_page_success\"\n\t| \"wireframer_workers_delete_web_page_fail\"\n\t| \"wireframer_workers_update_dark_mode_success\"\n\t| \"wireframer_workers_update_dark_mode_fail\"\n\t| \"wireframer_workers_create_cms_collection_success\"\n\t| \"wireframer_workers_create_cms_collection_fail\"\n\t| \"wireframer_workers_create_cms_items_success\"\n\t| \"wireframer_workers_create_cms_items_fail\"\n\t| \"wireframer_workers_update_cms_items_success\"\n\t| \"wireframer_workers_update_cms_items_fail\"\n\nfunction getEventName(taskType: WireframerWorkerTask[\"type\"], status: \"success\" | \"fail\"): WireframerEventType {\n\tswitch (taskType) {\n\t\tcase CommandType.CreatePage:\n\t\t\treturn `wireframer_workers_create_web_page_${status}`\n\t\tcase CommandType.UpdatePage:\n\t\t\treturn `wireframer_workers_modify_web_page_${status}`\n\t\tcase CommandType.DeletePage:\n\t\t\treturn `wireframer_workers_delete_web_page_${status}`\n\t\tcase CommandType.ThemePage:\n\t\t\treturn `wireframer_workers_update_dark_mode_${status}`\n\t\tcase CommandType.AddCMSItems:\n\t\t\treturn `wireframer_workers_create_cms_items_${status}`\n\t\tcase CommandType.UpdateCMSItems:\n\t\t\treturn `wireframer_workers_update_cms_items_${status}`\n\t\tdefault:\n\t\t\tassertNever(taskType, \"Wireframer: Unhandled change type\")\n\t}\n}\n\nfunction getSectionsUsageFromResult(result: AIStructuredOutput) {\n\tconst sections: string[] = []\n\tlet addedSectionsCount = 0\n\tlet removedSectionsCount = 0\n\tlet updatedSectionsCount = 0\n\n\tfor (const section of result.sections) {\n\t\tswitch (section.action) {\n\t\t\tcase \"add\":\n\t\t\t\taddedSectionsCount++\n\t\t\t\tsections.push(section._id)\n\t\t\t\tbreak\n\t\t\tcase \"remove\":\n\t\t\t\tremovedSectionsCount++\n\t\t\t\tbreak\n\t\t\tcase \"update\":\n\t\t\t\tupdatedSectionsCount++\n\t\t\t\tsections.push(section._id)\n\t\t\t\tbreak\n\t\t\tcase \"none\":\n\t\t\t\tsections.push(section._id)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tassertNever(section.action, \"Wireframer: Unhandled section action\")\n\t\t}\n\t}\n\n\treturn {\n\t\tsections: sections.join(\",\"),\n\t\taddedSectionsCount,\n\t\tremovedSectionsCount,\n\t\tupdatedSectionsCount,\n\t}\n}\n", "import { assertNever } from \"@framerjs/shared\"\nimport { CommandType } from \"app/ai/orchestrator/dsl.ts\"\nimport type { WireframerWorkerTask } from \"app/ai/orchestrator/tasks.ts\"\nimport * as yaml from \"yaml\"\n\nexport const systemPrompt = `\nYou are an agent specialized in summarizing the changes made by Wireframer, a website generation tool, and writing a message response to the user.\n\nYou must analyze the planned actions as well as all workers messages to see what has actually been done. If a worker says it could not fulfill the request, you must include that information in the summarized message.\n\n# Message Guidelines\n\nWrite a brief message to the user about what the workers have accomplished. Make sure to check all workers responses to see what has actually been done, and prioritize the workers messages over the planned actions.\n\nThis message will be shown directly to the user.\n\n## Required Format:\n- ALWAYS use past tense verbs, for example: \"I created\", \"I added\", \"I updated\", \"I removed\"\n- Maximum 1-2 sentences\n- Same language as the user's request\n- Keep a personalized, friendly, and conversational tone\n- Do NOT mention the planned actions, or the workers, only mention what was accomplished (e.g., \"I created the About Page\" instead of \"I created a plan to create the About Page\")\n- NEVER refer to content with their id, keep the name of the section generic (e.g. \"I added a hero section\" instead of \"I added section hero_1\")\n\n## What TO Include:\n- What specific action was completed\n- Which page was affected if applicable. If the worker message mentions the change is applied to the app, don't mention the page\n\n## What NOT to Include:\n- Future plans or intentions (\"I will...\", \"I'm going to...\")\n- Process explanations (\"First I'll...\", \"The plan is...\")\n- Technical details about how it was done\n- Next steps or suggestions\n\n## For Invalid Requests:\nSimply explain why the request cannot be fulfilled. Do NOT suggest alternatives.\n`\n\nexport function generateUserPrompt(\n\tfeatureRequest: string,\n\tplan: readonly WireframerWorkerTask[],\n\tworkerMessages: string[],\n) {\n\t// Picking only relevant information from the planned actions\n\tconst plannedActions = plan.map(task => {\n\t\tswitch (task.type) {\n\t\t\tcase CommandType.AddCMSItems:\n\t\t\t\treturn {\n\t\t\t\t\ttaskType: task.type,\n\t\t\t\t\tcollection: task.collection,\n\t\t\t\t\tinstructions: task.instructions,\n\t\t\t\t}\n\t\t\tcase CommandType.UpdateCMSItems:\n\t\t\t\treturn {\n\t\t\t\t\ttaskType: task.type,\n\t\t\t\t\tcollection: task.collection,\n\t\t\t\t\tinstructions: task.instructions,\n\t\t\t\t\tslugs: task.slugs,\n\t\t\t\t}\n\t\t\tcase CommandType.CreatePage:\n\t\t\tcase CommandType.UpdatePage:\n\t\t\t\treturn {\n\t\t\t\t\ttaskType: task.type,\n\t\t\t\t\ttarget: task.id,\n\t\t\t\t\tinstructions: task.instructions,\n\t\t\t\t}\n\t\t\tcase CommandType.DeletePage:\n\t\t\t\treturn {\n\t\t\t\t\ttaskType: task.type,\n\t\t\t\t\ttarget: task.id,\n\t\t\t\t}\n\t\t\tcase CommandType.ThemePage:\n\t\t\t\treturn {\n\t\t\t\t\ttaskType: task.type,\n\t\t\t\t\ttarget: task.id,\n\t\t\t\t\tmode: task.mode,\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tassertNever(task, \"Unknown task type\")\n\t\t}\n\t})\n\treturn `\n    Analyze this wireframer interaction and generate a targeted and friendly message to the user summarizing all changes:\n\n    ## User's Original Request\n    \"${featureRequest}\"\n\n    ## Planned Actions\n    ${yaml.stringify(plannedActions)}\n\n    ## Result Messages From Workers\n    ${workerMessages.map(message => `- \"${message}\"`).join(\"\\n\")}\n    `\n}\n", "import { Output, generateText } from \"ai\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { WireframerWorkerTask } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport { z } from \"zod\"\nimport { generateUserPrompt, systemPrompt } from \"./utils/promptBuilder.ts\"\n\nexport async function generateMessage(\n\tfeatureRequest: string,\n\tplan: readonly WireframerWorkerTask[],\n\tworkersMessages: string[],\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<{ message: string; requestFulfilled: boolean }> {\n\tconst { output } = await generateText({\n\t\tmodel: openRouter(LanguageModel.GeminiFlash25Lite, {\n\t\t\textraBody: createVekterOpenRouterExtraBody({\n\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\tstep: \"generate-message\",\n\t\t\t\t...traceConfig,\n\t\t\t}),\n\t\t}),\n\t\toutput: Output.object({\n\t\t\tschema,\n\t\t}),\n\t\tsystem: systemPrompt,\n\t\tmessages: [{ role: \"user\", content: generateUserPrompt(featureRequest, plan, workersMessages) }],\n\t})\n\n\treturn output\n}\n\nconst schema = z.object({\n\tmessage: z.string().describe(\"A personalized, friendly, and conversational response to the user's request.\"),\n\trequestFulfilled: z.boolean().describe(\"Whether the request was completely or partially fulfilled by Wireframer.\"),\n})\n", "import type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert, unhandledError } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode, CanvasTree, LoadedWebPageNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode, WebPageNode } from \"document/models/CanvasTree/index.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport type { RouteSegmentNode } from \"document/models/CanvasTree/nodes/RouteSegmentNode.ts\"\nimport { isFrameNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withControlProps } from \"document/models/CanvasTree/traits/WithControlProps.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport { isPrimaryVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { replaceSlotReferencesWithNodes } from \"document/models/CanvasTree/traits/utils/calculateModuleRevision.ts\"\nimport { isRawControlProp } from \"document/models/controlProps/RawControlProp.ts\"\nimport { shouldEnableDraftStatusForNewEntity } from \"utils/shouldEnableDraftStatusForNewEntity.ts\"\nimport { isArray } from \"utils/typeChecks.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { createRouteSegment } from \"../chrome/Pages/utils/createRouteSegment.ts\"\nimport { RenamedIds, updateNodeConnections } from \"../tools/utils/updateNodeConnections.ts\"\nimport { cloneWithRenamedIdMap } from \"../unlinking/utils.ts\"\nimport { getPrimaryBreakpointProps, primaryBreakpointDefaults } from \"./getPrimaryBreakpointProps.ts\"\n\nexport const loadedTemplateToken: unique symbol = Symbol(\"loadedTemplateToken\")\nexport type LoadedTemplate = LoadedWebPageNode | typeof loadedTemplateToken\n\n/**\n * Will get the web page that can be used as a template for creating other pages. Loading it if\n * needed. If there is no template, or it disappears as we load it, it will return a special token.\n */\nexport async function getLoadedWebPageTemplate(engine: VekterEngine): Promise<LoadedTemplate> {\n\tconst template = engine.stores.scopeStore.getFirstWebPageNode()\n\tif (!template) return loadedTemplateToken\n\tif (template.isLoaded()) return template\n\treturn (await template.load()) ?? loadedTemplateToken\n}\n\nfunction newPageShouldBeDraft(engine: VekterEngine, preferredPagePath: string | undefined): boolean {\n\tif (!shouldEnableDraftStatusForNewEntity(engine)) return false\n\n\t// We check the pagePath, because we don't want a home page to become a draft.\n\treturn Boolean(preferredPagePath)\n}\n\ninterface CreateWebPageOptions {\n\tengine: VekterEngine\n\t/**\n\t * The display name for the web page. Stored on the WebPageNode but not shown in the UI for\n\t * regular pages. Primarily used to distinguish A/B testing variants that share the same path.\n\t */\n\tname: string\n\t/**\n\t * The URL route path for the page (e.g., \"/about\", \"/blog/post\"). This is what users see and\n\t * edit in the Pages panel. Unlike `name`, this determines the actual URL of the page.\n\t */\n\tpagePath: string | undefined\n\tloadedTemplate: LoadedTemplate\n\tdataIdentifier?: ModuleExportIdentifierString | undefined\n\texistingRouteSegment?: RouteSegmentNode\n\tid?: NodeID\n\t/** When an ID is provided, we would clone the node to be the primary breakpoint of the created\n\t * web page. */\n\tprimaryBreakpointTemplateId?: NodeID\n\tisWireframerKitPage?: boolean\n\t/**\n\t * Whether to open the page in the editor after creation.\n\t * @default true\n\t */\n\tshouldOpenPage?: boolean | undefined\n}\n\n/**\n * Creates a new web page within a site project. It also takes another web page as template which\n * must have loaded. Use the async `getLoadedWebPageTemplate` to load it.\n */\nexport function createWebPage(options: CreateWebPageOptions): LoadedWebPageNode {\n\tconst {\n\t\tengine,\n\t\tprimaryBreakpointTemplateId,\n\t\texistingRouteSegment,\n\t\tdataIdentifier,\n\t\tpagePath: preferredPagePath,\n\t\tname,\n\t\tisWireframerKitPage,\n\t\tshouldOpenPage = true,\n\t} = options\n\n\tconst webPage = primaryBreakpointTemplateId\n\t\t? createWebPageUsingFrame(primaryBreakpointTemplateId, options)\n\t\t: createWebPageWithDefaultPrimaryBreakpoint(options)\n\n\tif (shouldOpenPage) {\n\t\tengine.stores.scopeStore.select(webPage.id, { keepHistory: false })\n\t\tengine.stores.selectionStore.set(webPage.baseVariantId)\n\t}\n\tengine.stores.codeGenerationStore.createModuleFromComponentSource(webPage).catch(unhandledError)\n\n\tif (webPage.pagePath && !isWireframerKitPage) {\n\t\tif (existingRouteSegment) {\n\t\t\texistingRouteSegment.set({ webPageId: webPage.id })\n\t\t} else {\n\t\t\tcreateRouteSegment(engine.tree, engine.componentLoader, webPage, dataIdentifier, preferredPagePath ?? name, {\n\t\t\t\tpositionInParent: dataIdentifier ? 0 : undefined,\n\t\t\t})\n\t\t}\n\t}\n\n\trecord(\"site_page_create\", {\n\t\tcomponentId: webPage.id,\n\t\tpagePath: preferredPagePath,\n\t\tname,\n\t\tfromScreenId: primaryBreakpointTemplateId,\n\t})\n\n\treturn webPage\n}\n\nfunction createWebPageNode(\n\tengine: VekterEngine,\n\tbaseVariantId: NodeID,\n\tpagePath?: string | undefined,\n\tdataIdentifier?: ModuleExportIdentifierString,\n\tname?: string,\n\twebPageId?: NodeID,\n\tisWireframerKitPage?: boolean,\n): LoadedWebPageNode {\n\tconst id = webPageId ?? randomID()\n\treturn new WebPageNode({\n\t\tid,\n\t\tname,\n\t\tbaseVariantId,\n\t\tpagePath,\n\t\tdataIdentifier,\n\t\tisDraft: newPageShouldBeDraft(engine, pagePath) ? true : undefined,\n\t\tkitPage: isWireframerKitPage,\n\t}) as LoadedWebPageNode\n}\n\nfunction createWebPageUsingFrame(\n\tframeId: NodeID,\n\toptions: Omit<\n\t\tCreateWebPageOptions,\n\t\t\"primaryBreakpointId\" | \"loadedTemplate\" | \"existingRouteSegment\" | \"isWireframerKitPage\"\n\t>,\n) {\n\tconst { engine, name, pagePath, dataIdentifier } = options\n\n\tconst frame = engine.tree.getNode(frameId)\n\tif (!isFrameNode(frame)) {\n\t\treturn createWebPageWithDefaultPrimaryBreakpoint({ ...options, loadedTemplate: loadedTemplateToken })\n\t}\n\n\tconst connectedNodes = collectConnectedNodes(engine.tree, frame)\n\n\tconst renamedIds = new RenamedIds()\n\tconst clonedFrame = cloneWithRenamedIdMap(frame, new Map(), new Map(), renamedIds, false)\n\tclonedFrame.set({ ...primaryBreakpointDefaults, name: Dictionary.Desktop })\n\n\tconst webPage = createWebPageNode(engine, clonedFrame.id, pagePath, dataIdentifier, name)\n\tengine.tree.insertNode(webPage, engine.tree.root.id)\n\n\t// Clone the connected nodes first, so that the new IDs are collected in renamedIds for updating the connections.\n\tconst rootFrameRect = frame.rect()\n\tfor (const node of connectedNodes) {\n\t\tconst rect = node.rect()\n\t\tconst clone = cloneWithRenamedIdMap(node, new Map(), new Map(), renamedIds, false)\n\t\t// Position the clone relative to the root frame so that it's in the same relative\n\t\t// position as the original node.\n\t\tassert(isPinnable(clone), \"Ground node must be pinnable\", clone.id)\n\t\tconst delta = { x: rect.x - rootFrameRect.x, y: rect.y - rootFrameRect.y }\n\t\tclone.set({ left: (clonedFrame.left ?? 0) + delta.x, top: (clonedFrame.top ?? 0) + delta.y })\n\n\t\tengine.tree.insertNode(clone, webPage.id)\n\t\tupdateNodeConnections(engine.tree, engine.componentLoader, clone, renamedIds, false)\n\t}\n\n\tengine.tree.insertNode(clonedFrame, webPage.id)\n\tupdateNodeConnections(engine.tree, engine.componentLoader, clonedFrame, renamedIds, false)\n\n\treturn webPage\n}\n\n// Walk the subtree, find any connected ground nodes that should be moved to the new page as well\n// (e.g. Frames connected to a Ticker).\nfunction collectConnectedNodes(tree: CanvasTree, rootFrame: FrameNode): Set<CanvasNode> {\n\tconst connectedNodes = new Set<CanvasNode>()\n\n\tconst scope = tree.getScopeNodeFor(rootFrame)\n\tif (!scope) return connectedNodes\n\n\tfor (const child of rootFrame.walk()) {\n\t\tif (!withControlProps(child)) continue\n\n\t\tfor (const key in child) {\n\t\t\tconst value = child[key as keyof typeof child]\n\t\t\tif (!isRawControlProp(value)) continue\n\t\t\tconst result = replaceSlotReferencesWithNodes(key, value, child, scope.id, tree)\n\t\t\tif (result && !isRawControlProp(result)) {\n\t\t\t\tif (isArray(result)) {\n\t\t\t\t\tfor (const node of result) {\n\t\t\t\t\t\tif (node) connectedNodes.add(node)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconnectedNodes.add(result)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn connectedNodes\n}\n\nfunction createWebPageWithDefaultPrimaryBreakpoint(\n\toptions: Omit<CreateWebPageOptions, \"primaryBreakpointId\" | \"existingRouteSegment\">,\n) {\n\tconst { engine, id, name, pagePath, dataIdentifier, loadedTemplate, isWireframerKitPage } = options\n\n\tconst baseVariantId = randomID()\n\tconst webPage = createWebPageNode(engine, baseVariantId, pagePath, dataIdentifier, name, id, isWireframerKitPage)\n\tconst template = loadedTemplate === loadedTemplateToken ? undefined : loadedTemplate\n\tconst baseVariant = webPage.addChild(\n\t\tnew FrameNode({\n\t\t\tid: baseVariantId,\n\t\t\t...getPrimaryBreakpointProps(template),\n\t\t}),\n\t)\n\tassert(isPrimaryVariant(baseVariant), \"primary variant for createWebPage\")\n\n\tengine.tree.insertNode(webPage, engine.tree.root.id)\n\tengine.processFrameCreation(webPage.id, baseVariant)\n\n\treturn webPage\n}\n\n/**\n * Create a new page without a template. Should only be used in tests. Or if no template is available.\n */\nexport function createWebPageWithoutTemplate(options: Omit<CreateWebPageOptions, \"loadedTemplate\">): LoadedWebPageNode {\n\treturn createWebPage({ ...options, loadedTemplate: loadedTemplateToken })\n}\n", "import type { GlobalModuleId } from \"@framerjs/shared\"\nimport { assert, ModuleType, assertNever, isLocalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport type { AvailableKitSectionField } from \"app/ai/utils/wireframerKit.ts\"\nimport type {\n\tCanvasNode,\n\tCanvasTree,\n\tCollectionItemNode,\n\tLoadedScopeNode,\n\tNodeID,\n} from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport {\n\thasCollectionDataSource,\n\twithCollectionDataSource,\n} from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport { withVariableProvider } from \"document/models/CanvasTree/traits/WithVariableProvider.ts\"\nimport type { VariableDefinition } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport {\n\tisVariableDefinition,\n\tisVectorSetItemVariableInitialValue,\n} from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { isImageControlProp } from \"document/models/controlProps/ControlProp.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport { getCopiedAsset } from \"utils/clipboard/getCopiedAssets.ts\"\nimport type { CollectedCollections } from \"utils/clipboard/utils.ts\"\nimport { collectCollections } from \"utils/clipboard/utils.ts\"\nimport { getCollectionForIdentifier, getCollectionIdForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\nimport { forEachVariableReferenceOfNode } from \"utils/updateDynamicValues.ts\"\nimport type {\n\tCMSConnectedField,\n\tKitCollectionTemplate,\n\tKitCollectionTemplateReference,\n\tKitCollectionTemplateVariable,\n\tVectorSetsModuleData,\n} from \"./types.ts\"\n\nexport function collectDetailPageCollection(\n\ttree: CanvasTree,\n\tnode: LoadedScopeNode | null,\n\tcollectedCollections: CollectedCollections,\n): NodeID | undefined {\n\tif (!isWebPageNode(node) || !hasCollectionDataSource(node)) return\n\n\tconst identifier = node.dataIdentifier\n\tif (!identifier) return\n\n\tconst parsedIdentifier = parseModuleIdentifier(node.dataIdentifier)\n\tif (!isLocalModuleIdentifier(parsedIdentifier)) return\n\n\tconst collectionNode = tree.getNodeWithTrait(parsedIdentifier.localIdName, isCollectionNode)\n\tif (!collectionNode) return\n\n\t// Collect the detail page collection and all referenced collections inside it.\n\tcollectCollections(tree, node, collectedCollections)\n\n\treturn collectionNode.id\n}\n\nexport function collectCMSConnectedFields(\n\ttree: CanvasTree,\n\tnode: CanvasNode,\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>,\n) {\n\t// Iterating through all node properties to find variable references.\n\tforEachVariableReferenceOfNode(tree, node, \"excludeInherited\", \"readsRawNodeData\", undefined, variableReference => {\n\t\t// Get the provider node for this variable reference\n\t\tconst providerNode = tree.getNodeWithTrait(variableReference.providerId, withVariableProvider)\n\t\tif (!providerNode || !withCollectionDataSource(providerNode)) return\n\t\tif (!providerNode.dataIdentifier) return\n\n\t\t// Get the collection node that contains the variable definition\n\t\tconst collectionNode = getCollectionForIdentifier(tree, providerNode.dataIdentifier)\n\t\tif (!collectionNode) return\n\n\t\t// Get the variable definition from the collection\n\t\tconst variable = collectionNode.getVariable(variableReference.id)\n\t\tif (!variable) return\n\n\t\t// Convert the variable definition to a CMS field\n\t\tconst fieldData = getVariableFieldData(variable)\n\t\tif (!fieldData) return\n\n\t\tconst field: CMSConnectedField = {\n\t\t\tid: variableReference.id,\n\t\t\tproviderId: variableReference.providerId,\n\t\t\t...fieldData,\n\t\t}\n\n\t\tconst collectionFields = cmsConnectedFields[collectionNode.id]\n\t\tif (!collectionFields) {\n\t\t\tcmsConnectedFields[collectionNode.id] = [field]\n\t\t\treturn\n\t\t}\n\n\t\tconst alreadyContainsField = collectionFields?.some(existing => existing.id === field.id)\n\t\tif (alreadyContainsField) return\n\n\t\tcollectionFields.push(field)\n\t})\n}\n\nexport function flattenCMSConnectedFields(\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>,\n): AvailableKitSectionField[] {\n\tconst flattened: AvailableKitSectionField[] = []\n\n\tfor (const collectionId in cmsConnectedFields) {\n\t\tconst cmsFields = cmsConnectedFields[collectionId]\n\t\tassert(cmsFields, \"CMS connected fields must be an array\")\n\n\t\tfor (const field of cmsFields) {\n\t\t\tconst { id, providerId, ...fieldData } = field\n\t\t\tflattened.push({ ...fieldData, collectionId, isCMSConnectedField: true })\n\t\t}\n\t}\n\n\treturn flattened\n}\n\nfunction getVariableFieldData(variable: VariableDefinition): Omit<CMSConnectedField, \"id\" | \"providerId\"> | undefined {\n\tswitch (variable.type) {\n\t\tcase ControlType.Date:\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t\trequired: variable.required,\n\t\t\t}\n\n\t\tcase ControlType.Number:\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t\tmin: variable.options?.min,\n\t\t\t\tmax: variable.options?.max,\n\t\t\t}\n\t\tcase ControlType.RichText:\n\t\tcase ControlType.String:\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t\trequired: variable.required,\n\t\t\t\tmaxLength: variable.options?.maxLength,\n\t\t\t}\n\t\tcase ControlType.Boolean:\n\t\tcase ControlType.Image:\n\t\tcase \"slug\":\n\t\tcase ControlType.VectorSetItem:\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t}\n\t\tcase ControlType.Enum:\n\t\t\treturn { name: variable.name, type: variable.type, cases: variable.cases }\n\t\tcase ControlType.CollectionReference: {\n\t\t\tconst targetCollectionId = getCollectionIdForIdentifier(variable.dataIdentifier)\n\t\t\tassert(targetCollectionId, \"Collection node must be found\")\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t\treference: { collectionId: targetCollectionId, kind: \"single\" },\n\t\t\t}\n\t\t}\n\t\tcase ControlType.MultiCollectionReference: {\n\t\t\tconst targetCollectionId = getCollectionIdForIdentifier(variable.dataIdentifier)\n\t\t\tassert(targetCollectionId, \"Collection node must be found\")\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t\treference: { collectionId: targetCollectionId, kind: \"multi\" },\n\t\t\t}\n\t\t}\n\t\tcase ControlType.Array:\n\t\tcase ControlType.BorderRadius:\n\t\tcase ControlType.Border:\n\t\tcase ControlType.BoxShadow:\n\t\tcase ControlType.Color:\n\t\tcase ControlType.Cursor:\n\t\tcase ControlType.CustomCursor:\n\t\tcase ControlType.EventHandler:\n\t\tcase ControlType.File:\n\t\tcase ControlType.Gap:\n\t\tcase ControlType.Link:\n\t\tcase ControlType.LinkRelValues:\n\t\tcase ControlType.Transition:\n\t\tcase ControlType.ScrollSectionRef:\n\t\tcase ControlType.Padding:\n\t\tcase ControlType.TrackingId:\n\t\tcase ControlType.Location:\n\t\tcase \"controlReference\":\n\t\tcase \"nodePropertyControlReference\":\n\t\t\treturn {\n\t\t\t\tname: variable.name,\n\t\t\t\ttype: variable.type,\n\t\t\t}\n\t\tdefault:\n\t\t\tassertNever(variable, \"Unsupported variable type\")\n\t}\n}\n\nexport function createSectionCollectionTemplates(\n\tmodulesStore: ModulesStore,\n\tcollectedCollections: CollectedCollections,\n\tisDefaultKit: boolean = false,\n\tvectorSets?: VectorSetsModuleData,\n\tonVectorSetCollected?: (setId: GlobalModuleId) => void,\n): KitCollectionTemplate[] {\n\t// 1. Create a map of all collection templates and the new names so we can also reuse in references.\n\tlet counter = 1\n\tconst collectionTemplatesMap = new Map<NodeID, string>()\n\tfor (const [_, collectionNode] of collectedCollections) {\n\t\tconst name = collectionNode.resolveValue(\"name\")\n\t\tassert(name, \"Collection node must have a name\")\n\t\tconst sanitizedName = isDefaultKit ? name : `Template ${counter++}`\n\t\tcollectionTemplatesMap.set(collectionNode.id, sanitizedName)\n\t}\n\n\t// 2. Serialize the kit collection template.\n\t// We store collections with the template name instead of the given name so they are then used in the LLM\n\t// in a way that does not influence the collection template selection.\n\tconst collectionTemplates: KitCollectionTemplate[] = []\n\tfor (const [_, collectionNode] of collectedCollections) {\n\t\tconst name = collectionTemplatesMap.get(collectionNode.id)\n\t\tassert(name, \"Collection node must have a name\")\n\n\t\tconst allCollectionItems = collectionNode.getUnsortedChildren()\n\n\t\tconst variables = collectionNode.variables.reduce<KitCollectionTemplateVariable[]>((acc, variable) => {\n\t\t\tif (!isVariableDefinition(variable)) return acc\n\n\t\t\t// Make sure we collect the target collection id for collection references.\n\t\t\t// We collect the assets from the collection items and set as possible suggestions to the variable.\n\t\t\tconst defaultValueSuggestions = collectAssetsFromCollectionItems(allCollectionItems, variable)\n\t\t\tconst vectorSet = collectVectorSetReference(variable, vectorSets)\n\n\t\t\tif (vectorSet) onVectorSetCollected?.(vectorSet)\n\n\t\t\tacc.push({\n\t\t\t\t...convertInitialValueToExternal(variable, modulesStore),\n\t\t\t\t...(defaultValueSuggestions && { defaultValueSuggestions }),\n\t\t\t\treference: getReference(variable, collectionTemplatesMap),\n\t\t\t\t...(vectorSet && { iconSet: vectorSet }),\n\t\t\t})\n\n\t\t\treturn acc\n\t\t}, [])\n\n\t\tcollectionTemplates.push({\n\t\t\tid: collectionNode.id,\n\t\t\tname,\n\t\t\tvariables,\n\t\t})\n\t}\n\n\treturn collectionTemplates\n}\n\nfunction getReference(\n\tvariable: VariableDefinition,\n\tcollectionTemplatesMap: Map<NodeID, string>,\n): KitCollectionTemplateReference | undefined {\n\tif (variable.type !== ControlType.CollectionReference && variable.type !== ControlType.MultiCollectionReference) {\n\t\treturn\n\t}\n\n\tconst targetCollectionId = getCollectionIdForIdentifier(variable.dataIdentifier)\n\tassert(targetCollectionId, \"Collection node must be found\")\n\tconst targetCollectionName = collectionTemplatesMap.get(targetCollectionId)\n\tassert(targetCollectionName, \"Target collection name must be found\")\n\n\treturn {\n\t\tcollection: targetCollectionName,\n\t\tkind: variable.type === ControlType.CollectionReference ? \"single\" : \"multi\",\n\t}\n}\n\nfunction collectAssetsFromCollectionItems(\n\tallCollectionItems: CollectionItemNode[],\n\tvariable: VariableDefinition,\n): string[] | undefined {\n\tif (variable.type !== ControlType.Image) return\n\n\tconst collectedAssets: string[] = []\n\n\tfor (const child of allCollectionItems) {\n\t\tconst imageControlProp = child.getControlProp(variable.id)\n\t\tif (!isImageControlProp(imageControlProp)) continue\n\n\t\tconst image = imageControlProp.value\n\t\tif (isUndefined(image) || isDynamicValue(image)) continue\n\n\t\tconst asset = getCopiedAsset(image)\n\t\tif (!asset) continue\n\n\t\tcollectedAssets.push(asset)\n\t}\n\n\treturn collectedAssets\n}\n\nfunction collectVectorSetReference(\n\tvariable: VariableDefinition,\n\tvectorSets?: VectorSetsModuleData,\n): GlobalModuleId | undefined {\n\tif (!vectorSets || variable.type !== ControlType.VectorSetItem) return\n\treturn vectorSets[variable.setModuleId] ? variable.setModuleId : undefined\n}\n\n/**\n * Converts the initial value of a vector set item variable to an external identifier.\n */\nfunction convertInitialValueToExternal<T extends VariableDefinition>(variable: T, modulesStore?: ModulesStore): T {\n\tif (variable.type !== ControlType.VectorSetItem) return variable\n\tif (!modulesStore) return variable\n\n\tconst initialValue = variable.initialValue\n\tif (!isVectorSetItemVariableInitialValue(initialValue)) return variable\n\n\tconst { identifier } = initialValue\n\tconst parsed = parseModuleIdentifier(identifier)\n\tif (!parsed || parsed.kind !== \"localModuleExport\") return variable\n\n\tconst module = modulesStore.forType(ModuleType.Vector).getByLocalId(parsed.localId)\n\tif (!module) return variable\n\n\tconst externalIdentifier = module.externalModuleIdentifier(parsed.exportSpecifier)\n\tif (!externalIdentifier) return variable\n\n\treturn {\n\t\t...variable,\n\t\tinitialValue: {\n\t\t\t...initialValue,\n\t\t\tidentifier: externalIdentifier.value,\n\t\t},\n\t}\n}\n", "import type { Asset } from \"@framerjs/assets\"\nimport {\n\ttype GlobalModuleId,\n\ttype LocalModuleExportIdentifierString,\n\ttype ModuleExportIdentifierString,\n\tgetLogger,\n} from \"@framerjs/shared\"\nimport { flattenCMSConnectedFields } from \"app/ai/sections/collections.ts\"\nimport type { CMSConnectedField, ControlPropFields, KitCollectionTemplate } from \"app/ai/sections/types.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode, CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { ReadonlyChildList } from \"document/models/CanvasTree/nodes/ChildList.ts\"\nimport { isSlotNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { DynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport type { WithCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { withCustomizationsKey } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport type { WithFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport type { WithLayout } from \"document/models/CanvasTree/traits/WithLayout.ts\"\nimport type { WithPadding } from \"document/models/CanvasTree/traits/WithPadding.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { SaveId } from \"modules/types.ts\"\nimport { isFramerLayersClipboardData } from \"utils/clipboard/helpers/isFramerLayersClipboardData.ts\"\nimport { isArray, isBoolean, isNumber, isObject, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\n\nconst log = getLogger(\"WireframerSession\")\n\n/**\n * A Kit that can be selected in the AI panel, sourced from the kit the project was created from,\n * the org library, or the local kit.\n */\nexport interface WireframerKitListItem {\n\tid: string\n\ttitle: string\n\ticon?: string\n\t/** Undefined for the base and local kit */\n\tmoduleId: GlobalModuleId | undefined\n\t/** Undefined for the base and local kit */\n\tsaveId: SaveId | undefined\n\t/** Undefined for the base and local kit */\n\tversion: string | undefined\n}\n\nexport interface KitSectionMeta {\n\tid: string\n\t/**\n\t * When the section is a local Smart Component instance with only a variant control, expose the\n\t * module identifier. When the section is inserted it will be inserted as detached layers, then\n\t * replaced with a newly generated local instance of the Smart Component.\n\t */\n\tmoduleIdentifier?: LocalModuleExportIdentifierString\n\tdescription: string\n\tfields: AvailableKitSectionField[]\n\tlayoutId?: NodeID\n\tdetailPageCollectionId?: NodeID\n\t// @TODO: Remove the optional once we migrate the fAI Wireframer to an actual kit.\n\tcategory?: string\n\trules?: readonly string[]\n\tintrinsicHeight?: number\n\tintrinsicWidth?: number\n}\n\nexport const layoutTemplateSlotKey = \"$SLOT\"\n\nexport function isLayoutTemplateSlotKey(key: string): key is typeof layoutTemplateSlotKey {\n\treturn key === layoutTemplateSlotKey\n}\n\nexport function createLayoutTemplatePattern(nodes: ReadonlyChildList<CanvasNode>): string[] {\n\treturn nodes.map(node => (isSlotNode(node) ? layoutTemplateSlotKey : node.id))\n}\n\nexport interface KitLayoutTemplateMeta {\n\tid: string\n\t/* Ground elements in the layout template in their original order. */\n\tpattern: Array<NodeID | typeof layoutTemplateSlotKey>\n\tprimaryBreakpoint: NodeID | undefined\n\tbreakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined\n\tpageProperties: Record<NodeID, Partial<WireframerKitPageProperties>> | undefined\n}\n\ninterface StaticField {\n\tname: string\n\ttype: string\n\ticonSet?: GlobalModuleId\n\tisCMSConnectedField?: never\n\toptions?: string[]\n}\n\ninterface CMSField extends Omit<CMSConnectedField, \"id\" | \"providerId\"> {\n\tcollectionId: NodeID\n\tisCMSConnectedField: true\n}\n\nexport type AvailableKitSectionField = StaticField | CMSField\n\nfunction isAvailableKitSectionField(field: unknown): field is AvailableKitSectionField {\n\tif (!isObject(field)) return false\n\tif (!isString(field.name)) return false\n\tif (!isString(field.type)) return false\n\tif (field.iconSet && !isString(field.iconSet)) return false\n\tif (isBoolean(field.isCMSConnectedField)) {\n\t\tif (field.isCMSConnectedField && !isString(field.collectionId)) return false\n\t}\n\treturn true\n}\n\nfunction isKitSectionMeta(section: unknown): section is KitSectionMeta {\n\tif (!isObject(section)) return false\n\tif (!isString(section.id)) return false\n\tif (!isString(section.description)) return false\n\tif (!isArray(section.fields) || !section.fields.every(isAvailableKitSectionField)) return false\n\tif (section.detailPageCollectionId && !isString(section.detailPageCollectionId)) return false\n\treturn true\n}\n\nexport interface WireframerKitColorToken {\n\tid: string\n\tname: string\n\tlight: string\n\t// The dark value can be undefined if the token doesn't define a dark color, and the undefined\n\t// key might be omitted in the JSON, so it's safer to assume it's optional.\n\tdark?: string | undefined\n}\n\n// Solid color or token variable.\nexport type WireframerKitPageBackground = Exclude<WithFill[\"fillColor\"], DynamicValue>\nexport type WireframerKitPagePadding = Exclude<WithPadding[\"padding\"], DynamicValue>\nexport type WireframerKitPageGap = Exclude<WithLayout[\"gap\"], DynamicValue>\n\nexport interface WireframerKitBreakpoint {\n\twidth: number\n\tname: string\n\tviewportHeight?: number\n}\n\nexport interface WireframerKitPageProperties {\n\tfillColor: WireframerKitPageBackground\n\tpadding: WireframerKitPagePadding\n\tpaddingTop: WireframerKitPagePadding\n\tpaddingRight: WireframerKitPagePadding\n\tpaddingBottom: WireframerKitPagePadding\n\tpaddingLeft: WireframerKitPagePadding\n\tgap: WireframerKitPageGap\n}\n\nexport interface WireframerKitVectorSetInfo {\n\tid: NodeID\n\tname: string\n\tsaveId: SaveId\n}\n\nexport interface WireframerKitJSON {\n\tid: string\n\ttitle: string\n\tsections: Record<NodeID, KitSectionMeta>\n\tlayoutTemplates: Record<string, KitLayoutTemplateMeta>\n\t/** Record of vector set info by module ID - actual vector data is in separate {setId}.json files */\n\tsets: Record<GlobalModuleId, WireframerKitVectorSetInfo>\n\tcollections: KitCollectionTemplate[]\n\t/** Color tokens used by the kit sections, or the page background. */\n\ttokens: Record<string, WireframerKitColorToken>\n\t/** The schema version of the kit JSON. */\n\tschemaVersion: number\n\t/** The prompt used to generate the kit. */\n\tprompt: string | undefined\n\tprimaryBreakpoint: NodeID | undefined\n\tbreakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined\n\tpageProperties: Record<NodeID, Partial<WireframerKitPageProperties>> | undefined\n}\n\nexport interface WireframerKit extends Omit<WireframerKitJSON, \"schemaVersion\" | \"sets\"> {\n\tgetSectionScreenshot: (engine: VekterEngine, id: NodeID, isDarkMode: boolean) => string | undefined\n\tgetClipboardDataById: (id: NodeID, source?: boolean) => Promise<KitClipboardData | undefined>\n\tgetSectionByUniqueTitle: (title: string) => KitSectionMeta | undefined\n\tgetSections: (filter?: (section: KitSectionMeta) => boolean, shuffle?: boolean) => Omit<KitSectionMeta, \"category\">[]\n\tgetUniqueTitleBySectionId: (id: NodeID) => string\n\tlookupVectorByName: (set: GlobalModuleId, name: string) => Promise<ModuleExportIdentifierString | undefined>\n\tcreateIconSetsForPrompt: () => Promise<string | undefined>\n\tduplicateAssets: (assetStore: AssetStore, keys: string[]) => Promise<readonly Asset[]>\n\tgetCollectionTemplate: (name: string) => KitCollectionTemplate | undefined\n\tgetCollectionTemplateById: (id: NodeID) => KitCollectionTemplate | undefined\n\tgetCollectionTemplatesPrompt: () => string\n\tgetSectionsPrompt: (tree: CanvasTree, filter?: (section: KitSectionMeta) => boolean) => string\n\tgetLayoutPatternsPrompt: () => string\n\tgetBreakpointIdByWidth: (width: number, layoutId: NodeID | undefined) => NodeID | undefined\n}\n\nfunction isKitVectorSetInfo(setInfo: unknown): setInfo is WireframerKitVectorSetInfo {\n\tif (!isObject(setInfo)) return false\n\tif (!isString(setInfo.id)) return false\n\tif (!isString(setInfo.name)) return false\n\tif (!isString(setInfo.saveId)) return false\n\treturn true\n}\n\nexport function isWireframerKitJSON(kit: unknown): kit is WireframerKitJSON {\n\ttry {\n\t\tif (!isObject(kit)) throw new Error(\"kit must be an object\")\n\t\tif (!isString(kit.id)) throw new Error(\"kit.id must be a string\")\n\t\tif (!isString(kit.title)) throw new Error(\"kit.title must be a string\")\n\t\tif (!isObject(kit.sections)) throw new Error(\"kit.sections must be an object\")\n\t\tif (!isNumber(kit.schemaVersion)) throw new Error(\"kit.schemaVersion must be a number\")\n\t\tif (!isObject(kit.sets)) throw new Error(\"kit.sets must be an object\")\n\t\tif (!isArray(kit.collections)) throw new Error(\"kit.collections must be an array\")\n\t\tif (!isObject(kit.layoutTemplates)) throw new Error(\"kit.layoutTemplates must be an object\")\n\t\tif (!isUndefined(kit.prompt) && !isString(kit.prompt)) throw new Error(\"kit.prompt must be a string if defined\")\n\t\tif (!isUndefined(kit.primaryBreakpoint) && !isString(kit.primaryBreakpoint)) {\n\t\t\tthrow new Error(\"kit.primaryBreakpoint must be a string if defined\")\n\t\t}\n\t\tif (!isUndefined(kit.breakpoints) && !isWireframerKitBreakpoints(kit.breakpoints)) {\n\t\t\tthrow new Error(\"kit.breakpoints must be a record of WireframerKitBreakpoint if defined\")\n\t\t}\n\n\t\tfor (const id in kit.sections) {\n\t\t\tconst section = kit.sections[id]\n\t\t\tif (!isKitSectionMeta(section)) throw new Error(\"section must be a KitSectionMeta\")\n\t\t}\n\n\t\tfor (const setId in kit.sets) {\n\t\t\tif (!isKitVectorSetInfo(kit.sets[setId])) throw new Error(\"set must be a KitVectorSetInfo\")\n\t\t}\n\n\t\tif (!isWireframerKitColorTokens(kit.tokens)) {\n\t\t\tthrow new Error(\"kit.tokens must be a record of WireframerKitColorToken\")\n\t\t}\n\t\tif (kit.pageProperties && !isWireframerKitPageProperties(kit.pageProperties)) {\n\t\t\tthrow new Error(\"kit.pageProperties must be a WireframerKitPageProperties if defined\")\n\t\t}\n\n\t\treturn true\n\t} catch (error) {\n\t\tlog.error(\"Invalid kit JSON:\", error)\n\t\treturn false\n\t}\n}\n\nfunction isWireframerKitPageProperties(\n\tpageProperties: unknown,\n): pageProperties is Record<NodeID, Partial<WireframerKitPageProperties>> {\n\tif (!isObject(pageProperties)) return false\n\n\tfor (const props of Object.values(pageProperties)) {\n\t\tif (!isObject(props)) return false\n\n\t\tconst { fillColor, padding, paddingTop, paddingRight, paddingBottom, paddingLeft, gap } = props\n\n\t\tif (!isUndefined(fillColor) && !isString(fillColor)) return false\n\t\tif (!isUndefined(padding) && !isNumber(padding)) return false\n\t\tif (!isUndefined(paddingTop) && !isNumber(paddingTop)) return false\n\t\tif (!isUndefined(paddingRight) && !isNumber(paddingRight)) return false\n\t\tif (!isUndefined(paddingBottom) && !isNumber(paddingBottom)) return false\n\t\tif (!isUndefined(paddingLeft) && !isNumber(paddingLeft)) return false\n\t\tif (!isUndefined(gap) && !isString(gap) && !isNumber(gap)) return false\n\t}\n\treturn true\n}\n\nfunction isWireframerKitBreakpoint(breakpoint: unknown): breakpoint is WireframerKitBreakpoint {\n\tif (!isObject(breakpoint)) return false\n\tif (!isNumber(breakpoint.width)) return false\n\tif (!isUndefined(breakpoint.name) && !isString(breakpoint.name)) return false\n\treturn true\n}\n\nfunction isWireframerKitBreakpoints(breakpoints: unknown): breakpoints is Record<NodeID, WireframerKitBreakpoint> {\n\tif (!isObject(breakpoints)) return false\n\tfor (const breakpoint of Object.values(breakpoints)) {\n\t\tif (!isWireframerKitBreakpoint(breakpoint)) return false\n\t}\n\treturn true\n}\n\nfunction isWireframerKitColorTokens(value: unknown): value is Record<string, WireframerKitColorToken> {\n\tif (!isObject(value)) return false\n\tfor (const key in value) {\n\t\tconst token = value[key]\n\t\tif (!isWireframerKitColorToken(token)) return false\n\t}\n\treturn true\n}\n\nfunction isWireframerKitColorToken(background: unknown): background is WireframerKitColorToken {\n\tif (!isObject(background)) return false\n\tif (!(\"id\" in background) || !isString(background.id)) return false\n\tif (!(\"name\" in background) || !isString(background.name)) return false\n\tif (!(\"light\" in background) || !isString(background.light)) return false\n\t// `dark` is optional\n\tif (\"dark\" in background && !isUndefined(background.dark) && !isString(background.dark)) return false\n\treturn true\n}\n\nexport function isKitItemClipboardData(data: unknown): data is KitClipboardData {\n\tif (!isObject(data)) return false\n\tif (!isObject(data.cmsConnectedFields)) return false\n\treturn isFramerLayersClipboardData(data)\n}\n\nexport function getFieldsForSection(\n\tdata: KitClipboardData,\n\tcontrolPropFields?: ControlPropFields,\n): AvailableKitSectionField[] {\n\tconst fields: AvailableKitSectionField[] = []\n\n\tfor (const value of walk(data.layers.tree.root)) {\n\t\tif (!isObject(value)) continue\n\t\tif (!isString(value.__class)) continue\n\n\t\tif (value.__class === \"CodeComponentNode\" && isString(value.codeComponentIdentifier)) {\n\t\t\tconst controlProps = controlPropFields?.[value.codeComponentIdentifier]\n\t\t\tfor (const controlProp of controlProps ?? []) {\n\t\t\t\tfields.push({ name: controlProp.title, type: \"string\" })\n\t\t\t}\n\t\t}\n\n\t\tif (!hasCustomizationsField(value) || !value.customizations) continue\n\n\t\tfor (const customization of value.customizations) {\n\t\t\tif (customization.type !== \"content\") continue\n\t\t\tconst { fieldPath } = customization\n\t\t\tfields.push({ name: fieldPath, type: \"string\" })\n\t\t}\n\t}\n\n\tfields.push(...flattenCMSConnectedFields(data.cmsConnectedFields))\n\n\treturn fields\n}\n\nfunction* walk(data: unknown): Iterable<object> {\n\tif (typeof data !== \"object\" || !data) return\n\tyield data\n\tif (!(\"children\" in data) || !isArray(data.children)) return\n\tfor (const subdata of data.children) {\n\t\tyield* walk(subdata)\n\t}\n}\n\nfunction hasCustomizationsField(value: object): value is WithCustomizations {\n\treturn withCustomizationsKey in value\n}\n", "import { isString, isUndefined } from \"utils/typeChecks.ts\"\n\nconst symbolIncompleteValue = Symbol(\"incomplete value\")\n\ntype SymbolIndexableArray<T = unknown> = T[] & {\n\t[key: symbol]: unknown\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: Assuming any data can come from the object created by the parser.\ntype SymbolIndexableObject = Record<PropertyKey, any>\n\nexport function isIncompleteValue(value: SymbolIndexableObject | null | undefined, key: string | number): boolean {\n\tif (!isString(key)) key = key.toString()\n\treturn value != null && value[symbolIncompleteValue] === key\n}\n\nexport function createIncompleteValueForTest(\n\tvalue: SymbolIndexableObject,\n\tkey: string | number,\n): SymbolIndexableObject {\n\tif (!isString(key)) key = key.toString()\n\tvalue[symbolIncompleteValue] = key\n\treturn value\n}\n\nexport enum TokenType {\n\tOpenCurly = \"{\",\n\tCloseCurly = \"}\",\n\tOpenBracket = \"[\",\n\tCloseBracket = \"]\",\n\tSingleQuote = \"'\",\n\tDoubleQuote = '\"',\n\tBacktick = \"`\",\n\tColon = \":\",\n\tComma = \",\",\n\tBackslash = \"\\\\\",\n\tWhitespace = \"whitespace\",\n\tText = \"text\",\n}\n\ntype Token =\n\t| { type: TokenType.OpenCurly }\n\t| { type: TokenType.CloseCurly }\n\t| { type: TokenType.OpenBracket }\n\t| { type: TokenType.CloseBracket }\n\t| { type: TokenType.SingleQuote }\n\t| { type: TokenType.DoubleQuote }\n\t| { type: TokenType.Colon }\n\t| { type: TokenType.Comma }\n\t| { type: TokenType.Backslash }\n\t| { type: TokenType.Backtick }\n\t| { type: TokenType.Whitespace; value: string }\n\t| { type: TokenType.Text; value: string }\n\nfunction stringForToken(token: Token): string {\n\tswitch (token.type) {\n\t\tcase TokenType.Text:\n\t\tcase TokenType.Whitespace:\n\t\t\treturn token.value\n\t\tdefault:\n\t\t\treturn token.type\n\t}\n}\nconst matchWhiteSpace = /^\\s+$/u\n// Everything that is not a token or whitespace\nconst matchText = /^[^{}[\\]'\":,\\\\`\\s]+$/u\nexport function tokenize(string: string): Token[] {\n\tconst result: Token[] = []\n\tconst chars = string.split(\"\")\n\tfor (let i = 0; i < chars.length; i++) {\n\t\tlet token = chars[i]\n\t\tswitch (token) {\n\t\t\tcase \"{\":\n\t\t\t\tresult.push({ type: TokenType.OpenCurly })\n\t\t\t\tbreak\n\t\t\tcase \"}\":\n\t\t\t\tresult.push({ type: TokenType.CloseCurly })\n\t\t\t\tbreak\n\t\t\tcase \"[\":\n\t\t\t\tresult.push({ type: TokenType.OpenBracket })\n\t\t\t\tbreak\n\t\t\tcase \"]\":\n\t\t\t\tresult.push({ type: TokenType.CloseBracket })\n\t\t\t\tbreak\n\t\t\tcase \"'\":\n\t\t\t\tresult.push({ type: TokenType.SingleQuote })\n\t\t\t\tbreak\n\t\t\tcase '\"':\n\t\t\t\tresult.push({ type: TokenType.DoubleQuote })\n\t\t\t\tbreak\n\t\t\tcase \":\":\n\t\t\t\tresult.push({ type: TokenType.Colon })\n\t\t\t\tbreak\n\t\t\tcase \",\":\n\t\t\t\tresult.push({ type: TokenType.Comma })\n\t\t\t\tbreak\n\t\t\tcase \"\\\\\":\n\t\t\t\tresult.push({ type: TokenType.Backslash })\n\t\t\t\tbreak\n\t\t\tcase \"`\":\n\t\t\t\tresult.push({ type: TokenType.Backtick })\n\t\t\t\tbreak\n\t\t\tdefault: {\n\t\t\t\t// Whitespace\n\t\t\t\tconst whitespace: string[] = []\n\t\t\t\twhile (token?.match(matchWhiteSpace)) {\n\t\t\t\t\twhitespace.push(token)\n\t\t\t\t\ti++\n\t\t\t\t\ttoken = chars[i]\n\t\t\t\t}\n\t\t\t\tif (whitespace.length > 0) {\n\t\t\t\t\tresult.push({ type: TokenType.Whitespace, value: whitespace.join(\"\") })\n\t\t\t\t\ti--\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Text\n\t\t\t\tconst text: string[] = []\n\t\t\t\twhile (token?.match(matchText)) {\n\t\t\t\t\ttext.push(token)\n\t\t\t\t\ti++\n\t\t\t\t\ttoken = chars[i]\n\t\t\t\t}\n\t\t\t\tif (text.length > 0) {\n\t\t\t\t\tresult.push({ type: TokenType.Text, value: text.join(\"\") })\n\t\t\t\t\ti--\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// biome-ignore lint/suspicious/noConsole: <explanation>\n\t\t\t\tconsole.error(\"Did not tokenize token\", token)\n\t\t\t}\n\t\t}\n\t}\n\treturn result\n}\n\nfunction isQuote(token: Token): boolean {\n\treturn (\n\t\ttoken.type === TokenType.DoubleQuote || token.type === TokenType.SingleQuote || token.type === TokenType.Backtick\n\t)\n}\n\ntype ParserValue<T> = { value: T; isFinal: true } | { value: T | undefined; isFinal: false }\n\nfunction incompleteValue<T>(value: T | undefined): { value: T | undefined; isFinal: false } {\n\treturn { value, isFinal: false }\n}\n\nfunction finalValue<T>(value: T): { value: T; isFinal: true } {\n\treturn { value, isFinal: true }\n}\n\nfunction setKeyValue(result: Record<string | symbol, unknown>, keyValue: [string, ParserValue<unknown>]) {\n\tconst [key, value] = keyValue\n\tconst update = value.value\n\tif (!isUndefined(update)) {\n\t\tresult[key] = update\n\t\tif (!value.isFinal) {\n\t\t\tresult[symbolIncompleteValue] = key\n\t\t}\n\t}\n}\n\nexport class SloppyJavaScriptParser {\n\tprivate js = \"\"\n\ttokens: Token[] = []\n\tindex = 0\n\n\tconstructor(private readonly onValue: (value: Record<string, unknown> | unknown[], isFinal: boolean) => void) {}\n\n\tprivate peekCurrentToken(): Token | undefined {\n\t\tif (!this.hasTokens) return\n\t\treturn this.tokens[this.index]\n\t}\n\n\tprivate popCurrentToken(): Token | undefined {\n\t\tconst token = this.peekCurrentToken()\n\t\tif (!token) return\n\t\tthis.increaseIndex()\n\t\treturn token\n\t}\n\n\tprivate increaseIndex() {\n\t\tthis.index += 1\n\t}\n\n\tprivate get hasTokens() {\n\t\treturn this.index < this.tokens.length\n\t}\n\n\tadd(js: string) {\n\t\tif (!js) return\n\t\tthis.js += js\n\t\tconst newTokens = tokenize(js)\n\t\tconst lastToken = this.tokens[this.tokens.length - 1]\n\t\tlet firstNewToken = newTokens.shift()\n\t\t// Combine tokens if needed\n\t\tif (\n\t\t\tlastToken &&\n\t\t\tfirstNewToken &&\n\t\t\tlastToken.type === firstNewToken.type &&\n\t\t\t\"value\" in lastToken &&\n\t\t\t\"value\" in firstNewToken\n\t\t) {\n\t\t\tlastToken.value += firstNewToken.value\n\t\t\tfirstNewToken = undefined\n\t\t}\n\t\tif (firstNewToken) {\n\t\t\tthis.tokens.push(firstNewToken)\n\t\t}\n\t\tthis.tokens.push(...newTokens)\n\t\tthis.tryParse()\n\t}\n\n\t/**\n\t * Stops the parser and returns the length of the ingested JS.\n\t */\n\tend(): { jsLength: number } {\n\t\tthis.tryParse(true)\n\t\tconst jsLength = this.js.length\n\t\tthis.js = \"\"\n\t\tthis.tokens = []\n\t\treturn { jsLength }\n\t}\n\n\tprivate tryParse(finalize = false) {\n\t\twhile (this.hasTokens) {\n\t\t\tconst token = this.peekCurrentToken()\n\t\t\tif (!token) break\n\t\t\tswitch (token?.type) {\n\t\t\t\tcase TokenType.OpenCurly: {\n\t\t\t\t\tconst { value: object, isFinal } = this.parseObject()\n\t\t\t\t\tif (!object) {\n\t\t\t\t\t\tthis.increaseIndex()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tthis.onValue(object, isFinal || finalize)\n\t\t\t\t\tif (!isFinal) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase TokenType.OpenBracket: {\n\t\t\t\t\tconst { value: array, isFinal } = this.parseArray()\n\t\t\t\t\tif (!array) {\n\t\t\t\t\t\tthis.increaseIndex()\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tthis.onValue(array, isFinal || finalize)\n\t\t\t\t\tif (!isFinal) {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t// Token is not relevant in this context, just skip it.\n\t\t\t\t\tthis.increaseIndex()\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\ttryParsing<T>() {\n\t\tconst currentIndex = this.index\n\t\treturn {\n\t\t\tbacktrack: () => {\n\t\t\t\tthis.index = currentIndex\n\t\t\t\treturn {\n\t\t\t\t\tandReturnUndefined: () => {\n\t\t\t\t\t\treturn undefined\n\t\t\t\t\t},\n\t\t\t\t\tandReturnIncomplete: (incomplete: T | undefined): { value: T | undefined; isFinal: false } => {\n\t\t\t\t\t\treturn incompleteValue(incomplete)\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t},\n\t\t\tsuccessful(final: T): { value: T; isFinal: true } {\n\t\t\t\treturn finalValue(final)\n\t\t\t},\n\t\t}\n\t}\n\n\tparseObject(): ParserValue<Record<string, unknown>> {\n\t\tconst { successful, backtrack } = this.tryParsing<Record<string, unknown>>()\n\t\tlet token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.OpenCurly) return backtrack().andReturnIncomplete(undefined)\n\t\tconst result: Record<string | symbol, unknown> = {}\n\t\tthis.dropWhitespace()\n\t\tlet keyValue = this.parseKeyValue()\n\t\tlet next = keyValue.value\n\t\twhile (next && keyValue.isFinal) {\n\t\t\tsetKeyValue(result, next)\n\t\t\tthis.dropWhitespace()\n\t\t\tkeyValue = this.parseKeyValue()\n\t\t\tnext = keyValue.value\n\t\t}\n\t\tif (next && !keyValue.isFinal) {\n\t\t\tsetKeyValue(result, next)\n\t\t}\n\t\ttoken = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.CloseCurly) return backtrack().andReturnIncomplete(result)\n\t\treturn successful(result)\n\t}\n\n\tparseKeyValue(): ParserValue<[string, ParserValue<unknown>]> {\n\t\tconst { successful, backtrack } = this.tryParsing<[string, ParserValue<unknown>]>()\n\t\tconst key = this.parseObjectKey()\n\t\tif (!isString(key)) return backtrack().andReturnIncomplete(undefined)\n\t\tthis.dropWhitespace()\n\t\tconst token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.Colon) {\n\t\t\treturn backtrack().andReturnIncomplete([key, incompleteValue(undefined)])\n\t\t}\n\t\tthis.dropWhitespace()\n\t\tconst value = this.parseValue()\n\t\tif (!value) return backtrack().andReturnIncomplete([key, value])\n\t\tthis.dropWhitespaceCommaWhiteSpace()\n\t\tif (!value.isFinal) {\n\t\t\treturn backtrack().andReturnIncomplete([key, value])\n\t\t}\n\t\treturn successful([key, value])\n\t}\n\n\tparseObjectKey(): string | undefined {\n\t\tconst { backtrack } = this.tryParsing<string>()\n\t\tconst string = this.parseString().value\n\t\tif (isString(string)) return string\n\t\tconst token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.Text) return backtrack().andReturnUndefined()\n\t\treturn token.value\n\t}\n\n\tparseValue(): ParserValue<string | boolean | unknown[] | Record<string, unknown>> {\n\t\tconst { backtrack } = this.tryParsing<string | boolean | unknown[] | Record<string, unknown>>()\n\t\tconst string = this.parseString()\n\t\tif (!isUndefined(string.value)) return string\n\t\tconst array = this.parseArray()\n\t\tif (array.value) return array\n\t\tconst object = this.parseObject()\n\t\tif (object.value) return object\n\t\tconst boolean = this.parseBoolean()\n\t\tif (boolean.value !== undefined) return boolean\n\t\treturn backtrack().andReturnIncomplete(undefined)\n\t}\n\n\tparseBoolean(): ParserValue<boolean> {\n\t\tconst { successful, backtrack } = this.tryParsing<boolean>()\n\t\tconst token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.Text) return backtrack().andReturnIncomplete(undefined)\n\t\tif (token.value === \"true\") {\n\t\t\treturn successful(true)\n\t\t}\n\t\tif (token.value === \"false\") {\n\t\t\treturn successful(false)\n\t\t}\n\n\t\treturn backtrack().andReturnIncomplete(undefined)\n\t}\n\n\tparseArray(): ParserValue<unknown[]> {\n\t\tconst { successful, backtrack } = this.tryParsing<unknown[]>()\n\t\tlet token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.OpenBracket) {\n\t\t\treturn backtrack().andReturnIncomplete(undefined)\n\t\t}\n\t\tthis.dropWhitespace()\n\t\tlet arrayValue = this.parseValue()\n\t\tlet next = arrayValue.value\n\t\tconst array = [] as unknown as SymbolIndexableArray\n\t\twhile (arrayValue.isFinal && next !== undefined) {\n\t\t\tarray.push(next)\n\t\t\tthis.dropWhitespaceCommaWhiteSpace()\n\t\t\tarrayValue = this.parseValue()\n\t\t\tnext = arrayValue.value\n\t\t}\n\t\tif (!arrayValue.isFinal && next) {\n\t\t\tarray.push(next)\n\t\t\tarray[symbolIncompleteValue] = String(array.length - 1)\n\t\t}\n\t\tthis.dropWhitespace()\n\t\ttoken = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.CloseBracket) {\n\t\t\treturn backtrack().andReturnIncomplete(array)\n\t\t}\n\t\treturn successful(array)\n\t}\n\n\tparseString(): ParserValue<string> {\n\t\tconst { successful, backtrack } = this.tryParsing<string>()\n\t\tconst startToken = this.popCurrentToken()\n\t\tif (!startToken || !isQuote(startToken)) return backtrack().andReturnIncomplete(undefined)\n\t\tlet next = this.peekCurrentToken()\n\t\tlet string = \"\"\n\t\twhile (next && next.type !== startToken.type) {\n\t\t\tconst value = this.parseEscapedCharacter() ?? this.parseText()\n\t\t\tif (value) {\n\t\t\t\tstring += value\n\t\t\t}\n\t\t\tnext = this.peekCurrentToken()\n\t\t}\n\t\tconst token = this.popCurrentToken()\n\t\tif (!token || token.type !== startToken.type) return backtrack().andReturnIncomplete(string)\n\t\treturn successful(string)\n\t}\n\n\tparseEscapedCharacter(): string | undefined {\n\t\tconst { backtrack } = this.tryParsing<string>()\n\t\tlet token = this.popCurrentToken()\n\t\tif (!token || token.type !== TokenType.Backslash) return backtrack().andReturnUndefined()\n\t\ttoken = this.popCurrentToken()\n\t\tif (!token) return backtrack().andReturnUndefined()\n\t\tif (token.type === TokenType.Text) {\n\t\t\tswitch (token.value[0]) {\n\t\t\t\tcase \"b\":\n\t\t\t\t\treturn \"\\b\" + token.value.substring(1)\n\t\t\t\tcase \"f\":\n\t\t\t\t\treturn \"\\f\" + token.value.substring(1)\n\t\t\t\tcase \"n\":\n\t\t\t\t\treturn \"\\n\" + token.value.substring(1)\n\t\t\t\tcase \"r\":\n\t\t\t\t\treturn \"\\r\" + token.value.substring(1)\n\t\t\t\tcase \"t\":\n\t\t\t\t\treturn \"\\t\" + token.value.substring(1)\n\t\t\t\t// TODO: Support Unicode\n\t\t\t\t// case \"u\":\n\t\t\t\t//     ...\n\t\t\t}\n\t\t}\n\t\treturn stringForToken(token)\n\t}\n\n\tparseText(): string | undefined {\n\t\tconst token = this.popCurrentToken()\n\t\tif (!token) return\n\t\treturn stringForToken(token)\n\t}\n\n\tdropWhitespaceCommaWhiteSpace() {\n\t\tthis.dropWhitespace()\n\t\tthis.dropComma()\n\t\tthis.dropWhitespace()\n\t}\n\n\tdropWhitespace() {\n\t\twhile (this.peekCurrentToken()?.type === TokenType.Whitespace) {\n\t\t\tthis.increaseIndex()\n\t\t}\n\t}\n\n\tdropComma() {\n\t\twhile (this.peekCurrentToken()?.type === TokenType.Comma) {\n\t\t\tthis.increaseIndex()\n\t\t}\n\t}\n}\n", "import { isIncompleteValue } from \"document/utils/SloppyJavaScriptParser.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\n\n// From Lodash: https://github.com/lodash/lodash/blob/4.17.21/lodash.js#L147\nconst rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g\nconst reEscapeChar = /\\\\(\\\\)?/gu\n\nexport function parsePath(path: string): string[] {\n\tconst result: string[] = []\n\tfor (const [match, number, quote, substring] of path.matchAll(rePropName)) {\n\t\tif (quote && isString(substring)) {\n\t\t\tresult.push(substring.replace(reEscapeChar, \"$1\"))\n\t\t} else if (isString(number)) {\n\t\t\tresult.push(number)\n\t\t} else if (isString(match)) {\n\t\t\tresult.push(match)\n\t\t}\n\t}\n\treturn result\n}\n\nexport class ContentContainer {\n\tprivate readonly pathCache = new Map<string, string[]>()\n\n\tprivate _isFinal = false\n\tget isFinal() {\n\t\treturn this._isFinal\n\t}\n\n\tconstructor(\n\t\tprivate data: Record<string, unknown>,\n\t\tisFinal = true,\n\t) {\n\t\tif (isFinal) this.finalize()\n\t}\n\n\tfinalize() {\n\t\tthis._isFinal = true\n\t}\n\n\tget(fieldPath: string): unknown {\n\t\tconst parsedPath = this.getParsedPath(fieldPath)\n\t\tlet object: object = this.data\n\t\tfor (const key of parsedPath) {\n\t\t\tif (object === null || object === undefined) break\n\t\t\tobject = object[key]\n\t\t}\n\t\treturn object\n\t}\n\n\tprivate readonly completeOnceSet = new Set<string[]>()\n\n\t/**\n\t * Gets the value *once* if it's complete. Calls before it's available or\n\t * while it's incomplete will return `undefined`. Once a value has been\n\t * returned once, all future calls will also return `undefined`. This method\n\t * is useful for handling a value exactly once.\n\t */\n\tgetCompleteValueOnce(fieldPath: string): unknown {\n\t\tconst parsedPath = this.getParsedPath(fieldPath)\n\t\t// FIXME: We rely on the same path always returning the same array. But\n\t\t// in reality the same path can be expressed by multiple strings,\n\t\t// resulting in different arrays.\n\t\tif (this.completeOnceSet.has(parsedPath)) return undefined\n\t\tlet object: object = this.data\n\t\tfor (const key of parsedPath) {\n\t\t\tif (object === null || object === undefined) break\n\t\t\tif (!(key in object)) return undefined\n\t\t\tif (isIncompleteValue(object, key)) return undefined\n\t\t\tobject = object[key]\n\t\t}\n\t\tthis.completeOnceSet.add(parsedPath)\n\t\treturn object\n\t}\n\n\tisIncomplete(fieldPath: string): boolean {\n\t\tconst parsedPath = this.getParsedPath(fieldPath)\n\t\tlet object: object = this.data\n\t\tfor (const key of parsedPath) {\n\t\t\tif (object === null || object === undefined) return false\n\t\t\tif (isIncompleteValue(object, key)) return true\n\t\t\tobject = object[key]\n\t\t}\n\t\treturn false\n\t}\n\n\tupdate(newData: Record<string, unknown>) {\n\t\tif (this._isFinal) throw new Error(\"Cannot update a finalized content container\")\n\t\t// TODO: We'd like to partially update at some point probably, but we\n\t\t// need the incomplete symbol to go away so we can't do that now.\n\t\tthis.data = newData\n\t}\n\n\tprivate getParsedPath(fieldPath: string): string[] {\n\t\tlet parsedPath = this.pathCache.get(fieldPath)\n\t\tif (!parsedPath) {\n\t\t\tparsedPath = parsePath(fieldPath)\n\t\t\tthis.pathCache.set(fieldPath, parsedPath)\n\t\t}\n\t\treturn parsedPath\n\t}\n}\n", "import type { FollowUpTask } from \"app/ai/WireframerSession.ts\"\nimport { CommandType } from \"app/ai/orchestrator/dsl.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\n\ninterface CreateAddCMSItemsTaskOptions {\n\tcollectionNodeId: NodeID\n\tcollectionName: string\n\tgetInstructions: () => string\n}\n\nexport function createAddCMSItems({\n\tcollectionNodeId,\n\tcollectionName,\n\tgetInstructions,\n}: CreateAddCMSItemsTaskOptions): FollowUpTask {\n\treturn {\n\t\tdescription: `Updating ${collectionName}`,\n\t\ttask: () => {\n\t\t\treturn {\n\t\t\t\ttype: CommandType.AddCMSItems,\n\t\t\t\tcollection: collectionNodeId,\n\t\t\t\tinstructions: getInstructions(),\n\t\t\t}\n\t\t},\n\t}\n}\n", "import { CREATE_NEW_COLLECTION_ALIAS } from \"app/ai/utils/kitSection.ts\"\nimport { isArray, isObject, isString } from \"utils/typeChecks.ts\"\nimport { z } from \"zod\"\n\ntype SectionId = string\ntype FieldPath = string\n\ninterface Field {\n\tfield: FieldPath\n\ttext: string\n}\n\nconst sectionActions = [\"add\", \"remove\", \"update\", \"none\"] as const\ntype SectionAction = (typeof sectionActions)[number]\nconst sectionActionsSet = new Set(sectionActions)\n\nexport interface CollectionBinding {\n\tfromTemplateCollection: string\n\tcollectionName: string\n\tnew: boolean\n}\n\nexport interface Section {\n\t_id: SectionId\n\t_layerId: string\n\taction: SectionAction\n\tcontent: Field[]\n\tcollectionBindings: CollectionBinding[]\n}\n\nexport interface AIStructuredOutput {\n\tlayout: string\n\tsections: Section[]\n}\n\nexport interface AIStructuredOutputWithMessage extends AIStructuredOutput {\n\tmessage: string\n}\n\nexport function isValidSectionAction(action: unknown): action is SectionAction {\n\treturn isString(action) && sectionActionsSet.has(action as SectionAction)\n}\n\nexport function isValidCollectionBindings(bindings: unknown): bindings is CollectionBinding[] {\n\tif (!isArray(bindings)) return false\n\treturn bindings.every(binding => {\n\t\treturn isObject(binding) && isString(binding.fromTemplateCollection) && isString(binding.collectionName)\n\t})\n}\n\nconst collectionBindingSchema = z.object({\n\tfromTemplateCollection: z\n\t\t.string()\n\t\t.describe(\n\t\t\t\"Collection template. Must match the key name used in supportedCollections to identify the existing collection to bind to in the section.\",\n\t\t),\n\tcollectionName: z\n\t\t.string()\n\t\t.describe(\n\t\t\t`Either: a) when creating a new collection from the \"${CREATE_NEW_COLLECTION_ALIAS}\" alias, a unique Title Case name for the collection whose content will be used to fill the section, or b) the exact name from the \"supportedCollections\" list for this template that the content in this section should be bound to.`,\n\t\t),\n\tnew: z.boolean().describe(\"Whether the collection is new (true) or existing (false).\"),\n})\n\nexport const schema = z.object({\n\tlayout: z.string().describe(\"The ID of the chosen layout. Empty string if no layout was chosen.\"),\n\tsections: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\t_id: z.string().describe(\"Unique identifier for the section type.\"),\n\t\t\t\t_layerId: z.string().describe(\"Existing layer ID of the section. Empty string for new sections.\"),\n\t\t\t\taction: z\n\t\t\t\t\t.enum(sectionActions)\n\t\t\t\t\t.describe(\"The action to perform: 'add' (new), 'remove' (delete), 'update' (change), or 'none' (unchanged).\"),\n\t\t\t\tcollectionBindings: z\n\t\t\t\t\t.array(collectionBindingSchema)\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"List of mappings of template collections to the selected existing collection name to bind to. Empty array if section has no CMS connected fields or no collections to bind to.\",\n\t\t\t\t\t),\n\t\t\t\tcontent: z\n\t\t\t\t\t.array(\n\t\t\t\t\t\tz.object({\n\t\t\t\t\t\t\tfield: z.string().describe(\"The field identifier for this static content.\"),\n\t\t\t\t\t\t\ttext: z.string().describe(\"The static text content.\"),\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t\t.describe(\"Array of field objects containing the section's text content.\"),\n\t\t\t}),\n\t\t)\n\t\t.describe(\"Ordered array of sections representing the page structure from top to bottom.\"),\n\tmessage: z\n\t\t.string()\n\t\t.describe(\n\t\t\t\"A message describing what changes were actually made. If some or none changes were possible, explain specifically why the request couldn't be fulfilled\",\n\t\t),\n})\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport { isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { HasCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { isRawControlProp } from \"document/models/controlProps/RawControlProp.ts\"\nimport { isPrefixedControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\n\nexport function getNodeProperty(\n\tengine: VekterEngine,\n\tnode: CanvasNode & HasCustomizations,\n\tproperty: string,\n): string | undefined {\n\tconst currentNode = engine.tree.current(node)\n\tif (!currentNode) return\n\n\tif (isPrefixedControlPropKey(property)) {\n\t\tconst controlProp = currentNode[property as keyof typeof currentNode]\n\t\tif (!isRawControlProp(controlProp) || !isString(controlProp.value)) return\n\t\treturn controlProp.value\n\t}\n\n\tif (!(property in currentNode)) {\n\t\treturn\n\t}\n\n\tif (property === \"textContent\" && isRichTextNode(currentNode)) {\n\t\treturn currentNode.getTextContent()\n\t}\n\n\tconst value = currentNode[property as keyof typeof currentNode]\n\tif (!isString(value)) return\n\n\treturn value\n}\n", "import type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { ControlProp } from \"document/models/controlProps/ControlProp.ts\"\nimport { isPrefixedControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport type { CanvasNode } from \"../CanvasNode.ts\"\nimport { isRichTextNode } from \"./nodeCheck.ts\"\nimport { updateHTMLText } from \"./updateHTMLText.ts\"\n\n/**\n * Updates a string property value of the provided node. This will correctly\n * handle RichTextNode behaviors, such as updating HTML.\n *\n * This function expects the caller to only call it from within a\n * `engine.scheduler.processWhenReady(\u2026)` (or equivalent) block.\n */\nexport function setStringValue(engine: VekterEngine, node: CanvasNode, property: string, value: string) {\n\tconst currentNode = engine.tree.current(node)\n\tif (!currentNode) {\n\t\treturn false\n\t}\n\tif (isPrefixedControlPropKey(property)) {\n\t\tconst controlProp: ControlProp = { type: ControlType.String, value }\n\t\tcurrentNode.set({ [property]: controlProp })\n\t} else {\n\t\tif (!(property in currentNode)) {\n\t\t\treturn false\n\t\t}\n\t\tif (property === \"textContent\" && isRichTextNode(currentNode)) {\n\t\t\tif (currentNode.getTextContent() === value) return true\n\n\t\t\tcurrentNode.set({ html: updateHTMLText(currentNode.html, value) })\n\t\t\treturn true\n\t\t} else {\n\t\t\tcurrentNode.set({ [property]: value })\n\t\t}\n\t}\n\treturn true\n}\n", "export function propKeyIsTitleLike(key: string): boolean {\n\tconst normalizedKey = key.toLowerCase().split(\" \")[0]\n\tswitch (normalizedKey) {\n\t\tcase \"title\":\n\t\tcase \"name\":\n\t\tcase \"heading\":\n\t\tcase \"header\":\n\t\t\treturn true\n\t\tdefault:\n\t\t\treturn false\n\t}\n}\n", "import { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport type { ComputedValue } from \"../ComputedValue.ts\"\nimport { createComputedValue } from \"../ComputedValue.ts\"\nimport type { ValueTransformToDateString } from \"../ValueTransform.ts\"\nimport type { VariableReference } from \"../VariableReference.ts\"\nimport { createValueTransformWithName } from \"./valueTransformUtils.ts\"\n\nexport function createComputedFormattedDate(\n\tstartValue: VariableReference,\n\tformattingOptions?: Partial<Pick<ValueTransformToDateString, \"dateStyle\" | \"display\">>,\n): ComputedValue {\n\tconst toDateString = createValueTransformWithName({\n\t\tname: \"toDateString\",\n\t\tinput: ControlType.Date,\n\t\toutput: ControlType.String,\n\t})\n\tif (formattingOptions?.dateStyle) toDateString.dateStyle = formattingOptions.dateStyle\n\tif (formattingOptions?.display) toDateString.display = formattingOptions.display\n\treturn createComputedValue(ControlType.String, startValue, [toDateString])\n}\n", "import type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { siteTitlePlaceholder } from \"document/components/chrome/siteSettings/metadataPlaceholders.ts\"\nimport { wrapInTemplateVariable } from \"document/components/chrome/siteSettings/templateVariables.ts\"\nimport type { LoadedTemplate } from \"document/components/utils/createWebPage.ts\"\nimport { createWebPage } from \"document/components/utils/createWebPage.ts\"\nimport { pathToName } from \"document/components/utils/pathToName.ts\"\nimport { propKeyIsTitleLike } from \"document/components/utils/propKeyIsTitleLike.ts\"\nimport { createRepeaterEmptyState } from \"document/components/utils/repeater.ts\"\nimport { valueToPath } from \"document/components/utils/valueToPath.ts\"\nimport type { CanvasNode, WebPageNode } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode, RichTextNode } from \"document/models/CanvasTree/index.ts\"\nimport { CanvasChildList } from \"document/models/CanvasTree/nodes/ChildList.ts\"\nimport type { DataRepeater } from \"document/models/CanvasTree/nodes/FrameNode.ts\"\nimport { LinkStylePresetNode } from \"document/models/CanvasTree/nodes/LinkStylePresetNode.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { createRichTextNodeWithTag, getDefaultPresets } from \"document/models/CanvasTree/nodes/RichTextNode.utils.ts\"\nimport { getRouteSegmentRootNode } from \"document/models/CanvasTree/nodes/RouteSegmentRootNode.utils.ts\"\nimport { TextStylePresetNode } from \"document/models/CanvasTree/nodes/TextStylePresetNode.ts\"\nimport { isDataRepeater } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { createComputedValue } from \"document/models/CanvasTree/traits/ComputedValue.ts\"\nimport type { DynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport type { ValueTransform } from \"document/models/CanvasTree/traits/ValueTransform.ts\"\nimport { createVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport type { WithCollectionOptions } from \"document/models/CanvasTree/traits/WithCollectionOptions.ts\"\nimport { withLink } from \"document/models/CanvasTree/traits/WithLink.ts\"\nimport { paddingDefinedDefaults } from \"document/models/CanvasTree/traits/WithPadding.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport type {\n\tMultiCollectionReferenceVariableDefinition,\n\tVariableID,\n} from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport type { WebMetadata } from \"document/models/CanvasTree/traits/WithWebMetadata.ts\"\nimport type { LinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { createLink, isLinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { createComputedFormattedDate } from \"document/models/CanvasTree/traits/utils/createComputedFormattedDate.ts\"\nimport type { StackDirection } from \"library/components/Stack/types.ts\"\nimport { DimensionType } from \"library/render/types/Constraints.ts\"\nimport type {\n\tControlDescription,\n\tDateControlDescription,\n\tPropertyControls,\n\tStringControlDescription,\n} from \"library/render/types/PropertyControls.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { setAnchorElementLink } from \"prosemirror/schema/link.ts\"\nimport { setStylePreset } from \"prosemirror/schema/utils.ts\"\nimport { createNestedVariableReference, getNestedVariableId } from \"utils/collectionReferenceUtils.ts\"\nimport { getCollectionForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { getDefaultLinkStylePreset } from \"utils/linkStylePresetUtils.ts\"\nimport { getRepeatedItemIdUpdate, getRepeatedItemOfDataRepeater } from \"utils/repeaterUtils.ts\"\nimport { insertStylePresets } from \"utils/stylePresetUtils.ts\"\nimport { getDefaultTextStylePreset } from \"utils/textStylePresetUtils.ts\"\nimport { titleCase } from \"utils/titleCase.ts\"\nimport {\n\tcreatedAtVariableId,\n\tnextItemVariableId,\n\tpreviousItemVariableId,\n\tupdatedAtVariableId,\n} from \"./CollectionItemVariables.ts\"\nimport { uniqueName } from \"./uniqueName.ts\"\n\n// The styles to use for items we place on the canvas when inserting collections\nexport const textColor = \"#999\"\nconst textColorWithReferences = \"#888\"\nconst indexPageWidth = 600\nexport const repeaterSize = 200\nexport const galleryImageHeight = 350\n\nexport function getAllAssociatedRepeaters(\n\tengine: VekterEngine,\n\tdataIdentifier: ModuleExportIdentifierString,\n): DataRepeater[] {\n\tconst result: DataRepeater[] = []\n\tconst tree = engine.stores.treeStore.getDataTreeOrLoadedTree()\n\n\tfor (const node of tree.root.walk()) {\n\t\tif (!isDataRepeater(node) || node.dataIdentifier !== dataIdentifier) continue\n\t\tif (isReplicaOrReplicaChild(node)) continue\n\t\tresult.push(node)\n\t}\n\n\treturn result\n}\n\nexport function generateCollectionPageMetadata(\n\tengine: VekterEngine,\n\twebPage: WebPageNode,\n\tcontrolDescription: ControlDescription,\n\tvariableId: VariableID,\n) {\n\tif (!controlDescription.title) return\n\n\t// Use dynamic text variables for page title and description\n\tconst lowerCaseName = controlDescription.title.toLowerCase()\n\n\tconst webMetadata = { ...webPage.webMetadata }\n\n\tswitch (lowerCaseName) {\n\t\tcase \"title\":\n\t\tcase \"description\": {\n\t\t\tconst metadataKey: keyof WebMetadata = lowerCaseName\n\t\t\tlet metadataValue = wrapInTemplateVariable(variableId)\n\t\t\tif (lowerCaseName === \"title\") {\n\t\t\t\tmetadataValue += \" - \" + (engine.tree.root.webMetadata?.title ?? siteTitlePlaceholder)\n\t\t\t}\n\t\t\twebMetadata[metadataKey] = metadataValue\n\t\t\twebPage.set({ webMetadata })\n\t\t\tbreak\n\t\t}\n\t\tcase \"image\": {\n\t\t\tif (controlDescription.type !== ControlType.ResponsiveImage) return\n\n\t\t\twebMetadata.socialImage = createVariableReference(variableId, webPage.id)\n\t\t\twebPage.set({ webMetadata })\n\t\t\tbreak\n\t\t}\n\t}\n}\n\ninterface CreateCollectionDetailPageOptions {\n\tengine: VekterEngine\n\tidentifier: ModuleExportIdentifierString\n\tpreferredName: string\n\tpath: string\n\tslugId: string\n\tproperties: PropertyControls\n\tstartEditingPageTitle?: boolean\n\tisForSample?: boolean\n\tisWireframerKitPage?: boolean\n}\n\nexport async function createCollectionDetailPage({\n\tengine,\n\tidentifier,\n\tpreferredName,\n\tpath,\n\tslugId,\n\tproperties,\n\tstartEditingPageTitle,\n\tisForSample,\n\tisWireframerKitPage,\n}: CreateCollectionDetailPageOptions): Promise<WebPageNode> {\n\t// When the pages has been created, we will go over all repeaters with the same identifier and\n\t// create links if possible. With a data tree the full document graph is already available.\n\tif (!engine.stores.treeStore.getDataTree()) {\n\t\tawait engine.runWithFullyLoadedTreeAsync({ name: \"create_collection_page\" })\n\t}\n\n\t// It's possible for two dynamic paths to be the same since the underlying data can still make them unique.\n\tconst pathBase = valueToPath(path)\n\tconst pathEndsWithSlash = pathBase.endsWith(\"/\")\n\tlet webPage = await engine.createWebPage({\n\t\tdataIdentifier: identifier,\n\t\tstartEditingPageTitle,\n\t\tpreferredPath: `${pathBase}${pathEndsWithSlash ? \"\" : \"/\"}:${slugId}`,\n\t\tisWireframerKitPage,\n\t})\n\n\treturn engine.scheduler.processWhenReadyAsync(() => {\n\t\tconst currentWebPage = engine.tree.current(webPage)\n\t\tassert(currentWebPage, \"Web page should exist\")\n\t\twebPage = currentWebPage\n\n\t\tconst existingWebPageNames = engine.stores.scopeStore.getWebPageNodes().map(webpage => webpage.name)\n\t\tif (!existingWebPageNames.includes(preferredName)) {\n\t\t\twebPage.set({ name: preferredName })\n\t\t}\n\n\t\tconst primaryVariant = webPage.getPrimaryVariant()\n\t\tprimaryVariant.set({\n\t\t\theightType: DimensionType.Auto,\n\t\t\tlayout: \"stack\",\n\t\t\tstackDirection: \"vertical\",\n\t\t\tstackDistribution: \"start\",\n\t\t\tstackAlignment: \"center\",\n\t\t\tgap: 160,\n\t\t\t...paddingDefinedDefaults,\n\t\t\tpaddingPerSide: true,\n\t\t\tpaddingTop: 140,\n\t\t\tpaddingRight: 20,\n\t\t\tpaddingBottom: 140,\n\t\t\tpaddingLeft: 20,\n\t\t})\n\n\t\tconst contentStack = new FrameNode({\n\t\t\twidth: 700,\n\t\t\twidthType: DimensionType.FixedNumber,\n\t\t\tmaxWidth: \"100%\",\n\t\t\theight: 1080,\n\t\t\theightType: DimensionType.Auto,\n\t\t\tlayout: \"stack\",\n\t\t\tstackDirection: \"vertical\",\n\t\t\tstackDistribution: \"start\",\n\t\t\tstackAlignment: \"center\",\n\t\t\tgap: 60,\n\t\t\tfillEnabled: false,\n\t\t})\n\t\tengine.stores.scopeStore.insertNode(contentStack, primaryVariant.id)\n\n\t\tconst headerStack = new FrameNode({\n\t\t\tfillEnabled: false,\n\t\t\twidth: 600,\n\t\t\twidthType: DimensionType.FixedNumber,\n\t\t\tmaxWidth: \"100%\",\n\t\t\theight: 1080,\n\t\t\theightType: DimensionType.Auto,\n\t\t\tlayout: \"stack\",\n\t\t\tstackDirection: \"vertical\",\n\t\t\tstackDistribution: \"start\",\n\t\t\tstackAlignment: \"center\",\n\t\t\tgap: 15,\n\t\t})\n\t\tengine.stores.scopeStore.insertNode(headerStack, contentStack.id)\n\n\t\tconst multiReferenceNodes: CanvasNode[] = []\n\t\tconst singleLineTextNodes: RichTextNode[] = []\n\t\tconst otherNodes: CanvasNode[] = []\n\n\t\tlet titleId: VariableID | undefined\n\t\tlet hasPreviousItemVariable = false\n\t\tlet hasNextItemVariable = false\n\n\t\tObject.entries(properties).forEach(([key, description]) => {\n\t\t\tif (key === slugId) return\n\t\t\tif (key === createdAtVariableId) return\n\t\t\tif (key === updatedAtVariableId) return\n\n\t\t\tswitch (description?.type) {\n\t\t\t\tcase ControlType.String:\n\t\t\t\tcase ControlType.Date: {\n\t\t\t\t\tif (description.type === ControlType.String) {\n\t\t\t\t\t\ttitleId ??= key\n\t\t\t\t\t}\n\n\t\t\t\t\tconst name = description.title ?? key\n\n\t\t\t\t\tgenerateCollectionPageMetadata(engine, webPage, description, key)\n\n\t\t\t\t\tconst isTitle = propKeyIsTitleLike(name)\n\t\t\t\t\tconst isMultiLine = description.type === ControlType.String && Boolean(description.displayTextArea)\n\n\t\t\t\t\tlet textContent: DynamicValue | undefined\n\n\t\t\t\t\tswitch (description.type) {\n\t\t\t\t\t\tcase ControlType.String:\n\t\t\t\t\t\t\ttextContent = createVariableReference(key, webPage.id)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase ControlType.Date:\n\t\t\t\t\t\t\ttextContent = createComputedFormattedDate(createVariableReference(key, webPage.id))\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tconst text = createRichTextNodeWithTag({\n\t\t\t\t\t\ttree: engine.tree,\n\t\t\t\t\t\ttag: isTitle ? \"h1\" : \"p\",\n\t\t\t\t\t\ttext: name,\n\t\t\t\t\t\tattributes: {\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\ttextContent,\n\t\t\t\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\t\theightType: DimensionType.Auto,\n\t\t\t\t\t\t\tmaxWidth: 600,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\n\t\t\t\t\tif (isMultiLine) {\n\t\t\t\t\t\totherNodes.push(text)\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttext.setTextAlignment(\"center\", false)\n\t\t\t\t\t\tif (!isTitle) {\n\t\t\t\t\t\t\ttext.setTextColor(textColor, false)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsingleLineTextNodes.push(text)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.CollectionReference: {\n\t\t\t\t\tif (key === previousItemVariableId) {\n\t\t\t\t\t\thasPreviousItemVariable = true\n\t\t\t\t\t}\n\n\t\t\t\t\tif (key === nextItemVariableId) {\n\t\t\t\t\t\thasNextItemVariable = true\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.MultiCollectionReference: {\n\t\t\t\t\tif (isForSample) {\n\t\t\t\t\t\tconst multiRefCollectionList = createMultiRefCollectionListForSample({\n\t\t\t\t\t\t\tengine,\n\t\t\t\t\t\t\tidentifier: identifier,\n\t\t\t\t\t\t\tproviderId: webPage.id,\n\t\t\t\t\t\t\tisForSample,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tif (multiRefCollectionList) {\n\t\t\t\t\t\t\tmultiReferenceNodes.push(multiRefCollectionList)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.RichText: {\n\t\t\t\t\tconst name = description.title ?? key\n\t\t\t\t\tconst richText = new RichTextNode({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\thtml: name,\n\t\t\t\t\t\thtmlContent: createVariableReference(key, webPage.id),\n\t\t\t\t\t\tparagraphSpacing: 32,\n\t\t\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\theightType: DimensionType.Auto,\n\t\t\t\t\t\tmaxWidth: 600,\n\t\t\t\t\t\t...getDefaultPresets(engine.tree),\n\t\t\t\t\t})\n\t\t\t\t\totherNodes.push(richText)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.Image:\n\t\t\t\tcase ControlType.ResponsiveImage: {\n\t\t\t\t\tconst image = new FrameNode({\n\t\t\t\t\t\tname: \"Banner\",\n\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\t\t\theight: 400,\n\t\t\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t\t\t\tfillEnabled: true,\n\t\t\t\t\t\tfillType: \"image\",\n\t\t\t\t\t\tfillImage: createVariableReference(key, webPage.id),\n\t\t\t\t\t\tradius: 24,\n\t\t\t\t\t})\n\t\t\t\t\totherNodes.push(image)\n\n\t\t\t\t\tgenerateCollectionPageMetadata(engine, webPage, description, key)\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\n\t\tmultiReferenceNodes.forEach(multiReferenceNode =>\n\t\t\tengine.stores.scopeStore.insertNode(multiReferenceNode, headerStack.id),\n\t\t)\n\n\t\tsingleLineTextNodes.forEach(singleLineTextNode =>\n\t\t\tengine.stores.scopeStore.insertNode(singleLineTextNode, headerStack.id),\n\t\t)\n\n\t\totherNodes.forEach(node => {\n\t\t\tengine.stores.scopeStore.insertNode(node, contentStack.id)\n\t\t})\n\n\t\tif (hasPreviousItemVariable && hasNextItemVariable) {\n\t\t\tconst paragraphStylePreset = getDefaultTextStylePreset(engine.tree, \"p\") ?? TextStylePresetNode.createDefault(\"p\")\n\n\t\t\tconst linkStylePreset = getDefaultLinkStylePreset(engine.tree) ?? LinkStylePresetNode.createDefault()\n\n\t\t\tinsertStylePresets(engine, [paragraphStylePreset, linkStylePreset])\n\n\t\t\tconst navigationLinksNode = createCollectionItemNavigationLinks({\n\t\t\t\tscopeId: webPage.id,\n\t\t\t\tslugVariableId: slugId,\n\t\t\t\ttitleVariableId: titleId,\n\t\t\t\tparagraphStylePreset,\n\t\t\t\tlinkStylePreset,\n\t\t\t})\n\n\t\t\tengine.stores.scopeStore.insertNode(navigationLinksNode, contentStack.id)\n\t\t}\n\n\t\tconst treeForRepeaters = engine.stores.treeStore.getDataTreeOrLoadedTree()\n\t\tgetAllAssociatedRepeaters(engine, identifier).forEach(associatedDataRepeater => {\n\t\t\tconst repeatedChild = getRepeatedItemOfDataRepeater(treeForRepeaters, associatedDataRepeater)\n\t\t\tif (!repeatedChild) return\n\t\t\tif (!withLink(repeatedChild)) return\n\t\t\tif (isReplicaOrReplicaChild(repeatedChild)) return\n\t\t\tconst link = repeatedChild.getLink()\n\n\t\t\t// Keep links that are not Framer page links intact (e.g.\n\t\t\t// www.example.com)\n\t\t\tif (!isLinkToWebPage(link)) return\n\t\t\tconst hasTargetNode = treeForRepeaters.has(link.webPageId)\n\t\t\t// Keep links that target known nodes intact\n\t\t\tif (hasTargetNode) return\n\n\t\t\tconst slugVariableBinding = createVariableReference(slugId, associatedDataRepeater.id)\n\t\t\trepeatedChild.set({\n\t\t\t\tlink: createLink({\n\t\t\t\t\twebPageId: webPage.id,\n\t\t\t\t\tpathVariables: { [slugId]: slugVariableBinding },\n\t\t\t\t}),\n\t\t\t})\n\t\t})\n\n\t\tengine.stores.selectionStore.clear()\n\n\t\treturn webPage.draftOrCurrent()\n\t})\n}\n\ninterface CreateCollectionListOptions {\n\tengine: VekterEngine\n\tidentifier: ModuleExportIdentifierString\n\tslugId: string | undefined\n\tproperties: PropertyControls\n\tdetailPageId: NodeID | undefined\n\tstackDirection?: StackDirection\n\tisForSample?: boolean\n}\n\nfunction createIndexPageCollectionListWithReferences({\n\tengine,\n\tidentifier,\n\tslugId,\n\tproperties,\n\tdetailPageId,\n\tisForSample,\n}: CreateCollectionListOptions): FrameNode {\n\tconst providerId = randomID()\n\tconst imageVariableId = getImageVariableIdFromPropertyControls(properties)\n\n\tconst textNodes = Object.entries(properties)\n\t\t.filter((value): value is [string, StringControlDescription | DateControlDescription] => {\n\t\t\tconst [key, description] = value\n\t\t\tif (key === slugId) return false\n\t\t\tif (key === createdAtVariableId) return false\n\t\t\tif (key === updatedAtVariableId) return false\n\t\t\tif (!description) return false\n\n\t\t\tswitch (description.type) {\n\t\t\t\tcase ControlType.String:\n\t\t\t\tcase ControlType.Date:\n\t\t\t\t\treturn true\n\t\t\t\tdefault:\n\t\t\t\t\treturn false\n\t\t\t}\n\t\t})\n\t\t.map(([key, description]) => {\n\t\t\tconst name: string = description.title ?? key\n\t\t\tconst isTitle = propKeyIsTitleLike(name)\n\n\t\t\tlet textContent: DynamicValue | undefined\n\n\t\t\tswitch (description.type) {\n\t\t\t\tcase ControlType.String:\n\t\t\t\t\ttextContent = createVariableReference(key, providerId)\n\t\t\t\t\tbreak\n\t\t\t\tcase ControlType.Date:\n\t\t\t\t\ttextContent = createComputedFormattedDate(createVariableReference(key, providerId))\n\t\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tconst text = createRichTextNodeWithTag({\n\t\t\t\ttree: engine.tree,\n\t\t\t\ttag: isTitle ? \"h6\" : \"p\",\n\t\t\t\ttext: name,\n\t\t\t\tattributes: {\n\t\t\t\t\tname,\n\t\t\t\t\ttextContent,\n\t\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theightType: DimensionType.Auto,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\t/* Default color for Date, Paragraphs, etc */\n\t\t\tif (!isTitle) {\n\t\t\t\ttext.setTextColor(textColorWithReferences, false)\n\t\t\t}\n\n\t\t\treturn text\n\t\t})\n\n\tconst multiRefCollectionList = createMultiRefCollectionListForSample({\n\t\tengine,\n\t\tidentifier,\n\t\tproviderId,\n\t\tisForSample,\n\t})\n\n\tconst link =\n\t\tslugId && detailPageId\n\t\t\t? createLink({\n\t\t\t\t\twebPageId: detailPageId,\n\t\t\t\t\tpathVariables: { [slugId]: createVariableReference(slugId, providerId) },\n\t\t\t\t})\n\t\t\t: undefined\n\n\tconst text = new FrameNode({\n\t\tname: Dictionary.Text,\n\t\tfillEnabled: false,\n\t\twidth: 1,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\theightType: DimensionType.Auto,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"vertical\",\n\t\tstackAlignment: \"start\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 0,\n\t\tchildren: new CanvasChildList(textNodes),\n\t})\n\n\tif (imageVariableId) {\n\t\tconst row = new FrameNode({\n\t\t\tlink,\n\t\t\twidth: 1,\n\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\theightType: DimensionType.Auto,\n\t\t\tfillEnabled: false,\n\t\t\tlayout: \"stack\",\n\t\t\tstackDirection: \"horizontal\",\n\t\t\tstackAlignment: \"center\",\n\t\t\tstackDistribution: \"start\",\n\t\t\tstackWrapEnabled: true,\n\t\t\tgap: 30,\n\t\t\t...paddingDefinedDefaults,\n\t\t\tchildren: new CanvasChildList([\n\t\t\t\tnew FrameNode({\n\t\t\t\t\twidth: 180,\n\t\t\t\t\twidthType: DimensionType.FixedNumber,\n\t\t\t\t\theight: 100,\n\t\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t\t\tradius: 20,\n\t\t\t\t\tcornerShape: 1.4,\n\t\t\t\t\tborderEnabled: true,\n\t\t\t\t\tborderWidth: 1,\n\t\t\t\t\tborderColor: \"#0000000F\",\n\t\t\t\t\tfillEnabled: true,\n\t\t\t\t\tfillType: \"image\",\n\t\t\t\t\tfillImage: createVariableReference(imageVariableId, providerId),\n\t\t\t\t}),\n\t\t\t\ttext,\n\t\t\t\t...(multiRefCollectionList ? [multiRefCollectionList] : []),\n\t\t\t]),\n\t\t})\n\t\tconst repeater = new FrameNode({\n\t\t\tdataIdentifier: identifier,\n\t\t\tid: providerId,\n\t\t\twidth: 1,\n\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\theightType: DimensionType.Auto,\n\t\t\tfillEnabled: false,\n\t\t\tlayout: \"stack\",\n\t\t\tstackDirection: \"vertical\",\n\t\t\tstackAlignment: \"center\",\n\t\t\tstackDistribution: \"start\",\n\t\t\tgap: 20,\n\t\t\t...paddingDefinedDefaults,\n\t\t\tchildren: new CanvasChildList([row]),\n\t\t\t...getRepeatedItemIdUpdate(row.id),\n\t\t})\n\t\trepeater.addChild(createRepeaterEmptyState(repeater))\n\t\treturn repeater\n\t}\n\n\tconst wrapper = new FrameNode({\n\t\tname: \"Wrapper\",\n\t\t// In case of an image a wrapper will contain the link\n\t\tlink: imageVariableId ? undefined : link,\n\t\twidth: 1,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\theightType: DimensionType.Auto,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"center\",\n\t\tgap: 10,\n\t\t...paddingDefinedDefaults,\n\t\tfillEnabled: false,\n\t\tchildren: new CanvasChildList([text, ...(multiRefCollectionList ? [multiRefCollectionList] : [])]),\n\t})\n\n\tconst repeater = new FrameNode({\n\t\tdataIdentifier: identifier,\n\t\tid: providerId,\n\t\twidth: 1,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"vertical\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 20,\n\t\t...paddingDefinedDefaults,\n\t\tchildren: new CanvasChildList([multiRefCollectionList ? wrapper : text]),\n\t\t...getRepeatedItemIdUpdate(multiRefCollectionList ? wrapper.id : text.id),\n\t})\n\trepeater.addChild(createRepeaterEmptyState(repeater))\n\treturn repeater\n}\n\ninterface CreateMultiRefCollectionListForSampleOptions {\n\tengine: VekterEngine\n\tidentifier: ModuleExportIdentifierString\n\tproviderId: string\n\tisForSample?: boolean\n}\n\nfunction createMultiRefCollectionListForSample({\n\tengine,\n\tidentifier,\n\tproviderId,\n\tisForSample,\n}: CreateMultiRefCollectionListForSampleOptions): FrameNode | null {\n\tif (!isForSample) return null\n\n\tconst collection = getCollectionForIdentifier(engine.tree, identifier)\n\tif (!collection) return null\n\n\tconst multiReference = collection.variables.find(\n\t\t(variable): variable is MultiCollectionReferenceVariableDefinition => {\n\t\t\treturn variable.type === ControlType.MultiCollectionReference\n\t\t},\n\t)\n\tif (!multiReference) return null\n\n\tconst referencedCollection = getCollectionForIdentifier(engine.tree, multiReference.dataIdentifier)\n\tif (!referencedCollection) return null\n\n\tconst referencedSlugVariable = referencedCollection.getSlugVariable()\n\tif (!referencedSlugVariable) return null\n\n\tconst multiReferenceProviderId = randomID()\n\tconst properties = referencedCollection.getPropertyControls(engine.tree, engine.componentLoader)\n\n\tconst titleProperties = Object.entries(properties)\n\t\t.filter((value): value is [string, StringControlDescription] => {\n\t\t\tconst [key, description] = value\n\t\t\tif (key === referencedSlugVariable.id) return false\n\t\t\tif (description?.type !== ControlType.String) return false\n\t\t\tconst name: string = description.title ?? key\n\t\t\treturn propKeyIsTitleLike(name)\n\t\t})\n\t\t.map(([key, description]) => {\n\t\t\tconst name: string = description.title ?? key\n\t\t\tconst textContent = createVariableReference(key, multiReferenceProviderId)\n\n\t\t\tconst text = createRichTextNodeWithTag({\n\t\t\t\ttree: engine.tree,\n\t\t\t\ttag: \"p\",\n\t\t\t\ttext: name,\n\t\t\t\tattributes: {\n\t\t\t\t\tname,\n\t\t\t\t\ttextContent,\n\t\t\t\t\twidthType: DimensionType.Auto,\n\t\t\t\t\theightType: DimensionType.Auto,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\ttext.setTextColor(textColorWithReferences, false)\n\n\t\t\treturn text\n\t\t})\n\tconst [title] = titleProperties\n\tif (!title) return null\n\n\tconst item = new FrameNode({\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"start\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 10,\n\t\t...paddingDefinedDefaults,\n\t\tpaddingPerSide: true,\n\t\tpaddingTop: 0,\n\t\tpaddingRight: 8,\n\t\tpaddingBottom: 0,\n\t\tpaddingLeft: 8,\n\t\tfillEnabled: true,\n\t\tfillColor: \"#00000008\",\n\t\tradius: 8,\n\t\tchildren: new CanvasChildList([title]),\n\t})\n\n\treturn new FrameNode({\n\t\tdataIdentifier: multiReference.dataIdentifier,\n\t\tid: multiReferenceProviderId,\n\t\tfillEnabled: false,\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"center\",\n\t\tgap: 10,\n\t\t...getRepeatedItemIdUpdate(item.id),\n\t\tcollectionFilters: {\n\t\t\tfilters: [\n\t\t\t\t{\n\t\t\t\t\tid: randomID(),\n\t\t\t\t\titemKey: \"id\",\n\t\t\t\t\ttransforms: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: randomID(),\n\t\t\t\t\t\t\ttype: \"valueTransform\",\n\t\t\t\t\t\t\tname: \"isIncludedIn\",\n\t\t\t\t\t\t\tvalue: createVariableReference(multiReference.id, providerId),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tchildren: new CanvasChildList([item]),\n\t})\n}\n\nfunction createTextNodeFromControlDescription(\n\tengine: VekterEngine,\n\tproviderId: string,\n\tkey: string,\n\tdescription: StringControlDescription,\n) {\n\tconst name: string = description.title ?? key\n\tconst textContent = createVariableReference(key, providerId)\n\n\tconst text = createRichTextNodeWithTag({\n\t\ttree: engine.tree,\n\t\ttag: \"p\",\n\t\ttext: name,\n\t\tattributes: {\n\t\t\tname,\n\t\t\ttextContent,\n\t\t\twidthType: DimensionType.Auto,\n\t\t\theightType: DimensionType.Auto,\n\t\t},\n\t})\n\n\treturn text\n}\n\nfunction getTextNodeFromProperties(\n\tengine: VekterEngine,\n\tproviderId: string,\n\tparentVariableId: string | undefined,\n\tslugId: string | undefined,\n\tproperties: PropertyControls,\n) {\n\tfor (const [key, control] of Object.entries(properties)) {\n\t\tif (key === slugId) continue\n\t\tif (control?.type !== ControlType.String) continue\n\n\t\treturn createTextNodeFromControlDescription(engine, providerId, getNestedVariableId(parentVariableId, key), control)\n\t}\n\n\tfor (const [key, control] of Object.entries(properties)) {\n\t\tif (key !== slugId) continue\n\t\tif (control?.type !== ControlType.String) continue\n\t\treturn createTextNodeFromControlDescription(engine, providerId, getNestedVariableId(parentVariableId, key), control)\n\t}\n\n\tthrow new Error(\"Slug entry must exist\")\n}\n\nfunction createCollectionItemLink(\n\tproviderId: NodeID,\n\tslugId: VariableID | undefined,\n\tparentVariableId: VariableID | undefined,\n\tdetailPageId: NodeID | undefined,\n) {\n\tif (!slugId || !detailPageId) return\n\n\tconst linkVariable = createNestedVariableReference(parentVariableId, slugId, providerId)\n\treturn createLink({\n\t\twebPageId: detailPageId,\n\t\tpathVariables: {\n\t\t\t[slugId]: linkVariable,\n\t\t},\n\t})\n}\n\ninterface CreateCollectionItemOptions {\n\tengine: VekterEngine\n\tproviderId: NodeID\n\tslugId: VariableID | undefined\n\tparentVariableId?: VariableID\n\tframeName?: string\n\tproperties: PropertyControls\n\tdetailPageId: NodeID | undefined\n}\n\nexport function createCollectionItem({\n\tengine,\n\tproviderId,\n\tslugId,\n\tparentVariableId,\n\tproperties,\n\tdetailPageId,\n}: CreateCollectionItemOptions): FrameNode {\n\tconst imageVariableId = getImageVariableIdFromPropertyControls(properties)\n\n\tconst children = new CanvasChildList<CanvasNode>()\n\n\tif (imageVariableId) {\n\t\tconst imageNode = new FrameNode({\n\t\t\twidth: 30,\n\t\t\theight: 30,\n\t\t\tradius: 8,\n\t\t\tfillEnabled: true,\n\t\t\tfillType: \"image\",\n\t\t\tfillImage: createNestedVariableReference(parentVariableId, imageVariableId, providerId),\n\t\t})\n\t\tchildren.push(imageNode)\n\t}\n\n\tconst textNode = getTextNodeFromProperties(engine, providerId, parentVariableId, slugId, properties)\n\tchildren.push(textNode)\n\n\tconst link = createCollectionItemLink(providerId, slugId, parentVariableId, detailPageId)\n\n\treturn new FrameNode({\n\t\tlink,\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 10,\n\t\t...paddingDefinedDefaults,\n\t\tchildren: new CanvasChildList(children),\n\t})\n}\n\nexport function createCollectionList({\n\tengine,\n\tidentifier,\n\tslugId,\n\tproperties,\n\tdetailPageId,\n\tstackDirection,\n}: CreateCollectionListOptions): FrameNode {\n\tconst providerId = randomID()\n\n\tconst itemNode = createCollectionItem({ engine, providerId, slugId, properties, detailPageId })\n\n\treturn new FrameNode({\n\t\tdataIdentifier: identifier,\n\t\tid: providerId,\n\t\twidth: repeaterSize,\n\t\twidthType: DimensionType.Auto,\n\t\theight: repeaterSize,\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: stackDirection ?? \"vertical\",\n\t\tstackAlignment: \"start\",\n\t\tstackDistribution: \"center\",\n\t\tgap: 20,\n\t\t...paddingDefinedDefaults,\n\t\tchildren: new CanvasChildList([itemNode]),\n\t\t...getRepeatedItemIdUpdate(itemNode.id),\n\t})\n}\n\nfunction getImageVariableIdFromPropertyControls(properties: PropertyControls): VariableID | undefined {\n\tfor (const key in properties) {\n\t\tconst control = properties[key]\n\t\tif (!control) continue\n\n\t\tif (control.type === ControlType.Image || control.type === ControlType.ResponsiveImage) {\n\t\t\treturn key\n\t\t}\n\t}\n}\n\nfunction createImageNode(imageVariableId: VariableID, providerId: NodeID, properties?: Partial<FrameNode>): FrameNode {\n\treturn new FrameNode({\n\t\tname: Dictionary.Image,\n\t\twidth: 30,\n\t\theight: 30,\n\t\tradius: 8,\n\t\tfillEnabled: true,\n\t\tfillType: \"image\",\n\t\tfillImage: createVariableReference(imageVariableId, providerId),\n\t\t...properties,\n\t})\n}\n\nfunction createRepeaterNode({\n\tid,\n\tdataRepeaterArray,\n\tproperties,\n}: {\n\tid?: NodeID\n\tdataRepeaterArray?: ReturnType<typeof createVariableReference>\n\tproperties: Required<Pick<FrameNode, \"children\">> & Partial<FrameNode & WithCollectionOptions>\n}): FrameNode {\n\treturn new FrameNode({\n\t\tid: id ?? randomID(),\n\t\tdataRepeaterArray,\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"center\",\n\t\tgap: 10,\n\t\t...paddingDefinedDefaults,\n\t\t...properties,\n\t})\n}\n\nfunction createRepeaterItemNode(properties: Required<Pick<FrameNode, \"children\">> & Partial<FrameNode>) {\n\treturn new FrameNode({\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"start\",\n\t\t...paddingDefinedDefaults,\n\t\t...properties,\n\t})\n}\n\ninterface CreateArrayListOptions {\n\tproviderId: NodeID\n\tvariableId: NodeID\n\tproperties: PropertyControls\n\titemHeight: number\n}\n\nexport function createArrayGrid({ providerId, variableId, properties, itemHeight }: CreateArrayListOptions) {\n\tconst gridProperties = {\n\t\twidth: 1,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\tlayout: \"grid\",\n\t\tgridAlignment: \"start\",\n\t\tgridColumnWidthType: \"minmax\",\n\t\tgridColumnCount: 2,\n\t\tgridColumnWidth: 200,\n\t\tgridColumnMinWidth: 0,\n\t\tgridRowHeightType: \"fit\",\n\t\tgridRowHeight: 200,\n\t} satisfies Partial<FrameNode>\n\n\tif (experiments.isOn(\"nodeLevelRepeat\")) {\n\t\tconst repeatNodeId = randomID()\n\t\tconst repeatedNode = createArrayGridItem({\n\t\t\tproviderId: repeatNodeId,\n\t\t\tproperties,\n\t\t\titemHeight,\n\t\t\tid: repeatNodeId,\n\t\t})\n\t\trepeatedNode.set({ repeatArray: createVariableReference(variableId, providerId) })\n\n\t\treturn createRepeaterNode({\n\t\t\tproperties: {\n\t\t\t\t...gridProperties,\n\t\t\t\tchildren: new CanvasChildList([repeatedNode]),\n\t\t\t},\n\t\t})\n\t}\n\n\tconst arrayRepeaterId = randomID()\n\tconst itemNode = createArrayGridItem({\n\t\tproviderId: arrayRepeaterId,\n\t\tproperties,\n\t\titemHeight,\n\t})\n\n\treturn createRepeaterNode({\n\t\tid: arrayRepeaterId,\n\t\tdataRepeaterArray: createVariableReference(variableId, providerId),\n\t\tproperties: {\n\t\t\t...gridProperties,\n\t\t\tchildren: new CanvasChildList([itemNode]),\n\t\t},\n\t})\n}\n\ninterface CreateArrayItemOptions {\n\tproviderId: NodeID\n\tid?: NodeID\n\tframeName?: string\n\tproperties: PropertyControls\n\titemHeight: number\n}\n\nfunction createArrayGridItem({ providerId, properties, itemHeight, id }: CreateArrayItemOptions): FrameNode {\n\tconst imageVariableId = getImageVariableIdFromPropertyControls(properties)\n\n\tconst children = new CanvasChildList<CanvasNode>()\n\n\tif (imageVariableId) {\n\t\t// If there is only one image property, we assume this is an array gallery and don't wrap\n\t\t// the image in a repeated item for a better UX.\n\t\tconst isArrayGallery = Object.values(properties).length === 1\n\t\tif (isArrayGallery) {\n\t\t\treturn createImageNode(imageVariableId, providerId, {\n\t\t\t\tid: id ?? randomID(),\n\t\t\t\twidth: 1,\n\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\theight: itemHeight,\n\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t\tgridItemFillCellWidth: true,\n\t\t\t\tgridItemFillCellHeight: true,\n\t\t\t\tradius: 24,\n\t\t\t\taspectRatio: 1,\n\t\t\t})\n\t\t}\n\n\t\tconst imageNode = createImageNode(imageVariableId, providerId, {\n\t\t\twidth: 1,\n\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\theight: itemHeight,\n\t\t\theightType: DimensionType.FixedNumber,\n\t\t\tgridItemFillCellWidth: true,\n\t\t\tgridItemFillCellHeight: true,\n\t\t\tradius: 24,\n\t\t\taspectRatio: 1,\n\t\t})\n\n\t\tchildren.push(imageNode)\n\t}\n\n\treturn createRepeaterItemNode({\n\t\tid: id ?? randomID(),\n\t\twidth: 1,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\tgridItemFillCellHeight: true,\n\t\tgridItemFillCellWidth: true,\n\t\tchildren,\n\t})\n}\n\nexport function createArrayStack({ providerId, variableId, properties }: Omit<CreateArrayListOptions, \"itemHeight\">) {\n\tif (experiments.isOn(\"nodeLevelRepeat\")) {\n\t\tconst repeatNodeId = randomID()\n\t\tconst repeatedNode = createArrayStackItem({\n\t\t\tproviderId: repeatNodeId,\n\t\t\tproperties,\n\t\t\tid: repeatNodeId,\n\t\t})\n\t\trepeatedNode.set({ repeatArray: createVariableReference(variableId, providerId) })\n\n\t\treturn createRepeaterNode({\n\t\t\tproperties: { children: new CanvasChildList([repeatedNode]) },\n\t\t})\n\t}\n\n\tconst arrayRepeaterId = randomID()\n\tconst itemNode = createArrayStackItem({ providerId: arrayRepeaterId, properties })\n\n\treturn createRepeaterNode({\n\t\tid: arrayRepeaterId,\n\t\tdataRepeaterArray: createVariableReference(variableId, providerId),\n\t\tproperties: { children: new CanvasChildList([itemNode]) },\n\t})\n}\n\nfunction createArrayStackItem({ providerId, properties, id }: Omit<CreateArrayItemOptions, \"itemHeight\">): FrameNode {\n\tconst imageVariableId = getImageVariableIdFromPropertyControls(properties)\n\n\tconst children = new CanvasChildList<CanvasNode>()\n\n\tif (imageVariableId) {\n\t\t// If there is only one image property, we assume this is an array gallery and don't wrap\n\t\t// the image in a repeated item for a better UX.\n\t\tconst isArrayGallery = Object.values(properties).length === 1\n\t\tif (isArrayGallery) {\n\t\t\treturn createImageNode(imageVariableId, providerId, {\n\t\t\t\tid: id ?? randomID(),\n\t\t\t})\n\t\t}\n\n\t\tconst imageNode = createImageNode(imageVariableId, providerId)\n\t\tchildren.push(imageNode)\n\t}\n\n\treturn createRepeaterItemNode({\n\t\tid: id ?? randomID(),\n\t\tchildren,\n\t})\n}\n\ninterface CreateCollectionIndexPageOptions {\n\tengine: VekterEngine\n\tidentifier: ModuleExportIdentifierString\n\tpreferredName: string\n\tpath: string\n\tproperties: PropertyControls\n\tslugId: string | undefined\n\tdetailPageId?: NodeID\n\tisForSample?: boolean\n\tloadedTemplate: LoadedTemplate\n\tisWireframerKitPage?: boolean\n}\n\nexport function createCollectionIndexPage({\n\tengine,\n\tidentifier,\n\tpreferredName,\n\tproperties,\n\tpath,\n\tslugId,\n\tdetailPageId,\n\tisForSample,\n\tloadedTemplate,\n\tisWireframerKitPage,\n}: CreateCollectionIndexPageOptions): WebPageNode {\n\tconst webPages = engine.stores.scopeStore.getWebPageNodes()\n\t// We use `generateWebPagePathByWebPageId` instead of `getAllExistingFolderAndPagePaths` because we want\n\t// to reuse folder paths. We only need to check for existing web pages, not folders.\n\n\tconst routeSegmentRoot = getRouteSegmentRootNode(engine.tree)\n\tconst existingWebPagePaths = routeSegmentRoot.getAllRawWebPagePaths(engine.tree)\n\tconst pagePath = uniqueName(path, existingWebPagePaths, { withDash: true })\n\n\tconst name = pathToName(pagePath)\n\tconst webPage = createWebPage({ engine, name, pagePath, loadedTemplate, isWireframerKitPage })\n\n\tconst pageId: NodeID | undefined = detailPageId ?? webPages.find(page => page.dataIdentifier === identifier)?.id\n\tconst list = createIndexPageCollectionListWithReferences({\n\t\tengine,\n\t\tidentifier,\n\t\tslugId,\n\t\tproperties,\n\t\tdetailPageId: pageId,\n\t\tisForSample,\n\t})\n\n\tconst title = createRichTextNodeWithTag({\n\t\ttree: engine.tree,\n\t\ttag: \"h1\",\n\t\ttext: titleCase(preferredName),\n\t\tattributes: {\n\t\t\twidthType: DimensionType.Auto,\n\t\t\theightType: DimensionType.Auto,\n\t\t},\n\t})\n\n\tconst content = new FrameNode({\n\t\tname: Dictionary.Content,\n\t\twidth: indexPageWidth,\n\t\twidthType: DimensionType.FixedNumber,\n\t\tmaxWidth: \"100%\",\n\t\theightType: DimensionType.Auto,\n\t\tfillEnabled: false,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"vertical\",\n\t\tstackAlignment: \"start\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 40,\n\t\t...paddingDefinedDefaults,\n\t\tchildren: new CanvasChildList([title, list]),\n\t})\n\n\tconst primaryVariant = webPage.getPrimaryVariant()\n\tconst primaryVariantId = primaryVariant.id\n\n\tengine.stores.scopeStore.insertNode(content, primaryVariantId)\n\n\tengine.tree.current(primaryVariant)?.set({\n\t\theightType: DimensionType.Auto,\n\t\tlayout: \"stack\",\n\t\tstackDirection: \"vertical\",\n\t\tstackAlignment: \"center\",\n\t\tstackDistribution: \"start\",\n\t\tgap: 40,\n\t\t...paddingDefinedDefaults,\n\t\tpaddingPerSide: true,\n\t\tpaddingTop: 160,\n\t\tpaddingRight: 20,\n\t\tpaddingBottom: 160,\n\t\tpaddingLeft: 20,\n\t})\n\n\tengine.stores.selectionStore.clear()\n\n\treturn webPage.draftOrCurrent()\n}\n\ninterface CollectionItemNavigationLinksOptions {\n\tscopeId: NodeID\n\tslugVariableId: VariableID\n\ttitleVariableId: VariableID | undefined\n\tparagraphStylePreset: TextStylePresetNode\n\tlinkStylePreset: LinkStylePresetNode\n}\n\nexport function createCollectionItemNavigationLinks({\n\tscopeId,\n\tslugVariableId,\n\ttitleVariableId = slugVariableId,\n\tparagraphStylePreset,\n\tlinkStylePreset,\n}: CollectionItemNavigationLinksOptions) {\n\tconst stack = new FrameNode({\n\t\t...paddingDefinedDefaults,\n\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\theightType: DimensionType.Auto,\n\t\twidth: 1,\n\t\tmaxWidth: \"600px\",\n\t\tgap: 10,\n\t\tlayout: \"stack\",\n\t\tstackAlignment: \"center\",\n\t\tstackDirection: \"horizontal\",\n\t\tstackDistribution: \"center\",\n\t\tstackWrapEnabled: false,\n\t\tfillEnabled: false,\n\t})\n\n\tstack.addChild(\n\t\tgetCollectionItemNavigationLink({\n\t\t\tname: Dictionary.Previous,\n\t\t\tscopeId,\n\t\t\tslugVariableId,\n\t\t\ttitleVariableId,\n\t\t\tpaginationVariableId: previousItemVariableId,\n\t\t\tparagraphStylePreset,\n\t\t\tlinkStylePreset,\n\t\t\ttextContentTransform: {\n\t\t\t\ttype: \"valueTransform\",\n\t\t\t\tid: randomID(),\n\t\t\t\tname: \"prefix\",\n\t\t\t\tvalue: \"\u2039 \",\n\t\t\t},\n\t\t}),\n\t)\n\n\tstack.addChild(\n\t\tnew FrameNode({\n\t\t\tname: \"Spacer\",\n\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\twidth: 1,\n\t\t\theightType: DimensionType.FractionOfFreeSpace,\n\t\t\theight: 1,\n\t\t\tfillEnabled: false,\n\t\t}),\n\t)\n\n\tstack.addChild(\n\t\tgetCollectionItemNavigationLink({\n\t\t\tname: Dictionary.Next,\n\t\t\tscopeId,\n\t\t\tslugVariableId,\n\t\t\ttitleVariableId,\n\t\t\tpaginationVariableId: nextItemVariableId,\n\t\t\tparagraphStylePreset,\n\t\t\tlinkStylePreset,\n\t\t\ttextContentTransform: {\n\t\t\t\ttype: \"valueTransform\",\n\t\t\t\tid: randomID(),\n\t\t\t\tname: \"suffix\",\n\t\t\t\tvalue: \" \u203A\",\n\t\t\t},\n\t\t}),\n\t)\n\n\treturn stack\n}\n\ninterface CollectionItemNavigationLinkOptions {\n\tname: string\n\tscopeId: NodeID\n\tslugVariableId: VariableID\n\ttitleVariableId: VariableID\n\tpaginationVariableId: VariableID\n\tparagraphStylePreset: TextStylePresetNode\n\tlinkStylePreset: LinkStylePresetNode\n\ttextContentTransform: ValueTransform\n}\n\nfunction getCollectionItemNavigationLink({\n\tname,\n\tscopeId,\n\tslugVariableId,\n\ttitleVariableId,\n\tpaginationVariableId,\n\tparagraphStylePreset,\n\tlinkStylePreset,\n\ttextContentTransform,\n}: CollectionItemNavigationLinkOptions) {\n\tconst paragraphElement = document.createElement(\"p\")\n\tsetStylePreset(paragraphElement, paragraphStylePreset.id)\n\n\tconst link: LinkToWebPage = {\n\t\ttype: \"webPage\",\n\t\twebPageId: scopeId,\n\t\tpathVariables: {\n\t\t\t[slugVariableId]: createNestedVariableReference(paginationVariableId, slugVariableId, scopeId),\n\t\t},\n\t}\n\n\tconst linkElement = document.createElement(\"a\")\n\tsetStylePreset(linkElement, linkStylePreset.id)\n\tsetAnchorElementLink(linkElement, link)\n\tlinkElement.textContent = name\n\n\tparagraphElement.append(linkElement)\n\n\tconst visibleVariable = createComputedValue(\n\t\tControlType.Boolean,\n\t\tcreateVariableReference(paginationVariableId, scopeId),\n\t\t[\n\t\t\t{\n\t\t\t\ttype: \"valueTransform\",\n\t\t\t\tid: randomID(),\n\t\t\t\tname: \"isSet\",\n\t\t\t},\n\t\t],\n\t)\n\n\tconst textContentVariable = createComputedValue(\n\t\tControlType.String,\n\t\tcreateNestedVariableReference(paginationVariableId, titleVariableId, scopeId),\n\t\t[textContentTransform],\n\t)\n\n\treturn new RichTextNode({\n\t\tname,\n\t\twidthType: DimensionType.Auto,\n\t\theightType: DimensionType.Auto,\n\t\thtml: paragraphElement.outerHTML,\n\t\ttextContent: textContentVariable,\n\t\tvisible: visibleVariable,\n\t})\n}\n", "import type { VariableReference } from \"@framerjs/document-migrations/src/types/V75.ts\"\nimport { assert } from \"@framerjs/shared\"\nimport { isOpenURLAction, updatedOpenURLAction } from \"document/models/CanvasTree/actions/openURLActions.ts\"\nimport type { CanvasNode, CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport {\n\tisCodeComponentNode,\n\tisCollectionItemNode,\n\tisRichTextNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { DynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { frameEventKeys, withFrameEvents } from \"document/models/CanvasTree/traits/WithFrameEvents.ts\"\nimport { hasLink, withLink } from \"document/models/CanvasTree/traits/WithLink.ts\"\nimport type { Link } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { getLink, isLink } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport type { EventAction } from \"document/models/EventAction.ts\"\nimport type {\n\tEventHandlerControlProp,\n\tLinkControlProp,\n\tRichTextControlProp,\n} from \"document/models/controlProps/ControlProp.ts\"\nimport { isRawControlProp } from \"document/models/controlProps/RawControlProp.ts\"\nimport { type PrefixedControlProps, isPrefixedControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { createEditorState } from \"prosemirror/editorState.ts\"\nimport { remapLinks } from \"prosemirror/remapLinks.ts\"\nimport { fullSchemaParams, makeSchema } from \"prosemirror/schema/index.ts\"\nimport { serializeRichText } from \"prosemirror/serialization/dom.ts\"\nimport { isKeySetAndNotInherited } from \"./isKeySetAndNotInherited.ts\"\nimport { isString } from \"./typeChecks.ts\"\n\nfunction actionsContainLinkThatNeedsUpdating(\n\tactions: EventAction[],\n\tupdateLink: (link: Link | VariableReference | undefined) => Link | null,\n): boolean {\n\treturn actions.some(action => {\n\t\tif (!isOpenURLAction(action)) return false\n\t\tconst link = getLink(action.controls.url?.value)\n\t\tif (!isLink(link)) return false\n\n\t\treturn Boolean(updateLink(link))\n\t})\n}\n\nfunction updateActionsWithLink(\n\tactions: EventAction[],\n\tupdateLink: (link: Link | VariableReference | undefined) => Link | null,\n): EventAction[] {\n\treturn actions.map(action => {\n\t\tif (!isOpenURLAction(action)) return action\n\t\tconst link = getLink(action.controls.url?.value)\n\t\tif (!isLink(link)) return action\n\n\t\tconst updatedLink = updateLink(link)\n\t\tif (!isLink(updatedLink)) return action\n\n\t\treturn updatedOpenURLAction(action, { url: { type: ControlType.String, value: updatedLink } })\n\t})\n}\n\nfunction remapLinksWithinRichTextIfNeeded(\n\thtml: string,\n\tupdateLink: (link: Link | VariableReference | undefined) => Link | null,\n): string | null {\n\tconst schema = makeSchema(fullSchemaParams)\n\tconst state = createEditorState(html, schema)\n\n\tconst transaction = remapLinks(schema, state, updateLink)\n\tif (!transaction) return null\n\n\tconst newState = state.apply(transaction)\n\treturn serializeRichText(newState.doc, schema)\n}\n\ninterface UpdateLinksOptions {\n\t/**\n\t * Whether to push changes to the upstream/master variant. Set to false when\n\t * the caller already walks all nodes (including replicas) so upstream\n\t * propagation is redundant.\n\t */\n\tupdateUpstream: boolean\n}\n\n/**\n * Finds all links in a node and allows for easy replacement.\n *\n * Previously this function included a tree walk. Now the caller is responsible\n * for initiating the walk and providing the node to this helper.\n */\nexport function updateLinks(\n\ttree: CanvasTree,\n\tnode: CanvasNode,\n\tupdateLink: (link: Link | DynamicValue | undefined) => Link | null,\n\t{ updateUpstream }: UpdateLinksOptions = { updateUpstream: true },\n) {\n\tif (withLink(node) && hasLink(node) && isKeySetAndNotInherited(tree, node, \"link\")) {\n\t\tconst updatedLink = updateLink(node.getLink())\n\t\tif (updatedLink) {\n\t\t\ttree.current(node)?.set({ link: updatedLink }, undefined, false, updateUpstream)\n\t\t}\n\t}\n\n\tif (withFrameEvents(node)) {\n\t\tfor (const frameEventKey of frameEventKeys) {\n\t\t\tconst actions = node[frameEventKey]\n\t\t\tif (!Array.isArray(actions)) continue\n\t\t\tif (!isKeySetAndNotInherited(tree, node, frameEventKey)) continue\n\t\t\tif (!actionsContainLinkThatNeedsUpdating(actions, updateLink)) continue\n\n\t\t\tconst updatedActions = updateActionsWithLink(actions, updateLink)\n\t\t\ttree.current(node)?.set({ [frameEventKey]: updatedActions }, undefined, false, updateUpstream)\n\t\t}\n\t}\n\n\tif (isRichTextNode(node) && isKeySetAndNotInherited(tree, node, \"html\")) {\n\t\tnode.remapLinks(updateLink)\n\t}\n\n\tif (isCodeComponentNode(node) || isCollectionItemNode(node)) {\n\t\tfor (const [key, controlProp] of node.entries()) {\n\t\t\tif (!isPrefixedControlPropKey(key)) continue\n\t\t\tif (!isRawControlProp(controlProp)) continue\n\t\t\tif (!isKeySetAndNotInherited(tree, node, key)) continue\n\n\t\t\tswitch (controlProp.type) {\n\t\t\t\tcase ControlType.EventHandler: {\n\t\t\t\t\tif (!Array.isArray(controlProp.value)) continue\n\t\t\t\t\tif (!actionsContainLinkThatNeedsUpdating(controlProp.value, updateLink)) continue\n\t\t\t\t\tconst updatedActions = updateActionsWithLink(controlProp.value, updateLink)\n\t\t\t\t\tassert(isCodeComponentNode(node), \"Event handlers are not supported inside collections\")\n\t\t\t\t\tconst update: PrefixedControlProps<EventHandlerControlProp> = {\n\t\t\t\t\t\t[key]: {\n\t\t\t\t\t\t\ttype: ControlType.EventHandler,\n\t\t\t\t\t\t\tvalue: updatedActions,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\ttree.current(node)?.set(update, undefined, false, updateUpstream)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.Link: {\n\t\t\t\t\tconst link = getLink(controlProp.value)\n\t\t\t\t\tif (!isLink(link)) continue\n\t\t\t\t\tconst updatedLink = updateLink(link)\n\t\t\t\t\tif (!updatedLink) continue\n\t\t\t\t\tconst update: PrefixedControlProps<LinkControlProp> = {\n\t\t\t\t\t\t[key]: {\n\t\t\t\t\t\t\ttype: ControlType.Link,\n\t\t\t\t\t\t\tvalue: updatedLink,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\ttree.current(node)?.set(update, undefined, false, updateUpstream)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase ControlType.RichText: {\n\t\t\t\t\tif (!isString(controlProp.value)) continue\n\t\t\t\t\tconst html = remapLinksWithinRichTextIfNeeded(controlProp.value, updateLink)\n\t\t\t\t\tif (!html) continue\n\t\t\t\t\tconst update: PrefixedControlProps<RichTextControlProp> = {\n\t\t\t\t\t\t[key]: {\n\t\t\t\t\t\t\ttype: ControlType.RichText,\n\t\t\t\t\t\t\tvalue: html,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t\ttree.current(node)?.set(update, undefined, false, updateUpstream)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert, isLocalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport type { CMSConnectedField } from \"app/ai/sections/types.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { RenamedIds } from \"document/components/tools/utils/updateNodeConnections.ts\"\nimport type { CanvasNode, CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { createVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { hasCollectionDataSource } from \"document/models/CanvasTree/traits/WithCollectionDataSource.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { createLink, isLinkToWebPage } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { getAllAssociatedRepeaters } from \"document/utils/contentCreationTemplates.ts\"\nimport { getSlugIdFromDataDefinition } from \"utils/collectionUtils.ts\"\nimport { getRepeatedItemOfDataRepeater } from \"utils/repeaterUtils.ts\"\nimport { updateLinks } from \"utils/updateLinks.ts\"\n\ninterface CollectionMappingParams {\n\tengine: VekterEngine\n\tparentId: NodeID\n\tcollectionNodes: CollectionNode[]\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>\n}\n\n/**\n * Creates a mapping of collection IDs to their corresponding collection node IDs so that when creating a new section\n * the new collection node id is used instead of the old one.\n * Also maps variable IDs to their corresponding new collection variable IDs.\n * Also maps provider IDs to the scope node for detail pages. This is needed for detail pages.\n *\n */\nexport function createConnectedFieldsToExistingCollectionsMap({\n\tengine,\n\tparentId,\n\tcollectionNodes,\n\tcmsConnectedFields,\n}: CollectionMappingParams): RenamedIds {\n\tconst renamedIds = new RenamedIds()\n\n\tif (!collectionNodes.length) {\n\t\treturn renamedIds\n\t}\n\n\tconst parentNode = engine.tree.get(parentId)\n\tassert(parentNode, \"Parent node not found for parent\", parentId)\n\n\tconst scopeNode = engine.tree.getScopeNodeFor(parentNode)\n\tassert(scopeNode, \"Scope node not found for parent\", parentId)\n\n\tfor (const templateCollectionId in cmsConnectedFields) {\n\t\tconst fields = cmsConnectedFields[templateCollectionId]\n\t\tassert(fields, \"CMS connected fields must be an array\")\n\n\t\t// Find the existing collection node that matches the template collection id (either by id for local kits or\n\t\t// by createdFromKitSchemaId for remote kits).\n\t\tconst existingCollectionNode = collectionNodes.find(\n\t\t\tcollectionNode =>\n\t\t\t\tcollectionNode.id === templateCollectionId || collectionNode.createdFromKitSchemaId === templateCollectionId,\n\t\t)\n\n\t\tassert(existingCollectionNode, \"Collection node not found for template collection id\", templateCollectionId)\n\n\t\tif (templateCollectionId !== existingCollectionNode.id) {\n\t\t\trenamedIds.set(templateCollectionId, existingCollectionNode.id)\n\t\t}\n\n\t\tprocessVariableMappings({\n\t\t\tfields,\n\t\t\tcollectionNode: existingCollectionNode,\n\t\t\tscopeNode,\n\t\t\trenamedIds,\n\t\t})\n\t}\n\n\treturn renamedIds\n}\n\nfunction processVariableMappings({\n\tfields,\n\tcollectionNode,\n\tscopeNode,\n\trenamedIds,\n}: {\n\tfields: CMSConnectedField[]\n\tcollectionNode: CollectionNode\n\tscopeNode: CanvasNode\n\trenamedIds: RenamedIds\n}) {\n\tfor (const field of fields) {\n\t\t// Is the name heuristic for finding the correct collection field enough?\n\t\tconst collectionField = collectionNode.variables.find(variable => variable.name === field.name)\n\n\t\tif (!collectionField) continue\n\n\t\t// Map variable IDs\n\t\tif (field.id !== collectionField.id) {\n\t\t\trenamedIds.set(field.id, collectionField.id)\n\t\t}\n\n\t\t// Map provider IDs to scope node for detail pages\n\t\tif (field.providerId && shouldMapScopeNodeProviderId(scopeNode, collectionNode, field)) {\n\t\t\trenamedIds.set(field.providerId, scopeNode.id)\n\t\t}\n\t}\n}\n\nfunction shouldMapScopeNodeProviderId(\n\tscopeNode: CanvasNode,\n\tcollectionNode: CollectionNode,\n\tfield: CMSConnectedField,\n): boolean {\n\tif (!hasCollectionDataSource(scopeNode)) return false\n\tif (!field.providerId || field.providerId === scopeNode.id) return false\n\n\tconst parsedIdentifier = parseModuleIdentifier(scopeNode.dataIdentifier)\n\tif (!isLocalModuleIdentifier(parsedIdentifier)) return false\n\n\treturn parsedIdentifier.localIdName === collectionNode.id\n}\n\nfunction getSlugIdFromDataIdentifier(\n\tcomponentLoader: ComponentLoader,\n\tdataIdentifier: ModuleExportIdentifierString,\n): string {\n\tconst dataDefinition = componentLoader.dataForIdentifier(dataIdentifier)\n\tassert(dataDefinition, \"Collection should have a data definition\")\n\n\tconst slugId = getSlugIdFromDataDefinition(dataDefinition)\n\tassert(slugId, \"Slug must exist\")\n\n\treturn slugId\n}\n\nfunction updateRepeaterLinksForDetailPage(\n\tengine: VekterEngine,\n\tdataIdentifier: ModuleExportIdentifierString,\n\twebPageId: NodeID,\n\tslugId: string,\n) {\n\t// We will go over all repeaters with the same identifier and create a links if possible.\n\t// To do so we need the whole document to have loaded.\n\tengine.scheduler.runWithFullyLoadedTree(\n\t\t() => {\n\t\t\tgetAllAssociatedRepeaters(engine, dataIdentifier).forEach(associatedDataRepeater => {\n\t\t\t\tconst repeatedChild = getRepeatedItemOfDataRepeater(engine.tree, associatedDataRepeater)\n\t\t\t\tif (!repeatedChild) return\n\n\t\t\t\tfor (const node of repeatedChild.walk()) {\n\t\t\t\t\tif (isReplicaOrReplicaChild(node)) continue\n\n\t\t\t\t\tupdateLinks(engine.tree, node, link => {\n\t\t\t\t\t\tif (!isLinkToWebPage(link)) return null\n\n\t\t\t\t\t\t// Keep links that target known nodes intact\n\t\t\t\t\t\tconst hasTargetNode = engine.tree.has(link.webPageId)\n\t\t\t\t\t\tif (hasTargetNode) return null\n\n\t\t\t\t\t\t// We only care about links that have path variables.\n\t\t\t\t\t\tif (!link.pathVariables) return null\n\n\t\t\t\t\t\t// @TODO: Fix this. We should only update the links that have path variables to the\n\t\t\t\t\t\t// collection we are targeting with datIdentifier.\n\t\t\t\t\t\tconst slugVariableBinding = createVariableReference(slugId, associatedDataRepeater.id)\n\t\t\t\t\t\treturn createLink({\n\t\t\t\t\t\t\twebPageId: webPageId,\n\t\t\t\t\t\t\tpathVariables: { [slugId]: slugVariableBinding },\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\t{ name: \"create_collection_page\" },\n\t)\n}\n\nexport function updateAllRepeaterLinks(engine: VekterEngine, dataIdentifier: ModuleExportIdentifierString) {\n\t// Get the detail page corresponding to the data identifier\n\tconst detailPage = engine.stores.scopeStore\n\t\t.getWebPageNodes()\n\t\t.find(webPage => webPage.dataIdentifier === dataIdentifier)\n\n\tif (!detailPage) return\n\n\tconst slugId = getSlugIdFromDataIdentifier(engine.componentLoader, dataIdentifier)\n\n\tupdateRepeaterLinksForDetailPage(engine, dataIdentifier, detailPage.id, slugId)\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { asGlobalId, getLogger, isModuleExportIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport { getNodeProperty } from \"app/ai/utils/getNodeProperty.ts\"\nimport { applyTypography } from \"app/ai/utils/typography.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasNode, CodeComponentNode, NodeID, RichTextNode } from \"document/models/CanvasTree/index.ts\"\nimport {\n\tisCodeComponentNode,\n\tisCollectionRepeater,\n\tisRichTextNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { setStringValue } from \"document/models/CanvasTree/nodes/utils/setStringValue.ts\"\nimport { getUniqueSlotNodeIdsFromAllSlots } from \"document/models/CanvasTree/nodes/utils/slotUtils.ts\"\nimport type { WithAltText } from \"document/models/CanvasTree/traits/WithAltText.ts\"\nimport { withAltText } from \"document/models/CanvasTree/traits/WithAltText.ts\"\nimport type { HasCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { hasCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport type { WithFill, WithFillImageAlts } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { hasAnyFillImageAlts, withOptionalFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { isReplicaVariantOrReplicaVariantChild } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport type { ContentContainer } from \"document/models/CanvasTree/traits/utils/ContentContainer.ts\"\nimport {\n\tgetRichTextNodesRequiringTextFitUpdates,\n\tupdateTextFitViewBox,\n} from \"document/models/CanvasTree/traits/utils/textFitHelpers.ts\"\nimport type { ControlProp } from \"document/models/controlProps/ControlProp.ts\"\nimport { removeControlPropKeyPrefix, isPrefixedControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport type { Mutable } from \"utils/Mutable.ts\"\nimport { isArray, isObject, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport { vectorInfoForIdentifier } from \"utils/vectorSets.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { updateAllRepeaterLinks } from \"./collections.ts\"\n\nconst log = getLogger(\"ai:generateWebPage:contentApplication\")\n\nconst loadingFont = \"GF;Flow Circular-regular\"\n\ninterface CodeComponentVariablesUpdateData {\n\tcontrolKey: string\n\tcontrolProp: ControlProp\n}\n\ninterface VectorSetUpdateData {\n\tcodeComponentIdentifier: string\n}\n\n/**\n * Applies content to all nodes in a section.\n */\nexport async function applyContentToNodes(\n\tengine: VekterEngine,\n\tnodeId: NodeID,\n\tcontentContainer: ContentContainer,\n\tkit: WireframerKit,\n) {\n\tconst seenNodeIds = new Set<string>()\n\tconst fitTextNodes = new Set<NodeID>()\n\tconst updates: Array<() => void> = []\n\n\tconst currentTopNode = engine.tree.get(nodeId)\n\tif (!currentTopNode) return\n\n\tfor (const walkNode of currentTopNode.walk()) {\n\t\tif (seenNodeIds.has(walkNode.id)) continue\n\t\tseenNodeIds.add(walkNode.id)\n\n\t\tif (isCollectionRepeater(walkNode)) {\n\t\t\tconst dataIdentifier = walkNode.dataIdentifier\n\t\t\tupdates.push(() => {\n\t\t\t\tupdateAllRepeaterLinks(engine, dataIdentifier)\n\t\t\t})\n\t\t}\n\n\t\tif (hasCustomizations(walkNode) && isRichTextNode(walkNode)) {\n\t\t\tconst nodeIdToUpdate = walkNode.id\n\t\t\tupdates.push(() => {\n\t\t\t\tconst node = engine.tree.get(nodeIdToUpdate)\n\t\t\t\tif (node && isRichTextNode(node) && hasCustomizations(node)) {\n\t\t\t\t\tapplyContentToNode(engine, node, fitTextNodes, contentContainer)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\n\t\tif (hasCustomizations(walkNode)) {\n\t\t\t// Check if this node has an image customization with fieldOptions\n\t\t\tconst hasImageCustomization = walkNode.customizations?.some(\n\t\t\t\tc => c.type === \"content\" && c.fieldType === \"image\" && c.fieldOptions,\n\t\t\t)\n\n\t\t\tif (hasImageCustomization) {\n\t\t\t\tupdates.push(() => {\n\t\t\t\t\tconst node = engine.tree.get(walkNode.id)\n\t\t\t\t\tif (!node || !hasCustomizations(node)) return\n\t\t\t\t\tapplyImageSelectionToNode(node, contentContainer)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif (isCodeComponentNode(walkNode)) {\n\t\t\tconst variablesUpdates = await prepareCodeComponentVariablesUpdates(\n\t\t\t\tengine.componentLoader,\n\t\t\t\twalkNode,\n\t\t\t\tcontentContainer,\n\t\t\t\tkit,\n\t\t\t)\n\t\t\tif (variablesUpdates.length > 0) {\n\t\t\t\tconst nodeIdToUpdate = walkNode.id\n\t\t\t\tupdates.push(() => {\n\t\t\t\t\tconst node = engine.tree.get(nodeIdToUpdate)\n\t\t\t\t\tif (node && isCodeComponentNode(node)) {\n\t\t\t\t\t\tfor (const { controlKey, controlProp } of variablesUpdates) {\n\t\t\t\t\t\t\tnode.setControlProp(controlKey, controlProp)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (hasCustomizations(walkNode) && walkNode.isVectorInstance) {\n\t\t\t\tconst vectorUpdate = await getVectorSetUpdate(engine, walkNode, contentContainer, kit)\n\t\t\t\tif (vectorUpdate) {\n\t\t\t\t\tconst nodeIdToUpdate = walkNode.id\n\t\t\t\t\tconst newIdentifier = vectorUpdate.codeComponentIdentifier\n\t\t\t\t\tupdates.push(() => {\n\t\t\t\t\t\tconst node = engine.tree.get(nodeIdToUpdate)\n\t\t\t\t\t\tif (!node || !isCodeComponentNode(node)) return\n\n\t\t\t\t\t\tnode.set({ codeComponentIdentifier: newIdentifier, isApplyingCustomizations: undefined })\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst slotNodeIds = getUniqueSlotNodeIdsFromAllSlots(engine.tree, walkNode, engine.componentLoader)\n\n\t\t\tfor (const slotNodeId of slotNodeIds) {\n\t\t\t\tconst slotNode = engine.tree.get(slotNodeId)\n\t\t\t\tif (!slotNode || seenNodeIds.has(slotNode.id)) continue\n\n\t\t\t\tfor (const slotNodeChild of slotNode.walk()) {\n\t\t\t\t\tif (seenNodeIds.has(slotNodeChild.id)) continue\n\t\t\t\t\tseenNodeIds.add(slotNodeChild.id)\n\n\t\t\t\t\tif (!hasCustomizations(slotNodeChild) || !isRichTextNode(slotNodeChild)) continue\n\n\t\t\t\t\tconst nodeIdToUpdate = slotNodeChild.id\n\t\t\t\t\tupdates.push(() => {\n\t\t\t\t\t\tconst node = engine.tree.get(nodeIdToUpdate)\n\t\t\t\t\t\tif (node && isRichTextNode(node) && hasCustomizations(node)) {\n\t\t\t\t\t\t\tapplyContentToNode(engine, node, fitTextNodes, contentContainer)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\tfor (const updateFn of updates) {\n\t\t\tupdateFn()\n\t\t}\n\t})\n\n\tif (fitTextNodes.size === 0) return\n\tawait updateTextFitViewBox(engine, getRichTextNodesRequiringTextFitUpdates(engine, Array.from(fitTextNodes)))\n}\n\n/**\n * Applies content to a single node with customizations.\n */\nfunction applyContentToNode(\n\tengine: VekterEngine,\n\tnode: RichTextNode & HasCustomizations,\n\tfitTextNodes: Set<NodeID>,\n\tcontentContainer: ContentContainer,\n) {\n\tif (isReplicaVariantOrReplicaVariantChild(node)) {\n\t\t// Ignore nodes inside of variants because it's probably a mistake.\n\t\tlog.warn(\"Ignoring attempt to apply customizations to variant node\", node.id)\n\t\treturn\n\t}\n\n\tconst { customization, value } = getContentCustomizationAndValue(node, contentContainer)\n\tif (!customization) return\n\n\tif (isUndefined(value)) {\n\t\tif (contentContainer.isFinal) {\n\t\t\tlog.warn(customization.fieldPath, \"is missing in provided content\")\n\t\t}\n\n\t\t// Give the text a placeholder appearance temporarily\n\t\tconst nodeValue = getNodeProperty(engine, node, customization.property)\n\t\tif (nodeValue && !node.isApplyingCustomizations) {\n\t\t\tnode.set({ isApplyingCustomizations: true })\n\n\t\t\t// Save the original font so we can restore it later.\n\t\t\t// Use flow to display a loading bar for this missing content.\n\t\t\t// TODO: Use a more elegant solution. Maybe take advantage of the isApplyingCustomizations flag and set\n\t\t\t// the font in the getProps method of the RichTextNode.\n\t\t\tconst fonts = node.getFontsWithVariationAxes(false)\n\t\t\tconst originalFont = fonts[0] ?? null\n\n\t\t\tnode.cache.originalFont = originalFont\n\n\t\t\tnode.setFont(loadingFont, false)\n\n\t\t\tfitTextNodes?.add(node.id)\n\t\t}\n\n\t\treturn\n\t}\n\n\t// We expect value to be either a string value or an Unsplash search query.\n\tif (!isString(value)) {\n\t\tlog.warn(\"Expected contentData to be contain text string for fieldPath\", customization.fieldPath)\n\t\treturn\n\t}\n\n\t// TODO: These conditions won't be necessary once we fix bug where\n\t// font size overrides are lost.\n\t// https://github.com/framer/company/issues/27166\n\tif (value !== \"\" || contentContainer.isFinal) {\n\t\tnode.set({ isApplyingCustomizations: undefined })\n\n\t\t// Restore the original font if it was set.\n\t\tif (node.cache.originalFont) {\n\t\t\tnode.setFont(node.cache.originalFont, false)\n\t\t\tnode.cache.originalFont = null\n\t\t}\n\n\t\tsetStringValue(engine, node, customization.property, applyTypography(value))\n\n\t\tfitTextNodes?.add(node.id)\n\t}\n}\n\n/**\n * Applies image selection from fieldOptions to a node with image customization.\n * The LLM returns an alt text key, which we use to look up the image URL from the\n * customization's fieldOptions (source of truth from the section field definition).\n */\nfunction applyImageSelectionToNode(node: CanvasNode & HasCustomizations, contentContainer: ContentContainer) {\n\tif (isReplicaVariantOrReplicaVariantChild(node)) {\n\t\tlog.warn(\"Ignoring attempt to apply image selection to variant node\", node.id)\n\t\treturn\n\t}\n\tif (!withOptionalFill(node)) return\n\n\tconst { customization, value } = getContentCustomizationAndValue(node, contentContainer)\n\tif (!customization || !isString(value)) return\n\n\t// Look up the image URL from the customization's fieldOptions (stored on the section field).\n\t// This is the source of truth that comes from the kit definition.\n\tconst fieldOptions = customization.fieldOptions\n\tif (!fieldOptions) return\n\n\tconst imageUrl = fieldOptions[value]\n\tif (!imageUrl) {\n\t\tcontentContainer.isFinal && log.warn(`Image alt text \"${value}\" not found in fieldOptions for node ${node.id}`)\n\t\treturn\n\t}\n\n\tconst updates: Mutable<Partial<WithFill & WithAltText & WithFillImageAlts>> = { fillImage: imageUrl }\n\tif (hasAnyFillImageAlts(node)) updates.fillImageAlts = undefined\n\tif (withAltText(node)) updates.altAttribute = value\n\tnode.set(updates)\n}\n\n/**\n * Prepares code component variables updates (async - performs vector lookups).\n */\nasync function prepareCodeComponentVariablesUpdates(\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n\tcontentContainer: ContentContainer,\n\tkit: WireframerKit,\n): Promise<CodeComponentVariablesUpdateData[]> {\n\tconst identifier = node.codeComponentIdentifier\n\tconst component = componentLoader.componentForIdentifier(identifier)\n\tif (!component) return []\n\n\tconst normalized = normalizeContentToControlKeyValueMap(node, component, contentContainer)\n\tconst updates: CodeComponentVariablesUpdateData[] = []\n\n\tfor (const [controlKey, value] of normalized) {\n\t\tconst controlProp = component.properties?.[controlKey]\n\t\tif (!controlProp) continue\n\n\t\tif (controlProp.type === ControlType.String) {\n\t\t\tupdates.push({ controlKey, controlProp: { ...controlProp, value } })\n\t\t} else if (controlProp.type === ControlType.VectorSetItem) {\n\t\t\tconst setModuleId = controlProp.setModuleId\n\t\t\tif (!setModuleId) continue\n\n\t\t\tconst newIcon = await kit.lookupVectorByName(asGlobalId(setModuleId), value)\n\t\t\tif (!newIcon) continue\n\t\t\tupdates.push({ controlKey, controlProp: { ...controlProp, value: newIcon } })\n\t\t}\n\t}\n\n\treturn updates\n}\n\nasync function getVectorSetUpdate(\n\tengine: VekterEngine,\n\tnode: CodeComponentNode & HasCustomizations,\n\tcontentContainer: ContentContainer,\n\tkit: WireframerKit,\n): Promise<VectorSetUpdateData | null> {\n\tconst { customization, value } = getContentCustomizationAndValue(node, contentContainer)\n\tif (!value || !customization) return null\n\n\tconst currentIdentifier = parseModuleIdentifier(node.codeComponentIdentifier)\n\tif (!currentIdentifier || !isModuleExportIdentifier(currentIdentifier)) return null\n\n\tconst vectorInfo = vectorInfoForIdentifier(currentIdentifier, engine.tree, engine.stores.modulesStore)\n\tconst setModuleId = vectorInfo?.set.moduleId\n\tif (!setModuleId) return null\n\n\tconst newCodeComponentIdentifier = await kit.lookupVectorByName(setModuleId, value)\n\n\tif (newCodeComponentIdentifier) {\n\t\treturn { codeComponentIdentifier: newCodeComponentIdentifier }\n\t} else if (contentContainer.isFinal) {\n\t\treturn { codeComponentIdentifier: node.codeComponentIdentifier }\n\t}\n\n\treturn null\n}\n\n/**\n * Gets content customization and value for a node.\n */\nfunction getContentCustomizationAndValue(node: CanvasNode & HasCustomizations, contentContainer: ContentContainer) {\n\tconst contentData = contentContainer.get(\"content\")\n\tif (!isArray(contentData)) return { customization: undefined, value: undefined }\n\n\tconst customizations = node.customizations?.filter(c => c.type === \"content\") ?? []\n\tif (customizations.length === 0) return { customization: undefined, value: undefined }\n\n\t// Build lookup for provided values by fieldPath\n\tconst fieldToText = new Map<string, string>()\n\tfor (const item of contentData) {\n\t\tif (isObject(item) && isString(item.field) && isString(item.text)) {\n\t\t\tfieldToText.set(item.field, item.text)\n\t\t}\n\t}\n\n\tfor (const customization of customizations) {\n\t\tconst value = fieldToText.get(customization.fieldPath)\n\t\tif (isString(value)) return { customization, value }\n\t}\n\n\t// Fallback to first customization for logging/placeholders\n\treturn { customization: customizations[0], value: undefined }\n}\n\n/**\n * Normalize incoming content into a mapping of controlKey -> value.\n * Supports both new fieldPath-based mapping (via customizations.property)\n * and legacy title-based mapping (matches content field to control.title).\n */\nfunction normalizeContentToControlKeyValueMap(\n\tnode: CodeComponentNode,\n\tcomponent: { properties?: Record<string, { title?: string; type: ControlType }> },\n\tcontentContainer: ContentContainer,\n) {\n\tconst contentData = contentContainer.get(\"content\")\n\tconst result = new Map<string, string>()\n\tif (!isArray(contentData)) return result\n\n\tconst fieldToText = new Map<string, string>()\n\tfor (const item of contentData) {\n\t\tif (isObject(item) && isString(item.field) && isString(item.text)) {\n\t\t\tfieldToText.set(item.field, item.text)\n\t\t}\n\t}\n\n\tconst nodeCustomizations = node.customizations\n\tconst customizationsArray = isArray(nodeCustomizations) ? nodeCustomizations : []\n\tconst hasCustomizations = customizationsArray.length > 0\n\n\tif (hasCustomizations) {\n\t\t// New format: set controlKey -> value directly while iterating customizations\n\t\tfor (const customization of customizationsArray) {\n\t\t\tif (customization?.type !== \"content\") continue\n\t\t\tconst property = customization.property\n\t\t\tif (!isString(property) || !isPrefixedControlPropKey(property)) continue\n\t\t\tconst controlKey = removeControlPropKeyPrefix(property)\n\t\t\tif (!isString(controlKey)) continue\n\t\t\tif (isString(customization.fieldPath)) {\n\t\t\t\tconst text = fieldToText.get(customization.fieldPath)\n\t\t\t\tif (isString(text)) result.set(controlKey, text)\n\t\t\t}\n\t\t}\n\t} else if (component.properties) {\n\t\t// Legacy format for the fAi project: content.field matches control.title\n\t\tfor (const [field, text] of fieldToText) {\n\t\t\tfor (const key in component.properties) {\n\t\t\t\tconst controlProp = component.properties[key]\n\t\t\t\tif (!controlProp) continue\n\t\t\t\tif (controlProp.title === field) {\n\t\t\t\t\tresult.set(key, text)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n", "import { assert, getLogger } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { FrameNode, LoadedWebPageNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport type { IsMaster } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport type { IsBreakpoint, IsVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\n\nconst log = getLogger(\"ai:generateWebPage:utils\")\n\n/**\n * Returns the latest primary variant of a web page node.\n */\nexport function getLatestPrimaryVariant(\n\tengine: VekterEngine,\n\twebPageNode: LoadedWebPageNode,\n): FrameNode & IsMaster & IsVariant & IsBreakpoint {\n\tconst latestWebPageNode = engine.tree.current(webPageNode)\n\tassert(latestWebPageNode, \"webPageNode should not be null\")\n\treturn latestWebPageNode.getPrimaryVariant()\n}\n\n/**\n * Deletes sections that are present in the page but were forgotten by the AI in the newly generated page structure.\n */\nexport function deleteSectionsThatAreNotInTheResponse(\n\tengine: VekterEngine,\n\tnodeId: NodeID,\n\tnodeIdsToDelete: Set<NodeID>,\n) {\n\tconst latestParent = engine.tree.get(nodeId)\n\tassert(latestParent, \"Cannot find container node for sections\", nodeId)\n\tassert(withChildren(latestParent), \"Container node cannot have children\", nodeId)\n\n\tfor (const child of latestParent.children) {\n\t\tnodeIdsToDelete.delete(child.id)\n\t}\n\n\tif (nodeIdsToDelete.size === 0) return\n\n\tengine.scheduler.processWhenReady(() => {\n\t\tlog.warn(\"Deleting nodes manually:\", nodeIdsToDelete, \"from:\", nodeId)\n\t\tengine.deleteNodes(nodeIdsToDelete)\n\t})\n}\n", "import type { KitSection } from \"code-generation/utils/KitSectionStructureCollector.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { AnyWebPageNode, CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isDesignPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { WireframerKit } from \"./wireframerKit.ts\"\n\nconst NAVIGATION_SECTION_PREFIX = \"navigation\"\nconst FOOTER_SECTION_PREFIX = \"footer\"\n\nexport interface KitSectionUsageData {\n\tsectionsCount: Record<NodeID, number>\n\ttopNavigation: KitSection | null\n\ttopFooter: KitSection | null\n}\n\n/**\n * Get the usage data for the kit sections for a list of nodes, including each section number of occurrences\n * and the most used section for navigation and footer.\n *\n * TODO: We are currently using the section id to match to navigation and footer sections. For kits the plan is to use\n * layout templates so we need to update this logic so the LLM applies layout templates consistently.\n *\n * @param engine - The engine\n * @param nodes - The nodes to get the usage data from\n *\n * @returns The usage data\n */\nfunction getKitSectionsUsageData(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tnodes: Iterable<AnyWebPageNode | CanvasNode>,\n): KitSectionUsageData {\n\tconst sectionsCount: Record<string, number> = {}\n\n\tconst navigationSections = new Map<string, { section: KitSection; count: number }>()\n\tconst footerSections = new Map<string, { section: KitSection; count: number }>()\n\n\tfor (const node of nodes) {\n\t\tconst structure = engine.stores.aiGenerationStore.getKitSectionsStructure(node.id, kit)\n\t\tif (!structure) continue\n\n\t\tfor (const section of structure) {\n\t\t\tconst sectionId = section._id\n\n\t\t\tsectionsCount[sectionId] = (sectionsCount[sectionId] ?? 0) + 1\n\n\t\t\t// Categorize and count nav/footer sections\n\t\t\tif (sectionId.startsWith(NAVIGATION_SECTION_PREFIX)) {\n\t\t\t\tupdateSectionMap(navigationSections, sectionId, section)\n\t\t\t} else if (sectionId.startsWith(FOOTER_SECTION_PREFIX)) {\n\t\t\t\tupdateSectionMap(footerSections, sectionId, section)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tsectionsCount,\n\t\ttopNavigation: getMostUsedSection(navigationSections),\n\t\ttopFooter: getMostUsedSection(footerSections),\n\t}\n}\n\nfunction updateSectionMap(\n\tsectionMap: Map<string, { section: KitSection; count: number }>,\n\tsectionId: string,\n\tsection: KitSection,\n) {\n\tconst existing = sectionMap.get(sectionId)\n\tif (existing) {\n\t\texisting.count++\n\t} else {\n\t\tsectionMap.set(sectionId, { section, count: 1 })\n\t}\n}\n\nfunction getMostUsedSection(sectionMap: Map<string, { section: KitSection; count: number }>): KitSection | null {\n\tif (sectionMap.size === 0) return null\n\n\treturn Array.from(sectionMap.values()).reduce((max, current) => (current.count > max.count ? current : max)).section\n}\n\nexport function getKitSectionsUsageDataForAllWebPages(engine: VekterEngine, kit: WireframerKit): KitSectionUsageData {\n\tconst webPages = engine.stores.scopeStore.getWebPageNodes()\n\treturn getKitSectionsUsageData(engine, kit, webPages)\n}\n\nexport function getKitSectionsUsageDataForDesignPageScreens(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tdesignPageId: NodeID,\n): KitSectionUsageData | undefined {\n\tconst designPage = engine.tree.get(designPageId)\n\tif (!isDesignPageNode(designPage) || !designPage.isLoaded()) return\n\n\treturn getKitSectionsUsageData(engine, kit, designPage.loaded.children)\n}\n", "import { CREATE_NEW_COLLECTION_ALIAS } from \"app/ai/utils/kitSection.ts\"\nimport { layoutTemplateSlotKey } from \"app/ai/utils/wireframerKit.ts\"\n\nexport const baseSystemPrompt = `You are an AI website generator that creates and manages web pages using predefined layout sections. Your goal is to help users structure, update, and iterate on professional pages.\n\n# Core Capabilities\n\nYou can:\n- Generate new page with structured sections.\n- Modify existing page by adding, removing, or updating sections.\n- Maintain design and content coherence across the whole site.\n- Set the color scheme of the page based on the user request.\n\n---\n\n# Input: Project Context\n\nYou will receive:\n- A list of available sections, each item includes:\n\t- description: Explains the section's features, layout, and intended usage.\n\t- fields: A list of customizable fields within the section. CMS-connected fields (\\`\"isCMSConnectedField\": true\\`) include a \"collection\" property pointing to the collection template name.\n\t- rules: A list of rules that the section must follow.\n\t- supportedCollections: A map from each template collection to the list of existing collection names that are allowed to be used for that template.\n\t- singleton: A Boolean that indicates the section can only be used once per page. When true, you must not select the section more than once.\n\t- layoutId (Optional on the input, but NOT optional in your reasoning):\n\t\t- If you select any section that has a \"layoutId\", you MUST:\n\t\t\t\t- Set the \"layout\" field to that \"layoutId\".\n\t\t\t\t- Use the layout pattern for that \"layoutId\" and include all sections of that layout in the correct order.\n\t\t- Sections without a \"layoutId\" are regular standalone/content sections for the page content.\n- A list of available layout patterns, which define the structure of each layout:\n\t- Each pattern is written as: \\`<layoutId>: <section1>, <section2>, ${layoutTemplateSlotKey}, ...\\`.\n\t- Every section listed in the pattern (except \\`${layoutTemplateSlotKey}\\`) corresponds to a section in **Available Sections** with a matching \"layoutId\".\n\t- The \\`${layoutTemplateSlotKey}\\` placeholder represents where page content sections (hero, features, contact, etc.) should be inserted.\n- A list of available icons by name.\n- The user prompt indicating desired changes or new page.\n- Some statistics about the usage of the available sections in the project.\n- Site-wide content consistency reference containing navigation and footer content from existing pages. Use this only for maintaining consistent navigation/footer content across pages when you need to add/update those sections.\n- The current page structure.\n- A list of existing CMS collections and their fields.\n\n---\n\n# Output: Structured Response Format\n\nYour response must include:\n\n- layout: The ID of the chosen layout from the \"Available Layout Patterns\" list. Empty string if no layout was chosen.\n\t\t- If ANY section in sections[] comes from a layout pattern (i.e. it has a \"layoutId\" in the Available Sections list), then:\n\t\t\t\t- The \"layout\" field MUST be set to that exact layoutId (never empty).\n\t\t\t\t- You MUST select all sections that share that layoutId and follow the pattern order.\n\t\t- If \"layout\" is an empty string, then sections[] MUST NOT include ANY section that has a \"layoutId\" in the Available Sections list.\n\t\t- It is INVALID to:\n\t\t\t\t- Use a section with \"layoutId\" while \"layout\" is empty.\n\t\t\t\t- Have \"layout\" set to one \"layoutId\" while sections[] contain a section with a different \"layoutId\".\n- sections[]: Ordered list of sections using:\n\t- _id: The ID of the section. The _id MUST be selected from \\`id\\` fields in the \"Available Sections\" list below, NEVER make up section IDs.\n\t- _layerId: Existing layer ID (or \"\" for new ones).\n\t- \\`action: \"add\"\\`, \\`action: \"update\"\\`, \\`action: \"remove\"\\`, or \\`action: \"none\"\\`\n\t- collectionBindings: Array with objects mapping every \"collection\" from the section definition to the name of the existing collection to bind. Include a value for every unique \"collectionTemplate\" from the section definition. When the section has no CMS connected fields leave the array empty.\n\t- content[]: List of field \u2192 text pairs. The amount of fields must satisfy the chosen section. e.g. If the section has 3 fields, you must provide 3 field \u2192 text pairs to populate the section.\n- message: A message including all the changes made to the page and all the things the worker couldn't do.\n\n---\n\n# Page Structure Rules\n\nWhen generating sections, you must follow the following rules:\n\n- Review the **Available Layout Patterns** list to determine the if there is a layout pattern that is suitable for the request.\n- Review the **Available Sections** list to determine if there are sections that can fulfil the user request, and if they have a \"layoutId\" property, you must use that layout pattern.\n- If you pick a layout from **Available Layout Patterns**, you MUST:\n\t\t- Pick all the sections that share the same \"layoutId\".\n\t\t- Use the exact ordering of sections shown in the pattern.\n\t\t- Insert all non-layout sections at the position of \\`${layoutTemplateSlotKey}\\`.\n\t\t- Do NOT mix sections with different \"layoutId\" properties.\n\t\t- Never reorder, remove, or duplicate sections that are part of a layout pattern.\n- When a layout pattern is chosen, its ordering ALWAYS overrides all other ordering rules.\n- If no layout pattern is chosen, you must follow the sections ordering rules. These rules overrule the order indicated by the section description.\n\t\t- If a navigation section is present, it must always be first section.\n\t\t- If a footer section is present, it must always be last section.\n\t\t- There should only be at most one navigation and one footer section.\n- Sections with a \"layoutId\" MUST only be used when generating a page using the matching layout pattern. Never use them independently.\n- Sections cannot be visually customized. When you need a different layout, use \\`action: \"update\"\\` to replace the section.\n- Icons must come from the \"Available Icons\" list. No logos.\n- Styling, images, and fonts are handled by the user in the Page Canvas Editor.\n- Do not mix standalone sections with other sections unless explicitly asked.\n- Use available section types only, do not make up new section types.\n- Never suggest placeholders like \"{ Title }\", always suggest real values like \"About Me\".\n\n**Examples:**\nAvailable sections:\n- hero_a, hero_b, feature_a, contact_a, navigation_a (layoutId: \"layout1\"), footer_a (layoutId: \"layout1\"), navigation_b (layoutId: \"layout2\"), banner_b (layoutId: \"layout2\"), navigation_c, footer_b, footer_c.\nAvailable layout patterns:\n- layout1: navigation_a, ${layoutTemplateSlotKey}, footer_a\n- layout2: navigation_b, banner_b, ${layoutTemplateSlotKey}\n\nGood structures:\n- navigation_a (layoutId: \"layout1\"), hero_a, feature_a, contact_a, footer_a (layoutId: \"layout1\")\n- navigation_b (layoutId: \"layout2\"), banner_b (layoutId: \"layout2\"), hero_a, feature_a, contact_a\n- hero_a, feature_a, contact_a\n\nBad structures:\n- navigation_a (layoutId: \"layout1\"), hero_a, feature_a, contact_a -> Bad. Picked navigation_a from \"layout1\", but did not pick all sections from the same layout (missing footer_a).\n- navigation_a (layoutId: \"layout1\"), hero_a, feature_a, contact_a, footer_b -> Bad. Picked navigation_a from \"layout1\", but did not pick all sections from the same layout (missing footer_a).\n- navigation_b (layoutId: \"layout2\"), banner_b (layoutId: \"layout2\"), hero_a, feature_a, contact_a, footer_a (layoutId: \"layout1\") -> Bad. Mixing sections from different layouts \"layout1\" and \"layout2\".\n- navigation_b (layoutId: \"layout2\"), banner_b (layoutId: \"layout2\"), hero_a, banner_b (layoutId: \"layout2\"), contact_a -> Bad. Repeatedly selecting the same section \"banner_b\" from \"layout2\".\n- navigation_b (layoutId: \"layout2\"), hero_a, feature_a, banner_b (layoutId: \"layout2\"), contact_a -> Bad. Using \"layout2\", but the structure violates the layout pattern for \"layout2\". \"banner_b\" should come before ${layoutTemplateSlotKey} where all other sections should be placed.\n- hero_a, navigation_a (layoutId: \"layout1\"), feature_a, contact_a, footer_a (layoutId: \"layout1\") -> Bad. Navigation is not the first.\n- navigation_a (layoutId: \"layout1\"), hero_a, feature_a, footer_a (layoutId: \"layout1\"), contact_a -> Bad. Footer is not the last.\n- navigation_a (layoutId: \"layout1\"), hero_a, feature_a, contact_a, footer_a (layoutId: \"layout1\"), footer_c -> Bad. There are two footer sections.\n\n## Icon/Vector Set Rules\n\n- Each icon field is tied to a specific icon set, **never mix sets.**\n- Check the field metadata for the icon set ID (iconSet property).\n- Use the **Icon Sets Catalog** to find valid icon names for that set.\n- Icon names must **exactly match** one in the set's \"icons\" array.\n- If multiple icon fields exist in a section, verify each field's assigned set before selecting icons.\n\n## Value Options Rules\n\n- Some sections have an valueOptions property that contains a list of options.\n- When valueOptions is present, you **must** select one of the options as the content text value based on the page context.\n- Choose the most appropriate option for the page's purpose and the user's request.\n\n## Navigation & Footer Consistency\n\nWebsite navigation provides the primary structure for moving between pages, typically in a header, while the footer is the section at the bottom of every page, offering additional, consistent links to important information.\nBoth enhance user experience (UX) by making content accessible and organized, and footers are crucial for user retention and improved SEO through internal linking.\n\nDepending on the page type, the navigation and footer sections may be required or optional.\n\nIf there is a navigation or footer section in other pages make sure you include those in the current page unless:\n- the user explicitly states it does not want to include it or\n- if it breaks any rules/best practices for the page type.\n\nWhen adding Navigation or Footer sections to a page:\n- If existing navigation/footer content is provided: Use it as a reference for consistency across the site.\n- Only apply consistency when you're actually adding/updating navigation or footer sections.\n- If the chosen Navigation/Footer section has a \"layoutId\", you must pick all the sections that share the same \"layoutId\".\n\n## Landing Pages Only\n\n- Mandatory: Always include Navigation (first) unless the user explicitly states it does not want to include it.\n- Mandatory: Always include Footer (last) unless the user explicitly states it does not want to include it.\n- Always include Hero + Features.\n- Include appropriate call-to-action section (CTA, newsletter signup, contact form, etc.) based on user request.\n- Optionally add FAQ above Footer.\n- Never place two call-to-action sections in a row.\n\n## CMS Collections\n\n- Leave CMS-connected fields connected; never return static text for them.\n- Always make a choice for every collection key in the \"supportedCollections\" record. Do not leave any collection key unassigned.\n- Never return the name \"${CREATE_NEW_COLLECTION_ALIAS}\" in the \"collectionName\" field.\n- The name \"${CREATE_NEW_COLLECTION_ALIAS}\" indicates that you can create a new collection with a new name to represent the appropriate data.\n- If the collection only has one option which is \"${CREATE_NEW_COLLECTION_ALIAS}\", you must flag the collection as new by setting \"new: true\" and providing the name of the new collection.\n- When existing collections are not appropriate, you must create a new collection by setting \"new\" to true, and providing the name of the new collection. The collection name should be unique, one word in most cases, capturing the core concept or subject of the items. Use two words only as a fallback, and only if necessary for uniqueness or clarity.\n- For example, when prompted to create a resume, and when creating a section to show languages with the following supported collections:\nsupportedCollections:\n\tTemplate 1:\n\t- Blog\n\t- ${CREATE_NEW_COLLECTION_ALIAS}\n\tTemplate 2:\n\t- ${CREATE_NEW_COLLECTION_ALIAS}\nsince Blog is not a list of languages, you must create a new collection with \"new: true\" and \"collectionName: \"Languages\". Since Template 2 is used to show language proficiency, you must use it and set \"collectionName: \"Language Proficiency\" and \"new: true\" etc. the final response would include \"collectionBindings\": [ { \"fromTemplateCollection\": \"Template 1\", \"collectionName\": \"Languages\", \"new\": true }, { \"fromTemplateCollection\": \"Template 2\", \"collectionName\": \"Language Proficiency\", \"new\": true } ].\n- If the section has CMS connected fields, identify the groups of fields that are connected to the same collection (same template id in \"collection\" property) and select the appropriate collection from that template's \"supportedCollections\" list and record it in an entry under \"collectionBindings\", making sure \"fromTemplateCollection\" is the template and \"collectionName\" is the collection name.\n- You must choose a single collection per collection template id. Do not mix multiple templates into one collection.\n- Only return entries in \"collectionBindings\" array for collection templates that are actually in use by the section.\n\n## CMS Detail Pages\n\nWhen creating or updating a cms detail page:\n- You must select a combination of sections that either: 1. all share the same \"detailPageTemplateId\" property value or 2. have no \"detailPageTemplateId\" property.\n- You must not select multiple sections with different \"detailPageTemplateId\" property values.\n- All sections that have the property \"detailPageTemplateId\" must reuse the same collection from the \"supportedCollections\" list for the template value of the \"detailPageTemplateId\" property.\n- A section that has the property \"detailPageTemplateId\" must only be used when creating or updating a cms detail page for that template.\n\n---\n\n# State Management and Diffing Rules\n\n## Section Action Rules\n\nFor sections within existing pages:\n\n| Action   | Meaning                                                                             |\n|----------|-------------------------------------------------------------------------------------|\n| add      | Add new section with _layerId: \"\"                                                   |\n| update   | Change section type (_id), content or position                                      |\n| remove   | Mark a section for deletion                                                         |\n| none     | Only use when the section remains in the same position and keeps the same content.\u201D |\n\n- Default to \"update\" action for any 1-to-1 change (changing type/layout, content, or position). Do NOT use \"remove\" + \"add\" when a single existing section maps to a single new section.\n- The ONLY time to use \"remove\" + \"add\" is when one section is explicitly split into multiple sections (1 \u2192 many) or multiple sections are merged into one (many \u2192 1).\n- For many \u2192 1: mark all old sections as \"remove\" and add the new one with \"add\".\n- For 1 \u2192 many: mark old section as \"remove\" and add the new ones with \"add\".\n- Each existing section from the current page structure must appear exactly once with one of these actions: \"update\" (changed), \"remove\" (deleted), or \"none\" (unchanged).\n- When replacing a section with another section with a different _id but the same _layerId, use a single update with the new _id.\n- Never use both remove + update for same _layerId.\n- When replacing 1 section with many, mark the old one as remove and add new ones with add.\n- When performing an \"update\" or \"remove\" action, strictly use the _layerId from the current page structure provided in the user prompt. Never generate/create a _layerId, or reuse _layerId from older responses.\n\n\n| Action   | _layerId Source             | Content Array |\n|----------|-----------------------------|---------------|\n| add      | \"\"                          | Filled        |\n| update   | From most recent response   | Filled        |\n| remove   | From most recent response   | Empty []      |\n| none     | From most recent response   | Empty []      |\n\n### Update Action\n\nUse the \"update\" action when:\n- replacing a section with another section\n- moving a section to a new position\n\nTo replace a section with another section (1 to 1 replacement) follow the steps carefully:\n1. Identify the section we want to replace based on _id and/or description.\n2. Identify the new section to use from the available sections list based on _id and/or description.\n3. Create a diff entry in the same position as the existing section, using:\n\t - the _id of the new section,\n\t - the _layerId of the existing section,\n\t - and the content of the new section.\n\n### Examples\n\n- Replace hero-1 with hero-2 in place\nCorrect:\n{ \"_id\": \"hero-2\", \"_layerId\": \"abc123\", \"action\": \"update\", \"collectionBindings\": [], \"content\": [ ... ] }\n\nIncorrect:\n{ \"_id\": \"hero-2\", \"_layerId\": \"\", \"action\": \"add\", \"collectionBindings\": [], \"content\": [ ... ] },\n{ \"_id\": \"hero-1\", \"_layerId\": \"abc123\", \"action\": \"remove\", \"collectionBindings\": [], \"content\": [] }\n\n---\n\n# Decision Process\n\n1. **Available resources**: Review the available resources provided in the system prompt, including sections and their descriptions, layout patterns, icons, and collections.\n2. **User request analysis**: Review the user request and determine if you are able to fulfill the request with what you have available. If you are not able to fulfill the request because:\n\t - No available sections match what the user is asking for.\n\t - The requested functionality doesn't exist in any available section.\n\t - The request is impossible given the current available sections.\n\t Then you MUST:\n\t - Return ALL existing sections with action: \"none\" and empty content arrays.\n\t - In the message field, clearly explain: \"I couldn't [specific request] because [specific reason].\".\n\t - DO NOT claim you made changes when you didn't.\n\t - DO NOT use action: \"update\" unless you actually found a suitable section to replace with.\n3. **Layout planning**: Only if the request CAN be fulfilled, determine if a layout pattern is suitable for the request. Choose a layout when using a layout provides a clearer or more consistent structure for the page. If a layout pattern is chosen:\n\t\t- You must select all the sections that share the same \"layoutId\" property in the order indicated by the layout pattern.\n\t\t- You must select other sections suitable for the page content. These sections should NOT be present in the layout pattern already.\n3. **Section planning**: Only if the request CAN be fulfilled, determine diffs per section.\n4. **Build atomic update**: Combine all changes into one consistent diff.\n\n---\n\n# Dead Ends\n\nWhen it is clear that the user request is not possible to fulfill, you should elaborate a message to the user explaining why its request is not possible to fulfill.\nNever say you have made changes when there are no sections that fulfill the user request.\n\n---\n\n# Final Reminders\n- Do not forget to review the available layout patterns in the system prompt.\n- Do not forget to review the available sections and its descriptions in the system prompt.\n- Do not forget to review the available icons in the system prompt.\n- Do not forget to review the site-wide consistency reference in the user prompt.\n- Do not forget to review the current page structure in the user prompt.\n- Make sure you are following the rules and process described in the system prompt.\n- Apply all changes atomically.\n- Avoid generic content in section fields.\n- Never output invalid actions or omit unchanged sections.\n- Double-check that every _layerId appears exactly once and in the final desired order.\n- Don\u2019t rely on the message to describe moves; the sections[] list must already reflect them.\n- If nothing changes for a section (content or position), return \\`action: \"none\"\\` and empty content.\n`\n", "import type { ModelMessage, UserModelMessage } from \"ai\"\nimport type { CreatePage, UpdatePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type { Collection } from \"app/ai/utils/collections.ts\"\nimport type { KitSectionUsageData } from \"app/ai/utils/getKitSectionsUsageData.ts\"\nimport {\n\tgetKitSectionsUsageDataForAllWebPages,\n\tgetKitSectionsUsageDataForDesignPageScreens,\n} from \"app/ai/utils/getKitSectionsUsageData.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { KitSection } from \"code-generation/utils/KitSectionStructureCollector.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { assert } from \"library/utils/assert.ts\"\nimport { isNull, isNumber, isString } from \"utils/typeChecks.ts\"\nimport * as yaml from \"yaml\"\nimport { baseSystemPrompt } from \"./systemPrompt.ts\"\n\n/**\n * Builds prompt messages for the LLM from chat history and system context.\n */\nexport async function buildPromptMessages(\n\tengine: VekterEngine,\n\tinitialFeatureRequest: string,\n\tkitSectionsStructure: KitSection[] | undefined,\n\ttask: CreatePage | UpdatePage,\n\tdesignPageId: NodeID | undefined,\n\tkit: WireframerKit,\n\tcreatedCollections: Collection[],\n): Promise<ModelMessage[]> {\n\tconst kitSectionsUsageData = designPageId\n\t\t? getKitSectionsUsageDataForDesignPageScreens(engine, kit, designPageId)\n\t\t: getKitSectionsUsageDataForAllWebPages(engine, kit)\n\n\tconst iconSetsCatalog = await kit.createIconSetsForPrompt()\n\n\tconst collectionNode = isString(task.collection)\n\t\t? engine.tree.getNodeWithTrait(task.collection, isCollectionNode)\n\t\t: undefined\n\n\tconst shouldAllowCMSSections = !designPageId\n\n\tconst systemMessage = await getSystemMessage(\n\t\tkit.getLayoutPatternsPrompt(),\n\t\tkit.getSectionsPrompt(engine.tree, section => {\n\t\t\t// Filter out detail page sections for non-detail page tasks.\n\t\t\tif (!task.collection && section.detailPageCollectionId) return false\n\n\t\t\t// For design pages, filter out sections that have CMS connected fields.\n\t\t\tconst hasCMSConnectedFields = section.fields?.some(field => field.isCMSConnectedField)\n\t\t\tif (!shouldAllowCMSSections && hasCMSConnectedFields) return false\n\n\t\t\t// When updating a detail page, filter out sections that cannot connect to the current\n\t\t\t// collection.\n\t\t\tif (\n\t\t\t\tisString(task.collection) &&\n\t\t\t\t(collectionNode?.createdFromKitSchemaId ?? collectionNode?.id) !== section.detailPageCollectionId\n\t\t\t) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\treturn true\n\t\t}),\n\t\ticonSetsCatalog,\n\t\tkit.prompt,\n\t\tcreatedCollections,\n\t\tkit.getCollectionTemplatesPrompt(),\n\t)\n\n\tconst userMessage = getUserPrompt(\n\t\tinitialFeatureRequest,\n\t\ttask,\n\t\tformatKitSectionsUsageData(kit, kitSectionsUsageData),\n\t\tkitSectionsStructure,\n\t)\n\n\tconst currentDate = new Date().toLocaleDateString(undefined, {\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t})\n\n\tconst currentUser = engine.stores.sessionStore.user\n\n\tconst additionalContextMessage: UserModelMessage = {\n\t\trole: \"user\",\n\t\tcontent: `Here is some additional context that may be relevant:\n            User Name: ${currentUser.name}\n            Date: ${currentDate}`,\n\t}\n\n\treturn [systemMessage, additionalContextMessage, userMessage]\n}\n\nexport function getExistingKitSectionsStructure(\n\tengine: VekterEngine,\n\tdesignPageId: NodeID | undefined,\n\tsectionContainerId: NodeID,\n\tkit: WireframerKit,\n): KitSection[] | undefined {\n\tif (designPageId) {\n\t\treturn engine.stores.aiGenerationStore.getKitSectionsStructure(sectionContainerId, kit)\n\t}\n\n\tconst node = engine.tree.get(sectionContainerId)\n\tif (!isBreakpointVariant(node)) return\n\n\tconst webPage = engine.tree.get(node.parentid)\n\tif (!isWebPageNode(webPage)) return\n\n\treturn engine.stores.aiGenerationStore.getKitSectionsStructure(webPage.id, kit)\n}\n\nfunction replaceId(kit: WireframerKit, section: KitSection | null) {\n\tif (isNull(section)) return section\n\n\treturn {\n\t\t...section,\n\t\t_id: kit.getUniqueTitleBySectionId(section._id),\n\t}\n}\n\n/**\n * The usage data uses the section node id as the key, but we only want to send the unique category\n * name to the LLM.\n */\nfunction formatKitSectionsUsageData(\n\tkit: WireframerKit,\n\tkitSectionsUsageData: KitSectionUsageData | undefined,\n): KitSectionUsageData | undefined {\n\tif (!kitSectionsUsageData) return\n\n\tconst sectionsCount: KitSectionUsageData[\"sectionsCount\"] = {}\n\tfor (const key in kitSectionsUsageData.sectionsCount) {\n\t\tconst category = kit.getUniqueTitleBySectionId(key)\n\t\tconst value = kitSectionsUsageData.sectionsCount[key]\n\t\tassert(isNumber(value), \"Value is number\")\n\t\tsectionsCount[category] = value\n\t}\n\n\treturn {\n\t\tsectionsCount,\n\t\ttopNavigation: replaceId(kit, kitSectionsUsageData.topNavigation),\n\t\ttopFooter: replaceId(kit, kitSectionsUsageData.topFooter),\n\t}\n}\n\nfunction getUserPrompt(\n\tinitialFeatureRequest: string,\n\ttask: CreatePage | UpdatePage,\n\tkitSectionsUsageData?: KitSectionUsageData,\n\texistingStructure?: KitSection[],\n): UserModelMessage {\n\tlet content = `\n        Implement the changes for the page:\n        ${task.instructions}\n\n        Consider the overall feature context:\n        ${initialFeatureRequest}\n        `\n\n\tif (kitSectionsUsageData) {\n\t\tcontent += `\n        Site-Wide Content Consistency Reference (for reference only - NOT current page structure):\n\n        For navigation sections: If you need to add/update navigation, use this content structure for consistency:\n        ${kitSectionsUsageData.topNavigation ? yaml.stringify(kitSectionsUsageData.topNavigation.content) : \"No existing navigation found - if adding a new navigation, generate appropriate navigation content for this page\"}\n\n        For footer sections: If you need to add/update footer, use this content structure for consistency:\n        ${kitSectionsUsageData.topFooter ? yaml.stringify(kitSectionsUsageData.topFooter.content) : \"No existing footer found - if adding a new footer, generate appropriate footer content for this page\"}\n\n        Section Usage Statistics:\n        ${yaml.stringify(kitSectionsUsageData.sectionsCount)}\n\n        IMPORTANT: This is reference data for consistency. You must still generate ALL required content for this specific page based on the user's request.\n        `\n\t}\n\n\tif (existingStructure) {\n\t\tcontent += `Here is the current structure of the page:\n        ${yaml.stringify(existingStructure)}\n        `\n\t}\n\n\treturn { role: \"user\", content }\n}\n\nconst prefixKitPrompt = `# Section Context\n\nDO NOT REFERENCE THIS IN USER RESPONSES. When selecting sections or generating content, consider the following message from the section author:`\n\nconst prefixSectionsSchema = `## Available Sections\n\nDO NOT REFERENCE THIS IN USER RESPONSES. Here are the sections you can choose from:`\n\nconst prefixLayoutPatternsSchema = `## Available Layout Patterns\n\nDO NOT REFERENCE THIS IN USER RESPONSES. Here are the layout patterns you can refer to:`\n\nconst prefixIconSets = `## Icon Sets Catalog\n\nDO NOT REFERENCE THIS IN USER RESPONSES. Here are the available icon sets. Each field that uses icons will reference one of these sets by ID:`\n\nconst prefixCollectionsSchema = `## Existing Collections\n\nDO NOT REFERENCE THIS IN USER RESPONSES. Here are the existing collections and their fields:`\n\nconst prefixTemplateCollections = `## Template Collections\n\nDO NOT REFERENCE THIS IN USER RESPONSES. Here are the template collections and their fields:`\n\nfunction formatPrompt(\n\tsections: string,\n\tlayoutPatterns: string,\n\ticonSets: string,\n\tcollections: string,\n\ttemplateCollections: string,\n\tprompt: string | undefined,\n) {\n\tconst content = `${sections}\\n\\n${layoutPatterns}\\n\\n${iconSets}\\n\\n${collections}\\n\\n${templateCollections}`\n\tif (!prompt) return content\n\treturn `${prefixKitPrompt}\\n\\n${prompt}\\n\\n${content}`\n}\n\nasync function getSystemMessage(\n\tlayoutPatternsPrompt: string,\n\tfilteredSectionsPrompt: string,\n\ticonSetsCatalog: string | undefined,\n\tprompt: string | undefined,\n\tcreatedCollections: Collection[],\n\ttemplateCollections: string,\n): Promise<ModelMessage> {\n\tconst sectionsSchema = `${prefixSectionsSchema}\\n\\n${filteredSectionsPrompt}`\n\tconst layoutPatternsSchema = `${prefixLayoutPatternsSchema}\\n\\n${layoutPatternsPrompt}`\n\tconst iconSetsSchema = iconSetsCatalog ? `${prefixIconSets}\\n\\n${iconSetsCatalog}` : \"\"\n\tconst collectionsSchema = `${prefixCollectionsSchema}\\n\\n${yaml.stringify(createdCollections)}`\n\tconst templateCollectionsSchema = `${prefixTemplateCollections}\\n\\n${templateCollections}`\n\tconst content = `${baseSystemPrompt}\\n\\n${formatPrompt(sectionsSchema, layoutPatternsSchema, iconSetsSchema, collectionsSchema, templateCollectionsSchema, prompt)}`\n\n\treturn { role: \"system\", content }\n}\n", "/**\n * A class that implements an async queue for tasks per item. It waits until the\n * previous task is done and then always starts the latest task\n */\nexport class AsyncQueue<Task extends () => Promise<void> = () => Promise<void>> {\n\tprivate nextTask?: Task\n\tprivate currentTask: Promise<void> | undefined\n\n\tenqueue(task: Task) {\n\t\tthis.nextTask = task\n\t\tvoid this.processQueue()\n\t}\n\n\tprivate async processQueue() {\n\t\tif (this.currentTask) {\n\t\t\treturn // Do not start processing if another task is running for the same item\n\t\t}\n\n\t\tconst task = this.nextTask\n\t\tif (!task) return\n\t\tthis.nextTask = undefined\n\n\t\tthis.currentTask = task()\n\t\tawait this.currentTask\n\t\tthis.currentTask = undefined\n\n\t\t// Continue processing an task that might have been added after this task has started\n\t\tvoid this.processQueue()\n\t}\n\n\tasync done() {\n\t\tif (!this.currentTask) return\n\t\tawait this.currentTask\n\t\tawait this.done()\n\t}\n}\n", "/** Does an in-place shuffle of the provided array. Returns the same array. */\nexport function shuffle<T>(array: T[]): T[] {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tconst j = Math.floor(Math.random() * (i + 1))\n\t\t// @ts-ignore: Suppress the noUncheckedIndexedAccess error on this line.\n\t\t// The logic above makes sure these indexes are correct, and we don't\n\t\t// want to add any inefficiencies by adding extra checks.\n\t\t;[array[i], array[j]] = [array[j], array[i]]\n\t}\n\treturn array\n}\n", "[{\"id\":\"aN9pmCgAn\",\"name\":\"Articles\",\"variables\":[{\"id\":\"oUrnuHZfq\",\"type\":\"string\",\"name\":\"Title\",\"initialValue\":\"\",\"options\":{\"maxLength\":120}},{\"id\":\"MNDPyEtDT\",\"type\":\"slug\",\"name\":\"Slug\",\"initialValue\":\"\",\"associatedStringVariable\":\"oUrnuHZfq\"},{\"id\":\"Oq3rJECoL\",\"type\":\"date\",\"name\":\"Date\",\"initialValue\":\"\"},{\"id\":\"h0H25p5JB\",\"type\":\"image\",\"name\":\"Image\",\"initialValue\":\"data:framer/asset-reference,d4DYq28IaBOSdIBQ1Rp9tTwHVcY.png?originalFilename=Placeholder%403x.png&preferredSize=auto&width=2880&height=1800\",\"defaultValueSuggestions\":[]},{\"id\":\"K1T8kigVr\",\"type\":\"richtext\",\"name\":\"Content\",\"initialValue\":\"\",\"description\":\"\"}]},{\"id\":\"mAOYzN_Xp\",\"name\":\"Updates\",\"variables\":[{\"id\":\"kOcd2RkZy\",\"type\":\"string\",\"name\":\"Title\",\"initialValue\":\"\"},{\"id\":\"xTS8qzuAR\",\"type\":\"date\",\"name\":\"Date\"},{\"id\":\"J4pNnIWfY\",\"type\":\"slug\",\"name\":\"Slug\",\"initialValue\":\"\",\"associatedStringVariable\":\"kOcd2RkZy\"},{\"id\":\"bnv0I682E\",\"type\":\"image\",\"initialValue\":\"data:framer/asset-reference,d4DYq28IaBOSdIBQ1Rp9tTwHVcY.png?originalFilename=Placeholder%403x.png&preferredSize=auto&width=2880&height=1800\",\"name\":\"Image\",\"defaultValueSuggestions\":[]},{\"id\":\"DYPt1neZe\",\"type\":\"richtext\",\"name\":\"Content\",\"initialValue\":\"\",\"description\":\"\"}]}]", "{\"local-module:canvasComponent/MCxea4nTh:default\":[{\"key\":\"GIL6YdmnZ\",\"title\":\"Label\"}],\"local-module:canvasComponent/uPK3M8bwy:default\":[{\"key\":\"N1DFKMWNl\",\"title\":\"Question 1\"},{\"key\":\"lvMeUTpra\",\"title\":\"Answer 1\"},{\"key\":\"hx0b_8Yll\",\"title\":\"Question 2\"},{\"key\":\"nNR17NJf8\",\"title\":\"Answer 2\"},{\"key\":\"HfER0Vust\",\"title\":\"Question 3\"},{\"key\":\"f6MCfUa9_\",\"title\":\"Answer 3\"}],\"local-module:canvasComponent/gKYQrzS7O:default\":[{\"key\":\"BYmjG5xmw\",\"title\":\"Question 1\"},{\"key\":\"S1rbI5BEW\",\"title\":\"Answer 1\"},{\"key\":\"Ngkn2biWE\",\"title\":\"Question 2\"},{\"key\":\"qIWVZ_yRZ\",\"title\":\"Answer 2\"},{\"key\":\"DFXQOiTiW\",\"title\":\"Question 3\"},{\"key\":\"Lbr7U2Fdz\",\"title\":\"Answer 3\"}],\"local-module:canvasComponent/T2TtxMLX8:default\":[{\"key\":\"a12iniMhA\",\"title\":\"Link 1\"},{\"key\":\"wiWjISY2o\",\"title\":\"Link 2\"},{\"key\":\"P1s75ZyNm\",\"title\":\"Link 3\"}]}", "// @ts-nocheck Ignore these files to speed up type checking and reduce memory usage\n// WARNING: This file is autogenerated! Manual edits may get lost!\n\nimport type { Section } from \"../types.ts\"\n\nexport const list: readonly Section[] = [\n\t{\n\tid: \"404-page_1\",\n\tdescription: \"A standalone 404 page for then something went wrong and the URL does not exist. The copy is usually kind of apologetic, describing something went wrong.\\n\\nHas a short title (2 words max) and a short description. Keep all copy punchy and short.\\n\\nBelow the text is a placeholder that says 404.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"RCBChp_6F\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_404-page_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_1\",\n\tdescription: \"A personal portfolio page that spans the viewport height, with big project titles below with inline images/placeholders/visuals mixed in the text. The project titles have to have 1 word titles. NEVER MORE THAN 1 WORD FOR THE PROJECT TITLES.\\n\\nThere are 10 projects total. The first 9 end with a comma. The last one has a period. So it looks like a single sentence with inline imagery.\\n\\nKeep the title short and punchy, preferably one word.\\n\\nThis is the only section with inline images.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"frLh1884e\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_2\",\n\tdescription: \"A simple personal page and about page, text-based with three paragraphs (around 200 characters each) that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and three paragraphs of copy, followed by a personal signature and copyright statement. The layout is left aligned.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"wJqREtJux\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_3\",\n\tdescription: \"A simple personal page and about page, text-based with three columns for projects, articles, and experience, that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and three columns with titles and short descriptions, a personal signature and copyright statement. The layout is left aligned.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\n\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"YzRTLBNDU\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_4\",\n\tdescription: \"A simple personal page and about page, text-based with two paragraphs (around 200 characters per paragraph) that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and two paragraphs of copy, followed by a call to action button, followed by a logo string with company names the individual/company has partnered with or worked with. Below that a copyright statement.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\n\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"wXApaxmuU\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_5\",\n\tdescription: \"A simple personal page and about page, text-based with three paragraphs (around 200 characters each) that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and three paragraphs of copy, followed by a set of buttons/links that point to other places you can find the person/company, and finally a personal signature. The layout is left aligned. Do not use full links in the social link buttons, but use nice capitalized labels.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\n\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"I__KaKgSb\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_6\",\n\tdescription: \"A simple personal page and about page, text-based with two paragraphs (around 200 characters per paragraph) that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and two paragraphs of copy, a button, a list with icons, a logo string, and a copyright statement.\\n\\nBelow the paragraph is a call to action button. Below the button there is a list of items where the text is prefixed with icons. This list is suitable for things like listing benefits of working with the studio/person/company, or services they offer (list of services).\\n\\nThe list is followed by a logo string with company names the individual/company has partnered with or worked with. Below that a copyright statement.\\n\\nKeep the list items short, 4 or less words max. Prefer simple icons.\\n\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\n\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"UAFzCjwyq\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"about_7\",\n\tdescription: \"A simple personal page and about page, text-based with two paragraphs (around 200 characters per paragraph) that is well suited for a personal studio or one-man-company too.\\n\\nThe page contains a logo, title, role, and two paragraphs of copy, a button, a list with icons, and a copyright statement.\\n\\nBelow the paragraph is a call to action button. Below the button there is a list of items where the text is prefixed with icons. This list is suitable for things like listing benefits of working with the studio/person/company, or services they offer (list of services).\\n\\nThe list is followed by a copyright statement.\\n\\nKeep the list items short, 4 or less words max. Prefer simple icons.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\\n\\nSwapping an about section with another about section makes for a great suggestion. Like adding links, adding a signature, adding a button, adding a logo string, or adding a list of services.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"C8Iz_pqj9\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_about_7.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_1\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline.\\n\\nBelow are posts, with a placeholder asset on the left, followed by the blog post title and date on the right. Here the blog posts are spread across 2 columns. No one specific post is featured here.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"FNOFjAJYO\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_2\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline. Blog titles are short and punchy too.\\n\\nBelow are posts with a placeholder asset on top of each post, and title and date below. So the posts are more like cards, arranged horizontally in a row, with bigger post images. No one specific post is featured here.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"sx6SM_NI8\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_3\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline. Blog titles are short and punchy too.\\n\\nBelow are posts with a placeholder asset on top of each post, and title and date below. So the posts are more like cards, arranged in a grid in a 2 column layout with bigger post images. No one specific post is featured here.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"aflQducpm\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_4\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline.\\n\\nBelow are posts, with a placeholder asset on the left, followed by the blog post title and date on the right. So the layout is more like a list, with blog post items stacked vertically, and small post images. No one specific post is featured here.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"TE_H3g09N\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_5\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline.\\n\\nDirectly below is a big featured blog post where the image spans the full width. The latest bog post is highlighted and featured.\\n\\nBelow that are posts, with a placeholder asset on the left, followed by the blog post title and date on the right. So the layout is more like a list, with blog post items stacked vertically, and small post images.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"N6b8QROul\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog_6\",\n\tdescription: \"This section represents the index page of a blog. Could be a personal blog or a company blog. It has a short title (often Blog) and a punchy subline. Blog titles are short and punchy too.\\n\\nBelow are posts, with a placeholder asset on top of each post, and title and date below. So the posts are more like cards, arranged in a grid in a 3 column layout with bigger post images. No one specific post is featured here.\\n\\nFor dates prefer Full month name (US style) formatting.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"SIeCaSOFf\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"blog-post_1\",\n\tdescription: \"This section represents the detail page of a specific blog post. The blog post has a header.\\n\\nSubtitles have to be short. But the content paragraphs have to be 5+ sentences long, like a real blog post.  Use H2s as subtitles unless specified in prompt. Default to 3 paragraphs unless specified in prompt.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"J5XbfCbzF\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_blog-post_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"contact-form_1\",\n\tdescription: \"A contact form section with input fields for name, email, and message. Message is a text area. There\u2019s a Submit button too, often just labelled \\\"Submit\\\".\\n\\nAbove the contact form there is a short title and an extremely short subtitle.\\n\\nThis section is usually near the bottom, above the footer, and usually only for landing pages.\\n\\nThe contact form is centered.\\n\\nIf a page contains a newsletter CTA it does not need this section.\\n\\nThis section is especially optimized for landing pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"EvmkIFS80\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_contact-form_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"contact-form_2\",\n\tdescription: \"A contact form section with three input fields: name, email, and message. The message is a textarea input. There\u2019s a Submit button too, often just labelled \\\"Submit\\\".\\n\\nThe form is left aligned. This contact section works especially well on personal/about pages.\\n\\nThis section is usually near the bottom, above the footer.\\n\\nIf a page contains a newsletter CTA it does not need this section.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Wnn5LSxLN\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_contact-form_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"cta_1\",\n\tdescription: \"A call to action (CTA) section that presents a newsletter signup form, designed to collect email addresses for updates and communication.\\n\\nCentered on the background are two lines of text. The first line is in bold, black letters, while the second is in a lighter gray, providing very short, less-than-4-word taglines.\\n\\nBelow the text is an input field for email addresses.  Directly beneath the input field is a black button where the title is often \\\"Submit.\\\"\\n\\nThis type of section is typically used to build an email list for marketing, announcements, or updates.\\n\\nThis section is usually near the bottom, above the footer, and usually only for landing pages.\\n\\nIt\u2019s important the headings here are short and punchy. Less than 3 total words in total. Never 4 or more words per line here. Use sentence case and add punctuation.\\n\\nIf a page contains a contact form it does not need this section. This section is mostly for landing pages.\\n\\nNever use straight quotes in copy.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"UO38_IawR\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_cta_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"cta_2\",\n\tdescription: \"A call to action (CTA) section with a button instead of a form. Always placed above a footer, always near the bottom of the badge.\\n\\nIt contains a centered tagline in bigger, bold text. Punchy and short. Below that it contains a subline. And below the subline is a powerful call to action button. This section is mostly for landing pages.\\n\\nThe copy is short and punchy, always. Never long.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Oeyhlg3cn\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_cta_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"download-page_1\",\n\tdescription: \"A download page for a product or service. Often to download a desktop app for platforms like macOS, Windows, iOS, Android, Linux, and more.\\n\\nThe copy is centered, very short and punchy. Keep the max length of tagline around 20 or less.\\n\\nBelow the copy is a download button. Below that a placeholder visual.\\n\\nDo not suggested more detailed descriptions or taglines here.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"ShoRCgHBz\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_download-page_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"faq_1\",\n\tdescription: \"This section presents an interactive FAQ (Frequently Asked Questions) component, designed to provide users with quick answers to common queries.\\n\\nThis section is usually near the bottom of a page, near the footer. Never standalone. Only ever add one FAQ per page.\\n\\nHere, expanding one item closes all others. This FAQ contains 3 questions and thus 3 answers.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"i6c4iVbHO\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_faq_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"faq_2\",\n\tdescription: \"This section presents an interactive FAQ (Frequently Asked Questions) component, designed to provide users with quick answers to common queries.\\n\\nThis section is usually near the bottom of a page, near the footer. Never standalone. Only ever add one FAQ per page.\\n\\nHere, expanding one item does not close all others, you can open as many as you like. This FAQ contains 3 questions and thus 3 answers.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"kBymwr1J5\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_faq_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"feature-summary_1\",\n\tdescription: \"A smaller feature section that can be added to landing pages (not as the leading feature section, but as extra section)\\n\\nContains 4x1 columns of short features with big icons above, and the feature heading below. Prefer simple icons.\\n\\nMake the copy fit with the icon above it by default.\\n\\nMake the copy the same length, of extremely similar, across all features. A nice default is all of them having two words.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"yaQs3weX1\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_feature-summary_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"feature-summary_2\",\n\tdescription: \"A smaller feature section that can be added to landing pages (not as the leading feature section, but as extra section)\\n\\nContains 4x2 columns of short features with big icons above, and the feature heading below. So total of 8 features here.\\n\\nPrefer simple icons.\\n\\nMake the copy fit with the icon above it by default.\\n\\nMake the copy the same length, of extremely similar, across all features. A nice default is all of them having two words.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"RdjkJYWOQ\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_feature-summary_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"features_1\",\n\tdescription: \"This section presents a feature section with a grid-based (or alternating) layout designed to showcase key features or benefits of a product or service. The feature block is composed of alternating text and visual elements, creating a dynamic and engaging arrangement.\\n\\nThe text elements provide a few lines with descriptions of features. The titles are short and punchy, and have proper punctuation. Always write \\\"sentence case\\\" titles, never use \\\"title case\\\" for titles. Try to use a similar total amount of letters/characters for all descriptions.\\n\\nThis type of section is typically used to highlight key selling points or unique features of a product or service.\\n\\nThis section would likely be placed within the main content area of a webpage, often below a hero section or introductory content. It serves to elaborate on the initial message and provide more detailed information about the product or service. \\n\\nUnless specifically asked for, sections like these do not work standalone, almost always below a header.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"TuKDEPksR\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_features_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"features_2\",\n\tdescription: \"This section presents a feature section with a row-based layout of two card-like blocks to showcase key features or benefits of a product or service. There\u2019s a visual and text below it.\\n\\nThe text elements provide concise descriptions of features. The titles are short and when possible can be just two words, followed with a period and written in sentence case. Always write \\\"sentence case\\\" titles, never use \\\"title case\\\" for titles. Try to use a similar total amount of letters/characters for all descriptions.\\n\\nThis type of section is typically used to highlight key selling points or unique features of a product or service.\\n\\nThis section would likely be placed within the main content area of a webpage, often below a hero section or introductory content. It serves to elaborate on the initial message and provide more detailed information about the product or service. \\n\\nUnless specifically asked for, sections like these do not work standalone, almost always below a header. This type of feature section is less common than the alternating one.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"kzr2d1m6X\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_features_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"features_3\",\n\tdescription: \"This section presents a feature section with a row-based layout of three blocks to showcase key features or benefits of a product or service. There\u2019s a visual and text below it.\\n\\nThe text elements provide concise descriptions of features. The titles are short and when possible can be just one or two words, followed with a period and written in sentence case. Always write \\\"sentence case\\\" titles, never use \\\"title case\\\" for titles. Try to use a similar total amount of letters/characters for all descriptions.\\n\\nThis type of section is typically used to highlight key selling points or unique features of a product or service. It aims to provide a quick overview and entice users to learn more.\\n\\nThis section would likely be placed within the main content area of a webpage, often below a hero section or introductory content.\\n\\nUnless specifically asked for, sections like these do not work standalone, almost always below a header.\\n\\nThis section has a 3 column layout. This type of feature section is less common than the alternating one.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"ZhKS1NRPt\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_features_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"features_4\",\n\tdescription: \"This section presents a feature section with a row-based layout of three cards to showcase key features or benefits of a product or service. This has the text/copy on top of the card, instead of below it. It also has less copy, it\u2019s better suited as clickable cards to other pages.\\n\\nTitles here are punchy, short, preferably single words, never sentences. The subtitle here is more like a badge. Keep it one word if possible.\\n\\nThis section has a 3 column card layout. This type of feature section is less common than the alternating one.\\n\\nHere, the text is positioned near the bottom of the cards. So image placeholders first, in the middle, then text near the bottom of each card.\\n\\n\\nThis type of section is typically used to highlight key selling points or unique features of a product or service. It aims to provide a quick overview and entice users to learn more.\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"zKl8dvxs1\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_features_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_1\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring two columns and a logo. Logo on the left, links on the right. It has 6 links total. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"ZnSlx7Y29\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_2\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring three columns and a logo. Logo on the left, links on the right. It has 9 links total. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"kli8uRkNi\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_3\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring four columns and a logo. Logo on the left, links on the right. It has 12 links total. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"A60UG_9LI\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_4\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring three columns and a logo, and a few social media icons. The logo is on the left, links are centered the middle, and the social media icons are positioned on the far right. It has 9 links in total. Only suggest this variant when people specfiically ask for social icons in the footer. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"LGF1VpTVL\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_5\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring four columns and no logo. So this is a more specific footer variant without a logo (instead, text-based) and with four columns, and 12 links total. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"qgmxrWK4O\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"footer_6\",\n\tdescription: \"This section represents a typical website footer, designed to provide essential navigation at the end of a webpage. \\n\\nThe primary purpose is to offer users quick access to key areas of the website.\\n\\nThe layout is clean and minimal, featuring five columns and no logo. So this is a more specific footer variant without a logo (instead, text-based) and with four columns, and 15 links total. Each column has 1 title (on top, first item in the list) and 3 links.\\n\\n\\nA footer is always positioned at the very bottom of a webpage. It acts as the final element, appearing after all the main content. It is generally not used elsewhere on a webpage.\\n\\nFooters are common on landing pages, saas pages, but not on personal pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"JgXiEf68M\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_footer_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"grid_1\",\n\tdescription: \"This section presents a grid of four visual elements, each contained within a square frame. The squares are arranged in a 2x2 layout, creating a balanced and symmetrical composition.\\n\\nEach square displays an image or video, serving as a visual representation of content or options. The images or videos could be static or dynamic, depending on the purpose of the section.\\n\\nThis type of grid is typically used for image galleries, video showcases, product grids, or any scenario where multiple visual elements need to be displayed in a concise and organized manner. The square format provides a consistent and visually appealing way to present visual content.\\n\\nThis section would likely be placed within the main content area of a webpage, particularly on pages dedicated to showcasing images or videos.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"SY8Junh20\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_grid_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_1\",\n\tdescription: \"This section presents a simple header / hero designed to capture attention and convey a concise message. Pages only have 1 header/hero.\\n\\nCentered are two lines of text. The first line is in bold, black letters. The second line is in a lighter shade of gray. The text is short and punchy.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site. It serves to immediately inform visitors about the key offerings or selling points.\\n\\nThis section is a header. Almost always on top, below a navigation bar. Great for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"aGNpHbZbm\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_2\",\n\tdescription: \"This section presents a simple header / hero designed to capture attention and convey a concise message. Pages only have 1 header/hero.\\n\\nCentered are two lines of text. The first line is in bold, black letters. The second line is in a lighter shade of gray. The text is short and punchy.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site. It serves to immediately inform visitors about the key offerings or selling points.\\n\\nThis section is a header. Almost always on top, below a navigation bar. Great for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods. \\n\\nThis version has a call to action (cta) button below the copy. Useful for products that can be signed up for, or downloaded.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"fNWu7Z3Fu\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_3\",\n\tdescription: \"This section presents a simple header / hero designed to capture attention and convey a concise message. Pages only have 1 header/hero.\\n\\nCentered are two lines of text. The first line is in bold, black letters. The second line is in a lighter shade of gray. The text is short and punchy.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site. It serves to immediately inform visitors about the key offerings or selling points.\\n\\nThis section is a header. Almost always on top, below a navigation bar. Great for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods. \\n\\nThis version has two call to action (cta) buttons below the copy. Useful for products that can be signed up for, or downloaded. One primary and one secondary button.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"svZWrbkKW\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_4\",\n\tdescription: \"This section presents a simple header / hero with banner designed to capture attention and convey a concise message.  Pages only have 1 header/hero.\\n\\nLeft-aligned are two lines of text. The first line is in bold, black letters.  The second line, slightly smaller and is in a lighter shade of gray.  The text is straightforward and aims to be both informative and slightly playful.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site. It serves to immediately inform visitors about the key offerings or selling points.\\n\\nThis hero variant has a banner (placeholder asset, image) below the copy. And this hero variant has left-aligned text/copy.\\n\\nGreat for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nIf this section is added to page, don't add another logo string section by default.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"cRTdLDAZ6\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_5\",\n\tdescription: \"This section presents a simple header / hero with banner designed to capture attention and convey a concise message.  Pages only have 1 header/hero.\\n\\nCentered are two lines of text. The first line is in bold, black letters.  The second line, slightly smaller and is in a lighter shade of gray.  The text is straightforward and aims to be both informative and slightly playful.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site.\\n\\nThis hero variant has a banner (placeholder asset /image).\\n\\nGreat for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"FFcsbAcS0\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_6\",\n\tdescription: \"This section presents a simple header / hero with banner designed to capture attention and convey a concise message.  Pages only have 1 header/hero.\\n\\nCentered is a very big punchy single-word title. No description below it, just the title. This ONLY works with there is a single short word. Has bigger font size than other heros. Is our punchiest header.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site.\\n\\nThis hero variant has a banner (placeholder asset /image).\\n\\nGreat for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"XxSbv9vH4\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_7\",\n\tdescription: \"This section presents a simple header / hero with banner designed to capture attention and convey a concise message.  Pages only have 1 header/hero.\\n\\nCentered are two lines of text. The first line is in bold, black letters.  The second line, slightly smaller and is in a lighter shade of gray.  The text is punchy. Below the text is a single call to action button with a single word label.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site.\\n\\nThis hero variant has a banner (placeholder asset /image). So it has text, CTA button, and a banner image.\\n\\nGreat for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"slq3dxciP\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_7.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"hero_8\",\n\tdescription: \"This section presents a simple header / hero designed to capture attention and convey a concise message. Pages only have 1 header/hero.\\n\\nCentered are two lines of text. Above the text there is a logo/graphic/image placeholder. Here that placeholder is small, like a logo. The first line is in bold, black letters. The second line is in a lighter shade of gray. The text is short and punchy.\\n\\nThis type of hero section is typically used at the top of a landing page to introduce the main topic or purpose of the site. It serves to immediately inform visitors about the key offerings or selling points.\\n\\nThis section is a header. Almost always on top, below a navigation bar. Great for landing pages, SaaS pages, etc. These types of pages ALWAYS need a header.\\n\\nKeep the copy punchy and short. Ideally 2-3-4 words max. With periods. \\n\\nThis version has two call to action (cta) buttons below the copy. Useful for products that can be signed up for, or downloaded. One primary and one secondary button.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"ZomKCcGkN\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_hero_8.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"link-in-bio_1\",\n\tdescription: \"This section represents a personal landing page or \\\"link in bio\\\" style website, designed to consolidate various online presences and content in one place.\\n\\nAt the top, a small profile picture / user avatar is displayed, followed by a user handle, title, and social icons. The central element is a placeholder for an image or a video. It has 3 social icons.\\n\\nBelow the placeholder, there are buttons / links.\\n\\nThis type of section is typically used by individuals, artists, or creators to gather their online presence and direct their audience to various content and platforms.\\n\\nThis section would likely be used as a standalone landing page, often linked from social media profiles or other online platforms.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"xa6kFpAGk\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_link-in-bio_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"link-in-bio_2\",\n\tdescription: \"This section represents a personal landing page or \\\"link in bio\\\" style website, designed to consolidate various online presences and content in one place.\\n\\nAt the top, a small profile picture / user avatar is displayed, followed by a user handle, title, and social icons. The central element is a placeholder for an image or a video. It has 4 social icons.\\n\\nBelow the placeholder, there are buttons / links.\\n\\nThis type of section is typically used by individuals, artists, or creators to gather their online presence and direct their audience to various content and platforms.\\n\\nThis section would likely be used as a standalone landing page, often linked from social media profiles or other online platforms.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"zBq6MguhU\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_link-in-bio_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"link-in-bio_3\",\n\tdescription: \"This section represents a personal landing page or \\\"link in bio\\\" style website, designed to consolidate various online presences and content in one place.\\n\\nAt the top, a small profile picture / user avatar is displayed, followed by a user handle, title, and social icons. The central element is a placeholder for an image or a video. It has 5 social icons.\\n\\nBelow the placeholder, there are buttons / links.\\n\\nThis type of section is typically used by individuals, artists, or creators to gather their online presence and direct their audience to various content and platforms.\\n\\nThis section would likely be used as a standalone landing page, often linked from social media profiles or other online platforms.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"f31x95Coi\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_link-in-bio_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"list_1\",\n\tdescription: \"A list section with titles on the left, and dates on the right. Titles are short and punchy. Dates are most often just standalone years, less often ranges.\\n\\nThis list section can be added to any page when specifically requested, but mostly are for landing pages. This list is not super common for \\\"about\\\" or \\\"personal\\\" pages.\\n\\nThe dates should really be dates, not descriptions.\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"AR4n8hSyA\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_list_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_1\",\n\tdescription: \"A logo string section with 3 logos, listing company names.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"oN9C85EpC\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_2\",\n\tdescription: \"A logo string section with 4 logos, listing company names.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"v1apvyQ11\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_3\",\n\tdescription: \"A logo string section with 5 logos, listing company names.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"hOW2AY_cu\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_4\",\n\tdescription: \"A logo string section with 3 logos, listing company names.\\n\\nHere, the distribution is set to \\\"space between\\\" so it occupies the full width.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"laNloVlFk\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_5\",\n\tdescription: \"A logo string section with 4 logos, listing company names.\\n\\nHere, the distribution is set to \\\"space between\\\" so it occupies the full width.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Jfgyk3aoU\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"logo-string_6\",\n\tdescription: \"A logo string section with 5 logos, listing company names.\\n\\nHere, the distribution is set to \\\"space between\\\" so it occupies the full width.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"tMtLEWT_7\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_logo-string_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_1\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. On the far right, a set of three text links is displayed.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"lV5Asewa4\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_2\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. On the far right, a single call-to-action button, which is the main action button, like a download or signup or 'try for free' action.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"N2p91WpO2\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_3\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. On the far right, two buttons. Both with short actionable titles, like call-to-actions. One button is styled like a primary button, and the other is a secondary button.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"GooKi97Xv\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_4\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented. On the far left is a logo. In the middle, three links, and on the far right, a call to action button. So here, there are also links in the middle.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"dujNe6NjX\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_5\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. In the middle, three links, and on the far right, a set of social media icons. So there are text links in the middle, and icons on the far right.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"l_FDs3Ecg\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_6\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with links centered in the middle, and no logo. There are three links total. There is no logo and there is no main button.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Q3K61NEBI\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_7\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with links spaced equally, filling the entire width of the navigation (space between). There are 5 links total.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"h7w8tTHHM\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_7.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_8\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented. Two links are on the left, the logo is in the middle/center, and two more links on the right. So only links, no site name here.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"iyYqy4Pk0\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_8.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_9\",\n\tdescription: \"This section presents a navigation element, designed for quick access to key pages or resources within a website.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. On the far right, a set of three text links is displayed.\\n\\nThis navigation is a component with variants. The phone variant (for the phone breakpoint) has the links collapsed under a menu (burger icon with 2 lines). You can then click the icon, which turns into a close (x) icon, and that expands the menu, revealing the links. Suggest this navigation when people ask for a component, or for collapsed links on mobile, or for an expanding and collapsing interaction.\\n\\nThis section would always be positioned at the top of a webpage. It would provide primary navigation. There should only be one instance of this section in a page. Finally, this section is not necessary on all pages; it depends on the context and whether the site needs navigation.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"f2btV104U\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_9.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_10\",\n\tdescription: \"This section is a navigation bar. It is taller than usual.\\n\\nIt is a taller (in height) navigation with 3 columns. Left is a logo and title, and on the right there are 2 columns with vertical lists of 3 links each. So it has 6 links in total. In between the links there is a border, and below the navigation a border too.\\n\\nThe three titles here are dimmed and typed in all-caps. It would be best if these are kept shorter and if they only were one word each.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"QU3tgVpVm\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_10.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_11\",\n\tdescription: \"This section is a navigation bar.\\n\\nThere is a logo on the left and a menu button on the right. All links are collapsed on all breakpoints, also on Desktop. You can hover the menu button and it reveals a relative overlay (an overlay popover/menu appears) containing 3 links.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"jwb7fPPLq\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_11.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_12\",\n\tdescription: \"This section is a navigation bar.\\n\\nOn the far left and far right, two small short succint titles in all caps. There is a menu button in the center. All links are collapsed on all breakpoints, also on Desktop. You can hover the menu button and it reveals a relative overlay (an overlay popover/menu appears) containing 3 links.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"CPlabeRcK\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_12.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_13\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo, there is no title. On the far right are three navigation links, within pills (so they have a colored background and border radius).\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"H5EsTDwXp\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_13.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_14\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a logo. In the middle, three links. All links are pills, with a background and border-radius. On the far right, a call to action button.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"UjcVdfWVz\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_14.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_15\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a short page title or site name in text with an R symbol (\u00AE). Make sure it\u2019s still a real legible word. On the far right, a set of three text links is displayed.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"xf2hPwTfu\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_15.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_16\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. On the far left is a short page title or site name in text with an R symbol (\u00AE). Make sure it\u2019s still a real legible word. On the far right are three navigation links, within pills (so they have a colored background and border radius).\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"u2MhXJGhr\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_16.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_17\",\n\tdescription: \"This section is a navigation bar. Links are displayed horizontally. On the far left there is a logo.\\n\\nIt has 3 links, and each link has a small subtitle that is dimmed. The subtitle is displayed in uppercase (capital) letters.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"EFfXZJuUa\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_17.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_18\",\n\tdescription: \"This section is a navigation bar. Links are displayed horizontally. On the far left there is a logo.\\n\\nIt has 3 links, and each link has a small number on the top-right of it, like 01, 02, and 03, highlighting which link number it is.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"epElsZyet\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_18.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_19\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles, and the links right next to the site title. So the links are on the left side of the navigation, and the right side of the site name (which is the leftmost element).\\n\\nOn the far right, a CTA button styled in a secondary-button style, so it does not draw too much attention. So the button is there, but generally subtle.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. Make sure the page title/site name is still a real legible word.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"OMdouOFAA\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_19.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_20\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles, and the links right next to the site title. So the links are on the left side of the navigation, and the right side of the site name (which is the leftmost element).\\n\\nOn the far right, a CTA button styled in a primary button style. So the button is bolder and more visible.\\n\\nThe layout is horizontally oriented, with elements aligned from left to right. Make sure the page title/site name is still a real legible word.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"i4RFQYlii\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_20.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_21\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles. There are 3 links in total. The logo and the 3 links are spaced evenly within the horizontal layout, from left to right, filling the entire width of the navigation.\\n\\nMake sure the page title/site name is still a real legible word.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"QQmvh_55u\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_21.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_22\",\n\tdescription: \"This section is a navigation bar with a text based logo on the left, useful for page names and site titles. There are 4 links in total. The logo and the 4 links are spaced evenly within the horizontal layout, from left to right, filling the entire width of the navigation.\\n\\nMake sure the page title/site name is still a real legible word.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"RhDakjDwn\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_22.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"navigation_23\",\n\tdescription: \"This section is a navigation bar.\\n\\nThe layout is horizontally oriented. The logo is in the middle. There are no links at all, no text, just the logo image in the middle.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"QI6GqKsnj\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_navigation_23.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"one-paragraph_1\",\n\tdescription: \"A text based section with a title and 2 paragraphs of content. Each paragraph has about 200 characters of text by default.\\n\\nThis section works best when added to personal pages, like portfolio or about pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"jCMcbExug\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_one-paragraph_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"paragraph-big_1\",\n\tdescription: \"A paragraph section for landing page descriptions, optimized to be placed below the header. Here the description is left-aligned.\\n\\nThe first line is highlighted in a black, the second line in gray. Make sure that copy-wise that makes sense.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"eOUT21fe1\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_paragraph-big_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"paragraph-big_2\",\n\tdescription: \"A paragraph section for landing page descriptions, optimized to be placed below the header. Here the description is centered.\\n\\nThe first line is highlighted in a black, the second line in gray. Make sure that copy-wise that makes sense.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"e8rJM_GgA\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_paragraph-big_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"placeholder_1\",\n\tdescription: \"A placeholder visual element/banner/image placeholder. Can be placed in between two text-based sections, like after a header/hero and before a FAQ/newsletter section, for example.\\n\\nThis is a section that can be replaced with a image or video, so it serves as a big image placeholder or a big video placeholder.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"xX1JOtVsR\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_placeholder_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_1\",\n\tdescription: \"A simple personal page and personal portfolio page with a list of projects. It has a profile picture/avatar, followed by the user name and a description. The description text provides context or an introduction to the individual or the work being presented. By default the description should be around 200 characters total.\\n\\nBelow the introductory text, a list of project titles and dates is presented.\\n\\nThis section is particularly suitable for personal pages and portfolio-focused pages.\\n\\nDo not use date ranges here for the project list, only use date ranges for the copyright years with the copy right symbol. The dates should really be dates, not descriptions.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"D9F_k6a1o\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_2\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, there is a list of projects, followed by a grid of projects with visual previews. \\n\\nThis section is not super common, it is a unique combination, to be provided in case people ask for both a list and a grid within a single page.\\n\\nThe dates should really be dates, not descriptions.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Fzl7ESv1R\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_3\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work. This page could also serve as a photo gallery in a 2x2 grid layout.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, a grid of projects with visual previews.\\n\\nThis section is suitable for personal pages and portfolio-focused pages. It serves as a central hub for presenting information about an individual.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"aXlcrXtZg\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_4\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work. This page could also serve as a photo gallery in a 2x3 grid layout.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, a grid of projects with visual previews.\\n\\nThis section is suitable for personal pages and portfolio-focused pages. It serves as a central hub for presenting information about an individual.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Yf5eMzh3x\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_5\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work. This page could also serve as a photo gallery in a 3x2 grid layout.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, a grid of projects with visual previews.\\n\\nThis section is suitable for personal pages and portfolio-focused pages. It serves as a central hub for presenting information about an individual.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"ZFgziqzjP\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_5.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_6\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work. This page could also serve as a photo gallery in a 3x3 grid layout.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, a grid of projects with visual previews.\\n\\nThis section is suitable for personal pages and portfolio-focused pages. It serves as a central hub for presenting information about an individual.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"YyC4g8N2d\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_6.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"portfolio_7\",\n\tdescription: \"A personal page and portfolio page with a grid of visual items, meant for showcasing work.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nThis section is suitable for personal pages and portfolio-focused pages. It serves as a central hub for presenting information about an individual.\\n\\nBelow the introductory text, a grid of projects with visual previews, dates and titles. Each visual preview (grid item) has a project title and a date below it. So it\u2019s a grid view with titles and dates, so visuals plus text.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"BEFqEkiWw\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_portfolio_7.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"press-page_1\",\n\tdescription: \"A press page with top stories about a company or service.\\n\\nIt contains a title followed by a few lines describing what the company does. Keep all copy short and punchy, especially the titles.\\n\\nBelow the text is a row of articles / top stories / posts with placeholder visuals, a title, and a date.\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"dTmBIIZf5\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_press-page_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"pricing-page_1\",\n\tdescription: \"This section represents a standalone pricing page. It has three tiers, with unique names, prices, and features.\\n\\nTitle is often just \\\"Pricing\\\". Listed items/features are short.\\n\\nButton labels are often \\\"Sign Up\\\".\\n\\nKeep the prices just numbers with a currency symbol. Keep the subtitle extremely short and punchy and only use short words for it.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"xw_4psTy1\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_pricing-page_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"pricing-section_1\",\n\tdescription: \"This section represents a pricing section part of a landing page, usually near the bottom of the page close to the footer, above a CTA/call to action section.\\n\\nIt has three tiers, with unique names, prices, and features.\\n\\nTitle is often just \\\"Pricing\\\". Listed items/features are short. The subtitle below pricing is extremely short and punchy. The button labels are often something like \\\"Sign Up\\\".\\n\\nKeep the prices just numbers with a currency symbol, don't include things like \\\"monthly\\\" in the price. Keep the subtitle extremely short and punchy and only use short words for it.\\n\\nThis section has a 3 column layout.\\n\\nThis section is mostly for landing pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"zW3bXAEjV\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_pricing-section_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"pricing-section_2\",\n\tdescription: \"This section represents a pricing section part of a landing page, usually near the bottom of the page close to the footer, above a CTA/call to action section.\\n\\nIt has two tiers, with unique names, prices, and features.\\n\\nTitle is often just \\\"Pricing\\\". Listed items/features are short. The subtitle below pricing is extremely short and punchy. The button labels are often something like \\\"Sign Up\\\".\\n\\nKeep the prices just numbers with a currency symbol, don't include things like \\\"monthly\\\" in the price. Keep the subtitle extremely short and punchy and only use short words for it.\\n\\nThis section has a 2 column layout.\\n\\nThis section is mostly for landing pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"PPkHpNH6J\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_pricing-section_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"projectSection_1\",\n\tdescription: \"A section with a visual / image / placeholder on top, and a (project) title and description below. The description can be around 200-300 characters long by default. Well suited as optional additions to personal pages.\\n\\nIdeal for showcasing a project, your work, a video, and more.\\n\\nAdd these below existing sections, not on top of the page.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"U1SVJO7Zt\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_projectSection_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"resume_1\",\n\tdescription: \"This section represents a personal page detailing someone's career trajectory. It is a CV and resume, with professional experience, designed to provide an overview of someone\u2019s background and skills.\\n\\nAt the top left, a small profile picture / user avatar is displayed, followed by the user name and a paragraph of text: the personal description. This description provides context or an introduction to the individual or the work being presented. The description can be a few sentences, like roughly 200 characters is ideal.\\n\\nBelow the introductory text, three square containers are arranged horizontally. Each container features an image or video, potentially representing different projects or experiences.\\n\\nFurther down, a list of professional experiences is presented in a timeline format. Each entry includes a date range, job title, and company name, along with a brief description of responsibilities and achievements. The entries are sorted in reverse chronological order, providing a clear progression of the individual's career. So most recent one on top, oldest one below. Use date ranges with en-dashes.\\n\\nThis type of section is typically used for personal websites, portfolios, or \\\"About Me\\\" pages. It aims to provide a comprehensive overview of an individual's background, skills, and experience.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"KooXEYan0\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_resume_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"resume_2\",\n\tdescription: \"This section represents a simple text based layout and is a type of standalone personal page. It is also a CV and resume, with professional experience, designed to provide an overview of someone\u2019s background and skills.\\n\\nAt the top left, a small profile icon is displayed, followed by the user name and a subtitle highlighting the user role.\\n\\nFurther down, a list of professional experiences is presented in a timeline format. Each entry includes a date range, job title, and company name, along with a brief description of responsibilities and achievements. The entries are sorted in reverse chronological order, providing a clear progression of the individual's career. So most recent one on top, oldest one below. Use date ranges with en-dashes.\\n\\nThis is a resume / CV page / about page.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"yyWmAj4q0\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_resume_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"row-three_1\",\n\tdescription: \"This section presents a row of three visual elements, each contained within a square frame. The squares are arranged in a 3x1 layout, creating a balanced and symmetrical composition.\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"eSAjGKMWr\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_row-three_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"stats_1\",\n\tdescription: \"A statistic section for landing pages. Useful for displaying achievements and accomplishments via big numbers.\\n\\nThe section has a three column layout (so 3 stats total), with each column containing a very largely sized number and a smaller subtitle detailing what the number is actually about.\\n\\nIf possible, keep the achievement metric (numbers) of matching length (so all 2 characters, or all 3, for example).\\n\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"f01G8zQqb\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_stats_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"stats_2\",\n\tdescription: \"A statistic section for landing pages. Useful for displaying achievements and accomplishments via big numbers.\\n\\nThe section has a two column layout (so 2 stats total), with each column containing a very largely sized number and a smaller subtitle detailing what the number is actually about.\\n\\nKeep the achievement metrics (numbers) of matching length (so all 2 characters, or all 3, for example).\\n\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"PzevFPzNL\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_stats_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"teaser-signup_1\",\n\tdescription: \"A teaser page for an upcoming product or service. A title followed by a description. The copy is centered, very short, very punchy. The subtitle should say something like \\\"Stay tuned\\\" and be less than 3 words ideally. The title is often the name of the product or app.\\n\\nBelow the text is an email input field. Directly beneath the input field is a black button labeled \\\"Sign Up.\\\" This button label should not exceed 20 text characters ever. This form allows visitors to subscribe for updates or notifications.\\n\\nThis type of section is typically used to create anticipation and gather interest for an upcoming launch. It provides a temporary landing page while the full website or product is being developed. The email signup form allows for building an audience and communicating updates.\\n\\nThis section would be placed as the primary content of a webpage, serving as the landing page for the website or product. Its purpose is to inform visitors about the upcoming launch and encourage them to subscribe for updates.\\nDo not suggest more detailed descriptions here.\\n\\nThis is a standalone section. Only one standalone section should be used per page. Do not combine it with other standalone sections.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"LYVPQpBDB\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_teaser-signup_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"testimonials_1\",\n\tdescription: \"A testimonial section with 4 customer testimonials. There is a title and subtitle above the testimonials. These are extremely short and punchy.\\n\\nTry using a similar length for all quotes. Use short names and short roles. Do not exceed 80 characters per quote/testimonial.\\n\\nThese types of sections are typically only part of landing pages, and always near the bottom, above CTA sections.\\n\\nUse sentence case and add punctuation.\\n\\nThis section has a 4 column layout.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"DdJJ37grY\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_testimonials_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"testimonials_2\",\n\tdescription: \"A testimonial section with a big single customer testimonial that is left-aligned.\\n\\nIMPORTANT: MAKE SURE the testimonial quote has 80 characters of text, that works best as a default. \\n\\nUse short names for authors.\\n\\nThese types of sections typically work best on landing pages, below feature sections or near CTA sections.\\n\\nUse sentence case and add punctuation. Add smart/curly quotes around the testimonial.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"vQvFtR7U5\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_testimonials_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"testimonials_3\",\n\tdescription: \"A testimonial section with a big single customer testimonial centered.\\n\\nIMPORTANT: make sure the testimonial quote has 80 characters of text, that works best as a default. \\n\\nUse short names for authors.\\n\\nThese types of sections typically work best on landing pages, below feature sections or near CTA sections.\\n\\nUse sentence case and add punctuation. Add smart/curly quotes around the testimonial.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"fbBvXovlm\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_testimonials_3.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"testimonials_4\",\n\tdescription: \"A testimonial section with 3 customer testimonials. There is a title and subtitle above the testimonials. These are extremely short and punchy.\\n\\nTry using a similar length for all quotes. Use short names and short roles. Do not exceed 280 characters of text per quote/testimonial.\\n\\nThese types of sections are typically only part of landing pages, and always near the bottom, above CTA sections.\\n\\nUse sentence case and add punctuation.\\n\\nThis section has a 3 column layout.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"XUMGNNYzl\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_testimonials_4.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"three-paragraphs_1\",\n\tdescription: \"A text based section with a title and 3 paragraphs of content. Each paragraph has about 200 characters of text by default.\\n\\nThis section works best when added to personal pages, like portfolio or about pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"VJ_oZIGkW\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_three-paragraphs_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"three-paragraphs_2\",\n\tdescription: \"A text based section with a title and 3 paragraphs of content. Each paragraph has about 200 characters of text by default.\\n\\nThis section works best when added to personal pages, like portfolio or about pages.\\n\\nBelow the three paragraphs there is a signature. \",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"abPtrgroD\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_three-paragraphs_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"two-paragraphs_1\",\n\tdescription: \"A text based section with a title and 2 paragraphs of content. Each paragraph has about 200 characters of text by default.\\n\\nThis section works best when added to personal pages, like portfolio or about pages.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"Z8CcUO0mW\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_two-paragraphs_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"two-paragraphs_2\",\n\tdescription: \"A text based section with a title and 2 paragraphs of content. Each paragraph has about 200 characters of text by default.\\n\\nThis section works best when added to personal pages, like portfolio or about pages.\\n\\nBelow the two paragraphs there is a signature. \",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"qDJxiN4Em\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_two-paragraphs_2.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"update-post_1\",\n\tdescription: \"This section represents the detail page of an update post or changelog post.\\n\\nThe content paragraphs have to be 5+ sentences long, like a update post. Ideally just one single paragraph though.\\n\\nThis update detail page has the title on the left.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"dHpRNkEfM\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_update-post_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}, {\n\tid: \"updates_1\",\n\tdescription: \"This section represents a changelog/updates page where a company or saas can post updates/changes to their product.\\n\\nIt has a title and date on the left, and these are sticky to the viewport/browser as you scroll, and an image + paragraph on the right you can scroll through.\\n\\nTitles and subtitles are short and punchy. Paragraphs are longer, around 250-350 characters. So always more than 2 sentences.\\n\\nMake sure to combine with the updates detail page that also has the title on the left.\",\n\tsource: {\"projectId\":\"2tOjuUIOzDx9tsAg9oLJ\",\"layerId\":\"hq3EdRIOM\"},\n\tenabled: true,\n\tload: () => import(\"./2tOjuUIOzDx9tsAg9oLJ_updates_1.json\", { with: { type: \"json\" } }) as Promise<{ default: unknown }>,\n}\n]", "{\"Logo\":\"module:K06Eo8IukrHSt5eCRID7/RTDDuN4RfusHPiFF01Xz/wNPebuw8s.js:default\",\"Lightning\":\"module:rGXusv4GuhX18iUc19o6/q3xHvDqEXFS2sbLC6TFG/SAyLqmjeK.js:default\",\"Acorn\":\"module:BLjRczXRCa2XMZlRX1af/3JLV0naPYn0LHwD9pOLX/ljGcHeWyh.js:default\",\"Address Book\":\"module:L00S2RH1zp3gjUauADCR/l2t8UZfSu562suAZ9M6H/ylAoGfSL3.js:default\",\"Address Book Tabs\":\"module:zKZRP1taQ7SiCL7Imka2/U40ypMCiZG0GA5GAuj1t/qUGmiMbTh.js:default\",\"Air Traffic Control\":\"module:ZIsmkNYbWu4Jnk92CHmz/5g2jUe2lvhzVthWoQ1oL/ANx4k8HE6.js:default\",\"Airplane\":\"module:bAE3K1LOlVkvhFXS3gmA/7HKpCrMDr6howeB6aSH4/TZefl2hgE.js:default\",\"Airplane In Flight\":\"module:UbpLZwe3yQoFqAefAnUx/1Q8GmVEf5O4CwywQfllp/Xv0oO96bH.js:default\",\"Airplane Landing\":\"module:XJt6IB9Wve2DQ3ABJ4j1/uaS6gnTzzh9loUoRU8qF/afbtLKSTU.js:default\",\"Airplane Takeoff\":\"module:oRZNz1OhAISK82DtcOGB/N62yml5nm6Kfn4RfwfiC/nIWEFZ57c.js:default\",\"Airplane Taxiing\":\"module:yyBDj89jzrei4pipnl7n/KEtJQVhvJBSoWrdxFpqZ/WVG3WWUvY.js:default\",\"Airplane Tilt\":\"module:hdxflSftTmA5pGQYkpq2/iAIrt8Geya56wvVutjH4/dBB0ubNtj.js:default\",\"Airplay\":\"module:JNgHwNDuaFUVW6LlovOS/Qt2qKHTii7YumCpvjHj8/ToUBkEhni.js:default\",\"Alarm\":\"module:FbGfS3LG7AO3IPi5uxD0/k6mk6X7kirMjtuWI23f3/RmHUi3oRu.js:default\",\"Alien\":\"module:hsgadPNE7VucL1IDc71Y/fV71XnF9d79kcpc0Spx9/GQ1I7VVeN.js:default\",\"Align Bottom\":\"module:J9o3ZXGfiPfMOyVqvs6J/SLPAnaUpcUkW5SEx4KmG/TWMSVpnV8.js:default\",\"Align Bottom Simple\":\"module:b0sAA7cNOlegomdGZLeN/kn8HrDSTHkmwrUeTPSS1/lRwjBfiz_.js:default\",\"Align Center Horizontal\":\"module:25QmxlHqQWmTaMDp641b/xGpaAswUr3wKoyFATCnU/TCX1gTUs2.js:default\",\"Align Center Horizontal Simple\":\"module:lJjdtVTVYyL4ZSrUFFWr/RvLqpxiv6hHaHlzYfaSQ/unur7AShG.js:default\",\"Align Center Vertical\":\"module:TGAYbmB39QNQpn5NQidt/TPkYXCq9a2QToucP5ZoO/CbnKwqN2_.js:default\",\"Align Center Vertical Simple\":\"module:ESiwSwagKkew90sj2uiA/dCJSTd6ySbGxwwfZSgXn/SRXdoBIev.js:default\",\"Align Left\":\"module:OHy3cYRpQUviD4ezvQzm/IHQ5vJwRpvro6S8GSW3G/DvzkibOdb.js:default\",\"Align Left Simple\":\"module:zvGRD2FffZExniFRk7H0/S5apMiXP1MGZZhyzLr3q/dVt2g2XTL.js:default\",\"Align Right\":\"module:Nd3GKFJW7ugaFENeNDKx/TzdTwWdBzqm3C9nl0Z9D/AtCi6lJlD.js:default\",\"Align Right Simple\":\"module:ncazihrwrri839nmgpsm/xsoUQyJrXgWiVozbHkTU/Hpn2Tzk_L.js:default\",\"Align Top\":\"module:xTx03GmLdCGFVW3vUIlO/6jmFUOCKXKzUbHGhY4nx/X4i3dzXvZ.js:default\",\"Align Top Simple\":\"module:PZPs1U9RxvNftZn2B2Lh/4yVsOvBosbSnJsq69cRR/wFOcanrXn.js:default\",\"Amazon Logo\":\"module:tu9TY1XZerwa2Wfvbehw/0v0xr8NDFTP1YuX2000x/ZQKe8njQb.js:default\",\"Ambulance\":\"module:ZlyC0rhOE0ZTqBNPeSaY/JB3WyTrOhgPIxiN7gUUD/eHwE9XhIP.js:default\",\"Anchor\":\"module:lS94LSPMKwwrDaOPBVi7/gz7RyZZpAWsWYF7FSckW/GhwU5ODKq.js:default\",\"Anchor Simple\":\"module:3pWws9N6smQ61ms4F7rI/BSIOHqjaAmqO1F53It4j/jAq87J61s.js:default\",\"Android Logo\":\"module:z40c0zm6r0iYrf6j4obb/GypA3fliPlwoi3z77zFs/Ouz8fpLQH.js:default\",\"Angle\":\"module:M0fOKhZcpcusNw0ml7us/JlWy5CMq71VkiQldt4j6/gQx5dPd3m.js:default\",\"Angular Logo\":\"module:LvONeE0EwGSjxZbX4zJz/Flwt0PfxEqgGaaAohhRP/WhTSFmPHV.js:default\",\"Aperture\":\"module:X65EuywvbTo2HBbNOQfQ/4o4g5KfpLcxgla4IYxkY/NXwBRWzC0.js:default\",\"App Store Logo\":\"module:tk985jymObOgy5ARzQZd/VidN5YjzI43tszsv2Nl5/ACvur2Mmb.js:default\",\"App Window\":\"module:n6am9iQm6ACcXG5Z5qWO/npfmJiuEICW2zBih4YsU/LHrY0qEim.js:default\",\"Apple Logo\":\"module:461JU8PGnDWvtaNPV7wG/OLgekpS1DC3aXLeOdeDy/Kymq9IoZM.js:default\",\"Apple Podcasts Logo\":\"module:fvjGCsG5oHp2pRoDPl33/gEfYg7bk2jLzLrsyGV4A/DmN3Dolou.js:default\",\"Approximate Equals\":\"module:te1LTSWOswNVu3Tmaujl/vdTVxzihV94E1F4T0O4i/Zxqlg0OsT.js:default\",\"Archive\":\"module:Y7VANGbu9JBm11Cekc2K/LdasiZWqmnTcnMNeadF3/IMIA3HICn.js:default\",\"Armchair\":\"module:y76ExCnVWMh8bdszjUQg/6PNy2LHJHivmNI0eW4ll/ccknp5Ns0.js:default\",\"Arrow Arc Left\":\"module:nuiFDTcvA5tkcJJ0uIUR/UetINQvp8jHUxsHNIYPq/Py9n1KpwE.js:default\",\"Arrow Arc Right\":\"module:KrfVF3QHQvNi2c0m4yJh/EKSpnvhw5w30Hc29Qpp1/GgNlUu_Hi.js:default\",\"Arrow Bend Double Up Left\":\"module:AbzmL3Re0ulQ0SDpCcC8/cQsE03FmdsiIvb5KWucc/BNPpxBeCS.js:default\",\"Arrow Bend Double Up Right\":\"module:KkAlzADkrvrRzsZ9WR4u/pVbC4HJf0khFRHMGTxIA/ou28wX6HA.js:default\",\"Arrow Bend Down Left\":\"module:xpLkGH4yUmCBrjsnC0xo/EnNhuoRIOt1BZSv4WkHM/M_bkLCT1c.js:default\",\"Arrow Bend Down Right\":\"module:jZtsCjVJnJEjdo0DHER9/3gZ5MkqVz55FhZSB6jAe/bWesmZrVl.js:default\",\"Arrow Bend Left Down\":\"module:UnZJnXw65CPetP0ptKVO/0z16zADQqrwdUXW4czTA/BJM3RbQxy.js:default\",\"Arrow Bend Left Up\":\"module:MQ3Ys4hk3FEhIDQFP9n7/3Kc4m2WWx8sSxsGvg368/T6XciNqRw.js:default\",\"Arrow Bend Right Down\":\"module:mfhTNc5WMzpZLhhHsss7/o3UdCaq93263avZysstX/lf8JFVB5n.js:default\",\"Arrow Bend Right Up\":\"module:9S4eNBSLN3ZHjPrRbYM6/f82aHY8AzSENeSgzXDwv/FlCFHObGt.js:default\",\"Arrow Bend Up Left\":\"module:FhGPcnCIdsuxpF8FHGb2/greb28UHF1N8q7bMjJRj/xs1aNWJXM.js:default\",\"Arrow Bend Up Right\":\"module:CtlLXKZj0s9QwOMVnpJh/3t1Ne6JrnKRwMcfJG1v4/yaTJcpFWu.js:default\",\"Arrow Circle Down\":\"module:Ff2rtPDa6zRgD2KzG8F5/W5yrhc1T4CDFAVzw8tWU/YjKCOobRT.js:default\",\"Arrow Circle Down Left\":\"module:metpV0KiyogjU8Htxfme/sieyOsnbQHVuCIFwS7W5/YUvoZw9t7.js:default\",\"Arrow Circle Down Right\":\"module:1XKIK2dvlbHT5HlhzKz6/CLZPgQTnM1KBcfVhAExa/mPtfh3s0S.js:default\",\"Arrow Circle Left\":\"module:4fYri5wn9FltYLXRioDN/ivsQrISPlRWqRbNb9GcQ/NUwpEu4Uy.js:default\",\"Arrow Circle Right\":\"module:7yr7lGvMZppXwMAjoAnq/7OawDEbXWhKEYMad16oq/KlB745hHu.js:default\",\"Arrow Circle Up\":\"module:suLABSLFcTESRCfLX0Ku/YuSQaxNB47mwId87pjic/M9amJlWui.js:default\",\"Arrow Circle Up Left\":\"module:vprIjvdQrogqGvD9m33a/wlEm0onojlowuePIQ3IZ/z16xZBaEH.js:default\",\"Arrow Circle Up Right\":\"module:iU1O8H4Gy7v7ggWb44sF/ryE0wCP3k5SLzVjOqdTd/ZE9XSgP8K.js:default\",\"Arrow Clockwise\":\"module:XrOc3PFKqIPcy366idts/41qCGNZhhuLYKJsAEb2w/xFByVSWoG.js:default\",\"Arrow Counter Clockwise\":\"module:wAVqLNFbfz6ZxYQNsqRv/Sn57PzE5VqzJNXQhLpXt/DeHtY4563.js:default\",\"Arrow Down\":\"module:sHXItYmaWFwxamyhif9k/F4o4KRfeIbSqEjMiKm1I/XBSVE_0Yo.js:default\",\"Arrow Down Left\":\"module:NFmmCdBNWpGHoFD3D1iQ/MLuDvTUPZQigrbnfooIH/lmr3BqSOn.js:default\",\"Arrow Down Right\":\"module:oHqgYqqacM49iVa4XjKd/fPsc2RxHPkhQZkyTGgk4/JeqFIvUu7.js:default\",\"Arrow Elbow Down Left\":\"module:FwLPRvxibN3tzJBJxOYg/NEUxsGG8InvxONZr5Ij1/IHJEobZPv.js:default\",\"Arrow Elbow Down Right\":\"module:bwjk3GwzzfMdmssuXeDQ/Rk6BpS4qO75cHjbBQQt8/OvmmyoWhA.js:default\",\"Arrow Elbow Left Down\":\"module:iJxIpKakuhivzH1FnMqR/spGqnLTWCidX2lKd5bfZ/rFZuLbchC.js:default\",\"Arrow Elbow Left\":\"module:muFjeusb3qeMZXycxgl1/FG9twNVofYdww6utkvS2/Jof07kGs7.js:default\",\"Arrow Elbow Left Up\":\"module:spvCK4LzWeD4yBYqswDN/sHvPgCNY2Em9OMcRjZsB/cvMcKEQkH.js:default\",\"Arrow Elbow Right Down\":\"module:kZTe1K5KRxypinVNXzQx/WsgGlPdqpBB2fkJdglst/SINNB77NP.js:default\",\"Arrow Elbow Right\":\"module:aGKySqa211TG79fHKUX2/kgVSkQLUo9aXOLnjaifA/VCZQ1Z6na.js:default\",\"Arrow Elbow Right Up\":\"module:EfNfFkTWgcLwQ82R1kZG/NukKEzRMueDlADDpjTLO/Vo9TI3YkO.js:default\",\"Arrow Elbow Up Left\":\"module:YnyVyZapSrMNTB8ClVFT/ZDVcXPobcgdLSSgS3e41/SBRmjoXTh.js:default\",\"Arrow Elbow Up Right\":\"module:zrlcEWMhHH6a2AGRvJVP/8nAwsGQyJTeKgTwm9u1X/zZvAeAhMI.js:default\",\"Arrow Fat Down\":\"module:ilRCqtyY6zZ5YoqvobtU/mDoReMbzZKKc3GBkiZl6/VNNpJREZv.js:default\",\"Arrow Fat Left\":\"module:o8uzr0uOKBgQhQug3Rxb/YPTcRPbfkqL6ErqMlbLK/xn29mx6ws.js:default\",\"Arrow Fat Line Down\":\"module:mpDU9qFhHnVAl7pS89k9/bqW3HZjEMWAJ8XV2vQdH/Gg8qFpoal.js:default\",\"Arrow Fat Line Left\":\"module:8ZXvJoVOyDYMkwk2E8x0/kfsoHE9zLl5hlKzPEObD/Qr5wfYSpd.js:default\",\"Arrow Fat Line Right\":\"module:W575Dg5dZhr8UIT8xvI1/QlOEbfIcoNZ8Ty2VA4AE/GHX47B29w.js:default\",\"Arrow Fat Line Up\":\"module:4Ajqy1IuLwg47GLyk0Va/7G3RG5hUa4wzaGcQXvkW/rr9zOI62r.js:default\",\"Arrow Fat Lines Down\":\"module:GR6IpDxrTl3DHg2C1fwv/2yFSZWkQntx9cYMy9Z2O/q9SZcIsTJ.js:default\",\"Arrow Fat Lines Left\":\"module:izwCOJm9D3aOXI42xE68/y4gmnZgbTftSjMPxx8ay/kfd8Tzbcq.js:default\",\"Arrow Fat Lines Right\":\"module:gCT1FxkIShieNRaI1qxS/74veshalZQjlFwCKXPut/vroEWIXdf.js:default\",\"Arrow Fat Lines Up\":\"module:GIUdCucUGuiJfHoN5F0Z/VfZZBFq8LMzKl3QRxuDC/w4Ud3l904.js:default\",\"Arrow Fat Right\":\"module:4CtP7796DuOod8ZhNPK0/EEpHuXLci21hPefwoZz8/z_vpdrPbZ.js:default\",\"Arrow Fat Up\":\"module:pAYDH9wNdsnX3O6BkYgt/tAwoyDpcX6dBovNwoFuC/pJoTlpnjj.js:default\",\"Arrow Left\":\"module:SulpgVrT1bx1PbM4v6vQ/NlB2xVoOI0SXwkP7BzsM/XcIlicl6R.js:default\",\"Arrow Line Down\":\"module:wv5nOJk5PM4V33DpjZN2/0Sg8z2yMZ66nKCgMgWSH/eMUuduEtJ.js:default\",\"Arrow Line Down Left\":\"module:JHyDu35bZTRxlRrIa7L0/sNbFkFduIt6D5XqZGLiH/Od6q1QcLN.js:default\",\"Arrow Line Down Right\":\"module:9Hm6E7XVPFQAom8taRoW/MkbA0kS2LnMJdT6LoifD/UICqjeNlG.js:default\",\"Arrow Line Left\":\"module:bbrXeHvyRlgKkIDm5GTk/CiOgKjVVpE1ZXfPFqT9H/ioolsr2Wl.js:default\",\"Arrow Line Right\":\"module:npCmnhiJkxVkAvzr0rH7/vuu02ctecLounU8xCRGp/fyILjmuGH.js:default\",\"Arrow Line Up\":\"module:ZZpxbrwF6wSX62EilgrF/iimdrXKk4ghY6N5tnggY/y52ysWUoo.js:default\",\"Arrow Line Up Left\":\"module:RbsT4UIfoBaldVPap76N/lK2vZhpaIbfwOp9gLAnb/wgPwjU1FP.js:default\",\"Arrow Line Up Right\":\"module:MB8zTEFOZsila2g1Hceb/Zuuy2QTtomjdHu6QehIh/z22n5ZrWK.js:default\",\"Arrow Right\":\"module:hI8timTlk8Fd762eIxi0/slkoCsyKxQigbCO9Bbjr/ae1wERNQB.js:default\",\"Arrow Square Down\":\"module:gAgTDHrud5fkF6LJEr5y/ZKb6IMaGkDYGZULfEZ9u/hQlhISTFf.js:default\",\"Arrow Square Down Left\":\"module:mEYcg8ufay4P4jatCXUF/5mOj3pcbNStSfLGTAZwc/uLVu4jNRO.js:default\",\"Arrow Square Down Right\":\"module:glqMvrLFcN8dgccnxEmI/1tT2o1G6TmyCsTDNxg70/dw9Y1gQuI.js:default\",\"Arrow Square In\":\"module:qVoqt1kfOJzO6XOi6tp1/CfpLwWykmlJgaCV0ad9F/hiO95K8aS.js:default\",\"Arrow Square Left\":\"module:4b1gjbGI9bVWhgLCSubV/5OJ7YYn7gGrS6VJQUN2K/V8RaIKFkI.js:default\",\"Arrow Square Out\":\"module:PQgesuYY22JSuBL9H08d/P8B9SA4qUncVzsKWh6dV/X2ct7fUb6.js:default\",\"Arrow Square Right\":\"module:TgdovPTf12h5e9mf5mKX/ny0lQDjRQ5zoBlru0VHq/tL6Nru9eO.js:default\",\"Arrow Square Up\":\"module:GKWUZCBmQGEgqffJJqdw/TpunvO2thFhLjoroN4Ug/caLbeBgdq.js:default\",\"Arrow Square Up Left\":\"module:oSE21JjQK4Yb8iH9Dz2X/LmeRTiELceedsn6Ky4ru/gPgKCJLDg.js:default\",\"Arrow Square Up Right\":\"module:b46S3mUyzaMSqCftQoT7/l4k0roAnLAjW9TUUI0t8/w4tjU0drF.js:default\",\"Arrow U Down Left\":\"module:59RbE0oR7wJGLVGh5lRN/G2FAN0DgAOOBLvUKoU51/UZSPasiYc.js:default\",\"Arrow U Down Right\":\"module:U7h7gJyq5mDcLwHn9lH4/D8USRW7oPWiIt1hd3COm/H_mDpAtqh.js:default\",\"Arrow U Left Down\":\"module:hE2j0TL2YFDIzFUjFw0V/2SQ4lnYRBxLthtnMFBwo/D3Vdo65o3.js:default\",\"Arrow U Left Up\":\"module:s95jsb16JvOlTdU3q7he/6uG2jEvJXn64b68X9u6K/DXF7nArK8.js:default\",\"Arrow U Right Down\":\"module:SRZu1aq2AS86ryhCaumm/rvo7daR3ZJkgzXoKTaMu/vVtoQsOQ5.js:default\",\"Arrow U Right Up\":\"module:e0MB5CdXkNVLEBRlRaWs/hHuH1KKk1ZHH70F78VsG/wFkZxqUdh.js:default\",\"Arrow U Up Left\":\"module:TOOWoEuss6lAooCQP8fR/4DIxl3LsLeVhXWbYMFqT/DqAX3gtXM.js:default\",\"Arrow U Up Right\":\"module:ouGbAt5LaaSUS6pyhqG4/XR0RZC6epXgHYh8iRJax/PhPeYo5zg.js:default\",\"Arrow Up\":\"module:oDl5u5dd3r8tNoCOXLF2/GQd9I8LrdvYjnkki4T3g/SBflGcDmP.js:default\",\"Arrow Up Left\":\"module:90eYs0nszA9AlWyRrKkE/eVGwZpi4Rwv68EeqKRct/eNUz7UWmc.js:default\",\"Arrow Up Right\":\"module:DNebL0iFTFVgHKIdBvQa/n8rJOMp2sMlbHfZwNrmO/PgcRnnsPH.js:default\",\"Arrows Clockwise\":\"module:xRwZymOE9XYoIlyDGx8a/zf3ilkon4LWmk149XiNO/WiRMsH_Oi.js:default\",\"Arrows Counter Clockwise\":\"module:9x4LRHBHyr6mrtmxBUDO/XyJw2o8jXno7ecC52nYb/BYx2nQV4_.js:default\",\"Arrows Down Up\":\"module:GnROezUT9EwtffXCwZp2/xR6aL9hoDrxK8GwOmdHQ/ZyIMERyRH.js:default\",\"Arrows Horizontal\":\"module:iAItocwE316gppKYPnAn/XkpfwNKHZP1jffMWajQs/eQMUPIb_u.js:default\",\"Arrows In Cardinal\":\"module:v5cmJ7jM2YS0hCnrVWOJ/YU5vlO1PxhOG4P0kd1jU/PprwdwelW.js:default\",\"Arrows In\":\"module:mmOrv4C3973ydDBwduUg/TXG9KZ6w38wugPmtSCdY/qNG5fLqlJ.js:default\",\"Arrows In Line Horizontal\":\"module:5fwGNoDBKGryx2JrzLp4/0JqWPuh6MuD5E9TOXKVi/QRGB_m9wK.js:default\",\"Arrows In Line Vertical\":\"module:CINjOgqlSBh8UWhyk5Ev/q7hy60BxzxkOITr8H6CJ/WU42DEfry.js:default\",\"Arrows In Simple\":\"module:gzcirpA4yyPOS82Ks4Zk/EdT6ZD5rWclfMMJ1okOH/u1I9qYisc.js:default\",\"Arrows Left Right\":\"module:FR13RboLESBo4l6lNlpN/Bn6YCvTEPQ346a0aTS3P/HHVsKwvNA.js:default\",\"Arrows Merge\":\"module:iXRtZK2L3WvuhiMczcTl/czOpn5291FfaMkbEGb3m/sNIzdGxT9.js:default\",\"Arrows Out Cardinal\":\"module:42XRayjYztiAcCyMmFPc/2nEEozGXDSPdFbeM4vrq/VrEHD8odT.js:default\",\"Arrows Out\":\"module:Gwf4Wsnu2WPZtXrCFakG/XuTTtL03ydkCAMQCzP3d/De5YmqPPW.js:default\",\"Arrows Out Line Horizontal\":\"module:Ve64SfyNsgI5rGReoiHT/hp33vwqgxgKmFvYdLeDi/v1HRELpG3.js:default\",\"Arrows Out Line Vertical\":\"module:YuSFNJH4n1OCMOOJRnnA/dveNuw6G0HUsB77Jv64u/L7NhnkTVI.js:default\",\"Arrows Out Simple\":\"module:qIvCNROPSxkCpRZWpINm/j4m7aE3xSj4FmHG8OGDS/Cb0UzSJp0.js:default\",\"Arrows Split\":\"module:dTHtjMjNdBplJTgr1erq/b0XQWmDVuoPG36NRhzHh/BAlPRVWuX.js:default\",\"Arrows Vertical\":\"module:d1anbADj0S0ZNAv6XeSl/xgF7ERZNnCoe74kWY2nI/YJx5V1PyD.js:default\",\"Article\":\"module:c6djO2P0KGXV7cScNokP/5XgwtcRReJrsilT42RB4/cO5t5X04q.js:default\",\"Article Medium\":\"module:Nt835tqumiK0Ux0arrPv/utdUIvCl5qGtA7xG0NS7/lXLBDeAJU.js:default\",\"Article Ny Times\":\"module:nN2xaCmtVeihM8iFnHLr/POkBYsSu7Pu4fxzWu9BI/VxoZ9OswP.js:default\",\"Asclepius\":\"module:o0hzb6XijCJbxI2OHxw3/gz6rPzN0Vm5luAWbwWfa/TyZDaEbAI.js:default\",\"Asterisk\":\"module:pqcDFXtuWbHBsf5jRx41/d7tpw3a4fVlTUZB6xXD1/fOeOSfwsH.js:default\",\"Asterisk Simple\":\"module:WCHZvAzIa8woPUexbnjh/BEcGRLEeewXxvpevFd7D/mjKS4EYXR.js:default\",\"At\":\"module:CH8ltzLWUOz4Z4jScqx6/r0rMGjXqT54VAUXNDRhj/MdqLbu6x_.js:default\",\"Atom\":\"module:BoqYyiUXqlOOCjRk2tyy/wqXubqxo7VPW63BVqSMs/ohixky3Rd.js:default\",\"Avocado\":\"module:yjGHpfU1U5ERVp6YGN4t/5OcFbybozegORssoSziP/m8jzjHyim.js:default\",\"Axe\":\"module:fH3Moaiwd417kgFsJv5k/Olu4xlJzJ9pGQWVcfh4o/SzlL2T6IJ.js:default\",\"Baby Carriage\":\"module:imy79LGB1HgHuPYYWXPU/Qnq9yeLauQoKdsREu4XZ/lseKkLiIc.js:default\",\"Baby\":\"module:XZjGh6WNSSoYvnWKMVf4/TznB3kyVH5yQerzixc4h/DxG26HiGs.js:default\",\"Backpack\":\"module:vxpiM8M7NRlzifvzhJKF/0DX47vxUuleBNxu226B8/aoAwbmWII.js:default\",\"Backspace\":\"module:WRFLMQHH6rFzCLFBDeHX/tQVeqPVgtoqrg9aNksc3/uKHmXfg4m.js:default\",\"Bag\":\"module:1q0lTyt9wYyRik6wN3JD/bu7d263GTMj3adylVZZl/d0JBbZDJu.js:default\",\"Bag Simple\":\"module:KiKIH3dYNWkIY8ohEU5e/o5LNJPoZgfjjLm8DR2wl/vJ_7e8gwQ.js:default\",\"Balloon\":\"module:WVhcsAKQYtTIkjYNC3LC/5aWiCIcnK9ixUTWYDGNs/GPmXpr24v.js:default\",\"Bandaids\":\"module:Q9oSDSjA3KI4s6IIqlyB/TVrBavVavuNuOMMRC45t/TlnJxmeVy.js:default\",\"Bank\":\"module:blZf7MI6XI6U6KYlOXQm/ohSBEjPewx7L3eMfMpcZ/zYmz0QONC.js:default\",\"Barbell\":\"module:HjGdMZdFsZdnnwB0J57s/PEgCr1lc1i790hpXRqKK/OqeeG4WQ9.js:default\",\"Barcode\":\"module:YjrHmfsL1RB7CX6kx57k/8AN7vWrGXkTve6FAF0tl/vSWuACCeu.js:default\",\"Barn\":\"module:raYiIztdpCe3zdn69vY1/gvV3GUSeWyfpF1Z0DPhL/NqvTr6WAQ.js:default\",\"Barricade\":\"module:FZXR2fjItm5pxxJ0a3sK/JHHqrNaXPWHae9VrgnWs/BOa2SVOyy.js:default\",\"Baseball Cap\":\"module:Pb2GnYYsa6GEh0Vi7eYI/GtovUetmxBfZ4jMDdG3h/PqQ0DaOp7.js:default\",\"Baseball\":\"module:WufXONMZm4OOzv4edxVA/MFw2GOxrWRtwZNR6Gh2c/Kn8qAYl2o.js:default\",\"Baseball Helmet\":\"module:yvlhChotNW7FbGvrK5q4/ZMV19PRKNVSyvtgyzy7k/MUM1XkndN.js:default\",\"Basket\":\"module:zlQedlx75OSE58IxDEdP/1582OQ5guWePVbagR1aF/r7WsnqDc4.js:default\",\"Basketball\":\"module:b9uVFDnUC5vWa2unIzGI/PqSmag0puhNDb62zQ6s3/sh3bDKKzE.js:default\",\"Bathtub\":\"module:1x79sg8CYYrNmFF5A5gH/wNUdgbPd1JanjmwXw5Mt/nMrctOtsK.js:default\",\"Battery Charging\":\"module:LqLWY6YKma6Yz0E3Hntz/617wrLm1oVswVYLYrzTY/da90MW48Z.js:default\",\"Battery Charging Vertical\":\"module:CzDkDywBavoIHVSwiImx/NxetDoqGit0s7nGUTe9Z/Xx8v3H4bB.js:default\",\"Battery Empty\":\"module:zFHBKNZBheJ1K5FHu0kY/GjBJ2G0M4ryAxHZFEkNA/Vj3DV0gON.js:default\",\"Battery Full\":\"module:u6c6JziUMAHoQFoGvYIR/IPcAbR1eGk4tlRZyrx8q/URStuTTvb.js:default\",\"Battery High\":\"module:cKwQtSThDw7nTQaoldN3/7DHUN2wgsa0BfQo0Nk4F/XwG53aVy8.js:default\",\"Battery Low\":\"module:HLnEjc6HbZVL4esemjyU/48Z5Fg0K8Pnd6ajIknvD/yaO7BkkQ2.js:default\",\"Battery Medium\":\"module:GA4uga7tREQV7xkFkz1a/biY3lHKHMTc0ja8KlHgD/Wy5BvkfNH.js:default\",\"Battery Plus\":\"module:nDCRMQxs1MYAwxwyQSuQ/OcAweGAL3jgdJ8jXOMio/BwZxJYobm.js:default\",\"Battery Plus Vertical\":\"module:qGVCwEOL2Z8bD1CoPieH/fm6fTQlxsEIfncOWJSBA/vC4M6oAYB.js:default\",\"Battery Vertical Empty\":\"module:paLeaUYhoZROcHHgf6cy/JZmdDIvsUNmuQSbeJDoP/DC5UjeRqb.js:default\",\"Battery Vertical Full\":\"module:neIvGQWDIGwhazMnMQKn/5g1cWSPqd1DEvQSw45cT/Cc1KF8sSW.js:default\",\"Battery Vertical High\":\"module:NyPgvxBBEBKvUuWA46Hs/OKufB5ZaHeYYsjz2JYkX/UKVhrg7Yq.js:default\",\"Battery Vertical Low\":\"module:Law6Q218lHq2QlpTBWn5/QKPxY0Er5X4SfqX4Z8mz/QcOAH_f4i.js:default\",\"Battery Vertical Medium\":\"module:8enz4aWNT3yDuoeTEX7o/X6YPUkFH8iTtJagxceAl/QbxmTZoIT.js:default\",\"Battery Warning\":\"module:iLAvnpYklJDNs7wnJf0N/YBIsuyl3eORvff1nFeQQ/rQ_N6Kq9Z.js:default\",\"Battery Warning Vertical\":\"module:eeaNeDEzLJNc4SnXhyLm/ZQWRSc2aVgaL1bxLE66h/arr_PR8jH.js:default\",\"Beach Ball\":\"module:mBFCRB6VdjsZcKm55Jzd/kr556ObG2GhqQsiRVI7v/u9cwnRJn2.js:default\",\"Beanie\":\"module:wR8ht9kjYfhQul9uUHaq/7yMFBzpqzsfvL559qTOK/k1PGH0NeD.js:default\",\"Bed\":\"module:705RSK6T2xTqpFwhLhHt/HXRLCLKxnBbpfBbhjkB3/Ouo2uHnEM.js:default\",\"Beer Bottle\":\"module:GVZAkXw9LWiPkEuCdR7X/AMdQudNpjbiqz4i0ha2H/gIIVn38Su.js:default\",\"Beer Stein\":\"module:Dk7ENXH1BnIGCwP16wO8/K4mxN97mRfbcqcN87Haj/ahAJpcrYd.js:default\",\"Behance Logo\":\"module:BZeY9UM00YAYebUkVjPi/RhcHDaaY6A7dVO64wEgF/fvj3l5AXS.js:default\",\"Bell\":\"module:p4Nheu45nvdf6rEySEBm/FSaGzq388cuRhfsZsljB/OBxZVv4sI.js:default\",\"Bell Ringing\":\"module:skhfV9BQITJLGpZldHz9/ZT0M9NjbpjEVxys0ExbL/BiW_7RTkW.js:default\",\"Bell Simple\":\"module:z6wSyiqCDWh3pfEQNccx/DZJCuAgaBlTztR1y1mJk/StZnqqm_i.js:default\",\"Bell Simple Ringing\":\"module:8KMVxJ1BRfQwo3wEPMqt/xbRXVifnuSBrwvK6tVN4/wB1OduEOZ.js:default\",\"Bell Simple Slash\":\"module:SoKfzJ64bUybD3XUheOU/OVTbrlIAMUKq78rN8u8n/YBO234GaL.js:default\",\"Bell Simple Z\":\"module:YugYW9SSBtVxnzTQ9x57/6ujdNbzZHPLGv6pgOhFX/CsXiCtnEl.js:default\",\"Bell Slash\":\"module:fEi5dRmhxmXCvHXZ9cWb/gn79MUQdpueddQGeUHgq/iCCdxsWHQ.js:default\",\"Bell Z\":\"module:s0znsbMUFOeAicnNe3Jt/H7NhSH6nmiEV5wXIbfil/E6HqrJvOK.js:default\",\"Belt\":\"module:QAcfjE6tNXInFlOWrJbt/n62mJn9IJIgwQqJXWSaG/GqGWxFepv.js:default\",\"Bezier Curve\":\"module:iwsC6ucG6RLFGgEP67AA/CHLATFebmKpskjHxJRrB/YbxAxcZei.js:default\",\"Bicycle\":\"module:Dj0p8tPgkKHI2Gr7EGCz/nQY4Sh7NJOOIbuJDPVgU/CW8LTgN50.js:default\",\"Binary\":\"module:TvWMjxWHU6gIKMW3J3N3/ucxGdyo6yza7v9IcpuWt/o2BE14US_.js:default\",\"Binoculars\":\"module:DF7NwkkIhVdIie9fRQ65/1cNcOaDCSwSX18HoYRFL/nLedwgS01.js:default\",\"Biohazard\":\"module:GRuT5cPoxbqK9OvZntbF/sK9ifmgPBSphoU8lkzr1/EN48esNjY.js:default\",\"Bird\":\"module:cynA81QdTRuInBVSoULg/M7ONI7C6evRopPoKF8Cc/c6fKi9jnx.js:default\",\"Blueprint\":\"module:qFQxk4DTOZVvKcEB8AgR/wCfawAwvrR8kYseofDBn/SRl1Tlfbw.js:default\",\"Bluetooth Connected\":\"module:SXms8QPV7HOdv0ymi7XL/xwXB3bgRHYCQxlj7S87e/WaQj1TO0h.js:default\",\"Bluetooth\":\"module:jI1HfuZKKxTgOK7uj4qY/0F9REA5aQ5nh5tee8RU2/Wc4knLEX3.js:default\",\"Bluetooth Slash\":\"module:NAuryDua5EXALmMLoWMN/XYCnEWBzVe7hY8nrlOgp/krUZKZh9U.js:default\",\"Bluetooth X\":\"module:48loXHDUDsNvtfteHQIT/8lFThuWfyojAoDmB0fWo/cOT5TDCMa.js:default\",\"Boat\":\"module:lQCw0XpBxETHkGkEZjNn/fcwFJAM1t1yJUJ0Xltci/FS4zAxoKC.js:default\",\"Bomb\":\"module:WYVamTTZPTYQGgw0HMq5/Uu5Wpxz6nR5Llfp242js/yFYCpcac2.js:default\",\"Bone\":\"module:IBTqokPCPcofTl3r4AzB/HPX2uBnx84NWb6RN8S2j/QxKugdttp.js:default\",\"Book Bookmark\":\"module:TxMSluis4fuJHuv3OgP6/QmqJDXr4l70IVrSZSYRV/i3VJy3GVw.js:default\",\"Book\":\"module:sG9x0MsHqDSXjpySmpnx/4HjDk2k6rdbu4D9nc4iK/WyXAJNjxq.js:default\",\"Book Open\":\"module:qhWZAwyugx39NcwtdcVx/YN8Vy3gl7tlg56RJstIm/TZmLlAtWc.js:default\",\"Book Open Text\":\"module:DB2COBAiRDwz6AhLm9XU/perwd7ool0KlgilAiVAo/to6hH0i12.js:default\",\"Book Open User\":\"module:8LpqiGDeJt8B3PCrbgx3/HTW8YxtBj7YeTcAYtJDz/UiFGDLp0o.js:default\",\"Bookmark\":\"module:6p8zU5jHa6w5T7AYqHD4/suRhy6MxFq0x613LSDhr/BAvIG6v3f.js:default\",\"Bookmark Simple\":\"module:ViNWnt8O12HFfiV82YrX/EZ3fcKYGk7UmcvXiRXXG/hGWhDNcnN.js:default\",\"Bookmarks\":\"module:Vg0u8Y7tPfe82ZS2aafp/MFJjN88J9H46JlNXCzr0/psj4JA7of.js:default\",\"Bookmarks Simple\":\"module:p8Jkl4mkekkdHr9VIaUS/wXz3P4vNzottOpBZGB6n/pn5zJ8_ft.js:default\",\"Books\":\"module:ru9xtyu4513QuMXHK2SP/rb1pWfJnwuuOLCEF8Lra/tgcaqtKk9.js:default\",\"Boot\":\"module:WExTffAlHjQeab0YmzMJ/4BraVnQLOicnqz2x0Bf9/FIOnVKZMV.js:default\",\"Boules\":\"module:tl8pk90yQHB7PPNiXaXi/6RJZMWBYr7SwIaeWzryd/EMIDZQ6WM.js:default\",\"Bounding Box\":\"module:qoAsvOTtfxPiWCAy9tEt/nb6keHw0c2jn0Pvma1qT/i_O0S9Wqd.js:default\",\"Bowl Food\":\"module:wsyalGUxid08ptENiUT7/l5jgniwrHMCKGJmabeHP/BCeL9KHfY.js:default\",\"Bowl Steam\":\"module:9dvyQiHFXw247uaTHngq/cPtElFjOC3Y3Z9kITUBM/cE9y6BwXG.js:default\",\"Bowling Ball\":\"module:IW8eT5WIk3KTWFMS60ea/RnmeAR2cnxQveMoaotee/ROMgNYbWo.js:default\",\"Box Arrow Down\":\"module:EyDinRb21u1mcg1MUGLy/wIT0GbcmW6C5gfJHVsmU/LI05NmotP.js:default\",\"Box Arrow Up\":\"module:haPPvNsBV5wV8IKVULsX/dD3aWXfqFZ8Dlf6JMz7j/TRYOO1xXC.js:default\",\"Boxing Glove\":\"module:lcGNLrfWlNF89ee92ePC/GwgYH29yKFKIV3XMFXA7/yudt9NN6j.js:default\",\"Brackets Angle\":\"module:HByDiKQzZftrykunIPCb/kqXEu81Ui4L0UBYtKyEU/admk45Y03.js:default\",\"Brackets Curly\":\"module:Pq665M2rbhg8ICsMkDjE/Pdt1QURTNcN9fe1e5cgK/YxLXilXb9.js:default\",\"Brackets Round\":\"module:0tTePSFS14c8K7kzkab8/eirpvy8PeE3lJDgkTs5C/A6pOPbs4x.js:default\",\"Brackets Square\":\"module:Y0BK3cL1mfnP0c3V0cbn/d349SnOH5QeCsPx1dIHy/JbdMKPqqn.js:default\",\"Brain\":\"module:BPw1TOnuldm5m9Qg3FdK/FMgEHmomsJjjSj0DbS86/CL8RHG6Uw.js:default\",\"Brandy\":\"module:MrOMF31jaOI6qovd9Jqo/5DtuRabSNW6oenrG892W/VV39KTCCP.js:default\",\"Bread\":\"module:TNteGgKOiiIsd63RL8AA/dODBocNcSE9JWDb0K4VO/oiDIJr3sr.js:default\",\"Bridge\":\"module:XfAcFyNmoZBEhE5Yoj1T/4LbplT5eAKjdRDWWwyRm/xRBMSzRsB.js:default\",\"Briefcase\":\"module:iFqcRxF8ZZEGF7diwteW/imM74r1wvRz3ZLLPqMiF/fYS5GjO1m.js:default\",\"Briefcase Metal\":\"module:xVq5l8jjMxpzMCvzBnlr/tMnCQHjTKiwBew4APyEN/SMdBZvblN.js:default\",\"Broadcast\":\"module:dW8JQTd5lArssKM3wUxG/4liLI26FE6isNON1vc1M/Lpom4wQZf.js:default\",\"Broom\":\"module:SfpfAoVtyGYpFp6of51Y/XNuIMYWgRFeQemOpgANW/hymgkY_n2.js:default\",\"Browser\":\"module:J2GSxTs97OCIV4As8Pxs/Cw1g8ondNuZclOJBeHiZ/qzJOH3ugX.js:default\",\"Browsers\":\"module:u1OFbCQ65WdzxT5O7TOv/8TVsOB0hwRPJeulQpb52/WMaqSJH5w.js:default\",\"Bug Beetle\":\"module:rkikqISV4SBgcimjPa08/DG564BxrzHz9omSsPhMX/vfSlNEjJd.js:default\",\"Bug Droid\":\"module:Ak8q8mqzku4PCxb1hkb2/EIPfYzBHRy52JHqKheoo/T5Gk_7eye.js:default\",\"Bug\":\"module:QOVmSU0VBOyfLz8WJ4Iq/AAjd6nGF5xcdq3WYxjjP/SzvwVio0N.js:default\",\"Building Apartment\":\"module:nHWpbcOHROwZuHrCuGcp/QkZJMqtGBwYQnlno0lGp/mkmWZVJfb.js:default\",\"Building\":\"module:2ShpCwa7lFs8ISJiulgC/tuTbzKwQZ2AfqKDDC99d/pqm6NnNZx.js:default\",\"Building Office\":\"module:oZNRW292Q82jLWLfVzas/hpLCsGM0JB0n34C07uH7/EvkSDa3SQ.js:default\",\"Buildings\":\"module:E50m9zmkPFqxC82t2ETz/FsDtqbhzVRRGMr8uTdW7/o7Li4LGej.js:default\",\"Bulldozer\":\"module:Fo7xvB73IJ06oZB41BtD/wi81NiCy9LaValUVFwOg/ssrcLUCl3.js:default\",\"Bus\":\"module:jK9thmeS5Rmuw0DV39SC/TG8oFaMHNweSlQyBh3zR/oyWadRgDM.js:default\",\"Butterfly\":\"module:SZI9z7BKpUDeuxxYpzT3/lOZgMqUMvUMINLWxYt73/rP3ajCvD6.js:default\",\"Cable Car\":\"module:iZxWL2HcUNh0lJIvNNJa/IcvN84JGfKIZjMOZt9zU/O1PggqBPy.js:default\",\"Cactus\":\"module:tvrNtgqbSpgMaDenwnsq/At1GBAx5ZaJ55qbZmUED/jV7ZTmoBw.js:default\",\"Cake\":\"module:FkKqFEJMKY3Sfp7MombN/clcSoYphnQV0wPday0bI/qcpBuOjI7.js:default\",\"Calculator\":\"module:JvIHftqBjEQ9sLrJFZ76/wRfjAND0wxk2xBB6o3K2/jBWi7MJNu.js:default\",\"Calendar Blank\":\"module:FAAlnwQTElEYCo1lZH9u/qz9oHw3uHOMqbMX3h9mu/LRxjSS5Jt.js:default\",\"Calendar Check\":\"module:6f50fMjSnKMK3YQRUtit/ahtMZPMgil4tGXLl1tvZ/H4mg7DsTZ.js:default\",\"Calendar Dot\":\"module:CvNh0DkFWNcS30UvEl4R/u1dqDeIfbIf0hQMiCWyd/M_BLrFuFX.js:default\",\"Calendar Dots\":\"module:aqJrJ87DxMmwOO7KAAEd/7WCVlrIMFn7R2ikAzYjQ/mQd6xySWF.js:default\",\"Calendar\":\"module:mB1tIpJmcRvtkcTnQXLI/qhSNUoAFz6iBXzW5gnju/tEPmNpmvd.js:default\",\"Calendar Heart\":\"module:7nucw1SdwMK8itMp9EvB/6lnCbix03B1lIvJ8X5Hx/rK0lTJbYW.js:default\",\"Calendar Minus\":\"module:atjGTxyFTBF9UKOcrpFg/n4xzSUHWgD1KYL24Sg69/QBgnTrwdu.js:default\",\"Calendar Plus\":\"module:birVkOHOTXq7JPJPZgKI/ClNnWNeRKJd6e4WYORwM/Q0xQ_lG5t.js:default\",\"Calendar Slash\":\"module:4yMcqAQYt16F9asChAG9/dm8vdwLHAv61RECxmCjM/zzg_GXjhk.js:default\",\"Calendar Star\":\"module:6zfd706egZeR7vAgTFF5/byVDRcVv18IjPArmWez0/RCVw9ZC_t.js:default\",\"Calendar X\":\"module:aZGbdWQLZhAZECo7a3sD/yl7pnDok0xPkP26259vZ/D3Vm5jw0w.js:default\",\"Call Bell\":\"module:FSsQeIaMMXZQKuNFJRWp/xOBTPYGp1bX1ZbHd7SXr/PliCLUDUm.js:default\",\"Camera\":\"module:H7F2OJJW4MLLfNDcqHS1/bSXRyHoaAKfD3XJLgBkp/tvIvV1TTl.js:default\",\"Camera Plus\":\"module:dzzAScYeSpyGWM12cljD/0Iiu0IsCuSRWyaJpolPC/pPddnIQs3.js:default\",\"Camera Rotate\":\"module:6eT0FBjlufPExz4iibnC/efKhYnkGnIxlJ6kFJMt4/iYZWMcx8a.js:default\",\"Camera Slash\":\"module:7IPzsxfFlN5Fu0gDBvyD/ZOxa2ocOonULMM9ASG1b/kGF0tHIRg.js:default\",\"Campfire\":\"module:7PeRBSPLnOd6mfDREaGZ/yp4ZBgWG3JSA2hLusgc7/T3tu1Cn7y.js:default\",\"Car Battery\":\"module:IFpEOzxQogkJLh2lBFy5/quSw69JIbveCYaLRTNF0/fHtHFOEPY.js:default\",\"Car\":\"module:M0zWsHXg79O1H1Il2TPh/Tnw373fTanBDlVXk4vtc/NL2Iesf5Y.js:default\",\"Car Profile\":\"module:uR616o8PPx6jdFw8nggy/HJU0DwvFgZigjmY5GjPp/odjVjKsgJ.js:default\",\"Car Simple\":\"module:gX6SA6kGKzS00nZYCp33/db2K6AKRz9o5BBqA5FKW/ZFllSj8_l.js:default\",\"Cardholder\":\"module:gz98yrXr8wtDHjIITPcq/EL477XJOKszGFHgktJBx/cdFzNf5Cx.js:default\",\"Cards\":\"module:XeevbhIzMhmnaWien3mz/rarCU2tIDXk80lqaJBC6/BfFaN_mLI.js:default\",\"Cards Three\":\"module:LnLHUNcyQ3nm4yfzQivl/E4f44dTxpygNs0Rmy93H/veRRGFHKl.js:default\",\"Caret Circle Double Down\":\"module:fflNZIO1oh6rrChaY8wI/7dMkchVaCl6fOLOlSdZE/vDeKjPsIn.js:default\",\"Caret Circle Double Left\":\"module:yyq4ygMKmmUaY6RsS3BE/og7Ha6AaxwYSGXD11PNd/rUxAXJp6g.js:default\",\"Caret Circle Double Right\":\"module:g4A4Mp6oOWUlsloHHFAu/TfapqVxuE9rDJmT3ICDu/XPYORF7x5.js:default\",\"Caret Circle Double Up\":\"module:tVPup4EQswjnLXCfgNzr/c5FSbTknhxPY8XIfn3yE/rxBEwv_5y.js:default\",\"Caret Circle Down\":\"module:VzsUVUz4n2ugwmL3KH5y/ZfL11pff8xmI5wUjhrA8/J76z_aka2.js:default\",\"Caret Circle Left\":\"module:vuxcaYUYHmmZMkK6hJZ2/i1o1EGAU8PYuvXFPKluE/tI2qDhGQM.js:default\",\"Caret Circle Right\":\"module:smOnX6lSe51znTkuEiB9/HXIn4qV0zyNoXYDNOWxJ/EUx6SozYk.js:default\",\"Caret Circle Up Down\":\"module:rkWRfmJ3Lq6lsHaN4Q5Q/RV5M4CVtH3W85I42W2rD/FVXd3JW5l.js:default\",\"Caret Circle Up\":\"module:MsmQ9vVH0DxY6GkOdubY/dl1MtVVcfmVmSbpLAO4d/ZSHK7nW52.js:default\",\"Caret Double Down\":\"module:7STF6n13xQTr7Te6VjK5/f21bYnx1nzrxKlajeVrX/ILjwwkbnG.js:default\",\"Caret Double Left\":\"module:72H4aCjGpSQO6llxpfth/ok0z5sRSg0zvhn1pVHcY/nDI4_wx40.js:default\",\"Caret Double Right\":\"module:CiqwWIr9HIGm0KE8xZNz/N2DnU1jM6mwdtkHbE4fC/BcrjS_qT7.js:default\",\"Caret Double Up\":\"module:fQt9R2zpzOk6ITku0tRO/BMI0UBdVjjDkGXmW2zTI/RKnGk4F2K.js:default\",\"Caret Down\":\"module:p4xyHAxz4hEgYi9H78wW/0miKoFUFTwcGWzrGBt8x/uKhhQBk6W.js:default\",\"Caret Left\":\"module:gPdSdZg1B6dNXfiAroOl/V1wkk4PEgsa3YeQhx5cU/S9MoGdgHH.js:default\",\"Caret Line Down\":\"module:fjNidIPnIyjenmXmOczM/SY4RFWQehXc7Hv2vjPqq/fSay91yKp.js:default\",\"Caret Line Left\":\"module:Q0NFy8Nnn1tURTiNe4CE/rno79AudYYQlUmnvEfkD/J5i0jMO0g.js:default\",\"Caret Line Right\":\"module:CfJu2rnfcj92DoJEz3t3/u1DxlTNhIzDFfyskYRCZ/VfE_b5EdC.js:default\",\"Caret Line Up\":\"module:Bi5PvhnwECxkyQbOh6D9/lmpvAcnecs45MgZl0WZD/tsTDk18WI.js:default\",\"Caret Right\":\"module:pAlGjrJ9K21ZZnox9gT0/3Dzx4dGWT045nuzNyZFP/KmHNOtSBz.js:default\",\"Caret Up Down\":\"module:nRyW9RYXxyvpcV1kladn/DAdqUqmwhr1ysMxhhQa6/DiwePmXJs.js:default\",\"Caret Up\":\"module:lQrAYHHJtdFNMDLtDObP/sM6w4EeTMWsymWqanMog/lDWUVpnhJ.js:default\",\"Carrot\":\"module:A7ybXQKqVbWUEKAZd8Qx/CstEeJsLfXGGHRpbw4RZ/nuyQQok6V.js:default\",\"Cash Register\":\"module:VvusyrHH3d8ST2Z8VtLi/pI6XyHMowDCTPg97Zjwx/XcNcpcUgq.js:default\",\"Cassette Tape\":\"module:iMEQ2g3J7RCkd6TZTm3x/HHsAuZZgkzCTkDxRWh0g/uxtPZhm1N.js:default\",\"Castle Turret\":\"module:jeJfsQxcnoMdOj2VHZHu/2nRjdXntkVCE8rYFaxKC/LjD4w349z.js:default\",\"Cat\":\"module:qUDN8aW4I5sicar2JXNU/vBfrGE40tvoBXPFk4Hlc/UA_wGzjDp.js:default\",\"Cell Signal Full\":\"module:e0gbZL75FJXmNIs1gVhm/2K47l6uS5TXfmmdt6w7O/a3a7cU5is.js:default\",\"Cell Signal High\":\"module:Hm6Amkco5vPjFkubiMua/SA3iuQK5HV3pUOczX7FJ/lY4yXNtr0.js:default\",\"Cell Signal Low\":\"module:qfmmaPViA0QVe7023tOh/ehAvCdkxI20pKfpLDOIp/i354PmV3j.js:default\",\"Cell Signal Medium\":\"module:JvEtxSD8RNN2fcJZjue1/qnP6dTm0plRLSeE09z4q/auPYC36Jm.js:default\",\"Cell Signal None\":\"module:nlfTBfY2Z9YXYVkEksZT/H6JIRfzbLK5DCEAK9lfb/SOW_2tMPP.js:default\",\"Cell Signal Slash\":\"module:oJCMIUDntgAWqC1Mmxbp/VHkz2ScbcIXbhDFrHym9/EAoSfPAm9.js:default\",\"Cell Signal X\":\"module:5rfXRBzvqeNLK9P4xRyD/9HkoIKVNQL5zC6ltyDSP/KPheLt3P7.js:default\",\"Cell Tower\":\"module:TwCtqgP9OFvVX1q38uJh/S6CFpSbF4vibbI8ftoso/LrJk4M9jM.js:default\",\"Certificate\":\"module:SVM4TNOA5eyPRl32CVAY/I9k8i9UfbBHLLgR7tVoB/HVCOxOLtz.js:default\",\"Chair\":\"module:ju3Ub6baOlXLPxiOY56J/U1kL38Mv8Nt5WROb0lPv/VH2vIam77.js:default\",\"Chalkboard\":\"module:MTFOC4sb1cmU6IQC5Umr/5I7igFmpxOGZ7UHYublN/GyD8KkLZn.js:default\",\"Chalkboard Simple\":\"module:2o6nimMuGjPIff9NTM0J/SvCTXa8m8cay4x8iFtK9/NK0O8afyZ.js:default\",\"Chalkboard Teacher\":\"module:CQQFvXcQOKqn0BKzvnC0/HbMojxsuYOwYslU0uCAj/jVqy4_3m7.js:default\",\"Champagne\":\"module:anGv0HYbpFo7HAHCP1G3/Kxqxn1G2PsjMSLI8DVJd/kGKjl7wJV.js:default\",\"Charging Station\":\"module:9W0fozrS0l1cWslQ2M08/aGL7BR4Pft2f5h6Zph0m/ZCKJk7zTn.js:default\",\"Chart Bar\":\"module:1v69KtPHxS2PPJspzqHP/VvW0MWRCZLlnxg4ZYjyQ/ecDtOnfJU.js:default\",\"Chart Bar Horizontal\":\"module:jaHhY7WwcXOjNV5nj7Sy/4jMHQnkQLaW323njecEa/wwRyp78rj.js:default\",\"Chart Donut\":\"module:4fAjiWZ6UodWho5mWQuC/J9GwD24gVEWQKqY72xzm/O_dkjQTAs.js:default\",\"Chart Line Down\":\"module:lhD2RXhqMlCTeO4Br79p/jT4cHqBVx1kh3egcdqsf/WF4RjQm0z.js:default\",\"Chart Line\":\"module:YbuLbtDqo6uJVJL1kt5f/aJKMhvTxnN5iekbJoCsA/nLWimypUp.js:default\",\"Chart Line Up\":\"module:q6AdYuVdn7nqnxRYPtBb/OYrLlDFAClRhsX9vzOMl/bDZjksbCJ.js:default\",\"Chart Pie\":\"module:YxPVfOaX7LHfPprMgDAG/l0PCGJskGCqtQxkSmz7j/xC9OS2SEH.js:default\",\"Chart Pie Slice\":\"module:MgoviYcci8jzlLtKNNSg/QMKxhotJBhaNM90mLE6s/ag22geHiY.js:default\",\"Chart Polar\":\"module:0Oeg03kWR7WmxPAiq70x/JgMFOMyyQPKdEUInw3Av/ZwT8Pp5eo.js:default\",\"Chart Scatter\":\"module:hs2RGA65ZGkLAVJ6obxc/v5vCYSkBGDnAHEk1lCIB/U9P0DPeZ4.js:default\",\"Chat Centered Dots\":\"module:mKVLVj8a256nH9Zz7TeT/CPgMgllwIcRPwdM0HYMB/rLRLcQyQp.js:default\",\"Chat Centered\":\"module:LDGa7ENvcOhw0RYurMdn/3lQWOFFWcbX2Alzuc5zO/dQUzKBSFx.js:default\",\"Chat Centered Slash\":\"module:8W9U6axwDNspMFfH31bt/PhwpiZCz9NXTp4ZSBYTg/wQIBCsEo9.js:default\",\"Chat Centered Text\":\"module:FCysAPlrL4Q8YnS4zXUe/QgoydfXuHBvsslDYXM9a/jfFMgDXZL.js:default\",\"Chat Circle Dots\":\"module:xniL1MzN1wly1VD8eMQb/qYa1vWl56jp9LXMpSwPh/wwnfoY1Zc.js:default\",\"Chat Circle\":\"module:ome8aKznzwhRVZTfQ0cC/Y45jRq6gHIMGSXqgx9aY/hm80GXBLx.js:default\",\"Chat Circle Slash\":\"module:vFuAT2zV5JTmcF2wkeFE/GI4NIUYaVdAUw4QlsCwj/GLaHBne3e.js:default\",\"Chat Circle Text\":\"module:RAnZ1san6v8QkVU6y6M0/L9R1ecCW7xI3VvGAaDjM/AzV5IWnDG.js:default\",\"Chat Dots\":\"module:lEqaLBbg3rzwX1v9MjBR/iEu6wpUfDmoNp9H2Olxj/QCzxHox0X.js:default\",\"Chat\":\"module:K01Zpc6LG1XA29E5g1cU/Uu5hrYMn17zWv64OtkyT/EbsZRKCAO.js:default\",\"Chat Slash\":\"module:CGFzHSXUpRBhROQdZueE/9XIHv1AuNXVSzrV3esum/p1Z8gWmuT.js:default\",\"Chat Teardrop Dots\":\"module:yWDPcx3UTs7kjNaV4865/2rZ5VOyvNZRYFNVyBC4X/C3lT31k7M.js:default\",\"Chat Teardrop\":\"module:0ffQUy0NpowJEiycjLHa/HLKujS5lPzaevgkPs5UN/XTE0cprNP.js:default\",\"Chat Teardrop Slash\":\"module:XfEcEoau41nqpj79lDnf/xNBjfSdclGwtj6BfJYBo/GvgGgA56B.js:default\",\"Chat Teardrop Text\":\"module:2YfxHV5oDx5CGtylRuG8/fkkvn4ZkLW1Rr4cgOsNc/IzYGpiRZV.js:default\",\"Chat Text\":\"module:BPNWJRRB5KF6Fyij0t14/jpYSRfqTq0TDujAE1Dow/D1yQPgfsq.js:default\",\"Chats Circle\":\"module:zAwBAMUFNVezM69VGIzO/LNDNbV0wcx5ZPjPXl4Bd/r1gKrMevv.js:default\",\"Chats\":\"module:kPpz8W4Kcul7GryF3oVg/VglRA87mSMagEKqaZfA2/UJG2BKbuv.js:default\",\"Chats Teardrop\":\"module:gQiww55KCAouOdGTUWmR/34FtTgI9L9sBlWQY1ejb/YjQKEMhpJ.js:default\",\"Check Circle\":\"module:sA40IuttSjNtfmAykIG4/FcLulfyRtBFXmkzGb4we/jiyAOZNbE.js:default\",\"Check\":\"module:RvM91VtLIONQCDM2DB6b/hKeTkWbMIpJUeTHgnOG9/rXHCePIVl.js:default\",\"Check Fat\":\"module:KTXKtS1LG4czpWzhX4IJ/yNyAFvp2KsrdO3hpTrdY/HKfGC4V4w.js:default\",\"Check Square\":\"module:pJ2dDowqslWMGILSQBiB/XJh2vwUBBfTPlPEZGhDo/toXbocl1m.js:default\",\"Check Square Offset\":\"module:MZq2DfWv9wHUjwslrsrT/dSMo1PIerAcfz0jRfxZx/rmGP3d2Fz.js:default\",\"Checkerboard\":\"module:X0BHGWKUt7CpOlQAtNiO/Daaj9gcpcDSJujTNhiGq/nbCay6N1C.js:default\",\"Checks\":\"module:DLbgIsf2mFiBgykb7GWi/59OqCoXso3RSB2CykQmA/sFLvwrLK7.js:default\",\"Cheers\":\"module:30rwfDng5ZdjRmRrKRfL/gZKTh47aVacdoAVXayzP/E1T3s41GV.js:default\",\"Cheese\":\"module:d0l9uniTp30hSIj7sF2y/YjJBLjLAmABkuW24djVN/casQ5_ejD.js:default\",\"Chef Hat\":\"module:yBG1c7iAhSxglnTFvsiS/8aN0l04uUOjfjAGzEat8/Sh5BQm6Vm.js:default\",\"Cherries\":\"module:TjmdEpCM7eSKK2jLwgFn/bMsW7FJ23jrkrwnIsDZf/nUFmQyrqI.js:default\",\"Church\":\"module:t3dzY0EllqOqqSL9Dts2/OlzdMdIvFWUN8o5cUgKB/x0zoV2hlU.js:default\",\"Cigarette\":\"module:1A4Xej4kHn5U2EpRhn8v/457nAR2ZmZBWIgS2Nmeu/iFDzglGO8.js:default\",\"Cigarette Slash\":\"module:E6wyXdShMSIQuPhnEVwO/xr1vPjPEvoibItVSdQ7l/N1v0kioA9.js:default\",\"Circle Dashed\":\"module:sTVg7a8pavIvZLhqKJ6w/Ug77nQ2TNOZY9qiZ4UHz/IuBz9r3vz.js:default\",\"Circle\":\"module:YqG1FdcAagUYVfZXSM3E/fFx7sFiKIlgPlCWQY1w0/nMg_eN8Kw.js:default\",\"Circle Half\":\"module:Zc2c3iTjad2IiZ0cfSpD/WSwIZgGlzQ62kyqatFUT/kCTbAfxFc.js:default\",\"Circle Half Tilt\":\"module:e7e1usGHGT3hQlk6Gre5/Gok8CTncezPbmWbKm2eH/Z7gQVgiUM.js:default\",\"Circle Notch\":\"module:MtooDegOD0HnvFsVN6Ps/o7HLpVsuv2qlZ7hVTKzk/cpucRV0Cy.js:default\",\"Circles Four\":\"module:QiYFjC5mbLivgQ5YJXN6/S6y4qP6Y8l9R94QooiTp/VyOssQTlH.js:default\",\"Circles Three\":\"module:EznYvymeKIVIpc9U9nWz/SXeDPCW4CQBMlZtxGa1U/pUCG5Jlg1.js:default\",\"Circles Three Plus\":\"module:0L3jSu4L6idsjv9EnAZH/eOK5vuw2VXoyGfnf52rN/nCUSjwAui.js:default\",\"Circuitry\":\"module:ilvfztKi9L4eptIgdbX5/wNcE3Bg5AuBVZDCqjd6p/fXSbjnAAD.js:default\",\"City\":\"module:sAXeBdgUfCO8OkP6W85o/m7gbS9fiDJD3PfwUSOpB/L7I4zONfC.js:default\",\"Clipboard\":\"module:tHk0zCFl56YC29aZEBPh/sWCW7F0as7BylXzhbZRd/xS5eTqbng.js:default\",\"Clipboard Text\":\"module:BMnKzw7CJNzuDI5WfhvF/V0AvuJizqZXDnxZeQqJd/V0WriU4Bq.js:default\",\"Clock Afternoon\":\"module:ofn3zIasK21TR70yLqbE/mXhnTG1ls2oWpirzvgcD/pR47iDUW2.js:default\",\"Clock Clockwise\":\"module:sSt5q4kunMaF5HlB0cnC/ID0q7Pxf1o9GhklP4N19/LMf5NZD0L.js:default\",\"Clock Countdown\":\"module:gPepxz5LkMyPolAQlk6b/dXpXFZxbFzw6KILlIQlH/YsUlOQ7uy.js:default\",\"Clock Counter Clockwise\":\"module:HvD5g5RMX1hK34aqLEjA/jws5bef6w6SEIBOBvpZ9/H97PrXACv.js:default\",\"Clock\":\"module:bNORwvR02wGMbARQ266w/8cSPQQ8U1lGNf08znwmV/P57b8hxa6.js:default\",\"Clock User\":\"module:zk37neETEWggVqwefEfK/mfYmqL3yLGIyUlaKfMNo/to6kR7O_q.js:default\",\"Closed Captioning\":\"module:vBFjECQeGP91XT5l25Mg/D6LkpZ8B4YxkjPnxkFVp/x6nBGCNDw.js:default\",\"Cloud Arrow Down\":\"module:vxgnBIAK0mHNmPROXlVM/TOvQ7rOkyS7QtK9c1HiU/ZcAQ5VyJB.js:default\",\"Cloud Arrow Up\":\"module:9sAA8DdTl06PVDEpKQ9n/LsSSSWVCPOYODVTty9vG/h4DUnNEKL.js:default\",\"Cloud Check\":\"module:ooxhuNQkBfwpBVpRUA5D/j3vpI4UUTD2KD3CQd7P6/T3xo1PAIP.js:default\",\"Cloud\":\"module:JlGv87RHR70w9DQhJNCQ/pHbT3OVlBArqLtvZgLRd/kEwlRx7jT.js:default\",\"Cloud Fog\":\"module:4PSxdbR3sVOb3F5j60pS/1JR39CD7KlILPye6BKDu/kciohgP6v.js:default\",\"Cloud Lightning\":\"module:247lMwVjiiiIPcIdt1nJ/zniwIVLNbkwN4Qj1E9oD/rfO7qqR1P.js:default\",\"Cloud Moon\":\"module:9uPZTnJ0cBQEJzfGkHEZ/w1cuYbrPI2swWuWnuqQd/M9SfSpsxM.js:default\",\"Cloud Rain\":\"module:kKfWZt4irUUKfQLdTjF8/eFeIv4no7QtFttap56qo/afNnueOvn.js:default\",\"Cloud Slash\":\"module:0rGlDTJqRhWZ5JVpwvOj/rbi33No64StCF2Rim0qO/SEeTgQsam.js:default\",\"Cloud Snow\":\"module:axvOxYT4vs1oRy38vU2q/XPi0IbGKBVzlQ4sgQNHn/iC_CGeCgb.js:default\",\"Cloud Sun\":\"module:26V4Hoi99umjIbJIY6qa/7QFV8U1zJBwyEenwxqk8/YcZgIjKIg.js:default\",\"Cloud Warning\":\"module:YMsUkAbzBXKhq2kqofhb/DuqQX5B7LSph8PK5spS1/nJUZ6wEEG.js:default\",\"Cloud X\":\"module:5OaR1gBtnGBqGopntXwq/lzRbns4pBSKXfuzrEtWu/Rj6SNi9NR.js:default\",\"Clover\":\"module:KYDUflQLUgri2ClnWbSc/hbSqrh7jjS1p298llfKR/LbleDDIuZ.js:default\",\"Club\":\"module:rsv8gCsc1tfTuxuFIGk9/DNFPN9WhDEqfmTL1g5eR/m7AUx2h9v.js:default\",\"Coat Hanger\":\"module:7N63308M0SVQ28RU0p9c/RCja54GkDaTKAhH2lH4q/uy1b43I7a.js:default\",\"Coda Logo\":\"module:pUT4JVaFr9WHKDPHgYUO/Lq5cEQVYZlSI8XcZuIVM/p3fqjDVCA.js:default\",\"Code Block\":\"module:WCNBSlB0dO1xWTHTWirH/dfoYiV7W0HOw89UQw2Er/C2dJZ1Mny.js:default\",\"Code\":\"module:mDouEZ73SmSINWyLjBEV/jC1o91a2I8nHUvKukPqS/DHDOz2Tvi.js:default\",\"Code Simple\":\"module:OG6d1e8vZDqXjFZCUCkl/uhxzpGhoCTIHQKek6X8X/lb8EQNRlG.js:default\",\"Codepen Logo\":\"module:KtQQ2WGcJcnTURo5SVuw/LBwXBR4wepB9blDCzwjr/tmElEU8R0.js:default\",\"Codesandbox Logo\":\"module:6G0A1CHC3ZkOqrsJjTKm/wxLFYSKD2gMLVuTj2FWO/W__jnrrc5.js:default\",\"Coffee Bean\":\"module:xqQasF1l7IgUzOJQ6ODE/NPWMAnpQc14wLKuEWSBx/IRTi3C2t9.js:default\",\"Coffee\":\"module:qnvd8fiYd7bMDd52Gg4r/R529c7balF9vZEeZX5mA/DQ1SZNVRI.js:default\",\"Coin\":\"module:3M8X8yqF1On6RZf35w3H/SXnZdGDOPiVe5k3peazu/yE8OoH7HQ.js:default\",\"Coin Vertical\":\"module:mJEoSIZJn1VbeqEm4GIw/TheVW2NXxIbrCFmyhfRC/Cq7HHwmNf.js:default\",\"Coins\":\"module:rMDwwqerhOGip5AofJ2m/f74Sna8Xv3gmfEan0h0h/Ek49kH1RY.js:default\",\"Columns\":\"module:JqFbJ07DcnaEER8y8cEb/7ENkSVQtCBLAoBO1g6Vw/lTso8s5XC.js:default\",\"Columns Plus Left\":\"module:6pY7UyoubjkebNSBDtbw/rJIwYbrVKTfZ3z2PmoZy/Uuh1Jfo9N.js:default\",\"Columns Plus Right\":\"module:yhUDD2uCGLh6W2XBNM6z/VEGspCHRE2d3GE98j3J0/yAQM77dnE.js:default\",\"Command\":\"module:gAPM6j6y8FYC8aAEZ08M/7pjT5VP0PhttcG5AHNkz/ZSMg6r6XR.js:default\",\"Compass\":\"module:D0d3D1arF0tjlRNCIbMy/Q6PT0fltcD7bm3JBW39t/FLKuEtMKB.js:default\",\"Compass Rose\":\"module:2bBO7ecGCaUAwBcUslR6/rA09pMRq6VWOkBdtu5sx/uAUTljIBr.js:default\",\"Compass Tool\":\"module:Nj1K1NzsklYIOGflOSBR/P6zZs9UaZRmq2JfM51lt/s8hsAxzdC.js:default\",\"Computer Tower\":\"module:yzd3XAPPqQUVvY78FgJt/tVq92cBQ4n5Zdw8Huy8R/bMH4fgQ3u.js:default\",\"Confetti\":\"module:pkyZ8sb5IUS18lDtUg5g/UWERd9oD2z1NvhVhtdMt/k4q1u_Sqa.js:default\",\"Contactless Payment\":\"module:X93qx4gHxilK0LLKNLwu/eDtkT7NKPmbjHtKdxoaO/OFEe0Bb2C.js:default\",\"Control\":\"module:VqMFqg9MWkBCw8HDJfTV/oknPUIlUkadFeUwU5elu/g2RhbjXNi.js:default\",\"Cookie\":\"module:FA54YuMVqmLVGQIb6CXP/EgtSVsEGyusKwDNibEKn/jnROQ9EsI.js:default\",\"Cooking Pot\":\"module:iu0p202iEjNfPwRyYr9k/zchUf4GIYlz0eAFi943k/MGKQMYcU_.js:default\",\"Copy\":\"module:JAHMTokngeA9GGzisyGP/XLcGrOA17MFCAwuXi5mB/oK82mNmE_.js:default\",\"Copy Simple\":\"module:6F570RTvUiV54rUWIkYh/5VsSaRIRgdGwC7XCtXeR/s75Vhi2HE.js:default\",\"Copyleft\":\"module:bGtQS466LEdXOXfblUtr/RrcLj07GrOWhXzNU3MzA/m3PBK2V_w.js:default\",\"Copyright\":\"module:tdRz8E193xqsn0qpi7Ky/A2ZpB7vDbjo6TBpzwjc1/CUpPzh3Sy.js:default\",\"Corners In\":\"module:G9f1kCpZrhHUmVtkWUG1/pvhoOxSEbyCWMG7RTApR/PPJ683Z9s.js:default\",\"Corners Out\":\"module:WQt8j0S3AAyD9eYHsk9t/4xlLYCcujCWMQhZLDewu/spwbrB51A.js:default\",\"Couch\":\"module:yQ8w0nRYxhD0EFiDCJq1/4M5EX9GCcVGczFasQGO4/bNuH194cF.js:default\",\"Court Basketball\":\"module:y38xD04zLUKeHuxkT8Mc/9FsAaC1IxMlVlUUNV3nr/cCFOMQq8_.js:default\",\"Cow\":\"module:3Hd5uWfrfLsyjZZzLov5/1fBT1WxbueLT6s8BH7TG/vAGOO6NPJ.js:default\",\"Cowboy Hat\":\"module:HeumI2FyZnE32aa2kzzr/E9xFGmKuRQ1EpBbHsXJY/hWbuVCcyb.js:default\",\"Cpu\":\"module:uAm2lfAvvfQdPGrRlKSX/uKUsuTBa5gXzkpGPn9KQ/r4LmfubY6.js:default\",\"Crane\":\"module:0zHxPh9A6Z7GvEZxBdXr/KWg4f4wxBdjHzb2GqMDW/ybNmy7YME.js:default\",\"Crane Tower\":\"module:0ITj9GM6atKbg8o13wDF/Mi5JRLMKQHOLirEPV4vM/zgVW7a2QG.js:default\",\"Credit Card\":\"module:DAkTdMqRXgtTCw4TLl7R/MD6goG2S72Aj0lQabVLX/IDI4BKkQZ.js:default\",\"Cricket\":\"module:jboziQLlmHIJVIb9liOh/tBzCpgC0beTbXqd7OqHT/eg_Jq8wQl.js:default\",\"Crop\":\"module:fw6r6lr0MlwT4W1I74YK/dCDGv8yWQIt21Xk5Wwn1/wnMK1n9u3.js:default\",\"Cross\":\"module:9vbhBC0hQHP4zEGcHq3g/1XaJqBMrswMLGP3rRVLP/tFxdmY2q_.js:default\",\"Crosshair\":\"module:QeejV3eny4iclsSYca5P/pQFR7jHZSOff7FnKUQLE/TKTEOy8al.js:default\",\"Crosshair Simple\":\"module:OtjEVrot9Nfkes97VMCN/irFN9A7BANlWObPgWRrM/fR3OeRQoq.js:default\",\"Crown Cross\":\"module:zaO3plQZOxnyOobEAX58/2tU2FY7TukWupMrYScwO/GoGUMCXmk.js:default\",\"Crown\":\"module:ka79aVdbORXjaMytRyjt/lIknUYSFQRxb4B3sBoSy/fEmYrHJob.js:default\",\"Crown Simple\":\"module:GEcBsJMtOeURQcLhxOQ0/IWLDNkurNEydBdsxRVTl/KUZtQebgZ.js:default\",\"Cube\":\"module:Z3SvZ0jTKaMZmlhJRmcE/mkaBUKIOEu7xMwHKV3w4/O8tBtOdoQ.js:default\",\"Cube Focus\":\"module:DqU5ay5UiyEh2jU5mdV7/spA4cLjjnsobSnME0Aye/IeSepG8eE.js:default\",\"Cube Transparent\":\"module:UgNivHRWeW4aghDObcuC/Z12hEPebDuNvuQlhjdLP/GqMy0DKo1.js:default\",\"Currency Btc\":\"module:yATp9e3CX89goVJolHPH/LlwFbiQb0ngxqSvKfdTJ/n6dnRCdnO.js:default\",\"Currency Circle Dollar\":\"module:O5RaG1McVbUBcjK13zz1/d14L6gVLK922EvAKI1C4/dB8DgMI7m.js:default\",\"Currency Cny\":\"module:adE3ZOgo4JqnCiSgJNix/6iaxz3NgsybkTOfU14Or/QPQ3lx3kA.js:default\",\"Currency Dollar\":\"module:Ll4wJJ07aFfh2l1qyzxF/oKlVVk6f07ssAPwdFYHq/ogwITLEdO.js:default\",\"Currency Dollar Simple\":\"module:is57xOkbKL7t0jHqBLEE/9fyDNwGlyrztdnd1xTZD/HCIgRL7JN.js:default\",\"Currency Eth\":\"module:5raBGd4KDRcUTz8ojjLf/7o8iqFulnPaGKDZXUCFi/SJfDxsK1u.js:default\",\"Currency Eur\":\"module:4Seet2R54L7sqo2Tx0dj/pktRiy6s45TciblX8VOd/EQK2pKxCn.js:default\",\"Currency Gbp\":\"module:zTzj3hGwo29C7swRoavi/n9puIGBgNG9yIFGngPxm/nCDs6gNWo.js:default\",\"Currency Inr\":\"module:oz7uwCruOYDNqzdsKdW7/qC9h0t3V6OFGhf7lfOBw/LKELN5cJ4.js:default\",\"Currency Jpy\":\"module:BKAGO3VEUNvKyXMOYCGW/PovosL69p3MvaNOoghlp/C7xtGyVt9.js:default\",\"Currency Krw\":\"module:OVIiUrpb8FFSE7D4NDEV/M51XxIOoS65mYvPrq0Gy/f8V_OLhzR.js:default\",\"Currency Kzt\":\"module:zVJTR9BkMg8TcLoFAR3Z/E6AFEN9qjvJFlaL0WoEl/ut2cBBn5P.js:default\",\"Currency Ngn\":\"module:8UUZDssPjyewv9WuqPA5/H0BuBBa0vseiX8b0cc43/rqA6Z6giY.js:default\",\"Currency Rub\":\"module:L7GHxRzyV1sLTjV1h5If/UEVcdAHL2B04aXA5RcC7/Yq5h_CKc2.js:default\",\"Cursor Click\":\"module:1LkhWojeCvXclJe989Km/z4Yx4VJeZ2sUaDWWAK1i/N6J5oZz4K.js:default\",\"Cursor\":\"module:Gkel6EDrWC7nIJfNaYkQ/DYbbg3TTyQp15yYPb072/XOMVRhRkg.js:default\",\"Cursor Text\":\"module:9LBMddbKBk8RgW4oeDs5/LeD7xanIV6NVgfuhXrlt/SIUOno74n.js:default\",\"Cylinder\":\"module:XHYxA6ZWIJ4WCscinr2o/zHVaFtptoHoUfIQspSGD/I0vtD9nat.js:default\",\"Database\":\"module:tU9w8z6JJr5WqSAGwED9/naosvQ2yF5OqXKbWsFip/sHNc_d4Cd.js:default\",\"Desk\":\"module:jXHuDBVtOayROWVdhUom/w9gtb76V3dLmZsoVw7ku/e4rb_aAFA.js:default\",\"Desktop\":\"module:TL4qh4kChNCExg4TyXqa/1kZbobWZeKOCmog2lLJN/TLDrU4Pzt.js:default\",\"Desktop Tower\":\"module:RzT5EBeVM5xlEWpYMtYo/5GfdyJIyN4Dlm1jHBbcC/C4vzvxPx3.js:default\",\"Detective\":\"module:LWUEFyNNEwIc7bli7kcD/NhJLdamcKkhnUfxfvdpk/ymCbJ6_zA.js:default\",\"Dev To Logo\":\"module:tyyr6kkGRqfYr2Ae2KuF/eDbU31Sru2PDikgQXd0v/fm5S0khgj.js:default\",\"Device Mobile Camera\":\"module:IBLoAAscLECuppSgVytk/7guHmBuKw1Xt3jpKwTAp/pyJLRL7rq.js:default\",\"Device Mobile\":\"module:eo3yjjf0YsE9OXjJQOzJ/DOZmNErypur1Tra1xTyB/aw85kyh6S.js:default\",\"Device Mobile Slash\":\"module:wdu9hS7CQizq6nf0KxEj/2ky4tEQkjPxEzdcG6sut/P4CxFtT4u.js:default\",\"Device Mobile Speaker\":\"module:qMaiC7m0sqdGQ8m8FvmK/c9kA4QaN8EzZe5ySESB3/oYR9CwlKQ.js:default\",\"Device Rotate\":\"module:z9LqkyLEtNfmGuvTroIh/wDS9mIKvlbqY3i4nL8We/NMUKfjOuy.js:default\",\"Device Tablet Camera\":\"module:6XvYOHY8ZP91Hcxx8If0/c6SDePqkTj5Zu8E1cPd3/tTp6FMAqU.js:default\",\"Device Tablet\":\"module:aw5psmWp1c9M2nUYHsFP/DU5krcICyQnlo8fQypNg/HZB6hjWf9.js:default\",\"Device Tablet Speaker\":\"module:tlLNtoAxNaoBds3bPBa1/f5P8B3MBID4DKUXCAPOq/SpESha9hh.js:default\",\"Devices\":\"module:cuSpN9CpgPCnZC2sJxl1/VlMfZnDx1wKOwNNtIYo7/BP1i4cK2D.js:default\",\"Diamond\":\"module:fFIizP6k6nxelQAzGRlu/uLIEkqzcNuDiFFRyHteZ/GcCUpMurA.js:default\",\"Diamonds Four\":\"module:jkuJZShGTCdiyYrwB0Vb/QaBAdgFYkwCjHCRw8k5y/vxUXkiOW0.js:default\",\"Dice Five\":\"module:4jQsk3x4vugA94eNaAoX/d5U1ZxkCYNTwtBjnNKcp/cLjxaN6hc.js:default\",\"Dice Four\":\"module:OndOHCIQApvt9B6XAagI/0jPPtYdcfa5epW3pej6E/rCI0IO7fv.js:default\",\"Dice One\":\"module:YAlGFAkaZlRweWlBXpx4/FetvQNjoqh4pCwoFSDih/nAcHkiB3a.js:default\",\"Dice Six\":\"module:OKrGrAOmYcP5ZIj2WIPD/pP1DPvtSLG5kS0KG318J/wfqKsqKLG.js:default\",\"Dice Three\":\"module:lOYomA5aGiHSBitiA6fE/vDcovVsn5kCvsHy9uZJE/AzV91kIqO.js:default\",\"Dice Two\":\"module:bRmlLSuRbtz3F7F29bzT/D0P2fJV3UmEUHT5TQJDa/rXRWzc8KB.js:default\",\"Disc\":\"module:mYKZVUKtXS2tTFvEoSoS/OJS2UJBrIHqHeBg1xZ31/ec891bMCj.js:default\",\"Disco Ball\":\"module:Nsxv2NhKLIuf1VWntOCe/zxPbZVEsLseeOiyKU7iP/bjr3HHBDh.js:default\",\"Discord Logo\":\"module:UHXvLV5S8LJef9TZ3U25/lr1wxDV6cmLvAjcjLiz1/HC05RtPwU.js:default\",\"Divide\":\"module:kU2s69XpzzXNUA5XA3hf/brOtcylmLcpKLu2FAImM/OfHXuWcy6.js:default\",\"Dna\":\"module:rmrNAom0JYHS0lfQ2RFP/V90emW12A3WWI2dVBDOP/PYYb01SoM.js:default\",\"Dog\":\"module:mnUzXNoSANQW9sdZt1dp/uyBl5cgMASxoO0ySyB2t/ld7AB1Ee5.js:default\",\"Door\":\"module:9V9wE4zGUbdj59V3Fyts/i03384sqA2jKotxD8K5M/FW__R1Op2.js:default\",\"Door Open\":\"module:khetdb2g1wrJNnY4sZ7y/oiq2exTGb6yYApgY8wCP/vav01OOpW.js:default\",\"Dot\":\"module:4RQtbiFmkSfGngcbOF0g/DB5WynBteLHC11zhPUOa/Y1qtwluax.js:default\",\"Dot Outline\":\"module:7bC5iMJxvK2W1YPj4tpS/qOV9H37hknTGZwKjKp5r/eGjIc3o09.js:default\",\"Dots Nine\":\"module:v8DPky1biMbem0zjkAy8/zS2Jyg06B49mtAazaNn7/G5Q9Vf0Ur.js:default\",\"Dots Six\":\"module:rMcvSqOb3ZbQqftN71ab/6k4BgajVJauY2tsvhIVO/pDTL_5Ojk.js:default\",\"Dots Six Vertical\":\"module:JEGhgcTXe4EF3nkO7LsS/m4S1do4CcZ84DZqRhnIP/h7EdBVWW0.js:default\",\"Dots Three Circle\":\"module:V7dqidNooVO0crdwKUBA/BPk4oml8hQZlk7sBbEKB/bgN7eM4Ym.js:default\",\"Dots Three Circle Vertical\":\"module:gPnEVGLwX7RaRxNugVor/fbcISU0MQjRUBRoOdbrk/U3SdU4r9R.js:default\",\"Dots Three\":\"module:d0hoNrRpYn872KjSwEK4/maLO4KP3jwxcoPSt5zHS/PJrK4EEcb.js:default\",\"Dots Three Outline\":\"module:8axVO4zPhczjblsYnklU/LaQhbLumeFX07Ta8gPBG/O5lR7I4S0.js:default\",\"Dots Three Outline Vertical\":\"module:NTDKPZoZtrCcLwdj81bJ/2fYUVaIgRZQoaoNrh4ko/gohayqiEO.js:default\",\"Dots Three Vertical\":\"module:vgb5zeT97VBGEHdhZjuG/hOPkBeoAHG8t1RNdaKVg/uhgjprvfw.js:default\",\"Download\":\"module:M0yrbnA5VY1vbYPZCQqw/PDCyImVfXCZxatqsn512/Ak1gqbmpf.js:default\",\"Download Simple\":\"module:uYFjnwvRnuJsEoDAuYNf/7Xd7rZk05KXzfcCigV1a/l1Hw26yRJ.js:default\",\"Dress\":\"module:G6WzB2MMNPCDGIVqs2l9/Css2UM9wHqHA0IXeBsaR/ZGxmXnQPu.js:default\",\"Dresser\":\"module:Nu5hJhS9fg62OH1UyH7l/SxgEndQsrXFskuoHnUjU/cwxOP2iMc.js:default\",\"Dribbble Logo\":\"module:RYCkzothGqoQNsbr7ktc/78xiIJx6IEdr14uFd72V/WZdfcqIBT.js:default\",\"Drone\":\"module:AVpOHmKXN7JndH8MaMVs/f8wWHqRS6Oog4H4JZigI/lS4RvG93Z.js:default\",\"Drop\":\"module:bkZpjxfqAeaJsJsqHQVs/sPLkYGWycQr3STLWRVBo/sSadowjJw.js:default\",\"Drop Half Bottom\":\"module:0AWaVNKghF9XuAGPOzYL/4nJcnAIkeKlpwO71dBXP/bpSwQlnhT.js:default\",\"Drop Half\":\"module:1ntChuqmOPhS8vur0Bn3/OxNnmrU4sAAuRt9yXV6k/D6H5l27wi.js:default\",\"Drop Simple\":\"module:m3l1Dvki4AFqHR2IUQeH/zeQ7p2H114T9fGvTSsog/Dhy6tD0v0.js:default\",\"Drop Slash\":\"module:NxbTYift8Rz55BiArGhy/zawaGCUzAziA2LYeTNSK/Y5ndNnx4z.js:default\",\"Dropbox Logo\":\"module:mMGyvUVBTNxDuqCEwjOr/s1Tcyp0QaImVUdoM2E5E/D4MkSyxYj.js:default\",\"Ear\":\"module:ESVgFAiOjIiHnC6O20iw/ntAZUtULN9zZFje9pVdp/RTghPsDqv.js:default\",\"Ear Slash\":\"module:sDFP8uS4LzF3J1gBbixd/BGoeLj9ClVkbebnj79ou/Xsoj1ShXo.js:default\",\"Egg Crack\":\"module:MoHBnkXg8GYkG3iCUYrZ/G9KWDHOTonKhZYFhBDQM/h_6eKlWxg.js:default\",\"Egg\":\"module:8spI8dI9tIVRwnFF4f8q/ZXr4EMo9B6RXHStpHvdY/OPU20Q3Tx.js:default\",\"Eject\":\"module:GLTyYgqbN951rbDofOIF/o9HElqZFQ7aHnMISbj7S/u7WUZbCHW.js:default\",\"Eject Simple\":\"module:X1EQzlJi0eGywiRd8MKE/HlOEAMMoNX9te3JfcdbJ/HGYQ0XuK_.js:default\",\"Elevator\":\"module:MzhEizeeiR8BDMywVa8p/vXaK1fFGDZiuhbzNU2KI/dRak8JwOO.js:default\",\"Empty\":\"module:IkJNeIDM3xxgZzfzlpEl/Zh1FgWqufoMZaplIh4ol/hfW7n2iOt.js:default\",\"Engine\":\"module:3cxeknh3qJKMVldpaqNO/GSJ987UXBBPyEgqTvODS/SKtbSB9ih.js:default\",\"Envelope\":\"module:PHnaEKMsCFmquemlCSxJ/MIdBdxZFJhImvZLivnwC/lHPjf9ulG.js:default\",\"Envelope Open\":\"module:bdbU0djEjcevzqN1TAey/2A1ffDZ5DsqiXYRgoqfw/Jz003i_fI.js:default\",\"Envelope Simple\":\"module:Uzqkv2OV8vOM0tvVJuKZ/Wcbds34669567Myvr1Km/sYXjYwbRE.js:default\",\"Envelope Simple Open\":\"module:7uTdH46iLNehHP7kkGpl/2PqXARzlPwj91G4bDZ1E/eHVt26DXj.js:default\",\"Equalizer\":\"module:8tdxeYNXmhjoHB9pKHB6/NOtdLRwj8IEMXAZHahUS/ZK9aJ771T.js:default\",\"Equals\":\"module:VH4hqSIkUpap9khIqsuH/QF0T8u4n13NChw3kIzpQ/Tw4kMPZWP.js:default\",\"Eraser\":\"module:34zP36dIdUY3N9ZDVhIz/I9hApwQZrXes1hPgaUzs/uFVA_J0Jb.js:default\",\"Escalator Down\":\"module:3hU2kL35Vb5HD1rYboNA/2p8A8ERbIkRPpTkOM6U8/Q69jK5wYp.js:default\",\"Escalator Up\":\"module:ne6b1WW0lSSejvRG8j6I/Lk5VtOWfjfV7ywxfpex5/oXOMEpiAR.js:default\",\"Exam\":\"module:CuW7RYdW1a7FPBKXgZ57/VmhTRMpONT0wexcXtNrg/NL944qSYG.js:default\",\"Exclamation Mark\":\"module:hUR40wq6mx4Jcc6ir0Vx/Lm1Q44fmjtbKpdWeZ5ui/qgND2xHud.js:default\",\"Exclude\":\"module:emlBBWEeIFepCVuMi6Vl/dyaO8YKgsVHQXZlGdi9L/S7B3YpnHy.js:default\",\"Exclude Square\":\"module:90GMUYNCfBZcO6V3Gy5U/9cPkJLt9nJiOFoPrYNue/fBpkq2utx.js:default\",\"Export\":\"module:UAPlZJM9V5zouvSyeyGu/KoLcPzFU1kvvM3riJPJs/M3ptG1QGj.js:default\",\"Eye Closed\":\"module:YqZup3gLGDf7yRL1wgNe/xi7ekC3jcvAYp6WsHlyv/w4NVMiDmg.js:default\",\"Eye\":\"module:FdwNdTy6aDDIW7d5h1R8/lGE5j2he2aiGj4Xh6AFk/guZQOz05G.js:default\",\"Eye Slash\":\"module:v5sLGTi4IcJ6yvFkNzCo/HvI1by3f5fpHPzdUxGtM/zWOE9BzSV.js:default\",\"Eyedropper\":\"module:pDqzp2Ao5Eqot6z66fX7/ybhEt80PLZw0YxOinDwv/FR_sHfT2U.js:default\",\"Eyedropper Sample\":\"module:qLB7v6pv70j9Kkp9Vr92/HX5WbnBhkLyvxibpigac/Trjapd2Rg.js:default\",\"Eyeglasses\":\"module:gSBPtpKpwoPrjO0NvJEB/dWLN7UnVnRlDqkZZdwxd/QjLH8FjXA.js:default\",\"Eyes\":\"module:WYPBtn4gKgEUrL3f2yri/VKRGjNJNEHtlN2eLc4iz/OOyUWTGPo.js:default\",\"Face Mask\":\"module:UpR8Lc9oLSYmN0XtlpLu/C0HUhOmXKltDyiPDkIjF/Dy60IoDQ7.js:default\",\"Facebook Logo\":\"module:Y0c19ostjQ6JrIrS9EpB/H6GkscheXEvK1c9LQrFc/QDC8_m4BS.js:default\",\"Factory\":\"module:9VpE6N1WmureiRKKtSQY/4xvVBohRuvYMdB12ZQ0a/Ozupmpcs2.js:default\",\"Faders\":\"module:5gcXIjpCCkwvtbmoTknn/FoR4IPed0sEKbJjRaUIO/G9klrlqRK.js:default\",\"Faders Horizontal\":\"module:Xl27eaczKCkrMuZQoAWC/UoyhKZ0RtMJRQ9ypA9ae/ypuxOUSey.js:default\",\"Fallout Shelter\":\"module:lv5qx4vyoFjsRK3CLEL7/QM4mhRC9f9081M4YYYh8/zZ7T7GRD8.js:default\",\"Fan\":\"module:j85yEVr8nEeUdcRbAh5f/dMtfGKlZA5dNwBgD7aIn/IEmyj0Ip7.js:default\",\"Farm\":\"module:Dz0SmxnzG6zhksyDdmor/njshuvsVH6Bymw8naSu9/gWdToE8cy.js:default\",\"Fast Forward Circle\":\"module:g10DbXO3exCP9r8obJjW/RdxgtVrWgoqUA8Ah5jja/RW_3tFtJA.js:default\",\"Fast Forward\":\"module:gLzNGDqDgl4cssAvf66g/rnqUx2z93CwGdsCA9hJ1/vc9mKvBzg.js:default\",\"Feather\":\"module:ttBsXGTy0KtormA2lK1Z/Qo83EvZ7F9EbIXk7lZJQ/zGwEGQcJr.js:default\",\"Fediverse Logo\":\"module:rpMjIfLsRAwpYojGbE6H/pFVvkXYacYSfbj0mOiCu/l1yGOJ_Fw.js:default\",\"Figma Logo\":\"module:kq8S957TBD9wLscySfuK/7xMcV7vp3MUd9K1ZeIOU/EzpB6oIKe.js:default\",\"File Archive\":\"module:h8MRgStZn8UrDDFbLeZN/H73SUZX6DtflEBWwSwLF/H6pKHeNqT.js:default\",\"File Arrow Down\":\"module:kJqqRmxJpawoX1FSgDGx/zpZ2e6i7IrLkrR3pBydy/grAWwEsyQ.js:default\",\"File Arrow Up\":\"module:vmRLgNTLQu9D65FotLmm/ArgFIicsdnOxqt0YW8sS/Ph7RPyIWM.js:default\",\"File Audio\":\"module:u8fSzjU3cYMqc2vAWRce/7GtV02i20YaZ2Ra9jzDH/dprPKiOH6.js:default\",\"File C\":\"module:y5zdPD4Jrx20TzqYKN1Z/fVY3aIvgWEKhiHXD8y5s/YDlGR34xS.js:default\",\"File C Sharp\":\"module:sFKd1FZFz0E8KK5ZDSQf/Asp24smYKolaHeRLfNgN/H9PHbRmR_.js:default\",\"File Cloud\":\"module:77LiPsYllL3Kb84ZtQrD/JrghFaaNvS2wM9zJfVOO/roaXpofjv.js:default\",\"File Code\":\"module:jmgzJfd6et8b6cmjpVWg/2MmB64MjIZ60LbX9COFt/Em9eq3vYb.js:default\",\"File Cpp\":\"module:eQLlUKjm9IwOtrZNlGQQ/sx3NwU6HtvlVqIbo5qDp/D7GHbipim.js:default\",\"File Css\":\"module:J5pPKpfIAIvF4hZYIZfO/Dc48x1nBI0EpRw2kPtx3/xsTND3GLk.js:default\",\"File Csv\":\"module:WygtfHwvqg0pQbZwHZAl/pMPNzyclNtnTt9kT2KyF/ctCGN_Emi.js:default\",\"File Dashed\":\"module:3868bUUG6G9raWVsx2iS/mk9JXnqpHThrDN5KsT3e/VeSeirUx3.js:default\",\"File Doc\":\"module:003tLYPsTzJi0MpmngZE/Auepg2okDyyNCIyjnm0S/bVdTtfbx6.js:default\",\"File\":\"module:KQ18XeYmL2Ed3puswl57/a6P7laPKR9deqW4lm2Bd/AEaqsVF2r.js:default\",\"File Html\":\"module:X1151YLB1O8cij1gknCE/swO4ynieRYu13C3N1zlW/FmFOFwKRI.js:default\",\"File Image\":\"module:hcxkMwg340BzEVyR44Za/6ndZ4rb7nYG6ptkUsQha/CjBDmf0dF.js:default\",\"File Ini\":\"module:IOVucNiCtFy0LvStY55c/oWV7zyzwSlP9lPaizREy/xrlF18mpc.js:default\",\"File Jpg\":\"module:T99625vfAt80N7YCx2VY/wlA7OUaXd98mFnYU79UM/PeonGGsZU.js:default\",\"File Js\":\"module:2LkzKGXKpCIF6lEImu1I/5VFqbMqSCMMyzr3jnV9U/AHW8f3m5k.js:default\",\"File Jsx\":\"module:DtNWhC1tPkrduYVMnW0m/RYHj6l3CcllLk6EnTvxR/Esgate495.js:default\",\"File Lock\":\"module:7zcEAehf8V37ZVbjsQ7B/4eZrWHW4YOIMsvkiThqI/KrsPWhqnW.js:default\",\"File Magnifying Glass\":\"module:dIhgg6qJ8ExnZ6ssz2g3/LKnQAEU2BMCvMJy64KOF/YQ18NsOhZ.js:default\",\"File Md\":\"module:UwWqg0vWhMWXqbSSIMJB/QEIB2J7iytW36Jttl7Kj/iYBcP9ZF4.js:default\",\"File Minus\":\"module:jfTwdHPB7uKYPiOSwpVB/LtXPQ7TOyIGmCHlXuBIZ/RIwvb71s8.js:default\",\"File Pdf\":\"module:7iPnkjduWS31AB8oZ45x/a8IhfYyx7DiWLm4mLuVY/yNiBm0P8W.js:default\",\"File Plus\":\"module:neEFNqKHGRG92TNto1mM/qOlDUbL3sdDgdCIGYLp5/jwRZlBuUh.js:default\",\"File Png\":\"module:3iaOzmhtjH1L1ZtEvh9t/tM4NwduFXqq6gr7ktR5B/ztSOhZb9H.js:default\",\"File Ppt\":\"module:rArG7BZ4alMTZfzyYEHS/bhiN6jE5wDTOIYAydFka/v__S7Ebsy.js:default\",\"File Py\":\"module:0Xazj7bC0BB1JejY8bhf/nHsvkSRorb6Ueg0rf1Xt/scVS3PExc.js:default\",\"File Rs\":\"module:B7IOOO4SIySjLr9Tg5qA/uD65wq9i08nessK7PuDl/nqes1f9Tm.js:default\",\"File Sql\":\"module:RupgD47QgEffvRJ7S6tq/u814jrsqwz6M6VLUBpDu/DAlCESsXd.js:default\",\"File Svg\":\"module:TkZH5AIKMagMtKYDH8XQ/akpM0mtFxZV1E57GpnxY/mSZbg_E1t.js:default\",\"File Text\":\"module:oIR1CjoMkYLcOugg0upf/q95kqB7RzDqFA2ItpHxE/e8lZnXAvF.js:default\",\"File Ts\":\"module:kkrfEz9m7qMCL2hagWrk/XpSyZdJzWbmL1ZFfomjy/UKTChTBhS.js:default\",\"File Tsx\":\"module:M6feSQdHIb1er2QCFCUr/8vhAXTQR6V9VeNYc9iFa/l6_uKW9f4.js:default\",\"File Txt\":\"module:p2XjoF4oJXJhH0oN1yxl/XwcjLloLCvx2NqSosgaT/a3qG7V4BR.js:default\",\"File Video\":\"module:Pp0Q390i51GI7ohn1i9x/vIjx64WM3RLtK8JNLH6g/pX7kCU3g8.js:default\",\"File Vue\":\"module:c71NIUpzzpKlKMNETvz8/8IFrF66x4b3KC2ghwjdc/qEftUJaAL.js:default\",\"File X\":\"module:Q2j6Lys3joF3EazKZFEV/AUAyxnmb3nN44q0Z5oK2/qki0i1K0N.js:default\",\"File Xls\":\"module:6sZjbewZQJ4R7mJuqbfS/N7NnseuIYPKTu62znfNF/nSrxSiE64.js:default\",\"File Zip\":\"module:7B0FVkAQD3cUAGyxQ2ZR/ri5mauyC4w4erynkbkIV/Lpkx9OCMP.js:default\",\"Files\":\"module:HmKkS2fLbwoBIvTQLpwC/GEzMWN849rkenKdA622G/TREzuqRsa.js:default\",\"Film Reel\":\"module:ByzCvRrsGnNeUqSb25U7/5YujfG4LbiT5XMoGROqP/nRQK6lQ_q.js:default\",\"Film Script\":\"module:TOnQnCT9tUqWcNQmIkFV/b7lQLGLiAOrTUZ0COHeX/Qlq6pVvAt.js:default\",\"Film Slate\":\"module:QVF1l0JSx48Xe9ZM7RxT/1SWAlSJjo5Lo8Aa2Zb6D/nETCj4_fx.js:default\",\"Film Strip\":\"module:WWEtXOiwrzmteFLcW2TZ/0VzfHxDOIXvG41gE8GzI/QnsmaidmF.js:default\",\"Fingerprint\":\"module:SNFI7AuakF6MGVKiulVw/4QskBury8SLFxFmGM0HV/CzMK0E2au.js:default\",\"Fingerprint Simple\":\"module:7o5ZqBxTPpt71AqmxzYr/J1ROHMGdvzagTKLJj214/OLoPo8nfh.js:default\",\"Finn The Human\":\"module:KpYcav9XCVC8P88fFEGg/8FsTUTnvJdtYty8XvAyV/gUAY1fZjB.js:default\",\"Fire\":\"module:EMbF5R4cSHxWtoIds42u/pczZnKZCnrjXrcUhFpQq/xt8A_Amrt.js:default\",\"Fire Extinguisher\":\"module:HCGy3DYuvOxb12G7WFhg/L80XXLhq0Vbi0Urrf2nA/Hh58NJEBX.js:default\",\"Fire Simple\":\"module:lkOKR3ppGJ4FcRRWzNQR/yurmYHlyOuRKigCP8AT0/VuwiM1ECb.js:default\",\"Fire Truck\":\"module:2nyuGU9KfiKMHN3T6uih/NXb3HWL5dsRhKofgogZh/CNDqGr1CY.js:default\",\"First Aid\":\"module:ASpTQ9FcDMmUGEyP5knA/IFW8uCfrljS8iYDXuXIK/GrIW2Ya7E.js:default\",\"First Aid Kit\":\"module:oqDIt25W9PSryg0urWK2/NcSsZfw5zcvCkklVGpE2/LKJ2AfP55.js:default\",\"Fish\":\"module:VTZGvmYuOVqufBukVCIS/s0HwEoMs8SgbBdLcmcUN/FeYuAQivo.js:default\",\"Fish Simple\":\"module:UxSb1s8LHRbMFgXcDhdi/Al3eEkXJ6FFhoOjzNPXL/snmqyZHQN.js:default\",\"Flag Banner\":\"module:YZxpOEXo0PIx6LBqlcFj/fpzdp5dUUvgsJcy2zoV0/FG6tGW0Ag.js:default\",\"Flag Banner Fold\":\"module:qwvOUbAjOxshGnS3PFhd/oa1ar00Vx9TgqTzjAlKI/ZLywRB_Ow.js:default\",\"Flag Checkered\":\"module:HX21h8ZyPy9owapbjMcJ/sWZMso60ROyR0HLuyDdq/vMXzCRIOW.js:default\",\"Flag\":\"module:a5HEmFOBPlj0dyGyz6Aa/s6EvqeqDkKEWfJ4qpfTy/E0G6yDB9m.js:default\",\"Flag Pennant\":\"module:08IDot5BkhWREtUvdGJA/jk4pBjXcdTqt5T1GvFtO/U9kDxh4yp.js:default\",\"Flame\":\"module:7Y30TDmoc2BkbOT3q8zf/MtjeVKbfbt6CCCQkeirZ/oYKmKjtAO.js:default\",\"Flashlight\":\"module:D1ebzmjwPsJWG4qGZa1J/gGZqvGNAAMK343hOa4Xa/OZGHkDNQv.js:default\",\"Flask\":\"module:fsVtSFtgiKRk9NggnXpL/PQGIJzS3eoPCoJARGl3A/pFXRzvfAN.js:default\",\"Flip Horizontal\":\"module:wVqPHeTuLkV6fIUc9SJu/EvKi7I1RHrRu8JPfiFle/ota2Z_rG1.js:default\",\"Flip Vertical\":\"module:YHTPQx5hHOMwGMP2FynO/V7QsPoj28WUUHmGRKreJ/oKV0vjTIv.js:default\",\"Floppy Disk Back\":\"module:HdOaaRjuGSUzpNrM5GvZ/yZ6lWX5VNmM9vGGL6AUQ/Y0yl2Udc0.js:default\",\"Floppy Disk\":\"module:q1mRYiyJxXSnIjNmIevc/LoJ6ZJLO8JJpCShn3ReC/F6royrvUf.js:default\",\"Flow Arrow\":\"module:AMhL5l1REdeGwAhxNuk1/x0Oi4pfgVs6s31ZBBnI4/qUX6TkDch.js:default\",\"Flower\":\"module:cK4Jox8mklBpholxK9Pb/2gs8dyl9lJGRYw1hkdxA/HDfQqX37h.js:default\",\"Flower Lotus\":\"module:HbwRv3FEhVD1WzRGDrSc/ZjktH4JZviVDMmHQlOt6/AM6zWjQJO.js:default\",\"Flower Tulip\":\"module:szUWjBXdZhoewGzzTlw3/ySMWNILTfCiQuZIXlSBN/uYeVrjTgd.js:default\",\"Flying Saucer\":\"module:f9cxVazuGDDycP0f5rsJ/Qq0IgFZ4wekHDwc3g7BL/F0AUoKPKp.js:default\",\"Folder Dashed\":\"module:p8jWqiO4ssJrTlJCPXiZ/guHRaRYzUMJXdVJbd8AX/VsDjkP7GO.js:default\",\"Folder\":\"module:9SQ20YCHmKpMM9rbnNpc/yv4sLZ9FZOQ33d0qXwc1/XngNxa4BX.js:default\",\"Folder Lock\":\"module:5t7I3s3kFWAZ5lM6VHOD/YEOdgrsRJfjfGj4Lyrtd/NqcuEnFdv.js:default\",\"Folder Minus\":\"module:zZZjGc19CLamroabRFr4/yWgMZptlcWCDClRmyDnT/klJOXUMj5.js:default\",\"Folder Open\":\"module:84kZWPYbmJL2XwgKTJ6G/BjHViGQExLBmnw5VHwnv/hTPArxa9e.js:default\",\"Folder Plus\":\"module:Kx5M8BJz4se6rF0V6qIu/bVLsdWTZ206jQS5hgHUe/v6i2TEj89.js:default\",\"Folder Simple Dashed\":\"module:L6Yv9Dk7H4xlzDmogG31/PMUmCcpvXwkxiYMFj5ev/K2r7vC85b.js:default\",\"Folder Simple\":\"module:v9WTn6v9pPntoueCM8vx/ZiVG8HAGgIaSG9Qhewae/j9JLByvpl.js:default\",\"Folder Simple Lock\":\"module:e1DR25BqjewUlWFWC8GV/j96TAaVTKjWcjcmgz83e/GKSQ5K4v6.js:default\",\"Folder Simple Minus\":\"module:MstA8PNc1XHJMUzvEmHX/WzaMk7bqHNNjGYwHnXMt/xipw_mHoQ.js:default\",\"Folder Simple Plus\":\"module:M3dmCbs52wBgp4c4RM6u/zXAi26m0SE29DORn6Kt9/r1_C5Q1ON.js:default\",\"Folder Simple Star\":\"module:1OjpkmwIBPe8KA3IXI25/I6xqw55XFxUuoCkrHznl/FK3f8h_be.js:default\",\"Folder Simple User\":\"module:7bTxRS441c1FkZaE5hEj/FVFDyUEIetfCbb0yYRAZ/MZFTt3Qqu.js:default\",\"Folder Star\":\"module:WIRJfHwbdiKJsmuDAvNi/njYvmBjqaZjjCHNQvev1/K6ylOwkKw.js:default\",\"Folder User\":\"module:ltm4mYlC5YXLhdpKmUn5/Fe0nzbdR6n9RLnYMhqjm/TVS_gW9ed.js:default\",\"Folders\":\"module:99nLRlaVPyKo4XhblE5w/4EhgiIGZWgvq2e1Vv4HB/g_cOKovBZ.js:default\",\"Football\":\"module:pSvolAnP55YThybN3VaP/Ukjk4ivcbX3fLP3Wy8mn/CI6wvRmU7.js:default\",\"Football Helmet\":\"module:41e2Y46t8UNRWZFWT6mB/nvQQmF1R0NGXx8XGrWS3/m4Qw2QpgS.js:default\",\"Footprints\":\"module:vNK3HTt7yJLL4L2H36WC/2C8UF8FRTWY4JL51h5m5/VWNWvuimV.js:default\",\"Fork Knife\":\"module:4r58fwjcBK6tIFrB3mUK/GPxvlexHfuCl7XL0JkaJ/AveH0WXw_.js:default\",\"Four K\":\"module:WSZVQTewRvKHIXsxSS1B/FH5rsTOjSnQPewWRWIxL/GsDnxrbu8.js:default\",\"Frame Corners\":\"module:Gg9KP0qRbKgzrcmRXo1j/VtU7Y5mUpyESDNyOOy5p/qnwyoLOY8.js:default\",\"Framer Logo\":\"module:KSvtBOJuMnaS19KCHdOk/nXQ6bONSGX4DWxA6b3Qy/QAgTWZoLn.js:default\",\"Function\":\"module:z0CC7NDfc6dDQEBEhn9J/QLKdvv60BVjnbLLovXDe/Idcq6D2x5.js:default\",\"Funnel\":\"module:BT7g7nlu4EloVSliaYIh/EEaWUp0QAepPKNAVaRcG/jlPwmK5MF.js:default\",\"Funnel Simple\":\"module:VyYXoc1L0A0xOR5M2iGT/6DPwQix3ICg5LkNexzyD/EgJPEWRar.js:default\",\"Funnel Simple X\":\"module:QP0QuUuHxqtnLIxlMb1g/3dOgiVkJbUNnj6PIeaLW/D9AAvL07e.js:default\",\"Funnel X\":\"module:PLMEA7ibAXI8qygrtYsW/C75JZE0OE92nOsl8zntY/HKJz9sM6P.js:default\",\"Game Controller\":\"module:OssV7d0sRIJO8Zof8BuY/IHvEvmW8U9H8QX28YsGj/rxz4wx8da.js:default\",\"Garage\":\"module:YgShl8VEEBtF9IkmSnNv/1qYbmMUkbNBc9kEEoNBq/ORzJKjgRq.js:default\",\"Gas Can\":\"module:6ev4xAgV0D6w3Ma1TpIb/JhvbYL1tXssj4iYmGhFd/gTdYYr_dW.js:default\",\"Gas Pump\":\"module:ug3ifVb3IvOU7Ct2IpoZ/YCDH9J6Dk4GtA34ImJBL/t44AfhBMg.js:default\",\"Gauge\":\"module:yjkYbesjvSwXQpgjwSrm/OEM7VsjsQCg0KeP9QSeB/VV3JTFq0w.js:default\",\"Gavel\":\"module:JOx3SOI3Auqid3EgdWFH/tIAvx8mvtliXgc9vodRr/UKJe__BQJ.js:default\",\"Gear\":\"module:ZS38eq055v900R8s8Wgj/g00BfQb5DCc5daFfRp9K/LiHPW3LTk.js:default\",\"Gear Fine\":\"module:lFTBXA2ti0BFjNje62Ql/5tbzLtI05MfCa4ltf41G/QpYB2lxbi.js:default\",\"Gear Six\":\"module:JlSoZaZWxzt4xNFRTojx/KrZlDU99ClxZ5aDF9szT/Tj_YO2pQL.js:default\",\"Gender Female\":\"module:6Gu4AexgJLLmYXVj18FR/jPgSx3wzbgxKDYwca9N7/t4madAR40.js:default\",\"Gender Intersex\":\"module:IwKlYxzgZiEC48qoGGQ9/KvlPdWlgCfUa2dfHNLYW/pGqX5e13A.js:default\",\"Gender Male\":\"module:7BGEbLuQsSKhxJlzihl8/W3v3Guskw2XI3zkcx0mM/H3EqLcuBo.js:default\",\"Gender Neuter\":\"module:xTqpH6ICMFHAlSKCBDq6/SgWYyE85KkEViBSPFv0h/ywmIPnG2G.js:default\",\"Gender Nonbinary\":\"module:eeLlyaANAhlwUzlkdxaH/Byty5b8fbwx08sJA5Q1f/TmcIBUF_S.js:default\",\"Gender Transgender\":\"module:2CNmNLPOXHVBg7yWBG3s/vyylG7miklE561J48xLP/VZ5fIT4id.js:default\",\"Ghost\":\"module:KUD8qhOEwHQlpHdZdRko/QkC62YkPowBiJ4nwEBJp/q0Rm19RPC.js:default\",\"Gif\":\"module:edPKecdOfzG4GtdqLJIO/e7No55l7RppXIp8d87v7/jQACMjvoY.js:default\",\"Gift\":\"module:tiqqxad36ZbuQh9iDdNg/oZ5UwWIetBksiOvQFqbk/APAaAAUOu.js:default\",\"Git Branch\":\"module:Zba0SLQij4vWlxhHoJgJ/6ByKbaC9nwoFx1f8np4h/mnd7TJ98o.js:default\",\"Git Commit\":\"module:5bj4WFDkZdTEJaVe9tWb/bsN76lxpJL8yS5xfEspK/wnS8pLow8.js:default\",\"Git Diff\":\"module:OABpTvM28tU9j5Ds0PNb/85heAwSDj7izc47dLwPs/kQcnx8HBR.js:default\",\"Git Fork\":\"module:pYqc6pToJAtwEsM61850/oog2TdgjmbyXRAwEmvoS/Aqz3ADxXm.js:default\",\"Git Merge\":\"module:TJcHLQvCBbmSD4UQkDQr/yQaA2Fl1xOcMnj79sjPa/PRD07hjRD.js:default\",\"Git Pull Request\":\"module:rVMRKTH6Ai1xkSuBkVOa/6RxxHHJK2zxfiEFp7v3o/bx7xSEF8Y.js:default\",\"Github Logo\":\"module:sFwNivXVM95fw5mikVrx/9XVl4XAH6axGPXfRPPcI/mPx1B_W4m.js:default\",\"Gitlab Logo\":\"module:KyIQtlWk4f5l1rnHsinO/hvBjNZ0ialAJ4I0wFbO8/lalOXdWWg.js:default\",\"Gitlab Logo Simple\":\"module:qtgy9XQh8UwUj0pRpLqM/J1NZS1dBj70AkTtH9ZDI/rvOeaCjLP.js:default\",\"Globe\":\"module:qg5O78z2q8kvZbQWStw5/OjxXH2GCT4nXPHo2IICz/YO7MK5PPy.js:default\",\"Globe Hemisphere East\":\"module:r1mtLsxRWxDRonFPINJg/X5BDgfO2nGJ2EvGk0pkr/eqehdntmM.js:default\",\"Globe Hemisphere West\":\"module:x0mDYH8exseX4pVzwfH7/qyCJQ2Cdbfg0ZPW4H7RA/lgrZ1oKmD.js:default\",\"Globe Simple\":\"module:61SNHA7bRTBw9kWpniCZ/5fY3u3BveuYMQ037vyco/tEf9qevmb.js:default\",\"Globe Simple X\":\"module:twN0HgnFUmMokypFCqhr/F0Fr2c5WcxRPz5eFQn6g/Y9Qu5kJP7.js:default\",\"Globe Stand\":\"module:SjoVf8dzdCKJ29K7LBv7/zDQfWzl4NH3PKhEGjVwX/Xzgzp9Sx3.js:default\",\"Globe X\":\"module:QJKWt3XZ3ML4Ga97fcHq/C9cJqhiO7amdJo0le8yW/pgDEQsOUO.js:default\",\"Goggles\":\"module:5GCNQdHjmfrS2UzXKQTE/Cg4uU9vI47wD0TPoAZD9/w6oy1fo6V.js:default\",\"Golf\":\"module:6q3I8Eee664qCoQ0EobT/rNxRfL0t2zvV5nbV7sTO/Ja0dWSpEl.js:default\",\"Goodreads Logo\":\"module:kgkzPWPnloaDUFAppc3e/s0vbCuUHmMMni2SiPJC1/bPZhJ3I1o.js:default\",\"Google Cardboard Logo\":\"module:JDiuoYPvBmSGPGdBEFGn/kEswpH6fywC90zyfQPP3/SkihAejjE.js:default\",\"Google Chrome Logo\":\"module:qdzYcCrLChZSgVZpbSpA/8ZqcYOjQVjvEItUcj5CC/hwV2tlbDf.js:default\",\"Google Drive Logo\":\"module:K9HPWOq6JzmGdWSziQuD/dVheGuWTsa8yCUsxdSX4/i3V_zQyj3.js:default\",\"Google Logo\":\"module:qiJEpkwSsFnqUfWbTBmG/XLyLJaRBM7cIlIUKbY9M/AvgDV_4pJ.js:default\",\"Google Photos Logo\":\"module:9Q8tCPHv6qkDLFL6IHSK/bROh4TU2HYTf5dZJWQGA/cjtZWkcKZ.js:default\",\"Google Play Logo\":\"module:JrqYV7JvuU0V1Ni409wh/6WsxlzxWy2KrmzUKwfIs/umoFRKPPa.js:default\",\"Google Podcasts Logo\":\"module:fa3ZrgZkVYJsjMCebpNy/AWYr7pfo5VloT0Q0pptD/dU7GYbkCZ.js:default\",\"Gps\":\"module:jC8H3THKtt3pSvlIrBEE/0IJpe2YxCr9Zdb53Wi1r/JgCxjjTQ5.js:default\",\"Gps Fix\":\"module:VYgbJ2kfExfRhlWiwxc4/Y1Z16EDUUPrYCxElsSSA/DrLRiRGGD.js:default\",\"Gps Slash\":\"module:1D8Q86Ke9JoJlPiP5A8z/scu4RBS01qEDNL8VrUiy/mJKqFHnb5.js:default\",\"Gradient\":\"module:4MLasmFcNZCdPyM5mcvK/6vanKKu845insd8Uqufg/pFCHcAsVT.js:default\",\"Graduation Cap\":\"module:B3EWDL4HFFuB73vUthaI/yhl83nuLvhMKLBzc6KhX/BdqO6xpcO.js:default\",\"Grains\":\"module:xjWvePRQzE4ERTLKmRF1/Sffp7MrtehbtVMwqF6Gq/aYYJBCfTK.js:default\",\"Grains Slash\":\"module:0Ky3JbT8rVIRosbXtR71/jHwBaJgib7MQUoCpvI3b/i2Qb2zF7f.js:default\",\"Graph\":\"module:Z1McvlGXbMwbnvT1NCPB/hkz47vmYlAR6FtMdfDot/kllkOSpR_.js:default\",\"Graphics Card\":\"module:mzX2orLkssSI1Ap0C4M1/3mbaZ66NcymLXPk76udc/ye36C6YgE.js:default\",\"Greater Than\":\"module:cO7imzF8GONpKcgS8Wrq/smikCeJIrszbBf43fU33/vTcyEnJeJ.js:default\",\"Greater Than Or Equal\":\"module:1yKPzh0PHj7DYtsnJl0c/ttWGa8RjRBkawKedol5O/HzZETzhNN.js:default\",\"Grid Four\":\"module:fTYi3lrRp0xjc6WkoKRc/hk0cTTzvxlXIQrp1IsiM/zhPQua7oZ.js:default\",\"Grid Nine\":\"module:R2NWtvHgOOj5087aQy0w/iiitIDHfsfkcFefK3p2w/lZpN6pqfe.js:default\",\"Guitar\":\"module:XWEJGwY0TkhXUhnAXRmO/2LFHKGDRA5tq0ij9pmiP/cBLl2TbZN.js:default\",\"Hair Dryer\":\"module:JtwoOsQrVEQ1EZ2hyEMt/W7LePeTjFLm7zlFGPD18/gflwChcwI.js:default\",\"Hamburger\":\"module:MG5nweeXkGE3oagk2n9h/WR9Jsnu4sT0lJ5aC9AsB/QZNd9kslX.js:default\",\"Hammer\":\"module:07UT6gYsceJw3jkcUPpV/BOY1u0F3ueX1hVznoRME/OSMSWI97H.js:default\",\"Hand Arrow Down\":\"module:k6XvzbRFzSNLhU4pQMJX/WbnvAha5physURjUM9Hx/AjESn2bNS.js:default\",\"Hand Arrow Up\":\"module:PYDTs2nLTfySOMz3BpNY/b275cz5TNgIEMACmlwqn/Dtz9GElHt.js:default\",\"Hand Coins\":\"module:5VrAqHFTiHHdh7ku55Y4/KTsQxHh39XzyrLLKF4JA/Ht3ca2was.js:default\",\"Hand Deposit\":\"module:iukYmEtGGTdiyVAB8o2U/UpwRRQ1a1ypnDCqdoL6J/qS4BAmy5l.js:default\",\"Hand\":\"module:SNvp1TRpXrXxwg4LCOxm/lhk4JEWbFpZeZpeJTAXF/IoTnWOXgK.js:default\",\"Hand Eye\":\"module:Jr9ktBodiHeBtuwQvofk/GXmvUK9NSO4YVh7sDQyi/ZLFRQDyBO.js:default\",\"Hand Fist\":\"module:ugkNZEcBMBD80oKb6GyB/SxetkM0SStt8rc6bUAsu/UtWAFHdWw.js:default\",\"Hand Grabbing\":\"module:HcpMI1gY2UH25UXGaQpN/L32loxQOHkmye5H4xgdF/ijJozYLoa.js:default\",\"Hand Heart\":\"module:VQZhf4yGLPXL6Yh3mWu2/TNMHAESDDcxZsWuLccGi/CeofsNecv.js:default\",\"Hand Palm\":\"module:4qIWUzzrP3iEm7kr7WRj/gY9X5S9qMsQ1lfzSyiRt/ThrPqiGDM.js:default\",\"Hand Peace\":\"module:txWQOQXA4BlKWUtDbEsr/0Eao3FDcPdRZKkzSPq0u/yajMvleK4.js:default\",\"Hand Pointing\":\"module:ijljSpXBO5pSfg7NEEKy/r4mj9zIKLwgtJuVgx3Or/GlRw_tFqJ.js:default\",\"Hand Soap\":\"module:JLy5MTmoMBSnv1UAAhze/VTrK6WoyEqCAt1c0pUBA/XFS4KoS4L.js:default\",\"Hand Swipe Left\":\"module:PrL6GRUPnfurjSicINDp/Z8URoiOjuFIBcmgiY2kR/CMc2tcPiE.js:default\",\"Hand Swipe Right\":\"module:6BRYJBuoNeVduSqV6OgX/n9LtVKyesvBd8vfCqCJ1/O3n52Lw1z.js:default\",\"Hand Tap\":\"module:ghlfelthRQ7U0wrQLThk/QvyLQu6F3nCE26OsG7v4/IgFIT6bq6.js:default\",\"Hand Waving\":\"module:BSGi0UPiLPne6PgPZnJs/524lOx4f1dHojaUC9EwV/T07cgT6Yn.js:default\",\"Hand Withdraw\":\"module:DRqwRuuLXRPoTgxVBpLS/GY4wYfgEHZn3fykJseEL/VueS7qIo4.js:default\",\"Handbag\":\"module:03sOE72rOJeW0mlTAsAW/3QkiqgFmRdHm1uO4ntuu/VS3EB4mHd.js:default\",\"Handbag Simple\":\"module:eKSK51cDUGKGeVtpZrC9/BTZukRw86x3zijJLIdN2/v3GmBlESz.js:default\",\"Hands Clapping\":\"module:uWyWpFx7LYoxeV47mULm/JKA5OQAdclcYrpHov8iR/BpXJZzF90.js:default\",\"Hands Praying\":\"module:KlKkeWZc8Etvg0kUose7/zCvvPKkLzs0cdQlBLuPO/Ydwr6ZRk9.js:default\",\"Handshake\":\"module:ESAQYWtLI78gTSolf8CX/8ZJjxQOlvWL2ptQDlVnn/D5cs2H7UB.js:default\",\"Hard Drive\":\"module:w4PF3MN6i3wMDZmTlCPU/KircZpZdtVFWcjpZYw2N/Dz6dhgmYe.js:default\",\"Hard Drives\":\"module:4wN4wjNLYRQjjDqaNYLa/4YbKmD9Mmvl0bdEPoNli/sukqTqOrn.js:default\",\"Hard Hat\":\"module:gpazJ28npTaz9l3CfTYB/ISd1QV1gc9m4QYQTt9HN/tY5p8NSV0.js:default\",\"Hash\":\"module:KvTGs4piYkTkOh8GwUP2/RKeD9wUCUJdxra9PQknC/xV93llpB2.js:default\",\"Hash Straight\":\"module:9BvShwEhWWBYmEIUOD8y/tLDm3hAYlIWJvC1aNw0l/ePYwBQEMX.js:default\",\"Head Circuit\":\"module:9JXODgtDQtO7oId0Pvgd/KVLpgUTKaqIY2Laa5FNt/TSkH3LnjD.js:default\",\"Headlights\":\"module:rRnSzWfeS4MW7HcMThIg/DrNa8usST9COsTHEX4L0/fjWUn7I0U.js:default\",\"Headphones\":\"module:uIVKEnvyiKaSbNLLAG44/n8zn8uKXkEwcX25sVsSr/jBZQRh5Fu.js:default\",\"Headset\":\"module:dK7lkugV6DXlz0PaEQWJ/wt0XkEx6tCSmyhIb48BX/wqFvUEbj4.js:default\",\"Heart Break\":\"module:c4EFKcRVIerM7Lx8ULWF/PPIW0Hev4gUaA0PM6yaV/Rxi6rMuxB.js:default\",\"Heart\":\"module:QhPq6AcNqNxwKfcjdc11/vWMMfdaZeuK6HPkItM27/IomeaNcRM.js:default\",\"Heart Half\":\"module:nQp88BmkdaAM8cvGsing/zH4xF9GRd3JxvnZWlnbG/CvHieETHx.js:default\",\"Heart Straight Break\":\"module:ymfAq2DVcLiKlsezjKVS/8WwrCHe8QToasxixJGmb/SfCyr4H8Y.js:default\",\"Heart Straight\":\"module:fpHyMBRoTFQ8ulgKipDJ/Igl1OlKuKW60Arr34xIB/ABzgAFNVD.js:default\",\"Heartbeat\":\"module:GwyVGSn0iusAMwVJtKfW/IC41yaDVUcUdPrhi5z7v/cmltrm2mS.js:default\",\"Hexagon\":\"module:rQupMI1lS1taUuPYVZK1/Pt4rVhv4rfus1sWkbg10/fx95fnKPs.js:default\",\"High Definition\":\"module:borgmbENt1bQbFB5bVss/CBeGaFPqUd7sWqZLftLJ/r6dP5lGuW.js:default\",\"High Heel\":\"module:jgoEg3RZZJaKCjT7c04g/kwEl0kiiMulr1DdKy3fg/JsQsSsbIr.js:default\",\"Highlighter Circle\":\"module:ABhxx44rlZj5cKdwiIWo/EXkwtSK4Tq9lbeQLQOoc/z1N2HazWA.js:default\",\"Highlighter\":\"module:YTsrGTK6liN6OyzxSxg2/5vr2FOSvXMKV7onjjzoH/Z06Mqm91Q.js:default\",\"Hockey\":\"module:dCHnEom3yZIxFDDrBOuR/r907qz4lBsrVHAe0xKWp/ymhow8o1O.js:default\",\"Hoodie\":\"module:PEfADLxzAgrNtB0DEK2p/xd2HOfeKEOfxySlrLbYk/MO7HC3i4P.js:default\",\"Horse\":\"module:6urCogANIxBCv3s3wf3L/q5xTus2XE8lfLCXNYcIW/RaY0ssYTs.js:default\",\"Hospital\":\"module:fpRuSZmFCHag9961hBaQ/1t4HA80qcwYqLpcncmYk/OHmTEisD4.js:default\",\"Hourglass\":\"module:XX0cySuUAroxpLs6csys/2vlirvfY4ucH6wvGrENg/cnD21AQTM.js:default\",\"Hourglass High\":\"module:7a6vthtxSkCO4RA4DOM8/Cvy1mvgqol4H57mT5X3B/k2aeE9Gsr.js:default\",\"Hourglass Low\":\"module:WyJQF05i3dTM2hFWEps5/VGCwxGxJaaGe3KSa4gU5/hmT8OcAIo.js:default\",\"Hourglass Medium\":\"module:QtGeitVkbN3PCoBI2QDN/zvAdF3QpGuqs2RJXEEQl/PKWuywvGO.js:default\",\"Hourglass Simple\":\"module:1cSJ6Efd50QJ7uW3nvtj/nMW4TCXvT3sGaIK0Yx9v/I74KZTnR4.js:default\",\"Hourglass Simple High\":\"module:V8zDJkvVhfusgG8jYAKo/RBaxPybkDD5z8JVPqjvz/VZtq4BauM.js:default\",\"Hourglass Simple Low\":\"module:QJ6E8ghddPXA7DAwsxTh/jlpl46N7KB17CSPVkCum/zRBbQSB_B.js:default\",\"Hourglass Simple Medium\":\"module:3nmZs2E1Mov38ixo7vIP/LF39xGGZpHcrvOivGArK/Ld2HrMxrJ.js:default\",\"House\":\"module:FVmCnCqw20xX4DJfDJYm/SFCB7H15XZWu6ihL6WN7/u5jXKuGDk.js:default\",\"House Line\":\"module:EUnymQnlbcEVKcI2X0r9/VYrK5eRHQLgMzPkHIia6/JdTuvSk2g.js:default\",\"House Simple\":\"module:3LAsldMmThOQBqKJ50qN/q1bPdH1vYkoscC6XxEUG/U8VMdCTEQ.js:default\",\"Hurricane\":\"module:zy7doF5lDnBlRzZuEyst/niuwhxsHgpXZm5fAdl9c/I472Qzqaw.js:default\",\"Ice Cream\":\"module:xqJJcRdp6zbCrnhHD9Z7/lVP9sCU2EOpfTWNM4hsC/BZ_sFCBdU.js:default\",\"Identification Badge\":\"module:X5DGtIjDvTt8vRP8LeGC/uWE1LPsXrJLrFTWikDMR/FAKYc4FJP.js:default\",\"Identification Card\":\"module:wntgnjcv0xBcqsiUGWns/7Lhtwu66mVcNfiKapBzX/xfJPEqeUL.js:default\",\"Image Broken\":\"module:4n353WOypX0YQKkDsutJ/LtPcZnl2gHXY3SRDzEC4/J7LJPFuac.js:default\",\"Image\":\"module:XszB2BzXuSJyMFWYVMDC/plRuXQdyxvs1QLf9rwNa/Cu4GB9tGO.js:default\",\"Image Square\":\"module:JKPk6PzfiRUDdnvc0eYg/XRzru1pN3dJcG3kf2xWv/d7Whs3g8r.js:default\",\"Images\":\"module:LtaeePSXBJejyU4SGxxG/oYDoQg66mlYkJqwijQ5O/BrPg5s_qj.js:default\",\"Images Square\":\"module:igjBkuoYmWA48g63Bj4s/LUurY0c7VZPbdSvUp6ld/hX4GEeLb2.js:default\",\"Infinity\":\"module:zRhvMMaj8jAG4s0SbzXg/e6YOWahXonryZhcs1kMp/QmKkkmqY6.js:default\",\"Info\":\"module:4KjHgbjzYThzxqpsmx4P/KbnKM0qrAjdhZauP6XoR/RqNoo3tj6.js:default\",\"Instagram Logo\":\"module:PtxaBiSAA5V6LvrpAt6G/EsR1AqByikNQR8Cp2V8c/UD0eTfbk_.js:default\",\"Intersect\":\"module:2eP0yRWqOiGUbjguLIH2/jUfqdpgWx9JXYxabHDh3/zemwpiqrW.js:default\",\"Intersect Square\":\"module:2k8x9xkvogSIMDQqdgv2/5KvZ87ER9gXXvJmkub0n/f0B8L_h0Z.js:default\",\"Intersect Three\":\"module:O7cnO9yfn6aXBeS7VEDl/6s4juMOm9lWiCMqYIj2Y/UVccEFSrf.js:default\",\"Intersection\":\"module:PEh2nynnk96MU2SyLjUm/yYUZS1lxrDQdqK5ordMe/W_3bSxiJf.js:default\",\"Invoice\":\"module:cqHX5cklx4BDFBo0B230/ukR4ViNRaGu0YaIKLFx3/jusSGKtnH.js:default\",\"Island\":\"module:lF83fGXo7EHHmwYgFCBI/qq0cdbJuv47uvoxwvX4T/gB_AmXszQ.js:default\",\"Jar\":\"module:529u8jiFjsTn0oTHiYHa/Gj8GCV3N7NFEZfQ0D0bt/WhyQgc4OD.js:default\",\"Jar Label\":\"module:V7U52N2z5PpUFrBh7EqJ/jxhvgMr7hcnchQLFBW2w/oULuUG9Hj.js:default\",\"Jeep\":\"module:V91CpuM7O2XlXwKI6x5j/cNndvn6pTEwurjV6857k/Uxq4GXTdt.js:default\",\"Joystick\":\"module:hW7OE1ajJU1tX5r2KIcs/tXxq5GDIfyZdbslefHZj/rhveRJwBo.js:default\",\"Kanban\":\"module:JBkAWHgmMCJrWg7hzkgU/buGUdi4xEH2fQU1sLwID/Z6w_tvUh9.js:default\",\"Key\":\"module:PfYvgoD40shWEab2QbW4/nKuIgozlQtzz9xFYIcUy/MzhPJYTlT.js:default\",\"Key Return\":\"module:YXlOTCxBHIYI1L9h7tf5/uMFaPN1v8uNnHYEq8jNL/d8wTgYpi9.js:default\",\"Keyboard\":\"module:RPAH06sUwMX73FD416xL/b9RP7u9bZ9v587iXh180/md2ab6NRo.js:default\",\"Keyhole\":\"module:cGEPlPLMJFYpXO56VFCx/S2ZJ2GzdwjM0Ve0kj6EG/HujRE2aO7.js:default\",\"Knife\":\"module:rOFGPTIoC4RnIrHCNbzS/5xrLzmos21zUEtSrfMJ7/BbwacFb2Q.js:default\",\"Ladder\":\"module:P5BoQJU8oqYjKAEjhXPN/cp0W2FiKYFulKszBYxMj/aVrMUm4UD.js:default\",\"Ladder Simple\":\"module:Ca2r2G7t5u4tcLyefvdP/L4qt1ny9s9IQXdV3Bq8w/SAw764AgQ.js:default\",\"Lamp\":\"module:q7gvUp8fJ69YpcIxVvcp/3LeCFrSANwFTmouBfQ46/LhpjkV_fc.js:default\",\"Lamp Pendant\":\"module:zTj0LNcwIwpYdcKRw0Zw/sf805ptXJq3wAODVxrQP/WGfzoAguW.js:default\",\"Laptop\":\"module:yV2QtYYJOEHoAM6l4bJF/0bp6a2sL9ERZeaNS9UdG/qHDjMJdcu.js:default\",\"Lasso\":\"module:N2Iedzm8lxuBA4Z3i7dq/LqFl3hnVcBNNoaVHenE0/MDB3az_i0.js:default\",\"Lastfm Logo\":\"module:gemr8ZvpIMtNtfWpZTGQ/yU27be5uYRuTGLknFCXn/taO38NQJ9.js:default\",\"Layout\":\"module:EkO8UO1eZ5gGPGylqVIa/YT0EiVRCAMpA8yEyO5ed/kW7p8nxxz.js:default\",\"Leaf\":\"module:KWNNduwKoKnTbOk1rXSC/tvASeTv7v4EcfcuyftvV/LbO3HXMGE.js:default\",\"Lectern\":\"module:bAAHEYvDAlDwhAS8xZiK/went4wiklz3v688jbfj2/sS8LF7G3I.js:default\",\"Lego\":\"module:8GKf38UfMa6hAs5TGslH/MZmdDnqy2Y42RwstnXxk/MkjNRFEtf.js:default\",\"Lego Smiley\":\"module:6dTvPKRCjyiFDXjppglx/JaWI96gKr4dDt4k4mZ4P/BeTbFy_NF.js:default\",\"Less Than\":\"module:yrqMfCQ87OJ2BsrzRSj3/QXLO56lbKilKf7lH5om6/p_ezi81bE.js:default\",\"Less Than Or Equal\":\"module:kUmBU4nNLUCuwMjpjMuY/DociqLmP8YfSLdbGhA8Y/f1UYWlBcy.js:default\",\"Letter Circle H\":\"module:JDu0Kr2UcsTbdaLSpL2h/vzWuB9pvKzmM02EH0U9A/vi3PSNiMw.js:default\",\"Letter Circle P\":\"module:xdgoM1tiaVDPW9p5ZbCA/0lOxPJK744RvOU3uXoaB/EunPHPk7j.js:default\",\"Letter Circle V\":\"module:PzLVsuIHG4r011V1IZVU/iyb4mV3kbV1DELnRjuLA/YpxT1ieLk.js:default\",\"Lifebuoy\":\"module:AjwMDtWtqFFZnGULH5tP/284guY5z06uem9hdkdYl/fr0OzsHeD.js:default\",\"Lightbulb\":\"module:OPX4uBYknw84rYfBug4H/TXzZXpKDEaZUl07smmk2/P8VvdfiXQ.js:default\",\"Lightbulb Filament\":\"module:8yhMIsjTbBKqe0ZQJrKS/FtIJeLMk9RkP6ghvcWn1/WzUIVtK7p.js:default\",\"Lighthouse\":\"module:zUNSZKUpaco4mYBOoTqv/dA2dIq89net2w0AAcQDy/HI1mLnqkq.js:default\",\"Lightning A\":\"module:ElA0xaUlqP7tD2LUleWq/nZ1OktysXPMuDsRLnUb3/bSb4Z4uiv.js:default\",\"Lightning Slash\":\"module:ep9FwJof1O8jAZeQ82uE/G6NC1lzwjIOM9VzFRbH3/XCQRU6jp9.js:default\",\"Line Segment\":\"module:NEszDNvXeA9ajOlXpgDt/OcUyPNjY3k62H9MLikFi/CSN6bDlFX.js:default\",\"Line Segments\":\"module:RSCileI2YqSS2Nll6x4m/vAZLpnpFt0TBp69QFpLi/PJi8H39LI.js:default\",\"Line Vertical\":\"module:tf0EacvPy7DacN4zq6PF/Mx6u0QSj1HtBUdZNhmCj/PlD8NJCQb.js:default\",\"Link Break\":\"module:JJBCfe9PJgfGamnq187A/j0wEX1DW8jN8xhNdGicB/ynbTnZdab.js:default\",\"Link\":\"module:WiitR9pg0FnfD2NJ73lu/m7AszHAuNDoZtmgqXbZc/zCnEq6lhz.js:default\",\"Link Simple Break\":\"module:bMKsbSiWaR2C9IeeVqqx/pNwLHZwsMDWYJUzlgpe9/dNMHUKgBW.js:default\",\"Link Simple\":\"module:VaHu2hDQgvT7QocJBeNI/1ebX6asMIUlTGuuREfja/lqLqTdUzT.js:default\",\"Link Simple Horizontal Break\":\"module:TlH2yR3izfRxUzffNRbO/QFxvxTQ9ooCodR5CwjIY/upMp96_YY.js:default\",\"Link Simple Horizontal\":\"module:QtsbQR2Yh5GCaKXZvNy5/EISkuRusq43kePfq3pMa/QKPndRBgo.js:default\",\"Linkedin Logo\":\"module:JNI0unvKLnSNOjYgWQPe/cFK4x7HnGbxoZXkZNw5W/hNcHJzSkR.js:default\",\"Linktree Logo\":\"module:6yWWR6xYgTJPEGrTDM9I/HNiXDf2J7kmIS9vlYNPE/TRAM0rGfL.js:default\",\"Linux Logo\":\"module:i2pV7iqBDtprIi90XUyQ/fKd9RtoTdAWgsnrbyRyH/cOarRvRig.js:default\",\"List Bullets\":\"module:nOK0kqUhx3R7pa5LFaCf/XWiyN5wdwdeFxeMO57Kz/P6cT9s0ni.js:default\",\"List Checks\":\"module:YPcaYhVtTLqA8aY3yf7A/X5YnK8CSmb5rDcY43LsI/arID8FpTr.js:default\",\"List Dashes\":\"module:XFAF66dZCrFSX6ltEa4d/mBebxFMLs9SFZ0sYTa6K/PSKhk7USh.js:default\",\"List\":\"module:4xJsJPc59it6XmHEERsh/koUifyDPwJ9ohyYl3uMd/itu1soPCZ.js:default\",\"List Heart\":\"module:C40qLpzjwbOTMWy00LFu/Y1AHByrn3YYUnHbnE2E1/wKGZZKvDC.js:default\",\"List Magnifying Glass\":\"module:VBeJlRAXwj8ulXBPB2gl/eJhOwdcZe33YJKPN0pGT/bUhpWyk5x.js:default\",\"List Numbers\":\"module:ED45enHBb4A1cTLeaKHc/C8YN5OTCNPLRuepzmdoe/ba2vTforR.js:default\",\"List Plus\":\"module:MTKUuJC3DeZECCip5ozz/NkiRkZRvRjK938K3KndU/AjBCvSiho.js:default\",\"List Star\":\"module:tyHWeg1SSSevVLJ8DX8m/1TXuqquzUlOjONxTVXmE/kQZs6jnEb.js:default\",\"Lock\":\"module:kyVe8qT3f5JdqXz0tlno/NpFEcmwji38dnMAIQiku/qhqwQB4K8.js:default\",\"Lock Key\":\"module:QSV1fFEnmWZZYwL7KLDz/Ej0Cays8vTVj5iAvxs7i/o1YlMuz42.js:default\",\"Lock Key Open\":\"module:ya05sdJFfRLoolqwAxk4/9bw3Rli4tl5JMss55z7y/S0SZCaHQ8.js:default\",\"Lock Laminated\":\"module:nNOEcvSrI8gYn5Lozb4x/Gco6sQeP4xfZVyei4cbF/y672fYdEO.js:default\",\"Lock Laminated Open\":\"module:VWWnpyJ9xyNwLGqcGv0m/EVvBXT2H7hoHHMnpQgxK/AWk2rCIbg.js:default\",\"Lock Open\":\"module:xmu4QMmFTH7Uhh6NG3Ct/a7fI8Iyc3OjFFb83R32x/Noah1AIRc.js:default\",\"Lock Simple\":\"module:WFahh94YAjaBNoeziInQ/PS4MZKQLRzMFxOwAAlKk/jFWybkDzk.js:default\",\"Lock Simple Open\":\"module:EVBYHrmKffBQ2lmDuGwg/MbzYekuu10G0lwwk8pwj/tCfmmcAeJ.js:default\",\"Lockers\":\"module:XLCwWQvHaItMS3ObW9Ly/MkQtH6xyoF4rMwnIsdFw/fPShMQ_c5.js:default\",\"Log\":\"module:NiOcHGAjn2uT9CAl2voa/RtWghyrFoJGAIRtEBXoX/kC4fgF1l9.js:default\",\"Magic Wand\":\"module:BZjVltslf0ooTGkXnYMn/sZp1AAFgZntx1cPB0lfV/hDgzfB4_z.js:default\",\"Magnet\":\"module:0WG1RWaJPj3jhQl82KEM/69z4kXwl3jl8MizNSMmx/XJFZnzrfq.js:default\",\"Magnet Straight\":\"module:xJ99rIg3CjRhGD7I3aio/tPDr4EYrCjZtbLbQJhg2/U09ZsYIvr.js:default\",\"Magnifying Glass\":\"module:78wJr0q4vFZTRbgiA8bC/Y2EfGRGz13i3kdwNCKGk/gU109MUNe.js:default\",\"Magnifying Glass Minus\":\"module:bS2yPJa2FII9QJHJ2Gd0/B3IrUf9Uyh3KF5iBFOYA/lPIDw6VST.js:default\",\"Magnifying Glass Plus\":\"module:sJzV8k5bHKFT18zSPBNJ/3hw6s6xs6TPNz8Wzxj40/ZKJZ4xZ08.js:default\",\"Mailbox\":\"module:HbZV1r5jc81IsalvUzEq/fyTiKy3Wx1OKdwVpo6r9/YdrMjw4s_.js:default\",\"Map Pin Area\":\"module:tdjteaDrHQe6tjNxAHOE/oNDf8G4CceUVioagQjYe/lQquXqUxz.js:default\",\"Map Pin\":\"module:FaxZInRwAZReJpbcbldd/muqXBKZwrJnuW4AxlyYL/Whn4aos15.js:default\",\"Map Pin Line\":\"module:DrMeT4B04O1n1LSSUeJv/kQD3hp2mwVKEBcad4O8c/Mcs8mgpsO.js:default\",\"Map Pin Plus\":\"module:A3ZzlRsaBTd8ewbVx4fX/rX593H3u5l6R5YRejMoh/PwvA1fF8A.js:default\",\"Map Pin Simple Area\":\"module:ilsbz3hTSStnGOYOEb0b/oQFLbSBg8CJc7LvRc64x/W7QSpsQnj.js:default\",\"Map Pin Simple\":\"module:OUZ0utNiooOoCk7K7Qui/nEaMFRPMeCyQmYrxYXO9/OOTOOdaMO.js:default\",\"Map Pin Simple Line\":\"module:e9cvs05bzL9udRSvOJRW/CDI3Dh5WnxO7umXyKyCs/DZsgsvcmk.js:default\",\"Map Trifold\":\"module:zeAt37uVx5nPlCz9CSY7/SUkAvz83OJteikM9ADHt/bpLyLK1Gn.js:default\",\"Markdown Logo\":\"module:sUYSRLyYfyDiGQmTfIRj/vXRRUH0GWDuqT58q03Da/j_Gr46LQy.js:default\",\"Marker Circle\":\"module:vgbKdGnJ0B70sER6qx6p/vU0VkLN0hdRvUKRkHj28/RCrkhELri.js:default\",\"Martini\":\"module:oXfFdAHPXBqSvQ6e0A7u/mv8U1zyP6uzhxnuV5c0e/IHf12Tp3T.js:default\",\"Mask Happy\":\"module:olaaXFnVQFtoOpfAqapx/BLaiAyIoIl59fhXfvmlX/XcLDLUOQW.js:default\",\"Mask Sad\":\"module:dnKz7yUT22yYDu0IMjvl/EoHGNIF7VqjIqCR82qPM/PRL2DyuV1.js:default\",\"Mastodon Logo\":\"module:5acdX2ZYtSOK8ar4NgTO/aYr4gU6hWenkoO2dOZaW/nNTLoAfpG.js:default\",\"Math Operations\":\"module:9CpW1eZpnshdEAk5sdBu/FMyKHWgPXlzdO8qnsDam/ecLexd3Y4.js:default\",\"Matrix Logo\":\"module:VTr2ajUMsrdyo1WwRaS7/q02f2JQ7DVKGUFVdJ2HR/bcfAqtjYx.js:default\",\"Medal\":\"module:zLUxejQE75JIeW2nbWJC/FlDrGHYJPXRLA6wAJAzC/nZ9QOUUgv.js:default\",\"Medal Military\":\"module:JwWM519ipSjq4Mr7jv4R/81tKBfvTDPQJ7WbqbYLA/MFnHkke6F.js:default\",\"Medium Logo\":\"module:8iVXlKeWlE30oCBLWAL6/UkomkIwi87fun47lijWB/SRgpV_OET.js:default\",\"Megaphone\":\"module:goM5KwGzkJXE95xpbTeD/FhH7EbwtoZuQndnOrDw0/IKTVpX5qn.js:default\",\"Megaphone Simple\":\"module:hl8NrzWj9RjF1oYwYhVC/BhxNocNfsWV3Vswv12Kp/rm8_yXqH0.js:default\",\"Member Of\":\"module:efV4ZnoLHCmqnucQ6YaK/cTAUO3tpxUl7nMhE8rzQ/LAfA0HvYI.js:default\",\"Memory\":\"module:ucTMMsVS5M1uNtmLqDKk/KawLSPz3mtxb6v7vxITO/EAea4VXCX.js:default\",\"Messenger Logo\":\"module:ayZa09p0VPJOdUh3L9I7/Krzj9E0EvQ4lVbz9P78Q/xH0_1QhWP.js:default\",\"Meta Logo\":\"module:vnWyhszjzDxv49kpZf92/PqgwbQNa2MSbxBXCXYLp/XzuOCCUMN.js:default\",\"Meteor\":\"module:43AaYMgSmDHegR2sqxOM/CTx82iLYR2TPEB7QWaG7/UvM0wDa6W.js:default\",\"Metronome\":\"module:J9gxzgcgllPanWwOJJbs/PgznMWRX3oB5sSuXc5jg/nSHvB2vIW.js:default\",\"Microphone\":\"module:AimJ5Cqqwr7oZRa7hDOW/Q4TD4ECJ7htL53uHoFMz/NYDb4xhqi.js:default\",\"Microphone Slash\":\"module:27FO2ERuFUbqV7eL5Nka/R0quCPyDsA8hHi9MWeRS/fqx6OLIJ5.js:default\",\"Microphone Stage\":\"module:hF3oE41WUyG1rmfOtVl9/t1CyLFLWy6qe46d4wQjW/wzi5BoPWo.js:default\",\"Microscope\":\"module:QP7SjxtqQD2kP15T62Bl/hFszZjRZInHPeG8AwhHw/ZmBTHQkWA.js:default\",\"Microsoft Excel Logo\":\"module:Nk8cehWKJYImaxqDBPbj/lXhMcsQWe0gRHd6clmO4/uKqbWtrZz.js:default\",\"Microsoft Outlook Logo\":\"module:uTnpkb19IVnbQuLdCsIQ/FdzW8Yl3XHnRfcRg8tKa/Q74tpPlJZ.js:default\",\"Microsoft Powerpoint Logo\":\"module:QLHnZrv0XF4ol7gcEe3N/Urw0EmNbjW4FJ0hH92XB/He4wh1UvR.js:default\",\"Microsoft Teams Logo\":\"module:phQAtT6L14bXNeLEy6BX/VPCLtRLmKc4ctyiLvT9A/HxzKFZR8h.js:default\",\"Microsoft Word Logo\":\"module:hIGlGpliYQglktbyK4Tp/IbxZM87LNoYOH6s8K5Ue/XkFrzvvjj.js:default\",\"Minus Circle\":\"module:WdFpQJrFJTopgUSdxeRA/uVbP4n3IvisRxHUSHeK0/P_JlO0RGY.js:default\",\"Minus\":\"module:XWlg8k1reSGaD8FxxtNM/bBmqMkWmu9cdiWRo7WqL/KgtuTnV_8.js:default\",\"Minus Square\":\"module:u96RdlpCbB0lsZhzqVPe/Tlueg6pwczT0tAI6w0mb/TYSG5Em8q.js:default\",\"Money\":\"module:KjptWbam6Lh9QGw0hBOy/HKHdbZcuMFOutmiIN7nj/tm1UxMYDS.js:default\",\"Money Wavy\":\"module:Oe74qjD353KYgpYBTfO4/kKNw5hUozgbkPXJOmU6F/hqKc9RA03.js:default\",\"Monitor Arrow Up\":\"module:poQCxjEVWUlgS0M9LFu3/CNmvoq4W8atGMSj25Dbg/OHz1crvNr.js:default\",\"Monitor\":\"module:jDKTm4jXG8iOSksImTiV/bCvMemNdesUJOIHqj1YJ/FRHUBKJFc.js:default\",\"Monitor Play\":\"module:Hfo2gmFrXym6Aru8EAp7/y2gITGTdMypbRgPirQLQ/yvLbx3Nxe.js:default\",\"Moon\":\"module:nbuNhfVKyPi0h5Tne2TL/eQ8JjTyXEuq1tnOS9r7Q/e3RoWW9O3.js:default\",\"Moon Stars\":\"module:8Kth5566AmP2f8alTIZu/gcpy7DRQjN5K7bdlGEPo/FmpP02mnR.js:default\",\"Moped\":\"module:YdnAOscDwx6X9wDUxf09/yAdjIgUJlgLPUv5tZfFD/eCe04DTTZ.js:default\",\"Moped Front\":\"module:RtkkPBNlcOw3TQz2BuhK/7ll1oclyam7LRG42Vi6M/E6DZmJ6B3.js:default\",\"Mosque\":\"module:CLVsw7vAXrQpyczQoI4q/6xxYPEoRte5rLhgqLdqD/Si1G7lObL.js:default\",\"Motorcycle\":\"module:eebraMUblXOiMp5ax5O8/K8KnvnrzPyLNcMascOmh/Ugi0NFftD.js:default\",\"Mountains\":\"module:SgWo11UEt2hezHJLbe3W/O8EXHSRIlRqJKZp0Wopk/YM1l33Vvs.js:default\",\"Mouse\":\"module:8goMmGL3Rl5j8KlYlNH4/fbIEvpL1KRJYNHMdVuSA/wxqTHx9EG.js:default\",\"Mouse Left Click\":\"module:wozSdOw9xLD4bU8vgbOn/wb4qoO69hzzfif5HcegI/TAL7dNgd3.js:default\",\"Mouse Middle Click\":\"module:9VayYiDYWwR9H7ooEDZv/U2BFmfTzcJMGnfjfqfe4/ASq_EOWod.js:default\",\"Mouse Right Click\":\"module:hnhhS9ydrL98W1PGp7gX/NebXgEhpcw4pNr7qXpe3/CbPNyWNUY.js:default\",\"Mouse Scroll\":\"module:KD4kbHruP1dP5yklcHSs/3uFCgMY2ZoIzlCSREwpa/GhRlwuzQR.js:default\",\"Mouse Simple\":\"module:VfS06vyz6VteShi8NFZK/i0woWPV3uRvfll9qnfmW/rThruZ45v.js:default\",\"Music Note\":\"module:1ssMJhMNDycTsXuT4vuA/1FWbLvhzrSihdcUqIyIb/OFYXFrstg.js:default\",\"Music Note Simple\":\"module:BUYAMrbJEUNEzKnwM2mf/rJYEFlpK8brNW90oNwor/FaF8XgPJ2.js:default\",\"Music Notes\":\"module:Vl9Dko5eDW59tu6L2zhH/5oB6ePmeNCJH2fFI8nWS/tDoQMjTKM.js:default\",\"Music Notes Minus\":\"module:dlpy2bDtdlAOh11wfgcX/zcqrJ5LcSOuPloMYAGZx/ujIa1yjgh.js:default\",\"Music Notes Plus\":\"module:Pp2Wa34hDENAfJQiMZ46/PFbqp53zwijCUl91UCrW/waI46aalD.js:default\",\"Music Notes Simple\":\"module:0L4lRA4XAxmcc07iarBW/EwBLhOPzZopTjulxLLiz/sQjTZbWnZ.js:default\",\"Navigation Arrow\":\"module:Njs6CMi6m8Sj59wlmtLM/nhfZbwaTimvMUUM4acOm/pMnGSiDdp.js:default\",\"Needle\":\"module:D16ZwOemAo7ryvwep6K1/khgsiurHODdcJhzaZIOk/qYt5GonfW.js:default\",\"Network\":\"module:Z63TTTzZrd8fxBqqOKLm/fKknV1ToJgXDwr5C0cto/XbLbnAiqk.js:default\",\"Network Slash\":\"module:9L1Ca1CdywwOeL5VVr1k/x51YCPMjaFzbFDd0yED7/sh_VTy39Q.js:default\",\"Network X\":\"module:xg1g3p4wIbJ74Qi96UCn/a0EDPqlbvSMSTLOAu4O6/TjEzCHIAk.js:default\",\"Newspaper Clipping\":\"module:C6mQ7TFcYytYISJWneeK/yLFrmBiRAFhxG5gXRZKZ/qaecwyQhQ.js:default\",\"Newspaper\":\"module:gr0AiXk48KHfWreN1017/VzD1CB93ECcIwaSQnIaC/XSMFCgWhJ.js:default\",\"Not Equals\":\"module:FuO4sDBHdJnk8lFyNGlq/8NmO5EqW36CZpU5T6CF0/POTW5I2Et.js:default\",\"Not Member Of\":\"module:1zCgpfI7hROqmf7ouHmn/vJI4b9d1q0pHcSMu8Ebs/xacyWwtKu.js:default\",\"Not Subset Of\":\"module:vbJzO0yUu28rHVesH110/cDpBhc96QzFH6FMAnthr/g_KpZNX7y.js:default\",\"Not Superset Of\":\"module:XAYwWi7h5E6DdUselJpg/py8jS8oay5hcs2rWV45y/fRqrUE3s0.js:default\",\"Notches\":\"module:D5I1x4gvg2ovUGf5NxPu/qRgILOWJzb0M7ECFtuV0/pXC9lCoW1.js:default\",\"Note Blank\":\"module:SnF3J7IGe0Pa4pGgTaGX/RsaJauc1SZo4bfBECyuC/niYXHtJbY.js:default\",\"Note\":\"module:ombG6td1yx47lQwZE9Kg/fezDztHOWbcN1BKF9ioU/B6RKbBfKy.js:default\",\"Note Pencil\":\"module:1fnQPx6IxfWY2HZgJTr9/ikVF7oAeIBDsyJE7ZFFo/OLGuV8t_d.js:default\",\"Notebook\":\"module:aXr5l29PuV24vmO61FKj/2rarMk2lRJTYaaCVxoZI/c7ye2DhyA.js:default\",\"Notepad\":\"module:u4oJBRYPkmNddfjjkw63/m9eP9cEGoT4FGnsz3UnL/zQuASIXSF.js:default\",\"Notification\":\"module:0mJSW58IcGkrsjTmDdxZ/Uz8w94YGlfGj9skJhIVt/BdHzrVV8X.js:default\",\"Notion Logo\":\"module:zcSotDXwC3ILDpYMuo5w/Yf8IivW8YMpET9VPAcuj/ciWRcWiCm.js:default\",\"Nuclear Plant\":\"module:rcoR01fObw5wmPPGbBpN/JaDWkrdKnJvr39M4RldL/cTOcM7LNl.js:default\",\"Number Circle Eight\":\"module:InUH5gQ6wh5eOmtUXG46/32rPnjkhsBXYYXPLIuwU/Ry8oLJ6Bq.js:default\",\"Number Circle Five\":\"module:KSQwPFMR1fK8ZNQAXTjl/2njOC1cnw31GzOoQh8Ie/Um5_dpzDV.js:default\",\"Number Circle Four\":\"module:er1a6KogPjES3KfaeCHU/Lj1cFHE8thDdzpy4ntk8/yVG5zanxx.js:default\",\"Number Circle Nine\":\"module:TU23sMAUBd22o7NYJD8O/xC7JaSeQTxdOA7DJyGay/RGmrBvNXE.js:default\",\"Number Circle One\":\"module:VDGQretpo1So3sv9K0TE/5SADXV6c3uyy4nWgqe4O/GISBaLnvI.js:default\",\"Number Circle Seven\":\"module:2lS4P6eohsMvJDllLVgX/BJcBnUtrpJ8mnJnWUjgf/zoA_7QwGr.js:default\",\"Number Circle Six\":\"module:afRfe0LqCld7aYfFURU4/7jasS3O0plMtEjmGLxuU/wYPzj8cxI.js:default\",\"Number Circle Three\":\"module:YiZiyQIisgTBRGQTiYkn/MieUXh5PTk2hINljY8Re/vTZj0voHW.js:default\",\"Number Circle Two\":\"module:pz1RqYohQVxg3jjXVvGa/g69VCgwN2gdzhNswAY3m/WcCmnIJO2.js:default\",\"Number Circle Zero\":\"module:vIK3I2JgmMrWYGFxbnyI/SYH5CMiRb2KNiPfKbwTH/OLu0Dkiyb.js:default\",\"Number Eight\":\"module:jBRBZEBu2Fbydb1frRIG/JlnaHGa1K0gUlUBSdKZm/Bm4N336ot.js:default\",\"Number Five\":\"module:yWVCr54lunxcCSAYQwiz/QmnfsYiUkPOXLsQijNlW/UoM4ZTHto.js:default\",\"Number Four\":\"module:se8rdXSnC5XlKicjLWg4/WtUCyDFCV4fiex5UQVF1/pDwica96c.js:default\",\"Number Nine\":\"module:RdyGkmbeTpXeFi7BjgR7/Dt6ZlQLUkdPY8xHHN57u/yg1pQ6Rai.js:default\",\"Number One\":\"module:Vg1NbO6o3iGM0Olg2fOp/BCOIqkIx76o7bRBcZzx9/DJp5JV2vV.js:default\",\"Number Seven\":\"module:Gy0ntLx4RYDJg4i5pcvm/OKzS6IlzIR6MFMtQij22/B3JdHUtyU.js:default\",\"Number Six\":\"module:bwXfXPGZTqehoi0cqpug/rOivfUoqtFNbSTTwArWN/HKF2TaAlt.js:default\",\"Number Square Eight\":\"module:nxvogt8bwJWxEENykfRh/kueTVGch42cLw4HufkWh/qqaLiiwNR.js:default\",\"Number Square Five\":\"module:12rYafsBVBB3d0kJrL1u/1XLnMn3X0g06M2I9eTuG/Bw0fO2JBm.js:default\",\"Number Square Four\":\"module:XKFHgQ7TA4mPiDLBrVjO/6yyoGY2UabqCUSFZtuYb/qvjKDTVFt.js:default\",\"Number Square Nine\":\"module:JGBpTmkuSK7INQiUPw2U/VeedXZIqCR9BLliV6bck/cEpTT02AP.js:default\",\"Number Square One\":\"module:pPxH0EIzA1HkZuqZqCek/gijKOunb36xlwLM639Vm/uAs1snkN0.js:default\",\"Number Square Seven\":\"module:jaW2MNRS9tUnzh2IlsB5/zVL2DD0j15vEplIb1QVy/effB1Cbtb.js:default\",\"Number Square Six\":\"module:ERxXxofExAIbOcjAzxpN/ovvg7kzft7xgXI2qxA3Y/tDl3eDa3m.js:default\",\"Number Square Three\":\"module:6JC7MXvZme3SiSH2cW09/yjWMG76kXY6zUVfmWlSA/gRuS0UFwv.js:default\",\"Number Square Two\":\"module:LKrjQ4QCcwCqAHwwpB1A/wjHhW5BgzusaFNooUnEf/Y4wd9leY7.js:default\",\"Number Square Zero\":\"module:KMufcIni3LIck92jDmjK/tt9bc73WP1KUKfbfF9th/ew6B3g3xl.js:default\",\"Number Three\":\"module:rM0nc1kQd29CrVBF4d45/InHn3W0AGuyKw6SmoMhc/QTO61oZhw.js:default\",\"Number Two\":\"module:0mOgx8cjJDSLcTzHnl82/OGg6ackC0TJEiThe8ijF/MRqvftRcA.js:default\",\"Number Zero\":\"module:gnb9wZDmqN81bVbqM7jB/EJCYsIW00Vb48O6aQ8Ug/ZO6jynvA7.js:default\",\"Numpad\":\"module:afXVpR4UZpEjPQoohRsb/VlDREMH2FEJB2A3NJNE6/MOMolfkn3.js:default\",\"Nut\":\"module:JK4FsOKo1mQWGpB7xe9o/Fc52NuPItyZWYV9DHAIQ/VoaWDzJMu.js:default\",\"Ny Times Logo\":\"module:6CdZS52JvXG1Ut8dkRtY/nOg9hb450klYuvDlef28/vN_xrhjUL.js:default\",\"Octagon\":\"module:ADa0XMsPRSiojS6rSCnz/Zwvo4Y3OfpjFp7Jfd4eg/QRrgQ_Js0.js:default\",\"Office Chair\":\"module:LlZUK631faB7vsernj5v/oTepSSXHXR1ZZsMY4JJo/M3QzvFAZV.js:default\",\"Onigiri\":\"module:DtxCZM52fAqanYjgeloz/zsyYYAehtvdwiz3yISAY/An2MLXuyQ.js:default\",\"Open Ai Logo\":\"module:3J2a9hSsfGA1vh4X7IJT/ksWmmn8Wkb1Y35lHCJxt/U4VlAAgoV.js:default\",\"Option\":\"module:UJpQhwGrcOAZ8IsyQ48H/1ZwDo5tSgl2qrthoqJlx/pKqJcP3zz.js:default\",\"Orange\":\"module:4WM4AmIufAxgxnfgPFpZ/5qJHntrOdmmhw8JWFPML/nXe0W8HSe.js:default\",\"Orange Slice\":\"module:zWac5JJXfKy90ZMMt9Zj/DelKI41N7pQWAlo98ywM/j8MyPiiwn.js:default\",\"Oven\":\"module:15dU9qPwuchMldzJKxxY/cwQOiwjpeXW08NCIjo8I/rzulcI6r2.js:default\",\"Package\":\"module:B1od0mD3J1wRp5dLOqXs/tcJXLcWAheneDzvfuQ1p/zXmOJWrNK.js:default\",\"Paint Brush Broad\":\"module:QHgtZU4K28B5eBimdzEO/064BUTjoKPldO1Gpo4tJ/G_SbAkJKt.js:default\",\"Paint Brush\":\"module:1kxeIGX0ofvt6AsOqrAN/C7GLWmrD0XbwwVZmrqfU/wL39W_sK4.js:default\",\"Paint Brush Household\":\"module:1EKN9W1Qe81BRAmxFenk/1NAtqCluHBevZNmhLMy5/mBtzdicFq.js:default\",\"Paint Bucket\":\"module:5j9Pcuc7pyRLjYX9Bbj5/XKbnZ33b6GDgcSPtZMl0/MiVpxl7gl.js:default\",\"Paint Roller\":\"module:GTvc1kQYfmJX19owRAkb/66xlGBV4QqbUwnQkmJ9V/Z2x0tQR0A.js:default\",\"Palette\":\"module:4RBETEGbdUKL1Vx9iSsS/56XyLBI4KuCaaEGbOxPl/qQpylMXlV.js:default\",\"Panorama\":\"module:03R4YqaXw84DZagLA0zB/FhUxvBic6Qivvhqgf6ix/aOGg_gHMQ.js:default\",\"Pants\":\"module:yUpS9omTFAkWz6ccqfTX/OtBHliCp0pNIPEWwyqey/PxPSgPNxs.js:default\",\"Paper Plane\":\"module:1mnldI69AdDswMS1GK1G/CuTPGY10ogNcXbTYBqMh/Mm22vlgs0.js:default\",\"Paper Plane Right\":\"module:8LmsymaXbpIaMANlTGFS/qxa8yqi4axRm8y9AqBWe/q5aV9Ifz7.js:default\",\"Paper Plane Tilt\":\"module:FkZd5HGV2AKnradbFrFT/0tKlhfGsXzTchyMSE4Ql/rBV10wjU7.js:default\",\"Paperclip\":\"module:f08GfijnwvCuljgn1nap/v48S6SztV3WP5JoSfEXc/rPNu169WM.js:default\",\"Paperclip Horizontal\":\"module:1ZEpZq59kiCdWWgPT8u6/7OfrkFJ9RGq8N1QTMO5K/VnofbI0gj.js:default\",\"Parachute\":\"module:yZ0Qd4hLuxTpTzviIMYv/eC1vV2U1lsqA16oAUEKk/ilf7KLmxo.js:default\",\"Paragraph\":\"module:8vfrl1lXMOLp3D3q95Tc/JoRd8s4vOkC2NlSLRASS/i7Skri_o7.js:default\",\"Parallelogram\":\"module:zrMbG9AyGftb2MUCrzHB/vGC67BaiG5BESduU2MNo/Jx9bo1Tog.js:default\",\"Park\":\"module:HBKJxjZ31UIUKFMNh6EY/gd4CCfxrbGwVUoIr6dYs/WgzzIA8zQ.js:default\",\"Password\":\"module:38G6U1L40yKwj4S2eB59/xw6kPKuIBr5Su2tHUfSl/bhFl1p35S.js:default\",\"Path\":\"module:OdYQf8z5HgLS1G2BXl5l/XugbtKjUI7FvkhuWxX3b/iIWY0Ex6N.js:default\",\"Patreon Logo\":\"module:hqVeTCve6CMdPIi4LYmV/r7D7DjIqF4mt2q4KuSkV/kajBup8Dr.js:default\",\"Pause Circle\":\"module:G9zpcIZvIVNDE6iqf8NS/sCCnYP3ysD0dRhQAHwSK/ZLHzO3qYe.js:default\",\"Pause\":\"module:EuzYmMd3iI5CJEYiy5YB/3ssBXocZzdmWLhNkra5E/Z6ZTyAsud.js:default\",\"Paw Print\":\"module:QjUNYWnJFEavEV8nSdtq/u8RFVZFfc8FFRN6XVuNx/wZ4kOEiUF.js:default\",\"Paypal Logo\":\"module:p4oOSvABGtGb4wyH98HD/e9xSgZ6sQJp0ahsyyy79/FzXHSV5y7.js:default\",\"Peace\":\"module:7plrdNd4idHublO9exnU/bQckAW4PNYOzyDAMJtqT/tWXRTpgEh.js:default\",\"Pen\":\"module:rCIiDaL66xeXm7w5DRgr/UEFNakjWaeeQf0iZuL8h/DujmLdlj8.js:default\",\"Pen Nib\":\"module:4RL6X2eHVk6xARVVCoWR/cYeCbxkEeh1F3hZjjGKT/F30VskPos.js:default\",\"Pen Nib Straight\":\"module:aFJ2oPJROgp9pR7i5MRi/404l55Ng8Y5GGFif60zT/tMEnJsdD1.js:default\",\"Pencil Circle\":\"module:8i1sddgF1KT4Z5j1yjjC/4RndtzmLVt0vpr6frZw5/VVAzrSrnB.js:default\",\"Pencil\":\"module:M0VEVaKXrdJLX6ecOcvg/EcEVxu5Yrso89op65CPC/gH6MT71T9.js:default\",\"Pencil Line\":\"module:NI4Z6adObgXOEipFwtzE/OEjMAacXy7WMJhuF7PYo/JhGbG2mDz.js:default\",\"Pencil Ruler\":\"module:jYZyGG2jIoX43YVjOFXW/bx5PqbdaRK8Tb6gELsQF/ViiZshjXY.js:default\",\"Pencil Simple\":\"module:4Sigt4a4qpC7GsHA3fwJ/vyK5ui3W4xe899C4fmGm/ZSpHMOL1t.js:default\",\"Pencil Simple Line\":\"module:qFLzZ5ZJ7ZfkWOEV5POd/nAEqz45GnQziX5e8gOhz/gfhNIBkms.js:default\",\"Pencil Simple Slash\":\"module:U5OURGoIYKM50sIKsvjH/2IuriFmo4rL0GUv6fC79/RhOlNvvjs.js:default\",\"Pencil Slash\":\"module:VR3oaCy1TO0aPPtpHS1m/82vRlMedP9PGuXcUe5Aw/b_fnXvReo.js:default\",\"Pentagon\":\"module:DuZgHxd231pSdtFgM1Xd/f6NvskbiY2OYYDFktk8P/HnZ_edZxP.js:default\",\"Pentagram\":\"module:Xx3hVgxLTqxsPLwlDGsS/ZLY27u6JwKtxoLZXP4sc/V8Otpr3_F.js:default\",\"Pepper\":\"module:o1SJozzQ42e3MiylWB2s/grIdR7DBAKiJIPwbv8v5/WorBDMTSz.js:default\",\"Percent\":\"module:yaTQKFBEJrO4XqHMiGZs/gJpf7y5RU9n0CZnB7E7v/DzTc6Gv1R.js:default\",\"Person Arms Spread\":\"module:av0gWC7xOf1OBz2lJq8v/zqUTFemCsUslze4fWSDx/UmMKzdcpq.js:default\",\"Person\":\"module:CMAp0nXDPQotB6O8PSGw/NmMv0WXKzuwR5fnNmVEw/BGbxynD4e.js:default\",\"Person Simple Bike\":\"module:E2GJCdjdQjXb3S8Zy6mH/63p0M07ooCbuR5EmbvZD/dVBh2c_Iq.js:default\",\"Person Simple Circle\":\"module:Zez5SJS5wQU1iDB7ukoY/GsVFtxa6opxPl0nJqexf/ZTnCZ8J1X.js:default\",\"Person Simple\":\"module:1etLexedXeEWUFqOxA21/EQNF3Dus47f9KQQpiLBy/nNOBLS0ei.js:default\",\"Person Simple Hike\":\"module:QmMmKTAO5G7QBIZ8DZEq/jNJrJe8gEf9gNna5nEFA/UHv5ZXK4e.js:default\",\"Person Simple Run\":\"module:O1L0h5tZUIJMsG1xSge2/wy0Ak2YlptydRkUT9Jgl/CiFmWTCoH.js:default\",\"Person Simple Ski\":\"module:pYvPr6AIbeGjKcCWieV0/oZ5dUjdbw5UAJoZHRNL9/xmATPwZPy.js:default\",\"Person Simple Snowboard\":\"module:tDDBXiYClbxSUdxAcnw7/uC3ZY800Xc2im4oZFI04/d6c1DbboN.js:default\",\"Person Simple Swim\":\"module:nJzVW2nydOYh6e1KGhRJ/qKRzV73ViHcZnLym3OkF/PV5T3ns0G.js:default\",\"Person Simple Tai Chi\":\"module:1OwQy7mM0gWs50hjoLVD/hXndZI5yrnPEmiTN8SEf/sTQa7Znux.js:default\",\"Person Simple Throw\":\"module:7k9hfIoi3Zp1rfFJWsrK/tczR3c5DEiv2LjkV2OvZ/QI27QauaO.js:default\",\"Person Simple Walk\":\"module:gUyZq4L80fcIJ28aRtkK/isgeiBWwsKr7XI8pGrFs/brHpE1BLN.js:default\",\"Perspective\":\"module:80E16pnHpsiS93AOulkP/CoHyja80YtEEeGAX3dHz/VSb8977RX.js:default\",\"Phone Call\":\"module:q9mPSllojTcxqGETzw3i/29xmuEUtqv6CYi28VFrM/XsTc5lxfv.js:default\",\"Phone Disconnect\":\"module:tc02PzhVD1AlPyYMrcG7/dJe5ZauWiBL8E9L0m3UA/xFkR2n4EI.js:default\",\"Phone\":\"module:JhjNU5admIi32bgBk7kN/piPqsNFW90HigDdjsxLZ/I13kdmfkC.js:default\",\"Phone Incoming\":\"module:aW1wHiJk9VaVoP0JtvIB/tDl8Q1CF4xr6GH0wB67o/bqXE3jHfK.js:default\",\"Phone List\":\"module:Rea68vxTX1DLtbJTl5ok/UppNyV5sRaUzY60FdUVc/sEAShLIhE.js:default\",\"Phone Outgoing\":\"module:d1FdYx5cIBCHcYeS3sy7/rnvDxFO6MR3xx3r9otVN/ey8PK9Dak.js:default\",\"Phone Pause\":\"module:ihu9qPk2tKfDE2p7EsAP/9VqSE1V2w97gPsglUsdr/NXvkXFFgC.js:default\",\"Phone Plus\":\"module:Y9DmvHbMb6AhG0p4HBzh/tn4bSDqfcv6iBrO62vKA/GKfckbJRo.js:default\",\"Phone Slash\":\"module:64d0Xvas7pz35Ms3Wher/rvqxCqG2BeD1qQylRtj4/KjZ5J76u8.js:default\",\"Phone Transfer\":\"module:bsEeqv40Gmn1fP6Pp86J/g34MeodgVHmu0OskRy3G/K944bryAi.js:default\",\"Phone X\":\"module:5oLTFdmx6uirXU8flS7L/CL5Nc7tGJv8TGzehxwxN/Z4XKOjS7L.js:default\",\"Phosphor Logo\":\"module:fM8v7M6AtUWGOtYVwk4H/Xav4Zht6ofhefrgOKsBS/cln3ln_PG.js:default\",\"Pi\":\"module:CeA0NUZFF0mIBAYhRx93/Gm6zYoGSffFhMXwtNaNh/uEpUHiomj.js:default\",\"Piano Keys\":\"module:8E3CLmPr7R2sYqUoMDyp/sRqo1RBx1ILOkRMZ2UAF/GF0SzsP9z.js:default\",\"Picnic Table\":\"module:nmLAS0Ggo3HhV1G5FLrR/xLt7jIxVeBQUpHAb9bAz/o9YPiyERg.js:default\",\"Picture In Picture\":\"module:KI668j0KFB2lq4IJQAx2/PWJYbmjmgBUhtTcohHeI/Ok6yn0mmB.js:default\",\"Piggy Bank\":\"module:0eCZ9y2H3cRxYZ7tz6L7/k2i1MT4nuPKgoIz2jOPS/n1vhlpUKD.js:default\",\"Pill\":\"module:Vj1YjdiufzrtOaw0mzON/L2SWN0xu992NmnvT4EaP/FjXnPUkmp.js:default\",\"Ping Pong\":\"module:PqBqVA3uPnWiYnpdiPGB/NFbZkRM0KdLlbOlE6kvf/osMDqtEPn.js:default\",\"Pint Glass\":\"module:LpjAc8TgRqHOV2LL6vJt/1JJXzvSJ1SbgY6umUhhs/azieVJZG6.js:default\",\"Pinterest Logo\":\"module:CIxCqRNZor3LLcCWlZoS/U5MgeOcJYvxiAVwmUkC0/db1FTsaH1.js:default\",\"Pinwheel\":\"module:JfyTr1vflOWzOTcpEQOI/ec6MPGWNYzPsfxyohxkO/wQcnVF1eT.js:default\",\"Pipe\":\"module:mSznNJxgQAlROwKnvfyy/Ecg2kXKQeQaVN6AnH54A/FKJjCf0VA.js:default\",\"Pipe Wrench\":\"module:O4jIk1kwaHGtmb3F3AIk/6h4IvlEJlYzECXkLknIl/VJMJfsrpb.js:default\",\"Pix Logo\":\"module:hULihFbITXFrVYoM2RgO/eOANYBDH8rfncmmrmWkN/dGowJfMKa.js:default\",\"Pizza\":\"module:Te2tYGVaPwC0mYhWFcX4/PLgr2cUhBNm9Ehhlnzfx/DMFpQmVI9.js:default\",\"Placeholder\":\"module:mXU7fBniR7uN2IQiOIm1/fo7yEHI80bhNaaV05NYE/lXdspAsuN.js:default\",\"Planet\":\"module:gqC6U5Cpo3x8mQnDqQq2/VHPIQQ2f42LjMXX3NkkN/Vlv5bYA8e.js:default\",\"Plant\":\"module:5advbv8NGQZQho465wZd/X7CEg7w4fLuWrawItHJV/u6IgvslaC.js:default\",\"Play Circle\":\"module:MxHsVqbUudrNfDeMSPHd/kH7DKQ45r97DM6nYL9fR/xKDXcCYiV.js:default\",\"Play\":\"module:HAXb8usAsbryfPorbMS4/szDG4SSfU1UCFng50IhF/nyoPQewhK.js:default\",\"Play Pause\":\"module:r4hRLAezKp2lf6QEiNUj/pXemhTWFoqrLjL8m5oWl/RAwWoOPrW.js:default\",\"Playlist\":\"module:r4q4puLe17pGg4R81l80/crDqHc5tJdRrWduhYm4z/XL8b5n1St.js:default\",\"Plug Charging\":\"module:IYdsF2vPyha1h7YUe1nd/FZAZTha96u5j3t6pTpgc/Gxusje4k7.js:default\",\"Plug\":\"module:CYV4Anh9EHgZZm1FS8vG/JxsQGXghWHEeK2FyP6tq/dOp20yDiW.js:default\",\"Plugs Connected\":\"module:i7FytJYRCoPtaoTYeLg1/Aaus265UU8PihgRMgqCM/NpA4cFHvp.js:default\",\"Plugs\":\"module:4bMkODMXuZBDGAlVvcWa/MMeJsfZ4HAKJk1k72FVF/Jf6zaDDcM.js:default\",\"Plus Circle\":\"module:YUsq1X4aLebh0gHS4DRm/Rs22TKaOQJJTw6AwQH2X/Qg4DI_FPg.js:default\",\"Plus\":\"module:sPPEJJGDR4eUvdon1Bel/f3XESni8XlI3ypQ6Exdb/HbzxRJMyi.js:default\",\"Plus Minus\":\"module:anNAGhXkBSVjfroMhQfo/LEWWnQjFpthK8Wre5XHA/O6sntXuZw.js:default\",\"Plus Square\":\"module:jXvwZWy6EfVlEqTYmUA0/2CITObxZ41AAPLSWABvT/urVUxQz32.js:default\",\"Poker Chip\":\"module:nABgoUmhB4eCYxxAWL9S/Elwt9BCirk2fRZzgT1YR/o08iygAgv.js:default\",\"Police Car\":\"module:6vtOD1LlJhfstFmq7qUv/GQGL1a7tLr1z6632SFcZ/qu0pYhlKQ.js:default\",\"Polygon\":\"module:YVHLBywj2tCsv73m8SH7/g5JYndmbYPmFgwMVTImX/kR2g_oAcA.js:default\",\"Popcorn\":\"module:9Znlxeq9fBUrUaCct5Km/4ZHGGc34ZaPBAlrmX4RF/ZFxKfuzQc.js:default\",\"Popsicle\":\"module:zyOuAmRmd2fMqGXcnHjY/qs2CFJeILo3aCEZKatGH/UXqTsfN22.js:default\",\"Potted Plant\":\"module:V5Jfx47US6FDWzKINPSN/fORtpuPfYoQo2WzLtO6e/An_BIh0aW.js:default\",\"Power\":\"module:ctjbmNZriHrHOKMbNtOH/7j4JUtzAzZPUyqrSwwKf/FpXQZ2cyc.js:default\",\"Prescription\":\"module:WkZASVuXfKiVR5PuOiaD/METq2pFFbefBb22NRgYf/Jk4y5YEnC.js:default\",\"Presentation Chart\":\"module:7gqYbJlw2gIBTIREtHHv/Kl81UNWAtDCe4AlWcLVP/ptZ9lmrKI.js:default\",\"Presentation\":\"module:HEwbua0gn1qyuXYPIo2v/crPbMOwFtW7aYItK3SBq/inh9qtYwr.js:default\",\"Printer\":\"module:uaMuYBRcZbFdQWKMtn3I/MPcvkzcGz2iHctHO9p79/EC82Lxrwu.js:default\",\"Prohibit\":\"module:TbqUYOeXUvh57GNMrfuz/DnVpj9hAAhuLYv4ZLeAl/OnIGxYENz.js:default\",\"Prohibit Inset\":\"module:uHU4aAOmYUOMHMcvXp0b/vztYjRqP2a4YOTDfLZmX/UuDDnFm9Z.js:default\",\"Projector Screen Chart\":\"module:fBGSBzZuvQb3aBU3gkpz/YzOvQ1swyamW9fxvXyLM/hHXuI_S0z.js:default\",\"Projector Screen\":\"module:HewqtKN9TGxZR8pnc5Nn/8gCeAmqzl8qsN3iNJ94z/epS0ybJEm.js:default\",\"Pulse\":\"module:K0V2wwh9TceAjpUIo9k3/s2FCctg96Tqii0dh8CTx/WV6qECQIm.js:default\",\"Push Pin\":\"module:ZgcsJ9e8Dop9M9WQ7dQR/CbJlSEN9DiJf76Y68DGR/RVz8EdnnK.js:default\",\"Push Pin Simple\":\"module:1DPhND9LCRz3NGijDQkn/isXhy9rHdLeydqvCZDb5/EVu5dX85C.js:default\",\"Push Pin Simple Slash\":\"module:FHlPEqjTpQ5R2PhWUBOy/5KeM1li1rxM6ldTkZpPB/qLyjdQ4BQ.js:default\",\"Push Pin Slash\":\"module:FHJrYit8ETC7GmxKV83T/CAgdpDwLQlo3SbFkUG38/XX41kUmdV.js:default\",\"Puzzle Piece\":\"module:znZYs5IfvSRk9eGwNPUd/pCNO8bu01tsXhmpk0oIt/McBVRiLx_.js:default\",\"Qr Code\":\"module:ruC6cmSIOE14DW7rrwRf/uFztWsy1s1Opz4xfvtkF/XgUVEEEnl.js:default\",\"Question\":\"module:cCzR4f807Kd70kx3phMH/Kbpay1bAKn96VVo4tQV7/N4kQEkBhq.js:default\",\"Question Mark\":\"module:IB5zXkr98p2X2ozDVUxf/s2BBSvtpUArg6QLESyAO/AjQXGkQtG.js:default\",\"Queue\":\"module:qxLOr706kEJw8S8jy7ju/9zvqva7eba0t5eWqatel/sVcq4W8iD.js:default\",\"Quotes\":\"module:kMwLTNZwbbCwh1ulHUWr/78mzEJx7EWcW0qf2dABH/umZAY4oqm.js:default\",\"Rabbit\":\"module:YtFBH4Mzlu7obFRrHxGw/zEY0h2QlNxQQN5vDc2ey/U6PkMw42y.js:default\",\"Racquet\":\"module:jH6rs1IfWrvlkMXTURFz/X497UcPvFqG6OE21toXX/WyjbKxEdl.js:default\",\"Radical\":\"module:s8KeuV4J2ZBR3hcZVodM/AlxCvCky44L0vVJS0SlH/abtWbd_sz.js:default\",\"Radio Button\":\"module:msAu9fEeq5U3ycdLwG1E/qn6tZiCLQk2h2S0AxKMG/qB5WNZbWT.js:default\",\"Radio\":\"module:OFUGRIPR8pbWv33Imd2x/oSy0n8R95617gX19Jray/E0OCYCnGG.js:default\",\"Radioactive\":\"module:dzQ5H7aFmukpMvT4hzRT/khVWYjf8Qa0NtOWbTbnb/Xnh8tpBPL.js:default\",\"Rainbow Cloud\":\"module:uwt8zHU9eefUvsb2EgZT/6sX1S1meewiPCrDo1Fq4/ITOVozF1r.js:default\",\"Rainbow\":\"module:TseFlI65sShK8JjiR6hs/o9o2FqbbJ4OtniXN8rwf/coxDRq2bU.js:default\",\"Ranking\":\"module:OOn3kjrBQTaKUkt8r7NY/9fKpLQLdqWO25Wm1wMi7/FIHJX1Owc.js:default\",\"Read Cv Logo\":\"module:FlsN7xcRcY1tEDkhGDRh/GIN7pVhc3t9U3ydQ2hYS/RnMhm4ZEp.js:default\",\"Receipt\":\"module:LEo9bqbsExQ5KsXnrmak/OqE3wzDOB6Cqrv65u6dm/Ilof8N0S5.js:default\",\"Receipt X\":\"module:OPFv195JrczSUp4gD5lt/5DiESHm9vYBdLHmsGulx/H5I16RtZg.js:default\",\"Record\":\"module:JZdCnkacBVfrRWA6mIVY/2WHLMHv8eRCicB8XST0t/EVnWxmptj.js:default\",\"Rectangle Dashed\":\"module:pFYvLvLZdoaejZaiv3RS/OFKEmZFytx0bhfs4sh1c/VQSk2JWF3.js:default\",\"Rectangle\":\"module:0xx2mcL4Xu1Xao6cucZY/iPYcBjK9AB3EOwW3QxC6/XAHTp7jqz.js:default\",\"Recycle\":\"module:n6vYC4SsnLgMcu5ciySM/AUHgOxR0VjK1ohs1wXmS/E4pwtumYQ.js:default\",\"Reddit Logo\":\"module:oHasmoNHg6ZpS9RAigLE/UAAxFnKFr7C5NJ1tiM86/F5lUenUzP.js:default\",\"Repeat\":\"module:aZ7DOv3ZZQ1LkO2tUPyw/L7sEmVieBWNJYkgeYb2F/eGDuanPUM.js:default\",\"Repeat Once\":\"module:K6FA3xqwucj7P2JtAV8F/JlEel1DIRla4fT3NMZBw/Y7orNNO89.js:default\",\"Replit Logo\":\"module:GfuGxGNuypRCwvjI8CeD/kZrEIJqOVprRls6XUrAK/RPazM1vpp.js:default\",\"Resize\":\"module:zrzVwZff89d6jHP19S6U/RPYF2HFiTlIyUF9TyfKZ/v1kQrQwsu.js:default\",\"Rewind Circle\":\"module:LSeMVGPsqbGGDd569KKS/sJsY9ed6b4q6KNfLd8o8/pmtNoLD8s.js:default\",\"Rewind\":\"module:imuIc6X2Q5Rr0J1oxW1m/fdQDKHbyFKtSuYs8XIRc/a1uCmgwQV.js:default\",\"Road Horizon\":\"module:SrqoouJvIIEudGypDoVW/TuR8pIY0LsDKcJi7js27/m0lWzMV2b.js:default\",\"Robot\":\"module:TulLCUwL2TSa9NZpeGmw/IM7U2YeqhUuD3aS05mdP/hOGPAg8Bl.js:default\",\"Rocket\":\"module:6OfMMI77R5mpvsdFgMhv/kqcAHHsJzDbmM8DiZQ3u/N56HpYPBp.js:default\",\"Rocket Launch\":\"module:4aDAOGy8TZoXOUt2Vkda/uFD3ECXDBegfUhNNEG0d/sFjCGjy1B.js:default\",\"Rows\":\"module:nNApeBzkTP4knoEs3Yc0/dBZwg1oMEx3IKIAnrOev/KBE7m9X6M.js:default\",\"Rows Plus Bottom\":\"module:AAfKUbB3fGKgD3wK8jYp/mOAV6D2ym6Ngt0dsn3l0/Fy18wdzNM.js:default\",\"Rows Plus Top\":\"module:DbWQN9cdLv5FHmwdUASK/onMKyJq73rQnLmuKkBv7/dBqZ8mnIk.js:default\",\"Rss\":\"module:kU9fkbNpM2ybOG3GJQs2/KPq22aAZo36PzKelHURU/FoBjEwCvt.js:default\",\"Rss Simple\":\"module:nQiLkBVHqsMfsWuGpWRp/UHxvMPd78XVK3YUfE2sy/C_aVGvywS.js:default\",\"Rug\":\"module:3aEvsWwqU2rUQvrpacnA/BfA11RFQkTuuBTh6Hps0/WGRAJqoma.js:default\",\"Ruler\":\"module:WqATklH6AQaIZiAWwTLw/xjaugiN0KA1vohepPyNP/BVX_ngAFB.js:default\",\"Sailboat\":\"module:MedlFhm38ovrLJglL1Sq/82bQtlaZxkxGaCsKQlTo/MybTZWNlX.js:default\",\"Scales\":\"module:8WJ879IquCP3ZmwfpBBt/YV7p4CTiwMu8cpoge2Kh/aIfmSu0Qn.js:default\",\"Scan\":\"module:6msbkJmnqOLtOjowa15S/5onTY5z8fvmdfHbIyOvr/wk_xzkByq.js:default\",\"Scan Smiley\":\"module:4R7lW85Dpfr4zHWJHLgw/tSMspDkO1Ns93N5kjsL3/KSOqqXVg8.js:default\",\"Scissors\":\"module:2TrBuucyYDKucsCOhUS8/2xCk3axM1VCERBnULhVo/DjuR9snt5.js:default\",\"Scooter\":\"module:UdEDWO2BpEn25EcxxEKP/DQ1a9QFYphXmxJ8xTfIE/vF_UCa5NE.js:default\",\"Screencast\":\"module:qgINE4LigxAtpbRQuzlE/yfgCvKXw61LG4zBk3dqb/faL2r0ebU.js:default\",\"Screwdriver\":\"module:vACc9SAJgJjdBEsP55xL/JyFmapVsI1tE2mSLpquI/uw8lZGyxj.js:default\",\"Scribble\":\"module:SHn9G5KKO1Mfvfjd3a8q/8DtoyMzJ7Tbza42OIT4e/n1LNquawU.js:default\",\"Scribble Loop\":\"module:f1rXZMhl8WOMqc5cCqLS/Q0LCwpscWlrXBabagWX2/da56YbPeW.js:default\",\"Scroll\":\"module:fho4Yz3ZlvfQDOFsfR3B/kkgfDKFe2X8R99AyZhgA/GfX6atzY3.js:default\",\"Seal Check\":\"module:ddSSnr51Ev6XhkbX5HBT/OSFL9ztXlvqRyHESys5O/mkaNE3fll.js:default\",\"Seal\":\"module:ROIDMWb35PZNv7bxwgg9/zpfUVuaz5CmxVTwkAfhj/NRiW8s_gb.js:default\",\"Seal Percent\":\"module:ebeSch6J4GNtBuhlijwV/HvRaVY1lTyY7JsVu6a6b/yXXkesduW.js:default\",\"Seal Question\":\"module:4p11PYDFURgqlfSWAc2o/VhwreAZ50A7RuYWkdbsj/SlvwGUded.js:default\",\"Seal Warning\":\"module:SbGHeNnMHelWBlJ8nEfa/wVjEB8ykNyNvdKp1vvfo/j0QgkB0rC.js:default\",\"Seat\":\"module:3glOrlUAi6Aj54FJBC8W/Np8d9rHn7RDuYwyZpeOS/UfHAvnCwY.js:default\",\"Seatbelt\":\"module:fQx8mmvoq2EQ2Ze2zxds/0sg5eXOCBlI0ByF43XCp/V69s8Wf70.js:default\",\"Security Camera\":\"module:rkTOprC3959fwwXbptR8/zY4gar1nziFjX7X1ATZ3/eVqg_L1l2.js:default\",\"Selection All\":\"module:9Ld6rktzOhwemy6nv79E/ZIOH0XCefaXaXAsBnwyc/eOrR6o5K4.js:default\",\"Selection Background\":\"module:VNN7uCocv6V0E4aK1Cq5/GvHOKIqTdAq2WcqLO3rD/PWOZdKBZQ.js:default\",\"Selection\":\"module:EuZxKWHvZjVolh7QdrDx/bkOX7JRRCFv6XovJ4P4l/GYr35i69Y.js:default\",\"Selection Foreground\":\"module:wLASyLps09aD1ccep4OZ/OlHp9CYvh3qbN0nPurdv/whOTS4RYJ.js:default\",\"Selection Inverse\":\"module:PeSseTbQABpDgUA98tqf/hLvmTnC7jqZ5MGydxwDc/eWMENDm7k.js:default\",\"Selection Plus\":\"module:02CbEzn4ys8TPoWPyX6U/A6vI3irNmwRVuxdQ09ev/KprUfqSU8.js:default\",\"Selection Slash\":\"module:Ip0MXNJXleFtOOxUVVpX/E9lJ8OyXWgHy6mnszUm0/FwZ4xkDpc.js:default\",\"Shapes\":\"module:SUBEdtCFaOJwrjN2Inhk/bznEUerLEqVVXGfsDOYE/pKERsxd4H.js:default\",\"Share\":\"module:FqzltHaWEqy8stiC0cEP/mzn7Gx2DvrRM9CizTDs2/KlF_hEBhO.js:default\",\"Share Fat\":\"module:GJgsRmxPBMgppaGRf6q3/GfbNNeTfIPWLkA8WvqOq/ZcViOt0ny.js:default\",\"Share Network\":\"module:Dn80xqXqDKOmiSgA64xV/Uq69ZJ9QgRYdVxMh0Qvm/fbnA8Pdl2.js:default\",\"Shield Check\":\"module:dIG7XN9KAmImdjhERNf1/nLNsEBRnziRZ9V6ywacR/f40ONlxDn.js:default\",\"Shield Checkered\":\"module:WyV7Q32F0EK6Z0UGvt6g/2Gpg60XJkD4Ode2klCIH/VLWQJOeif.js:default\",\"Shield Chevron\":\"module:S27Rn2XV0IhQFkUG0aQO/FBYhOPmZ4cgfEXv6wOEU/mNoisM7ar.js:default\",\"Shield\":\"module:gcPcyrpGybDlWABLSgUl/TbATwfhtLnRUyW2EJSlz/hM8LygbqM.js:default\",\"Shield Plus\":\"module:5VJ8gGT2UFFMVWJNzSZq/y4gnEki2G2I2EsmygEbL/LCVEzWJX6.js:default\",\"Shield Slash\":\"module:juuYQdIsdehARhnkSJQ3/4beOvsI3AodcWb9o1mLm/OGPUe1aiW.js:default\",\"Shield Star\":\"module:cwJog0DRQ13ZBH1JLotw/eBcAB3jGVMlmqn7TAJ3s/zfsrugkba.js:default\",\"Shield Warning\":\"module:aY0NLiEnKZdYyTrQc7Af/jhM1EWW6tyzzNDauhtMp/q2hX40jyU.js:default\",\"Shipping Container\":\"module:nQU4p9uE42FvRBAcPDjZ/5ykGsZMbuEDQ3r1NMXvp/G8rGrPjaA.js:default\",\"Shirt Folded\":\"module:cFKUPjFndHWCHDvfjrzT/ayPYF9H6Li359IAZdVSr/i9fFEXBL4.js:default\",\"Shooting Star\":\"module:p5iw1xTBEgFap9DML1Nq/dCw5RQGNRpOAz6Y7RU3l/ztXoSeDuu.js:default\",\"Shopping Bag\":\"module:iNskpJkEEiE86ehVtSWl/BB9FJt6uVvv3NeZaDi4M/c6sbUEU77.js:default\",\"Shopping Bag Open\":\"module:F1qnCNiXbxZaf2hLDD93/Tivtm7O91IIyMrp022w3/wmceaZECR.js:default\",\"Shopping Cart\":\"module:91QSpPtDAg2PhUp0KcA0/IoTDGcwd5Ot8lTDwLFK5/mE9knVSuw.js:default\",\"Shopping Cart Simple\":\"module:AaUsCN2P0PhEUfriOZlw/EqZufiIdbu8zZj2HlG8e/JfaLoQZWi.js:default\",\"Shovel\":\"module:wr4R6o1dbePE5zJui07z/KRJE3g4KTzqsDHMCI0C8/DphrkGUQ4.js:default\",\"Shower\":\"module:ntYWsCjtTngUTgNfG9GD/LUnVfDAfqCxTErOoF4Zs/b9NcSA8K6.js:default\",\"Shrimp\":\"module:prYCFyaO5Wj9SEZ17qc4/fZBtvKRnZGRAYrCZxqIO/aWh1goqco.js:default\",\"Shuffle Angular\":\"module:tn8Hq0mRz1TrseJkFbN0/YTru3ElsfmO77o5drF5T/OOBENBIPe.js:default\",\"Shuffle\":\"module:vqywFQBb4fLB5kSF1eY6/Bdv3lHKBW4txyfRYkQE3/P0NdfPPAq.js:default\",\"Shuffle Simple\":\"module:C5sfMzxrqxyod5CeXAD9/HNciE8diJd6TSql88TvC/EFt9aj1QM.js:default\",\"Sidebar\":\"module:D6McNHA4QAJAyYLJRrtY/uQ4P6SZWbTkoPMALbxcP/rUwYhPLdc.js:default\",\"Sidebar Simple\":\"module:sZBT1TUIaeHrurqzr3aF/78fvZzboajmIRQ8dnJlw/FRD52uWkr.js:default\",\"Sigma\":\"module:YjVUxVQ333DuSqmUpMuy/G91KihQnYfbEwE6yb58G/MIme4TusG.js:default\",\"Sign In\":\"module:6m16BjB5QaMrSVRzzLNi/j8zQRbAv9E08bbNJ5F66/jd41ybFzX.js:default\",\"Sign Out\":\"module:BImeRGOqcBRCBVuwoLoG/EkyICtatGlV40epsuKyp/TFmVlgAAz.js:default\",\"Signature\":\"module:YJ0Oz3t3YnVsLaNCsIoB/iVYQVkEVpq3ekjVWgdti/SBHoyZstZ.js:default\",\"Signpost\":\"module:cLq5keru0a1nz54xZO8y/G2i6clMjC9DWPJeegODF/IPTtoCoy_.js:default\",\"Sim Card\":\"module:WWOrmtDrBr6nOknFGfNc/pCuhTV0zrIy02yRV14sH/xQC0kdGQF.js:default\",\"Siren\":\"module:fH3vDTGWHfS7cy6cU0ju/FW00XHYlUTZ3pq3Vh1pn/T_RNfbnf6.js:default\",\"Sketch Logo\":\"module:FimOkeh2mai1nsNTBgzw/jwTuLZrbCwHvceuimbz4/QogO79j6b.js:default\",\"Skip Back Circle\":\"module:Ow9YsMFED6j85WrsbEZJ/2haHUcdE8bQWzYwEiBiq/BoFocNgc9.js:default\",\"Skip Back\":\"module:tCEjG2nUhbeA0QZgxRzy/hjKgNLdjjrFvGFclJO51/xn02T4sU8.js:default\",\"Skip Forward Circle\":\"module:mPvIIducJsUTbO6j3eeU/oXNjvYlHQEjaXYA0GZKH/w0qj6ThRx.js:default\",\"Skip Forward\":\"module:91eAQnqJ6iHoilhSsraK/15riJr6v23dJmgaSGSQm/UDYvAopzn.js:default\",\"Skull\":\"module:qlZUYJvaLmXSYinBg6gy/l3d2UzLH05Yz7io5kYg7/wYpYMqa3f.js:default\",\"Skype Logo\":\"module:Nf75P7ImiLCyIWUXUS9Y/NsKFxhcPkCXFYwn7EA2g/miaSWGkL1.js:default\",\"Slack Logo\":\"module:04CFp1cKSAT7XLZ69BGK/GHsWzZZQyek6ZUkG01Dl/k3N1zsh4N.js:default\",\"Sliders\":\"module:GOJTIeEFrxIO0sRZXw6D/oovlcPNOHP7pfe9ZTG39/XPAusmMAh.js:default\",\"Sliders Horizontal\":\"module:ulBPyVlHOxrJGCXyUVFe/axIVTnXDuNBdblxJ9bfX/lQYgbzZO_.js:default\",\"Slideshow\":\"module:1NRdVWunDTXTlPBJZ3Yq/EfL5v5RsjZ4BhlSNNPSz/wuYToTdA6.js:default\",\"Smiley Angry\":\"module:NHcGxJz0mCcWIDSX0srH/JlzCy6sFvd0gr46ZVcTz/OsHND2SYq.js:default\",\"Smiley Blank\":\"module:e2dB3MAtu6Deceerjx9m/MDUqjXSRJMsJ2OIOjnHL/amPD_T2WE.js:default\",\"Smiley\":\"module:lKIvk7pX0EFs5xAY8qqA/dJ0aq0HsUobb0b4AXJ7u/RrZ0Uh93U.js:default\",\"Smiley Meh\":\"module:ACEXwTIQeC3yNSfBkR2H/TAKrZAi0BY1oluG0XscY/ymwIneMce.js:default\",\"Smiley Melting\":\"module:SLG0yqDppDD85l7Pjc8x/97itMe0wM4kL5upBLOCJ/mbboVwxNY.js:default\",\"Smiley Nervous\":\"module:8j53W2aOgGOnBZuvROUk/sJ9SoNLX8w0eE9alGPet/cTc49mCOx.js:default\",\"Smiley Sad\":\"module:WoQj69epLXWX5WvF6TWa/4VvLjPbsC6qGqyC68iO1/rWdHcYcD_.js:default\",\"Smiley Sticker\":\"module:NOQ6JJqsM64Tr0KTbUBq/3yxhjsYBs2giSHeaWW2q/OHZHmY20Y.js:default\",\"Smiley Wink\":\"module:bqeLwVHAAeVK3R5qHjHb/9cAweHawQqxtCDNw7RpG/j1YzlyXJe.js:default\",\"Smiley X Eyes\":\"module:6sdsxWzwLxF8DpVVnDLc/0aGCIJD73GuN0qk7X4mb/xawwFTMjP.js:default\",\"Snapchat Logo\":\"module:edqkDdl3KfSTcDrNgp26/M0BnWPSASpKREKd5eI2a/WvpdKMikF.js:default\",\"Sneaker\":\"module:YLgTGjP7k9c3pLJCJhit/2uAL04U8aFytiA5HoCii/q2fzXvCYg.js:default\",\"Sneaker Move\":\"module:FmId0QhItF8ShX7sEcYI/NgPlhwPh2wLkb3fcgD5U/IXMexVX1s.js:default\",\"Snowflake\":\"module:892T96emKEjKJTNhipIZ/v9Lgxj9TzYNeoh8NeizS/HAD1jJArO.js:default\",\"Soccer Ball\":\"module:cnTeRdap4vWxnsLFfubO/zAuw6NpqTpq8DU9g2RM3/pREMXMTXz.js:default\",\"Sock\":\"module:hxni0dDbEnecRbv749JZ/HNV39WRkB81Rr2dMoSaU/dmLkpfcoe.js:default\",\"Solar Panel\":\"module:0SulfNPtRraPqe3XkSRd/eGiYlVvD6207af5iNfvP/iPZXZ_RvJ.js:default\",\"Solar Roof\":\"module:frjHMQEd53FtP2jqqryx/7BUMlQK07iS8hDG3qmiw/i_dvP5QGL.js:default\",\"Sort Ascending\":\"module:7ezO23CGNHUKEp2S4izJ/U5eDoclVNwadp1MbO4KJ/vbJMyMncv.js:default\",\"Sort Descending\":\"module:aPVEg3O5qcy2p9oS3mm3/dH3mYosw0Q3rG5oEb8Lo/sExBPHBXg.js:default\",\"Soundcloud Logo\":\"module:KUQojkcsSTXYF9iWYzoO/saylUppszAbZBVJMsF1r/CYY0X97nk.js:default\",\"Spade\":\"module:mSV5ewe61fChPdD1scJu/W7Zf1kUHcWP5xamVDGPO/cpmACyvlO.js:default\",\"Sparkle\":\"module:6E2CGo0e7Cc8gA9Pxqck/o74a7BK1ERiMNm6HcbIs/fhHgguzMk.js:default\",\"Speaker Hifi\":\"module:3WSd5Cb5ZISR1hLa6kpx/E7TkxPhIpTibHgOKXUmO/sdl2iuhkR.js:default\",\"Speaker High\":\"module:FLh27TU0c01HNbs7li85/CUaQiMtLb3vieGsNOqgo/tCp1eXS8m.js:default\",\"Speaker Low\":\"module:PVSI5UttIyiBdnPmOYjf/5ZVrM7lNW6p2gZWLdpuq/uOuPI4jYG.js:default\",\"Speaker None\":\"module:JhtG81XVWffC8g3UGUiB/8nusVKhNmBPbOHHueuzA/ljO9UZtQn.js:default\",\"Speaker Simple High\":\"module:GijPYfom44kUI1DGgDdM/IrOCzKTZzhQlAc46b90H/DzdT4ZmuN.js:default\",\"Speaker Simple Low\":\"module:CdoOFNAixi5YQpeSyJB5/2wLR7PwxeAiKP0p21dxF/DYnNW1CAa.js:default\",\"Speaker Simple None\":\"module:sDYgrIjFWk2eFoFrT6CF/ZKTp3ZNaA7rn1R3YEI71/mpRxDkyEA.js:default\",\"Speaker Simple Slash\":\"module:YimQMCzgngLQjI06PBTC/CYHpQ2PECLdDRR2lBj3M/jH2d_sBey.js:default\",\"Speaker Simple X\":\"module:21pMc7dtZMM39LoYqyUu/9aWSnawsjOnUx5oSuUxh/jzJ0UDeOm.js:default\",\"Speaker Slash\":\"module:Lm8HuRJo3rbRC96t9CmZ/EFjCe11FHEaQ2eVxUqGk/fzQCViPuw.js:default\",\"Speaker X\":\"module:nJNDwPoeGL5sxcUaknqI/ssL6V17BHtPUCRAcLxYu/ltZxQ9aeW.js:default\",\"Speedometer\":\"module:5v0jJmF3sqacmaChkilJ/EvP62127oCCRX7qec3u2/VByNAqDgV.js:default\",\"Sphere\":\"module:xdiwZk97L44ORgITYF7U/ngqIiRw7tpwIY742hSfw/LpC4M8LJ9.js:default\",\"Spinner Ball\":\"module:U6XRIPMuNOdQsIKnSdYS/nGsRUtGcHQFzsMbrgKlu/b9pMg9q6w.js:default\",\"Spinner\":\"module:Ju5ZOX7uxXJSW0QKtvNf/e8cf9cB2B1GSm9BhZWgb/fhMOLVg5H.js:default\",\"Spinner Gap\":\"module:SK7isvsqAq3NMP2RGqtK/U2eCrJBI5nMtzDAuu70U/aRD7otWxO.js:default\",\"Spiral\":\"module:5LYntYXpL3jTraajVmru/t2xTNTJ9nxmkTamIlDNP/b5uwpzQAw.js:default\",\"Split Horizontal\":\"module:71JgKc8ig37FoITZHZ4m/bdHocpz3V9xfE4TMrVtx/dJRJB_u4Y.js:default\",\"Split Vertical\":\"module:FMTudzgvTysNQu3ej4zW/aYlJPgWqb4wKjPqoc9xH/Q8xjI0Rbd.js:default\",\"Spotify Logo\":\"module:zRHLqV1CtgnFPo0zMbp4/bcVUkyQQSavDdcOoux8N/Wr4Bg8I6C.js:default\",\"Spray Bottle\":\"module:Rq5UCO07f0ChTWSCkWCh/ZLr6aa1aIgJfY7x1mcVz/OJdnTxlH0.js:default\",\"Square\":\"module:z0r0P1pEGdBwwr1sVaGH/hFVtK9fiGwlWg3bnTUvU/uSBxj3R_6.js:default\",\"Square Half Bottom\":\"module:3X9EVjMu9v2Q1T5tCwR0/IHoZH0oc9cWBbBXMlqOY/V5KVIIJbw.js:default\",\"Square Half\":\"module:Q9eCd2Stvb5ZXfN2OijL/Rcwp95CVZ0N72xh9mZ72/oPGgnRc3G.js:default\",\"Square Logo\":\"module:Fz1ts9NmHPRpxDvkMCYa/W38ZIoKAB7h0ai0D51BF/kwlAaIC7y.js:default\",\"Square Split Horizontal\":\"module:YYqkAuiBz80zYqj4wYQy/N8wXyx0mjtzThXKv7mAi/eSUCAYsPK.js:default\",\"Square Split Vertical\":\"module:lfjUecJItLKpqcaMiCOa/9pw2v1XicfQoVpCtjKer/DQwCncbP6.js:default\",\"Squares Four\":\"module:a2eRzYJXREpKUWgncpJ4/SQf654MpmZVISS60OTNr/vJ_WOT4J7.js:default\",\"Stack\":\"module:4xQYlh6neffoT4xOa3iK/6iUMRVu3yVVhfQVoL5Wh/s9Ir45kgf.js:default\",\"Stack Minus\":\"module:2jaPrdhM96q4hdNVC0zp/OEA1T00yM40jxXArP6KJ/mouNiyqMR.js:default\",\"Stack Overflow Logo\":\"module:Ygf8pHljODsxhOYBXAk0/Mm8ZRKtBTgD7o1LV2k7K/B41tBibbO.js:default\",\"Stack Plus\":\"module:spiQDgot8Oo8ZJwuLhkk/TOJjG26B7OcWWBpsjAU1/hw3wygNEd.js:default\",\"Stack Simple\":\"module:GHQKi0onuZHjSgriUg4z/NalB8RyNApjsRoa3ZotI/JlBSlkjgW.js:default\",\"Stairs\":\"module:DcPUi2T2PWePZEq0wenT/f8INZLpbwiCSGguYI6gu/pJ4fCvVsw.js:default\",\"Stamp\":\"module:wlrMPOiKuGtGGfLl7AYg/h86QDFS68U0Je8BEZphp/GnGEmOL2X.js:default\",\"Standard Definition\":\"module:Sy7ohwVT7ZQgMqJXnow6/lFVxXR7aVMyx86pCQf6m/gSsR28IJd.js:default\",\"Star And Crescent\":\"module:dF9SWKRotnCv5RxcCxAG/sHsJHWbWX4aypTT0tVvp/fSiAz4ff8.js:default\",\"Star\":\"module:lGjONevu0Qs1ZIO2v8WJ/9dhBJaKhHHBOoaR9HIyB/dZkd7bSHY.js:default\",\"Star Four\":\"module:tHzQguoLnFudxIlr6wYw/IbixbXoxx0IJxuL5neaS/p7FybHNy8.js:default\",\"Star Half\":\"module:ZWLnOj1fKCtpNXDZ3XEc/qYHDa2HvYy50txg59H49/TgQkOLglI.js:default\",\"Star Of David\":\"module:ZP1JJETNxUANkOH3PxtD/m99MRBNMnvrOtFxQzOg5/WkHVR9LFh.js:default\",\"Steam Logo\":\"module:Y8KoWmdgo6yI1CrbRFnG/qyb9m02sqtdoSGZbkL0D/HwtuhbYP_.js:default\",\"Steering Wheel\":\"module:xyQlISmXlDbCg5fDYv8y/cDUhjklYxqFaFW82OEAw/jHom6XzWX.js:default\",\"Steps\":\"module:ZWll1fJWgbCHlCe3KGMT/SraWy2OSYUCGJegcsR8n/C3_KUgzte.js:default\",\"Stethoscope\":\"module:mSxMDPoXJ97sybDBBP3n/nrAskUUjVVPiqYBX7uum/jyifHWzTt.js:default\",\"Sticker\":\"module:4RJ2cW1DiZmBWyBt8XIg/WB0AyfoBGewRICp6SXGt/A5SxDPruQ.js:default\",\"Stool\":\"module:haImarUy3yXSZoiI5Dqd/eaaAb7Tm4yoW1FfPWJLU/rZgerSGXz.js:default\",\"Stop Circle\":\"module:Lpj2eJ38ZrFAW3FIoXuf/LmfeApKa6N2x6k4Zdgry/S9P9750UQ.js:default\",\"Stop\":\"module:D4E50QBHI9mk6vXERh60/NeEr9jfAesAMzji8eTHs/anjpy0psy.js:default\",\"Storefront\":\"module:KcjzTBRSIvvQzanFZKHh/h8lpBroPmkWc0BVuwUm3/Z57gvtJ2V.js:default\",\"Strategy\":\"module:mmSMQWByLhrw1cCGNIy9/lwRwf1afnO4li856hBoB/DkLkWmjxd.js:default\",\"Stripe Logo\":\"module:k2GlPQrYeFintyfTdnEH/m3SeNOFcn0xePP7V55lK/GmlEYYbdI.js:default\",\"Student\":\"module:4tfK1EXQ32zTqLzBzRgB/cBl4Hy3X7pbkW6X2eZ8Q/qw64TE1rP.js:default\",\"Subset Of\":\"module:rQQUALAdUd5cAr8iCek9/oedp4lJdBHh0bqjJScEY/v29bsA6iN.js:default\",\"Subset Proper Of\":\"module:Mswy80CEDK2YaoCKbFZ3/jaZ3nOREYKn4RoqVz3WU/jnUUmb4YF.js:default\",\"Subtitles\":\"module:5xjxmssSaX0NCVPfFTfH/3vvWbETvXg6WF0A7iDAG/ib8hIkelh.js:default\",\"Subtitles Slash\":\"module:Ssvvdf15Kx9vaaswhnPl/pz6BPX3wscJfWcmjXcZh/waE0P90Q7.js:default\",\"Subtract\":\"module:N4u5aALDryP3QMuRk5qF/PT3n152qgIuJe6qhfAbV/gT5OIrGqu.js:default\",\"Subtract Square\":\"module:OTt2E4y3MHmHGMLGH4H2/uesCx5ygz6Q6IHn1hLf8/sRiorQdrV.js:default\",\"Subway\":\"module:V1mvdbADjtAKWEhGLlcq/TrTbMYTmZaRf5HXTkEQy/oNXIrJ3bw.js:default\",\"Suitcase\":\"module:0SAKOL2uaZQ03PXvSkq0/EHIBZLaLAoYaE6UcL3eh/aKXFzIzU2.js:default\",\"Suitcase Rolling\":\"module:R1X7E4dueuuUZTrGA8GY/6DuLPdRmFy78eMiIiDvL/f7U5cGX2n.js:default\",\"Suitcase Simple\":\"module:IaYhIxBrN05sG98Uofp8/a0MRQYx5qjRmfusqwVba/lHGnT3wLh.js:default\",\"Sun Dim\":\"module:E94zMRZBdKF0OZTKUaCW/bSV23lxE8dXLxX1JLPOD/w38sIEEfm.js:default\",\"Sun\":\"module:dYR263VirJKvk6AwrOVY/EdCIxqmASH9X0THK6juA/kL1rHJbfO.js:default\",\"Sun Horizon\":\"module:UlpuTkSnVCgL1FLFcMxw/SnrrIsYHcoUTA4FnjvG5/LBMnreiVS.js:default\",\"Sunglasses\":\"module:EToQQ6ZAPArePxeWAC9h/Gy8NcA22A1OQF6l3CB2h/lyehLSd8T.js:default\",\"Superset Of\":\"module:O9BAZX0rHWsAvntBMaWA/zRA2PxY5boY5C8ULDEEK/VPQEhCGyr.js:default\",\"Superset Proper Of\":\"module:NjuBHitNFMmhlpULCg8c/If8O4QbqH2K86aQG0ZIM/pUnbyFFzr.js:default\",\"Swap\":\"module:iLxuKHFnMSPrmHzFq3NF/WpL8bZFIelC8xhHYNHK7/ibZSDnvlF.js:default\",\"Swatches\":\"module:QVN7TcyxjLd32dmCDo3F/MPBD8IN3nQAZuSxGgFi9/V4FGjy_zn.js:default\",\"Swimming Pool\":\"module:Zwp4tNjbeRXUt31oJlks/pUkJpvuKV4X3q0qeRmlU/NWdGdUDmE.js:default\",\"Sword\":\"module:LgaVA9HeDYigoYEs12n3/CCC6xk9KevjTcjzqy6O1/b6s2AHAyA.js:default\",\"Synagogue\":\"module:4dXOW3I2RnqslU7JrUN7/PCGACmEBRmZMzqu720HE/Zt5BC3MlE.js:default\",\"Syringe\":\"module:GreIUqbKkbJJhG9gf6Zd/5oI5g5yM74JTcnPtUGMT/VuxuguNzg.js:default\",\"T Shirt\":\"module:AwXiaFsFCYP4gYqefLt2/rPprgAEq3gBt64uvocY7/iZvGlTmVH.js:default\",\"Table\":\"module:fAXpIlXYpxAFPDBDvndQ/qWdZyYG4p1T76mZm3z02/kx1Y7gvpE.js:default\",\"Tabs\":\"module:Yj36fh0CLiCESzxxSaex/7qhsJedmT2taoXfy5Uvw/kSpOWoLi6.js:default\",\"Tag Chevron\":\"module:OVgDrFNuFFGpfVB2kVpC/NpGthsf4Yss7d4t0tGQp/ucwWnqEd6.js:default\",\"Tag\":\"module:JVARKfztmfQlD9F1ywEe/BOYSGsjZhBpa0uypT6qR/JwXniSI7U.js:default\",\"Tag Simple\":\"module:pYheVChNibFIaMfCQrPJ/pdlLLSxkRRJdHAjoLzXY/k6_9L4QRp.js:default\",\"Target\":\"module:Z3OGsfRtsAS0i1AnPTjx/qckyFYXNm2Ajk43B5kti/BLA6mPLjC.js:default\",\"Taxi\":\"module:ZpSD2MkIDUuiNl5wHuYs/BrS9wZNx8HaKThajFbzp/tj19g72Z5.js:default\",\"Tea Bag\":\"module:M9Woz9BCCsfqnGpXxXPn/trlELmXRBg6mznfcoaYj/jvgSA0Dsr.js:default\",\"Telegram Logo\":\"module:qjdqd1Ujhe2h81P7f6x3/032cly3ueitT8YyiTo3q/EVK7RjOjy.js:default\",\"Television\":\"module:Nfa7U2lL00qb1djKYwTx/HfBBpJqG4lFZCgunbMPa/fofQBtUYJ.js:default\",\"Television Simple\":\"module:G32BpvB4AO0vTW7Zoy8G/crHm7PNOUXIC2BbeMsT4/GMSI4kIyF.js:default\",\"Tennis Ball\":\"module:zPrwTKz9iM7sILyOOAPR/kJGJ0UHfX5g4v9E9poiq/AX0IJInwb.js:default\",\"Tent\":\"module:o819dUgvCSw8cwVOBrby/3NoWKQWsYmxXMlxa4Wdf/Dmy4s4T50.js:default\",\"Terminal\":\"module:X748wBds2xX92kGlWXcN/Tm9hYKp6hCiVbItWr8wg/V9dB0UE0f.js:default\",\"Terminal Window\":\"module:SFOb659v0oyLAL8IWKtl/BcsvSbOgi7HYz9DlFaJH/RS9sgHZJX.js:default\",\"Test Tube\":\"module:m3X0ZO1iPYvbBkDEvwls/K3G8IRRYGVmld70Zj08f/e0M8g8_QC.js:default\",\"Text A Underline\":\"module:5cqaVEcKfiB56hIVdsmQ/MhQqQPUAvXNOJ2l7Yx0e/XqJ1wLGoc.js:default\",\"Text Aa\":\"module:4WxWhs3pKXJqlf44saVt/Qen5LyRfqyeSReEsTMbM/ErS86dQMZ.js:default\",\"Text Align Center\":\"module:zJcAcanJFg3ltfhKp3b8/WUJqqrOlC88MdNrpIyVW/uyATvYslC.js:default\",\"Text Align Justify\":\"module:gVHOEfOUJ6j7DoNGAGrz/6dzLFsFT6atvcDV35fP6/zbt7taXzI.js:default\",\"Text Align Left\":\"module:s8mLP5hIAP68vLWfbttV/lkD5Ga0e4qSh1EanFlWP/YRGFB5SGo.js:default\",\"Text Align Right\":\"module:qGfgHICNEX8ENi6liNeg/pg5WueBSvOalJVotOdPc/mR3GQ9nbA.js:default\",\"Text B\":\"module:jOstjcYAHI5n64SY6cji/e4Ttt7lRRjmudgE0Rczk/TpwuJL7Ua.js:default\",\"Text Columns\":\"module:rpCPKSpcx09ulMXiNCVb/icvcooky6QDSW0ElszTv/faIJmB88E.js:default\",\"Text H\":\"module:5RISGGPBR191jHlvd6gS/USMh51I07FWOVtTLKc8w/lckq_o7Rn.js:default\",\"Text H Five\":\"module:L5PUnC15WIQKnNvXK8pa/KvkwsT8nJVgA6jW5b6uY/sZRrpFeTr.js:default\",\"Text H Four\":\"module:K9PVkYeDf5NckzGkuLV9/JTs5x5oh8AyorwL5pY08/fNFaBzX9J.js:default\",\"Text H One\":\"module:LxNMkpKNnRugfPeEOGIG/7FBxPccMZl3UtaLIBNOO/QIa6sZ_Jw.js:default\",\"Text H Six\":\"module:sC4U3Jf7T3Qyn0oFxZDG/YAiP3cPal6OQIllHCZhR/k__Szc2d0.js:default\",\"Text H Three\":\"module:d6EomTG2hRXHlcLnSmlb/MatFns0N0wLhQsG2MAMX/SnhChz9xa.js:default\",\"Text H Two\":\"module:nb2pcrQZFJUmElRmDJnw/i8yx9O2qKfPOX3Vu61jF/fZn7ViJFQ.js:default\",\"Text Indent\":\"module:yT8v3EICp4IJWG1Ripwh/N9HsZrAfaxHsDYviOt02/eMJiW3CU5.js:default\",\"Text Italic\":\"module:inadGfHcBbHC05Nx2A7L/KrkVKr99mCo40H52ab65/dwvtNvv4z.js:default\",\"Text Outdent\":\"module:SQaoRCkI8A6GeaZ2ZOCQ/9AFyLERtVZhOXMWD4my1/YxSUVLs85.js:default\",\"Text Strikethrough\":\"module:dJKWFThPMiEtkYaeNd45/JQaL6H6nebRtMAmjTmY4/cDCX5yoZm.js:default\",\"Text Subscript\":\"module:lPbDHC0EtlA1D79XBLqP/hPtkymX7KyMoKwN5GkTp/QFaDOp3Tm.js:default\",\"Text Superscript\":\"module:h75o0jpA14lIe7GECKKh/S8sf35muEhYSsYEWIR2p/XXdKwaCFM.js:default\",\"Text T\":\"module:W86M7pkjI3qBTCaXk8a4/PwDtjO4GIF6Gkh7iTCo2/vYwh0safv.js:default\",\"Text T Slash\":\"module:jNEEDHtgchqW6Cw6O9N2/7st797bjBTR0Q4pGVsYy/sb08Ej2id.js:default\",\"Text Underline\":\"module:8zzuLK398VFFp1TWBvug/Hn8SUX3SNFPVPNAvzTH7/QSODfK5Pa.js:default\",\"Textbox\":\"module:gtAYSHUjH2gpvXkp3ljR/7RvvfVTcVKh7Bn1TyOoi/LCJJPFzqx.js:default\",\"Thermometer Cold\":\"module:sqSl3gVQwIJ0ysLsOXEf/0i0RSNbzaOUicGkY4V6D/HiDELS76V.js:default\",\"Thermometer\":\"module:piTR0QKXjLu3Bc5jENmS/msBbFwUQzdl6VOzQNK4A/y_WxbHxva.js:default\",\"Thermometer Hot\":\"module:bKEI69K1aA89cHb5KnwB/CNXcKJTlU4VHxXnDBzLy/RX2uK1ajR.js:default\",\"Thermometer Simple\":\"module:srSm7qDsbz2q9F4wNoD8/H9whTDh3ZW8uXguOZAhA/t9AlCNces.js:default\",\"Threads Logo\":\"module:UzpsxVD4xQ4Gsi5tov6k/XkdGdYEIAvitN20NjsDQ/MXELxDtuh.js:default\",\"Three D\":\"module:LePc5F4F1jgg4fHbqPkA/XlR3AowuS8mMePjXVU9K/tIQiIShyz.js:default\",\"Thumbs Down\":\"module:HBgwWBEINBCq3ezwjhxo/AthQIrBwHG7KF7qLzpAl/gxwiT7v8q.js:default\",\"Thumbs Up\":\"module:RsS8fp9KsCHlm9ulEVrJ/nP0GVDPqOFgbb581TO8V/vlkxKcqZk.js:default\",\"Ticket\":\"module:cfCcd8n3KumF9bFEcNkL/juD0PLHFZ9kJNc98YvW0/xNWqwp94G.js:default\",\"Tidal Logo\":\"module:lwHM9pQkUltfo50pLR2u/lPizmr3DN5baifMQTSbb/wT90FsVkg.js:default\",\"Tiktok Logo\":\"module:TNOWoCWEr5Q4rZJjW1Ys/7a6Npqy12wRch0Aakncs/X4yTai4nL.js:default\",\"Tilde\":\"module:WID9AiJp0m4Xye69cZbf/cwQywv1wMVlpzlwawRTR/hLBC7rzZ_.js:default\",\"Timer\":\"module:cEsxJQVRxwRsKpVCyZfF/FkZn2G6tHGtRHuEFpaXc/eSPEYyaDj.js:default\",\"Tip Jar\":\"module:yg7GGZjPVhkSTLjwLA4F/naQvjSEbvRGBYdUml7YN/F_t5B2JUo.js:default\",\"Tipi\":\"module:phJaeGvFuDBtsAGFjj4c/HqzrW2jd5iaQ9SZ7igjF/vTI61AGMc.js:default\",\"Tire\":\"module:rVertksLrP1MaSoHXGXR/MQlyKCXgY1uTgguXXzIq/ANW3sR5tg.js:default\",\"Toggle Left\":\"module:unXcjqVt8I3cnHDJ8sxF/s9lgpzp4nvouJW4Nc7JV/kU5HjkdJ2.js:default\",\"Toggle Right\":\"module:BvPYI1vTpNArrfCGgEwH/YG2Oz0RYpQD9DGCIU6JM/xAUv6Pkkb.js:default\",\"Toilet\":\"module:C3C09ZeCxGEWAzoO60ja/CbKrgQJtyFZ3b6ZNsKic/de6LNBHOV.js:default\",\"Toilet Paper\":\"module:EtFBZl3h3brApQQ5wgNA/coyxFB73nxBKKKO2b3ca/QckKOt1Uo.js:default\",\"Toolbox\":\"module:IdBYfXacSbkGkyum4gvx/ZfZNPX01yC9Lgb0YRqC9/VacaTily2.js:default\",\"Tooth\":\"module:1OsKJUY5WXoWngKt3nlU/2zOrJ56Y898jXPxLPC7X/EVJYX8Unh.js:default\",\"Tornado\":\"module:DqkI8ZXvmyS85jwDjjGG/2nKGD2D93RpdjXKcbavJ/ZBeIhSl95.js:default\",\"Tote\":\"module:bFgWzUomsQ1fQWu1z8lJ/RvHaNvVnenyT73O8IN68/yVW4oHWI8.js:default\",\"Tote Simple\":\"module:Z6cnvldJuaLonFZfGgb1/vLQ0bjODBoCfGgyeYkDZ/PW3VAIImL.js:default\",\"Towel\":\"module:DTfhvCftXTMhTf4CxtkG/HNNdg0YKeII77z9QlBrj/ZClcFui_T.js:default\",\"Tractor\":\"module:c2J6zIiwN4ZaR8FMxyST/TEJ4ePtNJjdssBf37VuP/JJFDc4x4M.js:default\",\"Trademark\":\"module:3emSWFbnYoUlCmteE2H9/xf7qctH528cL2YS38lBG/roaBN7aK2.js:default\",\"Trademark Registered\":\"module:WfH9cmMjWlowmj5CCSt6/RB6rA8h0NXBEscBiBkZq/ua9XUfheJ.js:default\",\"Traffic Cone\":\"module:nxXt87xAcRtMOzg36VEo/qeSUrDG4BSv2RfpKZSyC/dRETAm86Z.js:default\",\"Traffic Sign\":\"module:aDG7CjTuYTcRJ5MZsFOu/jXHZhehF95HZjxSlJulf/aGsUoL3m4.js:default\",\"Traffic Signal\":\"module:qw5xpzrbCYSdooIB200f/nJ13hCov3RpDqKTQdqY8/aBCg1sONk.js:default\",\"Train\":\"module:QNxyizbzye9YXL0aBVmY/ZbqTuURY7WTIPov2RbkR/bEb2drJ_T.js:default\",\"Train Regional\":\"module:5ktsg16HNHpnT3zX9599/LWfTGC9wKI5ltYHsR2Zg/gO80nIHGI.js:default\",\"Train Simple\":\"module:knNvxKcaE1QhV3iVA0rB/8smcw4Zp9WKLse87TF2X/WClf0uRT9.js:default\",\"Tram\":\"module:DBXq7c4iWOEOsOJSVyX9/XKinZB7BLkgKhiSyGVOO/ZkIH8p5zD.js:default\",\"Translate\":\"module:Vbv50GjcR2Gblmg1rUAO/SKrRAEbLdRXqYGZuNO3d/m5e39A4lp.js:default\",\"Trash\":\"module:pCN9XTmOU7fO9Thq6U6B/uwG1QoxPBXl0ebwMgLac/JHw_vEW2G.js:default\",\"Trash Simple\":\"module:cMIPtaWMCT8il4DuIxQb/8NbaZ0Fu3tM3VsFV3GRB/X0Qt8bdE7.js:default\",\"Tray Arrow Down\":\"module:ro1tZjTkLHIZkrzcpcR9/gUVnyW3w2OKH65tVnx71/jg8ZnVdw2.js:default\",\"Tray Arrow Up\":\"module:MFJYWojHP6FtuIza7KIa/8xWMCxLpsdSxBxEv0tEJ/HZd64ixvE.js:default\",\"Tray\":\"module:xmGk9gWE4UI2g3ERlEnY/oY5egq9InUi2TOn6I6sF/c0CnXx_wa.js:default\",\"Treasure Chest\":\"module:pxA5eUhPLPMMpAQM1ywD/OZVxJaGk8ui1IpTMB2qg/JSAohfE_G.js:default\",\"Tree\":\"module:ZR6sIif7s6cbR8uShPQ3/eCM8PqSz7JWOpzrHU7eT/R1WeKjY3P.js:default\",\"Tree Evergreen\":\"module:1w4ZLSwIQlplvikSlx3E/0IRY8az5iKU55f9JazbC/wivJ7aaiF.js:default\",\"Tree Palm\":\"module:iFsRQWu2YhjwxjIeW1yZ/JZ581VaLBl7Xq8m847iQ/JHIXaL8ks.js:default\",\"Tree Structure\":\"module:MoV06sfFqAYRWhiO5fss/SP21F6tHBD4HtJZQlKxA/ED5ha30S4.js:default\",\"Tree View\":\"module:EBPnDDccg4cEuCbz5clW/6WBZkFrAqsYCbWbwvsPB/iUryRvEUb.js:default\",\"Trend Down\":\"module:UeqmCnolDINBSHV42g4K/cfH09NdPDHXATpuSmtmW/DV80C3yuP.js:default\",\"Trend Up\":\"module:0OdcpekO0h56ut5Q6QwM/zBGgwQD1O48HEGzJEMBj/R1G4l0cyX.js:default\",\"Triangle Dashed\":\"module:shifnTqc4qiFvODVSFqZ/GPhYOjwHkuo4Drz2A2YI/P6P0vCzVJ.js:default\",\"Triangle\":\"module:bbffJ61FnoAng9D7EoCt/WpvnMKee8j4XNOCTUARh/IBVeg2C3Q.js:default\",\"Trolley\":\"module:NAuEP1XrvyoKrGEU90wH/IGkNCDPLbt1pOmKyQWlC/w_MHGRzqo.js:default\",\"Trolley Suitcase\":\"module:TdOh6ddCLgoGzRwGPbUF/AFZlBGf7qAoRYUkoTX5j/kmBp_wF7T.js:default\",\"Trophy\":\"module:xD1tQGy4pyZevRTI4Nw5/iOVoTU0oozI6tmm5ErAY/hF6G8oEjG.js:default\",\"Truck\":\"module:LDGILwZWTBSLsWs3x2kg/XoB7ihUNdR3qHn52Czmd/fAZ6otk8l.js:default\",\"Truck Trailer\":\"module:SLNLM4LcFBFWIqIOMZCf/nx8bs1ObEznfi115cgkK/EYIMyMRYa.js:default\",\"Tumblr Logo\":\"module:2PhawOmtJSDu5i7ARoDd/PdItEYESMGk1gfHDJMFG/pR4FTmQjO.js:default\",\"Twitch Logo\":\"module:i3sLb69q7KGYtLcRgo4G/l4wRjIe5h8VwFrH2BktP/Hx4Y4y4G3.js:default\",\"Twitter Logo\":\"module:c4HsHmhw2A874wd4HUv4/eiMgKnTLbWkmDtuRAl8s/Nz7HVaCWU.js:default\",\"Umbrella\":\"module:7iwHYmY8XoCTzakJSzSh/QPpVZcTUq5VFsahZ3Vy4/ayWHLg90M.js:default\",\"Umbrella Simple\":\"module:sAP2Q9TI1ZOMc94ezqfr/eXvPDWxHwdBt5ALVb7qU/cuPXBD66H.js:default\",\"Union\":\"module:wd7otw2OCJG20D6z5tzN/FFtWAVGPA01sXxt0vu1z/IQUtpOakM.js:default\",\"Unite\":\"module:4GLczcb69wBwt95mx7jh/E0tAW23P7Fvpmaqt5lb6/O2zAvSAlQ.js:default\",\"Unite Square\":\"module:ur8YbV3XmU288jhiwxmy/4oELCfWBb8pu5Hpd7mvZ/K0huGPJJw.js:default\",\"Upload\":\"module:CvSK5k3LM3jgT3dQ3L9V/111C3blWoQfXF3cRc2wK/VxWqy2IaJ.js:default\",\"Upload Simple\":\"module:GnNX9pFMOesct1kSpUxd/qXF00r10Mi7YdYOSxJG4/VCS3xz57P.js:default\",\"Usb\":\"module:4zuX492JWG59ltWgVCsW/XjlYc7e7hHa7zXEkmh7h/Ber6xemXa.js:default\",\"User Check\":\"module:tjjgb98omlVa09zHARR4/ggRLlXNJnxV689eAMtLP/LLhYBfdqv.js:default\",\"User Circle Check\":\"module:2sDHKbujyoerK2Lje6Gh/RfEuFZyBo1rW088h3KVJ/vg1v3uWYO.js:default\",\"User Circle Dashed\":\"module:OYW16c8IIKxGrekspfvM/17CygtNCjL3XdAufvZRD/EL06oeTJ8.js:default\",\"User Circle\":\"module:EubP0m9UZxWvAnUpaqn7/sIKO1w9cqIu9F9VHZAnx/c9gjQcKTN.js:default\",\"User Circle Gear\":\"module:aC0EIeFWvK3ETbaan5gU/pYVMNtBcr3Ci9QLGu5XY/QoPkpnUfR.js:default\",\"User Circle Minus\":\"module:IdIXPmP5gGYDUSTXttan/jlqnxmUGeoJJqZAx4uVk/GUxT18Sr5.js:default\",\"User Circle Plus\":\"module:kEc2Vy9gRd94E9t027bc/KJX0H5wIDTXZTxxp8xWm/yHh1iqqfx.js:default\",\"User\":\"module:2QGlX864pmL5cxqknTvK/sudwzLB4XBD5Atme8MXS/UvPxI2Cnv.js:default\",\"User Focus\":\"module:KVGVa3QUsEsb6bWddVo3/SNDuTPy8rXsS63NabRyi/T1IQicihP.js:default\",\"User Gear\":\"module:Ryyn4zvic0UcVSrIILAB/SeDE6EKg0BSUAhpndto5/OY9OstZA4.js:default\",\"User List\":\"module:P6sq4KyBMd1FljixNrfp/EXNxidXdhFbUjUaeK7av/xLAezFEgs.js:default\",\"User Minus\":\"module:5JGTC1eGZbs8uYmiWQ90/zJz3jBwGPpkcYH352mXP/NPEiaAyAA.js:default\",\"User Plus\":\"module:9rvCFUloZ67PRoPMrUnQ/MKksXQrDgvC3XRggv9vN/llSSeBGvs.js:default\",\"User Rectangle\":\"module:oe6dv3ufRGUTvyYjcFP7/dcOWg8vzMO8Fz9e7gNgj/hAMZ0MLYx.js:default\",\"User Sound\":\"module:RAGzHdd1S0tpvie25UTC/vtiQLsZWhhaTjAQrErbi/qTsHgcapL.js:default\",\"User Square\":\"module:8YmMKKZcBqahzkU5YAUK/kLwHWUlQFZe7fAGDiMvg/teUxumIG5.js:default\",\"User Switch\":\"module:AdSrte2MlA9ilyyY0O3O/7HTzWEIggps7ALl8jQVE/pAaH3K5ta.js:default\",\"Users\":\"module:4NPoFPQEhSNg2OoiApwj/ob6f5zVw0r8uyASOMKVq/KF85dqOX0.js:default\",\"Users Four\":\"module:SHkZw80jZWuy8szPEolr/RZenPBrelUTpuWgMhU4p/FKPBR4TdC.js:default\",\"Users Three\":\"module:oeG6xBwo7PnoRBdoRf9u/zD6oCfAKePdei90zk0xl/ILlKpAwNA.js:default\",\"Van\":\"module:IN35rfwUsqcKif6Xg4Al/bUyAqLpuep0SjbByszD7/V8_KrzahL.js:default\",\"Vault\":\"module:XomcDr5uH0LP0hsnXNPa/1BRr5pCaVgtjfsqtpe3Q/fuBqgYm2E.js:default\",\"Vector Three\":\"module:hHtJZjbcN7oviXycZXef/OWK7RJRPr64hpOs6u8wT/SfxMs8yaZ.js:default\",\"Vector Two\":\"module:QKcqzO7FSxGXzdDoNVPn/RS5fYoA5VOPnTtmwFffK/OePEa93J3.js:default\",\"Vibrate\":\"module:TSvxHJEMlOZv89zG2IAu/lrPLyyC5V0Brnof80pVd/kwNiRrems.js:default\",\"Video Camera\":\"module:hgMr2g96kcGEDPFkMF4X/Z6knuV4W9JO39sXiDbHl/nhE5uzhxF.js:default\",\"Video Camera Slash\":\"module:Yg0HaDovp5F2ah3YyPR4/cPVgzC4CICwAytpqFZje/cmh7ia0QB.js:default\",\"Video Conference\":\"module:OFHQjSUs8VzuYEOIBuWk/wnvEO3FgMDcc2aODuZid/c2eRcHSrN.js:default\",\"Video\":\"module:JCPGeMeSirrpINg04yKw/OAzRpmEGRv7uHMj2ZY3W/elLKxaYdA.js:default\",\"Vignette\":\"module:a6Zl4pmqHP1pyFGc4fxM/8UjfUOyyVbluwaext9df/iHcYDBQPE.js:default\",\"Vinyl Record\":\"module:rtAtZYBPti2edcKkKwA6/J0IMuCBFVU9PSoOUgllv/tOJ1xt3X_.js:default\",\"Virtual Reality\":\"module:Se9KwsAenJ1MoNPgKp9z/MNNTHxwA669aTYDUZZYV/XX11ODgRa.js:default\",\"Virus\":\"module:BYGHEXz2kOoAzmbGv69U/0KiVUG0myklCUPQ6384R/Jz_YwQY8_.js:default\",\"Visor\":\"module:p5tQXqEvK4Bzy9gcTfl7/TwaawKhH57R61sLou4rI/gYa5KC6c4.js:default\",\"Voicemail\":\"module:gEnoKpEHEYwy35C7vpWj/9uUHvQcK86ZAZmScqEPp/RYmMmLMbP.js:default\",\"Volleyball\":\"module:XMaIZh0biHEv2egESRK5/8nQ2LmwOcMcayCZYrjBZ/tOVQZ4Zk_.js:default\",\"Wall\":\"module:xLDL0NIWl1nRxVdGyeSR/9celPbhZMyxPaXHb8SlD/TVpiKbAVa.js:default\",\"Wallet\":\"module:uDua4ZMXrySszU1wcRr0/M1NJW56DI1M4XsiwNY3A/yZHqmVGag.js:default\",\"Warehouse\":\"module:5xPouwvQM8G7ZhDlYMOi/GZuaYCQlJCTIgDmF0TD0/fYpCfNn8R.js:default\",\"Warning Circle\":\"module:DhoJ57PI2yk0uHk4kdwM/ZiCyspu9B201PZtCJ8Xy/aLvTtyMNr.js:default\",\"Warning Diamond\":\"module:dZIsdCCzoLrckW7x3efR/GxVFoI36PkqlL5g6vvbi/EF958psgl.js:default\",\"Warning\":\"module:7E5ZpeYVpXKBrpzN1U6Y/HUD2rjuTrd6USeoHgkXa/Jqi_BRGpm.js:default\",\"Warning Octagon\":\"module:1v4AuYM3fB9bYCE51BcS/3blt9CcxMy4YnNZEJAC7/Jkxkq52Ww.js:default\",\"Washing Machine\":\"module:pQ28dAO5GV06oqyMOSi6/WwdDFXM4AVgxseihAi03/yc5ZnCDR6.js:default\",\"Watch\":\"module:oMzMsDFOh8o4qDTlkqbC/VaOCPZ6WnDDmGGr96UL9/XZuIXE2Yb.js:default\",\"Wave Sawtooth\":\"module:j5FT4QTiEOj04w6xSgvh/Q3O4DLAOG3qzRgSXacQn/bamR4iDjY.js:default\",\"Wave Sine\":\"module:RKwPmKSNEO0U2YAeBRQ4/3EWNBEujFD8OOx2jcB6O/ZK9iOT5i5.js:default\",\"Wave Square\":\"module:dJatz99pjf9ALXVnXHO9/CF1LCYBP4XII7lMdnEyQ/EIYbmqMhu.js:default\",\"Wave Triangle\":\"module:7WchLCUuHiGLZ8ea6xUJ/ZC9VoYyDRlAuUg1V8byc/ZRw0GlO0F.js:default\",\"Waveform\":\"module:x94Hq2wjrYTiFgxaN6vA/XsY7AfGjF9xRVKAWqRdJ/SuYPq6AUC.js:default\",\"Waveform Slash\":\"module:RmIeDKK3onjunQF8bUhZ/bvDYTtg9kXxYS3FTgTld/BOkP_onem.js:default\",\"Waves\":\"module:q4Np134GCRBYMXpaoYO2/uJ2SNxwkjRN8F5IKNJDE/bpn3X3frq.js:default\",\"Webcam\":\"module:D6C18RJ4wE9PIxz08k8d/HKKX7XZc6UVTqC1Zj3EB/ehzuGRE0y.js:default\",\"Webcam Slash\":\"module:EGIWUuKMiltdi0mpJ87M/e5Ss6WZIsDJRRnhlxU33/KzMvnvcjs.js:default\",\"Webhooks Logo\":\"module:8v1ZyD60UuJ9GI3OpLIE/EZ4wXnYvYtUUMpfTasBQ/l0V8bAA99.js:default\",\"Wechat Logo\":\"module:I3ge4zKWzWc6UDusQZ4Q/mUVIshxejAooHWY8GYvg/EnBFEd1fP.js:default\",\"Whatsapp Logo\":\"module:ppr8OWMIrtBvJ1C4wfqk/qhDP3PUI05OrL1yANxTR/wMj3wn618.js:default\",\"Wheelchair\":\"module:e44iZKh1MMUymr1YMAi9/H8FWEezDGznSrGh2uYH6/N_jrvqCsm.js:default\",\"Wheelchair Motion\":\"module:8aev5WUv645HkGK1MKrU/jQa47EmqzzLPipS9U0uZ/x0glEpuJ2.js:default\",\"Wifi High\":\"module:sd2RGFUXbHF4v6nN6C3m/Z39YkUeDolQgfMTkeg5B/NPulthYi1.js:default\",\"Wifi Low\":\"module:iMBrFS83rsbAWL8IEXMk/D0xX6Nt5nN0tEh5XVXMY/S80m1wLzy.js:default\",\"Wifi Medium\":\"module:oEoEDmXkPsxdNQRfcsGk/t55GJoHrylSTNpjBc7yq/qI0Ft0XB9.js:default\",\"Wifi None\":\"module:lVUR7YPeRcvpfyq9EDW5/fnhZuhrwH6izfM6j7rjb/QAaFJjiwJ.js:default\",\"Wifi Slash\":\"module:sPPRWrR1EAuPvzqoLCCD/vcLm4YcizxzXQ2H8alSY/wZEf6AX81.js:default\",\"Wifi X\":\"module:OyvP3iwtgn6HSsBIMn2v/9IARLo6iLYLjLdjdCBVP/ApQd0luTW.js:default\",\"Wind\":\"module:narGhyaATBIGAebIHwgo/pLWmJ9VXHJ4uA7InYCrP/MmEHA2BkB.js:default\",\"Windmill\":\"module:uT4ElH2Pl4dWe4903atD/AfCzpM6kjnT6sV0SrXNr/LU3JDINxb.js:default\",\"Windows Logo\":\"module:mtGEnA9HkJz9eOqVYz08/9uSxiWJTDgYy4Zx3C3rz/X9vIMbOW3.js:default\",\"Wine\":\"module:KKoK332fmHoAhjojgE3U/elTUEcIb9NhnvkkC9cMf/MB_1AcMh3.js:default\",\"Wrench\":\"module:WropPXEZ6wMwodqpajxp/irPqhPbmRNLTLGf61gFk/wKPPkMdvP.js:default\",\"X Circle\":\"module:CAVV5mJ4jls4nNw905yN/APysZic80Jb5eDeflwZZ/YQUHZ289n.js:default\",\"X\":\"module:wbL0GysLpUpZOLelXsKU/7IhRlKXIvqCTv7OUjGRe/q95pf4lLL.js:default\",\"X Logo\":\"module:oMiuMYAdxzz5yk7pBqrm/j2eV5wGWikO42mvtQ2hM/Xx_sbLkzD.js:default\",\"X Square\":\"module:U3rIWbfukQRnj77G5ByA/SsYjeJpx00xSh5bFW04q/f1X4NOi1X.js:default\",\"Yarn\":\"module:eH7BqOCteSdqlqy1WIcN/Kwec44SOTJnMOGjsDaoZ/Lbe1hD2ZK.js:default\",\"Yin Yang\":\"module:dR4b4lN6aH2zHZSUjM3M/d4PH8enSZmEBsdZzDoXb/XF8E9OyKS.js:default\",\"Youtube Logo\":\"module:4XTgiZQu54CjbB5dhliq/4qeXVdBQKTlCfMoVGgCT/rR4Yw6OW8.js:default\",\"Infinite\":\"module:zRhvMMaj8jAG4s0SbzXg/pgN1QlZHnmoKiflozDSf/QmKkkmqY6.js:default\"}", "import { getLogger } from \"@framerjs/shared\"\nimport collections from \"./data/collections.json\" with { type: \"json\" }\nimport controlProps from \"./data/controlProps.json\" with { type: \"json\" }\nimport { list } from \"./data/index.ts\"\nimport vectorSetModuleData from \"./data/vectorSetModuleData.json\" with { type: \"json\" }\nimport type {\n\tControlPropFields,\n\tKitCollectionTemplate,\n\tSectionOverride,\n\tSectionWithOverride,\n\tVectorSetModuleData,\n} from \"./types.ts\"\n\nconst log = getLogger(\"SectionsState\")\n\nexport class SectionsState {\n\t// Safely using a non-null assertion operator (`!`) here because this field\n\t// is initialized in applyOverrides() which is called in the constructor\n\tsectionsWithOverrides!: readonly SectionWithOverride[]\n\tcontrolPropFields?: ControlPropFields\n\tvectorSetModuleData?: VectorSetModuleData\n\tcollections?: KitCollectionTemplate[]\n\n\tconstructor() {\n\t\tthis.applyOverrides([])\n\n\t\tthis.controlPropFields = controlProps\n\t\tthis.vectorSetModuleData = vectorSetModuleData\n\t\tthis.collections = collections\n\t}\n\n\tapplyOverrides(overrides: readonly SectionOverride[]) {\n\t\t// Create a lookup of all overrides by source.\n\t\tconst lookup = new Map<string, SectionOverride>()\n\t\tfor (const override of overrides) {\n\t\t\tif (!override.source) {\n\t\t\t\tlog.warn(\"Skipping section override for id\", override.id, \"due to missing source\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst key = `${override.source.projectId}/${override.source.layerId}`\n\t\t\tif (lookup.has(key)) {\n\t\t\t\tlog.warn(\"Duplicate section override for source:\", key)\n\t\t\t}\n\t\t\tlookup.set(key, override)\n\t\t}\n\t\tconst result: SectionWithOverride[] = []\n\t\t// Do the initial pass where we add all sections from the repo, and apply\n\t\t// overrides as we go.\n\t\tconst handledSources = new Set<string>()\n\t\tfor (const section of list) {\n\t\t\tconst key = `${section.source.projectId}/${section.source.layerId}`\n\t\t\tlet sectionWithOverride: SectionWithOverride\n\t\t\tconst override = lookup.get(key)\n\t\t\tif (override) {\n\t\t\t\tif (override.data) {\n\t\t\t\t\tconst { load: _, ...sectionFields } = section\n\t\t\t\t\tsectionWithOverride = {\n\t\t\t\t\t\t...sectionFields,\n\t\t\t\t\t\t...override,\n\t\t\t\t\t\tdata: override.data,\n\t\t\t\t\t\thasOverride: true,\n\t\t\t\t\t\tisInRepo: true,\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsectionWithOverride = { ...section, ...override, hasOverride: true, isInRepo: true }\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsectionWithOverride = { ...section, hasOverride: false, isInRepo: true }\n\t\t\t}\n\t\t\thandledSources.add(key)\n\n\t\t\tresult.push(sectionWithOverride)\n\t\t}\n\t\t// Now find any unhandled overrides and add them to the map.\n\t\tfor (const override of overrides) {\n\t\t\tif (!override.source) continue // Legacy entry.\n\t\t\tconst key = `${override.source.projectId}/${override.source.layerId}`\n\t\t\tif (handledSources.has(key)) {\n\t\t\t\t// Already handled in the previous loop.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// We need to create a new section from the data in the override.\n\t\t\tif (!override.id || !override.description || !override.data) {\n\t\t\t\tlog.warn(\"Skipping section override\", key, \"due to missing id/description/data\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tresult.push({\n\t\t\t\tsource: override.source,\n\t\t\t\tid: override.id,\n\t\t\t\tdescription: override.description,\n\t\t\t\tenabled: override.enabled ?? true,\n\t\t\t\tdata: override.data,\n\t\t\t\thasOverride: true,\n\t\t\t\tisInRepo: false,\n\t\t\t})\n\t\t}\n\n\t\tthis.sectionsWithOverrides = result\n\t}\n}\n", "import type { CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { withCodeComponent } from \"document/models/CanvasTree/traits/WithCodeComponent.ts\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\n\nexport function equalHierarchies(nodeA: CanvasNode, nodeB: CanvasNode): boolean {\n\tif (nodeA.constructor !== nodeB.constructor) {\n\t\treturn false\n\t}\n\n\tif (\n\t\twithCodeComponent(nodeA) &&\n\t\twithCodeComponent(nodeB) &&\n\t\tnodeA.codeComponentIdentifier !== nodeB.codeComponentIdentifier\n\t) {\n\t\treturn false\n\t}\n\n\tif (!withChildren(nodeA)) {\n\t\treturn true\n\t}\n\n\tconst nodeAChildren = nodeA.children\n\tconst nodeBChildren = nodeB.children\n\tif (!nodeAChildren || !nodeBChildren) {\n\t\treturn isUndefined(nodeAChildren) && isUndefined(nodeBChildren)\n\t}\n\n\tconst nodeAChildCount = nodeAChildren.length\n\tif (nodeAChildCount !== nodeBChildren.length) {\n\t\treturn false\n\t}\n\n\tfor (let i = 0; i < nodeAChildCount; i++) {\n\t\tconst childA = nodeAChildren.at(i)!\n\t\tconst childB = nodeBChildren.at(i)!\n\t\tif (!equalHierarchies(childA, childB)) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n", "import type { AnyNodeKey, CanvasNode } from \"document/models/CanvasTree/index.ts\"\nimport { ignoredOverrideKeys } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport type { ReplicaNodeOverrides, ReplicaOverrides } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport { isFunction, isUndefined } from \"utils/typeChecks.ts\"\nimport { equalHierarchies } from \"./equalHierarchies.ts\"\n\nconst primaryRootKeysToIgnore: ReadonlySet<string> = new Set([\n\t\"top\",\n\t\"right\",\n\t\"bottom\",\n\t\"left\",\n\t\"centerAnchorX\",\n\t\"centerAnchorY\",\n\t\"aspectRatio\",\n\t\"zIndex\",\n] satisfies readonly AnyNodeKey[])\n\nfunction collectOverrides(overrides: ReplicaOverrides, nodeA: CanvasNode, nodeB: CanvasNode, isPrimaryRoot: boolean) {\n\tconst keysA = nodeA.keys()\n\n\tconst nodeOverrides: ReplicaNodeOverrides = {}\n\n\tconst children = nodeA.children\n\tif (children) {\n\t\tconst childCount = children.length\n\t\tfor (let i = 0; i < childCount; i++) {\n\t\t\tconst childA = children.at(i)!\n\t\t\tconst childB = nodeB.children?.at(i)\n\t\t\tif (!childB) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tcollectOverrides(overrides, childA.draftOrCurrent(), childB.draftOrCurrent(), false)\n\t\t}\n\t}\n\n\tfor (const key of keysA) {\n\t\tif (key === \"children\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tif (key.startsWith(\"_\")) continue\n\t\tif (ignoredOverrideKeys[key]) continue\n\n\t\tif (isPrimaryRoot && primaryRootKeysToIgnore.has(key)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst valueA = nodeA[key as keyof typeof nodeA]\n\t\tconst valueB = nodeB[key as keyof typeof nodeB]\n\n\t\tif (isFunction(valueA) || isFunction(valueB)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isEqual(valueA, valueB)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif (isUndefined(valueB)) {\n\t\t\tconst deleted = nodeOverrides._deleted ?? []\n\t\t\tnodeOverrides._deleted = deleted\n\t\t\tdeleted.push(key)\n\t\t} else {\n\t\t\tnodeOverrides[key] = valueB\n\t\t}\n\t}\n\n\tconst anyOverrides = Object.keys(nodeOverrides).length > 0\n\tif (anyOverrides) {\n\t\toverrides[nodeA.id] = nodeOverrides\n\t}\n}\n\nexport function generateReplicaOverrides(\n\tprimary: CanvasNode,\n\treplica: CanvasNode,\n\toptions?: { unsafe?: boolean },\n): ReplicaOverrides | null {\n\tif (!options?.unsafe && !equalHierarchies(primary, replica)) return null\n\n\tconst result: ReplicaOverrides = {}\n\tcollectOverrides(result, primary, replica, true)\n\treturn result\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport {\n\tassert,\n\ttype LocalModuleExportIdentifierString,\n\tisLocalModuleIdentifier,\n\tisModuleExportIdentifier,\n} from \"@framerjs/shared\"\nimport { generateReplicaOverrides } from \"document/components/utils/generateReplicaOverrides.ts\"\nimport type {\n\tAnySmartComponentNode,\n\tCanvasNode,\n\tCanvasTree,\n\tCodeComponentNode,\n\tNodeID,\n\tSmartComponentNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode } from \"document/models/CanvasTree/index.ts\"\nimport { CanvasChildList } from \"document/models/CanvasTree/nodes/ChildList.ts\"\nimport { generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport {\n\tisCodeComponentNode,\n\tisFrameNode,\n\tisKitPageNode,\n\tisLayoutTemplateNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport {\n\temptyValueMap,\n\ttype CombinedVariableProviderValueMap,\n} from \"document/models/CanvasTree/traits/VariableProvider.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\nimport type { ReplicaOverrides } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { EagerVariableProviderMap } from \"document/models/CanvasTree/traits/utils/EagerVariableProviderMap.ts\"\nimport type { VekterConstraintValues } from \"document/models/CanvasTree/traits/utils/VekterConstraintValues.ts\"\nimport {\n\tgetNodeUpdateResolvingDynamicValues,\n\tgetVariableToDefaultValueMap,\n} from \"document/models/CanvasTree/utils/getNodeUpdateResolvingDynamicValues.ts\"\nimport type { EnumControlProp } from \"document/models/controlProps/ControlProp.ts\"\nimport { isRawControlProp } from \"document/models/controlProps/RawControlProp.ts\"\nimport { prefixControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { getControlPropValues } from \"document/models/controlProps/getControlPropValues.ts\"\nimport { getCompatibleNodeProperties } from \"document/utils/getCompatibleNodeProperties.ts\"\nimport { ControlType, DimensionType } from \"library/index.ts\"\nimport { isArray, isObject, isString } from \"utils/typeChecks.ts\"\nimport { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\n\n/**\n * When a Smart Component is a Kit Section, flatten the instances to layers so that it can be\n * inserted and customized as if it were a section. After the content has been streamed in, we will\n * convert it back into the original Smart Component instances.\n */\nexport function createDetachedInstanceNodeAndOverrides(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tsection: CodeComponentNode,\n\tsmartComponent: Loaded<SmartComponentNode>,\n) {\n\tconst scope = tree.getScopeNodeFor(section)\n\tif (!isKitPageNode(scope) && !isLayoutTemplateNode(scope)) return\n\n\tconst instances: CodeComponentNode[] = []\n\tconst ancestorBreakpointSize: Record<NodeID, number> = {}\n\tfor (const replica of scope.getReplicaVariants()) {\n\t\tconst instance = tree.get(generateReplicaChildId(replica.id, section.id))\n\t\tif (!isCodeComponentNode(instance)) continue\n\n\t\tinstances.push(instance)\n\t\t// Record the size of the breakpoint that contains the instance, allowing us to match the\n\t\t// width when pasting.\n\t\tancestorBreakpointSize[instance.id] = replica.width\n\t}\n\n\tconst { node, overrides } = createDetachedLayersFromInstances(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tsection,\n\t\tinstances,\n\t\tsmartComponent,\n\t)\n\n\treturn { node, overrides, ancestorBreakpointSize }\n}\n\nfunction getVariant(\n\tvariant: unknown,\n\tvariants: Record<NodeID, CanvasNode>,\n\tsourceSmartComponent: Loaded<SmartComponentNode>,\n): CanvasNode {\n\tif (isString(variant)) {\n\t\tconst variantNode = variants[variant]\n\t\tif (variantNode) return variantNode\n\t}\n\n\treturn sourceSmartComponent.getPrimaryVariant()\n}\n\nfunction getVariants(sourceSmartComponent: Loaded<SmartComponentNode>): Record<NodeID, CanvasNode> {\n\tconst variants: Record<NodeID, CanvasNode> = {}\n\tfor (const node of sourceSmartComponent.getTopLevelVariants()) variants[node.id] = node\n\treturn variants\n}\n\nfunction replaceVariableReferencesWithValues(\n\ttree: CanvasTree,\n\tsource: CanvasNode,\n\tsmartComponent: Loaded<SmartComponentNode>,\n\tvariableValues: CombinedVariableProviderValueMap,\n) {\n\tfor (const node of source.walk()) {\n\t\tconst update = getNodeUpdateResolvingDynamicValues(tree, smartComponent.id, node, variableValues)\n\t\tif (!update) continue\n\t\tnode.set(update)\n\t}\n}\n\nconst cloneOverrides = { mutable: true, update: 0, originalid: null, duplicatedFrom: null }\nfunction cloneAsOriginalNode<T extends CanvasNode>(node: T, props: { [key: string]: any }): T {\n\tconst clone = new (node.constructor as any)() as T\n\tclone.assign(node, cloneOverrides, { cache: clone.cache, id: node.originalid ?? node.id }, props)\n\tconst children = node.children\n\tif (children) clone.children = new CanvasChildList(children.map(c => cloneAsOriginalNode(c, { parentid: clone.id })))\n\treturn clone\n}\n\n/**\n * Simulate detaching the instances in the WebPageNode to layers. Unlike regular detaching, the\n * variant of the instance in the primary breakpoint is treated as if it were the primary variant,\n * and new replica overrides are generated from that new base.\n */\nfunction createDetachedLayersFromInstances(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tinstance: CodeComponentNode,\n\treplicaInstances: CodeComponentNode[],\n\tsourceSmartComponent: Loaded<SmartComponentNode>,\n): { node: FrameNode; overrides: Record<NodeID, ReplicaOverrides | null> } {\n\tconst component = componentLoader.reactComponentForIdentifier(instance.codeComponentIdentifier)\n\tassert(component, \"Component must be defined\", instance.codeComponentIdentifier)\n\n\tconst defaultTargetNode = new FrameNode()\n\tconst props = getControlPropValues(component.properties, instance.getControlProps(component.properties))\n\tconst variants: Record<NodeID, CanvasNode> = getVariants(sourceSmartComponent)\n\tconst variant = getVariant(props.variant, variants, sourceSmartComponent)\n\tassert(isFrameNode(variant), \"Variant must be a frame node\")\n\n\tconst newPrimary = cloneAsOriginalNode(variant, {\n\t\t...getCompatibleNodeProperties(tree, componentLoader, instance, defaultTargetNode),\n\t\t...sizeUpdate(instance.constraintValues(), variant),\n\t\tparentid: null,\n\t\tconstraintsLocked: false,\n\t\t// Since this variant could be a primary or replica, we have to unset all flags.\n\t\treplicaInfo: undefined,\n\t\tisVariant: undefined,\n\t\tisMaster: undefined,\n\t\tvariantTransition: undefined,\n\t})\n\tassert(isFrameNode(newPrimary), \"Replacement must be a frame node\")\n\n\tconst defaultVariableValues = getVariableToDefaultValueMap(sourceSmartComponent) ?? emptyValueMap\n\n\tconst variableValues: CombinedVariableProviderValueMap = new Map([\n\t\t[sourceSmartComponent.id, new EagerVariableProviderMap([...defaultVariableValues, ...Object.entries(props)])],\n\t])\n\n\treplaceVariableReferencesWithValues(tree, newPrimary, sourceSmartComponent, variableValues)\n\n\tconst overrides: Record<NodeID, ReplicaOverrides | null> = {}\n\n\tfor (const replicaInstance of replicaInstances) {\n\t\tconst replicaProps = getControlPropValues(\n\t\t\tcomponent.properties,\n\t\t\treplicaInstance.getControlProps(component.properties),\n\t\t)\n\t\tconst replicaVariant = getVariant(replicaProps.variant, variants, sourceSmartComponent)\n\t\tassert(isFrameNode(replicaVariant), \"Replica variant must be a frame node\")\n\n\t\tconst newReplica = cloneAsOriginalNode(replicaVariant, {\n\t\t\t...getCompatibleNodeProperties(tree, componentLoader, replicaInstance, defaultTargetNode),\n\t\t\t...sizeUpdate(replicaInstance.constraintValues(), replicaVariant),\n\t\t\tparentid: null,\n\t\t\tconstraintsLocked: false,\n\t\t\t// Since this variant could be the primary or a replica, we have to unset all flags.\n\t\t\treplicaInfo: undefined,\n\t\t\tisVariant: undefined,\n\t\t\tisMaster: undefined,\n\t\t\tvariantTransition: undefined,\n\t\t})\n\t\tconst replicaVariableValues: CombinedVariableProviderValueMap = new Map([\n\t\t\t[\n\t\t\t\tsourceSmartComponent.id,\n\t\t\t\tnew EagerVariableProviderMap([...defaultVariableValues, ...Object.entries(replicaProps)]),\n\t\t\t],\n\t\t])\n\n\t\treplaceVariableReferencesWithValues(tree, newReplica, sourceSmartComponent, replicaVariableValues)\n\n\t\t// KITS @TODO - Blend nested opacity and rotation\n\n\t\toverrides[replicaInstance.id] = generateReplicaOverrides(newPrimary, newReplica, { unsafe: true })\n\t}\n\n\treturn { node: newPrimary, overrides }\n}\n\n/**\n * When we flatten an instance to layers, we want to retain the instance size unless it is auto.\n * Auto on instances reflect the size of the source layers, so then we use the source size.\n */\nfunction sizeUpdate(constraints: VekterConstraintValues, variant: FrameNode) {\n\tconst update: VekterConstraintValues = { ...constraints }\n\n\tif (constraints.widthType === DimensionType.Auto) {\n\t\tupdate.widthType = variant.widthType\n\t\tupdate.width = variant.width\n\t}\n\tif (constraints.heightType === DimensionType.Auto) {\n\t\tupdate.heightType = variant.heightType\n\t\tupdate.height = variant.height\n\t}\n\n\treturn update\n}\n\nfunction* walk(data: unknown): Iterable<object> {\n\tif (!isObject(data)) return\n\tyield data\n\tif (!isArray(data.children)) return\n\tfor (const subdata of data.children) {\n\t\tyield* walk(subdata)\n\t}\n}\n\nfunction isEnumControlPropValue(value: unknown): value is { type: ControlType.Enum; value: string } {\n\tif (!isRawControlProp(value) || value.type !== ControlType.Enum) return false\n\treturn isString(value.value)\n}\n\nfunction updateVariantControl(maybeNode: Record<string, unknown>, sourceNode: AnySmartComponentNode) {\n\tconst key = prefixControlPropKey(\"variant\")\n\tconst value = maybeNode[key]\n\n\t// KITS @TODO: The value could be a ComputedValue, which could remap to variants. We should\n\t// handle that here.\n\tif (!isEnumControlPropValue(value)) return\n\n\tconst variant = sourceNode.kitComponentSource?.sourceNodeVariants[value.value]\n\tif (!variant) return\n\n\tconst updatedValue: EnumControlProp = {\n\t\ttype: ControlType.Enum,\n\t\tvalue: variant,\n\t}\n\n\tmaybeNode[key] = updatedValue\n}\n\n/**\n * Reformat Kit Clipboard Data to use local kit sources inline before pasting. Doing this upfront\n * allows us to guarantee that multiple consumers will always use the correct local components.\n */\nexport function replaceReferencesToLocalKitSourcesInline(\n\tdata: KitClipboardData,\n\tsourceNodes: Map<LocalModuleExportIdentifierString, AnySmartComponentNode>,\n) {\n\tif (sourceNodes.size === 0) return\n\n\tconst sourcesByReferenceIds = new Map<NodeID, AnySmartComponentNode>()\n\tfor (const maybeNode of walk(data.layers.tree.root)) {\n\t\tif (!isObject(maybeNode)) continue\n\t\tif (!isString(maybeNode.__class)) continue\n\t\tif (!isString(maybeNode.id)) continue\n\n\t\tif (maybeNode.__class !== ClassDiscriminator.CodeComponentNode) continue\n\n\t\tconst identifier = maybeNode.codeComponentIdentifier\n\t\tif (\n\t\t\t!isString(identifier) ||\n\t\t\t!isLocalModuleIdentifier(identifier) ||\n\t\t\t!isModuleExportIdentifier(identifier) ||\n\t\t\t!sourceNodes.has(identifier)\n\t\t) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst sourceNode = sourceNodes.get(identifier)\n\t\tif (!sourceNode) continue\n\n\t\tsourcesByReferenceIds.set(maybeNode.id, sourceNode)\n\t\tmaybeNode.codeComponentIdentifier = sourceNode.instanceIdentifier\n\t\tupdateVariantControl(maybeNode, sourceNode)\n\t}\n\n\tfor (const key in data.layers.replicas) {\n\t\tconst replica = data.layers.replicas[key]\n\t\tif (!isObject(replica)) continue\n\n\t\tfor (const id in replica.overrides) {\n\t\t\tconst sourceNode = sourcesByReferenceIds.get(id)\n\t\t\tif (!sourceNode) continue\n\t\t\tif (!isObject(replica.overrides[id])) continue\n\n\t\t\tupdateVariantControl(replica.overrides[id], sourceNode)\n\t\t}\n\t}\n\n\tfor (const moduleIdentifier in data.layers.moduleData) {\n\t\tif (!isLocalModuleIdentifier(moduleIdentifier) || !isModuleExportIdentifier(moduleIdentifier)) continue\n\t\tif (!sourceNodes.has(moduleIdentifier)) continue\n\n\t\t// Once we've replaced the reference to the local component that we just created, we can\n\t\t// remove it from the clipboard data, otherwise on paste we will pull in the external\n\t\t// component.\n\t\tdelete data.layers.moduleData[moduleIdentifier]\n\t}\n\n\tif (!data.layers.breakpointOverrides) return\n\n\tfor (const [, overrides] of data.layers.breakpointOverrides) {\n\t\tfor (const id in overrides) {\n\t\t\tconst sourceNode = sourcesByReferenceIds.get(id)\n\t\t\tif (!sourceNode || !isObject(overrides[id])) continue\n\n\t\t\tupdateVariantControl(overrides[id], sourceNode)\n\t\t}\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, asGlobalId, assertNever, isModuleExportIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { collectImagesFromSubtree } from \"document/components/tools/utils/collectImages.ts\"\nimport { canCopyNode } from \"document/components/utils/contextActions.ts\"\nimport type {\n\tAnySmartComponentNode,\n\tCanvasNode,\n\tCanvasTree,\n\tCodeComponentNode,\n\tLayoutTemplateNode,\n\tLoadedScopeNode,\n\tNodeID,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { isCodeComponentNode, isSmartComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\nimport type { ReplicaOverrides } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isControlTypeWithColor } from \"document/models/CanvasTree/traits/utils/applyTokenOverrides.ts\"\nimport { CodeError, getNodeError } from \"document/models/CanvasTree/utils/getNodeError.ts\"\nimport type { LoadedExternalModulesStore } from \"document/stores/LoadedExternalModulesStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport {\n\tcleanupBrokenCodeOverrides,\n\tcollectAndCleanupTemplateData,\n\tgetClipboardRootTree,\n} from \"utils/clipboard/getClipboardData.ts\"\nimport { getCopiedAssets } from \"utils/clipboard/getCopiedAssets.ts\"\nimport type {\n\tBreakpointOverrides,\n\tClipboardModuleData,\n\tFramerLayersClipboardData,\n\tSerializableMap,\n} from \"utils/clipboard/helpers/types.ts\"\nimport type { CollectedCollections } from \"utils/clipboard/utils.ts\"\nimport {\n\tcollectClipboardModuleData,\n\tcollectCollections,\n\tcollectColorTokenNodes,\n\tcollectColorTokensFromValue,\n\tcollectOverridesForBreakpoints,\n\tcollectStylePresetNodes,\n} from \"utils/clipboard/utils.ts\"\nimport { vectorInfoForIdentifier } from \"utils/vectorSets.ts\"\nimport { createDetachedInstanceNodeAndOverrides } from \"../kits/clipboardData.ts\"\nimport {\n\tcollectCMSConnectedFields,\n\tcollectDetailPageCollection,\n\tcreateSectionCollectionTemplates,\n} from \"./collections.ts\"\nimport type {\n\tCMSConnectedField,\n\tControlPropField,\n\tControlPropFields,\n\tKitCollectionTemplate,\n\tVectorSetsModuleData,\n} from \"./types.ts\"\n\nexport interface KitClipboardData extends FramerLayersClipboardData {\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>\n\tdetailPageCollectionId?: NodeID\n}\n\ninterface KitItemData {\n\tclipboardData: KitClipboardData\n\tcollections?: KitCollectionTemplate[]\n\tvectorSetsModuleData?: VectorSetsModuleData\n\tcontrolPropFields?: ControlPropFields\n}\n\ninterface KitSectionClipboardContext {\n\timages: Set<string>\n\tbreakpointOverrides: Map<number, ReplicaOverrides>\n\tcollectedCollections: CollectedCollections\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>\n\tcontrolPropFields: ControlPropFields\n\tstylePresetNodes: SerializableMap\n\tcolorTokenNodes: SerializableMap\n\tdetailPageCollectionId: NodeID | undefined\n}\n\nfunction createKitSectionContext(tree: CanvasTree, scopeNode: LoadedScopeNode): KitSectionClipboardContext {\n\tconst images = new Set<string>()\n\tconst breakpointOverrides = new Map<number, ReplicaOverrides>()\n\tconst collectedCollections: CollectedCollections = new Map()\n\tconst cmsConnectedFields: Record<NodeID, CMSConnectedField[]> = {}\n\tconst controlPropFields: ControlPropFields = {}\n\tconst stylePresetNodes: SerializableMap = {}\n\tconst colorTokenNodes: SerializableMap = {}\n\tconst detailPageCollectionId = collectDetailPageCollection(tree, scopeNode, collectedCollections)\n\n\treturn {\n\t\timages,\n\t\tbreakpointOverrides,\n\t\tcollectedCollections,\n\t\tcmsConnectedFields,\n\t\tcontrolPropFields,\n\t\tstylePresetNodes,\n\t\tcolorTokenNodes,\n\t\tdetailPageCollectionId,\n\t}\n}\n\nfunction createClipboardLayers(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tmodulesStore: ModulesStore,\n\tprojectStore: ProjectStore,\n\tctx: KitSectionClipboardContext,\n\tscopeNode: LoadedScopeNode,\n\tnode: CanvasNode,\n\tisDefaultKit: boolean = false,\n): KitItemData {\n\tconst copyTree = getClipboardRootTree()\n\tif (isPinnable(node)) node.constraintsLocked = false\n\tcopyTree.insertNode(node)\n\n\tcollectImagesFromSubtree(componentLoader, node, ctx.images)\n\n\tconst { masters, replicas } = collectAndCleanupTemplateData(copyTree, true)\n\n\tconst committedCopyTree = copyTree.commit(componentLoader)\n\n\tconst { moduleData } = collectClipboardModuleData(\n\t\tmodulesStore,\n\t\ttree,\n\t\tcommittedCopyTree.root,\n\t\tscopeNode,\n\t\tctx.collectedCollections,\n\t)\n\n\tconst breakpointOverridesEntries = [...ctx.breakpointOverrides.entries()]\n\tconst colorTokensFromBreakpointOverrides = collectColorTokensFromBreakpointOverrides(tree, breakpointOverridesEntries)\n\n\tObject.assign(ctx.colorTokenNodes, colorTokensFromBreakpointOverrides)\n\n\tconst vectorSetsModuleData = collectVectorSetsModuleData(tree, modulesStore, moduleData)\n\n\treturn {\n\t\tclipboardData: {\n\t\t\tlayers: {\n\t\t\t\ttree: committedCopyTree.toJS(),\n\t\t\t\tmasters,\n\t\t\t\treplicas,\n\t\t\t\tbreakpointOverrides: breakpointOverridesEntries,\n\t\t\t\tcolorTokenNodes: ctx.colorTokenNodes,\n\t\t\t\tmoduleData,\n\t\t\t\toriginalFrames: {},\n\t\t\t\tstylePresetNodes: ctx.stylePresetNodes,\n\t\t\t},\n\t\t\tassets: getCopiedAssets(ctx.images),\n\t\t\tsourceProjectId: projectStore.projectId,\n\t\t\tcmsConnectedFields: ctx.cmsConnectedFields,\n\t\t\tdetailPageCollectionId: getDetailPageCollectionId(ctx.cmsConnectedFields, ctx.detailPageCollectionId),\n\t\t},\n\t\t// KITS @TODO - Everything else is not needed for kits, just wireframer.\n\t\tcollections: createSectionCollectionTemplates(\n\t\t\tmodulesStore,\n\t\t\tctx.collectedCollections,\n\t\t\tisDefaultKit,\n\t\t\tvectorSetsModuleData,\n\t\t),\n\t\tvectorSetsModuleData,\n\t\tcontrolPropFields: ctx.controlPropFields,\n\t}\n}\n\nexport function getKitSectionClipboardData(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\tmodulesStore: ModulesStore,\n\tprojectStore: ProjectStore,\n\tnodeId: NodeID,\n\tisDefaultKit: boolean = false,\n): KitItemData {\n\tconst selectedNode = tree.getNode(nodeId)\n\tassert(selectedNode, \"Selected node not found\")\n\tassert(canCopyNode(selectedNode), \"Selected node is not a copyable node\")\n\n\tconst scopeNode = tree.getScopeNodeFor(selectedNode)\n\tassert(scopeNode, \"Scope node not found\")\n\n\tconst ctx = createKitSectionContext(tree, scopeNode)\n\n\tconst copyOfTopLevelNode = selectedNode.cloneWithIds({ parentid: null })\n\tassert(tree.get(copyOfTopLevelNode.id), \"Node does not exist in tree\")\n\n\t// Walk the section children nodes and collect relevant data.\n\tfor (const copyOfNode of copyOfTopLevelNode.walk()) {\n\t\tcollectCollections(tree, copyOfNode, ctx.collectedCollections)\n\n\t\tcleanupBrokenCodeOverrides(tree, componentLoader, loadedExternalModulesStore, modulesStore, copyOfNode)\n\t\tcollectStylePresetNodes(tree, ctx.stylePresetNodes, copyOfNode)\n\t\tcollectOverridesForBreakpoints(tree, ctx.breakpointOverrides, copyOfNode)\n\t\t// cleanup originalid in the copy tree, later we will collect masters and replicas for\n\t\t// rebuilding replicas. Unlike getClipboardData, we don't cleanup generated replica IDs when\n\t\t// getting the clipboard data here. Because section clipboard data never originated from a\n\t\t// replica, i.e. considering that we're always copying a primary node with its replicas\n\t\t// together. Plus we don't do renames when getting kit clipboard data, so we can't actually\n\t\t// cleanup the generated IDs by renaming them to a new iID.\n\t\tcleanupOriginalId(copyOfNode)\n\n\t\tconst node = tree.get(copyOfNode.id)\n\t\tif (!node) continue\n\n\t\tcollectColorTokenNodes(tree, node, ctx.colorTokenNodes)\n\n\t\tcollectCMSConnectedFields(tree, node, ctx.cmsConnectedFields)\n\n\t\tif (!isCodeComponentNode(node)) continue\n\n\t\t// Clean up code components that have errors.\n\t\tconst nodeError = getNodeError(node, componentLoader, tree, loadedExternalModulesStore, modulesStore)\n\t\tif (nodeError && nodeError.kind === \"code\" && nodeError.codeError === CodeError.CodeComponentMissing) {\n\t\t\ttree.removeNode(node)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Collect variable fields and color tokens from code components.\n\t\tconst { fields, colorTokens } = getVariableFieldsAndColorTokens(tree, componentLoader, node)\n\t\tObject.assign(ctx.colorTokenNodes, colorTokens)\n\n\t\tif (!fields || fields.length === 0) continue\n\t\tctx.controlPropFields[node.codeComponentIdentifier] = fields\n\t}\n\n\treturn createClipboardLayers(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tmodulesStore,\n\t\tprojectStore,\n\t\tctx,\n\t\tscopeNode,\n\t\tcopyOfTopLevelNode,\n\t\tisDefaultKit,\n\t)\n}\n\nexport function getSmartComponentSectionClipboardData(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\tmodulesStore: ModulesStore,\n\tprojectStore: ProjectStore,\n\tnode: CodeComponentNode,\n\tsmartComponent: Loaded<SmartComponentNode>,\n\tscopeNode: Loaded<WebPageNode | LayoutTemplateNode>,\n): KitItemData {\n\tconst result = createDetachedInstanceNodeAndOverrides(tree, componentLoader, node, smartComponent)\n\tassert(result, \"Result must be defined\", node.id)\n\n\tconst ctx = createKitSectionContext(tree, scopeNode)\n\n\tctx.breakpointOverrides.set(scopeNode.getPrimaryVariant().width, {})\n\n\t// Walk the section children nodes and collect relevant data.\n\tfor (const copyOfNode of result.node.walk()) {\n\t\tcollectCollections(tree, copyOfNode, ctx.collectedCollections)\n\n\t\tcleanupBrokenCodeOverrides(tree, componentLoader, loadedExternalModulesStore, modulesStore, copyOfNode)\n\t\tcollectStylePresetNodes(tree, ctx.stylePresetNodes, copyOfNode)\n\t\tcollectColorTokenNodes(tree, copyOfNode, ctx.colorTokenNodes)\n\n\t\tcollectCMSConnectedFields(tree, copyOfNode, ctx.cmsConnectedFields)\n\n\t\tfor (const id in result.ancestorBreakpointSize) {\n\t\t\tconst width = result.ancestorBreakpointSize[id]\n\t\t\tconst overrides = result.overrides[id]?.[copyOfNode.id]\n\t\t\tif (!overrides || !width) continue\n\t\t\tconst existing = ctx.breakpointOverrides.get(width) ?? {}\n\t\t\texisting[copyOfNode.id] = overrides\n\t\t\tctx.breakpointOverrides.set(width, existing)\n\t\t}\n\n\t\tif (!isCodeComponentNode(copyOfNode)) continue\n\n\t\t// Collect variable fields and color tokens from code components.\n\t\tconst { fields, colorTokens } = getVariableFieldsAndColorTokens(tree, componentLoader, copyOfNode)\n\t\tObject.assign(ctx.colorTokenNodes, colorTokens)\n\n\t\tif (!fields || fields.length === 0) continue\n\t\tctx.controlPropFields[copyOfNode.codeComponentIdentifier] = fields\n\t}\n\n\treturn createClipboardLayers(tree, componentLoader, modulesStore, projectStore, ctx, scopeNode, result.node, false)\n}\n\n/**\n * Returns the detail page collection id only if the section actually uses it.\n *\n * Sections can be created on a detail page without being connected to that page's\n * collection. Those sections are generic and should remain reusable across pages.\n * Marking them as detail-specific would incorrectly filter them out when generating\n * with Wireframer for other collections. By requiring at least one CMS-connected\n * field for the detail collection, we only mark sections as detail-specific when\n * they truly depend on that collection.\n */\nexport function getDetailPageCollectionId(\n\tcmsConnectedFields: Record<NodeID, CMSConnectedField[]>,\n\tdetailPageCollectionId: NodeID | undefined,\n) {\n\treturn !!detailPageCollectionId && !!cmsConnectedFields[detailPageCollectionId] ? detailPageCollectionId : undefined\n}\n\nfunction collectColorTokensFromBreakpointOverrides(\n\ttree: CanvasTree,\n\tbreakpointOverrides: BreakpointOverrides,\n): SerializableMap | undefined {\n\tconst colorTokens: SerializableMap = {}\n\n\tfor (const [_, overrides] of breakpointOverrides) {\n\t\tfor (const key in overrides) {\n\t\t\tconst override = overrides[key]\n\t\t\tif (!override) continue\n\n\t\t\t// @TODO: Add support for box shadows and shadows for AI Kits.\n\t\t\tcollectColorTokensFromValue(tree, override.fillColor, colorTokens)\n\t\t\tcollectColorTokensFromValue(tree, override.borderColor, colorTokens)\n\t\t}\n\t}\n\n\treturn colorTokens\n}\n\nfunction collectVectorSetsModuleData(\n\ttree: CanvasTree,\n\tmodulesStore: ModulesStore,\n\tmodulesData: ClipboardModuleData | undefined,\n): VectorSetsModuleData | undefined {\n\tif (!modulesData) return\n\n\tconst vectorSetsModuleData: VectorSetsModuleData = {}\n\n\tfor (const [identifier, _moduleData] of Object.entries(modulesData)) {\n\t\tif (!isModuleExportIdentifier(identifier)) continue\n\n\t\tconst parsed = parseModuleIdentifier(identifier)\n\t\tif (!parsed) continue\n\n\t\tconst vectorInfo = vectorInfoForIdentifier(parsed, tree, modulesStore)\n\t\tif (!vectorInfo) continue\n\n\t\tconst setModuleId = vectorInfo.set.moduleId\n\t\tif (!vectorSetsModuleData[setModuleId]) {\n\t\t\tvectorSetsModuleData[setModuleId] = {}\n\t\t}\n\t\tvectorSetsModuleData[setModuleId][vectorInfo.name] = identifier\n\t}\n\treturn vectorSetsModuleData\n}\n\nfunction getVariableFieldsAndColorTokens(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n): {\n\tfields: ControlPropField[] | undefined\n\tcolorTokens: SerializableMap\n} {\n\tconst fields: ControlPropField[] | undefined = getVariableFields(componentLoader, node)\n\tconst colorTokens: SerializableMap = {}\n\n\tcollectColorTokensFromCodeComponentNode(tree, componentLoader, node, colorTokens)\n\n\treturn {\n\t\tfields,\n\t\tcolorTokens,\n\t}\n}\n\nfunction collectColorTokensFromCodeComponentNode(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n\tcolorTokens: SerializableMap,\n) {\n\tcollectColorTokensFromControlProps(tree, componentLoader, node, colorTokens)\n\tcollectColorTokensFromSmartComponentNode(tree, componentLoader, node, colorTokens)\n}\n\nfunction collectColorTokensFromControlProps(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n\tcolorTokens: SerializableMap,\n) {\n\tconst component = componentLoader.componentForIdentifier(node.codeComponentIdentifier)\n\tif (!component) return\n\n\tconst controlProps = node.getControlProps(component.properties)\n\tif (!controlProps) return\n\n\tfor (const key in controlProps) {\n\t\tconst controlProp = controlProps[key]\n\t\tif (!controlProp || !isControlTypeWithColor(controlProp)) continue\n\n\t\t// @TODO: Add support for box shadows and shadows for AI Kits.\n\t\tswitch (controlProp.type) {\n\t\t\tcase ControlType.Color:\n\t\t\tcase ControlType.Border:\n\t\t\t\tcollectColorTokensFromValue(tree, controlProp.value, colorTokens)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tassertNever(controlProp, \"Unsupported control type.\")\n\t\t}\n\t}\n}\n\nfunction collectColorTokensFromSmartComponentNode(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n\tcolorTokens: SerializableMap,\n) {\n\tconst smartComponentId = node.getLocalSmartComponentNodeId()\n\tif (!smartComponentId) return\n\n\tconst smartComponentNode = tree.get<AnySmartComponentNode>(smartComponentId)\n\tif (!isSmartComponentNode(smartComponentNode)) return\n\tif (!smartComponentNode.isLoaded()) return\n\n\tfor (const child of smartComponentNode.walk()) {\n\t\tcollectColorTokenNodes(tree, child, colorTokens)\n\n\t\tif (isCodeComponentNode(child)) {\n\t\t\tcollectColorTokensFromCodeComponentNode(tree, componentLoader, child, colorTokens)\n\t\t}\n\t}\n}\n\nfunction getVariableFields(componentLoader: ComponentLoader, node: CodeComponentNode): ControlPropField[] | undefined {\n\tconst identifier = node.codeComponentIdentifier\n\n\tconst component = componentLoader.componentForIdentifier(identifier)\n\tif (!component) return\n\n\tconst controlProps = node.getControlProps(component.properties)\n\tif (!controlProps) return\n\n\tconst controlPropFields: ControlPropField[] = []\n\tfor (const key in controlProps) {\n\t\tconst control = component.properties[key]\n\t\tif (!control || (control.type !== ControlType.String && control.type !== ControlType.VectorSetItem)) continue\n\n\t\tconst defaultTitle = control.type === ControlType.VectorSetItem ? Dictionary.Icon : Dictionary.Title\n\n\t\tconst field: ControlPropField = { key, title: control.title ?? defaultTitle }\n\n\t\tif (control.type === ControlType.VectorSetItem && control.setModuleId) {\n\t\t\tfield.iconSet = asGlobalId(control.setModuleId)\n\t\t}\n\n\t\tcontrolPropFields.push(field)\n\t}\n\n\treturn controlPropFields\n}\n\nfunction cleanupOriginalId(copyOfNode: CanvasNode) {\n\tconst originalid = copyOfNode.originalid\n\tif (!originalid) return\n\n\tcopyOfNode.originalid = null\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasTree, CodeComponentNode, FrameNode } from \"document/models/CanvasTree/index.ts\"\nimport type { CanvasNode, MaybeCanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisFrameNode,\n\tisKitPageNode,\n\tisLayoutTemplateNode,\n\tisSmartComponentNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { WithCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { isCustomizable } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { isPrimaryVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport type { LoadedExternalModulesStore } from \"document/stores/LoadedExternalModulesStore.ts\"\nimport type { LoadingStore } from \"document/stores/LoadingStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { getKitSectionId } from \"../utils/kitSection.ts\"\nimport { SectionsState } from \"./SectionsState.ts\"\nimport type { KitClipboardData } from \"./getKitSectionNodeData.ts\"\nimport { getKitSectionClipboardData } from \"./getKitSectionNodeData.ts\"\nimport type {\n\tControlPropFields,\n\tKitCollectionTemplate,\n\tKitItemSource,\n\tLocalNodeInfo,\n\tResolvedSection,\n\tResolvedSectionsWithControlPropFields,\n\tSectionOverride,\n\tSectionWithOverride,\n\tVectorSetModuleData,\n} from \"./types.ts\"\n\nconst state = new SectionsState()\n\nexport async function getSectionsWithOverrides(engine: VekterEngine) {\n\t// Make sure the tree is fully loaded before we start to get the sections.\n\tconst { loadingStore, projectStore, treeStore, loadedExternalModulesStore, modulesStore } = engine.stores\n\tif (!treeStore.getDataTree()) {\n\t\tawait engine.runWithFullyLoadedTreeAsync({ name: \"getSectionsWithOverridesList\" })\n\t}\n\n\tconst { sections } = getSectionsWithOverridesList(\n\t\tengine.componentLoader,\n\t\tloadingStore,\n\t\tprojectStore,\n\t\ttreeStore.getDataTreeOrPartialTree(),\n\t\tloadedExternalModulesStore,\n\t\tmodulesStore,\n\t)\n\treturn groupSections(sections)\n}\n\nconst sorter = new Intl.Collator(undefined, { numeric: true })\n\nexport async function loadAllSectionsWithUniqueIds(\n\tcomponentLoader: ComponentLoader,\n\tloadingStore: LoadingStore,\n\tprojectStore: ProjectStore,\n\ttreeStore: TreeStore,\n\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\tmodulesStore: ModulesStore,\n): Promise<ResolvedSectionsWithControlPropFields> {\n\tconst pendingSections: Promise<ResolvedSection>[] = []\n\n\tconst tree = treeStore.getDataTreeOrPartialTree()\n\tconst { sections, controlPropFields, vectorSetModuleData, collections } = getSectionsWithOverridesList(\n\t\tcomponentLoader,\n\t\tloadingStore,\n\t\tprojectStore,\n\t\ttree,\n\t\tloadedExternalModulesStore,\n\t\tmodulesStore,\n\t)\n\n\tfor (const section of sections) {\n\t\tif (!section.enabled) continue\n\t\tpendingSections.push(resolveSection(section))\n\t}\n\n\tconst resolvedSections = await Promise.all(pendingSections)\n\n\tconst counters: Record<string, number> = {}\n\tconst orderedSections = resolvedSections\n\t\t// Copy the list and remove all numeric suffixes.\n\t\t.map(section => ({ ...section, id: section.id.replace(/_\\d+$/u, \"\") }) as ResolvedSection)\n\t\t// Sort the list so that all sections appear in order of id.\n\t\t.sort((a, b) => sorter.compare(a.id, b.id))\n\t\t// Now add numeric suffixes to all sections.\n\t\t.map(section => {\n\t\t\t// Count number of identical ids before this one.\n\t\t\tconst count = (counters[section.id] ?? 0) + 1\n\t\t\tcounters[section.id] = count\n\t\t\treturn { ...section, id: `${section.id}_${count}` }\n\t\t})\n\n\tconst sourceProjectId = sections[0]?.source.projectId\n\n\treturn { sections: orderedSections, controlPropFields, vectorSetModuleData, collections, sourceProjectId }\n}\n\nexport function overrideSections(overrides: readonly SectionOverride[]) {\n\tstate.applyOverrides(overrides)\n}\n\n/** Groups sections by their ids. */\nfunction groupSections<T extends { id: string }>(sections: readonly T[], sort = true): Map<string, readonly T[]> {\n\tif (sort) {\n\t\tsections = sections.slice().sort((a, b) => sorter.compare(a.id, b.id))\n\t}\n\tconst map = new Map<string, T[]>()\n\tfor (const section of sections) {\n\t\tconst group = section.id.replace(/_\\d+$/u, \"\")\n\t\tconst sectionsInGroup = map.get(group) ?? []\n\t\tsectionsInGroup.push(section)\n\t\tmap.set(group, sectionsInGroup)\n\t}\n\treturn map\n}\n\nfunction getSectionsWithOverridesList(\n\tcomponentLoader: ComponentLoader,\n\tloadingStore: LoadingStore,\n\tprojectStore: ProjectStore,\n\ttree: CanvasTree,\n\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\tmodulesStore: ModulesStore,\n): {\n\tsections: readonly SectionWithOverride[]\n\tcontrolPropFields?: ControlPropFields\n\tvectorSetModuleData?: VectorSetModuleData\n\tcollections?: KitCollectionTemplate[]\n} {\n\tlet sections = state.sectionsWithOverrides\n\tconst controlPropFields = { ...state.controlPropFields }\n\tconst vectorSetModuleData = state.vectorSetModuleData ?? {}\n\tconst collectionArrays: KitCollectionTemplate[][] = []\n\tif (state.collections) collectionArrays.push(state.collections)\n\n\t// Synchronize list with local changes in project.\n\tsections = sections.map(section => {\n\t\tconst info = getLocalNodeInfo(\n\t\t\tcomponentLoader,\n\t\t\tloadingStore,\n\t\t\tprojectStore,\n\t\t\ttree,\n\t\t\tloadedExternalModulesStore,\n\t\t\tmodulesStore,\n\t\t\tsection.source,\n\t\t\ttrue,\n\t\t)\n\t\tif (!info) return section\n\t\tif (info.enabled === false) return section.enabled ? { ...section, enabled: false } : section\n\n\t\tconst mutableSection: SectionWithOverride = { ...section, data: info.clipboardData }\n\t\tif (info.id) mutableSection.id = info.id\n\t\tif (info.description) mutableSection.description = info.description\n\n\t\t// Merge the text variables from the local node info into the overall text variables.\n\t\tif (info.controlPropFields) {\n\t\t\tObject.assign(controlPropFields, info.controlPropFields)\n\t\t}\n\n\t\t// Merge the collected collections from the local node info into the overall collected collections.\n\t\tif (info.collections) {\n\t\t\tcollectionArrays.push(info.collections)\n\t\t}\n\n\t\treturn mutableSection\n\t})\n\n\t// Deduplicate all collections at the end\n\tconst collections = concatAndDeduplicateCollections(...collectionArrays)\n\n\treturn { sections, controlPropFields, vectorSetModuleData, collections }\n}\n\nfunction concatAndDeduplicateCollections(...collectionArrays: KitCollectionTemplate[][]): KitCollectionTemplate[] {\n\tconst allCollections = collectionArrays.flat()\n\n\tconst uniqueMap = new Map<string, KitCollectionTemplate>()\n\tfor (const collection of allCollections) {\n\t\tuniqueMap.set(collection.id, collection)\n\t}\n\n\treturn Array.from(uniqueMap.values())\n}\n\nasync function resolveSection(section: SectionWithOverride): Promise<ResolvedSection> {\n\tlet data: KitClipboardData\n\t// First load in the data from either override or repo.\n\tif (\"data\" in section) {\n\t\tdata = section.data\n\t} else {\n\t\tconst result = await section.load()\n\t\tdata = result.default as KitClipboardData\n\t}\n\tconst { id, description, source, hasOverride } = section\n\treturn { source, id, description, hasOverride, data }\n}\n\nexport type SectionNode = (CodeComponentNode | FrameNode) & WithCustomizations\n\nexport function isSectionNode(node: MaybeCanvasNode): node is SectionNode {\n\tif (!node || !isCustomizable(node)) return false\n\tconst tree = node.tree()\n\tif (!tree) return false\n\n\tconst parent = tree.get(node.parentid)\n\tif (!parent || !isPrimaryVariant(parent)) return false\n\n\tconst grandparent = tree.get(parent.parentid)\n\tif (!isKitPageNode(grandparent) && !isLayoutTemplateNode(grandparent)) return false\n\n\tif (!isCodeComponentNode(node) && !isFrameNode(node)) return false\n\n\treturn true\n}\n\nexport function getLocalNodeInfo(\n\tcomponentLoader: ComponentLoader,\n\tloadingStore: LoadingStore,\n\tprojectStore: ProjectStore,\n\ttree: CanvasTree,\n\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\tmodulesStore: ModulesStore,\n\tsource: KitItemSource,\n\tisDefaultKit: boolean = false,\n): LocalNodeInfo | undefined {\n\tif (!loadingStore.hasMinimalEditableData || !loadingStore.allModulesLoadedAndEvaluated) {\n\t\treturn\n\t}\n\tif (source.projectId !== projectStore.projectId) return\n\n\tconst node = tree.get(source.layerId)\n\n\t// The node could have been deleted, so consider it disabled.\n\tif (!isSectionNode(node) && !isLayoutTemplateNode(node) && !isSmartComponentNode(node)) return { enabled: false }\n\n\tconst isSection = isSectionNode(node)\n\tconst { clipboardData, collections, vectorSetsModuleData, controlPropFields } = getKitSectionClipboardData(\n\t\ttree,\n\t\tcomponentLoader,\n\t\tloadedExternalModulesStore,\n\t\tmodulesStore,\n\t\tprojectStore,\n\t\tnode.id,\n\t\tisDefaultKit,\n\t)\n\n\tconst info: LocalNodeInfo = {\n\t\tid: isSection ? getKitSectionId(node) : node.id,\n\t\tenabled: true,\n\t\tclipboardData,\n\t\tcollections,\n\t\tvectorSetsModuleData,\n\t\tcontrolPropFields,\n\t}\n\n\t// KITS @TODO: once we add the WithCustomizations trait to layout templates, we can remove this check.\n\tif (isSection) {\n\t\t// The union of CodeComponentNode and FrameNode prevents the overloads in resolveValue from\n\t\t// applying generic keys.\n\t\tconst category = (node as CanvasNode & WithCustomizations).resolveValue(\"customizationsCategory\")\n\t\tif (category) info.category = category\n\t\tif (node.customizationsDescription) info.description = node.customizationsDescription\n\t\tif (node.customizationsRules) info.rules = node.customizationsRules\n\t}\n\n\treturn info\n}\n", "import type { Asset } from \"@framerjs/assets\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { GlobalModuleId, ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert, emptyArray } from \"@framerjs/shared\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { LoadedExternalModulesStore } from \"document/stores/LoadedExternalModulesStore.ts\"\nimport type { LoadingStore } from \"document/stores/LoadingStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { shuffle } from \"utils/shuffle.ts\"\nimport * as yaml from \"yaml\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\nimport { loadAllSectionsWithUniqueIds } from \"../sections/index.ts\"\nimport type { KitCollectionTemplate, VectorSetModuleData } from \"../sections/types.ts\"\nimport { serializeKitSection } from \"../utils/kitSection.ts\"\nimport type {\n\tKitLayoutTemplateMeta,\n\tKitSectionMeta,\n\tWireframerKit,\n\tWireframerKitBreakpoint,\n\tWireframerKitColorToken,\n\tWireframerKitListItem,\n\tWireframerKitPageProperties,\n} from \"../utils/wireframerKit.ts\"\nimport { getFieldsForSection } from \"../utils/wireframerKit.ts\"\n\nexport interface DefaultKitOptions {\n\tcms?: boolean\n}\n\nconst emptyTokens: Record<string, WireframerKitColorToken> = Object.freeze({})\nconst emptyLayoutTemplates: Record<NodeID, KitLayoutTemplateMeta> = Object.freeze({})\nexport class DefaultKit implements WireframerKit {\n\tstatic id = \"wireframer\"\n\tpublic title = \"Wireframer\"\n\tpublic prompt: string | undefined = undefined\n\tpublic pageProperties: Record<NodeID, Partial<WireframerKitPageProperties>> | undefined = undefined\n\tpublic primaryBreakpoint: NodeID | undefined = undefined\n\tpublic breakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined = undefined\n\n\tstatic async load(\n\t\tcomponentLoader: ComponentLoader,\n\t\tloadingStore: LoadingStore,\n\t\tprojectStore: ProjectStore,\n\t\ttreeStore: TreeStore,\n\t\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tmodulesStore: ModulesStore,\n\t\t{ cms = true }: DefaultKitOptions,\n\t): Promise<DefaultKit> {\n\t\tconst { sections, controlPropFields, vectorSetModuleData, collections, sourceProjectId } =\n\t\t\tawait loadAllSectionsWithUniqueIds(\n\t\t\t\tcomponentLoader,\n\t\t\t\tloadingStore,\n\t\t\t\tprojectStore,\n\t\t\t\ttreeStore,\n\t\t\t\tloadedExternalModulesStore,\n\t\t\t\tmodulesStore,\n\t\t\t)\n\n\t\tassert(sourceProjectId, \"Source project id must be defined\")\n\t\tconst dictionary = new Map(sections.map(section => [section.id, section.data]))\n\n\t\treturn new DefaultKit(\n\t\t\tDefaultKit.id,\n\t\t\tsourceProjectId,\n\t\t\tshuffle(sections).reduce<Record<NodeID, KitSectionMeta>>((acc, section) => {\n\t\t\t\t// KITS @TODO - `cmsConnectedFields` needs to live on the section meta object for\n\t\t\t\t// all kits, so that kits that fetch their sections can know before fetching to\n\t\t\t\t// filter them.\n\t\t\t\tif (!cms && Object.keys(section.data.cmsConnectedFields ?? {}).length > 0) return acc\n\n\t\t\t\tacc[section.id] = {\n\t\t\t\t\tid: section.id,\n\t\t\t\t\tdescription: section.description,\n\t\t\t\t\tfields: getFieldsForSection(section.data, controlPropFields),\n\t\t\t\t\tdetailPageCollectionId: section.data.detailPageCollectionId,\n\t\t\t\t}\n\n\t\t\t\treturn acc\n\t\t\t}, {}),\n\t\t\tvectorSetModuleData ?? {},\n\t\t\tcollections ?? [],\n\t\t\tasync (id: string) => dictionary.get(id),\n\t\t)\n\t}\n\n\tconstructor(\n\t\tpublic readonly id: string,\n\t\tpublic readonly projectId: string,\n\t\tpublic readonly sections: Record<NodeID, KitSectionMeta>,\n\t\tprivate readonly vectors: VectorSetModuleData,\n\t\tpublic readonly collections: KitCollectionTemplate[],\n\t\tpublic readonly getClipboardDataById: (id: string) => Promise<KitClipboardData | undefined>,\n\t) {}\n\n\tget tokens(): Record<string, WireframerKitColorToken> {\n\t\treturn emptyTokens\n\t}\n\n\tget layoutTemplates(): Record<NodeID, KitLayoutTemplateMeta> {\n\t\treturn emptyLayoutTemplates\n\t}\n\n\tgetSections(filter?: (section: KitSectionMeta) => boolean): Omit<KitSectionMeta, \"category\">[] {\n\t\tconst out: Omit<KitSectionMeta, \"category\">[] = []\n\t\tfor (const id in this.sections) {\n\t\t\tconst section = this.sections[id]\n\t\t\tassert(section, \"Section must exist\")\n\t\t\tif (filter && !filter(section)) continue\n\n\t\t\tconst { category, ...rest } = section\n\n\t\t\tout.push(rest)\n\t\t}\n\t\treturn out\n\t}\n\n\tgetSectionByUniqueTitle(id: string): KitSectionMeta | undefined {\n\t\t// Unlike the Local or RemoteKits, the Default Kit can directly lookup the section by the id\n\t\t// returned by the LLM.\n\t\treturn this.sections[id]\n\t}\n\n\tgetUniqueTitleBySectionId(id: NodeID): string {\n\t\t// Unlike the Local or RemoteKits, the Default Kit can directly lookup the section by the id\n\t\t// returned by the LLM.\n\t\treturn id\n\t}\n\n\tgetSectionScreenshot(): string | undefined {\n\t\t// The default kit has no screenshots.\n\t\treturn\n\t}\n\n\tasync duplicateAssets(): Promise<readonly Asset[]> {\n\t\t// The default kit does not use any assets.\n\t\treturn emptyArray<Asset>()\n\t}\n\n\tgetCollectionTemplate(name: string): KitCollectionTemplate {\n\t\tconst collection = this.collections.find(collection => collection.name === name)\n\t\tassert(collection, \"Collection must be defined\")\n\t\treturn collection\n\t}\n\n\tgetCollectionTemplateById(id: NodeID): KitCollectionTemplate | undefined {\n\t\treturn this.collections.find(collection => collection.id === id)\n\t}\n\n\tgetCollectionTemplatesPrompt(): string {\n\t\tconst collectionTemplates = this.collections.map(collection => {\n\t\t\tconst normalizedVariables = collection.variables.map(variable => {\n\t\t\t\treturn { name: variable.name, type: variable.type, reference: variable.reference }\n\t\t\t})\n\n\t\t\treturn {\n\t\t\t\tname: collection.name,\n\t\t\t\tvariables: normalizedVariables,\n\t\t\t}\n\t\t})\n\n\t\treturn yaml.stringify(collectionTemplates)\n\t}\n\n\tgetSectionsPrompt(tree: CanvasTree, filter?: (section: KitSectionMeta) => boolean): string {\n\t\tconst kitSections = this.getSections(filter).map(section => serializeKitSection(tree, this.collections, section))\n\n\t\treturn yaml.stringify(kitSections)\n\t}\n\n\tasync lookupVectorByName(_: GlobalModuleId, name: string): Promise<ModuleExportIdentifierString | undefined> {\n\t\t// The default kit only supports one vector set (vectorSetModuleData).\n\t\treturn this.vectors[name]\n\t}\n\n\tasync createIconSetsForPrompt(): Promise<string | undefined> {\n\t\t// The default kit only supports one vector set (vectorSetModuleData).\n\t\treturn yaml.stringify({ icons: { icons: Object.keys(this.vectors) } })\n\t}\n\n\tgetBreakpointIdByWidth(_width: number, _layoutId: NodeID | undefined): NodeID | undefined {\n\t\t// Default kit never has page properties, so this is basically unused. KITS @TODO: once we\n\t\t// turn the default kit into a real kit, remove this method and use the one from the\n\t\t// KitAliasManager.\n\t\treturn undefined\n\t}\n\n\tgetLayoutPatternsPrompt(): string {\n\t\treturn \"There are no layout patterns available.\"\n\t}\n}\n\nexport function isDefaultKit(kit: WireframerKit | WireframerKitListItem) {\n\treturn kit.id === DefaultKit.id\n}\n", "import { ElectronThemeProvider, channelToParentFrame } from \"@framerjs/framer-services\"\nimport { isElectron } from \"@framerjs/shared\"\nimport { setLocalStorageAndUpdateListeners } from \"web/lib/useLocalStorage.ts\"\n\n// Used to programmatically set the dark mode without using the useDarkMode hook.\nconst electronThemeProvider = ElectronThemeProvider.on(channelToParentFrame).expect()\nexport function setDarkModeWithoutDarkModeProvider(isEnabled: boolean) {\n\tif (isElectron()) {\n\t\tvoid electronThemeProvider.setDarkMode({\n\t\t\tisEnabled,\n\t\t})\n\n\t\tvoid electronThemeProvider.setOverrideSystem({\n\t\t\tshouldOverride: true,\n\t\t})\n\n\t\treturn\n\t}\n\n\t// Browser\n\tsetLocalStorageAndUpdateListeners(\"dark-mode\", isEnabled)\n\tsetLocalStorageAndUpdateListeners(\"dark-mode-override-system\", true)\n}\n", "import { isDefaultKit } from \"app/ai/kits/DefaultKit.ts\"\nimport { PageMode } from \"app/ai/orchestrator/dsl.ts\"\nimport type { KitClipboardData } from \"app/ai/sections/getKitSectionNodeData.ts\"\nimport { getKitSectionIdFromGeneratedSection } from \"app/ai/utils/kitSection.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { canvasNodeFromValue } from \"document/models/CanvasTree/nodes/canvasNodeFromValue.ts\"\nimport { isColorStyleTokenNode, isFrameNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isCustomizable } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { applyTokenOverrides } from \"document/models/CanvasTree/traits/utils/applyTokenOverrides.ts\"\nimport { tokenToCSSCustomProperty } from \"document/models/CanvasTree/utils/tokens.ts\"\nimport type { CSSVariableName } from \"library/index.ts\"\nimport { isCSSVariableName } from \"library/index.ts\"\nimport { setDarkModeWithoutDarkModeProvider } from \"utils/updateDarkModeWithoutDarkModeProvider.ts\"\n\nconst defaultWireframerDarkModeColor = \"rgb(0, 0, 0)\"\nconst defaultWireframerLightModeColor = \"rgb(255, 255, 255)\"\n\nexport function getWireframerPageColor(mode: PageMode) {\n\treturn mode === PageMode.Dark ? defaultWireframerDarkModeColor : defaultWireframerLightModeColor\n}\n\n/**\n * Applies color scheme to a page and its sections.\n */\nexport async function applyColorScheme(\n\tengine: VekterEngine,\n\tscreenId: NodeID,\n\tkit: WireframerKit,\n\tmode: PageMode,\n): Promise<void> {\n\tconst screen = engine.tree.get(screenId)\n\tif (!screen || !isFrameNode(screen)) return\n\n\t// If the create action request specifies a theme, and we're using a non-base kit, update the\n\t// app theme, so everything generated would be previewed in the correct theme. For example, it\n\t// avoids us generate a light themed page (with a white background) in dark mode, where all\n\t// sections tokens would be showing the dark colors.\n\tif (!isDefaultKit(kit)) {\n\t\tsetDarkModeWithoutDarkModeProvider(mode === PageMode.Dark)\n\t\treturn\n\t}\n\n\t// Collect a list of updates to apply after fetching the kit sections required to determine the\n\t// overrides.\n\tconst fns: VoidFunction[] = []\n\tfor (const node of screen.children) {\n\t\tif (!isCustomizable(node)) continue\n\n\t\tconst sectionId = getKitSectionIdFromGeneratedSection(node)\n\t\tif (!sectionId) continue\n\n\t\tconst section = await kit.getClipboardDataById(sectionId)\n\t\tif (!section) continue\n\n\t\tfns.push(() => {\n\t\t\tconst tokenOverrides = buildTokenOverrides(section, mode)\n\t\t\tapplyTokenOverrides(engine, node.id, tokenOverrides)\n\t\t})\n\t}\n\n\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\tscreen.set({ fillColor: getWireframerPageColor(mode) })\n\n\t\t// If it's the base kit, we still need to apply token overrides.\n\t\tengine.stores.aiGenerationStore.setSectionBeingGenerated(screen.id)\n\t\tfns.forEach(fn => fn())\n\t})\n}\n\n/**\n * Builds token overrides for a section based on dark mode setting.\n */\nexport function buildTokenOverrides(data: KitClipboardData, mode: PageMode) {\n\tconst colorTokenNodes = data.layers.colorTokenNodes ?? {}\n\n\tconst isDark = mode === PageMode.Dark\n\n\tconst tokenOverrides: Record<CSSVariableName, string> = {}\n\tfor (const colorTokenId in colorTokenNodes) {\n\t\tconst rawColorToken = colorTokenNodes[colorTokenId]\n\t\tconst colorToken = canvasNodeFromValue(rawColorToken)\n\t\tif (isColorStyleTokenNode(colorToken)) {\n\t\t\tconst newColor = isDark && colorToken.dark ? colorToken.dark : colorToken.light\n\t\t\tconst cssVariableName = tokenToCSSCustomProperty({ id: colorTokenId })\n\t\t\tif (isCSSVariableName(cssVariableName)) {\n\t\t\t\ttokenOverrides[cssVariableName] = newColor\n\t\t\t}\n\t\t}\n\t}\n\treturn tokenOverrides\n}\n", "import { emptyArray, getLogger } from \"@framerjs/shared\"\nimport { AsyncQueue } from \"app/ai/AsyncQueue.ts\"\nimport { DefaultKit, isDefaultKit } from \"app/ai/kits/DefaultKit.ts\"\nimport { PageMode } from \"app/ai/orchestrator/dsl.ts\"\nimport type { KitClipboardData } from \"app/ai/sections/getKitSectionNodeData.ts\"\nimport { getKitSectionIdFromGeneratedSection } from \"app/ai/utils/kitSection.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { RenamedIds } from \"document/components/tools/utils/updateNodeConnections.ts\"\nimport type { CanvasNode, CodeComponentNode, CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode } from \"document/models/CanvasTree/index.ts\"\nimport { isCodeComponentNode, isFrameNode, isStackComponent } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { withOptionalFill } from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport type { WithOpacity } from \"document/models/CanvasTree/traits/WithOpacity.ts\"\nimport { ContentContainer } from \"document/models/CanvasTree/traits/utils/ContentContainer.ts\"\nimport { applyTokenOverrides } from \"document/models/CanvasTree/traits/utils/applyTokenOverrides.ts\"\nimport { DimensionType, Point } from \"library/index.ts\"\nimport { framerLayersClipboardHandler } from \"utils/clipboard/helpers/layers.ts\"\nimport { isLightOrDarkColor } from \"utils/isLightOrDarkColor.ts\"\nimport { isObject, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport {\n\ttype AIStructuredOutput,\n\ttype CollectionBinding,\n\tisValidCollectionBindings,\n\tisValidSectionAction,\n} from \"../schema.ts\"\nimport { applyContentToNodes } from \"./applyContentToNodes.ts\"\nimport { createConnectedFieldsToExistingCollectionsMap } from \"./collections.ts\"\nimport { buildTokenOverrides } from \"./colorScheme.ts\"\n\nconst log = getLogger(\"ai:generateWebPage:sectionOperations\")\n\n/**\n * Creates handlers for sections as partial chunks are received from the LLM.\n * Once we get an id we can immediately create a node for the section and we can\n * update later when we get the rest of the data.\n *\n * @param createSection - Creates a node for a section.\n * @param updateSection - Updates a node for a section.\n * @param removeSection - Removes a section node.\n */\nexport function createOnSectionHandlers(\n\tkit: WireframerKit,\n\tcreateSection: (\n\t\tsectionId: string,\n\t\tcontentContainer: ContentContainer,\n\t\tcollectionBindings: CollectionBinding[],\n\t\tposition: number,\n\t) => Promise<NodeID | undefined>,\n\tupdateSection: (\n\t\tid: string,\n\t\tnodeId: NodeID,\n\t\tcontentContainer: ContentContainer,\n\t\tcollectionBindings: CollectionBinding[],\n\t\tposition?: number,\n\t) => Promise<NodeID | undefined>,\n\tremoveSection: (nodeId: NodeID) => Promise<NodeID | undefined>,\n\tfinalizeSection: (\n\t\tsectionId: string,\n\t\tnodeId: NodeID,\n\t\tcontentContainer: ContentContainer,\n\t) => Promise<NodeID | undefined>,\n) {\n\t// As we get the partial data from the LLM, we need to keep track of the\n\t// sections that are still incomplete.\n\tconst infoForContent = new Map<\n\t\tContentContainer,\n\t\t{ nodeIdPromise: Promise<NodeID | undefined>; isFinal: boolean; queue: AsyncQueue }\n\t>()\n\n\t// Track the section order from the LLM response\n\tconst sectionOrder: [NodeID, NodeID][] = []\n\t// Ensure we await all finalization promises before returning the section order.\n\tconst finalizationPromises: Promise<void>[] = []\n\n\tconst onSections = (contentContainers: ContentContainer[]) => {\n\t\tlet previousContainer: ContentContainer | undefined\n\n\t\t// First pass: process all sections to handle their actions\n\t\tfor (const contentContainer of contentContainers) {\n\t\t\tconst previousInfo = previousContainer ? infoForContent.get(previousContainer) : undefined\n\t\t\tpreviousContainer = contentContainer\n\n\t\t\t// Check if this section is already finalized\n\t\t\tif (infoForContent.get(contentContainer)?.isFinal) continue\n\n\t\t\t// Skip incomplete sections that don't have an ID yet\n\t\t\tif (contentContainer.isIncomplete(\"_id\")) continue\n\t\t\tif (contentContainer.isIncomplete(\"_layerId\")) continue\n\t\t\tif (contentContainer.isIncomplete(\"action\")) continue\n\t\t\tif (contentContainer.isIncomplete(\"collectionBindings\")) continue\n\n\t\t\t// Get the action and existing layer ID if available\n\t\t\tconst action = contentContainer.get(\"action\")\n\t\t\tconst layerId = contentContainer.get(\"_layerId\")\n\t\t\tconst id = contentContainer.get(\"_id\")\n\t\t\t// We need to get the collection bindings to know which collections to connect to the section.\n\t\t\tconst collectionBindings = contentContainer.get(\"collectionBindings\")\n\n\t\t\tif (!isString(id)) continue\n\t\t\tif (!isString(action) || !isValidSectionAction(action)) continue\n\t\t\tif (!isString(layerId)) continue\n\t\t\tif (!isValidCollectionBindings(collectionBindings)) continue\n\n\t\t\tlog.trace(\n\t\t\t\t\"Processing section with id\",\n\t\t\t\tid,\n\t\t\t\t\"action\",\n\t\t\t\taction,\n\t\t\t\t\"layerId\",\n\t\t\t\tlayerId,\n\t\t\t\t\"cmsCollectionName\",\n\t\t\t\tcollectionBindings,\n\t\t\t)\n\n\t\t\tconst existingInfo = infoForContent.get(contentContainer)\n\t\t\tif (existingInfo) {\n\t\t\t\tconst task = async () => {\n\t\t\t\t\t// We capture isFinal from content to set it on info\n\t\t\t\t\t// at the end of the function\n\t\t\t\t\tconst isFinal = contentContainer.isFinal\n\n\t\t\t\t\tconst nodeId = await existingInfo.nodeIdPromise\n\t\t\t\t\tif (!nodeId) return\n\n\t\t\t\t\tif (action === \"update\" || action === \"add\") {\n\t\t\t\t\t\tawait updateSection(id, nodeId, contentContainer, collectionBindings)\n\t\t\t\t\t}\n\n\t\t\t\t\tinfoForContent.set(contentContainer, { ...existingInfo, isFinal })\n\t\t\t\t\tif (!isFinal) return\n\n\t\t\t\t\tfinalizationPromises.push(\n\t\t\t\t\t\tfinalizeSection(id, nodeId, contentContainer).then(instanceId => {\n\t\t\t\t\t\t\tif (!instanceId) return\n\n\t\t\t\t\t\t\tconst section = kit.getSectionByUniqueTitle(id)\n\t\t\t\t\t\t\tif (!section) return\n\n\t\t\t\t\t\t\t// Replace the section order with the new instance id.\n\t\t\t\t\t\t\tconst index = sectionOrder.findIndex(([nid]) => nid === nodeId)\n\t\t\t\t\t\t\tif (index === -1) return\n\t\t\t\t\t\t\tsectionOrder.splice(index, 1, [instanceId, section.id])\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\n\t\t\t\texistingInfo.queue?.enqueue(task)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst updateOrderTask = (newId: NodeID, sectionId: string) => {\n\t\t\t\tif (sectionOrder.some(([nid]) => nid === newId)) return\n\t\t\t\tconst section = kit.getSectionByUniqueTitle(sectionId)\n\t\t\t\tif (!section) return\n\t\t\t\tlog.trace(\"Update sections order\", sectionOrder)\n\t\t\t\tsectionOrder.push([newId, section.id])\n\t\t\t}\n\n\t\t\t// Handle the different actions\n\t\t\tswitch (action) {\n\t\t\t\tcase \"add\":\n\t\t\t\tcase \"update\": {\n\t\t\t\t\t// Create a new section\n\t\t\t\t\tlet task: () => Promise<NodeID | undefined>\n\t\t\t\t\tif (action === \"add\") {\n\t\t\t\t\t\t// Make sure we have completely run the creation of a node before starting the creation of the next\n\t\t\t\t\t\t// node so the order in the UI stack is preserved and correct.\n\t\t\t\t\t\ttask = () => createSection(id, contentContainer, collectionBindings, sectionOrder.length)\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttask = () => updateSection(id, layerId, contentContainer, collectionBindings, sectionOrder.length)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst taskAndUpdateOrder = async () => {\n\t\t\t\t\t\tconst newId = await task()\n\t\t\t\t\t\tif (!newId) return\n\t\t\t\t\t\tupdateOrderTask(newId, id)\n\t\t\t\t\t\treturn newId\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nodeIdPromise = previousInfo\n\t\t\t\t\t\t? previousInfo.nodeIdPromise.then(taskAndUpdateOrder)\n\t\t\t\t\t\t: taskAndUpdateOrder()\n\n\t\t\t\t\tconst newInfo = {\n\t\t\t\t\t\tnodeIdPromise,\n\t\t\t\t\t\tisFinal: false,\n\t\t\t\t\t\tqueue: new AsyncQueue(),\n\t\t\t\t\t}\n\n\t\t\t\t\tinfoForContent.set(contentContainer, newInfo)\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase \"none\": {\n\t\t\t\t\tconst nodeIdPromise = previousInfo\n\t\t\t\t\t\t? previousInfo.nodeIdPromise.then(() => {\n\t\t\t\t\t\t\t\tupdateOrderTask(layerId, id)\n\t\t\t\t\t\t\t\treturn layerId\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: Promise.resolve().then(() => {\n\t\t\t\t\t\t\t\tupdateOrderTask(layerId, id)\n\t\t\t\t\t\t\t\treturn layerId\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\tconst newInfo = { nodeIdPromise, isFinal: false, queue: new AsyncQueue() }\n\n\t\t\t\t\tinfoForContent.set(contentContainer, newInfo)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase \"remove\": {\n\t\t\t\t\tconst removeSectionTask = () => removeSection(layerId)\n\n\t\t\t\t\tconst nodeIdPromise = previousInfo ? previousInfo.nodeIdPromise.then(removeSectionTask) : removeSectionTask()\n\n\t\t\t\t\tconst newInfo = { nodeIdPromise, isFinal: false, queue: new AsyncQueue() }\n\n\t\t\t\t\tinfoForContent.set(contentContainer, newInfo)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tlog.warn(`No operation for ${action}`)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst allDone: () => Promise<Map<NodeID, NodeID>> = async () => {\n\t\t// First, wait for all updates to complete\n\t\tconst promises: Promise<void>[] = []\n\t\tfor (const info of infoForContent.values()) {\n\t\t\tpromises.push(info.queue.done())\n\t\t}\n\n\t\tawait Promise.allSettled([...promises, ...finalizationPromises])\n\n\t\tlog.trace(\"All done generating page\", sectionOrder)\n\n\t\treturn new Map(sectionOrder)\n\t}\n\n\treturn { onSections, allDone }\n}\n\n/**\n * Creates a node for a kit section.\n */\nexport async function createNodeForSection(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tparentId: string,\n\t{ data, id }: { data: KitClipboardData; id: string },\n\tcontentContainer: ContentContainer,\n\tposition: number,\n\tcollectionNodes: CollectionNode[],\n\tmode?: PageMode,\n\tonCreateNode?: () => void,\n\tgetCodeComponentNodeUpdate?: (node: CodeComponentNode) => Partial<CodeComponentNode> | undefined,\n): Promise<NodeID | undefined> {\n\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\tlet opacity: WithOpacity[\"opacity\"] = 1\n\n\tconst renamedIds = createConnectedFieldsToExistingCollectionsMap({\n\t\tengine,\n\t\tparentId,\n\t\tcollectionNodes,\n\t\tcmsConnectedFields: data.cmsConnectedFields,\n\t})\n\n\tconst colorTokenNodes = kit.id !== DefaultKit.id ? data.layers.colorTokenNodes : {}\n\n\ttry {\n\t\tconst success = await framerLayersClipboardHandler({\n\t\t\tengine,\n\t\t\tlayersData: {\n\t\t\t\t...data,\n\t\t\t\tlayers: {\n\t\t\t\t\t...data.layers,\n\t\t\t\t\tcolorTokenNodes,\n\t\t\t\t\trenamedIds: Object.fromEntries(renamedIds),\n\t\t\t\t},\n\t\t\t},\n\t\t\tposition: Point(0, 0),\n\t\t\tinsertTarget: { parentId: parentId },\n\t\t\tshouldDisplayImportAssetsToast: false,\n\t\t\tshouldDetachTextStyles: false,\n\t\t\tshouldPasteTextStyles: true,\n\t\t\treusePresetWithSameId: true,\n\t\t\tonInsertNode: (insertedNode: CanvasNode) => {\n\t\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\t\t\t\tif (insertedNode.parentid !== parentId) return\n\n\t\t\t\tconst parent = engine.tree.get(parentId)\n\t\t\t\tif (!isStackComponent(parent)) {\n\t\t\t\t\tlog.warn(\"Parent\", parent?.id, \"was not a stack component\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst latestInsertedNode = engine.tree.current(insertedNode)\n\t\t\t\tif (!isCodeComponentNode(latestInsertedNode) && !isFrameNode(latestInsertedNode)) {\n\t\t\t\t\tlog.warn(\"Inserted node\", latestInsertedNode?.id, \"was not a code component or frame node\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tonCreateNode?.()\n\n\t\t\t\t// Record the initial opacity so that we can restore it after we've finished generating.\n\t\t\t\topacity = latestInsertedNode.opacity\n\n\t\t\t\tengine.stores.aiGenerationStore.setSectionBeingGenerated(latestInsertedNode.id)\n\n\t\t\t\tengine.scheduler.processWhenReady(() => {\n\t\t\t\t\t// Hide the node while it's being styled and set kit source data so we can trace\n\t\t\t\t\t// the generated section back to the kit section.\n\t\t\t\t\tlatestInsertedNode.set({ opacity: 0, kitSectionSource: { kit: kit.id, section: id } })\n\n\t\t\t\t\tif (isCodeComponentNode(latestInsertedNode)) {\n\t\t\t\t\t\tconst update = getCodeComponentNodeUpdate?.(latestInsertedNode)\n\t\t\t\t\t\tif (update) latestInsertedNode.set(update)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Move the node to the correct position.\n\t\t\t\t\tengine.moveNode(latestInsertedNode.id, parentId, position)\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\n\t\tif (!success) throw Error(\"inserting clipboard data was unsuccessful\")\n\t} catch (error) {\n\t\tlog.error(\"Failed to generate\", id, \"section:\", error)\n\t\t// Insert an empty frame so that code can continue.\n\t\tengine.scheduler.processWhenReady(() => {\n\t\t\tif (!engine.tree.has(parentId)) return\n\n\t\t\tconst frameNode = new FrameNode({\n\t\t\t\twidth: 1,\n\t\t\t\twidthType: DimensionType.FractionOfFreeSpace,\n\t\t\t\theight: 200,\n\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t})\n\n\t\t\tengine.tree.insertNode(frameNode, parentId, position)\n\t\t})\n\t}\n\n\tconst parent = engine.tree.get(parentId)\n\tif (!parent) return\n\n\tconst insertedNode = parent.children?.at(position)\n\tif (!isCodeComponentNode(insertedNode) && !isFrameNode(insertedNode)) return\n\n\tawait new Promise(resolve => engine.scheduler.runBeforeNextFrame(resolve))\n\n\t// Apply current theme token overrides to the node.\n\t// Reuse the background color of the parent to determine the theme if none set.\n\tconst pageMode = mode ?? getScreenMode(parent)\n\tif (pageMode && isDefaultKit(kit)) {\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\tconst tokenOverrides = buildTokenOverrides(data, pageMode)\n\t\t\tapplyTokenOverrides(engine, insertedNode.id, tokenOverrides)\n\t\t})\n\t}\n\n\t// Apply the content to the node.\n\tawait applyContentToNodes(engine, insertedNode.id, contentContainer, kit)\n\n\t// Finally restore the initial/designed opacity.\n\tawait engine.scheduler.processWhenReadyAsync(() => engine.tree.current(insertedNode)?.set({ opacity }))\n\n\treturn insertedNode.id\n}\n\nexport function getScreenMode(screen: CanvasNode): PageMode | undefined {\n\tif (!withOptionalFill(screen)) return undefined\n\tif (!screen.fillEnabled || screen.fillType !== \"color\") return undefined\n\tif (!screen.fillColor || isDynamicValue(screen.fillColor)) return undefined\n\n\tconst colorType = isLightOrDarkColor(screen.fillColor)\n\tif (!colorType) return undefined\n\treturn colorType === \"dark\" ? PageMode.Dark : PageMode.Light\n}\n/**\n * Updates a node previously added from a kit section.\n */\nexport async function updateNodeForSection(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tparentId: string,\n\tsectionId: string,\n\tnodeId: string,\n\t{ data, id }: { data: KitClipboardData; id: string },\n\tcontentContainer: ContentContainer,\n\tcollectionNodes: CollectionNode[],\n\tmode?: PageMode,\n\tposition?: number,\n): Promise<NodeID | undefined> {\n\t// We are updating an in-progress section.\n\tconst latestParent = engine.tree.get(parentId)\n\tif (!latestParent) return\n\n\tconst latestNode = engine.tree.get(nodeId)\n\tif (!latestNode) return\n\n\tif (!isCodeComponentNode(latestNode) && !isFrameNode(latestNode)) return\n\n\tconst latestNodeSectionId = getKitSectionIdFromGeneratedSection(latestNode)\n\tif (!latestNodeSectionId) return\n\n\tengine.stores.aiGenerationStore.setSectionBeingGenerated(nodeId)\n\n\t// If the section ID has changed, we need to replace this node with a new one for the new section.\n\tif (!isUndefined(position) && sectionId !== latestNodeSectionId) {\n\t\treturn createNodeForSection(\n\t\t\tengine,\n\t\t\tkit,\n\t\t\tparentId,\n\t\t\t{ data, id },\n\t\t\tcontentContainer,\n\t\t\t// When creating a new node for the update, try to keep the same theme as the current page.\n\t\t\t// We check the background color of the screen as a shortcut, since applyColorScheme always\n\t\t\t// updates the screen background first.\n\t\t\tposition,\n\t\t\tcollectionNodes,\n\t\t\tmode,\n\t\t\t() => {\n\t\t\t\tengine.deleteNode(nodeId)\n\t\t\t},\n\t\t)\n\t}\n\n\t// If the position of the section has changed, we need to move the node to the new position.\n\tconst latestNodePosition = latestParent.children?.findIndex(child => child.id === nodeId)\n\tif (!isUndefined(position) && position !== latestNodePosition) {\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\tengine.moveNode(nodeId, parentId, position)\n\t\t})\n\t}\n\n\tawait applyContentToNodes(engine, latestNode.id, contentContainer, kit)\n\n\treturn latestNode.id\n}\n\nexport async function createNodeForScope(\n\tengine: VekterEngine,\n\tdata: KitClipboardData,\n\trenamedIds: RenamedIds,\n\tcloneWithScopeIds: boolean,\n): Promise<readonly NodeID[]> {\n\tif (getIsViewOnly(engine, \"canDesign\")) return emptyArray<NodeID>()\n\n\tconst insertedIds: NodeID[] = []\n\tawait framerLayersClipboardHandler({\n\t\tengine,\n\t\tlayersData: data,\n\t\tinitialRenamedIds: renamedIds,\n\t\tposition: Point(0, 0),\n\t\tshouldDisplayImportAssetsToast: false,\n\t\tshouldDetachTextStyles: false,\n\t\tshouldPasteTextStyles: true,\n\t\treusePresetWithSameId: true,\n\t\tcloneWithScopeIds,\n\t\tonInsertNode: node => insertedIds.push(node.id),\n\t})\n\n\treturn insertedIds\n}\n\nexport async function applyCustomizationsToLayoutTemplate(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tsections: AIStructuredOutput[\"sections\"],\n\trenamedIds: RenamedIds,\n) {\n\tconst contentContainers = createContentContainersForCustomizedSections(sections)\n\n\tfor (const contentContainer of contentContainers) {\n\t\tconst sectionTitle = contentContainer.get(\"_id\")\n\t\tif (!isString(sectionTitle)) continue\n\t\tconst section = kit.getSectionByUniqueTitle(sectionTitle)\n\t\tif (!section) continue\n\t\tconst oldNodeId = section.id\n\t\tconst newNodeId = renamedIds.get(oldNodeId) ?? oldNodeId\n\t\tawait applyContentToNodes(engine, newNodeId, contentContainer, kit)\n\t}\n}\n\nfunction createContentContainersForCustomizedSections(sections: AIStructuredOutput[\"sections\"]) {\n\tconst contentContainers: ContentContainer[] = []\n\tfor (const section of sections) {\n\t\tif (!isObject(section)) continue\n\t\tconst contentContainer = new ContentContainer(section, true)\n\t\tcontentContainers.push(contentContainer)\n\t}\n\treturn contentContainers\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport {\n\tassert,\n\tModuleType,\n\tResolvablePromise,\n\tgetLogger,\n\tisLocalModuleIdentifier,\n\tlocalModuleIdentifierForStableName,\n\tparseModuleIdentifier,\n} from \"@framerjs/shared\"\nimport { type ModelMessage, Output, streamText } from \"ai\"\nimport type { FollowUpTask } from \"app/ai/WireframerSession.ts\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { CreatePage, UpdatePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport {\n\tcreateCollection,\n\tcreateCollectionDependencyMap,\n\tcreateCollectionLookup,\n\tgetExistingCollections,\n} from \"app/ai/utils/collections.ts\"\nimport { CREATE_NEW_COLLECTION_ALIAS } from \"app/ai/utils/kitSection.ts\"\nimport { type KitSectionMeta, type WireframerKit, isLayoutTemplateSlotKey } from \"app/ai/utils/wireframerKit.ts\"\nimport type { KitSection } from \"code-generation/utils/KitSectionStructureCollector.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { BaseEngineScheduler } from \"document/base-engine/BaseEngine.ts\"\nimport { getRawRouteSegmentFullPath } from \"document/components/chrome/Pages/utils/getRouteSegmentFullPath.ts\"\nimport { getRouteSegmentNodeByWebPageId } from \"document/components/chrome/Pages/utils/getRouteSegmentNodeByWebPageId.ts\"\nimport { updateRouteSegmentPath } from \"document/components/chrome/Pages/utils/updateRouteSegmentPath.ts\"\nimport { createContentManagementNodeIfNeeded } from \"document/components/chrome/contentManagement/utils/createContentManagementNodeIfNeeded.ts\"\nimport { RenamedIds } from \"document/components/tools/utils/updateNodeConnections.ts\"\nimport { valueToPath } from \"document/components/utils/valueToPath.ts\"\nimport type {\n\tAnyLayoutTemplateNode,\n\tAnyWebPageNode,\n\tCanvasTree,\n\tCollectionNode,\n\tLayoutTemplateNode,\n\tNodeID,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport {\n\tLAYOUT_TEMPLATE_ENTITY_ROOT_ID,\n\tensureEntityTypeRootNode,\n} from \"document/models/CanvasTree/nodes/EntityTypeRootNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisCollectionNode,\n\tisLayoutTemplateNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\nimport { ContentContainer } from \"document/models/CanvasTree/traits/utils/ContentContainer.ts\"\nimport { SloppyJavaScriptParser, isIncompleteValue } from \"document/utils/SloppyJavaScriptParser.ts\"\nimport { uniqueName } from \"document/utils/uniqueName.ts\"\nimport { join } from \"utils/join.ts\"\nimport { isArray, isObject, isString } from \"utils/typeChecks.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport * as yaml from \"yaml\"\nimport { createAddCMSItems } from \"../../utils/followUpTasks.ts\"\nimport {\n\ttype AIStructuredOutput,\n\ttype AIStructuredOutputWithMessage,\n\ttype CollectionBinding,\n\tschema,\n} from \"./schema.ts\"\nimport { applyContentToNodes } from \"./utils/applyContentToNodes.ts\"\nimport { deleteSectionsThatAreNotInTheResponse } from \"./utils/common.ts\"\nimport { buildPromptMessages } from \"./utils/prompts/promptBuilder.ts\"\nimport {\n\tapplyCustomizationsToLayoutTemplate,\n\tcreateNodeForScope,\n\tcreateNodeForSection,\n\tcreateOnSectionHandlers,\n\tgetScreenMode,\n\tupdateNodeForSection,\n} from \"./utils/sectionOperations.ts\"\n\nconst log = getLogger(\"ai:singlePageGenerateWebPage\")\n\n/**\n * A page becomes a CMS page as soon as it has a detail page section, which allows us to know which\n * collection to use for the page.\n */\nasync function backfillWebPageDataIdentifier(\n\tscheduler: BaseEngineScheduler,\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tsection: KitSectionMeta,\n\tkit: WireframerKit,\n\tsectionContainerId: NodeID,\n\tcollectionNodesByTemplateId: Record<string, CollectionNode>,\n) {\n\tconst detailPageTemplateId = section.detailPageCollectionId\n\t\t? kit.getCollectionTemplateById(section.detailPageCollectionId)?.name\n\t\t: undefined\n\tconst container = tree.get(sectionContainerId)\n\tconst page = tree.getScopeNodeFor(container)\n\n\t// Don't backfill the data identifier if the page is already a CMS page.\n\tif (!detailPageTemplateId || !isWebPageNode(page) || isString(page.dataIdentifier)) return\n\tconst collection = collectionNodesByTemplateId[detailPageTemplateId]\n\tif (!collection) return\n\n\tconst slugId = collection.getSlugVariable()?.id\n\tassert(slugId, \"Slug variable must exist\")\n\n\tconst seg = getRouteSegmentNodeByWebPageId(tree, page.id)\n\tif (!seg) return\n\n\tconst rawPath = getRawRouteSegmentFullPath(tree, componentLoader, seg.id)\n\tif (!rawPath) return\n\n\tconst pathBase = valueToPath(rawPath).replace(\":slug\", `:${slugId}`)\n\n\tawait scheduler.processWhenReadyAsync(() => {\n\t\ttree.current(page)?.set({ dataIdentifier: collection.instanceIdentifier })\n\t\tupdateRouteSegmentPath(seg.id, pathBase, tree, componentLoader, undefined, collection.instanceIdentifier)\n\t})\n}\n\ntype TemplateId = string\n\n/**\n * When a section is selected, create any collections that the worker has selected to avoid errors\n * for missing collections when the section is added to the page, and schedule followup tasks to add\n * items to the collections.\n *\n * This allows the worker to select the best selection, even if the collections are not yet created,\n * or were not planned to be created.\n *\n * Only necessary collection references -- ones that are bound to fields in the section -- are created.\n */\nasync function backfillCollections(\n\tscheduler: BaseEngineScheduler,\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tkit: WireframerKit,\n\tcollectionIdsByName: Map<string, NodeID>,\n\tnewCollectionMap: Map<TemplateId, Record<string, CollectionNode>>,\n\tcollectionBindings: CollectionBinding[],\n\tcontentContainer: ContentContainer,\n\tsection: KitSectionMeta,\n\tsectionContainerId: NodeID,\n\tqueueTask: (task: FollowUpTask) => void,\n) {\n\t// 1. Create an ordered list of all of the collections required by the fields of this section.\n\t//    The first collections will be referenced by later collections. This will include existing\n\t//    collections, as well as collections the worker is asking to create.\n\tconst collections = createCollectionDependencyMap(section, collectionBindings, kit)\n\tif (collections.length === 0) return\n\n\tconst nodes: CollectionNode[] = []\n\tconst collectionNodesByTemplateId: Record<string, CollectionNode> = {}\n\n\t// 2. Iterate through the collections that the worker has selected, and add collections that\n\t//    already exist in the tree to a dictionary. We need to know all of the existing collection\n\t//    ids before we create any new collections so that we can lookup the ids.\n\tfor (const { id: templateId, name, new: isNewCollection } of collections) {\n\t\t// KITS @TODO - Add necessary references to existing collections.\n\t\tif (isNewCollection) {\n\t\t\t// If a collection with the same template and name was already created by the worker, we\n\t\t\t// reuse it to allow the same references to be shared between sections.\n\t\t\tconst existing = newCollectionMap.get(templateId)?.[name]\n\t\t\tif (existing) collectionNodesByTemplateId[templateId] = existing\n\t\t\tcontinue\n\t\t}\n\t\tconst nodeId = collectionIdsByName.get(name)\n\t\tconst node = tree.getNodeWithTrait(nodeId, isCollectionNode)\n\t\tif (!node) continue\n\n\t\tcollectionNodesByTemplateId[templateId] = node\n\t}\n\n\t// 3. Iterate through the remaining collections that the worker has selected to be created, and\n\t//    create them in reverse dependency order.\n\tfor (const { id: templateId, name, new: isNewCollection } of collections) {\n\t\tif (!isNewCollection) continue\n\n\t\t// If we have created a collection for this template with this name in the current session,\n\t\t// don't create a new one.\n\t\tconst existing = newCollectionMap.get(templateId)?.[name]\n\t\tif (existing) continue\n\n\t\tconst template = kit.getCollectionTemplate(templateId)\n\t\tif (!template) continue\n\n\t\t// If the collection name is the $NEW alias, fallback to \"Collection *\".\n\t\tconst collectionName = collectionNameWithFallback(name, collectionIdsByName)\n\n\t\tconst collection = (collectionNodesByTemplateId[templateId] = createCollection(\n\t\t\ttree,\n\t\t\tkit,\n\t\t\tcollectionName,\n\t\t\ttemplate,\n\t\t\tundefined,\n\t\t\t// When resolving references, use only the collections that are referenced in this\n\t\t\t// section. We don't need to create references to collections that have no bindings.\n\t\t\ttemplateCollectionName => collectionNodesByTemplateId[templateCollectionName],\n\t\t))\n\n\t\t// Update the collection lookup with the new collection.\n\t\tcollectionIdsByName.set(name, collection.id)\n\n\t\t// Record the new collection name to the newCollectionMap so that we can reuse it in any\n\t\t// subsequent sections that use the same template and name.\n\t\tconst map = newCollectionMap.get(templateId) ?? {}\n\t\tmap[name] = collection\n\t\tnewCollectionMap.set(templateId, map)\n\n\t\tnodes.push(collection)\n\n\t\t// Schedule a followup task to add items to the collection before completing the current worker.\n\t\tqueueTask(\n\t\t\tcreateAddCMSItems({\n\t\t\t\tcollectionNodeId: collection.id,\n\t\t\t\tcollectionName,\n\t\t\t\tgetInstructions: () => createCMSTaskInstructions(section, contentContainer),\n\t\t\t}),\n\t\t)\n\t}\n\n\t// 4. If the section is a detail page binding, backfill the data identifier of the web page to bind it.\n\tawait backfillWebPageDataIdentifier(\n\t\tscheduler,\n\t\ttree,\n\t\tcomponentLoader,\n\t\tsection,\n\t\tkit,\n\t\tsectionContainerId,\n\t\tcollectionNodesByTemplateId,\n\t)\n\n\tif (nodes.length === 0) return\n\n\t// 5. Finally, insert the collections into the tree.\n\tawait scheduler.processWhenReadyAsync(() => {\n\t\tconst contentManagementNode = createContentManagementNodeIfNeeded(tree)\n\t\tnodes.forEach(node => tree.insertNode(node, contentManagementNode.id))\n\t})\n}\n\nexport async function generateSections(\n\tengine: VekterEngine,\n\tscreenId: NodeID,\n\ttask: CreatePage | UpdatePage,\n\tinitialFeatureRequest: string,\n\tkitSectionsStructure: KitSection[] | undefined,\n\tdesignPageId: NodeID | undefined,\n\tkit: WireframerKit,\n\tonInitLayout: (layoutId: NodeID | undefined) => Promise<void>,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n) {\n\tconst collectionIdsByName = createCollectionLookup(engine.stores.treeStore.tree)\n\n\tconst newCollectionMap: Map<string, Record<string, CollectionNode>> = new Map()\n\n\t// Tasks to be executed after generating the page.\n\tconst tasks: FollowUpTask[] = []\n\n\tconst layoutPromise = new ResolvablePromise<NodeID | undefined>()\n\n\tasync function onLayout(layoutId: string | undefined) {\n\t\tawait onInitLayout(layoutId)\n\t\tlayoutPromise.resolve(layoutId)\n\t}\n\n\t// Handler that creates a node for a kit section.\n\tasync function createSection(\n\t\tid: string,\n\t\tcontentContainer: ContentContainer,\n\t\tcollectionBindings: CollectionBinding[],\n\t\tposition: number,\n\t): Promise<NodeID | undefined> {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\t\t// Wait for the layout to be updated first before populating sections\n\t\tawait layoutPromise\n\t\tconst screen = engine.tree.get(screenId)\n\t\tassert(screen, \"Container node not found for sections\", screenId)\n\n\t\tconst section = kit.getSectionByUniqueTitle(id)\n\t\tif (!section) return\n\t\tconst data = await kit.getClipboardDataById(section.id)\n\t\tif (!data) return\n\n\t\t// As soon as the section is selected, create any necessary collections.\n\t\tawait backfillCollections(\n\t\t\tengine.scheduler,\n\t\t\tengine.tree,\n\t\t\tengine.componentLoader,\n\t\t\tkit,\n\t\t\tcollectionIdsByName,\n\t\t\tnewCollectionMap,\n\t\t\tcollectionBindings,\n\t\t\tcontentContainer,\n\t\t\tsection,\n\t\t\tscreen.id,\n\t\t\tt => tasks.push(t),\n\t\t)\n\n\t\tconst themeMode = task.mode ?? getScreenMode(screen)\n\n\t\treturn createNodeForSection(\n\t\t\tengine,\n\t\t\tkit,\n\t\t\tscreen.id,\n\t\t\t{ data, id: section.id },\n\t\t\tcontentContainer,\n\t\t\tposition,\n\t\t\tresolveCollectionBindings(\n\t\t\t\tengine.tree,\n\t\t\t\tcollectionBindings,\n\t\t\t\t// Recreate the lookup to incorporate collections created in backfilling.\n\t\t\t\tcreateCollectionLookup(engine.stores.treeStore.tree),\n\t\t\t),\n\t\t\tthemeMode,\n\t\t)\n\t}\n\n\t// Handler that updates a node from the kit section.\n\tasync function updateSection(\n\t\tid: string,\n\t\tnodeId: NodeID,\n\t\tcontentContainer: ContentContainer,\n\t\tcollectionBindings: CollectionBinding[],\n\t\tposition?: number,\n\t): Promise<NodeID | undefined> {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\t\t// Wait for screenId to be set by handleLayout\n\t\tawait layoutPromise\n\t\tconst screen = engine.tree.get(screenId)\n\t\tassert(screen, \"Container node not found for sections\", screenId)\n\n\t\tconst section = kit.getSectionByUniqueTitle(id)\n\t\tif (!section) return\n\n\t\t// As soon as the section is selected, create any necessary collections.\n\t\tawait backfillCollections(\n\t\t\tengine.scheduler,\n\t\t\tengine.tree,\n\t\t\tengine.componentLoader,\n\t\t\tkit,\n\t\t\tcollectionIdsByName,\n\t\t\tnewCollectionMap,\n\t\t\tcollectionBindings,\n\t\t\tcontentContainer,\n\t\t\tsection,\n\t\t\tnodeId,\n\t\t\tt => tasks.push(t),\n\t\t)\n\n\t\t// KITS @TODO: If we ever want mix and match sections from different kits in the same page we need to\n\t\t// be able to get definition from any kit we have access to.\n\t\tconst data = await kit.getClipboardDataById(section.id)\n\t\tif (!data) return\n\n\t\tconst themeMode = task.mode ?? getScreenMode(screen)\n\t\treturn updateNodeForSection(\n\t\t\tengine,\n\t\t\tkit,\n\t\t\tscreen.id,\n\t\t\tsection.id,\n\t\t\tnodeId,\n\t\t\t{ data, id: section.id },\n\t\t\tcontentContainer,\n\t\t\tresolveCollectionBindings(\n\t\t\t\tengine.tree,\n\t\t\t\tcollectionBindings,\n\t\t\t\t// Recreate the lookup to incorporate collections created in backfilling.\n\t\t\t\tcreateCollectionLookup(engine.stores.treeStore.tree),\n\t\t\t),\n\t\t\tthemeMode,\n\t\t\tposition,\n\t\t)\n\t}\n\n\t// Handler that removes a node from the web page.\n\tasync function removeSection(nodeId: NodeID) {\n\t\treturn engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\tengine.stores.aiGenerationStore.setSectionBeingGenerated(nodeId)\n\n\t\t\tengine.deleteNode(nodeId)\n\n\t\t\treturn nodeId\n\t\t})\n\t}\n\n\tasync function finalizeSection(\n\t\tsectionId: string,\n\t\tnodeId: NodeID,\n\t\tcontentContainer: ContentContainer,\n\t): Promise<NodeID | undefined> {\n\t\tconst screen = engine.tree.get(screenId)\n\t\tif (!screen) return\n\n\t\tconst section = kit.getSectionByUniqueTitle(sectionId)\n\t\tif (!section || !section.moduleIdentifier) return\n\n\t\tconst node = engine.tree.get(nodeId)\n\t\tif (!node || isCodeComponentNode(node)) return\n\n\t\tconst parsed = parseModuleIdentifier(section.moduleIdentifier)\n\t\tif (!parsed || !isLocalModuleIdentifier(parsed)) return\n\n\t\tconst name = parsed.localIdName\n\t\tif (!name || engine.tree.getNodeWithTrait(name, isSmartComponentNode)) return\n\n\t\tconst data = await kit.getClipboardDataById(name)\n\t\tif (!data) return\n\n\t\tconst renamedIds = new RenamedIds()\n\t\tconst ids = await createNodeForScope(engine, data, renamedIds, false)\n\n\t\tconst scopeId = ids.find(id => engine.tree.getNodeWithTrait(id, isSmartComponentNode))\n\t\tif (!scopeId) return\n\n\t\tconst scope = engine.tree.get(scopeId)\n\t\tif (!scope || !isSmartComponentNode(scope) || !scope.isLoaded()) return\n\n\t\t// Track the source node variants to be able to replace the source node variants with the\n\t\t// new ones.\n\t\tconst sourceNodeVariants = getSourceNodeVariants(scope, renamedIds)\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tscope.set({ kitComponentSource: { kit: kit.id, sourceModuleIdentifier: parsed.value, sourceNodeVariants } })\n\t\t})\n\n\t\tawait applyContentToNodes(engine, scopeId, contentContainer, kit)\n\n\t\t// Make sure we have a local instance to render.\n\t\tawait engine.stores.codeGenerationStore.updateComponent(name)\n\n\t\t// Get the clipboard data again - this time force fetching the instance data.\n\t\tconst instance = await kit.getClipboardDataById(section.id, false)\n\t\tif (!instance) return\n\n\t\tconst parent = engine.tree.getParent(nodeId)\n\t\tif (!parent) return\n\n\t\tconst position = parent.children?.findIndex(child => child.id === nodeId)\n\t\tif (position === -1) return\n\n\t\t// Turn the clipboard that contains the original instance into a section, replacing the\n\t\t// existing one, and updating the instance to point to the new local instance.\n\t\treturn createNodeForSection(\n\t\t\tengine,\n\t\t\tkit,\n\t\t\tparent.id,\n\t\t\t{ data: instance, id: section.id },\n\t\t\tcontentContainer,\n\t\t\tposition,\n\t\t\t[], // No collections to resolve.\n\t\t\ttask.mode ?? getScreenMode(screen),\n\t\t\t() => engine.deleteNode(nodeId),\n\t\t)\n\t}\n\n\tconst { onSections, allDone } = createOnSectionHandlers(\n\t\tkit,\n\t\tcreateSection,\n\t\tupdateSection,\n\t\tremoveSection,\n\t\tfinalizeSection,\n\t)\n\n\ttry {\n\t\tengine.scheduler.process(() => engine.beginUndoGroup())\n\n\t\tconst result = await generatePageSectionsProposal(\n\t\t\tengine,\n\t\t\tinitialFeatureRequest,\n\t\t\tkitSectionsStructure,\n\t\t\ttask,\n\t\t\tdesignPageId,\n\t\t\tkit,\n\t\t\tonLayout,\n\t\t\tonSections,\n\t\t\ttraceConfig,\n\t\t)\n\n\t\tlog.info(\"Result\", result)\n\n\t\t// Waits for all sections to be created or updated.\n\t\tconst orderedNodeIds = await allDone()\n\n\t\tconst screen = engine.tree.get(screenId)\n\t\tassert(screen, \"Container node not found after generating sections\", screenId)\n\n\t\t// Delete all sections that were forgotten by the AI in the response.\n\t\t// Assume if they are not present they should be removed.\n\t\tdeleteSectionsThatAreNotInTheResponse(engine, screen.id, new Set(orderedNodeIds.keys()))\n\n\t\t// Should already be done by this point, but wait to be safe\n\t\tconst layoutId = await layoutPromise\n\n\t\tif (!designPageId) {\n\t\t\tconst webPage = engine.tree.getScopeNodeFor(screen)\n\t\t\tassert(isWebPageNode(webPage), \"Web page node not found\", screen.id)\n\t\t\tawait swapSectionsWithLayoutTemplate(engine, webPage, orderedNodeIds, kit, layoutId, result.sections)\n\t\t}\n\n\t\treturn { ...result, followUpTasks: tasks }\n\t} catch (error) {\n\t\tlog.reportError(error)\n\n\t\t// Allow retrying before the normal interval may have passed\n\t\tengine.stores.chromeStore.unblockGeneratingWithAI()\n\n\t\tthrow error\n\t} finally {\n\t\tengine.scheduler.process(() => engine.endUndoGroup())\n\t}\n}\n\n/**\n * Gets a proposal from the LLM for the page sections based on the chat history.\n * Processes chunks and feed them to the onSections callback.\n */\nasync function generatePageSectionsProposal(\n\tengine: VekterEngine,\n\tinitialFeatureRequest: string,\n\tkitSectionsStructure: KitSection[] | undefined,\n\ttask: CreatePage | UpdatePage,\n\tdesignPageId: NodeID | undefined,\n\tkit: WireframerKit,\n\tonLayout: (layoutId: string | undefined) => void,\n\tonSections: (sections: ContentContainer[]) => void,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<AIStructuredOutputWithMessage> {\n\tconst createdCollections = getExistingCollections(engine.stores.treeStore.tree, kit)\n\n\tconst messages: ModelMessage[] = await buildPromptMessages(\n\t\tengine,\n\t\tinitialFeatureRequest,\n\t\tkitSectionsStructure,\n\t\ttask,\n\t\tdesignPageId,\n\t\tkit,\n\t\tcreatedCollections,\n\t)\n\n\tlog.info(\"Messages\", messages)\n\n\tconst parser = sectionsParser(onLayout, onSections)\n\tconst abortController = new AbortController()\n\n\ttry {\n\t\tlet allData = \"\"\n\n\t\tconst { textStream } = streamText({\n\t\t\tmodel: openRouter(LanguageModel.GPT41, {\n\t\t\t\textraBody: {\n\t\t\t\t\t...createVekterOpenRouterExtraBody({\n\t\t\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\t\t\tfeatureName: traceConfig.featureName,\n\t\t\t\t\t\tsessionId: traceConfig.sessionId,\n\t\t\t\t\t\tstep: \"generate-web-page\",\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tmessages,\n\t\t\toutput: Output.object({ schema }),\n\t\t\tabortSignal: abortController.signal,\n\t\t})\n\n\t\tfor await (const textPart of textStream) {\n\t\t\tassert(!getIsViewOnly(engine, \"canDesign\"), \"Cannot generate page sections in view only mode\")\n\t\t\tparser.add(textPart)\n\t\t\tallData += textPart\n\t\t}\n\n\t\treturn JSON.parse(allData)\n\t} catch (error) {\n\t\tabortController.abort()\n\t\tlog.error(\"Error generating page sections proposal\", error)\n\t\tthrow error\n\t} finally {\n\t\tparser.end()\n\t}\n}\n\nfunction sectionsParser(\n\tonLayout: (layoutId: string | undefined) => void,\n\tonSections: (sections: ContentContainer[]) => void,\n) {\n\tconst sectionContentContainers: ContentContainer[] = []\n\tlet layoutComplete: boolean = false\n\n\tconst parser = new SloppyJavaScriptParser((value: unknown[] | Record<string, unknown>) => {\n\t\tif (!isObject(value)) return\n\t\tconst { layout, sections } = value\n\n\t\tif (isString(layout) && !isIncompleteValue(value, \"layout\") && !layoutComplete) {\n\t\t\tonLayout(layout ? layout : undefined)\n\t\t\tlayoutComplete = true\n\t\t}\n\n\t\tif (!isArray(sections)) return\n\n\t\tlet containersChanged = false\n\t\tfor (let i = 0; i < sections.length; i++) {\n\t\t\tconst data = sections[i]\n\t\t\tconst section = isObject(data) ? data : {}\n\n\t\t\t// Make sure that a container exists and is up-to-date for every section.\n\t\t\tlet contentContainer: ContentContainer | undefined = sectionContentContainers[i]\n\t\t\tif (!contentContainer) {\n\t\t\t\tcontentContainer = new ContentContainer(section, false)\n\t\t\t\tsectionContentContainers.push(contentContainer)\n\n\t\t\t\tcontainersChanged = true\n\t\t\t} else if (contentContainer.isFinal) {\n\t\t\t\t// We cannot do anything about already final sections.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcontentContainer.update(section)\n\t\t\tcontainersChanged = true\n\n\t\t\tif (!isIncompleteValue(sections, i)) {\n\t\t\t\tcontentContainer.finalize()\n\t\t\t}\n\t\t}\n\n\t\t// Don't call onSections if nothing changed about the containers\n\t\tif (containersChanged) {\n\t\t\tonSections(sectionContentContainers)\n\t\t}\n\t})\n\n\treturn parser\n}\n\nfunction resolveCollectionBindings(\n\ttree: CanvasTree,\n\tcollectionBindings: CollectionBinding[],\n\tcollectionLookup: Map<string, NodeID>,\n): CollectionNode[] {\n\tconst resolvedCollections: CollectionNode[] = []\n\n\tfor (const collectionBinding of collectionBindings) {\n\t\tconst collectionNodeId = collectionLookup.get(collectionBinding.collectionName)\n\t\tif (!collectionNodeId) continue\n\n\t\tconst collectionNode = tree.get(collectionNodeId)\n\t\tassert(isCollectionNode(collectionNode), \"Collection node not found\", collectionNodeId)\n\n\t\tresolvedCollections.push(collectionNode)\n\t}\n\n\treturn resolvedCollections\n}\n\nfunction createResolvedFieldValues(section: KitSectionMeta, contentContainer: ContentContainer) {\n\tconst resolvedFieldValues: [string, string][] = []\n\n\tfor (const field of section.fields) {\n\t\tif (field.isCMSConnectedField) continue\n\t\tif (field.type !== \"text\") continue\n\t\tconst value = contentContainer.get(\"content\")\n\t\tif (!isArray(value)) continue\n\t\tconst content = value.find(c => isObject(c) && c.field === field.name)\n\t\tif (!isObject(content) || !isString(content.text)) continue\n\t\tresolvedFieldValues.push([field.name, content.text])\n\t}\n\n\treturn Object.fromEntries(resolvedFieldValues)\n}\n\nfunction createCMSTaskInstructions(section: KitSectionMeta, contentContainer: ContentContainer) {\n\tconst rules = section.rules ?? []\n\tconst description = section.description\n\n\treturn join.lines(\n\t\t`Items will be used to provide content for a website section with the following description: ${description}.`,\n\t\trules.length > 0 && `Items will have the following rules: ${rules.join(\", \")}.`,\n\t\t`Items will have been filled with the following content:\n        ${yaml.stringify(createResolvedFieldValues(section, contentContainer))}.`,\n\t)\n}\n\nfunction collectionNameWithFallback(collectionName: string, collections: Map<string, NodeID>) {\n\tif (collectionName !== CREATE_NEW_COLLECTION_ALIAS) return collectionName\n\tconst existingNames = new Set(collections.keys())\n\treturn uniqueName(\"Collection\", existingNames)\n}\n\nasync function swapSectionsWithLayoutTemplate(\n\tengine: VekterEngine,\n\twebPageNode: AnyWebPageNode,\n\torderedNodeIds: Map<NodeID, NodeID>,\n\tkit: WireframerKit,\n\tselectedLayoutId: NodeID | undefined,\n\tsections: AIStructuredOutput[\"sections\"],\n) {\n\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\tconst layoutTemplateMeta = selectedLayoutId ? kit.layoutTemplates[selectedLayoutId] : undefined\n\tif (!layoutTemplateMeta) return\n\n\tlog.info(\"Using layout template:\", layoutTemplateMeta.id, layoutTemplateMeta.pattern)\n\n\t// If the layout template already exists in the tree, use it directly\n\tconst { id, pattern } = layoutTemplateMeta\n\tconst replacedSectionIds = pattern.filter(nodeId => !isLayoutTemplateSlotKey(nodeId))\n\n\tconst node = engine.tree.getNode(id)\n\n\tlet layoutTemplateId: NodeID | undefined = id\n\n\tif (!node) {\n\t\tconst data = await kit.getClipboardDataById(layoutTemplateMeta.id)\n\t\tif (!data) return\n\t\tconst renamedIds = new RenamedIds()\n\n\t\tensureEntityTypeRootNode(engine.tree, LAYOUT_TEMPLATE_ENTITY_ROOT_ID)\n\t\tconst insertedIds = await createNodeForScope(engine, data, renamedIds, true)\n\n\t\tconst scopeId = insertedIds.find(id => engine.tree.getNodeWithTrait(id, isLayoutTemplateNode))\n\t\tlayoutTemplateId = scopeId\n\t\tassert(layoutTemplateId, \"Create layout template failed\", id)\n\n\t\tconst layoutTemplateNode = engine.tree.getNode(layoutTemplateId)\n\t\tassert(isLayoutTemplateNode(layoutTemplateNode), \"Created layout template node not found\", layoutTemplateId)\n\t\tassert(layoutTemplateNode.isLoaded(), \"Created layout template node not loaded\", layoutTemplateId)\n\n\t\tawait applyCustomizationsToLayoutTemplate(engine, kit, sections, renamedIds)\n\t\t// After creating the layout template node, also record the kit component source metadata.\n\t\tconst sourceNodeVariants = getSourceNodeVariants(layoutTemplateNode, renamedIds)\n\t\tconst sourceModuleIdentifier = localModuleIdentifierForStableName(\n\t\t\tModuleType.LayoutTemplate,\n\t\t\tlayoutTemplateMeta.id,\n\t\t\t\"default\",\n\t\t).value\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tlayoutTemplateNode.set({\n\t\t\t\tkitComponentSource: { kit: kit.id, sourceModuleIdentifier, sourceNodeVariants },\n\t\t\t})\n\t\t})\n\t}\n\n\tassert(layoutTemplateId, \"No layout template to use:\", id)\n\n\tconst layoutTemplateNode = engine.tree.getNode(layoutTemplateId)\n\n\tif (!isLayoutTemplateNode(layoutTemplateNode)) {\n\t\t// This can happen if the ID is occupied, and it's not a layout template node, not much we can do.\n\t\tlog.error(\"Cannot find layout template node\", id)\n\t\t// KITS @TODO: if we track the source kit of a layout template, we can rename the layout\n\t\t// template on paste and ditch this.\n\t\treturn\n\t}\n\n\t// Wait till the layout template is compiled, so when applying it on the web page, it would be seamless.\n\tawait engine.stores.codeGenerationStore.updateComponent(layoutTemplateNode.id)\n\n\tawait applyLayoutTemplateAndRemoveReplacedSections(\n\t\tengine,\n\t\tlayoutTemplateNode,\n\t\twebPageNode,\n\t\torderedNodeIds,\n\t\treplacedSectionIds,\n\t)\n}\n\nasync function applyLayoutTemplateAndRemoveReplacedSections(\n\tengine: VekterEngine,\n\tlayoutTemplateNode: AnyLayoutTemplateNode,\n\twebPageNode: AnyWebPageNode,\n\torderedNodeIds: Map<NodeID, NodeID>,\n\treplacedSectionIds: NodeID[],\n) {\n\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\tif (webPageNode.id === engine.tree.root.homePageNodeId) {\n\t\t\tengine.tree.root.set({ layoutTemplateIdentifier: layoutTemplateNode.instanceIdentifier })\n\t\t} else {\n\t\t\t// Apply the layout template as **override** on the web page.\n\t\t\tengine.tree\n\t\t\t\t.get<WebPageNode>(webPageNode.id)\n\t\t\t\t?.set({ layoutTemplateIdentifier: layoutTemplateNode.instanceIdentifier })\n\t\t}\n\n\t\tconst replacedSections: string[] = []\n\t\tfor (const [newId, oldId] of orderedNodeIds) {\n\t\t\tif (!replacedSectionIds.includes(oldId)) continue\n\t\t\tengine.deleteNode(newId)\n\t\t\treplacedSections.push(newId)\n\t\t}\n\t\tlog.info(\"Sections replaced by layout template:\", replacedSections)\n\t})\n}\n\nfunction getSourceNodeVariants(\n\tscope: Loaded<SmartComponentNode | LayoutTemplateNode>,\n\trenamedIds: RenamedIds,\n): Record<NodeID, NodeID> {\n\tconst reverseRenamedIds = new Map<NodeID, NodeID>([...renamedIds.entries()].map(([key, value]) => [value, key]))\n\tconst result: Record<NodeID, NodeID> = {}\n\tfor (const variant of scope.getVariants()) {\n\t\tlet originalId = reverseRenamedIds.get(variant.id)\n\t\tif (!originalId) continue\n\n\t\t// Cloning can rename a node multiple times. The renames are tracked in the map. We need to\n\t\t// follow until there are no more renames.\n\t\twhile (originalId) {\n\t\t\tconst nextOriginalId = reverseRenamedIds.get(originalId)\n\t\t\tif (!nextOriginalId) break\n\t\t\toriginalId = nextOriginalId\n\t\t}\n\n\t\tresult[originalId] = variant.id\n\t}\n\treturn result\n}\n", "import { assert, getLogger } from \"@framerjs/shared\"\nimport type { CreatePage, DeletePage, ThemePage, UpdatePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type {\n\tWireframerKit,\n\tWireframerKitBreakpoint,\n\tWireframerKitPageBackground,\n\tWireframerKitPageProperties,\n} from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { getRouteSegmentNodeByWebPageId } from \"document/components/chrome/Pages/utils/getRouteSegmentNodeByWebPageId.ts\"\nimport { deleteRouteSegmentAndOrphanedWebPages } from \"document/components/chrome/Pages/utils/promptAndDeleteRouteSegment.ts\"\nimport { rightSideOf } from \"document/components/tools/utils/FramesHelper.ts\"\nimport { enableStackLayoutForNode } from \"document/components/tools/utils/stackCreateHelper.ts\"\nimport { suggestBreakpoints } from \"document/components/utils/breakpointSuggestion.ts\"\nimport { ContextAction } from \"document/components/utils/contextActions.ts\"\nimport type { AnyWebPageNode, FrameNode, LoadedWebPageNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { ColorStyleTokenListNode } from \"document/models/CanvasTree/nodes/ColorStyleTokenListNode.ts\"\nimport { ColorStyleTokenNode } from \"document/models/CanvasTree/nodes/ColorStyleTokenNode.ts\"\nimport { isColorStyleTokenNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isTokenCSSVariable, tokenIdFromCSSVariable } from \"document/models/CanvasTree/utils/tokens.ts\"\nimport type { Rect } from \"library/index.ts\"\nimport { DimensionType } from \"library/index.ts\"\nimport { isString, isUndefined } from \"utils/typeChecks.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { applyColorScheme } from \"./colorScheme.ts\"\nimport { getLatestPrimaryVariant } from \"./common.ts\"\n\nconst log = getLogger(\"WireframerSession\")\n\nexport function applyBreakpointOverrides(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\twebPageNode: LoadedWebPageNode,\n\tlayoutId: NodeID | undefined,\n) {\n\tfor (const variant of webPageNode.getReplicaVariants()) {\n\t\tconst kitBreakpointId = kit.getBreakpointIdByWidth(variant.width, layoutId)\n\t\tif (!kitBreakpointId) continue\n\n\t\tconst breakpointProps = layoutId\n\t\t\t? kit.layoutTemplates[layoutId]?.pageProperties?.[kitBreakpointId]\n\t\t\t: kit.pageProperties?.[kitBreakpointId]\n\t\tif (!breakpointProps) continue\n\n\t\tapplyFillColor(engine, variant, breakpointProps.fillColor, kit.tokens)\n\t\tapplyLayoutProperties(variant, breakpointProps)\n\t}\n}\n\nfunction applyLayoutProperties(node: FrameNode, props: Partial<WireframerKitPageProperties>) {\n\tconst { padding, paddingTop, paddingRight, paddingBottom, paddingLeft, gap } = props\n\tconst updates: Partial<FrameNode> = {}\n\n\tconst hasPerSidePadding =\n\t\t!isUndefined(paddingTop) || !isUndefined(paddingRight) || !isUndefined(paddingBottom) || !isUndefined(paddingLeft)\n\n\tif (hasPerSidePadding) {\n\t\tupdates.paddingPerSide = true\n\t\tif (!isUndefined(paddingTop)) updates.paddingTop = paddingTop\n\t\tif (!isUndefined(paddingRight)) updates.paddingRight = paddingRight\n\t\tif (!isUndefined(paddingBottom)) updates.paddingBottom = paddingBottom\n\t\tif (!isUndefined(paddingLeft)) updates.paddingLeft = paddingLeft\n\t} else if (!isUndefined(padding)) {\n\t\tupdates.paddingPerSide = false\n\t\tupdates.padding = padding\n\t}\n\n\tif (!isUndefined(gap)) updates.gap = gap\n\n\tif (Object.keys(updates).length > 0) node.set(updates)\n}\n\nfunction getBreakpointsToCreate(\n\tbreakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined,\n\tprimaryBreakpoint: NodeID | undefined,\n): WireframerKitBreakpoint[] | undefined {\n\tif (!breakpoints) return\n\tconst breakpointsToCreate: WireframerKitBreakpoint[] = []\n\tfor (const breakpointId in breakpoints) {\n\t\tif (breakpointId === primaryBreakpoint) continue\n\t\tconst breakpoint = breakpoints[breakpointId]\n\t\tif (!breakpoint) continue\n\t\tbreakpointsToCreate.push(breakpoint)\n\t}\n\n\treturn breakpointsToCreate\n}\n\nexport function getPageMetaForLayoutUpdate(\n\tkit: WireframerKit,\n\tlayoutId: NodeID | undefined,\n): {\n\tbreakpointsToCreate: WireframerKitBreakpoint[] | undefined\n\tprimaryBreakpoint: NodeID | undefined\n\tpageProperties: Record<NodeID, Partial<WireframerKitPageProperties>> | undefined\n} {\n\tconst source = layoutId ? (kit.layoutTemplates[layoutId] ?? kit) : kit\n\tconst { breakpoints, primaryBreakpoint, pageProperties } = source\n\n\treturn {\n\t\tbreakpointsToCreate: getBreakpointsToCreate(breakpoints, primaryBreakpoint),\n\t\tprimaryBreakpoint,\n\t\tpageProperties,\n\t}\n}\n\n/**\n * Applies the metadata changes, the default layout, page styles and dark mode to a page.\n *\n * @param engine - The engine instance.\n * @param task - The page change to apply.\n * @param webPage - The web page to apply the changes to.\n * @param kit - The wireframer kit containing page styles.\n * @returns The updated web page.\n */\nexport function applyPageChangesToCreatedWebPage(\n\tengine: VekterEngine,\n\ttask: CreatePage,\n\twebPage: LoadedWebPageNode,\n\tkit: WireframerKit,\n\tlayoutId: NodeID | undefined,\n) {\n\tconst { name: pageTitle } = task\n\n\tconst currentWebPage = engine.tree.current(webPage)\n\tif (!currentWebPage) return\n\n\t// Update page metadata\n\tcurrentWebPage.set({\n\t\tname: pageTitle,\n\t\twebMetadata: {\n\t\t\t...webPage.webMetadata,\n\t\t\ttitle: pageTitle,\n\t\t},\n\t})\n\n\tconst primaryNode = getLatestPrimaryVariant(engine, currentWebPage)\n\tapplyDefaultLayoutToScreen(engine, primaryNode)\n\n\tconst { primaryBreakpoint, breakpointsToCreate, pageProperties } = getPageMetaForLayoutUpdate(kit, layoutId)\n\tif (primaryBreakpoint) {\n\t\tapplyPagePropertiesToScreen(engine, primaryNode, pageProperties?.[primaryBreakpoint], kit.tokens)\n\t}\n\n\t// We optimistically remove existing breakpoints to prevent any duplicated breakpoints.\n\tremoveExistingBreakpoints(engine, currentWebPage)\n\n\tcreateBreakpoints(engine, currentWebPage, primaryNode.draftOrCurrent(), breakpointsToCreate)\n\tapplyBreakpointOverrides(engine, kit, currentWebPage.draftOrCurrent(), layoutId)\n\n\tengine.stores.scopeStore.select(currentWebPage.id, { keepHistory: false })\n\n\treturn currentWebPage.id\n}\n\n// If the page change has a nodeId, we use that to get the web page. Otherwise we use the route to find a match.\nfunction getWebPageForChange(\n\tengine: VekterEngine,\n\ttask: ThemePage | UpdatePage | DeletePage,\n): AnyWebPageNode | undefined {\n\tconst webPage = engine.tree.get(task.id)\n\tif (isWebPageNode(webPage)) {\n\t\treturn webPage\n\t}\n\n\tlog.error(\"Web page node not found for nodeId\", task)\n}\n\n/**\n * Removes all existing breakpoint variants from a page.\n * This does not remove the primary variant, only the breakpoints.\n */\nfunction removeExistingBreakpoints(engine: VekterEngine, webPageNode: LoadedWebPageNode) {\n\tconst existingBreakpoints = webPageNode.getTopLevelReplicaVariants()\n\n\tfor (const breakpoint of existingBreakpoints) {\n\t\tengine.tree.remove(breakpoint.id)\n\t}\n}\n\n/**\n * Updates an existing page\n */\nexport async function updatePage(\n\tengine: VekterEngine,\n\ttask: UpdatePage | ThemePage,\n\tkit: WireframerKit,\n\tshouldSelectPage: boolean = true,\n): Promise<LoadedWebPageNode | undefined> {\n\tconst existingPage = getWebPageForChange(engine, task)\n\tassert(existingPage, \"Web page we are trying to update should exist\")\n\n\tconst loadedPage = existingPage.isLoaded() ? existingPage : await existingPage.load()\n\tassert(loadedPage, \"Web page should be loaded\")\n\n\tconst { mode } = task\n\tif (mode) {\n\t\tconst primaryVariant = loadedPage.getPrimaryVariant()\n\t\tawait applyColorScheme(engine, primaryVariant.id, kit, mode)\n\t}\n\n\treturn engine.scheduler.processWhenReadyAsync(() => {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\tconst currentWebPage = engine.tree.current(loadedPage)\n\t\tif (!currentWebPage) return\n\n\t\tif (shouldSelectPage) {\n\t\t\tengine.stores.scopeStore.select(currentWebPage.id, { keepHistory: false })\n\t\t}\n\n\t\treturn currentWebPage.draftOrCurrent()\n\t})\n}\n\n/**\n * Removes a page\n */\nexport async function removePage(engine: VekterEngine, task: DeletePage): Promise<NodeID> {\n\treturn engine.scheduler.processWhenReadyAsync(() => {\n\t\tconst existingPage = getWebPageForChange(engine, task)\n\t\tassert(existingPage, \"Web page we are trying to delete should exist\")\n\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return existingPage.id\n\n\t\tconst routeSegmentNode = getRouteSegmentNodeByWebPageId(engine.tree, existingPage.id)\n\t\tassert(routeSegmentNode, \"Route segment node should exist\")\n\n\t\tdeleteRouteSegmentAndOrphanedWebPages(engine, routeSegmentNode.id)\n\n\t\treturn existingPage.id\n\t})\n}\n\n/**\n * Creates breakpoints for a page\n */\nfunction createBreakpoints(\n\tengine: VekterEngine,\n\twebPageNode: LoadedWebPageNode,\n\tparent: ReturnType<typeof getLatestPrimaryVariant>,\n\tbreakpoints: WireframerKitBreakpoint[] | undefined,\n) {\n\tconst breakpointsToCreate = breakpoints ?? suggestBreakpoints(engine, webPageNode)\n\n\tconst primaryNodeRect = engine.tree.getRect(parent)\n\n\tfor (const breakpoint of breakpointsToCreate) {\n\t\tconst newBreakpointRect: Rect | null = rightSideOf(engine.tree, webPageNode, parent, primaryNodeRect)\n\t\tconst viewportHeight = breakpoint.viewportHeight ?? Math.min(1200, parent.height)\n\n\t\tContextAction.createBreakpoint(\n\t\t\tengine,\n\t\t\tparent,\n\t\t\twebPageNode,\n\t\t\tnewBreakpointRect,\n\t\t\tbreakpoint.width,\n\t\t\tbreakpoint.name,\n\t\t\tviewportHeight,\n\t\t\tfalse,\n\t\t)\n\t}\n}\n\n/**\n * Applies the default layout to a screen.\n * @param engine - The engine instance.\n * @param screen - The screen node to apply the layout to.\n */\nexport function applyDefaultLayoutToScreen(engine: VekterEngine, screen: FrameNode) {\n\tenableStackLayoutForNode(engine, screen)\n\n\t// Set fill color and set padding on the screen\n\tscreen.set({\n\t\theightType: DimensionType.Auto,\n\t\tpaddingPerSide: true,\n\t\tpaddingLeft: 20,\n\t\tpaddingRight: 20,\n\t\tgap: 0,\n\t\toverflow: \"clip\",\n\t})\n}\n\nexport function applyPagePropertiesToScreen(\n\tengine: VekterEngine,\n\tscreen: FrameNode,\n\tpageProperties: Partial<WireframerKitPageProperties> | undefined,\n\ttokens: WireframerKit[\"tokens\"],\n) {\n\tif (!pageProperties) return\n\tconst { fillColor, ...layoutProperties } = pageProperties\n\tapplyFillColor(engine, screen, fillColor, tokens)\n\tapplyLayoutProperties(screen, layoutProperties)\n}\n\nfunction applyFillColor(\n\tengine: VekterEngine,\n\tnode: FrameNode,\n\tfillColor: WireframerKitPageBackground | undefined,\n\ttokens: WireframerKit[\"tokens\"],\n) {\n\tif (!fillColor) return\n\n\tif (isTokenCSSVariable(fillColor)) {\n\t\tconst tokenId = tokenIdFromCSSVariable(fillColor)\n\t\tif (!tokenId) return\n\n\t\tconst existingToken = engine.tree.get(tokenId)\n\t\tif (existingToken) {\n\t\t\tif (!isColorStyleTokenNode(existingToken)) {\n\t\t\t\tlog.error(\"Node with token ID exists but is not a ColorStyleTokenNode\", tokenId)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tnode.set({\n\t\t\t\tfillColor,\n\t\t\t\tfillType: \"color\",\n\t\t\t\tfillEnabled: true,\n\t\t\t})\n\n\t\t\treturn\n\t\t}\n\n\t\tconst tokenProps = tokens[tokenId]\n\t\tif (!tokenProps) {\n\t\t\tlog.error(\"Token not found in kit\", tokenId)\n\t\t\treturn\n\t\t}\n\n\t\tconst token = new ColorStyleTokenNode({ ...tokenProps })\n\t\tconst tokenListNode = ColorStyleTokenListNode.get(engine.tree)\n\t\tassert(tokenListNode, \"Token list node should exist in tree\")\n\n\t\tengine.tree.insertNode(token, tokenListNode.id)\n\t\tnode.set({\n\t\t\tfillColor,\n\t\t\tfillType: \"color\",\n\t\t\tfillEnabled: true,\n\t\t})\n\n\t\treturn\n\t}\n\n\t// Solid color\n\tassert(isString(fillColor), \"Fill color should be a string\")\n\tnode.set({\n\t\tfillColor,\n\t\tfillType: \"color\",\n\t\tfillEnabled: true,\n\t})\n\treturn\n}\n", "import type { StepResult } from \"app/ai/WireframerSession.ts\"\nimport { PageMode } from \"app/ai/orchestrator/dsl.ts\"\nimport type { CreatePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { rightSideOf } from \"document/components/tools/utils/FramesHelper.ts\"\nimport { createWebPage, getLoadedWebPageTemplate } from \"document/components/utils/createWebPage.ts\"\nimport { defaultBreakpointStylingProps } from \"document/components/utils/getPrimaryBreakpointProps.ts\"\nimport type { LoadedWebPageNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { FrameNode, isScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { Point } from \"library/index.ts\"\nimport { assert } from \"library/utils/assert.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { generateSections } from \"../generateWebPage.ts\"\nimport { applyColorScheme, getWireframerPageColor } from \"../utils/colorScheme.ts\"\nimport {\n\tapplyDefaultLayoutToScreen,\n\tapplyPageChangesToCreatedWebPage,\n\tapplyPagePropertiesToScreen,\n\tgetPageMetaForLayoutUpdate,\n} from \"../utils/pageOperations.ts\"\n\nasync function preparePageForSections(engine: VekterEngine, task: CreatePage): Promise<LoadedWebPageNode | undefined> {\n\tconst { path: route, name } = task\n\t// Special case for the home page.\n\tif (route === \"/\") {\n\t\tconst homePageNodeId = engine.tree.root.homePageNodeId\n\t\tassert(homePageNodeId, \"Home page node id is required\")\n\n\t\tconst existingHomePage = engine.tree.get(homePageNodeId)\n\t\tif (isWebPageNode(existingHomePage) && existingHomePage.isLoaded()) {\n\t\t\treturn existingHomePage\n\t\t}\n\t}\n\n\tconst loadedTemplate = await getLoadedWebPageTemplate(engine)\n\tassert(loadedTemplate, \"Loaded template should be defined\")\n\n\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\tconst createdWebPage = await engine.scheduler.processWhenReadyAsync(() =>\n\t\tcreateWebPage({\n\t\t\tengine,\n\t\t\tname,\n\t\t\tpagePath: route,\n\t\t\tloadedTemplate,\n\t\t}),\n\t)\n\n\treturn createdWebPage\n}\n\nexport async function createAIGeneratedPage(\n\tengine: VekterEngine,\n\tinitialFeatureRequest: string,\n\ttask: CreatePage,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<StepResult> {\n\tconst webPage = await preparePageForSections(engine, task)\n\tassert(webPage, \"Failed to create web page\", task)\n\n\tconst screen = webPage.getPrimaryVariant()\n\n\tif (task.mode) await applyColorScheme(engine, screen.id, kit, task.mode)\n\n\tasync function handleLayout(layoutId: NodeID | undefined) {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tassert(webPage, \"Cannot find web page for generation\")\n\t\t\tconst latestWebPage = webPage.draftOrCurrent()\n\t\t\tapplyPageChangesToCreatedWebPage(engine, task, latestWebPage, kit, layoutId)\n\t\t})\n\t}\n\n\tconst { message, followUpTasks, ...rest } = await engine.stores.chromeStore.runAIGeneration(() =>\n\t\tgenerateSections(\n\t\t\tengine,\n\t\t\tscreen.id,\n\t\t\ttask,\n\t\t\tinitialFeatureRequest,\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\tkit,\n\t\t\thandleLayout,\n\t\t\ttraceConfig,\n\t\t),\n\t)\n\n\t// After the generation wait for the code generation to be idle to avoid race conditions with kit-section structure.\n\tawait engine.stores.codeGenerationStore.updateComponent(webPage.id)\n\n\tconst themeMessage = task.mode ? `Created the page in ${task.mode.toLowerCase()} mode successfully.` : \"\"\n\n\treturn {\n\t\tnodeId: webPage.id,\n\t\tgenerated: rest,\n\t\tmessage: [message, themeMessage].join(\" \"),\n\t\tfollowUpTasks,\n\t}\n}\n\n/**\n * Create a new screen via Wireframer.\n */\nexport async function createScreen(\n\tengine: VekterEngine,\n\tscopeId: NodeID,\n\tinitialFeatureRequest: string,\n\ttask: CreatePage,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<StepResult> {\n\tengine.scheduler.process(() => engine.beginUndoGroup())\n\ttry {\n\t\tconst position = getSuggestedScreenPosition(engine, scopeId)\n\n\t\tconst screen = new FrameNode({\n\t\t\tname: task.name,\n\t\t\t...defaultBreakpointStylingProps,\n\t\t\tleft: position.x,\n\t\t\ttop: position.y,\n\t\t\t// Still need this for the default kit, until it's migrated to a kit with page styles & tokens.\n\t\t\tfillColor: getWireframerPageColor(task.mode ?? PageMode.Light),\n\t\t})\n\n\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\tengine.tree.insertNode(screen, scopeId)\n\t\t\tapplyDefaultLayoutToScreen(engine, screen)\n\n\t\t\tengine.stores.selectionStore.set(screen.id)\n\t\t\tengine.stores.canvasStore.zoomToCenter(\n\t\t\t\t{\n\t\t\t\t\tx: position.x,\n\t\t\t\t\ty: position.y,\n\t\t\t\t\twidth: screen.width,\n\t\t\t\t\theight: screen.height,\n\t\t\t\t},\n\t\t\t\t{ animated: engine.stores.persistedUserDefaults.animateOnZoom },\n\t\t\t)\n\t\t})\n\n\t\t// If the create action request specifies a theme, attempt to update the app theme at the\n\t\t// beginning of the generation, so everything generated would be previewed in the correct\n\t\t// theme.\n\t\tif (task.mode) await applyColorScheme(engine, screen.id, kit, task.mode)\n\n\t\tasync function handleLayout(layoutId: NodeID | undefined) {\n\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\tconst { primaryBreakpoint, pageProperties } = getPageMetaForLayoutUpdate(kit, layoutId)\n\t\t\tif (!primaryBreakpoint) return\n\n\t\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\t\tapplyPagePropertiesToScreen(engine, screen, pageProperties?.[primaryBreakpoint], kit.tokens)\n\t\t\t})\n\t\t}\n\n\t\tconst { message, followUpTasks, ...rest } = await generateSections(\n\t\t\tengine,\n\t\t\tscreen.id,\n\t\t\ttask,\n\t\t\tinitialFeatureRequest,\n\t\t\tundefined,\n\t\t\tscopeId,\n\t\t\tkit,\n\t\t\thandleLayout,\n\t\t\ttraceConfig,\n\t\t)\n\n\t\treturn { nodeId: screen.id, generated: rest, message, followUpTasks }\n\t} finally {\n\t\tengine.scheduler.process(() => engine.endUndoGroup())\n\t}\n}\n\nconst defaultPosition: Point = { x: 0, y: 0 }\nfunction getSuggestedScreenPosition(engine: VekterEngine, scopeId: NodeID): Point {\n\tconst scope = engine.tree.get(scopeId)\n\tassert(isScopeNode(scope) && scope.isLoaded(), \"Scope must be loaded for generation\", scopeId)\n\n\tconst firstScreen = scope.loaded.children.at(0)\n\tif (!firstScreen) return defaultPosition\n\n\tconst firstScreenRect = engine.tree.getRect(firstScreen)\n\tif (!firstScreenRect) return defaultPosition\n\n\treturn rightSideOf(engine.tree, scope, firstScreen, firstScreenRect)\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { StepResult } from \"app/ai/WireframerSession.ts\"\nimport type { DeletePage } from \"app/ai/orchestrator/tasks.ts\"\nimport { getCollectionNameForPage, normalizeRouteForLLM } from \"app/ai/utils/siteMap.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { getRawWebPagePath } from \"document/components/utils/getWebPagePath.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { removePage } from \"../utils/pageOperations.ts\"\n\nexport async function deleteWebPage(engine: VekterEngine, task: DeletePage): Promise<StepResult> {\n\tconst page = engine.tree.get(task.id)\n\tassert(isWebPageNode(page), \"Page should exist\")\n\tconst route = getRawWebPagePath(engine.tree, page)\n\tassert(route, \"Page route should exist\")\n\n\tconst collectionName = getCollectionNameForPage(engine.tree, page)\n\tconst normalizedRoute = normalizeRouteForLLM(route, collectionName)\n\tassert(normalizedRoute !== \"/\", \"Cannot delete the home page\")\n\n\tconst nodeId = await removePage(engine, task)\n\n\treturn { nodeId, message: `Deleted page at route ${normalizedRoute} successfully.` }\n}\n\nexport async function deleteScreen(engine: VekterEngine, task: DeletePage, designPageId: NodeID): Promise<StepResult> {\n\tconst screenId = task.id\n\tassert(screenId, \"DeleteWebPage action for a design page must have a nodeId:\", task, designPageId)\n\tconst screen = engine.tree.get(screenId)\n\tassert(screen, \"Cannot find target screen for change:\", task, designPageId)\n\n\tconst screenName = screen.name\n\n\tif (getIsViewOnly(engine, \"canDesign\")) {\n\t\treturn { nodeId: screen.id, message: \"Unable to delete the page in view only mode.\" }\n\t}\n\n\tconst nodeId = await engine.scheduler.processWhenReadyAsync<NodeID>(() => {\n\t\tengine.deleteNode(screenId)\n\t\treturn screen.id\n\t})\n\n\treturn { nodeId, message: `Deleted screen successfully with name: ${screenName}.` }\n}\n", "import type { StepResult } from \"app/ai/WireframerSession.ts\"\nimport type { UpdatePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isFrameNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { assert } from \"library/utils/assert.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { generateSections } from \"../generateWebPage.ts\"\nimport { applyColorScheme } from \"../utils/colorScheme.ts\"\nimport {\n\tapplyBreakpointOverrides,\n\tapplyPagePropertiesToScreen,\n\tgetPageMetaForLayoutUpdate,\n\tupdatePage,\n} from \"../utils/pageOperations.ts\"\nimport { getExistingKitSectionsStructure } from \"../utils/prompts/promptBuilder.ts\"\n\nexport async function modifyWebPage(\n\tengine: VekterEngine,\n\tinitialFeatureRequest: string,\n\ttask: UpdatePage,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<StepResult> {\n\tconst webPageNode = await updatePage(engine, task, kit)\n\tassert(webPageNode, \"Web page node should be defined\")\n\n\tconst primaryBreakpoint = webPageNode.getPrimaryVariant()\n\tconst { message, followUpTasks, ...rest } = await engine.stores.chromeStore.runAIGeneration(() =>\n\t\tgenerateSections(\n\t\t\tengine,\n\t\t\tprimaryBreakpoint.id,\n\t\t\ttask,\n\t\t\tinitialFeatureRequest,\n\t\t\tgetExistingKitSectionsStructure(engine, undefined, primaryBreakpoint.id, kit),\n\t\t\tundefined,\n\t\t\tkit,\n\t\t\tasync (layoutId: NodeID | undefined) => {\n\t\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\t\t// When the LLM picks a layout while updating an existing page, we try to apply the\n\t\t\t\t// layout properties to the existing breakpoints, so when we swapped the detached\n\t\t\t\t// sections back to the layout template, visually it would be seamless.\n\t\t\t\tconst { primaryBreakpoint: primaryBreakpointId, pageProperties } = getPageMetaForLayoutUpdate(kit, layoutId)\n\n\t\t\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\t\t\tif (primaryBreakpointId) {\n\t\t\t\t\t\tapplyPagePropertiesToScreen(engine, primaryBreakpoint, pageProperties?.[primaryBreakpointId], kit.tokens)\n\t\t\t\t\t}\n\n\t\t\t\t\tapplyBreakpointOverrides(engine, kit, webPageNode.draftOrCurrent(), layoutId)\n\t\t\t\t})\n\t\t\t},\n\t\t\ttraceConfig,\n\t\t),\n\t)\n\n\t// After the generation wait for the code generation to be idle to avoid race conditions with kit-section structure.\n\tawait engine.stores.codeGenerationStore.updateComponent(webPageNode.id)\n\n\tconst themeMessage = task.mode ? `Updated the page theme to ${task.mode.toLowerCase()} mode successfully.` : \"\"\n\n\treturn {\n\t\tnodeId: webPageNode.id,\n\t\tmode: task.mode,\n\t\tgenerated: rest,\n\t\tmessage: [message, themeMessage].join(\" \"),\n\t\tfollowUpTasks,\n\t}\n}\n\nexport async function modifyScreen(\n\tengine: VekterEngine,\n\tinitialFeatureRequest: string,\n\ttask: UpdatePage,\n\tdesignPageId: NodeID,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<StepResult> {\n\tconst screen = engine.tree.get(task.id)\n\tassert(isFrameNode(screen), \"Cannot find screen for change:\", screen, task, designPageId)\n\n\tengine.stores.selectionStore.set(screen.id)\n\tengine.stores.canvasStore.zoomToCenter(engine.tree.getRect(screen), {\n\t\tanimated: engine.stores.persistedUserDefaults.animateOnZoom,\n\t})\n\n\tengine.scheduler.process(() => engine.beginUndoGroup())\n\n\ttry {\n\t\t// If the change involved a theme change specifically, update the screen to match the theme\n\t\t// first.\n\t\tif (task.mode) await applyColorScheme(engine, screen.id, kit, task.mode)\n\n\t\tconst { message, followUpTasks, ...rest } = await generateSections(\n\t\t\tengine,\n\t\t\tscreen.id,\n\t\t\ttask,\n\t\t\tinitialFeatureRequest,\n\t\t\tgetExistingKitSectionsStructure(engine, designPageId, screen.id, kit),\n\t\t\tdesignPageId,\n\t\t\tkit,\n\t\t\tasync (layoutId: NodeID | undefined) => {\n\t\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\t\t\tconst { primaryBreakpoint: primaryBreakpointId, pageProperties } = getPageMetaForLayoutUpdate(kit, layoutId)\n\n\t\t\t\tif (!primaryBreakpointId) return\n\n\t\t\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\t\t\t// Design page screens are always created with the primary 'breakpoint' only.\n\t\t\t\t\tapplyPagePropertiesToScreen(engine, screen, pageProperties?.[primaryBreakpointId], kit.tokens)\n\t\t\t\t})\n\t\t\t},\n\t\t\ttraceConfig,\n\t\t)\n\n\t\treturn { nodeId: screen.id, mode: task.mode, generated: rest, message, followUpTasks }\n\t} finally {\n\t\tengine.scheduler.process(() => engine.endUndoGroup())\n\t}\n}\n", "import type { StepResult } from \"app/ai/WireframerSession.ts\"\nimport { isDefaultKit } from \"app/ai/kits/DefaultKit.ts\"\nimport type { ThemePage } from \"app/ai/orchestrator/tasks.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { assert } from \"library/utils/assert.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { applyColorScheme } from \"../utils/colorScheme.ts\"\nimport { updatePage } from \"../utils/pageOperations.ts\"\n\nexport async function updateDarkMode(engine: VekterEngine, task: ThemePage, kit: WireframerKit): Promise<StepResult> {\n\tconst webPageNode = await updatePage(engine, task, kit, false)\n\tassert(webPageNode, \"Web page node should be defined when updating dark mode\")\n\n\t// After the generation wait for the code generation to be idle to avoid race conditions.\n\tawait engine.stores.codeGenerationStore.updateComponent(webPageNode.id)\n\n\treturn {\n\t\tnodeId: webPageNode.id,\n\t\tmode: task.mode,\n\t\tmessage: isDefaultKit(kit)\n\t\t\t? `Updated the page theme to ${task.mode.toLowerCase()} mode successfully.`\n\t\t\t: \"Switched the app mode to show the requested theme.\",\n\t}\n}\n\nexport async function updateScreenDarkMode(\n\tengine: VekterEngine,\n\ttask: ThemePage,\n\tdesignPageId: NodeID,\n\tkit: WireframerKit,\n): Promise<StepResult> {\n\tconst screen = engine.tree.get(task.id)\n\tassert(screen, \"Cannot find target screen for change:\", task, designPageId)\n\n\tif (getIsViewOnly(engine, \"canDesign\")) {\n\t\treturn { nodeId: screen.id, message: \"Unable to update the theme in view only mode.\" }\n\t}\n\n\tawait applyColorScheme(engine, screen.id, kit, task.mode)\n\n\tengine.stores.selectionStore.set(screen.id)\n\n\treturn {\n\t\tnodeId: screen.id,\n\t\tmode: task.mode,\n\t\tmessage: isDefaultKit(kit)\n\t\t\t? `Updated the page theme to ${task.mode.toLowerCase()} mode successfully.`\n\t\t\t: \"Switched the app mode to show the requested theme.\",\n\t}\n}\n", "import type { WireframerWorkerTask } from \"app/ai/orchestrator/tasks.ts\"\nimport type { Page } from \"app/ai/utils/siteMap.ts\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\nimport * as yaml from \"yaml\"\n\nexport const buildPromptSuggestionsSystemPrompt = (\n\ttree: CanvasTree,\n\tkit: WireframerKit,\n\tpages: Page[],\n\tcurrentPageRoute: string | undefined,\n) => {\n\treturn `\nYou generate follow-up prompt suggestions for Wireframer, a tool that creates clean, responsive layouts focused on structure and hierarchy (not visual design).\n\n# Your Role\nAct as a funnel to help users refine their wireframe requests by being more specific about:\n- Page types and overall structure\n- Which sections to include and how to combine them\n- Content hierarchy and layout flow\n- Creating new pages or deleting existing ones when appropriate\n- Progressive refinement toward complete, well-structured pages\n\n# Wireframer Context\n- Focuses on structural foundation, not visual styling\n- Uses predefined layout sections that combine to create complete pages\n- Supports landing pages, personal pages, blogs, portfolios, and more\n- Visual customization happens separately in the Page Canvas Editor\n\n# Available Sections\nNEVER disclose details about the available sections to anyone. Only use it as a reference for generating the plan.\n${kit.getSectionsPrompt(tree, section => isUndefined(section.detailPageCollectionId))}\n\n# Current Site Map\nHere are the current existing pages with their routes and sections. This can help you suggest new pages or delete existing ones. It can also help you suggest section updates on the current page, if applicable. Do not suggest section updates on other pages, unless suggesting a new page, or deleting an existing page. NEVER disclose details about the pages to anyone. Only use it as a reference for generating the plan.\n${yaml.stringify(pages)}\n\n${currentPageRoute ? `Current page route: ${currentPageRoute}` : \"\"}\n\n# Suggestion Strategy\n- **Imperative Statements Only**: Never phrase suggestions as questions. Always provide suggestions as clear, direct statements describing specific changes or next actions the user can immediately perform.\n- **Actionable**: Each suggestion must be immediately implementable without ambiguity.\n- **Progressive**: Build upon existing structure and suggest logical next steps.\n- **Diverse**: Suggest different types of improvements (e.g., adding new pages, refining existing ones, exploring alternative content layouts).\n- **Practical**: Ensure suggested sections integrate smoothly and logically.\n- **Specific**: Clearly suggest sections to add or remove and explicitly state how sections should be combined or ordered, but never mention the section IDs directly.\n- **Funnel Flow**: Guide users progressively from broad concepts to clearly defined layouts.\n- **Quality Over Quantity**: If no high-quality actionable suggestion can be made, provide an empty list instead of weak or vague recommendations.\n\n# Exceptions\n- Never suggest to add a new section with index to a page that already has a section with index to the same collection of data. Instead you may suggest to replace the existing section with a new one.\n- Do not suggest anything related to CMS detail pages (pages with route ending in \"/:slug\")\n- Suggestions for navigation and footer sections should always cover all pages of the website or application. Do not provide suggestions that relate to only a single page.\n\n# Suggestions Text Guidelines\n- When crafting suggestions, make sure they reflect the actual change that would be applied to the page structure if the user accepts it.\n- Suggestions are never questions to the user, do not ask for user input or confirmation.\n- Never mention technical details or sectionIds.\n- Phrase suggestions as if you are the user and use the same language as the user's request.\n\n## Short Text\n- Be precise with verbs in suggestions 'shortText'.\n- Prefer high-signal verbs and nouns (e.g., \u201CAdd FAQ\u201D, \u201CImprove copy\u201D, \u201CReplace hero\u201D)\n- You can also suggest updating navigation and footer sections as long as they are consistent in the different pages.\n- If the user's action will result in an existing section being replaced or removed to make way for a new one, use the verb \"Replace\" or \"Swap\", not \"Add\". Only if the section that is going to replace the old section has the same fields as the old section plus a few more fields (1 or more) use \"Add\".\n- If a section is going to be added and nothing is implicitly removed or replaced use the verb \"Add\".\n- Be honest and accurate.\n- Be concise and to the point.\n- Abbreviate common terms if necessary (e.g., \u201CCTA\u201D for call-to-action, \u201Cnav\u201D for navigation)\n- Drop non-essential articles or filler words\n- Whitespaces count as characters. Each whitespace is 1 character.\n- Never ends with a period (.), this would be considered invalid output.\n- Use a maximum of 30 characters. NEVER allow 'shortText' to exceed 30 characters, not even slightly.\n- Never oversimplify or exaggerate the change. If the change implies several differences or affects multiple sections, pick and highlight the main one.\n`\n}\n\nexport function generateUserPrompt(featureRequest: string, plan: readonly WireframerWorkerTask[]) {\n\treturn `\n    Analyze this wireframer interaction and generate targeted follow-up suggestions:\n\n    ## User's Original Request\n    \"${featureRequest}\"\n\n    ## What was just executed by Wireframer\n    ${yaml.stringify(plan)}\n    `\n}\n", "import { Output, generateText } from \"ai\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { WireframerWorkerTask } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport type { Suggestion } from \"app/ai/types/AIChatHistory.ts\"\nimport { PromptSuggestion } from \"app/ai/types/AIChatHistory.ts\"\nimport { getWebPagesSiteMap } from \"app/ai/utils/siteMap.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { AIGenerationStore } from \"document/stores/AIGenerationStore.ts\"\nimport type { ScopeStore } from \"document/stores/ScopeStore.ts\"\nimport { z } from \"zod\"\nimport type { WireframerKit } from \"../../utils/wireframerKit.ts\"\nimport { buildPromptSuggestionsSystemPrompt, generateUserPrompt } from \"./utils/promptBuilder.ts\"\n\nexport async function getPromptSuggestions(\n\ttree: CanvasTree,\n\tscopeStore: ScopeStore,\n\taiGenerationStore: AIGenerationStore,\n\tfeatureRequest: string,\n\tplan: readonly WireframerWorkerTask[],\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<Suggestion[]> {\n\t// We don't show suggestions on design pages, so okay to assume that this is for web pages only.\n\t// Let's get the site map again to make sure it includes all newly created/updated pages.\n\tconst { pages, currentPageRoute } = getWebPagesSiteMap(tree, scopeStore, aiGenerationStore, kit)\n\n\tconst { output } = await generateText({\n\t\tmodel: openRouter(LanguageModel.GeminiFlash25, {\n\t\t\textraBody: createVekterOpenRouterExtraBody({\n\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\tstep: \"prompt-suggestions\",\n\t\t\t\t...traceConfig,\n\t\t\t}),\n\t\t}),\n\t\toutput: Output.object({\n\t\t\tschema,\n\t\t}),\n\t\tsystem: buildPromptSuggestionsSystemPrompt(tree, kit, pages, currentPageRoute),\n\t\tmessages: [{ role: \"user\", content: generateUserPrompt(featureRequest, plan) }],\n\t})\n\n\treturn output.suggestions\n}\n\nconst schema = z.object({\n\tsuggestions: z\n\t\t.array(PromptSuggestion)\n\t\t.max(3, \"Suggestions should be at most 3 items\")\n\t\t.describe(\"List of suggestions for further refining the website or empty array.\"),\n})\n", "// As of 15/07/2025, the resources list only includes the lessons from the Framer Academy.\n// For the moment, it's fine to not automatically populate the resources list.\n\n// To obtain them, we simply perform a CSV export of the `Academy Lessons` Collection on the Site project (https://framer.com/projects/Site--8fqVJpvFoZgxIjNnhLvt).\n// Then, we simply concatenated the `Short Title` and `Slug` fields to include the base URL and format the URL as a markdown link.\n// Here is the Google sheet we used (https://docs.google.com/spreadsheets/d/1Zku-lvdNGvkQoiYoPfOiqN2ROe_aDg3jI48YC5iojQ4/edit?usp=sharing).\n\nexport const resourceSuggestionsSystemPrompt = `You are a resource assistant for Wireframer, an AI system that helps users create and modify web pages through natural language requests.\n\nYour goal is to provide helpful guidance and resources when a user's feature request falls outside of Wireframer's capabilities.\n\n# Output Format\n\nYour response must follow this structure exactly:\n\n- **resources**: Array of ResourceSuggestion objects - Recommend relevant documentation, videos, or tutorials that could help\n\t- variant: Always \"resource\" (literal value)\n\t- text: Brief description of the resource\n\t- url: URL of the resource\n\n## Resource Selection Strategy\n\n- Maximum 3 suggestions per response\n- Choose resources that are most relevant to the user's request and the reason why it failed in Wireframer\n- Prioritize resources that provide alternatives or workarounds for achieving similar goals\n- Focus on educational content that helps users understand what's possible in Framer\n- If the user request was completely or partially fulfilled by Wireframer, do not suggest resources, send empty array instead.\n\n# Available Resources\n\nHere are some resources that you can choose from to help the user when a request is invalid:\n\n## SEO & Accessibility\n- [SEO testing](https://www.framer.com/academy/lessons/framer-seo-testing-auditing)\n- [Site settings & accessibility](https://www.framer.com/academy/lessons/framer-seo-site-settings)\n- [Page titles, descriptions, & URLs](https://www.framer.com/academy/lessons/framer-seo-titles-descriptions-urls)\n- [Optimizing images and graphics](https://www.framer.com/academy/lessons/framer-seo-optimizing-images)\n- [Structuring content with semantic tags](https://www.framer.com/academy/lessons/framer-seo-semantic-tags)\n- [Intro to SEO & accessibility](https://www.framer.com/academy/lessons/framer-seo-introduction)\n\n## Animations & Effects\n- [Animating vector paths](https://www.framer.com/academy/lessons/framer-animations-vector-effects)\n- [Animating text](https://www.framer.com/academy/lessons/framer-animations-text-effects)\n- [Setting up custom cursors](https://www.framer.com/academy/lessons/framer-animations-custom-cursors)\n- [Creating persistent animations between pages](https://www.framer.com/academy/lessons/framer-animations-persistent-transition-elements)\n- [Animating transitions between pages](https://www.framer.com/academy/lessons/framer-animations-page-transition-effects)\n- [Using Events for nested interactions](https://www.framer.com/academy/lessons/framer-animations-component-events)\n- [Effects at the component level](https://www.framer.com/academy/lessons/framer-animations-component-effects)\n- [Creating animated component interactions](https://www.framer.com/academy/lessons/framer-animations-component-interactions)\n- [Animating between variants on scroll](https://www.framer.com/academy/lessons/framer-animations-scroll-variants)\n- [Creating parallax with Scroll Speed](https://www.framer.com/academy/lessons/framer-animations-scroll-speed-parallax)\n- [Transforming elements on scroll](https://www.framer.com/academy/lessons/framer-animations-scroll-transform)\n- [Triggering animations on scroll](https://www.framer.com/academy/lessons/framer-animations-trigger-on-scroll)\n- [Using the Appear Effect](https://www.framer.com/academy/lessons/framer-animations-appear-effect)\n- [Using the Drag Effect](https://www.framer.com/academy/lessons/framer-animations-drag-effect)\n- [Using the Loop Effect](https://www.framer.com/academy/lessons/framer-animations-loop-effect)\n- [Mastering transitions and easing](https://www.framer.com/academy/lessons/framer-animations-transitions-and-easing)\n- [Using Hover and Press Effects](https://www.framer.com/academy/lessons/framer-animations-hover-and-press-effects)\n- [Bringing websites to life with animation](https://www.framer.com/academy/lessons/bringing-websites-to-life-with-animation)\n\n## Advanced Features\n- [Creating advanced components with Workshop](https://www.framer.com/academy/lessons/creating-advanced-components-with-workshop)\n- [Generating layouts with AI using Wireframer](https://www.framer.com/academy/lessons/generating-layouts-with-ai-using-wireframer)\n- [Funnels & AB testing](https://www.framer.com/academy/lessons/funnels-a-b-testing)\n- [Workspace plugins](https://www.framer.com/academy/lessons/workspace-plugins)\n- [CMS plugins](https://www.framer.com/academy/lessons/cms-plugins)\n- [Index variable](https://www.framer.com/academy/lessons/index-variable)\n- [REM sizing](https://www.framer.com/academy/lessons/rem-sizing)\n\n## CMS & Content Management\n- [Utilizing collection lists in Framer](https://www.framer.com/academy/lessons/creating-cms-collection-lists)\n- [CMS pages & dynamic content](https://www.framer.com/academy/lessons/cms-pages-dynamic-content)\n- [Understanding CMS collections, items & fields](https://www.framer.com/academy/lessons/understanding-cms-collections-items-fields)\n- [What is the Framer CMS?](https://www.framer.com/academy/lessons/what-is-framer-cms)\n- [CMS canvas sorting](https://www.framer.com/academy/lessons/cms-canvas-sorting)\n- [CMS references](https://www.framer.com/academy/lessons/cms-collection-references-introduction)\n\n## Fundamentals\n- [Analytics](https://www.framer.com/academy/lessons/framer-fundamentals-analytics)\n- [Publishing and domains](https://www.framer.com/academy/lessons/framer-fundamentals-publishing)\n- [Choosing a plan](https://www.framer.com/academy/lessons/framer-fundamentals-choosing-the-right-plan-for-your-site)\n- [Site and page settings](https://www.framer.com/academy/lessons/framer-fundamentals-site-and-page-settings)\n- [SEO and accessibility](https://www.framer.com/academy/lessons/framer-fundamentals-optimizing-for-search-engines-and-accessibility)\n- [Creating breakpoints](https://www.framer.com/academy/lessons/framer-fundamentals-breakpoints)\n- [Designing fluid layouts](https://www.framer.com/academy/lessons/framer-fundamentals-designing-fluid-layouts)\n- [What is responsive design?](https://www.framer.com/academy/lessons/framer-fundamentals-what-is-responsive-design)\n- [Layout templates](https://www.framer.com/academy/lessons/framer-fundamentals-layout-templates)\n- [Components](https://www.framer.com/academy/lessons/framer-fundamentals-components)\n- [Themes](https://www.framer.com/academy/lessons/framer-fundamentals-themes)\n- [Text styles](https://www.framer.com/academy/lessons/framer-fundamentals-text-styles)\n- [Link and color Styles](https://www.framer.com/academy/lessons/framer-fundamentals-styles)\n- [Text properties](https://www.framer.com/academy/lessons/framer-fundamentals-text-properties)\n- [Styling frames](https://www.framer.com/academy/lessons/framer-fundamentals-styling-frames)\n- [Adding links](https://www.framer.com/academy/lessons/framer-fundamentals-adding-links)\n- [Importing from Figma and the web](https://www.framer.com/academy/lessons/framer-fundamentals-importing-from-figma-and-the-web)\n- [The insert panel](https://www.framer.com/academy/lessons/framer-fundamentals-the-insert-panel)\n- [Adding images, video, and text](https://www.framer.com/academy/lessons/framer-fundamentals-adding-images-video-and-text)\n- [Min and max sizing](https://www.framer.com/academy/lessons/framer-fundamentals-min-and-max-sizing)\n- [Relative, fixed, and viewport sizing](https://www.framer.com/academy/lessons/framer-fundamentals-fixed-and-relative-sizing)\n- [Fixed and sticky positioning](https://www.framer.com/academy/lessons/framer-fundamentals-fixed-and-sticky-positioning)\n- [Stacks vs grids](https://www.framer.com/academy/lessons/framer-fundamentals-stacks-vs-grids)\n- [Sizing to fill and fit content](https://www.framer.com/academy/lessons/framer-fundamentals-sizing-to-fill-and-fit-content)\n- [Stacks and relative positioning](https://www.framer.com/academy/lessons/framer-fundamentals-stacks-and-relative-positioning)\n- [Absolute positioning](https://www.framer.com/academy/lessons/framer-fundamentals-absolute-positioning)\n- [Thinking in frames](https://www.framer.com/academy/lessons/framer-fundamentals-thinking-in-frames)\n- [Interacting with layers](https://www.framer.com/academy/lessons/framer-fundamentals-interacting-with-layers)\n- [The anatomy of a project](https://www.framer.com/academy/lessons/framer-fundamentals-the-anatomy-of-a-framer-project)\n- [The Framer interface](https://www.framer.com/academy/lessons/framer-fundamentals-framer-interface)\n\n## Forms & Interactions\n- [Creating your first form](https://www.framer.com/academy/lessons/creating-your-first-form)\n- [Optional form input props](https://www.framer.com/academy/lessons/optional-form-input-props)\n- [Custom form submit buttons](https://www.framer.com/academy/lessons/custom-form-submit-button)\n- [Update Form Status](https://www.framer.com/academy/lessons/update-form-status)\n- [Form input variants & validation](https://www.framer.com/academy/lessons/input-variants-and-validation)\n\n## Advanced Techniques\n- [Fetch](https://www.framer.com/academy/lessons/fetch)\n- [Text Effects](https://www.framer.com/academy/lessons/text-effects)\n- [Localize your site](https://www.framer.com/academy/lessons/localization)\n- [3D Transforms](https://www.framer.com/academy/lessons/3d-transforms)\n- [Advanced Localization](https://www.framer.com/academy/lessons/advanced-localization)\n- [Custom Cursors](https://www.framer.com/academy/lessons/custom-cursors)\n- [Creative Elements](https://www.framer.com/academy/lessons/creative-elements)\n- [How to use Templates](https://www.framer.com/academy/lessons/how-to-use-templates)\n- [Stack Variables](https://www.framer.com/academy/lessons/stack-variables)\n- [Prepare your Template](https://www.framer.com/academy/lessons/get-your-template-ready)\n- [AI Translations Style](https://www.framer.com/academy/lessons/ai-style)\n- [Page Effects](https://www.framer.com/academy/lessons/page-effects)\n- [Component Effects](https://www.framer.com/academy/lessons/component-effects)\n- [Creative Effects](https://www.framer.com/academy/lessons/light-effects)\n- [Wave Animation](https://www.framer.com/academy/lessons/wave-animation)\n- [Apple Zoom Scroll Effect](https://www.framer.com/academy/lessons/zoom-scroll-effect)\n- [Canvas-like website](https://www.framer.com/academy/lessons/canvas-like-website)\n- [Sell on Lemon Squeezy](https://www.framer.com/academy/lessons/sell-on-lemon-squeezy)\n- [Metadata](https://www.framer.com/academy/lessons/metadata)\n- [Password Protection](https://www.framer.com/academy/lessons/password-protection)\n- [Custom Code](https://www.framer.com/academy/lessons/custom-code)\n- [Redirects](https://www.framer.com/academy/lessons/redirects)\n- [Versions](https://www.framer.com/academy/lessons/staging-versions)\n\n## Components & UI Elements\n- [Carousel](https://www.framer.com/academy/lessons/carousel)\n- [Cookie Banner](https://www.framer.com/academy/lessons/cookie-banner-component)\n- [Input](https://www.framer.com/academy/lessons/input)\n- [Search](https://www.framer.com/academy/lessons/search)\n- [Slideshow](https://www.framer.com/academy/lessons/slideshow)\n- [Ticker](https://www.framer.com/academy/lessons/ticker)\n- [Desktop Menu](https://www.framer.com/academy/lessons/desktop-menus)\n- [Mobile Menu](https://www.framer.com/academy/lessons/mobile-menu)\n- [Mobile Menu: Fade-In](https://www.framer.com/academy/lessons/mobile-menu-fade-in)\n- [Responsive Dropdown Menu](https://www.framer.com/academy/lessons/responsive-dropdown-menu)\n- [Overlays](https://www.framer.com/academy/lessons/overlays)\n\n## Advanced Features & Filtering\n- [CSV import](https://www.framer.com/academy/lessons/csv-import)\n- [Filtering](https://www.framer.com/academy/lessons/cms-filtering)\n- [Date Filtering](https://www.framer.com/academy/lessons/date-filtering)\n- [Conditionals & Transforms](https://www.framer.com/academy/lessons/conditionals-transforms)\n\n## Layout & Scroll Effects\n- [Scroll Sections](https://www.framer.com/academy/lessons/scroll-sections)\n- [Horizontal Side Scroller](https://www.framer.com/academy/lessons/horizontal-side-scroller)\n- [Scroll Direction](https://www.framer.com/academy/lessons/scroll-direction)\n- [Relative Overlays](https://www.framer.com/academy/lessons/relative-overlays)\n- [Scroll Targets](https://www.framer.com/academy/lessons/scroll-targets)\n- [Sticky Scrolling](https://www.framer.com/academy/lessons/sticky-scrolling)\n- [Scroll Animations](https://www.framer.com/academy/lessons/scroll-animations)\n- [Scroll Transforms](https://www.framer.com/academy/lessons/scroll-transforms)\n- [Scroll Variant](https://www.framer.com/academy/lessons/scroll-variant)\n\n## Styling & Design\n- [Bold & Italic](https://www.framer.com/academy/lessons/bold-italic)\n- [Code Blocks](https://www.framer.com/academy/lessons/code-blocks)\n- [Viewport Height](https://www.framer.com/academy/lessons/viewport-height)\n- [Light & Dark Mode](https://www.framer.com/academy/lessons/light-dark-mode)\n- [Realistic Shadows](https://www.framer.com/academy/lessons/realistic-shadows)\n- [Fit Text](https://www.framer.com/academy/lessons/fit-text)\n- [Selection colors](https://www.framer.com/academy/lessons/selection-colors)\n- [Scale tool (K)](https://www.framer.com/academy/lessons/scale-tool-(k))\n- [5 hidden design features](https://www.framer.com/academy/lessons/5-hidden-design-features)\n\n## Getting Started\n- [Build Your First Site](https://www.framer.com/academy/lessons/build-your-first-site)\n- [Intro](https://www.framer.com/academy/lessons/intro)\n- [Setting Up Your CMS](https://www.framer.com/academy/lessons/setting-up-your-cms)\n- [Creating your Navigation](https://www.framer.com/academy/lessons/creating-your-navigation)\n- [Adding Search](https://www.framer.com/academy/lessons/adding-search)\n- [Adding the Homepage](https://www.framer.com/academy/lessons/adding-the-homepage)\n- [Publishing the site](https://www.framer.com/academy/lessons/publishing-the-site)\n- [Version History](https://www.framer.com/academy/lessons/version-history)\n- [Drafts](https://www.framer.com/academy/lessons/drafts)\n- [10 Framer shortcuts to supercharge your productivity](https://www.framer.com/academy/lessons/10-framer-shortcuts-to-supercharge-your-productivity)\n`\n", "import { Output, generateText } from \"ai\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport { ResourceSuggestion } from \"app/ai/types/AIChatHistory.ts\"\nimport z from \"zod\"\nimport { resourceSuggestionsSystemPrompt } from \"./utils/systemPrompt.ts\"\n\nexport async function getSuggestedResources(\n\tfeatureRequest: string,\n\tfinalMessage: string,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<ResourceSuggestion[]> {\n\tconst result = await generateText({\n\t\tmodel: openRouter(LanguageModel.GeminiFlash25Lite, {\n\t\t\textraBody: createVekterOpenRouterExtraBody({\n\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\tstep: \"resource-suggestions\",\n\t\t\t\t...traceConfig,\n\t\t\t}),\n\t\t}),\n\t\toutput: Output.object({\n\t\t\tschema,\n\t\t}),\n\t\tsystem: resourceSuggestionsSystemPrompt,\n\t\tmessages: [{ role: \"user\", content: generateUserPrompt(featureRequest, finalMessage) }],\n\t})\n\n\treturn result.output.resources\n}\n\nconst userPromptPrefix =\n\t\"Analyze a feature request and the final result that summarizes all that was possible or not to fulfill and suggest resources that can be used to help the user.\"\n\nfunction generateUserPrompt(featureRequest: string, finalMessage: string) {\n\treturn `${userPromptPrefix}${featureRequest}\\n\\nFinal result summary: ${finalMessage}`\n}\n\nconst schema = z.object({\n\tresources: z\n\t\t.array(ResourceSuggestion)\n\t\t.max(3, \"Maximum 3 suggested resources\")\n\t\t.describe(\n\t\t\t\"List of suggested resources that can be used to help the user. If you don't have any suggestions, it should be undefined.\",\n\t\t),\n})\n", "import { assert, assertNever } from \"@framerjs/shared\"\nimport { CommandType } from \"app/ai/orchestrator/dsl.ts\"\nimport type { AddCMSItems, UpdateCMSItems } from \"app/ai/orchestrator/tasks.ts\"\nimport type { CanvasTree, CollectionNode } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type {\n\tCollectionReferenceVariableDefinition,\n\tMultiCollectionReferenceVariableDefinition,\n\tVariableDefinition,\n} from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { isVariableDefinition } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { getCollectionForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { z } from \"zod\"\n\nexport function createZodSchemaForCollection(tree: CanvasTree, task: AddCMSItems | UpdateCMSItems) {\n\tconst collectionNode = tree.get(task.collection)\n\tassert(isCollectionNode(collectionNode), \"Collection node not found\", task.collection)\n\n\tconst collectionName = collectionNode.resolveValue(\"name\")\n\tassert(collectionName, \"Collection must have a name\")\n\n\t// 1. Build the variables schema.\n\tconst itemShape = createItemShape(tree, collectionNode)\n\n\t// 2. Build the collection schema.\n\tconst isUpdate = task.type === CommandType.UpdateCMSItems\n\n\tconst itemSchema = isUpdate ? z.object(itemShape).partial() : z.object(itemShape)\n\n\treturn z.object({\n\t\titems: z\n\t\t\t.array(itemSchema)\n\t\t\t.min(1)\n\t\t\t.describe(\n\t\t\t\tisUpdate\n\t\t\t\t\t? `Updated items for ${collectionName} collection`\n\t\t\t\t\t: `Generated items for ${collectionName} collection`,\n\t\t\t),\n\t})\n}\n\nfunction createItemShape(tree: CanvasTree, collectionNode: CollectionNode): Record<string, z.ZodTypeAny> {\n\tconst shape: Record<string, z.ZodTypeAny> = {}\n\n\tfor (const variable of collectionNode.variables) {\n\t\tif (!isVariableDefinition(variable)) continue\n\n\t\tconst fieldSchema = createZodSchemaForVariableType(tree, variable)\n\t\tif (!fieldSchema) continue\n\n\t\tshape[variable.name] = fieldSchema\n\t}\n\n\treturn shape\n}\n\nfunction createZodSchemaForVariableType(tree: CanvasTree, variable: VariableDefinition): z.ZodTypeAny | undefined {\n\tconst variableName = variable.name\n\n\tswitch (variable.type) {\n\t\tcase ControlType.Boolean:\n\t\t\treturn z.boolean().describe(`Boolean value for ${variableName}`)\n\t\tcase ControlType.Color:\n\t\t\treturn z.string().describe(`Color value for ${variableName} (hex, rgb, etc.)`)\n\t\tcase ControlType.Date:\n\t\t\treturn z.string().datetime().describe(`Date value for ${variableName} (ISO format)`)\n\t\tcase ControlType.Enum:\n\t\t\treturn z.enum(variable.cases.map(c => c.name) as [string, ...string[]]).describe(`Enum value for ${variableName}`)\n\t\tcase ControlType.Image:\n\t\t\treturn z.string().describe(`Image alt value for ${variableName}`)\n\t\tcase ControlType.Link:\n\t\t\treturn z.string().url().describe(`URL for ${variableName}`)\n\t\tcase ControlType.Number:\n\t\t\treturn z.number().describe(`Number value for ${variableName}`)\n\t\tcase ControlType.RichText:\n\t\t\treturn z\n\t\t\t\t.string()\n\t\t\t\t.describe(\n\t\t\t\t\t`Rich text (HTML allowed: <p>, <h2>, <h3>, <strong>, <em>, <ul>, <li>; no styles or scripts) for ${variableName}`,\n\t\t\t\t)\n\t\tcase ControlType.String:\n\t\tcase \"slug\":\n\t\t\treturn z.string().describe(`${variableName} field`)\n\t\tcase ControlType.VectorSetItem: {\n\t\t\tconst iconSetId = variable.setModuleId\n\n\t\t\treturn z\n\t\t\t\t.string()\n\t\t\t\t.describe(\n\t\t\t\t\ticonSetId\n\t\t\t\t\t\t? `Icon name from the \"${iconSetId}\" icon set (see Icon Sets Catalog for available options)`\n\t\t\t\t\t\t: `Icon value for ${variableName}`,\n\t\t\t\t)\n\t\t}\n\t\tcase ControlType.CollectionReference:\n\t\tcase ControlType.MultiCollectionReference:\n\t\t\treturn createZodSchemaForCollectionReference(tree, variable)\n\t\t// Unsupported variable types\n\t\tcase ControlType.Array:\n\t\tcase ControlType.BorderRadius:\n\t\tcase ControlType.Border:\n\t\tcase ControlType.BoxShadow:\n\t\tcase ControlType.Cursor:\n\t\tcase ControlType.CustomCursor:\n\t\tcase ControlType.EventHandler:\n\t\tcase ControlType.File:\n\t\tcase ControlType.Gap:\n\t\tcase ControlType.LinkRelValues:\n\t\tcase ControlType.Transition:\n\t\tcase ControlType.ScrollSectionRef:\n\t\tcase ControlType.Padding:\n\t\tcase ControlType.TrackingId:\n\t\tcase ControlType.Location:\n\t\tcase \"controlReference\":\n\t\tcase \"nodePropertyControlReference\":\n\t\t\treturn undefined\n\t\tdefault:\n\t\t\tassertNever(variable, \"Unsupported variable type\")\n\t}\n}\n\nfunction createZodSchemaForCollectionReference(\n\ttree: CanvasTree,\n\tvariable: CollectionReferenceVariableDefinition | MultiCollectionReferenceVariableDefinition,\n): z.ZodTypeAny | undefined {\n\tconst targetCollection = getCollectionForIdentifier(tree, variable.dataIdentifier)\n\tassert(targetCollection, `Target collection \"${variable.dataIdentifier}\" not found`)\n\n\tconst targetCollectionName = targetCollection.resolveValue(\"name\")\n\tassert(targetCollectionName, \"Target collection must have a name\")\n\n\tconst slugVariable = targetCollection.getSlugVariable()\n\tassert(slugVariable, `Slug variable not found for collection \"${variable.dataIdentifier}\"`)\n\n\tconst itemSchema = z.object({\n\t\t[slugVariable.name]: z\n\t\t\t.string()\n\t\t\t.describe(`Slug value for the item in the ${targetCollectionName} collection to associate with ${variable.name}`),\n\t})\n\n\tconst isSingleReference = variable.type === ControlType.CollectionReference\n\tif (isSingleReference) {\n\t\treturn itemSchema.describe(`Object with properties for ${variable.name}`)\n\t}\n\n\treturn z.array(itemSchema).describe(`List of items for ${variable.name}`)\n}\n", "import { cmsSchemaParams, makeSchema } from \"prosemirror/schema/index.ts\"\nimport { parseRichText, serializeRichText } from \"prosemirror/serialization/dom.ts\"\n\nconst incompleteTagRegex = /<[^>]*$/\nconst tagRegex = /<\\/?([a-z][a-z0-9]*)[^>]*>/gi\n\nconst selfClosingTags = [\n\t\"br\",\n\t\"hr\",\n\t\"img\",\n\t\"input\",\n\t\"meta\",\n\t\"link\",\n\t\"area\",\n\t\"base\",\n\t\"col\",\n\t\"embed\",\n\t\"param\",\n\t\"source\",\n\t\"track\",\n\t\"wbr\",\n]\n\n/**\n * Sanitizes a rich text string by:\n *  - closing any open tags,\n *  - adding data-preset-tag attributes,\n *  - normalizing mismatched nesting,\n *  - and closing any still-open tags.\n *\n * @param html - The rich text string to sanitize.\n * @returns The sanitized rich text string.\n */\nexport function sanitizeRichText(html: string): string {\n\treturn addDataPresetTagsToHTML(closeOpenHtmlTags(html))\n}\n\n/**\n * Repairs a possibly-truncated HTML fragment by:\n *  - removing/fixing partial tags at the end,\n *  - normalizing mismatched nesting,\n *  - and closing any still-open tags.\n *\n * Designed for streaming scenarios where chunks can end mid-tag.\n * Atm we only support a subset of tags that we instruct the LLM to use.\n */\nexport function closeOpenHtmlTags(html: string): string {\n\tif (!html.trim()) return html\n\n\t// Remove any incomplete tag at the end\n\tconst cleaned = html.replace(incompleteTagRegex, \"\")\n\n\t// Track open tags\n\tconst openTags: string[] = []\n\n\tfor (const match of cleaned.matchAll(tagRegex)) {\n\t\tconst tagName = match[1]?.toLowerCase()\n\t\tif (!tagName) continue\n\n\t\tconst isClosing = match[0].startsWith(\"</\")\n\t\tconst isSelfClosing = match[0].endsWith(\"/>\") || selfClosingTags.includes(tagName)\n\n\t\tif (isSelfClosing) continue\n\n\t\tif (isClosing) {\n\t\t\t// Remove the last matching opening tag\n\t\t\tconst lastIndex = openTags.lastIndexOf(tagName)\n\t\t\tif (lastIndex === -1) continue\n\n\t\t\topenTags.splice(lastIndex, 1)\n\t\t} else {\n\t\t\topenTags.push(tagName)\n\t\t}\n\t}\n\n\t// Close remaining open tags in reverse order\n\treturn (\n\t\tcleaned +\n\t\topenTags\n\t\t\t.reverse()\n\t\t\t.map(tag => `</${tag}>`)\n\t\t\t.join(\"\")\n\t)\n}\n\n/**\n * Adds data-preset-tag attributes to a rich text string.\n *\n * When manually generating content for Wireframer, you should:\n * - Always include data-preset-tag=\"p\" on <li> elements if they contain paragraph content\n * - Use appropriate tag values (\"h1\", \"h2\", etc.) if the list item contains heading content\n * - Set the value to match the tag name of the first child element within the <li>\n *\n * This ensures that your generated content will render consistently with Framer's rich text styling system and\n * maintain proper style preset application.\n *\n * @param html - The rich text string to add data-preset-tag attributes to.\n * @returns The rich text string with data-preset-tag attributes added.\n */\nfunction addDataPresetTagsToHTML(html: string): string {\n\t// Use the exact same schema as CMS rich text fields\n\tconst schema = makeSchema(cmsSchemaParams)\n\n\t// Parse HTML string to ProseMirror document\n\tconst doc = parseRichText(html, schema)\n\n\t// Serialize back to HTML with data-preset-tag attributes automatically added\n\treturn serializeRichText(doc, schema)\n}\n", "import { createAssetReference, getAssetFilename } from \"@framerjs/assets\"\nimport { assert, assertNever, getLogger } from \"@framerjs/shared\"\nimport type { WireframerKit } from \"app/ai/utils/wireframerKit.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { CollectionItemNode } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionItemNode, isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type {\n\tCollectionReferenceVariableDefinition,\n\tImageVariableDefinition,\n\tMultiCollectionReferenceVariableDefinition,\n\tVariableDefinition,\n} from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { isVariableDefinition } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport type { ContentContainer } from \"document/models/CanvasTree/traits/utils/ContentContainer.ts\"\nimport { createLink } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport type { CollectionControlProp } from \"document/models/controlProps/CollectionControlProp.ts\"\nimport type {\n\tCollectionReferenceControlProp,\n\tMultiCollectionReferenceControlProp,\n} from \"document/models/controlProps/ControlProp.ts\"\nimport { type PrefixedControlProps, prefixControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport type { Mutable } from \"utils/Mutable.ts\"\nimport { getCollectionForIdentifier } from \"utils/getCollectionForIdentifier.ts\"\nimport { isArray, isDefined, isObject, isString } from \"utils/typeChecks.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { sanitizeRichText } from \"./richText.ts\"\n\nconst log = getLogger(\"ai:createCmsItems:cmsItemsOperations\")\n\nexport interface CMSItem {\n\tcontentContainer: ContentContainer\n\tcollectionName: string\n\titemIndex: number\n}\n\n/**\n * Method that builds the collection item with the parsed data.\n * Only supports one collection at a time.\n *\n * @param engine - The engine instance.\n * @param kit - The kit instance.\n * @param collectionNode - The collection node.\n * @param itemsToUpdate - The list of items to update.\n * @returns The onCmsItems handler.\n */\nexport function createOnCmsItemsHandler(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tcollectionNode: CollectionNode,\n\titemsToUpdate: NodeID[],\n) {\n\t// Chain all updates sequentially to maintain order and process by collection\n\t// so we can create references.\n\tlet updateChain = Promise.resolve()\n\n\t// Track which items have been fully processed to avoid race conditions.\n\t// During async operations (e.g., vector lookups), items can become finalized\n\t// while we're still processing them.\n\tconst processedItems = new Set<string>()\n\n\tconst onCmsItems = (cmsItems: CMSItem[]) => {\n\t\tupdateChain = updateChain.then(async () => {\n\t\t\tconst pendingUpdates: (() => void)[] = []\n\n\t\t\tconst activeCollectionNode = engine.tree.get(collectionNode.id)\n\t\t\tassert(isCollectionNode(activeCollectionNode), \"Collection node not found\", collectionNode.id)\n\n\t\t\tfor (const cmsItem of cmsItems) {\n\t\t\t\tconst itemKey = `${cmsItem.collectionName}:${cmsItem.itemIndex}`\n\n\t\t\t\t// Skip items that have already been fully processed\n\t\t\t\tif (cmsItem.contentContainer.isFinal && processedItems.has(itemKey)) continue\n\n\t\t\t\tconst nodeId = await ensureCollectionItemNode(engine, collectionNode, cmsItem, itemsToUpdate)\n\t\t\t\tconst controlProps = await createControlPropsForCmsItem(engine, kit, collectionNode, nodeId, cmsItem)\n\n\t\t\t\t// Mark as processed after successfully preparing the update\n\t\t\t\t// This handles the race condition where items become final during async operations\n\t\t\t\tif (cmsItem.contentContainer.isFinal) processedItems.add(itemKey)\n\n\t\t\t\tif (Object.keys(controlProps).length === 0) continue\n\n\t\t\t\tpendingUpdates.push(() => {\n\t\t\t\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\t\t\t\t\tconst collectionItemNode = engine.tree.get(nodeId)\n\t\t\t\t\tassert(isCollectionItemNode(collectionItemNode), `CMS item node \"${nodeId}\" not found`)\n\t\t\t\t\tcollectionItemNode.set(controlProps)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tif (pendingUpdates.length === 0) return\n\n\t\t\tawait new Promise<void>(resolve => {\n\t\t\t\tengine.scheduler.scheduleDocumentUpdateIgnoringUndo(() => {\n\t\t\t\t\tfor (const update of pendingUpdates) update()\n\t\t\t\t\tresolve()\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\treturn { onCmsItems, allDone: () => updateChain }\n}\n\nasync function ensureCollectionItemNode(\n\tengine: VekterEngine,\n\tcollectionNode: CollectionNode,\n\tcmsItem: CMSItem,\n\titemsToUpdate: NodeID[],\n): Promise<NodeID> {\n\tconst existingId = itemsToUpdate[cmsItem.itemIndex]\n\tif (existingId) return existingId\n\n\tconst newNode = await engine.scheduler.processWhenReadyAsync(() => {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\t\tconst node = CollectionItemNode.create({ parentid: collectionNode.id })\n\t\tengine.stores.scopeStore.insertNodes([node])\n\t\treturn node\n\t})\n\n\tassert(newNode, `Failed to create CMS item for \"${cmsItem.collectionName}\"`)\n\n\titemsToUpdate[cmsItem.itemIndex] = newNode.id\n\n\treturn newNode.id\n}\n\nasync function createControlPropsForCmsItem(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tcollection: CollectionNode,\n\tcollectionItemNodeId: NodeID,\n\tcmsItem: CMSItem,\n): Promise<PrefixedControlProps<CollectionControlProp>> {\n\tconst collectionItemNode = engine.tree.get(collectionItemNodeId)\n\tassert(isCollectionItemNode(collectionItemNode), `CMS item node \"${collectionItemNodeId}\" not found`)\n\n\t// Update each field that exists in the collection schema\n\tconst controlProps: Mutable<PrefixedControlProps<CollectionControlProp>> = {}\n\tfor (const variable of collection.variables) {\n\t\tif (!isVariableDefinition(variable)) continue\n\n\t\tconst { contentContainer, itemIndex } = cmsItem\n\t\tconst fieldName = variable.name\n\n\t\tconst isIncompleteField = cmsItem.contentContainer.isIncomplete(fieldName)\n\t\tif (variable.type !== ControlType.VectorSetItem && !supportsPartialUpdates(variable) && isIncompleteField) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst fieldValue =\n\t\t\tvariable.type === ControlType.VectorSetItem\n\t\t\t\t? // For VectorSetItem, wait for the complete value to avoid partial matches (e.g., \"El\" vs \"Elixir\")\n\t\t\t\t\tcontentContainer.getCompleteValueOnce(fieldName)\n\t\t\t\t: // Get the field value from the content container\n\t\t\t\t\tcontentContainer.get(fieldName)\n\t\tif (fieldValue == null) continue\n\n\t\tconst controlProp = await createControlPropFromValue(\n\t\t\tengine,\n\t\t\tkit,\n\t\t\tvariable,\n\t\t\tfieldValue,\n\t\t\titemIndex,\n\t\t\tcollection.createdFromKitSchemaId,\n\t\t)\n\n\t\t// Skip if the control prop is null, which means it is incomplete or invalid.\n\t\tif (!controlProp) continue\n\n\t\t// Only include the control prop if it has changed the value to set\n\t\tconst currentControlProp = collectionItemNode.getControlProp(variable.id)\n\t\tif (currentControlProp?.value === controlProp.value) continue\n\n\t\tcontrolProps[prefixControlPropKey(variable.id)] = controlProp\n\t}\n\n\treturn controlProps\n}\n\nfunction supportsPartialUpdates(variable: VariableDefinition) {\n\tswitch (variable.type) {\n\t\tcase ControlType.RichText:\n\t\tcase ControlType.String:\n\t\tcase ControlType.Number:\n\t\tcase \"slug\":\n\t\tcase ControlType.CollectionReference:\n\t\tcase ControlType.MultiCollectionReference:\n\t\t\treturn true\n\t\tcase ControlType.Array:\n\t\tcase ControlType.Boolean:\n\t\tcase ControlType.Color:\n\t\tcase ControlType.Date:\n\t\tcase ControlType.Enum:\n\t\tcase ControlType.EventHandler:\n\t\tcase ControlType.Image:\n\t\tcase ControlType.File:\n\t\tcase ControlType.Link:\n\t\tcase ControlType.LinkRelValues:\n\t\tcase ControlType.Transition:\n\t\tcase ControlType.BoxShadow:\n\t\tcase ControlType.ScrollSectionRef:\n\t\tcase ControlType.CustomCursor:\n\t\tcase ControlType.Border:\n\t\tcase ControlType.Cursor:\n\t\tcase ControlType.Padding:\n\t\tcase ControlType.BorderRadius:\n\t\tcase ControlType.Gap:\n\t\tcase ControlType.TrackingId:\n\t\tcase ControlType.VectorSetItem:\n\t\tcase ControlType.Location:\n\t\tcase \"controlReference\":\n\t\tcase \"nodePropertyControlReference\":\n\t\t\treturn false\n\t\tdefault:\n\t\t\tassertNever(variable)\n\t}\n}\n\nasync function createControlPropFromValue(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tvariable: VariableDefinition,\n\tvalue: unknown,\n\tindex: number,\n\tcreatedFromKitSchemaId?: NodeID,\n): Promise<CollectionControlProp | null> {\n\tswitch (variable.type) {\n\t\tcase ControlType.Boolean:\n\t\t\treturn { type: ControlType.Boolean, value: Boolean(value) }\n\t\tcase ControlType.Color:\n\t\t\treturn { type: ControlType.Color, value: String(value) }\n\t\tcase ControlType.Date:\n\t\t\treturn { type: ControlType.Date, value: String(value) }\n\t\tcase ControlType.Enum:\n\t\t\treturn { type: ControlType.Enum, value: String(value) }\n\t\tcase ControlType.Image: {\n\t\t\t// We handle images ourselves. We have a list of all possible values for the variable from the kit section.\n\t\t\t// We then select one of the values and set it as the value of the control prop.\n\t\t\tconst value = await getImageDefaultValueSuggestion(engine, kit, variable, index, createdFromKitSchemaId)\n\t\t\treturn {\n\t\t\t\ttype: ControlType.Image,\n\t\t\t\tvalue,\n\t\t\t}\n\t\t}\n\t\tcase ControlType.Link:\n\t\t\treturn { type: ControlType.Link, value: createLink({ url: String(value) }) }\n\t\tcase ControlType.Number:\n\t\t\treturn { type: ControlType.Number, value: Number(value) }\n\t\tcase ControlType.RichText: {\n\t\t\tconst sanitizedFieldValue = sanitizeRichText(String(value))\n\t\t\treturn { type: ControlType.RichText, value: sanitizedFieldValue }\n\t\t}\n\t\tcase \"slug\":\n\t\tcase ControlType.String:\n\t\t\treturn { type: ControlType.String, value: String(value) }\n\t\tcase ControlType.CollectionReference:\n\t\t\treturn createCollectionReferenceControlProp(engine, variable, value)\n\t\tcase ControlType.MultiCollectionReference:\n\t\t\treturn createMultiCollectionReferenceControlProp(engine, variable, value)\n\t\t// Unsupported control types - return null\n\t\tcase ControlType.File:\n\t\tcase ControlType.Array:\n\t\tcase ControlType.EventHandler:\n\t\tcase ControlType.Transition:\n\t\tcase ControlType.BoxShadow:\n\t\tcase ControlType.ScrollSectionRef:\n\t\tcase ControlType.CustomCursor:\n\t\tcase ControlType.Border:\n\t\tcase ControlType.Cursor:\n\t\tcase ControlType.Padding:\n\t\tcase ControlType.BorderRadius:\n\t\tcase ControlType.Gap:\n\t\tcase ControlType.TrackingId:\n\t\tcase ControlType.LinkRelValues:\n\t\tcase ControlType.Location:\n\t\tcase \"controlReference\":\n\t\tcase \"nodePropertyControlReference\":\n\t\t\treturn null\n\t\tcase ControlType.VectorSetItem: {\n\t\t\tif (!isString(value)) return null\n\t\t\tconst identifier = await kit.lookupVectorByName(variable.setModuleId, value)\n\t\t\tif (!identifier) return null\n\t\t\treturn { type: ControlType.VectorSetItem, value: identifier }\n\t\t}\n\t\tdefault:\n\t\t\tassertNever(variable)\n\t}\n}\n\n/**\n * Creates a collection reference control prop from a value.\n *\n * @param engine The engine instance.\n * @param variable The variable definition.\n * @param value The value to create the control prop from.\n * @returns The collection reference control prop or null if it is still missing the slug value or if it can't find\n * the item in the referenced collection with the current slug value.\n */\nasync function createCollectionReferenceControlProp(\n\tengine: VekterEngine,\n\tvariable: CollectionReferenceVariableDefinition,\n\tvalue: unknown,\n): Promise<CollectionReferenceControlProp | null> {\n\tif (!isObject(value)) return null\n\n\tconst collection = getCollectionForIdentifier(engine.tree, variable.dataIdentifier)\n\tassert(collection, `Collection \"${variable.dataIdentifier}\" not found`)\n\n\t// We are using the slugs to reference an item in another collection.\n\t// When creating items we don't have ids.\n\tconst slugVariable = collection.getSlugVariable()\n\tassert(slugVariable, `Slug variable not found for collection \"${variable.dataIdentifier}\"`)\n\n\tconst slugValue = value[slugVariable.name]\n\tif (!isString(slugValue)) return null\n\n\tconst item = findItemBySlug(collection, slugValue)\n\tif (!item) return null\n\n\t// Value is an id from an item in the referenced collection.\n\treturn { type: ControlType.CollectionReference, value: item.id }\n}\n\n/**\n * Creates a multi collection reference control prop from a value.\n *\n * @param engine The engine instance.\n * @param variable The variable definition.\n * @param value The value to create the control prop from.\n * @returns The multi collection reference control prop or null if it is incomplete or invalid referenced slugs.\n */\nfunction createMultiCollectionReferenceControlProp(\n\tengine: VekterEngine,\n\tvariable: MultiCollectionReferenceVariableDefinition,\n\tvalue: unknown,\n): MultiCollectionReferenceControlProp | null {\n\tif (!isArray(value)) return null\n\n\tconst collection = getCollectionForIdentifier(engine.tree, variable.dataIdentifier)\n\tassert(collection, `Collection \"${variable.dataIdentifier}\" not found`)\n\n\tconst slugVariable = collection.getSlugVariable()\n\tassert(slugVariable, `Slug variable not found for collection \"${variable.dataIdentifier}\"`)\n\n\tconst collectedSlugs: string[] = []\n\tfor (const item of value) {\n\t\tif (!isObject(item)) continue\n\n\t\tconst slugValue = item[slugVariable.name]\n\t\tif (!isString(slugValue)) continue\n\n\t\tcollectedSlugs.push(slugValue)\n\t}\n\n\tconst items = collectedSlugs.map(slug => findItemBySlug(collection, slug)?.id).filter(isDefined)\n\tif (!items.length) return null\n\n\t// Value is a list of ids from items in the referenced collection.\n\treturn { type: ControlType.MultiCollectionReference, value: items }\n}\n\n/**\n * Finds an item in a collection by its slug.\n *\n * @param collection - The collection to search in.\n * @param slug - The slug to search for.\n * @returns The item if found, undefined otherwise.\n */\nfunction findItemBySlug(collection: CollectionNode, slug: string): CollectionItemNode | undefined {\n\tconst slugVariable = collection.getSlugVariable()\n\tassert(slugVariable, `Slug variable not found \"${slug}\"`)\n\n\tfor (const item of collection.getUnsortedChildren()) {\n\t\tconst controlProp = item.getControlProp(slugVariable.id)\n\n\t\tconst currentSlug = controlProp?.value ?? slugVariable.initialValue\n\t\t// We pre create items so this happens when it hasn't been filled yet.\n\t\tif (!currentSlug) continue\n\t\tif (currentSlug === slug) return item\n\t}\n}\n\nasync function getImageDefaultValueSuggestion(\n\tengine: VekterEngine,\n\tkit: WireframerKit,\n\tvariable: ImageVariableDefinition,\n\tindex: number,\n\tcreatedFromKitSchemaId?: NodeID,\n): Promise<string | undefined> {\n\t// For local collections we don't import assets.\n\tif (!createdFromKitSchemaId) return\n\n\t// For existing collections created from the schema, we need to get the default value suggestions for images.\n\t// And select one of the values based on the index.\n\tconst collectionTemplate = kit.collections.find(\n\t\tcollectionTemplate => collectionTemplate.id === createdFromKitSchemaId,\n\t)\n\n\tif (!collectionTemplate) return\n\n\tconst defaultValueSuggestions = collectionTemplate.variables.find(\n\t\tvariableSchema => variableSchema.id === variable.id,\n\t)?.defaultValueSuggestions\n\n\tif (!defaultValueSuggestions || defaultValueSuggestions.length === 0) return\n\n\tconst asset = defaultValueSuggestions[index % defaultValueSuggestions.length]\n\tassert(asset, \"No asset found\")\n\n\tconst assetStore = engine.stores.assetStore\n\tif (!assetStore) return\n\tconst { assetMap } = engine.stores.assetStore\n\n\tif (assetMap.assetForKey(asset)) return asset\n\n\ttry {\n\t\t// Duplicate the specific asset key from the source kit module into this project.\n\t\tconst duplicatedAssets = await kit.duplicateAssets(assetStore, [asset])\n\t\tconst duplicatedAsset = duplicatedAssets[0]\n\t\tassert(duplicatedAsset, \"Failed to duplicate asset\")\n\t\treturn createAssetReference(getAssetFilename(duplicatedAsset))\n\t} catch {\n\t\t// We failed to duplicate the asset, so we ignore it.\n\t\tlog.error(\"Failed to duplicate asset\", { asset, kit: kit.id })\n\t\treturn\n\t}\n}\n", "export const createCmsItemsSystemPrompt = `# CMS Items Generator\n\nYou are an AI assistant specialized in generating realistic, contextual CMS items for web applications.\n\nGenerate high-quality, production-ready CMS content that enhances the user experience and matches the requested feature context.\n\n## Your Task\n- Generate CMS items for a single collection\n- Follow the exact schema provided for that collection\n- Create content that matches the given context and prompts\n- Ensure data is realistic, varied, and appropriate for the use case\n- Strive for creative, clear and engaging copy. Avoid overly generic or placeholder-like text unless specifically requested or if no other information can be inferred.\n- Generate sufficient content for each field; avoid responses that are too short or incomplete if more detail can be reasonably provided or inferred from the context.\n\n## Input You'll Receive\n- **Collection:** With specific schema and requirements\n- **Context prompts:** Descriptions of what the content should represent\n- **Existing items (optional):** Current data to update or reference\n- **Additional guidance:** Any extra requirements for the generated content\n\n## Output Requirements\nYour response must be a JSON object with an \"items\" array:\n- Each entry represents one item for the target collection\n- Each item must conform to the provided schema for that collection\n- In update mode (when instructed), only include the fields that need to change; omit untouched fields entirely\n- **Valid JSON:** Always return valid JSON; field names and value types and rules must match the schema\n- **Realistic content:** Use appropriate, believable data for each field\n- **Variety:** Generate diverse content across items in the collection\n- **Consistency:** Maintain thematic coherence with the overall feature context\n\n## Special Field Guidelines\n- **Slug fields:** Generate URL-friendly slugs (lowercase, hyphenated) based on titles\n- **Date fields:** Use ISO date format (YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss)\n- **Image fields:** Provide realistic image descriptions or alt text when requested\n- **Rich text fields:** Use basic HTML tags like <p>, <h2>, <h3>, <strong>, <em>, <ul>, <li>; no styles or scripts\n- **Boolean fields:** Use true/false values appropriately\n- **Collection references:** When a field points to another collection, output objects that include the referenced item\u2019s slug. For multi-references, return an array of such objects. Keep the slugs consistent with the target collection so the system can link them.\n\n## HTML Structure Rules\n- **List items:** Always wrap list item content in paragraph tags\n\t- Correct: \"<li><p>Your list item content</p></li>\"\n\t- Incorrect: \"<li>Your list item content</li>\"\n\t- This applies to both \"<ul>\" and \"<ol>\" lists\n\n## Icon/Vector Set Rules\n- Each icon field is tied to a specific icon set, **never mix sets.**\n- Check the field description for the icon set ID.\n- Use the **Icon Sets Catalog** to find valid icon names for that set.\n- Icon names must **exactly match** one in the set\u2019s \"icons\" array.\n- If multiple icon fields exist, verify each field\u2019s assigned set before selecting icons.\n`\n", "import type { CollectionItemSnapshot } from \"app/ai/utils/collections.ts\"\nimport * as yaml from \"yaml\"\n\n// Max number of tokens allowed in the example. This is an estimation based\n// on the assumption that each token is 3 characters. 10000 tokens is roughly 30000 characters.\n// This might be too much, but it's a good starting point. Let's get back to this if we need to\n// when we have more information.\nconst maxExampleTokens = 10000\nconst maxCharsPerItem = maxExampleTokens * 3\n\n/**\n * Returns a sample of items and a list of other slugs that did not fit the token limit.\n * It processes items one by one and adds them to the sample while they still fit the token limit.\n * If an item does not fit the token limit, it is added to the other slugs list.\n *\n * @param items - The items to process.\n * @returns A sample of items and a list of other slugs that did not fit the token limit.\n */\nexport function getItemsSampleByTokens(items: CollectionItemSnapshot[]): {\n\tsample: CollectionItemSnapshot[]\n\totherSlugs: string[]\n} {\n\tconst sample: CollectionItemSnapshot[] = []\n\tconst otherSlugs: string[] = []\n\n\t// Tracks the minimum size of an item seen so far.\n\t// We will use this as a threshold to determine if we need to stop adding items to the sample\n\t// and avoid stringify from a certain point on.\n\tlet minSeenSize = Infinity\n\n\tlet remainingChars = maxCharsPerItem\n\tfor (const item of items) {\n\t\t// No room left for even a minimal item.\n\t\t// Just collect slugs and avoid checking the item yaml size.\n\t\tif (minSeenSize !== Infinity && remainingChars < minSeenSize) {\n\t\t\totherSlugs.push(item.slug)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst itemYaml = yaml.stringify(item)\n\n\t\tif (itemYaml.length > remainingChars) {\n\t\t\totherSlugs.push(item.slug)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Only update minSeenSize for items that fit\n\t\tminSeenSize = Math.min(minSeenSize, itemYaml.length)\n\n\t\tsample.push(item)\n\t\tremainingChars -= itemYaml.length\n\t}\n\n\treturn {\n\t\tsample,\n\t\totherSlugs,\n\t}\n}\n", "import { assert, assertNever } from \"@framerjs/shared\"\nimport { CommandType } from \"app/ai/orchestrator/dsl.ts\"\nimport type { AddCMSItems, UpdateCMSItems } from \"app/ai/orchestrator/tasks.ts\"\nimport type { Collection, CollectionItemSnapshot } from \"app/ai/utils/collections.ts\"\nimport type { VariablesAndDividers } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { join } from \"utils/join.ts\"\nimport * as yaml from \"yaml\"\nimport { getItemsSampleByTokens } from \"./getItemsSampleByTokens.ts\"\n\nexport function generateUserPrompt(\n\tinitialFeatureRequest: string,\n\ttask: AddCMSItems | UpdateCMSItems,\n\tcollectionName: string,\n\tvariables: VariablesAndDividers,\n\treferencedCollections: Collection[],\n\titems: CollectionItemSnapshot[],\n) {\n\tconst { action, guidelines } = getPromptVariant(task.type)\n\n\treturn `# ${action} CMS Items Request\n\n## Feature Context\n${initialFeatureRequest}\n\n## Target Collection\n### ${collectionName}\n- **Context:** ${task.instructions}\n- **Output Format:** Return a JSON object with an \"items\" array. Each entry must follow the schema below.\n- **Reference note:** If this collection references other collections, use the referenced item\u2019s slug to establish relationships.\n${getTaskAdditionalInstructions(task, items)}\n\n- **Schema:**\n${yaml.stringify(variables)}\n\n${guidelines}\n\n${formatReferencedCollections(referencedCollections)}\n`\n}\n\nfunction getPromptVariant(taskType: CommandType.AddCMSItems | CommandType.UpdateCMSItems) {\n\tswitch (taskType) {\n\t\tcase CommandType.AddCMSItems:\n\t\t\treturn {\n\t\t\t\taction: \"Generate\",\n\t\t\t\tguidelines:\n\t\t\t\t\t\"Please generate appropriate CMS items for the collection above, following its schema and considering the feature context.\",\n\t\t\t}\n\t\tcase CommandType.UpdateCMSItems:\n\t\t\treturn {\n\t\t\t\taction: \"Update\",\n\t\t\t\tguidelines:\n\t\t\t\t\t\"Only output the fields that need to change for each item. Do not include fields that should remain as they are.\",\n\t\t\t}\n\t\tdefault:\n\t\t\tassert(false, \"Wireframer: Unhandled action type in CMS content generation\")\n\t}\n}\n\nfunction getTaskAdditionalInstructions(task: AddCMSItems | UpdateCMSItems, items: CollectionItemSnapshot[]) {\n\tswitch (task.type) {\n\t\tcase CommandType.AddCMSItems:\n\t\t\treturn formatAddItemsInstructions(items)\n\t\tcase CommandType.UpdateCMSItems:\n\t\t\treturn formatUpdateItemsInstructions(items)\n\t\tdefault:\n\t\t\tassertNever(task, \"Wireframer: Unhandled action type in CMS content generation\")\n\t}\n}\n\nconst addItemsInstructions =\n\t\"- **Items to generate:** Check the context for the desired count or default to a sensible number (for example, 3).\"\n\nfunction formatAddItemsInstructions(items: CollectionItemSnapshot[]): string {\n\tif (items.length === 0) {\n\t\treturn addItemsInstructions\n\t}\n\n\tconst { sample, otherSlugs } = getItemsSampleByTokens(items)\n\n\tconst sampleSection =\n\t\tsample.length > 0\n\t\t\t? `- **Existing items for reference (match their style and tone):**\\n${yaml.stringify(sample)}`\n\t\t\t: undefined\n\tconst otherSlugsSection =\n\t\totherSlugs.length > 0\n\t\t\t? `- **Additional existing items (slugs only):**\\n${yaml.stringify(otherSlugs.join(\", \"))}`\n\t\t\t: undefined\n\n\treturn join.linesFrom([addItemsInstructions, sampleSection, otherSlugsSection])\n}\n\nfunction formatUpdateItemsInstructions(items: CollectionItemSnapshot[]): string {\n\treturn `- **Update Guidance:** Include only the fields that change. Omit untouched properties.\n- **Existing Items to update:**\n${yaml.stringify(items)}\n`\n}\n\nfunction formatReferencedCollections(referencedCollections: { name: string; items?: CollectionItemSnapshot[] }[]) {\n\tif (!referencedCollections.length) return \"\"\n\n\tconst lines = referencedCollections.map(({ name, items }) => {\n\t\tconst title = `### ${name}`\n\n\t\tif (!items?.length) {\n\t\t\treturn `${title}\n- No existing items yet.`\n\t\t}\n\n\t\tconst itemsSlugs = items.map(item => item.slug)\n\t\treturn `${title}\n- Available slugs for references: ${yaml.stringify(itemsSlugs)}\n`\n\t})\n\n\treturn `## Referenced Collections\\n${lines.join(\"\\n\")}`\n}\n", "import { assert, delay, getLogger } from \"@framerjs/shared\"\nimport { type ModelMessage, Output, streamText } from \"ai\"\nimport type { FollowUpTask, StepResult } from \"app/ai/WireframerSession.ts\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { AddCMSItems, UpdateCMSItems } from \"app/ai/orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CollectionNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { ContentContainer } from \"document/models/CanvasTree/traits/utils/ContentContainer.ts\"\nimport { SloppyJavaScriptParser, isIncompleteValue } from \"document/utils/SloppyJavaScriptParser.ts\"\nimport { isArray, isObject, isString } from \"utils/typeChecks.ts\"\nimport { getExistingCollectionSnapshot, getReferencedCollections } from \"../../utils/collections.ts\"\nimport { createAddCMSItems } from \"../../utils/followUpTasks.ts\"\nimport type { WireframerKit } from \"../../utils/wireframerKit.ts\"\nimport { createZodSchemaForCollection } from \"./schema.ts\"\nimport type { CMSItem } from \"./utils/cmsItemsOperations.ts\"\nimport { createOnCmsItemsHandler } from \"./utils/cmsItemsOperations.ts\"\nimport { createCmsItemsSystemPrompt } from \"./utils/systemPrompt.ts\"\nimport { generateUserPrompt } from \"./utils/userPrompt.ts\"\n\nconst log = getLogger(\"ai:upsertCmsItems\")\n\nexport async function createCmsItems(\n\tengine: VekterEngine,\n\tfeatureRequest: string,\n\ttask: AddCMSItems,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<StepResult> {\n\tconst collectionNode = engine.tree.get(task.collection)\n\tassert(isCollectionNode(collectionNode), \"Collection node not found\", task.collection)\n\n\tconst name = collectionNode.resolveValue(\"name\")\n\tassert(name, \"Collection must have a name\")\n\n\tconst referencedCollections = getReferencedCollections(engine.tree, collectionNode)\n\tconst collectionsWithMissingItems = referencedCollections.filter(\n\t\tcollection => collection.getUnsortedChildren().length === 0,\n\t)\n\n\t// When referenced collection have no items we make sure we generate items for them first.\n\tif (collectionsWithMissingItems.length > 0) {\n\t\tconst followUpTasks: FollowUpTask[] = collectionsWithMissingItems.map(referencedCollection => {\n\t\t\tconst referencedName = referencedCollection.resolveValue(\"name\") ?? \"Referenced collection\"\n\n\t\t\treturn createAddCMSItems({\n\t\t\t\tcollectionNodeId: referencedCollection.id,\n\t\t\t\tcollectionName: referencedName,\n\t\t\t\tgetInstructions: () =>\n\t\t\t\t\t`Original instructions for ${name}: ${task.instructions}\\n\\nGenerate CMS items for the \"${referencedName}\" collection so \"${name}\" references have data.`,\n\t\t\t})\n\t\t})\n\n\t\t// Make sure we include the original main task as a follow up task.\n\t\tfollowUpTasks.push(\n\t\t\tcreateAddCMSItems({\n\t\t\t\tcollectionNodeId: collectionNode.id,\n\t\t\t\tcollectionName: name,\n\t\t\t\tgetInstructions: () => task.instructions,\n\t\t\t}),\n\t\t)\n\n\t\treturn {\n\t\t\tfollowUpTasks,\n\t\t}\n\t}\n\n\tawait upsertCmsItems(engine, featureRequest, task, kit, collectionNode, traceConfig)\n\n\treturn { message: buildMessage(name, false) }\n}\n\nexport async function updateCMSItems(\n\tengine: VekterEngine,\n\tfeatureRequest: string,\n\ttask: UpdateCMSItems,\n\tkit: WireframerKit,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n) {\n\tconst collectionNode = engine.tree.get(task.collection)\n\tassert(isCollectionNode(collectionNode), \"Collection node not found\", task.collection)\n\n\tconst name = collectionNode.resolveValue(\"name\")\n\tassert(name, \"Collection must have a name\")\n\n\tconst itemsToUpdate = resolveTargetItemNodeIds(collectionNode, task.slugs)\n\tawait upsertCmsItems(engine, featureRequest, task, kit, collectionNode, traceConfig, itemsToUpdate)\n\n\treturn { message: buildMessage(name, true) }\n}\n\nfunction buildMessage(collection: string, isUpdate: boolean) {\n\treturn `${isUpdate ? \"Updated\" : \"Created\"} CMS items successfully for collection: ${collection}.`\n}\n\nfunction addIconSetsCatalog(systemPrompt: string, iconSetsCatalog: string | undefined) {\n\tif (!iconSetsCatalog) return systemPrompt\n\n\treturn `${systemPrompt}\n\n## Icon Sets Catalog\n\n${iconSetsCatalog}`\n}\n\nasync function addKitPrompt(kit: WireframerKit) {\n\tconst { prompt: kitPrompt } = kit\n\tconst iconSetsCatalog = await kit.createIconSetsForPrompt()\n\tconst systemPrompt = addIconSetsCatalog(createCmsItemsSystemPrompt, iconSetsCatalog)\n\n\tif (!kitPrompt) return systemPrompt\n\treturn `${systemPrompt}\n\n## System Context\n${kitPrompt}`\n}\n\nasync function upsertCmsItems(\n\tengine: VekterEngine,\n\tfeatureRequest: string,\n\ttask: AddCMSItems | UpdateCMSItems,\n\tkit: WireframerKit,\n\tcollectionNode: CollectionNode,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n\titemsToUpdate?: Set<NodeID>,\n) {\n\t// itemsToUpdate will be empty for add CMS items.\n\tconst selectedCollection = getExistingCollectionSnapshot(engine.tree, kit, collectionNode, {\n\t\tfilterOnItemIds: itemsToUpdate,\n\t\tfullSnapshot: true,\n\t})\n\tassert(selectedCollection, \"Collection not found\")\n\n\tconst referencedCollections = getReferencedCollections(engine.tree, collectionNode)\n\tconst referencedCollectionSnapshots = referencedCollections.map(referenced =>\n\t\tgetExistingCollectionSnapshot(engine.tree, kit, referenced),\n\t)\n\n\tconst systemPrompt = await addKitPrompt(kit)\n\n\tconst messages: ModelMessage[] = [\n\t\t{ role: \"system\", content: systemPrompt },\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent: generateUserPrompt(\n\t\t\t\tfeatureRequest,\n\t\t\t\ttask,\n\t\t\t\tselectedCollection.name,\n\t\t\t\tcollectionNode.variables,\n\t\t\t\treferencedCollectionSnapshots,\n\t\t\t\tselectedCollection.items,\n\t\t\t),\n\t\t},\n\t]\n\n\t// Items to update needs to be an array for the createOnCmsItemsHandler as this is using\n\t// indexes to match the streamed items to the actual items to update.\n\tconst { onCmsItems, allDone } = createOnCmsItemsHandler(\n\t\tengine,\n\t\tkit,\n\t\tcollectionNode,\n\t\titemsToUpdate ? Array.from(itemsToUpdate) : [],\n\t)\n\n\tconst parser = cmsItemsParser(selectedCollection.name, onCmsItems)\n\tconst abortController = new AbortController()\n\tconst schema = createZodSchemaForCollection(engine.tree, task)\n\n\ttry {\n\t\tconst { textStream } = streamText({\n\t\t\tmodel: openRouter(LanguageModel.GPT41, {\n\t\t\t\textraBody: {\n\t\t\t\t\t...createVekterOpenRouterExtraBody({\n\t\t\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\t\t\tfeatureName: traceConfig.featureName,\n\t\t\t\t\t\tsessionId: traceConfig.sessionId,\n\t\t\t\t\t\tstep: \"upsert-cms-items\",\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t}),\n\t\t\tmessages,\n\t\t\toutput: Output.object({ schema }),\n\t\t\tabortSignal: abortController.signal,\n\t\t})\n\n\t\tfor await (const textPart of textStream) {\n\t\t\tparser.add(textPart)\n\t\t}\n\n\t\t// Wait for all updates to complete\n\t\tawait allDone()\n\n\t\t// Wait for all visual changes to settle and be rendered\n\t\tawait delay(2000)\n\t} catch (error) {\n\t\tabortController.abort()\n\t\tlog.error(\"Error upserting CMS items\", error)\n\t\tthrow error\n\t} finally {\n\t\tparser.end()\n\t}\n}\n\nfunction resolveTargetItemNodeIds(collectionNode: CollectionNode, itemsToUpdateSlugs: string[]): Set<NodeID> {\n\tconst slugVariable = collectionNode.getSlugVariable()\n\tassert(slugVariable, \"Slug variable not found\")\n\n\tconst targetNodeIds: Set<NodeID> = new Set()\n\tfor (const item of collectionNode.getUnsortedChildren()) {\n\t\tconst slug = item.getControlProp(slugVariable.id)?.value\n\t\tif (!isString(slug) || !itemsToUpdateSlugs.includes(slug)) continue\n\n\t\ttargetNodeIds.add(item.id)\n\t}\n\n\treturn targetNodeIds\n}\n\n// Create a CMS items parser similar to sectionsParser\nfunction cmsItemsParser(collectionName: string, onCmsItems: (items: CMSItem[]) => void) {\n\tconst cmsItems: Map<string, CMSItem> = new Map()\n\n\tconst parser = new SloppyJavaScriptParser((value: unknown[] | Record<string, unknown>) => {\n\t\tif (!isObject(value)) return\n\n\t\tconst items = value.items\n\t\tif (!isArray(items)) return\n\n\t\tlet containersChanged = false\n\n\t\t// Process each item in the collection\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst itemData = items[itemIndex]\n\t\t\tconst item = isObject(itemData) ? itemData : {}\n\n\t\t\t// Create unique key for this item\n\t\t\tconst itemKey = `${collectionName}:${itemIndex}`\n\n\t\t\tlet cmsItem = cmsItems.get(itemKey)\n\t\t\t// We cannot do anything about already final sections.\n\t\t\tif (cmsItem?.contentContainer.isFinal) continue\n\n\t\t\tif (!cmsItem) {\n\t\t\t\t// First time seeing this item - create tracker\n\t\t\t\tcmsItem = {\n\t\t\t\t\tcontentContainer: new ContentContainer(item, false),\n\t\t\t\t\tcollectionName,\n\t\t\t\t\titemIndex,\n\t\t\t\t}\n\t\t\t\tcmsItems.set(itemKey, cmsItem)\n\t\t\t} else {\n\t\t\t\t// Update existing item\n\t\t\t\tcmsItem.contentContainer.update(item)\n\t\t\t}\n\n\t\t\tcontainersChanged = true\n\n\t\t\t// Finalize if the item is complete\n\t\t\tif (!isIncompleteValue(items, itemIndex)) {\n\t\t\t\tcmsItem.contentContainer.finalize()\n\t\t\t}\n\t\t}\n\n\t\t// Don't call onCmsItems if nothing changed about the containers\n\t\tif (containersChanged) onCmsItems(Array.from(cmsItems.values()))\n\t})\n\n\treturn parser\n}\n", "import { assert, List, assertNever, delay, getLogger } from \"@framerjs/shared\"\nimport type { LanguageModelUsage, ModelMessage } from \"ai\"\nimport type {\n\tAIAssistantMessage,\n\tAIChatHistory,\n\tAIChatMessage,\n\tAIUserMessage,\n\tAssistantContent,\n\tStep,\n\tSuggestion,\n} from \"app/ai/types/AIChatHistory.ts\"\nimport { StepStatus, isAssistantMessage } from \"app/ai/types/AIChatHistory.ts\"\nimport { applyTypography } from \"app/ai/utils/typography.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { createContentManagementNodeIfNeeded } from \"document/components/chrome/contentManagement/utils/createContentManagementNodeIfNeeded.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isObject, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport { v4 } from \"uuid\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { CommandType, type PageMode, formatCommand } from \"./orchestrator/dsl.ts\"\nimport { streamPlan } from \"./orchestrator/streamPlan.ts\"\nimport type { WireframerWorkerTask } from \"./orchestrator/tasks.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"./tracing/openRouterTrace.ts\"\nimport type { Page } from \"./utils/siteMap.ts\"\nimport {\n\tcollectDesignPageScreens,\n\tcreateDesignPageLookup,\n\tcreatePageRouteLookup,\n\tgetDesignPageSiteMap,\n\tgetWebPagesSiteMap,\n} from \"./utils/siteMap.ts\"\nimport { getDurationMs } from \"./utils/tracking.ts\"\nimport type { WireframerKit } from \"./utils/wireframerKit.ts\"\nimport { generateMessage } from \"./workers/generateMessage/generateMessage.ts\"\nimport { createAIGeneratedPage, createScreen } from \"./workers/generateWebPage/actions/createWebPage.ts\"\nimport { deleteScreen, deleteWebPage } from \"./workers/generateWebPage/actions/deleteWebPage.ts\"\nimport { modifyScreen, modifyWebPage } from \"./workers/generateWebPage/actions/modifyWebPage.ts\"\nimport { updateDarkMode, updateScreenDarkMode } from \"./workers/generateWebPage/actions/updateDarkMode.ts\"\nimport type { AIStructuredOutput } from \"./workers/generateWebPage/schema.ts\"\nimport { getPromptSuggestions } from \"./workers/promptSuggestions/getPromptSuggestions.ts\"\nimport { getSuggestedResources } from \"./workers/resourceSuggestions/getResourceSuggestions.ts\"\nimport { createCmsItems, updateCMSItems } from \"./workers/upsertCmsItems/upsertCmsItems.ts\"\n\nconst log = getLogger(\"WireframerSession\")\n\nexport interface FollowUpTask {\n\ttask: () => WireframerWorkerTask\n\tdescription: string\n}\n\nexport type StepResult =\n\t| {\n\t\t\tnodeId?: NodeID\n\t\t\tmode?: PageMode\n\t\t\tgenerated?: AIStructuredOutput\n\t\t\tmessage?: string\n\t\t\tusage?: LanguageModelUsage\n\t\t\tfollowUpTasks?: FollowUpTask[]\n\t  }\n\t| undefined\n\nexport interface WireframerSessionUpdateCallbacks {\n\t/** Whenever the chat history is updated, through out the whole session. */\n\tonMessageUpdate?: (chatHistory: AIChatHistory) => void\n\t/** When a turn is started. */\n\tonTurnStart?: (session: WireframerSession) => void\n\t/** When a turn is successfully completed. */\n\tonTurnComplete?: (session: WireframerSession, durationMs: number) => void\n\t/** When a turn fails to complete. */\n\tonTurnError?: (session: WireframerSession, error: unknown, durationMs: number) => void\n\t/** When a plan is successfully generated. */\n\tonPlanReady?: (\n\t\tsession: WireframerSession,\n\t\tplan: readonly WireframerWorkerTask[],\n\t\tusage: LanguageModelUsage,\n\t\tdurationMs: number,\n\t) => void\n\t/** When a plan fails to generate. */\n\tonPlanError?: (session: WireframerSession, error: unknown, durationMs: number) => void\n\t/** When a step is started. */\n\tonStepStart?: (session: WireframerSession, task: WireframerWorkerTask) => void\n\t/** When a step is successfully completed. */\n\tonStepComplete?: (\n\t\tsession: WireframerSession,\n\t\ttask: WireframerWorkerTask,\n\t\tresult: StepResult,\n\t\tdurationMs: number,\n\t) => void\n\t/** When a step fails to execute. */\n\tonStepError?: (session: WireframerSession, task: WireframerWorkerTask, error: unknown, durationMs: number) => void\n}\n\ninterface WireframerTurn {\n\tid: string\n\tmessage: AIUserMessage\n\tstartTime: number\n}\n\n/**\n * A session/chat/conversation with Wireframer.\n *\n * Each session can consist of multiple turns, where each turn is a ping-pong between the user and\n * the agent. To start a turn, call `session.startTurn(engine, message)`. Each turn typically\n * consists of the following steps:\n * 1. The orchestrator generates a plan\n * 2. The generator worker executes the plan, step by step.\n * 3. If the plan is not giving suggested resources, it returns the prompt suggestions for the next\n *    turn and concludes the turn.\n *\n * Each session maintains its own chat history. You can pass in a set of (optional) callbacks to be\n * notified of the different events on initialization. All callbacks receive the session as the\n * first argument, where you can access the chat history and internal states like the session/turn\n * ID.\n */\nexport class WireframerSession {\n\tsessionId: string\n\t/** Indicates if the session is for a design page. If undefined, the session is for all web pages. */\n\tdesignPageId: NodeID | undefined\n\n\t/** Don't start a new generation if we're already generating. */\n\tisGenerating: boolean = false\n\n\tcallbacks?: WireframerSessionUpdateCallbacks\n\n\tconstructor(designPageId: NodeID | undefined, callbacks?: WireframerSessionUpdateCallbacks) {\n\t\tthis.sessionId = v4()\n\t\tthis.designPageId = designPageId\n\t\tthis._chatHistory = []\n\t\tthis.callbacks = callbacks\n\t}\n\n\tget traceConfig(): OpenRouterFeatureStepTraceConfig {\n\t\treturn { featureName: \"wireframer\", sessionId: this.sessionId }\n\t}\n\n\tprivate _chatHistory: AIChatHistory = []\n\n\tget chatHistory() {\n\t\treturn this._chatHistory\n\t}\n\n\tset chatHistory(chatHistory: AIChatHistory) {\n\t\tthis._chatHistory = chatHistory\n\t\tthis.callbacks?.onMessageUpdate?.(chatHistory)\n\t}\n\n\tprivate addMessage(message: AIChatMessage) {\n\t\tthis.chatHistory = [...this._chatHistory, message]\n\t}\n\n\tprivate updateLastAssistantMessage(content: Partial<AssistantContent>) {\n\t\tconst lastMessage = this.chatHistory[this.chatHistory.length - 1]\n\t\tif (!lastMessage || !isAssistantMessage(lastMessage)) return\n\n\t\tconst updatedMessage = getUpdatedAssistantMessage(lastMessage, content)\n\t\tthis.chatHistory = [...this.chatHistory.slice(0, -1), updatedMessage]\n\t}\n\n\tprivate getStep(index: number): Step | undefined {\n\t\tconst lastMessage = this.chatHistory[this.chatHistory.length - 1]\n\t\tif (!lastMessage || !isAssistantMessage(lastMessage) || !lastMessage.content.steps) return\n\n\t\treturn lastMessage.content.steps[index]\n\t}\n\n\tprivate updateStep(stepIndex: number, step: Partial<Step>) {\n\t\tconst lastMessage = this.chatHistory[this.chatHistory.length - 1]\n\t\tif (!lastMessage || !isAssistantMessage(lastMessage) || !lastMessage.content.steps) return\n\n\t\tconst updatedSteps = List.update(lastMessage.content.steps, stepIndex, currentStep => ({\n\t\t\t...currentStep,\n\t\t\tstatus: step.status ?? currentStep.status,\n\t\t\tdescription: step.description ?? currentStep.description,\n\t\t})) as Step[]\n\n\t\tthis.updateLastAssistantMessage({ steps: updatedSteps })\n\t}\n\n\tturn: WireframerTurn | undefined\n\n\t/**\n\t * Respond to a new user message.\n\t */\n\tasync startTurn(engine: VekterEngine, message: AIUserMessage) {\n\t\tif (this.isGenerating) return\n\n\t\tconst { content: prompt } = message\n\t\tif (!prompt) return\n\n\t\tconst { treeStore, aiGenerationStore, scopeStore, codeGenerationStore } = engine.stores\n\n\t\t// Initialize a turn\n\t\tthis.turn = {\n\t\t\tid: v4(),\n\t\t\tmessage,\n\t\t\tstartTime: performance.now(),\n\t\t}\n\n\t\ttry {\n\t\t\tthis.isGenerating = true\n\n\t\t\t// First add the user message into the chat history\n\t\t\tthis.addMessage(message)\n\n\t\t\t// Add a \"Thinking...\" message as soon as the user message is added\n\t\t\tconst thinkingMessage = createAssistantMessage(\"\")\n\t\t\tthis.addMessage(thinkingMessage)\n\n\t\t\tthis.callbacks?.onTurnStart?.(this)\n\n\t\t\tconst cmsEnabled = !this.designPageId\n\n\t\t\t// Build available sections object.\n\t\t\tconst kit = await aiGenerationStore.getKit(engine, { cms: cmsEnabled })\n\n\t\t\t// 1. Generate plan\n\t\t\tconst { plan, rejected } = await this.generatePlan(engine, prompt, kit, cmsEnabled)\n\n\t\t\tif (rejected) {\n\t\t\t\tconst lastMessage = this.chatHistory[this.chatHistory.length - 1]\n\t\t\t\tconst rejection = isObject(lastMessage?.content) ? lastMessage.content.message : lastMessage\n\t\t\t\tassert(isString(rejection), \"When rejected, the last message should be a rejection message.\")\n\t\t\t\tawait this.showResourcesSuggestions(prompt, rejection)\n\n\t\t\t\tthis.callbacks?.onTurnComplete?.(this, getDurationMs(this.turn.startTime))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// 2. Execute plan\n\t\t\t// Wait for the code generation to be idle so we get the latest kit sections structure for the generated pages.\n\t\t\tawait codeGenerationStore.generateAndUpdateQueuedComponents()\n\n\t\t\tconst allResponses = await this.executePlan(engine, prompt, plan, kit)\n\n\t\t\t// 3. After all changes complete, request the final message and hide steps.\n\t\t\tconst { message: finalMessage, requestFulfilled } = await this.generateFinalMessage(prompt, plan, allResponses)\n\n\t\t\tthis.updateLastAssistantMessage({\n\t\t\t\tmessage: finalMessage,\n\t\t\t\tsteps: undefined, // Clear steps when showing final message\n\t\t\t})\n\n\t\t\t// 4. If there are suggested resources, update the chat to show the resources.\n\t\t\tif (!requestFulfilled) {\n\t\t\t\tawait this.showResourcesSuggestions(prompt, finalMessage)\n\t\t\t} else if (isWebPageNode(scopeStore.active) && !this.designPageId) {\n\t\t\t\tconst targetPageId = scopeStore.active.id\n\t\t\t\tconst promptSuggestions = await getPromptSuggestions(\n\t\t\t\t\ttreeStore.tree,\n\t\t\t\t\tscopeStore,\n\t\t\t\t\taiGenerationStore,\n\t\t\t\t\tprompt,\n\t\t\t\t\tplan,\n\t\t\t\t\tkit,\n\t\t\t\t\tthis.traceConfig,\n\t\t\t\t)\n\n\t\t\t\t// Request prompt suggestions for the next turn, only on web pages.\n\t\t\t\t// Show prompt suggestions only on the active page we land on.\n\t\t\t\tthis.updateLastAssistantMessage({\n\t\t\t\t\t...(promptSuggestions && {\n\t\t\t\t\t\tsuggestions: {\n\t\t\t\t\t\t\toptions: promptSuggestions,\n\t\t\t\t\t\t\ttargetPageId,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tthis.callbacks?.onTurnComplete?.(this, getDurationMs(this.turn.startTime))\n\t\t} catch (error) {\n\t\t\tlog.error(`Error in turn ${this.turn.id}: `, error)\n\t\t\tthis.callbacks?.onTurnError?.(this, error, getDurationMs(this.turn.startTime))\n\t\t} finally {\n\t\t\tthis.isGenerating = false\n\t\t}\n\t}\n\n\tprivate async showResourcesSuggestions(prompt: string, finalMessage: string) {\n\t\tconst suggestedResources = await getSuggestedResources(prompt, finalMessage, this.traceConfig)\n\t\tthis.updateLastAssistantMessage({\n\t\t\tsuggestions: {\n\t\t\t\toptions: suggestedResources,\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate async generateFinalMessage(\n\t\tprompt: string,\n\t\tplan: readonly WireframerWorkerTask[],\n\t\tallResponses: string[],\n\t): Promise<{ message: string; requestFulfilled: boolean }> {\n\t\t// When the plan includes multiple steps, we delay the generation of the final message to allow\n\t\t// the steps to show as completed in the UI.\n\t\tconst shouldDelay = plan.length > 1\n\n\t\tconst summaryPromise = generateMessage(prompt, plan, allResponses, this.traceConfig)\n\t\tif (!shouldDelay) return summaryPromise\n\n\t\tconst [, summaryResult] = await Promise.allSettled([delay(500), summaryPromise] as const)\n\t\tif (summaryResult.status === \"rejected\") throw summaryResult.reason\n\t\treturn summaryResult.value\n\t}\n\n\tprivate async generatePlan(\n\t\tengine: VekterEngine,\n\t\tfeatureRequest: string,\n\t\tkit: WireframerKit,\n\t\tcmsEnabled: boolean,\n\t): Promise<{ plan: readonly WireframerWorkerTask[]; rejected: boolean }> {\n\t\tconst startTime = performance.now()\n\n\t\ttry {\n\t\t\tconst { treeStore, scopeStore, selectionStore, aiGenerationStore } = engine.stores\n\t\t\tlet designPageScreens: Map<NodeID, Page> | undefined\n\t\t\tif (this.designPageId) {\n\t\t\t\tdesignPageScreens = collectDesignPageScreens(\n\t\t\t\t\ttreeStore.tree,\n\t\t\t\t\tengine.componentLoader,\n\t\t\t\t\taiGenerationStore,\n\t\t\t\t\tkit,\n\t\t\t\t\tthis.designPageId,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst siteMap = this.designPageId\n\t\t\t\t? getDesignPageSiteMap(\n\t\t\t\t\t\ttreeStore.tree,\n\t\t\t\t\t\tengine.componentLoader,\n\t\t\t\t\t\tselectionStore,\n\t\t\t\t\t\taiGenerationStore,\n\t\t\t\t\t\tkit,\n\t\t\t\t\t\tthis.designPageId,\n\t\t\t\t\t\tdesignPageScreens,\n\t\t\t\t\t)\n\t\t\t\t: getWebPagesSiteMap(treeStore.tree, scopeStore, aiGenerationStore, kit)\n\t\t\tconst pagesLookup = this.designPageId\n\t\t\t\t? createDesignPageLookup(\n\t\t\t\t\t\ttreeStore.tree,\n\t\t\t\t\t\tengine.componentLoader,\n\t\t\t\t\t\taiGenerationStore,\n\t\t\t\t\t\tkit,\n\t\t\t\t\t\tthis.designPageId,\n\t\t\t\t\t\tdesignPageScreens,\n\t\t\t\t\t)\n\t\t\t\t: createPageRouteLookup(engine.tree)\n\n\t\t\tconst { plan, collections, usage, rejected } = await streamPlan(\n\t\t\t\ttreeStore,\n\t\t\t\tkit,\n\t\t\t\t[...prepareChatHistoryForOrchestrator(this.chatHistory), { role: \"user\", content: featureRequest }],\n\t\t\t\tmessage => this.updateLastAssistantMessage(message),\n\t\t\t\t{\n\t\t\t\t\tcmsEnabled,\n\t\t\t\t\tsiteMap,\n\t\t\t\t\texistingPages: pagesLookup,\n\t\t\t\t},\n\t\t\t\tthis.traceConfig,\n\t\t\t)\n\n\t\t\tthis.callbacks?.onPlanReady?.(this, plan, usage, getDurationMs(startTime))\n\n\t\t\t// When in CMS mode, we need to insert the collections into the tree before adding any items.\n\t\t\t// Creating the necessary collections is a hidden step.\n\t\t\tif (collections.length > 0) {\n\t\t\t\tawait engine.scheduler.processWhenReadyAsync(() => {\n\t\t\t\t\tconst contentManagementNode = createContentManagementNodeIfNeeded(engine.tree)\n\t\t\t\t\tfor (const collection of collections) engine.tree.insertNode(collection, contentManagementNode.id)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn { plan, rejected }\n\t\t} catch (error) {\n\t\t\tlog.reportError(error, {\n\t\t\t\tfeatureRequest,\n\t\t\t\tisDesignPage: !!this.designPageId,\n\t\t\t\tkit: kit.id,\n\t\t\t\tcmsEnabled,\n\t\t\t})\n\t\t\tthis.callbacks?.onPlanError?.(this, error, getDurationMs(startTime))\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprotected async executePlan(\n\t\tengine: VekterEngine,\n\t\tfeatureRequest: string,\n\t\tplan: readonly WireframerWorkerTask[],\n\t\tkit: WireframerKit,\n\t): Promise<string[]> {\n\t\tconst workersMessages: string[] = []\n\t\tfor (let index = 0; index < plan.length; index++) {\n\t\t\tconst action = plan[index]\n\t\t\tassert(action, \"Action should be defined\")\n\t\t\tawait this.executeStep(engine, featureRequest, action, kit, index, workersMessages)\n\t\t}\n\n\t\treturn workersMessages\n\t}\n\n\tprivate async executeStep(\n\t\tengine: VekterEngine,\n\t\tfeatureRequest: string,\n\t\ttask: WireframerWorkerTask,\n\t\tkit: WireframerKit,\n\t\tindex: number,\n\t\tworkersMessages: string[],\n\t) {\n\t\tthis.updateStep(index, { status: StepStatus.Loading })\n\n\t\tthis.callbacks?.onStepStart?.(this, task)\n\n\t\tconst stepStartTime = performance.now()\n\n\t\tconst shouldRestore = this.shouldRestoreStepDescription()\n\t\tconst originalStepDescription = this.getStep(index)?.description\n\t\tassert(originalStepDescription, \"Original step description should be defined\")\n\n\t\ttry {\n\t\t\tconst result = await this.executeAction(engine, featureRequest, task, kit)\n\n\t\t\tif (result?.message) workersMessages.push(result.message)\n\n\t\t\tif (result?.followUpTasks?.length) {\n\t\t\t\t// Execute follow up tasks in sequence.\n\t\t\t\tfor (const followUpTask of result.followUpTasks) {\n\t\t\t\t\tthis.updateStep(index, { description: followUpTask.description })\n\n\t\t\t\t\tconst followUpTaskResult = await this.executeAction(engine, featureRequest, followUpTask.task(), kit)\n\n\t\t\t\t\tif (followUpTaskResult?.message) workersMessages.push(followUpTaskResult.message)\n\n\t\t\t\t\tthis.updateStep(index, { description: followUpTask.description })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.updateStep(index, {\n\t\t\t\t...(shouldRestore ? { description: originalStepDescription } : {}),\n\t\t\t\tstatus: StepStatus.Done,\n\t\t\t})\n\n\t\t\tthis.callbacks?.onStepComplete?.(this, task, result, getDurationMs(stepStartTime))\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tthis.updateStep(index, {\n\t\t\t\t...(shouldRestore ? { description: originalStepDescription } : {}),\n\t\t\t\tstatus: StepStatus.Error,\n\t\t\t})\n\n\t\t\tthis.callbacks?.onStepError?.(this, task, error, getDurationMs(stepStartTime))\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprivate shouldRestoreStepDescription() {\n\t\tconst lastMessage = this.chatHistory[this.chatHistory.length - 1]\n\t\tif (!lastMessage || !isAssistantMessage(lastMessage)) return true\n\t\tconst stepCount = lastMessage.content.steps?.length ?? 0\n\t\treturn stepCount > 1\n\t}\n\n\tprivate async executeAction(\n\t\tengine: VekterEngine,\n\t\tinitialFeatureRequest: string,\n\t\ttask: WireframerWorkerTask,\n\t\tkit: WireframerKit,\n\t): Promise<StepResult> {\n\t\tassert(!getIsViewOnly(engine, \"canDesign\"), \"Cannot execute actions in view-only mode\")\n\n\t\tswitch (task.type) {\n\t\t\tcase CommandType.CreatePage: {\n\t\t\t\tif (this.designPageId) {\n\t\t\t\t\treturn createScreen(engine, this.designPageId, initialFeatureRequest, task, kit, this.traceConfig)\n\t\t\t\t}\n\n\t\t\t\treturn createAIGeneratedPage(engine, initialFeatureRequest, task, kit, this.traceConfig)\n\t\t\t}\n\t\t\tcase CommandType.UpdatePage: {\n\t\t\t\tif (this.designPageId) {\n\t\t\t\t\treturn modifyScreen(engine, initialFeatureRequest, task, this.designPageId, kit, this.traceConfig)\n\t\t\t\t}\n\n\t\t\t\treturn modifyWebPage(engine, initialFeatureRequest, task, kit, this.traceConfig)\n\t\t\t}\n\t\t\tcase CommandType.DeletePage:\n\t\t\t\tif (this.designPageId) {\n\t\t\t\t\treturn deleteScreen(engine, task, this.designPageId)\n\t\t\t\t}\n\t\t\t\treturn deleteWebPage(engine, task)\n\t\t\tcase CommandType.ThemePage:\n\t\t\t\tif (this.designPageId) {\n\t\t\t\t\treturn updateScreenDarkMode(engine, task, this.designPageId, kit)\n\t\t\t\t}\n\t\t\t\treturn updateDarkMode(engine, task, kit)\n\t\t\tcase CommandType.AddCMSItems:\n\t\t\t\treturn createCmsItems(engine, initialFeatureRequest, task, kit, this.traceConfig)\n\t\t\tcase CommandType.UpdateCMSItems:\n\t\t\t\treturn updateCMSItems(engine, initialFeatureRequest, task, kit, this.traceConfig)\n\n\t\t\tdefault:\n\t\t\t\tassertNever(task, \"Wireframer: Unhandled action type\")\n\t\t}\n\t}\n}\n\nfunction prepareChatHistoryForOrchestrator(chatHistory: AIChatHistory): ModelMessage[] {\n\t// We remove the last user message so we can add more details to the orchestrator prompt.\n\t// We also remove the last assistant message which is the \"Thinking...\" message.\n\treturn chatHistory.slice(0, -2).map(message => {\n\t\tif (!isAssistantMessage(message)) return message\n\t\tassert(isObject(message.content), \"Assistant message content should be parsed json.\")\n\n\t\tconst { dslCommands } = message.content\n\t\tassert(dslCommands?.length, \"DSL commands should be defined\")\n\n\t\treturn { role: message.role, content: dslCommands.map(formatCommand).join(\" \") }\n\t})\n}\n\nfunction createAssistantMessage(message: string): AIAssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: { message, multiStepPlan: undefined },\n\t\ttimestamp: Date.now(),\n\t}\n}\n\nfunction smartQuotesSuggestion(suggestion: Suggestion): Suggestion {\n\tconst { variant } = suggestion\n\n\tswitch (variant) {\n\t\tcase \"prompt\":\n\t\t\treturn {\n\t\t\t\tvariant: \"prompt\",\n\t\t\t\ttext: applyTypography(suggestion.text),\n\t\t\t\tprompt: applyTypography(suggestion.prompt),\n\t\t\t}\n\t\tcase \"resource\":\n\t\t\treturn {\n\t\t\t\tvariant: \"resource\",\n\t\t\t\ttext: applyTypography(suggestion.text),\n\t\t\t\turl: suggestion.url,\n\t\t\t}\n\t}\n}\n\nfunction getUpdatedAssistantMessage(\n\tmessage: AIAssistantMessage,\n\tcontent: Partial<AssistantContent>,\n): AIAssistantMessage {\n\treturn {\n\t\t...message,\n\t\tcontent: {\n\t\t\t...message.content,\n\t\t\t...content,\n\t\t\t...(content.message && { message: applyTypography(content.message) }),\n\t\t\t...(!isUndefined(content.multiStepPlan) && { multiStepPlan: content.multiStepPlan }),\n\t\t\t...(content.suggestions && {\n\t\t\t\tsuggestions: {\n\t\t\t\t\t...content.suggestions,\n\t\t\t\t\toptions: content.suggestions.options.map(smartQuotesSuggestion),\n\t\t\t\t},\n\t\t\t}),\n\t\t},\n\t}\n}\n\n/**\n * For debugbar utils.\n */\nexport class DebugWireframerSession extends WireframerSession {\n\toverride async executePlan(\n\t\tengine: VekterEngine,\n\t\tprompt: string,\n\t\tplan: WireframerWorkerTask[],\n\t\tkit: WireframerKit,\n\t): Promise<string[]> {\n\t\tthis.isGenerating = true\n\t\tthis.turn = {\n\t\t\tid: v4(),\n\t\t\tmessage: {\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: prompt,\n\t\t\t\tisSuggestion: false,\n\t\t\t\tsource: \"panel\",\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t},\n\t\t\tstartTime: performance.now(),\n\t\t}\n\n\t\tawait super.executePlan(engine, prompt, plan, kit)\n\n\t\tthis.isGenerating = false\n\n\t\treturn []\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { SafeJS } from \"code-generation/js/serializeJS.ts\"\nimport { jsxForNode } from \"code-generation/jsx/jsxForNode.ts\"\nimport type { JSXContext, JSXEngineDependencies } from \"code-generation/jsx/types.ts\"\nimport type {\n\tCanvasNode,\n\tLayoutTemplateNode,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { isCodeComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { getSmartComponentForCodeComponent } from \"document/models/CanvasTree/nodes/utils/smartComponentInstanceHelpers.ts\"\nimport { isSmartComponentSourceNode } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\n\ntype ScopeNode = Loaded<WebPageNode | LayoutTemplateNode | SmartComponentNode>\n\ninterface SourceNodes {\n\tscope: ScopeNode\n\tsource: CanvasNode\n}\n\n/**\n * For Smart Component instances, returns the primary variant as the source node.\n * This ensures we analyze the actual design content, not the instance wrapper.\n */\nfunction resolveSourceNode(node: CanvasNode, scopeNode: ScopeNode, dependencies: JSXEngineDependencies): SourceNodes {\n\tif (isCodeComponentNode(node)) {\n\t\tconst smartComponent = getSmartComponentForCodeComponent(dependencies.tree, node)\n\t\tif (isSmartComponentSourceNode(smartComponent)) {\n\t\t\tassert(smartComponent.isLoaded(), \"Smart component must be loaded\")\n\t\t\treturn { scope: smartComponent, source: smartComponent.getPrimaryVariant() }\n\t\t}\n\t}\n\treturn { scope: scopeNode, source: node }\n}\n\ninterface LLMJSXResult {\n\tjsx: SafeJS\n\tctx: JSXContext\n}\n\n/** Generates JSX with inline styles for LLM analysis. */\nexport async function generateLLMJSXForNode(\n\tnode: CanvasNode,\n\tscopeNode: ScopeNode,\n\tdependencies: JSXEngineDependencies,\n): Promise<LLMJSXResult> {\n\tconst { source, scope } = resolveSourceNode(node, scopeNode, dependencies)\n\n\t// llmSnapshot mode inlines styles - this JSX is for analysis, not compilation\n\tconst { jsx, ctx } = await jsxForNode(source, scope, dependencies, undefined, \"\", true)\n\n\tassert(jsx, \"No JSX generated for node\", node.id)\n\treturn { jsx, ctx }\n}\n\n/** Generates combined JSX for multiple nodes, processed in parallel. */\nexport async function generateLLMJSXForNodes(\n\tnodes: CanvasNode[],\n\tscopeNode: ScopeNode,\n\tdependencies: JSXEngineDependencies,\n): Promise<{ combinedJsx: string; results: LLMJSXResult[] }> {\n\tassert(nodes.length > 0, \"No nodes provided\")\n\n\tconst results = await Promise.all(nodes.map(node => generateLLMJSXForNode(node, scopeNode, dependencies)))\n\tconst combinedJsx = results.map(r => r.jsx).join(\"\\n\\n\")\n\n\treturn { combinedJsx, results }\n}\n", "import { emptyArray, getLogger } from \"@framerjs/shared\"\nimport { Output, generateText } from \"ai\"\nimport type { SafeJS } from \"code-generation/js/serializeJS.ts\"\nimport type { JSXContext, JSXEngineDependencies } from \"code-generation/jsx/types.ts\"\nimport type {\n\tCanvasNode,\n\tLayoutTemplateNode,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport type { WithCustomizations } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { defaultCustomizationCategories } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\nimport { z } from \"zod\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"../config/openRouter.ts\"\nimport { LanguageModel } from \"../languageModels.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"../tracing/openRouterTrace.ts\"\nimport { generateLLMJSXForNode } from \"../utils/generateLLMJSX.ts\"\n\nconst log = getLogger(\"AIGenerationStore\")\n\nexport interface ResolvedField {\n\tid: string\n\ttitle: string\n\tpropKey?: string\n}\n\nexport interface GeneratedSectionCustomizations {\n\tcategory: string | null\n\tdescription: string | null\n\tfields: readonly ResolvedField[]\n}\n\n/**\n * Generate metadata for a website section from its JSX snapshot.\n * Returns category, human-readable description, and a list of customizable fields.\n */\nexport async function generateCustomizations(\n\tsourceNode: CanvasNode & WithCustomizations,\n\tscopeNode: Loaded<WebPageNode | SmartComponentNode | LayoutTemplateNode>,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n\tdependencies: JSXEngineDependencies,\n\t// KITS @TODO: Add categories including user-defined ones\n\tcategories?: [string, ...string[]],\n): Promise<[NodeID, GeneratedSectionCustomizations]> {\n\tconst start = performance.now()\n\n\tconst id = sourceNode.id\n\n\ttry {\n\t\tconst { jsx, ctx } = await generateLLMJSXForNode(sourceNode, scopeNode, dependencies)\n\n\t\tconst generatedCustomizations = await requestSectionCustomizations(jsx, ctx, traceConfig)\n\t\tlog.debug(`Request description ${id} took ${performance.now() - start}ms`)\n\t\treturn [id, generatedCustomizations]\n\t} catch (error) {\n\t\t// Keep failures non-fatal; upstream callers can decide on fallbacks.\n\t\tlog.error(\"Failed to generate customizations\", { id, error })\n\t\treturn [\n\t\t\tid,\n\t\t\t{\n\t\t\t\tcategory: null,\n\t\t\t\tdescription: null,\n\t\t\t\tfields: emptyArray<ResolvedField>(),\n\t\t\t},\n\t\t]\n\t} finally {\n\t\tlog.debug(`Request description for ${id} took ${performance.now() - start}ms`)\n\t}\n}\n\nconst DesignDescriptionSchema = z\n\t.array(z.string())\n\t.describe(\"A list of bullet points describing the design features of the fragment.\")\nconst LayoutDescriptionSchema = z\n\t.array(z.string())\n\t.describe(\"A list of bullet points describing the layout features of the fragment.\")\nconst UsageDescriptionSchema = z\n\t.array(z.string())\n\t.describe(\"A list of bullet points describing what this fragment is best for.\")\n\nasync function requestSectionCustomizations(\n\tjsx: SafeJS,\n\tctx: JSXContext,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): Promise<GeneratedSectionCustomizations> {\n\tconst { output } = await generateText({\n\t\tmodel: openRouter(LanguageModel.GeminiFlash25, {\n\t\t\textraBody: createVekterOpenRouterExtraBody({\n\t\t\t\tfeatureCategory: \"wireframer\",\n\t\t\t\t...traceConfig,\n\t\t\t\tstep: \"generate-section-customisations\",\n\t\t\t}),\n\t\t}),\n\t\toutput: Output.object({\n\t\t\tschema: z.object({\n\t\t\t\tcategory: z\n\t\t\t\t\t.enum(defaultCustomizationCategories)\n\t\t\t\t\t.describe(\"Pick the best matching category from the provided options.\"),\n\t\t\t\tdescription: SectionDescriptionSchema,\n\t\t\t\tfields: FieldsSchema,\n\t\t\t}),\n\t\t}),\n\t\tsystem: sectionDescriptionSystemPrompt,\n\t\tmessages: [{ role: \"user\", content: `\\`\\`\\`${jsx}\\`\\`\\`` }],\n\t})\n\n\treturn {\n\t\tcategory: output.category,\n\t\tdescription: formatSectionDescription(output.description),\n\t\tfields: resolveFields(ctx, output.fields),\n\t}\n}\n\nconst sectionDescriptionSystemPrompt =\n\t\"Attached is a React JSX HTML fragment that is the source code of a section of a website. Always state descriptions confidently. Do not describe the implementation details.\"\n\nconst SectionDescriptionSchema = z\n\t.object({\n\t\tdesign: DesignDescriptionSchema,\n\t\tlayout: LayoutDescriptionSchema,\n\t\tusage: UsageDescriptionSchema,\n\t\tplacement: z\n\t\t\t.array(z.string())\n\t\t\t.describe(\n\t\t\t\t\"A list of bullet points describing where in a website this section belongs, e.g below a hero or above a footer.\",\n\t\t\t),\n\t\ttextLength: z\n\t\t\t.array(z.string())\n\t\t\t.describe(\n\t\t\t\t\"A list of bullet points describing how long (number of words or characters) text in the section should be.\",\n\t\t\t),\n\t\tinteractions: z\n\t\t\t.array(z.string())\n\t\t\t.optional()\n\t\t\t.describe(\n\t\t\t\t\"A list of bullet points describing the interactions of the section, like a lightbox, hover, RichTextNode effect, scroll animations, etc.\",\n\t\t\t),\n\t})\n\t.describe(\n\t\t\"Describe the design features of the section in a way that would allow a designer to decide when and where to include a section without looking at the design.\",\n\t)\n\nconst FieldsSchema = z\n\t.array(\n\t\tz.object({\n\t\t\tclassName: z.string().describe(\"The className value of a supported component.\"),\n\t\t\ttitle: z\n\t\t\t\t.string()\n\t\t\t\t.describe(\n\t\t\t\t\t\"Generate a unique title (max three words) that describes the conceptual role or category the element represents in the interface. Do not describe the element by its content, visible text, icons, or specific element type. Avoid mentioning what it is or contains. Instead, use broad, generic terms that capture the element\u2019s purpose or function in the UI hierarchy. For lists, use a shared base title for items. Titles must be unique per instance except for list items.\",\n\t\t\t\t),\n\t\t\tpropKey: z\n\t\t\t\t.string()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t\"Only for elements with data-type='component'. The specific prop key from the data-prop-keys attribute.\",\n\t\t\t\t),\n\t\t}),\n\t)\n\t.describe(\n\t\t\"Only identify customizable fields in the JSX, that have both a className attribute and a defined data-type attribute. For each listed prop key, create a separate field entry using the same className and that prop key. Do not return values for elements that do not have a data-type attribute.\",\n\t)\ntype Fields = z.infer<typeof FieldsSchema>\n\n/**\n * Resolve the fields to their corresponding node ids by looking up the className in the JSX context.\n */\nfunction resolveFields(ctx: JSXContext, fields: Fields): ResolvedField[] {\n\tconst resolvedFields: ResolvedField[] = []\n\tfor (const field of fields) {\n\t\tconst nodeId = ctx.css.getNodeIdForClassName(field.className)\n\t\tif (!nodeId) continue\n\t\tresolvedFields.push({\n\t\t\tid: nodeId,\n\t\t\ttitle: field.title,\n\t\t\tpropKey: field.propKey,\n\t\t})\n\t}\n\n\treturn resolvedFields\n}\n\nfunction formatMDList(title: string, items?: string[]): string | undefined {\n\tif (!items || items.length === 0) return undefined\n\treturn `**${title}**\\n${items.map(point => `- ${point}`).join(\" \")}`\n}\n\nfunction formatSectionDescription(description: z.infer<typeof SectionDescriptionSchema>): string {\n\treturn [\n\t\tformatMDList(\"Design\", description.design),\n\t\tformatMDList(\"Layout\", description.layout),\n\t\tformatMDList(\"Placement\", description.placement),\n\t\tformatMDList(\"Usage\", description.usage),\n\t\tformatMDList(\"Text Length\", description.textLength),\n\t\tformatMDList(\"Interactions\", description.interactions),\n\t]\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\")\n}\n", "import { getServiceMap } from \"@framerjs/shared\"\n\nconst sectionScreenshotExtension = \".png\"\n\nexport function getSectionScreenshotUrl(\n\tmoduleId: string,\n\tsectionId: string,\n\t{ darkMode, saveId }: { darkMode: boolean; saveId?: string },\n) {\n\tconst sectionScreenshotBaseUrl = `${getServiceMap().userContent}/screenshots`\n\tconst filename = `${sectionId}${darkMode ? \".dark\" : \"\"}${sectionScreenshotExtension}`\n\n\treturn saveId\n\t\t? `${sectionScreenshotBaseUrl}/kits/${moduleId}/${saveId}/${filename}`\n\t\t: `${sectionScreenshotBaseUrl}/draft-kits/${moduleId}/${filename}`\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { uniqueName } from \"document/utils/uniqueName.ts\"\nimport { join } from \"utils/join.ts\"\nimport { shuffle as shuffleArray } from \"utils/shuffle.ts\"\nimport * as yaml from \"yaml\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\nimport type { KitCollectionTemplate } from \"../sections/types.ts\"\nimport { serializeKitSection } from \"../utils/kitSection.ts\"\nimport {\n\ttype KitLayoutTemplateMeta,\n\ttype KitSectionMeta,\n\ttype WireframerKit,\n\ttype WireframerKitBreakpoint,\n\ttype WireframerKitJSON,\n\tisLayoutTemplateSlotKey,\n} from \"../utils/wireframerKit.ts\"\n\ntype KitAliasManagerInterface = Pick<\n\tWireframerKit,\n\t| \"getClipboardDataById\"\n\t| \"getSections\"\n\t| \"getSectionByUniqueTitle\"\n\t| \"getUniqueTitleBySectionId\"\n\t| \"getCollectionTemplate\"\n\t| \"getCollectionTemplatesPrompt\"\n\t| \"getSectionsPrompt\"\n>\n\n/**\n * Kits store sections by node id, but stream them to LLMs by a unique category name. That\n * dictionary has to be persistent for the duration of the Wireframer Session so that the LLM\n * doesn't get confused.\n * We also store the alias for each kit collection as to not influence the LLM with the collection name.\n */\nexport abstract class KitAliasManager implements KitAliasManagerInterface {\n\tprivate readonly widthToBreakpointId: BreakpointWidthToIdMap | undefined = undefined\n\n\tconstructor(\n\t\tpublic readonly sections: Record<NodeID, KitSectionMeta>,\n\t\tpublic readonly collectionsTemplates: KitCollectionTemplate[],\n\t\tpublic readonly layoutTemplates: Record<NodeID, KitLayoutTemplateMeta>,\n\t\tpublic readonly breakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined,\n\t) {\n\t\t// Instantiate the dictionary.\n\t\tthis.getSections(undefined, true)\n\t\tthis.widthToBreakpointId = createWidthToBreakpointIdMap(breakpoints, layoutTemplates)\n\t}\n\n\tabstract getClipboardDataById(id: NodeID): Promise<KitClipboardData>\n\n\tprivate getAllNames(): Set<string> {\n\t\treturn new Set(this.uniqueTitleBySectionId.values())\n\t}\n\n\tprivate readonly uniqueTitleBySectionId = new Map<NodeID, string>()\n\tgetSections(filter?: (section: KitSectionMeta) => boolean, shuffle?: boolean): Omit<KitSectionMeta, \"category\">[] {\n\t\tconst out: Omit<KitSectionMeta, \"category\">[] = []\n\t\tconst sections = Object.values(this.sections)\n\t\t// If we are shuffling, clear the category dictionary so that the unique names are re-generated.\n\t\tif (shuffle) {\n\t\t\tshuffleArray(sections)\n\t\t\tthis.uniqueTitleBySectionId.clear()\n\t\t}\n\n\t\tconst names = this.getAllNames()\n\n\t\tfor (const section of sections) {\n\t\t\tconst { category, id, ...rest } = section\n\t\t\tassert(category, \"Section must have a category.\")\n\n\t\t\t// Store the category before applying any filters.\n\t\t\tconst name =\n\t\t\t\tthis.uniqueTitleBySectionId.get(id) ??\n\t\t\t\tuniqueName(category.toLowerCase(), names, { omitCountIfFirst: false, withDash: true })\n\n\t\t\tnames.add(name)\n\t\t\tthis.uniqueTitleBySectionId.set(id, name)\n\n\t\t\tif (filter && !filter(section)) continue\n\n\t\t\tout.push({\n\t\t\t\t...rest,\n\t\t\t\tid: name,\n\t\t\t})\n\t\t}\n\n\t\treturn out\n\t}\n\n\tgetSectionByUniqueTitle(uniqueTitle: string): KitSectionMeta | undefined {\n\t\t// Force creation of the category dictionary.\n\t\tif (this.uniqueTitleBySectionId.size === 0) this.getSections()\n\n\t\tfor (const [id, title] of this.uniqueTitleBySectionId) {\n\t\t\tif (title !== uniqueTitle) continue\n\t\t\tconst section = this.sections[id]\n\t\t\tassert(section, \"Section must exist\")\n\t\t\treturn section\n\t\t}\n\t}\n\n\tgetUniqueTitleBySectionId(id: NodeID): string {\n\t\t// Force creation of the category dictionary.\n\t\tif (this.uniqueTitleBySectionId.size === 0) this.getSections()\n\n\t\t// When the kit no longer records the section id, we fall back to the section id.\n\t\treturn this.uniqueTitleBySectionId.get(id) ?? id\n\t}\n\n\tget collections(): KitCollectionTemplate[] {\n\t\treturn this.collectionsTemplates\n\t}\n\n\tgetCollectionTemplate(name: string): KitCollectionTemplate {\n\t\tconst collection = this.collectionsTemplates.find(collection => collection.name === name)\n\t\tassert(collection, \"Collection must be defined\")\n\t\treturn collection\n\t}\n\n\tgetCollectionTemplateById(id: NodeID): KitCollectionTemplate {\n\t\tconst collection = this.collectionsTemplates.find(collection => collection.id === id)\n\t\tassert(collection, \"Collection must be defined\")\n\t\treturn collection\n\t}\n\n\tgetCollectionTemplatesPrompt(): string {\n\t\tconst collectionTemplates = this.collectionsTemplates.map(collection => {\n\t\t\tconst normalizedVariables = collection.variables.map(variable => {\n\t\t\t\treturn { name: variable.name, type: variable.type, reference: variable.reference }\n\t\t\t})\n\n\t\t\treturn {\n\t\t\t\tname: collection.name,\n\t\t\t\tvariables: normalizedVariables,\n\t\t\t}\n\t\t})\n\n\t\treturn yaml.stringify(collectionTemplates)\n\t}\n\n\tgetSectionsPrompt(tree: CanvasTree, filter?: (section: KitSectionMeta) => boolean): string {\n\t\tconst kitSections = this.getSections(filter).map(section =>\n\t\t\tserializeKitSection(tree, this.collectionsTemplates, section),\n\t\t)\n\n\t\treturn yaml.stringify(kitSections)\n\t}\n\n\tgetLayoutPatternsPrompt(): string {\n\t\tconst patterns: string[] = []\n\t\tfor (const nodeId in this.layoutTemplates) {\n\t\t\tconst meta = this.layoutTemplates[nodeId]\n\t\t\tif (!meta) continue\n\t\t\tconst { pattern } = meta\n\t\t\tconst renamedPattern = pattern.map(id => {\n\t\t\t\tif (isLayoutTemplateSlotKey(id)) return id\n\t\t\t\treturn this.getUniqueTitleBySectionId(id)\n\t\t\t})\n\t\t\tpatterns.push(`${nodeId}: ${renamedPattern.join(\", \")}`)\n\t\t}\n\n\t\treturn join.linesFrom(patterns)\n\t}\n\n\tgetBreakpointIdByWidth(width: number, layoutId: NodeID | undefined): NodeID | undefined {\n\t\tconst breakpoints = layoutId\n\t\t\t? this.widthToBreakpointId?.get(layoutId)\n\t\t\t: this.widthToBreakpointId?.get(defaultPageKey)\n\t\tif (!breakpoints) return undefined\n\t\treturn findBreakpointIdByWidth(width, breakpoints)\n\t}\n}\n\nconst defaultPageKey = Symbol(\"default\")\n/** A map keeping breakpoint widths to breakpoint IDs of each layout/project default from the kit */\ntype BreakpointWidthToIdMap = Map<NodeID | typeof defaultPageKey, Map<number, NodeID>>\n\n/**\n * Creates a map from breakpoint width to breakpoint ID for efficient lookups.\n * This is computed once when a kit is instantiated to avoid recreating it on every page operation.\n */\nfunction createWidthToBreakpointIdMap(\n\tbreakpoints: WireframerKitJSON[\"breakpoints\"],\n\tlayoutTemplates: WireframerKitJSON[\"layoutTemplates\"],\n): BreakpointWidthToIdMap {\n\tconst result: Map<NodeID | typeof defaultPageKey, Map<number, NodeID>> = new Map()\n\tfunction getBreakpointWidthsToIds(breakpoints: Record<NodeID, WireframerKitBreakpoint> | undefined) {\n\t\tconst breakpointMap: Map<number, NodeID> = new Map()\n\t\tif (!breakpoints) return breakpointMap\n\t\t// Sorted from the widest to the smallest breakpoint.\n\t\tconst sortedBreakpoints = Object.entries(breakpoints).sort((a, b) => b[1].width - a[1].width)\n\t\tfor (const [id, breakpoint] of sortedBreakpoints) {\n\t\t\tbreakpointMap.set(breakpoint.width, id)\n\t\t}\n\t\treturn breakpointMap\n\t}\n\n\tresult.set(defaultPageKey, getBreakpointWidthsToIds(breakpoints))\n\n\tfor (const id in layoutTemplates) {\n\t\tconst layoutMeta = layoutTemplates[id]\n\t\tif (!layoutMeta) continue\n\t\tconst { breakpoints } = layoutMeta\n\t\tif (!breakpoints) continue\n\t\tresult.set(id, getBreakpointWidthsToIds(breakpoints))\n\t}\n\n\treturn result\n}\n\nfunction findBreakpointIdByWidth(width: number, breakpoints: Map<number, NodeID>): NodeID | undefined {\n\tlet smallestBreakpointId: NodeID | undefined = undefined\n\tfor (const [breakpointWidth, breakpointId] of breakpoints) {\n\t\tif (width >= breakpointWidth) {\n\t\t\treturn breakpointId\n\t\t}\n\t\tsmallestBreakpointId = breakpointId\n\t}\n\n\treturn smallestBreakpointId\n}\n", "import type { Asset } from \"@framerjs/assets\"\nimport { parseAssetReference, splitExtension } from \"@framerjs/assets\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { AnnotationKey } from \"@framerjs/framer-runtime/crossorigin\"\nimport type { GlobalModuleId, ModuleExportIdentifierString, ModuleIdentifier } from \"@framerjs/shared\"\nimport {\n\tassert,\n\tModuleType,\n\tasGlobalId,\n\temptyArray,\n\tgetLogger,\n\tisEmptyObject,\n\tisModuleExportIdentifier,\n\tlocalModuleIdentifier,\n\tparseModuleIdentifier,\n} from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { projectFeatures } from \"app/projectFeatures.ts\"\nimport { difference } from \"code-generation/jsx/difference.ts\"\nimport { isFramerVectorInfo, isFramerVectorSetInfo } from \"code-generation/utils/annotations.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport type {\n\tAnySmartComponentNode,\n\tCanvasNode,\n\tCanvasTree,\n\tCodeComponentNode,\n\tFrameNode,\n\tLayoutTemplateNode,\n\tNodeID,\n\tScopeNode,\n\tSmartComponentNode,\n\tWebPageNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport type { SerializableMutableNode } from \"document/models/CanvasTree/nodes/MutableNode.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport {\n\tisCodeComponentNode,\n\tisExternalModuleNode,\n\tisKitPageNode,\n\tisLayoutTemplateNode,\n\tisRichTextNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { getSmartComponentForCodeComponent } from \"document/models/CanvasTree/nodes/utils/smartComponentInstanceHelpers.ts\"\nimport { isDynamicValue } from \"document/models/CanvasTree/traits/DynamicValue.ts\"\nimport { createGeneratedValue } from \"document/models/CanvasTree/traits/Generated.ts\"\nimport { isVariableReference } from \"document/models/CanvasTree/traits/VariableReference.ts\"\nimport { fallbackAltText, withAltText } from \"document/models/CanvasTree/traits/WithAltText.ts\"\nimport type {\n\tCustomization,\n\tCustomizationFieldType,\n\tWithCustomizations,\n} from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport {\n\tgetSourceNodeForSection,\n\thasCustomizations,\n\tisCustomizable,\n\twithCustomizations,\n} from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport {\n\ttype WithFill,\n\ttype WithFillImageAlts,\n\thasAnyFillImageAlts,\n} from \"document/models/CanvasTree/traits/WithFill.ts\"\nimport { type WithKitSectionHash, withKitSectionHash } from \"document/models/CanvasTree/traits/WithKitSectionHash.ts\"\nimport { usesModuleRevision } from \"document/models/CanvasTree/traits/WithModuleRevision.ts\"\nimport type { Loaded } from \"document/models/CanvasTree/traits/WithScopeLoader.ts\"\nimport type { IsReplica } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport type { IsBreakpoint, IsVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { calculateKitSectionHash } from \"document/models/CanvasTree/traits/utils/calculateModuleRevision.ts\"\nimport { findTokenNode } from \"document/models/CanvasTree/utils/findTokenNode.ts\"\nimport {\n\tisTokenCSSVariable,\n\tstripMetadataFromCSSVariable,\n\ttokenIdFromCSSVariable,\n} from \"document/models/CanvasTree/utils/tokens.ts\"\nimport { prefixControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { DebugStore } from \"document/stores/DebugStore.ts\"\nimport type { LoadedExternalModulesStore } from \"document/stores/LoadedExternalModulesStore.ts\"\nimport type { LoadingStore } from \"document/stores/LoadingStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { PublishStore } from \"document/stores/PublishStore.ts\"\nimport type { ScopeStore } from \"document/stores/ScopeStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { uniqueName } from \"document/utils/uniqueName.ts\"\nimport { ControlType } from \"library/index.ts\"\nimport { kitModuleName } from \"modules/ModulesStorage.ts\"\nimport { splitTypeSlashName } from \"modules/utils.ts\"\nimport type { CollectedCollections } from \"utils/clipboard/utils.ts\"\nimport { collectCollections, collectColorTokenNodes } from \"utils/clipboard/utils.ts\"\nimport { cssSizeAsNumber } from \"utils/cssSizeAsNumber.ts\"\nimport { isNull, isNumber, isString, isUndefined } from \"utils/typeChecks.ts\"\nimport {\n\texternalVectorSetInfo,\n\tlocalVectorSetInfo,\n\tvectorInfoForIdentifier,\n\tvectorSetInfoForIdentifier,\n} from \"utils/vectorSets.ts\"\nimport { v4 as uuid } from \"uuid\"\nimport * as yaml from \"yaml\"\nimport {\n\tcollectCMSConnectedFields,\n\tcollectDetailPageCollection,\n\tcreateSectionCollectionTemplates,\n\tflattenCMSConnectedFields,\n} from \"../sections/collections.ts\"\nimport type { GeneratedSectionCustomizations, ResolvedField } from \"../sections/generateSectionCustomizations.ts\"\nimport { generateCustomizations } from \"../sections/generateSectionCustomizations.ts\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\nimport { getDetailPageCollectionId, getSmartComponentSectionClipboardData } from \"../sections/getKitSectionNodeData.ts\"\nimport { getLocalNodeInfo } from \"../sections/index.ts\"\nimport type { CMSConnectedField, VectorSetDictionary } from \"../sections/types.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"../tracing/openRouterTrace.ts\"\nimport { getSectionScreenshotUrl } from \"../utils/sectionScreenshot.ts\"\nimport type {\n\tAvailableKitSectionField,\n\tKitLayoutTemplateMeta,\n\tKitSectionMeta,\n\tWireframerKit,\n\tWireframerKitBreakpoint,\n\tWireframerKitColorToken,\n\tWireframerKitJSON,\n\tWireframerKitPageBackground,\n\tWireframerKitPageGap,\n\tWireframerKitPagePadding,\n\tWireframerKitPageProperties,\n\tWireframerKitVectorSetInfo,\n} from \"../utils/wireframerKit.ts\"\nimport { createLayoutTemplatePattern } from \"../utils/wireframerKit.ts\"\nimport { KitAliasManager } from \"./KitAliasManager.ts\"\nimport { requestLocalKitScreenshots } from \"./screenshots.ts\"\n\nconst KIT_SCHEMA_VERSION = 1\nconst defaultKitTitle = \"My Kit\"\n\nconst log = getLogger(\"LocalKit\")\n\nexport function createNewLocalKit(): WireframerKitJSON {\n\treturn {\n\t\tid: uuid(),\n\t\ttitle: defaultKitTitle,\n\t\tsections: {},\n\t\tlayoutTemplates: {},\n\t\tsets: {},\n\t\tcollections: [],\n\t\ttokens: {},\n\t\tschemaVersion: KIT_SCHEMA_VERSION,\n\t\tprompt: undefined,\n\t\tpageProperties: undefined,\n\t\tprimaryBreakpoint: undefined,\n\t\tbreakpoints: undefined,\n\t}\n}\n\nexport class LocalKit extends KitAliasManager implements WireframerKit {\n\tpublic readonly schemaVersion = KIT_SCHEMA_VERSION\n\n\tstatic createKitContext({\n\t\tcomponentLoader,\n\t\ttreeStore,\n\t\tmodulesStore,\n\t\tloadedExternalModulesStore,\n\t\tassetStore,\n\t}: {\n\t\tcomponentLoader: ComponentLoader\n\t\ttreeStore: TreeStore\n\t\tmodulesStore: ModulesStore\n\t\tloadedExternalModulesStore: LoadedExternalModulesStore\n\t\tassetStore: AssetStore\n\t}): LocalKitContext {\n\t\treturn {\n\t\t\tcomponentLoader,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tassetStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tseenVectorSets: new Set(),\n\t\t\tcollectedCollections: new Map(),\n\t\t\tkitSectionHashes: new Map(),\n\t\t\tcollectionIdMap: new Map(),\n\t\t\tsets: {},\n\t\t\tvectors: {},\n\t\t\ttokens: {},\n\t\t}\n\t}\n\n\tstatic async fromTree(\n\t\tcomponentLoader: ComponentLoader,\n\t\ttreeStore: TreeStore,\n\t\tmodulesStore: ModulesStore,\n\t\tassetStore: AssetStore,\n\t\tloadingStore: LoadingStore,\n\t\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tprojectStore: ProjectStore,\n\t\tengineScheduler: VekterEngineScheduler,\n\t) {\n\t\tconst kitManifest = treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest must be defined\")\n\n\t\t// KITS @TODO - In the future, this should be a kit with pages, not just sections.\n\t\tconst ctx = LocalKit.createKitContext({\n\t\t\tcomponentLoader,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tassetStore,\n\t\t})\n\n\t\tlet firstKitPageBreakpointsAndProperties:\n\t\t\t| Pick<WireframerKit, \"primaryBreakpoint\" | \"breakpoints\" | \"pageProperties\">\n\t\t\t| undefined = undefined\n\t\tconst sectionCustomizationPromises: Promise<[NodeID, GeneratedSectionCustomizations]>[] = []\n\t\tconst kittraceConfig: OpenRouterFeatureStepTraceConfig = { featureName: \"wireframer\", sessionId: randomID() }\n\t\tconst sections: Record<NodeID, KitSectionMeta> = {}\n\t\tconst layoutTemplates: Record<NodeID, KitLayoutTemplateMeta> = {}\n\t\tconst scopeIds: Set<NodeID> = new Set()\n\n\t\tfor (const node of treeStore.tree.root.children) {\n\t\t\tif (!isKitPageNode(node)) continue\n\t\t\tscopeIds.add(node.id)\n\n\t\t\tconst layoutTemplate = node.getLayoutTemplateNode(treeStore.tree)\n\t\t\tif (layoutTemplate) {\n\t\t\t\tscopeIds.add(layoutTemplate.id)\n\t\t\t}\n\t\t}\n\n\t\tfor (const scopeId of scopeIds) {\n\t\t\tconst scope = treeStore.tree.get<ScopeNode>(scopeId)\n\t\t\tif (!isKitPageNode(scope) && !isLayoutTemplateNode(scope)) {\n\t\t\t\tlog.error(\"Scope with sections not found\", scopeId)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst loadedScope = scope.isLoaded() ? scope : await scope.load()\n\t\t\tif (!isKitPageNode(loadedScope) && !isLayoutTemplateNode(loadedScope)) {\n\t\t\t\tlog.error(\"Loaded scope not found\", scopeId)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcollectSectionCustomizationsOnPage(\n\t\t\t\tloadedScope,\n\t\t\t\tsections,\n\t\t\t\tsectionCustomizationPromises,\n\t\t\t\tengineScheduler,\n\t\t\t\tctx,\n\t\t\t\tkittraceConfig,\n\t\t\t)\n\n\t\t\tconst primaryVariant = loadedScope.getPrimaryVariant()\n\n\t\t\tif (isLayoutTemplateNode(loadedScope)) {\n\t\t\t\tlayoutTemplates[loadedScope.id] = {\n\t\t\t\t\tid: loadedScope.id,\n\t\t\t\t\tpattern: createLayoutTemplatePattern(primaryVariant.children),\n\t\t\t\t\t...getBreakpointsAndPagePropertiesForKit(treeStore.tree, loadedScope, ctx.tokens),\n\t\t\t\t}\n\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Preload all top-level sections that are smart components so that we can freely\n\t\t\t// process them without loading one by one.\n\t\t\tconst maybeShallowLocalSmartComponents: AnySmartComponentNode[] = []\n\t\t\tfor (const section of primaryVariant.children) {\n\t\t\t\tif (!isCodeComponentNode(section)) continue\n\t\t\t\tconst smartComponent = getSmartComponentForCodeComponent(treeStore.tree, section)\n\t\t\t\tif (!smartComponent) continue\n\t\t\t\tmaybeShallowLocalSmartComponents.push(smartComponent)\n\t\t\t}\n\t\t\tawait ctx.treeStore.tree.loadScopes(maybeShallowLocalSmartComponents)\n\n\t\t\t// Only collect breakpoints and page properties from the first kit page\n\t\t\tfirstKitPageBreakpointsAndProperties ??= getBreakpointsAndPagePropertiesForKit(\n\t\t\t\ttreeStore.tree,\n\t\t\t\tloadedScope,\n\t\t\t\tctx.tokens,\n\t\t\t)\n\t\t}\n\n\t\tconst llmSectionResponses = await Promise.all(sectionCustomizationPromises)\n\n\t\t// Add sections that were reliant on new LLM customizations, updating the nodes in the tree\n\t\t// before returning the sections.\n\t\tconst { sections: llmSections, updates: sectionCustomizationUpdates } = processLLMSectionCustomizations(\n\t\t\tllmSectionResponses,\n\t\t\tctx,\n\t\t)\n\n\t\tawait engineScheduler.scheduleUpdateBypassingModuleRevisionHints(latestTree => {\n\t\t\tsectionCustomizationUpdates.forEach(fn => fn(latestTree))\n\t\t})\n\n\t\treturn new LocalKit(\n\t\t\tcomponentLoader,\n\t\t\tloadingStore,\n\t\t\tprojectStore,\n\t\t\ttreeStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tmodulesStore,\n\t\t\tctx.vectors,\n\t\t\t{\n\t\t\t\tsections: { ...sections, ...llmSections },\n\t\t\t\tcollections: createSectionCollectionTemplates(\n\t\t\t\t\tctx.modulesStore,\n\t\t\t\t\tctx.collectedCollections,\n\t\t\t\t\tfalse,\n\t\t\t\t\tundefined,\n\t\t\t\t\tsetId => collectVectorSet(setId, ctx),\n\t\t\t\t),\n\t\t\t\tlayoutTemplates,\n\t\t\t\ttokens: createWireframerTokens(ctx.tokens),\n\t\t\t\tsets: ctx.sets,\n\t\t\t\t...(firstKitPageBreakpointsAndProperties ?? {\n\t\t\t\t\tprimaryBreakpoint: undefined,\n\t\t\t\t\tbreakpoints: undefined,\n\t\t\t\t\tpageProperties: undefined,\n\t\t\t\t}),\n\t\t\t},\n\t\t)\n\t}\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly loadingStore: LoadingStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly loadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly sets: Record<GlobalModuleId, VectorSetDictionary>,\n\t\tprivate readonly kit: Pick<\n\t\t\tWireframerKitJSON,\n\t\t\t| \"sections\"\n\t\t\t| \"collections\"\n\t\t\t| \"layoutTemplates\"\n\t\t\t| \"tokens\"\n\t\t\t| \"sets\"\n\t\t\t| \"primaryBreakpoint\"\n\t\t\t| \"breakpoints\"\n\t\t\t| \"pageProperties\"\n\t\t>,\n\t) {\n\t\tsuper(kit.sections, kit.collections, kit.layoutTemplates, kit.breakpoints)\n\t}\n\n\tget id(): string {\n\t\tconst kitManifest = this.treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest must be defined\")\n\t\treturn kitManifest.id\n\t}\n\n\tget title(): string {\n\t\tconst kitManifest = this.treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest must be defined\")\n\t\treturn kitManifest.title\n\t}\n\n\tget prompt(): string | undefined {\n\t\tconst kitManifest = this.treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest must be defined\")\n\t\treturn kitManifest.prompt\n\t}\n\n\tget tokens(): Record<string, WireframerKitColorToken> {\n\t\treturn this.kit.tokens\n\t}\n\n\tget projectId(): string {\n\t\treturn this.projectStore.projectId\n\t}\n\n\tget pageProperties(): Record<NodeID, Partial<WireframerKitPageProperties>> | undefined {\n\t\treturn this.kit.pageProperties\n\t}\n\n\tget primaryBreakpoint(): NodeID | undefined {\n\t\treturn this.kit.primaryBreakpoint\n\t}\n\n\tasync getClipboardDataById(id: NodeID): Promise<KitClipboardData> {\n\t\tconst node = this.treeStore.tree.get(id)\n\t\tassert(node, \"Node must exist\", id)\n\n\t\tconst info = getLocalNodeInfo(\n\t\t\tthis.componentLoader,\n\t\t\tthis.loadingStore,\n\t\t\tthis.projectStore,\n\t\t\tthis.treeStore.tree,\n\t\t\tthis.loadedExternalModulesStore,\n\t\t\tthis.modulesStore,\n\t\t\t{\n\t\t\t\tprojectId: this.projectId,\n\t\t\t\tlayerId: node.id,\n\t\t\t},\n\t\t)\n\n\t\tassert(info?.enabled, \"Local node must be enabled\")\n\t\tassert(info.id, \"Local node must have an id\")\n\n\t\treturn info.clipboardData\n\t}\n\n\tprivate getSmartComponentSourceClipboardData(\n\t\tnode: CodeComponentNode,\n\t\tsmartComponent: Loaded<SmartComponentNode>,\n\t): KitClipboardData {\n\t\tconst scopeNode = this.treeStore.tree.getScopeNodeFor(node)\n\t\tassert(\n\t\t\t(isWebPageNode(scopeNode) || isLayoutTemplateNode(scopeNode)) && scopeNode.isLoaded(),\n\t\t\t\"Scope node must be defined and loaded\",\n\t\t\tnode.id,\n\t\t)\n\n\t\tconst { clipboardData } = getSmartComponentSectionClipboardData(\n\t\t\tthis.treeStore.tree,\n\t\t\tthis.componentLoader,\n\t\t\tthis.loadedExternalModulesStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.projectStore,\n\t\t\tnode,\n\t\t\tsmartComponent,\n\t\t\tscopeNode,\n\t\t)\n\n\t\treturn clipboardData\n\t}\n\n\ttoJSON(title: string, prompt: string | undefined): WireframerKitJSON {\n\t\treturn {\n\t\t\tid: this.id,\n\t\t\ttitle,\n\t\t\tprompt,\n\t\t\tsections: this.sections,\n\t\t\tsets: this.kit.sets,\n\t\t\tcollections: this.collections,\n\t\t\tlayoutTemplates: this.layoutTemplates,\n\t\t\ttokens: this.tokens,\n\t\t\tschemaVersion: KIT_SCHEMA_VERSION,\n\t\t\tprimaryBreakpoint: this.kit.primaryBreakpoint,\n\t\t\tbreakpoints: this.kit.breakpoints,\n\t\t\tpageProperties: this.pageProperties,\n\t\t}\n\t}\n\n\tasync duplicateAssets(): Promise<readonly Asset[]> {\n\t\t// A local kit never needs to duplicate assets; the assets will already be local to the project.\n\t\treturn emptyArray<Asset>()\n\t}\n\n\tstatic async update(\n\t\tcomponentLoader: ComponentLoader,\n\t\ttreeStore: TreeStore,\n\t\tmodulesStore: ModulesStore,\n\t\tassetStore: AssetStore,\n\t\tloadingStore: LoadingStore,\n\t\tloadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tprojectStore: ProjectStore,\n\t\tcodeGenerationStore: CodeGenerationStore,\n\t\tscopeStore: ScopeStore,\n\t\tdebugStore: DebugStore,\n\t\tpublishStore: PublishStore,\n\t\tscheduler: VekterEngineScheduler,\n\t): Promise<void> {\n\t\tassert(projectFeatures.isOn(\"kit\"), \"Project must be a kit project\")\n\n\t\tconst kitManifest = treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest must be defined\")\n\n\t\tconst kit = await LocalKit.fromTree(\n\t\t\tcomponentLoader,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tassetStore,\n\t\t\tloadingStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tprojectStore,\n\t\t\tscheduler,\n\t\t)\n\t\tconst { icon, title, prompt } = kitManifest\n\n\t\tconst assets = new Set<string>()\n\t\tconst kitIconAssetIdentifier = icon ? parseAssetReference(icon)?.identifier : undefined\n\t\tif (kitIconAssetIdentifier) assets.add(kitIconAssetIdentifier)\n\n\t\tconst clipboardData: {\n\t\t\tid: string\n\t\t\tcontent: KitClipboardData\n\t\t}[] = []\n\n\t\tconst seenSmartComponentNodes = new Set<NodeID>()\n\n\t\tfor (const id in kit.sections) {\n\t\t\tconst node = treeStore.tree.get(kit.sections[id]?.id)\n\t\t\tif (!node) continue\n\n\t\t\t// KITS @TODO - Collect asset keys from all sections.\n\t\t\tclipboardData.push({\n\t\t\t\tid: node.id,\n\t\t\t\tcontent: await kit.getClipboardDataById(node.id),\n\t\t\t})\n\n\t\t\tif (!isCodeComponentNode(node)) continue\n\n\t\t\tconst smartComponent = getSmartComponentForCodeComponent(treeStore.tree, node)\n\t\t\tif (!isSmartComponentNode(smartComponent)) continue\n\n\t\t\tassert(smartComponent.isLoaded(), \"Node must be loaded\", id)\n\n\t\t\tclipboardData.push({\n\t\t\t\tid: `${node.id}-source`,\n\t\t\t\tcontent: kit.getSmartComponentSourceClipboardData(node, smartComponent),\n\t\t\t})\n\n\t\t\tif (seenSmartComponentNodes.has(smartComponent.id)) continue\n\t\t\tseenSmartComponentNodes.add(smartComponent.id)\n\n\t\t\tclipboardData.push({\n\t\t\t\tid: smartComponent.id,\n\t\t\t\tcontent: await kit.getClipboardDataById(smartComponent.id),\n\t\t\t})\n\t\t}\n\n\t\tfor (const id in kit.layoutTemplates) {\n\t\t\tconst node = treeStore.tree.get(kit.layoutTemplates[id]?.id)\n\t\t\tif (!isLayoutTemplateNode(node)) continue\n\n\t\t\tclipboardData.push({\n\t\t\t\tid: node.id,\n\t\t\t\tcontent: await kit.getClipboardDataById(node.id),\n\t\t\t})\n\t\t}\n\n\t\tconst sets: { id: string; content: VectorSetDictionary }[] = []\n\n\t\tfor (const id in kit.sets) {\n\t\t\tconst items = kit.sets[asGlobalId(id)]\n\t\t\tif (!items) continue\n\n\t\t\tsets.push({ id, content: items })\n\t\t}\n\n\t\tawait modulesStore.updateKit(kit.toJSON(title, prompt), kitIconAssetIdentifier, clipboardData, sets, assets)\n\n\t\t// Once the module has been published, request screenshots for all sections.\n\t\t// KITS @TODO - We need to handle some retries, and then do some error toast if we must give up.\n\t\tawait requestLocalKitScreenshots(\n\t\t\tcomponentLoader,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tcodeGenerationStore,\n\t\t\tdebugStore,\n\t\t\tpublishStore,\n\t\t\tprojectStore,\n\t\t\tassetStore,\n\t\t\tscheduler,\n\t\t)\n\t}\n\n\tgetSectionScreenshot(engine: VekterEngine, id: string, darkMode: boolean): string | undefined {\n\t\tconst moduleHandle = engine.stores.modulesStore.forType(ModuleType.Kit).getByStableName(kitModuleName)\n\t\treturn moduleHandle ? getSectionScreenshotUrl(moduleHandle.id, id, { darkMode }) : undefined\n\t}\n\n\tasync lookupVectorByName(setId: GlobalModuleId, name: string): Promise<ModuleExportIdentifierString | undefined> {\n\t\tconst externalSetNode = this.treeStore.tree.getNodeWithTrait(setId, isExternalModuleNode)\n\n\t\tif (externalSetNode) {\n\t\t\tconst setInfo = externalVectorSetInfo(this.treeStore.tree, setId)\n\t\t\tif (!setInfo) return\n\n\t\t\tconst parsed = parseModuleIdentifier(externalSetNode.codeComponentIdentifier)\n\t\t\tif (!parsed || parsed.kind !== \"externalModuleExport\") return\n\n\t\t\tconst item = setInfo.items.find(item => item.name === name)\n\t\t\tif (!item) return\n\n\t\t\treturn this.treeStore.tree.getNodeWithTrait(item.moduleId, isExternalModuleNode)?.codeComponentIdentifier\n\t\t}\n\n\t\tconst persistedModule = this.modulesStore.getPersistedModuleByGlobalId(setId)\n\t\tif (!persistedModule) return\n\n\t\tconst setInfo = localVectorSetInfo(this.modulesStore, persistedModule.localId)\n\t\tif (!setInfo) return\n\n\t\tconst item = setInfo.items.find(item => item.name === name)\n\t\tif (!item) return\n\n\t\tconst handle = this.modulesStore.forType(ModuleType.Vector).getByStableName(item.id)\n\t\tif (!handle) return\n\n\t\treturn localModuleIdentifier(handle.localId, \"default\").value\n\t}\n\n\tasync createIconSetsForPrompt(): Promise<string | undefined> {\n\t\tif (Object.keys(this.sets).length === 0) return undefined\n\n\t\tconst catalog: Record<GlobalModuleId, { icons: string[] }> = {}\n\t\tfor (const [setId, items] of Object.entries(this.sets)) {\n\t\t\tcatalog[asGlobalId(setId)] = { icons: Object.keys(items) }\n\t\t}\n\n\t\treturn yaml.stringify(catalog)\n\t}\n}\n\ninterface LocalKitContext {\n\tcomponentLoader: ComponentLoader\n\tkitSectionHashes: Map<NodeID, number>\n\tcollectionIdMap: Map<NodeID, NodeID | undefined>\n\ttreeStore: TreeStore\n\tmodulesStore: ModulesStore\n\tassetStore: AssetStore\n\tseenVectorSets: Set<GlobalModuleId>\n\tsets: Record<GlobalModuleId, WireframerKitVectorSetInfo>\n\tvectors: Record<GlobalModuleId, VectorSetDictionary>\n\ttokens: Record<string, SerializableMutableNode>\n\tloadedExternalModulesStore: LoadedExternalModulesStore\n\tcollectedCollections: CollectedCollections\n}\n\nfunction getVectorSet(moduleId: GlobalModuleId, ctx: LocalKitContext): WireframerKitVectorSetInfo | undefined {\n\tconst node = ctx.treeStore.tree.getNodeWithTrait(moduleId, isExternalModuleNode)\n\n\tif (node) {\n\t\tconst parsed = parseModuleIdentifier(node.codeComponentIdentifier)\n\t\tif (!parsed || !isModuleExportIdentifier(parsed)) return\n\t\tconst [filename] = splitExtension(parsed.file)\n\t\treturn { name: node.title, saveId: parsed.saveId, id: filename }\n\t}\n\n\tconst persistedModule = ctx.modulesStore.getPersistedModuleByGlobalId(moduleId)\n\tif (!persistedModule) return\n\n\treturn {\n\t\tname: persistedModule.title,\n\t\tsaveId: persistedModule.saveId,\n\t\tid: splitTypeSlashName(persistedModule.localId)[1],\n\t}\n}\n\nfunction collectVectors(node: CanvasNode, identifier: ModuleIdentifier | undefined, ctx: LocalKitContext) {\n\tif (!isCodeComponentNode(node)) return\n\tif (!node.isVectorInstance) return\n\tif (!isModuleExportIdentifier(identifier)) return\n\n\tconst vector = vectorInfoForIdentifier(identifier, ctx.treeStore.tree, ctx.modulesStore)\n\tif (!vector?.set.moduleId) return\n\tif (ctx.seenVectorSets.has(vector.set.moduleId)) return\n\n\tconst set = vectorSetInfoForIdentifier(identifier, vector, ctx.treeStore.tree, ctx.modulesStore)\n\tif (!set) return\n\n\tctx.seenVectorSets.add(vector.set.moduleId)\n\n\tconst setInfo = getVectorSet(vector.set.moduleId, ctx)\n\tif (!setInfo) return\n\n\tctx.sets[vector.set.moduleId] = setInfo\n\n\tconst items: VectorSetDictionary = {}\n\n\tfor (const item of set.items) {\n\t\titems[item.name] = item.moduleId\n\t}\n\n\tctx.vectors[vector.set.moduleId] = items\n}\n\nfunction getVectorSetDictionary(moduleId: GlobalModuleId, ctx: LocalKitContext): VectorSetDictionary | undefined {\n\tconst node = ctx.treeStore.tree.getNodeWithTrait(moduleId, isExternalModuleNode)\n\n\tif (node) {\n\t\tconst value = node.annotation(AnnotationKey.FramerVectorSet)\n\t\tconst info = isFramerVectorSetInfo(value) ? value : undefined\n\n\t\tif (info) {\n\t\t\tconst dictionary: VectorSetDictionary = {}\n\n\t\t\tfor (const item of info.items) {\n\t\t\t\tconst annotation = ctx.treeStore.tree\n\t\t\t\t\t.getNodeWithTrait(item.moduleId, isExternalModuleNode)\n\t\t\t\t\t?.annotation(AnnotationKey.FramerVector)\n\t\t\t\tif (!isFramerVectorInfo(annotation)) continue\n\n\t\t\t\tdictionary[annotation.name] = item.moduleId\n\t\t\t}\n\n\t\t\treturn dictionary\n\t\t}\n\t}\n\n\tconst persistedModule = ctx.modulesStore.getPersistedModuleByGlobalId(moduleId)\n\tif (!persistedModule) return\n\n\tconst handle = ctx.modulesStore.forType(ModuleType.VectorSet).getByLocalId(persistedModule.localId)\n\tconst value = handle?.annotations(null, AnnotationKey.FramerVectorSet)\n\tif (!isFramerVectorSetInfo(value)) return\n\n\tconst dictionary: VectorSetDictionary = {}\n\tfor (const item of value.items) {\n\t\tconst annotation = ctx.modulesStore\n\t\t\t.forType(ModuleType.Vector)\n\t\t\t.getByStableName(item.id)\n\t\t\t?.annotations(null, AnnotationKey.FramerVector)\n\t\tif (!isFramerVectorInfo(annotation)) continue\n\n\t\tdictionary[annotation.name] = item.moduleId\n\t}\n\n\treturn dictionary\n}\n\ninterface SectionMetadata {\n\tdescription: string\n\tcategory: string\n\trules: readonly string[]\n}\n\n/**\n * Walk a section node to collect fields/rules/categories on it, as well collections/tokens (and\n * @TODO assets) used in it.\n */\nfunction createKitSectionMetaFromNode(\n\tsection: CanvasNode,\n\tctx: LocalKitContext,\n\tdetailPageCollectionId: NodeID | undefined,\n\tlayoutId: NodeID | undefined,\n\twebPageVariants: (FrameNode & IsReplica & IsVariant)[],\n\tcollectFields: boolean = true,\n\tmetadata?: SectionMetadata,\n): KitSectionMeta | undefined {\n\tif (!isCustomizable(section)) return\n\n\tconst fields: AvailableKitSectionField[] = []\n\tconst cmsConnectedFields: Record<NodeID, CMSConnectedField[]> = {}\n\n\t// When the section is a Smart Component instance, we store some customizations on the\n\t// SmartComponentNode, we walk the primary variant of the SmartComponentNode to collect the\n\t// customizations, and we use the SmartComponentNode's variants.\n\tconst referenceNode = getLoadedSourceNodeForSection(ctx.treeStore.tree, section)\n\tconst { node, variants, moduleIdentifier } =\n\t\tisSmartComponentNode(referenceNode) && referenceNode.isLoaded()\n\t\t\t? {\n\t\t\t\t\tnode: referenceNode.getPrimaryVariant(),\n\t\t\t\t\tvariants: referenceNode.getReplicaVariants(),\n\t\t\t\t\tmoduleIdentifier: referenceNode.instanceIdentifier,\n\t\t\t\t}\n\t\t\t: { node: section, variants: webPageVariants }\n\n\tfor (const child of node.walk()) {\n\t\tcollectCollections(ctx.treeStore.tree, child, ctx.collectedCollections)\n\t\tcollectCMSConnectedFields(ctx.treeStore.tree, child, cmsConnectedFields)\n\t\tcollectColorTokenNodes(ctx.treeStore.tree, child, ctx.tokens)\n\t\tfor (const variant of variants) {\n\t\t\tconst replica = ctx.treeStore.tree.get(generateReplicaChildId(variant.id, child.id))\n\t\t\tif (!replica) continue\n\t\t\tcollectColorTokenNodes(ctx.treeStore.tree, replica, ctx.tokens)\n\t\t}\n\n\t\tif (isCodeComponentNode(child)) {\n\t\t\tcollectVectors(child, parseModuleIdentifier(child.codeComponentIdentifier), ctx)\n\t\t}\n\n\t\tif (!hasCustomizations(child) || !child.customizations || !collectFields) continue\n\n\t\tfor (const customization of child.customizations) {\n\t\t\tif (customization.type !== \"content\") continue\n\t\t\tconst { fieldPath, fieldOptions = {} } = customization\n\t\t\tfields.push({\n\t\t\t\tname: fieldPath,\n\t\t\t\ttype: customization.fieldType,\n\t\t\t\toptions: !isEmptyObject(fieldOptions) ? Object.keys(fieldOptions) : undefined,\n\t\t\t})\n\t\t}\n\t}\n\n\tfields.push(...flattenCMSConnectedFields(cmsConnectedFields))\n\n\tconst description = metadata?.description ?? referenceNode.customizationsDescription\n\tconst category = metadata?.category ?? getCustomizationsCategory(referenceNode)\n\tconst rules = metadata?.rules ?? section.customizationsRules\n\n\tassert(description, \"Description must be defined\")\n\tassert(category, \"Category must be defined\")\n\tassert(rules, \"Rules must be defined\")\n\n\tconst rect = ctx.treeStore.tree.getRect(section)\n\n\treturn {\n\t\tid: section.id,\n\t\tmoduleIdentifier,\n\t\tdescription,\n\t\tcategory,\n\t\trules,\n\t\tfields,\n\t\tdetailPageCollectionId: getDetailPageCollectionId(cmsConnectedFields, detailPageCollectionId),\n\t\tlayoutId,\n\t\tintrinsicWidth: Math.floor(rect.width),\n\t\tintrinsicHeight: Math.floor(rect.height),\n\t}\n}\n\n// Typescript is finicky about overloads on complex union types, so we use a helper function to get\n// the customizations category.\nfunction getCustomizationsCategory(node: CanvasNode & WithCustomizations): string | undefined {\n\treturn node.resolveValue(\"customizationsCategory\")\n}\n\nfunction getUniqueTitleCounts(fields: readonly ResolvedField[]): Map<string, number> {\n\tconst titleCounts = new Map<string, number>()\n\tfields?.forEach(field => titleCounts.set(field.title, (titleCounts.get(field.title) ?? 0) + 1))\n\treturn titleCounts\n}\n\ninterface FieldUpdate {\n\tfieldPath: string\n\tpropKey?: string\n\tfieldType: CustomizationFieldType\n\tfieldOptions?: Record<string, string>\n}\n\ninterface FieldMetadata {\n\tfieldType: CustomizationFieldType\n\tfieldOptions?: Record<string, string>\n\tkitField?: AvailableKitSectionField\n}\n\nfunction getValidCustomizablePropKeys(\n\tcomponentLoader: ComponentLoader,\n\tnode: CodeComponentNode,\n): Set<string> | undefined {\n\tif (node.isVectorInstance) return undefined\n\n\tconst component = componentLoader.componentForIdentifier(node.codeComponentIdentifier)\n\tif (!component?.properties) return undefined\n\n\tconst controlProps = node.getControlProps(component.properties)\n\tconst validPropKeys = new Set<string>()\n\n\tfor (const key in controlProps) {\n\t\tconst control = controlProps[key]\n\t\tif (!control) continue\n\n\t\t// Only String and VectorSetItem controls are customizable\n\t\tconst { type, value } = control\n\t\tif (type !== ControlType.String && type !== ControlType.VectorSetItem) continue\n\t\tif (isDynamicValue(value) || isVariableReference(value)) continue\n\t\tvalidPropKeys.add(key)\n\t}\n\n\treturn validPropKeys.size > 0 ? validPropKeys : undefined\n}\n\nfunction createCustomizations(\n\ttree: CanvasTree,\n\tcomponentLoader: ComponentLoader,\n\tid: NodeID,\n\tfields: FieldUpdate[],\n): Customization[] | undefined {\n\tconst node = tree.get(id)\n\tif (!isCustomizable(node)) return\n\n\tconst isCodeComponent = isCodeComponentNode(node)\n\tconst validPropKeys = isCodeComponent ? getValidCustomizablePropKeys(componentLoader, node) : undefined\n\n\treturn fields.map<Customization>(({ fieldPath, propKey, fieldType, fieldOptions }) => {\n\t\tconst validatedPropKey = isCodeComponent && propKey && validPropKeys?.has(propKey) ? propKey : undefined\n\n\t\treturn {\n\t\t\tid: randomID(),\n\t\t\ttype: \"content\",\n\t\t\tproperty: isCodeComponent && validatedPropKey ? prefixControlPropKey(validatedPropKey) : \"textContent\",\n\t\t\tfieldType,\n\t\t\tfieldPath,\n\t\t\tfieldOptions,\n\t\t}\n\t})\n}\n\nfunction processGeneratedFields(\n\ttree: CanvasTree,\n\tsection: KitSectionMeta,\n\tfields: readonly ResolvedField[],\n\tctx: LocalKitContext,\n) {\n\tconst existing = new Set<string>(section.fields.map(field => field.name))\n\tconst nextFields: AvailableKitSectionField[] = [...section.fields]\n\n\tconst nodeIdToFieldPath = new Map<NodeID, FieldUpdate[]>()\n\n\tconst uniqueTitleCounts = getUniqueTitleCounts(fields)\n\n\tfor (const field of fields) {\n\t\tconst node = tree.getNodeWithTrait(field.id, withCustomizations)\n\t\tif (!node) continue\n\n\t\t// Skip any node that is not a code component or rich text node.\n\t\tif (!isCodeComponentNode(node) && !isRichTextNode(node) && !hasAnyFillImageAlts(node)) continue\n\t\t// Skip rich text nodes with dynamic text content. Assume they are CMS bindings and\n\t\t// therefore would be duplicated when merged with the calculated fields.\n\t\tif (isRichTextNode(node) && isDynamicValue(node.textContent)) {\n\t\t\t// Make sure we clean up any customizations that may have been generated for this node previously.\n\t\t\t// Before it became a variable reference.\n\t\t\tif (node.customizations?.length) nodeIdToFieldPath.set(node.id, [])\n\t\t\tcontinue\n\t\t}\n\n\t\tconst fieldTitleCount = uniqueTitleCounts.get(field.title) ?? 0\n\t\tconst fieldPath = uniqueName(field.title, existing, { omitCountIfFirst: fieldTitleCount <= 1 })\n\t\texisting.add(fieldPath)\n\n\t\tconst metadata = getFieldMetadata(node, fieldPath, tree, ctx)\n\t\tif (!metadata) continue\n\t\tif (metadata.kitField) {\n\t\t\tnextFields.push(metadata.kitField)\n\t\t}\n\n\t\tconst entries = nodeIdToFieldPath.get(node.id) ?? []\n\t\tentries.push({\n\t\t\tfieldPath,\n\t\t\tpropKey: field.propKey,\n\t\t\tfieldType: metadata.fieldType,\n\t\t\tfieldOptions: metadata.fieldOptions,\n\t\t})\n\t\tnodeIdToFieldPath.set(node.id, entries)\n\t}\n\n\tconst updates: Array<(tree: CanvasTree) => void> = []\n\tfor (const [sectionChildId, entries] of nodeIdToFieldPath) {\n\t\tconst customizations = createCustomizations(tree, ctx.componentLoader, sectionChildId, entries)\n\n\t\tupdates.push(latestTree => {\n\t\t\tconst node = latestTree.get(sectionChildId)\n\t\t\tif (!isCustomizable(node)) return\n\t\t\tnode.set({ customizations })\n\t\t})\n\t}\n\n\treturn {\n\t\tfields: nextFields,\n\t\tupdates,\n\t}\n}\n\nfunction getSetFromVector(codeComponentIdentifier: string, tree: CanvasTree, modulesStore: ModulesStore) {\n\tconst identifier = parseModuleIdentifier(codeComponentIdentifier)\n\tif (!isModuleExportIdentifier(identifier)) return undefined\n\n\tconst vectorInfo = vectorInfoForIdentifier(identifier, tree, modulesStore)\n\treturn vectorInfo?.set.moduleId\n}\n\nfunction getFieldMetadata(\n\tnode: CanvasNode & WithCustomizations,\n\tfieldPath: string,\n\ttree: CanvasTree,\n\tctx: LocalKitContext,\n): FieldMetadata | undefined {\n\tif (isRichTextNode(node)) {\n\t\t// Skip rich text nodes with dynamic text content. Assume they are CMS bindings and\n\t\t// therefore would be duplicated when merged with the calculated fields.\n\t\tif (isDynamicValue(node.textContent)) {\n\t\t\treturn undefined\n\t\t}\n\t\treturn {\n\t\t\tfieldType: \"text\",\n\t\t\tkitField: { name: fieldPath, type: \"text\" },\n\t\t}\n\t}\n\n\tif (isCodeComponentNode(node)) {\n\t\tif (node.isVectorInstance) {\n\t\t\tconst iconSet = getSetFromVector(node.codeComponentIdentifier, tree, ctx.modulesStore)\n\t\t\treturn {\n\t\t\t\tfieldType: \"icon\",\n\t\t\t\tkitField: { name: fieldPath, type: \"icon\", iconSet },\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tfieldType: \"text\",\n\t\t\tkitField: { name: fieldPath, type: \"text\" },\n\t\t}\n\t}\n\n\tif (hasAnyFillImageAlts(node)) {\n\t\tconst fieldOptions = buildFillImageAltOptions(node) ?? {}\n\t\treturn {\n\t\t\tfieldType: \"image\",\n\t\t\tfieldOptions,\n\t\t\tkitField: {\n\t\t\t\tname: fieldPath,\n\t\t\t\ttype: \"image\",\n\t\t\t\toptions: !isEmptyObject(fieldOptions) ? Object.keys(fieldOptions) : undefined,\n\t\t\t},\n\t\t}\n\t}\n}\n\nfunction buildFillImageAltOptions(node: CanvasNode & WithFill & WithFillImageAlts): Record<string, string> | undefined {\n\tconst result: Record<string, string> = {}\n\n\tconst mainImage = node.fillImage\n\tif (isString(mainImage)) {\n\t\tconst mainImageAlt = (withAltText(node) ? node.altAttribute : undefined) ?? fallbackAltText\n\t\tresult[mainImageAlt] = mainImage\n\t}\n\n\tconst fillImageAlts = node.fillImageAlts ?? emptyArray()\n\tfor (const alt of fillImageAlts) {\n\t\tif (!alt) continue\n\t\tresult[alt.alt] = alt.image\n\t}\n\n\treturn !isEmptyObject(result) ? result : undefined\n}\n\nexport function processLLMSectionCustomizations(\n\tresponses: [NodeID, GeneratedSectionCustomizations][],\n\tctx: LocalKitContext,\n): { sections: Record<NodeID, KitSectionMeta>; updates: Array<(tree: CanvasTree) => void> } {\n\tconst updates: Array<(tree: CanvasTree) => void> = []\n\tconst start = performance.now()\n\tconst sections: Record<NodeID, KitSectionMeta> = {}\n\tconst tree = ctx.treeStore.tree\n\n\tfor (const [id, { category, description, fields }] of responses) {\n\t\tconst sectionNode = tree.get<CanvasNode & WithCustomizations>(id)\n\t\tif (!sectionNode || isNull(category) || isNull(description)) continue\n\t\tconst scopeNode = tree.getScopeNodeFor(sectionNode)\n\t\tif (!isKitPageNode(scopeNode) && !isLayoutTemplateNode(scopeNode)) continue\n\n\t\tconst isLayoutTemplate = isLayoutTemplateNode(scopeNode)\n\t\tconst layoutId = isLayoutTemplate ? scopeNode.id : undefined\n\n\t\tconst section = createKitSectionMetaFromNode(\n\t\t\tsectionNode,\n\t\t\tctx,\n\t\t\tctx.collectionIdMap.get(sectionNode.id),\n\t\t\tlayoutId,\n\t\t\tscopeNode.getReplicaVariants(),\n\t\t\tfalse,\n\t\t\t{\n\t\t\t\tdescription,\n\t\t\t\tcategory,\n\t\t\t\trules: sectionNode.customizationsRules ?? emptyArray(),\n\t\t\t},\n\t\t)\n\t\tif (!section) continue\n\n\t\tconst customizations = processGeneratedFields(tree, section, fields, ctx)\n\n\t\t// We must update the kit section hash to the hash calculated at the time the customizations\n\t\t// were generated, otherwise it may have changed since, and subsequent requests to get the\n\t\t// latest customizations might prematurely be cancelled.\n\t\tconst kitSectionHash = ctx.kitSectionHashes.get(id)\n\t\tassert(isNumber(kitSectionHash), \"Kit section hash must be a number\")\n\n\t\tsections[id] = {\n\t\t\t...section,\n\t\t\tfields: customizations.fields,\n\t\t}\n\n\t\tupdates.push(latestTree => {\n\t\t\t// When a section is a Smart Component instance, we store updated customizations on the\n\t\t\t// SmartComponentNode.\n\t\t\tconst reference = getLoadedSourceNodeForSection(tree, sectionNode)\n\t\t\tconst latest = latestTree.getNodeWithTrait(reference.id, isCustomizable)\n\t\t\tif (!latest || !withKitSectionHash(latest)) return\n\n\t\t\t// Only overwrite user set values.\n\t\t\tconst customizationsCategory = isString(latest.customizationsCategory)\n\t\t\t\t? latest.customizationsCategory\n\t\t\t\t: createGeneratedValue(category)\n\t\t\tlatest.set({\n\t\t\t\tcustomizationsDescription: description,\n\t\t\t\tcustomizationsCategory,\n\t\t\t\tkitSectionHash,\n\t\t\t})\n\t\t})\n\n\t\tupdates.push(...customizations.updates)\n\t}\n\n\tlog.debug(`Request ${updates.length} descriptions took ${performance.now() - start}ms`)\n\n\treturn { sections, updates }\n}\n\nfunction getPageBackground(\n\ttree: CanvasTree,\n\tvariant: FrameNode & IsVariant & IsBreakpoint,\n\ttokens: Record<string, SerializableMutableNode>,\n): WireframerKitPageBackground | undefined {\n\tif (!variant.fillEnabled) return undefined\n\t// Ignore gradients for now, should be rare as a page background.\n\tif (variant.fillType !== \"color\") return undefined\n\tconst fillColor = variant.resolveValue(\"fillColor\")\n\n\tif (isTokenCSSVariable(fillColor)) {\n\t\tconst tokenId = tokenIdFromCSSVariable(fillColor)\n\t\tif (!tokenId) return undefined\n\t\tconst token = findTokenNode(tokenId, tree)\n\t\tif (!token) return undefined\n\n\t\ttokens[token.id] = token.toJS()\n\t\treturn stripMetadataFromCSSVariable(fillColor)\n\t}\n\n\treturn fillColor\n}\n\nfunction getPagePadding(variant: FrameNode & IsVariant & IsBreakpoint): {\n\tpadding: WireframerKitPagePadding | undefined\n\tpaddingTop: WireframerKitPagePadding | undefined\n\tpaddingRight: WireframerKitPagePadding | undefined\n\tpaddingBottom: WireframerKitPagePadding | undefined\n\tpaddingLeft: WireframerKitPagePadding | undefined\n} {\n\tconst paddingPerSide = variant.resolveValue(\"paddingPerSide\")\n\n\tif (paddingPerSide) {\n\t\treturn {\n\t\t\tpadding: undefined,\n\t\t\tpaddingTop: resolveAsNumber(variant, \"paddingTop\"),\n\t\t\tpaddingRight: resolveAsNumber(variant, \"paddingRight\"),\n\t\t\tpaddingBottom: resolveAsNumber(variant, \"paddingBottom\"),\n\t\t\tpaddingLeft: resolveAsNumber(variant, \"paddingLeft\"),\n\t\t}\n\t}\n\n\treturn {\n\t\tpadding: resolveAsNumber(variant, \"padding\"),\n\t\tpaddingTop: undefined,\n\t\tpaddingRight: undefined,\n\t\tpaddingBottom: undefined,\n\t\tpaddingLeft: undefined,\n\t}\n}\n\nfunction resolveAsNumber(\n\tvariant: FrameNode & IsVariant & IsBreakpoint,\n\tkey: \"padding\" | \"paddingTop\" | \"paddingRight\" | \"paddingBottom\" | \"paddingLeft\",\n): number | undefined {\n\tconst value = variant.resolveValue(key)\n\treturn isUndefined(value) ? undefined : cssSizeAsNumber(value, 0)\n}\n\nfunction getPageGap(variant: FrameNode & IsVariant & IsBreakpoint): WireframerKitPageGap | undefined {\n\treturn variant.resolveValue(\"gap\")\n}\n\n/**\n * Record the breakpoints as well as page properties like layout and background color in the kit.\n */\nfunction getBreakpointsAndPagePropertiesForKit(\n\ttree: CanvasTree,\n\tscopeNode: Loaded<WebPageNode | LayoutTemplateNode> | undefined,\n\ttokens: Record<string, SerializableMutableNode>,\n): Pick<WireframerKit, \"primaryBreakpoint\" | \"breakpoints\" | \"pageProperties\"> {\n\tif (!scopeNode) return { primaryBreakpoint: undefined, breakpoints: undefined, pageProperties: undefined }\n\n\tconst primaryVariant = scopeNode.getPrimaryVariant()\n\tconst replicaVariants = scopeNode.getReplicaVariants()\n\tconst variants = [primaryVariant, ...replicaVariants]\n\tconst primaryProperties = getPagePropertiesForVariant(tree, primaryVariant, tokens)\n\n\tconst breakpoints: Record<NodeID, WireframerKitBreakpoint> = {}\n\tconst pageProperties: Record<NodeID, Partial<WireframerKitPageProperties>> = {}\n\tfor (const variant of variants) {\n\t\tconst breakpointId = variant.id\n\t\tconst isPrimary = breakpointId === primaryVariant.id\n\n\t\tconst variantName = variant.resolveValue(\"name\")\n\t\tbreakpoints[breakpointId] = {\n\t\t\twidth: variant.width,\n\t\t\tname: variantName ?? Dictionary.Breakpoint,\n\t\t\tviewportHeight: variant.viewportHeight,\n\t\t}\n\n\t\tconst properties = isPrimary ? primaryProperties : getBreakpointOverrides(tree, primaryProperties, variant, tokens)\n\n\t\tif (!isEmptyObject(properties)) pageProperties[breakpointId] = properties\n\t}\n\n\treturn { primaryBreakpoint: primaryVariant.id, breakpoints, pageProperties }\n}\n\nfunction getPagePropertiesForVariant(\n\ttree: CanvasTree,\n\tvariant: FrameNode & IsVariant & IsBreakpoint,\n\ttokens: Record<string, SerializableMutableNode>,\n): Partial<WireframerKitPageProperties> {\n\tconst fillColor = getPageBackground(tree, variant, tokens)\n\tconst { padding, paddingTop, paddingRight, paddingBottom, paddingLeft } = getPagePadding(variant)\n\treturn {\n\t\tfillColor,\n\t\tpadding,\n\t\tpaddingTop,\n\t\tpaddingRight,\n\t\tpaddingBottom,\n\t\tpaddingLeft,\n\t\tgap: getPageGap(variant),\n\t}\n}\n\nfunction getBreakpointOverrides(\n\ttree: CanvasTree,\n\tprimaryProperties: Partial<WireframerKitPageProperties>,\n\treplicaVariant: FrameNode & IsVariant & IsBreakpoint,\n\ttokens: Record<string, SerializableMutableNode>,\n): Partial<WireframerKitPageProperties> {\n\tconst replicaProperties = getPagePropertiesForVariant(tree, replicaVariant, tokens)\n\treturn difference(replicaProperties, primaryProperties) ?? {}\n}\n\nfunction createWireframerToken(token: SerializableMutableNode): WireframerKitColorToken {\n\tassert(isString(token.id), \"Token ID must be a string\")\n\tassert(isString(token.name), \"Token name must be a string\")\n\tassert(isString(token.light), \"Token light must be a string\")\n\tassert(isUndefined(token.dark) || isString(token.dark), \"Token dark must be a string or undefined\")\n\n\treturn {\n\t\tid: token.id,\n\t\tname: token.name,\n\t\tlight: token.light,\n\t\tdark: token.dark,\n\t}\n}\n\nfunction createWireframerTokens(\n\ttokens: Record<string, SerializableMutableNode>,\n): Record<string, WireframerKitColorToken> {\n\tconst result: Record<string, WireframerKitColorToken> = {}\n\tfor (const id in tokens) {\n\t\tconst token = tokens[id]\n\t\tassert(token, \"Token must be defined\")\n\n\t\tresult[id] = createWireframerToken(token)\n\t}\n\treturn result\n}\n\nfunction getLoadedSourceNodeForSection<T extends CanvasNode & WithCustomizations>(\n\ttree: CanvasTree,\n\tnode: T,\n): T | Loaded<SmartComponentNode> {\n\tconst source = getSourceNodeForSection(tree, node)\n\tif (!isSmartComponentNode(source, true)) return node\n\n\t// We preload the scope nodes for sections that are smart component instances so that we can\n\t// freely process them without loading one by one.\n\tassert(source.isLoaded(), \"Smart component must be loaded\")\n\treturn source.loaded\n}\n\n/**\n * We must request new customizations from the LLM if the section has changed since the last time we\n * generated customizations for it, or if the category or description is missing.\n */\nexport function getNewKitSectionHash(\n\ttree: CanvasTree,\n\tsection: CanvasNode & WithKitSectionHash & WithCustomizations,\n\tvariants: readonly CanvasNode[],\n\tseenSmartComponentSourceNodes?: Set<NodeID>,\n): number | undefined {\n\tconst node = getLoadedSourceNodeForSection(tree, section)\n\n\t// When processing a Smart Component instance that we are going to use as the source node for\n\t// the section, don't generate new customizations multiple times.\n\tif (isSmartComponentNode(node) && seenSmartComponentSourceNodes) {\n\t\tif (seenSmartComponentSourceNodes.has(node.id)) return undefined\n\t\tseenSmartComponentSourceNodes.add(node.id)\n\t}\n\n\tif (usesModuleRevision(node, tree)) {\n\t\tif (!node.customizationsDescription || !node.customizationsCategory) return node.moduleSourceRevision\n\t\tif (node.kitSectionHash === node.moduleSourceRevision) return undefined\n\t\treturn node.moduleSourceRevision\n\t}\n\n\t// If the category or description is missing, we must generate new customizations.\n\tif (!node.customizationsDescription || !node.customizationsCategory) {\n\t\treturn calculateKitSectionHash(tree, node, variants)\n\t}\n\n\t// Otherwise, we must generate new customizations if the hash has changed.\n\tconst hash = calculateKitSectionHash(tree, node, variants)\n\tif (hash === node.kitSectionHash) return undefined\n\treturn hash\n}\n\n/**\n * Iterate the page sections to either gather metadata recorded in the tree for the Kit, or ask an\n * LLM to generate the customizations for the sections if applicable.\n */\nfunction collectSectionCustomizationsOnPage(\n\tscopeNode: Loaded<WebPageNode | LayoutTemplateNode>,\n\tsections: Record<NodeID, KitSectionMeta>,\n\tpromises: Promise<[NodeID, GeneratedSectionCustomizations]>[],\n\tengineScheduler: VekterEngineScheduler,\n\tctx: LocalKitContext,\n\ttraceConfig: OpenRouterFeatureStepTraceConfig,\n): void {\n\tconst { treeStore, modulesStore, assetStore } = ctx\n\tconst detailPageCollectionId = collectDetailPageCollection(treeStore.tree, scopeNode, ctx.collectedCollections)\n\n\tconst primaryVariant = scopeNode.getPrimaryVariant()\n\tif (primaryVariant.children.length === 0) return\n\n\tconst isLayoutTemplate = isLayoutTemplateNode(scopeNode)\n\tconst layoutId = isLayoutTemplate ? scopeNode.id : undefined\n\tconst replicaVariants = scopeNode.getReplicaVariants()\n\tconst smartComponentSourceNodes = new Set<NodeID>()\n\n\tfor (const section of primaryVariant.children) {\n\t\tif (!isCustomizable(section) || !withKitSectionHash(section)) continue\n\n\t\tctx.collectionIdMap.set(section.id, detailPageCollectionId)\n\n\t\tconst newKitSectionHash = getNewKitSectionHash(treeStore.tree, section, replicaVariants, smartComponentSourceNodes)\n\t\tif (isNumber(newKitSectionHash)) {\n\t\t\tconst promise = generateCustomizations(section, scopeNode, traceConfig, {\n\t\t\t\tcomponentLoader: ctx.componentLoader,\n\t\t\t\tmodulesStore,\n\t\t\t\ttree: ctx.treeStore.tree,\n\t\t\t\tengineChanges: engineScheduler.changes,\n\t\t\t\tassetMap: assetStore.assetMap,\n\t\t\t})\n\t\t\tctx.kitSectionHashes.set(section.id, newKitSectionHash)\n\t\t\tpromises.push(promise)\n\t\t} else {\n\t\t\tconst reference = getLoadedSourceNodeForSection(treeStore.tree, section)\n\t\t\tconst description = reference.customizationsDescription\n\t\t\tconst category = getCustomizationsCategory(reference)\n\n\t\t\tassert(description, \"Description must be defined\", reference.id)\n\t\t\tassert(category, \"Category must be defined\", reference.id)\n\n\t\t\tconst result = createKitSectionMetaFromNode(\n\t\t\t\tsection,\n\t\t\t\tctx,\n\t\t\t\tdetailPageCollectionId,\n\t\t\t\tlayoutId,\n\t\t\t\treplicaVariants,\n\t\t\t\ttrue,\n\t\t\t\t{\n\t\t\t\t\tdescription,\n\t\t\t\t\tcategory,\n\t\t\t\t\trules: section.customizationsRules ?? emptyArray(),\n\t\t\t\t},\n\t\t\t)\n\t\t\tif (result) sections[section.id] = result\n\t\t}\n\t}\n}\n\nfunction collectVectorSet(setId: GlobalModuleId, ctx: LocalKitContext) {\n\tconst vectorSet = getVectorSet(setId, ctx)\n\tif (!vectorSet) return\n\n\tctx.sets[setId] = vectorSet\n\tconst dictionary = getVectorSetDictionary(setId, ctx)\n\tif (dictionary) ctx.vectors[setId] = dictionary\n}\n", "import type { GlobalModuleId, ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { CollectionVariableDefinition } from \"document/models/CanvasTree/traits/CollectionVariableDefinition.ts\"\nimport type { EnumVariableCase, VariableID } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { isObject, isString } from \"utils/typeChecks.ts\"\nimport type { KitClipboardData } from \"./getKitSectionNodeData.ts\"\n\nexport interface KitItemSource {\n\tprojectId: string\n\tlayerId: string\n}\n\nexport interface Section {\n\tsource: KitItemSource\n\tid: string\n\tdescription: string\n\tenabled: boolean\n\tload: () => Promise<{ default: unknown }>\n}\n\nexport type SectionWithOverride = Omit<Section, \"load\"> & { hasOverride: boolean; isInRepo: boolean } & (\n\t\t| Pick<Section, \"load\">\n\t\t| { data: KitClipboardData }\n\t)\n\nexport interface SectionOverride {\n\tsource: KitItemSource\n\tid?: string\n\tdescription?: string\n\tenabled?: boolean\n\tdata?: KitClipboardData\n}\n\nexport interface ResolvedSection {\n\tsource: KitItemSource\n\t// KITS @TODO: Make this NodeID once we migrate fAI Wireframer kit to a real kit.\n\tid: string\n\tdescription: string\n\thasOverride: boolean\n\tdata: KitClipboardData\n}\n\nexport interface ControlPropField {\n\tkey: string\n\ttitle: string\n\ticonSet?: GlobalModuleId\n}\n\nexport interface ControlPropFields {\n\t[key: string]: ControlPropField[]\n}\n\n/**\n * Dictionary of vector set display names to their corresponding {@link GlobalModuleId}.\n */\nexport type VectorSetDictionary = Record<string, GlobalModuleId>\n\n/**\n * Dictionary of vector/icon names to their {@link ModuleExportIdentifierString}.\n */\nexport type VectorSetModuleData = Record<string, ModuleExportIdentifierString>\n\n/**\n * Dictionary of vector sets (by {@link GlobalModuleId}) to their icons.\n */\nexport type VectorSetsModuleData = Record<GlobalModuleId, VectorSetModuleData>\n\nexport function isVectorSetDictionary(data: unknown): data is VectorSetDictionary {\n\treturn isObject(data) && Object.values(data).every(value => isString(value))\n}\n\ntype KitCollectionReferenceKind = \"single\" | \"multi\"\n\nexport interface KitCollectionTemplateReference {\n\tcollection: string // The name of the collection template.\n\tkind: KitCollectionReferenceKind\n}\n\n/**\n * These variables define the collection schema.\n * We use defaultValueSuggestions to store all possible image values for an image variable.\n * We use reference to store a single or multiple reference to another collection template.\n */\nexport type KitCollectionTemplateVariable = CollectionVariableDefinition & {\n\tdefaultValueSuggestions?: string[]\n\treference?: KitCollectionTemplateReference\n\ticonSet?: GlobalModuleId\n}\n\nexport interface KitCollectionTemplate {\n\tid: NodeID\n\tname: string\n\tvariables: KitCollectionTemplateVariable[]\n}\n\ninterface CMSConnectedFieldReference {\n\tcollectionId: NodeID // When building section fields we don't know the collection template names so we store the id.\n\tkind: KitCollectionReferenceKind\n}\n\n// These fields are used to connect the section to a collection.\n// We send this data to the LLM so it knows which fields are possible to connect to a collection and\n// how to connect them. We also send this information to the LLm when generating content for these fields.\nexport interface CMSConnectedField {\n\tid: VariableID\n\tproviderId?: NodeID\n\tname: string\n\ttype: string\n\trequired?: boolean\n\tmaxLength?: number\n\tmin?: number\n\tmax?: number\n\tcases?: readonly EnumVariableCase[]\n\treference?: CMSConnectedFieldReference\n}\n\nexport interface ResolvedSectionsWithControlPropFields {\n\tsections: ResolvedSection[]\n\tcontrolPropFields?: ControlPropFields\n\tvectorSetModuleData?: VectorSetModuleData\n\tcollections?: KitCollectionTemplate[]\n\tsourceProjectId?: string\n}\n\nexport type LocalNodeInfo =\n\t| {\n\t\t\tenabled: true\n\t\t\tid: string\n\t\t\tdescription?: string\n\t\t\tcategory?: string\n\t\t\trules?: readonly string[]\n\t\t\tclipboardData: KitClipboardData\n\t\t\tcontrolPropFields?: ControlPropFields\n\t\t\tvectorSetsModuleData?: VectorSetsModuleData\n\t\t\tcollections?: KitCollectionTemplate[]\n\t  }\n\t| {\n\t\t\tenabled: false\n\t  }\n", "import type { Asset } from \"@framerjs/assets\"\nimport type { GlobalModuleId, LocalModuleExportIdentifierString, ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert, asGlobalId, getServiceMap, localModuleIdentifier } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { AnySmartComponentNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isExternalModuleNode, isSmartComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { AssetStore } from \"document/stores/AssetStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { isEqual } from \"library/render/utils/isEqual.ts\"\nimport type { SaveId } from \"modules/types.ts\"\nimport { isObject } from \"utils/typeChecks.ts\"\nimport * as yaml from \"yaml\"\nimport type { KitClipboardData } from \"../sections/getKitSectionNodeData.ts\"\nimport type { VectorSetDictionary } from \"../sections/types.ts\"\nimport { isVectorSetDictionary } from \"../sections/types.ts\"\nimport { getSectionScreenshotUrl } from \"../utils/sectionScreenshot.ts\"\nimport type {\n\tWireframerKit,\n\tWireframerKitColorToken,\n\tWireframerKitJSON,\n\tWireframerKitPageProperties,\n\tWireframerKitVectorSetInfo,\n} from \"../utils/wireframerKit.ts\"\nimport { isKitItemClipboardData, isWireframerKitJSON } from \"../utils/wireframerKit.ts\"\nimport { KitAliasManager } from \"./KitAliasManager.ts\"\nimport { replaceReferencesToLocalKitSourcesInline } from \"./clipboardData.ts\"\n\nexport class RemoteKit extends KitAliasManager implements WireframerKit {\n\tconstructor(\n\t\tprivate readonly moduleId: GlobalModuleId,\n\t\tprivate readonly saveId: SaveId,\n\t\tprivate readonly kit: WireframerKitJSON,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t) {\n\t\tsuper(kit.sections, kit.collections, kit.layoutTemplates, kit.breakpoints)\n\t}\n\n\tstatic async fromModule(\n\t\tmoduleId: GlobalModuleId,\n\t\tsaveId: SaveId,\n\t\ttreeStore: TreeStore,\n\t\tmodulesStore: ModulesStore,\n\t): Promise<RemoteKit> {\n\t\tconst response = await fetch(`${getServiceMap().modulesCDN}/${moduleId}/${saveId}/kit.json`)\n\t\tassert(response.ok, \"Failed to fetch kit\")\n\n\t\tconst kit = await response.json()\n\t\tassert(isWireframerKitJSON(kit), \"Invalid kit\", moduleId, saveId)\n\n\t\treturn new RemoteKit(moduleId, saveId, kit, treeStore, modulesStore)\n\t}\n\n\tget id(): string {\n\t\treturn this.kit.id\n\t}\n\n\tget title(): string {\n\t\treturn this.kit.title\n\t}\n\n\tget prompt(): string | undefined {\n\t\treturn this.kit.prompt\n\t}\n\n\tget sets(): Record<GlobalModuleId, WireframerKitVectorSetInfo> {\n\t\treturn this.kit.sets\n\t}\n\n\tget tokens(): Record<string, WireframerKitColorToken> {\n\t\treturn this.kit.tokens\n\t}\n\n\tget pageProperties(): Record<NodeID, Partial<WireframerKitPageProperties>> | undefined {\n\t\treturn this.kit.pageProperties\n\t}\n\n\tget primaryBreakpoint(): NodeID | undefined {\n\t\treturn this.kit.primaryBreakpoint\n\t}\n\n\tprivate lastIdentifierBySourceNodeId: Record<LocalModuleExportIdentifierString, NodeID> = {}\n\tprivate getKitSourceNodes(): Map<LocalModuleExportIdentifierString, AnySmartComponentNode> {\n\t\tconst sourceNodes = new Map<LocalModuleExportIdentifierString, AnySmartComponentNode>()\n\t\tconst identifierBySourceId: Record<LocalModuleExportIdentifierString, NodeID> = {}\n\t\tfor (const scope of this.treeStore.tree.root.children) {\n\t\t\tif (!isSmartComponentNode(scope) || !scope.kitComponentSource) continue\n\t\t\tsourceNodes.set(scope.kitComponentSource.sourceModuleIdentifier, scope)\n\t\t\tidentifierBySourceId[scope.kitComponentSource.sourceModuleIdentifier] = scope.id\n\t\t}\n\n\t\t// When the source nodes change, we need to clear the cache to ensure that new insertions of\n\t\t// clipboard data are modified to reference the latest source nodes.\n\t\tif (!isEqual(identifierBySourceId, this.lastIdentifierBySourceNodeId, true)) {\n\t\t\tthis.kitItemCache.clear()\n\t\t}\n\t\tthis.lastIdentifierBySourceNodeId = identifierBySourceId\n\t\treturn sourceNodes\n\t}\n\n\t/**\n\t * When the section is a top-level smart component that is not local to this project, we want to\n\t * insert \"detached\" layers during generation before replacing the section with newly generated\n\t * instances.\n\t */\n\tprivate getSectionFileName(\n\t\tid: NodeID,\n\t\tsource: boolean,\n\t\tsourceNodes: Map<LocalModuleExportIdentifierString, AnySmartComponentNode>,\n\t): string {\n\t\tconst section = this.sections[id]\n\t\tif (!section || !section.moduleIdentifier || !source || sourceNodes.has(section.moduleIdentifier)) {\n\t\t\treturn id\n\t\t}\n\n\t\treturn `${id}-source`\n\t}\n\n\t/** Sections and layout templates are immutable so we can cache them in memory. */\n\tprivate kitItemCache = new Map<NodeID, KitClipboardData>()\n\tasync getClipboardDataById(id: NodeID, source: boolean = true): Promise<KitClipboardData> {\n\t\tconst sourceNodes = this.getKitSourceNodes()\n\t\tconst fileName = this.getSectionFileName(id, source, sourceNodes)\n\t\tconst cached = this.kitItemCache.get(fileName)\n\t\tif (cached) return cached\n\n\t\tconst response = await fetch(`${getServiceMap().modulesCDN}/${this.moduleId}/${this.saveId}/${fileName}.json`)\n\t\tassert(response.ok, \"Failed to fetch kit item json\", fileName)\n\n\t\tconst data = await response.json()\n\t\tassert(isObject(data), \"Invalid kit item\")\n\t\tassert(isKitItemClipboardData(data), \"Invalid kit section\")\n\n\t\t// If we have created local copies of Smart Components, we want to always add sections to\n\t\t// the project that point to the local copies, and the renamed variants. By doing this\n\t\t// before returning the clipboard data we guarantee that all consumers will use the local\n\t\t// copies. It is safe to modify inline since we know it will not be consumed before this\n\t\t// point.\n\t\treplaceReferencesToLocalKitSourcesInline(data, sourceNodes)\n\n\t\tthis.kitItemCache.set(fileName, data)\n\t\treturn data\n\t}\n\n\tgetSectionScreenshot(_: VekterEngine, id: string, darkMode: boolean): string | undefined {\n\t\treturn getSectionScreenshotUrl(this.moduleId, id, { darkMode, saveId: this.saveId })\n\t}\n\n\t/** Vector sets are immutable so we can cache them in memory. */\n\tprivate vectorsCache = new Map<GlobalModuleId, VectorSetDictionary>()\n\tprivate async getVectorSetDictionary(setId: GlobalModuleId): Promise<VectorSetDictionary | undefined> {\n\t\tconst cached = this.vectorsCache.get(setId)\n\t\tif (cached) return cached\n\n\t\tconst response = await fetch(`${getServiceMap().modulesCDN}/${this.moduleId}/${this.saveId}/${setId}.json`)\n\t\tif (!response.ok) return\n\n\t\tconst data = await response.json()\n\t\tif (!isObject(data) || !isVectorSetDictionary(data)) return\n\n\t\tthis.vectorsCache.set(setId, data)\n\t\treturn data\n\t}\n\n\tasync lookupVectorByName(setId: GlobalModuleId, name: string): Promise<ModuleExportIdentifierString | undefined> {\n\t\tconst set = this.kit.sets[setId]\n\t\tif (!set) return undefined\n\n\t\tconst hasSet =\n\t\t\tthis.treeStore.tree.getNodeWithTrait(setId, isExternalModuleNode) ??\n\t\t\tthis.modulesStore.getPersistedModuleByGlobalId(setId)\n\t\tif (!hasSet) await this.modulesStore.addOrUpdateVectorSetAndVectors({ moduleId: setId, saveId: set.saveId })\n\n\t\tconst data = await this.getVectorSetDictionary(setId)\n\t\tif (!data) return undefined\n\n\t\tconst vectorGlobalId = data[name]\n\t\tif (!vectorGlobalId) return undefined\n\n\t\tconst external = this.treeStore.tree.getNodeWithTrait(vectorGlobalId, isExternalModuleNode)\n\t\tif (external) return external.codeComponentIdentifier\n\n\t\tconst local = this.modulesStore.getPersistedModuleByGlobalId(vectorGlobalId)\n\t\tif (local) return localModuleIdentifier(local.localId, \"default\").value\n\t}\n\n\tasync createIconSetsForPrompt(): Promise<string | undefined> {\n\t\tconst vectorSets = await this.loadVectorSets()\n\t\tif (vectorSets.size === 0) return undefined\n\n\t\tconst catalog: Record<GlobalModuleId, { icons: string[] }> = {}\n\t\tfor (const [setId, items] of vectorSets) {\n\t\t\tcatalog[asGlobalId(setId)] = { icons: Object.keys(items) }\n\t\t}\n\n\t\treturn yaml.stringify(catalog)\n\t}\n\n\tasync duplicateAssets(assetStore: AssetStore, keys: string[]): Promise<readonly Asset[]> {\n\t\tassert(assetStore.assetService, \"Asset service is not available\")\n\t\treturn assetStore.assetService.duplicateModuleAssets(this.moduleId, this.saveId, keys)\n\t}\n\n\tprivate async loadVectorSets(): Promise<Map<GlobalModuleId, VectorSetDictionary>> {\n\t\tawait Promise.all(Object.keys(this.sets).map(setId => this.getVectorSetDictionary(asGlobalId(setId))))\n\t\treturn this.vectorsCache\n\t}\n}\n", "import type { ModulesAPI } from \"@framerjs/framer-services\"\nimport type { GlobalModuleId } from \"@framerjs/shared\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\n\nexport interface Library {\n\tid: string\n\townerTeamId: string\n\ttitle: string\n\tpermissions: LibraryPermissions\n}\n\nexport interface LibraryPermissions {\n\tcanEdit: boolean\n}\n\nexport interface LibraryModule {\n\tmodule: ModulesAPI.ModuleWithSave\n\texportSpecifier: string\n\tpath: string\n\ttitle: string\n\taddedBy: {\n\t\tid: string\n\t\tname: string\n\t}\n}\n\nexport async function getLibraries(req: { teamId?: string; moduleId?: string }): Promise<Library[]> {\n\tconst response = await apiFetcher.get(\"/modules/v1/libraries/\", req)\n\treturn response.data\n}\n\nexport async function addToLibrary({\n\tlibraryId,\n\tmoduleId,\n\texportSpecifier,\n\tpath,\n\ttitle,\n}: {\n\tlibraryId: string\n\tmoduleId: GlobalModuleId\n\texportSpecifier: string\n\tpath?: string\n\ttitle?: string\n}): Promise<LibraryModule> {\n\treturn apiFetcher.post(`/modules/v1/libraries/${libraryId}/modules/`, {\n\t\tmoduleId,\n\t\texportSpecifier,\n\t\tpath,\n\t\ttitle,\n\t})\n}\n\nexport async function getModulesForLibrary(req: {\n\tlibraryId: string\n}): Promise<{ data: LibraryModule[]; permissions: LibraryPermissions }> {\n\treturn apiFetcher.get(`/modules/v1/libraries/${req.libraryId}/modules/`)\n}\n\nexport async function removeModuleFromLibrary(req: {\n\tlibraryId: string\n\tmoduleId: GlobalModuleId\n\texportSpecifier: string\n}): Promise<void> {\n\treturn apiFetcher.delete(`/modules/v1/libraries/${req.libraryId}/modules/${req.moduleId}/${req.exportSpecifier}`)\n}\n\nexport async function updateModule(req: {\n\tlibraryId: string\n\tmoduleId: GlobalModuleId\n\texportSpecifier: string\n\tpath?: string\n\ttitle?: string\n\tdescription?: string | null\n}): Promise<LibraryModule> {\n\tconst { libraryId, moduleId, exportSpecifier, ...changes } = req\n\treturn apiFetcher.post(`/modules/v1/libraries/${libraryId}/modules/${moduleId}/${exportSpecifier}`, changes)\n}\n", "import { ApiError } from \"@framerjs/app-shared\"\nimport { createAbsoluteImageAssetURL } from \"@framerjs/assets\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, type GlobalModuleId, ModuleType, asGlobalId, unhandledError } from \"@framerjs/shared\"\nimport type { LanguageModelUsage } from \"ai\"\nimport type { StepResult, WireframerSessionUpdateCallbacks } from \"app/ai/WireframerSession.ts\"\nimport { WireframerSession } from \"app/ai/WireframerSession.ts\"\nimport { DefaultKit, type DefaultKitOptions } from \"app/ai/kits/DefaultKit.ts\"\nimport { LocalKit } from \"app/ai/kits/LocalKit.ts\"\nimport { RemoteKit } from \"app/ai/kits/RemoteKit.ts\"\nimport type { WireframerWorkerTask } from \"app/ai/orchestrator/tasks.ts\"\nimport type { AIChatHistory, AIUserMessage } from \"app/ai/types/AIChatHistory.ts\"\nimport {\n\ttrackOrchestratorPlanFail,\n\ttrackOrchestratorPlanSuccess,\n\ttrackStepFail,\n\ttrackStepSuccess,\n\ttrackWireframerFinish,\n\ttrackWireframerStart,\n} from \"app/ai/utils/tracking.ts\"\nimport type { WireframerKit, WireframerKitListItem } from \"app/ai/utils/wireframerKit.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { projectFeatures } from \"app/projectFeatures.ts\"\nimport type { KitSection } from \"code-generation/utils/KitSectionStructureCollector.ts\"\nimport { KitSectionsStructureCollector } from \"code-generation/utils/KitSectionStructureCollector.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { addToLibrary } from \"document/library/libraryApi.ts\"\nimport type { CanvasNode, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isDesignPageNode, isFrameNode, isWebPageNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport { slugify } from \"library/utils/slugify.ts\"\nimport type { SaveId } from \"modules/types.ts\"\nimport { ModuleMetadata } from \"modules/types.ts\"\nimport { inc } from \"semver\"\nimport { isObject, isString } from \"utils/typeChecks.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport type { LibraryStore } from \"./LibraryStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { ProjectStore } from \"./ProjectStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst EMPTY_CHAT_HISTORY: AIChatHistory = []\n\nconst webPageSessionKey = Symbol(\"web-pages\")\ntype SessionId = NodeID | typeof webPageSessionKey\n\nexport class AIGenerationStore extends EngineStore {\n\t// Generation tracking\n\tprivate _currentPageBeingGenerated: NodeID | null = null\n\tprivate _currentSectionBeingGenerated: NodeID | null = null\n\n\t// Each design page has its own session, and all the web pages share the same session.\n\tprivate sessions: Map<SessionId, WireframerSession> = new Map()\n\tprivate currentWireframerSessionId: SessionId | undefined = undefined\n\n\t// In memory kit sections structure per page...\n\tprivate _transientKitSectionsStructure = new Map<NodeID, KitSection[]>()\n\n\t// Using a counter to track if the chat history has changed.\n\t// This is used to trigger engine changes updates on this store instead of setting a new chat history array every time.\n\tprivate chatHistoryUpdateCount = 0\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly libraryStore: LibraryStore,\n\t) {\n\t\tsuper()\n\n\t\tif (!experiments.isOn(\"wireframerKits\")) return\n\t\tvoid this.listKits().catch(unhandledError)\n\t}\n\n\t// Unified methods that work for both behaviors\n\tgetChatHistory(sessionId: SessionId = this.currentWireframerSessionId ?? webPageSessionKey): AIChatHistory {\n\t\treturn this.sessions.get(sessionId)?.chatHistory ?? EMPTY_CHAT_HISTORY\n\t}\n\n\tisGeneratingPage(nodeId: NodeID): boolean {\n\t\treturn this._currentPageBeingGenerated === nodeId\n\t}\n\n\tget isGenerating(): boolean {\n\t\tif (!this.currentWireframerSessionId) return false\n\t\treturn this.sessions.get(this.currentWireframerSessionId)?.isGenerating ?? false\n\t}\n\n\tgetSectionBeingGenerated(): NodeID | null {\n\t\treturn this._currentSectionBeingGenerated\n\t}\n\n\tsetSectionBeingGenerated(sectionId: NodeID | null): void {\n\t\tconst actualSectionId = sectionId || null\n\n\t\tif (actualSectionId) {\n\t\t\tconst sectionNode = this.treeStore.tree.get(actualSectionId)\n\t\t\tif (!sectionNode) return\n\n\t\t\tconst scopeNode = this.treeStore.tree.getScopeNodeFor(sectionNode)\n\t\t\tif (!isWebPageNode(scopeNode) && !isDesignPageNode(scopeNode)) return\n\n\t\t\tthis._currentPageBeingGenerated = scopeNode.id\n\t\t}\n\n\t\tthis._currentSectionBeingGenerated = actualSectionId\n\t}\n\n\tresetGenerationState() {\n\t\tthis._currentPageBeingGenerated = null\n\t\tthis._currentSectionBeingGenerated = null\n\t}\n\n\tcacheKitSectionsStructure(nodeId: NodeID, structure: KitSection[]) {\n\t\tthis._transientKitSectionsStructure.set(nodeId, structure)\n\n\t\treturn structure\n\t}\n\n\tdeleteKitSectionsStructure(nodeId: NodeID) {\n\t\tthis._transientKitSectionsStructure.delete(nodeId)\n\t}\n\n\tgetKitSectionsStructure(nodeId: NodeID, kit: WireframerKit): KitSection[] | undefined {\n\t\tconst node = this.treeStore.tree.get(nodeId)\n\t\tif (!node) return\n\n\t\tif (isWebPageNode(node)) {\n\t\t\tconst transient = this._transientKitSectionsStructure.get(nodeId)\n\t\t\tif (transient) replaceKitSectionId(kit, transient)\n\n\t\t\tconst localModule = this.modulesStore.forType(ModuleType.Screen).getByStableName(nodeId)\n\t\t\treturn replaceKitSectionId(kit, localModule?.getKitSectionsStructure())\n\t\t}\n\n\t\t// Otherwise assume it's a design page screen.\n\t\tconst scope = this.treeStore.tree.get(node.parentid)\n\t\tif (!isDesignPageNode(scope)) return\n\n\t\treturn replaceKitSectionId(kit, this.getDesignPageScreenKitSectionsStructure(node))\n\t}\n\n\tprivate createUserMessage(\n\t\tprompt: AIUserMessage[\"content\"],\n\t\tsource: AIUserMessage[\"source\"],\n\t\tisSuggestion: boolean,\n\t): AIUserMessage {\n\t\treturn {\n\t\t\trole: \"user\",\n\t\t\tcontent: prompt,\n\t\t\ttimestamp: Date.now(),\n\t\t\tisSuggestion,\n\t\t\tsource,\n\t\t}\n\t}\n\n\tasync generate(\n\t\tengine: VekterEngine,\n\t\tprompt: AIUserMessage[\"content\"],\n\t\tsource: AIUserMessage[\"source\"],\n\t\tisSuggestion = false,\n\t\tonError?: () => void,\n\t) {\n\t\tif (getIsViewOnly(engine, \"canDesign\")) return\n\n\t\tconst normalizedPrompt = prompt.trim()\n\t\tconst userMessage = this.createUserMessage(normalizedPrompt, source, isSuggestion)\n\n\t\tconst designPageId = isDesignPageNode(engine.stores.scopeStore.active)\n\t\t\t? engine.stores.scopeStore.active.id\n\t\t\t: undefined\n\t\tconst existingSessionId = designPageId ?? webPageSessionKey\n\t\tconst existingSession = this.sessions.get(existingSessionId)\n\t\t// If there's an existing session, start a new turn in the current session. Otherwise, create a new session.\n\t\tif (existingSession) {\n\t\t\tthis.currentWireframerSessionId = existingSessionId\n\t\t\tvoid existingSession.startTurn(engine, userMessage)\n\t\t\treturn\n\t\t}\n\n\t\t// Note: the callbacks are created only once when creating the session, any values\n\t\t// used in the callbacks would be captured in the closure. Use the information stored in\n\t\t// the session to make sure they are updated.\n\t\tconst callbacks: WireframerSessionUpdateCallbacks = {\n\t\t\tonMessageUpdate: () => {\n\t\t\t\tthis.chatHistoryUpdateCount++\n\t\t\t},\n\t\t\tonTurnStart: (session: WireframerSession) => {\n\t\t\t\tconst { sessionId, turn, chatHistory } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on turn start\")\n\t\t\t\ttrackWireframerStart(\n\t\t\t\t\tturn.message.content,\n\t\t\t\t\t{ sessionId, generationId: turn.id },\n\t\t\t\t\tturn.message.isSuggestion,\n\t\t\t\t\tchatHistory.length,\n\t\t\t\t\tturn.message.source,\n\t\t\t\t)\n\t\t\t},\n\t\t\tonTurnComplete: (session: WireframerSession, durationMs: number) => {\n\t\t\t\tthis.resetGenerationState()\n\n\t\t\t\tconst { sessionId, turn } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on turn complete\")\n\t\t\t\ttrackWireframerFinish({ sessionId, generationId: turn.id }, durationMs)\n\t\t\t},\n\t\t\tonTurnError: () => {\n\t\t\t\t// @TODO: do we want to track turn error?\n\t\t\t\tonError?.()\n\t\t\t},\n\t\t\tonPlanReady: (\n\t\t\t\tsession: WireframerSession,\n\t\t\t\tplan: WireframerWorkerTask[],\n\t\t\t\tusage: LanguageModelUsage,\n\t\t\t\tdurationMs: number,\n\t\t\t) => {\n\t\t\t\tconst { sessionId, turn } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on plan ready\")\n\t\t\t\ttrackOrchestratorPlanSuccess({ sessionId, generationId: turn.id }, usage, plan.length, durationMs)\n\t\t\t},\n\t\t\tonPlanError: (session: WireframerSession, error: unknown, durationMs: number) => {\n\t\t\t\tconst { sessionId, turn } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on plan error\")\n\t\t\t\ttrackOrchestratorPlanFail({ sessionId, generationId: turn.id }, error, durationMs)\n\t\t\t},\n\t\t\tonStepComplete: (\n\t\t\t\tsession: WireframerSession,\n\t\t\t\ttask: WireframerWorkerTask,\n\t\t\t\tresult: StepResult,\n\t\t\t\tdurationMs: number,\n\t\t\t) => {\n\t\t\t\tthis.resetGenerationState()\n\n\t\t\t\tconst { sessionId, turn } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on step complete\")\n\t\t\t\ttrackStepSuccess({ sessionId, generationId: turn.id }, task, result, durationMs)\n\t\t\t},\n\t\t\tonStepError: (session: WireframerSession, task: WireframerWorkerTask, error: unknown, durationMs: number) => {\n\t\t\t\tconst { sessionId, turn } = session\n\t\t\t\tassert(turn, \"Wireframer turn must be defined on step error\")\n\t\t\t\ttrackStepFail({ sessionId, generationId: turn.id }, task, error, durationMs)\n\t\t\t},\n\t\t}\n\t\tconst newSession = new WireframerSession(designPageId, callbacks)\n\n\t\tthis.sessions.set(existingSessionId, newSession)\n\t\tthis.currentWireframerSessionId = existingSessionId\n\t\tvoid newSession.startTurn(engine, userMessage)\n\t}\n\n\tsetCurrentSessionId(sessionId: SessionId | undefined = webPageSessionKey) {\n\t\tthis.currentWireframerSessionId = sessionId\n\t}\n\n\tprivate designPageKitSectionsStructureCache = new Map<\n\t\tNodeID,\n\t\t{\n\t\t\trevision: number\n\t\t\tstructure: KitSection[]\n\t\t}\n\t>()\n\n\tprivate getDesignPageScreenKitSectionsStructure(node: CanvasNode): KitSection[] | undefined {\n\t\tif (!isFrameNode(node)) return\n\t\t// Wireframer compares the name of the screen to the route in the proposal. Without a name,\n\t\t// it's not really helpful.\n\t\tif (!node.name) return\n\n\t\t// Design page screens run code generation on demand (when previewing), so its module\n\t\t// revision is not always recalculated in time. But the revision hint is always bumped\n\t\t// whenever a node is set to draft, so we use that to invalidate the cache.\n\t\tconst revision = node.moduleSourceRevisionHint\n\t\tif (!revision) return\n\n\t\tconst cachedValue = this.designPageKitSectionsStructureCache.get(node.id)\n\t\tif (cachedValue && cachedValue.revision === revision) {\n\t\t\treturn cachedValue.structure\n\t\t}\n\n\t\tconst collector = new KitSectionsStructureCollector(this.modulesStore, this.treeStore.tree, this.componentLoader)\n\t\tcollectKitSectionsStructure(node, collector, undefined)\n\n\t\tconst structure = collector.structure\n\n\t\t// Reset the cache if there are too many entries.\n\t\tif (this.designPageKitSectionsStructureCache.size > 100) {\n\t\t\tthis.designPageKitSectionsStructureCache.clear()\n\t\t}\n\n\t\tthis.designPageKitSectionsStructureCache.set(node.id, {\n\t\t\trevision: revision,\n\t\t\tstructure,\n\t\t})\n\n\t\treturn structure\n\t}\n\n\tasync getKit(engine: VekterEngine, options: DefaultKitOptions): Promise<WireframerKit> {\n\t\t// We also need to check the experiment here because the project feature is also used for the project that\n\t\t// drives Wireframer default sections.\n\t\tconst isKitProject = experiments.isOn(\"wireframerKits\") && projectFeatures.isOn(\"kit\")\n\n\t\tconst selectedKitId = this.selectedKitId ?? this.treeStore.tree.root.kitManifest?.id\n\t\tconst kitManifest = this.treeStore.tree.root.kitManifest\n\t\tif (isKitProject && selectedKitId && selectedKitId === kitManifest?.id) {\n\t\t\tconst localKit = await this.getLocalKit(engine)\n\t\t\tif (localKit) return localKit\n\t\t}\n\n\t\tconst firstRemoteKit = this.kits?.[0]\n\t\tconst kit = selectedKitId ? this.kits?.find(({ id }) => id === selectedKitId) : firstRemoteKit\n\t\tif (experiments.isOn(\"wireframerKits\") && kit?.moduleId && kit?.saveId) {\n\t\t\tconst selectedKit = await this.getRemoteKit({ moduleId: kit.moduleId, saveId: kit.saveId })\n\t\t\tif (selectedKit) return selectedKit\n\t\t}\n\n\t\treturn this.getDefaultKit(engine, options)\n\t}\n\n\tselectedKitId: string | null = null\n\tkits: readonly WireframerKitListItem[] | null = null\n\n\tasync listKits() {\n\t\tif (this.kits) return this.kits\n\n\t\tconst { data } = await this.modulesStore.listKits()\n\n\t\tconst list: WireframerKitListItem[] = []\n\n\t\tfor (const kit of data) {\n\t\t\tconst kitMetadata = kit.module.metadata[ModuleMetadata.Kit]\n\t\t\tif (!isObject(kitMetadata)) continue\n\t\t\tif (!isString(kitMetadata.id)) continue\n\t\t\tif (!isString(kitMetadata.title)) continue\n\n\t\t\tlist.push({\n\t\t\t\tid: kitMetadata.id,\n\t\t\t\ttitle: kitMetadata.title,\n\t\t\t\ticon: isString(kitMetadata.icon) ? createAbsoluteImageAssetURL(kitMetadata.icon) : undefined,\n\t\t\t\tmoduleId: asGlobalId(kit.module.id),\n\t\t\t\tsaveId: kit.module.saveId,\n\t\t\t\tversion: kit.module.lastPublish?.version,\n\t\t\t})\n\t\t}\n\n\t\treturn (this.kits = list)\n\t}\n\n\tasync publishLocalKit(engine: VekterEngine) {\n\t\tassert(this.projectStore.project?.id, \"ProjectStore must be initialized to publish a kit.\")\n\n\t\tconst {\n\t\t\tassetStore,\n\t\t\tloadingStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tcodeGenerationStore,\n\t\t\tscopeStore,\n\t\t\tdebugStore,\n\t\t\tpublishStore,\n\t\t} = engine.stores\n\n\t\tconst handle = this.modulesStore.forType(ModuleType.Kit).getByStableName(\"kit\")\n\t\tconst publish = handle.lastPublish\n\n\t\tconst kitManifest = this.treeStore.tree.root.kitManifest\n\t\tassert(kitManifest, \"Kit manifest is required\")\n\n\t\tconst { title } = kitManifest\n\t\tassert(title, \"Kit title is required\")\n\n\t\t// Only users in a team can publish kit modules for the first time.\n\t\tconst teamLibrary = this.libraryStore.teamLibrary\n\t\tassert(teamLibrary || publish, \"Access to the team library is required to publish a kit module for the first time.\")\n\n\t\tconst namespaceId =\n\t\t\tpublish?.namespaceId ??\n\t\t\t// We need to create a namespace if one does not exist yet.\n\t\t\t(await this.modulesStore.createNamespace(this.projectStore.project.id, \"project\")).namespaceId\n\n\t\t// Generate the kit module and persist it.\n\t\tawait LocalKit.update(\n\t\t\tthis.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tassetStore,\n\t\t\tloadingStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tthis.projectStore,\n\t\t\tcodeGenerationStore,\n\t\t\tscopeStore,\n\t\t\tdebugStore,\n\t\t\tpublishStore,\n\t\t\tengine.scheduler,\n\t\t)\n\n\t\t// Publish the kit module to the team library.\n\t\tconst nextVersion = inc(publish?.version ?? \"0.0.0\", \"minor\") ?? \"0.1.0\"\n\t\tawait handle.publish(namespaceId, slugify(title), nextVersion)\n\n\t\t// If the user is not in a team, we can stop here. We will have early returned before\n\t\t// publishing if this was the first publish and the user didn't have access to the team\n\t\t// library.\n\t\tif (!teamLibrary) return\n\n\t\t// Add to library is idempotent so it is ok to call it even if the module is already in the library.\n\t\t// For updates (when publish exists), we silently ignore 403 errors since the kit is already\n\t\t// in the library and project collaborators don't have write access to the team library.\n\t\ttry {\n\t\t\tawait addToLibrary({\n\t\t\t\tlibraryId: teamLibrary.id,\n\t\t\t\tmoduleId: handle.id,\n\t\t\t\texportSpecifier: \"default\",\n\t\t\t\ttitle,\n\t\t\t})\n\t\t} catch (error) {\n\t\t\t// Only suppress 403 errors for updates (when kit was already published)\n\t\t\tif (error instanceof ApiError && error.isForbidden() && publish) {\n\t\t\t\t// Kit is already in the library, so we can safely ignore this error\n\t\t\t} else {\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tthis.libraryStore.triggerUpdate()\n\t}\n\n\t// Cache remote kits in memory to avoid fetching them on every chat request.\n\t#defaultKit: DefaultKit | undefined = undefined\n\t#remoteKitCache = new Map<GlobalModuleId, { [saveId: SaveId]: RemoteKit }>()\n\n\tasync getRemoteKit({ moduleId, saveId }: { moduleId: GlobalModuleId; saveId: SaveId }): Promise<RemoteKit> {\n\t\tconst cached = this.#remoteKitCache.get(moduleId)?.[saveId]\n\t\tif (cached) return cached\n\n\t\tconst kit = await RemoteKit.fromModule(moduleId, saveId, this.treeStore, this.modulesStore)\n\n\t\t// Reset the cache to erase older saves.\n\t\tthis.#remoteKitCache.set(moduleId, { [saveId]: kit })\n\t\treturn kit\n\t}\n\n\tasync getDefaultKit(engine: VekterEngine, { cms = true }: { cms?: boolean } = {}): Promise<DefaultKit> {\n\t\t// The base kit can't change once being loaded, so we can cache it indefinitely.\n\t\tif (this.#defaultKit) return this.#defaultKit\n\t\tconst { loadingStore, loadedExternalModulesStore } = engine.stores\n\t\treturn (this.#defaultKit = await DefaultKit.load(\n\t\t\tthis.componentLoader,\n\t\t\tloadingStore,\n\t\t\tthis.projectStore,\n\t\t\tthis.treeStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tthis.modulesStore,\n\t\t\t{ cms },\n\t\t))\n\t}\n\n\tasync getLocalKit(engine: VekterEngine): Promise<LocalKit> {\n\t\tconst { assetStore, loadingStore, loadedExternalModulesStore } = engine.stores\n\t\t// The Local Kit can never be cached as it changes whenever the tree does.\n\t\treturn LocalKit.fromTree(\n\t\t\tthis.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tassetStore,\n\t\t\tloadingStore,\n\t\t\tloadedExternalModulesStore,\n\t\t\tthis.projectStore,\n\t\t\tengine.scheduler,\n\t\t)\n\t}\n}\n\nfunction collectKitSectionsStructure(\n\tnode: CanvasNode,\n\tcollector: KitSectionsStructureCollector,\n\tancestorSectionNodeId: NodeID | undefined,\n): void {\n\tif (!withChildren(node)) return\n\n\tfor (const child of node.children) {\n\t\tcollector.addCustomizations(child, ancestorSectionNodeId)\n\n\t\tconst kitSectionNodeId = collector.addSection(child)\n\t\tcollectKitSectionsStructure(child, collector, ancestorSectionNodeId ?? kitSectionNodeId)\n\t}\n}\n\nfunction replaceKitSectionId(kit: WireframerKit, section: KitSection[] | undefined): KitSection[] | undefined {\n\treturn section?.map(section => ({\n\t\t...section,\n\t\t_id: kit.getUniqueTitleBySectionId(section._id),\n\t}))\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport * as idb from \"@iamakulov/idb-keyval\"\nimport { type LatestAgentStorageSnapshot, loadSnapshot } from \"../agentSnapshotMigration/index.ts\"\n\nconst log = getLogger(\"AgentStoreStorage\")\n// AGENT @TODO: We can drop the version in the prefix before we ship.\nconst storageKeyPrefix = \"agent-store-v1\"\n\nexport async function loadPersistedAgentSnapshots(projectId: string): Promise<LatestAgentStorageSnapshot | undefined> {\n\ttry {\n\t\tconst snapshot = await idb.get<unknown>(getStorageKey(projectId))\n\t\tif (!snapshot) return undefined\n\n\t\tconst loadedSnapshot = loadSnapshot(snapshot)\n\t\tif (!loadedSnapshot) return undefined\n\n\t\tif (loadedSnapshot.didMigrate) {\n\t\t\ttry {\n\t\t\t\tawait savePersistedAgentStore(projectId, loadedSnapshot.snapshot)\n\t\t\t} catch {\n\t\t\t\tlog.reportError(\"Failed to save migrated agent snapshot\")\n\t\t\t}\n\t\t}\n\n\t\treturn loadedSnapshot.snapshot\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\nexport async function savePersistedAgentStore(projectId: string, snapshot: LatestAgentStorageSnapshot): Promise<void> {\n\tawait idb.set(getStorageKey(projectId), snapshot)\n}\n\nexport async function clearPersistedAgentStore(projectId: string): Promise<void> {\n\tawait idb.del(getStorageKey(projectId))\n}\n\nfunction getStorageKey(projectId: string): string {\n\treturn `${storageKeyPrefix}:${projectId}`\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, emptyArray, getLogger } from \"@framerjs/shared\"\nimport type { AgentAttachmentFile, AgentAttachmentImage } from \"app/agent/attachments.ts\"\nimport type { AgentInputSegment, CmsMetadataColumn } from \"app/agent/editor/agentInputSchema.ts\"\nimport type { AttachmentItem } from \"app/agent/hooks/useAttachments.ts\"\nimport { Agent, type AgentID, type AgentLifeCycleHooks } from \"app/ai/agents/Agent.ts\"\nimport type { AgentContextHooks } from \"app/ai/agents/context/AgentContext.ts\"\nimport type { EvalExportArchiveSnapshot, EvalExportOptions } from \"app/ai/agents/evals/export/AgentStoreEvalExport.ts\"\nimport type { EvalExportV1 } from \"app/ai/agents/evals/export/evalExportTypes.ts\"\nimport type { LoadEvalExportOptions } from \"app/ai/agents/evals/export/loadEvalExportDocument.ts\"\nimport { mergeCmsNodeUpdates, type CmsNodeUpdates } from \"app/ai/agents/nodesMutatedByAgent.ts\"\nimport type { Source } from \"app/ai/agents/source.ts\"\nimport type { LanguageModel } from \"app/ai/languageModels.ts\"\nimport type { AgentReasoningEffort } from \"app/ai/models.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { RemoteDocumentHandler } from \"document/RemoteDocumentHandler.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/CanvasTree.ts\"\nimport { isDrawableNode, isScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport { type NodeID, randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { withReplicaVariants } from \"document/models/CanvasTree/traits/WithReplicaVariants.ts\"\nimport type { VariableID } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { ActiveContentPanelTab, ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { LockQueue } from \"document/utils/LockQueue.ts\"\nimport type { EditorState } from \"prosemirror-state\"\nimport type { API } from \"web/pages/project/lib/useAPI.ts\"\nimport { latestVersion, type LatestAgentStorageSnapshot } from \"../agentSnapshotMigration/index.ts\"\nimport { clearPersistedAgentStore, loadPersistedAgentSnapshots, savePersistedAgentStore } from \"./AgentStoreStorage.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { CodeGenerationStore } from \"./CodeGenerationStore.ts\"\nimport type { FormsStore } from \"./FormsStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { PersistedUserDefaults } from \"./PersistedUserDefaults.ts\"\nimport type { ScopeStore } from \"./ScopeStore.ts\"\nimport type { SessionStore } from \"./SessionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\nimport type { VectorsStore } from \"./VectorsStore.ts\"\n\nconst log = getLogger(\"AgentStore\")\n\ntype CreateAgentOptions = Pick<Agent, \"scopeId\"> & Partial<Omit<Agent, \"scopeId\">>\n\nexport const newAgentChatId = Symbol(\"new-chat\")\ntype ChatID = typeof newAgentChatId | AgentID\n\nexport type PersistedEditorState = Partial<Pick<EditorState, \"doc\" | \"selection\">>\n\nexport interface PersistedChatState {\n\teditorState: PersistedEditorState\n\tattachedImages?: readonly AttachmentItem[]\n}\n\ninterface PendingLayerSelection {\n\tid: string\n\ttype: \"layerSelection\"\n\tnodeIds: readonly NodeID[]\n\tfocusInput: boolean\n}\n\ninterface PendingCmsSelection {\n\tid: string\n\ttype: \"cmsSelection\"\n\tcollectionId: NodeID\n\tcollectionName: string\n\tcollectionItemIds: readonly NodeID[]\n\tvariableColumnIds: readonly VariableID[]\n\tmetadataColumnIds: readonly CmsMetadataColumn[]\n\tfocusInput: boolean\n}\n\ninterface PendingCmsFullCollectionSelection {\n\tid: string\n\ttype: \"cmsCollection\"\n\tcollectionId: NodeID\n\tcollectionName: string\n\tfocusInput: boolean\n}\n\ninterface PendingChatInputPrefill {\n\tparts: readonly AgentInputSegment[]\n\timages: readonly AgentAttachmentImage[]\n\tfiles: readonly AgentAttachmentFile[]\n\tmodel?: LanguageModel\n\treasoningEffort?: AgentReasoningEffort\n}\n\nexport type PendingSelection = PendingLayerSelection | PendingCmsSelection | PendingCmsFullCollectionSelection\n\ninterface PendingLayerSelectionPayload {\n\ttype: \"layerSelection\"\n\tnodeIds: readonly NodeID[]\n\tfocusInput?: boolean\n}\n\ninterface PendingCmsSelectionPayload {\n\ttype: \"cmsSelection\"\n\tcollectionId: NodeID\n\tcollectionName: string\n\tcollectionItemIds: readonly NodeID[]\n\tvariableColumnIds: readonly VariableID[]\n\tmetadataColumnIds: readonly CmsMetadataColumn[]\n\tfocusInput?: boolean\n}\n\ninterface PendingCmsFullCollectionSelectionPayload {\n\ttype: \"cmsCollection\"\n\tcollectionId: NodeID\n\tcollectionName: string\n\tfocusInput?: boolean\n}\n\ntype PendingSelectionPayload =\n\t| PendingLayerSelectionPayload\n\t| PendingCmsSelectionPayload\n\t| PendingCmsFullCollectionSelectionPayload\n\nexport class AgentStore extends EngineStore {\n\tprivate _agents: Map<AgentID, Agent> = new Map()\n\tprivate agentEditorStates: Map<ChatID, PersistedChatState> = new Map()\n\tprivate _pendingChatInputPrefills: Partial<Record<AgentID, PendingChatInputPrefill>> = {}\n\tprivate _editingQueueItemIds: Record<AgentID, string> = {}\n\tprivate readonly persistQueue = new LockQueue()\n\tprivate isHydrating = false\n\tprivate isHistoryPersistenceSuppressed = false\n\tprivate hydrationPromise: Promise<void> | undefined\n\tprivate hasHydrated = false\n\tprivate readonly serializedAgentCache = new Map<AgentID, LatestAgentStorageSnapshot[\"agents\"][number]>()\n\n\t/** Canvas nodes to highlight when the agent touches them */\n\tupdatingCanvasNodes: Set<NodeID> = new Set()\n\t/** CMS cells to highlight when the agent touches them */\n\tupdatingCmsNodes: Map<NodeID, CmsNodeUpdates> = new Map()\n\t/** Nodes (selection/breakpoints) to highlight throughout the turn */\n\tactiveSelectionNodes: Set<NodeID> = new Set()\n\t/** Breakpoints (title bars) to highlight throughout the turn */\n\tactiveBreakpoints: Set<NodeID> = new Set()\n\tprivate activeSelectionByAgentId: Map<AgentID, Set<NodeID>> = new Map()\n\tprivate activeBreakpointsByAgentId: Map<AgentID, Set<NodeID>> = new Map()\n\tprivate updatingCanvasNodesTimeout: Map<ReturnType<typeof setTimeout>, { ids: Set<NodeID>; agentId: AgentID }> =\n\t\tnew Map()\n\tprivate updatingCmsNodesTimeout: Map<\n\t\tReturnType<typeof setTimeout>,\n\t\t{ updates: Map<NodeID, CmsNodeUpdates>; agentId: AgentID }\n\t> = new Map()\n\tprivate _activeChatAgentId: AgentID | undefined = undefined\n\tprivate _followModeAgentId: AgentID | undefined = undefined\n\n\tprivate _pendingSelection: PendingSelection | undefined\n\tprivate _pendingNewChatInputPrefill: PendingChatInputPrefill | undefined\n\tprivate detachedRemoteDocument: RemoteDocumentHandler | null = null\n\tprivate _activeEvaluationAgentId: AgentID | undefined\n\tprivate _activeEvaluationRunAbortController: AbortController | undefined\n\n\tprivate api: API | undefined\n\n\t/** Identifier of the active input/editor ID. It could either be an inline editor in a user\n\t * bubble, or the main chat input. We use the identifier to determine where to send the pending\n\t * selection. Undefined falls back to the main input. */\n\tactiveInputId: string | undefined = undefined\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly vectorsStore: VectorsStore,\n\t\tprivate readonly formsStore: FormsStore,\n\t\tprivate readonly sessionStore: SessionStore,\n\t\tprivate readonly codeGenerationStore: CodeGenerationStore,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly projectId: string,\n\t\tprivate readonly persistedUserDefaults: PersistedUserDefaults,\n\t\tprivate readonly hooks: AgentContextHooks,\n\t) {\n\t\tsuper()\n\t}\n\n\tsetProjectAPI(api: API | undefined): void {\n\t\tthis.api = api\n\t}\n\n\tget activeChatAgentId(): AgentID | undefined {\n\t\tif (!this._activeChatAgentId) return undefined\n\t\tconst agent = this._agents.get(this._activeChatAgentId)\n\t\treturn agent?.id\n\t}\n\n\tset activeChatAgentId(id: AgentID | undefined) {\n\t\tthis._activeChatAgentId = id\n\t\tvoid this.persist()\n\t}\n\n\tget followModeAgentId(): AgentID | undefined {\n\t\tif (this.chromeStore.isEvaluationsModeActive && this._activeEvaluationAgentId) {\n\t\t\treturn this._activeEvaluationAgentId\n\t\t}\n\t\tif (!this._followModeAgentId) return undefined\n\t\treturn this._agents.get(this._followModeAgentId)?.id\n\t}\n\n\tisFollowModeEnabledForAgent(agentId: AgentID | undefined): boolean {\n\t\treturn !!agentId && this.followModeAgentId === agentId\n\t}\n\n\tsetFollowModeForAgent(agentId: AgentID, enabled: boolean): void {\n\t\tthis.persistedUserDefaults.agentFollowMode = enabled\n\t\tthis._followModeAgentId = enabled ? agentId : undefined\n\t\tthis.notifyChange()\n\t}\n\n\tclearFollowMode(): void {\n\t\tif (!this._followModeAgentId && !this.persistedUserDefaults.agentFollowMode) return\n\n\t\tthis.persistedUserDefaults.agentFollowMode = false\n\t\tthis._followModeAgentId = undefined\n\t\tthis.notifyChange()\n\t}\n\n\tget agents(): ReadonlyMap<AgentID, Agent> {\n\t\treturn this._agents\n\t}\n\n\tget pendingSelection(): PendingSelection | undefined {\n\t\treturn this._pendingSelection\n\t}\n\n\tget pendingChatInputPrefills(): Partial<Record<AgentID, PendingChatInputPrefill>> {\n\t\treturn this._pendingChatInputPrefills\n\t}\n\n\tget pendingNewChatInputPrefill(): PendingChatInputPrefill | undefined {\n\t\treturn this._pendingNewChatInputPrefill\n\t}\n\n\tget editingQueueItemIds(): Record<AgentID, string> {\n\t\treturn this._editingQueueItemIds\n\t}\n\n\tsetEditingQueueItemId(agentId: AgentID, itemId: string): void {\n\t\tthis._editingQueueItemIds = { ...this._editingQueueItemIds, [agentId]: itemId }\n\t\tthis.notifyChange()\n\t}\n\n\tclearEditingQueueItemId(agentId: AgentID): void {\n\t\tif (!this._editingQueueItemIds[agentId]) return\n\t\tconst { [agentId]: _, ...remaining } = this._editingQueueItemIds\n\t\tthis._editingQueueItemIds = remaining\n\t\tthis.notifyChange()\n\t}\n\n\tenqueueSelection(selection: PendingSelectionPayload): void {\n\t\tswitch (selection.type) {\n\t\t\tcase \"layerSelection\": {\n\t\t\t\tconst nodeIds = Array.from(new Set(selection.nodeIds))\n\t\t\t\tif (nodeIds.length === 0) return\n\n\t\t\t\tthis._pendingSelection = {\n\t\t\t\t\tid: randomID(),\n\t\t\t\t\ttype: \"layerSelection\",\n\t\t\t\t\tnodeIds,\n\t\t\t\t\tfocusInput: selection.focusInput ?? true,\n\t\t\t\t}\n\t\t\t\tthis.notifyChange()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcase \"cmsSelection\": {\n\t\t\t\tif (selection.collectionItemIds.length === 0) return\n\n\t\t\t\tthis._pendingSelection = {\n\t\t\t\t\tid: randomID(),\n\t\t\t\t\ttype: \"cmsSelection\",\n\t\t\t\t\tcollectionId: selection.collectionId,\n\t\t\t\t\tcollectionName: selection.collectionName,\n\t\t\t\t\tcollectionItemIds: selection.collectionItemIds,\n\t\t\t\t\tvariableColumnIds: selection.variableColumnIds,\n\t\t\t\t\tmetadataColumnIds: selection.metadataColumnIds,\n\t\t\t\t\tfocusInput: selection.focusInput ?? true,\n\t\t\t\t}\n\t\t\t\tthis.notifyChange()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcase \"cmsCollection\": {\n\t\t\t\tthis._pendingSelection = {\n\t\t\t\t\tid: randomID(),\n\t\t\t\t\ttype: \"cmsCollection\",\n\t\t\t\t\tcollectionId: selection.collectionId,\n\t\t\t\t\tcollectionName: selection.collectionName,\n\t\t\t\t\tfocusInput: selection.focusInput ?? true,\n\t\t\t\t}\n\t\t\t\tthis.notifyChange()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tclearPendingSelection(id: string): void {\n\t\tif (!this._pendingSelection) return\n\t\tif (this._pendingSelection.id !== id) return\n\n\t\tthis._pendingSelection = undefined\n\t\tthis.notifyChange()\n\t}\n\n\tprefillChatInput(\n\t\tagentId: AgentID,\n\t\tparts: readonly AgentInputSegment[],\n\t\timages: readonly AgentAttachmentImage[] = [],\n\t\tfiles: readonly AgentAttachmentFile[] = [],\n\t\tmodel?: LanguageModel,\n\t\treasoningEffort?: AgentReasoningEffort,\n\t): void {\n\t\tthis._pendingChatInputPrefills = {\n\t\t\t...this._pendingChatInputPrefills,\n\t\t\t[agentId]: { parts, images, files, model, reasoningEffort },\n\t\t}\n\t\tthis.notifyChange()\n\t}\n\n\tclearPendingChatInputPrefill(agentId?: AgentID): void {\n\t\tif (!agentId) {\n\t\t\tif (!this._pendingNewChatInputPrefill) return\n\t\t\tthis._pendingNewChatInputPrefill = undefined\n\t\t\tthis.notifyChange()\n\t\t\treturn\n\t\t}\n\n\t\tif (!this._pendingChatInputPrefills[agentId]) return\n\t\tconst { [agentId]: _, ...remainingPrefills } = this._pendingChatInputPrefills\n\t\tthis._pendingChatInputPrefills = remainingPrefills\n\t\tthis.notifyChange()\n\t}\n\n\tprefillNewChatInput(\n\t\tparts: readonly AgentInputSegment[],\n\t\timages: readonly AgentAttachmentImage[] = [],\n\t\tfiles: readonly AgentAttachmentFile[] = [],\n\t): void {\n\t\tthis._pendingNewChatInputPrefill = { parts, images, files }\n\t\tthis.notifyChange()\n\t}\n\n\tgetPersistedChatState(id: ChatID): PersistedChatState | undefined {\n\t\treturn this.agentEditorStates.get(id)\n\t}\n\n\tsetPersistedChatState(state: PersistedChatState, id: ChatID = newAgentChatId): void {\n\t\tthis.agentEditorStates.set(id, state)\n\t}\n\n\thasNonIdleAgents(): boolean {\n\t\tfor (const agent of this._agents.values()) {\n\t\t\tif (agent.state !== \"idle\" && agent.state !== \"follow-up\") return true\n\t\t}\n\n\t\treturn false\n\t}\n\n\tcreate(options: CreateAgentOptions, lifecycleHooks?: AgentLifeCycleHooks): Agent {\n\t\tconst id = randomID()\n\t\tconst agent = new Agent(\n\t\t\tid,\n\t\t\toptions.scopeId,\n\t\t\toptions.selection,\n\t\t\tthis.getAgentDependencies(id),\n\t\t\tthis.createLifecycleHooks(id, lifecycleHooks),\n\t\t)\n\n\t\tthis.registerAgent(agent)\n\t\tthis._agents.set(id, agent)\n\t\tthis.notifyChange()\n\n\t\tlog.info(\"Created agent\", id)\n\t\treturn agent\n\t}\n\n\tasync hydratePersistedAgents(): Promise<void> {\n\t\tif (this.hasHydrated) return\n\t\tif (this.hydrationPromise) return this.hydrationPromise\n\n\t\tthis.hydrationPromise = this.runHydration().finally(() => {\n\t\t\tthis.hydrationPromise = undefined\n\t\t})\n\t\treturn this.hydrationPromise\n\t}\n\n\tprivate async runHydration(): Promise<void> {\n\t\tconst snapshot = await loadPersistedAgentSnapshots(this.projectId)\n\t\tthis.hasHydrated = true\n\t\tif (!snapshot) return\n\n\t\tthis.isHydrating = true\n\t\ttry {\n\t\t\tthis.serializedAgentCache.clear()\n\t\t\tthis._agents = new Map(\n\t\t\t\tsnapshot.agents.map(agentSnapshot => {\n\t\t\t\t\tconst agent = this.hydrateAgent(agentSnapshot)\n\t\t\t\t\tthis.serializedAgentCache.set(agent.id, agentSnapshot)\n\t\t\t\t\treturn [agent.id, agent] as const\n\t\t\t\t}),\n\t\t\t)\n\t\t\tthis._activeChatAgentId = snapshot.activeChatAgentId\n\t\t\tthis.notifyChange()\n\t\t} finally {\n\t\t\tthis.isHydrating = false\n\t\t}\n\t}\n\n\tgetAgent(id: AgentID): Agent | undefined {\n\t\treturn this._agents.get(id)\n\t}\n\n\tgetHistorySnapshot(): LatestAgentStorageSnapshot {\n\t\treturn {\n\t\t\tagents: [...this._agents.values()].map(agent => agent.serialize()),\n\t\t\tactiveChatAgentId: this._activeChatAgentId,\n\t\t\tversion: latestVersion,\n\t\t}\n\t}\n\n\tasync getEvalExportSnapshot(options: EvalExportOptions = {}): Promise<EvalExportV1> {\n\t\tconst archiveSnapshot = await this.getEvalExportArchiveSnapshot(options)\n\t\treturn archiveSnapshot.manifest\n\t}\n\n\tasync getEvalExportArchiveSnapshot(options: EvalExportOptions = {}): Promise<EvalExportArchiveSnapshot> {\n\t\tconst { buildEvalExportArchiveSnapshot } = await import(\"app/ai/agents/evals/export/AgentStoreEvalExport.ts\")\n\t\tconst engine = this.hooks.getEngine()\n\t\tassert(engine, \"Engine is required to create an eval export.\")\n\t\treturn buildEvalExportArchiveSnapshot({\n\t\t\toptions,\n\t\t\tactiveChatAgentId: this.activeChatAgentId,\n\t\t\tgetAgent: agentId => this.getAgent(agentId),\n\t\t\tassetStore: engine.stores.assetStore,\n\t\t\ttreeStore: this.treeStore,\n\t\t})\n\t}\n\n\tasync loadEvalExportArchiveSnapshot(\n\t\tarchiveSnapshot: EvalExportArchiveSnapshot,\n\t\toptions: LoadEvalExportOptions = {},\n\t\tlifecycleHooks?: AgentLifeCycleHooks,\n\t): Promise<Agent> {\n\t\tassert(this._agents.size === 0, \"Eval export loading requires a fresh AgentStore.\")\n\t\t// Eval export replay engines are synthetic. They borrow the browser's project id, but their\n\t\t// hydrated agents and turn updates must not overwrite that project's real chat history.\n\t\tthis.isHistoryPersistenceSuppressed = true\n\n\t\tconst engine = this.hooks.getEngine()\n\t\tassert(engine, \"Engine is required to load an eval export.\")\n\t\tengine.stores.chromeStore.enableDetachedEditableMode()\n\n\t\tconst {\n\t\t\tcreatePersistedAgentSnapshotFromEvalExport,\n\t\t\thydrateEvalExportAgent,\n\t\t\tloadEvalExportDocumentIntoEngine,\n\t\t\tresolveEvalExportReplayTarget,\n\t\t} = await import(\"app/ai/agents/evals/export/loadEvalExportDocument.ts\")\n\t\tconst replayTarget = resolveEvalExportReplayTarget(archiveSnapshot.manifest, options)\n\n\t\tawait loadEvalExportDocumentIntoEngine({\n\t\t\tengine,\n\t\t\tarchiveSnapshot,\n\t\t\treplayTarget,\n\t\t\texternalModuleEvaluationMode: options.externalModuleEvaluationMode,\n\t\t})\n\n\t\tconst persistedAgentSnapshot = createPersistedAgentSnapshotFromEvalExport(replayTarget)\n\t\tconst agent = hydrateEvalExportAgent({\n\t\t\tarchiveSnapshot,\n\t\t\treplayTarget,\n\t\t\tagent: Agent.hydrate(\n\t\t\t\tpersistedAgentSnapshot,\n\t\t\t\tthis.getAgentDependencies(persistedAgentSnapshot.id),\n\t\t\t\tthis.createLifecycleHooks(persistedAgentSnapshot.id, lifecycleHooks),\n\t\t\t),\n\t\t})\n\n\t\tthis.registerAgent(agent)\n\t\tthis._agents.set(agent.id, agent)\n\t\tthis._activeChatAgentId = agent.id\n\t\tthis.notifyChange()\n\n\t\treturn agent\n\t}\n\n\tasync clearHistory(): Promise<void> {\n\t\tfor (const [agentId, agent] of this._agents) {\n\t\t\tvoid agent.stop()\n\t\t\tthis.clearUpdatingNodesForAgent(agentId)\n\t\t}\n\n\t\tfor (const timeout of this.updatingCanvasNodesTimeout.keys()) {\n\t\t\tclearTimeout(timeout)\n\t\t}\n\t\tfor (const timeout of this.updatingCmsNodesTimeout.keys()) {\n\t\t\tclearTimeout(timeout)\n\t\t}\n\n\t\t// Prevent race conditions by synchronizing the persist queue before clearing the store.\n\t\tawait this.persistQueue.synchronize()\n\n\t\tthis._agents = new Map()\n\t\tthis.serializedAgentCache.clear()\n\t\tthis.agentEditorStates = new Map()\n\t\tthis.updatingCanvasNodes = new Set()\n\t\tthis.updatingCmsNodes = new Map()\n\t\tthis.activeSelectionNodes = new Set()\n\t\tthis.activeSelectionByAgentId = new Map()\n\t\tthis.activeBreakpoints = new Set()\n\t\tthis.activeBreakpointsByAgentId = new Map()\n\t\tthis.updatingCanvasNodesTimeout = new Map()\n\t\tthis.updatingCmsNodesTimeout = new Map()\n\t\tthis._activeChatAgentId = undefined\n\t\tthis._followModeAgentId = undefined\n\t\tthis._pendingSelection = undefined\n\t\tthis._pendingChatInputPrefills = {}\n\t\tthis._pendingNewChatInputPrefill = undefined\n\t\tthis._editingQueueItemIds = {}\n\n\t\tawait clearPersistedAgentStore(this.projectId)\n\t}\n\n\t/**\n\t * Stop and unregister an agent from the store.\n\t *\n\t * @param id - The ID of the agent to dismiss.\n\t * @param shouldNotify - Whether to notify the change. Defaults to true. Can be used to prevent notifications\n\t * when calling from a test or when dismissing multiple agents where we would only want to notify once at the end.\n\t * @returns void\n\t */\n\tdismiss(id: AgentID, shouldNotify: boolean = true): void {\n\t\tif (!this._agents.has(id)) return\n\n\t\tthis.stop(id, false)\n\n\t\tthis._agents.delete(id)\n\t\tthis.agentEditorStates.delete(id)\n\t\tthis.serializedAgentCache.delete(id)\n\n\t\tif (this._activeChatAgentId === id) {\n\t\t\tthis._activeChatAgentId = undefined\n\t\t}\n\t\tif (this._followModeAgentId === id) {\n\t\t\tthis._followModeAgentId = undefined\n\t\t}\n\n\t\tif (shouldNotify) this.notifyChange()\n\n\t\tlog.info(\"Dismissed agent\", id)\n\t}\n\n\tstop(id: AgentID, shouldNotify: boolean = true): void {\n\t\tconst agent = this._agents.get(id)\n\t\tif (!agent) return\n\n\t\tvoid agent.stop()\n\t\tthis.clearUpdatingNodesForAgent(id)\n\n\t\tif (shouldNotify) this.notifyChange()\n\t\tlog.info(\"Stopped agent\", id)\n\t}\n\n\tprivate notifyChange() {\n\t\tthis._agents = new Map(this._agents)\n\t\tvoid this.persist()\n\t}\n\n\tprivate hydrateAgent(snapshot: LatestAgentStorageSnapshot[\"agents\"][number]): Agent {\n\t\tconst agent = Agent.hydrate(\n\t\t\tsnapshot,\n\t\t\tthis.getAgentDependencies(snapshot.id),\n\t\t\tthis.createLifecycleHooks(snapshot.id),\n\t\t)\n\t\tthis.registerAgent(agent)\n\t\treturn agent\n\t}\n\n\tprivate getAgentDependencies(agentId: AgentID) {\n\t\tconst store = this\n\t\tconst source: Source = { agent: \"app\", prompt: \"in-app\" }\n\t\treturn {\n\t\t\ttreeStore: this.treeStore,\n\t\t\tmodulesStore: this.modulesStore,\n\t\t\tvectorsStore: this.vectorsStore,\n\t\t\tcodeGenerationStore: this.codeGenerationStore,\n\t\t\tformsStore: this.formsStore,\n\t\t\tsessionStore: this.sessionStore,\n\t\t\tscheduler: this.scheduler,\n\t\t\tcomponentLoader: this.componentLoader,\n\t\t\tisFollowModeEnabled: () => this.isFollowModeEnabledForAgent(agentId),\n\t\t\tselectScopeByAgent: (scopeId: NodeID) => this.scopeStore.selectScopeByAgent(scopeId),\n\t\t\tgetActiveScopeId: () => this.scopeStore.active.id,\n\t\t\thooks: this.hooks,\n\t\t\tsource,\n\t\t\tprojectId: this.projectId,\n\t\t\tget api() {\n\t\t\t\treturn store.api\n\t\t\t},\n\t\t}\n\t}\n\n\tprivate createLifecycleHooks(agentId: AgentID, lifecycleHooks?: AgentLifeCycleHooks): AgentLifeCycleHooks {\n\t\treturn {\n\t\t\t...lifecycleHooks,\n\t\t\tonCommandReceived: (command, raw) => {\n\t\t\t\tlifecycleHooks?.onCommandReceived?.(command, raw)\n\t\t\t},\n\t\t\tonCommandApplied: (command, diagnostics, raw) => {\n\t\t\t\tlifecycleHooks?.onCommandApplied?.(command, diagnostics, raw)\n\t\t\t},\n\t\t\tonCommandFailed: (raw, error) => {\n\t\t\t\tlifecycleHooks?.onCommandFailed?.(raw, error)\n\t\t\t},\n\t\t\tonUpdateNodes: mutatingNodes => {\n\t\t\t\tthis.markCanvasNodesBeingUpdated(agentId, mutatingNodes.canvas)\n\t\t\t\tthis.markCmsNodesBeingUpdated(agentId, mutatingNodes.cms)\n\t\t\t\tlifecycleHooks?.onUpdateNodes?.(mutatingNodes)\n\t\t\t},\n\t\t\tonTurnStart: async currentAgent => {\n\t\t\t\tthis._followModeAgentId = this.persistedUserDefaults.agentFollowMode ? currentAgent.id : undefined\n\n\t\t\t\t// On the canvas, turn to layers panel on start\n\t\t\t\tif (this.chromeStore.mainView === ActiveMainView.Canvas) {\n\t\t\t\t\tthis.chromeStore.removePanelOverrides()\n\t\t\t\t\tthis.chromeStore.contentPanelTab = ActiveContentPanelTab.Layers\n\t\t\t\t}\n\n\t\t\t\t// Mark associated nodes as updating.\n\t\t\t\tconst { selection, breakpoints } = await getSelectionHighlightForAgent(this.treeStore.tree, currentAgent)\n\t\t\t\tthis.activeSelectionNodes = new Set([...this.activeSelectionNodes, ...selection])\n\t\t\t\tthis.activeSelectionByAgentId.set(currentAgent.id, new Set(selection))\n\t\t\t\tthis.activeBreakpoints = new Set([...this.activeBreakpoints, ...breakpoints])\n\t\t\t\tthis.activeBreakpointsByAgentId.set(currentAgent.id, new Set(breakpoints))\n\n\t\t\t\tlifecycleHooks?.onTurnStart?.(currentAgent)\n\t\t\t},\n\t\t\tonTurnEnd: currentAgent => {\n\t\t\t\tthis.clearUpdatingNodesForAgent(currentAgent.id)\n\n\t\t\t\treturn lifecycleHooks?.onTurnEnd?.(currentAgent)\n\t\t\t},\n\t\t}\n\t}\n\n\tprivate registerAgent(agent: Agent): void {\n\t\tagent.subscribe(() => {\n\t\t\tthis.serializedAgentCache.delete(agent.id)\n\t\t\tvoid this.persist()\n\t\t})\n\t}\n\n\tprivate getPersistedSnapshot(): LatestAgentStorageSnapshot {\n\t\treturn {\n\t\t\tagents: [...this._agents.values()].map(agent => {\n\t\t\t\tconst cached = this.serializedAgentCache.get(agent.id)\n\t\t\t\tif (cached) return cached\n\t\t\t\tconst serialized = agent.serialize()\n\t\t\t\tthis.serializedAgentCache.set(agent.id, serialized)\n\t\t\t\treturn serialized\n\t\t\t}),\n\t\t\tactiveChatAgentId: this._activeChatAgentId,\n\t\t\tversion: latestVersion,\n\t\t}\n\t}\n\n\tprivate async persist(): Promise<void> {\n\t\tif (this.isHydrating) return\n\t\tif (this.isHistoryPersistenceSuppressed) return\n\t\tconst snapshot = this.getPersistedSnapshot()\n\t\tawait this.persistQueue.request(() => savePersistedAgentStore(this.projectId, snapshot))\n\t}\n\n\t/**\n\t * Mark nodes as updating by an agent, clearing them after 2 seconds. If the same nodes are\n\t * marked again within 2 seconds, we reset the timeout.\n\t */\n\tmarkCanvasNodesBeingUpdated(agentId: AgentID, nodeIds: ReadonlySet<NodeID> | readonly NodeID[]) {\n\t\tconst newIds = Array.isArray(nodeIds) ? nodeIds : Array.from(nodeIds)\n\t\tif (newIds.length === 0) return\n\n\t\tconst activeSelectionNodes = this.activeSelectionByAgentId.get(agentId)\n\t\t// If a node is already being updated because it's part of the selection, don't repeatedly mark it as updating.\n\t\tconst updatingIds = newIds.filter(id => !activeSelectionNodes?.has(id))\n\n\t\tif (updatingIds.length === 0) return\n\n\t\t// First mark the nodes as updating.\n\t\tthis.updatingCanvasNodes = new Set([...this.updatingCanvasNodes, ...updatingIds])\n\n\t\t// A new update has marked these nodes. Remove these IDs from older batches so they\n\t\t// won't be cleared when those batches' timeouts fire (debounce).\n\t\tfor (const batch of this.updatingCanvasNodesTimeout.values()) {\n\t\t\tfor (const id of updatingIds) {\n\t\t\t\tbatch.ids.delete(id)\n\t\t\t}\n\t\t}\n\n\t\t// Setup the timeout to clear this batch of nodes.\n\t\tconst timeout = setTimeout(() => {\n\t\t\tconst batch = this.updatingCanvasNodesTimeout.get(timeout)\n\t\t\tif (batch) {\n\t\t\t\tfor (const id of batch.ids) {\n\t\t\t\t\tthis.updatingCanvasNodes.delete(id)\n\t\t\t\t}\n\n\t\t\t\tthis.updatingCanvasNodes = new Set(this.updatingCanvasNodes)\n\t\t\t}\n\t\t\tthis.updatingCanvasNodesTimeout.delete(timeout)\n\t\t}, 2000)\n\n\t\tthis.updatingCanvasNodesTimeout.set(timeout, { ids: new Set(updatingIds), agentId })\n\t}\n\n\tmarkCmsNodesBeingUpdated(agentId: AgentID, updates: ReadonlyMap<NodeID, CmsNodeUpdates>) {\n\t\tconst filteredUpdates = new Map<NodeID, CmsNodeUpdates>()\n\t\tfor (const [nodeId, cmsUpdates] of updates) {\n\t\t\tif (!cmsUpdates.changedControlProps?.size) continue\n\t\t\tfilteredUpdates.set(nodeId, {\n\t\t\t\tchangedControlProps: cmsUpdates.changedControlProps,\n\t\t\t})\n\t\t}\n\n\t\tif (filteredUpdates.size === 0) return\n\n\t\t// First mark the CMS cells as updating.\n\t\tconst newUpdatingCmsNodes = new Map(this.updatingCmsNodes)\n\t\tfor (const [nodeId, cmsUpdates] of filteredUpdates) {\n\t\t\tconst nextUpdates = mergeCmsNodeUpdates(newUpdatingCmsNodes.get(nodeId), cmsUpdates)\n\t\t\tif (nextUpdates.changedControlProps?.size) {\n\t\t\t\tnewUpdatingCmsNodes.set(nodeId, nextUpdates)\n\t\t\t}\n\t\t}\n\t\tthis.updatingCmsNodes = newUpdatingCmsNodes\n\n\t\t// A new update has marked these CMS cells. Remove them from older batches so they\n\t\t// won't be cleared when those batches' timeouts fire (debounce).\n\t\tfor (const batch of this.updatingCmsNodesTimeout.values()) {\n\t\t\tbatch.updates = removeCmsNodeUpdates(batch.updates, filteredUpdates)\n\t\t}\n\n\t\t// Setup the timeout to clear this batch of CMS cells.\n\t\tconst timeout = setTimeout(() => {\n\t\t\tconst batch = this.updatingCmsNodesTimeout.get(timeout)\n\t\t\tif (batch) {\n\t\t\t\tthis.updatingCmsNodes = removeCmsNodeUpdates(this.updatingCmsNodes, batch.updates)\n\t\t\t}\n\t\t\tthis.updatingCmsNodesTimeout.delete(timeout)\n\t\t}, 2000)\n\n\t\tthis.updatingCmsNodesTimeout.set(timeout, { updates: filteredUpdates, agentId })\n\t}\n\n\tclearUpdatingNodesForAgent(agentId: AgentID) {\n\t\t// Clear the selection highlight first.\n\t\tconst activeSelections = this.activeSelectionByAgentId.get(agentId)\n\t\tif (activeSelections) {\n\t\t\tfor (const id of activeSelections) {\n\t\t\t\tthis.activeSelectionNodes.delete(id)\n\t\t\t}\n\t\t\tthis.activeSelectionNodes = new Set(this.activeSelectionNodes)\n\t\t\tthis.activeSelectionByAgentId.delete(agentId)\n\t\t}\n\n\t\t// Invalidate the active breakpoints.\n\t\tconst activeBreakpoints = this.activeBreakpointsByAgentId.get(agentId)\n\t\tif (activeBreakpoints) {\n\t\t\tfor (const id of activeBreakpoints) {\n\t\t\t\tthis.activeBreakpoints.delete(id)\n\t\t\t}\n\t\t\tthis.activeBreakpoints = new Set(this.activeBreakpoints)\n\t\t\tthis.activeBreakpointsByAgentId.delete(agentId)\n\t\t}\n\n\t\t// If there are any IDs inserted by this agent pending to be cleared, clear them immediately.\n\t\tfor (const [timeout, batch] of this.updatingCanvasNodesTimeout) {\n\t\t\tif (batch.agentId !== agentId) continue\n\n\t\t\tfor (const id of batch.ids) {\n\t\t\t\tthis.updatingCanvasNodes.delete(id)\n\t\t\t}\n\n\t\t\tclearTimeout(timeout)\n\t\t\tthis.updatingCanvasNodesTimeout.delete(timeout)\n\t\t}\n\n\t\tthis.updatingCanvasNodes = new Set(this.updatingCanvasNodes)\n\t\tthis.clearCmsUpdatingNodesForAgent(agentId)\n\t}\n\n\tprivate clearCmsUpdatingNodesForAgent(agentId: AgentID) {\n\t\tfor (const [timeout, batch] of this.updatingCmsNodesTimeout) {\n\t\t\tif (batch.agentId !== agentId) continue\n\t\t\tthis.updatingCmsNodes = removeCmsNodeUpdates(this.updatingCmsNodes, batch.updates)\n\t\t\tclearTimeout(timeout)\n\t\t\tthis.updatingCmsNodesTimeout.delete(timeout)\n\t\t}\n\t}\n\n\t/** Returns the breakpoint IDs of the active scope. Debug-only. */\n\tasync debugGetActiveScopeBreakpointIds(): Promise<readonly NodeID[]> {\n\t\tconst result: NodeID[] = []\n\t\tconst activeScope = this.scopeStore.active\n\t\tif (!isScopeNode(activeScope)) return result\n\t\tconst loadedScope = await activeScope.load()\n\t\tif (!withReplicaVariants(loadedScope)) return result\n\t\tfor (const variant of loadedScope.getVariants()) {\n\t\t\tresult.push(variant.id)\n\t\t\tfor (const child of variant.walk()) {\n\t\t\t\tif (!isDrawableNode(child)) continue\n\t\t\t\tresult.push(child.id)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\t/** Adds nodes to `updatingCanvasNodes` without a timeout. Debug-only. */\n\tdebugAddToUpdatingNodes(nodeIds: readonly NodeID[]): void {\n\t\tif (nodeIds.length === 0) return\n\t\tthis.updatingCanvasNodes = new Set([...this.updatingCanvasNodes, ...nodeIds])\n\t}\n\n\t/** Clears all `updatingCanvasNodes`. Debug-only. */\n\tdebugClearUpdatingNodes(): void {\n\t\tif (this.updatingCanvasNodes.size === 0) return\n\t\tthis.updatingCanvasNodes = new Set()\n\t}\n\n\t/** When manually switching scope, stop follow only if the active follow chat is running. */\n\tswitchScope() {\n\t\tconst followAgentId = this.followModeAgentId\n\t\tif (!followAgentId) return\n\n\t\tconst followAgent = this._agents.get(followAgentId)\n\t\tif (!followAgent?.isBusy) return\n\n\t\tthis.clearFollowMode()\n\t}\n\n\tenterEvaluationsMode() {\n\t\tthis.isHistoryPersistenceSuppressed = true\n\t\tthis.chromeStore.enterEvaluationsMode()\n\t}\n\n\texitEvaluationsMode() {\n\t\tconst isInEvaluationsMode = this.chromeStore.isEvaluationsModeActive\n\t\tif (!isInEvaluationsMode) return\n\n\t\tthis.stopActiveEvaluation()\n\t\tthis.chromeStore.exitEvaluationsMode()\n\t\tthis.isHistoryPersistenceSuppressed = false\n\t\tthis.modulesStore.resetModuleStateAndPermissions(\"readwrite\")\n\t\tthis.reconnectProjectAfterEvaluations()\n\t}\n\n\tdetachProjectForEvaluations() {\n\t\tif (this.detachedRemoteDocument) return\n\n\t\tconst engine = this.hooks.getEngine()\n\t\tconst remoteDocument = engine?.remoteDocument\n\t\tif (!remoteDocument) return\n\n\t\tthis.detachedRemoteDocument = remoteDocument\n\t\tremoteDocument.debugDetachClientFromServer({ keepAPIFetcherWritable: true })\n\t}\n\n\tget activeEvaluationAgentId(): AgentID | undefined {\n\t\treturn this._activeEvaluationAgentId\n\t}\n\n\tset activeEvaluationAgentId(agentId: AgentID | undefined) {\n\t\tthis._activeEvaluationAgentId = agentId\n\t}\n\n\tclearActiveEvaluationAgentId(agentId: AgentID) {\n\t\tif (this.activeEvaluationAgentId !== agentId) return\n\t\tthis.activeEvaluationAgentId = undefined\n\t}\n\n\tget activeEvaluationRunAbortController(): AbortController | undefined {\n\t\treturn this._activeEvaluationRunAbortController\n\t}\n\n\tset activeEvaluationRunAbortController(abortController: AbortController | undefined) {\n\t\tthis._activeEvaluationRunAbortController = abortController\n\t}\n\n\tclearActiveEvaluationRunAbortController(abortController: AbortController) {\n\t\tif (this.activeEvaluationRunAbortController !== abortController) return\n\t\tthis.activeEvaluationRunAbortController = undefined\n\t}\n\n\tstopActiveEvaluation() {\n\t\tthis.activeEvaluationRunAbortController?.abort()\n\t\tif (!this.activeEvaluationAgentId) return\n\t\tthis.stop(this.activeEvaluationAgentId)\n\t}\n\n\tprivate reconnectProjectAfterEvaluations() {\n\t\tif (!this.detachedRemoteDocument) return\n\n\t\tconst remoteDocument = this.detachedRemoteDocument\n\t\tthis.detachedRemoteDocument = null\n\t\tremoteDocument.debugReattachClientToServer()\n\t}\n}\n\nfunction removeCmsNodeUpdates(\n\tcurrentUpdates: Map<NodeID, CmsNodeUpdates>,\n\tupdatesToRemove: ReadonlyMap<NodeID, CmsNodeUpdates>,\n): Map<NodeID, CmsNodeUpdates> {\n\tconst newCmsNodeUpdates = new Map(currentUpdates)\n\n\tfor (const [nodeId, updatesToRemoveForNode] of updatesToRemove) {\n\t\tconst controlPropsToRemove = updatesToRemoveForNode.changedControlProps\n\t\tif (!controlPropsToRemove?.size) continue\n\n\t\tconst currentUpdate = currentUpdates.get(nodeId)\n\t\tconst currentChangedControlProps = currentUpdate?.changedControlProps\n\n\t\tif (!currentChangedControlProps?.size) {\n\t\t\t// already empty for some reason\n\t\t\tnewCmsNodeUpdates.delete(nodeId)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst newChangedControlProps = new Set(currentChangedControlProps)\n\t\tfor (const controlProp of controlPropsToRemove) {\n\t\t\tnewChangedControlProps.delete(controlProp)\n\t\t}\n\n\t\t// nothing changes after removal\n\t\tif (newChangedControlProps.size === currentChangedControlProps.size) continue\n\n\t\tif (newChangedControlProps.size === 0) {\n\t\t\t// no changed control props to highlight anymore, we can delete the node\n\t\t\tnewCmsNodeUpdates.delete(nodeId)\n\t\t} else {\n\t\t\tnewCmsNodeUpdates.set(nodeId, { ...currentUpdate, changedControlProps: newChangedControlProps })\n\t\t}\n\t}\n\n\treturn newCmsNodeUpdates\n}\n\nasync function getSelectionHighlightForAgent(\n\ttree: CanvasTree,\n\tagent: Agent,\n): Promise<{ selection: readonly NodeID[]; breakpoints: readonly NodeID[] }> {\n\tif (agent.selection?.length) {\n\t\tconst drawableSelection: NodeID[] = []\n\t\tconst breakpoints: NodeID[] = []\n\t\tfor (const id of agent.selection) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\t\t\tconst scope = isScopeNode(node) ? node : tree.getScopeNodeFor(node)\n\t\t\tif (!isScopeNode(scope)) continue\n\n\t\t\tconst loadedScope = await scope.load()\n\t\t\tif (!withReplicaVariants(loadedScope)) continue\n\n\t\t\tif (isDrawableNode(node)) {\n\t\t\t\tdrawableSelection.push(id)\n\t\t\t}\n\t\t\tbreakpoints.push(...loadedScope.getTopLevelVariants().map(variant => variant.id))\n\t\t}\n\n\t\tconst selectionWithoutDescendants = tree.withoutDescendants(tree.getNodes(drawableSelection)).map(node => node.id)\n\t\treturn { selection: selectionWithoutDescendants, breakpoints }\n\t}\n\n\tif (agent.scopeId) {\n\t\tconst scope = tree.get(agent.scopeId)\n\t\tif (!isScopeNode(scope)) return { selection: emptyArray(), breakpoints: emptyArray() }\n\t\tconst loadedScope = await scope.load()\n\t\tif (!withReplicaVariants(loadedScope)) {\n\t\t\treturn { selection: emptyArray(), breakpoints: emptyArray() }\n\t\t}\n\n\t\tconst breakpoints = loadedScope.getTopLevelVariants().map(variant => variant.id)\n\t\treturn { selection: breakpoints, breakpoints }\n\t}\n\n\treturn { selection: emptyArray(), breakpoints: emptyArray() }\n}\n", "import { AssetMap, type AssetService, readAssetUpdatesStream } from \"@framerjs/assets\"\nimport { Assets } from \"@framerjs/framer-services\"\nimport { EngineChange, type EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { BaseAssetStore } from \"document/base-engine/BaseAssetStore.ts\"\nimport { CodeComponentNode } from \"document/models/CanvasTree/index.ts\"\nimport { channelToWebOrAutomation } from \"utils/serviceChannels.ts\"\nimport type { LoadingStore } from \"./LoadingStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport class AssetStore extends EngineStore implements BaseAssetStore {\n\treadonly assetMap = new AssetMap()\n\n\t#assetService: AssetService | undefined\n\n\tget assetService() {\n\t\treturn this.#assetService\n\t}\n\n\tconstructor(\n\t\tprivate readonly addChanges: EngineChangeSignal,\n\t\tprivate readonly loadingStore: LoadingStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\tsuper()\n\n\t\t// FIXME: Keep all asset map management in one place and don't use services in editor frame.\n\t\treadAssetUpdatesStream(\n\t\t\tAssets.on(channelToWebOrAutomation).discover(),\n\t\t\tevent =>\n\t\t\t\tthis.scheduler.process(() => {\n\t\t\t\t\tif (!event.assets) return\n\t\t\t\t\tthis.loadingStore.assetMapLoaded = true\n\t\t\t\t\tthis.assetMap.set(event.assets)\n\n\t\t\t\t\t// Query only the loaded and actual nodes. Because we need to clear their caches.\n\t\t\t\t\tthis.treeStore\n\t\t\t\t\t\t.query()\n\t\t\t\t\t\t.whereNodeIsLoaded()\n\t\t\t\t\t\t.whereClass(CodeComponentNode)\n\t\t\t\t\t\t.forEach(node => {\n\t\t\t\t\t\t\tnode.cache.clearRawControlProps()\n\t\t\t\t\t\t})\n\t\t\t\t\tthis.addChanges(EngineChange.AssetMap)\n\t\t\t\t}, \"nonUserEvent\"),\n\t\t\tabortSignal,\n\t\t)\n\t}\n\n\tsetAssetService(assetService: AssetService) {\n\t\tthis.#assetService = assetService\n\t}\n}\n", "import type { ComponentLoader, EntityDefinition } from \"@framerjs/framer-runtime\"\nimport type { LocalModuleId, ModuleBareIdentifierString } from \"@framerjs/shared\"\nimport {\n\tasLocalId,\n\tgetLogger,\n\tisDependenciesFileId,\n\tisLocalModuleIdentifier,\n\tparseModuleIdentifier,\n} from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { TogglePreviewVisibleOptions } from \"document/preview/togglePreviewVisibleWithoutEngineDependency.ts\"\nimport { ActiveAssetsPanelTab, ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport type { ImportStatement } from \"modules/utils.ts\"\nimport { createCodeFileModule } from \"utils/codeFiles.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport type { CodeFilePosition } from \"#framer-plugin/framerAPI.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\n\nconst log = getLogger(\"CodeEditorStore\")\n\nexport class CodeEditorStore extends EngineStore {\n\tprivate _currentCodeFileId?: LocalModuleId | null = null\n\tprivate saveCurrentFileHandler?: () => Promise<void>\n\n\t/**\n\t * localId (modulesStorage) of the currently selected codeFile\n\t */\n\n\tget currentCodeFileId() {\n\t\treturn this._currentCodeFileId\n\t}\n\n\tset currentCodeFileId(id: LocalModuleId | null | undefined) {\n\t\tthis._currentCodeFileId = id\n\t\tthis.chromeStore.onChangeCodeFile(id ?? undefined)\n\t}\n\n\tcurrentCodeFileEdited = false\n\tcurrentCodeFileSyncing = false\n\tversionHistoryActive = false\n\tversionHistoryDiffFile: null | string = null\n\n\t/**\n\t * Position to scroll to when the editor is ready\n\t */\n\tpendingScrollPosition: CodeFilePosition | null = null\n\n\timportsToAdd: ImportStatement[] = []\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly togglePreviewVisible: (options: TogglePreviewVisibleOptions) => void,\n\t) {\n\t\tsuper()\n\t}\n\n\tget currentFilePath(): string | undefined {\n\t\tif (!this.currentCodeFileId) return undefined\n\t\tif (isDependenciesFileId(this.currentCodeFileId)) return this.currentCodeFileId\n\n\t\tconst entry = this.modulesStore.getModuleEntryByLocalId(this.currentCodeFileId)\n\t\tif (!entry) return undefined\n\t\treturn entry.name\n\t}\n\n\thasUnsavedChanges() {\n\t\treturn this.currentCodeFileEdited || this.modulesStore.hasLocalCodeFileChanges()\n\t}\n\n\tcloseEditor = () => {\n\t\tthis.togglePreviewVisible({ visible: false })\n\t\tif (this.currentCodeFileId) {\n\t\t\tthis.currentCodeFileId = null\n\t\t}\n\t}\n\n\t/**\n\t * This will create a new code file\n\t */\n\tcreateFile({\n\t\tpath,\n\t\tcontent,\n\t\topenFile,\n\t\topenPreview,\n\t\tonSuccess,\n\t}: {\n\t\tpath: string\n\t\tcontent: string\n\t\topenFile: boolean\n\t\topenPreview?: boolean\n\t\tonSuccess?: (id: LocalModuleId) => void\n\t}) {\n\t\tcreateCodeFileModule(this.modulesStore, path, content)\n\t\t\t.then(moduleEntry => {\n\t\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\t\tif (this.chromeStore.mainView === ActiveMainView.CodeEditor || openFile) {\n\t\t\t\t\t\tthis.chromeStore.assetsExpanded = true\n\t\t\t\t\t\tthis.chromeStore.assetsPanelTab = ActiveAssetsPanelTab.Code\n\t\t\t\t\t\tthis.currentCodeFileId = moduleEntry.localId\n\t\t\t\t\t\t// Allow the \"openPreview\" boolean to be optional (undefined)\n\t\t\t\t\t\t// This allows us to leave the current preview state \"as is\"\n\t\t\t\t\t\tif (openPreview !== undefined) this.togglePreviewVisible({ visible: openPreview })\n\t\t\t\t\t}\n\t\t\t\t\tonSuccess?.(moduleEntry.localId)\n\t\t\t\t})\n\t\t\t})\n\t\t\t.catch(error => {\n\t\t\t\tlog.reportError(error)\n\n\t\t\t\tconst detailedMessage = error instanceof Error ? error.message : \"an unexpected error occurred\"\n\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"error\",\n\t\t\t\t\ttext: `Failed to save file: ${detailedMessage}`,\n\t\t\t\t\tkey: \"external-component-unlink-error\",\n\t\t\t\t\ticon: \"error\",\n\t\t\t\t})\n\t\t\t})\n\t}\n\n\t/**\n\t * Used to open the code panel and set the active code file\n\t * This get called from with a filePath, since we don't always have access to the File.id\n\t */\n\teditFile(filePath: string | ModuleBareIdentifierString, position?: CodeFilePosition) {\n\t\tif (!filePath) return\n\t\tif (filePath.startsWith(\"./\")) {\n\t\t\tfilePath = filePath.slice(2)\n\t\t}\n\t\tconst parsed = parseModuleIdentifier(filePath)\n\n\t\tlet fileLocalId: LocalModuleId | undefined\n\n\t\tif (isLocalModuleIdentifier(parsed)) {\n\t\t\tfileLocalId = parsed.localId\n\t\t} else if (isDependenciesFileId(filePath)) {\n\t\t\tfileLocalId = asLocalId(filePath)\n\t\t} else {\n\t\t\tconst entry = this.modulesStore.getModuleEntryByUniqueName(filePath)\n\t\t\tif (!entry) return\n\t\t\tfileLocalId = entry.localId\n\t\t}\n\n\t\tconst componentsInFile = this.getComponentsInLocalFile(`./${filePath}`)\n\t\tconst shouldOpenPreview = componentsInFile && componentsInFile.length > 0\n\n\t\t// Store the position to scroll to when the editor is ready\n\t\tif (position) {\n\t\t\tthis.pendingScrollPosition = position\n\t\t}\n\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tthis.chromeStore.assetsExpanded = true\n\t\t\tthis.chromeStore.assetsPanelTab = ActiveAssetsPanelTab.Code\n\t\t\tthis.currentCodeFileId = fileLocalId\n\t\t\tif (shouldOpenPreview) this.togglePreviewVisible({ visible: true })\n\t\t})\n\t}\n\n\tprivate getComponentsInLocalFile(file: string): EntityDefinition[] | null {\n\t\tconst componentsInFile: EntityDefinition[] = []\n\n\t\tfor (const component of this.componentLoader.getAllLocalModules()) {\n\t\t\tif (component.type !== \"component\") continue\n\t\t\tif (component.file !== file) continue\n\n\t\t\tcomponentsInFile.push(component)\n\t\t}\n\n\t\treturn componentsInFile\n\t}\n\n\t/**\n\t * Clear any pending scroll position\n\t */\n\tclearPendingScrollPosition() {\n\t\tthis.pendingScrollPosition = null\n\t}\n\n\tqueueImportToAdd(importStatement: ImportStatement) {\n\t\tthis.importsToAdd = [...this.importsToAdd, importStatement]\n\t}\n\n\tregisterSaveCurrentFileHandler(handler: () => Promise<void>) {\n\t\tthis.saveCurrentFileHandler = handler\n\t}\n\n\tasync saveCurrentFile() {\n\t\tawait this.saveCurrentFileHandler?.()\n\t}\n}\n", "import type { PillTone } from \"@framerjs/fresco\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport type { CollectionItemNode } from \"document/models/CanvasTree/index.ts\"\nimport { collectionItemTableStatusColumnKey } from \"document/models/CanvasTree/nodes/utils/collectionStatusMetadata.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport type { ComboBoxCellPillItem } from \"../ComboBoxCellPills.tsx\"\nimport type { CollectionItemTableColumn } from \"./collectionItemTableColumns.ts\"\n\nexport const collectionItemTableDraftStatus = Dictionary.Draft\nexport const collectionItemTableLiveStatus = Dictionary.Live\n\nexport const collectionItemTableStatusControl = {\n\ttype: ControlType.Enum,\n\ttitle: \"Status\",\n\toptions: [collectionItemTableDraftStatus, collectionItemTableLiveStatus],\n\toptionTitles: [collectionItemTableDraftStatus, collectionItemTableLiveStatus],\n\tdefaultValue: collectionItemTableLiveStatus,\n} satisfies CollectionItemTableColumn[\"control\"]\n\nexport function isCollectionItemTableStatusColumnKey(columnKey: string): boolean {\n\treturn columnKey === collectionItemTableStatusColumnKey\n}\n\nexport function isCollectionItemTableStatusColumn(column: Pick<CollectionItemTableColumn, \"key\">): boolean {\n\treturn isCollectionItemTableStatusColumnKey(column.key)\n}\n\nexport function getCollectionItemTableStatusValue(\n\titem: Pick<CollectionItemNode, \"isDraft\">,\n): typeof collectionItemTableDraftStatus | typeof collectionItemTableLiveStatus {\n\treturn item.isDraft ? collectionItemTableDraftStatus : collectionItemTableLiveStatus\n}\n\nexport function getCollectionItemTableStatusPillTone(\n\tstatus: typeof collectionItemTableDraftStatus | typeof collectionItemTableLiveStatus | undefined,\n): PillTone {\n\tif (status === collectionItemTableDraftStatus) return \"tint\"\n\tif (status === collectionItemTableLiveStatus) return \"success\"\n\treturn \"default\"\n}\n\nexport function getCollectionItemTableStatusPillItems(\n\titem: Pick<CollectionItemNode, \"isDraft\">,\n): readonly ComboBoxCellPillItem[] {\n\tconst value = getCollectionItemTableStatusValue(item)\n\treturn [{ key: value, label: value, tone: getCollectionItemTableStatusPillTone(value) }]\n}\n\nexport function getCollectionItemTableDraftValueForStatus(status: string): true | undefined {\n\treturn status === collectionItemTableDraftStatus ? true : undefined\n}\n", "import { assert, assertNever, emptyMap } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport type { CollectionItemNode, CollectionNode } from \"document/models/CanvasTree/index.ts\"\nimport {\n\ttype ImageVariableDefinition,\n\tisVariableDefinition,\n\ttype VariableDefinition,\n\ttype VariableID,\n\ttype VariablesAndDividers,\n} from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { getLink, isLinkToURL } from \"document/models/CanvasTree/traits/utils/Link.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { getNegatedLabel } from \"utils/getNegatedLabel.ts\"\nimport { isNonEmptyString } from \"utils/typeChecks.ts\"\nimport { collectionItemTableStatusColumnKey } from \"../../../../models/CanvasTree/nodes/utils/collectionStatusMetadata.ts\"\nimport type { EnumControlPropValue } from \"../../../../models/controlProps/ControlProp.ts\"\nimport type { Link } from \"../../../tools/linkTool/Link.tsx\"\nimport { collectionItemTableDraftStatus, collectionItemTableLiveStatus } from \"./collectionItemTableStatusColumn.ts\"\nimport { getAssociatedVariableStringValue } from \"./getAssociatedVariableStringValue.ts\" // MARK: Field definitions\n\n// MARK: Field definitions\n\ninterface CollectionItemTableOption<Value> {\n\treadonly value: Value\n\treadonly label: string\n}\n\ninterface FieldDefinition<Type, Value, Config> {\n\ttype: Type\n\tid: string\n\tname: string\n\tresolveValue: (item: CollectionItemNode) => Value | undefined\n\tconfig: Config\n}\n\ntype BinaryOptions = readonly [CollectionItemTableOption<true>, CollectionItemTableOption<false>]\n\ntype OptionValue = EnumControlPropValue\n\nexport type CollectionItemTableFieldDefinition =\n\t| FieldDefinition<\"boolean\", boolean, { options: BinaryOptions }>\n\t| FieldDefinition<\"file\", string, { options: BinaryOptions }>\n\t| FieldDefinition<\"image\", string, { options: BinaryOptions }>\n\t| FieldDefinition<\"link\", Link, { options: BinaryOptions }>\n\t| FieldDefinition<\"option\", OptionValue, { options: readonly CollectionItemTableOption<string>[] }>\n\t| FieldDefinition<\"status\", boolean, { options: BinaryOptions }>\n\t| FieldDefinition<\"string\", string, { options: BinaryOptions }>\n\nexport type CollectionItemTableFieldDefinitionType = CollectionItemTableFieldDefinition[\"type\"]\nexport type CollectionItemTableFieldDefinitionFor<T extends CollectionItemTableFieldDefinitionType> =\n\tCollectionItemTableFieldDefinition & { type: T }\n\nexport function isCollectionItemTableFieldDefinitionType<T extends CollectionItemTableFieldDefinitionType>(\n\ttype: T,\n\tvalue: CollectionItemTableFieldDefinition,\n): value is CollectionItemTableFieldDefinitionFor<T> {\n\treturn value.type === type\n}\n\n// MARK: Filter definitions\n\ninterface FieldFilter<Type extends CollectionItemTableFieldDefinitionType, FilterState> {\n\ttype: Type\n\tstate: FilterState\n\tfield: CollectionItemTableFieldDefinitionFor<Type>\n}\n\nexport type CollectionItemTableFilter =\n\t| FieldFilter<\"boolean\", { value: boolean }>\n\t| FieldFilter<\"file\", { isSet: boolean }>\n\t| FieldFilter<\"image\", { isSet: boolean }>\n\t| FieldFilter<\"link\", { isSet: boolean }>\n\t| FieldFilter<\"option\", { value: string }>\n\t| FieldFilter<\"status\", { isLive: boolean }>\n\t| FieldFilter<\"string\", { isSet: boolean }>\n\nexport type CollectionItemTableFilterFor<Field extends CollectionItemTableFieldDefinition> =\n\tCollectionItemTableFilter & { field: Field }\n\nexport type CollectionFiltersByTarget = ReadonlyMap<string, CollectionItemTableFilter>\n\nexport interface CollectionItemTableFilterState {\n\tsearchTerm: string\n\tfiltersByTarget: CollectionFiltersByTarget\n}\n\nexport function createCollectionItemTableFilterState(\n\tfilterState?: Partial<CollectionItemTableFilterState>,\n): CollectionItemTableFilterState {\n\treturn {\n\t\tsearchTerm: \"\",\n\t\tfiltersByTarget: emptyMap(),\n\t\t...filterState,\n\t}\n}\n\nexport function isCollectionItemTableFilterStateEmpty(filterState: CollectionItemTableFilterState): boolean {\n\treturn filterState.searchTerm.trim().length === 0 && filterState.filtersByTarget.size === 0\n}\n\nconst isSetFieldOptions = [\n\t{ value: true, label: Dictionary.IsSet },\n\t{ value: false, label: Dictionary.IsntSet },\n] as const\n\nconst statusFieldOptions = [\n\t{ value: true, label: Dictionary.Live },\n\t{ value: false, label: Dictionary.Draft },\n] as const\n\nexport function getCollectionItemTableFieldDefinitions(\n\tcollectionNode: CollectionNode,\n): CollectionItemTableFieldDefinition[] {\n\tconst fieldDefinitions: CollectionItemTableFieldDefinition[] = [\n\t\t{\n\t\t\ttype: \"status\",\n\t\t\tid: collectionItemTableStatusColumnKey,\n\t\t\tname: Dictionary.Status,\n\t\t\tconfig: { options: statusFieldOptions },\n\t\t\tresolveValue: item => item.isDraft,\n\t\t},\n\t]\n\n\tconst variableDefinitionsById = getCollectionItemTableVariableDefinitionMap(collectionNode.variables)\n\n\tfor (const variable of collectionNode.variables) {\n\t\tif (!isVariableDefinition(variable)) continue\n\n\t\tconst fieldDefinition = getCollectionItemFieldDefinition(variable, variableDefinitionsById)\n\t\tif (fieldDefinition === null) continue\n\n\t\tfieldDefinitions.push(fieldDefinition)\n\t}\n\n\treturn fieldDefinitions\n}\n\nfunction getCollectionItemFieldDefinition(\n\tvariable: VariableDefinition,\n\tvariableDefinitionsById: ReadonlyMap<VariableID, VariableDefinition>,\n): CollectionItemTableFieldDefinition | null {\n\tswitch (variable.type) {\n\t\tcase ControlType.Boolean:\n\t\t\treturn {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\tconst value = controlProp?.type === ControlType.Boolean ? controlProp.value : variable.initialValue\n\t\t\t\t\treturn value === true\n\t\t\t\t},\n\t\t\t\tconfig: {\n\t\t\t\t\toptions: [\n\t\t\t\t\t\t{ value: true, label: variable.name },\n\t\t\t\t\t\t{ value: false, label: getNegatedLabel(variable.name) },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t}\n\t\tcase ControlType.Enum:\n\t\t\treturn {\n\t\t\t\ttype: \"option\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\treturn controlProp?.type === ControlType.Enum ? controlProp.value : variable.initialValue\n\t\t\t\t},\n\t\t\t\tconfig: {\n\t\t\t\t\toptions: variable.cases.map(option => ({ value: option.id, label: option.name })),\n\t\t\t\t},\n\t\t\t}\n\t\tcase ControlType.String:\n\t\t\treturn {\n\t\t\t\ttype: \"string\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\t// Keep filter semantics aligned with the table cell: when a CMS string is unset, it can still display\n\t\t\t\t\t// an associated string fallback before falling back to its own initial value.\n\t\t\t\t\tif (controlProp?.type === ControlType.String && hasFieldValue(controlProp.value)) {\n\t\t\t\t\t\treturn controlProp.value as string\n\t\t\t\t\t}\n\n\t\t\t\t\treturn getAssociatedVariableStringValue(variable, variableDefinitionsById, item) ?? variable.initialValue\n\t\t\t\t},\n\t\t\t\tconfig: { options: isSetFieldOptions },\n\t\t\t}\n\t\tcase ControlType.Link:\n\t\t\treturn {\n\t\t\t\ttype: \"link\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\tconst value = controlProp?.type === ControlType.Link ? controlProp.value : undefined\n\t\t\t\t\treturn hasLinkValue(value) ? value : undefined\n\t\t\t\t},\n\t\t\t\tconfig: { options: isSetFieldOptions },\n\t\t\t}\n\t\tcase ControlType.Image: {\n\t\t\tif (!supportsImageIsSetFilter(variable)) return null\n\n\t\t\treturn {\n\t\t\t\ttype: \"image\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\tconst value = controlProp?.type === ControlType.Image ? controlProp.value : variable.initialValue\n\t\t\t\t\treturn isNonEmptyString(value) ? value : undefined\n\t\t\t\t},\n\t\t\t\tconfig: { options: isSetFieldOptions },\n\t\t\t}\n\t\t}\n\t\tcase ControlType.File:\n\t\t\treturn {\n\t\t\t\ttype: \"file\",\n\t\t\t\tid: variable.id,\n\t\t\t\tname: variable.name,\n\t\t\t\tresolveValue: item => {\n\t\t\t\t\tconst controlProp = item.getControlProp(variable.id)\n\t\t\t\t\tconst value = controlProp?.type === ControlType.File ? controlProp.value : variable.initialValue\n\t\t\t\t\treturn isNonEmptyString(value) ? value : undefined\n\t\t\t\t},\n\t\t\t\tconfig: { options: isSetFieldOptions },\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn null\n\t}\n}\n\nfunction getCollectionItemTableVariableDefinitionMap(\n\tvariables: VariablesAndDividers,\n): ReadonlyMap<VariableID, VariableDefinition> {\n\tconst variableDefinitionsById = new Map<VariableID, VariableDefinition>()\n\n\tfor (const variable of variables) {\n\t\tif (!isVariableDefinition(variable)) continue\n\n\t\tvariableDefinitionsById.set(variable.id, variable)\n\t}\n\n\treturn variableDefinitionsById\n}\n\nfunction getCollectionItemTableFieldFilterTargetKey(fieldId: VariableID): string {\n\treturn `field:${fieldId}`\n}\n\nexport function shouldInvalidateFilter(\n\tfilter: CollectionItemTableFilter,\n\tcurrentField: CollectionItemTableFieldDefinition | undefined,\n): boolean {\n\tif (!currentField || currentField.type !== filter.type) return true\n\tswitch (filter.type) {\n\t\tcase \"option\":\n\t\t\tassert(currentField.type === \"option\")\n\t\t\treturn !currentField.config.options.some(option => option.value === filter.state.value)\n\t\tcase \"boolean\":\n\t\tcase \"file\":\n\t\tcase \"image\":\n\t\tcase \"link\":\n\t\tcase \"status\":\n\t\tcase \"string\":\n\t\t\treturn false\n\t\tdefault:\n\t\t\tassertNever(filter)\n\t}\n}\n\nexport function toggleCollectionItemTableFieldFilter(\n\tfiltersByTarget: ReadonlyMap<string, CollectionItemTableFilter>,\n\tfilter: CollectionItemTableFilter,\n): ReadonlyMap<string, CollectionItemTableFilter> {\n\tconst nextFiltersByTarget = new Map(filtersByTarget)\n\tconst filterKey = getCollectionItemTableFieldFilterTargetKey(filter.field.id)\n\tconst activeFilter = filtersByTarget.get(filterKey)\n\n\tif (activeFilter && areFiltersEquivalent(filter, activeFilter)) {\n\t\tnextFiltersByTarget.delete(filterKey)\n\t\treturn nextFiltersByTarget\n\t}\n\n\tnextFiltersByTarget.set(filterKey, filter)\n\treturn nextFiltersByTarget\n}\n\nfunction areFiltersEquivalent(filter: CollectionItemTableFilter, other: CollectionItemTableFilter): boolean {\n\tswitch (filter.type) {\n\t\tcase \"boolean\":\n\t\t\treturn other.type === \"boolean\" && filter.state.value === other.state.value\n\t\tcase \"option\":\n\t\t\treturn other.type === \"option\" && filter.state.value === other.state.value\n\t\tcase \"status\":\n\t\t\treturn other.type === \"status\" && filter.state.isLive === other.state.isLive\n\t\tcase \"file\":\n\t\tcase \"image\":\n\t\tcase \"link\":\n\t\tcase \"string\":\n\t\t\treturn other.type === filter.type && filter.state.isSet === other.state.isSet\n\t}\n}\n\nexport function setCollectionItemTableFieldFilter(\n\tfiltersByTarget: ReadonlyMap<string, CollectionItemTableFilter>,\n\tfilter: CollectionItemTableFilter,\n): ReadonlyMap<string, CollectionItemTableFilter> {\n\tconst nextFiltersByTarget = new Map(filtersByTarget)\n\tnextFiltersByTarget.set(getCollectionItemTableFieldFilterTargetKey(filter.field.id), filter)\n\treturn nextFiltersByTarget\n}\n\nexport function removeCollectionItemTableFieldFilter(\n\tfiltersByTarget: ReadonlyMap<string, CollectionItemTableFilter>,\n\tfilter: CollectionItemTableFilter,\n): ReadonlyMap<string, CollectionItemTableFilter> {\n\tconst nextFiltersByTarget = new Map(filtersByTarget)\n\tnextFiltersByTarget.delete(getCollectionItemTableFieldFilterTargetKey(filter.field.id))\n\treturn nextFiltersByTarget\n}\n\nexport function getCollectionItemTableFieldFilterLabel(filter: CollectionItemTableFilter): string {\n\tconst fieldName = filter.field.name\n\n\tswitch (filter.type) {\n\t\tcase \"boolean\":\n\t\t\treturn filter.state.value ? fieldName : getNegatedLabel(fieldName)\n\t\tcase \"option\": {\n\t\t\tconst option = filter.field.config.options.find(option => option.value === filter.state.value)\n\t\t\treturn option?.label ?? filter.state.value\n\t\t}\n\t\tcase \"file\":\n\t\tcase \"image\":\n\t\tcase \"link\":\n\t\tcase \"string\":\n\t\t\treturn `${fieldName} ${filter.state.isSet ? Dictionary.IsSet : Dictionary.IsntSet}`\n\t\tcase \"status\":\n\t\t\treturn filter.state.isLive ? collectionItemTableLiveStatus : collectionItemTableDraftStatus\n\t}\n}\n\nfunction hasDefaultImage(variableDefinition: ImageVariableDefinition): boolean {\n\tif (typeof variableDefinition.initialValue === \"string\") {\n\t\treturn variableDefinition.initialValue.length > 0\n\t}\n\tif (typeof variableDefinition.initialValue?.value === \"string\") {\n\t\treturn variableDefinition.initialValue.value.length > 0\n\t}\n\treturn false\n}\n\nfunction supportsImageIsSetFilter(variableDefinition: ImageVariableDefinition): boolean {\n\t// Default images render as populated values in the CMS, so filtering them by set/unset would never\n\t// distinguish items.\n\treturn !hasDefaultImage(variableDefinition)\n}\n\nfunction hasFieldValue(value: unknown): boolean {\n\treturn value !== undefined && value !== null && value !== \"\"\n}\n\nfunction hasLinkValue(value: unknown): value is Link {\n\tconst link = getLink(value)\n\tif (!link) return false\n\tif (isLinkToURL(link) && link.url === \"\") return false\n\treturn true\n}\n\ninterface FilterCollectionItemsParams {\n\titems: readonly CollectionItemNode[]\n\trawSearchTerm: string\n\tactiveFilters: readonly CollectionItemTableFilter[]\n}\n\nexport function filterCollectionItemTableItems({\n\titems,\n\trawSearchTerm,\n\tactiveFilters,\n}: FilterCollectionItemsParams): CollectionItemNode[] {\n\tconst searchTerm = rawSearchTerm.toLowerCase().trim()\n\n\treturn items.filter(item => {\n\t\tfor (const filter of activeFilters) {\n\t\t\tswitch (filter.type) {\n\t\t\t\tcase \"status\": {\n\t\t\t\t\tconst isDraft = filter.field.resolveValue(item)\n\t\t\t\t\tif (!!isDraft === filter.state.isLive) return false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase \"boolean\": {\n\t\t\t\t\tconst value = filter.field.resolveValue(item)\n\t\t\t\t\tif (value !== filter.state.value) return false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase \"option\": {\n\t\t\t\t\tconst value = filter.field.resolveValue(item)\n\t\t\t\t\tif (value !== filter.state.value) return false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase \"file\":\n\t\t\t\tcase \"image\":\n\t\t\t\tcase \"link\":\n\t\t\t\tcase \"string\": {\n\t\t\t\t\tconst value = filter.field.resolveValue(item)\n\t\t\t\t\tif (!!value !== filter.state.isSet) return false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tassertNever(filter)\n\t\t\t}\n\t\t}\n\n\t\treturn searchTerm.length !== 0 ? item.containsSearchFilter(searchTerm) : true\n\t})\n}\n", "import { assert, List, ReadonlySet } from \"@framerjs/shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { CollectionItemNode } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionItemNode, isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { privateDraftCollectionItemHasUserData } from \"document/models/CanvasTree/nodes/utils/privateDraftCollectionItemHasUserData.ts\"\nimport type { VariableID } from \"document/models/CanvasTree/traits/WithVariables.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { isCurrentUserPrivateDraftCollectionItem } from \"document/utils/collectionItemVisibility.ts\"\nimport type {\n\tAddReferenceAction,\n\tArrayItemStackElement,\n\tCollectionStackElement,\n\tExistingCollectionStackElement,\n\tNewCollectionStackElement,\n\tOverlayStackElement,\n\tPrivateDraftCollectionStackElement,\n\tTemporaryCollectionStackElement,\n} from \"document/utils/contentManagementOverlayStack.ts\"\nimport {\n\tgetActiveCollectionStackElement,\n\tisNewCollectionItemStackElement,\n} from \"document/utils/contentManagementOverlayStack.ts\"\nimport { ScopeType } from \"document/utils/scopeType.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport type { CollectionItemTableFilterState } from \"../components/chrome/contentManagement/utils/collectionItemTableFilters.ts\"\nimport {\n\tcreateCollectionItemTableFilterState,\n\tisCollectionItemTableFilterStateEmpty,\n} from \"../components/chrome/contentManagement/utils/collectionItemTableFilters.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { SessionStore } from \"./SessionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport class ContentManagementStore extends EngineStore {\n\tisLoadingSampleData = false\n\tprivate _multiSelectedItems: ReadonlySet<NodeID> | null = null\n\tprivate _agentSelectionModeActive = false\n\n\tpublic constructor(\n\t\tprivate readonly selection: SelectionStore,\n\t\tprivate readonly chromeStore: ChromeStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly sessionStore: SessionStore,\n\t) {\n\t\tsuper()\n\t}\n\n\tprivate _temporaryItemCache = new Map<NodeID, CollectionItemNode>()\n\n\ttableFiltersByCollection: ReadonlyMap<NodeID, CollectionItemTableFilterState> = new Map()\n\n\tcollectionItemIdBasedOnCurrentSelection: NodeID | null = null\n\n\tgetCollectionItemIdBasedOnCurrentSelection(): NodeID | null {\n\t\tconst activeElement = this.getActiveCollectionStackElement()\n\t\tif (activeElement?.type === \"existing\") {\n\t\t\tconst item = this.treeStore.tree.getNodeWithTrait(activeElement.itemId, isCollectionItemNode)\n\t\t\tif (item?.privateToUserId) return null\n\t\t\treturn activeElement.itemId\n\t\t}\n\t\tif (activeElement?.type === \"temporary\" || activeElement?.type === \"privateDraft\") return null\n\t\treturn this.collectionItemIdBasedOnCurrentSelection\n\t}\n\n\tsetCollectionItemIdBasedOnCurrentSelection(itemId: NodeID | null) {\n\t\tthis.collectionItemIdBasedOnCurrentSelection = itemId\n\t}\n\n\tupdateCollectionItemTableFilterState(\n\t\tcollectionId: NodeID,\n\t\tupdate: (filterState: CollectionItemTableFilterState) => CollectionItemTableFilterState,\n\t) {\n\t\tconst currentFilterState = this.tableFiltersByCollection.get(collectionId) ?? createCollectionItemTableFilterState()\n\t\tconst nextFilterState = update(currentFilterState)\n\t\tconst nextTableFiltersByCollection = new Map(this.tableFiltersByCollection)\n\n\t\tif (isCollectionItemTableFilterStateEmpty(nextFilterState)) {\n\t\t\tnextTableFiltersByCollection.delete(collectionId)\n\t\t} else {\n\t\t\tnextTableFiltersByCollection.set(collectionId, nextFilterState)\n\t\t}\n\n\t\tthis.tableFiltersByCollection = nextTableFiltersByCollection\n\t}\n\n\tsetCollectionItemTableSearchTerm(collectionId: NodeID, searchTerm: string) {\n\t\tthis.updateCollectionItemTableFilterState(collectionId, filterState => ({\n\t\t\t...filterState,\n\t\t\tsearchTerm,\n\t\t}))\n\t}\n\n\tget temporaryItemCache(): ReadonlyMap<NodeID, CollectionItemNode> {\n\t\treturn this._temporaryItemCache\n\t}\n\n\t/** The collection item node that we use before the user changed any values. */\n\tprivate _temporaryCollectionItemUpdateCount = 0\n\n\tgetActiveCollectionStackElement(): CollectionStackElement | null {\n\t\treturn getActiveCollectionStackElement(this.chromeStore.contentManagementOverlayStack)\n\t}\n\n\t/**\n\t * The last element of the overlay stack if it is a temporary collection item, or nothing. If there are temporary\n\t * collection items in the stack but the last one is an existing item, the temporary items are not considered active.\n\t */\n\tgetActiveTemporaryCollectionStackElement(): TemporaryCollectionStackElement | null {\n\t\tconst element = this.getActiveCollectionStackElement()\n\t\treturn element?.type === \"temporary\" ? element : null\n\t}\n\n\tgetActivePrivateDraftCollectionStackElement(): NewCollectionStackElement | null {\n\t\tconst element = this.getActiveCollectionStackElement()\n\t\tif (!element) return null\n\t\treturn isNewCollectionItemStackElement(element) ? element : null\n\t}\n\n\tisActiveCollectionItemSelected(): boolean {\n\t\tif (this.chromeStore.contentManagementOverlayStack.length !== 1 || this.selection.ids.length !== 1) return false\n\t\tconst activeCollectionStackElement = this.getActiveCollectionStackElement()\n\t\treturn (\n\t\t\tactiveCollectionStackElement?.type === \"existing\" && activeCollectionStackElement.itemId === this.selection.ids[0]\n\t\t)\n\t}\n\n\thasActivePrivateDraftCollectionItem() {\n\t\treturn Boolean(this.getActivePrivateDraftCollectionStackElement())\n\t}\n\n\thasAnyPrivateDraftCollectionItem() {\n\t\treturn this.chromeStore.contentManagementOverlayStack.some(isNewCollectionItemStackElement)\n\t}\n\n\thasAnyUnsavedTemporaryCollectionItem() {\n\t\treturn this.chromeStore.contentManagementOverlayStack.some(element => {\n\t\t\tif (element.type !== \"temporary\") return false\n\n\t\t\tconst collectionItem = this.temporaryItemCache.get(element.itemId)\n\t\t\tconst collection = this.treeStore.tree.getNodeWithTrait(element.collectionId, isCollectionNode)\n\t\t\tif (!collectionItem || !collection) return false\n\n\t\t\treturn privateDraftCollectionItemHasUserData({\n\t\t\t\tcollection,\n\t\t\t\tcollectionItem,\n\t\t\t})\n\t\t})\n\t}\n\n\tshowErrorsOnActivePrivateDraftCollectionItem() {\n\t\tthis.updateActivePrivateDraftCollectionStackElement(element => ({\n\t\t\t...element,\n\t\t\tshowErrors: true,\n\t\t}))\n\t}\n\n\tsetAttemptedCloseOnActivePrivateDraftCollectionItem() {\n\t\tthis.updateActivePrivateDraftCollectionStackElement(element => ({\n\t\t\t...element,\n\t\t\tattemptedClose: true,\n\t\t}))\n\t}\n\n\tmarkActivePrivateDraftCollectionItemAsSaved(itemId: NodeID) {\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tif (stack.length === 1) {\n\t\t\tthis.selection.set(itemId)\n\t\t}\n\n\t\t// Ensure we can't accidentally go back to this item\n\t\t// e.g. by Edit Author > New Article > Back + Save > Undo > Forward\n\t\tthis._temporaryItemCache.delete(itemId)\n\n\t\tthis.updateActivePrivateDraftCollectionStackElement(element => {\n\t\t\tconst nextElement: ExistingCollectionStackElement = {\n\t\t\t\tcollectionId: element.collectionId,\n\t\t\t\titemId,\n\t\t\t\ttype: \"existing\",\n\t\t\t}\n\t\t\tif (element.saveAction) nextElement.saveAction = element.saveAction\n\t\t\treturn nextElement\n\t\t})\n\t}\n\n\topenPrivateDraftCollectionItem({\n\t\tcollectionId,\n\t\titemId,\n\t\tsaveAction,\n\t}: {\n\t\tcollectionId: NodeID\n\t\titemId: NodeID\n\t\tsaveAction?: AddReferenceAction\n\t}) {\n\t\tconst nextElement: PrivateDraftCollectionStackElement = {\n\t\t\tcollectionId,\n\t\t\titemId,\n\t\t\tshowErrors: false,\n\t\t\ttype: \"privateDraft\",\n\t\t}\n\t\tif (saveAction) nextElement.saveAction = saveAction\n\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tconst activeElement = stack.at(-1)\n\t\tif (activeElement?.type === \"privateDraft\" && activeElement.itemId === itemId) {\n\t\t\tthis.chromeStore.setContentManagementOverlayStack(List.replace(stack, stack.length - 1, nextElement))\n\t\t\treturn\n\t\t}\n\n\t\tif (stack.length === 0) {\n\t\t\tthis.selection.set(itemId)\n\t\t}\n\n\t\tthis.chromeStore.setContentManagementOverlayStack(List.push(stack, nextElement))\n\t}\n\n\t/**\n\t * Legacy cache-backed path used only while cmsPrivateDraftItems can be off.\n\t * Remove this when private draft items become the only new-item model.\n\t */\n\topenTemporaryCollectionItem({\n\t\tcollectionId,\n\t\titemId,\n\t\tsaveAction,\n\t}: {\n\t\tcollectionId: NodeID\n\t\titemId: NodeID\n\t\tsaveAction?: AddReferenceAction\n\t}) {\n\t\tconst nextElement: TemporaryCollectionStackElement = {\n\t\t\tcollectionId,\n\t\t\titemId,\n\t\t\tsaveAction,\n\t\t\tshowErrors: false,\n\t\t\ttype: \"temporary\",\n\t\t}\n\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tconst activeElement = this.chromeStore.contentManagementOverlayStack.at(-1)\n\t\tif (activeElement?.type === \"temporary\" && activeElement.itemId === itemId) {\n\t\t\tthis.chromeStore.setContentManagementOverlayStack(List.replace(stack, stack.length - 1, nextElement))\n\t\t\treturn\n\t\t}\n\n\t\tthis.chromeStore.setContentManagementOverlayStack(List.push(stack, nextElement))\n\t}\n\n\t/**\n\t * Legacy cache-backed path used only while cmsPrivateDraftItems can be off.\n\t * Remove this when private draft items become the only new-item model.\n\t */\n\tcreateTemporaryCollectionItem({\n\t\tcollectionId,\n\t\tsaveAction,\n\t\ttemplate,\n\t}: {\n\t\tcollectionId: NodeID\n\t\tsaveAction?: AddReferenceAction\n\t\ttemplate?: CollectionItemNode\n\t}) {\n\t\tconst newItem = template ?? CollectionItemNode.create()\n\t\tthis._temporaryItemCache.set(newItem.id, newItem)\n\n\t\tthis.openTemporaryCollectionItem({\n\t\t\tcollectionId,\n\t\t\titemId: newItem.id,\n\t\t\tsaveAction,\n\t\t})\n\t}\n\n\t/**\n\t * Updates the active private draft collection item stack element, if it exists.\n\t * Private drafts can still be represented by legacy cache-backed temporary elements.\n\t */\n\tprivate updateActivePrivateDraftCollectionStackElement(\n\t\tupdate: (element: NewCollectionStackElement) => OverlayStackElement,\n\t) {\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tconst index = stack.length - 1\n\t\tconst element = stack[index]\n\t\tif (!element || !isNewCollectionItemStackElement(element)) return\n\t\tthis.chromeStore.setContentManagementOverlayStack(List.replace(stack, index, update(element)))\n\t}\n\n\tclearOverlayStack() {\n\t\tthis.chromeStore.setContentManagementOverlayStack([])\n\t}\n\n\tpushExistingItemToOverlayStack(id: NodeID) {\n\t\tconst collectionId = this.treeStore.tree.getParent(id)?.id\n\t\tassert(collectionId, \"Existing collection item must have a parent collection\")\n\t\tthis.chromeStore.setContentManagementOverlayStack(\n\t\t\tList.push(this.chromeStore.contentManagementOverlayStack, {\n\t\t\t\tcollectionId,\n\t\t\t\ttype: \"existing\",\n\t\t\t\titemId: id,\n\t\t\t}),\n\t\t)\n\t}\n\n\tpopOverlayStack(tree: CanvasTree) {\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tconst itemToBePopped = stack.at(-1)\n\t\tconst activeElement = this.getActiveCollectionStackElement()\n\t\tconst selectedItem = tree.getNodeWithTrait(this.selection.ids[0], isCollectionItemNode)\n\n\t\tif (stack.length === 1 && activeElement?.type === \"existing\" && selectedItem?.parentid) {\n\t\t\t// The last existing item will be popped automatically by post-processing\n\t\t\tthis.selection.set(selectedItem.parentid)\n\t\t}\n\n\t\tif (itemToBePopped?.type === \"temporary\") {\n\t\t\t// Ensure we can't accidentally go back to this item.\n\t\t\t// e.g. by Edit Author in Canvas > New Article > \u2318K + Switch to other + Discard > Back\n\t\t\tthis._temporaryItemCache.delete(itemToBePopped.itemId)\n\t\t} else if (itemToBePopped?.type === \"privateDraft\") {\n\t\t\tconst treeItem = this.treeStore.tree.getNodeWithTrait(itemToBePopped.itemId, isCollectionItemNode)\n\t\t\tif (\n\t\t\t\ttreeItem?.parentid === itemToBePopped.collectionId &&\n\t\t\t\tisCurrentUserPrivateDraftCollectionItem(treeItem, { currentUserId: this.sessionStore.user.id })\n\t\t\t) {\n\t\t\t\tif (stack.length === 1 && selectedItem?.id === treeItem.id) {\n\t\t\t\t\tthis.selection.set(treeItem.parentid)\n\t\t\t\t}\n\t\t\t\tthis.treeStore.discardUndoRedoEntriesForNode(treeItem.id)\n\t\t\t\tthis.treeStore.timeline.setFlagsForNextCommit({ ignoreInUndo: true })\n\t\t\t\tthis.treeStore.tree.remove(treeItem.id)\n\t\t\t}\n\t\t}\n\n\t\tthis.chromeStore.setContentManagementOverlayStack(List.pop(stack))\n\t}\n\n\treplaceActiveArrayItemOverlay(itemId: NodeID) {\n\t\tconst stack = this.chromeStore.contentManagementOverlayStack\n\t\tconst index = stack.length - 1\n\t\tconst active = stack[index]\n\t\tif (active?.type !== \"arrayItem\") return\n\n\t\tconst nextActive: ArrayItemStackElement = { ...active, arrayItemId: itemId }\n\t\tconst nextStack = List.replace(stack, index, nextActive)\n\t\tthis.chromeStore.setContentManagementOverlayStack(nextStack)\n\t}\n\n\t/** Required to trigger a re-render of the UI, necessary because the node is not yet part of the tree. */\n\tdidUpdateTemporaryCollectionItem() {\n\t\tthis._temporaryCollectionItemUpdateCount++\n\t}\n\n\trichTextEditorHasUnsavedChanges = false\n\n\t#samplePagesHaveBeenAdded = false\n\n\tprivate displayCollectionSampleModal() {\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tvariant: \"info\",\n\t\t\tprimaryText: \"Added sample blog\",\n\t\t\tsecondaryText: \"index and detail page.\",\n\t\t})\n\t}\n\n\tdidAddSampleDataPages(contentManagementActive: boolean) {\n\t\tif (contentManagementActive) {\n\t\t\t// Wait with showing the modal until the user exits the CMS\n\t\t\tthis.#samplePagesHaveBeenAdded = true\n\t\t} else {\n\t\t\tthis.displayCollectionSampleModal()\n\t\t}\n\t}\n\n\tonChangeScopeType(scopeType: ScopeType) {\n\t\tif (!this.#samplePagesHaveBeenAdded) return\n\t\tif (scopeType === ScopeType.ContentManagement) return\n\t\tthis.#samplePagesHaveBeenAdded = false\n\t\tthis.displayCollectionSampleModal()\n\t}\n\n\tprivate _collectionItemControlToHighlight: VariableID | null = null\n\n\tsetCollectionItemControlToHighlight(variableId: VariableID) {\n\t\tthis._collectionItemControlToHighlight = variableId\n\t}\n\n\tclearCollectionItemControlToHighlight() {\n\t\tthis._collectionItemControlToHighlight = null\n\t}\n\n\tget collectionItemControlToHighlight(): VariableID | null {\n\t\treturn this._collectionItemControlToHighlight\n\t}\n\n\tget isMultiSelectionModeActive(): boolean {\n\t\treturn Boolean(this._multiSelectedItems)\n\t}\n\n\tget multiSelectedItems() {\n\t\treturn this._multiSelectedItems\n\t}\n\n\tget isAgentSelectionModeActive(): boolean {\n\t\treturn this._agentSelectionModeActive\n\t}\n\n\tenterAgentSelectionMode() {\n\t\tif (!experiments.isOn(\"agent\")) return\n\t\tif (this.chromeStore.mainView !== ActiveMainView.ContentManagement) return\n\t\tif (this._agentSelectionModeActive) return\n\t\tthis.exitMultiSelectionMode()\n\t\tthis._agentSelectionModeActive = true\n\t}\n\n\texitAgentSelectionMode() {\n\t\tif (!this._agentSelectionModeActive) return\n\t\tthis._agentSelectionModeActive = false\n\t}\n\n\tenterMultiSelectionMode() {\n\t\tthis.exitAgentSelectionMode()\n\t\tif (this.isMultiSelectionModeActive) return\n\t\tthis._multiSelectedItems = new Set()\n\t}\n\n\texitMultiSelectionMode() {\n\t\tif (!this.isMultiSelectionModeActive) return\n\t\tthis._multiSelectedItems = null\n\t}\n\n\tselectItems(items: string[], behaviour?: \"exclusive\") {\n\t\tif (!this.isMultiSelectionModeActive) this.enterMultiSelectionMode()\n\n\t\tconst setToAddTo =\n\t\t\tthis._multiSelectedItems === null || behaviour === \"exclusive\" ? new Set<string>() : this._multiSelectedItems\n\t\tthis._multiSelectedItems = ReadonlySet.add(setToAddTo, ...items)\n\t}\n\n\tdeselectItems(items: string[]) {\n\t\tif (!this._multiSelectedItems) return\n\n\t\tthis._multiSelectedItems = ReadonlySet.remove(this._multiSelectedItems, ...items)\n\t}\n\n\tdeselectAllItems() {\n\t\tthis._multiSelectedItems = new Set()\n\t}\n\n\ttoggleSelectItem(item: string) {\n\t\tif (!this.isMultiSelectionModeActive) this.enterMultiSelectionMode()\n\n\t\tthis._multiSelectedItems = ReadonlySet.toggle(this._multiSelectedItems ?? new Set(), item)\n\t}\n\n\t/** This is readonly because changes should not trigger engine updates (renders). */\n\treadonly previousPostProcessState = { multiSelectionModeActive: false }\n\n\tpostProcess(engine: VekterEngine) {\n\t\tconst cmsHidden = engine.stores.chromeStore.mainView !== ActiveMainView.ContentManagement\n\t\tif (cmsHidden && this.collectionItemIdBasedOnCurrentSelection !== null) {\n\t\t\tthis.collectionItemIdBasedOnCurrentSelection = null\n\t\t}\n\n\t\tif ((cmsHidden || !experiments.isOn(\"agent\")) && this.isAgentSelectionModeActive) {\n\t\t\tthis.exitAgentSelectionMode()\n\t\t}\n\n\t\tif (!this.isMultiSelectionModeActive) {\n\t\t\tthis.previousPostProcessState.multiSelectionModeActive = false\n\t\t\treturn\n\t\t}\n\t\tconst multiSelectionModeDidUpdate = !this.previousPostProcessState.multiSelectionModeActive\n\t\tthis.previousPostProcessState.multiSelectionModeActive = true\n\n\t\tconst selectionDidChange = engine.scheduler.changes.flags.has(engine.stores.selectionStore)\n\t\tconst isDeleteConfirmationModalShown =\n\t\t\tengine.stores.modalStore.active.type === ModalType.ConfirmDeleteCollectionItems\n\t\tconst isStatusChangeItemsModalShown =\n\t\t\tengine.stores.modalStore.active.type === ModalType.ConfirmCollectionItemStatusChange\n\t\tconst isNonMultiSelectionModalVisible =\n\t\t\tengine.stores.modalStore.isVisible() && !isDeleteConfirmationModalShown && !isStatusChangeItemsModalShown\n\n\t\tconst shouldExitMultiSelectionMode =\n\t\t\tisNonMultiSelectionModalVisible || (selectionDidChange && !multiSelectionModeDidUpdate) || cmsHidden\n\n\t\tif (shouldExitMultiSelectionMode) {\n\t\t\tthis.exitMultiSelectionMode()\n\t\t}\n\t}\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { EffectPreviewState, EffectPreviewType } from \"document/utils/EffectPreviewType.ts\"\nimport { isEqual } from \"library/render/utils/isEqual.ts\"\nimport { isNull } from \"utils/typeChecks.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\n\nconst NO_EFFECT_PREVIEW: EffectPreviewState = {\n\ttype: null,\n\teffectIds: null,\n\tnodes: new Set(),\n}\nObject.freeze(NO_EFFECT_PREVIEW)\n\nexport class EffectStore extends EngineStore {\n\tactiveEffect: EffectPreviewType | null = null\n\tactiveEffectIds: NodeID[] | null = null\n\n\tconstructor(private readonly selectionStore: SelectionStore) {\n\t\tsuper()\n\t}\n\n\texitPreview = () => {\n\t\tthis.activeEffect = null\n\t\tthis.activeEffectIds = null\n\t}\n\n\tenterPreview = ({ effect, effectIds }: { effect: EffectPreviewType; effectIds?: NodeID[] }) => {\n\t\tif (this.activeEffect === effect && isEqual(this.activeEffectIds, effectIds)) return\n\n\t\tthis.activeEffect = effect\n\t\tthis.activeEffectIds = effectIds ?? null\n\t}\n\n\tget nodesInEffectPreview(): NodeID[] {\n\t\tif (isNull(this.activeEffect)) return nodesInEffectPreviewFallback\n\t\treturn this.selectionStore.ids\n\t}\n\n\tgetState(): EffectPreviewState {\n\t\treturn {\n\t\t\ttype: this.activeEffect,\n\t\t\teffectIds: new Set(this.activeEffectIds),\n\t\t\tnodes: new Set(this.nodesInEffectPreview),\n\t\t}\n\t}\n}\n\nconst nodesInEffectPreviewFallback: NodeID[] = []\n", "import { assert } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { PresetsListNode } from \"document/models/CanvasTree/nodes/PresetsListNode.ts\"\nimport { generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport { extractRichTextOverrideKeys } from \"document/models/CanvasTree/nodes/utils/extractRichTextOverrideKeys.ts\"\nimport { isStylePresetPrimaryNode } from \"document/models/CanvasTree/nodes/utils/isStylePresetNode.ts\"\nimport { isCodeComponentNode, isRichTextNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { WithFontVariants } from \"document/models/CanvasTree/traits/WithFontVariants.ts\"\nimport { withReplicaVariants } from \"document/models/CanvasTree/traits/WithReplicaVariants.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { getPrimaryVariantAncestor } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport {\n\tformInputFontSelectorKey,\n\twithFormInputFontStyles,\n} from \"document/models/CanvasTree/traits/forms/WithFormInputTextStyles.ts\"\nimport { prefixControlPropKey } from \"document/models/controlProps/controlPropKey.ts\"\nimport type { FontPreview, StylePresetFontPreview } from \"document/utils/FontPreviewTypes.ts\"\nimport { canPatchRichText } from \"prosemirror/patching.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst emptyMap: ReadonlyMap<NodeID, FontPreview> = new Map()\n\n/**\n * While hovering fonts in the font popout list, we preview the highlighted fonts under the mouse on\n * the selected nodes in the canvas. This store is the source of truth for which fonts are being\n * previewed on which nodes.\n */\nexport class FontPreviewStore extends EngineStore {\n\t/**\n\t * Only one font-family may be highlighted at a time, but that can still result in different\n\t * font variants being previewed on different nodes, depending on which font variant\n\t * (weight/style) is currently being used on each node, since we try to apply a variant matching\n\t * the previous weight and style. That is why each node has it's own font preview object, possibly\n\t * with different font variants.\n\t */\n\tfontPreviewByNodeId: ReadonlyMap<NodeID, FontPreview> = emptyMap\n\n\tconstructor(private readonly treeStore: TreeStore) {\n\t\tsuper()\n\t}\n\n\t/**\n\t * Enter font preview for Rich Text nodes, Code Components (font property control), Form input\n\t * elements (FormPlainTextInputNode, FormSelectNode, etc.)\n\t */\n\tenterPreview = (fontSelectorsByNodeId: ReadonlyMap<NodeID, string>, controlKey?: string) => {\n\t\tconst expanded = this.expandToReplicas(fontSelectorsByNodeId, controlKey)\n\t\tconst newFontPreviewByNodeId = new Map<NodeID, FontPreview>()\n\t\tfor (const [nodeId, fontSelector] of expanded) {\n\t\t\tconst fontPreview: FontPreview = controlKey\n\t\t\t\t? { type: \"property-control\", fontSelector, controlKey }\n\t\t\t\t: { type: \"rich-text\", fontSelector }\n\t\t\tnewFontPreviewByNodeId.set(nodeId, fontPreview)\n\t\t}\n\t\tthis.fontPreviewByNodeId = newFontPreviewByNodeId\n\t}\n\n\texitPreview = () => {\n\t\tthis.fontPreviewByNodeId = emptyMap\n\t}\n\n\t/** Enter font preview for Style Presets (Text, Blockquote, Inline Code, etc). */\n\tenterPreviewForStylePreset = (presetId: NodeID, fontSelector: string, variantSelectors?: WithFontVariants) => {\n\t\tconst preset = this.treeStore.tree.get(presetId)\n\t\tif (!preset || !isStylePresetPrimaryNode(preset)) return\n\n\t\tconst fontPreview: StylePresetFontPreview = { type: \"style-preset\", fontSelector, variantSelectors }\n\t\tconst newFontPreviewByNodeId = new Map<NodeID, FontPreview>()\n\n\t\tconst presetsListNode = PresetsListNode.get(this.treeStore.tree)\n\t\tassert(presetsListNode, \"Presets list node should exist\")\n\n\t\tfor (const presetNode of presetsListNode.children) {\n\t\t\t// Only preview the preset or its breakpoints\n\t\t\tif (presetId !== presetNode.getPrimaryId()) continue\n\t\t\tnewFontPreviewByNodeId.set(presetNode.id, fontPreview)\n\t\t\t// Set the node cache in the main app tree to preview the font while editing text. Other nodes\n\t\t\t// only get the cache set in canvas sandbox tree, because there we use the RichTextEditTool to\n\t\t\t// preview only the selected text, while here, style presets always apply to the entire node.\n\t\t\tpresetNode.cache.fontPreview = fontPreview\n\t\t}\n\n\t\tthis.fontPreviewByNodeId = newFontPreviewByNodeId\n\t}\n\n\texitPreviewForStylePreset = () => {\n\t\t// Clear all style preset nodes' cache\n\t\tconst presetsListNode = PresetsListNode.get(this.treeStore.tree)\n\t\tassert(presetsListNode, \"Presets list node should exist\")\n\t\tfor (const presetNode of presetsListNode.children) {\n\t\t\tpresetNode.cache.fontPreview = null\n\t\t}\n\t\tthis.fontPreviewByNodeId = emptyMap\n\t}\n\n\t/** Expand the preview to replicas of the selected nodes, where the font change would also apply. */\n\tprivate expandToReplicas(\n\t\tfontSelectorsByNodeId: ReadonlyMap<NodeID, string>,\n\t\tcontrolKey?: string,\n\t): ReadonlyMap<NodeID, string> {\n\t\tconst expanded = new Map<NodeID, string>(fontSelectorsByNodeId)\n\t\tfor (const [nodeId, fontSelector] of fontSelectorsByNodeId) {\n\t\t\tfor (const replicaChildId of this.getReplicaChildIdsToPreview(nodeId, controlKey)) {\n\t\t\t\texpanded.set(replicaChildId, fontSelector)\n\t\t\t}\n\t\t}\n\t\treturn expanded\n\t}\n\n\t/**\n\t * Gets the IDs of replica children corresponding to a node in a primary variant,\n\t * excluding those where the font change wouldn't be visible due to overrides.\n\t */\n\tprivate getReplicaChildIdsToPreview(nodeId: NodeID, controlKey?: string): NodeID[] {\n\t\tconst node = this.treeStore.tree.get(nodeId)\n\t\tif (!node) return []\n\n\t\tconst primaryVariant = getPrimaryVariantAncestor(node)\n\t\tif (!primaryVariant) return []\n\n\t\tconst tree = this.treeStore.tree\n\t\tconst scope = primaryVariant.parentid ? tree.get(primaryVariant.parentid) : null\n\t\tif (!scope || !withReplicaVariants(scope)) return []\n\n\t\tconst replicaChildIds: NodeID[] = []\n\n\t\tfor (const replicaVariant of scope.getReplicaVariants()) {\n\t\t\tconst replicaChildId = generateReplicaChildId(replicaVariant.id, node.id)\n\t\t\tconst replicaChild = tree.get(replicaChildId)\n\n\t\t\tassert(replicaChild, \"Replica child should exist\")\n\t\t\tassert(isReplicaOrReplicaChild(replicaChild), \"It should be a replica child\")\n\n\t\t\tif (isRichTextNode(node) && isRichTextNode(replicaChild)) {\n\t\t\t\t// If the font has been overridden in the replica, it won't be applied\n\t\t\t\tconst overrideKeys = extractRichTextOverrideKeys(tree, replicaChild)\n\t\t\t\tif (overrideKeys.includes(\"font\")) continue\n\n\t\t\t\t// If the replica has different node count/types/text, the font won't be applied\n\t\t\t\tconst [primaryState] = node.getEditorState(false)\n\t\t\t\tconst [replicaState] = replicaChild.getEditorState(false)\n\t\t\t\tif (!canPatchRichText(primaryState, replicaState)) continue\n\t\t\t} else if (isCodeComponentNode(node) && isCodeComponentNode(replicaChild)) {\n\t\t\t\t// Check if the control prop has been overridden in this replica\n\t\t\t\tassert(controlKey, \"Control key is required for code component nodes\")\n\t\t\t\tconst overrides = replicaVariant.replicaInfo.overrides[node.id]\n\t\t\t\tif (overrides && prefixControlPropKey(controlKey) in overrides) continue\n\t\t\t} else if (withFormInputFontStyles(node) && withFormInputFontStyles(replicaChild)) {\n\t\t\t\t// Check if the form input font has been overridden in this replica\n\t\t\t\tconst overrides = replicaVariant.replicaInfo.overrides[node.id]\n\t\t\t\tif (overrides && formInputFontSelectorKey in overrides) continue\n\t\t\t} else {\n\t\t\t\tcontinue // Unexpected node type, should never happen\n\t\t\t}\n\n\t\t\treplicaChildIds.push(replicaChildId)\n\t\t}\n\n\t\treturn replicaChildIds\n\t}\n}\n", "export class ChangeTracker<T> {\n\tcurrent: T\n\tdidChange = false\n\n\tconstructor(private getState: () => T) {\n\t\tthis.current = getState()\n\t}\n\n\tupdate() {\n\t\tconst updated = this.getState()\n\t\tthis.didChange = updated !== this.current\n\t\tthis.current = updated\n\t}\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport { withDOMLayout } from \"document/models/CanvasTree/traits/WithDOMLayout.ts\"\nimport { isPinnable } from \"document/models/CanvasTree/traits/WithPins.ts\"\nimport type { WithSize } from \"document/models/CanvasTree/traits/WithSize.ts\"\nimport type { IsBreakpoint, IsVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport {\n\tisBreakpointVariant,\n\tisSmartComponentVariant,\n\tisVariant,\n} from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { canNodeProvideViewportRect } from \"document/models/CanvasTree/traits/utils/viewportHelpers.ts\"\nimport { ChangeTracker } from \"document/preview/ChangeTracker.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { DimensionType } from \"library/index.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { PreviewStore } from \"./PreviewStore.ts\"\n\nexport interface ResizablePreviewSize {\n\twidth?: number\n\theight?: number\n}\n\nexport class FullsizePreviewStore extends EngineStore {\n\t#visibleTracker: ChangeTracker<boolean>\n\n\tconstructor(\n\t\tprivate chromeStore: ChromeStore,\n\t\tprivate previewStore: PreviewStore,\n\t) {\n\t\tsuper()\n\n\t\tthis.#visibleTracker = new ChangeTracker(() => this.chromeStore.mainView === ActiveMainView.Preview)\n\t}\n\n\tisPreviewUIVisible = true\n\ttogglePreviewUIVisible() {\n\t\tthis.isPreviewUIVisible = !this.isPreviewUIVisible\n\t}\n\n\tresizablePreviewSize?: ResizablePreviewSize\n\n\tpostProcess() {\n\t\tthis.#visibleTracker.update()\n\n\t\tconst previewNode = this.previewStore.previewNode\n\t\tif (this.#visibleTracker.didChange && this.#visibleTracker.current && previewNode) {\n\t\t\tthis.updatePreviewSize(previewNode)\n\t\t}\n\t}\n\n\tupdatePreviewWidthWithBreakpoint(breakpointNode: (CanvasNode & WithSize & IsVariant & IsBreakpoint) | null) {\n\t\tif (!breakpointNode) return\n\t\tthis.resizablePreviewSize = {\n\t\t\t...this.resizablePreviewSize,\n\t\t\twidth: breakpointNode.width,\n\t\t}\n\t}\n\n\tupdatePreviewSize(previewNode: CanvasNode) {\n\t\tconst { width: rectWidth, height: rectHeight } = previewNode.rect()\n\t\tif (withDOMLayout(previewNode) && previewNode.usesDOMRectCached() && !previewNode.getDOMRect()) {\n\t\t\t// Node is auto-sizing, but no auto-sizing data is available!\n\t\t\tif (isPinnable(previewNode)) {\n\t\t\t\t// Rect will be inaccurate on the auto-sizing dimensions, set\n\t\t\t\t// these to undefined.\n\t\t\t\tconst width = previewNode.widthType !== DimensionType.Auto ? rectWidth : undefined\n\t\t\t\tconst height = previewNode.heightType !== DimensionType.Auto ? rectHeight : undefined\n\t\t\t\tthis.resizablePreviewSize = { width, height }\n\t\t\t} else {\n\t\t\t\t// We have nothing to fall back to.\n\t\t\t\tthis.resizablePreviewSize = undefined\n\t\t\t}\n\t\t} else {\n\t\t\tthis.resizablePreviewSize = { width: rectWidth, height: rectHeight }\n\t\t}\n\n\t\t// When previewing a variant in isolation, if the viewport height is defined, use that as the initial preview height\n\t\tconst viewportHeight =\n\t\t\tcanNodeProvideViewportRect(previewNode) &&\n\t\t\tisSmartComponentVariant(previewNode) &&\n\t\t\tpreviewNode.viewportHeight !== undefined\n\t\t\t\t? previewNode.viewportHeight\n\t\t\t\t: undefined\n\n\t\tthis.resizablePreviewSize = {\n\t\t\twidth: this.resizablePreviewSize?.width,\n\t\t\theight: viewportHeight ?? this.resizablePreviewSize?.height,\n\t\t}\n\n\t\t// Don't attemp to fit the preview to the node size when previewing a Smart Component variant. We provide a\n\t\t// responsive canvas with a min width/height, making it easier to preview components with layout changes (such\n\t\t// as dropdowns) in isolation.\n\t\tif (isVariant(previewNode) && !isBreakpointVariant(previewNode)) {\n\t\t\tthis.resizablePreviewSize = { height: viewportHeight }\n\t\t}\n\t}\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\nimport type { GuideSelector } from \"document/models/CanvasTree/traits/WithGuides.ts\"\n\nexport class GuidesStore extends EngineStore {\n\tselected?: GuideSelector\n\thighlighted?: GuideSelector\n\tghost?: GuideSelector\n\n\tclearSelected() {\n\t\tthis.selected = undefined\n\t\tthis.ghost = undefined\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\n\nconst SECONDS = 1000\nexport const MINUTES = 60 * SECONDS\nconst HOURS = 60 * MINUTES\nexport const DAYS = 24 * HOURS\nexport const MONTHS = 30 * DAYS\n\nexport interface HistoryPanelParameters {\n\t/** Defines a series of durations used to consider when sets of changes should bundled together.\n\t * Typically: [10 * MINUTES, 1 * HOURS, 8 * HOURS] */\n\ttimeSpans: number[]\n\n\t/** When computing a timeline of changes, we use a longer duration time spans for older changes.\n\t * This parameter tunes when to use the next time span. Typically: [5 * HOURS, 25 * HOURS]\n\t *\n\t * Example: we use `timeSpan[0]` as long as the changes we are processing are younger than\n\t * `useTimeSpanIfBefore[0]`. */\n\tuseTimeSpanIfBefore: number[]\n\n\tlookForPauses?: boolean\n}\n\nexport const defaultParams: HistoryPanelParameters = {\n\ttimeSpans: [5 * MINUTES, 1 * HOURS, 4 * HOURS, 24 * HOURS],\n\tuseTimeSpanIfBefore: [4 * HOURS, 24 * HOURS, 48 * HOURS],\n}\n\nexport function verifyParams(params: HistoryPanelParameters) {\n\tassert(\n\t\tparams.timeSpans.length === params.useTimeSpanIfBefore.length + 1,\n\t\t\"params.useTimeSpanIfBefore should have params.spans.length - 1 entries\",\n\t)\n\tfor (let i = 0; i < params.timeSpans.length - 1; i++) {\n\t\tassert(params.timeSpans[i]! < params.timeSpans[i + 1]!, \"params.spans should be increasing durations\")\n\t}\n\tfor (let i = 0; i < params.useTimeSpanIfBefore.length - 1; i++) {\n\t\tassert(\n\t\t\tparams.useTimeSpanIfBefore[i]! < params.useTimeSpanIfBefore[i + 1]!,\n\t\t\t\"params.useTimeSpanIfBefore should be increasing durations\",\n\t\t)\n\t}\n}\n\nexport type Authors = Record<string, number>\n\nexport interface Period {\n\tstartTreeVersion: number\n\tstartTime: number\n\t/** The total number of tree changes. */\n\ttreeChanges: number\n\t/** A map of author ids to number of edits. */\n\tauthors: Authors\n\t/** The document mode when this period was created. */\n\tmode?: \"json\" | \"crdt\"\n}\n\nexport interface Activity {\n\ttreeVersion: number\n\ttime: number\n\tauthors: Authors\n\t/** The document mode when this activity was created. */\n\tmode?: \"json\" | \"crdt\"\n}\n\n// ** getClustersFromPauses **\n\nfunction spanLengthForAge(params: HistoryPanelParameters, age: number) {\n\tconst timeSpans = params.timeSpans\n\tconst useTimeSpanIfBefore = params.useTimeSpanIfBefore\n\tfor (let i = 0; i < useTimeSpanIfBefore.length; i++) {\n\t\tif (age < useTimeSpanIfBefore[i]!) {\n\t\t\treturn timeSpans[i]!\n\t\t}\n\t}\n\treturn timeSpans[timeSpans.length - 1]!\n}\n\nfunction findFirstLikelyEndIndex(periods: Period[], spanLength: number, beginIndex: number, beginTime: number): number {\n\t// skip any periods we want to include\n\tlet firstLikelySpanEndIndex = beginIndex\n\tfor (let i = 0; i < 10000; i++) {\n\t\tif (firstLikelySpanEndIndex <= 0) break\n\t\tconst maybeSpanEnd = periods[firstLikelySpanEndIndex - 1]!\n\t\tif (beginTime - maybeSpanEnd.startTime > spanLength * 0.5) break\n\t\tfirstLikelySpanEndIndex -= 1\n\t}\n\treturn firstLikelySpanEndIndex\n}\n\nfunction findLongestPause(periods: Period[], spanLength: number, beginTime: number, start: number): number {\n\t// go over all periods we are willing to include, finding the largest pause\n\tlet lastLikelySpanEndIndex = start\n\tlet idleSpan = 0\n\tlet longestIdleSpanIndex = start\n\tfor (let i = 0; i < 10000; i++) {\n\t\tif (lastLikelySpanEndIndex <= 0) break\n\t\tconst maybeSpanEnd = periods[lastLikelySpanEndIndex - 1]!\n\t\tif (beginTime - maybeSpanEnd.startTime > spanLength * 1.5) break\n\n\t\tconst delta = periods[lastLikelySpanEndIndex]!.startTime - maybeSpanEnd.startTime\n\t\tif (delta > idleSpan) {\n\t\t\tidleSpan = delta\n\t\t\tlongestIdleSpanIndex = lastLikelySpanEndIndex\n\t\t}\n\t\tlastLikelySpanEndIndex -= 1\n\t}\n\n\treturn longestIdleSpanIndex\n}\n\nfunction authorsForPeriods(periods: Period[], begin: Period, beginIndex: number, endIndex: number): Authors {\n\tconst authors = { ...begin.authors }\n\tfor (let i = endIndex; i < beginIndex; i++) {\n\t\tconst current = periods[i]\n\t\tassert(current, \"current should be defined\")\n\t\tfor (const author in current.authors) {\n\t\t\tauthors[author] = current.authors[author]! + (authors[author] ?? 0)\n\t\t}\n\t}\n\treturn authors\n}\n\nexport function getClustersFromInactivity(\n\tparams: HistoryPanelParameters,\n\tstartTime: number,\n\ttimeLimit: number,\n\tperiods: Period[],\n): Activity[] {\n\tverifyParams(params)\n\tif (periods.length === 0) return []\n\n\tconst clusters: Activity[] = []\n\tlet beginIndex = periods.length - 1\n\twhile (beginIndex >= 0) {\n\t\tconst begin = periods[beginIndex]!\n\t\tconst beginTime = begin.startTime\n\n\t\t// Don't show entries that are too old.\n\t\tif (beginTime < timeLimit) break\n\n\t\tconst age = startTime - beginTime\n\t\tconst spanLength = spanLengthForAge(params, age)\n\t\tconst firstLikelyEndIndex = findFirstLikelyEndIndex(periods, spanLength, beginIndex, beginTime)\n\t\tconst endIndex = findLongestPause(periods, spanLength, beginTime, firstLikelyEndIndex)\n\n\t\t// use the period just before the largest pause\n\t\tconst treeVersion = begin.startTreeVersion + begin.treeChanges\n\t\tconst authors = authorsForPeriods(periods, begin, beginIndex, endIndex)\n\t\tclusters.push({ time: beginTime, treeVersion, authors, mode: begin.mode })\n\n\t\t// we move backwards in time ...\n\t\tbeginIndex = endIndex - 1\n\t}\n\n\treturn clusters\n}\n\n// ** processTreeUpdates **\n\ninterface Diff {\n\tuserId?: string\n\tts?: number\n\tnext: number\n}\n\nconst timesToIgnore = Date.now() / 1000\nfunction timestampFromChange(change: Diff, timestamp?: string) {\n\tif (change.ts && change.ts > timesToIgnore) return change.ts\n\tif (!timestamp) return 0\n\tconst ts = new Date(timestamp).getTime()\n\tif (ts < timesToIgnore) return 0\n\treturn ts\n}\n\nfunction createPeriod(startTree: number, startTime: number, mode?: \"json\" | \"crdt\"): Period {\n\treturn { startTreeVersion: startTree, startTime, treeChanges: 0, authors: {}, mode }\n}\n\n/** Processes tree update files from the server, adding to the passed in periods array. */\nexport function processTreeUpdates(diff: Diff[], fallbackStartTime?: string, mode?: \"json\" | \"crdt\"): Period[] {\n\tconst MIN_SPAN = 1 * MINUTES\n\n\tlet currentPeriod: Period | undefined\n\tlet startTime = 0\n\n\tconst periods: Period[] = []\n\n\tfor (const change of diff) {\n\t\tstartTime = timestampFromChange(change, fallbackStartTime)\n\t\tif (startTime === 0) continue\n\n\t\tif (!currentPeriod) {\n\t\t\tcurrentPeriod = createPeriod(change.next, startTime, mode)\n\t\t} else if (startTime - currentPeriod.startTime > MIN_SPAN) {\n\t\t\tperiods.push(currentPeriod)\n\t\t\tcurrentPeriod = createPeriod(change.next, startTime, mode)\n\t\t}\n\n\t\tif (currentPeriod) {\n\t\t\tcurrentPeriod.treeChanges += 1\n\n\t\t\tconst author = change.userId\n\t\t\tif (author && author.length > 0) {\n\t\t\t\tcurrentPeriod.authors[author] = 1 + (currentPeriod.authors[author] ?? 0)\n\t\t\t}\n\t\t}\n\t}\n\n\tif (currentPeriod) {\n\t\tperiods.push(currentPeriod)\n\t}\n\treturn periods\n}\n", "import { type SerializableRow, Table, migrateFormat, migrateSerializableRows } from \"@framerjs/crdtree2\"\nimport { assert, getLogger } from \"@framerjs/shared\"\nimport type { NodeChange } from \"document/models/CanvasTree/TreeDiff.ts\"\nimport type { CrdtUpdate } from \"document/models/CanvasTree/treeSyncUtils.ts\"\nimport { fetchWithRetry } from \"utils/fetch.ts\"\nimport { xRequestedByHeader } from \"web/lib/xRequestedByHeader.ts\"\nimport type { Authors } from \"./dataProcessing.ts\"\n\nexport type ServerHistorySummary = [time: number, treeVersion: number, authors: Authors]\n\nconst log = getLogger(\"history\")\n\n/** The metadata a history entry might have. */\ninterface HistoryEntryMetaData {\n\tfromVersion?: number\n\ttoVersion?: number\n\tupdatesFile?: string\n\tsnapshotFile?: string\n\tmode?: \"json\" | \"crdt\"\n\thistory?: ServerHistorySummary[]\n}\n\n/** A single entry that describes a stored tree, usually due to a snapshot, but might have been a\n * migration or rollback or other things. */\nexport interface HistoryEntry {\n\tid: string\n\ttimestamp: string\n\toperation: \"snapshot\" | unknown\n\n\ttreeId: string\n\tschema: number\n\tversion: number\n\tmetadata: HistoryEntryMetaData\n}\n\n/** The server history API returns this. */\nexport interface HistoryData {\n\tdata: HistoryEntry[]\n}\n\n/** The overall shape of a treeUpdate file we fetch from the server. */\nexport interface Diffs {\n\tts: number\n\tnext: number\n\tsession: number\n\tuserId: string\n\tchanges: NodeChange[]\n}\n\nexport async function getEntriesForVersion(\n\tserverHistoryURL: string,\n\tfromVersion: number,\n\ttoVersion = fromVersion,\n): Promise<HistoryEntry[]> {\n\tassert(fromVersion >= 1, \"cannot load treeVersion < 1\")\n\tassert(toVersion >= fromVersion, \"toVersion must be >= fromVersion\")\n\tconst json: HistoryData = await fetchJSON(`${serverHistoryURL}?from=${fromVersion}&to=${toVersion}`)\n\tassert(Array.isArray(json.data), \"unexpected history data\")\n\tlog.debug(\"loadTest:\", json.data.length, \"latest entry:\", json.data[0])\n\tassert(json.data.length > 0, \"no history found\")\n\n\treturn json.data\n}\n\nexport function findSnapshotAndUpdates(\n\ttreeVersion: number,\n\thistoryEntries: HistoryEntry[],\n\tfallbackToOldestEntry = false,\n) {\n\t// Find either the actual snapshot entry, or a snapshot + updates.\n\tlet snapshotEntry: HistoryEntry | undefined\n\tlet entryWithUpdates: HistoryEntry | undefined\n\tfor (const entry of historyEntries) {\n\t\tif (entry.version === treeVersion) {\n\t\t\tsnapshotEntry = entry\n\t\t\tbreak\n\t\t}\n\t\tconst { fromVersion, toVersion } = entry.metadata\n\n\t\tif (fromVersion && toVersion && treeVersion > fromVersion && treeVersion < toVersion) {\n\t\t\tentryWithUpdates = entry\n\t\t}\n\n\t\t// If we find an entry with updates, the entry we check after that\n\t\t// has to have smaller version because published history entries\n\t\t// are sorted from most recent to older. If nothing is found at this point,\n\t\t// we should throw error.\n\t\tif (entryWithUpdates && entryWithUpdates.version > entry.version) {\n\t\t\tsnapshotEntry = entry\n\t\t\tbreak\n\t\t}\n\n\t\tif (fallbackToOldestEntry) {\n\t\t\tsnapshotEntry = entry\n\t\t}\n\t}\n\tassert(snapshotEntry, \"unable to find a snapshot to start from\")\n\n\tlet update: { entry: HistoryEntry; delta: number } | undefined\n\n\tif (entryWithUpdates) {\n\t\tassert(entryWithUpdates.metadata.fromVersion)\n\t\tconst delta = treeVersion - entryWithUpdates.metadata.fromVersion\n\n\t\tif (delta > 0) {\n\t\t\tupdate = { entry: entryWithUpdates, delta }\n\t\t} else {\n\t\t\tassert(snapshotEntry.version === treeVersion, \"snapshotEntry.version !== version\")\n\t\t}\n\t}\n\n\treturn { snapshotEntry, update }\n}\n\nexport async function loadCrdtData(\n\tsnapshot: HistoryEntry,\n\tupdate: { entry: HistoryEntry; delta: number } | undefined,\n\tfetchDiffs: (url: string) => Promise<unknown> = fetchJSON,\n) {\n\tassert(snapshot.metadata.snapshotFile)\n\tconst response = await fetch(snapshot.metadata.snapshotFile).then(r => r.arrayBuffer())\n\tlet diffs: CrdtUpdate[] = []\n\tif (update) {\n\t\tdiffs = await downloadDiffsFor<CrdtUpdate>(update.entry, fetchDiffs)\n\t\tdiffs = diffs.slice(0, update.delta)\n\t}\n\n\tconst buffer = new Uint8Array(response)\n\tconst result = migrateFormat(buffer)\n\tconst table = Table.fromBuffer(result.migrated ? result.buffer : buffer)\n\tconst branch = table.main\n\n\tconst rows: SerializableRow[] = []\n\tfor (const diff of diffs) {\n\t\trows.push(...diff.rows)\n\t}\n\n\tif (result.migrated) {\n\t\t// If snapshot is migrated, updates file might also need\n\t\t// migration. This can happen if the version user wants to load\n\t\t// is >= 2 format versions behind.\n\t\tconst migratedRows = migrateSerializableRows(rows, result.from)\n\t\tbranch.addRows(migratedRows)\n\t} else {\n\t\t// If nothing is migrated, we just load the snapshot and add the rows\n\t\tbranch.addSerializableRows(rows)\n\t}\n\n\treturn table.toBuffer()\n}\n\nexport async function downloadDiffsFor<T = Diffs>(\n\tentry: HistoryEntry,\n\tfetch: (url: string) => Promise<unknown> = fetchJSON,\n): Promise<T[]> {\n\tassert(entry.metadata.updatesFile, \"no updates file defined\")\n\tconst diffs = await fetch(entry.metadata.updatesFile)\n\tassert(Array.isArray(diffs), \"unexpected diff data\")\n\treturn diffs\n}\n\nexport async function fetchJSON(url: string): Promise<HistoryData> {\n\tconst response = await fetchWithRetry(url, {\n\t\tmethod: \"GET\",\n\t\tcredentials: \"include\",\n\t\theaders: xRequestedByHeader,\n\t})\n\tif (!response.ok) throw Error(\"failed: \" + response)\n\treturn response.json()\n}\n", "import { createVekterCrdtStore } from \"@framerjs/crdtree2\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, getLogger } from \"@framerjs/shared\"\nimport type { RemoteDocumentHandler } from \"document/RemoteDocumentHandler.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport { getCrdtSession } from \"document/crdt/CrdtSession.ts\"\nimport { CrdtDocumentLoader } from \"document/crdt/sync/index.ts\"\nimport { DocumentLoader, type DocumentLoaderSettings } from \"document/loader/DocumentLoader.ts\"\nimport { jsonApplyChanges } from \"document/models/CanvasTree/TreeDiff.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { CodeGenerationStore } from \"document/stores/CodeGenerationStore.ts\"\nimport type { DocumentSettingsStore } from \"document/stores/DocumentSettingsStore.ts\"\nimport type { HistoryStore } from \"document/stores/HistoryStore.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport type { ProjectStore } from \"document/stores/ProjectStore.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { Period } from \"./dataProcessing.ts\"\nimport { DAYS, MINUTES, processTreeUpdates } from \"./dataProcessing.ts\"\nimport {\n\ttype Diffs,\n\ttype HistoryData,\n\ttype HistoryEntry,\n\ttype ServerHistorySummary,\n\tdownloadDiffsFor,\n\tfetchJSON,\n\tfindSnapshotAndUpdates,\n\tgetEntriesForVersion,\n\tloadCrdtData,\n} from \"./utils.ts\"\n\ntype ProgressCallback = (controller: ServerHistoryController, data: Period[], more: boolean) => void\n\nconst log = getLogger(\"history\")\n\nfunction periodFromSummary(entry: HistoryEntry, history: ServerHistorySummary[]): Period[] {\n\tif (history.length === 0) return []\n\n\tconst mode = entry.metadata.mode\n\tconst periods = history.map(([startTime, startTreeVersion, authors]) => ({\n\t\tstartTime,\n\t\tstartTreeVersion,\n\t\tauthors,\n\t\ttreeChanges: -1,\n\t\tmode,\n\t}))\n\n\t// Compute and add the period.treeChanges which is not stored in the server summary.\n\tlet nextPeriodStartTreeVersion = entry.metadata.toVersion ?? periods[periods.length - 1]!.startTreeVersion + 1\n\tfor (let i = periods.length - 1; i >= 0; i--) {\n\t\tconst period = periods[i]!\n\t\tperiod.treeChanges = nextPeriodStartTreeVersion - period.startTreeVersion\n\t\tnextPeriodStartTreeVersion = period.startTreeVersion\n\t}\n\n\treturn periods\n}\n\nconst IGNORE_BEFORE_TIME = new Date(\"2022-12-13 13:00:00 UTC\").getTime()\nconst DIFF_DOWNLOAD_LIMIT = 10\n\n/** Can fetch data from the server history api, cache the results, and load documents at any tree version. */\nexport class ServerHistoryController {\n\tprivate readonly projectId: string\n\n\tprivate versionsLoaded = new Set<number>()\n\n\t/** Always sorted oldest to newest. But notice the server API returns newest to oldest. */\n\tprivate historyEntries: HistoryEntry[] = []\n\tprivate periods: Period[] = []\n\n\t/** For historic versions from before the server created the summary data, we limit how many\n\t * diffs we download. */\n\tprivate diffsDownloaded = 0\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly documentSettings: DocumentSettingsStore,\n\t\tprivate readonly codeGenerationStore: CodeGenerationStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly historyStore: HistoryStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly remoteDocument: RemoteDocumentHandler,\n\t\tprivate readonly load: VekterEngine[\"load\"],\n\t\tprivate readonly newTreeAfterRemoteUpdate: VekterEngine[\"newTreeAfterRemoteUpdate\"],\n\t\tprivate readonly runBeforeNextFrame: VekterEngineScheduler[\"runBeforeNextFrame\"],\n\t\tprivate readonly runWhenIdle: VekterEngineScheduler[\"runWhenIdle\"],\n\t) {\n\t\tthis.projectId = remoteDocument.projectId\n\t}\n\n\tasync loadRecentEntries(): Promise<HistoryEntry[]> {\n\t\tconst json: HistoryData = await fetchJSON(`${this.treeStore.serverHistoryURL}?count=200`)\n\n\t\tassert(Array.isArray(json.data), \"unexpected history data\")\n\t\tlog.debug(\"loadRecentEntries:\", json.data.length, \"latest entry:\", json.data[0])\n\t\treturn json.data\n\t}\n\n\tasync loadMoreEntries(treeVersion: number): Promise<HistoryEntry[]> {\n\t\tassert(treeVersion >= 1, \"cannot load treeVersion < 1\")\n\t\tconst from = Math.max(1, treeVersion - 200)\n\t\tconst json: HistoryData = await fetchJSON(`${this.treeStore.serverHistoryURL}?from=${from}&to=${treeVersion}`)\n\t\tassert(Array.isArray(json.data), \"unexpected history data\")\n\t\tlog.debug(\"loadMoreEntries:\", json.data.length, \"latest entry:\", json.data[0])\n\t\treturn json.data\n\t}\n\n\tprivate isCrdtEntry(entry: HistoryEntry) {\n\t\treturn entry.metadata.snapshotFile?.endsWith(\".crdt\")\n\t}\n\n\tprivate async createTreeFromCrdt(snapshot: HistoryEntry, update?: { entry: HistoryEntry; delta: number }) {\n\t\tconst loadedData = await loadCrdtData(snapshot, update, url => this.fetchJSONCached(url))\n\t\treturn this.downloadTreeFor(snapshot, loadedData)\n\t}\n\n\tprivate async createEntryFromJson(snapshot: HistoryEntry, update?: { entry: HistoryEntry; delta: number }) {\n\t\tif (update) {\n\t\t\tlet tree = await this.downloadTreeFor(snapshot)\n\t\t\tconst diffs = await downloadDiffsFor(update.entry, url => this.fetchJSONCached(url))\n\t\t\tfor (let i = 0; i < update.delta; i++) {\n\t\t\t\tconst diff = diffs[i]\n\t\t\t\tif (diff) jsonApplyChanges(tree, diff.changes)\n\t\t\t}\n\t\t\ttree = tree.commit(this.componentLoader)\n\n\t\t\treturn tree\n\t\t}\n\t\treturn this.downloadTreeFor(snapshot)\n\t}\n\n\tprivate async createTreeFromEntries(\n\t\ttreeVersion: number,\n\t\thistoryEntries: HistoryEntry[],\n\t\tfallbackToOldestEntry?: boolean,\n\t) {\n\t\tconst { snapshotEntry, update } = findSnapshotAndUpdates(treeVersion, historyEntries, fallbackToOldestEntry)\n\n\t\tif (this.isCrdtEntry(snapshotEntry)) {\n\t\t\treturn this.createTreeFromCrdt(snapshotEntry, update)\n\t\t} else {\n\t\t\treturn this.createEntryFromJson(snapshotEntry, update)\n\t\t}\n\t}\n\n\tasync loadDocumentAtPublishedVersion(treeVersion: number): Promise<CanvasTree> {\n\t\treturn this.runAfterFrame(async () => {\n\t\t\tconst historyEntries = await getEntriesForVersion(this.treeStore.serverHistoryURL, treeVersion)\n\t\t\treturn this.createTreeFromEntries(treeVersion, historyEntries)\n\t\t})\n\t}\n\n\tasync resolveSnapshotVersion(treeVersion: number): Promise<number> {\n\t\tconst historyEntries = await getEntriesForVersion(this.treeStore.serverHistoryURL, treeVersion)\n\t\tconst { snapshotEntry } = findSnapshotAndUpdates(treeVersion, historyEntries)\n\t\treturn snapshotEntry.version\n\t}\n\n\tprivate moreRecentEntries: { entries: HistoryEntry[]; loadedAt: number } | undefined\n\n\t// Return and clear the recently polled entries, if any.\n\tprivate getAndClearRecentlyLoadedEntries(): HistoryEntry[] | undefined {\n\t\tif (!this.moreRecentEntries) return\n\t\tconst { entries, loadedAt } = this.moreRecentEntries\n\t\tthis.moreRecentEntries = undefined\n\t\tif (performance.now() - loadedAt > 1 * MINUTES) return\n\t\treturn entries\n\t}\n\n\tasync pollServerForMoreHistory(): Promise<boolean> {\n\t\tconst entries = await this.loadRecentEntries()\n\t\tif (!entries || entries.length === 0) return false\n\n\t\tconst newest = this.historyEntries[this.historyEntries.length - 1]\n\t\tconst noNewEntries = entries[0]!.version === newest?.version\n\t\tlog.info(\"pollServerForMoreHistory:\", noNewEntries ? \"no change\" : \"found new entries\")\n\t\tif (noNewEntries) return false\n\n\t\tthis.moreRecentEntries = { entries, loadedAt: performance.now() }\n\t\treturn true\n\t}\n\n\tprivate getVersionHistoryLimitMs() {\n\t\tconst licenseLimit = (this.projectStore.resourceLimits?.versionHistoryInDays ?? 3) * DAYS\n\t\tconst historyLimit = Date.now() - this.historyStore.clusteredTimelineDataOldestTimestamp\n\t\treturn Math.min(licenseLimit, historyLimit)\n\t}\n\n\t/** Will load the most recent entries and upto 1 month. Calling this again after a while will\n\t * load the most recent entries again incase new versions appeared on the server. */\n\tasync loadHistory(progress: ProgressCallback) {\n\t\tconst reportProgress = (more: boolean) => {\n\t\t\t// The history entries and periods should be mostly sorted. But, while normally we\n\t\t\t// download them in reverse chronological order, sometimes we are filling in newer data.\n\t\t\t// By just doing simple list operations while loading and processing, and sorting just\n\t\t\t// before giving control back, we keep these lists sorted for little cpu and developer\n\t\t\t// effort.\n\t\t\tthis.historyEntries.sort((a, b) => a.version - b.version)\n\t\t\tthis.periods.sort((a, b) => a.startTreeVersion - b.startTreeVersion)\n\t\t\tprogress(this, this.periods, more)\n\t\t}\n\n\t\ttry {\n\t\t\tif (!this.projectId) throw Error(\"failed: no project id\")\n\n\t\t\t// A safe while(true) loop. The loop body itself will return when one of the many\n\t\t\t// stopping conditions have been met.\n\t\t\tfor (let i = 0; i < 1000; i++) {\n\t\t\t\tconst newest: HistoryEntry | undefined = this.historyEntries[this.historyEntries.length - 1]\n\t\t\t\tconst oldest: HistoryEntry | undefined = this.historyEntries[0]\n\n\t\t\t\tassert(\n\t\t\t\t\t!oldest || !newest || oldest === newest || newest.version > oldest.version,\n\t\t\t\t\t\"history entries aren't sorted correctly\",\n\t\t\t\t)\n\n\t\t\t\tconst recentEntries = this.getAndClearRecentlyLoadedEntries()\n\t\t\t\tif (recentEntries) {\n\t\t\t\t\tlog.debug(\"loadHistory using recently loaded newer entries\")\n\t\t\t\t\tawait this.processHistoryEntries(recentEntries, reportProgress)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif (!newest || !oldest) {\n\t\t\t\t\tlog.debug(\"loadHistory going to download recent entries\")\n\t\t\t\t\tconst entries = await this.loadRecentEntries()\n\t\t\t\t\tif (!entries || entries.length === 0) {\n\t\t\t\t\t\tlog.debug(\"loadHistory stopping because loadRecentEntries returned no results\")\n\t\t\t\t\t}\n\t\t\t\t\tawait this.processHistoryEntries(entries, reportProgress)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tconst newestTime = new Date(newest.timestamp).getTime()\n\t\t\t\tconst oldestTime = new Date(oldest.timestamp).getTime()\n\t\t\t\tconst versionHistoryLimit = this.getVersionHistoryLimitMs()\n\t\t\t\tif (newestTime - oldestTime > versionHistoryLimit) {\n\t\t\t\t\tlog.debug(`loadHistory stopping because we have more than ${versionHistoryLimit / DAYS} days of data`)\n\t\t\t\t\treturn reportProgress(false)\n\t\t\t\t}\n\n\t\t\t\tif (oldest.version <= 1) {\n\t\t\t\t\tlog.debug(\"loadHistory stopping because we have first entry\")\n\t\t\t\t\treturn reportProgress(false)\n\t\t\t\t}\n\n\t\t\t\tif (oldestTime < IGNORE_BEFORE_TIME) {\n\t\t\t\t\tlog.debug(\"loadHistory stopping because we reached the before limit\")\n\t\t\t\t\treturn reportProgress(false)\n\t\t\t\t}\n\n\t\t\t\t// We start with recent entries, then request more entries lower in version and thus\n\t\t\t\t// back in time.\n\t\t\t\tconst entries = await this.loadMoreEntries(oldest.version - 1)\n\n\t\t\t\tconst periodsLengthBeforeProcessing = this.periods.length\n\t\t\t\tawait this.processHistoryEntries(entries, reportProgress)\n\t\t\t\tif (this.periods.length === periodsLengthBeforeProcessing) {\n\t\t\t\t\tlog.debug(\"loadHistory stopping because processing data didn't generate anything new\")\n\t\t\t\t\treturn reportProgress(false)\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(false, \"too many rounds of loadHistory\")\n\t\t} catch (e) {\n\t\t\tlog.reportErrorOncePerMinute(e, { context: \"loadHistory failed with error\" })\n\t\t\treturn reportProgress(false)\n\t\t}\n\t}\n\n\tasync processHistoryEntries(entries: HistoryEntry[], progress: (more: boolean) => void) {\n\t\tif (entries.length === 0) return\n\t\tassert(entries[0], \"unexpected empty entry\")\n\t\tassert(entries[0].version >= entries[entries.length - 1]!.version, \"loaded history entries aren't sorted correctly\")\n\n\t\tlet newestEntry = entries[0]\n\t\tconst firstHistoryEntry = this.historyEntries[0]\n\t\tif (firstHistoryEntry && firstHistoryEntry.version > newestEntry.version) {\n\t\t\tnewestEntry = firstHistoryEntry\n\t\t}\n\t\tconst versionHistoryInDays = this.projectStore?.resourceLimits?.versionHistoryInDays ?? 0\n\t\tlet oldestEntryToLoadTime = new Date(newestEntry.timestamp).getTime() - versionHistoryInDays * DAYS\n\t\tif (oldestEntryToLoadTime < IGNORE_BEFORE_TIME) {\n\t\t\toldestEntryToLoadTime = IGNORE_BEFORE_TIME\n\t\t}\n\n\t\tlet didCallProgress = false\n\n\t\t// Notice entries coming from the backend and are reverse ordered (newest to oldest).\n\t\tfor (let i = 0; i < entries.length; i++) {\n\t\t\tconst entry = entries[i]!\n\t\t\tconst entryTimestamp = new Date(entry.timestamp).getTime()\n\n\t\t\t// We might download somewhat overlapping ranges so we ignore extra entries.\n\t\t\tif (this.versionsLoaded.has(entry.version)) continue\n\n\t\t\t// Keep this history entry.\n\t\t\tthis.versionsLoaded.add(entry.version)\n\t\t\tthis.historyEntries.unshift(entry)\n\n\t\t\t// Skip entries that don't have an associated updates file (eg igrations, forced updates).\n\t\t\tif (!entry.metadata.updatesFile) {\n\t\t\t\tdidCallProgress = false\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Use the server side history summary data if available.\n\t\t\tconst history = entry.metadata.history\n\t\t\tif (history) {\n\t\t\t\tfor (const period of periodFromSummary(entry, history).reverse()) {\n\t\t\t\t\t// By doing reverse and unshift, the periods list stays ordered oldest to newest.\n\t\t\t\t\tthis.periods.unshift(period)\n\t\t\t\t}\n\t\t\t\tdidCallProgress = false\n\t\t\t\tif (entryTimestamp < oldestEntryToLoadTime) {\n\t\t\t\t\tlog.debug(\"stopping processing, reached older entries:\", entry.timestamp)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise we need to download and create summary data ourselves, but we will only do\n\t\t\t// that for a limited amount of diffs.\n\t\t\tif (this.diffsDownloaded >= DIFF_DOWNLOAD_LIMIT) {\n\t\t\t\tlog.debug(\"stopping processing, reached diff download limit:\", this.diffsDownloaded)\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// We keep upto 10 diffs preloaded via the cache, speeds up the history panel\n\t\t\t// considerably.\n\t\t\tfor (let p = 0; p < 10; p++) {\n\t\t\t\tconst entryToCache = this.historyEntries[i + p]\n\t\t\t\tif (!entryToCache) continue\n\t\t\t\tif (!entryToCache.metadata.updatesFile) continue\n\t\t\t\tif (entryToCache.metadata.history) continue\n\t\t\t\tthis.preloadDiffsFor(entryToCache)\n\t\t\t}\n\n\t\t\t// Actually download and process a diff.\n\t\t\tthis.diffsDownloaded += 1\n\t\t\tconst diff = await downloadDiffsFor<Diffs>(entry, url => this.fetchJSONCached(url))\n\t\t\tfor (const period of processTreeUpdates(diff, entry.timestamp, entry.metadata.mode).reverse()) {\n\t\t\t\t// By doing reverse and unshift, the periods list stays ordered oldest to newest.\n\t\t\t\tthis.periods.unshift(period)\n\t\t\t}\n\t\t\tprogress(true)\n\t\t\tdidCallProgress = true\n\t\t\tif (entryTimestamp < oldestEntryToLoadTime) {\n\t\t\t\tlog.debug(\"stopping processing, reached older entries:\", entry.timestamp)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif (didCallProgress) return\n\t\tprogress(true)\n\t}\n\n\trestoreLatestDocument() {\n\t\tif (!this.remoteDocument) return\n\t\tthis.resetLoader()\n\t\tlog.debug(\"restore to latest document\")\n\t\tthis.remoteDocument.makeReadWrite()\n\n\t\ttoast({\n\t\t\ttype: \"remove\",\n\t\t\tkey: \"disconnected-by-history-controller\",\n\t\t})\n\t}\n\n\tasync loadDocumentAtVersion(version: number): Promise<CanvasTree> {\n\t\t// Kick off re-generating screens or design components of the current scope.\n\t\tif (this.historyStore.activeTreeVersion === \"latest\") {\n\t\t\tthis.codeGenerationStore.changeScope()\n\t\t}\n\n\t\t// We postpone the heavy work after the event handler and after the engine has rendered.\n\t\treturn this.runAfterFrame(async () => {\n\t\t\tif (this.historyEntries.length === 0) {\n\t\t\t\t// If the timeline data was cached, we might still need to download the history entries\n\t\t\t\t// before we can load older documents.\n\t\t\t\tthis.historyEntries = await this.loadRecentEntries()\n\t\t\t}\n\t\t\treturn this.createTreeFromEntries(version, this.historyEntries, true)\n\t\t})\n\t}\n\n\tasync loadTreeAtVersion(version: number, tree: CanvasTree, onSwitchToViewOnly?: () => void): Promise<void> {\n\t\t// First wait for any modules to save before we go read only.\n\t\tawait this.modulesStore.waitForModulesToSave()\n\n\t\treturn new Promise<void>(resolve =>\n\t\t\tsetTimeout(() => {\n\t\t\t\t// Here we compute how far the loaded version is behind the actual version, but we don't\n\t\t\t\t// know the server tree version, only the latest version in the history entries.\n\t\t\t\tconst newestTreeVersion = this.historyEntries[this.historyEntries.length - 1]?.version ?? version\n\t\t\t\trecord(\"historic_document_opened\", { treeVersion: version, behind: newestTreeVersion - version })\n\n\t\t\t\t// Detach from the server, so we won't be sending any diffs around.\n\t\t\t\tthis.remoteDocument.makeReadOnly()\n\t\t\t\tonSwitchToViewOnly?.()\n\n\t\t\t\tassert(tree.getService(\"loader\"), \"tree must have a loader\")\n\t\t\t\t// Actually have the engine load the tree.\n\t\t\t\tthis.load(tree)\n\t\t\t\tthis.treeStore.timeline.reset(tree, { isLoading: true })\n\t\t\t\tresolve()\n\t\t\t}),\n\t\t)\n\t}\n\n\tasync runAfterFrame<T = void>(cb: () => Promise<T>): Promise<T> {\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tthis.runBeforeNextFrame(async () => {\n\t\t\t\tawait new Promise(resolve => requestAnimationFrame(resolve))\n\t\t\t\ttry {\n\t\t\t\t\tresolve(await cb())\n\t\t\t\t} catch (e) {\n\t\t\t\t\treject(e)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\tloader?: DocumentLoader\n\n\tresetLoader() {\n\t\tif (!this.loader) return\n\t\tthis.loader.removeAllListeners(\"loadedFirstData\")\n\t\tthis.loader.removeAllListeners(\"loadedScope\")\n\t\tthis.loader.removeAllListeners(\"error\")\n\t\tthis.loader = undefined\n\t}\n\n\tcreateLoaderFromUrl(snapshotUrl: string, loadedData: Uint8Array | string | undefined) {\n\t\tconst settings: DocumentLoaderSettings = {\n\t\t\tpartialParsing: true,\n\t\t\tactiveNodeId: this.historyStore.activeScopeIdToPreserveOnLoad || this.documentSettings.activeNode?.id,\n\t\t\trequestIdleCallback: this.runWhenIdle,\n\t\t\tasyncEventWrapper: this.remoteDocument.processBetweenFramesAsync,\n\t\t\tloadedData,\n\t\t}\n\n\t\ttry {\n\t\t\tconst url = new URL(snapshotUrl, window.location.origin)\n\n\t\t\tif (url.pathname.endsWith(\".crdt\")) {\n\t\t\t\tconst store = createVekterCrdtStore(\"\", getCrdtSession().client)\n\t\t\t\treturn new CrdtDocumentLoader(store, undefined, this.componentLoader, 0, snapshotUrl, settings)\n\t\t\t}\n\t\t} catch {\n\t\t\t// Do nothing on error; so, JSON loader is created\n\t\t}\n\n\t\treturn new DocumentLoader(this.componentLoader, 0, snapshotUrl, settings)\n\t}\n\n\t/** loads a partial tree, with current scope only */\n\tasync downloadTreeFor(entry: HistoryEntry, loadedData?: Uint8Array | string): Promise<CanvasTree> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tassert(entry.metadata.snapshotFile, \"no snapshot file defined\")\n\t\t\tconst loader = this.createLoaderFromUrl(entry.metadata.snapshotFile, loadedData)\n\n\t\t\tloader.on(\"loadedDocumentVersion\", () => {\n\t\t\t\tloader.removeAllListeners(\"loadedDocumentVersion\")\n\t\t\t\tthis.resetLoader()\n\t\t\t\tthis.loader = loader\n\t\t\t\tthis.loader.on(\"loadedFirstData\", tree => {\n\t\t\t\t\tassert(this.loader, \"loader must exist\")\n\t\t\t\t\tassert(tree.getService(\"loader\") === this.loader, \"loader in tree must be the same as in controller\")\n\t\t\t\t\ttree.setService(\"metadata\", { projectId: `${this.projectId}_${entry.version}` })\n\t\t\t\t\tthis.loader.pauseLoadingScopes()\n\t\t\t\t\tresolve(tree)\n\t\t\t\t})\n\t\t\t\tthis.loader.on(\"loadedScope\", scope => {\n\t\t\t\t\tassert(this.loader, \"loader must exist\")\n\t\t\t\t\tassert(\n\t\t\t\t\t\tthis.treeStore.tree.getService(\"loader\") === this.loader,\n\t\t\t\t\t\t\"loader in tree must be the same as in controller\",\n\t\t\t\t\t)\n\n\t\t\t\t\tthis.remoteDocument.loadOneScope(scope, false)\n\t\t\t\t\tthis.newTreeAfterRemoteUpdate(this.treeStore.timeline.tree)\n\t\t\t\t\tthis.loader.pauseLoadingScopes()\n\t\t\t\t})\n\t\t\t\tthis.loader.on(\"error\", err => reject(err))\n\t\t\t})\n\t\t\tvoid loader.start()\n\t\t})\n\t}\n\n\tpreloadDiffsFor(entry?: HistoryEntry): void {\n\t\tconst url = entry?.metadata.updatesFile\n\t\tif (!url || this.cache.has(url)) return\n\t\tvoid this.fetchJSONCached(url)\n\t}\n\n\tcache = new Map<string, { promise: Promise<unknown>; time: number }>()\n\tfetchJSONCached(url: string): Promise<unknown> {\n\t\tconst cached = this.cache.get(url)\n\t\tif (cached) {\n\t\t\tcached.time = performance.now()\n\t\t\treturn cached.promise\n\t\t}\n\n\t\tthis.maybeShrinkCache()\n\n\t\tconst promise = fetchJSON(url)\n\t\tthis.cache.set(url, { promise, time: performance.now() })\n\t\treturn promise\n\t}\n\n\tmaybeShrinkCache() {\n\t\tif (this.cache.size < 50) return\n\n\t\tconst keepIfNewer = performance.now() - 10 * 1000\n\t\tfor (const [key, value] of this.cache.entries()) {\n\t\t\tif (value.time > keepIfNewer) continue\n\t\t\tif (Math.random() < 0.5) continue\n\t\t\tthis.cache.delete(key)\n\t\t}\n\t}\n}\n", "import type { VersionDeployment } from \"@framerjs/app-shared\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { RemoteDocumentHandler } from \"document/RemoteDocumentHandler.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { ServerHistoryController } from \"history/ServerHistoryController.ts\"\nimport type { Activity, HistoryPanelParameters, Period } from \"history/dataProcessing.ts\"\nimport { DAYS, defaultParams, getClustersFromInactivity, verifyParams } from \"history/dataProcessing.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport type { CodeGenerationStore } from \"./CodeGenerationStore.ts\"\nimport type { DocumentSettingsStore } from \"./DocumentSettingsStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { ProjectStore } from \"./ProjectStore.ts\"\nimport type { ScopeStore } from \"./ScopeStore.ts\"\nimport { Tools } from \"./ToolEnum.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst POLL_HISTORY_FROM_SERVER = 60_000\n\nexport class HistoryStore extends EngineStore {\n\tloadingState: \"init\" | \"loading\" | \"ready\" = \"init\"\n\tactiveTreeVersion: number | \"latest\" = \"latest\"\n\tactiveVersionName: string | null = null\n\tactiveVersionDeploymentId: string | null = null\n\tactiveScopeIdToPreserveOnLoad: NodeID | null = null\n\tisLoadingDocument = false\n\tcanLoadMoreHistory = false\n\n\t// A flat list of changes and author information, provided by the server, created from the\n\t// document history.\n\tprivate timelineData: Period[] = []\n\n\t// A list of changes and author information, clustered in ever longer periods of work. These\n\t// clusters are computed relative to the current time, thus might change as time passes even if\n\t// the input data stays the same.\n\tprivate clusteredTimelineData: Activity[] = []\n\n\tclusteredTimelineDataOldestTimestamp = 0\n\n\t// For development and experimentation purposes, how we compute the clusters can be fine tune\n\t// with these params via the inspector.\n\tprivate params: HistoryPanelParameters = defaultParams\n\n\tprivate remoteDocument: RemoteDocumentHandler | undefined\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly documentSettings: DocumentSettingsStore,\n\t\tprivate readonly codeGenerationStore: CodeGenerationStore,\n\t\tprivate readonly projectStore: ProjectStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly scopeStore: ScopeStore,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly load: VekterEngine[\"load\"],\n\t\tprivate readonly newTreeAfterRemoteUpdate: VekterEngine[\"newTreeAfterRemoteUpdate\"],\n\t\tprivate setTool: (tool: Tools) => void,\n\t\tabortSignal?: AbortSignal,\n\t) {\n\t\tsuper()\n\t\tabortSignal?.addEventListener(\"abort\", () => this.stopLoadingAndPolling())\n\t}\n\n\tsetRemoteDocument(remoteDocument: RemoteDocumentHandler) {\n\t\tthis.remoteDocument = remoteDocument\n\t}\n\n\tprivate computeClusteredTimelineData() {\n\t\tconst clusterTimestampLimit = Math.max(\n\t\t\tthis.clusteredTimelineDataOldestTimestamp,\n\t\t\tDate.now() - (this.projectStore.resourceLimits?.versionHistoryInDays ?? 3) * DAYS,\n\t\t)\n\n\t\tthis.clusteredTimelineData = getClustersFromInactivity(\n\t\t\tthis.params,\n\t\t\tDate.now(),\n\t\t\tclusterTimestampLimit,\n\t\t\tthis.timelineData,\n\t\t)\n\t}\n\n\trestrictOldestClusterTo(timestamp: number) {\n\t\tif (timestamp === this.clusteredTimelineDataOldestTimestamp) return\n\t\tthis.clusteredTimelineDataOldestTimestamp = timestamp\n\t\tthis.computeClusteredTimelineData()\n\t}\n\n\t// Callback passed into ServerHistoryController.loadHistory(), will be called as multiple times\n\t// as loading happens, until more === false and loading is done.\n\tprivate didLoadSomeTimelineData = (controller: ServerHistoryController, data: Period[], more: boolean) => {\n\t\tif (this.#historyController !== controller) return\n\n\t\tthis.canLoadMoreHistory = false\n\t\tthis.timelineData = data\n\t\tthis.computeClusteredTimelineData()\n\n\t\tif (more) {\n\t\t\tthis.loadingState = \"loading\"\n\t\t} else {\n\t\t\tthis.loadingState = \"ready\"\n\t\t}\n\t}\n\n\t#historyController: ServerHistoryController | undefined\n\t#pollInterval = 0\n\t#lastServerPoll = 0\n\n\tprivate shouldLoadHistoryFromServer(): boolean {\n\t\tif (this.canLoadMoreHistory) return true\n\t\tif (!this.#lastServerPoll) return true\n\t\treturn performance.now() - this.#lastServerPoll > POLL_HISTORY_FROM_SERVER\n\t}\n\n\tprivate startPolling(): void {\n\t\tif (this.#pollInterval) return\n\t\tthis.#pollInterval = window.setInterval(async () => {\n\t\t\tif (!this.#historyController) return\n\t\t\tif (this.loadingState === \"loading\") return\n\t\t\tthis.#lastServerPoll = performance.now()\n\t\t\tthis.canLoadMoreHistory = await this.#historyController.pollServerForMoreHistory()\n\n\t\t\t// Start loading more history automatically if we are showing the empty state. Otherwise\n\t\t\t// we load more only if the panel opens or the user clicks a button.\n\t\t\tif (this.clusteredTimelineData.length > 1) return\n\t\t\tthis.startLoadingHistory()\n\t\t}, 30_000)\n\t}\n\n\tprivate startLoadingHistory(): void {\n\t\tif (!this.#historyController) return\n\t\tif (this.loadingState === \"loading\") return\n\t\tthis.loadingState = \"loading\"\n\t\tthis.#lastServerPoll = performance.now()\n\t\tvoid this.#historyController.loadHistory(this.didLoadSomeTimelineData)\n\t}\n\n\tinit() {\n\t\tif (!this.#historyController) {\n\t\t\tassert(this.remoteDocument, \"must have a remote document for history panel to function\")\n\t\t\tthis.#historyController = new ServerHistoryController(\n\t\t\t\tthis.componentLoader,\n\t\t\t\tthis.documentSettings,\n\t\t\t\tthis.codeGenerationStore,\n\t\t\t\tthis.projectStore,\n\t\t\t\tthis,\n\t\t\t\tthis.modulesStore,\n\t\t\t\tthis.treeStore,\n\t\t\t\tthis.remoteDocument,\n\t\t\t\tthis.load,\n\t\t\t\tthis.newTreeAfterRemoteUpdate,\n\t\t\t\tthis.scheduler.runBeforeNextFrame.bind(this.scheduler),\n\t\t\t\tthis.scheduler.runWhenIdle.bind(this.scheduler),\n\t\t\t)\n\t\t}\n\t}\n\n\tstartLoadingAndPolling() {\n\t\tthis.init()\n\t\tthis.startPolling()\n\n\t\tif (this.loadingState === \"loading\") return\n\t\tif (!this.shouldLoadHistoryFromServer()) return\n\n\t\tsetTimeout(() => this.startLoadingHistory())\n\t}\n\n\tstopLoadingAndPolling() {\n\t\tif (!this.#pollInterval) return\n\t\twindow.clearInterval(this.#pollInterval)\n\t\tthis.#pollInterval = 0\n\t}\n\n\tget clusters(): Activity[] {\n\t\treturn this.clusteredTimelineData\n\t}\n\n\tisLatestTreeVersion() {\n\t\treturn this.activeTreeVersion === \"latest\"\n\t}\n\n\trestoreLatest() {\n\t\tif (this.activeTreeVersion === \"latest\") return\n\n\t\tthis.activeTreeVersion = \"latest\"\n\t\tthis.activeVersionName = null\n\t\tthis.activeVersionDeploymentId = null\n\t\tthis.activeScopeIdToPreserveOnLoad = this.scopeStore.active.id\n\t\tthis.loadStart()\n\t\tthis.#historyController?.restoreLatestDocument()\n\t}\n\n\tasync loadVersionDeployment(deployment: VersionDeployment, name: string) {\n\t\tconst { id, treeVersion } = deployment\n\n\t\tassert(!!treeVersion, \"no tree version\")\n\t\tassert(treeVersion > 0, \"bad tree version: \", treeVersion)\n\n\t\tthis.activeVersionDeploymentId = id\n\n\t\tif (this.activeTreeVersion === treeVersion) return\n\n\t\tconst controller = this.#historyController\n\t\tif (!controller) return\n\n\t\tthis.activeTreeVersion = treeVersion\n\t\tthis.activeVersionName = name\n\t\tthis.activeScopeIdToPreserveOnLoad = this.scopeStore.active.id\n\n\t\t// While loading, check if our load is still current, and catch any errors and recover.\n\t\ttry {\n\t\t\tthis.loadStart()\n\t\t\tconst tree = await controller.loadDocumentAtPublishedVersion(treeVersion)\n\t\t\tif (this.activeTreeVersion !== treeVersion) return\n\t\t\tawait controller.loadTreeAtVersion(treeVersion, tree, this.showHistoryViewOnlyToast)\n\t\t} catch (e) {\n\t\t\tif (this.activeTreeVersion === treeVersion) {\n\t\t\t\tthis.loadFinish()\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync loadVersion(version: number, name: string) {\n\t\tassert(version > 0, \"bad tree version:\", version)\n\t\tif (this.activeTreeVersion === version) return\n\n\t\tconst controller = this.#historyController\n\t\tif (!controller) return\n\n\t\tthis.activeTreeVersion = version\n\t\tthis.activeVersionName = name\n\t\tthis.activeVersionDeploymentId = null\n\t\tthis.activeScopeIdToPreserveOnLoad = this.scopeStore.active.id\n\n\t\t// While loading, check if our load is still current, and catch any errors and recover.\n\t\ttry {\n\t\t\tthis.loadStart()\n\t\t\tconst tree = await controller.loadDocumentAtVersion(version)\n\t\t\tif (this.activeTreeVersion !== version) return\n\t\t\tawait controller.loadTreeAtVersion(version, tree, this.showHistoryViewOnlyToast)\n\t\t} catch (e) {\n\t\t\tif (this.activeTreeVersion === version) {\n\t\t\t\tthis.loadFinish()\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync resolveSnapshotVersion(version: number): Promise<number> {\n\t\tthis.init()\n\t\tconst controller = this.#historyController\n\t\tassert(controller, \"history controller not initialized\")\n\t\treturn controller.resolveSnapshotVersion(version)\n\t}\n\n\tprivate getIndexOfActiveTreeVersion(): number {\n\t\tif (this.isLatestTreeVersion()) return 0\n\t\treturn this.clusteredTimelineData.findIndex(activity => activity.treeVersion === this.activeTreeVersion)\n\t}\n\n\tolderVersion(): number | undefined {\n\t\tconst currentIndex = this.getIndexOfActiveTreeVersion()\n\t\tif (currentIndex < 0) return\n\t\treturn this.clusteredTimelineData[currentIndex + 1]?.treeVersion\n\t}\n\n\tnewerVersion(): number | undefined {\n\t\tconst currentIndex = this.getIndexOfActiveTreeVersion()\n\t\tif (currentIndex <= 1) return // If the previous version is the latest, it should just call restoreLatest\n\t\treturn this.clusteredTimelineData[currentIndex - 1]?.treeVersion\n\t}\n\n\tloadStart() {\n\t\tthis.isLoadingDocument = true\n\t\tthis.setTool(Tools.LoadingShield)\n\t}\n\n\tloadFinish() {\n\t\tthis.isLoadingDocument = false\n\t}\n\n\t/** Can be used to tune the paramaters from which the timeline with the clusters of activity are\n\t * generated. For debugging and experimentation. */\n\tsetParams(timeSpans: number[], useTimeSpanIfBefore: number[]) {\n\t\t// Turn from minutes into milliseconds if needed.\n\t\tconst firstTimeSpan = timeSpans[0]\n\t\tassert(isNumber(firstTimeSpan), \"Time span must be a number\")\n\t\tif (firstTimeSpan < 1000) {\n\t\t\ttimeSpans = timeSpans.map(s => s * 60 * 1000)\n\t\t\tuseTimeSpanIfBefore = useTimeSpanIfBefore.map(s => s * 60 * 1000)\n\t\t}\n\n\t\tconst params: HistoryPanelParameters = { timeSpans, useTimeSpanIfBefore }\n\t\tverifyParams(params)\n\t\tthis.params = params\n\t\tthis.computeClusteredTimelineData()\n\t}\n\n\tdebugReset() {\n\t\tthis.restoreLatest()\n\t\tthis.params = defaultParams\n\t\tthis.loadingState = \"init\"\n\t\tthis.activeScopeIdToPreserveOnLoad = null\n\t\tthis.#historyController = undefined\n\t\tthis.#lastServerPoll = 0\n\t\tthis.timelineData = []\n\t\tthis.clusteredTimelineData = []\n\t\tthis.activeVersionName = null\n\n\t\t// Start a reload if the poll interval is active.\n\t\tif (this.#pollInterval !== 0) {\n\t\t\tthis.startLoadingAndPolling()\n\t\t}\n\t}\n\n\tshowHistoryViewOnlyToast() {\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tvariant: \"info\",\n\t\t\tkey: \"disconnected-by-history-controller\",\n\t\t\tprimaryText: \"Previous versions are\",\n\t\t\tsecondaryText: \"view-only.\",\n\t\t\tduration: Infinity,\n\t\t\tshowCloseButton: \"never\",\n\t\t})\n\t}\n\n\tremoveHistoryViewOnlyToast() {\n\t\ttoast({ type: \"remove\", key: \"disconnected-by-history-controller\" })\n\t}\n}\n", "import { BaseHostnameStore } from \"document/base-engine/BaseHostnameStore.ts\"\nimport type { PublishStore } from \"./PublishStore.ts\"\n\n/**\n * This store exists as a compatibility layer with the editor bar.\n * But it would be nice to migrate the hostname logic from {@link PublishStore} to here.\n */\nexport class HostnameStore extends BaseHostnameStore {\n\tconstructor(private readonly publishStore: PublishStore) {\n\t\tsuper()\n\t}\n\n\tget customHostnameString(): string | undefined {\n\t\treturn this.publishStore.customHostname?.hostname\n\t}\n\n\tget defaultHostnameString(): string | undefined {\n\t\treturn this.publishStore.defaultHostname?.hostname\n\t}\n}\n", "import { environment } from \"@framerjs/framer-environment\"\nimport { assert } from \"@framerjs/shared\"\nimport { experiments } from \"app/experiments.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type {\n\tCategory,\n\tCategoryTypes,\n\tColorScheme,\n\tDataSourceCategory,\n\tDataSourceItem,\n\tEditBehavior,\n\tInsertContextType,\n\tLayoutVariants,\n\tOverlayType,\n\tSearchResults,\n\tVariantName,\n} from \"document/components/chrome/insertSidebar/types.ts\"\nimport { dataSourceCategoryHasItems, isDataSourceSection } from \"document/components/chrome/insertSidebar/types.ts\"\nimport {\n\tisCanvasPageNode,\n\tisDesignPageNode,\n\tisLayoutTemplateNode,\n\tisSmartComponentNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport { isShallowSetEqual } from \"utils/isShallowEqual.ts\"\nimport type { InsertSidebarDataSource } from \"../components/chrome/insertSidebar/InsertSidebarDataSource.ts\"\nimport type { LoadedScopeNode } from \"../models/CanvasTree/index.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\ninterface ScopeInfo {\n\tscope: LoadedScopeNode\n\thasWebPageNodes: boolean\n\thasCanvasPageNodes: boolean\n}\n\nexport class InsertSidebarStore extends EngineStore {\n\t#isLoading: boolean = false\n\t#activeScopeContextTypes: Set<InsertContextType> = new Set([\"webdesign\"])\n\tcolorSchemePreference: ColorScheme = \"light\"\n\n\tprivate _isLoaded: boolean = false\n\n\tget isLoaded() {\n\t\treturn this._isLoaded\n\t}\n\n\tprivate _dataSource: InsertSidebarDataSource | null = null\n\n\tget dataSource(): InsertSidebarDataSource | null {\n\t\treturn this._dataSource\n\t}\n\n\tprivate _categories: CategoryTypes[] | null = null\n\n\tget categories() {\n\t\treturn this._categories\n\t}\n\n\tactiveCategoryType: Category | null = null\n\n\tprivate _search: string = \"\"\n\tprivate _searchResults: SearchResults | null = null\n\n\tget search() {\n\t\treturn this._search\n\t}\n\n\tget searchResults() {\n\t\treturn this._searchResults\n\t}\n\n\tconstructor(\n\t\tprivate modulesStore: ModulesStore,\n\t\tprivate chromeStore: ChromeStore,\n\t\tprivate treeStore: TreeStore,\n\t) {\n\t\tsuper()\n\t}\n\n\tprivate async load(): Promise<void> {\n\t\t// Load `InsertSidebarDataSource` async, which includes a ton of SVG\n\t\tconst InsertSidebarDataSource = (await import(\"../components/chrome/insertSidebar/InsertSidebarDataSource.ts\"))\n\t\t\t.InsertSidebarDataSource\n\n\t\tthis._dataSource = new InsertSidebarDataSource()\n\t\tawait this._dataSource.load(this.modulesStore)\n\t\tthis._categories = this._dataSource.getCategories(this.#activeScopeContextTypes)\n\t}\n\n\tloadIfNeeded() {\n\t\tif (this.isLoaded || this.#isLoading) return\n\t\tif (environment.isAutomation) return\n\n\t\tthis.#isLoading = true\n\n\t\tvoid this.load()\n\t\t\t.then(() => {\n\t\t\t\tthis._isLoaded = true\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tthis.#isLoading = false\n\t\t\t})\n\t}\n\n\t/**\n\t * Show the insert sidebar on load when:\n\t * 1. it is a new document that is being created (template, duplicate, or blank) except if the agent experiment is on\n\t * 2. it is an existing document but a specific condition determines it should load\n\t * (e.g. `insertPanel` query param in the URL)\n\t */\n\tdetermineStateOnLoad(forceState?: \"show\" | \"hide\") {\n\t\tif (forceState === \"hide\") return\n\t\t// TODO: Migrate this to look at whether the user has canvas edit permissions.\n\t\tif (this.chromeStore.userIsViewer || this.chromeStore.displayMinimalUI) return\n\t\t// If the agent experiment is on, we want to hide the insert sidebar by default\n\t\t// because the agent shows an agent sidebar instead.\n\t\tif (experiments.isOn(\"agent\") && this.treeStore.isNewDocument) return\n\n\t\tif (this.treeStore.isNewDocument || forceState === \"show\") {\n\t\t\tthis.chromeStore.showInsertSidebar()\n\t\t}\n\t}\n\n\tupdateSearch = (value: string) => {\n\t\tif (value === this._search) return\n\n\t\tthis.activeCategoryType = null\n\t\tthis._search = value\n\n\t\tif (value.trim().length === 0) {\n\t\t\tthis._searchResults = null\n\t\t\treturn\n\t\t}\n\n\t\tthis._searchResults = this.dataSource?.getSearchResult(value, this.#activeScopeContextTypes) ?? null\n\t}\n\n\tclearSearch = () => {\n\t\tthis.updateSearch(\"\")\n\t}\n\n\tgetItemByURL(moduleURL: string) {\n\t\treturn this.dataSource?.getItemByURL(moduleURL)\n\t}\n\n\tgetEditBehavior(moduleId: string): EditBehavior | undefined {\n\t\treturn this.dataSource?.getEditBehavior(moduleId)\n\t}\n\n\tshouldBecomeFullWidthForVariants(moduleId: string): LayoutVariants {\n\t\treturn this.dataSource?.shouldBecomeFullWidthForVariants(moduleId) ?? new Set<VariantName>()\n\t}\n\n\tshouldDetachOnInsert(moduleId: string): boolean {\n\t\treturn this.dataSource?.shouldDetachOnInsert(moduleId) ?? false\n\t}\n\n\tshouldInsertAsOverlayType(moduleId: string): OverlayType | undefined {\n\t\treturn this.dataSource?.shouldInsertAsOverlayType(moduleId) ?? undefined\n\t}\n\n\tonScopeChange(scopeInfo: ScopeInfo) {\n\t\tconst contextTypes = getInsertContextTypes(scopeInfo)\n\t\tif (isShallowSetEqual(contextTypes, this.#activeScopeContextTypes)) {\n\t\t\treturn\n\t\t}\n\t\tthis.#activeScopeContextTypes = contextTypes\n\t\tif (!this.isLoaded || !this.dataSource) return\n\t\t// Rebuild sections\n\t\tthis._categories = this.dataSource.getCategories(this.#activeScopeContextTypes)\n\t\t// Clear existing search, else search results would need to be regenerated. Insert sidebar is probably\n\t\t// hidden when switching scopes, so this probably won't be noticed by the user.\n\t\tthis.updateSearch(\"\")\n\t}\n\n\tgetCategoryForItem(item: DataSourceItem): DataSourceCategory {\n\t\tassert(this.categories, \"Item keys can only be known if the categories data source has loaded\")\n\n\t\tconst foundCategory = this.categories.find((category): category is DataSourceCategory => {\n\t\t\tif (!dataSourceCategoryHasItems(category)) return false\n\n\t\t\treturn category.items.some(categoryItem => {\n\t\t\t\tif (isDataSourceSection(categoryItem)) {\n\t\t\t\t\treturn categoryItem.items.includes(item)\n\t\t\t\t}\n\n\t\t\t\treturn categoryItem === item\n\t\t\t})\n\t\t})\n\n\t\tassert(foundCategory, \"All items should have a category\")\n\t\treturn foundCategory\n\t}\n}\n\nfunction getInsertContextTypes({ scope, hasCanvasPageNodes, hasWebPageNodes }: ScopeInfo): Set<InsertContextType> {\n\tconst result: Set<InsertContextType> = new Set()\n\tif (isWebPageNode(scope) || isDesignPageNode(scope)) result.add(\"webpage\")\n\n\tif (isWebPageNode(scope) || isLayoutTemplateNode(scope) || isDesignPageNode(scope)) {\n\t\tif (hasCanvasPageNodes) result.add(\"webpage-with-canvas-pages-in-document\")\n\t\tresult.add(\"webdesign\")\n\t} else if (isCanvasPageNode(scope)) {\n\t\tresult.add(\"prototyping\")\n\t} else if (isSmartComponentNode(scope)) {\n\t\tif (hasWebPageNodes) result.add(\"webdesign\")\n\t\tif (hasCanvasPageNodes) result.add(\"prototyping\")\n\t}\n\treturn result\n}\n", "import hash from \"@emotion/hash\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { DebouncedTask, getLogger, unhandledError } from \"@framerjs/shared\"\nimport { LocalKit, getNewKitSectionHash, processLLMSectionCustomizations } from \"app/ai/kits/LocalKit.ts\"\nimport type { GeneratedSectionCustomizations } from \"app/ai/sections/generateSectionCustomizations.ts\"\nimport { generateCustomizations } from \"app/ai/sections/generateSectionCustomizations.ts\"\nimport type { OpenRouterFeatureStepTraceConfig } from \"app/ai/tracing/openRouterTrace.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { projectFeatures } from \"app/projectFeatures.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { TaskScheduler } from \"document/loader/TaskScheduler.ts\"\nimport type { NodeChangesReader } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { AnySmartComponentNode, CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isLocalModuleNode } from \"document/models/CanvasTree/nodes/LocalModuleNode.ts\"\nimport { randomID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport { isStylePresetNode } from \"document/models/CanvasTree/nodes/utils/isStylePresetNode.ts\"\nimport {\n\tisCodeComponentNode,\n\tisColorStyleTokenNode,\n\tisExternalModuleNode,\n\tisKitPageNode,\n\tisSmartComponentNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { getSourceNodeForSection, isCustomizable } from \"document/models/CanvasTree/traits/WithCustomizations.ts\"\nimport { withKitSectionHash } from \"document/models/CanvasTree/traits/WithKitSectionHash.ts\"\nimport { hasModuleRevisionChanged, usesModuleRevision } from \"document/models/CanvasTree/traits/WithModuleRevision.ts\"\nimport { LockQueue } from \"document/utils/LockQueue.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport type { AssetStore } from \"./AssetStore.ts\"\nimport type { LoadedExternalModulesStore } from \"./LoadedExternalModulesStore.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst log = getLogger(\"kit-screenshot-store\")\n\nexport class KitScreenshotStore extends EngineStore {\n\tget enabled(): boolean {\n\t\treturn experiments.isOn(\"wireframerKits\") && projectFeatures.isOn(\"kit\")\n\t}\n\n\t#nodeChangesReader: NodeChangesReader | undefined\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly assetStore: AssetStore,\n\t\tprivate readonly loadedExternalModulesStore: LoadedExternalModulesStore,\n\t\tprivate readonly scheduleDocumentUpdateIgnoringUndo: <T>(\n\t\t\ttask: (latestTree: CanvasTree) => T,\n\t\t) => Promise<T | undefined>,\n\t\tprivate readonly generateScreenshotHTML: (kitPageId: NodeID) => Promise<string | undefined>,\n\t) {\n\t\tsuper()\n\t\tif (!this.enabled) return\n\t\t// The reader only receives changes once it's opened. We must open the reader on\n\t\t// initialization if the project is a kit project to ensure we capture changes made in the\n\t\t// first tree frame.\n\t\tthis.getNodeChangesReader()\n\t}\n\n\tprivate getNodeChangesReader(): NodeChangesReader {\n\t\t// Instantiate the node changes reader if it doesn't exist. It is only needed if the project\n\t\t// is a kit project, which can change after initialization.\n\t\tthis.#nodeChangesReader ??= this.treeStore.timeline.openNodeChangesReader()\n\t\treturn this.#nodeChangesReader\n\t}\n\n\tpostProcess(tree: CanvasTree, remote: boolean) {\n\t\tif (!this.enabled) return\n\t\tif (this.treeStore.tree.isViewOnly) return\n\n\t\tconst reader = this.getNodeChangesReader()\n\n\t\tif (remote) {\n\t\t\t// When postProcessing after remote changes, clear the reader so\n\t\t\t// that processing future local changes doesn't cause changes made\n\t\t\t// remotely to be processed.\n\t\t\treader.clear()\n\t\t\treturn\n\t\t}\n\n\t\t// Ingest all changes into the store.\n\t\tthis.ingestChanges(tree)\n\t}\n\n\t#lockQueue = new LockQueue()\n\t#debounce = new DebouncedTask({\n\t\t// KITS @TODO - These are rough durations that will need to be tuned based on how it feels when\n\t\t// we can see the latest screenshots.\n\t\tdelay: 500,\n\t\tmaxDelay: 1_000,\n\t\ttask: () => this.processQueue(),\n\t})\n\n\tprivate ingestChanges(tree: CanvasTree) {\n\t\tif (!this.enabled) return\n\n\t\tconst reader = this.getNodeChangesReader()\n\n\t\tlet debounce = false\n\t\tfor (const [id, changes] of reader.read()) {\n\t\t\tif (changes.length === 0 || changes.every(change => change.ignoreInCodeGeneration)) continue\n\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\n\t\t\t// KITS @TODO - This is a rough heuristic that will guarantee updates, but will generate\n\t\t\t// html, and request screenshots more often than necessary. Improvements:\n\t\t\t// - Distinguish between updates to the section nodes themselves, and dependencies like\n\t\t\t//   modules, tokens, or presets. The latter require all of the kit page screenshots to\n\t\t\t//   be updated, while the former just the page.\n\t\t\t// - Module Updates can be further optimized by only debouncing if the module is a\n\t\t\t//   dependency of the kit page.\n\t\t\tif (usesModuleRevision(node, this.treeStore.tree) && isKitPageNode(node)) {\n\t\t\t\tif (hasModuleRevisionChanged(changes)) debounce = true\n\t\t\t} else if (\n\t\t\t\tisStylePresetNode(node) ||\n\t\t\t\tisLocalModuleNode(node) ||\n\t\t\t\tisExternalModuleNode(node) ||\n\t\t\t\tisColorStyleTokenNode(node)\n\t\t\t) {\n\t\t\t\tdebounce = true\n\t\t\t}\n\t\t}\n\n\t\tif (!debounce) return\n\n\t\tlog.trace(\"\uD83C\uDF71 Debouncing queue\")\n\t\tthis.#debounce.debounce()\n\t}\n\n\tasync updatePage(pageId: NodeID): Promise<void> {\n\t\tif (!this.enabled) return\n\n\t\tconst node = this.treeStore.tree.getNodeWithTrait(pageId, isKitPageNode)\n\t\tif (!node) return\n\n\t\t// If the node is already scheduled, and hasn't started yet, no need to schedule it\n\t\t// again.\n\t\tif (this.#lockQueue.isScheduled(node.id)) {\n\t\t\tawait this.#lockQueue.await(node.id)\n\t\t\treturn\n\t\t}\n\n\t\t// Add the task to the queue. Using slow here with a callback that executes immediately disables yielding\n\t\t// to prevent the task from pausing in this case (check yield implementation for more details).\n\t\tconst taskScheduler = new TaskScheduler(callback => callback()).slow()\n\t\tawait this.#lockQueue.request(() => taskScheduler.run(() => this.handleKitPageTask(node.id, taskScheduler)), {\n\t\t\tid: node.id,\n\t\t})\n\t}\n\n\tprivate processQueue() {\n\t\tif (!this.enabled) return\n\n\t\tlog.trace(\"\uD83C\uDF71 Processing queue\")\n\n\t\tfor (const node of this.treeStore.tree.root.children) {\n\t\t\tif (!isKitPageNode(node)) continue\n\n\t\t\t// If the node is already scheduled, and hasn't started yet, no need to schedule it\n\t\t\t// again.\n\t\t\tif (this.#lockQueue.isScheduled(node.id)) continue\n\n\t\t\t// Ensure each task waits for the previous task to complete before starting, but queue\n\t\t\t// them freely.\n\t\t\tconst taskScheduler = new TaskScheduler((callback: VoidFunction) => this.scheduler.runWhenIdle(callback)).slow()\n\n\t\t\tvoid this.#lockQueue.request(() => taskScheduler.run(() => this.handleKitPageTask(node.id, taskScheduler)), {\n\t\t\t\tid: node.id,\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * When changes to the tree might alter kit section screenshots, or kit section customizations,\n\t * perform those tasks, ensuring that we don't block the CPU during major engine operations.\n\t */\n\tprivate async handleKitPageTask(id: NodeID, taskScheduler: TaskScheduler): Promise<void> {\n\t\tlog.trace(\"\uD83C\uDF71 Update Kit Page\", id)\n\n\t\tconst page = this.treeStore.tree.getNodeWithTrait(id, isKitPageNode)\n\t\tif (!page) return\n\n\t\tawait taskScheduler.yield()\n\n\t\t// Load the kit page if it isn't already loaded.\n\t\tconst loaded = page.isLoaded() ? page : await page.load()\n\t\tif (!loaded) return\n\n\t\tawait taskScheduler.yield()\n\n\t\tconst latest = this.treeStore.tree.current(loaded)\n\t\tif (!latest) return\n\n\t\t// Update categories and descriptions for sections with changed hashes.\n\t\tconst variants = latest.getReplicaVariants()\n\t\tconst primaryVariant = latest.getPrimaryVariant()\n\t\tconst promises: Promise<[NodeID, GeneratedSectionCustomizations]>[] = []\n\t\tconst ctx = LocalKit.createKitContext({\n\t\t\tcomponentLoader: this.componentLoader,\n\t\t\ttreeStore: this.treeStore,\n\t\t\tmodulesStore: this.modulesStore,\n\t\t\tloadedExternalModulesStore: this.loadedExternalModulesStore,\n\t\t\tassetStore: this.assetStore,\n\t\t})\n\n\t\t// Preload all top-level sections that are smart components so that we can freely\n\t\t// process them without loading one by one.\n\t\tconst maybeShallowLocalSmartComponents: AnySmartComponentNode[] = []\n\t\tfor (const section of primaryVariant.children) {\n\t\t\tif (!isCodeComponentNode(section)) continue\n\t\t\tconst sourceNode = getSourceNodeForSection(this.treeStore.tree, section)\n\t\t\tif (isSmartComponentNode(sourceNode, true)) maybeShallowLocalSmartComponents.push(sourceNode)\n\t\t}\n\n\t\tawait this.treeStore.tree.loadScopes(maybeShallowLocalSmartComponents)\n\n\t\t// Wait for the engine to be idle as we just awaited the scopes loading.\n\t\tawait taskScheduler.yield()\n\n\t\tconst traceConfig: OpenRouterFeatureStepTraceConfig = { featureName: \"kit-screenshot\", sessionId: randomID() }\n\n\t\tconst ids = new Set<NodeID>()\n\t\tconst smartComponentSourceNodes = new Set<NodeID>()\n\t\tfor (const section of primaryVariant.children) {\n\t\t\tif (!isCustomizable(section) || !withKitSectionHash(section)) continue\n\n\t\t\t// Track the ids. We send these to SQS to create individual jobs for parallel lambda\n\t\t\t// executions.\n\t\t\tids.add(section.id)\n\n\t\t\tconst newKitSectionHash = getNewKitSectionHash(this.treeStore.tree, section, variants, smartComponentSourceNodes)\n\t\t\tif (!isNumber(newKitSectionHash)) continue\n\n\t\t\tlog.trace(\"\uD83C\uDF71 Generating customizations for section\", section.id)\n\t\t\tconst promise = generateCustomizations(section, latest, traceConfig, {\n\t\t\t\tcomponentLoader: this.componentLoader,\n\t\t\t\tmodulesStore: this.modulesStore,\n\t\t\t\ttree: this.treeStore.tree,\n\t\t\t\tengineChanges: this.scheduler.changes,\n\t\t\t\tassetMap: this.assetStore.assetMap,\n\t\t\t})\n\n\t\t\tctx.kitSectionHashes.set(section.id, newKitSectionHash)\n\t\t\tpromises.push(promise)\n\t\t}\n\n\t\tif (promises.length === 0) log.trace(\"\uD83C\uDF71 No customizations to generate for Kit Page\", id)\n\n\t\tconst result = await Promise.all(promises)\n\n\t\t// Wait for the engine to be idle as we are about to walk every updated section.\n\t\tawait taskScheduler.yield()\n\n\t\t// Process the customizations into node updates.\n\t\tconst { updates } = processLLMSectionCustomizations(result, ctx)\n\t\tawait this.scheduleDocumentUpdateIgnoringUndo(latestTree => {\n\t\t\tupdates.forEach(fn => fn(latestTree))\n\t\t})\n\n\t\tawait taskScheduler.yield()\n\n\t\tconst start = performance.now()\n\n\t\t// Generate the screenshot HTML.\n\t\tconst html = await this.generateScreenshotHTML(page.id)\n\t\tif (!html) return\n\n\t\tlog.trace(\"\uD83C\uDF71 Generated screenshot HTML for Kit Page\", id, performance.now() - start)\n\n\t\tawait taskScheduler.yield()\n\n\t\t// Hash the html and check if it has changed. By returning early when the hash hasn't\n\t\t// changed, we avoid filling the SQS queue with unnecessary screenshots. We hash the HTML\n\t\t// instead of *just* using the Kit Page module revision, because the html includes tokens\n\t\t// and the import map.\n\t\tconst kitPageHTMLHash = hash(html)\n\n\t\tif (kitPageHTMLHash === latest.kitPageHTMLHash) {\n\t\t\tlog.trace(\"\uD83C\uDF71 Page HTML hash has not changed, skipping screenshots\", id)\n\t\t\treturn\n\t\t}\n\n\t\t// If the html has changed, update the hash and enqueue the screenshots.\n\t\tlog.trace(\n\t\t\t`\uD83C\uDF71 Page HTML hash has changed updating kit page hash ${id} previous: ${latest.kitPageHTMLHash} new: ${kitPageHTMLHash}`,\n\t\t\thtml,\n\t\t)\n\n\t\tawait this.scheduleDocumentUpdateIgnoringUndo(latestTree => {\n\t\t\tlatestTree.current(page)?.set({ kitPageHTMLHash })\n\t\t})\n\n\t\tthis.modulesStore.enqueueKitScreenshots(html, ids, true).catch(unhandledError)\n\t}\n}\n", "import type { GlobalModuleId } from \"@framerjs/shared\"\nimport { getLogger } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { Library, LibraryModule, LibraryPermissions } from \"document/library/libraryApi.ts\"\nimport {\n\tgetLibraries,\n\tgetModulesForLibrary,\n\tremoveModuleFromLibrary,\n\tupdateModule,\n} from \"document/library/libraryApi.ts\"\n\nconst log = getLogger(\"library-store\")\n\nexport class LibraryStore extends EngineStore {\n\tupdate = 0\n\tprivate _teamLibrary: Library | undefined\n\n\tpublic triggerUpdate() {\n\t\tthis.update += 1\n\t}\n\n\tpublic async getLibraryForTeam(teamId: string) {\n\t\tconst libraries = await getLibraries({ teamId })\n\t\tif (!libraries[0]) {\n\t\t\treturn\n\t\t}\n\t\tthis._teamLibrary = libraries[0]\n\t\tthis.triggerUpdate()\n\t}\n\n\tget teamLibrary() {\n\t\treturn this._teamLibrary\n\t}\n\n\tprivate updateOfLastFetch: number = 0\n\tprivate libraryModulesMap: Map<string, LibraryModule> = new Map()\n\tpublic libraryModules: LibraryModule[] = []\n\tpublic loadingModules: boolean = false\n\tpublic libraryPermissions: LibraryPermissions = { canEdit: false }\n\tpublic fetchLibraryModules(teamLibrary: Library) {\n\t\tif (this.updateOfLastFetch === this.update) return\n\n\t\tthis.libraryModulesMap = new Map()\n\t\tthis.loadingModules = true\n\t\tthis.updateOfLastFetch = this.update\n\n\t\tgetModulesForLibrary({ libraryId: teamLibrary.id })\n\t\t\t.then(({ data, permissions }) => {\n\t\t\t\tdata.forEach(libraryModule => {\n\t\t\t\t\tthis.libraryModulesMap.set(libraryModule.module.id, libraryModule)\n\t\t\t\t})\n\t\t\t\tthis.libraryPermissions = permissions\n\t\t\t\tthis.libraryModules = [...this.libraryModulesMap.values()]\n\t\t\t\tthis.loadingModules = false\n\t\t\t})\n\t\t\t.catch(e => {\n\t\t\t\tlog.reportError(e)\n\t\t\t\tthis.loadingModules = false\n\t\t\t})\n\t}\n\n\tpublic lookupLibraryModule(moduleId: string): LibraryModule | undefined {\n\t\treturn this.libraryModulesMap.get(moduleId)\n\t}\n\n\tpublic async removeFromLibrary(moduleId: GlobalModuleId, exportSpecifier: string) {\n\t\tif (!this._teamLibrary) return\n\n\t\ttry {\n\t\t\tawait removeModuleFromLibrary({ libraryId: this._teamLibrary.id, moduleId, exportSpecifier })\n\n\t\t\tconst newMap = new Map(this.libraryModulesMap)\n\t\t\tnewMap.delete(moduleId)\n\t\t\tthis.libraryModulesMap = newMap\n\t\t\tthis.libraryModules = [...this.libraryModulesMap.values()]\n\t\t\tthis.triggerUpdate()\n\t\t} catch (err) {\n\t\t\tlog.reportError(err)\n\t\t\t// the UI will handle communicating the error to the user.\n\t\t\tthrow err\n\t\t}\n\t}\n\n\t/**\n\t * @deprecated this is only used by the legacy insert menu\n\t */\n\tpublic async updateModuleDescription(moduleId: GlobalModuleId, exportSpecifier: string, description: string) {\n\t\tif (!this._teamLibrary) return\n\n\t\ttry {\n\t\t\tconst updatedModule = await updateModule({\n\t\t\t\tlibraryId: this._teamLibrary.id,\n\t\t\t\tmoduleId,\n\t\t\t\texportSpecifier,\n\t\t\t\tdescription: description.length > 0 ? description : null,\n\t\t\t})\n\n\t\t\tconst newMap = new Map(this.libraryModulesMap)\n\t\t\tnewMap.set(moduleId, updatedModule)\n\t\t\tthis.libraryModulesMap = newMap\n\t\t\tthis.libraryModules = [...this.libraryModulesMap.values()]\n\t\t\tthis.triggerUpdate()\n\t\t} catch (err) {\n\t\t\tlog.reportError(err)\n\t\t\t// the UI will handle communicating the error to the user.\n\t\t\tthrow err\n\t\t}\n\t}\n}\n", "import type { ComponentLoader, EntityDefinition } from \"@framerjs/framer-runtime\"\nimport type { ExternalModuleBareIdentifierString, ExternalModuleIdentifier, ModuleIdentifier } from \"@framerjs/shared\"\nimport {\n\tassert,\n\tResolvablePromise,\n\tgetLogger,\n\tisExternalModuleIdentifier,\n\tparseModuleIdentifier,\n\twithoutExportSpecifier,\n} from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { BaseLoadedExternalModulesStore } from \"document/base-engine/BaseLoadedExternalModulesStore.ts\"\nimport type { SelectionStore } from \"document/stores/SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport type ExternalModuleEvaluationMode = \"sandbox\" | \"noop\"\n\nexport class LoadedExternalModulesStore extends EngineStore implements BaseLoadedExternalModulesStore {\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly selectionStore: SelectionStore,\n\t\tprivate readonly ensureExternalModuleLoaded: (identifier: ExternalModuleIdentifier) => Promise<void>,\n\t\tprivate readonly engineDebounce: (fn: () => void, millis: number) => () => void,\n\t) {\n\t\tsuper()\n\t\tthis.debouncedHandleExternalModulesLoaded = this.engineDebounce(() => {\n\t\t\tthis.handleExternalModulesLoaded(this.loadedExternalModulesBuffer)\n\t\t\tthis.loadedExternalModulesBuffer.clear()\n\t\t}, 200)\n\n\t\tthis.debouncedCalculate = this.engineDebounce(() => {\n\t\t\tthis.treeStore.updateConnectedScreens(this.selectionStore.ids)\n\t\t\tthis.treeStore.updateVariableProviderInfo(this.selectionStore.ids)\n\t\t}, 200)\n\t}\n\n\t#loadingExternalModules: Map<ExternalModuleBareIdentifierString, ResolvablePromise<void>> = new Map()\n\n\t/** Bare module identifiers of the external modules that have been loaded. */\n\tloadedExternalModules = new Set<ExternalModuleBareIdentifierString>()\n\n\tprivate externalModuleEvaluationMode: ExternalModuleEvaluationMode = \"sandbox\"\n\n\t// We batch externalModuleLoaded events via a debounce. Avoids a lot of work in larger\n\t// documents with many code components.\n\tprivate readonly loadedExternalModulesBuffer = new Map<string, EntityDefinition[]>()\n\tprivate readonly debouncedHandleExternalModulesLoaded: () => void\n\n\t// Update arrows when external components are loaded in a debounced manner.\n\tprivate debouncedCalculate: () => void\n\n\t/** Signal that an external module has loaded. The store will first buffer these updates and\n\t * process them after a small delay in batches. */\n\tpublic signalExternalModuleLoaded(identifier: string, entities: EntityDefinition[]): void {\n\t\tthis.loadedExternalModulesBuffer.set(identifier, entities)\n\t\tthis.debouncedHandleExternalModulesLoaded()\n\t}\n\n\tprivate handleExternalModulesLoaded(modules: ReadonlyMap<string, EntityDefinition[]>): void {\n\t\tgetLogger(\"componentLoader\").info(\"externalModulesLoaded\", modules.size)\n\n\t\tlet didUpdateEntities = false\n\t\tconst newLoadedExternalModules = new Set(this.loadedExternalModules)\n\n\t\tfor (const [identifier, entities] of modules) {\n\t\t\tconst moduleIdentifier = parseModuleIdentifier(identifier)\n\t\t\tassert(moduleIdentifier?.kind === \"externalModule\")\n\t\t\tfor (const entity of entities) {\n\t\t\t\tdidUpdateEntities = true\n\t\t\t\tconst entityIdentifier = parseModuleIdentifier(entity.identifier)\n\t\t\t\tassert(\n\t\t\t\t\tentityIdentifier && withoutExportSpecifier(entityIdentifier).value === moduleIdentifier.value,\n\t\t\t\t\t\"handleExternalModuleLoaded for module\",\n\t\t\t\t\tmoduleIdentifier,\n\t\t\t\t\t\"but got an entity whose identifier doesn't match that module\",\n\t\t\t\t\tentity.identifier,\n\t\t\t\t)\n\t\t\t\tthis.componentLoader.updateEntity(entity.identifier, entity)\n\t\t\t}\n\n\t\t\tthis.#loadingExternalModules.get(moduleIdentifier.value)?.resolve()\n\t\t\tthis.#loadingExternalModules.delete(moduleIdentifier.value)\n\n\t\t\tnewLoadedExternalModules.add(moduleIdentifier.value)\n\t\t}\n\n\t\t// Actually trigger a store update.\n\t\tthis.loadedExternalModules = newLoadedExternalModules\n\t\tif (!didUpdateEntities) return\n\n\t\t// Update the TreeStore dependencies, re-index the CodeComponents and\n\t\t// add derived NavigationActionNodes and VariantActionNodes.\n\t\tthis.treeStore.updateCodeComponents()\n\t\tthis.debouncedCalculate()\n\t}\n\n\tpublic hasModuleForIdentifier(identifier: ModuleIdentifier | string | undefined) {\n\t\tif (typeof identifier === \"string\") {\n\t\t\tidentifier = parseModuleIdentifier(identifier)\n\t\t}\n\t\tif (!isExternalModuleIdentifier(identifier)) return false\n\t\tconst bareIdentifier = withoutExportSpecifier(identifier)\n\t\treturn this.loadedExternalModules.has(bareIdentifier.value)\n\t}\n\n\tpublic setExternalModuleEvaluationMode(mode: ExternalModuleEvaluationMode): void {\n\t\tthis.externalModuleEvaluationMode = mode\n\t}\n\n\tpublic usesNoopExternalModuleEvaluation(): boolean {\n\t\treturn this.externalModuleEvaluationMode === \"noop\"\n\t}\n\n\t/**\n\t * Ensures that the given module got evaluated in the canvas sandbox, and\n\t * that the result of that evaluation has already made it into the host and\n\t * is available in the component loader.\n\t */\n\tpublic async ensureModuleEvaluatedInSandbox(identifier: ExternalModuleIdentifier) {\n\t\t// We never evaluate individual exports inside a module, only entire\n\t\t// modules, so let's strip the export specifier from the request.\n\t\tconst bareIdentifier = withoutExportSpecifier(identifier)\n\n\t\tif (this.loadedExternalModules.has(bareIdentifier.value)) {\n\t\t\t// We don't support re-evaluating an already-loaded external module.\n\t\t\treturn\n\t\t}\n\n\t\tif (this.externalModuleEvaluationMode === \"noop\") {\n\t\t\t// Eval export replay engines are detached from the canvas sandbox. Mark modules as loaded\n\t\t\t// so read-only project inspection can proceed without waiting for sandbox callbacks.\n\t\t\tconst nextLoadedExternalModules = new Set(this.loadedExternalModules)\n\t\t\tnextLoadedExternalModules.add(bareIdentifier.value)\n\t\t\tthis.loadedExternalModules = nextLoadedExternalModules\n\t\t\treturn\n\t\t}\n\n\t\tlet loadingPromise = this.#loadingExternalModules.get(bareIdentifier.value)\n\t\tif (!loadingPromise) {\n\t\t\tloadingPromise = new ResolvablePromise()\n\t\t\tthis.#loadingExternalModules.set(bareIdentifier.value, loadingPromise)\n\t\t}\n\n\t\tawait this.ensureExternalModuleLoaded(bareIdentifier)\n\n\t\t// The sandbox might be rather busy. So we use a rather long timeout to hear back about an\n\t\t// external module having loaded.\n\t\t//\n\t\t// We capture the stack trace for the potential timeout error here, instead of inside the\n\t\t// setTimeout callback, where it wouldn't be as helpful.\n\t\tconst timeoutError = new Error(\n\t\t\t`ensureModuleEvaluatedInSandbox timed out awaiting handleExternalModuleLoaded for ${bareIdentifier.value}`,\n\t\t)\n\t\tconst timeout = new Promise((_, reject) => setTimeout(() => reject(timeoutError), 30_000))\n\t\tawait Promise.race([loadingPromise, timeout])\n\t}\n}\n", "import type { ModalOpenSource } from \"@framerjs/events\"\nimport { unhandledError } from \"@framerjs/shared\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { UpsellFeature } from \"document/components/chrome/siteSettings/Plans/Stripe/utils/upsell.ts\"\nimport { SiteSettingsTabNames } from \"document/stores/SiteSettingsStore.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\n\n/** Only enforce the limit for non framer employees and when the agent experiment is on */\nexport function isAiCreditLimitEnforced(engine: VekterEngine): boolean {\n\treturn experiments.isOn(\"agent\") && !engine.stores.sessionStore.user.isFramerEmployee\n}\n\n/**\n * Fractions of the monthly AI credit limit at which we warn the user, in descending order.\n * The hook fires at most one toast per session; the highest crossed threshold at that moment wins.\n */\nexport const aiCreditsWarningThresholds = [0.9, 0.8] as const\n\nexport function showBuyAiCreditsModal(engine: VekterEngine, source: ModalOpenSource) {\n\tengine.stores.modalStore.set({ type: ModalType.BuyAiCreditsModal, source })\n}\n\nexport function showAgentsUsage(engine: VekterEngine) {\n\tvoid engine.stores.siteSettingsStore\n\t\t.setActiveTab({ tab: SiteSettingsTabNames.usage, usageType: \"agents\" })\n\t\t.catch(unhandledError)\n}\n\nexport function isAiMonthlyCreditLimitReached(engine: VekterEngine): boolean {\n\tif (!isAiCreditLimitEnforced(engine)) return false\n\tconst limit = engine.stores.projectStore.resourceLimits?.aiCredits ?? null\n\tconst usage = engine.stores.projectStore.usageData?.aiCredits?.currentMonth ?? 0\n\treturn limit != null && usage >= limit\n}\n\nexport function isAiDailyCreditLimitReached(engine: VekterEngine): boolean {\n\tif (!isAiCreditLimitEnforced(engine)) return false\n\tconst limit = engine.stores.projectStore.resourceLimits?.aiCreditsDaily ?? null\n\tconst usage = engine.stores.projectStore.usageData?.aiCredits?.currentDay ?? 0\n\treturn limit != null && usage >= limit\n}\n\nexport function isAiCreditLimitReached(engine: VekterEngine): boolean {\n\treturn isAiDailyCreditLimitReached(engine) || isAiMonthlyCreditLimitReached(engine)\n}\n\nexport function showAiCreditLimitModal(engine: VekterEngine, source: ModalOpenSource, onNavigateToPlans?: () => void) {\n\tconst hasDailyLimit = typeof engine.stores.projectStore.resourceLimits?.aiCreditsDaily === \"number\"\n\tconst isDailyLimit = isAiDailyCreditLimitReached(engine)\n\n\tconst navigateToPlans =\n\t\tonNavigateToPlans ??\n\t\t(() =>\n\t\t\tengine.stores.siteSettingsStore\n\t\t\t\t.setActiveTab({ tab: SiteSettingsTabNames.plans, upsellFeature: UpsellFeature.aiCredits })\n\t\t\t\t.catch(unhandledError))\n\n\tengine.stores.modalStore.set({\n\t\ttype: ModalType.Confirmation,\n\t\tsource,\n\t\ttitle: \"Out of Credits\",\n\t\tdescription: isDailyLimit\n\t\t\t? \"Your workspace has used all available credits today. Agents and all other AI-powered features are now disabled.\"\n\t\t\t: \"Your workspace has used all available credits this month. Agents and all other AI-powered features are now disabled.\",\n\t\tconfirmLabel: hasDailyLimit ? \"Upgrade\" : \"Buy Credits\",\n\t\tcancelLabel: Dictionary.Dismiss,\n\t\t// onConfirm replaces the modal stack via modalStore.set, so block ConfirmModal's\n\t\t// trailing dismiss() \u2014 otherwise it would pop the modal we just opened.\n\t\tavoidDismissOnConfirm: !hasDailyLimit,\n\t\tonConfirm: hasDailyLimit ? navigateToPlans : () => showBuyAiCreditsModal(engine, source),\n\t})\n}\n\n/** Returns true and shows the credit-limit modal when the workspace has run out of AI credits. */\nexport function showAiCreditLimitModalIfReached(engine: VekterEngine, source: ModalOpenSource): boolean {\n\tif (!isAiCreditLimitReached(engine)) return false\n\tshowAiCreditLimitModal(engine, source)\n\treturn true\n}\n", "import { isString } from \"@framerjs/fresco/src/components/utils/typeCheck\"\nimport { parseHTML } from \"utils/parseHTML.ts\"\n\ntype ElementId = string\ntype AttributeName = string\ntype AttributeValue = string\n\nexport interface AttributeMap {\n\t[key: ElementId]: { [key: AttributeName]: AttributeValue }\n}\n\nexport function stripHtmlAttributes(html: string): { strippedHtml: string; attributeMap: AttributeMap } {\n\tconst container = parseHTML(html)\n\n\tlet idCounter = 1\n\tconst attributeMap: AttributeMap = {}\n\n\tconst elements = container.querySelectorAll(\"*\")\n\tfor (const element of elements) {\n\t\tconst attributes = Array.from(element.attributes)\n\t\tif (attributes.length === 0) continue\n\n\t\tconst id = idCounter.toString()\n\t\tidCounter += 1\n\n\t\tconst elementAttributes: { [key: AttributeName]: AttributeValue } = {}\n\t\tattributeMap[id] = elementAttributes\n\t\telement.setAttribute(\"id\", id)\n\n\t\tfor (const attribute of attributes) {\n\t\t\tif (attribute.name === \"id\") continue\n\n\t\t\telementAttributes[attribute.name] = attribute.value\n\t\t\telement.removeAttribute(attribute.name)\n\t\t}\n\t}\n\n\treturn { strippedHtml: container.innerHTML, attributeMap }\n}\n\nexport function applyHtmlAttributes(strippedHtml: string, attributeMap: AttributeMap): string {\n\tconst container = parseHTML(strippedHtml)\n\n\tconst elements = container.querySelectorAll(\"*\")\n\tfor (const element of elements) {\n\t\tconst id = element.getAttribute(\"id\")\n\t\tif (!isString(id)) continue\n\n\t\telement.removeAttribute(\"id\")\n\n\t\tconst attributes = attributeMap[id]\n\t\tif (!attributes) continue\n\n\t\tfor (const attributeName in attributes) {\n\t\t\tconst attributeValue = attributes[attributeName]\n\t\t\tif (!isString(attributeValue)) continue\n\t\t\telement.setAttribute(attributeName, attributeValue)\n\t\t}\n\t}\n\n\treturn container.innerHTML\n}\n", "import { getTemplateVariableNameRegex } from \"@framerjs/shared/src/custom-code/templateVariableRegexes.ts\"\nimport type { LocalizationSource } from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport type { GlossaryForLocale } from \"document/components/chrome/localization/glossaryUtils.ts\"\nimport { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { type AttributeMap, stripHtmlAttributes } from \"./stripHTMLAttributes.ts\"\n\ntype LocalizationSourceType = LocalizationSource[\"type\"]\n\nexport const systemPromptForStringTranslation =\n\t\"You are a translator that takes text from the user and responds with a JavaScript \" +\n\t\"object with a single `text` property with a string containing the translation. \" +\n\t\"Only respond with a single valid JavaScript object. Never return more than one object. \" +\n\t\"Keep in mind that your target audience is website visitors.\"\n\nexport const systemPromptForHtmlTranslation =\n\t\"You are a translator that takes HTML input from the user and responds with valid HTML in which the text is translated. \" +\n\t\"Maintain the integrity of the original HTML structure: do not add, remove, or alter HTML elements that are not directly related to the text content being translated. \" +\n\t\"Do not create or introduce new hyperlinks; preserve only the hyperlinks that exist in the original content.\" +\n\t\"Ensure that text values that are translated remain within the same HTML tags. \"\n\nconst generateSystemPromptForGlossaryTermTranslation = (glossaryTerms: GlossaryForLocale | null) => {\n\tif (!glossaryTerms || glossaryTerms.length === 0) return \"\"\n\n\treturn `\n<instructions>\nThe following glossary JSON describes a glossary of terms that you must take into account when you translate the text.\nThe glossary JSON is structured as an array of objects, with the shape {\"term\":<entire_term>,\"translation\":<translation>,\"caseSensitive\":boolean, \"description\": string. It contains the information how to handle text that matches the \"term\" field.\n\nFollow the matching rules to replace <entire_term> with <translation>.\n    1. For any \\`\"caseSensitive\":true\\` entry, do only substitute the <entire_term> with <translation> if the casing matches.\n    If casing does NOT match - do NOT apply glossary, and instead translate that occurrence normally (as if it were an ordinary word, not in the glossary).\n    <example>\n        Glossary: [{ term: \"Bird\", translation: \"Bird\", caseSensitive: true }]\n        Input: \"normal Bird, uppercased BIRD, lowercased bird\",\n        Target locale: dutch\n        Output: \"normale Bird, hoofdletters VOGEL, kleine letters vogel\"\n    </example>\n\n    2. For any \\`\"caseSensitive\":false\\` entry, substitute the <entire_term> with <translation>. DO maintain the casing of the original text.\n    <example>\n        Glossary: [{ term: \"Bird\", translation: \"Bird\", caseSensitive: false }]\n        Input: \"normal Bird, uppercased BIRD, lowercased bird\",\n        Target locale: dutch\n        Output: \"normale Bird, hoofdletters BIRD, kleine letters bird\"\n    </example>\n\nThe glossary json: ${JSON.stringify(glossaryTerms)}\n</instructions>\n`\n}\n\nfunction getSourceSpecificPromptInstructions(type: LocalizationSourceType, value: string): string {\n\tconst templateVariableNameRegex = getTemplateVariableNameRegex()\n\n\tif (type === ClassDiscriminator.WebPageNode && templateVariableNameRegex.exec(value)) {\n\t\treturn \"Ensure that any text between double curly brackets remains unchanged in the result.\"\n\t}\n\n\treturn \"\"\n}\n\n// Important! This prompt must include the word \"JSON\" so we can use\n// `response_type: \"json_object\"` in the OpenAI API.\nexport function getPromptForStringTranslation(\n\ttype: LocalizationSourceType,\n\tvalue: string,\n\ttranslationConfig: TranslationConfig,\n\tglossaryForLocale: GlossaryForLocale | null,\n): string {\n\treturn `You will translate a \"text\" property containing text in a JSON object using the following configuration:\n\n    ${JSON.stringify(translationConfig)}\n\n    ${generateSystemPromptForGlossaryTermTranslation(glossaryForLocale)}\n\n    This is the JSON object you need to translate:\n\n    {\"text\":${JSON.stringify(value)}}\n\n    ${getSourceSpecificPromptInstructions(type, value)}\n\n    Return a modified version of the JSON object where the \"text\" property has been translated.\n`\n}\n\nexport function getPromptForSlugTranslation(\n\tvalue: string,\n\ttranslationConfig: TranslationConfig,\n\tglossaryForLocale: GlossaryForLocale | null,\n): string {\n\treturn `You will translate a \"text\" property containing text in a JSON object using the following config:\n\n        ${JSON.stringify(translationConfig)}\n\n        Your text input is a slug. The translation should retain the slug format as well, which has the following rules:\n        - All characters should be lowercase.\n        - Use dashes (-) to separate words instead of spaces.\n        - Any leading or trailing whitespace should be removed.\n        - Any leading or trailing dashes should be removed.\n\n        ${generateSystemPromptForGlossaryTermTranslation(glossaryForLocale)}\n\n        This is the JSON object you need to translate.\n\n        {\"text\":${JSON.stringify(value)}}\n\n        Return a modified version of the JSON object where the \"text\" property has been translated into a valid slug.\n    `\n}\n\nexport interface TranslationConfig {\n\ttoLanguage: string\n\tfromLanguage?: string\n\tcustomTranslationInstructions?: string\n}\n\nexport function getPromptForHTMLTranslation(\n\tvalue: string,\n\ttranslationConfig: TranslationConfig,\n\tglossaryForLocale: GlossaryForLocale | null,\n): { prompt: string; attributeMap: AttributeMap } {\n\tconst { strippedHtml, attributeMap } = stripHtmlAttributes(value)\n\n\tconst prompt = `You will translate a \"html\" property in a JSON object using the following config:\n\n    ${JSON.stringify(translationConfig)}\n\n    ${generateSystemPromptForGlossaryTermTranslation(glossaryForLocale)}\n\n    This is the JSON object you need to translate:\n\n    {\"html\":${JSON.stringify(strippedHtml)}}\n\n    Return a modified version of the JSON where the \"html\" property has been translated and remains valid HTML.\n`\n\n\treturn { prompt, attributeMap }\n}\n", "const selfClosingTags = new Set([\"br\", \"input\", \"hr\", \"img\"])\n\ninterface TagInfo {\n\ttagName: string\n\topen: boolean\n}\n\nconst fixStreamingHtmlRegex = /<(\\/?)([a-z\\d]*)([^>]*)>/gi\n\n/** Fixes partially streamed HTML to be valid HTML. */\nexport function fixStreamingHTML(html: string): string {\n\tconst tagStack: TagInfo[] = []\n\n\tlet result = \"\"\n\tlet lastIdx = 0\n\tlet partialTag = \"\"\n\n\t// remove any incomplete trailing tags for which we don't have the tagname yet\n\tconst incompleteTagIndex = html.lastIndexOf(\"<\")\n\tif (incompleteTagIndex > -1 && !html.includes(\">\", incompleteTagIndex)) {\n\t\thtml = html.slice(0, incompleteTagIndex)\n\t}\n\n\t// also trim incomplete escape sequences at the end of the input\n\tif (html.endsWith(\"\\\\\")) {\n\t\thtml = html.slice(0, -1)\n\t}\n\n\t// eslint-disable-next-line no-constant-condition\n\twhile (true) {\n\t\t// eslint-disable-next-line framer-studio/no-global-regex-in-test-exec -- lastIndex is reset below.\n\t\tconst match = fixStreamingHtmlRegex.exec(html)\n\t\tif (match === null) {\n\t\t\tbreak\n\t\t}\n\t\tconst [fullMatch, closingSlash, tagName] = match\n\t\tconst isOpening = closingSlash !== \"/\"\n\t\tconst tagInfo: TagInfo | undefined = tagName\n\t\t\t? {\n\t\t\t\t\ttagName: tagName.toLowerCase(),\n\t\t\t\t\topen: isOpening,\n\t\t\t\t}\n\t\t\t: undefined\n\n\t\tif (isOpening) {\n\t\t\tif (partialTag) {\n\t\t\t\tresult += `<${partialTag}>`\n\t\t\t\ttagStack.push({ tagName: partialTag, open: true })\n\t\t\t\tpartialTag = \"\"\n\t\t\t}\n\t\t\tif (tagInfo) {\n\t\t\t\ttagStack.push(tagInfo)\n\t\t\t} else {\n\t\t\t\tpartialTag = \"\"\n\t\t\t}\n\t\t} else {\n\t\t\tlet lastTag = tagStack.pop()\n\t\t\twhile (lastTag) {\n\t\t\t\tif (lastTag.tagName === tagInfo?.tagName) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif (!selfClosingTags.has(lastTag.tagName)) {\n\t\t\t\t\tresult += `</${lastTag.tagName}>`\n\t\t\t\t}\n\t\t\t\tlastTag = tagStack.pop()\n\t\t\t}\n\t\t}\n\t\tif (!tagName && isOpening) {\n\t\t\tpartialTag = html.slice(lastIdx, match.index)\n\t\t} else {\n\t\t\tresult += html.slice(lastIdx, match.index) + fullMatch\n\t\t\tlastIdx = fixStreamingHtmlRegex.lastIndex\n\t\t}\n\t}\n\n\tfixStreamingHtmlRegex.lastIndex = 0\n\n\tresult += html.slice(lastIdx)\n\tif (partialTag) {\n\t\tresult += `<${partialTag}>`\n\t}\n\twhile (tagStack.length > 0) {\n\t\tconst lastTag = tagStack.pop() as TagInfo\n\n\t\tif (!selfClosingTags.has(lastTag.tagName)) {\n\t\t\tresult += `</${lastTag.tagName}>`\n\t\t}\n\t}\n\treturn result\n}\n", "import type { LocalizationSource } from \"./getLocalizationSources.ts\"\nimport { isHTMLBackedRichTextSource, isRichTextSource, isSlugSource } from \"./getLocalizationSources.ts\"\n\nexport type TranslationSourceType = \"html\" | \"text\" | \"slug\"\n\nexport function getTranslationSourceType(source: LocalizationSource): TranslationSourceType {\n\tif (isRichTextSource(source)) {\n\t\t// TODO(richTextJson): Support HTML-preserving translation for JSON-backed rich text and\n\t\t// remove this plain-text fallback.\n\t\tif (isHTMLBackedRichTextSource(source)) return \"html\"\n\t\treturn \"text\"\n\t}\n\tif (isSlugSource(source)) return \"slug\"\n\n\treturn \"text\"\n}\n", "import type { LocalizationGlossaryItemNode } from \"document/models/CanvasTree/nodes/LocalizationGlossaryItemNode.ts\"\nimport type { AnyLocalizationGlossaryNode } from \"document/models/CanvasTree/nodes/LocalizationGlossaryNode.ts\"\nimport { isLocalizationGlossaryNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { getHTMLTextContentPreservingNewLinesCached } from \"utils/getHTMLTextContent.ts\"\nimport type { LocalizationSource } from \"./getLocalizationSources.ts\"\nimport { getTranslationSourceType } from \"./getTranslationSourceType.ts\"\n\nexport interface GlossaryForLocaleItem {\n\tterm: string\n\tcaseSensitive: boolean\n\ttranslation: string\n\tdescription?: string\n}\n\nexport type GlossaryForLocale = GlossaryForLocaleItem[]\n\nexport function buildGlossaryForLocale(\n\tlocale: Locale,\n\tallLocales: readonly Locale[],\n\tglossaryNode: AnyLocalizationGlossaryNode | null,\n): GlossaryForLocale | null {\n\tif (!isLocalizationGlossaryNode(glossaryNode) || !glossaryNode.isLoaded()) return null\n\n\tconst relevantGlossaryTerms: GlossaryForLocale = []\n\n\tfor (const glossaryItem of glossaryNode.children) {\n\t\tconst { term, translatable, caseSensitive, description } = glossaryItem\n\n\t\tif (!term) continue\n\n\t\tlet translation: string | null = null\n\n\t\tif (!translatable) {\n\t\t\ttranslation = term\n\t\t} else {\n\t\t\ttranslation = getTranslationForLocale(locale.id, glossaryItem, allLocales)\n\t\t}\n\n\t\tif (!translation) continue\n\n\t\trelevantGlossaryTerms.push({\n\t\t\tterm,\n\t\t\tcaseSensitive,\n\t\t\ttranslation,\n\t\t\t...(description ? { description } : undefined),\n\t\t})\n\t}\n\n\treturn relevantGlossaryTerms.length ? relevantGlossaryTerms : null\n}\n\nexport function getTranslationForLocale(\n\tlocaleId: string,\n\tglossaryItem: LocalizationGlossaryItemNode,\n\tallLocales: readonly Locale[],\n): string | null {\n\tif (!glossaryItem.translatable) return null\n\n\tconst localeSpecificTranslation = glossaryItem.translations[localeId]?.value\n\n\tif (localeSpecificTranslation) return localeSpecificTranslation\n\n\tconst localeIndex = allLocales.findIndex(({ id, fallback }) => id === localeId && fallback !== localeId)\n\tconst locale = allLocales[localeIndex]\n\tif (!locale || !locale.fallback) return null\n\n\tconst localesLeft: readonly Locale[] = allLocales.toSpliced(localeIndex, 1)\n\n\treturn getTranslationForLocale(locale.fallback, glossaryItem, localesLeft)\n}\n\n/**\n * checks that\n * - source DOES NOT contain any terms from the glossary\n * or\n * - translation DOES contain the correct translation(s) for the glossary term(s)\n */\nexport function translationIsValidAccordingToGlossary(\n\tsource: LocalizationSource,\n\ttranslation: string,\n\tglossaryForLocale: GlossaryForLocale | null,\n): boolean {\n\tif (!glossaryForLocale) return true\n\n\tconst sourceType = getTranslationSourceType(source)\n\tconst plainTextValue =\n\t\tsourceType === \"html\" ? getHTMLTextContentPreservingNewLinesCached(source.value, \" \") : source.value\n\n\tconst lowercasedPlainTextValue = plainTextValue.toLowerCase()\n\tconst lowercasedTranslation = translation.toLowerCase()\n\n\tfor (const glossaryItem of glossaryForLocale) {\n\t\tconst { term, caseSensitive, translation: glossaryTranslation } = glossaryItem\n\n\t\tconst sourceContainsTerm = caseSensitive\n\t\t\t? plainTextValue.includes(term)\n\t\t\t: lowercasedPlainTextValue.includes(term.toLowerCase())\n\n\t\tif (!sourceContainsTerm) continue\n\n\t\tconst translationContainsCorrectTerm = caseSensitive\n\t\t\t? translation.includes(glossaryTranslation)\n\t\t\t: lowercasedTranslation.includes(glossaryTranslation.toLowerCase())\n\n\t\tif (!translationContainsCorrectTerm) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n", "import { Mixed, emptyArray, isMixed } from \"@framerjs/shared\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { LocalizedValue, LocalizedValueHash } from \"document/models/LocalizedValue.ts\"\nimport { getLocalizedValueText, isNonNullLocalizedValue } from \"document/models/LocalizedValue.ts\"\nimport type { RichTextDocument } from \"document/models/richText/RichTextDocument.ts\"\nimport type { LocalizationStore } from \"document/stores/LocalizationStore.ts\"\nimport { isString, isUndefined } from \"utils/typeChecks.ts\"\nimport {\n\ttype GlossaryForLocale,\n\ttype GlossaryForLocaleItem,\n\ttranslationIsValidAccordingToGlossary,\n} from \"./glossaryUtils.ts\"\nimport { forEachLocalizationSourceInGroup } from \"./localizationSourceGroupUtils.ts\"\n\nexport function getReusableTranslationsByHash(\n\tactiveLocale: Locale | null,\n\tlocalizationStore: LocalizationStore,\n\tglossaryForLocale: GlossaryForLocale | null,\n\thashesToInclude: Set<number>,\n\tlocalizedValueToExclude?: LocalizedValue<string | RichTextDocument>,\n): Map<LocalizedValueHash, string> {\n\t// Mixed means we found different translations for the same hash.\n\tconst reducedTranslationByHash: Map<LocalizedValueHash, string | Mixed> = new Map()\n\n\tif (!activeLocale) {\n\t\treturn new Map()\n\t}\n\n\tconst glossaryForLocaleItemByTerm = new Map<string, GlossaryForLocaleItem>(\n\t\tglossaryForLocale?.map(item => [item.term, item]) ?? emptyArray(),\n\t)\n\tconst translationToExclude = getReusableTranslation(localizedValueToExclude)\n\n\tif (localizationStore.groups && activeLocale) {\n\t\tforEachLocalizationSourceInGroup(localizationStore.groups, source => {\n\t\t\t// The source string of this item is not the same as the source of any of these translation(s)\n\t\t\tif (!hashesToInclude.has(source.hash)) return\n\n\t\t\t// If there is an exact glossary match, we should use that before any other matching translation\n\t\t\tconst glossaryItem = glossaryForLocaleItemByTerm.get(source.value)\n\t\t\tif (glossaryItem) {\n\t\t\t\treducedTranslationByHash.set(source.hash, glossaryItem.translation)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst status = source.localizedValueStatuses[activeLocale.id]\n\t\t\tif (status !== \"done\") return\n\n\t\t\tconst localizedValue = source.localizedValues[activeLocale.id]\n\t\t\tconst translation = getReusableTranslation(localizedValue)\n\t\t\tif (!translation || translation === translationToExclude) return\n\n\t\t\tconst currentValue = reducedTranslationByHash.get(source.hash)\n\t\t\tif (isMixed(currentValue)) return\n\n\t\t\t// Check that the matching translation is valid according to the glossary;\n\t\t\t// glossary terms may have been changed/added since the translation was created\n\t\t\tif (!translationIsValidAccordingToGlossary(source, translation, glossaryForLocale)) return\n\n\t\t\tif (isUndefined(currentValue)) {\n\t\t\t\treducedTranslationByHash.set(source.hash, translation)\n\t\t\t} else if (currentValue !== translation) {\n\t\t\t\treducedTranslationByHash.set(source.hash, Mixed)\n\t\t\t}\n\t\t})\n\t}\n\n\tconst translationByHash = new Map<LocalizedValueHash, string>()\n\n\tfor (const [hash, translation] of reducedTranslationByHash.entries()) {\n\t\tif (!isString(translation)) continue\n\n\t\ttranslationByHash.set(hash, translation)\n\t}\n\n\treturn translationByHash\n}\n\nfunction getReusableTranslation(\n\tlocalizedValue: LocalizedValue<string | RichTextDocument> | null | undefined,\n): string | undefined {\n\t// TODO(JSON rich text localization): Revisit this once reusable translations\n\t// can preserve full rich text instead of only reusing plain string content.\n\tif (!isNonNullLocalizedValue(localizedValue)) return\n\tif (isString(localizedValue.value)) return localizedValue.value\n\treturn getLocalizedValueText(localizedValue, { preserveNewLines: true })\n}\n", "import { Dictionary } from \"app/dictionary.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { showAiCreditLimitModal } from \"../shared/UpsellModal/utils/aiCreditsUpsell.ts\"\n\nconst automatedTranslationDisabledToastKey = \"automated-translation-credit-limit\"\n\nexport function showAutomatedTranslationDisabledToast(engine: VekterEngine) {\n\ttoast({\n\t\ttype: \"add\",\n\t\tkey: automatedTranslationDisabledToastKey,\n\t\tvariant: \"alert\",\n\t\ticon: \"warning\",\n\t\tprimaryText: \"Auto translate\",\n\t\tsecondaryText: \"is disabled.\",\n\t\tduration: 5000,\n\t\tshowCloseButton: \"never\",\n\t\taction: {\n\t\t\ttitle: Dictionary.LearnMore,\n\t\t\tonClick: () => showAiCreditLimitModal(engine, \"toast\"),\n\t\t},\n\t})\n}\n", "import { ProjectLicenseType } from \"@framerjs/app-shared/src/ProjectLicense.ts\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { assert, delay, emptyArray, getLogger, unhandledError } from \"@framerjs/shared\"\nimport { type ModelMessage, streamText } from \"ai\"\nimport { isAiCreditLimitError } from \"app/ai/aiServiceError.ts\"\nimport { createVekterOpenRouterExtraBody, openRouter } from \"app/ai/config/openRouter.ts\"\nimport { LanguageModel } from \"app/ai/languageModels.ts\"\nimport { getReasoningForTranslationModel } from \"app/ai/models.ts\"\nimport {\n\ttype TranslationConfig,\n\tgetPromptForHTMLTranslation,\n\tgetPromptForSlugTranslation,\n\tgetPromptForStringTranslation,\n\tsystemPromptForHtmlTranslation,\n\tsystemPromptForStringTranslation,\n} from \"app/ai/translation/prompts.ts\"\nimport { experimentIsOnOrForceEnabled } from \"app/experiments.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { LocalizationGlossaryNode } from \"document/models/CanvasTree/nodes/LocalizationGlossaryNode.ts\"\nimport { isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { LocalizedValueHash } from \"document/models/LocalizedValue.ts\"\nimport { SloppyJavaScriptParser } from \"document/utils/SloppyJavaScriptParser.ts\"\nimport { clamp } from \"framer-motion\"\nimport { assertNever } from \"library/utils/assert.ts\"\nimport { createEditorState } from \"prosemirror/editorState.ts\"\nimport { fullSchemaParams, makeSchema } from \"prosemirror/schema/index.ts\"\nimport { serializeRichText } from \"prosemirror/serialization/dom.ts\"\nimport { getFirstItemFromIterable } from \"utils/getFirstItemFromIterable.ts\"\nimport { getHTMLTextContentPreservingNewLinesCached } from \"utils/getHTMLTextContent.ts\"\nimport { isShallowEqual } from \"utils/isShallowEqual.ts\"\nimport { isObject, isString } from \"utils/typeChecks.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport { type AttributeMap, applyHtmlAttributes } from \"../../../../app/ai/translation/stripHTMLAttributes.ts\"\nimport { showAiCreditLimitModal } from \"../shared/UpsellModal/utils/aiCreditsUpsell.ts\"\nimport { canBeBatchTranslated } from \"./canBeBatchTranslated.ts\"\nimport { fixStreamingHTML } from \"./fixStreamingHTML.ts\"\nimport { getCodeGenerationScopeId } from \"./getCodeGenerationScopeId.ts\"\nimport type { LocalizationSource } from \"./getLocalizationSources.ts\"\nimport { isRichTextControlPropSource } from \"./getLocalizationSources.ts\"\nimport { getReusableTranslationsByHash } from \"./getReusableTranslationsByHash.ts\"\nimport { type TranslationSourceType, getTranslationSourceType } from \"./getTranslationSourceType.ts\"\nimport { type GlossaryForLocale, buildGlossaryForLocale } from \"./glossaryUtils.ts\"\nimport {\n\thydrateTranslatedRichTextModules,\n\tisRichTextModuleTranslationError,\n\tprepareRichTextModulesForTranslation,\n} from \"./richTextModuleTranslation.ts\"\nimport { showAutomatedTranslationDisabledToast } from \"./translationCreditLimit.ts\"\nimport { setLocalizedValue } from \"./updateLocalizedValue.ts\"\n\nconst parallelTranslationsTasks = 6\n\nconst log = getLogger(\"BatchTranslation\")\n\ntype KeyPath = string\n\ntype TranslationTaskState = { type: \"translating\"; value: string } | { type: \"error\" } | { type: \"done\"; value: string }\nexport type TranslationTaskFinishedState = Extract<TranslationTaskState, { type: \"done\" | \"error\" }>\n\nfunction applyProseMirrorSchema(html: string) {\n\tconst schema = makeSchema(fullSchemaParams)\n\tconst editorState = createEditorState(html, schema)\n\treturn serializeRichText(editorState.doc, schema)\n}\n\ntype TranslationUIContext = \"singleTranslation\" | \"batch\" | \"automated\"\n\nfunction showTranslationErrorToast(uiContext: TranslationUIContext) {\n\ttoast({\n\t\ttype: \"add\",\n\t\tkey: `${uiContext}-translation-error`,\n\t\tvariant: \"alert\",\n\t\ticon: \"warning\",\n\t\tprimaryText: uiContext === \"batch\" ? \"Some translations failed.\" : \"Translation failed.\",\n\t\tsecondaryText: uiContext === \"batch\" ? `Continuing with the rest\u2026` : \"Please try again.\",\n\t\tduration: 5000,\n\t\tshowCloseButton: \"never\",\n\t})\n}\n\nfunction notifyTranslationError(engine: VekterEngine, error: unknown, uiContext: TranslationUIContext) {\n\tif (isAiCreditLimitError(error)) {\n\t\tif (uiContext === \"automated\") {\n\t\t\tshowAutomatedTranslationDisabledToast(engine)\n\t\t} else {\n\t\t\tshowAiCreditLimitModal(engine, uiContext === \"batch\" ? \"localization_table\" : \"properties\")\n\t\t}\n\t\treturn\n\t}\n\n\tshowTranslationErrorToast(uiContext)\n}\n\ntype TranslationTaskBehavior = \"parseWhileStreaming\" | \"parseWhenFinished\"\ntype TranslationTaskChangeHandler = (state: TranslationTaskState) => void\n\nfunction reduceGlossaryLocale(\n\tglossaryForLocale: GlossaryForLocale | null,\n\tsourceValue: string,\n\tsourceType: TranslationSourceType,\n): GlossaryForLocale | null {\n\tif (!glossaryForLocale) return null\n\n\t// For html sources, replace newlines with a space so we don't get words from different paragraphs merged together\n\tconst plainTextValue =\n\t\tsourceType === \"html\" ? getHTMLTextContentPreservingNewLinesCached(sourceValue, \" \") : sourceValue\n\tconst lowercasedPlainTextValue = plainTextValue.toLowerCase()\n\n\tconst filteredGlossary = glossaryForLocale.filter(glossaryItem => {\n\t\tif (glossaryItem.caseSensitive) {\n\t\t\treturn plainTextValue.includes(glossaryItem.term)\n\t\t}\n\n\t\tconst lowercasedTerm = glossaryItem.term.toLowerCase()\n\t\treturn lowercasedPlainTextValue.includes(lowercasedTerm)\n\t})\n\n\treturn filteredGlossary.length ? filteredGlossary : null\n}\n\nfunction chooseModel(\n\tlocale: Locale,\n\tglossaryForLocale: GlossaryForLocale | null,\n\tprojectLicenseType: ProjectLicenseType,\n\tframerSiteId?: string,\n): LanguageModel {\n\tconst localizationAiUpdateExperimentEnabled = experimentIsOnOrForceEnabled(\"localizationAiUpdate\", framerSiteId)\n\tif (localizationAiUpdateExperimentEnabled) {\n\t\tif (projectLicenseType === ProjectLicenseType.EnterpriseSite && locale.aiModel) return locale.aiModel\n\n\t\t// Now that we allow users to opt-in to better/more expensive models, we can default to a more balanced one\n\t\treturn LanguageModel.Gemini35Flash\n\t}\n\n\tif (experimentIsOnOrForceEnabled(\"translationModelGemini3Flash\", framerSiteId)) {\n\t\treturn LanguageModel.Gemini3Flash\n\t}\n\n\t// GPT Omni is the only model able to reliably handle glossary terms\n\tif (glossaryForLocale) return LanguageModel.OmniModel\n\t// GPT Omni listens to custom AI instructions a lot better than GPT Omni mini. So we use it when\n\t// custom AI instructions are set\n\tif (locale.customAiInstructions) return LanguageModel.OmniModel\n\treturn LanguageModel.OmniModelMini\n}\n\nexport class TranslationTask {\n\tprivate abortController = new AbortController()\n\tprivate parser: SloppyJavaScriptParser\n\tprivate streamedText = \"\"\n\tprivate engine: VekterEngine\n\tprivate uiContext: TranslationUIContext\n\n\treadonly source: LocalizationSource\n\treadonly onChange: TranslationTaskChangeHandler\n\treadonly behavior: TranslationTaskBehavior\n\treadonly componentLoader: ComponentLoader\n\n\tpromise: Promise<TranslationTaskFinishedState>\n\n\tprivate _state: TranslationTaskState = { type: \"translating\", value: \"\" }\n\n\tget state() {\n\t\treturn this._state\n\t}\n\n\tget progress() {\n\t\tconst state = this.state\n\t\tif (state.type !== \"translating\") return 1\n\n\t\t// Only when listening for streaming changes we parse the value mid-stream\n\t\tconst translatedValueLength =\n\t\t\tthis.behavior === \"parseWhileStreaming\" ? state.value.length : this.streamedText.length\n\t\tconst originalValueLength = this.source.value.length\n\n\t\tconst ratio = translatedValueLength / Math.max(originalValueLength, 1)\n\t\tconst safeRatio = clamp(0, 1, ratio)\n\n\t\treturn safeRatio * 0.8\n\t}\n\n\tprivate updateState(state: TranslationTaskState) {\n\t\t// Only when currently translating we can update the state, all other states (done & error)\n\t\t// are immutable.\n\t\tif (this.state.type !== \"translating\") return\n\t\tthis._state = state\n\t\tthis.onChange(state)\n\t}\n\n\tprivate parseStreamedText() {\n\t\tif (!this.streamedText) return\n\n\t\tthis.parser.add(this.streamedText)\n\t\tthis.streamedText = \"\"\n\t}\n\n\tprivate textStreamUpdate(text: string) {\n\t\tthis.streamedText += text\n\n\t\tif (this.behavior === \"parseWhileStreaming\") {\n\t\t\tthis.parseStreamedText()\n\t\t} else {\n\t\t\t// Notify change listeners for progress updates but without expensive parsing.\n\t\t\tthis.onChange(this.state)\n\t\t}\n\t}\n\n\tcancel() {\n\t\tthis.updateState({ type: \"error\" })\n\t\tthis.abortController.abort()\n\t}\n\n\tconstructor({\n\t\tengine,\n\t\tsource,\n\t\tlocale,\n\t\tfromLanguage,\n\t\tonChange,\n\t\tbehavior,\n\t\tglossaryForLocale,\n\t\tframerSiteId,\n\t\tprojectLicenseType,\n\t\tsessionId,\n\t\tuiContext,\n\t\tcomponentLoader,\n\t}: {\n\t\tengine: VekterEngine\n\t\tsource: LocalizationSource\n\t\tbehavior: TranslationTaskBehavior\n\t\tlocale: Locale\n\t\tfromLanguage: string | undefined\n\t\tonChange: TranslationTaskChangeHandler\n\t\tglossaryForLocale: GlossaryForLocale | null\n\t\tframerSiteId: string | undefined\n\t\tprojectLicenseType: ProjectLicenseType\n\t\tsessionId: string\n\t\tuiContext: TranslationUIContext\n\t\tcomponentLoader: ComponentLoader\n\t}) {\n\t\tthis.engine = engine\n\t\tthis.source = source\n\t\tthis.onChange = onChange\n\t\tthis.behavior = behavior\n\t\tthis.uiContext = uiContext\n\t\tthis.componentLoader = componentLoader\n\n\t\tconst sourceType = getTranslationSourceType(source)\n\t\tconst messages: ModelMessage[] = []\n\t\tlet attributes: AttributeMap | undefined\n\n\t\tconst translationConfig: TranslationConfig = {\n\t\t\ttoLanguage: `${locale.name} (${locale.code})`,\n\t\t}\n\n\t\tif (fromLanguage) {\n\t\t\ttranslationConfig.fromLanguage = fromLanguage\n\t\t}\n\n\t\tif (locale.customAiInstructions) {\n\t\t\ttranslationConfig.customTranslationInstructions = locale.customAiInstructions\n\t\t}\n\n\t\t// HTML-backed rich text control props keep source.value as HTML, and also carry it in\n\t\t// source.richTextValue. Canvas rich text nodes have HTML in source.value directly.\n\t\t// TODO(richTextJson): Support HTML-preserving translation for JSON-backed rich text and\n\t\t// remove this plain-text fallback.\n\t\tconst sourceValueForTranslation =\n\t\t\tisRichTextControlPropSource(source) && typeof source.richTextValue === \"string\"\n\t\t\t\t? prepareRichTextModulesForTranslation(source.richTextValue, componentLoader)\n\t\t\t\t: source.value\n\t\tconst reducedGlossaryLocale = reduceGlossaryLocale(glossaryForLocale, sourceValueForTranslation, sourceType)\n\n\t\tswitch (sourceType) {\n\t\t\tcase \"html\": {\n\t\t\t\tconst { prompt, attributeMap } = getPromptForHTMLTranslation(\n\t\t\t\t\tsourceValueForTranslation,\n\t\t\t\t\ttranslationConfig,\n\t\t\t\t\treducedGlossaryLocale,\n\t\t\t\t)\n\n\t\t\t\tmessages.push({ role: \"system\", content: systemPromptForHtmlTranslation }, { role: \"user\", content: prompt })\n\t\t\t\tattributes = attributeMap\n\n\t\t\t\tthis.parser = new SloppyJavaScriptParser((value, isFinal) => {\n\t\t\t\t\tif (!isObject(value)) return // Something went wrong.\n\t\t\t\t\tif (!isString(value.html)) return\n\n\t\t\t\t\tassert(attributes, \"Attribute map should be defined for HTML\")\n\n\t\t\t\t\tlet hydratedHtml: string\n\t\t\t\t\ttry {\n\t\t\t\t\t\thydratedHtml = hydrateTranslatedRichTextModules(\n\t\t\t\t\t\t\tapplyHtmlAttributes(fixStreamingHTML(value.html), attributes),\n\t\t\t\t\t\t\tcomponentLoader,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstrict: isFinal,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t// Structural mismatches are expected on partial streams (helper nodes not yet closed,\n\t\t\t\t\t\t// signatures not yet emitted, etc.); wait for more tokens. Strict validation still\n\t\t\t\t\t\t// runs on the final value.\n\t\t\t\t\t\tif (!isFinal && isRichTextModuleTranslationError(error)) return\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t\tconst parsedValue = applyProseMirrorSchema(hydratedHtml)\n\n\t\t\t\t\tthis.updateState({ type: \"translating\", value: parsedValue })\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase \"slug\":\n\t\t\tcase \"text\": {\n\t\t\t\tconst userPrompt =\n\t\t\t\t\tsourceType === \"slug\"\n\t\t\t\t\t\t? getPromptForSlugTranslation(source.value, translationConfig, reducedGlossaryLocale)\n\t\t\t\t\t\t: getPromptForStringTranslation(source.type, source.value, translationConfig, reducedGlossaryLocale)\n\n\t\t\t\tmessages.push(\n\t\t\t\t\t{ role: \"system\", content: systemPromptForStringTranslation },\n\t\t\t\t\t{ role: \"user\", content: userPrompt },\n\t\t\t\t)\n\n\t\t\t\tthis.parser = new SloppyJavaScriptParser(value => {\n\t\t\t\t\tif (!isObject(value)) return // Something went wrong.\n\t\t\t\t\tif (!isString(value.text)) return\n\n\t\t\t\t\tthis.updateState({ type: \"translating\", value: value.text })\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tassertNever(sourceType)\n\t\t\t}\n\t\t}\n\n\t\tconst model = chooseModel(locale, reducedGlossaryLocale, projectLicenseType, framerSiteId)\n\t\tconst reasoning = getReasoningForTranslationModel(model)\n\n\t\tconst generationStartedAt = performance.now()\n\n\t\tthis.promise = this.streamTranslation(model, messages, reasoning, generationStartedAt, sessionId)\n\t}\n\n\tprivate async streamTranslation(\n\t\tmodel: LanguageModel,\n\t\tmessages: ModelMessage[],\n\t\treasoning: ReturnType<typeof getReasoningForTranslationModel>,\n\t\tgenerationStartedAt: number,\n\t\tsessionId: string,\n\t): Promise<TranslationTaskFinishedState> {\n\t\ttry {\n\t\t\tconst { textStream } = streamText({\n\t\t\t\tmodel: openRouter(model, {\n\t\t\t\t\treasoning,\n\t\t\t\t\textraBody: createVekterOpenRouterExtraBody({\n\t\t\t\t\t\tfeatureCategory: \"translation\",\n\t\t\t\t\t\tfeatureName: \"translation\",\n\t\t\t\t\t\tstep: \"translate\",\n\t\t\t\t\t\tsessionId,\n\t\t\t\t\t}),\n\t\t\t\t}),\n\t\t\t\tmessages,\n\t\t\t\tproviderOptions: {\n\t\t\t\t\topenrouter: { response_format: { type: \"json_object\" } },\n\t\t\t\t},\n\t\t\t\tabortSignal: this.abortController.signal,\n\t\t\t\tonError: ({ error }) => {\n\t\t\t\t\t// The error is swallowed by default, so we need to rethrow so that our catch\n\t\t\t\t\t// block shows the error toast\n\t\t\t\t\tthrow error\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tfor await (const textPart of textStream) {\n\t\t\t\tthis.textStreamUpdate(textPart)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.error(error)\n\t\t\tnotifyTranslationError(this.engine, error, this.uiContext)\n\n\t\t\tthis.updateState({ type: \"error\" })\n\t\t}\n\n\t\tlet streamLength = 0\n\t\ttry {\n\t\t\tthis.parseStreamedText()\n\t\t\tstreamLength = this.parser.end().jsLength\n\t\t} catch (error) {\n\t\t\tlog.error(error)\n\t\t\tnotifyTranslationError(this.engine, error, this.uiContext)\n\t\t\tthis.updateState({ type: \"error\" })\n\t\t}\n\n\t\tlet finalState = this.state\n\n\t\tif (finalState.type === \"translating\") {\n\t\t\tif (finalState.value) {\n\t\t\t\tfinalState = { type: \"done\", value: finalState.value }\n\t\t\t} else {\n\t\t\t\tfinalState = { type: \"error\" }\n\t\t\t}\n\t\t}\n\n\t\tthis.updateState(finalState)\n\t\tconst isSuccess = finalState.type === \"done\"\n\t\trecordTaskResult(isSuccess, streamLength, generationStartedAt)\n\t\treturn finalState\n\t}\n}\n\nfunction recordTaskResult(isSuccess: boolean, streamLength: number, generationStartedAt: number) {\n\tconst event = isSuccess ? \"localized_task_ai_translation_success\" : \"localized_task_ai_translation_error\"\n\tconst now = performance.now()\n\tconst durationMilliseconds = now - generationStartedAt\n\tconst durationSeconds = durationMilliseconds / 1_000\n\trecord(event, {\n\t\tdurationSeconds: Math.round(durationSeconds),\n\t\tcharactersPerSecond: Math.round(streamLength / durationSeconds),\n\t})\n}\n\n/** Means we couldn't translate it so we don't want to save it. */\nconst ignore = Symbol(\"Ignore\")\n/** Means we couldn't translate it so we don't want to save it. */\ntype Ignore = typeof ignore\n\ninterface TranslationContext {\n\treadonly engine: VekterEngine\n\treadonly reusableTranslationsByHash: Map<LocalizedValueHash, string>\n\treadonly taskByHash: Map<LocalizedValueHash, TranslationTask>\n\treadonly activeLocale: Locale\n\treadonly glossaryForLocale: GlossaryForLocale | null\n\treadonly sessionId: string\n}\n\nclass BatchTranslationScope {\n\tprivate _state: \"idle\" | \"translating\" | \"readyForSave\" | \"saving\" | \"done\" | \"canceled\" = \"idle\"\n\tprivate persistencePromise: Promise<void> | null = null\n\n\tget state() {\n\t\treturn this._state\n\t}\n\n\tprivate readonly tasks: Set<TranslationTask> = new Set()\n\tprivate readonly finishedToDos: Map<KeyPath, string | Ignore> = new Map()\n\tprivate readonly toDos: Set<KeyPath> = new Set()\n\n\treadonly totalItemSize: number\n\n\tget finishedItemSize() {\n\t\tif (this.state === \"idle\") return 0\n\t\tif (this.state !== \"translating\") return this.totalItemSize\n\n\t\tlet finishedItemSize = 0\n\n\t\tfor (const keyPath of this.initialToDos) {\n\t\t\tconst source = this.context.engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\t\tif (!source) continue\n\n\t\t\tif (this.finishedToDos.has(keyPath)) {\n\t\t\t\tfinishedItemSize += source.value.length\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst task = this.context.taskByHash.get(source.hash)\n\t\t\tif (!task) continue\n\t\t\tfinishedItemSize += task.progress * source.value.length\n\t\t}\n\n\t\treturn Math.min(this.totalItemSize, finishedItemSize)\n\t}\n\n\tget totalItemCount() {\n\t\treturn this.initialToDos.size\n\t}\n\n\tget finishedItemCount() {\n\t\treturn this.finishedToDos.size\n\t}\n\n\tget progress() {\n\t\treturn this.finishedItemCount / this.totalItemCount\n\t}\n\n\tconstructor(\n\t\treadonly scopeId: NodeID,\n\t\treadonly codeGenerationScopeId: NodeID,\n\t\treadonly initialToDos: ReadonlySet<KeyPath>,\n\t\treadonly context: TranslationContext,\n\t\treadonly onChangeProgress: VoidFunction,\n\t) {\n\t\tthis.toDos = new Set(initialToDos)\n\n\t\tlet totalItemSize = 0\n\n\t\tfor (const keyPath of initialToDos) {\n\t\t\tconst source = context.engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\t\tif (!source) continue\n\t\t\ttotalItemSize += source.value.length\n\t\t}\n\n\t\tthis.totalItemSize = totalItemSize\n\t}\n\n\tcancel() {\n\t\tif (this._state === \"done\") return\n\t\tif (this._state === \"canceled\") return\n\n\t\tthis._state = \"canceled\"\n\t\tthis.tasks.forEach(task => task.cancel())\n\t}\n\n\tprivate hasFinishedTranslations() {\n\t\tfor (const valueForKeyPath of this.finishedToDos.values()) {\n\t\t\tif (isString(valueForKeyPath)) return true\n\t\t}\n\n\t\treturn false\n\t}\n\n\tasync save() {\n\t\tassert(this._state === \"readyForSave\", \"Can only save from readyForSave\")\n\t\tawait this.runPersistence(\"Saving scope\")\n\t}\n\n\tasync stopAndSavePartial() {\n\t\tassert(this._state === \"translating\", \"Can only cancel & save partial when translating\")\n\n\t\tconst completedTasks = Array.from(this.tasks).filter(task => task.state.type === \"done\")\n\n\t\tthis.cancel()\n\n\t\tawait Promise.allSettled(completedTasks.map(task => task.promise))\n\n\t\tif (!this.hasFinishedTranslations()) {\n\t\t\tthis._state = \"done\"\n\t\t\treturn\n\t\t}\n\n\t\tawait this.runPersistence(\"Saving partial scope\")\n\t}\n\n\twaitForPersistence() {\n\t\treturn this.persistencePromise ?? Promise.resolve()\n\t}\n\n\tprivate async runPersistence(logLabel: string) {\n\t\tthis.persistencePromise = this.persistFinishedTranslations(logLabel)\n\t\tawait this.persistencePromise\n\t}\n\n\tprivate async persistFinishedTranslations(logLabel: string) {\n\t\tthis._state = \"saving\"\n\n\t\tlog.debug(`${logLabel}: ${this.scopeId}`)\n\t\tthis.updateTree()\n\n\t\tconst codeGenerationTimeout = delay(15_000)\n\n\t\tconst codeGenerationMetrics = this.context.engine.stores.codeGenerationStore.getMetrics()\n\n\t\tawait Promise.race([\n\t\t\tthis.context.engine.stores.codeGenerationStore\n\t\t\t\t.generateAndPersistAllQueuedComponents()\n\t\t\t\t.then(() => \"done\" as const),\n\t\t\tcodeGenerationTimeout.then(() => \"timeout\" as const),\n\t\t]).then(result => {\n\t\t\t// We still continue from a timeout because it's probably going to succeed at some point\n\t\t\t// and we don't want to completely block follow-up scopes from saving.\n\t\t\tif (result === \"timeout\") {\n\t\t\t\tlog.debug(\"Code generation timed out\")\n\t\t\t\tlog.reportError(\"Batch translation timed out\", codeGenerationMetrics)\n\t\t\t}\n\t\t})\n\n\t\tif (this._state === \"saving\") {\n\t\t\tthis._state = \"done\"\n\t\t}\n\n\t\tlog.debug(`Done saving scope: ${this.scopeId}`)\n\t}\n\n\tprivate updateTree() {\n\t\tconst { engine, activeLocale } = this.context\n\n\t\tfor (const [keyPath, valueForKeyPath] of this.finishedToDos) {\n\t\t\tif (!isString(valueForKeyPath)) continue\n\n\t\t\tconst source = engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\t\tif (!source) continue\n\n\t\t\tif (!canBeBatchTranslated(activeLocale, source, engine.stores.previewStore.framerSiteId)) continue\n\n\t\t\ttry {\n\t\t\t\tsetLocalizedValue(engine, valueForKeyPath, source, activeLocale, {\n\t\t\t\t\tgeneratedByAI: true,\n\t\t\t\t\ttrackingSource: \"batch-translate-modal\",\n\t\t\t\t\tignoreTracking: true,\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tunhandledError(error)\n\t\t\t}\n\t\t}\n\t}\n\n\tcanStartTask() {\n\t\treturn (this.state === \"translating\" || this.state === \"idle\") && this.toDos.size > 0\n\t}\n\n\tasync startTask(): Promise<void> {\n\t\tassert(this.canStartTask(), \"Can only start task when translating or idle\")\n\n\t\tif (this.state === \"idle\") {\n\t\t\tthis._state = \"translating\"\n\t\t}\n\n\t\tconst source = this.getNextSource()\n\t\tassert(source, \"Expected source\")\n\n\t\tlog.debug(`Adding task. scope: ${this.scopeId}, keyPath: ${source.keyPath}`)\n\n\t\t// Using existing translation if it exists\n\t\tconst preexistingTranslation = this.context.reusableTranslationsByHash.get(source.hash)\n\t\tif (isString(preexistingTranslation)) {\n\t\t\tthis.finishToDo(source.keyPath, source, preexistingTranslation)\n\t\t\tlog.debug(\"Updating value using existing translation\")\n\t\t\treturn\n\t\t}\n\n\t\tconst task =\n\t\t\tthis.context.taskByHash.get(source.hash) ??\n\t\t\tnew TranslationTask({\n\t\t\t\tengine: this.context.engine,\n\t\t\t\tsource,\n\t\t\t\tbehavior: \"parseWhenFinished\",\n\t\t\t\tlocale: this.context.activeLocale,\n\t\t\t\tfromLanguage: this.context.engine.tree.root.webMetadata?.language,\n\t\t\t\tonChange: this.onChangeProgress,\n\t\t\t\tglossaryForLocale: this.context.glossaryForLocale,\n\t\t\t\tframerSiteId: this.context.engine.stores.previewStore.framerSiteId,\n\t\t\t\tprojectLicenseType: this.context.engine.stores.projectStore.projectLicenseType,\n\t\t\t\tsessionId: this.context.sessionId,\n\t\t\t\tuiContext: \"batch\",\n\t\t\t\tcomponentLoader: this.context.engine.componentLoader,\n\t\t\t})\n\t\tthis.tasks.add(task)\n\t\tthis.context.taskByHash.set(source.hash, task)\n\n\t\tawait task.promise\n\t\t\t.then(() => {\n\t\t\t\tif (task.state.type === \"done\") {\n\t\t\t\t\tthis.context.reusableTranslationsByHash.set(source.hash, task.state.value)\n\t\t\t\t\tthis.finishToDo(source.keyPath, source, task.state.value)\n\t\t\t\t} else {\n\t\t\t\t\tthis.finishToDo(source.keyPath, source, ignore)\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.finishToDo(source.keyPath, source, ignore)\n\t\t\t})\n\t}\n\n\tprivate finishToDo(keyPath: KeyPath, source: LocalizationSource | undefined, value: string | Ignore) {\n\t\tassert(!this.toDos.has(keyPath))\n\t\tassert(!this.finishedToDos.has(keyPath))\n\n\t\tif (value !== ignore && source) {\n\t\t\tthis.context.reusableTranslationsByHash.set(source.hash, value)\n\t\t}\n\t\tthis.finishedToDos.set(keyPath, value)\n\n\t\tif (this.state !== \"translating\") return\n\n\t\tif (this.finishedToDos.size === this.initialToDos.size) {\n\t\t\tlog.debug(`Finished translating scope: ${this.scopeId}`)\n\t\t\tthis._state = \"readyForSave\"\n\t\t}\n\n\t\tthis.onChangeProgress()\n\t}\n\n\tprivate getNextSource(): LocalizationSource | null {\n\t\tif (this._state !== \"translating\") return null\n\n\t\tconst keyPath = this.getNextKeyPath()\n\t\tif (!keyPath) return null\n\n\t\tconst source = this.context.engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\tif (!source) {\n\t\t\tthis.finishToDo(keyPath, undefined, ignore)\n\t\t\treturn this.getNextSource()\n\t\t}\n\n\t\tif (\n\t\t\t!canBeBatchTranslated(this.context.activeLocale, source, this.context.engine.stores.previewStore.framerSiteId)\n\t\t) {\n\t\t\tthis.finishToDo(keyPath, source, ignore)\n\t\t\treturn this.getNextSource()\n\t\t}\n\n\t\treturn source\n\t}\n\n\tprivate getNextKeyPath(): KeyPath | null {\n\t\tif (this._state !== \"translating\") return null\n\n\t\tconst keyPath = getFirstItemFromIterable(this.toDos)\n\t\tif (!keyPath) return null\n\n\t\tthis.toDos.delete(keyPath)\n\t\treturn keyPath\n\t}\n}\n\ntype BatchTranslationState =\n\t| {\n\t\t\ttype: \"idle\"\n\t\t\tfinishedCount: 0\n\t\t\tprogress: 0\n\t  }\n\t| {\n\t\t\ttype: \"translating\"\n\t\t\tfinishedCount: number\n\t\t\tprogress: number\n\t  }\n\t| {\n\t\t\ttype: \"persistingPartialResults\"\n\t\t\tfinishedCount: number\n\t\t\tprogress: number\n\t  }\n\t| {\n\t\t\ttype: \"done\"\n\t\t\tfinishedCount: number\n\t\t\tprogress: 1\n\t  }\n\t| {\n\t\t\ttype: \"stopped\"\n\t\t\tfinishedCount: number\n\t\t\tprogress: number\n\t  }\n\nexport const initialBatchTranslationState: BatchTranslationState = {\n\ttype: \"idle\",\n\tfinishedCount: 0,\n\tprogress: 0,\n}\n\nObject.freeze(initialBatchTranslationState)\n\ntype ResumeCodeGeneration = VoidFunction\n\nexport class BatchTranslation {\n\tprivate _state: BatchTranslationState = initialBatchTranslationState\n\n\tprivate readonly scopes: readonly BatchTranslationScope[]\n\tprivate readonly context: TranslationContext\n\tprivate readonly pausedCodeGenerationScopes: Map<NodeID, ResumeCodeGeneration> = new Map()\n\n\tprivate readonly buckets: {\n\t\ttoDo: Set<BatchTranslationScope>\n\t\tinProgress: Set<BatchTranslationScope>\n\t\tfinished: Set<BatchTranslationScope>\n\t}\n\n\tprivate batchStartedAt: number | undefined\n\n\tget state() {\n\t\treturn this._state\n\t}\n\n\tget isDone() {\n\t\treturn this._state.type === \"done\" || this._state.type === \"stopped\"\n\t}\n\n\tget isPersistingPartialResults() {\n\t\treturn this._state.type === \"persistingPartialResults\"\n\t}\n\n\tprivate updateState(state: BatchTranslationState) {\n\t\tif (isShallowEqual(this._state, state)) return\n\t\tthis.onStateChange(state)\n\t\tthis._state = state\n\t}\n\n\tconstructor(\n\t\tprivate engine: VekterEngine,\n\t\tprivate activeLocale: Locale,\n\t\tinitialToDo: ReadonlySet<KeyPath>,\n\t\tprivate readonly onStateChange: (state: BatchTranslationState) => void,\n\t) {\n\t\tconst tree = engine.stores.treeStore.getDataTreeOrPartialTree()\n\t\tconst glossaryForLocale = buildGlossaryForLocale(\n\t\t\tactiveLocale,\n\t\t\ttree.root.locales || emptyArray(),\n\t\t\tLocalizationGlossaryNode.get(tree),\n\t\t)\n\t\tconst reusableTranslationsByHash = getReusableTranslationsByHash(\n\t\t\tactiveLocale,\n\t\t\tengine.stores.localizationStore,\n\t\t\tglossaryForLocale,\n\t\t\tthis.getHashesForInitialToDo(initialToDo),\n\t\t)\n\t\tthis.context = {\n\t\t\tengine,\n\t\t\treusableTranslationsByHash,\n\t\t\ttaskByHash: new Map(),\n\t\t\tactiveLocale,\n\t\t\tglossaryForLocale,\n\t\t\tsessionId: crypto.randomUUID(),\n\t\t}\n\t\tthis.scopes = this.calculateScopes(initialToDo)\n\n\t\tthis.buckets = {\n\t\t\ttoDo: new Set(this.scopes),\n\t\t\tinProgress: new Set(),\n\t\t\tfinished: new Set(),\n\t\t}\n\t}\n\n\tprivate getHashesForInitialToDo(initialToDo: ReadonlySet<KeyPath>): Set<number> {\n\t\tconst hashes = new Set<number>()\n\t\tfor (const keyPath of initialToDo) {\n\t\t\tconst source = this.engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\t\tif (!source) continue\n\t\t\thashes.add(source.hash)\n\t\t}\n\t\treturn hashes\n\t}\n\n\tprivate calculateScopes(initialToDo: ReadonlySet<KeyPath>): BatchTranslationScope[] {\n\t\tconst toDoByScopeId: Map<NodeID, Set<KeyPath>> = new Map()\n\t\tconst codeGenerationScopeIdByScopeId: Map<NodeID, NodeID> = new Map()\n\n\t\tfor (const keyPath of initialToDo) {\n\t\t\tconst source = this.engine.stores.localizationStore.getSourceForKeyPath(keyPath)\n\t\t\tif (!source) continue\n\n\t\t\tconst codeGenerationScopeId = getCodeGenerationScopeId(this.engine, source)\n\t\t\tcodeGenerationScopeIdByScopeId.set(source.scopeId, codeGenerationScopeId)\n\n\t\t\tconst toDoForScope = toDoByScopeId.get(source.scopeId) ?? new Set()\n\t\t\ttoDoByScopeId.set(source.scopeId, toDoForScope)\n\t\t\ttoDoForScope.add(keyPath)\n\t\t}\n\n\t\tconst scopes: BatchTranslationScope[] = []\n\n\t\tfor (const [scopeId, toDoForScope] of toDoByScopeId) {\n\t\t\tconst codeGenerationScopeId = codeGenerationScopeIdByScopeId.get(scopeId)\n\t\t\tassert(codeGenerationScopeId, \"Expected code generation scope id\")\n\n\t\t\tconst translationScope = new BatchTranslationScope(\n\t\t\t\tscopeId,\n\t\t\t\tcodeGenerationScopeId,\n\t\t\t\ttoDoForScope,\n\t\t\t\tthis.context,\n\t\t\t\tthis.updateFinishedCount,\n\t\t\t)\n\t\t\tscopes.push(translationScope)\n\t\t}\n\n\t\treturn scopes\n\t}\n\n\tprivate calculateFinishedCountAndProgress(): { finishedCount: number; progress: number } {\n\t\tlet totalCount = 0\n\t\tlet finishedCount = 0\n\n\t\tfor (const translationScope of this.scopes) {\n\t\t\ttotalCount += translationScope.totalItemCount\n\t\t\tfinishedCount += translationScope.finishedItemCount\n\t\t}\n\n\t\t// Computing the accurate progress when there are a lot of items is too expensive. So we\n\t\t// just use the item count instead.\n\t\tif (totalCount > 100) {\n\t\t\tconst progress = finishedCount / (totalCount || 1)\n\n\t\t\treturn { finishedCount, progress }\n\t\t}\n\n\t\tlet totalItemSize = 0\n\t\tlet finishedItemSize = 0\n\n\t\tfor (const translationScope of this.scopes) {\n\t\t\ttotalItemSize += translationScope.totalItemSize\n\t\t\tfinishedItemSize += translationScope.finishedItemSize\n\t\t}\n\n\t\tconst progress = finishedItemSize / (totalItemSize || 1)\n\n\t\treturn { finishedCount, progress }\n\t}\n\n\tprivate updateFinishedCount = () => {\n\t\tif (this.state.type !== \"translating\") return\n\t\tthis.updateState({ type: \"translating\", ...this.calculateFinishedCountAndProgress() })\n\t}\n\n\tprivate async startTranslateTask(): Promise<\n\t\t{ nothingToDo: false; scope: BatchTranslationScope } | { nothingToDo: true }\n\t> {\n\t\tfor (const inProgressScope of this.buckets.inProgress) {\n\t\t\tif (!inProgressScope.canStartTask()) continue\n\n\t\t\tawait inProgressScope.startTask()\n\n\t\t\treturn {\n\t\t\t\tnothingToDo: false,\n\t\t\t\tscope: inProgressScope,\n\t\t\t}\n\t\t}\n\n\t\tconst toDoScope = getFirstItemFromIterable(this.buckets.toDo)\n\n\t\tif (!toDoScope) {\n\t\t\treturn { nothingToDo: true }\n\t\t}\n\n\t\tthis.buckets.inProgress.add(toDoScope)\n\t\tthis.buckets.toDo.delete(toDoScope)\n\n\t\tawait toDoScope.startTask()\n\n\t\treturn {\n\t\t\tnothingToDo: false,\n\t\t\tscope: toDoScope,\n\t\t}\n\t}\n\n\tprivate async startTranslationTaskLoop(id: number) {\n\t\tlog.debug(`Start translation task loop ${id}`)\n\n\t\ttry {\n\t\t\twhile (this.state.type === \"translating\") {\n\t\t\t\tconst translationResult = await this.startTranslateTask()\n\n\t\t\t\t// Stop the loop if there is nothing left to do\n\t\t\t\tif (translationResult.nothingToDo) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (translationResult.scope.state === \"readyForSave\") {\n\t\t\t\t\tawait this.saveTranslationScope(translationResult.scope)\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.debug(`Error in translation task loop ${id}`, error)\n\t\t} finally {\n\t\t\tlog.debug(`End translation task loop ${id}`)\n\t\t}\n\t}\n\n\tprivate async saveTranslationScope(scope: BatchTranslationScope) {\n\t\tif (this.isDone) return\n\n\t\tassert(this.buckets.inProgress.has(scope), \"Expected scope to be in progress\")\n\t\tassert(!this.buckets.finished.has(scope), \"Expected scope to be in progress\")\n\n\t\tthis.buckets.finished.add(scope)\n\t\tthis.buckets.inProgress.delete(scope)\n\n\t\tawait scope.save()\n\t\tthis.updateFinishedCount()\n\n\t\tthis.resumeCodeGenerationForScopeIfPossible(scope.codeGenerationScopeId)\n\n\t\tif (this.buckets.inProgress.size === 0 && this.buckets.toDo.size === 0) {\n\t\t\tthis.finish()\n\t\t}\n\t}\n\n\tstart() {\n\t\tassert(this.state.type === \"idle\", \"Can only start from idle\")\n\t\tthis.updateState({ type: \"translating\", finishedCount: 0, progress: 0 })\n\n\t\tthis.batchStartedAt = performance.now()\n\t\tlog.debug(`Start batch translation for ${this.activeLocale.code}`)\n\n\t\tthis.pauseCodeGenerationForAllCollections()\n\n\t\tthis.engine.scheduler.processWhenReady(() => {\n\t\t\tArray(parallelTranslationsTasks)\n\t\t\t\t.fill(null)\n\t\t\t\t.forEach((_, index) => this.startTranslationTaskLoop(index + 1))\n\t\t})\n\t}\n\n\t/**\n\t * Pause code generation for all collections, because we want them to only be code generated\n\t * after all items are translated, and we batch translations by collection item.\n\t */\n\tprivate pauseCodeGenerationForAllCollections() {\n\t\tfor (const scope of this.scopes) {\n\t\t\tconst codeGenerationScope = this.engine.tree.get(scope.codeGenerationScopeId)\n\t\t\tif (!isCollectionNode(codeGenerationScope)) continue\n\n\t\t\tconst resumeCodeGeneration = this.engine.stores.codeGenerationStore.pauseCodeGeneration(\n\t\t\t\tscope.codeGenerationScopeId,\n\t\t\t)\n\n\t\t\tthis.pausedCodeGenerationScopes.set(scope.codeGenerationScopeId, resumeCodeGeneration)\n\t\t}\n\t}\n\n\tprivate resumeCodeGenerationForAllScopes() {\n\t\tfor (const resumeCodeGeneration of this.pausedCodeGenerationScopes.values()) {\n\t\t\tresumeCodeGeneration()\n\t\t}\n\t\tthis.pausedCodeGenerationScopes.clear()\n\t}\n\n\tprivate resumeCodeGenerationForScopeIfPossible(codeGenerationScopeId: NodeID): void {\n\t\tconst resumeCodeGeneration = this.pausedCodeGenerationScopes.get(codeGenerationScopeId)\n\t\tif (!resumeCodeGeneration) return\n\n\t\tfor (const scope of this.buckets.toDo) {\n\t\t\tif (scope.codeGenerationScopeId === codeGenerationScopeId) {\n\t\t\t\tlog.debug(`Not resuming code generation for scope ${codeGenerationScopeId} because it is in toDo`)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tfor (const scope of this.buckets.inProgress) {\n\t\t\tif (scope.codeGenerationScopeId === codeGenerationScopeId) {\n\t\t\t\tlog.debug(`Not resuming code generation for scope ${codeGenerationScopeId} because it is in inProgress`)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tlog.debug(`Resuming code generation for scope ${codeGenerationScopeId}`)\n\t\tresumeCodeGeneration()\n\t\tthis.pausedCodeGenerationScopes.delete(codeGenerationScopeId)\n\t}\n\n\tprivate finish() {\n\t\tif (this.isDone) return\n\n\t\tassert(this.buckets.toDo.size === 0, \"Expected toDo to be empty\")\n\t\tassert(this.buckets.inProgress.size === 0, \"Expected inProgress to be empty\")\n\t\tassert(this.buckets.finished.size === this.scopes.length, \"Expected all scopes to be finished\")\n\n\t\tthis.engine.scheduler.process(() => {\n\t\t\tif (this.isPersistingPartialResults || this.isDone) return\n\n\t\t\tlog.debug(`Finished in ${performance.now() - (this.batchStartedAt ?? 0)}ms`)\n\n\t\t\trecord(\"localized_value_batch_ai_translation\", {\n\t\t\t\tcode: this.activeLocale.code,\n\t\t\t\titemCount: this.state.finishedCount,\n\t\t\t\tsource: \"batch-translate-modal\",\n\t\t\t})\n\n\t\t\tthis.updateState({ ...this.state, type: \"done\", progress: 1 })\n\t\t})\n\t}\n\n\tstop() {\n\t\tif (this.isPersistingPartialResults || this.isDone) return\n\n\t\tlog.debug(\"Cancel\")\n\t\tthis.updateState({ ...this.state, type: \"persistingPartialResults\" })\n\t\tvoid this.stopAndSavePartialScopes()\n\t}\n\n\tprivate async stopAndSavePartialScopes() {\n\t\tconst scopesToWaitFor = this.scopes.filter(\n\t\t\tscope => scope.state === \"translating\" || scope.state === \"readyForSave\" || scope.state === \"saving\",\n\t\t)\n\n\t\tawait Promise.allSettled(\n\t\t\tscopesToWaitFor.map(scope => {\n\t\t\t\tif (scope.state === \"saving\") return scope.waitForPersistence()\n\t\t\t\tif (scope.state === \"readyForSave\") return scope.save()\n\t\t\t\treturn scope.stopAndSavePartial()\n\t\t\t}),\n\t\t)\n\n\t\tthis.resumeCodeGenerationForAllScopes()\n\t\tthis.updateState({ ...this.state, type: \"stopped\" })\n\t}\n}\n", "import type { ProjectLicenseType } from \"@framerjs/app-shared/src/ProjectLicense.ts\"\nimport { assert } from \"@framerjs/shared/src/assert.ts\"\nimport { emptyArray } from \"@framerjs/shared/src/emptyArray.ts\"\nimport { noop } from \"@framerjs/shared/src/noop.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { BaseEngine } from \"document/base-engine/BaseEngine.ts\"\nimport type { NodeChangesReader } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { CanvasNode, CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { LocalizationGlossaryNode } from \"document/models/CanvasTree/nodes/LocalizationGlossaryNode.ts\"\nimport { isScopeNode } from \"document/models/CanvasTree/nodes/ScopeNode.ts\"\nimport { type Locale, type LocaleId, isLocalesUpdate } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { isEmptyRichTextValue } from \"utils/isEmptyRichTextValue.ts\"\nimport { memoizeOne } from \"utils/memoizeOne.ts\"\nimport { isAiCreditLimitReached } from \"../shared/UpsellModal/utils/aiCreditsUpsell.ts\"\nimport { TranslationTask, type TranslationTaskFinishedState } from \"./BatchTranslation.ts\"\nimport { canBeBatchTranslated } from \"./canBeBatchTranslated.ts\"\nimport type { LocalizationSource, LocalizationSourceKeyPath } from \"./getLocalizationSources.ts\"\nimport { getLocalizationSourcesForNode } from \"./getLocalizationSourcesForNode.ts\"\nimport { type GlossaryForLocale, buildGlossaryForLocale } from \"./glossaryUtils.ts\"\nimport { clearLocalizedValue, setLocalizedValue } from \"./updateLocalizedValue.ts\"\n\nconst keySplitter = \":\"\ntype KeySplitter = typeof keySplitter\ntype SourceLocaleKey = `${LocalizationSourceKeyPath}${KeySplitter}${LocaleId}`\ninterface InFlightTranslation {\n\thash: LocalizationSource[\"hash\"]\n\ttype: LocalizationSource[\"type\"]\n\ttask: DeduplicatedTranslationTask\n}\n\nconst autoTranslationTrackingSource = \"auto-translation\"\n\nexport class AutomaticTranslationService {\n\tprivate readonly inFlightTranslations = new Map<SourceLocaleKey, InFlightTranslation>()\n\tprivate readonly nodesToTranslate = new Set<NodeID>()\n\tprivate readonly nodeChangesReader: NodeChangesReader\n\tprivate idleTaskScheduled = false\n\n\tconstructor(private readonly engine: VekterEngine) {\n\t\tthis.nodeChangesReader = engine.stores.treeStore.timeline.openNodeChangesReader()\n\t}\n\n\tpublic ingestTreeChanges(tree: CanvasTree, remote: boolean): void {\n\t\tconst managedLocales = getManagedLocales(tree.root.locales)\n\t\tif (managedLocales.length === 0) {\n\t\t\tthis.nodeChangesReader.clear()\n\t\t\treturn\n\t\t}\n\n\t\tif (remote) {\n\t\t\t// When postProcessing after remote changes, clear the reader so\n\t\t\t// that we don't translate changes made remotely.\n\t\t\tthis.nodeChangesReader.clear()\n\t\t\treturn\n\t\t}\n\n\t\tfor (const [id, changes] of this.nodeChangesReader.read()) {\n\t\t\tif (changes.length === 0) continue\n\n\t\t\tif (id === tree.root.id && shouldSkipRootChange(changes)) continue\n\n\t\t\t// TODO: It would be great to only add nodes that have changed properties that are\n\t\t\t// actually localizable\n\t\t\tif (this.nodesToTranslate.has(id)) continue\n\t\t\tthis.nodesToTranslate.add(id)\n\t\t}\n\n\t\tthis.scheduleTranslateNodesIfNeeded()\n\t}\n\n\tprivate scheduleTranslateNodesIfNeeded(): void {\n\t\tif (this.nodesToTranslate.size === 0 || this.idleTaskScheduled) return\n\n\t\tthis.idleTaskScheduled = true\n\t\tthis.engine.scheduler.runWhenIdle(() => {\n\t\t\tthis.idleTaskScheduled = false\n\t\t\tthis.translateNodes()\n\t\t})\n\t}\n\n\tprivate translateNodes() {\n\t\tif (this.engine.tree.isViewOnly) return\n\t\tif (this.nodesToTranslate.size === 0) return\n\n\t\tconst managedLocales = getManagedLocales(this.engine.tree.root.locales)\n\t\tif (managedLocales.length === 0) return\n\n\t\t// Clone and clear the set to avoid deleting new items if they are added whilst we are iterating\n\t\tconst clonedNodesToTranslate = new Set<NodeID>(this.nodesToTranslate)\n\t\tthis.nodesToTranslate.clear()\n\n\t\tfor (const locale of managedLocales) {\n\t\t\tconst tree = this.engine.stores.treeStore.getDataTreeOrPartialTree()\n\t\t\tconst glossaryNode = LocalizationGlossaryNode.get(tree)\n\t\t\tconst glossaryForLocale = buildGlossaryForLocale(locale, tree.root.locales ?? [], glossaryNode)\n\n\t\t\tfor (const nodeId of clonedNodesToTranslate) {\n\t\t\t\tconst node = this.engine.tree.get(nodeId)\n\t\t\t\tif (!node) continue\n\n\t\t\t\tthis.translateNode(node, locale, glossaryForLocale)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate translateNode(node: CanvasNode, locale: Locale, glossaryForLocale: GlossaryForLocale | null): void {\n\t\tlet skippedAiDueToCredits = false\n\n\t\tif (this.engine.tree.isViewOnly) {\n\t\t\tthis.nodesToTranslate.add(node.id)\n\t\t\treturn\n\t\t}\n\n\t\tif (isScopeNode(node, true) && !node.isLoaded()) {\n\t\t\tthis.nodesToTranslate.add(node.id)\n\t\t\treturn\n\t\t}\n\n\t\tfor (const source of getLocalizationSourcesForNode(node, this.engine, true)) {\n\t\t\tconst key = getSourceLocaleKey(source.keyPath, locale.id)\n\t\t\tconst existingInFlightTranslation = this.inFlightTranslations.get(key)\n\t\t\tif (!canBeBatchTranslated(locale, source, this.engine.stores.previewStore.framerSiteId, \"allowEmptyValue\")) {\n\t\t\t\t// If the source can no longer be translated, invalidate any existing\n\t\t\t\t// in-flight task so stale async completions are ignored.\n\t\t\t\tif (existingInFlightTranslation) {\n\t\t\t\t\texistingInFlightTranslation.task.cancel(key)\n\t\t\t\t\tthis.inFlightTranslations.delete(key)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst directlyApplicableTranslation = this.getDirectlyApplicableTranslation(source, glossaryForLocale)\n\t\t\tif (directlyApplicableTranslation !== null) {\n\t\t\t\t// The source changed to a value that can be applied synchronously\n\t\t\t\t// (for example empty text or a glossary exact match), so any\n\t\t\t\t// older async request for the same source+locale is now stale.\n\t\t\t\tif (existingInFlightTranslation) {\n\t\t\t\t\texistingInFlightTranslation.task.cancel(key)\n\t\t\t\t\tthis.inFlightTranslations.delete(key)\n\t\t\t\t}\n\t\t\t\tthis.applyTranslation(source, locale, directlyApplicableTranslation)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\texistingInFlightTranslation &&\n\t\t\t\tverifySourceNotChanged(source, existingInFlightTranslation.hash, existingInFlightTranslation.type)\n\t\t\t) {\n\t\t\t\t// We're already running a translation for this source\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// The source has changed, cancel the existing translation so we can start a new one\n\t\t\tif (existingInFlightTranslation) {\n\t\t\t\texistingInFlightTranslation.task.cancel(key)\n\t\t\t}\n\n\t\t\t// Skip AI requests while the workspace is out of credits, but keep the node queued\n\t\t\t// so the work resumes once credits are restored.\n\t\t\tif (isAiCreditLimitReached(this.engine)) {\n\t\t\t\t// Drop the cancelled entry so reverting to the old hash doesn't look in-flight.\n\t\t\t\tif (existingInFlightTranslation) this.inFlightTranslations.delete(key)\n\t\t\t\tskippedAiDueToCredits = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Capture the hash at creation time to verify it hasn't changed when callback fires\n\t\t\tconst sourceHash = source.hash\n\t\t\tconst sourceType = source.type\n\n\t\t\tconst task = new DeduplicatedTranslationTask({\n\t\t\t\tengine: this.engine,\n\t\t\t\tsourceLocaleKey: key,\n\t\t\t\tsource,\n\t\t\t\tlocale,\n\t\t\t\tfromLanguage: this.engine.tree.root.webMetadata?.language,\n\t\t\t\tglossaryForLocale,\n\t\t\t\tonComplete: value => {\n\t\t\t\t\tthis.inFlightTranslations.delete(key)\n\n\t\t\t\t\t// Get a current snapshot of the source in case it has changed externally\n\t\t\t\t\tconst currentSource = getCurrentSource(this.engine, source)\n\t\t\t\t\tif (!currentSource) return\n\t\t\t\t\tif (!verifySourceNotChanged(currentSource, sourceHash, sourceType)) return\n\n\t\t\t\t\tthis.applyTranslation(currentSource, locale, value)\n\t\t\t\t},\n\t\t\t\tonError: () => {\n\t\t\t\t\tthis.inFlightTranslations.delete(key)\n\t\t\t\t},\n\t\t\t\tframerSiteId: this.engine.stores.previewStore.framerSiteId,\n\t\t\t\tprojectLicenseType: this.engine.stores.projectStore.projectLicenseType,\n\t\t\t\tcomponentLoader: this.engine.componentLoader,\n\t\t\t})\n\n\t\t\tthis.inFlightTranslations.set(key, {\n\t\t\t\thash: sourceHash,\n\t\t\t\ttype: sourceType,\n\t\t\t\ttask,\n\t\t\t})\n\t\t}\n\n\t\tif (skippedAiDueToCredits) this.nodesToTranslate.add(node.id)\n\t}\n\n\tprivate applyTranslation(source: LocalizationSource, locale: Locale, translation: string): void {\n\t\tif (this.engine.tree.isViewOnly) return\n\t\tif (translation === \"\" || isEmptyRichTextValue(translation)) {\n\t\t\tclearLocalizedValue(this.engine, source, locale, {\n\t\t\t\ttarget: \"default\",\n\t\t\t\ttrackingSource: autoTranslationTrackingSource,\n\t\t\t\teventType: \"nonUserEvent\",\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tsetLocalizedValue(this.engine, translation, source, locale, {\n\t\t\tgeneratedByAI: true,\n\t\t\ttrackingSource: autoTranslationTrackingSource,\n\t\t\teventType: \"nonUserEvent\",\n\t\t})\n\t}\n\n\tprivate getDirectlyApplicableTranslation(\n\t\tsource: LocalizationSource,\n\t\tglossaryForLocale: GlossaryForLocale | null,\n\t): string | null {\n\t\tif (source.value === \"\" || isEmptyRichTextValue(source.value)) return \"\"\n\n\t\t// Check for exact glossary match\n\t\tconst matchingValueFromGlossary = getMatchingValueFromGlossary(glossaryForLocale, source)\n\t\tif (matchingValueFromGlossary) return matchingValueFromGlossary\n\n\t\treturn null\n\t}\n}\n\n/**\n * Skip the change to the root node if it is from a locale changing from unmanaged to managed\n */\nfunction shouldSkipRootChange(changes: readonly { from?: unknown; to: unknown }[]): boolean {\n\tfor (const change of changes) {\n\t\tconst { from, to } = change\n\n\t\tif (!isLocalesUpdate(to)) continue\n\t\tif (!to.locales || to.locales.length === 0) continue\n\n\t\tconst fromLocales = isLocalesUpdate(from) && from.locales ? from.locales : []\n\n\t\tfor (const toLocale of to.locales) {\n\t\t\tconst fromLocale = fromLocales.find(({ id }) => id === toLocale.id)\n\n\t\t\t// It might be a new locale, so we treat a missing from locale the same as an existing unmanaged one\n\t\t\tconst wasManaged = fromLocale?.managedByAI === true\n\t\t\tconst isManaged = toLocale.managedByAI === true\n\t\t\tif (!wasManaged && isManaged) return true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunction getSourceLocaleKey(keyPath: LocalizationSourceKeyPath, localeId: LocaleId): SourceLocaleKey {\n\treturn `${keyPath}${keySplitter}${localeId}`\n}\n\nfunction getMatchingValueFromGlossary(\n\tglossaryForLocale: GlossaryForLocale | null,\n\tsource: LocalizationSource,\n): string | null {\n\tif (!glossaryForLocale) return null\n\tfor (const glossaryItem of glossaryForLocale) {\n\t\tif (glossaryItem.term === source.value && !!glossaryItem.translation) return glossaryItem.translation\n\t}\n\treturn null\n}\n\n// Get an up to date source, in case it has changed externally\nfunction getCurrentSource(engine: BaseEngine, source: LocalizationSource): LocalizationSource | null {\n\tconst currentNode = engine.tree.get(source.nodeId)\n\tif (!currentNode) return null\n\tconst currentSource = getLocalizationSourcesForNode(currentNode, engine, true).find(\n\t\tcandidateSource => candidateSource.keyPath === source.keyPath,\n\t)\n\treturn currentSource || null\n}\n\nfunction verifySourceNotChanged(\n\tsource: LocalizationSource,\n\toriginalHash: LocalizationSource[\"hash\"],\n\toriginalType: LocalizationSource[\"type\"],\n): boolean {\n\treturn source.hash === originalHash && source.type === originalType\n}\n\ntype TranslationTaskKey =\n\t`${LocalizationSource[\"hash\"]}${KeySplitter}${LocalizationSource[\"type\"]}${KeySplitter}${LocaleId}`\n\nfunction getTranslationTaskKey(\n\thash: LocalizationSource[\"hash\"],\n\ttype: LocalizationSource[\"type\"],\n\tlocaleId: LocaleId,\n): TranslationTaskKey {\n\treturn `${hash}${keySplitter}${type}${keySplitter}${localeId}`\n}\n\nconst getManagedLocales = memoizeOne((locales: readonly Locale[] | undefined): readonly Locale[] => {\n\tif (!locales) return emptyArray()\n\treturn locales.filter(locale => locale.managedByAI)\n})\n\nclass TaskEntry {\n\tprivate task: TranslationTask | null = null\n\treadonly dependents = new Set<SourceLocaleKey>()\n\treadonly promise: Promise<TranslationTaskFinishedState>\n\tprivate resolve: ((result: TranslationTaskFinishedState) => void) | undefined\n\n\tconstructor(\n\t\tsourceLocaleKey: SourceLocaleKey,\n\t\tprivate readonly createTask: () => TranslationTask,\n\t) {\n\t\tthis.dependents.add(sourceLocaleKey)\n\t\tthis.promise = new Promise<TranslationTaskFinishedState>(resolve => {\n\t\t\tthis.resolve = resolve\n\t\t})\n\t}\n\n\t/** Creates and starts the underlying TranslationTask. Can only be called once. */\n\tstart(): TranslationTask {\n\t\tassert(!this.task, \"TaskEntry.start() called more than once\")\n\t\tthis.task = this.createTask()\n\t\treturn this.task\n\t}\n\n\tget started(): boolean {\n\t\treturn this.task !== null\n\t}\n\n\tfinish(result: TranslationTaskFinishedState): void {\n\t\tassert(this.resolve, \"Resolve is set in the constructor\")\n\t\tthis.resolve(result)\n\t}\n\n\tcancel(): void {\n\t\tif (this.task) {\n\t\t\t// \"Finish\" handling is done by the DeduplicatedTranslationTask class\n\t\t\tthis.task.cancel()\n\t\t\treturn\n\t\t}\n\n\t\t// There's no promise handling built in as the task is not started, so we need to resolve\n\t\t// the promise manually\n\t\tthis.finish({ type: \"error\" })\n\t}\n}\n\n/**\n * A deduplicating wrapper around TranslationTask that shares tasks with the same hash & type\n */\nclass DeduplicatedTranslationTask {\n\tprivate static readonly maxConcurrentTasks = 6\n\tprivate static readonly activeTaskKeys = new Set<TranslationTaskKey>()\n\tprivate static readonly queuedTaskKeys = new Set<TranslationTaskKey>()\n\tprivate static readonly taskMap = new Map<TranslationTaskKey, TaskEntry>()\n\n\tprivate readonly taskKey: TranslationTaskKey\n\tprivate cancelled = false\n\n\tprivate static startQueuedTasksIfPossible(engine: VekterEngine): void {\n\t\tif (engine.tree.isViewOnly) return\n\t\twhile (\n\t\t\tDeduplicatedTranslationTask.activeTaskKeys.size < DeduplicatedTranslationTask.maxConcurrentTasks &&\n\t\t\tDeduplicatedTranslationTask.queuedTaskKeys.size > 0\n\t\t) {\n\t\t\tconst taskKey = DeduplicatedTranslationTask.queuedTaskKeys.values().next().value\n\t\t\tassert(taskKey, \"Next value doesn't exist in queued task keys\")\n\t\t\tDeduplicatedTranslationTask.queuedTaskKeys.delete(taskKey)\n\n\t\t\tconst entry = DeduplicatedTranslationTask.taskMap.get(taskKey)\n\t\t\tassert(entry, \"Entry must exist\")\n\t\t\tassert(!entry.started, \"Entry must not already be started\")\n\n\t\t\tDeduplicatedTranslationTask.activeTaskKeys.add(taskKey)\n\t\t\tconst task = entry.start()\n\n\t\t\tvoid task.promise\n\t\t\t\t.then(result => {\n\t\t\t\t\tentry.finish(result)\n\t\t\t\t})\n\t\t\t\t.catch(() => {\n\t\t\t\t\tentry.finish({ type: \"error\" })\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tDeduplicatedTranslationTask.activeTaskKeys.delete(taskKey)\n\t\t\t\t\tDeduplicatedTranslationTask.startQueuedTasksIfPossible(engine)\n\t\t\t\t})\n\t\t}\n\t}\n\n\tconstructor({\n\t\tengine,\n\t\tsourceLocaleKey,\n\t\tsource,\n\t\tlocale,\n\t\tfromLanguage,\n\t\tglossaryForLocale,\n\t\tonComplete,\n\t\tonError,\n\t\tframerSiteId,\n\t\tprojectLicenseType,\n\t\tcomponentLoader,\n\t}: {\n\t\tengine: VekterEngine\n\t\tsourceLocaleKey: SourceLocaleKey\n\t\tsource: LocalizationSource\n\t\tlocale: Locale\n\t\tfromLanguage: string | undefined\n\t\tglossaryForLocale: GlossaryForLocale | null\n\t\tonComplete: (value: string) => void\n\t\tonError: () => void\n\t\tframerSiteId: string | undefined\n\t\tprojectLicenseType: ProjectLicenseType\n\t\tcomponentLoader: VekterEngine[\"componentLoader\"]\n\t}) {\n\t\tthis.taskKey = getTranslationTaskKey(source.hash, source.type, locale.id)\n\n\t\tconst existingEntry = DeduplicatedTranslationTask.taskMap.get(this.taskKey)\n\t\tif (existingEntry) {\n\t\t\texistingEntry.dependents.add(sourceLocaleKey)\n\t\t\tvoid existingEntry.promise.then(result => this.handlePromiseResult(result, sourceLocaleKey, onComplete, onError))\n\t\t\treturn\n\t\t}\n\n\t\tconst entry = new TaskEntry(\n\t\t\tsourceLocaleKey,\n\t\t\t() =>\n\t\t\t\tnew TranslationTask({\n\t\t\t\t\tengine,\n\t\t\t\t\tsource,\n\t\t\t\t\tbehavior: \"parseWhenFinished\",\n\t\t\t\t\tlocale,\n\t\t\t\t\tfromLanguage,\n\t\t\t\t\tonChange: noop,\n\t\t\t\t\tglossaryForLocale,\n\t\t\t\t\tsessionId: crypto.randomUUID(),\n\t\t\t\t\tframerSiteId,\n\t\t\t\t\tprojectLicenseType,\n\t\t\t\t\tuiContext: \"automated\",\n\t\t\t\t\tcomponentLoader,\n\t\t\t\t}),\n\t\t)\n\t\tDeduplicatedTranslationTask.taskMap.set(this.taskKey, entry)\n\t\tDeduplicatedTranslationTask.queuedTaskKeys.add(this.taskKey)\n\t\tDeduplicatedTranslationTask.startQueuedTasksIfPossible(engine)\n\n\t\tvoid entry.promise.then(result => this.handlePromiseResult(result, sourceLocaleKey, onComplete, onError))\n\t}\n\n\tcancel(sourceLocaleKey: SourceLocaleKey): void {\n\t\tif (this.cancelled) return\n\t\tthis.cancelled = true\n\n\t\tconst entry = DeduplicatedTranslationTask.taskMap.get(this.taskKey)\n\t\tif (!entry) return\n\n\t\tentry.dependents.delete(sourceLocaleKey)\n\n\t\tthis.conditionallyCleanup()\n\t}\n\n\tprivate handlePromiseResult(\n\t\tresult: TranslationTaskFinishedState,\n\t\tsourceLocaleKey: SourceLocaleKey,\n\t\tonComplete: (value: string) => void,\n\t\tonError: () => void,\n\t): TranslationTaskFinishedState {\n\t\tthis.notifyCallback(result, sourceLocaleKey, onComplete, onError)\n\t\tthis.conditionallyCleanup()\n\t\t// We need to ensure that all chained callbacks are called, so we return the result\n\t\treturn result\n\t}\n\n\t// Cleanup the task if there are no more dependents\n\tprivate conditionallyCleanup(): void {\n\t\tconst entry = DeduplicatedTranslationTask.taskMap.get(this.taskKey)\n\t\tif (!entry) return\n\t\tif (entry.dependents.size > 0) return\n\n\t\t// Last consumer, actually cancel the underlying task (or remove it from the queue if it is\n\t\t// yet to start)\n\t\tentry.cancel()\n\t\tDeduplicatedTranslationTask.queuedTaskKeys.delete(this.taskKey)\n\t\tDeduplicatedTranslationTask.taskMap.delete(this.taskKey)\n\t}\n\n\t// Only notify callbacks where the sourceLocaleKey is still relevant\n\tprivate notifyCallback(\n\t\tresult: TranslationTaskFinishedState,\n\t\tsourceLocaleKey: SourceLocaleKey,\n\t\tonComplete: (value: string) => void,\n\t\tonError: () => void,\n\t) {\n\t\tif (this.cancelled) return\n\n\t\tconst entry = DeduplicatedTranslationTask.taskMap.get(this.taskKey)\n\t\tif (!entry) return\n\t\tif (!entry.dependents.has(sourceLocaleKey)) return\n\n\t\tif (result.type === \"done\") {\n\t\t\tonComplete(result.value)\n\t\t} else {\n\t\t\tonError()\n\t\t}\n\n\t\tentry.dependents.delete(sourceLocaleKey)\n\t}\n}\n", "import type {\n\tLocalizationGroupID,\n\tLocalizationSourceGroup,\n} from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport type { Locale } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { isBoolean } from \"utils/typeChecks.ts\"\nimport { isGroupExcludedInLocale } from \"./isGroupExcludedInLocale.ts\"\n\nexport function isExpandedSourceGroup(\n\tgroup: LocalizationSourceGroup,\n\tactiveLocale: Locale,\n\texpandedSourceGroups: ReadonlyMap<LocalizationGroupID, boolean>,\n): boolean {\n\tconst setExpandedState = expandedSourceGroups.get(group.nodeId)\n\tif (isBoolean(setExpandedState)) return setExpandedState\n\n\tconst isExcluded = isGroupExcludedInLocale(group, activeLocale)\n\treturn !isExcluded\n}\n", "import { DebouncedTask } from \"@framerjs/shared\"\nimport { toast } from \"web/lib/toaster.ts\"\n\n// Short delay used the first time we defer (no prior result to compare against). Long enough\n// for React to commit the toast and the browser to paint it (a few frames) before we hand\n// control back to the host for the heavy calc, but short enough to feel snappy on view open.\nconst FIRST_CALC_DELAY_MS = 50\n\ninterface AdaptiveDeferralOptions {\n\t/** Debounce window for batching tree changes before kicking off the heavy recalc. */\n\tdebounceMs: number\n\t/** A real recalc above this duration flips the task into sticky \"defer mode.\" */\n\tslowThresholdMs: number\n\t/** Unique key used to add/remove the progress toast. */\n\ttoastKey: string\n\t/** Leading emphasized text shown in the progress toast. */\n\ttoastPrimaryText: string\n\t/** Supporting muted text shown next to `toastPrimaryText` in the progress toast. */\n\ttoastSecondaryText: string\n\t/**\n\t * Called after the debounce has elapsed to wake the engine and re-enter the host's\n\t * processing step (typically `engine.scheduler.signalChanges(storeProxy)`).\n\t */\n\ttriggerReentry: () => void\n\t/**\n\t * If true, `shouldDefer` always returns false so the host runs its calc inline. Intended\n\t * for tests, which can't flush the async `setTimeout` chain that drives the debounce.\n\t */\n\tdisabled?: boolean\n\t/**\n\t * Aborting this signal cancels the pending debounce timer and removes the in-flight toast.\n\t * Engine-store callers should pass `engine.eventListenerAbortController.signal` so the task\n\t * is cleaned up when the engine is disposed.\n\t */\n\tabortSignal?: AbortSignal\n}\n\n/**\n * Defers a heavy synchronous recalculation behind a debounce + non-blocking progress toast,\n * when previous recalcs have been observed to be slow.\n *\n * Why this exists: e.g. `calculateLocalizationSourceState` walks the whole tree and can take\n * many seconds on large projects. Running it inline freezes the page with no feedback. The\n * task:\n * - Debounces consecutive tree changes so typing bursts don't compound recalcs.\n * - Holds the host off long enough for React to commit and paint the toast before we hand\n *   control back for the calc that will block the main thread.\n * - Sticks in defer mode after any slow calc. Calc times are bimodal \u2014 memoized edits are\n *   typically <100ms while cache-busting recalcs (scope load, components rebuild, big tree\n *   change) can be seconds \u2014 so \"last calc was fast\" is not predictive of the next one.\n *\n * Lifecycle, per recalc cycle:\n *   shouldDefer(...) \u2192 returns true while the caller should bail out of its processing step\n *                      and wait for the task to call `triggerReentry`.\n *   shouldDefer(...) \u2192 returns false once the debounce has elapsed; caller runs the calc.\n *   recordCalc(...)  \u2192 caller reports the duration; task clears toast + updates sticky flag.\n *\n * Call `reset()` when the host should drop in-flight state (e.g. the view was closed).\n */\nexport class AdaptiveDeferral {\n\tprivate recalcInProgress: boolean = false\n\tprivate debouncing: boolean = false\n\tprivate toastShown: boolean = false\n\t// Starts true so the first-ever calc is treated as potentially slow. The first real\n\t// measurement replaces this; subsequent measurements can only flip false \u2192 true.\n\tprivate shouldDeferFlag: boolean = true\n\tprivate hasMeasured: boolean = false\n\tprivate readonly debouncedTriggerReentry: DebouncedTask\n\n\tconstructor(private readonly options: AdaptiveDeferralOptions) {\n\t\tthis.debouncedTriggerReentry = new DebouncedTask({\n\t\t\tdelay: options.debounceMs,\n\t\t\ttask: () => {\n\t\t\t\tthis.debouncing = false\n\t\t\t\tthis.options.triggerReentry()\n\t\t\t},\n\t\t\tabortSignal: options.abortSignal,\n\t\t})\n\t\t// `DebouncedTask`'s abort handler only clears the timer. We also need to remove the\n\t\t// in-flight toast so it doesn't linger after the engine is disposed.\n\t\toptions.abortSignal?.addEventListener(\"abort\", () => this.reset(), { once: true })\n\t}\n\n\t/**\n\t * Decides whether the caller should bail this cycle. When this returns true the caller\n\t * must return early from its processing step; the task will call `triggerReentry` once\n\t * the debounce elapses.\n\t *\n\t * @param willActuallyRecalc Whether the upcoming calc would do real work (caller's check).\n\t *        When false, the task is a no-op \u2014 short-circuited calls don't need deferral.\n\t * @param hasExistingResult Whether the caller already has a previous result. When false\n\t *        (very first calc), the task uses a short delay \u2014 there's no typing burst to\n\t *        batch and we don't want to add 500ms to the initial view load.\n\t */\n\tshouldDefer({\n\t\twillActuallyRecalc,\n\t\thasExistingResult,\n\t}: {\n\t\twillActuallyRecalc: boolean\n\t\thasExistingResult: boolean\n\t}): boolean {\n\t\tif (this.options.disabled) return false\n\t\tif (!willActuallyRecalc || !this.shouldDeferFlag) return false\n\n\t\tif (!this.recalcInProgress) {\n\t\t\tthis.recalcInProgress = true\n\t\t\t// Synchronously dispatch the toast. A delayed dispatch can race React's render\n\t\t\t// task and the toast may never get committed to the DOM before we block the main\n\t\t\t// thread with the heavy calc.\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tkey: this.options.toastKey,\n\t\t\t\tvariant: \"progress\",\n\t\t\t\tprimaryText: this.options.toastPrimaryText,\n\t\t\t\tsecondaryText: this.options.toastSecondaryText,\n\t\t\t\tduration: Infinity,\n\t\t\t\tshowCloseButton: \"always\",\n\t\t\t})\n\t\t\tthis.toastShown = true\n\t\t\tthis.debouncing = true\n\t\t\tthis.debouncedTriggerReentry.debounce(hasExistingResult ? this.options.debounceMs : FIRST_CALC_DELAY_MS)\n\t\t} else if (this.debouncing) {\n\t\t\t// Further tree changes during the debounce window reset the timer so we wait for\n\t\t\t// the burst to settle before kicking off the calc.\n\t\t\tthis.debouncedTriggerReentry.debounce()\n\t\t}\n\n\t\treturn this.debouncing\n\t}\n\n\t/**\n\t * Records the result of a real calc the caller just ran. Updates the sticky defer flag\n\t * and clears the in-flight toast / timer state.\n\t *\n\t * @param didRealWork Whether the calc actually did work (vs. short-circuiting). Pass\n\t *        false when the call returned the cached/previous result.\n\t * @param durationMs Wall-clock duration of the calc.\n\t */\n\trecordCalc({ didRealWork, durationMs }: { didRealWork: boolean; durationMs: number }) {\n\t\tif (didRealWork) {\n\t\t\tconst wasSlow = durationMs > this.options.slowThresholdMs\n\t\t\tif (this.hasMeasured) {\n\t\t\t\t// Sticky: only allow false \u2192 true, never true \u2192 false. A memoized fast calc\n\t\t\t\t// shouldn't convince us the next calc will be fast.\n\t\t\t\tthis.shouldDeferFlag ||= wasSlow\n\t\t\t} else {\n\t\t\t\t// First measurement: trust it. Lets small projects opt out of defer mode.\n\t\t\t\tthis.shouldDeferFlag = wasSlow\n\t\t\t\tthis.hasMeasured = true\n\t\t\t}\n\t\t}\n\t\tthis.reset()\n\t}\n\n\t/** Drop all in-flight state. Call from the host when the view closes. */\n\treset() {\n\t\tthis.debouncedTriggerReentry.cancel()\n\t\tif (this.toastShown) {\n\t\t\ttoast({ type: \"remove\", key: this.options.toastKey })\n\t\t\tthis.toastShown = false\n\t\t}\n\t\tthis.recalcInProgress = false\n\t\tthis.debouncing = false\n\t}\n}\n", "import { assert, shouldBeNever } from \"@framerjs/shared\"\nimport { noop } from \"@framerjs/shared/src/noop.ts\"\nimport { experimentIsOnOrForceEnabled } from \"app/experiments.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { AutomaticTranslationService } from \"document/components/chrome/localization/automaticTranslationService.ts\"\nimport {\n\ttype CountPerLocale,\n\ttype LocalizationSourceState,\n\tcalculateLocalizationSourceState,\n\tisHiddenLocalizationSource,\n} from \"document/components/chrome/localization/calculateLocalizationSourceState.ts\"\nimport { dismissMatchingItemsToast } from \"document/components/chrome/localization/dismissMatchingItemsToast.ts\"\nimport {\n\ttype LocalizationGroupID,\n\ttype LocalizationSource,\n\ttype LocalizationSourceGroup,\n\ttype LocalizationSourceKeyPath,\n\ttype LocalizationSourceOrGroupStatus,\n\ttype LocalizationSourceStatus,\n\tisImageSource,\n\tisRichTextSource,\n\tisLinkSource,\n\tisSlugSource,\n\ttoSourceStatus,\n\twithLocalizationSourceControlProp,\n\twithLocalizationSubGroups,\n} from \"document/components/chrome/localization/getLocalizationSources.ts\"\nimport { getLocalizedFallback } from \"document/components/chrome/localization/getLocalizedFallback.ts\"\nimport { isExpandedSourceGroup } from \"document/components/chrome/localization/isExpandedSourceGroup.ts\"\nimport { isGroupExcludedInLocale } from \"document/components/chrome/localization/isGroupExcludedInLocale.ts\"\nimport { someLocalizationSourceInGroup } from \"document/components/chrome/localization/localizationSourceGroupUtils.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionItemNode, isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { Locale, LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport { getLocalizedValueText, isNonNullLocalizedValue } from \"document/models/LocalizedValue.ts\"\nimport { AdaptiveDeferral } from \"document/stores/AdaptiveDeferral.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { isEqual } from \"library/render/utils/isEqual.ts\"\nimport { capitalizeFirstLetter } from \"utils/capitalizeFirstLetter.ts\"\nimport { isShallowSetEqual } from \"utils/isShallowEqual.ts\"\nimport { memoizeOne } from \"utils/memoizeOne.ts\"\nimport { ClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\n\nfunction localizationSourceIncludesSearchTerm(\n\tactiveLocale: Locale,\n\tlocales: readonly Locale[],\n\tsource: LocalizationSource,\n\tnormalizedSearchTerm: string,\n): boolean {\n\tif (source.value.toLowerCase().includes(normalizedSearchTerm)) {\n\t\treturn true\n\t}\n\n\tconst localizedValue = source.localizedValues[activeLocale.id]\n\tif (\n\t\tisNonNullLocalizedValue(localizedValue) &&\n\t\tgetLocalizedValueText(localizedValue, { preserveNewLines: true }).toLowerCase().includes(normalizedSearchTerm)\n\t) {\n\t\treturn true\n\t}\n\n\tconst localizedFallback = getLocalizedFallback(source, activeLocale, locales)\n\tif (\n\t\tlocalizedFallback &&\n\t\tgetLocalizedValueText(localizedFallback, { preserveNewLines: true }).toLowerCase().includes(normalizedSearchTerm)\n\t) {\n\t\treturn true\n\t}\n\n\tif (\n\t\twithLocalizationSourceControlProp(source) &&\n\t\tsource.controlPropName?.toLowerCase().includes(normalizedSearchTerm)\n\t) {\n\t\treturn true\n\t}\n\n\tif (isLinkSource(source) && \"link\".includes(normalizedSearchTerm)) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunction getSortScoreForLocalizationStatus(status: LocalizationSourceStatus | undefined): number {\n\tswitch (status) {\n\t\tcase \"done\":\n\t\t\treturn 4\n\t\tcase \"needsReview\":\n\t\t\treturn 3\n\t\tcase \"new\":\n\t\t\treturn 2\n\t\tcase \"warning\":\n\t\t\treturn 1\n\t\tcase undefined:\n\t\t\treturn 0\n\t\tdefault:\n\t\t\tshouldBeNever(status)\n\t\t\treturn 0\n\t}\n}\n\ntype SourceCategory = \"string\" | \"richText\" | \"image\" | \"slug\"\n\nfunction getSourceCategory(source: LocalizationSource): SourceCategory {\n\tif (isRichTextSource(source)) return \"richText\"\n\tif (isImageSource(source)) return \"image\"\n\tif (isSlugSource(source)) return \"slug\"\n\treturn \"string\"\n}\n\nfunction getSortScoreForCategory(category: SourceCategory): number {\n\tswitch (category) {\n\t\tcase \"slug\":\n\t\t\treturn 4\n\t\tcase \"image\":\n\t\t\treturn 3\n\t\tcase \"richText\":\n\t\t\treturn 2\n\t\tcase \"string\":\n\t\t\treturn 1\n\t\tdefault:\n\t\t\tshouldBeNever(category)\n\t\t\treturn 0\n\t}\n}\n\nfunction sortLocalizationSources(activeLocale: Locale, sources: LocalizationSource[]): readonly LocalizationSource[] {\n\treturn sources.sort((a, b) => {\n\t\tconst statusA = a.localizedValueStatuses[activeLocale.id]\n\t\tconst statusB = b.localizedValueStatuses[activeLocale.id]\n\n\t\tif (statusA !== statusB) {\n\t\t\treturn getSortScoreForLocalizationStatus(statusA) - getSortScoreForLocalizationStatus(statusB)\n\t\t}\n\n\t\tconst categoryA = getSourceCategory(a)\n\t\tconst categoryB = getSourceCategory(b)\n\n\t\tif (categoryA !== categoryB) {\n\t\t\treturn getSortScoreForCategory(categoryA) - getSortScoreForCategory(categoryB)\n\t\t}\n\n\t\tconst localizedValueA = a.localizedValues[activeLocale.id]\n\t\tconst localizedValueB = b.localizedValues[activeLocale.id]\n\n\t\tif (localizedValueA && localizedValueB) {\n\t\t\t// Show values that were most recently edited at the top\n\t\t\treturn localizedValueB.lastEdited - localizedValueA.lastEdited\n\t\t}\n\n\t\treturn 0\n\t})\n}\n\nfunction filterLocalizationSources(\n\tactiveLocale: Locale,\n\tlocales: readonly Locale[],\n\tvisibleScopes: ReadonlySet<NodeID> | null,\n\tsearchTerm: string,\n\tstatus: LocalizationSourceStatus | null,\n\tsources: readonly LocalizationSource[],\n) {\n\tconst normalizedSearchTerm = searchTerm.trim().toLowerCase()\n\n\tconst filteredSources = sources.filter(localizationSource => {\n\t\tif (isHiddenLocalizationSource(localizationSource, activeLocale.id)) return false\n\n\t\tif (visibleScopes && !visibleScopes.has(localizationSource.scopeId)) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst sourceStatus = localizationSource.localizedValueStatuses[activeLocale.id]\n\t\tif (status && sourceStatus !== status) {\n\t\t\treturn false\n\t\t}\n\n\t\tif (\n\t\t\tnormalizedSearchTerm.length > 0 &&\n\t\t\t!localizationSourceIncludesSearchTerm(activeLocale, locales, localizationSource, normalizedSearchTerm)\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t})\n\n\treturn sortLocalizationSources(activeLocale, filteredSources)\n}\n\nfunction getGroupDataKey(status: LocalizationSourceStatus) {\n\treturn `has${capitalizeFirstLetter(status)}` as const\n}\n\ntype GroupDataKey = ReturnType<typeof getGroupDataKey>\ntype GroupData = Record<GroupDataKey, boolean> &\n\tPick<LocalizationSourceGroup, \"name\" | \"groupType\" | \"nodeId\" | \"items\"> & {\n\t\tisExcluded: boolean\n\t}\n\nconst groupDataKeyByStatus: Record<LocalizationSourceStatus, GroupDataKey> = {\n\tnew: \"hasNew\",\n\tdone: \"hasDone\",\n\tneedsReview: \"hasNeedsReview\",\n\twarning: \"hasWarning\",\n}\n\nconst groupTypeOrder: Record<GroupData[\"groupType\"], number> = {\n\tsettings: 0,\n\ttemplate: 1,\n\tpage: 2,\n\tcollection: 3,\n\tcollectionItem: 4,\n\tcomponent: 5,\n}\n\nfunction compareGroupData(a: GroupData, b: GroupData, scopeFilter: NodeID | null): number {\n\tif (a.nodeId === scopeFilter) return -1\n\tif (b.nodeId === scopeFilter) return 1\n\n\tif (a.groupType !== b.groupType) {\n\t\treturn groupTypeOrder[a.groupType] - groupTypeOrder[b.groupType]\n\t}\n\n\treturn a.name.localeCompare(b.name)\n}\n\nfunction compareGroupDataByStatus(a: GroupData, b: GroupData, scopeFilter: NodeID | null): number {\n\tif (a.isExcluded || b.isExcluded) {\n\t\tif (a.isExcluded === b.isExcluded) return compareGroupData(a, b, scopeFilter)\n\n\t\t// Unlike the other statuses, excluded items are moved to bottom instead of to the top\n\t\treturn a.isExcluded ? 1 : -1\n\t}\n\n\tif (a.hasWarning || b.hasWarning) {\n\t\tif (a.hasWarning === b.hasWarning) return compareGroupData(a, b, scopeFilter)\n\t\treturn a.hasWarning ? -1 : 1\n\t}\n\tif (a.hasNew || b.hasNew) {\n\t\tif (a.hasNew === b.hasNew) return compareGroupData(a, b, scopeFilter)\n\t\treturn a.hasNew ? -1 : 1\n\t}\n\n\tif (a.hasNeedsReview || b.hasNeedsReview) {\n\t\tif (a.hasNeedsReview === b.hasNeedsReview) return compareGroupData(a, b, scopeFilter)\n\t\treturn a.hasNeedsReview ? -1 : 1\n\t}\n\n\treturn compareGroupData(a, b, scopeFilter)\n}\n\nfunction collectAllGroupData(\n\tgroup: LocalizationSourceGroup,\n\tactiveLocale: Locale,\n\tcache: GroupDataByGroup,\n\tresult: Map<string, GroupData>,\n) {\n\tif (withLocalizationSubGroups(group)) {\n\t\tfor (const subGroup of group.groups) {\n\t\t\tcollectAllGroupData(subGroup, activeLocale, cache, result)\n\t\t}\n\t}\n\n\tconst cachedGroupData = cache.get(group)\n\tif (cachedGroupData) {\n\t\tresult.set(group.nodeId, cachedGroupData)\n\t\treturn\n\t}\n\n\tconst groupData: GroupData = {\n\t\tname: group.name,\n\t\tgroupType: group.groupType,\n\t\tnodeId: group.nodeId,\n\t\titems: group.items,\n\t\tisExcluded: isGroupExcludedInLocale(group, activeLocale),\n\t\thasNew: false,\n\t\thasDone: false,\n\t\thasNeedsReview: false,\n\t\thasWarning: false,\n\t}\n\n\tresult.set(group.nodeId, groupData)\n\tcache.set(group, groupData)\n\n\tfor (const source of group.items) {\n\t\tconst status = source.localizedValueStatuses[activeLocale.id]\n\t\tif (!status) continue\n\n\t\tconst key = groupDataKeyByStatus[status]\n\t\tgroupData[key] = true\n\t}\n\n\tif (withLocalizationSubGroups(group)) {\n\t\tfor (const subGroup of group.groups) {\n\t\t\t// Skip excluded sub groups, because they should not impact the sorting of the parent group\n\t\t\tif (isGroupExcludedInLocale(subGroup, activeLocale)) continue\n\n\t\t\tconst subGroupData = result.get(subGroup.nodeId)\n\t\t\t// Sub group data is collected first, so should exist\n\t\t\tassert(subGroupData)\n\n\t\t\tgroupData.hasNew ||= subGroupData.hasNew\n\t\t\tgroupData.hasDone ||= subGroupData.hasDone\n\t\t\tgroupData.hasNeedsReview ||= subGroupData.hasNeedsReview\n\t\t\tgroupData.hasWarning ||= subGroupData.hasWarning\n\t\t}\n\t}\n}\n\ntype GroupDataByGroup = WeakMap<LocalizationSourceGroup, GroupData>\n\ninterface GroupDataCache {\n\tactiveLocale: Locale\n\tgroupDataByGroup: GroupDataByGroup\n}\n\nconst getGroupDataByGroupCache = (() => {\n\tlet groupDataCache: GroupDataCache | null = null\n\n\treturn (activeLocale: Locale): GroupDataByGroup => {\n\t\tif (!groupDataCache || groupDataCache.activeLocale !== activeLocale) {\n\t\t\tgroupDataCache = {\n\t\t\t\tactiveLocale,\n\t\t\t\tgroupDataByGroup: new WeakMap(),\n\t\t\t}\n\t\t}\n\t\treturn groupDataCache.groupDataByGroup\n\t}\n})()\n\nfunction getAllGroupData(groups: readonly LocalizationSourceGroup[], activeLocale: Locale): Map<string, GroupData> {\n\tconst result: Map<string, GroupData> = new Map()\n\tconst cache = getGroupDataByGroupCache(activeLocale)\n\n\tfor (const group of groups) {\n\t\tcollectAllGroupData(group, activeLocale, cache, result)\n\t}\n\n\treturn result\n}\n\nfunction sortGroups(\n\tgroups: readonly LocalizationSourceGroup[],\n\tdataByGroup: Map<string, GroupData>,\n\tscopeFilter: NodeID | null,\n): readonly LocalizationSourceGroup[] {\n\treturn groups.toSorted((a, b) => {\n\t\t// biome-ignore lint/style/noNonNullAssertion: data exists for all groups\n\t\tconst dataA = dataByGroup.get(a.nodeId)!\n\t\t// biome-ignore lint/style/noNonNullAssertion: data exists for all groups\n\t\tconst dataB = dataByGroup.get(b.nodeId)!\n\t\treturn compareGroupDataByStatus(dataA, dataB, scopeFilter)\n\t})\n}\n\nfunction sortLocalizationSourceGroups(\n\tactiveLocale: Locale,\n\tgroups: readonly LocalizationSourceGroup[],\n\tscopeFilter: NodeID | null,\n): readonly LocalizationSourceGroup[] {\n\tconst dataByGroup = getAllGroupData(groups, activeLocale)\n\n\tconst sortedGroups = sortGroups(groups, dataByGroup, scopeFilter)\n\n\tfor (const group of sortedGroups) {\n\t\tif (!withLocalizationSubGroups(group)) continue\n\n\t\tgroup.groups = sortGroups(group.groups, dataByGroup, scopeFilter)\n\t}\n\n\treturn sortedGroups\n}\n\ntype FilteredGroupByGroup = WeakMap<LocalizationSourceGroup, LocalizationSourceGroup>\n\ninterface FilteredGroupCache {\n\tactiveLocale: Locale\n\tlocales: readonly Locale[]\n\tscopeFilter: NodeID | null\n\tvisibleScopes: ReadonlySet<NodeID> | null\n\tsearchTerm: string\n\tstatus: LocalizationSourceOrGroupStatus | null\n\tfilteredGroupByGroup: FilteredGroupByGroup\n}\n\nconst getFilteredGroupByGroupCache = (() => {\n\tlet filteredGroupCache: FilteredGroupCache | null = null\n\n\treturn (\n\t\tactiveLocale: Locale,\n\t\tlocales: readonly Locale[],\n\t\tscopeFilter: NodeID | null,\n\t\tvisibleScopes: ReadonlySet<NodeID> | null,\n\t\tsearchTerm: string,\n\t\tstatus: LocalizationSourceOrGroupStatus | null,\n\t): FilteredGroupByGroup => {\n\t\tif (\n\t\t\t!filteredGroupCache ||\n\t\t\tfilteredGroupCache.activeLocale !== activeLocale ||\n\t\t\tfilteredGroupCache.locales !== locales ||\n\t\t\tfilteredGroupCache.scopeFilter !== scopeFilter ||\n\t\t\tfilteredGroupCache.visibleScopes !== visibleScopes ||\n\t\t\tfilteredGroupCache.searchTerm !== searchTerm ||\n\t\t\tfilteredGroupCache.status !== status\n\t\t) {\n\t\t\tfilteredGroupCache = {\n\t\t\t\tactiveLocale,\n\t\t\t\tlocales,\n\t\t\t\tscopeFilter,\n\t\t\t\tvisibleScopes,\n\t\t\t\tsearchTerm,\n\t\t\t\tstatus,\n\t\t\t\tfilteredGroupByGroup: new WeakMap(),\n\t\t\t}\n\t\t}\n\n\t\treturn filteredGroupCache.filteredGroupByGroup\n\t}\n})()\n\nconst filterLocalizationSourceGroups = memoizeOne(\n\t(\n\t\tactiveLocale: Locale,\n\t\tlocales: readonly Locale[],\n\t\tscopeFilter: NodeID | null,\n\t\tvisibleScopes: ReadonlySet<NodeID> | null,\n\t\tsearchTerm: string,\n\t\tstatus: LocalizationSourceOrGroupStatus | null,\n\t\tgroups: readonly LocalizationSourceGroup[],\n\t): readonly LocalizationSourceGroup[] => {\n\t\tconst cache = getFilteredGroupByGroupCache(activeLocale, locales, scopeFilter, visibleScopes, searchTerm, status)\n\n\t\tconst filteredGroups: LocalizationSourceGroup[] = []\n\n\t\tfunction getFilteredGroup(group: LocalizationSourceGroup): LocalizationSourceGroup | undefined {\n\t\t\tconst cachedFilteredGroup = cache.get(group)\n\t\t\tif (cachedFilteredGroup) {\n\t\t\t\treturn cachedFilteredGroup\n\t\t\t}\n\n\t\t\tconst sources = filterLocalizationSources(\n\t\t\t\tactiveLocale,\n\t\t\t\tlocales,\n\t\t\t\tvisibleScopes,\n\t\t\t\tsearchTerm,\n\t\t\t\ttoSourceStatus(status),\n\t\t\t\tgroup.items,\n\t\t\t)\n\n\t\t\tconst isHidden = isGroupExcludedInLocale(group, activeLocale)\n\n\t\t\tlet subGroups: LocalizationSourceGroup[] | undefined\n\t\t\tlet containsHiddenSubGroup = false\n\t\t\tif (!isHidden && withLocalizationSubGroups(group)) {\n\t\t\t\tsubGroups = []\n\n\t\t\t\tfor (const subGroup of group.groups) {\n\t\t\t\t\tcontainsHiddenSubGroup ||= isGroupExcludedInLocale(subGroup, activeLocale)\n\n\t\t\t\t\tconst filteredSubGroup = getFilteredGroup(subGroup)\n\t\t\t\t\tif (filteredSubGroup) subGroups.push(filteredSubGroup)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (sources.length === 0 && (!subGroups || subGroups.length === 0)) return\n\n\t\t\t// We only show hidden groups when the status is hidden\n\t\t\tif (status === \"hidden\" && !isHidden && !containsHiddenSubGroup) return\n\n\t\t\t// If a source status filter is set (its not null) and the item is hidden continue\n\t\t\tif (status !== null && status !== \"hidden\" && isHidden) return\n\n\t\t\tconst filteredGroup = { ...group, items: sources }\n\n\t\t\tif (subGroups) {\n\t\t\t\tassert(withLocalizationSubGroups(filteredGroup))\n\t\t\t\tfilteredGroup.groups = subGroups\n\t\t\t}\n\n\t\t\tcache.set(group, filteredGroup)\n\t\t\treturn filteredGroup\n\t\t}\n\n\t\tfor (const group of groups) {\n\t\t\tconst filteredGroup = getFilteredGroup(group)\n\t\t\tif (filteredGroup) filteredGroups.push(filteredGroup)\n\t\t}\n\n\t\treturn sortLocalizationSourceGroups(activeLocale, filteredGroups, scopeFilter)\n\t},\n)\n\nfunction getActiveLocale(tree: CanvasTree, selectedLocaleId: LocaleId | null): Locale | null {\n\tconst locales = tree.root.locales\n\tif (!locales) return null\n\treturn locales.find(locale => locale.id === selectedLocaleId) ?? locales[0] ?? null\n}\n\ninterface ViewState {\n\tselectedLocaleId: LocaleId | null\n\tsearchTerm: string\n\tstatus: LocalizationSourceOrGroupStatus | null\n\tscopeFilter: string | null\n}\n\ntype VisibleScopes = ReadonlySet<NodeID> | null\n\n/**\n *  Collects the associated scope ids for an active scope filter.\n */\nfunction getVisibleScopes(\n\ttree: CanvasTree,\n\tscopeFilter: NodeID | null,\n\tpreviousVisibleScopes: VisibleScopes,\n): VisibleScopes | null {\n\tif (!scopeFilter) return null\n\n\tconst filterNodes = new Set<NodeID>([scopeFilter])\n\n\tconst node = tree.get(scopeFilter)\n\n\tif (isCollectionNode(node)) {\n\t\tfor (const collectionItem of node.getUnsortedChildren()) {\n\t\t\tif (isCollectionItemNode(collectionItem)) filterNodes.add(collectionItem.id)\n\t\t}\n\t}\n\n\tif (isCollectionItemNode(node)) {\n\t\tconst collectionNode = tree.get(node.parentid)\n\n\t\tif (isCollectionNode(collectionNode)) filterNodes.add(collectionNode.id)\n\t}\n\n\tif (previousVisibleScopes && isShallowSetEqual(previousVisibleScopes, filterNodes)) {\n\t\treturn previousVisibleScopes\n\t}\n\n\treturn filterNodes\n}\n\nexport type UniqueLocalizedValues = ReadonlySet<string>\n\ntype SourceOrderByGroup = Map<LocalizationGroupID, Set<LocalizationSourceKeyPath>>\ntype SubGroupOrderByGroup = Map<LocalizationGroupID, SourceOrderByGroup>\n\n/**\n * Existing empty set is used as a return value to prevent breaking memoization.\n */\nconst emptyUniqueLocalizedValues: UniqueLocalizedValues = new Set()\n\nexport class LocalizationStore extends EngineStore implements ViewState {\n\tprivate _visibleScopes: VisibleScopes = null\n\n\t// View State, changes to these should reset the persisted source order of the items, see `this.postProcess`\n\tselectedLocaleId: LocaleId | null = null\n\tsearchTerm: string = \"\"\n\tstatus: LocalizationSourceOrGroupStatus | null = null\n\tscopeFilter: string | null = null\n\t#previousViewState: ViewState = { selectedLocaleId: null, searchTerm: \"\", status: null, scopeFilter: null }\n\n\t// Defers heavy `calculateLocalizationSourceState` recalcs behind a debounce + non-blocking\n\t// toast once we've observed a slow calc this session. Disabled under jest \u2014 tests can't\n\t// flush the setTimeout chain that drives the debounce, and they rely on reading store state\n\t// synchronously after `processFrame`. The engine abort signal cancels the pending debounce\n\t// timer (and clears the toast) when the engine is disposed.\n\t#recalcTask: AdaptiveDeferral\n\n\tconstructor(abortSignal: AbortSignal) {\n\t\tsuper()\n\t\tthis.#recalcTask = new AdaptiveDeferral({\n\t\t\tdebounceMs: 500,\n\t\t\tslowThresholdMs: 250,\n\t\t\ttoastKey: \"localization-recalculating\",\n\t\t\ttoastPrimaryText: \"Loading translations.\",\n\t\t\ttoastSecondaryText: \"Just a moment\u2026\",\n\t\t\ttriggerReentry: () => this.scheduler.signalChanges(this),\n\t\t\tdisabled: process.env.NODE_ENV === \"test\",\n\t\t\tabortSignal,\n\t\t})\n\t}\n\n\t// Visible sources\n\tpersistedGroupAndSourceOrder: SourceOrderByGroup = new Map()\n\tpersistedSubGroupAndSourcesOrder: SubGroupOrderByGroup = new Map()\n\tgroups: readonly LocalizationSourceGroup[] | null = null\n\tfilteredGroupsAndSources: readonly LocalizationSourceGroup[] | null = null\n\tvirtualListItems: readonly (LocalizationSourceGroup | LocalizationSource)[] | null = null\n\t#sourceState: LocalizationSourceState | undefined\n\texpandedSourceGroups: ReadonlyMap<LocalizationGroupID, boolean> = new Map()\n\n\t/** Progress has a range of 0 - 1. */\n\tprogressPerLocale: CountPerLocale = {}\n\n\t#previousMainView: ActiveMainView | undefined\n\t#stopLoading?: () => void\n\t#releasePersistedCaches?: () => void\n\t#hasAutoSetTranslatePagePaths = false\n\t#automaticTranslationService: AutomaticTranslationService | undefined\n\n\t/**\n\t * Used to observe both tree changes as well as LocalizationStore changes that have a side\n\t * effect that causes the view to require an update, like changing the search term.\n\t */\n\tpostProcess(engine: VekterEngine) {\n\t\tconst {\n\t\t\tstores: { chromeStore, componentsStore, modalStore, loadingStore },\n\t\t} = engine\n\t\tconst { mainView } = chromeStore\n\t\tconst componentsHash = componentsStore.activeBundleHash\n\n\t\tif (!loadingStore.isReady) {\n\t\t\treturn\n\t\t}\n\n\t\t// Capture but don't yet commit the previous main view. If we defer the recalc below,\n\t\t// `willAppear` needs to stay true so the deferred re-entry runs `resetPersistedOrder`\n\t\t// and `dismissMatchingItemsToast` \u2014 we only consume the signal once we actually run\n\t\t// the calc this cycle.\n\t\tconst previousMainView = this.#previousMainView\n\n\t\t// Don't do any expensive work unless the localization is visible\n\t\tif (\n\t\t\tmainView !== ActiveMainView.Localizations &&\n\t\t\tchromeStore.overlay?.type !== \"localization\" &&\n\t\t\t!chromeStore.isPreviewingLocaleOnCanvas &&\n\t\t\tmodalStore.active.type !== ModalType.BatchTranslate\n\t\t) {\n\t\t\tthis.#stopLoading?.()\n\t\t\tthis.#stopLoading = undefined\n\t\t\tthis.#releasePersistedCaches?.()\n\t\t\tthis.#releasePersistedCaches = undefined\n\t\t\tthis.#recalcTask.reset()\n\t\t\tthis.#previousMainView = mainView\n\t\t\treturn\n\t\t}\n\n\t\t// When the data-only tree is available (CRDT mode), all node data is accessible\n\t\t// directly from the CRDT store \u2014 no scope loading required. Fall back to the real\n\t\t// tree with its loader-based loading flow when the data tree is not available.\n\t\tconst dataTree = engine.stores.treeStore.getDataTree()\n\t\tconst tree = dataTree?.getCanvasTreeProxy() ?? engine.tree\n\n\t\t// The data tree drops per-node caches each frame. The localization view repeatedly\n\t\t// reads those caches (e.g. `localizationSourceGroup`) for every source on every\n\t\t// postProcess, so keep them alive while the view is open.\n\t\tthis.#releasePersistedCaches ??= tree.persistCaches()\n\n\t\tif (!dataTree) {\n\t\t\tconst loader = engine.tree.getService(\"loader\")\n\t\t\tif (loader) {\n\t\t\t\t// if there is no active loading subscription signal to start loading the full tree\n\t\t\t\tthis.#stopLoading ??= engine.runWithFullyLoadedTree(\n\t\t\t\t\tnoop,\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"LocalizationStore#postProcess\",\n\t\t\t\t\t\tmodalTitle: \"Loading Content\u2026\",\n\t\t\t\t\t\tmodalDescription: \"Loading all of your project content for localization. Just a moment\u2026\",\n\t\t\t\t\t\tmodalIncludeLocalizationState: true,\n\t\t\t\t\t\tcancellable: true,\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tchromeStore.setLocalizationsVisible(false)\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t// we are still loading and missing scopes data, so we return early\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst willAppear = previousMainView !== ActiveMainView.Localizations\n\n\t\t// Recalc is cheap if the tree and components hash are unchanged \u2014 the early return inside\n\t\t// `calculateLocalizationSourceState` makes that path nearly free, so don't defer for it.\n\t\tconst previousSourceState = this.#sourceState\n\t\tconst willActuallyRecalc =\n\t\t\t!previousSourceState ||\n\t\t\tpreviousSourceState.componentsHash !== componentsHash ||\n\t\t\t!previousSourceState.tree.equals(tree)\n\n\t\t// Defer when the upcoming calc would do real work and the gate has decided this project\n\t\t// is slow enough to warrant a debounce + paint barrier + toast.\n\t\tif (\n\t\t\tthis.#recalcTask.shouldDefer({\n\t\t\t\twillActuallyRecalc,\n\t\t\t\thasExistingResult: previousSourceState !== undefined,\n\t\t\t})\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// We're committed to running the calc this cycle, so consume the appearance signal.\n\t\tthis.#previousMainView = mainView\n\n\t\t// Sources calculation \u2014 measured so the gate can adapt future deferral decisions.\n\t\tconst calcStart = performance.now()\n\t\tconst sourceState = calculateLocalizationSourceState(\n\t\t\ttree,\n\t\t\tengine.componentLoader,\n\t\t\tcomponentsHash,\n\t\t\tpreviousSourceState,\n\t\t\tengine.stores.previewStore.framerSiteId,\n\t\t)\n\t\tthis.#recalcTask.recordCalc({\n\t\t\tdidRealWork: sourceState !== previousSourceState,\n\t\t\tdurationMs: performance.now() - calcStart,\n\t\t})\n\t\tthis.#sourceState = sourceState\n\n\t\t// initializeTranslatePagePathsSetting writes to the real tree and asserts it has no\n\t\t// loader; skip it when operating on the data-only tree because the real tree may\n\t\t// still be loading.\n\t\tif (!dataTree) {\n\t\t\tthis.initializeTranslatePagePathsSetting(engine, sourceState)\n\t\t}\n\n\t\tif (this.groups !== sourceState.groups) {\n\t\t\tthis.groups = sourceState.groups\n\t\t}\n\t\tif (this.progressPerLocale !== sourceState.progressPerLocale) {\n\t\t\tthis.progressPerLocale = sourceState.progressPerLocale\n\t\t}\n\n\t\t// View State\n\t\tconst locales = tree.root.locales\n\t\tconst activeLocale = getActiveLocale(tree, this.selectedLocaleId)\n\t\tconst activeLocaleId = activeLocale?.id ?? null\n\n\t\tif (activeLocaleId !== this.selectedLocaleId) {\n\t\t\tthis.selectedLocaleId = activeLocaleId\n\t\t}\n\n\t\t// Update scope filter if it no longer exists\n\t\tconst scopeFilter = this.scopeFilter && tree.has(this.scopeFilter) ? this.scopeFilter : null\n\t\tif (scopeFilter !== this.scopeFilter) {\n\t\t\tthis.scopeFilter = scopeFilter\n\t\t}\n\n\t\tconst visibleScopes = getVisibleScopes(tree, this.scopeFilter, this.visibleScopes)\n\t\tif (visibleScopes !== this.visibleScopes) {\n\t\t\tthis._visibleScopes = visibleScopes\n\t\t}\n\n\t\tconst viewState: ViewState = {\n\t\t\tscopeFilter,\n\t\t\tselectedLocaleId: activeLocaleId,\n\t\t\tsearchTerm: this.searchTerm,\n\t\t\tstatus: this.status,\n\t\t}\n\n\t\tconst viewStateDidChange = !isEqual(viewState, this.#previousViewState)\n\t\tthis.#previousViewState = viewState\n\n\t\tif (!locales || locales.length === 0 || !activeLocale) {\n\t\t\tif (this.persistedGroupAndSourceOrder.size > 0) {\n\t\t\t\tthis.persistedGroupAndSourceOrder = new Map()\n\t\t\t}\n\t\t\tif (this.persistedSubGroupAndSourcesOrder.size > 0) {\n\t\t\t\tthis.persistedSubGroupAndSourcesOrder = new Map()\n\t\t\t}\n\t\t\tthis.groups = null\n\t\t\tthis.virtualListItems = null\n\t\t\tthis.filteredGroupsAndSources = null\n\t\t\treturn\n\t\t}\n\n\t\tthis.filteredGroupsAndSources = filterLocalizationSourceGroups(\n\t\t\tactiveLocale,\n\t\t\tlocales,\n\t\t\tthis.scopeFilter,\n\t\t\tthis.visibleScopes,\n\t\t\tthis.searchTerm,\n\t\t\tthis.status,\n\t\t\tthis.groups,\n\t\t)\n\n\t\tconst filteredGroupsById = updatePersistedSourceOrderAndGetFilteredGroupsById(\n\t\t\tthis.filteredGroupsAndSources,\n\t\t\tthis.persistedGroupAndSourceOrder,\n\t\t\tthis.persistedSubGroupAndSourcesOrder,\n\t\t)\n\n\t\tthis.virtualListItems = getVirtualListItems(\n\t\t\tthis.persistedGroupAndSourceOrder,\n\t\t\tthis.persistedSubGroupAndSourcesOrder,\n\t\t\tthis.expandedSourceGroups,\n\t\t\tfilteredGroupsById,\n\t\t\tsourceState,\n\t\t\tactiveLocale,\n\t\t)\n\n\t\tif (viewStateDidChange || willAppear) {\n\t\t\tdismissMatchingItemsToast()\n\t\t\tthis.resetPersistedOrder(tree)\n\t\t}\n\t}\n\n\tget hasCalculatedLocalizationState() {\n\t\treturn Boolean(this.#sourceState)\n\t}\n\n\tget visibleScopes(): ReadonlySet<NodeID> | null {\n\t\treturn this._visibleScopes\n\t}\n\n\tprivate readonly uniqueLocalizedValuesByHashCache = new Map<number, UniqueLocalizedValues>()\n\n\t/**\n\t * For a given source, returns a list of all translated strings without\n\t * duplicates. Letter casing and leading/trailing white space **is** taken\n\t * into account.\n\t * */\n\tgetUniqueLocalizedValues(source: LocalizationSource, activeLocale: Locale): UniqueLocalizedValues {\n\t\tif (!this.#sourceState || !source.value) return emptyUniqueLocalizedValues\n\n\t\tconst keyPaths = this.#sourceState.keyPathsByHash.get(source.hash)\n\t\tif (!keyPaths) return emptyUniqueLocalizedValues\n\n\t\tconst uniqueLocalizedValues = new Set<string>()\n\n\t\tfor (const keyPath of keyPaths) {\n\t\t\tconst sourceWithEqualHash = this.#sourceState.sourceByKeyPath.get(keyPath)\n\t\t\tif (!sourceWithEqualHash) continue\n\n\t\t\tconst localizedValue = sourceWithEqualHash.localizedValues[activeLocale.id]\n\t\t\tif (!isNonNullLocalizedValue(localizedValue)) continue\n\n\t\t\tconst value = getLocalizedValueText(localizedValue, { preserveNewLines: true })\n\t\t\tif (!value) continue\n\n\t\t\tuniqueLocalizedValues.add(value)\n\t\t}\n\n\t\tconst cachedValue = this.uniqueLocalizedValuesByHashCache.get(source.hash)\n\n\t\tif (cachedValue && isShallowSetEqual(cachedValue, uniqueLocalizedValues)) {\n\t\t\treturn cachedValue\n\t\t}\n\n\t\tthis.uniqueLocalizedValuesByHashCache.set(source.hash, uniqueLocalizedValues)\n\t\treturn uniqueLocalizedValues\n\t}\n\n\tgetSourceForKeyPath = (keyPath: string) => {\n\t\treturn this.#sourceState?.sourceByKeyPath.get(keyPath)\n\t}\n\n\tgetLocalizedValueCountForLocale(localeId: LocaleId) {\n\t\tconst state = this.#sourceState\n\t\tif (!state) return 0\n\n\t\treturn countLocalizedValuesForLocale(state.groups, localeId)\n\t}\n\n\tget totalTranslatedItemCount(): number {\n\t\treturn this.#sourceState?.totalTranslatedItemCount ?? 0\n\t}\n\n\tget batchTranslatableItemCountPerLocale(): CountPerLocale {\n\t\treturn this.#sourceState?.batchTranslatableItemCountPerLocale ?? batchTranslatableItemCountPerLocaleFallback\n\t}\n\n\tgetTranslatedWordCountForLocale(localeId: LocaleId): number {\n\t\tif (!this.#sourceState?.translatedWordCountPerLocale) return 0\n\t\treturn this.#sourceState.translatedWordCountPerLocale[localeId] ?? 0\n\t}\n\n\tsetSourceGroupExpanded(groupId: LocalizationGroupID, activeLocale: Locale, expanded: boolean, all: boolean) {\n\t\tconst sourceState = this.#sourceState\n\t\tif (!sourceState) return\n\n\t\tconst expandedSourceGroups = new Map(this.expandedSourceGroups)\n\t\texpandedSourceGroups.set(groupId, expanded)\n\n\t\tif (all) {\n\t\t\tconst selectedGroup = sourceState.groupById.get(groupId)\n\t\t\tconst selectedGroupIsExcluded = selectedGroup ? isGroupExcludedInLocale(selectedGroup, activeLocale) : false\n\n\t\t\tfunction applyToAllGroups(groups: readonly LocalizationSourceGroup[]) {\n\t\t\t\tfor (const group of groups) {\n\t\t\t\t\tif (!selectedGroupIsExcluded && isGroupExcludedInLocale(group, activeLocale)) continue\n\n\t\t\t\t\texpandedSourceGroups.set(group.nodeId, expanded)\n\n\t\t\t\t\tif (withLocalizationSubGroups(group)) {\n\t\t\t\t\t\tapplyToAllGroups(group.groups)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (selectedGroup?.groupType === \"collectionItem\") {\n\t\t\t\tconst parentGroup = sourceState.groupById.get(selectedGroup.collectionNodeId)\n\t\t\t\tif (parentGroup && withLocalizationSubGroups(parentGroup)) {\n\t\t\t\t\tapplyToAllGroups(parentGroup.groups)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tapplyToAllGroups(sourceState.groups)\n\t\t\t}\n\t\t}\n\n\t\tthis.expandedSourceGroups = expandedSourceGroups\n\t}\n\n\t/** Removes items that should be hidden according to the latest filters. And sorts all items. */\n\tresetPersistedOrder(tree: CanvasTree) {\n\t\tif (!this.filteredGroupsAndSources || !this.#sourceState) return\n\n\t\tconst activeLocale = getActiveLocale(tree, this.selectedLocaleId)\n\t\tif (!activeLocale) return\n\n\t\tthis.persistedGroupAndSourceOrder.clear()\n\t\tthis.persistedSubGroupAndSourcesOrder.clear()\n\n\t\tconst filteredGroupsById = updatePersistedSourceOrderAndGetFilteredGroupsById(\n\t\t\tthis.filteredGroupsAndSources,\n\t\t\tthis.persistedGroupAndSourceOrder,\n\t\t\tthis.persistedSubGroupAndSourcesOrder,\n\t\t)\n\n\t\tthis.virtualListItems = getVirtualListItems(\n\t\t\tthis.persistedGroupAndSourceOrder,\n\t\t\tthis.persistedSubGroupAndSourcesOrder,\n\t\t\tthis.expandedSourceGroups,\n\t\t\tfilteredGroupsById,\n\t\t\tthis.#sourceState,\n\t\t\tactiveLocale,\n\t\t)\n\t}\n\n\tpostProcessAutoTranslation(engine: VekterEngine, tree: CanvasTree, remote: boolean): void {\n\t\t// Process tree changes for auto-translation to managed locales\n\t\tconst framerSiteId = engine.stores.previewStore.framerSiteId\n\t\tconst aiManagedLocalesEnabled = experimentIsOnOrForceEnabled(\"localizationAiUpdate\", framerSiteId)\n\t\tif (!aiManagedLocalesEnabled) return\n\n\t\tif (!this.#automaticTranslationService) {\n\t\t\tthis.#automaticTranslationService = new AutomaticTranslationService(engine)\n\t\t}\n\n\t\tthis.#automaticTranslationService.ingestTreeChanges(tree, remote)\n\t}\n\n\t// Auto-set translatePagePaths site metadata if it is undefined (runtime migration) based on\n\t// whether translated CMS slugs exist. Sites using localized slugs get the setting turned\n\t// on, sites without them get it turned off.\n\tinitializeTranslatePagePathsSetting(engine: VekterEngine, sourceState: LocalizationSourceState) {\n\t\tassert(!engine.tree.getService(\"loader\"), \"Tree should be fully loaded\")\n\t\tif (this.#hasAutoSetTranslatePagePaths) return\n\t\tif (engine.tree.root.translatePagePaths !== \"legacy\") return\n\t\tif (getIsViewOnly(engine, \"canEditSiteSettings\")) return\n\n\t\tthis.#hasAutoSetTranslatePagePaths = true\n\n\t\tconst hasCMSSlugTranslations = (sourceState.groups || []).some(group =>\n\t\t\tsomeLocalizationSourceInGroup(group, source => {\n\t\t\t\tif (source.type !== \"slug\" && source.type !== ClassDiscriminator.RouteSegmentNode) return false\n\n\t\t\t\tfor (const localizedValue of Object.values(source.localizedValues)) {\n\t\t\t\t\tif (isNonNullLocalizedValue(localizedValue) && localizedValue.value) return true\n\t\t\t\t}\n\n\t\t\t\treturn false\n\t\t\t}),\n\t\t)\n\n\t\tengine.scheduler.processWhenReady(() => {\n\t\t\tconst rootNode = engine.tree.root\n\t\t\tconst translatePagePaths = hasCMSSlugTranslations\n\t\t\trootNode.set({ webMetadata: { ...rootNode.webMetadata, translatePagePaths } })\n\t\t}, \"nonUserEvent\")\n\t}\n}\n\ntype GroupByID = Map<string, LocalizationSourceGroup>\n\nfunction collectPersistedSourceOrderAndGroupByID(\n\tfilteredGroupsAndSources: readonly LocalizationSourceGroup[],\n\tpersistedGroupAndSourceOrder: SourceOrderByGroup,\n\tpersistedSubGroupAndSourcesOrder: SubGroupOrderByGroup,\n\tfilteredGroupsById: GroupByID,\n): void {\n\tfor (const group of filteredGroupsAndSources) {\n\t\tfilteredGroupsById.set(group.nodeId, group)\n\n\t\tconst persistedSourceOrder = persistedGroupAndSourceOrder.get(group.nodeId) || new Set()\n\t\tpersistedGroupAndSourceOrder.set(group.nodeId, persistedSourceOrder)\n\n\t\tfor (const source of group.items) {\n\t\t\t// Append new items to the end\n\t\t\tpersistedSourceOrder.add(source.keyPath)\n\t\t}\n\n\t\tif (withLocalizationSubGroups(group)) {\n\t\t\tconst persistedSubGroupSourceOrder: SourceOrderByGroup =\n\t\t\t\tpersistedSubGroupAndSourcesOrder.get(group.nodeId) ?? new Map()\n\t\t\tpersistedSubGroupAndSourcesOrder.set(group.nodeId, persistedSubGroupSourceOrder)\n\t\t\tcollectPersistedSourceOrderAndGroupByID(\n\t\t\t\tgroup.groups,\n\t\t\t\tpersistedSubGroupSourceOrder,\n\t\t\t\tpersistedSubGroupAndSourcesOrder,\n\t\t\t\tfilteredGroupsById,\n\t\t\t)\n\t\t}\n\t}\n}\n\nfunction updatePersistedSourceOrderAndGetFilteredGroupsById(\n\tfilteredGroupsAndSources: readonly LocalizationSourceGroup[],\n\tpersistedGroupAndSourceOrder: SourceOrderByGroup,\n\tpersistedSubGroupAndSourcesOrder: SubGroupOrderByGroup,\n): GroupByID {\n\tconst filteredGroupsById: GroupByID = new Map()\n\n\tcollectPersistedSourceOrderAndGroupByID(\n\t\tfilteredGroupsAndSources,\n\t\tpersistedGroupAndSourceOrder,\n\t\tpersistedSubGroupAndSourcesOrder,\n\t\tfilteredGroupsById,\n\t)\n\n\treturn filteredGroupsById\n}\n\n/**\n * Returns a flattened list of the filtered groups and sources. The order is persisted so newly\n * added items are appended to the end. This should prevent big jumps in the scroll position due to\n * multi player edits. Items and sub groups of collapsed groups are not included.\n */\nfunction getVirtualListItems(\n\tgroupAndSourceOrder: SourceOrderByGroup,\n\tsubGroupAndSourcesOrder: SubGroupOrderByGroup,\n\texpandedSourceGroups: ReadonlyMap<LocalizationGroupID, boolean>,\n\tfilteredGroupsById: GroupByID,\n\tsourceState: LocalizationSourceState,\n\tactiveLocale: Locale,\n\tcollectedVirtualListItems: (LocalizationSourceGroup | LocalizationSource)[] = [],\n): (LocalizationSourceGroup | LocalizationSource)[] {\n\tfor (const [activeSourceGroupId, sourceOrder] of groupAndSourceOrder) {\n\t\tconst group =\n\t\t\tfilteredGroupsById.get(activeSourceGroupId) ??\n\t\t\t// When you unhide a source group and a \"hidden\" filter is active it will be removed\n\t\t\t// from the filtered groups. But we still want to display them (only on \"reset persisted\n\t\t\t// order\" are they hidden). So we fallback to the sourceState if that occurs.\n\t\t\tsourceState.groupById.get(activeSourceGroupId)\n\n\t\tif (!group) continue\n\n\t\tcollectedVirtualListItems.push(group)\n\n\t\tif (!isExpandedSourceGroup(group, activeLocale, expandedSourceGroups)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor (const keyPath of sourceOrder) {\n\t\t\tconst source = sourceState.sourceByKeyPath.get(keyPath)\n\t\t\tif (source) collectedVirtualListItems.push(source)\n\t\t}\n\n\t\tif (withLocalizationSubGroups(group)) {\n\t\t\tconst subGroupOrderByGroup = subGroupAndSourcesOrder.get(group.nodeId)\n\t\t\tassert(subGroupOrderByGroup)\n\n\t\t\tgetVirtualListItems(\n\t\t\t\tsubGroupOrderByGroup,\n\t\t\t\tsubGroupAndSourcesOrder,\n\t\t\t\texpandedSourceGroups,\n\t\t\t\tfilteredGroupsById,\n\t\t\t\tsourceState,\n\t\t\t\tactiveLocale,\n\t\t\t\tcollectedVirtualListItems,\n\t\t\t)\n\t\t}\n\t}\n\n\treturn collectedVirtualListItems\n}\n\nfunction countLocalizedValuesForLocale(groups: readonly LocalizationSourceGroup[], activeLocaleId: LocaleId): number {\n\tlet count = 0\n\n\tfor (const group of groups) {\n\t\tfor (const source of group.items) {\n\t\t\tif (source.localizedValues[activeLocaleId]) {\n\t\t\t\tcount += 1\n\t\t\t}\n\t\t}\n\t\tif (withLocalizationSubGroups(group)) {\n\t\t\tcount += countLocalizedValuesForLocale(group.groups, activeLocaleId)\n\t\t}\n\t}\n\n\treturn count\n}\n\nconst batchTranslatableItemCountPerLocaleFallback: CountPerLocale = {}\n", "import { EngineStore } from \"document/EngineStore.ts\"\n\nexport class MouseCursorStore extends EngineStore {\n\tcurrent?: string\n\n\tclear() {\n\t\tthis.current = undefined\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { List } from \"@framerjs/shared\"\nimport { getRelatedReplicaNodes } from \"code-generation/utils/isOnlyVisibleInCurrentVariant.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { eventsForNode } from \"document/components/chrome/properties/utils/eventActions.ts\"\nimport { isShowOverlayAction } from \"document/models/CanvasTree/actions/overlayActions.ts\"\nimport type {\n\tCanvasNode,\n\tCanvasTree,\n\tCodeComponentNode,\n\tMaybeNodeID,\n\tNodeID,\n\tOverlayNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport { getVariantForNode } from \"document/models/CanvasTree/nodes/utils/breakpointHelpers.ts\"\nimport { isCodeComponentNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport {\n\tisFixedOrRelativeOverlay,\n\tisValidOverlay,\n\tnodeIsInOverlay,\n} from \"document/models/CanvasTree/nodes/utils/overlayHelpers.ts\"\nimport type { WithFloatingPosition } from \"document/models/CanvasTree/traits/WithFloatingPosition.ts\"\nimport { hasFloatingPosition } from \"document/models/CanvasTree/traits/WithFloatingPosition.ts\"\nimport type { WithFrameEvents } from \"document/models/CanvasTree/traits/WithFrameEvents.ts\"\nimport { withFrameEvents } from \"document/models/CanvasTree/traits/WithFrameEvents.ts\"\nimport { isReplicaOrReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport type { WithFormInputEvents } from \"document/models/CanvasTree/traits/forms/WithFormInputEvents.ts\"\nimport { withFormInputEvents } from \"document/models/CanvasTree/traits/forms/WithFormInputEvents.ts\"\nimport type { EventAction } from \"document/models/EventAction.ts\"\nimport { prefixControlProps } from \"document/models/controlProps/controlPropKey.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport { setOverlayAndDescendantVisibility } from \"utils/setOverlayAndDescendantVisibility.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\ntype OverlayID = NodeID\ntype BreakpointID = NodeID\nlet _cachedVariantsWithActiveOverlays: Map<BreakpointID, OverlayID> = new Map()\nlet _prevActiveOverlays: ReadonlySet<OverlayID> | null = null\n\ninterface OverlayInfo {\n\toverlayToSelect: OverlayID\n\toverlaysToShow: Set<OverlayID>\n}\n\nexport class OverlayStore extends EngineStore {\n\tprivate _activeOverlays: ReadonlySet<OverlayID> = new Set<OverlayID>()\n\tprivate _activeRelativeOverlayTriggers: ReadonlySet<NodeID> = new Set<NodeID>()\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t) {\n\t\tsuper()\n\t}\n\n\tget activeOverlays() {\n\t\treturn this._activeOverlays\n\t}\n\n\tget activeRelativeOverlayTriggers() {\n\t\treturn this._activeRelativeOverlayTriggers\n\t}\n\n\tget variantsWithActiveOverlays() {\n\t\tconst { tree } = this.treeStore\n\t\tif (this._activeOverlays === _prevActiveOverlays) return _cachedVariantsWithActiveOverlays\n\n\t\tconst variants: Map<BreakpointID, OverlayID> = new Map()\n\t\tthis._activeOverlays.forEach(overlayId => {\n\t\t\tconst variant = getVariantForNode(tree, overlayId)\n\t\t\tif (variant) variants.set(variant.id, overlayId)\n\t\t})\n\t\t_cachedVariantsWithActiveOverlays = variants\n\t\t_prevActiveOverlays = this._activeOverlays\n\t\treturn variants\n\t}\n\n\tdelete(selection: SelectionStore, overlayNodeId: NodeID, triggerNodeId: NodeID) {\n\t\tconst { tree } = this.treeStore\n\t\t// Allow cleaning up the overlay action even if the overlay node no\n\t\t// longer exists.\n\t\tthis.cleanupOverlay(selection, overlayNodeId, triggerNodeId)\n\n\t\tconst overlayNode = tree.get(overlayNodeId)\n\t\tif (!overlayNode || !isFixedOrRelativeOverlay(overlayNode)) return\n\n\t\ttree.remove(overlayNode.id)\n\t}\n\n\tget editModeActive() {\n\t\tfor (const id of this._activeOverlays) {\n\t\t\tconst node = this.treeStore.tree.get(id)\n\t\t\tif (isFixedOrRelativeOverlay(node)) return true\n\t\t}\n\t\treturn false\n\t}\n\n\texitEditMode(selection: SelectionStore, triggerSelectionChange: boolean = true) {\n\t\tif (triggerSelectionChange) {\n\t\t\tconst nodeId = selection.ids[0]\n\t\t\tconst node = this.treeStore.tree.get(nodeId)\n\t\t\tconst overlayNode = this.treeStore.tree.get(node?.cache.overlayAncestorId)\n\t\t\tconst overlayTrigger = this.treeStore.tree.get(overlayNode?.parentid)\n\t\t\tif (overlayTrigger) {\n\t\t\t\tselection.set(overlayTrigger.id)\n\t\t\t} else {\n\t\t\t\tselection.clear()\n\t\t\t}\n\t\t}\n\t\tthis.hideAll()\n\t}\n\n\t/**\n\t * Use the selection to ensure that a selected overlay is always shown when\n\t * it or any of its descendants are selected, without ever hiding overlays.\n\t * The user is in control of hiding overlays to allow contents outside of\n\t * the overlay to be manipulated.\n\t */\n\tonCanvasSelectionChange(\n\t\tids: Iterable<NodeID>,\n\t\t{ toggle, tree = this.treeStore.tree }: { toggle?: boolean; tree?: CanvasTree } = {},\n\t) {\n\t\tconst overlays = new Set<NodeID>(toggle ? [] : this._activeOverlays)\n\n\t\t// Prune the active overlays to only include ones in the tree at the\n\t\t// time of the selection change.\n\t\tfor (const id of overlays) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) overlays.delete(id)\n\t\t}\n\n\t\tfor (const id of ids) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\n\t\t\tif (isFixedOrRelativeOverlay(node)) {\n\t\t\t\toverlays.add(node.id)\n\t\t\t} else if (nodeIsInOverlay(node)) {\n\t\t\t\tconst overlay = tree.get(node.cache.overlayAncestorId)\n\t\t\t\tif (isFixedOrRelativeOverlay(overlay)) overlays.add(overlay.id)\n\t\t\t}\n\t\t}\n\n\t\tthis.show(overlays, tree)\n\t}\n\n\t/**\n\t * Sometimes we want to show a primary overlay, but select its replica.\n\t */\n\tshowOverlay(\n\t\tselection: SelectionStore,\n\t\toverlay: OverlayNode | (CanvasNode & WithFloatingPosition),\n\t\ttriggerId: MaybeNodeID,\n\t\tsetSelection: boolean = true,\n\t) {\n\t\tconst overlayInfo = this.overlayInfo(overlay, triggerId)\n\t\tif (!overlayInfo) return\n\n\t\tconst { overlayToSelect, overlaysToShow } = overlayInfo\n\n\t\tif (setSelection) selection.set(overlayToSelect)\n\n\t\tthis.show(overlaysToShow, this.treeStore.tree)\n\t}\n\n\t/**\n\t * Collect the overlays we need to show and select based on the overlay id\n\t * and the trigger node id. The function needs to anticipate both cases when\n\t * the overlay/trigger id is a primary id and replica id. For example, the\n\t * overlay id recorded in the action is the primary overlay node id, and we\n\t * may be trying to select the overlay of the replica.\n\t */\n\tprivate overlayInfo(\n\t\toverlayNode: OverlayNode | (CanvasNode & WithFloatingPosition),\n\t\ttriggerId: MaybeNodeID,\n\t): OverlayInfo | undefined {\n\t\tconst { tree } = this.treeStore\n\n\t\tconst triggerNode = tree.get(triggerId)\n\t\tif (!triggerNode) return\n\n\t\tconst triggerIsReplica = isReplicaOrReplicaChild(triggerNode)\n\n\t\tconst primaryOverlayId = overlayNode.getPrimaryId()\n\t\tconst primaryTriggerNode = triggerNode.originalid ? tree.getNode(triggerNode.originalid) : triggerNode\n\t\tif (!primaryTriggerNode) return\n\n\t\tlet overlayToSelect: NodeID | null = overlayNode.id\n\t\tif (triggerIsReplica) {\n\t\t\tconst replica = getVariantForNode(tree, triggerNode.id)\n\t\t\tif (replica) overlayToSelect = generateReplicaChildId(replica.id, primaryOverlayId)\n\t\t}\n\n\t\tconst primaryAndReplicaOverlayIds = new Set<NodeID>()\n\n\t\tif (primaryTriggerNode.isVisible() && primaryTriggerNode.cache.visible) {\n\t\t\tprimaryAndReplicaOverlayIds.add(primaryOverlayId)\n\t\t}\n\n\t\tfor (const { relatedNode } of getRelatedReplicaNodes(tree, primaryTriggerNode)) {\n\t\t\tif (relatedNode.isVisible() && relatedNode.cache.visible) {\n\t\t\t\tconst replica = getVariantForNode(tree, relatedNode.id)\n\t\t\t\tif (replica) primaryAndReplicaOverlayIds.add(generateReplicaChildId(replica.id, primaryOverlayId))\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\toverlayToSelect,\n\t\t\toverlaysToShow: primaryAndReplicaOverlayIds,\n\t\t}\n\t}\n\n\tprivate show(overlayNodeIds: Iterable<NodeID>, tree: CanvasTree) {\n\t\tconst activeOverlays = new Set<OverlayID>()\n\t\tconst activeRelativeOverlayTriggers = new Set<NodeID>()\n\t\tthis._activeOverlays = activeOverlays\n\t\tthis._activeRelativeOverlayTriggers = activeRelativeOverlayTriggers\n\n\t\tfor (const overlayNodeId of overlayNodeIds) {\n\t\t\tconst overlayNode = tree.get(overlayNodeId)\n\t\t\tif (!overlayNode || !isFixedOrRelativeOverlay(overlayNode) || !isValidOverlay(overlayNode, tree)) continue\n\n\t\t\tactiveOverlays.add(overlayNodeId)\n\n\t\t\tif (overlayNode.parentid && hasFloatingPosition(overlayNode)) {\n\t\t\t\tactiveRelativeOverlayTriggers.add(overlayNode.parentid)\n\t\t\t}\n\n\t\t\tsetOverlayAndDescendantVisibility(tree, overlayNode, true)\n\t\t}\n\t}\n\n\thide(overlayNodeIds: Iterable<NodeID>) {\n\t\tconst activeOverlays = new Set(this._activeOverlays)\n\t\tthis._activeOverlays = activeOverlays\n\n\t\t// Groom the active overlay ids to remove any deleted nodes.\n\t\tfor (const id of this._activeOverlays) {\n\t\t\tconst node = this.treeStore.tree.get(id)\n\t\t\tif (!isFixedOrRelativeOverlay(node)) activeOverlays.delete(id)\n\t\t}\n\n\t\tconst activeRelativeOverlayTriggers = new Set(this._activeRelativeOverlayTriggers)\n\t\tthis._activeRelativeOverlayTriggers = activeRelativeOverlayTriggers\n\n\t\tconst { tree } = this.treeStore\n\n\t\tfor (const overlayNodeId of overlayNodeIds) {\n\t\t\tactiveOverlays.delete(overlayNodeId)\n\n\t\t\tconst overlayNode = tree.get(overlayNodeId)\n\t\t\tif (!overlayNode) continue\n\n\t\t\tif (overlayNode.parentid && hasFloatingPosition(overlayNode)) {\n\t\t\t\tactiveRelativeOverlayTriggers.delete(overlayNode.parentid)\n\t\t\t}\n\n\t\t\tsetOverlayAndDescendantVisibility(tree, overlayNode, false)\n\t\t}\n\t}\n\n\thideAll() {\n\t\tif (this._activeOverlays.size === 0) return\n\n\t\tthis.hide(this._activeOverlays)\n\t}\n\n\tcleanupOverlay(\n\t\tselection: SelectionStore,\n\t\toverlayId: NodeID,\n\t\ttriggerNodeId: MaybeNodeID,\n\t\ttrackDelete: boolean = true,\n\t) {\n\t\tif (this._activeOverlays.has(overlayId)) {\n\t\t\tthis._activeOverlays = new Set()\n\t\t\tthis._activeRelativeOverlayTriggers = new Set()\n\t\t}\n\t\tif (!this.editModeActive) this.exitEditMode(selection)\n\n\t\tthis.cleanupOverlayAction(overlayId, triggerNodeId)\n\n\t\tif (trackDelete) {\n\t\t\trecord(\"overlay_delete\", {})\n\t\t}\n\t}\n\n\tprivate cleanupOverlayAction(overlayId: NodeID, triggerNodeId: MaybeNodeID) {\n\t\tif (!triggerNodeId) return\n\t\tconst { tree } = this.treeStore\n\t\tlet trigger = tree.getNode(triggerNodeId)\n\t\tif (trigger?.originalid) {\n\t\t\ttrigger = tree.getNode(trigger.originalid)\n\t\t}\n\t\tif (!trigger || !(isCodeComponentNode(trigger) || withFrameEvents(trigger) || withFormInputEvents(trigger))) {\n\t\t\treturn\n\t\t}\n\n\t\tfor (const eventKey in eventsForNode(this.componentLoader, trigger)) {\n\t\t\tconst actions = getNodeActions(trigger, eventKey)\n\t\t\tfor (let index = 0; index < actions.length; index++) {\n\t\t\t\tconst action = actions[index]\n\t\t\t\tif (isShowOverlayAction(action) && action.controls.overlay.value === overlayId) {\n\t\t\t\t\tconst newActions = List.remove(getNodeActions(trigger, eventKey), index)\n\t\t\t\t\tif (isCodeComponentNode(trigger)) {\n\t\t\t\t\t\ttrigger.set(prefixControlProps({ [eventKey]: { type: ControlType.EventHandler, value: newActions } }))\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\ttrigger.set({ [eventKey]: newActions })\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate someOverlaysAreDeleted(tree: CanvasTree): boolean {\n\t\tfor (const overlayId of this._activeOverlays) {\n\t\t\tif (!tree.has(overlayId)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tpostProcess(tree: CanvasTree) {\n\t\tif (!this.someOverlaysAreDeleted(tree)) return\n\n\t\t// Clean up any active overlay that is no longer in the tree\n\t\tconst activeOverlays = new Set(this._activeOverlays)\n\t\tthis._activeOverlays = activeOverlays\n\n\t\tfor (const activeOverlayId of activeOverlays) {\n\t\t\tif (tree.has(activeOverlayId)) continue\n\t\t\tactiveOverlays.delete(activeOverlayId)\n\t\t}\n\t}\n}\n\ntype NodeWithActions<T extends CanvasNode> = (T & WithFrameEvents) | (T & WithFormInputEvents) | CodeComponentNode\n\nfunction getNodeActions<T extends CanvasNode>(node: NodeWithActions<T>, eventKey: string): readonly EventAction[] {\n\tif (isCodeComponentNode(node)) {\n\t\tconst controlProp = node.getRawControlProp(eventKey)\n\t\tif (!controlProp || !Array.isArray(controlProp.value)) return []\n\t\treturn controlProp.value\n\t} else {\n\t\treturn (node[eventKey as keyof typeof node] as EventAction[] | undefined) ?? []\n\t}\n}\n", "import type {\n\tPaidProjectLicenseType,\n\tProjectLicensePeriod,\n\tProjectLicenseType,\n\tTeamLicenseType,\n} from \"@framerjs/app-shared\"\nimport type { AddOnLicenseType } from \"@framerjs/app-shared/src/AddOnPlan.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { CheckoutPreview } from \"document/components/chrome/siteSettings/Plans/Stripe/api/checkoutPreview.ts\"\nimport type {\n\tLicenseSettings,\n\tPaidLicenseSettings,\n} from \"document/components/chrome/siteSettings/Plans/Stripe/api/licenseSettings.ts\"\nimport type {\n\tCurrentAddOn,\n\tCurrentSiteSubscription,\n\tPollUpdateProps,\n} from \"document/components/chrome/siteSettings/Plans/Stripe/api/subscriptions.ts\"\nimport type { CurrentTeamSubscription } from \"document/components/chrome/siteSettings/Plans/Stripe/api/teamSubscription.ts\"\nimport type { PollResponse } from \"web/pages/project/lib/api/pollProject.ts\"\n\nexport enum SitePlansStatus {\n\tLoading,\n\tDraftProjectError,\n\tEnterprisePlan,\n\tUnauthorizedError,\n\tFailedToFetchSubscriptionsError,\n\tStripe,\n\tRedirectedFromStripe,\n\tRedirectedFromStripePollingError,\n}\n\nexport type SitePlans =\n\t| { status: SitePlansStatus.Loading }\n\t| { status: SitePlansStatus.DraftProjectError }\n\t| { status: SitePlansStatus.EnterprisePlan }\n\t| { status: SitePlansStatus.UnauthorizedError }\n\t| { status: SitePlansStatus.FailedToFetchSubscriptionsError }\n\t| {\n\t\t\tstatus: SitePlansStatus.Stripe\n\t\t\tprojectId: string\n\t\t\tteamId: string\n\t\t\tcurrentProjectLicenseType: Exclude<ProjectLicenseType, ProjectLicenseType.EnterpriseSite>\n\t\t\tcurrentTeamLicenseType: Exclude<TeamLicenseType, TeamLicenseType.EnterprisePlan>\n\t\t\tcurrentSiteSubscription: CurrentSiteSubscription | null\n\t\t\tcurrentTeamSubscription: CurrentTeamSubscription | null\n\t\t\tpollSubscriptionsUpdate: (newProps: PollUpdateProps) => Promise<void>\n\t\t\tpollProjectLicenseUpdate: (licenseType: ProjectLicenseType) => Promise<PollResponse>\n\t\t\trefreshSubscriptions: () => Promise<void>\n\t\t\tteamCurrentEditors: number\n\t\t\tteamHasPastDueSubscriptions: boolean\n\t\t\tcurrentAddOns: CurrentAddOn[]\n\t  }\n\t| {\n\t\t\tstatus: SitePlansStatus.RedirectedFromStripe\n\t\t\tcurrentProjectLicenseType: PaidProjectLicenseType\n\t\t\tcurrentTeamLicenseType: Exclude<TeamLicenseType, TeamLicenseType.EnterprisePlan>\n\t\t\tbillingPeriod: ProjectLicensePeriod | null\n\t\t\tteamCurrentEditors: number\n\t\t\tcurrentTeamSubscription: CurrentTeamSubscription | null\n\t\t\tcurrentAddOns: CurrentAddOn[]\n\t  }\n\t| { status: SitePlansStatus.RedirectedFromStripePollingError }\n\nexport enum StripePlansStatus {\n\tLoading,\n\tPlans,\n\tLoadingPreview,\n\tReactivating,\n\tPreview,\n\tUpdatingPreview,\n\tConfirmingPurchase,\n\tSuccess,\n\tUnauthorizedError,\n\tFailedToFetchPricesError,\n\tCheckoutSessionError,\n\tDuplicateCheckoutError,\n\tCheckoutPreviewError,\n\tReactivatePlanError,\n\tUpdateSubscriptionError,\n\tPaymentDeclinedError,\n\tOverEditorLimitError,\n\tOverProjectEditorLimitError,\n\tCantMoveAddOnError,\n\tInvalidPromotionCodeError,\n}\n\nexport type PromotionCodeState =\n\t| { status: \"applied\"; code: string }\n\t| { status: \"error\"; reason: \"invalid\" }\n\t| { status: \"error\"; reason: \"noDiscount\"; code: string }\n\nexport type StripePlans =\n\t| { status: StripePlansStatus.Loading }\n\t| {\n\t\t\tstatus: StripePlansStatus.Plans\n\t\t\tlicensesSettings: LicenseSettings[]\n\t\t\t/** @deprecated delete after we enable the \"newPricing\" experiment */\n\t\t\tinitialLicenseTypeForPlansToggle: ProjectLicenseType | null\n\t  }\n\t| {\n\t\t\tstatus: StripePlansStatus.LoadingPreview | StripePlansStatus.Reactivating\n\t\t\tlicensesSettings: LicenseSettings[]\n\t\t\t/** To be used to show a spinner in a selected plan button */\n\t\t\tselectedProjectLicenseType: PaidProjectLicenseType\n\t\t\t/** @deprecated delete after we enable the \"newPricing\" experiment */\n\t\t\tinitialLicenseTypeForPlansToggle: ProjectLicenseType | null\n\t\t\tselectedAddons?: AddOnLicenseType[]\n\t  }\n\t| {\n\t\t\tstatus: StripePlansStatus.Preview | StripePlansStatus.UpdatingPreview | StripePlansStatus.ConfirmingPurchase\n\t\t\tcheckoutPreview: CheckoutPreview\n\t\t\tlicensesSettings: LicenseSettings[]\n\t\t\tselectedPlan: PaidLicenseSettings\n\t\t\tpreviousProjectLicenseType: ProjectLicenseType\n\t\t\tpreviousProjectPeriod?: ProjectLicensePeriod\n\t\t\tselectedProjectPeriod: ProjectLicensePeriod\n\t\t\tselectedAddons?: AddOnLicenseType[]\n\t\t\tpromotionCode?: PromotionCodeState\n\t  }\n\t| {\n\t\t\tstatus: StripePlansStatus.Success\n\t\t\tpreviousProjectLicenseType: ProjectLicenseType\n\t\t\tselectedProjectLicenseType: PaidProjectLicenseType\n\t\t\tlicensesSettings: LicenseSettings[]\n\t\t\tpreviousProjectPeriod?: ProjectLicensePeriod\n\t\t\tselectedProjectPeriod: ProjectLicensePeriod\n\t  }\n\t| {\n\t\t\tstatus:\n\t\t\t\t| StripePlansStatus.UnauthorizedError\n\t\t\t\t| StripePlansStatus.FailedToFetchPricesError\n\t\t\t\t| StripePlansStatus.CheckoutSessionError\n\t\t\t\t| StripePlansStatus.DuplicateCheckoutError\n\t\t\t\t| StripePlansStatus.CheckoutPreviewError\n\t\t\t\t| StripePlansStatus.ReactivatePlanError\n\t\t\t\t| StripePlansStatus.UpdateSubscriptionError\n\t\t\t\t| StripePlansStatus.InvalidPromotionCodeError\n\t  }\n\t| { status: StripePlansStatus.PaymentDeclinedError; message: string; tryAgain: () => void; reason?: string }\n\t| { status: StripePlansStatus.OverEditorLimitError; newLimit: number; currentEditorCount: number }\n\t| { status: StripePlansStatus.OverProjectEditorLimitError; newLimit: number; currentEditorCount: number }\n\t| { status: StripePlansStatus.CantMoveAddOnError; addonLicenseType: AddOnLicenseType }\n\nexport class PaymentsStore extends EngineStore {\n\tsitePlans: SitePlans\n\tstripePlans: StripePlans\n\n\tconstructor() {\n\t\tsuper()\n\t\tthis.sitePlans = { status: SitePlansStatus.Loading }\n\t\tthis.stripePlans = { status: StripePlansStatus.Loading }\n\t}\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\nimport { assertIsValidPluginManifestId, assertIsValidPluginModes } from \"./pluginManifestValidation.ts\"\nimport type { HostedPluginManifest } from \"./plugins.ts\"\n\nconst log = getLogger(\"pluginService\")\n\nexport type PluginServicePluginId = string\n\ninterface PluginServicePluginVersion {\n\tid: string\n\ticon: string\n\tname: string\n\tprettyVersion: number\n\tmodes: string[]\n\tstatus: string\n\turl: string\n\tprereleaseStyles?: boolean\n}\n\nexport interface PluginServicePluginInfo {\n\tid: PluginServicePluginId\n\tmanifestId: string\n\tdescription: string\n\tcreatedAt: string\n\tupdatedAt: string\n\townerId: string\n\tcurrentVersion: PluginServicePluginVersion\n\texternal?: boolean\n}\n\nexport interface PluginServicePlugins {\n\tplugins: PluginServicePluginInfo[]\n\ttotalCount: number\n}\n\nfunction servicePluginToPluginManifest(plugin: PluginServicePluginInfo): HostedPluginManifest {\n\tassertIsValidPluginManifestId(plugin.manifestId, \"plugin-service\")\n\tassertIsValidPluginModes(plugin.currentVersion.modes, \"plugin-service\")\n\n\tconst id = plugin.external ? `workspace:${plugin.ownerId}/${plugin.manifestId}` : plugin.manifestId\n\n\treturn {\n\t\ttype: \"hosted\",\n\t\tid,\n\t\tname: plugin.currentVersion.name,\n\t\ticon: plugin.currentVersion.icon,\n\t\tmodes: plugin.currentVersion.modes,\n\t\tentrypointUrl: plugin.currentVersion.url,\n\t\taliases: undefined,\n\t\tpluginId: plugin.id,\n\t\tversionId: plugin.currentVersion.id,\n\t\townerId: plugin.ownerId,\n\t\tstatus: plugin.currentVersion.status,\n\t\texternal: plugin.external,\n\t\tprereleaseStyles: plugin.currentVersion.prereleaseStyles,\n\t}\n}\n\n/* Fetches all public plugins from the service */\nexport async function loadPublicPluginsFromService(): Promise<HostedPluginManifest[]> {\n\tconst servicePlugins: PluginServicePlugins = await apiFetcher.get(\"/web/v1/plugins\")\n\n\tconst result: HostedPluginManifest[] = []\n\n\tfor (const plugin of servicePlugins.plugins) {\n\t\ttry {\n\t\t\tconst manifest = servicePluginToPluginManifest(plugin)\n\t\t\tresult.push(manifest)\n\t\t} catch (error) {\n\t\t\tlog.reportError(`Failed to load plugin: ${plugin.manifestId}, error: ${error}`)\n\t\t}\n\t}\n\n\treturn result\n}\n\n/* Fetches all public plugins and team-specific workspace plugins for a given team from the service */\nexport async function loadPublicAndTeamPluginsFromService(teamId: string): Promise<HostedPluginManifest[]> {\n\tconst servicePlugins: PluginServicePlugins = await apiFetcher.get(`/web/v1/plugins/teams/${teamId}`)\n\n\tconst result: HostedPluginManifest[] = []\n\n\tfor (const plugin of servicePlugins.plugins) {\n\t\ttry {\n\t\t\tconst manifest = servicePluginToPluginManifest(plugin)\n\t\t\tresult.push(manifest)\n\t\t} catch (error) {\n\t\t\tlog.reportError(`Failed to load plugin: ${plugin.manifestId}, error: ${error}`)\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunction getSpecificVersionUrl(urlString: string, manifest: HostedPluginManifest): string {\n\tconst url = new URL(urlString)\n\n\tconst [_currentVersionSubdomain, ...rest] = manifest.entrypointUrl.split(\".\")\n\n\tconst specificVersionSubdomain = `${manifest.pluginId}-${manifest.versionId}`\n\n\turl.hostname = [specificVersionSubdomain, ...rest].join(\".\")\n\n\treturn url.toString()\n}\n\nexport async function loadPluginVersionFromService(pluginId: string, version: string): Promise<HostedPluginManifest> {\n\tconst pluginInfo: PluginServicePluginInfo = await apiFetcher.get(`/web/v1/plugins/${pluginId}/versions/${version}`)\n\tconst manifest = servicePluginToPluginManifest(pluginInfo)\n\tmanifest.entrypointUrl = getSpecificVersionUrl(manifest.entrypointUrl, manifest)\n\tif (manifest.icon) {\n\t\tmanifest.icon = getSpecificVersionUrl(manifest.icon, manifest)\n\t}\n\tmanifest.versionOverride = true\n\treturn manifest\n}\n", "import type { EntityFolderNode } from \"../EntityFolderNode.ts\"\nimport type { EntityReferenceNode } from \"../EntityReferenceNode.ts\"\nimport { type EntityTypeRootId, type EntityTypeRootNode, isEntityTypeRootNode } from \"../EntityTypeRootNode.ts\"\nimport { isEntityFolderNode, isEntityReferenceNode } from \"./nodeCheck.ts\"\n\ntype AnyEntityNode = EntityTypeRootNode | EntityReferenceNode | EntityFolderNode\n\n/**\n * Returns the root type id for the given entity node.\n *\n * If the node is a type root, it returns the id of the node. If the node is a\n * reference or a folder, it returns the id of the type root at the top of its subtree.\n */\nexport function entityRootTypeIdForEntityNode(node: AnyEntityNode): EntityTypeRootId {\n\tif (isEntityTypeRootNode(node)) return node.id\n\n\tif (isEntityFolderNode(node) || isEntityReferenceNode(node)) {\n\t\tfor (const ancestor of node.ancestors()) {\n\t\t\tif (!isEntityTypeRootNode(ancestor)) continue\n\n\t\t\treturn ancestor.id\n\t\t}\n\t}\n\n\tthrow new Error(\"EntityReferenceNode | EntityFolderNode must have an EntityTypeRootNode as ancestor\")\n}\n", "import { assertNever } from \"@framerjs/shared\"\nimport type { NodeChangesReader } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport {\n\tAB_TESTS_ENTITY_TYPE_ROOT_ID,\n\tBLOCKQUOTE_ENTITY_ROOT_ID,\n\tCMS_ENTITY_ROOT_ID,\n\tCODE_FILE_ENTITY_TYPE_ROOT_ID,\n\tCOLOR_ENTITY_ROOT_ID,\n\tCOMPONENTS_ENTITY_TYPE_ROOT_ID,\n\tCONTENT_MANAGEMENT_ENTITY_TYPE_ROOT_ID,\n\tFUNNELS_ENTITY_TYPE_ROOT_ID,\n\tINLINE_CODE_ENTITY_ROOT_ID,\n\tLAYOUT_TEMPLATE_ENTITY_ROOT_ID,\n\tLINK_ENTITY_ROOT_ID,\n\tTEXT_ENTITY_ROOT_ID,\n\tVECTOR_SET_ENTITY_TYPE_ROOT_ID,\n\tisEntityTypeRootNode,\n} from \"document/models/CanvasTree/nodes/EntityTypeRootNode.ts\"\nimport { entityRootTypeIdForEntityNode } from \"document/models/CanvasTree/nodes/utils/entityTypeRootNode.ts\"\nimport {\n\tisEntityFolderNode,\n\tisEntityReferenceNode,\n\tisRedirectRouteNode,\n\tisRouteSegmentNode,\n\tisRouteSegmentRootNode,\n\tisRoutesNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport type { PluginSubscriptionTopic } from \"#framer-plugin/messages.ts\"\n\nexport function collectTopicsFromNodeChanges(\n\ttree: CanvasTree,\n\tnodeChangesReader: NodeChangesReader,\n\ttopics: Set<PluginSubscriptionTopic>,\n) {\n\tfor (const [id, changes] of nodeChangesReader.read()) {\n\t\tif (changes.length === 0) continue\n\t\tconst node = tree.getNode(id)\n\t\tif (!node) continue\n\n\t\tconst isRouteNode =\n\t\t\tisRouteSegmentNode(node) || isRouteSegmentRootNode(node) || isRedirectRouteNode(node) || isRoutesNode(node)\n\t\tif (isRouteNode) {\n\t\t\ttopics.add(\"redirects\")\n\t\t\tcontinue\n\t\t}\n\n\t\tconst isEntityNode = isEntityTypeRootNode(node) || isEntityFolderNode(node) || isEntityReferenceNode(node)\n\t\tif (!isEntityNode) continue\n\n\t\tconst typeRootId = entityRootTypeIdForEntityNode(node)\n\t\tswitch (typeRootId) {\n\t\t\tcase TEXT_ENTITY_ROOT_ID:\n\t\t\t\ttopics.add(\"textStyles\")\n\t\t\t\treturn\n\t\t\tcase COLOR_ENTITY_ROOT_ID:\n\t\t\t\ttopics.add(\"colorStyles\")\n\t\t\t\treturn\n\t\t\tcase CMS_ENTITY_ROOT_ID:\n\t\t\tcase INLINE_CODE_ENTITY_ROOT_ID:\n\t\t\tcase CODE_FILE_ENTITY_TYPE_ROOT_ID:\n\t\t\tcase COMPONENTS_ENTITY_TYPE_ROOT_ID:\n\t\t\tcase LAYOUT_TEMPLATE_ENTITY_ROOT_ID:\n\t\t\tcase VECTOR_SET_ENTITY_TYPE_ROOT_ID:\n\t\t\tcase BLOCKQUOTE_ENTITY_ROOT_ID:\n\t\t\tcase LINK_ENTITY_ROOT_ID:\n\t\t\tcase FUNNELS_ENTITY_TYPE_ROOT_ID:\n\t\t\tcase AB_TESTS_ENTITY_TYPE_ROOT_ID:\n\t\t\tcase CONTENT_MANAGEMENT_ENTITY_TYPE_ROOT_ID:\n\t\t\t\tcontinue\n\t\t\tdefault:\n\t\t\t\tassertNever(typeRootId)\n\t\t}\n\t}\n}\n", "import type { WindowWithCurrentUser } from \"@framerjs/app-shared\"\nimport { environment } from \"@framerjs/framer-environment\"\nimport type { ToastVariant } from \"@framerjs/fresco/src/components/Toaster\"\nimport { assert, type LocalModuleId, ReadonlyMap, assertNever, unhandledError } from \"@framerjs/shared\"\nimport { features } from \"app/features.ts\"\nimport { prewarmTypechecker } from \"code-editor/workers/codeCheckerAndAta.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport type { NodeChangesReader } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isCollectionNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { fontStore } from \"library/render/fonts/fontStore.ts\"\nimport type { ActivePlugin, ModeHandlers } from \"plugins/ActivePlugin.ts\"\nimport { PluginConfigurationError } from \"plugins/pluginErrors.ts\"\nimport {\n\tisExternalPluginIdOfPublishedPlugin,\n\tisExternalPluginManifestId,\n\tisLocalDevelopmentPluginManifestId,\n\tisModeSupported,\n} from \"plugins/pluginManifestValidation.ts\"\nimport type { PluginServicePluginId } from \"plugins/pluginService.ts\"\nimport {\n\tloadPluginVersionFromService,\n\tloadPublicAndTeamPluginsFromService,\n\tloadPublicPluginsFromService,\n} from \"plugins/pluginService.ts\"\nimport type { HostedPluginManifest, PluginManifestId, VekterPluginManifest } from \"plugins/plugins.ts\"\nimport {\n\tisHostedPluginManifest,\n\tloadPersistedExternalManifests,\n\tloadPersistedRecentlyUsedIds,\n\tloadPluginManifestFromUrl,\n\tpersistExternalManifests,\n\tpersistRecentlyUsedPluginManifestIds,\n\tsortAlphabetically,\n\ttemporaryWorkshopManifestId,\n\tworkshopManifestId,\n} from \"plugins/plugins.ts\"\nimport { showPluginLoadFailedToast, showUnsupportedModeToast } from \"plugins/toast.ts\"\nimport type { PluginTransport } from \"plugins/transport.ts\"\nimport { collectTopicsFromNodeChanges } from \"plugins/utils/collectTopicsFromNodeChanges.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport type { ShowProgressOnInstancesAttributes } from \"#framer-plugin/codeFile.ts\"\nimport type { ComponentInstancePlaceholderData } from \"#framer-plugin/componentInstancePlaceholder.ts\"\nimport type { Mode, PluginSubscriptionTopic } from \"#framer-plugin/messages.ts\"\nimport type { ThemeMode } from \"#framer-plugin/theme.ts\"\nimport type { ProjectStore } from \"./ProjectStore.ts\"\n\nconst maxRecentItemsCount = 5\n\ntype PluginManifestById = Map<PluginManifestId, VekterPluginManifest>\ntype ReadonlyPluginManifestById = ReadonlyMap<PluginManifestId, VekterPluginManifest>\n\ninterface ComponentInstancePlaceholder extends Readonly<ComponentInstancePlaceholderData> {\n\tscopeId: NodeID\n}\n\nexport class PluginStore extends EngineStore {\n\t// Used when a plugin is launched with the \"openPlugin\" query param or from\n\t// the Desktop app\n\t#preparedPlugin: { id: PluginManifestId | PluginServicePluginId; version: string | null } | null = null\n\n\t#nodeChangesReader: NodeChangesReader | null = null\n\n\t// Ordered set - most recent first\n\tprivate _recentlyUsedPluginManifestIds: ReadonlySet<PluginManifestId>\n\n\tprivate servicePluginManifests: ReadonlyPluginManifestById = new Map()\n\tprivate workspacePluginManifests: ReadonlyPluginManifestById = new Map()\n\tprivate persistedExternalManifests: ReadonlyPluginManifestById = new Map()\n\tprivate preparedPluginWithVersionManifest: HostedPluginManifest | undefined\n\n\tprivate loading = false\n\thasLoaded = false\n\n\tget isLoading() {\n\t\treturn this.loading\n\t}\n\n\t/**\n\t * Unsubscribe function for the modules storage. It added when the plugin is\n\t * opened and should be removed when the plugin is closed.\n\t */\n\t#unsubscribeFromModulesStorage: VoidFunction | null = null\n\n\t// Dark/light mode theme is synced from a React context. It is not available\n\t// in an engine store because it persists in places where no engine is\n\t// available (like dashboard). The value is \"null\" when the theme is not yet\n\t// known.\n\tprivate _theme: ThemeMode | null = null\n\n\tpluginManifestIdToPreload: PluginManifestId | null = null\n\n\tcomponentInstancePlaceholder: ComponentInstancePlaceholder | null = null\n\tcodeFilesProgressState: ReadonlyMap<LocalModuleId, ShowProgressOnInstancesAttributes> = new Map()\n\n\tconstructor(private projectStore: ProjectStore) {\n\t\tsuper()\n\n\t\tconst persistedExternalPluginManifestById: PluginManifestById = new Map()\n\t\tthis.persistedExternalManifests = persistedExternalPluginManifestById\n\t\tconst persistedExternalManifests = loadPersistedExternalManifests()\n\t\tfor (const externalManifest of persistedExternalManifests) {\n\t\t\tpersistedExternalPluginManifestById.set(externalManifest.id, externalManifest)\n\t\t}\n\n\t\tthis._recentlyUsedPluginManifestIds = loadPersistedRecentlyUsedIds()\n\t}\n\n\t/** Only needed for opening plugins during loading of a document or some external signal */\n\tasync preparePluginToOpen(\n\t\tengine: VekterEngine,\n\t\tid: PluginManifestId | PluginServicePluginId,\n\t\tversion: string | null,\n\t): Promise<void> {\n\t\tthis.#preparedPlugin = { id, version }\n\n\t\tif (!version) {\n\t\t\t// Load plugins immediately because the info is needed to start the plugin.\n\t\t\treturn this.loadIfNeeded()\n\t\t}\n\n\t\ttry {\n\t\t\tconst manifest = await loadPluginVersionFromService(id, version)\n\n\t\t\tif (!currentUserCanAccessPluginVersion(engine, manifest)) {\n\t\t\t\taddToast(pluginVersionNotAllowedMessage, \"warning\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.preparedPluginWithVersionManifest = manifest\n\t\t} catch {\n\t\t\taddToast(\"Failed to load requested version of plugin\", \"warning\")\n\t\t}\n\t}\n\n\tgetManifestByPluginId(id: PluginServicePluginId): HostedPluginManifest | undefined {\n\t\tfor (const manifest of this.manifestById.values()) {\n\t\t\tif (isHostedPluginManifest(manifest) && manifest.pluginId === id) return manifest\n\t\t}\n\t}\n\n\tprivate getPreparedPluginManifest(): HostedPluginManifest | undefined {\n\t\tif (!this.#preparedPlugin) return\n\n\t\tconst { id, version } = this.#preparedPlugin\n\n\t\tif (version) {\n\t\t\treturn this.preparedPluginWithVersionManifest\n\t\t}\n\n\t\tconst manifest = this.manifestById.get(id) ?? this.getManifestByPluginId(id)\n\t\treturn isHostedPluginManifest(manifest) ? manifest : undefined\n\t}\n\n\tpreloadPlugin(engine: VekterEngine, manifestId: PluginManifestId) {\n\t\tif (this.pluginManifestIdToPreload === manifestId) return\n\n\t\t// The ActivePlugin chunk is lazily loaded so we also preload it.\n\t\tvoid import(\"plugins/ActivePlugin.ts\")\n\t\tengine.scheduler.processWhenReady(() => {\n\t\t\tthis.pluginManifestIdToPreload = manifestId\n\t\t})\n\t}\n\n\topenPreparedPlugin(engine: VekterEngine) {\n\t\tif (!this.#preparedPlugin) return\n\n\t\tconst manifest = this.getPreparedPluginManifest()\n\n\t\tif (!manifest) {\n\t\t\taddToast(\"Unknown plugin could not be launched\", \"warning\")\n\t\t\treturn\n\t\t}\n\n\t\tif (manifest.modes.includes(\"canvas\")) {\n\t\t\tthis.openPlugin(manifest, engine, { mode: \"canvas\" }).catch(unhandledError)\n\t\t\treturn\n\t\t}\n\n\t\tconst firstMode = manifest.modes[0]\n\t\tassert(firstMode, \"Plugin must have at least one mode\")\n\n\t\tswitch (firstMode) {\n\t\t\tcase \"canvas\":\n\t\t\t\tthis.openPlugin(manifest, engine, { mode: \"canvas\" }).catch(unhandledError)\n\t\t\t\tbreak\n\t\t\tcase \"image\":\n\t\t\tcase \"editImage\":\n\t\t\t\tthis.addToRecentlyUsedPluginManifestIds(manifest.id)\n\t\t\t\taddToast(`${manifest.name} can be launched from the image picker`, \"info\")\n\t\t\t\tbreak\n\t\t\tcase \"collection\":\n\t\t\t\tthis.openPlugin(manifest, engine, { mode: \"collection\" }).catch(unhandledError)\n\t\t\t\tbreak\n\t\t\tcase \"syncManagedCollection\":\n\t\t\tcase \"configureManagedCollection\":\n\t\t\t\tengine.stores.modalStore.set({ type: ModalType.CreateManagedCollection, manifest, source: \"url_param\" })\n\t\t\t\tbreak\n\t\t\tcase \"localization\": {\n\t\t\t\tengine.stores.chromeStore.setLocalizationsVisible(true, () => {\n\t\t\t\t\tthis.openPlugin(manifest, engine, { mode: \"localization\" }).catch(unhandledError)\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase \"code\":\n\t\t\t\tthis.openPlugin(manifest, engine, { mode: \"code\" }).catch(unhandledError)\n\t\t\t\tbreak\n\t\t\tcase \"api\":\n\t\t\t\tthis.openPlugin(manifest, engine, { mode: \"api\" }).catch(unhandledError)\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tassertNever(firstMode)\n\t\t}\n\t}\n\n\tprivate async loadIfNeeded(): Promise<void> {\n\t\tif (this.hasLoaded) return\n\t\tif (this.loading) return\n\t\tif (environment.isTest) return\n\n\t\t// Headless mode doesn't need service plugins\n\t\tif (environment.isApiPlugin) {\n\t\t\tthis.hasLoaded = true\n\t\t\treturn\n\t\t}\n\n\t\tthis.loading = true\n\n\t\ttry {\n\t\t\tconst project = await this.projectStore.getProject()\n\t\t\tconst space = project.space\n\t\t\tconst isOrganization = space?.scope === \"organization\"\n\t\t\tconst teamId = isOrganization ? space.ownerId : undefined\n\n\t\t\t// `loadIfNeeded` can be called before features have been updated with the actual values\n\t\t\t// from the server, so we await the feature set to be updated.\n\t\t\tconst shouldLoadWorkspacePlugins = await features.didUpdateAndIsOn(\"canUseWorkspacePlugins\")\n\n\t\t\tlet manifests: VekterPluginManifest[] = []\n\t\t\tif (shouldLoadWorkspacePlugins && teamId) {\n\t\t\t\tmanifests = await loadPublicAndTeamPluginsFromService(teamId)\n\t\t\t} else {\n\t\t\t\tmanifests = await loadPublicPluginsFromService()\n\t\t\t}\n\n\t\t\tconst pluginManifestById: PluginManifestById = new Map()\n\t\t\tthis.servicePluginManifests = pluginManifestById\n\n\t\t\tconst workspacePluginManifestById: PluginManifestById = new Map()\n\t\t\tthis.workspacePluginManifests = workspacePluginManifestById\n\n\t\t\tfor (const pluginManifest of manifests) {\n\t\t\t\tpluginManifestById.set(pluginManifest.id, pluginManifest)\n\n\t\t\t\tif (isHostedPluginManifest(pluginManifest) && pluginManifest.external) {\n\t\t\t\t\tworkspacePluginManifestById.set(pluginManifest.id, pluginManifest)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.hasLoaded = true\n\t\t\tthis.loading = false\n\t\t} catch (error) {\n\t\t\tunhandledError(error)\n\t\t} finally {\n\t\t\tif (this.loading) {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t}\n\t}\n\n\tdocumentDidLoad() {\n\t\tvoid this.loadIfNeeded()\n\t}\n\n\tprivate _activePlugin: ActivePlugin | undefined\n\n\tget activePlugin() {\n\t\treturn this._activePlugin\n\t}\n\n\tget recentlyUsedPluginManifestIds(): ReadonlySet<PluginManifestId> {\n\t\treturn this._recentlyUsedPluginManifestIds\n\t}\n\n\tprivate addToRecentlyUsedPluginManifestIds(pluginManifestId: PluginManifestId) {\n\t\tif (isLocalDevelopmentPluginManifestId(pluginManifestId)) return\n\t\tif (isExternalPluginIdOfPublishedPlugin(pluginManifestId, this.publishedPluginManifests)) return\n\n\t\tconst recentIds = new Set([pluginManifestId])\n\t\tfor (const recentId of this._recentlyUsedPluginManifestIds) {\n\t\t\trecentIds.add(recentId)\n\t\t\tif (recentIds.size === maxRecentItemsCount) break\n\t\t}\n\n\t\tthis._recentlyUsedPluginManifestIds = recentIds\n\t\tpersistRecentlyUsedPluginManifestIds(recentIds)\n\t}\n\n\t#manifestByIdCache: {\n\t\tservicePluginManifests: ReadonlyPluginManifestById\n\t\tworkspacePluginManifests: ReadonlyPluginManifestById\n\t\tpersistedExternalManifests: ReadonlyPluginManifestById\n\t\tpreparedPluginWithVersionManifest: VekterPluginManifest | undefined\n\t\tresult: ReadonlyPluginManifestById\n\t} | null = null\n\n\tget manifestById(): ReadonlyPluginManifestById {\n\t\tconst cache = this.#manifestByIdCache\n\t\tif (\n\t\t\tcache &&\n\t\t\tcache.servicePluginManifests === this.servicePluginManifests &&\n\t\t\tcache.workspacePluginManifests === this.workspacePluginManifests &&\n\t\t\tcache.persistedExternalManifests === this.persistedExternalManifests &&\n\t\t\tcache.preparedPluginWithVersionManifest === this.preparedPluginWithVersionManifest\n\t\t) {\n\t\t\treturn cache.result\n\t\t}\n\n\t\tconst result = new Map(this.persistedExternalManifests)\n\n\t\tfor (const [id, manifest] of this.servicePluginManifests) {\n\t\t\tresult.set(id, manifest)\n\t\t}\n\n\t\tif (features.isOn(\"canUseWorkspacePlugins\")) {\n\t\t\tfor (const [id, manifest] of this.workspacePluginManifests) {\n\t\t\t\tresult.set(id, manifest)\n\t\t\t}\n\t\t}\n\n\t\tif (this.preparedPluginWithVersionManifest) {\n\t\t\tresult.set(this.preparedPluginWithVersionManifest.id, this.preparedPluginWithVersionManifest)\n\t\t}\n\n\t\tthis.#manifestByIdCache = {\n\t\t\tservicePluginManifests: this.servicePluginManifests,\n\t\t\tworkspacePluginManifests: this.workspacePluginManifests,\n\t\t\tpersistedExternalManifests: this.persistedExternalManifests,\n\t\t\tpreparedPluginWithVersionManifest: this.preparedPluginWithVersionManifest,\n\t\t\tresult,\n\t\t}\n\n\t\treturn result\n\t}\n\n\t#sortedManifestsCache: {\n\t\trecentlyUsedPluginManifestIds: ReadonlySet<PluginManifestId>\n\t\tmanifestByIdMap: ReadonlyPluginManifestById\n\t\tresult: readonly VekterPluginManifest[]\n\t} | null = null\n\n\tget sortedManifests() {\n\t\tconst manifestByIdMap = this.manifestById\n\n\t\tconst cache = this.#sortedManifestsCache\n\t\tif (\n\t\t\tcache &&\n\t\t\tcache.recentlyUsedPluginManifestIds === this.recentlyUsedPluginManifestIds &&\n\t\t\tcache.manifestByIdMap === manifestByIdMap\n\t\t) {\n\t\t\treturn cache.result\n\t\t}\n\n\t\tconst recentManifests: VekterPluginManifest[] = []\n\t\tconst otherManifests: VekterPluginManifest[] = []\n\n\t\tfor (const pluginManifestId of this.recentlyUsedPluginManifestIds) {\n\t\t\tconst pluginManifest = this.manifestById.get(pluginManifestId)\n\t\t\tif (pluginManifest) recentManifests.push(pluginManifest)\n\t\t}\n\n\t\tfor (const [pluginManifestId, pluginManifest] of this.manifestById) {\n\t\t\tif (this.recentlyUsedPluginManifestIds.has(pluginManifestId)) continue\n\t\t\totherManifests.push(pluginManifest)\n\t\t}\n\n\t\tconst result = [...recentManifests, ...sortAlphabetically(otherManifests)]\n\n\t\tthis.#sortedManifestsCache = {\n\t\t\trecentlyUsedPluginManifestIds: this.recentlyUsedPluginManifestIds,\n\t\t\tmanifestByIdMap,\n\t\t\tresult,\n\t\t}\n\n\t\treturn result\n\t}\n\n\tget publishedPluginManifests() {\n\t\treturn this.servicePluginManifests\n\t}\n\n\t// State\n\n\tasync openPlugin(\n\t\tpluginManifest: VekterPluginManifest,\n\t\tengine: VekterEngine,\n\t\tmodeHandlers: ModeHandlers,\n\t\ttransport?: PluginTransport,\n\t\tsessionId?: string,\n\t\tclientId?: string,\n\t) {\n\t\tif (this.activePlugin?.manifestId === pluginManifest.id) {\n\t\t\tconst currentMode = this.activePlugin.modeHandlers.mode\n\t\t\tif (currentMode === modeHandlers.mode) return\n\t\t}\n\n\t\tlet updatedManifest = pluginManifest\n\t\tif (isHostedPluginManifest(pluginManifest) && isExternalPluginManifestId(pluginManifest.id)) {\n\t\t\ttry {\n\t\t\t\tupdatedManifest = await this.loadManifestFromUrl(pluginManifest.entrypointUrl)\n\t\t\t\tif (updatedManifest.id !== pluginManifest.id) {\n\t\t\t\t\tthrow new PluginConfigurationError(\n\t\t\t\t\t\t\"This Plugin has a different ID than expected. Are you running the right Plugin?\",\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tshowPluginLoadFailedToast(engine, pluginManifest, error)\n\n\t\t\t\trecord(\"plugin_load_error\", {\n\t\t\t\t\turl: pluginManifest.entrypointUrl,\n\t\t\t\t\tmode: modeHandlers.mode,\n\t\t\t\t\tid: pluginManifest.id,\n\t\t\t\t\tpluginName: pluginManifest.name,\n\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (!isModeSupported(updatedManifest.modes, modeHandlers.mode)) {\n\t\t\tif (isHostedPluginManifest(pluginManifest)) {\n\t\t\t\trecord(\"plugin_load_error\", {\n\t\t\t\t\turl: pluginManifest.entrypointUrl,\n\t\t\t\t\tmode: modeHandlers.mode,\n\t\t\t\t\tpluginName: pluginManifest.name,\n\t\t\t\t\tmessage: \"Plugin was launched in unsupported mode\",\n\t\t\t\t\tid: pluginManifest.id,\n\t\t\t\t})\n\t\t\t}\n\t\t\tshowUnsupportedModeToast(modeHandlers.mode)\n\t\t\treturn\n\t\t}\n\n\t\tthis.addToRecentlyUsedPluginManifestIds(updatedManifest.id)\n\n\t\tif (this._activePlugin) {\n\t\t\tthis.closePlugin(this._activePlugin.manifestId)\n\t\t\tassert(!this._activePlugin, `Cannot replace active plugin \"${this._activePlugin?.manifestId}\": close was refused`)\n\t\t}\n\n\t\tif (isHostedPluginManifest(updatedManifest) && updatedManifest.versionOverride) {\n\t\t\tassert(currentUserCanAccessPluginVersion(engine, updatedManifest), pluginVersionNotAllowedMessage)\n\t\t\taddToast(\n\t\t\t\t`Launching specific version of ${updatedManifest.name} with status: ${updatedManifest.status ?? \"unknown\"}`,\n\t\t\t\t\"info\",\n\t\t\t)\n\t\t}\n\n\t\tif (this.pluginManifestIdToPreload) {\n\t\t\tthis.pluginManifestIdToPreload = null\n\t\t}\n\n\t\tawait this.startActivePlugin(modeHandlers, updatedManifest, engine, transport, sessionId, clientId)\n\t}\n\n\tprivate disposeNodeChangeReaderIfNeeded() {\n\t\tif (this.#nodeChangesReader) {\n\t\t\tthis.#nodeChangesReader.dispose()\n\t\t\tthis.#nodeChangesReader = null\n\t\t}\n\t}\n\n\tprivate createNodeChangeReaderIfNeeded(engine: VekterEngine) {\n\t\tif (this.#nodeChangesReader) return\n\t\tthis.#nodeChangesReader = engine.stores.treeStore.timeline.openNodeChangesReader()\n\t}\n\n\tprivate async startActivePlugin(\n\t\tmodeHandlers: ModeHandlers,\n\t\tpluginManifest: VekterPluginManifest,\n\t\tengine: VekterEngine,\n\t\ttransport: PluginTransport | undefined,\n\t\tsessionId: string | undefined,\n\t\tclientId: string | undefined,\n\t) {\n\t\tconst ActivePlugin = (await import(\"plugins/ActivePlugin.ts\")).ActivePlugin\n\n\t\tconst plugin = new ActivePlugin(\n\t\t\tmodeHandlers,\n\t\t\tpluginManifest,\n\t\t\tengine,\n\t\t\tfontStore,\n\t\t\tengine.stores.selectionStore.ids,\n\t\t\ttransport,\n\t\t\tsessionId,\n\t\t\tclientId,\n\t\t)\n\t\tthis._activePlugin = plugin\n\t\tthis._activePlugin.start()\n\n\t\t// Prewarm the typechecker in the background in case the plugin ends up using it through the API.\n\t\t// Logic:\n\t\t// - wait 3 seconds because the plugin might have to load network resources as well\n\t\t// - requestIdleCallback too, in case the main thread is busy\n\t\tsetTimeout(() => {\n\t\t\trequestIdleCallback(() => {\n\t\t\t\tprewarmTypechecker().catch(unhandledError)\n\t\t\t})\n\t\t}, 3000)\n\n\t\tthis.#unsubscribeFromModulesStorage = engine.stores.modulesStore.subscribeToModulesStorage(() => {\n\t\t\tvoid plugin.publishTopic(\"codeFiles\")\n\t\t})\n\t}\n\n\tasync loadManifestFromUrl(url: string): Promise<VekterPluginManifest> {\n\t\tconst manifest = await loadPluginManifestFromUrl(url)\n\n\t\tthis.persistedExternalManifests = ReadonlyMap.set(this.persistedExternalManifests, manifest.id, manifest)\n\t\tpersistExternalManifests(this.persistedExternalManifests)\n\n\t\treturn manifest\n\t}\n\n\tgetWorkshopManifest(): VekterPluginManifest | undefined {\n\t\tconst workshopManifest = this.manifestById.get(workshopManifestId)\n\t\tif (workshopManifest) return workshopManifest\n\n\t\tconst temporaryWorkshopManifest = this.manifestById.get(temporaryWorkshopManifestId)\n\t\tif (temporaryWorkshopManifest) return temporaryWorkshopManifest\n\t}\n\n\thasRecentPlugins(): boolean {\n\t\tfor (const manifestId of this.recentlyUsedPluginManifestIds) {\n\t\t\tif (this.manifestById.has(manifestId)) return true\n\t\t}\n\t\treturn false\n\t}\n\n\tclearRecentPlugins(): void {\n\t\tconst recentIds = new Set<string>()\n\t\tthis._recentlyUsedPluginManifestIds = recentIds\n\t\tpersistRecentlyUsedPluginManifestIds(recentIds)\n\t}\n\n\tgetRecentPluginForMode(mode: Mode): VekterPluginManifest | null {\n\t\tconst recentManifestIds = this._recentlyUsedPluginManifestIds\n\t\tfor (const manifestId of recentManifestIds) {\n\t\t\tconst manifest = this.manifestById.get(manifestId)\n\t\t\tif (!manifest) continue\n\t\t\tif (manifest.modes.includes(mode)) return manifest\n\t\t}\n\t\treturn null\n\t}\n\n\tuninstallPlugin(id: PluginManifestId) {\n\t\tthis.persistedExternalManifests = ReadonlyMap.remove(this.persistedExternalManifests, id)\n\t\tpersistExternalManifests(this.persistedExternalManifests)\n\t\tthis.#sortedManifestsCache = null\n\t}\n\n\tclosePlugin(manifestId: PluginManifestId) {\n\t\tconst activePlugin = this.activePlugin\n\t\tif (!activePlugin || activePlugin.manifestId !== manifestId) return\n\n\t\tif (!activePlugin.allowClose) return\n\n\t\tactivePlugin.stop()\n\t\tthis._activePlugin = undefined\n\t\tthis.componentInstancePlaceholder = null\n\t\tthis.codeFilesProgressState = new Map()\n\t\tthis.#unsubscribeFromModulesStorage?.()\n\t}\n\n\tsetTheme(theme: ThemeMode) {\n\t\tif (this._theme === theme) return\n\t\tthis._theme = theme\n\t}\n\n\tget theme() {\n\t\treturn this._theme\n\t}\n\n\t// Utils\n\n\tpostProcess(engine: VekterEngine) {\n\t\tconst activePlugin = this.activePlugin\n\t\tif (!activePlugin) {\n\t\t\t// No active plugin anymore, so we can close the reader to free resources\n\t\t\tthis.disposeNodeChangeReaderIfNeeded()\n\t\t\treturn\n\t\t}\n\n\t\tconst { selectionStore, chromeStore, codeEditorStore, scopeStore, publishStore } = engine.stores\n\n\t\tthis.createNodeChangeReaderIfNeeded(engine)\n\n\t\tconst { mode } = activePlugin.modeHandlers\n\n\t\tif (canSwitchMode(mode, chromeStore.mainView)) {\n\t\t\tconst newMode = getCorrectModeForSwitchingMainView(activePlugin.manifest.modes, chromeStore.mainView)\n\n\t\t\tif (newMode === null) {\n\t\t\t\tactivePlugin.hiddenDueToUnsupportedView = true\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (newMode !== mode) {\n\t\t\t\tvoid this.openPlugin(activePlugin.manifest, engine, { mode: newMode })\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif (activePlugin.hiddenDueToUnsupportedView) {\n\t\t\t// restore UI if supported mode\n\t\t\tconst supportedMode = getCorrectModeForSwitchingMainView(activePlugin.manifest.modes, chromeStore.mainView)\n\t\t\tif (supportedMode === mode) {\n\t\t\t\tactivePlugin.hiddenDueToUnsupportedView = false\n\t\t\t}\n\t\t}\n\n\t\tif (activePlugin.selectionAtStart !== selectionStore.ids) {\n\t\t\tconst singleSelectedNode = selectionStore.nodes.length === 1 ? selectionStore.nodes[0] : null\n\t\t\tswitch (mode) {\n\t\t\t\tcase \"canvas\":\n\t\t\t\tcase \"api\":\n\t\t\t\t\t// Selection changes are expected; fall through to publish subscription updates.\n\t\t\t\t\tbreak\n\t\t\t\tcase \"collection\":\n\t\t\t\t\t// In collection mode you are allowed to switch between collections.\n\t\t\t\t\tif (!isCollectionNode(singleSelectedNode)) {\n\t\t\t\t\t\tthis.closePlugin(activePlugin.manifestId)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase \"syncManagedCollection\":\n\t\t\t\tcase \"configureManagedCollection\":\n\t\t\t\t\t// Managed collections are only allowed to switch between managed collections they own.\n\t\t\t\t\tif (!isCollectionNode(singleSelectedNode) || singleSelectedNode.managedByPlugin !== activePlugin.manifestId) {\n\t\t\t\t\t\tthis.closePlugin(activePlugin.manifestId)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\tcase \"image\":\n\t\t\t\tcase \"editImage\":\n\t\t\t\tcase \"localization\":\n\t\t\t\tcase \"code\":\n\t\t\t\t\tthis.closePlugin(activePlugin.manifestId)\n\t\t\t\t\treturn\n\t\t\t\tdefault:\n\t\t\t\t\tassertNever(mode)\n\t\t\t}\n\t\t}\n\n\t\t// Send updates\n\n\t\tconst collectedTopics = new Set<PluginSubscriptionTopic>([\n\t\t\t// The theme might not have changed but if it's only actually send if different by\n\t\t\t// equality\n\t\t\t\"theme\",\n\t\t])\n\n\t\tif (engine.scheduler.changes.has(EngineChange.TreeStore) && this.#nodeChangesReader) {\n\t\t\tcollectTopicsFromNodeChanges(engine.tree, this.#nodeChangesReader, collectedTopics)\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(EngineChange.Tree)) {\n\t\t\tcollectedTopics.add(\"customCode\")\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(selectionStore)) {\n\t\t\tcollectedTopics.add(\"selection\")\n\t\t\tcollectedTopics.add(\"image\")\n\t\t\tcollectedTopics.add(\"text\")\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(scopeStore) || engine.scheduler.changes.has(EngineChange.Tree)) {\n\t\t\tcollectedTopics.add(\"canvasRoot\")\n\t\t}\n\n\t\tif (\n\t\t\tengine.scheduler.changes.has(scopeStore) ||\n\t\t\tengine.scheduler.changes.has(publishStore) ||\n\t\t\t// Selected Collection Item on CMS detail pages is stored in the node cache.\n\t\t\tengine.scheduler.changes.has(EngineChange.Tree)\n\t\t) {\n\t\t\tcollectedTopics.add(\"publishInfo\")\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(EngineChange.ColorStyleTokens)) {\n\t\t\tcollectedTopics.add(\"colorStyles\")\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(EngineChange.TextStylePresets)) {\n\t\t\tcollectedTopics.add(\"textStyles\")\n\t\t}\n\n\t\tif (engine.scheduler.changes.has(codeEditorStore)) {\n\t\t\tcollectedTopics.add(\"openCodeFile\")\n\t\t}\n\n\t\tfor (const topic of collectedTopics) {\n\t\t\tvoid activePlugin.publishTopic(topic)\n\t\t}\n\t}\n}\n\nfunction addToast(message: string, variant: ToastVariant) {\n\ttoast({\n\t\ttype: \"add\",\n\t\tvariant,\n\t\ttext: message,\n\t\tduration: 5000,\n\t})\n}\n\nfunction currentUserCanAccessPluginVersion(engine: VekterEngine, pluginManifest: HostedPluginManifest): boolean {\n\tif (engine.stores.chromeStore.userIsEmployee) return true\n\n\tconst user = (window as WindowWithCurrentUser).framerUser\n\tif (!user) return false\n\n\treturn user.id === pluginManifest.ownerId\n}\n\nconst pluginVersionNotAllowedMessage = \"Loading this version of the plugin is only allowed by the plugin author\"\n\ntype SwitchableMode = Extract<Mode, \"code\" | \"canvas\">\n\nconst modeToViewsMap: Readonly<Record<SwitchableMode, readonly ActiveMainView[]>> = {\n\tcanvas: [ActiveMainView.Canvas, ActiveMainView.Preview],\n\tcode: [ActiveMainView.CodeEditor],\n}\n\nfunction isSwitchableMode(mode: Mode): mode is SwitchableMode {\n\treturn mode in modeToViewsMap\n}\n\nfunction canSwitchMode(mode: Mode, mainView: ActiveMainView): mode is SwitchableMode {\n\treturn isSwitchableMode(mode) && !modeToViewsMap[mode].includes(mainView)\n}\n\nfunction getCorrectModeForSwitchingMainView(\n\tsupportedModes: readonly Mode[],\n\tmainView: ActiveMainView,\n): SwitchableMode | null {\n\treturn (\n\t\tsupportedModes.find((mode): mode is SwitchableMode => {\n\t\t\treturn isSwitchableMode(mode) && modeToViewsMap[mode].includes(mainView)\n\t\t}) ?? null\n\t)\n}\n", "import type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport { assert, assertNever } from \"@framerjs/shared\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\n\ninterface PreviewItemBase {\n\t/**\n\t * Collection item to provide pathVariables for the preview item.\n\t */\n\tcollectionItemNodeId?: string\n}\n\ninterface PreviewItemNode extends PreviewItemBase {\n\ttype: \"node\"\n\tnodeId: NodeID\n}\n\ninterface PreviewItemComponent extends PreviewItemBase {\n\ttype: \"component\"\n\tcomponentId: string | ModuleExportIdentifierString\n}\n\nexport type PreviewItem = PreviewItemNode | PreviewItemComponent\n\nexport function isPreviewItemEqual(item1: PreviewItem | undefined, item2: PreviewItem | undefined): boolean {\n\t// Same object, or both undefined.\n\tif (item1 === item2) return true\n\t// One of the items is undefined while the other is defined.\n\tif (Boolean(item1) !== Boolean(item2)) return false\n\t// By now we're sure both items are defined.\n\tassert(item1)\n\tassert(item2)\n\n\tif (item1.collectionItemNodeId !== item2.collectionItemNodeId) return false\n\n\tif (item1.type !== item2.type) return false\n\tconst commonType = item1.type\n\tswitch (commonType) {\n\t\tcase \"node\":\n\t\t\tassert(item2.type === commonType)\n\t\t\treturn item1.nodeId === item2.nodeId\n\t\tcase \"component\":\n\t\t\tassert(item2.type === commonType)\n\t\t\treturn item1.componentId === item2.componentId\n\t\tdefault:\n\t\t\tassertNever(commonType)\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { ModuleType, parseModuleIdentifier } from \"@framerjs/shared\"\nimport { getTitleForWebPageId } from \"document/components/utils/webPageTitles.ts\"\nimport { isLocalModuleNode } from \"document/models/CanvasTree/nodes/LocalModuleNode.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\n\nexport function getLabelForComponent(\n\tcomponentLoader: ComponentLoader,\n\ttreeStore: TreeStore,\n\tcodeComponentIdentifier: string | undefined,\n\tname: string,\n): string {\n\tconst componentIdentifier = parseModuleIdentifier(codeComponentIdentifier)\n\tif (componentIdentifier?.kind === \"localModuleExport\" && componentIdentifier.exportSpecifier === \"default\") {\n\t\tconst module = treeStore.tree.getNodeWithTrait(componentIdentifier.localId, isLocalModuleNode)\n\t\tif (module?.save.type === ModuleType.Screen) {\n\t\t\tif (name.startsWith(\"Screens/\")) {\n\t\t\t\treturn name.replace(\"Screens/\", \"\") + \" - \" + module.save.title\n\t\t\t}\n\t\t\treturn getTitleForWebPageId(treeStore.tree, componentLoader, componentIdentifier.localIdName)\n\t\t}\n\t\tif (name === \"default\") {\n\t\t\treturn module?.save.title || name\n\t\t}\n\t}\n\treturn name\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { isErrorDefinition } from \"@framerjs/framer-runtime\"\nimport { assertNever } from \"@framerjs/shared\"\nimport { getLabelForComponent } from \"document/components/chrome/preview/getLabelForComponent.ts\"\nimport { getDefaultName } from \"document/components/utils/nodes.ts\"\nimport type { PreviewItem } from \"document/preview/PreviewItem.ts\"\nimport { isPreviewItemEqual } from \"document/preview/PreviewItem.ts\"\nimport type { TreeStore } from \"document/stores/TreeStore.ts\"\n\nexport type PreviewItemWithName = PreviewItem & { name: string }\n\nconst MAX_ITEMS = 5\n\nexport class PreviewRecentList {\n\tconstructor(\n\t\tprivate componentLoader: ComponentLoader,\n\t\tprivate treeStore: TreeStore,\n\t) {}\n\n\t// 0 = most recent\n\tprivate _items: PreviewItem[] = []\n\n\t/**\n\t * Returns the list of recent preview items with names resolved at the time\n\t * of the call, and omitting items which no longer exist.\n\t */\n\tget items(): PreviewItemWithName[] {\n\t\treturn this._items.reduce<PreviewItemWithName[]>((result, item) => {\n\t\t\tconst name = this.getName(item)\n\t\t\tif (name) {\n\t\t\t\tresult.push({ ...item, name })\n\t\t\t}\n\t\t\treturn result\n\t\t}, [])\n\t}\n\n\taddItem(newItem: PreviewItem) {\n\t\tconst existingIndex = this._items.findIndex(existingItem => isPreviewItemEqual(newItem, existingItem))\n\t\tif (existingIndex !== -1) {\n\t\t\tthis._items.splice(existingIndex, 1)\n\t\t}\n\n\t\tthis._items.unshift(newItem)\n\n\t\tif (this._items.length > MAX_ITEMS) {\n\t\t\tthis._items.pop()\n\t\t}\n\t}\n\n\tprivate getName(item: PreviewItem) {\n\t\tswitch (item.type) {\n\t\t\tcase \"node\": {\n\t\t\t\tconst node = this.treeStore.tree.get(item.nodeId)\n\t\t\t\treturn node ? node.resolveValue(\"name\") || getDefaultName(this.componentLoader, node) : undefined\n\t\t\t}\n\t\t\tcase \"component\": {\n\t\t\t\tconst component = this.componentLoader.componentForIdentifier(item.componentId)\n\t\t\t\tif (!component || isErrorDefinition(component)) return\n\t\t\t\treturn getLabelForComponent(this.componentLoader, this.treeStore, component.identifier, component.name)\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tassertNever(item)\n\t\t}\n\t}\n}\n", "import type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport type { DeviceNode } from \"document/models/CanvasTree/nodes/DeviceNode.ts\"\nimport { withFramePreset } from \"document/models/CanvasTree/traits/WithFramePreset.ts\"\nimport type { WithPreviewSettings } from \"document/models/CanvasTree/traits/WithPreviewSettings.ts\"\nimport { withPreviewSettings } from \"document/models/CanvasTree/traits/WithPreviewSettings.ts\"\nimport { isScreen } from \"document/models/CanvasTree/traits/WithScreen.ts\"\nimport { getControlPropsValues } from \"document/models/CanvasTree/traits/utils/codeComponentProps.ts\"\nimport type { FramePresetID } from \"document/models/CanvasTree/traits/utils/framePresets.ts\"\nimport type { DeviceOptions, DevicePresetID } from \"library/components/Device/index.ts\"\nimport {\n\tconvertPropsToDeviceOptions,\n\tdefaultDeviceProps,\n\tdevicePresets,\n\tgetDevicePreset,\n} from \"library/components/Device/index.ts\"\nimport type { Size } from \"library/render/types/Size.ts\"\n\n// Mappings included here will have the preview default to the given device.\n// If there's no mapping, the preview will default to no device.\nexport const frameDeviceMappings: Partial<Record<FramePresetID, DevicePresetID>> = {\n\t// Phones\n\tiPhone_320_568: \"iphone-se\",\n\tiPhone_375_667: \"iphone-8\",\n\tiPhone_414_736: \"iphone-8-plus\",\n\tiPhone_414_896: \"iphone-11\",\n\tiPhone_375_812: \"iphone-11-pro\",\n\tiPhone_414_896_pro: \"iphone-11-pro-max\",\n\tiPhone_390_844: \"iphone-12\",\n\tiPhone_375_812_mini: \"iphone-12-mini\",\n\tiPhone_390_844_pro: \"iphone-12-pro\",\n\tiPhone_428_926_pro: \"iphone-12-pro-max\",\n\tGooglePixel_360_780: \"pixel-5\",\n\tGooglePixel_360_760_xl: \"pixel-4-xl\",\n\tGooglePixel_360_760: \"pixel-4\",\n\n\t// Tablets\n\tiPad_810_1080: \"ipad\",\n\tiPad_834_1194: \"ipad-pro-11\",\n\tiPad_768_1024: \"ipad-mini\",\n\tiPad_820_1180: \"ipad-air\",\n\tiPad_1024_1366: \"ipad-pro-12-9\",\n\tSurface_1440_960: \"surface-3\",\n\tSurface_1368_912: \"surface-pro-4\",\n\n\t// Desktops/Laptops\n\tMacBook_1440_900: \"macbook-air\",\n\tiMac_2560_1440: \"imac-27\",\n\tPro_Display_XDR_3008_1692: \"pro-display-xdr\",\n\tDellXPS_1920_1080: \"dell-xps\",\n\tSurfaceBook_1500_1000: \"surface-book\",\n\n\t// Watches\n\tAppleWatch_44: \"apple-watch-44\",\n\tAppleWatch_40: \"apple-watch-40\",\n\n\t// TVs\n\tFullHD_TV_1920_1080: \"tv-full-hd\",\n\t\"4K_TV_3840_2160\": \"tv-4k\",\n}\n\nexport function deviceOptionsForDeviceNode(deviceNode: DeviceNode): DeviceOptions | undefined {\n\tconst controlProps = deviceNode.getRawControlProps()\n\tconst deviceCodeComponentProps = getControlPropsValues(controlProps) as any\n\treturn convertPropsToDeviceOptions({ ...deviceCodeComponentProps, skin: \"clay\" }, { forceOldClay: true })\n}\nexport function devicePresetForDeviceNode(deviceNode: DeviceNode): DevicePresetID {\n\tconst controlProps = deviceNode.getRawControlProps()\n\tconst deviceCodeComponentProps = getControlPropsValues(controlProps)\n\treturn deviceCodeComponentProps.preset as any\n}\n\nexport function deviceOptionsForNode(node: CanvasNode, overrideTheme?: \"dark\" | \"light\"): DeviceOptions | undefined {\n\tif (!withPreviewSettings(node)) return\n\n\tconst devicePreset = devicePresetForNode(node)\n\tif (devicePreset === \"no-device\") return\n\n\tconst skin = node.previewSettings?.deviceSkin ?? \"realistic\"\n\tconst rotated = node.previewSettings?.deviceRotated ?? guessDeviceRotated(node, devicePreset)\n\n\tconst deviceOptions = convertPropsToDeviceOptions({\n\t\t...defaultDeviceProps,\n\t\tpreset: devicePreset,\n\t\trotated,\n\t\tskin,\n\t\ttheme: overrideTheme || \"light\",\n\t\tcolorId: node.previewSettings?.deviceColorId,\n\t\thand: isHandAllowed({\n\t\t\tdevicePreset,\n\t\t\tdeviceSkin: skin,\n\t\t\tdeviceRotated: rotated,\n\t\t})\n\t\t\t? node.previewSettings?.deviceHand\n\t\t\t: undefined,\n\t\tshadow: node.previewSettings?.deviceShadow ?? skin === \"clay\",\n\t})\n\tif (!deviceOptions) {\n\t\treturn undefined\n\t}\n\n\treturn {\n\t\t...deviceOptions,\n\t}\n}\n\n/**\n * Determines the device preset to use for the given node.\n *\n * This might be either the preset explicitly set by the user, or an implicit\n * preset based on the frame preset.\n */\nexport function devicePresetForNode(node: CanvasNode & WithPreviewSettings): DevicePresetID | \"no-device\" {\n\tconst hasExplicitDevicePreset = node.previewSettings?.devicePreset !== undefined\n\n\tconst devicePresetId = node.previewSettings?.devicePreset ?? \"no-device\"\n\tconst implicitDevicePresetId = getDevicePresetFromFramePreset(node)\n\n\tif (hasExplicitDevicePreset || !implicitDevicePresetId) {\n\t\treturn devicePresetId\n\t}\n\n\tconst implicitPreset = devicePresets.find(devicePreset => devicePreset.id === implicitDevicePresetId)\n\tif (!implicitPreset) return devicePresetId\n\n\treturn implicitDevicePresetId\n}\n\nexport function getDevicePresetFromFramePreset(node: CanvasNode & WithPreviewSettings): DevicePresetID | undefined {\n\tif (isScreen(node) && withFramePreset(node) && node.framePreset) {\n\t\treturn frameDeviceMappings[node.framePreset]\n\t} else {\n\t\treturn undefined\n\t}\n}\n\nfunction isHandAllowed({\n\tdevicePreset: presetId,\n\tdeviceSkin,\n\tdeviceRotated,\n}: {\n\tdevicePreset?: DevicePresetID | \"no-device\"\n\tdeviceSkin?: \"clay\" | \"realistic\"\n\tdeviceRotated: boolean\n}) {\n\tif (!presetId || presetId === \"no-device\" || deviceRotated) return false\n\tconst preset = getDevicePreset(presetId)\n\treturn deviceSkin !== \"clay\" && preset.realisticImage?.handOffset !== undefined\n}\n\nfunction getIsPresetOrientationPortrait(presetId: DevicePresetID | \"no-device\" | undefined): boolean {\n\tif (!isValidDevicePreset(presetId)) {\n\t\treturn true\n\t}\n\n\tconst preset = getDevicePreset(presetId)\n\treturn isPortrait(preset.screenWidth, preset.screenHeight)\n}\n\nexport function guessDeviceRotated(\n\tnode: CanvasNode | null,\n\tpresetId: DevicePresetID | \"no-device\" | undefined,\n): boolean {\n\tconst nodeSize = getNodeSize(node)\n\tconst isNodePortrait = isPortrait(nodeSize.width, nodeSize.height)\n\tconst isPresetLandscape = getIsPresetOrientationPortrait(presetId)\n\treturn isPresetLandscape !== isNodePortrait\n}\n\nfunction isPortrait(width: number, height: number): boolean {\n\treturn height >= width\n}\n\nfunction getNodeSize(node: CanvasNode | null): Size {\n\treturn node?.rect() || { width: 0, height: 0 }\n}\n\nfunction isValidDevicePreset(presetId: DevicePresetID | \"no-device\" | undefined): presetId is DevicePresetID {\n\treturn presetId !== undefined && presetId !== \"no-device\"\n}\n", "import type { DeviceOptions } from \"library/components/Device/index.ts\"\n\n/**\n * Provides a fake device for scale to fit functionality\n */\nexport function scaleToFitConfig({ width, height }: { width: number; height: number }): DeviceOptions {\n\treturn {\n\t\tdeviceWidth: width,\n\t\tdeviceHeight: height,\n\t\tscreenWidth: width,\n\t\tscreenHeight: height,\n\t\tappearance: {\n\t\t\ttype: \"none\",\n\t\t},\n\t\ttheme: \"dark\",\n\t\tnoPadding: true,\n\t}\n}\n", "import type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport { isDesignPageNode, isLayoutTemplateNode } from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withPreviewSettings } from \"document/models/CanvasTree/traits/WithPreviewSettings.ts\"\nimport { isBreakpointVariant, isSmartComponentVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { isVectorSetItem } from \"document/models/CanvasTree/traits/WithVectorSetItem.ts\"\nimport { isDeviceNode } from \"document/models/CanvasTree/traits/utils/hardCodedCodeComponentIdentifierChecks.ts\"\nimport { isUserComponentInstance } from \"document/models/CanvasTree/traits/utils/isUserComponent.ts\"\nimport type { DeviceOptions } from \"library/components/Device/index.ts\"\nimport { deviceOptionsForDeviceNode } from \"preview-module/utils/deviceConfigForNode.ts\"\nimport { scaleToFitConfig } from \"preview-module/utils/scaleToFitConfig.ts\"\n\nexport interface PresentationMetadata {\n\tdeviceOptions?: DeviceOptions\n\tisDevice: boolean\n\tisResponsive: boolean\n\tcanChangeResponsive: boolean\n\ttouchCursor: boolean\n}\n\nfunction isLayoutTemplateVariant<N extends CanvasNode>(tree: CanvasTree, node: N | null | undefined) {\n\tif (!node || !isBreakpointVariant(node)) return false\n\treturn isLayoutTemplateNode(tree.getScopeNodeFor(node))\n}\n\nexport function getPresentationMetadata(node: CanvasNode | null, tree: CanvasTree): PresentationMetadata {\n\tif (!node) {\n\t\treturn {\n\t\t\tisDevice: false,\n\t\t\tisResponsive: true,\n\t\t\tcanChangeResponsive: false,\n\t\t\ttouchCursor: false,\n\t\t}\n\t}\n\n\tconst touchCursor = Boolean(withPreviewSettings(node) && node.previewSettings?.touch)\n\n\tif (isDeviceNode(node)) {\n\t\treturn {\n\t\t\tdeviceOptions: deviceOptionsForDeviceNode(node),\n\t\t\tisDevice: true,\n\t\t\tisResponsive: false,\n\t\t\tcanChangeResponsive: false,\n\t\t\ttouchCursor,\n\t\t}\n\t}\n\n\t// When previewing a Smart Component or Layout Template variant, don't scale\n\t// to fit the preview. We provide a responsive canvas with a min\n\t// width/height, making it easier to preview components with layout changes\n\t// (such as dropdowns) in isolation.\n\tif (isSmartComponentVariant(node) || isLayoutTemplateVariant(tree, node)) {\n\t\treturn {\n\t\t\tisDevice: false,\n\t\t\tisResponsive: true,\n\t\t\tcanChangeResponsive: false,\n\t\t\ttouchCursor,\n\t\t}\n\t}\n\n\tif (isUserComponentInstance(node) || isVectorSetItem(node)) {\n\t\tconst { width, height } = node.rect()\n\t\treturn {\n\t\t\tdeviceOptions: scaleToFitConfig({ width, height }),\n\t\t\tisDevice: false,\n\t\t\tisResponsive: false,\n\t\t\tcanChangeResponsive: false,\n\t\t\ttouchCursor,\n\t\t}\n\t}\n\n\tconst scope = tree.getScopeNodeFor(node)\n\tif (isDesignPageNode(scope)) {\n\t\treturn {\n\t\t\tisDevice: false,\n\t\t\tisResponsive: true,\n\t\t\tcanChangeResponsive: false,\n\t\t\ttouchCursor,\n\t\t}\n\t}\n\n\tconst responsive = withPreviewSettings(node) ? node.previewSettings?.responsive : undefined\n\tif (responsive) {\n\t\treturn {\n\t\t\tisDevice: false,\n\t\t\tisResponsive: true,\n\t\t\tcanChangeResponsive: !isBreakpointVariant(node),\n\t\t\ttouchCursor,\n\t\t}\n\t}\n\n\tconst { width, height } = node.rect()\n\tconst scaleToFitDeviceOptions = scaleToFitConfig({\n\t\twidth,\n\t\theight,\n\t})\n\n\treturn {\n\t\tdeviceOptions: scaleToFitDeviceOptions,\n\t\tisDevice: false,\n\t\tisResponsive: false,\n\t\tcanChangeResponsive: true,\n\t\ttouchCursor,\n\t}\n}\n", "import type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { isErrorDefinition, isPreviewPluginDefinition } from \"@framerjs/framer-runtime\"\nimport { AnnotationKey, hasAnnotation } from \"@framerjs/framer-runtime/crossorigin\"\nimport type { ModulePreviewSandbox } from \"@framerjs/framer-services\"\nimport { assert, getLogger, isExternalModuleIdentifier, parseModuleIdentifier } from \"@framerjs/shared\"\nimport type { EngineChanges } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { getLocalizedValueForActiveLocale } from \"document/components/chrome/localization/getValueForActiveLocale.ts\"\nimport { getSelectedCollectionItem } from \"document/components/utils/collectionItemUtils.ts\"\nimport { getRawWebPagePath } from \"document/components/utils/getWebPagePath.ts\"\nimport type { AnyWebPageNode, ScopeNode } from \"document/models/CanvasTree/index.ts\"\nimport type { CanvasNode } from \"document/models/CanvasTree/nodes/CanvasNode.ts\"\nimport type { ExternalModuleNode } from \"document/models/CanvasTree/nodes/ExternalModuleNode.ts\"\nimport type { MaybeNodeID, NodeID } from \"document/models/CanvasTree/nodes/NodeID.ts\"\nimport {\n\tisCanvasPageNode,\n\tisCollectionItemNode,\n\tisCollectionNode,\n\tisDesignPageNode,\n\tisWebPageNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { withPreviewSettings } from \"document/models/CanvasTree/traits/WithPreviewSettings.ts\"\nimport { withReplicaVariants } from \"document/models/CanvasTree/traits/WithReplicaVariants.ts\"\nimport { isBreakpointVariant } from \"document/models/CanvasTree/traits/WithVariant.ts\"\nimport { withVectorSetItems } from \"document/models/CanvasTree/traits/WithVectorSetItems.ts\"\nimport { getHomeNode } from \"document/models/CanvasTree/utils/homeNode.ts\"\nimport { ChangeTracker } from \"document/preview/ChangeTracker.ts\"\nimport type { PreviewItem } from \"document/preview/PreviewItem.ts\"\nimport { isPreviewItemEqual } from \"document/preview/PreviewItem.ts\"\nimport { PreviewRecentList } from \"document/preview/PreviewRecentList.ts\"\nimport type { PresentationMetadata } from \"document/preview/getPresentationMetadata.ts\"\nimport { getPresentationMetadata } from \"document/preview/getPresentationMetadata.ts\"\nimport { ActiveMainView } from \"document/utils/ActiveEditorType.ts\"\nimport { isPreviewableNode } from \"document/utils/isPreviewableNode.ts\"\nimport { ScopeType } from \"document/utils/scopeType.ts\"\nimport type { UnresolvedSlug } from \"library/modules/LinkToWebPage.ts\"\nimport { ControlType } from \"library/render/types/PropertyControls.ts\"\nimport type { Locale } from \"library/router/types.ts\"\nimport type { PreviewSettings } from \"preview-module/utils/PreviewSettings.ts\"\nimport { isShallowEqual } from \"utils/isShallowEqual.ts\"\nimport { extractPathVariables } from \"utils/pathVariables.ts\"\nimport { sha256 } from \"utils/sha256.ts\"\nimport { isString } from \"utils/typeChecks.ts\"\nimport type { ChromeStore } from \"./ChromeStore.ts\"\nimport type { CodeEditorStore } from \"./CodeEditorStore.ts\"\nimport type { ComponentsStore } from \"./ComponentsStore.ts\"\nimport type { ContentManagementStore } from \"./ContentManagementStore.ts\"\nimport type { LoadingStore } from \"./LoadingStore.ts\"\nimport type { ScopeStore } from \"./ScopeStore.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst log = getLogger(\"PreviewStore\")\n\ninterface Metadata extends Partial<PresentationMetadata> {\n\titem?: PreviewItem\n\thighlights?: boolean\n\tpluginComponentId?: string\n\tpluginContentWidth?: number\n\tpluginContentHeight?: number\n}\n\nexport class PreviewStore extends EngineStore {\n\tprivate _didInitialize = false\n\n\t#trackers: {\n\t\tactiveScopeId: ChangeTracker<NodeID>\n\t\tcodeEditorFile: ChangeTracker<string | undefined>\n\t\tisCanvasVisible: ChangeTracker<boolean>\n\t\tisCodeEditorVisible: ChangeTracker<boolean>\n\t\tisCompleteDocumentLoaded: ChangeTracker<boolean>\n\t\tpreviewNodeSettings: ChangeTracker<PreviewSettings | null>\n\t\tpreviewNodeWidth: ChangeTracker<number | undefined>\n\t\tpreviewNodeHeight: ChangeTracker<number | undefined>\n\t\tselectedGroundNodeId: ChangeTracker<MaybeNodeID>\n\t}\n\n\tconstructor(\n\t\tprivate componentLoader: ComponentLoader,\n\t\tprivate chromeStore: ChromeStore,\n\t\tprivate codeEditorStore: CodeEditorStore,\n\t\tprivate componentsStore: ComponentsStore,\n\t\tprivate contentManagementStore: ContentManagementStore,\n\t\tprivate loadingStore: LoadingStore,\n\t\tprivate scopeStore: ScopeStore,\n\t\tprivate selectionStore: SelectionStore,\n\t\tprivate treeStore: TreeStore,\n\t) {\n\t\tsuper()\n\n\t\tthis.recent = new PreviewRecentList(componentLoader, treeStore)\n\n\t\tthis.#trackers = {\n\t\t\tactiveScopeId: new ChangeTracker(() => this.scopeStore.active.id),\n\t\t\tcodeEditorFile: new ChangeTracker(() => this.codeEditorStore.currentFilePath),\n\t\t\tisCanvasVisible: new ChangeTracker(() => this.chromeStore.mainView === ActiveMainView.Canvas),\n\t\t\tisCodeEditorVisible: new ChangeTracker(() => this.chromeStore.mainView === ActiveMainView.CodeEditor),\n\t\t\tisCompleteDocumentLoaded: new ChangeTracker(() => this.loadingStore.hasMinimalEditableData),\n\t\t\tpreviewNodeSettings: new ChangeTracker(() =>\n\t\t\t\tthis.previewNode && withPreviewSettings(this.previewNode) ? this.previewNode.previewSettings : null,\n\t\t\t),\n\t\t\tpreviewNodeWidth: new ChangeTracker(() => this.previewNode?.rect().width),\n\t\t\tpreviewNodeHeight: new ChangeTracker(() => this.previewNode?.rect().height),\n\t\t\tselectedGroundNodeId: new ChangeTracker(() => this.selectionStore.commonGroundNodeId),\n\t\t}\n\t}\n\n\t/** Indicates the preview should start loading. Set to true by vekter after the sandbox has\n\t * fully rendered. */\n\tshouldStartPreloading = false\n\n\t/** Indicates the preview should be shown on load. Set to true by url params on page load. */\n\tshouldShowPreviewOnLoad = false\n\n\t/** If set to true, the preview will be rendered in the Chrome component regardless of the device. */\n\tforceOverCanvasPreviewRender = false\n\n\t/** Indicates the preview should be shown in fullscreen. Set to true by url params on page load. */\n\tisFullScreen = false\n\n\trecent: PreviewRecentList\n\tframerSiteId: string | undefined = undefined\n\n\t/**\n\t * Hash the projectId the same way we do on publish for use in the preview\n\t * FormContext.\n\t */\n\tasync initialize(projectId: string) {\n\t\tif (this._didInitialize) return\n\t\tthis._didInitialize = true\n\n\t\tthis.framerSiteId = await sha256(projectId)\n\t}\n\n\tprivate _item?: PreviewItem\n\tget item() {\n\t\treturn this._item\n\t}\n\tset item(item: PreviewItem | undefined) {\n\t\tif (isPreviewItemEqual(item, this._item)) return\n\n\t\tlog.debug(\"changing preview item\", item)\n\t\tthis._item = item\n\n\t\tthis.updatePreviewNodeMetadata()\n\n\t\t// Let the relevant trackers know we've handled this previewNode change.\n\t\tthis.#trackers.previewNodeSettings.update()\n\t\tthis.#trackers.previewNodeWidth.update()\n\t\tthis.#trackers.previewNodeHeight.update()\n\n\t\tif (item && this.isActive) {\n\t\t\tthis.recent.addItem(item)\n\t\t}\n\t}\n\n\ttargetModuleRevisions: ModulePreviewSandbox.TargetModuleRevision[] = []\n\n\t/** Conveniece getter for when this.item is a node. */\n\tget previewNode(): CanvasNode | null {\n\t\tif (this._item?.type === \"node\") {\n\t\t\treturn this.treeStore.tree.get(this._item.nodeId)\n\t\t} else {\n\t\t\treturn null\n\t\t}\n\t}\n\n\t/**\n\t * Allows Preview selection to \"stick\" until closed\n\t * Currently only used for the Code Editor\n\t */\n\tstickyPreviewItem: boolean = false\n\n\thighlights = false\n\ttoggleHighlights() {\n\t\tthis.highlights = !this.highlights\n\t}\n\n\tpluginComponentId?: string\n\n\tprivate _previewNodeMetadata?: Metadata\n\tprivate updatePreviewNodeMetadata() {\n\t\tif (this.previewNode) {\n\t\t\tassert(this.item?.type === \"node\")\n\n\t\t\tconst presentationMetadata = getPresentationMetadata(this.previewNode, this.treeStore.tree)\n\t\t\tconst { width, height } = this.previewNode.rect()\n\t\t\tthis._previewNodeMetadata = {\n\t\t\t\t...presentationMetadata,\n\t\t\t\tpluginContentWidth: width,\n\t\t\t\tpluginContentHeight: height,\n\t\t\t}\n\t\t} else {\n\t\t\tthis._previewNodeMetadata = undefined\n\t\t}\n\t\tlog.debug(\"updated preview node metadata\", this._previewNodeMetadata)\n\t}\n\n\t#previousMetadata: Metadata | undefined\n\n\tget metadata(): Metadata {\n\t\tconst metadata: Metadata = {\n\t\t\titem: this.item,\n\t\t\thighlights: this.highlights,\n\t\t\tpluginComponentId: this.pluginComponentId,\n\t\t\t...this._previewNodeMetadata,\n\t\t}\n\n\t\tif (this.item?.type === \"component\" || this.pluginComponentId) {\n\t\t\tmetadata.isDevice = false\n\t\t\tmetadata.deviceOptions = undefined\n\t\t\tmetadata.isResponsive = true\n\t\t\tmetadata.canChangeResponsive = false\n\t\t}\n\n\t\tif (this.#previousMetadata && isShallowEqual(this.#previousMetadata, metadata)) {\n\t\t\treturn this.#previousMetadata\n\t\t}\n\n\t\tthis.#previousMetadata = metadata\n\t\treturn metadata\n\t}\n\n\tpostProcess(changes: EngineChanges) {\n\t\tfor (const tracker of Object.values(this.#trackers)) {\n\t\t\ttracker.update()\n\t\t}\n\n\t\tif (!this.#trackers.isCompleteDocumentLoaded.current) {\n\t\t\treturn\n\t\t}\n\n\t\tlet item: PreviewItem | undefined\n\t\tif (this.#trackers.isCodeEditorVisible.current) {\n\t\t\titem = this.processCodeEditorPreviewUpdate(changes)\n\t\t}\n\n\t\tif (item) {\n\t\t\tthis.item = item\n\t\t} else if (\n\t\t\tthis.#trackers.previewNodeSettings.didChange ||\n\t\t\tthis.#trackers.previewNodeWidth.didChange ||\n\t\t\tthis.#trackers.previewNodeHeight.didChange\n\t\t) {\n\t\t\tlog.debug(\"updating preview node metadata because its presentation-affecting props changed\")\n\t\t\tthis.updatePreviewNodeMetadata()\n\t\t} else if (changes.has(EngineChange.AssetMap) && this._previewNodeMetadata?.deviceOptions?.background) {\n\t\t\tlog.debug(\"updating preview node metadata because it has background and asset map changed\")\n\t\t\tthis.updatePreviewNodeMetadata()\n\t\t}\n\n\t\tif (\n\t\t\tthis.pluginComponentId &&\n\t\t\tchanges.has(EngineChange.ActiveBundle, EngineChange.Tree) &&\n\t\t\t!this.isValidPreviewPlugin(this.pluginComponentId)\n\t\t) {\n\t\t\tthis.pluginComponentId = undefined\n\t\t}\n\t}\n\n\t#codeEditorPreviousComponentId: string | undefined = undefined\n\n\t/**\n\t * Looks at the code editor state changes and decided whether to re-compute\n\t * the preview item.\n\t */\n\tprivate processCodeEditorPreviewUpdate(changes: EngineChanges): PreviewItem | undefined {\n\t\tif (this.stickyPreviewItem) return\n\t\tif (this.#trackers.isCodeEditorVisible.didChange || this.#trackers.codeEditorFile.didChange) {\n\t\t\treturn this.computeCodeEditorPreviewItem()\n\t\t} else if (changes.has(EngineChange.ActiveBundle)) {\n\t\t\tconst item = this.computeCodeEditorPreviewItem()\n\n\t\t\t// Update the preview item if the file change failed.\n\t\t\tif (this.#codeEditorFileChangeFailed) {\n\t\t\t\treturn item\n\t\t\t}\n\n\t\t\t// Update the preview item if the component export changed.\n\t\t\tif (item?.type === \"component\" && this.#codeEditorPreviousComponentId !== item.componentId) {\n\t\t\t\tthis.#codeEditorPreviousComponentId = item.componentId\n\t\t\t\treturn item\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Computes the preview item from the current editor state.\n\t */\n\tcomputePreviewItem(): PreviewItem | undefined {\n\t\tif (this.chromeStore.mainView === ActiveMainView.CodeEditor) {\n\t\t\treturn this.computeCodeEditorPreviewItem()\n\t\t} else {\n\t\t\treturn this.computeMainPreviewItem()\n\t\t}\n\t}\n\n\t/**\n\t * Computes the non-code-editor preview item from the current editor state.\n\t */\n\tprivate computeMainPreviewItem(): PreviewItem | undefined {\n\t\tconst selection = this.selectionStore.nodes\n\t\tconst collectionItemIdBasedOnCurrentSelection =\n\t\t\tthis.scopeStore.scopeType === ScopeType.ContentManagement\n\t\t\t\t? this.contentManagementStore.getCollectionItemIdBasedOnCurrentSelection()\n\t\t\t\t: null\n\n\t\tif (selection.length === 1 && isCollectionItemNode(selection[0])) {\n\t\t\treturn this.getPreviewItemForCollectionItem(selection[0].id)\n\t\t}\n\n\t\tif (collectionItemIdBasedOnCurrentSelection) {\n\t\t\treturn this.getPreviewItemForCollectionItem(collectionItemIdBasedOnCurrentSelection)\n\t\t}\n\n\t\tconst activeScope = this.scopeStore.active\n\t\tconst getCollectionItemNodeId = (scope: ScopeNode, node: CanvasNode): string | undefined => {\n\t\t\tif (isWebPageNode(scope) && isBreakpointVariant(node)) {\n\t\t\t\tconst selectedItem = getSelectedCollectionItem(\n\t\t\t\t\tthis.treeStore.tree,\n\t\t\t\t\tthis.componentLoader,\n\t\t\t\t\tscope.dataIdentifier,\n\t\t\t\t\tthis.scopeStore.getSelectedCollectionItemForWebPage(scope),\n\t\t\t\t\tthis.chromeStore.canvasLocaleId,\n\t\t\t\t)\n\t\t\t\treturn selectedItem?.id\n\t\t\t}\n\t\t}\n\n\t\tconst selectedGroundNode = this.selectionStore.commonGroundNode\n\t\tif (selectedGroundNode && !isCollectionNode(selectedGroundNode)) {\n\t\t\tif (isPreviewableNode(selectedGroundNode, this.treeStore.tree)) {\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"node\",\n\t\t\t\t\tnodeId: selectedGroundNode.id,\n\t\t\t\t\tcollectionItemNodeId: getCollectionItemNodeId(activeScope, selectedGroundNode),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the selected ground node is not previewable, find a fallback.\n\t\t\tif (withReplicaVariants(activeScope)) {\n\t\t\t\t// Here we disable previewing ground nodes in web pages, because we\n\t\t\t\t// do not generate modules for them, so they won't work in the\n\t\t\t\t// module preview.\n\t\t\t\tconst node = activeScope.getPrimaryVariant()\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"node\",\n\t\t\t\t\tnodeId: node.id,\n\t\t\t\t\tcollectionItemNodeId: getCollectionItemNodeId(activeScope, node),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// When in a vector set, fallback to the first vector if the selected node is not a previewable node.\n\t\t\tif (withVectorSetItems(activeScope)) {\n\t\t\t\tconst firstVector = activeScope.getVectorSetItems()[0]\n\t\t\t\tif (!firstVector) return undefined\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"node\",\n\t\t\t\t\tnodeId: firstVector.id,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (isCanvasPageNode(activeScope)) {\n\t\t\tconst homeNode = getHomeNode(this.treeStore.tree, activeScope)\n\t\t\tif (homeNode) {\n\t\t\t\treturn { type: \"node\", nodeId: homeNode.id }\n\t\t\t}\n\t\t} else if (isDesignPageNode(activeScope)) {\n\t\t\t// From the selection, pick the first node whose ground node is previewable.\n\t\t\tfor (const node of selection) {\n\t\t\t\tconst groundNode = this.treeStore.tree.getGroundNodeFor(node)\n\t\t\t\tif (isPreviewableNode(groundNode, this.treeStore.tree)) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"node\",\n\t\t\t\t\t\tnodeId: groundNode.id,\n\t\t\t\t\t\tcollectionItemNodeId: getCollectionItemNodeId(activeScope, groundNode),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (withReplicaVariants(activeScope)) {\n\t\t\tconst primaryVariant = activeScope.getPrimaryVariant()\n\t\t\treturn {\n\t\t\t\ttype: \"node\",\n\t\t\t\tnodeId: primaryVariant.id,\n\t\t\t\tcollectionItemNodeId: getCollectionItemNodeId(activeScope, primaryVariant),\n\t\t\t}\n\t\t}\n\n\t\t// When in a vector set, fallback to the first vector if nothing is selected.\n\t\tif (withVectorSetItems(activeScope)) {\n\t\t\tconst firstVector = activeScope.getVectorSetItems()[0]\n\t\t\tif (!firstVector) return undefined\n\t\t\treturn {\n\t\t\t\ttype: \"node\",\n\t\t\t\tnodeId: firstVector.id,\n\t\t\t}\n\t\t}\n\t}\n\n\tgetWebPageNodeForCollectionItem(collectionItemNodeId: string): AnyWebPageNode | undefined {\n\t\tconst collectionItemNode = this.treeStore.tree.get(collectionItemNodeId)\n\t\tif (!collectionItemNode || !isCollectionItemNode(collectionItemNode)) return\n\n\t\tconst collectionNodeId = collectionItemNode.parentid\n\t\tif (!collectionNodeId) return\n\n\t\tconst collectionNode = this.treeStore.tree.get(collectionNodeId)\n\t\tif (!collectionNode || !isCollectionNode(collectionNode)) return\n\n\t\tconst dataIdentifier = collectionNode.instanceIdentifier\n\t\treturn this.scopeStore.getWebPageNodes().find(node => node.dataIdentifier === dataIdentifier)\n\t}\n\n\tgetPreviewItemForCollectionItem(collectionItemNodeId: string): PreviewItem | undefined {\n\t\tconst webPageNode = this.getWebPageNodeForCollectionItem(collectionItemNodeId)\n\t\tconst pagePath = getRawWebPagePath(this.treeStore.tree, webPageNode)\n\t\t// TODO Check and handle shallow/fully loaded scope state\n\t\tif (!webPageNode || !pagePath || !webPageNode.isLoaded()) return\n\n\t\treturn { type: \"node\", nodeId: webPageNode.getPrimaryVariant().id, collectionItemNodeId }\n\t}\n\n\tgetPathSlugs(\n\t\tpreviewNodeId: string,\n\t\tcollectionItemNodeId: string,\n\t\tactiveLocale: Locale | undefined,\n\t): { unresolvedSlugs: Record<string, UnresolvedSlug>; pathVariables: Record<string, string> } | undefined {\n\t\tconst node = this.treeStore.tree.get(previewNodeId)\n\n\t\tif (!node) return\n\t\tconst webPageNode = this.treeStore.tree.getScopeNodeFor(node)\n\t\tif (!isWebPageNode(webPageNode) || !webPageNode.dataIdentifier) return\n\n\t\tconst pagePath = getRawWebPagePath(this.treeStore.tree, webPageNode)\n\t\tif (!pagePath) return\n\n\t\tconst collectionItemNode = this.treeStore.tree.get(collectionItemNodeId)\n\t\tif (!collectionItemNode || !isCollectionItemNode(collectionItemNode)) return\n\n\t\tconst collectionNodeId = collectionItemNode.parentid\n\t\tif (!collectionNodeId) return\n\t\tconst collectionNode = this.treeStore.tree.get(collectionNodeId)\n\t\tif (!collectionNode || !isCollectionNode(collectionNode)) return\n\n\t\tconst collectionData = this.componentLoader.dataForIdentifier(webPageNode.dataIdentifier)\n\n\t\tconst pathVariableKeys = extractPathVariables(pagePath)\n\t\tconst unresolvedSlugs: Record<string, UnresolvedSlug> = {}\n\t\tconst pathVariables: Record<string, string> = {}\n\t\tfor (const variable of collectionNode.variables) {\n\t\t\tif (!pathVariableKeys.includes(variable.id)) continue\n\n\t\t\tconst controlProp = collectionItemNode.getControlProp(variable.id)\n\t\t\tif (controlProp?.type !== ControlType.String) continue\n\n\t\t\tconst localizedValue = getLocalizedValueForActiveLocale(activeLocale, controlProp.valueLocalized)\n\t\t\tconst value = localizedValue?.value ?? controlProp.value\n\t\t\tif (!isString(value)) continue\n\n\t\t\tpathVariables[variable.id] = value\n\n\t\t\t// Old collections can exists which don't have the collection utils yet.\n\t\t\t// For these we rely on the already existing \"pathVariables\" with their resolved values.\n\t\t\tif (!collectionData?.annotations?.[AnnotationKey.FramerCollectionUtils]) continue\n\n\t\t\tunresolvedSlugs[variable.id] = {\n\t\t\t\tcollectionId: collectionNode.id,\n\t\t\t\tcollectionItemId: collectionItemNode.id,\n\t\t\t}\n\t\t}\n\n\t\treturn { unresolvedSlugs, pathVariables }\n\t}\n\n\t#codeEditorFileChangeFailed = false\n\n\t/**\n\t * Computes the code-editor preview item from the current code editor state.\n\t */\n\tprivate computeCodeEditorPreviewItem(): PreviewItem | undefined {\n\t\tconst currentFilePath = this.codeEditorStore.currentFilePath\n\t\tif (currentFilePath) {\n\t\t\tconst component = this.componentsStore.componentDefinitionForFile(currentFilePath)\n\t\t\tif (component && !isErrorDefinition(component)) {\n\t\t\t\tthis.#codeEditorFileChangeFailed = false\n\t\t\t\treturn { type: \"component\", componentId: component.identifier }\n\t\t\t} else {\n\t\t\t\t// This may be a newly-created file which doesn't yet exist in\n\t\t\t\t// the ComponentsStore. So let's mark the update as failed, and\n\t\t\t\t// we'll start listening for ComponentsStore updates to retry.\n\t\t\t\tthis.#codeEditorFileChangeFailed = true\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isValidPreviewPlugin(pluginComponentId: string) {\n\t\tconst parsedModuleIdentifier = parseModuleIdentifier(pluginComponentId)\n\t\tif (isExternalModuleIdentifier(parsedModuleIdentifier)) {\n\t\t\t// Verify external module plugins against the ExternalModulesListNode\n\t\t\tconst node = this.treeStore.tree.get<ExternalModuleNode>(parsedModuleIdentifier.moduleId)\n\t\t\treturn (\n\t\t\t\tnode?.codeComponentIdentifier === pluginComponentId &&\n\t\t\t\thasAnnotation(node.annotations, AnnotationKey.FramerPreviewPlugin)\n\t\t\t)\n\t\t} else {\n\t\t\t// Verify local plugins against the component loader\n\t\t\tconst pluginComponent = this.componentLoader.componentForIdentifier(pluginComponentId)\n\t\t\treturn Boolean(pluginComponent && isPreviewPluginDefinition(pluginComponent))\n\t\t}\n\t}\n\n\tprivate _isActive = false\n\tget isActive() {\n\t\treturn this._isActive\n\t}\n\t#activeSessions = 0\n\taddActiveSession() {\n\t\t++this.#activeSessions\n\n\t\tif (this.#activeSessions === 1) {\n\t\t\tlog.debug(\"preview went active\")\n\t\t\tthis._isActive = true\n\n\t\t\tif (this.item) {\n\t\t\t\tthis.recent.addItem(this.item)\n\t\t\t}\n\t\t}\n\t}\n\tremoveActiveSession() {\n\t\tif (this.#activeSessions === 0) {\n\t\t\tlog.warn(\"got a call to removeActiveSessions, but there are no active sessions\")\n\t\t\treturn\n\t\t}\n\n\t\t--this.#activeSessions\n\n\t\tif (this.#activeSessions === 0) {\n\t\t\tlog.debug(\"preview went inactive\")\n\t\t\tthis._isActive = false\n\t\t}\n\t}\n}\n", "import type {\n\tAccessRequestACLEntry,\n\tAiUsage,\n\tInviteACLEntry,\n\tLoadingProjectState,\n\tProject,\n\tProjectCanvasFeature,\n\tUserACLEntry,\n} from \"@framerjs/app-shared\"\nimport { ProjectLicenseType } from \"@framerjs/app-shared\"\nimport type { BootstrappedWindow } from \"@framerjs/bootstrap\"\nimport { assert, ResolvablePromise } from \"@framerjs/shared\"\nimport { defaultProjectFeatures, projectFeatures } from \"app/projectFeatures.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { BaseProjectStore } from \"document/base-engine/BaseProjectStore.ts\"\nimport { environment } from \"environment/index.ts\"\nimport type { UserStateData } from \"socket/types.ts\"\nimport { isUndefined } from \"utils/typeChecks.ts\"\n\nexport class ProjectStore extends EngineStore implements LoadingProjectState, BaseProjectStore {\n\tacl: (UserACLEntry | InviteACLEntry)[] = []\n\taccessRequests: AccessRequestACLEntry[] = []\n\taclById: { [id: string]: UserACLEntry | InviteACLEntry | undefined } = {}\n\tactiveIds: Set<string> = new Set<string>()\n\tprojectId: string\n\n\tuserStates: {\n\t\t[id: string]: UserStateData\n\t} = {}\n\n\tprivate _project?: Project\n\tprivate readonly projectHasBeenSet = new ResolvablePromise<void>()\n\n\tget project(): Project | undefined {\n\t\treturn this._project\n\t}\n\n\tconstructor() {\n\t\tsuper()\n\n\t\tconst projectId = (window as BootstrappedWindow).bootstrap?.project?.id\n\t\tconst evalProjectIdFromEnv =\n\t\t\ttypeof process !== \"undefined\" && process.env.FRAMER_AI_PROJECT_ID ? process.env.FRAMER_AI_PROJECT_ID : undefined\n\t\tif (projectId) {\n\t\t\tthis.projectId = projectId\n\t\t} else if (evalProjectIdFromEnv) {\n\t\t\t// CLI eval harness workers run without bootstrap project data and rely on auth setup env vars.\n\t\t\tthis.projectId = evalProjectIdFromEnv\n\t\t} else if (environment.isAutomation || environment.isTest) {\n\t\t\tthis.projectId = \"FAKE_TEST_PROJECT_ID\"\n\t\t} else {\n\t\t\tthrow Error(\"Can\u2019t find project id\")\n\t\t}\n\t}\n\n\tupdate(data: LoadingProjectState) {\n\t\tthis.acl = data.acl\n\t\tthis.accessRequests = data.accessRequests\n\t\tthis.aclById = data.aclById\n\t\tthis.activeIds = data.activeIds\n\t\tthis.projectId = data.projectId\n\t\tthis.userStates = data.userStates\n\n\t\tthis.updateProject(data.project)\n\n\t\tif (this.project && !this.projectHasBeenSet.isResolved()) {\n\t\t\tthis.projectHasBeenSet.resolve()\n\t\t}\n\t}\n\n\tasync getProject(): Promise<Project> {\n\t\tawait this.projectHasBeenSet\n\t\tassert(this.project, \"Project should be defined after it has been set\")\n\t\treturn this.project\n\t}\n\n\t/**\n\t * Updates the project and the project features.\n\t *\n\t * @param project The new project data or undefined. Supports partial updates.\n\t * @returns void\n\t */\n\tupdateProject(project: Project | undefined): void\n\tupdateProject(project: Partial<Project>): void\n\tupdateProject(project: Project | Partial<Project> | undefined): void {\n\t\tif (isUndefined(project)) {\n\t\t\tthis._project = undefined\n\t\t} else if (isUndefined(this._project)) {\n\t\t\t// We are casting to project here because there is no clear way to check if the project is type Project\n\t\t\t// There are lots of optional fields and some non optional properties that have comments mentioning\n\t\t\t// they are not always sent in the type\n\t\t\tthis._project = project as Project\n\t\t} else {\n\t\t\tthis._project = {\n\t\t\t\t...this._project,\n\t\t\t\t...project,\n\t\t\t}\n\t\t}\n\n\t\tprojectFeatures.update({\n\t\t\t...defaultProjectFeatures,\n\t\t\t...(this._project?.canvasFeatures ?? {}),\n\t\t})\n\t}\n\n\t/**\n\t * Updates the project canvas features.\n\t *\n\t * @param features The project features to update.\n\t * @returns void\n\t */\n\t// TODO: Remove \"crdt\" once CRDT is fully shipped; this only supports temporary backend conversion writes.\n\tupdateProjectFeatures(features: Partial<Record<ProjectCanvasFeature | \"crdt\", boolean>>) {\n\t\tif (!this._project) return\n\n\t\tconst updatedCanvasFeatures = {\n\t\t\tcanvasFeatures: {\n\t\t\t\t...this._project.canvasFeatures,\n\t\t\t\t...features,\n\t\t\t},\n\t\t}\n\n\t\tthis.updateProject(updatedCanvasFeatures)\n\t}\n\n\t/** Setting to `true` notifies other clients over WebSocket in Project.tsx */\n\taiCreditLimitReachedPending = false\n\n\tupdateAiUsage(update: Partial<AiUsage>) {\n\t\tif (!this._project) return\n\t\tconst current = this._project.usage.aiCredits\n\t\tthis.updateProject({\n\t\t\tusage: {\n\t\t\t\t...this._project.usage,\n\t\t\t\taiCredits: {\n\t\t\t\t\tcurrentMonth: update.currentMonth ?? current?.currentMonth ?? 0,\n\t\t\t\t\tcurrentDay: update.currentDay ?? current?.currentDay ?? 0,\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t}\n\n\tupdateAiCreditLimits(update: { aiCredits?: number; aiCreditsDaily?: number }) {\n\t\tif (!this._project) return\n\t\tconst current = this._project.settings.resourceLimits\n\t\tthis.updateProject({\n\t\t\tsettings: {\n\t\t\t\t...this._project.settings,\n\t\t\t\tresourceLimits: {\n\t\t\t\t\t...current,\n\t\t\t\t\taiCredits: update.aiCredits ?? current.aiCredits,\n\t\t\t\t\taiCreditsDaily: update.aiCreditsDaily ?? current.aiCreditsDaily,\n\t\t\t\t},\n\t\t\t},\n\t\t})\n\t}\n\n\tget resourceLimits() {\n\t\treturn this.project?.settings.resourceLimits\n\t}\n\n\tget featureFlags() {\n\t\treturn this.project?.settings.featureFlags\n\t}\n\n\tget projectLicenseType() {\n\t\treturn this.project?.license.type ?? ProjectLicenseType.FreeSite\n\t}\n\n\tget isDraft() {\n\t\treturn !this.project || this.project.space.scope === \"user\"\n\t}\n\n\tget teamSyncAction() {\n\t\treturn this.project?.teamSyncAction\n\t}\n\n\tget usageData() {\n\t\treturn this.project?.usage\n\t}\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\nimport { ColorStyleTokenListNode } from \"document/models/CanvasTree/nodes/ColorStyleTokenListNode.ts\"\nimport type { FramePresetCategory } from \"document/models/CanvasTree/traits/utils/framePresets.ts\"\nimport type { ActiveLinkStyle } from \"document/utils/activeLinkStylePreset.ts\"\nimport { newSetByTogglingItem } from \"document/utils/newSetByTogglingItem.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport type { VekterEngine } from \"../VekterEngine.ts\"\nexport class PropertiesPanelStore extends EngineStore {\n\t// Frame preset categories\n\n\tprivate _expandedFrameCategories: ReadonlySet<FramePresetCategory> = new Set([\"Phone\", \"Desktop\"])\n\n\t// Link Style Presets\n\tactiveLinkStyle: ActiveLinkStyle | undefined = undefined\n\n\tget expandedFrameCategories() {\n\t\treturn this._expandedFrameCategories\n\t}\n\n\ttoggleFrameCategory = (category: FramePresetCategory) => {\n\t\tthis._expandedFrameCategories = newSetByTogglingItem(this._expandedFrameCategories, category)\n\t}\n\n\tdocumentDidLoad(engine: VekterEngine) {\n\t\tconst { tree } = engine\n\t\tconst activeTokensCount = ColorStyleTokenListNode.getTokenNodes(tree).length\n\t\tif (isNumber(activeTokensCount) && activeTokensCount > 0) {\n\t\t\treturn\n\t\t}\n\t}\n}\n", "import { ReadonlySet } from \"@framerjs/shared\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport { isShallowSetEqual } from \"utils/isShallowEqual.ts\"\nimport type { SelectionStore } from \"./SelectionStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nexport type RepeatersShowingEmptyState = ReadonlySet<NodeID>\n\nexport class RepeaterStore extends EngineStore {\n\tconstructor(private readonly treeStore: TreeStore) {\n\t\tsuper()\n\t}\n\n\t// Sets must always be new instances to trigger change detection\n\n\tprivate _repeatersShowingEmptyState: RepeatersShowingEmptyState = new Set()\n\tget repeatersShowingEmptyState(): RepeatersShowingEmptyState {\n\t\treturn this._repeatersShowingEmptyState\n\t}\n\tprivate set repeatersShowingEmptyState(value: RepeatersShowingEmptyState) {\n\t\tthis._repeatersShowingEmptyState = value\n\t}\n\n\tprivate _groundNodesWithEmptyStates: ReadonlySet<NodeID> = new Set()\n\tget groundNodesWithEmptyStates(): ReadonlySet<NodeID> {\n\t\treturn this._groundNodesWithEmptyStates\n\t}\n\tprivate set groundNodesWithEmptyStates(value: ReadonlySet<NodeID>) {\n\t\tthis._groundNodesWithEmptyStates = value\n\t}\n\n\tshowEmptyState(nodeId: NodeID) {\n\t\tif (this.repeatersShowingEmptyState.has(nodeId)) return\n\n\t\tthis.repeatersShowingEmptyState = ReadonlySet.add(this.repeatersShowingEmptyState, nodeId)\n\n\t\tconst repeaterNode = this.treeStore.tree.get(nodeId)\n\t\tif (!repeaterNode) return\n\n\t\tconst groundNode = this.treeStore.tree.getGroundNodeFor(repeaterNode)\n\t\tif (this.groundNodesWithEmptyStates.has(groundNode.id)) return\n\n\t\tthis.groundNodesWithEmptyStates = ReadonlySet.add(this.groundNodesWithEmptyStates, groundNode.id)\n\t}\n\n\thideEmptyState(nodeId: NodeID) {\n\t\tif (!this.repeatersShowingEmptyState.has(nodeId)) return\n\n\t\tthis.repeatersShowingEmptyState = ReadonlySet.remove(this.repeatersShowingEmptyState, nodeId)\n\n\t\t// The ground node might still have other repeaters showing empty state, so we cannot simply remove, we must rescan fully.\n\t\tthis.recomputeGroundNodesWithEmptyStates()\n\t}\n\n\tprivate recomputeGroundNodesWithEmptyStates() {\n\t\tconst nextGroundNodes = new Set<NodeID>()\n\t\tfor (const repeaterId of this.repeatersShowingEmptyState) {\n\t\t\tconst repeaterNode = this.treeStore.tree.get(repeaterId)\n\t\t\tif (!repeaterNode) continue\n\t\t\tnextGroundNodes.add(this.treeStore.tree.getGroundNodeFor(repeaterNode).id)\n\t\t}\n\t\tif (!isShallowSetEqual(this._groundNodesWithEmptyStates, nextGroundNodes)) {\n\t\t\tthis._groundNodesWithEmptyStates = nextGroundNodes\n\t\t}\n\t}\n\n\tprivate resetAllEmptyStates() {\n\t\tif (this.repeatersShowingEmptyState.size === 0) return\n\t\tthis.repeatersShowingEmptyState = new Set()\n\t\tthis._groundNodesWithEmptyStates = new Set()\n\t}\n\n\texitEditMode(selection: SelectionStore) {\n\t\tselection.clear()\n\t\tthis.resetAllEmptyStates()\n\t}\n\n\tprivate areSomeRepeatersDeleted(tree: CanvasTree): boolean {\n\t\tfor (const repeaterId of this.repeatersShowingEmptyState) {\n\t\t\tif (!tree.has(repeaterId)) return true\n\t\t}\n\t\treturn false\n\t}\n\n\tpostProcess(tree: CanvasTree) {\n\t\tif (!this.areSomeRepeatersDeleted(tree)) return\n\n\t\tconst nextRepeaters = new Set(this.repeatersShowingEmptyState)\n\t\tfor (const repeaterId of nextRepeaters) {\n\t\t\tif (!tree.has(repeaterId)) nextRepeaters.delete(repeaterId)\n\t\t}\n\t\tthis.repeatersShowingEmptyState = nextRepeaters\n\t\tthis.recomputeGroundNodesWithEmptyStates()\n\t}\n}\n", "import type { EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport type {\n\tCanvasNode,\n\tCodeComponentNode,\n\tFrameNode,\n\tSVGNode,\n\tShapeContainerNode,\n\tTextNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { Tools } from \"./ToolStore.ts\"\n\n/**\n * Manages the visibility of the outlines around the current highlighted node or the\n * bounding box around a collection of selected nodes. Visibility is determined by\n * the property on the CanvasNode being changed, external modules can also override\n * hiding the selection by calling forceEnableSelectionOutline().\n */\nexport class SelectionOutlineTracker {\n\t/**\n\t * Track whether we want to display the outline around the current selection when\n\t * using the Highlight or Selection tool. This will always be false unless the\n\t * user has interacted directly with the canvas.\n\t */\n\tprivate shouldDisableSelectionOutlineUntil: number | null = null\n\n\tprivate shouldIgnoreAfterCommit = false\n\n\tprivate disableSelectionOutlineTimerId: number | undefined\n\n\t/** Duration until we reset the selection outline */\n\tprivate disableSelectionOutlineDuration = 2 * 1000\n\n\tprivate previouslySelectedNodes: CanvasNode[] = []\n\n\tconstructor(\n\t\tprivate addChanges: EngineChangeSignal,\n\t\tprivate wrapHandler: (fn: Function) => Function,\n\t) {}\n\n\tafterCommit(selectedNodes: CanvasNode[], tool: Tools) {\n\t\t// Do nothing if forceEnableSelectionOutline() has been called.\n\t\tif (this.shouldIgnoreAfterCommit) {\n\t\t\tthis.shouldIgnoreAfterCommit = false\n\t\t\tthis.previouslySelectedNodes = selectedNodes\n\t\t\treturn\n\t\t}\n\n\t\tif (selectedNodes !== this.previouslySelectedNodes) {\n\t\t\tif (shouldDisableSelectionOutlineAfterChange(this.previouslySelectedNodes, selectedNodes, tool)) {\n\t\t\t\tthis.addChanges(EngineChange.SelectionOutline)\n\n\t\t\t\tconst expires = this.disableSelectionOutlineDuration\n\t\t\t\tthis.queueSelectionOutlineTimer(expires)\n\t\t\t}\n\n\t\t\tthis.previouslySelectedNodes = selectedNodes\n\t\t}\n\n\t\tif (this.shouldDisableSelectionOutlineUntil && this.shouldDisableSelectionOutlineUntil <= Date.now()) {\n\t\t\tthis.clearSelectionOutlineTimer()\n\t\t\tthis.addChanges(EngineChange.SelectionOutline)\n\t\t}\n\t}\n\n\t/**\n\t * Used to enforce the display of the outline on selections, for example when the mouse is moving\n\t * within the canvas.\n\t */\n\tforceEnableSelectionOutline = () => {\n\t\tthis.clearSelectionOutlineTimer()\n\t\tthis.shouldIgnoreAfterCommit = true\n\t}\n\n\t/** Returns true if the the ToolManager should render an outline around the current selection */\n\tshouldShowSelectionOutlineForTool(tool: Tools) {\n\t\treturn this.shouldDisableSelectionOutlineUntil === null && !ToolsHidingSelectionOutline.has(tool)\n\t}\n\n\tprivate clearSelectionOutlineTimer() {\n\t\tif (!this.shouldDisableSelectionOutlineUntil) return\n\n\t\tthis.shouldDisableSelectionOutlineUntil = null\n\t\tclearTimeout(this.disableSelectionOutlineTimerId)\n\t\tthis.addChanges(EngineChange.SelectionOutline)\n\t}\n\n\tprivate queueSelectionOutlineTimer = (timeout: number) => {\n\t\tthis.clearSelectionOutlineTimer()\n\n\t\tthis.shouldDisableSelectionOutlineUntil = timeout + Date.now()\n\t\tthis.disableSelectionOutlineTimerId = window.setTimeout(\n\t\t\tthis.wrapHandler(() => {\n\t\t\t\tthis.clearSelectionOutlineTimer()\n\t\t\t\tthis.addChanges(EngineChange.SelectionOutline)\n\t\t\t}),\n\t\t\ttimeout,\n\t\t)\n\t}\n}\n\nconst ToolsHidingSelectionOutline = new Set([Tools.Pan, Tools.SampleColor])\n\n/** Properties of top level CanvasNode types. */\ntype CanvasNodeProps = keyof (CanvasNode & FrameNode & ShapeContainerNode & SVGNode & TextNode<any> & CodeComponentNode)\n\n/** Properties that will not affect rendering when changed. */\nconst CanvasNodeInteralPropsArray: CanvasNodeProps[] = [\n\t\"children\",\n\t\"name\",\n\t\"cache\",\n\t\"mutable\",\n\t\"update\",\n\t\"styledText\",\n\t\"parentid\",\n]\nconst CanvasNodeInteralProps = new Set(CanvasNodeInteralPropsArray)\n\n/**\n * Properties that will affect rendering but should not hide the selection outline.\n * These are usually properties that affect the dimensions of the rect itself.\n * NOTE: Width and height are included here but this should also include top/left/bottom/right\n * in situations where the width/height are adjusted and constraints are active.\n */\nconst CanvasNodePropsForcingSelectionOutlineArray: CanvasNodeProps[] = [\"widthType\", \"width\", \"height\", \"autoSize\"]\nconst CanvasNodePropsForcingSelectionOutline = new Set(CanvasNodePropsForcingSelectionOutlineArray)\n\n/**\n * Diffs the changes to the nodes in the current selection and returns true if the change should\n * hide the selection outline.\n */\nfunction shouldDisableSelectionOutlineAfterChange(\n\tprevSelection: CanvasNode[],\n\tnextSelection: CanvasNode[],\n\ttool: Tools,\n) {\n\tif (prevSelection === nextSelection) {\n\t\treturn false\n\t}\n\n\t// When scale does an update, like with pulling handles or scrubbing, we want to hide the outline.\n\t// When we do want to keep the outline, the tool or panel will call `forceEnableSelectionOutline()`.\n\tif (tool === Tools.Scale) {\n\t\treturn true\n\t}\n\n\tconst prevNodeById: { [id: string]: CanvasNode } = {}\n\tprevSelection.forEach(node => (prevNodeById[node.id] = node))\n\n\tfor (const node of nextSelection) {\n\t\tconst prev = prevNodeById[node.id]\n\t\tif (node === prev || !node || !prev) continue\n\n\t\tfor (const prop of node.keys() as CanvasNodeProps[]) {\n\t\t\tif (node[prop] === prev[prop] || CanvasNodeInteralProps.has(prop)) continue\n\n\t\t\t// Exit early as soon as we hit a prop that should disable the display of the selection.\n\t\t\tif (doesPropDisableSelectionOutline(prop)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false\n}\n\n/** Returns true if the prop should hide the selection outline when changed */\nfunction doesPropDisableSelectionOutline(prop: CanvasNodeProps) {\n\treturn !CanvasNodeInteralProps.has(prop) && !CanvasNodePropsForcingSelectionOutline.has(prop)\n}\n", "import type { Space } from \"./Space.ts\"\n\nexport interface User {\n\tid: string\n\n\t// Note: In reality this field is string | null but Services library doesn't support it.\n\t// TODO: This can be changed to use Nullable support in Services runtime.\n\tavatar?: string\n\tinitials: string\n\tname: string\n\t// TODO: This can most likely be changed to not be optional (should be confirmed with API).\n\tisFramerEmployee?: boolean\n\tisFramerExpert?: boolean\n\tisPartner?: boolean\n}\ninterface OrganizationPermissions {\n\tcanCreateTeamInOrg: string\n}\n\nexport interface CurrentUser extends User {\n\tachievements: Record<string, boolean>\n\tdefaultSpaceId: string\n\n\temail: string\n\tisOnLatestTerms: boolean\n\tspaces: Space[]\n\n\torganizationPermissions: OrganizationPermissions | null\n\n\tintercomUserHash: string\n\tcompanySize?: number\n}\n\nexport function createMockUser(): CurrentUser {\n\treturn {\n\t\tid: \"FAKE_TEST_USER_ID\",\n\t\tinitials: \"FAKE\",\n\t\tname: \"Fake Test User\",\n\t\tachievements: {},\n\t\tdefaultSpaceId: \"FAKE_TEST_SPACE_ID\",\n\t\temail: \"fake.test.user@example.com\",\n\t\tisOnLatestTerms: true,\n\t\tspaces: [],\n\t\torganizationPermissions: null,\n\t\tintercomUserHash: \"FAKE_TEST_USER_HASH\",\n\t}\n}\n\nexport interface UserEnrichmentInfo {\n\tcompanySize: number\n}\n", "import type { CurrentUser, WindowWithCurrentUser } from \"@framerjs/app-shared\"\nimport { createMockUser } from \"@framerjs/app-shared/src/User.ts\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport { environment } from \"environment/index.ts\"\n\nexport class SessionStore extends EngineStore {\n\tuser: CurrentUser\n\n\tconstructor() {\n\t\tsuper()\n\n\t\tconst user = (window as WindowWithCurrentUser).framerUser\n\t\tif (user) {\n\t\t\tthis.user = user\n\t\t} else if (environment.isAutomation || environment.isTest) {\n\t\t\tthis.user = createMockUser()\n\t\t} else {\n\t\t\tthrow Error(\"Can\u2019t find user\")\n\t\t}\n\t}\n}\n", "import hash from \"@emotion/hash\"\nimport type { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport { DebouncedTask, getLogger, unhandledError } from \"@framerjs/shared\"\nimport type { Remote } from \"comlink\"\nimport { transfer, wrap } from \"comlink\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { NodeChangesReader } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { CanvasTree, NodeID } from \"document/models/CanvasTree/index.ts\"\nimport {\n\tisColorStyleTokenListNode,\n\tisColorStyleTokenNode,\n\tisShaderNode,\n} from \"document/models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { iterateShaderUniforms } from \"document/models/CanvasTree/nodes/utils/shaderUniforms.ts\"\nimport { createAssetReferenceForUploadImageResult } from \"document/utils/createAssetReferenceFromImageUpload.ts\"\nimport type {\n\tBufferDescriptor,\n\tUniformName,\n\tUniformValue,\n} from \"library/render/presentation/Shader/WebGL2ShaderRenderer.ts\"\nimport { closeImageBitmaps, resolveUniforms } from \"library/render/presentation/Shader/helpers.ts\"\nimport type { ShaderUniformInput } from \"library/render/presentation/Shader/types.ts\"\nimport { resolveShaderTokenColors } from \"renderer/ShaderNodeRenderer.tsx\"\nimport { getAssetResolverWithHash } from \"renderer/getAssetResolver.ts\"\nimport { absoluteEditorPath } from \"utils/platformPaths.ts\"\nimport { uploadService } from \"web/pages/project/lib/UploadService.ts\"\nimport type { ModulesStore } from \"./ModulesStore.ts\"\nimport type { TreeStore } from \"./TreeStore.ts\"\n\nconst log = getLogger(\"ShaderFallbackImageStore\")\nconst maxGenerationAttempts = 3\nconst maxSyncPasses = 3\n\n// Imported from worker - not an unused export\nexport interface CreateFallbackImageRequest {\n\thash: string\n\twidth: number\n\theight: number\n\tvertexShader?: string\n\tfragmentShader: string\n\tuniforms?: Record<UniformName, UniformValue>\n\tbuffers?: readonly BufferDescriptor[]\n}\n\n// Imported from worker - not an unused export\nexport interface CreateFallbackImageResponse {\n\tblob: Blob\n\tmimeType: \"image/png\"\n\twidth: number\n\theight: number\n}\n\ninterface ShaderWorkerApi {\n\tcreateFallbackImage(request: CreateFallbackImageRequest): Promise<CreateFallbackImageResponse>\n}\n\ninterface ShaderHashInput {\n\twidth: number\n\theight: number\n\tidentifier: string\n\tcontrols: unknown\n\tfragmentShader: string\n\tvertexShader?: string\n\tbuffers?: readonly BufferDescriptor[]\n}\n\nlet shaderWorker: Remote<ShaderWorkerApi>\nfunction getShaderWorker(): Remote<ShaderWorkerApi> {\n\tif (!shaderWorker) {\n\t\tshaderWorker = wrap(new Worker(absoluteEditorPath(\"./shader-worker.js\")))\n\t}\n\treturn shaderWorker\n}\n\n/**\n * Generates static PNG fallback images for shader nodes so published sites\n * can show a fallback image until the shader is loaded, or the canvas sandbox\n * a still image when the node is unselected.\n *\n * Two triggers queue nodes for generation:\n * 1. **Node property changes** \u2014 detected via `postProcess()` which reads a\n *    `NodeChangesReader` after every tree commit and queues changed shader nodes.\n * 2. **Shader source changes** \u2014 detected via a `ModulesStorage` subscription\n *    that hashes each shader definition and queues all nodes whose definition changed.\n *\n * Both paths feed into a debounced queue. When the debounce fires, `processQueue()`\n * kicks off `generateFallbackImage()` for each pending node:\n * hash-check \u2192 render via Web Worker (OffscreenCanvas) \u2192 upload \u2192 write to tree.\n *\n * The tree write uses `scheduleDocumentUpdateIgnoringUndo` so fallback images\n * stay off the undo stack. An in-flight map prevents concurrent generation for\n * the same node, and a dimension guard at write time discards results rendered\n * against a stale `canvasRect` (e.g. during publish tree transitions).\n */\nexport class ShaderFallbackImageStore extends EngineStore {\n\t#nodeChangesReader: NodeChangesReader | undefined\n\t#debounce = new DebouncedTask({\n\t\tdelay: 1_000,\n\t\tmaxDelay: 5_000,\n\t\ttask: () => this.processQueue(undefined, true),\n\t})\n\t#pendingNodes = new Set<NodeID>()\n\t#inFlight = new Map<NodeID, string>()\n\t/** List of fallback-image jobs that are currently running */\n\t#inFlightPromises = new Map<NodeID, Promise<void>>()\n\t/** Tracks shader definition hashes so we only queue nodes when the shader source actually changes. */\n\t#knownDefinitionHashes = new Map<string, string>()\n\t/** In-memory failure counts to avoid infinite retry loops for persistently failing shaders. */\n\t#failureCountsByNodeId = new Map<NodeID, number>()\n\n\tconstructor(\n\t\tprivate readonly componentLoader: ComponentLoader,\n\t\tprivate readonly treeStore: TreeStore,\n\t\tprivate readonly modulesStore: ModulesStore,\n\t\tprivate readonly scheduleDocumentUpdateIgnoringUndo: <T>(\n\t\t\ttask: (latestTree: CanvasTree) => T,\n\t\t) => Promise<T | undefined>,\n\t) {\n\t\tsuper()\n\t\tthis.#nodeChangesReader = this.treeStore.timeline.openNodeChangesReader()\n\n\t\tthis.modulesStore.subscribeToModulesStorage(() => {\n\t\t\tthis.queueAllShaderNodes()\n\t\t})\n\t}\n\n\t/** Lifecycle: resets all queues and caches when a new document is loaded. */\n\tdocumentDidLoad() {\n\t\tthis.#pendingNodes.clear()\n\t\tthis.#inFlight.clear()\n\t\tthis.#inFlightPromises.clear()\n\t\tthis.#nodeChangesReader?.clear()\n\t\tthis.#knownDefinitionHashes.clear()\n\t\tthis.#failureCountsByNodeId.clear()\n\t}\n\n\t/**\n\t * Force shader fallback generation to finish before publishing.\n\t * This bypasses debounce delays and waits until there are no stale fallback images.\n\t */\n\tasync ensureFallbackImagesUpToDate(): Promise<Set<NodeID>> {\n\t\tconst startTime = performance.now()\n\t\tconst updatedScopeNodeIds = new Set<NodeID>()\n\t\tlog.info(\"Publish time - ensuring shader fallback images are up to date\")\n\n\t\t// Keep flushing until there is nothing queued/in-flight and all shader nodes\n\t\t// have up-to-date fallback hashes.\n\t\tfor (let pass = 1; pass <= maxSyncPasses; pass++) {\n\t\t\tlog.trace(\"Shader fallback sync pass\", `pass=${pass}`)\n\t\t\tthis.queueAllStaleShaderNodes()\n\t\t\tconst queuedCount = this.#pendingNodes.size\n\t\t\tthis.processQueue(updatedScopeNodeIds, false)\n\n\t\t\tif (this.#pendingNodes.size === 0 && this.#inFlightPromises.size === 0) {\n\t\t\t\tconst exhaustedNodeIds = this.getExhaustedNodeIds()\n\t\t\t\tif (exhaustedNodeIds.length > 0) {\n\t\t\t\t\tconst exhausted = exhaustedNodeIds.join(\",\")\n\t\t\t\t\tlog.warn(\"Shader fallback generation exhausted retries\", `nodes=${exhausted}`)\n\t\t\t\t\tthrow new Error(`Shader fallback image generation exhausted retries for nodes: ${exhausted}`)\n\t\t\t\t}\n\n\t\t\t\tlog.trace(\n\t\t\t\t\t\"Shader fallback image sync completed\",\n\t\t\t\t\t`passes=${pass}`,\n\t\t\t\t\t`initialQueued=${queuedCount}`,\n\t\t\t\t\t`updatedScopes=${updatedScopeNodeIds.size}`,\n\t\t\t\t\t`durationMs=${Math.round(performance.now() - startTime)}`,\n\t\t\t\t)\n\t\t\t\treturn updatedScopeNodeIds\n\t\t\t}\n\n\t\t\tconst inFlight = [...this.#inFlightPromises.values()]\n\t\t\tif (inFlight.length === 0) continue\n\n\t\t\tconst results = await Promise.allSettled(inFlight)\n\t\t\tconst rejected = results.find(result => result.status === \"rejected\")\n\t\t\tif (rejected?.status === \"rejected\") {\n\t\t\t\tlog.warn(\"Shader fallback image generation failed\", rejected.reason)\n\t\t\t\tthrow rejected.reason\n\t\t\t}\n\t\t}\n\n\t\tlog.warn(\n\t\t\t\"Shader fallback image sync timed out\",\n\t\t\t`passes=${maxSyncPasses}`,\n\t\t\t`pending=${this.#pendingNodes.size}`,\n\t\t\t`inFlight=${this.#inFlightPromises.size}`,\n\t\t\t`updatedScopes=${updatedScopeNodeIds.size}`,\n\t\t\t`durationMs=${Math.round(performance.now() - startTime)}`,\n\t\t)\n\t\tthrow new Error(\"Shader fallback image generation timed out before publish\")\n\t}\n\n\t/** Lifecycle: Called after tree commits: queues shader nodes for generation. */\n\tpostProcess(tree: CanvasTree, remote: boolean) {\n\t\tif (tree.isViewOnly) return\n\n\t\tconst reader = this.#nodeChangesReader\n\t\tif (!reader) return\n\n\t\tif (remote) {\n\t\t\treader.clear()\n\t\t\treturn\n\t\t}\n\n\t\tthis.ingestChanges(tree)\n\t}\n\n\t/** Reads pending node changes and adds any shader nodes to the generation queue. */\n\tprivate ingestChanges(tree: CanvasTree) {\n\t\tif (!this.#nodeChangesReader) return\n\n\t\tlet shouldDebounce = false\n\t\tfor (const [id] of this.#nodeChangesReader.read()) {\n\t\t\tconst node = tree.get(id)\n\t\t\tif (!node) continue\n\n\t\t\tif (isShaderNode(node) && node.shaderModuleIdentifier) {\n\t\t\t\tshouldDebounce = this.queueNodeForGeneration(id) || shouldDebounce\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// When a color token changes, all shader nodes that reference it may\n\t\t\t// need their fallback regenerated. Queue every shader node since we\n\t\t\t// don't track which shaders reference which tokens.\n\t\t\tif (isColorStyleTokenNode(node) || isColorStyleTokenListNode(node)) {\n\t\t\t\tfor (const shaderNode of this.treeStore.getPartialIndexes().shaderNodes) {\n\t\t\t\t\tif (shaderNode.shaderModuleIdentifier) {\n\t\t\t\t\t\tshouldDebounce = this.queueNodeForGeneration(shaderNode.id) || shouldDebounce\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// When a non-shader ancestor changes (e.g. frame resized via properties\n\t\t\t// panel), shader descendants with relative sizing need regeneration even\n\t\t\t// though their own properties didn't change.\n\t\t\ttry {\n\t\t\t\tfor (const descendant of node.descendants()) {\n\t\t\t\t\tif (isShaderNode(descendant) && descendant.shaderModuleIdentifier) {\n\t\t\t\t\t\tshouldDebounce = this.queueNodeForGeneration(descendant.id) || shouldDebounce\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Tree may be partially loaded (shallow scopes during publish).\n\t\t\t}\n\t\t}\n\n\t\tif (shouldDebounce) {\n\t\t\tthis.#debounce.debounce()\n\t\t}\n\t}\n\n\t/** Queues all shader nodes whose definition changed since last check. */\n\tprivate queueAllShaderNodes() {\n\t\tif (this.treeStore.tree.isViewOnly) return\n\n\t\tconst nodesByIdentifier = new Map<string, NodeID[]>()\n\n\t\tfor (const node of this.treeStore.getPartialIndexes().shaderNodes) {\n\t\t\tconst { shaderModuleIdentifier } = node\n\t\t\tif (!shaderModuleIdentifier) continue\n\t\t\tlet ids = nodesByIdentifier.get(shaderModuleIdentifier)\n\t\t\tif (!ids) {\n\t\t\t\tids = []\n\t\t\t\tnodesByIdentifier.set(shaderModuleIdentifier, ids)\n\t\t\t}\n\t\t\tids.push(node.id)\n\t\t}\n\n\t\tlet found = false\n\t\tfor (const [identifier, nodeIds] of nodesByIdentifier) {\n\t\t\tconst definition = this.componentLoader.shaderForIdentifier(identifier)\n\t\t\tif (!definition) continue\n\n\t\t\t// Skip if the shader source hasn't changed since last check.\n\t\t\tconst { fragment, vertex, properties, buffers } = definition\n\t\t\tconst defHash = hash(JSON.stringify([fragment, vertex, properties, buffers]))\n\t\t\tif (this.#knownDefinitionHashes.get(identifier) === defHash) continue\n\t\t\tthis.#knownDefinitionHashes.set(identifier, defHash)\n\n\t\t\tfor (const nodeId of nodeIds) {\n\t\t\t\tfound = this.queueNodeForGeneration(nodeId) || found\n\t\t\t}\n\t\t}\n\n\t\tif (found) {\n\t\t\tthis.#debounce.debounce()\n\t\t}\n\t}\n\n\tprivate queueAllStaleShaderNodes() {\n\t\tconst tree = this.treeStore.tree\n\t\tfor (const node of this.treeStore.getPartialIndexes().shaderNodes) {\n\t\t\tconst identifier = node.shaderModuleIdentifier\n\t\t\tif (!identifier) continue\n\n\t\t\tconst definition = this.componentLoader.shaderForIdentifier(identifier)\n\t\t\tif (!definition) continue\n\n\t\t\tconst desiredHash = this.computeDesiredHash(tree, node.id, identifier, definition)\n\t\t\tif (!desiredHash) continue\n\n\t\t\tif (node.shaderFallbackImageHash !== desiredHash || !node.shaderFallbackImage) {\n\t\t\t\tthis.queueNodeForGeneration(node.id)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate queueNodeForGeneration(nodeId: NodeID): boolean {\n\t\tconst failures = this.#failureCountsByNodeId.get(nodeId) ?? 0\n\t\tif (failures >= maxGenerationAttempts) return false\n\t\tthis.#pendingNodes.add(nodeId)\n\t\treturn true\n\t}\n\n\tprivate getExhaustedNodeIds(): NodeID[] {\n\t\tconst exhaustedNodeIds: NodeID[] = []\n\t\tfor (const [nodeId, failures] of this.#failureCountsByNodeId) {\n\t\t\tif (failures >= maxGenerationAttempts) exhaustedNodeIds.push(nodeId)\n\t\t}\n\t\treturn exhaustedNodeIds\n\t}\n\n\t/** Drains the pending set, skipping nodes already in-flight, and fires off generation. */\n\tprivate processQueue(updatedScopeNodeIds?: Set<NodeID>, catchErrors = true) {\n\t\tconst nodes = new Set(this.#pendingNodes)\n\t\tthis.#pendingNodes.clear()\n\n\t\tlet requeued = false\n\t\tfor (const nodeId of nodes) {\n\t\t\tif (!this.queueNodeForGeneration(nodeId)) continue\n\t\t\tthis.#pendingNodes.delete(nodeId)\n\n\t\t\tif (this.#inFlight.has(nodeId)) {\n\t\t\t\t// Re-queue so updated state is processed after the in-flight generation completes.\n\t\t\t\trequeued = this.queueNodeForGeneration(nodeId) || requeued\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst inFlightPromise = this.generateFallbackImage(nodeId, updatedScopeNodeIds)\n\t\t\tthis.#inFlightPromises.set(nodeId, inFlightPromise)\n\t\t\tconst cleanupInFlightPromise = () => {\n\t\t\t\tif (this.#inFlightPromises.get(nodeId) === inFlightPromise) {\n\t\t\t\t\tthis.#inFlightPromises.delete(nodeId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (catchErrors) {\n\t\t\t\tvoid inFlightPromise.catch(unhandledError).finally(cleanupInFlightPromise)\n\t\t\t} else {\n\t\t\t\tvoid inFlightPromise.then(cleanupInFlightPromise, cleanupInFlightPromise)\n\t\t\t}\n\t\t}\n\n\t\tif (requeued) {\n\t\t\tthis.#debounce.debounce()\n\t\t}\n\t}\n\n\tprivate computeDesiredHash(\n\t\ttree: CanvasTree,\n\t\tnodeId: NodeID,\n\t\tidentifier: string,\n\t\tdefinition: NonNullable<ReturnType<ComponentLoader[\"shaderForIdentifier\"]>>,\n\t): string | undefined {\n\t\tconst node = tree.get(nodeId)\n\t\tif (!node || !isShaderNode(node)) return undefined\n\n\t\tconst canvasRect = node.cache.canvasRect\n\t\tif (!canvasRect || !canvasRect.width || !canvasRect.height) return undefined\n\n\t\tconst propertyControls = definition.properties ?? {}\n\t\tconst rawResolvedControlProps = node.getResolvedControlPropValues(this.componentLoader, getAssetResolverWithHash())\n\t\tconst resolvedControlProps = resolveShaderTokenColors(rawResolvedControlProps, propertyControls, tree, false)\n\n\t\treturn this.hashFallbackImageInputs({\n\t\t\twidth: canvasRect.width,\n\t\t\theight: canvasRect.height,\n\t\t\tidentifier,\n\t\t\tcontrols: resolvedControlProps,\n\t\t\tfragmentShader: definition.fragment,\n\t\t\tvertexShader: definition.vertex,\n\t\t\tbuffers: definition.buffers,\n\t\t})\n\t}\n\n\tprivate hashFallbackImageInputs(hashInput: ShaderHashInput): string {\n\t\treturn hash(JSON.stringify(hashInput))\n\t}\n\n\t/** Renders a shader to an image blob via Web Worker (shader worker), uploads it, and writes the asset to the tree. */\n\tprivate async generateFallbackImage(nodeId: NodeID, updatedScopeNodeIds?: Set<NodeID>): Promise<void> {\n\t\tconst tree = this.treeStore.tree\n\t\tconst node = tree.get(nodeId)\n\t\tif (!node || !isShaderNode(node)) return\n\n\t\tconst identifier = node.shaderModuleIdentifier\n\t\tif (!identifier) return\n\n\t\tconst canvasRect = node.cache.canvasRect\n\t\tif (!canvasRect) return\n\n\t\tconst { width, height } = canvasRect\n\t\tif (!width || !height) return\n\n\t\tconst definition = this.componentLoader.shaderForIdentifier(identifier)\n\t\tif (!definition) {\n\t\t\tlog.trace(\"Could not find shader definition for\", identifier)\n\t\t\treturn\n\t\t}\n\t\tconst propertyControls = definition.properties ?? {}\n\t\tconst { fragment: fragmentShader, vertex: vertexShader, heightmapSource, buffers } = definition\n\n\t\tconst rawResolvedControlProps = node.getResolvedControlPropValues(this.componentLoader, getAssetResolverWithHash())\n\t\tconst resolvedControlProps = resolveShaderTokenColors(rawResolvedControlProps, propertyControls, tree, false)\n\n\t\tconst desiredHash = this.hashFallbackImageInputs({\n\t\t\twidth,\n\t\t\theight,\n\t\t\tidentifier,\n\t\t\tcontrols: resolvedControlProps,\n\t\t\tfragmentShader,\n\t\t\tvertexShader,\n\t\t\tbuffers,\n\t\t})\n\n\t\tif (node.shaderFallbackImageHash === desiredHash) return\n\n\t\tthis.#inFlight.set(nodeId, desiredHash)\n\n\t\tlet uniforms: Record<UniformName, UniformValue> | undefined\n\t\ttry {\n\t\t\tlet highLevelUniforms: Record<UniformName, ShaderUniformInput> | undefined\n\t\t\tfor (const { name, uniform } of iterateShaderUniforms(propertyControls, resolvedControlProps)) {\n\t\t\t\tif (!highLevelUniforms) highLevelUniforms = {}\n\t\t\t\thighLevelUniforms[name] = uniform\n\t\t\t}\n\n\t\t\tuniforms = highLevelUniforms ? await resolveUniforms(highLevelUniforms, undefined, heightmapSource) : undefined\n\n\t\t\tlog.trace(\"Generating fallback image for\", nodeId, \"hash:\", desiredHash)\n\n\t\t\tconst genStart = performance.now()\n\t\t\tconst worker = getShaderWorker()\n\n\t\t\t// Convert non-transferable image sources (e.g. HTMLImageElement) to\n\t\t\t// ImageBitmaps for the worker. Web Workers can't access DOM elements,\n\t\t\t// and comlink requires Transferable objects to send image data.\n\t\t\tconst transferables: Transferable[] = []\n\t\t\tif (uniforms) {\n\t\t\t\tfor (const uniform of Object.values(uniforms)) {\n\t\t\t\t\tif (uniform.type === \"sampler2D\" && !(uniform.value instanceof ImageBitmap)) {\n\t\t\t\t\t\tconst bitmap = await createImageBitmap(uniform.value)\n\t\t\t\t\t\tuniform.value = bitmap\n\t\t\t\t\t\ttransferables.push(bitmap)\n\t\t\t\t\t} else if (uniform.type === \"sampler2D\" && uniform.value instanceof ImageBitmap) {\n\t\t\t\t\t\ttransferables.push(uniform.value)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst request: CreateFallbackImageRequest = {\n\t\t\t\thash: desiredHash,\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tfragmentShader,\n\t\t\t\tvertexShader,\n\t\t\t\tuniforms,\n\t\t\t\tbuffers,\n\t\t\t}\n\t\t\tconst result = await worker.createFallbackImage(transfer(request, transferables))\n\t\t\tconst generateDuration = Math.round(performance.now() - genStart)\n\n\t\t\tconst file = new File([result.blob], `shader-fallback-${nodeId}.png`, { type: \"image/png\" })\n\n\t\t\tconst uploadStart = performance.now()\n\t\t\tconst uploadResult = await uploadService.uploadImage(file, { silent: true })\n\t\t\tconst uploadDuration = Math.round(performance.now() - uploadStart)\n\t\t\tif (!uploadResult) {\n\t\t\t\tthrow new Error(`Upload failed for shader fallback image ${nodeId}`)\n\t\t\t}\n\n\t\t\tconst assetReference = createAssetReferenceForUploadImageResult(uploadResult)\n\n\t\t\tconst persistStart = performance.now()\n\t\t\tconst persistResult = await this.scheduleDocumentUpdateIgnoringUndo(latestTree => {\n\t\t\t\tconst latestNode = latestTree.get(nodeId)\n\t\t\t\tif (!latestNode || !isShaderNode(latestNode)) return\n\n\t\t\t\t// If dimensions changed since generation started (e.g. stale canvasRect\n\t\t\t\t// during publish tree transitions), discard the result.\n\t\t\t\tconst currentRect = latestNode.cache.canvasRect\n\t\t\t\tif (currentRect && (currentRect.width !== width || currentRect.height !== height)) return\n\n\t\t\t\tlatestNode.set({\n\t\t\t\t\tshaderFallbackImage: assetReference,\n\t\t\t\t\tshaderFallbackImageHash: desiredHash,\n\t\t\t\t})\n\t\t\t\tconst persistDuration = Math.round(performance.now() - persistStart)\n\n\t\t\t\tlog.trace(\n\t\t\t\t\t`Fallback generated for ${nodeId} (${result.width}\u00D7${result.height}). Capture: ${generateDuration}ms; Upload: ${uploadDuration}ms; Write: ${persistDuration}ms`,\n\t\t\t\t)\n\n\t\t\t\treturn {\n\t\t\t\t\twrote: true,\n\t\t\t\t\tscopeNodeId: latestTree.getScopeNodeFor(latestNode)?.id,\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tif (persistResult?.wrote) {\n\t\t\t\tthis.#failureCountsByNodeId.delete(nodeId)\n\t\t\t\tif (persistResult.scopeNodeId) {\n\t\t\t\t\tupdatedScopeNodeIds?.add(persistResult.scopeNodeId)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.queueNodeForGeneration(nodeId)\n\t\t\t\tthis.#debounce.debounce()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst failures = (this.#failureCountsByNodeId.get(nodeId) ?? 0) + 1\n\t\t\tthis.#failureCountsByNodeId.set(nodeId, failures)\n\n\t\t\t// If fallback image generation failed, no fallback image is better than a wrong one.\n\t\t\tawait this.scheduleDocumentUpdateIgnoringUndo(latestTree => {\n\t\t\t\tconst latestNode = latestTree.get(nodeId)\n\t\t\t\tif (!latestNode || !isShaderNode(latestNode)) return\n\t\t\t\tif (latestNode.shaderFallbackImageHash === desiredHash) return\n\n\t\t\t\tlatestNode.set({\n\t\t\t\t\tshaderFallbackImage: undefined,\n\t\t\t\t\tshaderFallbackImageHash: undefined,\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tif (failures === maxGenerationAttempts) {\n\t\t\t\tconst message = `Failed to generate shader fallback image after ${maxGenerationAttempts} attempts`\n\t\t\t\tlog.warn(message)\n\t\t\t\tlog.reportError(error, { context: message })\n\t\t\t}\n\n\t\t\tlog.warn(\"Failed to generate shader fallback image for\", nodeId, error)\n\t\t\tthrow error\n\t\t} finally {\n\t\t\tif (uniforms) closeImageBitmaps(uniforms)\n\t\t\tif (this.#inFlight.get(nodeId) === desiredHash) {\n\t\t\t\tthis.#inFlight.delete(nodeId)\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { EngineStore } from \"document/EngineStore.ts\"\n\nconst emptySnapLines = new Set<number>()\n\nexport class SnapLinesStore extends EngineStore {\n\tx = emptySnapLines\n\ty = emptySnapLines\n\n\tclear() {\n\t\tthis.x = emptySnapLines\n\t\tthis.y = emptySnapLines\n\t}\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { EngineChangeSignal } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport { type BaseUndoRedoEntry, BaseUndoRedoManager } from \"document/base-engine/BaseUndoRedoManager.ts\"\nimport type { ReversibleNodeChange } from \"document/models/CanvasTree/TreeDiff.ts\"\nimport { collapseChanges } from \"document/models/CanvasTree/TreeDiff.ts\"\nimport { isOverrideId, parseOverrideId } from \"document/models/CanvasTree/TreeDiffOverrides.ts\"\nimport type { TreeUpdater } from \"document/models/CanvasTree/TreeUpdater.ts\"\nimport type { CanvasNode, CanvasTree, NodeID, VectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { isVectorNode } from \"document/models/CanvasTree/index.ts\"\nimport { TemplateHelper, generateReplicaChildId } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport type { LocaleId } from \"document/models/CanvasTree/traits/WithLocales.ts\"\nimport type { IsReplica } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isMaster, isReplica } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport type { Selection } from \"./SelectionStore.ts\"\n\ninterface UndoRedoEntryMetadata {\n\tselection: Selection\n\tscopeId: NodeID\n\tlocaleId?: LocaleId\n\tselectedGradientStopId?: NodeID\n}\n\nexport interface TreeEditUndoEntry extends BaseUndoRedoEntry, UndoRedoEntryMetadata {\n\tkind: \"treeEdit\"\n}\n\nexport interface BranchSwitchUndoEntry extends BaseUndoRedoEntry, UndoRedoEntryMetadata {\n\tkind: \"branchSwitch\"\n\tchanges: []\n\tfromBranchId: string\n\ttoBranchId: string\n}\n\nexport type UndoRedoEntry = TreeEditUndoEntry | BranchSwitchUndoEntry\n\nexport class UndoRedoManager extends BaseUndoRedoManager<UndoRedoEntry> {\n\tconstructor(private readonly addChanges: EngineChangeSignal) {\n\t\tsuper()\n\t}\n\n\tremoveEntriesForNode(nodeId: NodeID) {\n\t\tconst includesNode = (entry: UndoRedoEntry) => entry.changes.some(changeIncludesNode(nodeId))\n\t\tconst undoGroup = this.undoGroup.map(index => countEntriesBeforeIndex(this.undoBuffer, index, includesNode))\n\t\tconst scheduledEndUndoGroup =\n\t\t\tthis.scheduledEndUndoGroup === undefined\n\t\t\t\t? undefined\n\t\t\t\t: countEntriesBeforeIndex(this.undoBuffer, this.scheduledEndUndoGroup, includesNode)\n\n\t\tconst undoEntriesRemoved = removeMatchingEntries(this.undoBuffer, includesNode)\n\t\tconst redoEntriesRemoved = removeMatchingEntries(this.redoBuffer, includesNode)\n\t\tif (undoEntriesRemoved === 0 && redoEntriesRemoved === 0) return\n\n\t\tthis.undoGroup.length = 0\n\t\tthis.undoGroup.push(...undoGroup)\n\t\tthis.scheduledEndUndoGroup = scheduledEndUndoGroup\n\t\tthis.addChanges(EngineChange.TreeStore)\n\t}\n\n\toverride beginUndoGroup() {\n\t\tsuper.beginUndoGroup()\n\t\tthis.addChanges(EngineChange.TreeStore)\n\t}\n\n\toverride clearUndoStack() {\n\t\tsuper.clearUndoStack()\n\t\tthis.addChanges(EngineChange.TreeStore)\n\t}\n\n\tresetTreeWithToken(updater: TreeUpdater, token: number) {\n\t\tif (token >= this.undoBuffer.length) return\n\n\t\tconst tree = updater.tree\n\n\t\tconst edits = this.undoBuffer.splice(token)\n\t\tconst firstEdit = edits[0]\n\t\tassert(firstEdit?.kind === \"treeEdit\", \"Tree edit must be defined\")\n\t\tconst changes = collapseChanges(edits)\n\t\tthis.undoBuffer.push({ ...firstEdit, changes })\n\n\t\tupdater.applyReverseChanges(changes)\n\n\t\tconst updatedVectors = getChangedReplicaShapes(tree, changes)\n\t\tfor (const vectorNode of updatedVectors) {\n\t\t\t// We apply `override/` changes directly to the replica, which means the updated\n\t\t\t// descendants aren't necessarily marked as drafts. We need to explicitly clear their\n\t\t\t// render cache so that the move tool doesn't work with outdated boxes.\n\t\t\tfor (const [, renderInstance] of vectorNode.cache.iterateRenderInstances()) {\n\t\t\t\trenderInstance.matrix = undefined\n\t\t\t\trenderInstance.parentMatrix = undefined\n\t\t\t}\n\t\t\tvectorNode.cache.groundNodeMatrix = null\n\t\t}\n\n\t\tconst replicasToRebuild = new Set<CanvasNode & IsReplica>()\n\t\tconst changedGroundNodes = new Set<CanvasNode>()\n\n\t\t// Check the nodes that are marked mutable, if there are replicas marked to rebuild, do that now.\n\t\tfor (const node of tree.unsafeGetDraftNodes()) {\n\t\t\tif (tree.isGroundNode(node)) {\n\t\t\t\tchangedGroundNodes.add(node)\n\t\t\t}\n\n\t\t\t// Reset all matrices\n\t\t\tfor (const [, renderInstance] of node.cache.iterateRenderInstances()) {\n\t\t\t\trenderInstance.matrix = undefined\n\t\t\t\trenderInstance.parentMatrix = undefined\n\t\t\t}\n\t\t\tnode.cache.groundNodeMatrix = null\n\n\t\t\t// Make sure all replicas are rebuild. This normally happens on commit.\n\t\t\tif (isReplica(node)) {\n\t\t\t\treplicasToRebuild.add(node)\n\t\t\t}\n\n\t\t\t// Also rebuild replicas when a master changed.\n\t\t\tif (isMaster(node) && node.cache.replicaInstances) {\n\t\t\t\tfor (const replicaId of node.cache.replicaInstances) {\n\t\t\t\t\tconst replica = tree.get(replicaId)\n\t\t\t\t\tif (!isReplica(replica)) continue\n\t\t\t\t\treplicasToRebuild.add(replica)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const replica of replicasToRebuild) {\n\t\t\tTemplateHelper.replicaWithChanges(tree, replica)\n\t\t\tchangedGroundNodes.add(replica)\n\t\t}\n\n\t\treturn { selection: firstEdit.selection, changedGroundNodes }\n\t}\n}\n\nfunction changeIncludesNode(nodeId: NodeID) {\n\treturn (change: ReversibleNodeChange) => {\n\t\treturn change.id === nodeId || change.fromChildren?.includes(nodeId) || change.toChildren?.includes(nodeId)\n\t}\n}\n\nfunction countEntriesBeforeIndex(\n\tentries: UndoRedoEntry[],\n\tindex: number,\n\tmatches: (entry: UndoRedoEntry) => boolean,\n): number {\n\tlet count = 0\n\tfor (let i = 0; i < index; i++) {\n\t\tconst entry = entries[i]\n\t\tif (!entry || matches(entry)) continue\n\t\tcount++\n\t}\n\treturn count\n}\n\nfunction removeMatchingEntries(entries: UndoRedoEntry[], matches: (entry: UndoRedoEntry) => boolean): number {\n\tlet removed = 0\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i]\n\t\tif (!entry || !matches(entry)) continue\n\t\tentries.splice(i, 1)\n\t\tremoved++\n\t}\n\treturn removed\n}\n\n// Collect replica shape associated with the `override/` changes.\nfunction getChangedReplicaShapes(tree: CanvasTree, changes: ReversibleNodeChange[]) {\n\tconst result: VectorNode[] = []\n\tfor (const change of changes) {\n\t\tif (change.removed) continue\n\t\tif (!isOverrideId(change.id)) continue\n\n\t\tconst [replicaId, originalId] = parseOverrideId(change.id)\n\t\tif (!replicaId || !originalId) continue\n\n\t\tconst replicaChildId = generateReplicaChildId(replicaId, originalId)\n\t\tconst replicaChild = tree.get(replicaChildId)\n\t\tif (!isVectorNode(replicaChild)) continue\n\n\t\tresult.push(replicaChild)\n\t}\n\n\treturn result\n}\n", "import type { VariableCreateScopeType } from \"@framerjs/events\"\nimport { EngineStore } from \"document/EngineStore.ts\"\nimport type { CreateVariableOptions } from \"document/components/chrome/properties/utils/createVariable.ts\"\nimport { createVariable } from \"document/components/chrome/properties/utils/createVariable.ts\"\nimport type { NodeID } from \"document/models/CanvasTree/index.ts\"\nimport type { VariableDefinition, VariableID } from \"document/models/CanvasTree/traits/WithVariables.ts\"\n\nexport interface TemporaryTarget {\n\tid: NodeID\n\tprop: string\n}\n\ntype ArrayVariableID = VariableID\ntype ArrayItemVariableID = VariableID | null\n\nexport type SelectedVariablePath = readonly [VariableID] | readonly [ArrayVariableID, ArrayItemVariableID]\n\nexport class VariablesStore extends EngineStore {\n\tselectedVariablePath: SelectedVariablePath | null = null\n\n\t/* A temporary variable to display in the variable creation flow */\n\ttemporaryVariable: VariableDefinition | null = null\n\n\t/* Node and prop the temporary variable is targeting at */\n\ttemporaryTarget: TemporaryTarget | null = null\n\n\tcreateTemporaryVariable(\n\t\ttargetId: NodeID,\n\t\ttargetProp: string,\n\t\tscopeType: VariableCreateScopeType,\n\t\toptions: CreateVariableOptions,\n\t): VariableDefinition {\n\t\tthis.temporaryTarget = { id: targetId, prop: targetProp }\n\n\t\tconst variable = createVariable(options, scopeType)\n\t\tthis.temporaryVariable = variable\n\n\t\treturn this.temporaryVariable\n\t}\n\n\tclearTemporaryVariable(): void {\n\t\tthis.temporaryVariable = null\n\t\tthis.temporaryTarget = null\n\t}\n}\n", "import type { AgentContextHooks } from \"app/ai/agents/context/AgentContext.ts\"\nimport { generateScreenshotHTML } from \"app/ai/kits/screenshots.ts\"\nimport { LayoutCache } from \"document/LayoutCache.ts\"\nimport { LayoutState } from \"document/LayoutState.ts\"\nimport type { VekterEngineScheduler } from \"document/VekterEngineScheduler.ts\"\nimport { createToolKeyDownHandler } from \"document/components/tools/createToolKeyDownHandler.ts\"\nimport { CanvasStore } from \"document/stores/CanvasStore.ts\"\nimport { ChromeStore } from \"document/stores/ChromeStore.ts\"\nimport { ComponentsStore } from \"document/stores/ComponentsStore.ts\"\nimport { CustomFontStore } from \"document/stores/CustomFontStore.ts\"\nimport { DebugStore } from \"document/stores/DebugStore.ts\"\nimport { DocumentSettingsStore } from \"document/stores/DocumentSettingsStore.ts\"\nimport { FeedbackStore } from \"document/stores/FeedbackStore.ts\"\nimport { ModulesStore } from \"document/stores/ModulesStore.ts\"\nimport { MouseStore } from \"document/stores/MouseStore.ts\"\nimport { PersistedUserDefaults } from \"document/stores/PersistedUserDefaults.ts\"\nimport { ScopeStore } from \"document/stores/ScopeStore.ts\"\nimport { ToolStore, Tools } from \"document/stores/ToolStore.ts\"\nimport { TreeStore } from \"document/stores/TreeStore.ts\"\nimport { WebFontStore } from \"document/stores/WebFontStore.ts\"\nimport { getModulesAPI } from \"modules/getModulesAPI.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { RemoteUsers } from \"./RemoteUsers.ts\"\nimport type { VekterEngine } from \"./VekterEngine.ts\"\nimport type { BaseEngineStores } from \"./base-engine/BaseEngine.ts\"\nimport { CanvasMouseTarget } from \"./components/canvas/CanvasMouseTarget.tsx\"\nimport { getActiveWebPageURL } from \"./components/utils/getActiveWebPageURL.ts\"\nimport type { CanvasTree, ScopeNode } from \"./models/CanvasTree/index.ts\"\nimport { updateTreeCacheForVekterWithStores } from \"./models/updateTreeCacheForVekter.ts\"\nimport type { TogglePreviewVisibleOptions } from \"./preview/togglePreviewVisibleWithoutEngineDependency.ts\"\nimport { togglePreviewVisibleWithoutEngineDependency } from \"./preview/togglePreviewVisibleWithoutEngineDependency.ts\"\nimport { AIGenerationStore } from \"./stores/AIGenerationStore.ts\"\nimport { AgentStore } from \"./stores/AgentStore.ts\"\nimport { AnalyticsStore } from \"./stores/AnalyticsStore.ts\"\nimport { AssetStore } from \"./stores/AssetStore.ts\"\nimport { CodeEditorStore } from \"./stores/CodeEditorStore.ts\"\nimport { CodeGenerationStore } from \"./stores/CodeGenerationStore.ts\"\nimport { ContentManagementStore } from \"./stores/ContentManagementStore.ts\"\nimport { ContextMenuStore } from \"./stores/ContextMenuStore.ts\"\nimport { EffectStore } from \"./stores/EffectStore.ts\"\nimport { FontPreviewStore } from \"./stores/FontPreviewStore.ts\"\nimport { FormsStore } from \"./stores/FormsStore.ts\"\nimport { FramerFontStore } from \"./stores/FramerFontStore.ts\"\nimport { FullsizePreviewStore } from \"./stores/FullsizePreviewStore.ts\"\nimport { GuidesStore } from \"./stores/GuidesStore.ts\"\nimport { HistoryStore } from \"./stores/HistoryStore.ts\"\nimport { HostnameStore } from \"./stores/HostnameStore.ts\"\nimport { InsertSidebarStore } from \"./stores/InsertSidebarStore.ts\"\nimport { KitScreenshotStore } from \"./stores/KitScreenshotStore.ts\"\nimport { LibraryStore } from \"./stores/LibraryStore.ts\"\nimport { LoadedExternalModulesStore } from \"./stores/LoadedExternalModulesStore.ts\"\nimport { LoadingStore } from \"./stores/LoadingStore.ts\"\nimport { LocalizationStore } from \"./stores/LocalizationStore.ts\"\nimport { ModalStore } from \"./stores/ModalStore.ts\"\nimport { MouseCursorStore } from \"./stores/MouseCursorStore.ts\"\nimport { OverlayStore } from \"./stores/OverlayStore.ts\"\nimport { PathSelectionStore } from \"./stores/PathSelectionStore.ts\"\nimport { PaymentsStore } from \"./stores/PaymentsStore.ts\"\nimport { PluginStore } from \"./stores/PluginStore.ts\"\nimport { PopoverStore } from \"./stores/PopoverStore.ts\"\nimport { PreviewStore } from \"./stores/PreviewStore.ts\"\nimport { ProjectStore } from \"./stores/ProjectStore.ts\"\nimport { PropertiesPanelStore } from \"./stores/PropertiesPanelStore.ts\"\nimport { PublishStore } from \"./stores/PublishStore.ts\"\nimport { RepeaterStore } from \"./stores/RepeaterStore.ts\"\nimport { SelectionOutlineTracker } from \"./stores/SelectionOutlineTracker.ts\"\nimport { SelectionStore } from \"./stores/SelectionStore.ts\"\nimport { SessionStore } from \"./stores/SessionStore.ts\"\nimport { ShaderFallbackImageStore } from \"./stores/ShaderFallbackImageStore.ts\"\nimport { SiteSettingsStore } from \"./stores/SiteSettingsStore.ts\"\nimport { SnapLinesStore } from \"./stores/SnapLinesStore.ts\"\nimport { UndoRedoManager } from \"./stores/UndoRedoManager.ts\"\nimport { UsageStore } from \"./stores/UsageStore.ts\"\nimport { VariablesStore } from \"./stores/VariablesStore.ts\"\nimport { VectorsStore } from \"./stores/VectorsStore.ts\"\nimport type { EffectPreviewState } from \"./utils/EffectPreviewType.ts\"\n\nexport class EngineStores implements BaseEngineStores {\n\t// Core stores\n\treadonly agentStore: AgentStore\n\treadonly debugStore: DebugStore\n\treadonly loadingStore: LoadingStore\n\treadonly persistedUserDefaults: PersistedUserDefaults\n\treadonly modalStore: ModalStore\n\treadonly chromeStore: ChromeStore\n\treadonly snapLinesStore: SnapLinesStore\n\treadonly guidesStore: GuidesStore\n\treadonly treeStore: TreeStore\n\treadonly assetStore: AssetStore\n\treadonly overlayStore: OverlayStore\n\treadonly selectionStore: SelectionStore\n\treadonly effectStore: EffectStore\n\treadonly fontPreviewStore: FontPreviewStore\n\treadonly popoverStore: PopoverStore\n\treadonly contextMenuStore: ContextMenuStore\n\treadonly mouseCursorStore: MouseCursorStore\n\treadonly canvasStore: CanvasStore\n\treadonly mouseStore: MouseStore\n\treadonly pathSelectionStore: PathSelectionStore\n\treadonly documentSettingsStore: DocumentSettingsStore\n\treadonly propertiesPanelStore: PropertiesPanelStore\n\treadonly feedbackStore: FeedbackStore\n\treadonly localizationStore: LocalizationStore\n\treadonly loadedExternalModulesStore: LoadedExternalModulesStore\n\treadonly modulesStore: ModulesStore\n\treadonly codeEditorStore: CodeEditorStore\n\treadonly componentsStore: ComponentsStore\n\treadonly webFontStore: WebFontStore\n\treadonly customFontStore: CustomFontStore\n\treadonly framerFontStore: FramerFontStore\n\treadonly formsStore: FormsStore\n\treadonly vectorsStore: VectorsStore\n\treadonly codeGenerationStore: CodeGenerationStore\n\treadonly insertSidebarStore: InsertSidebarStore\n\treadonly repeaterStore: RepeaterStore\n\treadonly contentManagementStore: ContentManagementStore\n\treadonly scopeStore: ScopeStore\n\treadonly siteSettingsStore: SiteSettingsStore\n\treadonly projectStore: ProjectStore\n\treadonly historyStore: HistoryStore\n\treadonly toolStore: ToolStore\n\treadonly libraryStore: LibraryStore\n\treadonly sessionStore: SessionStore\n\treadonly analyticsStore: AnalyticsStore\n\treadonly usageStore: UsageStore\n\treadonly publishStore: PublishStore\n\treadonly hostnameStore: HostnameStore\n\treadonly variablesStore: VariablesStore\n\treadonly layoutState: LayoutState\n\treadonly previewStore: PreviewStore\n\treadonly paymentsStore: PaymentsStore\n\treadonly pluginStore: PluginStore\n\treadonly fullsizePreviewStore: FullsizePreviewStore\n\treadonly aiGenerationStore: AIGenerationStore\n\treadonly kitScreenshotStore: KitScreenshotStore\n\treadonly shaderFallbackImageStore: ShaderFallbackImageStore\n\n\t// Non-store fields\n\treadonly layoutCache: LayoutCache\n\treadonly undoRedoManager: UndoRedoManager\n\treadonly remoteUsers: RemoteUsers\n\treadonly selectionOutlineTracker: SelectionOutlineTracker\n\treadonly canvasMouseTarget: CanvasMouseTarget\n\n\tconstructor(engine: VekterEngine, taskScheduler: VekterEngineScheduler) {\n\t\tconst changes = taskScheduler.changes\n\n\t\t// Initialize stores in dependency order\n\t\tthis.debugStore = DebugStore.new(taskScheduler)\n\t\tthis.loadingStore = LoadingStore.new(taskScheduler)\n\t\tthis.persistedUserDefaults = new PersistedUserDefaults(\n\t\t\tchanges.addChanges,\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\t\tthis.modalStore = ModalStore.new(taskScheduler)\n\n\t\tthis.chromeStore = ChromeStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.persistedUserDefaults,\n\t\t\tthis.loadingStore,\n\t\t\tthis.modalStore,\n\t\t\t() => {\n\t\t\t\t// Because in getActiveScope, we return no scope if in localizations, we\n\t\t\t\t// need to reset the scope when we leave localizations.\n\t\t\t\tthis.modulesStore.changeScope(this.scopeStore.active)\n\t\t\t},\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.snapLinesStore = SnapLinesStore.new(taskScheduler)\n\t\tthis.guidesStore = GuidesStore.new(taskScheduler)\n\t\tthis.layoutCache = new LayoutCache()\n\t\tthis.undoRedoManager = new UndoRedoManager(changes.addChanges)\n\n\t\tthis.treeStore = new TreeStore(\n\t\t\tchanges.addChanges,\n\t\t\tengine.componentLoader,\n\t\t\tthis.persistedUserDefaults,\n\t\t\tthis.chromeStore,\n\t\t\tthis.guidesStore,\n\t\t\tthis.undoRedoManager,\n\t\t\tthis.layoutCache,\n\t\t\t// When the TreeStore updates the cache after sandbox rendering, it\n\t\t\t// needs to call updateTreeCacheForVekter(), and shouldn't cancel any\n\t\t\t// effects that are being previewed on the canvas.\n\t\t\t(): EffectPreviewState => this.effectStore.getState(),\n\t\t\t{ editHooks: taskScheduler },\n\t\t)\n\n\t\tthis.assetStore = AssetStore.new(\n\t\t\ttaskScheduler,\n\t\t\tchanges.addChanges,\n\t\t\tthis.loadingStore,\n\t\t\tthis.treeStore,\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\t\tthis.sessionStore = SessionStore.new(taskScheduler)\n\t\tthis.overlayStore = OverlayStore.new(taskScheduler, engine.componentLoader, this.treeStore)\n\t\tthis.repeaterStore = RepeaterStore.new(taskScheduler, this.treeStore)\n\t\tthis.selectionStore = SelectionStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.guidesStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.overlayStore,\n\t\t\tthis.sessionStore,\n\t\t)\n\t\tthis.effectStore = EffectStore.new(taskScheduler, this.selectionStore)\n\t\tthis.fontPreviewStore = FontPreviewStore.new(taskScheduler, this.treeStore)\n\t\tthis.popoverStore = PopoverStore.new(taskScheduler)\n\t\tthis.contextMenuStore = ContextMenuStore.new(taskScheduler)\n\t\tthis.mouseCursorStore = MouseCursorStore.new(taskScheduler)\n\t\tthis.selectionOutlineTracker = new SelectionOutlineTracker(\n\t\t\tchanges.addChanges,\n\t\t\ttaskScheduler.wrapHandler.bind(taskScheduler),\n\t\t)\n\t\tthis.mouseStore = new MouseStore(\n\t\t\tchanges.addChanges,\n\t\t\tthis.selectionOutlineTracker,\n\t\t\t() => engine.tool,\n\t\t\t() => {\n\t\t\t\tif (engine.tool.enum === Tools.ZoomSelect) return\n\t\t\t\tif (engine.tool.enum === Tools.Zoom) return\n\t\t\t\tengine.setTool(Tools.Zoom)\n\t\t\t},\n\t\t\tcreateToolKeyDownHandler(engine),\n\t\t)\n\t\tthis.projectStore = ProjectStore.new(taskScheduler)\n\t\tthis.pluginStore = PluginStore.new(taskScheduler, this.projectStore)\n\t\tthis.documentSettingsStore = new DocumentSettingsStore(changes.addChanges)\n\t\tthis.canvasStore = new CanvasStore(\n\t\t\ttaskScheduler,\n\t\t\tthis,\n\t\t\tthis.pluginStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.mouseStore,\n\t\t\tthis.persistedUserDefaults,\n\t\t\tthis.selectionStore,\n\t\t\tthis.treeStore,\n\t\t\tthis.documentSettingsStore,\n\t\t\tchanges,\n\t\t\t() => this.scopeStore.active,\n\t\t\t(scope: ScopeNode) => this.scopeStore.select(scope.id, { keepHistory: false }),\n\t\t)\n\t\tthis.pathSelectionStore = new PathSelectionStore(changes.addChanges, this.chromeStore)\n\t\tthis.propertiesPanelStore = PropertiesPanelStore.new(taskScheduler)\n\n\t\tthis.toolStore = ToolStore.new(taskScheduler, changes.addChanges, this.effectStore)\n\t\tthis.feedbackStore = FeedbackStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.toolStore,\n\t\t\tthis.selectionStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.projectStore,\n\t\t)\n\n\t\tthis.localizationStore = LocalizationStore.new(taskScheduler, engine.eventListenerAbortController.signal)\n\n\t\tthis.loadedExternalModulesStore = LoadedExternalModulesStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.selectionStore,\n\t\t\tidentifier => engine.canvasSandbox?.sandbox.modulesRuntime.ensureExternalModuleLoaded(identifier),\n\t\t\t(fn, millis) => taskScheduler.debounce(fn, millis),\n\t\t)\n\n\t\tthis.modulesStore = ModulesStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.loadedExternalModulesStore,\n\t\t\tthis.chromeStore,\n\t\t\tgetModulesAPI(),\n\t\t\t() => engine.remoteDocument?.makeReadOnly?.(),\n\t\t\tasync importMap => {\n\t\t\t\t// Wait for the canvas sandbox so temp maps are installed before external module evaluation.\n\t\t\t\tconst canvasSandbox = await engine.canvasSandboxPromise\n\t\t\t\tawait canvasSandbox.sandbox.modulesRuntime.insertTemporaryImportMap(importMap)\n\t\t\t},\n\t\t\tasync () => engine?.canvasSandbox?.sandbox.modulesRuntime.loadAllLocalModules(),\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.codeEditorStore = CodeEditorStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.modulesStore,\n\t\t\tthis.chromeStore,\n\t\t\t// We are passing this function in to avoid a circular dependency\n\t\t\t(options: TogglePreviewVisibleOptions) => togglePreviewVisibleWithoutEngineDependency(engine, options),\n\t\t)\n\n\t\tthis.componentsStore = new ComponentsStore(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.selectionStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.chromeStore,\n\t\t\tchanges,\n\t\t\t() => !!engine.remoteDocument?.waitingForSync(),\n\t\t)\n\t\tthis.webFontStore = WebFontStore.new(taskScheduler, this.treeStore)\n\t\tthis.customFontStore = new CustomFontStore(\n\t\t\tthis.assetStore,\n\t\t\tthis.treeStore,\n\t\t\tthis.documentSettingsStore,\n\t\t\tchanges,\n\t\t\t(task, options) => engine.runWithFullyLoadedTree(task, options),\n\t\t)\n\t\tthis.framerFontStore = new FramerFontStore()\n\t\tthis.formsStore = FormsStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.treeStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.modalStore,\n\t\t\tthis.projectStore,\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\t\tthis.vectorsStore = VectorsStore.new(taskScheduler, this.modulesStore)\n\n\t\tthis.libraryStore = LibraryStore.new(taskScheduler)\n\n\t\tthis.aiGenerationStore = AIGenerationStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.projectStore,\n\t\t\tthis.libraryStore,\n\t\t)\n\n\t\tthis.kitScreenshotStore = KitScreenshotStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.assetStore,\n\t\t\tthis.loadedExternalModulesStore,\n\t\t\ttask => taskScheduler.scheduleUpdateBypassingModuleRevisionHints(task),\n\t\t\tkitPageId =>\n\t\t\t\tgenerateScreenshotHTML(\n\t\t\t\t\tengine.componentLoader,\n\t\t\t\t\tthis.treeStore,\n\t\t\t\t\tthis.modulesStore,\n\t\t\t\t\tthis.codeGenerationStore,\n\t\t\t\t\tthis.debugStore,\n\t\t\t\t\tthis.publishStore,\n\t\t\t\t\tthis.projectStore,\n\t\t\t\t\tthis.assetStore,\n\t\t\t\t\ttaskScheduler,\n\t\t\t\t\tkitPageId,\n\t\t\t\t),\n\t\t)\n\n\t\tthis.shaderFallbackImageStore = ShaderFallbackImageStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\ttask => taskScheduler.scheduleUpdateBypassingModuleRevisionHints(task),\n\t\t)\n\n\t\tthis.codeGenerationStore = CodeGenerationStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.vectorsStore,\n\t\t\tthis.aiGenerationStore,\n\t\t\tthis.assetStore.assetMap,\n\t\t\tthis.treeStore.timeline,\n\t\t\tchanges,\n\t\t\ttask => taskScheduler.scheduleUpdateWithDataTreeBypassingModuleRevisionHints(task),\n\t\t\tscopeId => updateTreeCacheForVekterWithStores(engine.componentLoader, this, scopeId),\n\t\t\tasync nodeIds => engine.canvasSandbox?.sandbox.renderer.measureNodes(nodeIds),\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.insertSidebarStore = InsertSidebarStore.new(taskScheduler, this.modulesStore, this.chromeStore, this.treeStore)\n\t\tthis.contentManagementStore = ContentManagementStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.selectionStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.treeStore,\n\t\t\tthis.sessionStore,\n\t\t)\n\n\t\tthis.scopeStore = ScopeStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.canvasStore,\n\t\t\tthis.selectionStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.contentManagementStore,\n\t\t\tthis.overlayStore,\n\t\t\tthis.codeGenerationStore,\n\t\t\tthis.insertSidebarStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.aiGenerationStore,\n\t\t\t() => this.agentStore.switchScope(),\n\t\t)\n\n\t\tconst agentHooks: AgentContextHooks = {\n\t\t\tgetEngine: () => engine,\n\t\t}\n\n\t\tthis.agentStore = AgentStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.chromeStore,\n\t\t\tthis.treeStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.vectorsStore,\n\t\t\tthis.formsStore,\n\t\t\tthis.sessionStore,\n\t\t\tthis.codeGenerationStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.projectStore.projectId,\n\t\t\tthis.persistedUserDefaults,\n\t\t\tagentHooks,\n\t\t)\n\n\t\tthis.remoteUsers = new RemoteUsers(\n\t\t\ttaskScheduler,\n\t\t\tthis.scopeStore,\n\t\t\tthis.canvasStore,\n\t\t\tthis.mouseStore,\n\t\t\tthis.treeStore,\n\t\t\tchanges,\n\t\t\t() => engine.remoteDocument?.remote ?? null,\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.siteSettingsStore = SiteSettingsStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.chromeStore,\n\t\t\tthis.modalStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.treeStore,\n\t\t)\n\n\t\tthis.historyStore = HistoryStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.documentSettingsStore,\n\t\t\tthis.codeGenerationStore,\n\t\t\tthis.projectStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.treeStore,\n\t\t\t(tree: CanvasTree) => engine.load(tree),\n\t\t\t(tree: CanvasTree) => engine.newTreeAfterRemoteUpdate(tree),\n\t\t\ttaskScheduler.wrapHandler((tool: Tools) => engine.setTool(tool)),\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.analyticsStore = AnalyticsStore.new(\n\t\t\ttaskScheduler,\n\t\t\tthis.projectStore.projectId,\n\t\t\tthis.chromeStore,\n\t\t\t() => this.projectStore.resourceLimits?.analyticsRangeInDays,\n\t\t)\n\n\t\tthis.usageStore = UsageStore.new(taskScheduler, this.sessionStore, this.projectStore)\n\n\t\tthis.publishStore = PublishStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.treeStore,\n\t\t\tthis.projectStore,\n\t\t\tthis.codeGenerationStore,\n\t\t\tthis.modulesStore,\n\t\t\tthis.pluginStore,\n\t\t\tthis.siteSettingsStore,\n\t\t\tthis.popoverStore,\n\t\t\tthis.debugStore,\n\t\t\tthis.chromeStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.selectionStore,\n\t\t\tthis.shaderFallbackImageStore,\n\t\t\tthis.loadedExternalModulesStore,\n\t\t\tthis.assetStore,\n\t\t\tthis.modalStore,\n\t\t\t(hostname: string) => getActiveWebPageURL(engine.componentLoader, this, hostname),\n\t\t\tpermission => getIsViewOnly(engine, permission),\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.hostnameStore = HostnameStore.new(taskScheduler, this.publishStore)\n\t\tthis.variablesStore = VariablesStore.new(taskScheduler)\n\n\t\tthis.layoutState = new LayoutState(\n\t\t\tchanges,\n\t\t\tthis.chromeStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.insertSidebarStore,\n\t\t\tthis.codeEditorStore,\n\t\t\tengine.eventListenerAbortController.signal,\n\t\t)\n\n\t\tthis.previewStore = PreviewStore.new(\n\t\t\ttaskScheduler,\n\t\t\tengine.componentLoader,\n\t\t\tthis.chromeStore,\n\t\t\tthis.codeEditorStore,\n\t\t\tthis.componentsStore,\n\t\t\tthis.contentManagementStore,\n\t\t\tthis.loadingStore,\n\t\t\tthis.scopeStore,\n\t\t\tthis.selectionStore,\n\t\t\tthis.treeStore,\n\t\t)\n\n\t\tthis.paymentsStore = PaymentsStore.new(taskScheduler)\n\t\tthis.fullsizePreviewStore = FullsizePreviewStore.new(taskScheduler, this.chromeStore, this.previewStore)\n\t\tthis.canvasMouseTarget = new CanvasMouseTarget(taskScheduler, this.canvasStore, this.mouseStore)\n\t}\n}\n", "import type { HeadlessAPI } from \"./HeadlessAPI.ts\"\n\n/** Singleton accessor that avoids the HeadlessAPI import (and its `engine.ts`\n *  module-graph cycle) for callers in the document/ tree. Returns null when\n *  the api-plugin isn't running. */\nexport function getHeadlessAPI(): HeadlessAPI | null {\n\treturn (window as Window & { HeadlessAPI?: HeadlessAPI | null }).HeadlessAPI ?? null\n}\n", "import type { Primitive } from \"@framerjs/shared\"\nimport { enrichWithLogs } from \"@framerjs/shared/src/logger.ts\"\nimport { experiments } from \"../app/experiments.ts\"\nimport type { RemoteDocumentHandler } from \"./RemoteDocumentHandler.ts\"\nimport type { VekterEngine } from \"./VekterEngine.ts\"\nimport { isCrdt } from \"./crdt/isCrdt.ts\"\n\n// having value as undefined will result in a key being removed from the object during JSON serialization\ninterface Metadata {\n\t[key: string]: Primitive\n\tscopesToLoadCount?: number\n\tactiveScopeUsersCount?: number\n\tonlineUsersCount?: number\n\tsessionDurationSeconds: number\n\ttreeSize: number\n\tdocumentSizeMB: number\n\teditReason: string | undefined\n\tlogs?: string\n\tmemoryUsage: number | undefined\n\tsandboxMemoryUsage: number | undefined\n}\n\ninterface ExperimentTags {\n\t[experiment: `exp.${string}`]: boolean\n}\n\ninterface Tags extends ExperimentTags {\n\t[key: string]: Primitive\n\tloader: RemoteDocumentHandler[\"loaderType\"] | \"none\"\n\ttreeBucket: \"XS\" | \"S\" | \"M\" | \"L\" | \"XL\"\n\tdocumentSizeBucket: \"XS\" | \"S\" | \"M\" | \"L\" | \"XL\"\n\tsessionCategory:\n\t\t| \"less than 1 minute\"\n\t\t| \"1 to 3 minutes\"\n\t\t| \"3 to 10 minutes\"\n\t\t| \"10 to 20 minutes\"\n\t\t| \"more than 20 minutes\"\n\tactiveTool: string\n\tactivePlugin: string\n\thasMultipleActiveUsers: boolean\n\thasMultipleActiveUsersOneScope: boolean\n\thasExtraExperiments: boolean\n\ttabIsActive: boolean\n\tgeneratingCode: boolean\n\tprocessingModules: boolean\n\tcrdt: boolean\n\tmps: boolean\n}\n\n// we don't want to include logs in the reports to sentry by default\n// <https://framer-team.slack.com/archives/C064S2N6MJM/p1731608834329479>\nexport function getContextsForErrorReporting(engine: VekterEngine, withLogs = false) {\n\treturn new VekterEngineMeta(engine).getContextsForErrorReporting(withLogs)\n}\n\nclass VekterEngineMeta {\n\tprivate createdAt = performance.now()\n\n\tconstructor(private engine: VekterEngine) {}\n\n\tgetContextsForErrorReporting(withLogs: boolean) {\n\t\tconst meta = this.buildMeta(withLogs)\n\t\tconst tags = this.buildTags(meta)\n\n\t\treturn { tags, meta } satisfies {\n\t\t\ttags: Record<string, Primitive>\n\t\t\tmeta: Record<string, Primitive>\n\t\t}\n\t}\n\n\t/**\n     * Use tags for context information that is important to be searchable,\n     * so having the distribution of values can help with debugging.\n     *\n     * Changing how tags values calculation may affect might make reasoning about the long-standing errors harder\n     * as tag values will be different between versions of the code when the error happened\n\n     * @param meta {Metadata}\n     * @private\n     */\n\tprivate buildTags(meta: Metadata): Tags {\n\t\treturn {\n\t\t\tloader: this.engine.remoteDocument?.loaderType || \"none\",\n\t\t\thasMultipleActiveUsers: meta.onlineUsersCount ? meta.onlineUsersCount > 1 : false,\n\t\t\thasMultipleActiveUsersOneScope: meta.activeScopeUsersCount ? meta.activeScopeUsersCount > 1 : false,\n\t\t\thasExtraExperiments: !!meta.extraExperiments,\n\t\t\ttabIsActive: document.visibilityState === \"visible\",\n\t\t\tactiveTool: this.engine.currentToolName(),\n\t\t\tgeneratingCode: !this.engine.stores.codeGenerationStore.isIdle(),\n\t\t\tprocessingModules: this.engine.stores.modulesStore.isProcessingModules(),\n\t\t\ttreeBucket: getTreeBucket(meta.treeSize),\n\t\t\tdocumentSizeBucket: getDocumentSizeBucket(meta.documentSizeMB),\n\t\t\tsessionCategory: getSessionDurationCategory(meta.sessionDurationSeconds),\n\t\t\tactivePlugin: this.engine.stores.pluginStore.activePlugin?.name ?? \"none\",\n\t\t\tcrdt: isCrdt(),\n\t\t\tmps: this.engine.stores.treeStore.isMPSSocket,\n\t\t\t...getExperimentTags(),\n\t\t}\n\t}\n\n\t/**\n\t * Use extras for context information that heps with debugging but is not important to be searchable.\n\t * @private\n\t */\n\tprivate buildMeta(withLogs: boolean): Metadata {\n\t\tconst { debugStore, remoteUsers, scopeStore, treeStore } = this.engine.stores\n\t\tconst loader = treeStore.tree.getService(\"loader\")\n\n\t\tlet extras: Metadata = {\n\t\t\tsessionDurationSeconds: Math.round((performance.now() - this.createdAt) / 1000),\n\t\t\ttreeSize: treeStore.tree.size(),\n\t\t\tdocumentSizeMB: byteToMB(this.engine.remoteDocument?.documentByteSize ?? 0),\n\t\t\teditReason: treeStore.tree.lineage.peekEditReason() || undefined,\n\t\t\tmemoryUsage: Math.round(debugStore.getVekterMemory() / 1024 / 1024),\n\t\t\tsandboxMemoryUsage: Math.round(debugStore.getSandboxMemoryUse() / 1024 / 1024),\n\t\t}\n\n\t\tif (withLogs) {\n\t\t\textras = enrichWithLogs(extras)\n\t\t}\n\n\t\tif (loader) {\n\t\t\textras.scopesToLoadCount = loader.numberOfScopesToLoad()\n\t\t}\n\n\t\tconst remoteDocument = this.engine.remoteDocument\n\t\tif (remoteDocument) {\n\t\t\tconst activePage = scopeStore.activeId\n\t\t\textras.onlineUsersCount = 1\n\t\t\textras.activeScopeUsersCount = 1\n\t\t\tfor (const cursor of remoteUsers.cursors) {\n\t\t\t\tif (cursor.userId === remoteDocument.userId) continue\n\t\t\t\textras.onlineUsersCount++\n\t\t\t\tif (cursor.pageId === activePage) {\n\t\t\t\t\textras.activeScopeUsersCount++\n\t\t\t\t}\n\t\t\t}\n\t\t\t// if there is only one user online, we don't need to report it\n\t\t\tif (extras.onlineUsersCount === 1) {\n\t\t\t\t// biome-ignore lint/performance/noDelete: Changing to `undefined` does not cover `in` operator on object\n\t\t\t\tdelete extras.onlineUsersCount\n\n\t\t\t\t// biome-ignore lint/performance/noDelete: Changing to `undefined` does not cover `in` operator on object\n\t\t\t\tdelete extras.activeScopeUsersCount\n\t\t\t}\n\t\t}\n\n\t\treturn extras\n\t}\n}\n\n/**\n * returns any extra experiments as a string \"a=on; b=off\"\n */\nexport function getExtraExperiments() {\n\treturn Object.entries(experiments.diffFromInitial())\n\t\t.map(x => x.join(\"=\"))\n\t\t.join(\"; \")\n\t\t.trim()\n}\n\nfunction getExperimentTags(): ExperimentTags {\n\tconst overrides = experiments.diffFromInitial()\n\tconst result: ExperimentTags = {}\n\tfor (const key in overrides) {\n\t\tresult[`exp.${key}` satisfies keyof ExperimentTags] = overrides[key as keyof typeof overrides] === \"on\"\n\t}\n\n\treturn result\n}\n\nfunction getSessionDurationCategory(sessionDurationSeconds: number): Tags[\"sessionCategory\"] {\n\tif (sessionDurationSeconds < 60) return \"less than 1 minute\"\n\tif (sessionDurationSeconds < 180) return \"1 to 3 minutes\"\n\tif (sessionDurationSeconds < 600) return \"3 to 10 minutes\"\n\tif (sessionDurationSeconds < 1200) return \"10 to 20 minutes\"\n\treturn \"more than 20 minutes\"\n}\n\n// based on big query introspection of tree sizes, we might adjust it later\nfunction getTreeBucket(treeSize: number): Tags[\"treeBucket\"] {\n\tif (treeSize > 150_000) return \"XL\"\n\tif (treeSize > 50_000) return \"L\"\n\tif (treeSize > 5_000) return \"M\"\n\tif (treeSize > 250) return \"S\"\n\treturn \"XS\"\n}\n\n// arbitrary values based on big query data in 7 days when change was done,\n// around 90% of the documents are less than 5MB, and ~7% are less than 10MB\nfunction getDocumentSizeBucket(documentSizeMB: number): Tags[\"documentSizeBucket\"] {\n\tif (documentSizeMB > 40) return \"XL\"\n\tif (documentSizeMB > 10) return \"L\"\n\tif (documentSizeMB > 5) return \"M\"\n\tif (documentSizeMB > 1) return \"S\"\n\treturn \"XS\"\n}\n\n// Returns the size of the document in MB, rounded to 3 decimal places: 0.00075 => 0.001\nfunction byteToMB(bytes: number) {\n\treturn Math.round((bytes / 1_000_000) * 1000) / 1000\n}\n", "import { button, buttonPrimary } from \"@framerjs/fresco/src/components/Button.styles\"\nimport { fonts, palette } from \"@framerjs/fresco/tokens\"\nimport { ReportTag, getLogger, reportableError } from \"@framerjs/shared\"\nimport type { ErrorTags } from \"@framerjs/shared/src/logger.ts\"\nimport * as Sentry from \"@sentry/browser\"\nimport { randomBase62 } from \"utils/base62.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { ErrorArea, record } from \"web/lib/tracker.ts\"\nimport { getHeadlessAPI } from \"../app/headlessApiContext.ts\"\nimport type { VekterEngine } from \"./VekterEngine.ts\"\nimport type { VekterTool } from \"./VekterTool.ts\"\nimport { githubDark, githubLight } from \"./components/chrome/richTextEditor/CodeBlockView/themes/themes.ts\"\nimport { isCrdtTreeCommitter } from \"./crdt/sync/CrdtTreeCommitter.ts\"\nimport { getExtraExperiments } from \"./getContextsForErrorReporting.ts\"\nimport { safeLoadDocument } from \"./models/CanvasTree/TreeRepair.ts\"\nimport { PopoverType } from \"./stores/PopoverStore.ts\"\nimport { Tools } from \"./stores/ToolEnum.ts\"\n\nlet hadFatalError = false\nlet lastError = 0\nlet initialEngineUpdateAtError = -1\nlet initialError: Error | undefined\n\n// This is called as a last resort. It will show a banner to the user in plain HTML, and remove any react elements.\nexport function fatalError(engine: VekterEngine | undefined, message: string, error: Error): Error {\n\tif (hadFatalError) return new Error(\"FatalError\", { cause: error })\n\thadFatalError = true\n\n\tif (!initialError) {\n\t\tinitialError = error\n\t}\n\n\tconsole.error(`FatalError: ${message}`)\n\tif (engine) {\n\t\tengine.treeReflectsDocument = false\n\t\tengine.scheduler.hadFatalError = true\n\t}\n\n\tgetLogger(\"fatal\").reportError(error)\n\trecord(\"application_error\", { message: initialError.message, area: ErrorArea.vekter })\n\n\t// Show a hardcoded error display, if possible.\n\tif (typeof document !== \"undefined\" && document.body) {\n\t\tconst isDark = document.body.getAttribute(\"data-framer-theme\") === \"dark\"\n\t\tconst full = `position: absolute; width: 100%; height: 100%; background: var(--framer-fresco-panelBackground-color, #fff);`\n\t\tconst center = \"display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 15px;\"\n\t\tconst text = `color: var(--framer-fresco-panelText-color, #999999); text-align: center; font-size: ${fonts.size.base}; font-family: ${fonts.family.sansSerif};`\n\n\t\tconst detailsStyle = `\n        background-color: var(--framer-fresco-inputBackground-color, #f3f3f3);\n        color: ${isDark ? githubDark.syntax.plain : githubLight.colors.accent};\n        caret-color: ${isDark ? githubDark.syntax.plain : githubLight.colors.accent};\n        border-radius: 15px;\n        border: 0;\n        outline-color: transparent; /* a11y: keeps the outline visible in high contrast mode */\n        outline-style: solid; /* a11y: keeps the outline visible in high contrast mode */\n        margin: 0;\n        padding: 15px;\n        text-align: left;\n        width: 400px;\n        font-family: ${fonts.family.monospace};\n        font-size: ${fonts.size.labelLarge};\n        white-space: pre;\n        field-sizing: content;\n        overflow: hidden;\n        resize: none;\n        `\n\t\tconst iconStyle = `\n        width: 30px;\n        height: 30px;\n        padding: 0 10px;\n        background-color: ${palette.blue60}1a;\n        border-radius: 8px;\n        display: flex;\n        justify-content: center;\n        align-items: center;`\n\t\tconst icon = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\" overflow=\"visible\"><path d=\"M 8 0 C 12.418 0 16 3.582 16 8 C 16 12.418 12.418 16 8 16 C 3.582 16 0 12.418 0 8 C 0 3.582 3.582 0 8 0 Z M 8 12 C 8.552 12 9 11.552 9 11 C 9 10.448 8.552 10 8 10 C 7.448 10 7 10.448 7 11 C 7 11.552 7.448 12 8 12 Z M 7 8 C 7 8.552 7.448 9 8 9 C 8.552 9 9 8.552 9 8 L 9 5 C 9 4.448 8.552 4 8 4 C 7.448 4 7 4.448 7 5 Z\" fill=\"rgb(0, 153, 255)\"></path></svg>`\n\n\t\tconst fadeStyle = `\n        background: linear-gradient(90deg, transparent 0%, var(--framer-fresco-inputBackground-color) 100%);\n        user-select: none;\n        bottom: 0;\n        top: 0;\n        right: 0px;\n        width: 100px;\n        border-radius: 15px;\n        overflow: visible;\n        position: absolute;\n        z-index: 10;\n        pointer-events: none;`\n\n\t\tconst stores = engine?.stores\n\t\tconst timeline = stores?.treeStore.timeline\n\t\tconst crdt = timeline && isCrdtTreeCommitter(timeline) ? timeline : undefined\n\t\tconst showCrdtButton = crdt && stores?.chromeStore.userIsEmployee\n\n\t\t// for CRDT-based projects, we need to fit an additional button\n\t\tconst buttonWidth = showCrdtButton ? \"33%\" : \"50%\"\n\t\tconst crdtSaveButton = showCrdtButton\n\t\t\t? `<button class=\"${button}\" id=\"saveCrdtButton\" style=\"width: ${buttonWidth}\">Save CRDT Store</button>`\n\t\t\t: \"\"\n\n\t\tdocument.body.innerHTML = `\n        <div style='${full} ${center} ${text}'>\n            <div style=\"${iconStyle}\">${icon}</div>\n\n            <div style=\"display: grid; gap: 10px\">\n                <h1 style=\"color: var(--framer-fresco-settingsContainerTitle-color, #222222); margin: 0; font-size: 22px; letter-spacing: -0.8px;\">Your project crashed</h1>\n                <p style=\"margin: 0; font-weight: ${fonts.weight.baseActive};\">Please try reloading your project first.<br/>\n                If the error persists, <a style=\"color: currentcolor; text-decoration: none;\" href=\"https://www.framer.com/contact/\">contact support</a>.</p>\n            </div>\n\n            <div style=\"display: flex; gap: 10px; width: ${showCrdtButton ? \"380px\" : \"210px\"}\">\n                <button class=\"${button} ${buttonPrimary}\" style=\"width: ${buttonWidth}\" onclick=\"location.reload()\">Reload</button>\n                <button class=\"${button}\" id=\"copyErrorBtn\" style=\"width: ${buttonWidth}\">Copy Error</button>\n                ${crdtSaveButton}\n            </div>\n\n            <div style=\"position: relative; margin-top: 15px\">\n                <textarea readonly style='${detailsStyle}' id=\"details\" spellcheck=\"false\" autocorrect=\"off\" autocapitalize=\"off\" translate=\"no\"></textarea>\n                <div style=\"${fadeStyle}\"></div>\n            </div>\n\n        </div>`\n\n\t\tconst errorText = `${initialError?.message ?? \"Unknown error.\"}\\n${initialError?.stack ?? \"\"}`\n\t\t;(document.querySelector(\"#details\") as HTMLTextAreaElement).value = errorText\n\t\tconst copyBtn = document.getElementById(\"copyErrorBtn\")!\n\t\tcopyBtn.addEventListener(\"click\", async () => {\n\t\t\tawait navigator.clipboard.writeText(errorText)\n\t\t\tcopyBtn.textContent = \"Copied\"\n\t\t\tsetTimeout(() => {\n\t\t\t\tcopyBtn.textContent = \"Copy Error\"\n\t\t\t}, 2000)\n\t\t})\n\n\t\tconst saveCrdtButton = document.getElementById(\"saveCrdtButton\")\n\t\tif (saveCrdtButton) {\n\t\t\tsaveCrdtButton.addEventListener(\"click\", async () => {\n\t\t\t\tif (!crdt || !stores) return\n\n\t\t\t\t// create a link element with store encoded as data url in href\n\t\t\t\tconst json = JSON.stringify(crdt.store.getSerializableRows())\n\t\t\t\tconst blob = new Blob([json], { type: \"application/json\" })\n\t\t\t\tconst url = URL.createObjectURL(blob)\n\t\t\t\tconst a = document.createElement(\"a\")\n\t\t\t\ta.href = url\n\n\t\t\t\t// enable download with a meaningful file name\n\t\t\t\tconst projectName = stores.projectStore.project?.title ?? stores.projectStore.projectId\n\t\t\t\tconst date = new Date().toISOString().split(\"T\")[0]\n\t\t\t\ta.download = `store-${projectName}-${date}.json`\n\n\t\t\t\t// add the link to DOM, force click, clean up\n\t\t\t\tdocument.body.appendChild(a)\n\t\t\t\ta.click()\n\t\t\t\tdocument.body.removeChild(a)\n\t\t\t\tURL.revokeObjectURL(url)\n\t\t\t})\n\t\t}\n\t}\n\n\treturn new Error(`FatalError: ${message}`, { cause: error })\n}\n\nclass RecoveryTool extends withClassDiscriminator(\"RecoveryTool\") implements VekterTool {\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\n\tconstructor(engine: VekterEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t}\n\n\tstartTime = Date.now()\n\tstart() {}\n\tupdate() {\n\t\t// delay 500 millis before re-enabling tooling\n\t\tif (Date.now() - this.startTime < 500) return\n\t\tthis.engine.setTool(Tools.Highlight)\n\t}\n\tstop() {}\n}\n\n/**\n * Try to recover the tree, using different levels. Will return the level it\n * ended up at when trying to recover or throws an Error if recovery fails\n */\nfunction tryErrorRecovery(engine: VekterEngine): void {\n\tengine.tree.lineage.enablePartialScopeAccessChecks = false\n\tengine.stores.treeStore.timeline.saveTimelineDataForRecovery()\n\n\t// The normal case: try to recover the document by starting at the server version.\n\ttry {\n\t\tconst remoteDocument = engine.remoteDocument\n\t\tconst activeScopeId = engine.stores.scopeStore.activeId\n\t\tif (remoteDocument?.canReloadServerDocumentForRecovery()) {\n\t\t\tconst tree = remoteDocument.resetTreesForRecovery(activeScopeId)\n\t\t\tengine.load(tree)\n\t\t\tconsole.warn(\"[repaired] success recovering the server tree.\")\n\t\t\treturn\n\t\t}\n\t\tif (remoteDocument) {\n\t\t\tengine.treeReflectsDocument = false\n\t\t\treturn\n\t\t}\n\t} catch (errorValue) {\n\t\tconst error = reportableError(errorValue)\n\t\tconsole.error(\"remote tree error recovery failed:\", error)\n\t\tthrow fatalError(engine, \"Unable to recover tree.\", error)\n\t}\n\n\t// In offline cases, or debugging, etc. try to recover by fully reloading the engine.tree\n\ttry {\n\t\tconst errors: string[] = []\n\t\tconst json: unknown = JSON.parse(JSON.stringify(engine.tree.toJS()))\n\t\tconst tree = safeLoadDocument(json, engine.componentLoader, errors)\n\t\tengine.load(tree)\n\t\tconsole.warn(\"[repaired] success recovering the local tree.\")\n\t} catch (errorValue) {\n\t\tconst error = reportableError(errorValue)\n\t\tconsole.error(\"local tree error recovery failed:\", error)\n\t\tthrow fatalError(engine, \"Unable to recover tree.\", error)\n\t}\n}\n\nfunction getErrorTags(): ErrorTags {\n\tconst errorRef = randomBase62(5)\n\tconst tags: ErrorTags = {\n\t\t[ReportTag.ErrorRef]: errorRef,\n\t}\n\n\ttry {\n\t\t// join experiments as a string \"a=on; b=off\"\n\t\tconst extraExperiments = getExtraExperiments()\n\n\t\tif (extraExperiments) {\n\t\t\ttags.extraExperiments = extraExperiments\n\t\t}\n\t} catch (e) {\n\t\tconsole.error(\"Error getting tags for error recovery:\", e)\n\t}\n\n\treturn tags\n}\n\nexport function recoverFromError(engine: VekterEngine, error: Error, info?: React.ErrorInfo) {\n\tif (hadFatalError) return\n\n\t// If we tried to recover from an error the previous update, we show a fatal error.\n\tif (engine.scheduler.update - initialEngineUpdateAtError <= 1) {\n\t\tthrow fatalError(engine, \"Crash recovery crashed.\", error)\n\t}\n\n\t// If we tried to recover from an error a short while back, we also show a fatal error.\n\tif (Date.now() - lastError <= 2500) {\n\t\tthrow fatalError(engine, \"Crash recovery happening too fast\", error)\n\t}\n\n\tinitialEngineUpdateAtError = engine.scheduler.update\n\tlastError = Date.now()\n\tinitialError = error\n\n\tif (info) {\n\t\tconst stack = info.componentStack\n\t\t\t?.split(\"\\n\")\n\t\t\t.filter(line => line.length !== 0)\n\t\t\t.join(\"\\n\")\n\n\t\tconsole.warn(`Had Error: ${error.name} -- ${error.message}\\n${stack}\\n`, error)\n\t} else {\n\t\tconsole.warn(`Had Error: ${error.name} -- ${error.message}\\n`, error)\n\t}\n\n\tconst log = getLogger(\"recovery\")\n\n\t// This error mostly happens when something, usually a translation tool, removes a node from the DOM without React\n\t// knowing about it. Later on, if React attempts to remove the same node, it'll fail with this error.\n\t//\n\t// React seems to be recovering from this error just fine (by re-creating/re-mounting the component tree below the\n\t// error boundary), so let's just do the minimum necessary engine recovery, and don't report it as a critical error,\n\t// reset the user state, or show the red bar.\n\tif (isRemoveChildError(error)) {\n\t\tlog.reportError(error, { ...info })\n\t\tengine.scheduler.eventHandlingError = null\n\t\tengine.scheduler.inEventHandling = 0\n\t\tengine.scheduler.inPostProcessing = false\n\t\tengine.scheduler.inRendering = false\n\t\tengine.scheduler.needToolProcessing = false\n\t\tengine.scheduler.needRendering = false\n\t\tengine.scheduler.needReport = false\n\t\treturn\n\t}\n\n\tconst errorTags = getErrorTags()\n\n\t// This matches the user experience (red bar) and avoids missing errors that\n\t// are fixed by the recovery mechanism.\n\tlog.reportCriticalError(error, { ...info }, errorTags)\n\tconst errorId = Sentry.lastEventId()\n\n\t// In-flight plugin methods never resolve through this path; fail them\n\t// fast so awaiting agents don't wait out the 120s backend timeout.\n\tgetHeadlessAPI()?.failPendingMethods(`HeadlessSessionDegraded: recovery from ${error.message}`)\n\n\t// Don't commit, try to continue\n\tengine.tool = new RecoveryTool(engine)\n\n\t// recover the engine, clearing as much state as we can\n\tengine.scheduler.eventHandlingError = null\n\tengine.scheduler.inEventHandling = 1\n\tengine.scheduler.inPostProcessing = false\n\tengine.scheduler.inRendering = false\n\ttry {\n\t\tengine.tree.makeLatest()\n\t} catch (e) {\n\t\tlog.warn(\"error clearing tree state:\", e)\n\t}\n\n\tconst { selectionStore, toolStore, modalStore, popoverStore, documentSettingsStore, treeStore } = engine.stores\n\n\ttry {\n\t\ttreeStore.setHighlight(null)\n\t\tselectionStore.clear()\n\t} catch (e) {\n\t\tlog.warn(\"error clearing selection state:\", e)\n\t}\n\n\ttry {\n\t\ttoolStore.setTool(engine.tool.enum)\n\t} catch (e) {\n\t\tlog.warn(\"error clearing toolstore.tool:\", e)\n\t}\n\n\ttry {\n\t\tmodalStore.dismiss()\n\t\tpopoverStore.active = PopoverType.None\n\t} catch (e) {\n\t\tlog.warn(\"error clearing modal and popover state:\", e)\n\t}\n\n\t// go to a state where engine.load() can be called if needed\n\tengine.scheduler.inEventHandling = 0\n\tengine.scheduler.needToolProcessing = false\n\tengine.scheduler.needRendering = false\n\tengine.scheduler.needReport = false\n\n\t// reset mouse\n\tengine.stores.mouseStore.resetMouse()\n\n\t// NOTE: This will throw if it fails, which will then become a fatal error. Otherwise it will\n\t// have called engine.load() with a recovered tree.\n\ttryErrorRecovery(engine)\n\n\t// Don't override any already showing error.\n\tif (!documentSettingsStore.crashData) {\n\t\tdocumentSettingsStore.crashData = {\n\t\t\tmessage: error.message,\n\t\t\tstack: error.stack,\n\t\t\ttags: errorTags,\n\t\t\terrorRef: errorTags.errorRef,\n\t\t\tsentryErrorId: errorId,\n\t\t}\n\t}\n}\n\n/** For tests that depend on error recovery, they might need to reset the global state. */\nexport function resetErrorRecoveryForTesting(engine?: VekterEngine) {\n\thadFatalError = false\n\tinitialEngineUpdateAtError = -1\n\tlastError = 0\n\tinitialError = undefined\n\tif (engine) {\n\t\tengine.scheduler.hadFatalError = false\n\t}\n}\n\nfunction isRemoveChildError(error: Error): boolean {\n\t// removeChild error is always a \"NotFoundError\" DOMException\n\tif (!(error instanceof DOMException && error.name === \"NotFoundError\")) {\n\t\treturn false\n\t}\n\n\t// Chromium and Firefox have distinct messages to help us identify the removeChild error.\n\tif (\n\t\terror.message ===\n\t\t\t\"Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.\" ||\n\t\terror.message === \"Node.removeChild: The node to be removed is not a child of this node\"\n\t) {\n\t\treturn true\n\t}\n\n\t// Safari has a generic \"The object can not be found here.\" message which is also used for other errors, but on the\n\t// other hand it includes `removeChild@[native code]` in the stack trace, which is perhaps even more elegant than\n\t// checking the message. Sadly, Chromium and Firefox don't seem to include `removeChild` in the stack, so we can't\n\t// use the same trick there.\n\tif (error.stack?.startsWith(\"removeChild@[native code]\")) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n", "import { migrateDocument } from \"@framerjs/document-migrations\"\nimport type { SnapshotNode, SnapshotTree } from \"@framerjs/document-snapshotter\"\nimport { DocumentParser, serializeDocument } from \"@framerjs/document-snapshotter\"\nimport { assert, reportableError } from \"@framerjs/shared\"\nimport { environment } from \"environment/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { isPromise } from \"utils/typeChecks.ts\"\nimport type { VekterEngine } from \"./VekterEngine.ts\"\nimport { recoverFromError, resetErrorRecoveryForTesting } from \"./VekterEngineErrorRecovery.ts\"\nimport { safeLoadDocument } from \"./models/CanvasTree/TreeRepair.ts\"\nimport { TreeTimeline } from \"./models/CanvasTree/TreeTimeline.ts\"\nimport type { CanvasNode, NodeID } from \"./models/CanvasTree/index.ts\"\nimport { CanvasTree } from \"./models/CanvasTree/index.ts\"\nimport { CanvasChildList } from \"./models/CanvasTree/nodes/ChildList.ts\"\nimport { TemplateHelper } from \"./models/CanvasTree/nodes/TemplateHelper.ts\"\nimport { canvasNodeFromValue } from \"./models/CanvasTree/nodes/canvasNodeFromValue.ts\"\nimport { assembleTree, loadOneRootChild, loadPartialDocument } from \"./partialDocument.ts\"\n\nexport type BenchmarkFunction = (testing: EngineTesting, arg: any) => void\n\nclass BenchmarkingSupport {\n\tconstructor(readonly testing: EngineTesting) {}\n\n\tenvironment = environment\n\twasIdleFor = 0\n\n\tidle(millis = 50) {\n\t\tconst start = performance.now()\n\t\tfor (let i = 0; i < 10000; i++) {\n\t\t\tif (performance.now() - start > millis) break\n\t\t}\n\t\tthis.wasIdleFor += performance.now() - start\n\t}\n\n\trunBenchmarkOnce(body: BenchmarkFunction, args: unknown) {\n\t\tbody(this.testing, args)\n\t}\n\n\tbenchmark(body: BenchmarkFunction, args: unknown): number {\n\t\tthis.wasIdleFor = 0\n\t\tlet rounds = 1\n\t\tconst start = performance.now()\n\t\tfor (; rounds <= 100; rounds++) {\n\t\t\tif (rounds > 1) {\n\t\t\t\tthis.idle()\n\t\t\t}\n\t\t\tthis.runBenchmarkOnce(body, args)\n\n\t\t\t// Do at least 3 rounds.\n\t\t\tif (rounds <= 3) continue\n\t\t\t// If we have been going on for longer than 2.5 seconds, stop.\n\t\t\tif (performance.now() - start > 2500 + this.wasIdleFor) break\n\t\t}\n\t\tconst totalTime = performance.now() - start\n\t\treturn (totalTime - this.wasIdleFor) / rounds / 1000\n\t}\n}\n\nexport class EngineTesting {\n\tbenchmarking = new BenchmarkingSupport(this)\n\n\tconstructor(readonly engine: VekterEngine) {}\n\n\t// Process a single mouse state update (Vekter doesn't use mouse events, only state)\n\tdispatchMouseEvent = (\n\t\tx: number,\n\t\ty: number,\n\t\tdown = false,\n\t\taltKey = false,\n\t\tcmdKey = false,\n\t\tshiftKey = false,\n\t\tctrlKey = false,\n\t\tdoubleClick = false,\n\t) => {\n\t\tthis.engine.scheduler.enterEventHandling()\n\n\t\tconst point = Point(x, y)\n\t\tthis.engine.stores.mouseStore.setMousePosition(point, point, altKey, cmdKey, shiftKey, ctrlKey)\n\n\t\tif (down !== !!this.engine.stores.mouseStore.canvasMouseDownPosition) {\n\t\t\tthis.engine.stores.mouseStore.setMouseDown(down)\n\t\t}\n\n\t\tif (doubleClick !== !!this.engine.stores.mouseStore.canvasDoubleClickPosition) {\n\t\t\tthis.engine.stores.mouseStore.setDoubleClick(doubleClick)\n\t\t}\n\n\t\tthis.engine.scheduler.exitEventHandling()\n\n\t\tif (this.engine.scheduler.inEventHandling) return\n\t\tthis.nextFrame()\n\t}\n\n\t// Process a single keyboard event.\n\tdispatchKeyboardEvent = (event: KeyboardEvent) => {\n\t\tthis.engine.scheduler.enterEventHandling()\n\t\ttry {\n\t\t\tif (event.type === \"keydown\") {\n\t\t\t\tthis.engine.stores.mouseStore.onKeyDown(event)\n\t\t\t} else if (event.type === \"keypress\") {\n\t\t\t\tthis.engine.stores.mouseStore.onKeyPress(event)\n\t\t\t} else if (event.type === \"keyup\") {\n\t\t\t\tthis.engine.stores.mouseStore.onKeyUp(event)\n\t\t\t} else {\n\t\t\t\tthrow Error(`Invalid event type \"${event.type}\"`)\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.engine.scheduler.exitEventHandling()\n\t\t}\n\n\t\tif (this.engine.scheduler.inEventHandling) return\n\t\tthis.nextFrame()\n\t}\n\n\t// Must be an arrow to bind `this`\n\tprivate finalizeProcessFrame = (type?: \"nonUserEvent\"): void => {\n\t\tthis.engine.scheduler.exitEventHandling(type)\n\t\tif (this.engine.scheduler.inEventHandling) return\n\t\tthis.nextFrame()\n\t}\n\n\t/**\n\t * Convenience function while testing for processing actions [optionally async]\n\t * To test if your async actions throws, look at https://jestjs.io/docs/expect#tothrowerror\n\t *\n\t * @param func [async] function\n\t * @returns\n\t */\n\tprocessFrame<T>(\n\t\tfunc: () => T,\n\t\ttype?: \"nonUserEvent\",\n\t): Extract<T, PromiseLike<unknown>> extends never ? void : Promise<void> {\n\t\tthis.engine.scheduler.enterEventHandling(type)\n\n\t\t// We're okay with it throwing and bypassing `finalizeProcessFrame`\n\t\tconst result = func()\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: No way around it\n\t\tif (isPromise(result)) return result.finally(this.finalizeProcessFrame) as any\n\n\t\tthis.finalizeProcessFrame(type)\n\n\t\t// biome-ignore lint/suspicious/noExplicitAny: No way around it\n\t\treturn undefined as any\n\t}\n\n\t/**\n\t * Similar to `processFrame`, but resets the engine including pending tree changes when an error\n\t * is thrown. Similar to real life.\n\t */\n\tasync processFrameWithRecovery(func: () => PromiseLike<void>): Promise<void> {\n\t\tconst consoleWarnMock = jest.spyOn(global.console, \"warn\").mockImplementation(() => {})\n\t\tconst consoleErrorMock = jest.spyOn(global.console, \"error\").mockImplementation(() => {})\n\n\t\tthis.engine.scheduler.enterEventHandling()\n\t\ttry {\n\t\t\treturn await func()\n\t\t} catch (error) {\n\t\t\trecoverFromError(this.engine, reportableError(error))\n\t\t\tthrow error\n\t\t} finally {\n\t\t\tthis.engine.scheduler.exitEventHandling()\n\t\t\tresetErrorRecoveryForTesting(this.engine)\n\t\t\tconsoleWarnMock.mockRestore()\n\t\t\tconsoleErrorMock.mockRestore()\n\t\t}\n\t}\n\n\t// After using engine.scheduler.process(...), this will do the processing to end the frame and begin a new one\n\tnextFrame = (idleFrame = false) => {\n\t\tif (!this.engine.scheduler.needToolProcessing) {\n\t\t\tthis.engine.scheduler.enterEventHandling()\n\t\t\tthis.engine.scheduler.exitEventHandling()\n\t\t}\n\n\t\tthis.engine.doToolProcessing()\n\t\tthis.engine.doRendering()\n\t\tthis.engine.doReport(idleFrame)\n\t}\n\n\t// ** Exposed Vekter APIs to access during end-to-end tests or micro benchmarks.\n\n\t/** Will waste a short amount of millis. This is helpful for separating otherwise similar call\n\t * stacks in benchmarks. Also used between the various rounds of the benchmarks. The time wasted\n\t * in this way will not count to the total runtime of the test. */\n\tidle(millis?: number) {\n\t\tthis.benchmarking.idle(millis)\n\t}\n\n\t/** Exposes the assert from \"@framerjs/shared\". */\n\tassert(condition: any, ...msg: any[]) {\n\t\tassert(condition, ...msg)\n\t}\n\n\tmigrateDocument(json: unknown) {\n\t\treturn migrateDocument(json)\n\t}\n\n\t// Serialize a document JSON into a Byte Addressable Document.\n\tserializeDocument(json: unknown) {\n\t\treturn serializeDocument(json as SnapshotTree)\n\t}\n\n\tjsonToCanvasTree(json: unknown) {\n\t\treturn safeLoadDocument(json, this.engine.componentLoader, [])\n\t}\n\n\tprivate lastPartiallyLoadedDocument: CanvasTree | undefined\n\tloadPartialDocument(data: string, scopeIds: NodeID[]) {\n\t\tconst parser = new DocumentParser(data)\n\n\t\tthis.lastPartiallyLoadedDocument = loadPartialDocument(parser, this.engine.componentLoader, scopeIds)\n\t\tassert(!this.lastPartiallyLoadedDocument.hasUncommittedChanges())\n\n\t\treturn { tree: this.lastPartiallyLoadedDocument, parser }\n\t}\n\n\tloadRemainingDocument(parser: DocumentParser) {\n\t\tassert(this.lastPartiallyLoadedDocument, \"have not called loadPartialDocument yet\")\n\n\t\tconst tree = this.lastPartiallyLoadedDocument\n\t\tthis.lastPartiallyLoadedDocument = undefined\n\t\tconst loadedPages = new Map<string, CanvasNode>()\n\n\t\tlet isDoneProcessing = false\n\n\t\twhile (!isDoneProcessing) {\n\t\t\tisDoneProcessing = loadOneRootChild(parser, loadedPages)\n\t\t\tif (isDoneProcessing) break\n\t\t}\n\n\t\treturn assembleTree(tree, this.engine.componentLoader, loadedPages)\n\t}\n\n\tloadDocument(json: SnapshotTree) {\n\t\tconst root = json.root\n\t\tassert(root.children, \"root does not contain children\")\n\n\t\tconst children = root.children.map((node: SnapshotNode) => {\n\t\t\tconst result = canvasNodeFromValue(node, root.id)\n\t\t\tassert(result, \"error loading canvas node:\", node.id)\n\t\t\treturn result\n\t\t})\n\n\t\tconst rootNode = canvasNodeFromValue({ ...root, children: [] })\n\t\tassert(rootNode, \"error loading root node:\", root.id)\n\t\trootNode.children = new CanvasChildList(children)\n\n\t\tlet canvasTree = CanvasTree.createByAdoptingRoot(rootNode)\n\t\tcanvasTree = TemplateHelper.treeDidLoad(canvasTree, this.engine.componentLoader, []).didNonLinearMove(\n\t\t\tthis.engine.componentLoader,\n\t\t)\n\n\t\treturn canvasTree\n\t}\n\n\tnewTreeTimeline(tree: CanvasTree): TreeTimeline {\n\t\treturn new TreeTimeline(tree, this.engine.componentLoader)\n\t}\n\n\tloadCrdtDocument(tree: CanvasTree) {\n\t\tthis.engine.stores.treeStore.mode = \"crdt\"\n\t\tconst committer = this.engine.stores.treeStore.crdtTimeline\n\n\t\tthis.engine.load(tree)\n\t\tthis.nextFrame()\n\n\t\tcommitter.store.setObject(tree.root.id, tree.root.toJS())\n\t\tcommitter.store.setRoot(tree.root.id)\n\t\tcommitter.store.setVersion(tree.serializationVersion)\n\n\t\treturn committer.store.toBuffer()\n\t}\n}\n", "import type { LockMessage } from \"socket/types.ts\"\n\nexport class LockState {\n\tconstructor(\n\t\tpublic id: string,\n\t\tpublic userId: string,\n\t\tpublic expires: number,\n\t) {}\n\thasExpired(now: number) {\n\t\treturn this.expires < now\n\t}\n}\n\nexport class RemoteLocks {\n\tknown = new Map<string, LockState>()\n\n\tconstructor(public userId: string) {}\n\n\tregister(lockId: string, userId: string, time: number) {\n\t\tif (time === 0) {\n\t\t\tthis.known.delete(lockId)\n\t\t} else {\n\t\t\tthis.known.set(lockId, new LockState(lockId, userId, performance.now() + time))\n\t\t}\n\t}\n\n\tclaim(lockId: string, time = 30): LockMessage | null {\n\t\t// A time of 0 is meant to release the lock, but if there is no known lock there's nothing to release\n\t\tif (!this.getLockById(lockId) && time === 0) return null\n\t\tif (this.isTaken(lockId)) return null\n\t\tconst id = this.userId\n\t\tthis.register(lockId, id, time)\n\t\treturn { type: \"lock\", value: { lockId, time } }\n\t}\n\n\tgetLockById(lockId: string): LockState | undefined {\n\t\tconst lock = this.known.get(lockId)\n\t\tif (!lock) return undefined\n\t\tif (lock.hasExpired(performance.now())) {\n\t\t\tthis.known.delete(lock.id)\n\t\t\treturn undefined\n\t\t}\n\t\treturn lock\n\t}\n\n\tisOurs(lockId: string): boolean {\n\t\tconst lock = this.getLockById(lockId)\n\t\treturn !!lock && lock.userId === this.userId\n\t}\n\n\tisTaken(lockId: string): boolean {\n\t\tconst lock = this.getLockById(lockId)\n\t\treturn !!lock && lock.userId !== this.userId\n\t}\n}\n", "import { getLogger } from \"@framerjs/shared\"\nimport * as idb from \"@iamakulov/idb-keyval\"\n\nconst log = getLogger(\"LocalCache\")\n\nexport type BackendType = \"idb\" | \"cache-api\" | \"opfs\"\n\n/**\n * A value read from the backend together with the number of bytes it\n * occupies in storage. Exact semantics are backend-dependent:\n *  - `idb`: approximated from the parsed value (structured-clone size is\n *    opaque to us), so this is a best-effort estimate.\n *  - `cache-api`: exact byte length of the stored response body.\n *  - `opfs`: exact file size on disk (including the 1-byte type prefix).\n */\nexport interface ValueWithStorageSize {\n\tvalue: unknown\n\tstorageBytes: number\n}\n\nexport interface LocalCacheDataBackend {\n\treadonly type: BackendType\n\t/**\n\t * The backend's handle to the shared `crdt-sync-cache`/`crdt-data` IDB\n\t * object store. Every backend opens this store for its own bookkeeping\n\t * (primary data for `idb`, reference rows for `cache-api`/`opfs`), and\n\t * the cache-meta helpers (`readCacheMeta`, `writeCacheMeta`, \u2026) write\n\t * into it as well. Exposing it on the interface lets callers do meta\n\t * reads/writes without any module-level `idb.createStore` side-effects\n\t * at import time.\n\t */\n\treadonly idbStore: idb.UseStore\n\tget<T = unknown>(key: string): Promise<T | undefined>\n\tgetAsBlob(key: string): Promise<Blob | undefined>\n\tgetMany(keys: string[]): Promise<unknown[]>\n\t/**\n\t * Like {@link getMany}, but also reports the storage footprint of each\n\t * value. Missing keys are returned as `undefined` at the corresponding\n\t * index. Use when read-path telemetry wants to know how much space the\n\t * cache occupies on disk.\n\t */\n\tgetManyWithSize(keys: string[]): Promise<(ValueWithStorageSize | undefined)[]>\n\tsetMany(entries: [string, unknown][]): Promise<void>\n\tdelMany(keys: string[]): Promise<void>\n}\n\n/**\n * Best-effort byte count for a value as it would live in storage. Used by\n * backends that can't cheaply ask their store for an exact size (IDB's\n * structured clone, and for in-memory pending data we haven't flushed yet).\n */\nexport function estimateStorageBytes(value: unknown): number {\n\tif (value === undefined || value === null) return 0\n\tif (value instanceof Uint8Array) return value.byteLength\n\tif (value instanceof ArrayBuffer) return value.byteLength\n\treturn new TextEncoder().encode(JSON.stringify(value) ?? \"\").length\n}\n\nfunction toBlob(value: unknown): Blob {\n\tif (value instanceof Uint8Array) {\n\t\treturn new Blob([value as Uint8Array<ArrayBuffer>], { type: \"application/octet-stream\" })\n\t}\n\tif (value instanceof ArrayBuffer) {\n\t\treturn new Blob([new Uint8Array(value)], { type: \"application/octet-stream\" })\n\t}\n\n\tif (typeof value === \"string\") {\n\t\treturn new Blob([`${value}\\n`], { type: \"text/plain;charset=utf-8\" })\n\t}\n\n\tif (typeof value === \"number\" || typeof value === \"boolean\" || value === null || value === undefined) {\n\t\treturn new Blob([`${String(value ?? \"\")}\\n`], { type: \"text/plain;charset=utf-8\" })\n\t}\n\n\treturn new Blob([JSON.stringify(value, null, \"\\t\")], { type: \"application/json;charset=utf-8\" })\n}\n\n// ---------------------------------------------------------------------------\n// IndexedDB \u2013 stores values directly (current behaviour)\n// ---------------------------------------------------------------------------\n\nexport class IdbLocalCacheDataBackend implements LocalCacheDataBackend {\n\treadonly type = \"idb\" as const\n\treadonly idbStore = idb.createStore(\"crdt-sync-cache\", \"crdt-data\")\n\n\tasync get<T>(key: string): Promise<T | undefined> {\n\t\treturn idb.get<T>(key, this.idbStore)\n\t}\n\n\tasync getAsBlob(key: string): Promise<Blob | undefined> {\n\t\tconst value = await this.get(key)\n\t\tif (value === undefined) return undefined\n\t\treturn toBlob(value)\n\t}\n\n\tasync getMany(keys: string[]): Promise<unknown[]> {\n\t\treturn idb.getMany(keys, this.idbStore)\n\t}\n\n\tasync getManyWithSize(keys: string[]): Promise<(ValueWithStorageSize | undefined)[]> {\n\t\tconst values = await idb.getMany(keys, this.idbStore)\n\t\treturn values.map(value => (value === undefined ? undefined : { value, storageBytes: estimateStorageBytes(value) }))\n\t}\n\n\tasync setMany(entries: [string, unknown][]): Promise<void> {\n\t\tawait idb.setMany(entries, this.idbStore)\n\t}\n\n\tasync delMany(keys: string[]): Promise<void> {\n\t\tawait idb.delMany(keys, this.idbStore)\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Cache API \u2013 stores values as Response objects, writes references to IDB\n// ---------------------------------------------------------------------------\n\nclass CacheApiLocalCacheDataBackend implements LocalCacheDataBackend {\n\treadonly type = \"cache-api\" as const\n\treadonly idbStore = idb.createStore(\"crdt-sync-cache\", \"crdt-data\")\n\tprivate readonly cacheName = \"crdt-sync-cache\"\n\n\tprivate url(key: string): string {\n\t\treturn `https://local-cache.invalid/${encodeURIComponent(key)}`\n\t}\n\n\tprivate async open(): Promise<Cache> {\n\t\treturn caches.open(this.cacheName)\n\t}\n\n\tprivate toResponse(value: unknown): Response {\n\t\tif (value instanceof Uint8Array) {\n\t\t\treturn new Response(new Blob([value as Uint8Array<ArrayBuffer>]), {\n\t\t\t\theaders: { \"X-Value-Type\": \"bytes\" },\n\t\t\t})\n\t\t}\n\t\treturn new Response(JSON.stringify(value), {\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t})\n\t}\n\n\tprivate async fromResponse<T = unknown>(response: Response): Promise<T> {\n\t\tconst value: unknown =\n\t\t\tresponse.headers.get(\"X-Value-Type\") === \"bytes\"\n\t\t\t\t? new Uint8Array(await response.arrayBuffer())\n\t\t\t\t: await response.json()\n\t\treturn value as T\n\t}\n\n\tasync get<T>(key: string): Promise<T | undefined> {\n\t\tconst cache = await this.open()\n\t\tconst response = await cache.match(this.url(key))\n\t\tif (!response) return undefined\n\t\treturn this.fromResponse<T>(response)\n\t}\n\n\tasync getAsBlob(key: string): Promise<Blob | undefined> {\n\t\tconst value = await this.get(key)\n\t\tif (value === undefined) return undefined\n\t\treturn toBlob(value)\n\t}\n\n\tasync getMany(keys: string[]): Promise<unknown[]> {\n\t\tconst cache = await this.open()\n\t\treturn Promise.all(\n\t\t\tkeys.map(async key => {\n\t\t\t\tconst response = await cache.match(this.url(key))\n\t\t\t\tif (!response) return undefined\n\t\t\t\treturn this.fromResponse(response)\n\t\t\t}),\n\t\t)\n\t}\n\n\tasync getManyWithSize(keys: string[]): Promise<(ValueWithStorageSize | undefined)[]> {\n\t\tconst cache = await this.open()\n\t\treturn Promise.all(\n\t\t\tkeys.map(async key => {\n\t\t\t\tconst response = await cache.match(this.url(key))\n\t\t\t\tif (!response) return undefined\n\t\t\t\t// Consume the body once as raw bytes so we can both report\n\t\t\t\t// the exact stored length and decode it.\n\t\t\t\tconst buffer = await response.arrayBuffer()\n\t\t\t\tconst storageBytes = buffer.byteLength\n\t\t\t\tconst value: unknown =\n\t\t\t\t\tresponse.headers.get(\"X-Value-Type\") === \"bytes\"\n\t\t\t\t\t\t? new Uint8Array(buffer)\n\t\t\t\t\t\t: JSON.parse(new TextDecoder().decode(buffer))\n\t\t\t\treturn { value, storageBytes }\n\t\t\t}),\n\t\t)\n\t}\n\n\tasync setMany(entries: [string, unknown][]): Promise<void> {\n\t\tconst cache = await this.open()\n\t\tconst refs: [string, string][] = []\n\t\tfor (const [key, value] of entries) {\n\t\t\tawait cache.put(this.url(key), this.toResponse(value))\n\t\t\trefs.push([key, `cache:${this.cacheName}/${key}`])\n\t\t}\n\t\tawait idb.setMany(refs, this.idbStore)\n\t}\n\n\tasync delMany(keys: string[]): Promise<void> {\n\t\t// First clear the idb, but temporarily ignore the error, rethrowing it in the end.\n\t\tlet hadError: unknown = undefined\n\t\ttry {\n\t\t\tawait idb.delMany(keys, this.idbStore)\n\t\t} catch (error) {\n\t\t\thadError = error\n\t\t}\n\t\tconst cache = await this.open()\n\t\tawait Promise.all(keys.map(key => cache.delete(this.url(key))))\n\t\tif (hadError) throw hadError\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// OPFS (Origin Private File System) \u2013 stores values as files, writes\n// references to IDB. Uses a type-prefix byte to distinguish binary from JSON.\n// ---------------------------------------------------------------------------\n\nconst OPFS_JSON_PREFIX = 0x00\nconst OPFS_BINARY_PREFIX = 0x01\n\nclass OpfsLocalCacheDataBackend implements LocalCacheDataBackend {\n\treadonly type = \"opfs\" as const\n\treadonly idbStore = idb.createStore(\"crdt-sync-cache\", \"crdt-data\")\n\tprivate readonly directoryName = \"crdt-sync-cache\"\n\n\tprivate async getDirectory(): Promise<FileSystemDirectoryHandle> {\n\t\tconst root = await navigator.storage.getDirectory()\n\t\treturn root.getDirectoryHandle(this.directoryName, { create: true })\n\t}\n\n\tprivate fileName(key: string): string {\n\t\treturn encodeURIComponent(key)\n\t}\n\n\tprivate encode(value: unknown): Uint8Array<ArrayBuffer> {\n\t\tif (value instanceof Uint8Array) {\n\t\t\tconst result = new Uint8Array(value.length + 1)\n\t\t\tresult[0] = OPFS_BINARY_PREFIX\n\t\t\tresult.set(value, 1)\n\t\t\treturn result\n\t\t}\n\t\tconst json = new TextEncoder().encode(JSON.stringify(value))\n\t\tconst result = new Uint8Array(json.length + 1)\n\t\tresult[0] = OPFS_JSON_PREFIX\n\t\tresult.set(json, 1)\n\t\treturn result\n\t}\n\n\tprivate decode<T = unknown>(data: Uint8Array): T {\n\t\tconst value: unknown =\n\t\t\tdata[0] === OPFS_BINARY_PREFIX ? data.slice(1) : JSON.parse(new TextDecoder().decode(data.subarray(1)))\n\t\treturn value as T\n\t}\n\n\tasync get<T>(key: string): Promise<T | undefined> {\n\t\ttry {\n\t\t\tconst dir = await this.getDirectory()\n\t\t\tconst handle = await dir.getFileHandle(this.fileName(key))\n\t\t\tconst file = await handle.getFile()\n\t\t\treturn this.decode<T>(new Uint8Array(await file.arrayBuffer()))\n\t\t} catch (error) {\n\t\t\tif (error instanceof DOMException && error.name === \"NotFoundError\") {\n\t\t\t\tlog.debug(\"opfs get: key not found:\", key)\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync getAsBlob(key: string): Promise<Blob | undefined> {\n\t\tconst value = await this.get(key)\n\t\tif (value === undefined) return undefined\n\t\treturn toBlob(value)\n\t}\n\n\tasync getMany(keys: string[]): Promise<unknown[]> {\n\t\treturn Promise.all(keys.map(key => this.get(key)))\n\t}\n\n\tasync getManyWithSize(keys: string[]): Promise<(ValueWithStorageSize | undefined)[]> {\n\t\treturn Promise.all(\n\t\t\tkeys.map(async key => {\n\t\t\t\ttry {\n\t\t\t\t\tconst dir = await this.getDirectory()\n\t\t\t\t\tconst handle = await dir.getFileHandle(this.fileName(key))\n\t\t\t\t\tconst file = await handle.getFile()\n\t\t\t\t\tconst storageBytes = file.size\n\t\t\t\t\tconst value: unknown = this.decode(new Uint8Array(await file.arrayBuffer()))\n\t\t\t\t\treturn { value, storageBytes }\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof DOMException && error.name === \"NotFoundError\") {\n\t\t\t\t\t\tlog.debug(\"opfs getManyWithSize: key not found:\", key)\n\t\t\t\t\t\treturn undefined\n\t\t\t\t\t}\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tasync setMany(entries: [string, unknown][]): Promise<void> {\n\t\tconst dir = await this.getDirectory()\n\t\tconst refs: [string, string][] = []\n\t\tfor (const [key, value] of entries) {\n\t\t\tconst handle = await dir.getFileHandle(this.fileName(key), { create: true })\n\t\t\t// eslint-disable-next-line framer-studio/tscompat -- guarded by isBackendSupported(\"opfs\")\n\t\t\tconst writable = await handle.createWritable()\n\t\t\t// eslint-disable-next-line framer-studio/tscompat -- guarded by isBackendSupported(\"opfs\")\n\t\t\tawait writable.write(new Blob([this.encode(value)]))\n\t\t\t// eslint-disable-next-line framer-studio/tscompat -- guarded by isBackendSupported(\"opfs\")\n\t\t\tawait writable.close()\n\t\t\trefs.push([key, `opfs:${this.directoryName}/${key}`])\n\t\t}\n\t\tawait idb.setMany(refs, this.idbStore)\n\t}\n\n\tasync delMany(keys: string[]): Promise<void> {\n\t\t// First clear the idb, but temporarily ignore the error, rethrowing it in the end.\n\t\tlet hadError: unknown = undefined\n\t\ttry {\n\t\t\tawait idb.delMany(keys, this.idbStore)\n\t\t} catch (error) {\n\t\t\thadError = error\n\t\t}\n\n\t\tconst dir = await this.getDirectory()\n\t\tawait Promise.all(\n\t\t\tkeys.map(async key => {\n\t\t\t\ttry {\n\t\t\t\t\tawait dir.removeEntry(this.fileName(key))\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof DOMException && error.name === \"NotFoundError\") {\n\t\t\t\t\t\tlog.debug(\"opfs delMany: file not found:\", key)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t\tif (hadError) throw hadError\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Configuration \u2013 change BACKEND_TYPE to benchmark a different backend.\n// ---------------------------------------------------------------------------\n\nexport const BACKEND_TYPE: BackendType = \"opfs\"\n\nconst BACKEND_OVERRIDE_KEY = \"crdt-backend-override\"\nconst ALL_BACKEND_TYPES: BackendType[] = [\"idb\", \"cache-api\", \"opfs\"]\n\nexport function isBackendType(value: string): value is BackendType {\n\treturn ALL_BACKEND_TYPES.includes(value as BackendType)\n}\n\nexport function getBackendOverride(): BackendType | undefined {\n\tconst stored = localStorage.getItem(BACKEND_OVERRIDE_KEY)\n\tif (stored && isBackendType(stored)) return stored\n\treturn undefined\n}\n\nexport function setBackendOverride(type: BackendType): void {\n\tlocalStorage.setItem(BACKEND_OVERRIDE_KEY, type)\n}\n\nexport function clearBackendOverride(): void {\n\tlocalStorage.removeItem(BACKEND_OVERRIDE_KEY)\n}\n\nconst FALLBACK_ORDER: BackendType[] = [\"opfs\", \"cache-api\", \"idb\"]\n\nfunction isBackendSupported(type: BackendType): boolean {\n\tswitch (type) {\n\t\tcase \"opfs\":\n\t\t\treturn (\n\t\t\t\ttypeof navigator !== \"undefined\" &&\n\t\t\t\ttypeof navigator.storage?.getDirectory === \"function\" &&\n\t\t\t\t\"FileSystemFileHandle\" in globalThis &&\n\t\t\t\t// eslint-disable-next-line framer-studio/tscompat -- feature-detecting createWritable\n\t\t\t\ttypeof FileSystemFileHandle.prototype.createWritable === \"function\"\n\t\t\t)\n\t\tcase \"cache-api\":\n\t\t\treturn typeof caches !== \"undefined\"\n\t\tcase \"idb\":\n\t\t\treturn typeof indexedDB !== \"undefined\"\n\t}\n}\n\nfunction resolveSupportedBackendType(preferred: BackendType): BackendType {\n\tif (isBackendSupported(preferred)) return preferred\n\tfor (const candidate of FALLBACK_ORDER) {\n\t\tif (isBackendSupported(candidate)) return candidate\n\t}\n\treturn \"idb\"\n}\n\nfunction getEffectiveBackendType(): BackendType {\n\treturn resolveSupportedBackendType(getBackendOverride() ?? BACKEND_TYPE)\n}\n\nexport function createLocalCacheDataBackend(type: BackendType = getEffectiveBackendType()): LocalCacheDataBackend {\n\tswitch (type) {\n\t\tcase \"idb\":\n\t\t\treturn new IdbLocalCacheDataBackend()\n\t\tcase \"cache-api\":\n\t\t\treturn new CacheApiLocalCacheDataBackend()\n\t\tcase \"opfs\":\n\t\t\treturn new OpfsLocalCacheDataBackend()\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Per-project cache metadata.\n//\n// These live directly in the shared `crdt-sync-cache`/`crdt-data` IDB store\n// (alongside the backend reference rows) so the initial readData path can\n// discover which backend holds the snapshot/rows BEFORE touching that\n// backend, and so the authoritative tree version survives backend swaps.\n// Only the snapshot and row payloads go through the configurable data\n// backend; everything else \u2014 including `snapshot-version` and `version` \u2014\n// lives directly in IDB.\n//\n// The meta helpers take an explicit `idb.UseStore` handle rather than\n// reading from a module-level `idb.createStore(...)` constant: that\n// previous shape kicked off `indexedDB.open(...)` (and touched\n// `navigator.userAgent`) at import time, which is unsafe in Node / test\n// environments and wasteful in any context that doesn't end up reading the\n// cache. Callers pass `backend.idbStore`, which is opened lazily inside\n// the backend's constructor.\n//\n// The `crdt-tree-version:<projectId>` mirror in localStorage remains for\n// synchronous reads during early page bootstrap.\n// ---------------------------------------------------------------------------\n\nconst META_BACKEND_SUFFIX = \":backend\"\nconst META_LAST_UPDATED_SUFFIX = \":last-accessed\"\nconst META_DATA_MODEL_SUFFIX = \":data-model\"\nconst META_SNAPSHOT_VERSION_SUFFIX = \":snapshot-version\"\nconst META_VERSION_SUFFIX = \":version\"\n\nexport const META_KEY_SUFFIXES = [\n\tMETA_BACKEND_SUFFIX,\n\tMETA_LAST_UPDATED_SUFFIX,\n\tMETA_DATA_MODEL_SUFFIX,\n\tMETA_SNAPSHOT_VERSION_SUFFIX,\n\tMETA_VERSION_SUFFIX,\n] as const\n\ninterface CacheMeta {\n\tbackend: BackendType | undefined\n\tlastUpdatedAt: number | undefined\n\tdataModel: number | undefined\n\tsnapshotVersion: number | undefined\n\tversion: number | undefined\n}\n\nfunction backendMetaKey(projectId: string): string {\n\treturn `${projectId}${META_BACKEND_SUFFIX}`\n}\nfunction lastUpdatedMetaKey(projectId: string): string {\n\treturn `${projectId}${META_LAST_UPDATED_SUFFIX}`\n}\nfunction dataModelMetaKey(projectId: string): string {\n\treturn `${projectId}${META_DATA_MODEL_SUFFIX}`\n}\nfunction snapshotVersionMetaKey(projectId: string): string {\n\treturn `${projectId}${META_SNAPSHOT_VERSION_SUFFIX}`\n}\nfunction versionMetaKey(projectId: string): string {\n\treturn `${projectId}${META_VERSION_SUFFIX}`\n}\n\nexport async function readCacheMeta(projectId: string, store: idb.UseStore): Promise<CacheMeta> {\n\tconst [backend, lastUpdatedAt, dataModel, snapshotVersion, version] = await idb.getMany(\n\t\t[\n\t\t\tbackendMetaKey(projectId),\n\t\t\tlastUpdatedMetaKey(projectId),\n\t\t\tdataModelMetaKey(projectId),\n\t\t\tsnapshotVersionMetaKey(projectId),\n\t\t\tversionMetaKey(projectId),\n\t\t],\n\t\tstore,\n\t)\n\treturn {\n\t\tbackend: typeof backend === \"string\" && isBackendType(backend) ? backend : undefined,\n\t\tlastUpdatedAt: typeof lastUpdatedAt === \"number\" ? lastUpdatedAt : undefined,\n\t\tdataModel: typeof dataModel === \"number\" ? dataModel : undefined,\n\t\tsnapshotVersion: typeof snapshotVersion === \"number\" ? snapshotVersion : undefined,\n\t\tversion: typeof version === \"number\" ? version : undefined,\n\t}\n}\n\nexport async function writeCacheMeta(projectId: string, meta: Partial<CacheMeta>, store: idb.UseStore): Promise<void> {\n\tconst entries: [string, unknown][] = []\n\tif (meta.backend !== undefined) entries.push([backendMetaKey(projectId), meta.backend])\n\tif (meta.lastUpdatedAt !== undefined) entries.push([lastUpdatedMetaKey(projectId), meta.lastUpdatedAt])\n\tif (meta.dataModel !== undefined) entries.push([dataModelMetaKey(projectId), meta.dataModel])\n\tif (meta.snapshotVersion !== undefined) entries.push([snapshotVersionMetaKey(projectId), meta.snapshotVersion])\n\tif (meta.version !== undefined) entries.push([versionMetaKey(projectId), meta.version])\n\tif (entries.length === 0) return\n\tawait idb.setMany(entries, store)\n}\n\nexport async function readLastUpdated(projectId: string, store: idb.UseStore): Promise<number | undefined> {\n\tconst value = await idb.get(lastUpdatedMetaKey(projectId), store)\n\treturn typeof value === \"number\" ? value : undefined\n}\n\nexport async function readCacheTreeVersion(projectId: string, store: idb.UseStore): Promise<number | undefined> {\n\tconst value = await idb.get(versionMetaKey(projectId), store)\n\treturn typeof value === \"number\" ? value : undefined\n}\n\nexport async function deleteCacheMeta(projectId: string, store: idb.UseStore): Promise<void> {\n\tawait idb.delMany(\n\t\t[\n\t\t\tbackendMetaKey(projectId),\n\t\t\tlastUpdatedMetaKey(projectId),\n\t\t\tdataModelMetaKey(projectId),\n\t\t\tsnapshotVersionMetaKey(projectId),\n\t\t\tversionMetaKey(projectId),\n\t\t],\n\t\tstore,\n\t)\n}\n", "import { getLogger, schedulerYield } from \"@framerjs/shared\"\nimport * as idb from \"@iamakulov/idb-keyval\"\nimport { accessTokenRefresher } from \"web/lib/accessTokenRefresherWeb.ts\"\nimport { getMultiplayerServiceURL } from \"web/lib/multiplayerService.ts\"\nimport { META_KEY_SUFFIXES, readLastUpdated } from \"./LocalCacheDataBackend.ts\"\n\nconst log = getLogger(\"LocalCacheMaintenance\")\n\n// Snapshot refresh support.\n\nconst SNAPSHOT_REFRESH_ROW_THRESHOLD = 10_000\nconst SNAPSHOT_REFRESH_COOLDOWN_MS = 24 * 60 * 60 * 1000\n/** Require no addRows activity for this long before attempting snapshot refresh. */\nconst SNAPSHOT_REFRESH_QUIET_PERIOD_MS = 1 * 60 * 1000\nconst SNAPSHOT_REFRESH_FETCH_TIMEOUT_MS = 30_000\nconst SNAPSHOT_REFRESH_LAST_RUN_PREFIX = \"crdt-snapshot-refresh-last-run:\"\n\ninterface SnapshotRefreshContext {\n\tprojectId: string\n\tisMPSSocket: boolean\n\tisUserIdle: () => boolean\n\thasPending: boolean\n\tlastAddRowsAt: number\n\tgetCachedTreeVersion(): number\n\treadStoredRowCount(): Promise<number>\n\tapplySnapshotRefresh(snapshot: Uint8Array, snapshotVersion: number): Promise<void>\n}\n\nconst VERSION_ETAG_REGEX = /Version-(\\d+)/u\n\ninterface LatestSnapshot {\n\tsnapshot: Uint8Array\n\tversion: number\n}\n\nasync function fetchLatestSnapshot(\n\tprojectId: string,\n\tisMPSSocket: boolean,\n\tsignal?: AbortSignal,\n): Promise<LatestSnapshot | undefined> {\n\tconst path = `/projects/${projectId}/tree/latest`\n\t// TODO: Remove the conditional once we've fully migrated to FramerMultiplayerService\n\tconst url = isMPSSocket ? new URL(getMultiplayerServiceURL(path)) : new URL(path, window.location.href)\n\tconst response = await fetch(url, { ...(await accessTokenRefresher.withAuthorizationHeader({})), signal })\n\tif (!response.ok) return undefined\n\n\tconst etag = response.headers.get(\"etag\") || \"\"\n\tconst version = Number.parseInt(etag.match(VERSION_ETAG_REGEX)?.[1] ?? \"0\", 10)\n\tif (!Number.isFinite(version) || version <= 0) return undefined\n\n\tconst snapshot = new Uint8Array(await response.arrayBuffer())\n\tif (snapshot.byteLength === 0) return undefined\n\treturn { snapshot, version }\n}\n\n/**\n * Replaces the cached snapshot with a fresh one from the server.\n *\n * Runs at most once per day. And only if we have a decent amount of rows cached. The goal is to not\n * accumulate a large number of rows, as that gets slower and slower to open.\n *\n * The caller is responsible for managing any write-blocking flags around this\n * call (see {@link LocalCache.runSnapshotRefresh}).\n */\nexport async function performSnapshotRefresh(\n\tcontext: SnapshotRefreshContext,\n\tversionAtStart: number,\n): Promise<boolean> {\n\tconst now = Date.now()\n\tconst cooldownKey = `${SNAPSHOT_REFRESH_LAST_RUN_PREFIX}${context.projectId}`\n\n\tconst lastRun = localStorage.getItem(cooldownKey)\n\tif (lastRun && now - Number(lastRun) < SNAPSHOT_REFRESH_COOLDOWN_MS) return true\n\n\tif (context.hasPending) return true\n\tif (context.lastAddRowsAt > 0 && now - context.lastAddRowsAt < SNAPSHOT_REFRESH_QUIET_PERIOD_MS) return true\n\n\tconst rowCount = await context.readStoredRowCount()\n\tif (rowCount < SNAPSHOT_REFRESH_ROW_THRESHOLD) {\n\t\tlocalStorage.setItem(cooldownKey, now.toString())\n\t\treturn true\n\t}\n\n\tif (!context.isUserIdle()) return false\n\n\tlog.debug(\"starting snapshot refresh for project:\", context.projectId, \"rows:\", rowCount)\n\n\tconst abortController = new AbortController()\n\tconst fetchTimeoutId = setTimeout(() => abortController.abort(), SNAPSHOT_REFRESH_FETCH_TIMEOUT_MS)\n\ttry {\n\t\t// If anything goes wrong, we try again after 10% of the cooldown period has passed.\n\t\tlocalStorage.setItem(cooldownKey, (now - SNAPSHOT_REFRESH_COOLDOWN_MS * 0.9).toString())\n\n\t\tlet result: LatestSnapshot | undefined\n\t\ttry {\n\t\t\tresult = await fetchLatestSnapshot(context.projectId, context.isMPSSocket, abortController.signal)\n\t\t} catch (error) {\n\t\t\tlog.warn(\"snapshot refresh: fetch failed:\", error)\n\t\t\treturn true\n\t\t}\n\n\t\tif (!result) {\n\t\t\tlog.warn(\"snapshot refresh: server returned no snapshot\")\n\t\t\treturn true\n\t\t}\n\n\t\tconst versionNow = context.getCachedTreeVersion()\n\t\tconst snapshotVersion = result.version\n\n\t\tif (snapshotVersion < versionAtStart) {\n\t\t\t// Server returned a snapshot strictly behind what we already have\n\t\t\t// (CDN staleness, replica lag, etc.). Applying it could only\n\t\t\t// regress and yields no compaction win \u2014 skip until next attempt.\n\t\t\tlog.debug(\"snapshot refresh aborted: snapshot version\", snapshotVersion, \"behind cache version\", versionAtStart)\n\t\t} else {\n\t\t\t// Rows are stored as version-tagged batches, so applySnapshotRefresh\n\t\t\t// can split them at any version boundary. This handles all cases:\n\t\t\t//   - snapshotVersion >= versionNow (snapshot covers everything pending)\n\t\t\t//   - versionAtStart <= snapshotVersion <  versionNow (rows arrived during fetch\n\t\t\t//     and span the snapshot's version; surviving batches > S are\n\t\t\t//     kept).\n\t\t\tawait context.applySnapshotRefresh(result.snapshot, snapshotVersion)\n\t\t\tlog.debug(\n\t\t\t\t\"snapshot refresh complete: snapshot at version\",\n\t\t\t\tsnapshotVersion,\n\t\t\t\t\"kept rows up to version\",\n\t\t\t\tMath.max(versionNow, snapshotVersion),\n\t\t\t)\n\t\t}\n\n\t\tlocalStorage.setItem(cooldownKey, now.toString())\n\n\t\treturn true\n\t} finally {\n\t\tclearTimeout(fetchTimeoutId)\n\t}\n}\n\n// Global cache eviction support.\n\nconst EVICTION_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000\n\nconst TREE_VERSION_PREFIX = \"crdt-tree-version:\"\n\n// Legacy prefixes: these live in IDB now but may still be present in\n// localStorage from older sessions. Kept in CRDT_KEY_PREFIXES so the debug\n// \"clear everything\" path can sweep them up.\nconst LEGACY_LAST_ACCESSED_PREFIX = \"crdt-last-accessed:\"\nconst LEGACY_BACKEND_PREFIX = \"crdt-backend:\"\nconst LEGACY_DATA_MODEL_PREFIX = \"crdt-data-model:\"\n\nconst CRDT_KEY_PREFIXES = [\n\tTREE_VERSION_PREFIX,\n\tLEGACY_LAST_ACCESSED_PREFIX,\n\tLEGACY_BACKEND_PREFIX,\n\tLEGACY_DATA_MODEL_PREFIX,\n\tSNAPSHOT_REFRESH_LAST_RUN_PREFIX,\n\t\"crdt-maintenance-last-run\",\n\t\"crdt-backend-override\",\n]\n\n/** Suffixes of all IDB keys (data + metadata) that belong to a single project. */\nconst ALL_PROJECT_IDB_SUFFIXES = [\":snapshot\", \":rows\", ...META_KEY_SUFFIXES] as const\n\nconst IDB_DB_NAME = \"crdt-sync-cache\"\nconst IDB_STORE_NAME = \"crdt-data\"\nconst CACHE_API_NAME = \"crdt-sync-cache\"\nconst OPFS_DIR_NAME = \"crdt-sync-cache\"\n\n/**\n * Discovers all cached project IDs by scanning both localStorage (which holds\n * per-project metadata keys) and the IDB object store (which may contain data\n * for projects that lack localStorage entries, e.g. after a crash).\n */\nfunction discoverCachedProjectIds(allIdbKeys: string[]): Set<string> {\n\tconst projectIds = new Set<string>()\n\n\t// Only `crdt-tree-version:` lives in localStorage now; the rest of the\n\t// per-project metadata has moved to IDB. We still scan the legacy\n\t// localStorage prefixes to discover any stale projects left behind by\n\t// older code versions so they get evicted.\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst key = localStorage.key(i)\n\t\tif (!key) continue\n\t\tif (key.startsWith(TREE_VERSION_PREFIX)) {\n\t\t\tprojectIds.add(key.slice(TREE_VERSION_PREFIX.length))\n\t\t} else if (key.startsWith(LEGACY_LAST_ACCESSED_PREFIX)) {\n\t\t\tprojectIds.add(key.slice(LEGACY_LAST_ACCESSED_PREFIX.length))\n\t\t} else if (key.startsWith(LEGACY_BACKEND_PREFIX)) {\n\t\t\tprojectIds.add(key.slice(LEGACY_BACKEND_PREFIX.length))\n\t\t} else if (key.startsWith(LEGACY_DATA_MODEL_PREFIX)) {\n\t\t\tprojectIds.add(key.slice(LEGACY_DATA_MODEL_PREFIX.length))\n\t\t}\n\t}\n\n\tfor (const key of allIdbKeys) {\n\t\tfor (const suffix of ALL_PROJECT_IDB_SUFFIXES) {\n\t\t\tif (key.endsWith(suffix)) {\n\t\t\t\tprojectIds.add(key.slice(0, -suffix.length))\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn projectIds\n}\n\nasync function getLastUpdatedAt(\n\tprojectId: string,\n\tstore: ReturnType<typeof idb.createStore>,\n): Promise<number | undefined> {\n\tconst fromIdb = await readLastUpdated(projectId, store)\n\tif (fromIdb !== undefined) return fromIdb\n\n\t// Fall back to the legacy localStorage entry for projects that haven't\n\t// been rewritten since the metadata moved to IDB.\n\tconst raw = localStorage.getItem(`${LEGACY_LAST_ACCESSED_PREFIX}${projectId}`)\n\tif (!raw) return undefined\n\tconst ts = Number(raw)\n\treturn Number.isFinite(ts) ? ts : undefined\n}\n\nfunction idbKeysForProject(projectId: string): string[] {\n\treturn ALL_PROJECT_IDB_SUFFIXES.map(suffix => `${projectId}${suffix}`)\n}\n\nasync function deleteFromCacheApi(keys: string[]): Promise<void> {\n\tif (typeof caches === \"undefined\") return\n\tconst cache = await caches.open(CACHE_API_NAME)\n\tawait Promise.all(keys.map(key => cache.delete(`https://local-cache.invalid/${encodeURIComponent(key)}`)))\n}\n\nasync function deleteFromOpfs(keys: string[]): Promise<void> {\n\tif (typeof navigator === \"undefined\" || typeof navigator.storage?.getDirectory !== \"function\") return\n\tconst root = await navigator.storage.getDirectory()\n\tconst dir = await root.getDirectoryHandle(OPFS_DIR_NAME)\n\tawait Promise.all(\n\t\tkeys.map(async key => {\n\t\t\ttry {\n\t\t\t\tawait dir.removeEntry(encodeURIComponent(key))\n\t\t\t} catch {\n\t\t\t\t// File may not exist\n\t\t\t}\n\t\t}),\n\t)\n}\n\n/**\n * Removes all cached data for a single project across every storage layer\n * (IDB, Cache API, OPFS, localStorage). Backends other than the one\n * currently configured may still hold orphaned data from migrations, so we\n * scrub all of them unconditionally.\n */\nasync function evictProject(projectId: string, store: ReturnType<typeof idb.createStore>): Promise<void> {\n\tconst keys = idbKeysForProject(projectId)\n\n\tawait idb.delMany(keys, store)\n\n\ttry {\n\t\tawait deleteFromCacheApi(keys)\n\t} catch {\n\t\t// Cache API may not be available or may fail\n\t}\n\n\ttry {\n\t\tawait deleteFromOpfs(keys)\n\t} catch {\n\t\t// OPFS directory may not exist\n\t}\n\n\tlocalStorage.removeItem(`${TREE_VERSION_PREFIX}${projectId}`)\n\tlocalStorage.removeItem(`${SNAPSHOT_REFRESH_LAST_RUN_PREFIX}${projectId}`)\n\t// Legacy: older code versions stored these per-project keys in\n\t// localStorage. They live in IDB now but may still be on disk.\n\tlocalStorage.removeItem(`${LEGACY_BACKEND_PREFIX}${projectId}`)\n\tlocalStorage.removeItem(`${LEGACY_LAST_ACCESSED_PREFIX}${projectId}`)\n\tlocalStorage.removeItem(`${LEGACY_DATA_MODEL_PREFIX}${projectId}`)\n}\n\n/**\n * Scans all locally cached project data across every storage layer and evicts\n * caches that have not been accessed within the last 30 days.\n *\n * Will return false if the task did not complete, because the user is no longer idle.\n */\nexport async function performLocalCacheMaintenance(isUserIdle: () => boolean): Promise<boolean> {\n\tconst now = Date.now()\n\n\ttry {\n\t\tconst store = idb.createStore(IDB_DB_NAME, IDB_STORE_NAME)\n\t\tconst allIdbKeys = await idb.keys<string>(store)\n\t\tconst projectIds = discoverCachedProjectIds(allIdbKeys)\n\n\t\tfor (const projectId of projectIds) {\n\t\t\tif (!isUserIdle()) return false\n\n\t\t\tconst lastUpdated = await getLastUpdatedAt(projectId, store)\n\t\t\tconst isStale = !lastUpdated || now - lastUpdated > EVICTION_THRESHOLD_MS\n\n\t\t\tif (isStale) {\n\t\t\t\ttry {\n\t\t\t\t\tawait evictProject(projectId, store)\n\t\t\t\t\tlog.debug(\"evicted stale cache for project:\", projectId)\n\t\t\t\t\tawait schedulerYield()\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlog.warn(\"failed to evict cache for project:\", projectId, error)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tlog.warn(\"maintenance failed:\", error)\n\t}\n\n\treturn true\n}\n\n// ---------------------------------------------------------------------------\n// Debug: nuke all local caches via URL param\n// ---------------------------------------------------------------------------\n\nexport const debugClearLocalCacheParam = \"__debugClearLocalCache\"\n\nfunction removeCrdtLocalStorageKeys(): void {\n\tif (typeof localStorage === \"undefined\") return\n\tconst toRemove: string[] = []\n\tfor (let i = 0; i < localStorage.length; i++) {\n\t\tconst key = localStorage.key(i)\n\t\tif (key && CRDT_KEY_PREFIXES.some(prefix => key.startsWith(prefix))) {\n\t\t\ttoRemove.push(key)\n\t\t}\n\t}\n\tfor (const key of toRemove) {\n\t\tlocalStorage.removeItem(key)\n\t}\n}\n\nasync function clearAllLocalCaches(): Promise<void> {\n\tremoveCrdtLocalStorageKeys()\n\n\ttry {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tconst req = indexedDB.deleteDatabase(IDB_DB_NAME)\n\t\t\treq.onsuccess = () => resolve()\n\t\t\treq.onerror = () => reject(req.error)\n\t\t\treq.onblocked = () => reject()\n\t\t})\n\t} catch {\n\t\t// IDB may not be available\n\t}\n\n\ttry {\n\t\tif (typeof caches !== \"undefined\") {\n\t\t\tawait caches.delete(CACHE_API_NAME)\n\t\t}\n\t} catch {\n\t\t// Cache API may not be available\n\t}\n\n\ttry {\n\t\tif (typeof navigator !== \"undefined\" && typeof navigator.storage?.getDirectory === \"function\") {\n\t\t\tconst root = await navigator.storage.getDirectory()\n\t\t\tawait root.removeEntry(OPFS_DIR_NAME, { recursive: true })\n\t\t}\n\t} catch {\n\t\t// OPFS directory may not exist\n\t}\n}\n\nfunction stripDebugParam(): void {\n\ttry {\n\t\tconst url = new URL(window.location.href)\n\t\turl.searchParams.delete(debugClearLocalCacheParam)\n\t\twindow.history.replaceState(window.history.state, \"\", url.toString())\n\t} catch {\n\t\t// Ignore if history API is unavailable\n\t}\n}\n\n/**\n * Resolves once the debug nuke has finished (or immediately if the URL param\n * was not present). LocalCache gates readData() on this so a nuked cache is\n * never accidentally read back before the delete completes.\n */\nexport let pendingDebugCacheClear: Promise<void> | undefined\n\ntry {\n\tif (typeof window !== \"undefined\" && new URLSearchParams(window.location.search).has(debugClearLocalCacheParam)) {\n\t\tlog.info(\"clearing all local caches (triggered by URL param)\")\n\t\tstripDebugParam()\n\t\tpendingDebugCacheClear = clearAllLocalCaches().then(\n\t\t\t() => log.info(\"all local caches cleared\"),\n\t\t\terror => log.warn(\"failed to clear all local caches:\", error),\n\t\t)\n\t}\n} catch {\n\t// Ignore \u2014 module may be imported in a non-browser context (tests, SSR)\n}\n", "import type { SerializableRow } from \"@framerjs/crdtree2\"\nimport { reportableError } from \"@framerjs/shared\"\nimport { accessTokenRefresher } from \"web/lib/accessTokenRefresherWeb.ts\"\nimport type { CrdtCacheData, RowsWithNext, RowsWithVersion } from \"./LocalCache.ts\"\n\n/**\n * Ceiling for how many local rows may sit beyond the range verified against\n * the server. A reasonable ceiling catches obvious corruption without\n * flagging normal steady-state caches.\n */\nconst DEBUG_VERIFY_MAX_TRAILING_ROWS = 100_000\n\n/**\n * Upper bound on how many times `performDebugVerifyRows` will binary-search\n * forward when the server keeps returning fresh snapshots instead of\n * updates.\n */\nconst DEBUG_VERIFY_MAX_BINARY_SEARCH_ATTEMPTS = 20\n\nexport interface DebugVerifyRowsResult {\n\tok: boolean\n\tmessage: string\n\trequestedVersion: number\n\tserverLatestVersion: number\n\tbinarySearchAttempts: number\n\tstrategy: \"incremental\" | \"up-to-date\" | \"snapshot\" | \"unknown\" | \"none\"\n\tstats: {\n\t\trowUpdates: number\n\t\tserverUpdates: number\n\t\tserverRows: number\n\t\tcomparedBatches: number\n\t\tmismatchedBatches: number\n\t\tmissingLocalBatches: number\n\t\ttrailingLocalRows: number\n\t}\n}\n\ninterface DebugVerifyRowsContext {\n\treadonly syncURL: string\n\treadData(): Promise<CrdtCacheData | undefined>\n}\n\n/**\n * Re-fetches `/tree/sync` starting at the cached snapshot version and\n * compares the server's incremental updates against our locally-cached\n * `RowsWithVersion[]`.\n *\n * Behaviour:\n *   - If the server replies with a fresh snapshot (we asked too far back),\n *     the snapshot is ignored and the request is retried halfway between\n *     `lastRequestVersion` and the server's latest version.\n *   - If the server reports we're up-to-date, we can't verify anything\n *     concrete but we sanity-check that the number of locally-cached rows\n *     beyond `lastRequestVersion` doesn't exceed a reasonable ceiling.\n *   - Once we do receive incremental updates, we walk our local batches and\n *     verify their `SerializableRow[]` matches the server's\n *     `RowsWithNext[]` at the same version. The earliest server updates may\n *     have no local counterpart (our cache was reset from a newer snapshot)\n *     \u2014 that's allowed. Trailing local rows past the server's reported\n *     latest version are bounded by the same ceiling.\n *\n * This function does not mutate the cache; it is intended purely for\n * debug/diagnostic use from the Tools panel.\n */\nexport async function performDebugVerifyRows(context: DebugVerifyRowsContext): Promise<DebugVerifyRowsResult> {\n\tconst data = await context.readData()\n\tif (!data) {\n\t\treturn makeDebugVerifyResult({\n\t\t\tok: false,\n\t\t\tmessage: \"no cached data to verify\",\n\t\t\tstrategy: \"none\",\n\t\t})\n\t}\n\n\tconst localRows = data.rows\n\n\tlet requestVersion = data.snapshotVersion\n\tlet attempts = 0\n\n\twhile (attempts < DEBUG_VERIFY_MAX_BINARY_SEARCH_ATTEMPTS) {\n\t\tattempts++\n\t\tlet response: Response\n\t\ttry {\n\t\t\tresponse = await fetchTreeSyncForDebug(context.syncURL, requestVersion)\n\t\t} catch (error) {\n\t\t\treturn makeDebugVerifyResult({\n\t\t\t\tok: false,\n\t\t\t\tmessage: `fetch failed: ${reportableError(error).message}`,\n\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\tstrategy: \"unknown\",\n\t\t\t\tlocalRows,\n\t\t\t})\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\treturn makeDebugVerifyResult({\n\t\t\t\tok: false,\n\t\t\t\tmessage: `tree/sync HTTP ${response.status}`,\n\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\tstrategy: \"unknown\",\n\t\t\t\tlocalRows,\n\t\t\t})\n\t\t}\n\n\t\tconst strategy = response.headers.get(\"Sync-Strategy\")\n\t\tconst serverLatestVersion = Number.parseInt(response.headers.get(\"Tree-Version\") ?? \"0\", 10)\n\n\t\tif (strategy === \"snapshot\") {\n\t\t\tif (!Number.isFinite(serverLatestVersion) || serverLatestVersion <= requestVersion) {\n\t\t\t\treturn makeDebugVerifyResult({\n\t\t\t\t\tok: false,\n\t\t\t\t\tmessage: `snapshot strategy but server version ${serverLatestVersion} is not ahead of request ${requestVersion}`,\n\t\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\t\tserverLatestVersion,\n\t\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\t\tstrategy: \"snapshot\",\n\t\t\t\t\tlocalRows,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst step = Math.floor((serverLatestVersion - requestVersion) / 2)\n\t\t\tif (step <= 0) {\n\t\t\t\treturn makeDebugVerifyResult({\n\t\t\t\t\tok: false,\n\t\t\t\t\tmessage: `cannot narrow binary search further (gap ${serverLatestVersion - requestVersion})`,\n\t\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\t\tserverLatestVersion,\n\t\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\t\tstrategy: \"snapshot\",\n\t\t\t\t\tlocalRows,\n\t\t\t\t})\n\t\t\t}\n\t\t\trequestVersion += step\n\t\t\tcontinue\n\t\t}\n\n\t\tif (strategy === \"up-to-date\") {\n\t\t\tconst trailing = countLocalRowsAfterVersion(localRows, requestVersion)\n\t\t\tconst ok = trailing <= DEBUG_VERIFY_MAX_TRAILING_ROWS\n\t\t\treturn makeDebugVerifyResult({\n\t\t\t\tok,\n\t\t\t\tmessage: ok\n\t\t\t\t\t? `up-to-date at ${requestVersion}; ${trailing} local rows beyond request version`\n\t\t\t\t\t: `up-to-date at ${requestVersion}; too many trailing local rows (${trailing} > ${DEBUG_VERIFY_MAX_TRAILING_ROWS})`,\n\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\tserverLatestVersion,\n\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\tstrategy: \"up-to-date\",\n\t\t\t\tlocalRows,\n\t\t\t\ttrailingLocalRows: trailing,\n\t\t\t})\n\t\t}\n\n\t\tif (strategy === \"incremental\") {\n\t\t\tlet serverUpdates: RowsWithNext[]\n\t\t\ttry {\n\t\t\t\tconst parsed: unknown = await response.json()\n\t\t\t\tif (!isRowsWithNextArray(parsed)) {\n\t\t\t\t\treturn makeDebugVerifyResult({\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\tmessage: \"incremental response did not match RowsWithNext[] shape\",\n\t\t\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\t\t\tserverLatestVersion,\n\t\t\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\t\t\tstrategy: \"incremental\",\n\t\t\t\t\t\tlocalRows,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tserverUpdates = parsed\n\t\t\t} catch (error) {\n\t\t\t\treturn makeDebugVerifyResult({\n\t\t\t\t\tok: false,\n\t\t\t\t\tmessage: `failed to parse incremental response: ${reportableError(error).message}`,\n\t\t\t\t\trequestedVersion: requestVersion,\n\t\t\t\t\tserverLatestVersion,\n\t\t\t\t\tbinarySearchAttempts: attempts,\n\t\t\t\t\tstrategy: \"incremental\",\n\t\t\t\t\tlocalRows,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn verifyIncrementalUpdates({\n\t\t\t\trequestVersion,\n\t\t\t\tserverLatestVersion,\n\t\t\t\tattempts,\n\t\t\t\tserverUpdates,\n\t\t\t\tlocalRows,\n\t\t\t})\n\t\t}\n\n\t\treturn makeDebugVerifyResult({\n\t\t\tok: false,\n\t\t\tmessage: `unknown sync strategy: ${strategy ?? \"<none>\"}`,\n\t\t\trequestedVersion: requestVersion,\n\t\t\tserverLatestVersion,\n\t\t\tbinarySearchAttempts: attempts,\n\t\t\tstrategy: \"unknown\",\n\t\t\tlocalRows,\n\t\t})\n\t}\n\n\treturn makeDebugVerifyResult({\n\t\tok: false,\n\t\tmessage: `exceeded max binary-search attempts (${DEBUG_VERIFY_MAX_BINARY_SEARCH_ATTEMPTS})`,\n\t\trequestedVersion: requestVersion,\n\t\tbinarySearchAttempts: attempts,\n\t\tstrategy: \"snapshot\",\n\t\tlocalRows: data.rows,\n\t})\n}\n\nasync function fetchTreeSyncForDebug(syncURL: string, version: number): Promise<Response> {\n\tconst url = new URL(syncURL)\n\turl.searchParams.set(\"version\", version.toString())\n\treturn fetch(url, await accessTokenRefresher.withAuthorizationHeader({}))\n}\n\nfunction isRowsWithNextArray(value: unknown): value is RowsWithNext[] {\n\tif (!Array.isArray(value)) return false\n\tif (value.length === 0) return true\n\tconst firstEntry = value[0]\n\tif (firstEntry === null || typeof firstEntry !== \"object\") return false\n\tif (!(\"next\" in firstEntry) || typeof firstEntry.next !== \"number\") return false\n\tif (!(\"rows\" in firstEntry) || !Array.isArray(firstEntry.rows)) return false\n\treturn true\n}\n\nfunction countLocalRowsAfterVersion(localRows: RowsWithVersion[], version: number): number {\n\tlet n = 0\n\tfor (const batch of localRows) {\n\t\tif (batch.version > version) n += batch.rows.length\n\t}\n\treturn n\n}\n\nfunction serializableRowArraysEqual(a: SerializableRow[], b: SerializableRow[]): boolean {\n\tif (a.length !== b.length) return false\n\t// Debug-only path: JSON stringify is acceptable for deep equality.\n\treturn JSON.stringify(a) === JSON.stringify(b)\n}\n\ninterface VerifyIncrementalArgs {\n\trequestVersion: number\n\tserverLatestVersion: number\n\tattempts: number\n\tserverUpdates: RowsWithNext[]\n\tlocalRows: RowsWithVersion[]\n}\n\nfunction verifyIncrementalUpdates(args: VerifyIncrementalArgs): DebugVerifyRowsResult {\n\tconst { requestVersion, serverLatestVersion, attempts, serverUpdates, localRows } = args\n\n\tconst localByVersion = new Map<number, SerializableRow[]>()\n\tfor (const batch of localRows) localByVersion.set(batch.version, batch.rows)\n\n\t// Local's earliest \"version after update\". If the cache has been reset\n\t// from a newer snapshot, the server may send updates predating this \u2014\n\t// those are allowed to have no local counterpart.\n\tconst localFirstVersion = localRows[0]?.version\n\n\tlet comparedBatches = 0\n\tlet mismatchedBatches = 0\n\tlet missingLocalBatches = 0\n\tconst problems: string[] = []\n\n\tfor (const update of serverUpdates) {\n\t\tconst version = update.next\n\t\tconst localBatchRows = localByVersion.get(version)\n\n\t\tif (localBatchRows === undefined) {\n\t\t\tconst isInFrontGap = localFirstVersion === undefined || version < localFirstVersion\n\t\t\tif (isInFrontGap) continue\n\t\t\tmissingLocalBatches++\n\t\t\tif (problems.length < 5) problems.push(`missing local batch for version ${version}`)\n\t\t\tcontinue\n\t\t}\n\n\t\tcomparedBatches++\n\t\tif (!serializableRowArraysEqual(localBatchRows, update.rows)) {\n\t\t\tmismatchedBatches++\n\t\t\tif (problems.length < 5) {\n\t\t\t\tproblems.push(\n\t\t\t\t\t`mismatch at version ${version}: local ${localBatchRows.length} rows vs server ${update.rows.length} rows`,\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst trailingLocalRows = countLocalRowsAfterVersion(localRows, serverLatestVersion)\n\tconst trailingOk = trailingLocalRows <= DEBUG_VERIFY_MAX_TRAILING_ROWS\n\n\tconst ok = mismatchedBatches === 0 && missingLocalBatches === 0 && trailingOk\n\tconst summaryParts: string[] = []\n\tif (mismatchedBatches > 0) summaryParts.push(`${mismatchedBatches} mismatched`)\n\tif (missingLocalBatches > 0) summaryParts.push(`${missingLocalBatches} missing local`)\n\tif (!trailingOk) summaryParts.push(`${trailingLocalRows} trailing local rows > ${DEBUG_VERIFY_MAX_TRAILING_ROWS}`)\n\tsummaryParts.push(...problems)\n\n\tconst message = ok\n\t\t? `verified ${comparedBatches}/${serverUpdates.length} batches; ${trailingLocalRows} trailing local rows`\n\t\t: summaryParts.join(\"; \") || \"verification failed\"\n\n\tconst serverRows = serverUpdates.reduce((n, u) => n + u.rows.length, 0)\n\n\treturn {\n\t\tok,\n\t\tmessage,\n\t\trequestedVersion: requestVersion,\n\t\tserverLatestVersion,\n\t\tbinarySearchAttempts: attempts,\n\t\tstrategy: \"incremental\",\n\t\tstats: {\n\t\t\trowUpdates: localRows.length,\n\t\t\tserverUpdates: serverUpdates.length,\n\t\t\tserverRows,\n\t\t\tcomparedBatches,\n\t\t\tmismatchedBatches,\n\t\t\tmissingLocalBatches,\n\t\t\ttrailingLocalRows,\n\t\t},\n\t}\n}\n\ninterface MakeDebugVerifyResultArgs {\n\tok: boolean\n\tmessage: string\n\trequestedVersion?: number\n\tserverLatestVersion?: number\n\tbinarySearchAttempts?: number\n\tstrategy: DebugVerifyRowsResult[\"strategy\"]\n\tlocalRows?: RowsWithVersion[]\n\ttrailingLocalRows?: number\n}\n\nfunction makeDebugVerifyResult(args: MakeDebugVerifyResultArgs): DebugVerifyRowsResult {\n\tconst localRows = args.localRows ?? []\n\treturn {\n\t\tok: args.ok,\n\t\tmessage: args.message,\n\t\trequestedVersion: args.requestedVersion ?? 0,\n\t\tserverLatestVersion: args.serverLatestVersion ?? 0,\n\t\tbinarySearchAttempts: args.binarySearchAttempts ?? 0,\n\t\tstrategy: args.strategy,\n\t\tstats: {\n\t\t\trowUpdates: localRows.length,\n\t\t\tserverUpdates: 0,\n\t\t\tserverRows: 0,\n\t\t\tcomparedBatches: 0,\n\t\t\tmismatchedBatches: 0,\n\t\t\tmissingLocalBatches: 0,\n\t\t\ttrailingLocalRows: args.trailingLocalRows ?? 0,\n\t\t},\n\t}\n}\n", "import type { BranchedSerializableRow } from \"@framerjs/crdtree2\"\nimport { assert, getLogger, reportableError } from \"@framerjs/shared\"\nimport { signal as createSignal } from \"alien-signals\"\nimport type { PrefetchSyncPromise } from \"document/stores/TreeStore.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport {\n\tcreateLocalCacheDataBackend,\n\tdeleteCacheMeta,\n\testimateStorageBytes,\n\treadCacheMeta,\n\treadCacheTreeVersion,\n\twriteCacheMeta,\n\ttype BackendType,\n\ttype LocalCacheDataBackend,\n} from \"./LocalCacheDataBackend.ts\"\nimport {\n\tpendingDebugCacheClear,\n\tperformLocalCacheMaintenance,\n\tperformSnapshotRefresh,\n} from \"./LocalCacheMaintenance.ts\"\nimport { performDebugVerifyRows, type DebugVerifyRowsResult } from \"./LocalCacheVerifyRows.ts\"\n\nconst log = getLogger(\"LocalCache\")\n\nlet defaultBackend: LocalCacheDataBackend | undefined\n\nfunction getDefaultBackend(): LocalCacheDataBackend {\n\tdefaultBackend ??= createLocalCacheDataBackend()\n\treturn defaultBackend\n}\n\n/** How fast we write pending snapshot to storage. */\nconst WRITE_SNAPSHOT_DEBOUNCE_MS = 5_000\n/** How fast we write pending rows to storage. */\nconst WRITE_ROWS_DEBOUNCE_MS = 60_000\n\n/** How often we run maintenance like check all caches and delete outdated ones. */\nconst MAINTENANCE_CHECK_INTERVAL_MS = 300_000\n\n/** Don't run maintenance more than once per hour. */\nconst MAINTENANCE_COOLDOWN_MS = 60 * 60 * 1000\nconst MAINTENANCE_LAST_RUN_KEY = \"crdt-maintenance-last-run\"\n\n/** The format in which we store rows in the local cache. */\nexport interface RowsWithVersion {\n\tversion: number\n\trows: BranchedSerializableRow[]\n}\n\nfunction isRowsWithVersionsArray(value: unknown): value is RowsWithVersion[] {\n\tif (!Array.isArray(value)) return false\n\tif (value.length === 0) return true\n\tconst firstEntry = value[0]\n\tif (firstEntry === null || typeof firstEntry !== \"object\") return false\n\tif (!(\"version\" in firstEntry) || typeof firstEntry.version !== \"number\") return false\n\tif (!(\"rows\" in firstEntry) || !Array.isArray(firstEntry.rows)) return false\n\treturn true\n}\n\n/** The format in which the server sends rows. */\nexport interface RowsWithNext {\n\tnext: number\n\trows: BranchedSerializableRow[]\n}\n\nexport interface CrdtCacheData {\n\t/** The initial snapshot we have stored. */\n\tsnapshot: Uint8Array\n\t/** The tree version of the initial snapshot. */\n\tsnapshotVersion: number\n\t/** The rows we have stored, bringing the snapshot up to date. */\n\trows: RowsWithVersion[]\n\t/** The last version of the tree we have in the cache (snapshot + rows) */\n\tversion: number\n\t/**\n\t * Byte size of the snapshot payload as reported by the backend on the\n\t * most recent read. Exact for cache-api/opfs; approximated for idb.\n\t * `0` when nothing is persisted yet (e.g. when the caller is holding\n\t * an unflushed pending snapshot).\n\t */\n\tsnapshotStorageBytes: number\n\t/**\n\t * Byte size of the rows payload as reported by the backend on the\n\t * most recent read. Pending (unflushed) rows are NOT included \u2014 this\n\t * only reflects what is actually on disk.\n\t */\n\trowsStorageBytes: number\n}\n\n/** Data storage model versioning. Any mismatch will reset all data. */\nconst LOCAL_CACHE_DATA_MODEL = 3\n\n/** Last CRDT sync / load path that touched the local cache (debug + telemetry). */\nexport type LocalCrdtSyncStrategy = \"incremental\" | \"snapshot\" | \"up-to-date\" | \"full-load\"\n\ninterface SyncCrdtMeta {\n\tsyncStrategy: Exclude<LocalCrdtSyncStrategy, \"full-load\">\n\tsnapshotSource: \"cached\" | \"downloaded\"\n\tcacheBackend: BackendType\n\tcachedRows: number\n\t/** Byte size of the cached rows as reported by the backend on read. */\n\tcachedRowBytes: number\n\tdownloadedRows: number\n\tdownloadedRowBytes: number\n\thierarchyHash: number\n}\n\nfunction getLocalStorageVersionKey(projectId: string): string {\n\treturn `crdt-tree-version:${projectId}`\n}\n\nexport function deleteLocalStorageVersionKey(projectId: string): void {\n\tif (typeof localStorage === \"undefined\") return\n\tlocalStorage.removeItem(getLocalStorageVersionKey(projectId))\n}\n\nexport class LocalCache {\n\t/** Set on error/inconsistency; disables the cache and resets persisted data. */\n\taborted = false\n\n\tprivate pendingSnapshot: Uint8Array | undefined\n\tprivate pendingSnapshotVersion = 0\n\tprivate pendingRows: RowsWithVersion[] = []\n\tprivate pendingVersion = 0\n\n\t/** If true, indicates the pending rows will be concatenated with what is already in the cache.\n\t * Otherwise, the cached rows will be replaced with the pending rows. */\n\tprivate concatPendingRows = true\n\tprivate flushTimer: ReturnType<typeof setTimeout> | undefined\n\n\t/** Bumped when in-memory pending state or persisted cache metadata changes (debug UI). */\n\tprivate readonly debugGeneration = createSignal(0)\n\n\t/** Last server / load strategy observed for this project (undefined until first sync or full-load cache write). */\n\tprivate readonly lastCrdtSyncStrategy = createSignal<LocalCrdtSyncStrategy | undefined>(undefined)\n\n\t/** Timestamp of the most recent addRows call (used by compaction quiet-period check). */\n\tlastAddRowsAt = 0\n\tsnapshotRefreshInProgress = false\n\tsnapshotRefreshVersionAtStart = 0\n\n\tprivate readonly snapshotKey: string\n\tprivate readonly rowsKey: string\n\n\tprivate readonly localStorageVersionKey: string\n\n\tprivate readonly maintenanceTimer: ReturnType<typeof setInterval>\n\n\tconstructor(\n\t\treadonly projectId: string,\n\t\treadonly isUserIdle: () => boolean,\n\t\tprivate backend: LocalCacheDataBackend = getDefaultBackend(),\n\t\tsignal?: AbortSignal,\n\t\treadonly isMPSSocket = false,\n\t) {\n\t\tthis.snapshotKey = `${this.projectId}:snapshot`\n\t\tthis.rowsKey = `${this.projectId}:rows`\n\t\tthis.localStorageVersionKey = getLocalStorageVersionKey(this.projectId)\n\n\t\tthis.maintenanceTimer = setInterval(() => this.maybeRunMaintenance(), MAINTENANCE_CHECK_INTERVAL_MS)\n\t\tsignal?.addEventListener(\"abort\", this.dispose.bind(this))\n\t}\n\n\tabortAndClearCache() {\n\t\tif (this.aborted) return\n\t\tlog.warn(\"Clearing local cache and stopping further processing.\")\n\t\tthis.aborted = true\n\t\tthis.clearCache().catch(error => log.error(\"error clearing local cache:\", error))\n\t}\n\n\tprivate bumpDebugGeneration(): void {\n\t\tconst gen = this.debugGeneration()\n\t\tthis.debugGeneration(gen + 1)\n\t}\n\n\t/**\n\t * Generation counter for debug tools; subscribe via alien-signals / useSignalState.\n\t */\n\tgetDebugGeneration(): number {\n\t\treturn this.debugGeneration()\n\t}\n\n\tgetLastCrdtSyncStrategyForDebug(): LocalCrdtSyncStrategy | undefined {\n\t\treturn this.lastCrdtSyncStrategy()\n\t}\n\n\tprivate setLastCrdtSyncStrategy(strategy: LocalCrdtSyncStrategy): void {\n\t\tif (this.lastCrdtSyncStrategy() === strategy) return\n\n\t\tthis.lastCrdtSyncStrategy(strategy)\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\tasync readTreeVersion(): Promise<number> {\n\t\treturn (await readCacheTreeVersion(this.projectId, this.backend.idbStore)) ?? 0\n\t}\n\n\tgetCachedTreeVersion(): number {\n\t\tif (typeof localStorage === \"undefined\") return 0\n\n\t\tconst stored = localStorage.getItem(this.localStorageVersionKey)\n\t\tconst storedVersion = stored ? Number(stored) : 0\n\t\treturn Math.max(storedVersion, this.pendingVersion)\n\t}\n\n\tasync readData(): Promise<CrdtCacheData | undefined> {\n\t\tif (typeof navigator !== \"undefined\" && navigator.locks) {\n\t\t\treturn navigator.locks.request(this.projectId, { mode: \"exclusive\" }, this.readDataLocked)\n\t\t} else {\n\t\t\treturn this.readDataLocked()\n\t\t}\n\t}\n\n\treadDataLocked = async (): Promise<CrdtCacheData | undefined> => {\n\t\tif (typeof localStorage === \"undefined\") return undefined\n\t\tif (pendingDebugCacheClear) await pendingDebugCacheClear\n\n\t\t// Step 1: read cache metadata from IDB. This tells us which backend\n\t\t// holds the snapshot/rows and whether the on-disk data model matches\n\t\t// this code version. We must do this BEFORE touching the backend,\n\t\t// because the backend type may have changed between sessions.\n\t\tconst meta = await readCacheMeta(this.projectId, this.backend.idbStore)\n\n\t\tif (meta.backend && meta.backend !== this.backend.type) {\n\t\t\tlog.debug(\"backend changed from\", meta.backend, \"to\", this.backend.type, \"\u2013 discarding cache\")\n\t\t\tawait this.clearCache()\n\t\t\treturn undefined\n\t\t}\n\n\t\t// If we have a pending snapshot that hasn't been flushed yet, use it\n\t\t// directly \u2014 no need to hit the backend. Storage bytes are reported\n\t\t// as 0 since nothing is on disk yet; we only track storage bytes\n\t\t// after a read or write.\n\t\tif (this.pendingSnapshot) {\n\t\t\treturn {\n\t\t\t\tsnapshot: this.pendingSnapshot,\n\t\t\t\tsnapshotVersion: this.pendingSnapshotVersion,\n\t\t\t\trows: [...this.pendingRows],\n\t\t\t\tversion: this.pendingVersion,\n\t\t\t\tsnapshotStorageBytes: 0,\n\t\t\t\trowsStorageBytes: 0,\n\t\t\t}\n\t\t}\n\n\t\t// Persisted rows live in the on-disk format described by\n\t\t// LOCAL_CACHE_DATA_MODEL. If the stored model version doesn't match the\n\t\t// current code (e.g. a legacy flat-row layout from before model 2, or\n\t\t// a layout from before snapshot-version/version moved to IDB meta),\n\t\t// we treat the cache as empty; the next write will overwrite it in\n\t\t// the new shape.\n\t\tif (meta.dataModel !== LOCAL_CACHE_DATA_MODEL) {\n\t\t\tif (meta.dataModel !== undefined) {\n\t\t\t\tlog.debug(\n\t\t\t\t\t\"data model mismatch \u2014 stored:\",\n\t\t\t\t\tmeta.dataModel,\n\t\t\t\t\t\"expected:\",\n\t\t\t\t\tLOCAL_CACHE_DATA_MODEL,\n\t\t\t\t\t\"\u2014 treating cache as empty\",\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t}\n\n\t\t// snapshotVersion and version now live in IDB meta alongside backend/\n\t\t// dataModel. They must both be present and positive for the cache to\n\t\t// be considered valid.\n\t\tconst snapshotVersion = meta.snapshotVersion\n\t\tconst version = meta.version\n\t\tif (snapshotVersion === undefined || snapshotVersion <= 0) return undefined\n\t\tif (version === undefined || version <= 0) return undefined\n\n\t\t// Step 2: read the actual snapshot/rows through the backend, and\n\t\t// capture their on-disk byte sizes while we're at it.\n\t\tconst [snapshotResult, rowsResult] = await this.backend.getManyWithSize([this.snapshotKey, this.rowsKey])\n\t\tif (!snapshotResult || !(snapshotResult.value instanceof Uint8Array)) return undefined\n\t\tconst snapshot = snapshotResult.value\n\t\tconst persistedRows: RowsWithVersion[] =\n\t\t\trowsResult && isRowsWithVersionsArray(rowsResult.value) ? rowsResult.value : []\n\t\tconst snapshotStorageBytes = snapshotResult.storageBytes\n\t\tconst persistedRowsStorageBytes = rowsResult?.storageBytes ?? 0\n\n\t\t// If another tab already flushed data at or beyond our pending version,\n\t\t// our pending rows are stale \u2014 IDB is authoritative.\n\t\tif (this.pendingRows.length > 0 && version >= this.pendingVersion) {\n\t\t\tthis.pendingRows = []\n\t\t\tthis.concatPendingRows = true\n\t\t\tthis.pendingVersion = version\n\t\t\tthis.bumpDebugGeneration()\n\t\t}\n\n\t\t// Overlay pending rows that haven't been flushed yet. Pending rows\n\t\t// are explicitly excluded from rowsStorageBytes \u2014 we only report\n\t\t// what the backend has actually persisted.\n\t\tif (this.pendingRows.length > 0) {\n\t\t\tconst effectiveRows = this.concatPendingRows ? persistedRows.concat(this.pendingRows) : [...this.pendingRows]\n\t\t\treturn {\n\t\t\t\tsnapshot,\n\t\t\t\tsnapshotVersion,\n\t\t\t\trows: effectiveRows,\n\t\t\t\tversion: this.pendingVersion,\n\t\t\t\tsnapshotStorageBytes,\n\t\t\t\trowsStorageBytes: this.concatPendingRows ? persistedRowsStorageBytes : 0,\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tsnapshot,\n\t\t\tsnapshotVersion,\n\t\t\trows: persistedRows,\n\t\t\tversion,\n\t\t\tsnapshotStorageBytes,\n\t\t\trowsStorageBytes: persistedRowsStorageBytes,\n\t\t}\n\t}\n\n\tstoreSnapshot(snapshot: Uint8Array, version: number, options?: { syncStrategy?: LocalCrdtSyncStrategy }): void {\n\t\tif (this.aborted) return\n\n\t\tthis.pendingSnapshot = snapshot\n\t\tthis.pendingSnapshotVersion = version\n\n\t\tif (version >= this.pendingVersion) {\n\t\t\t// Normal case: the snapshot is at-or-ahead of any rows we have pending.\n\t\t\t// Discard pending rows; they're either older than the snapshot or\n\t\t\t// already included in it.\n\t\t\tthis.pendingRows = []\n\t\t\tthis.pendingVersion = version\n\t\t} else {\n\t\t\t// Race case: pendingVersion has already advanced past `version` because\n\t\t\t// addRows ran (e.g. CrdtDocumentLoader emits loadedFirstData -> setTree\n\t\t\t// -> processRemoteUpdates draining queued confirms via addRows) before\n\t\t\t// reaching storeSnapshot in createTreeFromBuffer. Drop only the rows\n\t\t\t// covered by the snapshot; keep rows strictly past it. pendingVersion\n\t\t\t// stays where it was so the next addRows doesn't trip the gap check.\n\t\t\tthis.pendingRows = this.pendingRows.filter(batch => batch.version > version)\n\t\t}\n\t\tthis.concatPendingRows = false\n\t\tthis.scheduleWrite()\n\t\tthis.bumpDebugGeneration()\n\n\t\tif (options?.syncStrategy !== undefined) {\n\t\t\tthis.setLastCrdtSyncStrategy(options.syncStrategy)\n\t\t}\n\t}\n\n\t/**\n\t * Replace the full set of cached rows, preserving per-update version\n\t * boundaries encoded in the `RowsWithVersion[]` structure.\n\t */\n\tresetRows(rows: RowsWithVersion[], version: number): void {\n\t\tif (this.aborted) return\n\n\t\tthis.pendingRows = rows\n\t\tthis.pendingVersion = version\n\t\tthis.concatPendingRows = false\n\t\tthis.scheduleWrite()\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\taddRows(rows: BranchedSerializableRow[], treeVersion: number): void {\n\t\tthis.lastAddRowsAt = Date.now()\n\n\t\tif (this.aborted) return\n\n\t\tif (treeVersion <= this.pendingVersion) {\n\t\t\tlog.debug(\"skipping addRows: overlap:\", treeVersion, this.pendingVersion)\n\t\t\treturn\n\t\t}\n\n\t\t// With isMPSSocket we cannot check for gaps because the versions are timestamps.\n\t\tif (!this.isMPSSocket && this.pendingVersion > 0 && treeVersion > this.pendingVersion + 1) {\n\t\t\tlog.reportError(new Error(\"gap detected in local cache after addRows\"), {\n\t\t\t\tsnapshotVersion: this.pendingSnapshotVersion,\n\t\t\t\tversion: this.pendingVersion,\n\t\t\t\tnextVersion: treeVersion,\n\t\t\t\tbackend: this.backend.type,\n\t\t\t})\n\t\t\tthis.abortAndClearCache()\n\t\t\treturn\n\t\t}\n\n\t\tthis.pendingRows.push({ version: treeVersion, rows })\n\t\tthis.pendingVersion = treeVersion\n\t\tthis.scheduleWrite()\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\tasync write(): Promise<void> {\n\t\tif (this.snapshotRefreshInProgress) return\n\t\tthis.cancelPendingWrite()\n\t\tif (this.aborted) return\n\n\t\ttry {\n\t\t\t// Use Web Locks API if available to coordinate across tabs.\n\t\t\tif (typeof navigator !== \"undefined\" && navigator.locks) {\n\t\t\t\tawait navigator.locks.request(this.projectId, { mode: \"exclusive\" }, this.writeLocked)\n\t\t\t} else {\n\t\t\t\tawait this.writeLocked()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlog.reportError(reportableError(error), {\n\t\t\t\tbackend: this.backend.type,\n\t\t\t\tsnapshotVersion: this.pendingSnapshotVersion,\n\t\t\t\tversion: this.pendingVersion,\n\t\t\t})\n\t\t\tthis.abortAndClearCache()\n\t\t}\n\t}\n\n\tprivate writeLocked = async (): Promise<void> => {\n\t\tif (this.aborted) return\n\t\tconst start = performance.now()\n\n\t\t// First read the cache, so the rest of this method is atomic, and we are free to change\n\t\t// pending data.\n\t\tconst existingTreeVersion = await this.readTreeVersion()\n\t\tconst existingMeta = await readCacheMeta(this.projectId, this.backend.idbStore)\n\n\t\tconst snapshot = this.pendingSnapshot\n\t\tconst snapshotVersion = this.pendingSnapshotVersion\n\t\tlet rows = this.pendingRows\n\t\tconst version = this.pendingVersion\n\n\t\t// True if we should concatenate the pending rows with the existing rows.\n\t\tconst concatRows = this.concatPendingRows\n\n\t\t// If we are not going to do any work, early return.\n\t\tif (!snapshot && rows.length === 0) return\n\n\t\t// reset\n\t\tthis.pendingSnapshot = undefined\n\t\tthis.pendingRows = []\n\t\tthis.concatPendingRows = true\n\t\tthis.bumpDebugGeneration()\n\n\t\t// Same tree version from another tab skips redundant payload writes only when\n\t\t// the persisted rows/snapshot are already in the current data-model shape.\n\t\t// After a code upgrade, version may match while legacy rows/meta remain \u2014\n\t\t// then we must rewrite payloads instead of stamping dataModel alone.\n\t\tif (existingTreeVersion === version && existingMeta.dataModel === LOCAL_CACHE_DATA_MODEL) {\n\t\t\tlog.debug(\"skipping write: data already up to date:\", existingTreeVersion, version)\n\t\t\t// Keep IDB meta and localStorage version in sync with what is\n\t\t\t// already on disk. Meta first (IDB), localStorage last.\n\t\t\tawait writeCacheMeta(\n\t\t\t\tthis.projectId,\n\t\t\t\t{\n\t\t\t\t\tbackend: this.backend.type,\n\t\t\t\t\tdataModel: LOCAL_CACHE_DATA_MODEL,\n\t\t\t\t},\n\t\t\t\tthis.backend.idbStore,\n\t\t\t)\n\t\t\tlocalStorage.setItem(this.localStorageVersionKey, version.toString())\n\t\t\treturn\n\t\t} else if (existingTreeVersion > version) {\n\t\t\tthis.pendingVersion = existingTreeVersion\n\t\t\tlog.debug(\"skipping write: data already written by concurrent tab:\", existingTreeVersion, version)\n\t\t\treturn\n\t\t}\n\n\t\t// Write order (per design):\n\t\t//   1. snapshot/rows payload via the active backend\n\t\t//   2. per-project metadata in IDB (backend, dataModel, versions, lastUpdatedAt)\n\t\t//   3. the tree version in localStorage (reader-friendly optimization)\n\t\tif (snapshot) {\n\t\t\tawait this.backend.setMany([\n\t\t\t\t[this.snapshotKey, snapshot],\n\t\t\t\t[this.rowsKey, rows],\n\t\t\t])\n\t\t\tlog.debug(\"written snapshot:\", snapshot.byteLength, \"updates:\", rows.length, \"version:\", version)\n\t\t} else if (!concatRows) {\n\t\t\tawait this.backend.setMany([[this.rowsKey, rows]])\n\t\t\tlog.debug(\"written rows:\", rows.length, this.pendingVersion)\n\t\t} else {\n\t\t\tconst newRowCount = rows.length\n\t\t\tconst existing = (await this.backend.get<RowsWithVersion[]>(this.rowsKey)) ?? []\n\t\t\trows = existing.concat(rows)\n\t\t\tawait this.backend.setMany([[this.rowsKey, rows]])\n\t\t\tlog.debug(\"appended rows:\", newRowCount, \"total rows:\", rows.length, \"version:\", version)\n\t\t}\n\n\t\tconst metaToWrite: Parameters<typeof writeCacheMeta>[1] = {\n\t\t\tbackend: this.backend.type,\n\t\t\tdataModel: LOCAL_CACHE_DATA_MODEL,\n\t\t\tlastUpdatedAt: Date.now(),\n\t\t\tversion,\n\t\t}\n\t\tif (snapshot) metaToWrite.snapshotVersion = snapshotVersion\n\t\tawait writeCacheMeta(this.projectId, metaToWrite, this.backend.idbStore)\n\n\t\tlocalStorage.setItem(this.localStorageVersionKey, version.toString())\n\t\tthis.bumpDebugGeneration()\n\n\t\t// Track statistics.\n\t\tconst durationMs = Math.round(performance.now() - start)\n\t\tif (snapshot) {\n\t\t\trecord(\"local_cache_snapshot_stored\", {\n\t\t\t\ttree_version: version,\n\t\t\t\tsnapshot_bytes: snapshot.byteLength,\n\t\t\t\tcache_backend: this.backend.type,\n\t\t\t\tdurationMs,\n\t\t\t})\n\t\t}\n\t\tconst writtenRowCount = rows.length\n\t\tif (writtenRowCount > 0) {\n\t\t\t// Round-trip to the backend so `row_bytes` reflects the actual\n\t\t\t// storage footprint (exact for cache-api/opfs; approximated for\n\t\t\t// idb) rather than an in-memory estimate of the value we wrote.\n\t\t\tconst [written] = await this.backend.getManyWithSize([this.rowsKey])\n\t\t\trecord(\"local_cache_pending_rows_added\", {\n\t\t\t\ttree_version: version,\n\t\t\t\trow_count: writtenRowCount,\n\t\t\t\trow_bytes: written?.storageBytes ?? 0,\n\t\t\t\tcache_backend: this.backend.type,\n\t\t\t\tdurationMs,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate scheduleWrite(): void {\n\t\tif (this.aborted) return\n\t\tif (this.flushTimer !== undefined) return\n\n\t\tthis.flushTimer = setTimeout(\n\t\t\t() => {\n\t\t\t\tif (!this.flushTimer) return\n\n\t\t\t\tthis.flushTimer = undefined\n\t\t\t\tif (this.isUserIdle()) {\n\t\t\t\t\tvoid this.write()\n\t\t\t\t} else {\n\t\t\t\t\tthis.scheduleWrite()\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.pendingSnapshot ? WRITE_SNAPSHOT_DEBOUNCE_MS : WRITE_ROWS_DEBOUNCE_MS,\n\t\t)\n\t}\n\n\tprivate cancelPendingWrite(): void {\n\t\tif (this.flushTimer !== undefined) {\n\t\t\tclearTimeout(this.flushTimer)\n\t\t\tthis.flushTimer = undefined\n\t\t}\n\t}\n\n\tasync clearCache(): Promise<void> {\n\t\tthis.cancelPendingWrite()\n\t\tthis.pendingSnapshot = undefined\n\t\tthis.pendingSnapshotVersion = 0\n\t\tthis.pendingRows = []\n\t\tthis.concatPendingRows = false\n\t\tthis.pendingVersion = 0\n\t\t// Backend data first, then IDB metadata (which now holds the\n\t\t// snapshot-version/version markers too), then localStorage \u2014 mirror\n\t\t// of the write ordering. clearCache is best-effort; any single step\n\t\t// may fail but we still want to try all of them.\n\t\tawait this.backend.delMany([this.snapshotKey, this.rowsKey])\n\t\tawait deleteCacheMeta(this.projectId, this.backend.idbStore)\n\t\tlocalStorage.removeItem(this.localStorageVersionKey)\n\t\tthis.lastCrdtSyncStrategy(undefined)\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\tasync clearRows(version?: number): Promise<void> {\n\t\tthis.cancelPendingWrite()\n\t\tconst targetVersion = version ?? (await this.readTreeVersion())\n\t\tthis.pendingRows = []\n\t\tthis.concatPendingRows = false\n\t\tthis.pendingVersion = targetVersion\n\t\tawait this.backend.setMany([[this.rowsKey, [] satisfies RowsWithVersion[]]])\n\t\tawait writeCacheMeta(\n\t\t\tthis.projectId,\n\t\t\t{\n\t\t\t\tdataModel: LOCAL_CACHE_DATA_MODEL,\n\t\t\t\tversion: targetVersion,\n\t\t\t},\n\t\t\tthis.backend.idbStore,\n\t\t)\n\t\tlocalStorage.setItem(this.localStorageVersionKey, targetVersion.toString())\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\t/**\n\t * Reads cached data, reporting and aborting on storage errors.\n\t * Returns undefined both when no data is cached and when the backend is broken.\n\t */\n\tprivate async readDataOrAbort(): Promise<CrdtCacheData | undefined> {\n\t\ttry {\n\t\t\t// `return await` (not bare `return`) so the try/catch actually\n\t\t\t// observes async rejections from the backend.\n\t\t\treturn await this.readData()\n\t\t} catch (error) {\n\t\t\tlog.reportError(reportableError(error), {\n\t\t\t\tsnapshotVersion: this.pendingSnapshotVersion,\n\t\t\t\tversion: this.pendingVersion,\n\t\t\t\tbackend: this.backend.type,\n\t\t\t})\n\t\t\tthis.abortAndClearCache()\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\tasync syncCrdtData(prefetchSyncPromise: PrefetchSyncPromise): Promise<(CrdtCacheData & SyncCrdtMeta) | undefined> {\n\t\tif (this.aborted) return undefined\n\n\t\tconst response = await prefetchSyncPromise\n\t\tif (response.status < 200 || response.status >= 300) {\n\t\t\tthrow new Error(`Failed to fetch project data. Status code: ${response.status}`)\n\t\t}\n\t\tconst hierarchyHash = Number(response.headers.get(\"Hierarchy-Hash\")) || 0\n\n\t\tif (response.updates) {\n\t\t\tlog.debug(\"syncCrdtData: updates\")\n\t\t\tconst cached = await this.readDataOrAbort()\n\t\t\tif (!cached) return undefined\n\n\t\t\tconst serverUpdates = await response.updates\n\t\t\tconst allRows: RowsWithVersion[] = [...cached.rows]\n\t\t\tlet version = cached.version\n\t\t\tconst downloadedNewRows: BranchedSerializableRow[] = []\n\t\t\tfor (const update of serverUpdates) {\n\t\t\t\tif (update.next <= version) {\n\t\t\t\t\tlog.trace(\"skipping overlapping update\", update.next, \"<=\", version)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// With isMPSSocket we cannot check for gaps because the versions are timestamps.\n\t\t\t\tif (!this.isMPSSocket && update.next > version + 1) {\n\t\t\t\t\tlog.reportError(new Error(\"gap detected in local cache after updates\"), {\n\t\t\t\t\t\tsnapshotVersion: cached.snapshotVersion,\n\t\t\t\t\t\tversion,\n\t\t\t\t\t\tnextVersion: update.next,\n\t\t\t\t\t\tbackend: this.backend.type,\n\t\t\t\t\t})\n\t\t\t\t\tthis.abortAndClearCache()\n\t\t\t\t\treturn undefined\n\t\t\t\t}\n\n\t\t\t\tallRows.push({ version: update.next, rows: update.rows })\n\t\t\t\tfor (const row of update.rows) downloadedNewRows.push(row)\n\t\t\t\tversion = update.next\n\t\t\t}\n\t\t\tthis.resetRows(allRows, version)\n\t\t\tthis.setLastCrdtSyncStrategy(\"incremental\")\n\t\t\treturn {\n\t\t\t\tsnapshot: cached.snapshot,\n\t\t\t\tsnapshotVersion: cached.snapshotVersion,\n\t\t\t\trows: allRows,\n\t\t\t\tversion,\n\t\t\t\tsnapshotStorageBytes: cached.snapshotStorageBytes,\n\t\t\t\trowsStorageBytes: cached.rowsStorageBytes,\n\t\t\t\tsyncStrategy: \"incremental\",\n\t\t\t\tsnapshotSource: \"cached\",\n\t\t\t\tcacheBackend: this.backend.type,\n\t\t\t\tcachedRows: cached.rows.reduce((acc, row) => acc + row.rows.length, 0),\n\t\t\t\tcachedRowBytes: cached.rowsStorageBytes,\n\t\t\t\tdownloadedRows: downloadedNewRows.length,\n\t\t\t\tdownloadedRowBytes: estimateStorageBytes(downloadedNewRows),\n\t\t\t\thierarchyHash,\n\t\t\t}\n\t\t} else if (response.snapshot) {\n\t\t\tlog.debug(\"syncCrdtData: snapshot\")\n\t\t\tconst version = Number(response.headers.get(\"Tree-Version\"))\n\t\t\tassert(version > 0, \"Invalid tree version:\", version)\n\t\t\tconst snapshot = new Uint8Array(await response.snapshot)\n\t\t\tthis.storeSnapshot(snapshot, version, { syncStrategy: \"snapshot\" })\n\t\t\treturn {\n\t\t\t\tsnapshot,\n\t\t\t\tsnapshotVersion: version,\n\t\t\t\trows: [],\n\t\t\t\tversion,\n\t\t\t\t// Freshly downloaded \u2014 nothing is on disk yet. Storage bytes\n\t\t\t\t// only get populated once the upcoming write finishes and a\n\t\t\t\t// subsequent read picks the new sizes up.\n\t\t\t\tsnapshotStorageBytes: 0,\n\t\t\t\trowsStorageBytes: 0,\n\t\t\t\tsyncStrategy: \"snapshot\",\n\t\t\t\tsnapshotSource: \"downloaded\",\n\t\t\t\tcacheBackend: this.backend.type,\n\t\t\t\tcachedRows: 0,\n\t\t\t\tcachedRowBytes: 0,\n\t\t\t\tdownloadedRows: 0,\n\t\t\t\tdownloadedRowBytes: 0,\n\t\t\t\thierarchyHash,\n\t\t\t}\n\t\t} else {\n\t\t\tconst strategy = response.headers.get(\"Sync-Strategy\")\n\t\t\tassert(strategy === \"up-to-date\", \"unknown sync strategy:\", strategy)\n\t\t\tlog.debug(\"syncCrdtData: up-to-date\")\n\t\t\tconst cached = await this.readDataOrAbort()\n\t\t\tif (!cached) return undefined\n\t\t\tthis.setLastCrdtSyncStrategy(\"up-to-date\")\n\t\t\treturn {\n\t\t\t\t...cached,\n\t\t\t\tsyncStrategy: \"up-to-date\",\n\t\t\t\tsnapshotSource: \"cached\",\n\t\t\t\tcacheBackend: this.backend.type,\n\t\t\t\tcachedRows: cached.rows.reduce((acc, row) => acc + row.rows.length, 0),\n\t\t\t\tcachedRowBytes: cached.rowsStorageBytes,\n\t\t\t\tdownloadedRows: 0,\n\t\t\t\tdownloadedRowBytes: 0,\n\t\t\t\t/** Explicitly use 0, so we don't use the hash in the up-to-date strategy, because\n\t\t\t\t * we might have more rows cached, that the server still has to snapshot. */\n\t\t\t\thierarchyHash: 0,\n\t\t\t}\n\t\t}\n\t}\n\n\tget hasPending(): boolean {\n\t\treturn this.pendingSnapshot !== undefined || this.pendingRows.length > 0\n\t}\n\n\t/** Pending row count for debug UI only. */\n\tget pendingRowCountForDebug(): number {\n\t\treturn this.pendingRows.length\n\t}\n\n\t/** Whether a snapshot is waiting to flush (debug UI only). */\n\tget pendingSnapshotForDebug(): boolean {\n\t\treturn this.pendingSnapshot !== undefined\n\t}\n\n\tasync migrateToBackend(type: BackendType): Promise<void> {\n\t\tif (this.aborted) return\n\t\tawait this.write()\n\n\t\tconst data = await this.readData()\n\n\t\tconst newBackend = createLocalCacheDataBackend(type)\n\t\tthis.backend = newBackend\n\n\t\tif (data) {\n\t\t\tawait this.backend.setMany([\n\t\t\t\t[this.snapshotKey, data.snapshot],\n\t\t\t\t[this.rowsKey, data.rows],\n\t\t\t])\n\t\t\tawait writeCacheMeta(\n\t\t\t\tthis.projectId,\n\t\t\t\t{\n\t\t\t\t\tbackend: type,\n\t\t\t\t\tdataModel: LOCAL_CACHE_DATA_MODEL,\n\t\t\t\t\tsnapshotVersion: data.snapshotVersion,\n\t\t\t\t\tversion: data.version,\n\t\t\t\t},\n\t\t\t\tthis.backend.idbStore,\n\t\t\t)\n\t\t\tlocalStorage.setItem(this.localStorageVersionKey, data.version.toString())\n\t\t} else {\n\t\t\tawait writeCacheMeta(this.projectId, { backend: type }, this.backend.idbStore)\n\t\t}\n\t\tthis.bumpDebugGeneration()\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Snapshot compaction support\n\t// -----------------------------------------------------------------------\n\n\tasync readStoredRowCount(): Promise<number> {\n\t\tconst rawRows = await this.backend.get<RowsWithVersion[]>(this.rowsKey)\n\t\tif (!Array.isArray(rawRows)) return 0\n\t\tlet count = 0\n\t\tfor (const batch of rawRows) count += batch.rows.length\n\t\treturn count\n\t}\n\n\t/**\n\t * Applies a compacted snapshot at `snapshotVersion`, preserving any row\n\t * batches whose version is strictly greater than `snapshotVersion`. Both\n\t * persisted batches (from the data backend) and pending in-memory batches\n\t * are considered, so this works even when rows have arrived during the\n\t * snapshot fetch and span the snapshot's version boundary.\n\t */\n\tasync applySnapshotRefresh(snapshot: Uint8Array, snapshotVersion: number): Promise<void> {\n\t\tif (this.aborted) return\n\n\t\tconst persistedRows: RowsWithVersion[] = this.concatPendingRows\n\t\t\t? ((await this.backend.get<RowsWithVersion[]>(this.rowsKey)) ?? [])\n\t\t\t: []\n\t\tconst allRows = [...persistedRows, ...this.pendingRows]\n\t\tconst surviving = allRows.filter(b => b.version > snapshotVersion)\n\t\tconst lastSurviving = surviving[surviving.length - 1]\n\n\t\tthis.storeSnapshot(snapshot, snapshotVersion)\n\t\tif (lastSurviving !== undefined) {\n\t\t\t// storeSnapshot already set concatPendingRows = false.\n\t\t\tthis.pendingRows = surviving\n\t\t\tthis.pendingVersion = lastSurviving.version\n\t\t\tthis.scheduleWrite()\n\t\t\tthis.bumpDebugGeneration()\n\t\t}\n\t}\n\n\t/**\n\t * Runs snapshot refresh with proper write-blocking lifecycle.\n\t * Sets `snapshotRefreshInProgress` to block writes during the fetch,\n\t * then always clears it and flushes any rows that accumulated.\n\t */\n\tasync runSnapshotRefresh(): Promise<boolean> {\n\t\tthis.snapshotRefreshVersionAtStart = await this.readTreeVersion()\n\t\tthis.snapshotRefreshInProgress = true\n\t\ttry {\n\t\t\t// `return await` (not bare `return`) so the flag stays true\n\t\t\t// until the refresh actually settles; bare `return` would let\n\t\t\t// `finally` run as soon as the promise is created.\n\t\t\treturn await performSnapshotRefresh(this, this.snapshotRefreshVersionAtStart)\n\t\t} finally {\n\t\t\tthis.snapshotRefreshInProgress = false\n\t\t\tif (this.hasPending) this.scheduleWrite()\n\t\t}\n\t}\n\n\tprivate async maybeRunCompaction(): Promise<void> {\n\t\tawait this.runSnapshotRefresh()\n\t}\n\n\tprivate async maybeRunMaintenance(): Promise<void> {\n\t\tif (typeof localStorage === \"undefined\") return\n\n\t\tawait this.maybeRunCompaction()\n\n\t\tconst lastRun = localStorage.getItem(MAINTENANCE_LAST_RUN_KEY)\n\t\tif (lastRun && Date.now() - Number(lastRun) < MAINTENANCE_COOLDOWN_MS) return\n\t\tif (!this.isUserIdle()) return\n\n\t\tconst completed = await performLocalCacheMaintenance(this.isUserIdle)\n\t\tif (!completed) return\n\t\tlocalStorage.setItem(MAINTENANCE_LAST_RUN_KEY, Date.now().toString())\n\t}\n\n\t/** Will download rows from the server and verify they match the rows we have in the cache. */\n\tasync debugVerifyRows(syncURL: string): Promise<DebugVerifyRowsResult> {\n\t\treturn performDebugVerifyRows({\n\t\t\tsyncURL,\n\t\t\treadData: () => this.readData(),\n\t\t})\n\t}\n\n\tdispose(): void {\n\t\tclearInterval(this.maintenanceTimer)\n\t\tvoid this.write()\n\t}\n}\n", "import { openNewTab } from \"@framerjs/app-shared\"\nimport { BINARY_SCHEMA_VERSION } from \"@framerjs/crdtree2\"\nimport { triggerErrorToastEvent } from \"@framerjs/framer-events\"\nimport type { ToastAction } from \"@framerjs/fresco\"\nimport { assert, assertNever, getLogger, hostInfo } from \"@framerjs/shared\"\nimport { employeesOnlySettings } from \"app/employeesOnlySettings.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { loadDocumentMetrics } from \"app/trackDocumentLoad.ts\"\nimport { shouldNeverLoadRest, treeModeMismatch, treeModeWithFallback } from \"document/crdt/isCrdt.ts\"\nimport { environment } from \"environment/index.ts\"\nimport type { LockMessageData, Message, Socket, TreeMessageData, TreeVerifyData } from \"socket/types.ts\"\nimport { DisconnectReason } from \"socket/types.ts\"\nimport { isRecoverableDisconnectReason } from \"socket/useSocket.ts\"\nimport { isNumber } from \"utils/typeChecks.ts\"\nimport { performanceClearMarks, performanceMark, performanceMeasure } from \"utils/userTiming.ts\"\nimport { updateProject } from \"web/lib/ProjectAPI.js\"\nimport { accessTokenRefresher } from \"web/lib/accessTokenRefresherWeb.ts\"\nimport { apiFetcher } from \"web/lib/apiFetcher.ts\"\nimport { getMultiplayerServiceURL } from \"web/lib/multiplayerService.ts\"\nimport { showTreeModeMismatchToast } from \"web/lib/showTreeModeMismatchToast.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { JsonRemoteDocumentDataHandler } from \"./JsonRemoteDocumentDataHandler.ts\"\nimport type { RemoteDocumentDataHandler, RemoteDocumentDataHandlerCallbacks } from \"./RemoteDocumentDataHandler.ts\"\nimport type { RemoteDocumentConnection, RemoteDocumentHandler, ServerTreeUpdate } from \"./RemoteDocumentHandler.ts\"\nimport type { LockState } from \"./RemoteLocks.ts\"\nimport { RemoteLocks } from \"./RemoteLocks.ts\"\nimport type { VekterEngine } from \"./VekterEngine.ts\"\nimport { deleteLocalStorageVersionKey, LocalCache } from \"./crdt/sync/LocalCache.ts\"\nimport { CrdtRemoteDocumentDataHandler } from \"./crdt/sync/index.ts\"\nimport type { DocumentLoaderSettings } from \"./loader/DocumentLoader.ts\"\nimport { CanvasTreeVersion } from \"./models/CanvasTree/CanvasTreeVersion.ts\"\nimport { treeLibrary } from \"./models/CanvasTree/FastTreeLibrary.ts\"\nimport { type CanvasNode, CanvasTree } from \"./models/CanvasTree/index.ts\"\nimport type { CrdtConfirm, CrdtUpdate } from \"./models/CanvasTree/treeSyncUtils.ts\"\nimport type { LoadingStore } from \"./stores/LoadingStore.ts\"\nimport type { TreeMode } from \"./stores/TreeMode.ts\"\nimport type { TreeStore } from \"./stores/TreeStore.ts\"\nimport { addBeforeUnloadHandler } from \"./utils/beforeUnloadHandler.ts\"\n\nconst log = getLogger(\"remote:connection\")\n\n/** After a client error, another error before the recovery time will turn it\n * into a permanent error. */\nconst CLIENT_ERROR_RECOVERY_MS = 30 * 1000\nconst RETRY_SENDING_MS = 100\n\ninterface DesiredToast {\n\ttext?: string\n\tprimaryText?: string\n\tsecondaryText?: string\n\tvariant: \"progress\" | \"warning\"\n\ticon: \"reconnecting\" | \"warning\"\n\taction?: ToastAction\n\tevent?: Parameters<typeof triggerErrorToastEvent>[0]\n}\n\nfunction getToastTextSignature(options: Pick<DesiredToast, \"text\" | \"primaryText\" | \"secondaryText\">): string {\n\treturn `${options.text ?? \"\"}|${options.primaryText ?? \"\"}|${options.secondaryText ?? \"\"}`\n}\n\nconst reconnectToast: DesiredToast = {\n\tprimaryText: \"Reconnecting.\",\n\tsecondaryText: \"Just a moment\u2026\",\n\tvariant: \"progress\",\n\ticon: \"reconnecting\",\n}\n\n// we enumerate all possible prefixes here to ensure type safety and to avoid unexpected values\ntype LoaderTypePrefix =\n\t| \"FullParse\"\n\t| \"ShallowScopes\"\n\t| \"Debug+ShallowScopes\"\n\t| \"FullParse+ShallowScopes\"\n\t| \"FullParse+Debug+ShallowScopes\"\n\n/**\n * The LoaderType is used to identify the type of loader that is currently active.\n */\ntype LoaderType = \"DocumentLoader\" | `${LoaderTypePrefix}+DocumentLoader`\n\nexport class RemoteDocument implements RemoteDocumentHandler {\n\tprivate permanentlyFailed = false\n\tprivate lastClientSideError = -CLIENT_ERROR_RECOVERY_MS\n\tprivate loadingStore: LoadingStore\n\tprivate postponedLastUpdate: ReturnType<typeof setTimeout> | undefined\n\tremote: RemoteDocumentConnection | null = null\n\tlocks: RemoteLocks\n\ttreeSchema = CanvasTreeVersion\n\n\tget isMPSSocket(): boolean {\n\t\treturn this.engine.stores.treeStore.isMPSSocket\n\t}\n\n\tprivate currentDocumentUrl: string | undefined\n\tprivate scheduledProcessing = false\n\n\t/** Used when the page loads for the first time. */\n\tinitialLoad = true\n\n\t/** Used when we load the page, or by the history panel, will delay the connection toast. */\n\tprivate initialConnection = true\n\n\t/** Used to track the time between the remote connection and the document having loaded. */\n\tprivate startLoadingTime = 0\n\n\t/** Suppresses the disconnected toast. */\n\tprivate isReconnecting = false\n\n\t// track time spend\n\tprivate totalTime = 0\n\n\t// for debugging\n\tsocket?: Socket\n\n\t/** Will refuse any init message, thus not load any document. Use DebugBar -> controls -> Reload\n\t * Document From Server to actually load the document. Can be used to separate debugging of\n\t * loading Framer from loading the document. */\n\tsuppressLoadingForDebugging = employeesOnlySettings.isOn(\"suppressDocumentLoading\")\n\n\tsetSocket(socket: Socket) {\n\t\tthis.socket = socket\n\t}\n\n\tget loader() {\n\t\treturn this.treeDataHandler.loader\n\t}\n\n\tpublic documentByteSize = 0\n\n\tprivate updateConnectionTimerID: number | undefined = undefined\n\n\ttreeDataHandler: RemoteDocumentDataHandler\n\treadonly localCache?: LocalCache\n\tprivate readonly treeDataHandlerCallbacks: RemoteDocumentDataHandlerCallbacks\n\n\tconstructor(\n\t\treadonly engine: VekterEngine,\n\t\treadonly projectId: string,\n\t\treadonly userId: string,\n\t\treadonly onError: (error: Error) => void,\n\t\treadonly onInitialLoad: (startLoadingTime: number) => void,\n\t\treadonly onPermanentlyFailed: (reason: DisconnectReason) => void,\n\t\treadonly requestIdleCallback?: (task: () => void) => void,\n\t) {\n\t\tif (experiments.isOn(\"localCache\")) {\n\t\t\tthis.localCache = new LocalCache(\n\t\t\t\tprojectId,\n\t\t\t\tengine.scheduler.isUserIdle.bind(engine.scheduler),\n\t\t\t\tundefined,\n\t\t\t\tengine.eventListenerAbortController.signal,\n\t\t\t\tengine.stores.treeStore.isMPSSocket,\n\t\t\t)\n\t\t} else {\n\t\t\t// If the experiment is off, we want to make sure to delete the local storage key,\n\t\t\t// otherwise `web.ejs` will always prefetch using the stale cached version.\n\t\t\tthis.localCache = undefined\n\t\t\tdeleteLocalStorageVersionKey(projectId)\n\t\t}\n\n\t\tthis.treeDataHandlerCallbacks = {\n\t\t\trequestIdleCallback,\n\t\t\terror: onError,\n\t\t\terrorRecoverable: this.handleErrorRecoverable,\n\t\t\tupdateProcessed: this.handleUpdateProcessed,\n\t\t}\n\n\t\tthis.treeDataHandler = this.createTreeDataHandler()\n\t\tthis.loadingStore = engine.stores.loadingStore\n\t\tthis.locks = new RemoteLocks(userId)\n\n\t\t// Tell the data handler about the current tab visibility, and keep it\n\t\t// in sync. CRDT verifies are buffered while hidden because the engine\n\t\t// scheduler is throttled but websocket messages still arrive \u2014 the\n\t\t// next `processRemoteUpdates` after the tab becomes visible re-checks\n\t\t// the latest buffered verify against fully-drained state.\n\t\tthis.treeDataHandler.setDocumentHidden?.(document.hidden)\n\t\tdocument.addEventListener(\n\t\t\t\"visibilitychange\",\n\t\t\t() => {\n\t\t\t\tthis.treeDataHandler.setDocumentHidden?.(document.hidden)\n\t\t\t},\n\t\t\t{ signal: engine.eventListenerAbortController.signal },\n\t\t)\n\n\t\tthis.updateConnectionTimerID = window.setInterval(this.updateConnectionTimer, 500)\n\t\tsetTimeout(this.updateConnectionTimer, 0)\n\t\taddBeforeUnloadHandler({\n\t\t\tcheck: () => {\n\t\t\t\tif (!this.remote) return false\n\t\t\t\treturn this.treeDataHandler.hasUnconfirmedChanges()\n\t\t\t},\n\t\t\teffect: () => {\n\t\t\t\tif (!this.remote) return\n\t\t\t\tthis.treeDataHandler.flushUpdates(this.remote)\n\t\t\t},\n\t\t})\n\t}\n\n\tprivate createTreeDataHandler(): RemoteDocumentDataHandler {\n\t\tconst appEnvironment = environment.isApiPlugin ? \"api\" : \"vekter\"\n\t\tconst treeStore: TreeStore = this.engine.stores.treeStore\n\t\tif (treeStore.mode === \"crdt\") {\n\t\t\treturn new CrdtRemoteDocumentDataHandler(\n\t\t\t\ttreeStore.crdtTimeline,\n\t\t\t\tthis.engine.componentLoader,\n\t\t\t\tthis.userId,\n\t\t\t\tthis.projectId,\n\t\t\t\tthis.treeDataHandlerCallbacks,\n\t\t\t\tthis.localCache,\n\t\t\t\ttreeStore.isMPSSocket,\n\t\t\t\tappEnvironment,\n\t\t\t)\n\t\t}\n\n\t\treturn new JsonRemoteDocumentDataHandler(\n\t\t\ttreeStore.timeline,\n\t\t\tthis.engine.componentLoader,\n\t\t\tthis.projectId,\n\t\t\tthis.treeDataHandlerCallbacks,\n\t\t\ttreeStore.isMPSSocket,\n\t\t\tappEnvironment,\n\t\t)\n\t}\n\n\tprivate setTreeModeFromInit(mode: TreeMode | undefined): void {\n\t\tconst treeMode = treeModeWithFallback(mode)\n\t\tconst treeStore: TreeStore = this.engine.stores.treeStore\n\t\tif (treeStore.mode === treeMode) return\n\n\t\ttreeStore.mode = treeMode\n\t\tthis.treeDataHandler = this.createTreeDataHandler()\n\t\tthis.treeDataHandler.setDocumentHidden?.(document.hidden)\n\t}\n\n\tprivate errorClientTooNew() {\n\t\tthis.setPermanentlyFailed(DisconnectReason.ClientTooNew)\n\t\tthis.engine.stores.loadingStore.hasError = true\n\t\tthis.engine.remoteDocument = null\n\t\tif (environment.isDebugBuild) {\n\t\t\t// Pretend loading went fine. This means we will\n\t\t\t// continue creating localDB snapshots, enable preview,\n\t\t\t// enable save-as, etc.\n\t\t\tthis.engine.treeReflectsDocument = true\n\t\t} else {\n\t\t\t// If not in a debug build, this will set the document\n\t\t\t// to read only.\n\t\t\tthis.setDisconnected(true)\n\t\t}\n\t}\n\n\tprivate errorClientNeedsUpdate() {\n\t\tthis.setPermanentlyFailed(DisconnectReason.ClientNeedsUpdate)\n\t\tthis.engine.stores.loadingStore.hasError = true\n\n\t\tif (environment.isDebugBuild) {\n\t\t\t// Remove the remote document, so the document will work locally.\n\t\t\tthis.engine.remoteDocument = null\n\t\t} else {\n\t\t\t// Put in read only mode\n\t\t\tthis.setDisconnected(true)\n\t\t}\n\t}\n\n\tprivate handleErrorRecoverable = (recoveredTree?: CanvasTree) => {\n\t\tthis.setRemoteConnectionFailure(DisconnectReason.ClientSideRecoverableError)\n\n\t\tif (recoveredTree) {\n\t\t\tthis.engine.treeReflectsDocument = false\n\t\t\tthis.engine.tree = recoveredTree\n\t\t}\n\t}\n\n\tprivate handleUpdateProcessed = (tree: CanvasTree) => {\n\t\tif (tree !== this.engine.tree) {\n\t\t\tthis.engine.newTreeAfterRemoteUpdate(tree)\n\t\t}\n\n\t\tif (this.treeDataHandler.isReady) {\n\t\t\tthis.handleInitialLoad()\n\t\t\tthis.setNetworkReady(true)\n\t\t}\n\t}\n\n\thandleRows(id: string, update: CrdtUpdate): void {\n\t\tthis.treeDataHandler.handleRows(id, update)\n\t\tif (this.treeDataHandler.hasUpdatesToProcess) {\n\t\t\tthis.scheduleProcessUpdates()\n\t\t}\n\t}\n\n\thandleConfirmRows(_id: string, value: CrdtConfirm): void {\n\t\tthis.treeDataHandler.handleConfirmRows(value)\n\t\tif (this.treeDataHandler.hasUpdatesToProcess) {\n\t\t\tthis.scheduleProcessUpdates()\n\t\t}\n\t}\n\n\tcreateLoader(url: string, version: number, settings: DocumentLoaderSettings) {\n\t\treturn this.treeDataHandler.createLoader(url, version, settings)\n\t}\n\n\tprivate setPermanentlyFailed(reason: DisconnectReason) {\n\t\tthis.permanentlyFailed = true\n\t\tthis.networkReady = false\n\t\tclearInterval(this.updateConnectionTimerID)\n\n\t\t// Hide the connection ping toast if shown.\n\t\tthis.setDesiredToast(null)\n\n\t\tthis.onPermanentlyFailed(reason)\n\n\t\tif (reason === DisconnectReason.ClientNeedsUpdate) {\n\t\t\t// If the reason we failed is because there's a newer version available, show a toast.\n\t\t\tif (environment.isDebugBuild) {\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"warning\",\n\t\t\t\t\tprimaryText: \"Server too new.\",\n\t\t\t\t\tsecondaryText: \"Cannot load or save.\",\n\t\t\t\t\tkey: \"client-outdated\",\n\t\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\t\ticon: \"warning\",\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.setDisconnected(true)\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"warning\",\n\t\t\t\t\tprimaryText: \"A new version\",\n\t\t\t\t\tsecondaryText: \"of Framer is available. Please reload the page to continue working.\",\n\t\t\t\t\tkey: \"client-outdated\",\n\t\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\t\ticon: \"warning\",\n\t\t\t\t\tshowCloseButton: \"never\",\n\t\t\t\t\taction: {\n\t\t\t\t\t\ttitle: \"Reload\",\n\t\t\t\t\t\tonClick: () => window.top!.location.reload(),\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (reason === DisconnectReason.ClientTooNew) {\n\t\t\t// If the client is newer, it is likely a development branch, show a toast.\n\t\t\t// Make sure the toast is a sticky error if we\u2019re not a development build\n\t\t\tif (environment.isDebugBuild) {\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"warning\",\n\t\t\t\t\tprimaryText: \"Server cannot save changes.\",\n\t\t\t\t\tsecondaryText: \"Client too new.\",\n\t\t\t\t\tkey: \"client-too-new\",\n\t\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\t\ticon: \"warning\",\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.setDisconnected(true)\n\t\t\t\ttoast({\n\t\t\t\t\ttype: \"add\",\n\t\t\t\t\tvariant: \"error\",\n\t\t\t\t\tprimaryText: \"Beta under maintenance.\",\n\t\t\t\t\tsecondaryText: \"Switch to Framer.\",\n\t\t\t\t\tkey: \"client-too-new\",\n\t\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\t\ticon: \"error\",\n\t\t\t\t\tshowCloseButton: \"never\",\n\t\t\t\t\taction: {\n\t\t\t\t\t\ttitle: \"Switch\",\n\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\tif (!hostInfo.hosts) return\n\t\t\t\t\t\t\t// Sneakily switch to production, where this should never happen\n\t\t\t\t\t\t\tconst url = new URL(window.location.href)\n\t\t\t\t\t\t\turl.host = hostInfo.hosts.main\n\t\t\t\t\t\t\twindow.location.href = url.href\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (reason === DisconnectReason.Maintenance) {\n\t\t\t// Server communicates maintenance mode\n\t\t\tthis.setDisconnected(true)\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"warning\",\n\t\t\t\tprimaryText: \"Ongoing maintenance.\",\n\t\t\t\tsecondaryText: \"Please reload later.\",\n\t\t\t\tkey: \"maintenance-mode\",\n\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\ticon: \"warning\",\n\t\t\t\tshowCloseButton: \"never\",\n\t\t\t\taction: {\n\t\t\t\t\ttitle: \"Reload\",\n\t\t\t\t\tonClick: () => window.top!.location.reload(),\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif (reason === DisconnectReason.CrdtMigrationFailed) {\n\t\t\t// Server communicates maintenance mode\n\t\t\tthis.setDisconnected(true)\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"warning\",\n\t\t\t\tprimaryText: \"CRDT migration failed.\",\n\t\t\t\tsecondaryText: \"Switch to JSON mode.\",\n\t\t\t\tkey: \"maintenance-mode\",\n\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\ticon: \"warning\",\n\t\t\t\tshowCloseButton: \"never\",\n\t\t\t\taction: {\n\t\t\t\t\ttitle: \"Switch\",\n\t\t\t\t\tonClick: async () => {\n\t\t\t\t\t\tconst projectId = this.projectId\n\t\t\t\t\t\tif (!projectId) return\n\n\t\t\t\t\t\t// Update the projects service to toggle the feature\n\t\t\t\t\t\t// TODO: Remove this legacy canvasFeatures.crdt write once CRDT is fully shipped.\n\t\t\t\t\t\tawait updateProject(projectId, { canvasFeatures: { crdt: false } })\n\n\t\t\t\t\t\twindow.top!.location.reload()\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tif (reason === DisconnectReason.TreeModeMismatch) {\n\t\t\tthis.setDisconnected(true)\n\t\t\tshowTreeModeMismatchToast()\n\t\t\treturn\n\t\t}\n\n\t\t// Otherwise always report an error and show a generic error toast to the user.\n\t\tlog.reportError(\"Connection permanently failed: \" + reason)\n\t\tthis.setDisconnected(true)\n\t\tconst isReconnectingReason =\n\t\t\treason === DisconnectReason.ReconnectToNewServer || reason.toLowerCase() === \"reconnecting\"\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\tvariant: \"error\",\n\t\t\tprimaryText: \"Connection error.\",\n\t\t\tsecondaryText: isReconnectingReason ? \"Currently reconnecting\u2026\" : `Currently ${reason}.`,\n\t\t\tkey: \"connection-error\",\n\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\ticon: \"error\",\n\t\t\tshowCloseButton: \"never\",\n\t\t})\n\t}\n\n\t/** Sets the document in read only mode if not connected. */\n\tprivate setDisconnected(disconnected: boolean) {\n\t\tthis.loadingStore.busyReconnecting = disconnected\n\t}\n\n\tprivate lastUpdate = -1\n\tprivate averageUIDelay = -1\n\tprivate updateAverageUIDelay() {\n\t\tconst now = performance.now()\n\t\tif (this.lastUpdate < 0) {\n\t\t\tthis.lastUpdate = now\n\t\t}\n\t\tconst delta = now - this.lastUpdate\n\t\tthis.lastUpdate = now\n\t\tconst delay = Math.max(0, delta - 500)\n\t\tif (this.averageUIDelay < 0) {\n\t\t\tthis.averageUIDelay = delay\n\t\t}\n\t\tthis.averageUIDelay = this.averageUIDelay * 0.8 + delay * 0.2\n\t}\n\n\tprivate updateConnectionTimer = () => {\n\t\tthis.updateAverageUIDelay()\n\t\tthis.updateConnectionState()\n\t}\n\n\tnetworkReady = false\n\tprivate setNetworkReady(ready: boolean) {\n\t\tif (this.networkReady === ready) return\n\t\tif (ready) {\n\t\t\tthis.initialConnection = false\n\t\t}\n\t\tthis.networkReady = ready\n\t\tthis.updateConnectionState()\n\n\t\tif (!ready || !this.remote) return\n\t\tthis.treeDataHandler.resendUnconfirmedUpdates(this.remote)\n\n\t\t// On the new Multiplayer Service the server does not auto-replay\n\t\t// pending updates after a reconnect, so flush them explicitly.\n\t\tif (this.engine.stores.treeStore.isMPSSocket) {\n\t\t\tthis.sendToRemote()\n\t\t}\n\t}\n\n\tprivate handleInitialLoad() {\n\t\tif (!this.initialLoad) return\n\t\tlog.debug(\"handling initial load\")\n\t\tthis.initialLoad = false\n\t\tthis.onInitialLoad(this.startLoadingTime)\n\t}\n\n\tprivate updateConnectionState() {\n\t\tif (!this.remote && this.permanentlyFailed) return\n\n\t\t// Warn the user that the connection is slow when client is out of sync by this many seconds.\n\t\tconst warningThreshold = 15\n\t\t// Tell the user that server connection is unavailable and disable UI after this many seconds.\n\t\tconst stalledThreshold = 30\n\n\t\tconst error = this.treeDataHandler.hasError\n\t\tconst ready = this.treeDataHandler.isReady && this.networkReady\n\t\tconst online =\n\t\t\tnavigator.onLine || window.location.hostname === \"localhost\" || window.location.hostname === \"127.0.0.1\"\n\n\t\t// Don't do any toasts when we are in an error state, and Vekter is showing its red error bar.\n\t\tconst redBarErrorShowing = !!this.engine.stores.documentSettingsStore.crashData\n\t\tif (error && redBarErrorShowing) {\n\t\t\tthis.setDesiredToast(null)\n\t\t\tthis.setDisconnected(true)\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.remote) {\n\t\t\tif (this.isReconnecting) return\n\t\t\tthis.setDesiredToast(reconnectToast)\n\t\t\tthis.setDisconnected(true)\n\t\t\treturn\n\t\t}\n\n\t\t// Calculate the latency in seconds, taking UI delays into account.\n\t\tconst latency = (this.remote.rtt() - this.averageUIDelay) / 1000\n\t\tif (latency >= stalledThreshold) {\n\t\t\tthis.setDesiredToast({\n\t\t\t\t...(online\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tprimaryText: \"Slow connection.\",\n\t\t\t\t\t\t\tsecondaryText: \"Editing is disabled.\",\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tprimaryText: \"Offline.\",\n\t\t\t\t\t\t\tsecondaryText: \"Editing is disabled.\",\n\t\t\t\t\t\t}),\n\t\t\t\tvariant: \"warning\",\n\t\t\t\ticon: \"warning\",\n\t\t\t\tevent: { errorType: \"connection_lost\", message: \"slow_connection_editing_disabled\" },\n\t\t\t\taction: {\n\t\t\t\t\ttitle: \"Learn more\",\n\t\t\t\t\tonClick() {\n\t\t\t\t\t\topenNewTab(\"https://www.framer.com/learn/offline-or-slow-connection/\")\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t})\n\t\t\tthis.setDisconnected(true)\n\t\t} else if (latency >= warningThreshold) {\n\t\t\tthis.setDesiredToast({\n\t\t\t\tprimaryText: \"Slow connection.\",\n\t\t\t\tsecondaryText: \"Edits may not work\u2026\",\n\t\t\t\tvariant: \"warning\",\n\t\t\t\ticon: \"warning\",\n\t\t\t\tevent: { errorType: \"connection_lost\", message: \"slow_connection_warning\" },\n\t\t\t})\n\t\t\tthis.setDisconnected(!ready)\n\t\t} else if (!ready && !error) {\n\t\t\tif (this.initialConnection) {\n\t\t\t\t// When this is the first load, don't immediately show a toast, but only after a while\n\t\t\t\tconst secondsLoading = (Date.now() - this.startLoadingTime) / 1000\n\t\t\t\tif (secondsLoading < warningThreshold) return\n\n\t\t\t\tthis.setDesiredToast({\n\t\t\t\t\tprimaryText: \"Connecting\u2026\",\n\t\t\t\t\tsecondaryText: \"Editing is disabled.\",\n\t\t\t\t\tvariant: \"progress\",\n\t\t\t\t\ticon: \"reconnecting\",\n\t\t\t\t})\n\t\t\t\tthis.setDisconnected(true)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tthis.setDesiredToast({\n\t\t\t\tprimaryText: \"Restoring connection.\",\n\t\t\t\tsecondaryText: \"Editing is disabled.\",\n\t\t\t\tvariant: \"progress\",\n\t\t\t\ticon: \"reconnecting\",\n\t\t\t})\n\t\t\tthis.setDisconnected(true)\n\t\t} else {\n\t\t\t// errors show up via the red bar and it offers a reload button, no need to deal with it here\n\t\t\tthis.setDesiredToast(null)\n\t\t\tthis.setDisconnected(!ready)\n\t\t}\n\t}\n\n\tprivate desiredToastSignature: string | undefined\n\tprivate desiredToastShowing: boolean = false\n\tprivate lastToastChange = 0\n\n\t// Show a toast, but wait a short amount of time in case circumstances change (to avoid flashing toasts).\n\tprivate setDesiredToast(desiredToast: DesiredToast | null) {\n\t\t// Don't show toasts in the test environment.\n\t\tif (environment.isTest) return\n\n\t\t// setDesiredToast is regularly called, we want to track when a new toast was requested\n\t\tconst desiredToastSignature = desiredToast ? getToastTextSignature(desiredToast) : undefined\n\t\tif (this.desiredToastSignature !== desiredToastSignature) {\n\t\t\tthis.desiredToastShowing = false\n\t\t\tthis.desiredToastSignature = desiredToastSignature\n\t\t\tthis.lastToastChange = performance.now()\n\t\t}\n\n\t\t// Use a key for the toasts so there can only be one at a time.\n\t\tconst TOAST_KEY_CONNECTION_STATUS = \"connection-status\"\n\n\t\t// Apply removal of toasts right away. Because the toast function is a\n\t\t// reducer action, and this method might be called from another reducer,\n\t\t// React will warn when that happens, so we will schedule the action to\n\t\t// happen at the end of the current run loop. This has a small\n\t\t// performance hit due to the re-render, but it's relatively rare.\n\t\tif (!desiredToast) {\n\t\t\t// this avoids an infinite re-render loop\n\t\t\tif (this.desiredToastShowing) return\n\n\t\t\tthis.desiredToastShowing = true\n\t\t\tqueueMicrotask(() => {\n\t\t\t\ttoast({ type: \"remove\", key: TOAST_KEY_CONNECTION_STATUS })\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\t// Schedule a toast a short amount of time from now.\n\t\twindow.setTimeout(() => {\n\t\t\tif (performance.now() - this.lastToastChange < 500) return\n\n\t\t\tconst { text, primaryText, secondaryText, variant, icon, event, action } = desiredToast\n\t\t\tif (this.desiredToastSignature !== getToastTextSignature(desiredToast)) return\n\n\t\t\t// Add the toast to the screen (replacing any previous connection toast).\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant,\n\t\t\t\tkey: TOAST_KEY_CONNECTION_STATUS,\n\t\t\t\tduration: Number.POSITIVE_INFINITY,\n\t\t\t\tshowCloseButton: \"never\",\n\t\t\t\ttext,\n\t\t\t\tprimaryText,\n\t\t\t\tsecondaryText,\n\t\t\t\ticon,\n\t\t\t\taction,\n\t\t\t})\n\n\t\t\t// Also log an event associated with the display of the toast.\n\t\t\tif (event) {\n\t\t\t\ttriggerErrorToastEvent(event)\n\t\t\t}\n\t\t}, 500)\n\t}\n\n\tprepareForReconnect(): void {\n\t\tif (this.permanentlyFailed) {\n\t\t\tthis.permanentlyFailed = false\n\t\t\tthis.updateConnectionTimerID = window.setInterval(this.updateConnectionTimer, 500)\n\t\t}\n\t\tthis.lastClientSideError = -CLIENT_ERROR_RECOVERY_MS\n\t}\n\n\thasRemoteConnection(): boolean {\n\t\treturn !!this.remote\n\t}\n\n\tasync forceServerSnapshot(options?: { forceCompact?: boolean }): Promise<void> {\n\t\tconst forceCompact = options?.forceCompact ?? false\n\t\tconst path = `/projects/${this.projectId}/tree/latest`\n\t\t// TODO: Remove the conditional once we've fully migrated to FramerMultiplayerService\n\t\tconst documentURL = this.engine.stores.treeStore.isMPSSocket\n\t\t\t? new URL(getMultiplayerServiceURL(path))\n\t\t\t: new URL(path, window.location.href)\n\n\t\tdocumentURL.searchParams.set(\"forceSnapshot\", forceCompact ? \"forceCompact\" : \"true\")\n\t\tconst crdtResponse = await fetch(documentURL, await accessTokenRefresher.withAuthorizationHeader({}))\n\t\tif (!crdtResponse.ok) {\n\t\t\tthrow Error(\n\t\t\t\t`error requesting latest tree with forceSnapshot=true: ${crdtResponse.status} ${crdtResponse.statusText}`,\n\t\t\t)\n\t\t}\n\t}\n\n\t/** For testing purposes. */\n\tverifyTreeWithServer(): Promise<number> {\n\t\treturn this.treeDataHandler.verifyTreeWithServer()\n\t}\n\n\tfinishPartialLoad() {\n\t\tif (!this.loader) return\n\n\t\t// We will be called multiple times, as the deferred rendering phase goes to normal, or\n\t\t// as the modules runtime is loading modules state changes. Only if we are done loading\n\t\t// modules will we resume the loader. Calling resume a second time is harmless.\n\t\tif (shouldNeverLoadRest()) return\n\t\tif (this.engine.stores.loadingStore.isLoadingModules) return\n\t\tthis.loader.resumeLoadingScopes()\n\t}\n\n\tget loaderType(): LoaderType {\n\t\tlet prefix: LoaderTypePrefix = experiments.isOn(\"debugEditWhileNeverLoadingRest\")\n\t\t\t? \"Debug+ShallowScopes\"\n\t\t\t: \"ShallowScopes\"\n\t\tif (employeesOnlySettings.isOn(\"disablePartialDocumentLoading\")) {\n\t\t\tprefix = prefix ? `FullParse+${prefix}` : \"FullParse\"\n\t\t}\n\n\t\tconst result: LoaderType = prefix ? `${prefix}+DocumentLoader` : \"DocumentLoader\"\n\n\t\t// ensure that any new loader types are also returned in this getter\n\t\t// will be dropped from the bundle in production\n\t\tif (process.env.NODE_ENV === \"development\") {\n\t\t\tswitch (result) {\n\t\t\t\tcase \"DocumentLoader\":\n\t\t\t\tcase \"ShallowScopes+DocumentLoader\":\n\t\t\t\tcase \"Debug+ShallowScopes+DocumentLoader\":\n\t\t\t\tcase \"FullParse+ShallowScopes+DocumentLoader\":\n\t\t\t\tcase \"FullParse+Debug+ShallowScopes+DocumentLoader\":\n\t\t\t\tcase \"FullParse+DocumentLoader\":\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tassertNever(result)\n\t\t\t}\n\t\t}\n\n\t\treturn result\n\t}\n\n\t/** Downloads and renders the tree for the version provided in treeInitData.\n\t * Only renders the tree if it no tree has been rendered yet.\n\t */\n\tprivate fallbackToInitialDocumentJson = async () => {\n\t\tconst version = this.engine.stores.treeStore.initialSnapshotVersion\n\n\t\tconst noVersionWasRendered = this.treeDataHandler.treeVersion === 0\n\n\t\t// We only download the initial document if we haven't rendered any version yet.\n\t\t// This allows us to render a project without the server owning the lock for it,\n\t\t// but we want to ensure that we don't render an old version of the project if\n\t\t// the server loses the lock (e.g. restarts) while the user is actively working on the project.\n\t\tif (!noVersionWasRendered || !version) return\n\n\t\ttry {\n\t\t\tawait this.downloadDocument(\"\", version)\n\t\t\tloadDocumentMetrics.trackRemainingLoad({\n\t\t\t\tstartLoadingTime: this.startLoadingTime,\n\t\t\t\ttreeSize: this.engine.tree.size(),\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tlog.error(\"Failed to download initial document JSON:\", e)\n\t\t}\n\t}\n\n\t#resetChatTextTimerId: number | undefined\n\tprivate clearScheduledChatTextReset() {\n\t\twindow.clearTimeout(this.#resetChatTextTimerId)\n\t\tthis.#resetChatTextTimerId = undefined\n\t}\n\n\t/** Schedules any active chat text to be cleared after a grace period. */\n\tscheduleChatTextReset() {\n\t\tthis.clearScheduledChatTextReset()\n\t\tthis.#resetChatTextTimerId = window.setTimeout(() => {\n\t\t\tthis.setChatText(\"\")\n\t\t}, 5_000)\n\t}\n\n\t/** Sets a text to show next to the current user's cursor on other users' screens. This also clears any scheduled reset. */\n\tsetChatText(chat: string) {\n\t\tthis.clearScheduledChatTextReset()\n\t\t// We don't really expect chat messages to get this long, but if they do...\n\t\tif (chat.length > 300) chat = chat.substring(0, 300)\n\t\tthis.remote?.updateUserState({ chat })\n\t}\n\n\trequestFileLock(id: string, duration = 30): boolean {\n\t\tif (!this.remote) return false\n\t\tconst msg = this.locks.claim(`file:${id}`, duration)\n\t\tif (!msg) return false\n\t\tthis.remote.sendMessage(msg)\n\t\treturn true\n\t}\n\n\treleaseFileLock(id: string) {\n\t\treturn this.requestFileLock(id, 0)\n\t}\n\n\tgetFileLockState(id: string): LockState | undefined {\n\t\treturn this.locks.getLockById(`file:${id}`)\n\t}\n\n\tprivate setRemote(remote: RemoteDocumentConnection | null) {\n\t\tif (!this.startLoadingTime) {\n\t\t\tthis.startLoadingTime = Date.now()\n\t\t}\n\n\t\tif (this.remote === remote) return\n\n\t\tlog.debug(\"setRemoteConnection:\", !!remote)\n\t\tthis.remote = remote\n\n\t\tthis.engine.stores.treeStore.timeline.setOnline(remote !== null)\n\n\t\tclearTimeout(this.postponedLastUpdate)\n\t\tthis.postponedLastUpdate = undefined\n\n\t\tthis.setDisconnected(true)\n\t\tthis.setNetworkReady(false)\n\t}\n\n\t/** LocalDocumentHandler */\n\ttreeVersion(): number {\n\t\treturn this.treeDataHandler.treeVersion\n\t}\n\n\t/** LocalDocumentHandler */\n\tsetRemoteConnection(remote: RemoteDocumentConnection) {\n\t\tif (this.permanentlyFailed) {\n\t\t\tlog.warn(\"attempted to setRemoteConnection after initialization has failed\")\n\t\t\treturn\n\t\t}\n\t\tthis.setRemote(remote)\n\t\tthis.isReconnecting = false\n\t}\n\n\t/** LocalDocumentHandler */\n\tsetRemoteConnectionFailure(reason: DisconnectReason) {\n\t\tif (!this.remote) return\n\n\t\t// If the initial socket connection fails (before we render any version),\n\t\t// we'll try to render the version from treeInitData.\n\t\t// If there is recoverable error (that comes from useSocket.getReasonFromCloseEvent),\n\t\t// we assume we can fetch the tree from the server. If the connection closes while\n\t\t// the user is already editing the project, we don't re-render the tree, since the\n\t\t// current rendered tree is the latest.\n\t\tif (reason === DisconnectReason.UnknownRecoverableError) {\n\t\t\tvoid this.fallbackToInitialDocumentJson()\n\t\t}\n\n\t\t// If this is a client side error, perhaps we want to mark it as a permanent error.\n\t\tif (reason === DisconnectReason.ClientSideRecoverableError) {\n\t\t\tif (performance.now() - this.lastClientSideError < CLIENT_ERROR_RECOVERY_MS) {\n\t\t\t\treason = DisconnectReason.ClientSidePermanentError\n\t\t\t}\n\t\t\tthis.lastClientSideError = performance.now()\n\t\t}\n\n\t\tif (!isRecoverableDisconnectReason(reason)) {\n\t\t\tlog.error(\"remote connection failed, recovery is not possible, reason:\", reason)\n\t\t\tthis.setPermanentlyFailed(reason)\n\t\t} else {\n\t\t\tlog.info(\"remote connection failed, reason:\", reason)\n\t\t}\n\n\t\tthis.setRemote(null)\n\n\t\tif (this.#reloadOnDisconnect) {\n\t\t\t// We expected this disconnection, and should hard reload the window now.\n\t\t\twindow.location.reload()\n\t\t}\n\t}\n\n\t/** LocalDocumentHandler */\n\twaitingForSync(): boolean {\n\t\treturn !this.treeDataHandler.isReady\n\t}\n\n\t/** Used by things like the history controller. */\n\tmakeReadOnly() {\n\t\tthis.treeDataHandler.resetSession()\n\t\tthis.networkReady = false\n\t\tthis.remote = null\n\n\t\tthis.treeDataHandler.cancelAndClearLoader()\n\n\t\tthis.setDisconnected(true)\n\t\tthis.socket?.disconnect()\n\t\tclearInterval(this.updateConnectionTimerID)\n\t\tthis.permanentlyFailed = true\n\n\t\tthis.engine.stores.modulesStore.resetModuleStateAndPermissions(\"readonly\")\n\t}\n\n\tmakeReadWrite() {\n\t\t// Before we connect the socket, make sure the updateConnectionTimer will behave the same as\n\t\t// when the page first loads. Not showing a reconnection toast. And waiting longer before\n\t\t// showing a connection warning.\n\t\tthis.startLoadingTime = 0\n\t\tthis.initialConnection = true\n\t\tthis.isReconnecting = true\n\t\tthis.permanentlyFailed = false\n\t\tthis.loadingStore.busyReconnecting = true\n\t\tthis.updateConnectionTimerID = window.setInterval(this.updateConnectionTimer, 500)\n\t\tthis.socket?.connect()\n\t}\n\n\tcanReloadServerDocumentForRecovery() {\n\t\treturn !this.permanentlyFailed && !!this.remote && this.treeVersion() > 0\n\t}\n\n\tdebugCreateNewTreeSyncSession(tree: CanvasTree) {\n\t\tthis.engine.load(tree)\n\t\tthis.treeDataHandler.debugResetSessionAndTree(this.engine.tree)\n\t}\n\n\t/** Will disconnect the client from the server. The user can continue to locally edit the\n\t * document. Nothing goes back to the server and all edits will be lost when the window is\n\t * closed. */\n\tdebugDetachClientFromServer(options: { keepAPIFetcherWritable?: boolean } = {}) {\n\t\tlog.info(\"detaching client from server ...\")\n\t\tthis.permanentlyFailed = true\n\t\tthis.networkReady = false\n\t\tthis.loadingStore.busyReconnecting = false\n\t\tthis.remote = null\n\t\tthis.engine.stores.treeStore.timeline.setOnline(false)\n\n\t\tthis.treeDataHandler.cancelAndClearLoader()\n\n\t\tclearInterval(this.updateConnectionTimerID)\n\t\tthis.engine.remoteDocument = null\n\n\t\tthis.socket?.disconnect()\n\t\tif (!options.keepAPIFetcherWritable) apiFetcher.debugSetReadOnly()\n\t}\n\n\tdebugReattachClientToServer() {\n\t\tif (!this.permanentlyFailed) return\n\n\t\tlog.info(\"attaching to server again ...\")\n\t\tthis.permanentlyFailed = false\n\t\tthis.updateConnectionTimerID = window.setInterval(this.updateConnectionTimer, 500)\n\t\tthis.treeDataHandler.resetSession()\n\t\tthis.engine.remoteDocument = this\n\t\tthis.loadingStore.busyReconnecting = true\n\t\tthis.socket?.connect()\n\t\tapiFetcher.debugSetReadOnly(false)\n\t}\n\n\tprivate sendToRemote() {\n\t\tif (this.postponedLastUpdate) {\n\t\t\tclearTimeout(this.postponedLastUpdate)\n\t\t\tthis.postponedLastUpdate = undefined\n\t\t}\n\n\t\tif (!this.remote) return\n\n\t\tif (this.treeDataHandler.maybeSend(this.remote) === \"postpone\") {\n\t\t\tthis.postponedLastUpdate = setTimeout(() => this.sendToRemote(), RETRY_SENDING_MS)\n\t\t}\n\t}\n\n\t/** Called by engine on any tree commit not done by EngineTreeSync. */\n\tafterCommit(tree: CanvasTree): void {\n\t\tassert(this.engine.stores.treeStore.timeline.tree === tree)\n\t\tif (!this.treeDataHandler.canProcessChanges()) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.engine.treeReflectsDocument) {\n\t\t\tthrow Error(\"cannot create local updates when document hasn't loaded\")\n\t\t}\n\n\t\tif (this.engine.stores.chromeStore.userIsViewer) {\n\t\t\tthis.treeDataHandler.processViewOnly()\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.postponedLastUpdate) {\n\t\t\tthis.postponedLastUpdate = setTimeout(() => this.sendToRemote(), 10)\n\t\t}\n\t}\n\n\t/** To call maybeSend from a test instead of a timer. */\n\tdebugMaybeSendNow() {\n\t\tif (!this.remote) return\n\t\tthis.treeDataHandler.maybeSend(this.remote)\n\t}\n\n\tdebugCrash() {\n\t\tthis.treeDataHandler.debugCrash()\n\t}\n\n\tprivate scheduleProcessUpdates() {\n\t\tif (!this.scheduledProcessing) {\n\t\t\tthis.scheduledProcessing = true\n\t\t\tthis.processBetweenFrames(() => {\n\t\t\t\tthis.scheduledProcessing = false\n\n\t\t\t\t// If the loader is busy loading scopes, we need to schedule again, and try again in a little bit.\n\t\t\t\tif (this.loader?.activelyLoadingScope) {\n\t\t\t\t\tsetTimeout(() => this.scheduleProcessUpdates(), 100)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.treeDataHandler.processRemoteUpdates()\n\t\t\t})\n\t\t}\n\t}\n\n\t/** LocalDocumentHandler */\n\thandleLock(userId: string, lock: LockMessageData) {\n\t\tif (!this.remote) return\n\t\tthis.locks.register(lock.lockId, userId, lock.time * 1000)\n\t}\n\n\thandleTreeMessage(_userId: string, message: TreeMessageData) {\n\t\tif (!this.remote) return\n\n\t\tswitch (message.type) {\n\t\t\tcase \"init\": {\n\t\t\t\tif (this.suppressLoadingForDebugging) return\n\t\t\t\tif (treeModeMismatch(message.data.mode)) {\n\t\t\t\t\tthis.setPermanentlyFailed(DisconnectReason.TreeModeMismatch)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.setTreeModeFromInit(message.data.mode)\n\t\t\t\tconst res = this.treeDataHandler.handleInit(message.data.treeVersion, message.data.initialUpdates)\n\t\t\t\tif (res.needsDownload) {\n\t\t\t\t\tvoid this.downloadDocument(message.data.file, message.data.treeVersion)\n\t\t\t\t} else {\n\t\t\t\t\tthis.scheduleProcessUpdates()\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tassertNever(message.type, \"unknown treeMessage type\")\n\t\t}\n\t}\n\n\thandleTreeUpdate(_userId: string, update: ServerTreeUpdate) {\n\t\tthis.treeDataHandler.handleTreeUpdate(update)\n\t\tif (this.treeDataHandler.hasUpdatesToProcess) {\n\t\t\tthis.scheduleProcessUpdates()\n\t\t}\n\t}\n\n\thandleTreeVerify(verify: TreeVerifyData) {\n\t\tconst needsFullData = this.engine.stores.treeStore.getDataTree() === undefined\n\t\tif (needsFullData && !this.engine.stores.loadingStore.hasFullDocumentData) return\n\n\t\tthis.treeDataHandler.handleTreeVerify(this.currentDocumentUrl ?? \"\", verify.version, verify.hash)\n\t}\n\n\tpublic downloadDocument(newDocumentURL: string, treeVersion: number) {\n\t\tthis.engine.stores.loadingStore.busyLoadingFirstData = true\n\n\t\t// Use the document URL sent on the WS message.\n\t\t// If empty, we use the one in the treeInitData\n\t\tconst documentURL = this.engine.stores.treeStore.getDocumentURL(newDocumentURL)\n\n\t\tlog.debug(\"downloading document:\", documentURL || \"null\")\n\t\tif (!documentURL) {\n\t\t\tthis.onError(this.treeDataHandler.error(\"No document url to start downloading.\"))\n\t\t\treturn Promise.resolve()\n\t\t}\n\n\t\tthis.currentDocumentUrl = documentURL\n\n\t\tconst settings: DocumentLoaderSettings = {\n\t\t\tactiveNodeId: this.engine.stores.documentSettingsStore.activeNode?.id,\n\t\t\tpartialParsing: !employeesOnlySettings.isOn(\"disablePartialDocumentLoading\"),\n\t\t\tloadInBackground: true,\n\t\t\tinitData: this.engine.stores.treeStore.initData,\n\t\t\ttreeServices: {\n\t\t\t\tupgradeManager: this.engine.upgradeManager,\n\t\t\t\teditHooks: this.engine.scheduler,\n\t\t\t},\n\t\t\trefreshAccessToken: (initData: RequestInit) => accessTokenRefresher.withAuthorizationHeader(initData),\n\t\t\tasyncEventWrapper: this.processBetweenFramesAsync,\n\t\t\trequestIdleCallback: this.requestIdleCallback,\n\t\t\tlocalCache: this.localCache,\n\t\t}\n\n\t\tthis.documentByteSize = 0\n\t\tconst loader = this.createLoader(documentURL, treeVersion, settings)\n\t\tassert(this.engine.stores.loadingStore.busyLoadingFirstData, \"must be busy loading already\")\n\n\t\tthis.engine.stores.loadingStore.hasError = false\n\t\tthis.engine.stores.loadingStore.busyLoadingFullData = true\n\n\t\tconst forInit = this.treeDataHandler.init\n\t\tloader.on(\"loadedFormatVersion\", formatVersion => {\n\t\t\tif (loader !== this.treeDataHandler.loader) return\n\n\t\t\tif (!this.verifyDocumentVersion(treeVersion, formatVersion, forInit, BINARY_SCHEMA_VERSION)) {\n\t\t\t\tloader.scheduler.cancel()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (formatVersion < BINARY_SCHEMA_VERSION) {\n\t\t\t\tthis.errorClientTooNew()\n\t\t\t\tlog.error(this.treeDataHandler.error(\"Document format version is too low.\"))\n\t\t\t\tloader.scheduler.cancel()\n\t\t\t}\n\t\t})\n\n\t\tloader.on(\"loadedDocumentVersion\", schemaVersion => {\n\t\t\tif (loader !== this.treeDataHandler.loader) return\n\n\t\t\tthis.documentByteSize = loader.documentSize\n\n\t\t\tif (!this.verifyDocumentVersion(treeVersion, schemaVersion, forInit, CanvasTreeVersion)) {\n\t\t\t\tloader.scheduler.cancel()\n\t\t\t}\n\t\t})\n\n\t\tloader.on(\"loadedFirstData\", tree => {\n\t\t\tif (this.treeDataHandler.loader !== loader) return\n\n\t\t\t// Pause the loader, if this is partial loading, later we will call run() again to resume it.\n\t\t\tloader.pauseLoadingScopes()\n\n\t\t\ttreeLibrary.setDocumentAndUserInfo(loader.documentSize)\n\n\t\t\t// Implementation taken from the old style document loading.\n\t\t\ttry {\n\t\t\t\tthis.engine.stores.modulesStore.resetModuleStateAndPermissions(\"readwrite\")\n\t\t\t\tthis.engine.load(tree)\n\t\t\t\tthis.treeDataHandler.setTree(this.engine.tree, treeVersion, {\n\t\t\t\t\tisLoading: loader.settings.partialParsing,\n\t\t\t\t})\n\n\t\t\t\tthis.scheduledProcessing = false\n\t\t\t\tthis.treeDataHandler.processRemoteUpdates()\n\n\t\t\t\tassert(this.engine.stores.treeStore.timeline.tree.isLatest())\n\n\t\t\t\t// Check if the client is newer than the server. In which case\n\t\t\t\t// we disconnect and go in a local-only mode.\n\t\t\t\tif (loader.canvasTreeVersion < CanvasTreeVersion) {\n\t\t\t\t\tthis.errorClientTooNew()\n\t\t\t\t\tlog.error(this.treeDataHandler.error(\"Document version is too low, showing read-only.\"))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.engine.treeReflectsDocument = true\n\t\t\t} catch (e) {\n\t\t\t\tlog.error(\"Error opening document:\", e)\n\t\t\t\tthis.handleErrorRecoverable(CanvasTree.createWithDefaultPage())\n\t\t\t\tthrow this.treeDataHandler.error(\"Error opening document: \" + e, e)\n\t\t\t}\n\t\t})\n\n\t\tloader.on(\"loadedScope\", scope => {\n\t\t\tif (loader !== this.treeDataHandler.loader) return\n\t\t\tthis.treeDataHandler.loadOneScope(scope, false)\n\t\t\tthis.engine.newTreeAfterRemoteUpdate(this.engine.stores.treeStore.timeline.tree)\n\t\t})\n\n\t\tloader.on(\"loadedAllData\", () => {\n\t\t\t// Implementation taken from loadRestOfDocument() above\n\t\t\tif (loader !== this.treeDataHandler.loader) return\n\n\t\t\tthis.treeDataHandler.finishLoading()\n\t\t\tthis.engine.stores.loadingStore.busyLoadingFullData = false\n\n\t\t\t// If not loading partial, loadedFirstData already did all the work.\n\t\t\tif (loader.settings.partialParsing) {\n\t\t\t\tthis.treeDataHandler.loadedAllScopes()\n\t\t\t}\n\n\t\t\tthis.engine.didLoadCompleteDocument()\n\t\t\tloadDocumentMetrics.trackRemainingLoad({\n\t\t\t\tstartLoadingTime: this.startLoadingTime,\n\t\t\t\ttreeSize: this.engine.stores.treeStore.tree.size(),\n\t\t\t})\n\t\t})\n\n\t\treturn loader.start().catch(e => {\n\t\t\t// Ignore cancellation errors from switching loaders, e.g., when switching branches.\n\t\t\tif (loader.scheduler.isCancelled() && loader !== this.treeDataHandler.loader) return\n\n\t\t\tlog.error(\"Error loading document:\", e)\n\t\t\tthis.engine.stores.loadingStore.hasError = true\n\t\t\tif (loader.scheduler.isCancelled()) {\n\t\t\t\tthis.treeDataHandler.error(e)\n\t\t\t} else {\n\t\t\t\tthis.onError(this.treeDataHandler.error(e))\n\t\t\t}\n\t\t})\n\t}\n\n\t/** Used in this.loadDocument to verify the tree before loading a document */\n\tprivate verifyDocumentVersion(\n\t\ttreeVersion: number,\n\t\tdocumentVersion: number,\n\t\tforInit: number,\n\t\texpectedVersion: number,\n\t) {\n\t\tif (forInit !== this.treeDataHandler.init) {\n\t\t\tlog.debug(\"ignoring loadDocument that got passed over by a new init\", forInit, this.treeDataHandler.init)\n\t\t\treturn false\n\t\t}\n\n\t\tlog.info(\"loadDocument\", { initial: this.initialLoad, treeVersion, init: forInit })\n\n\t\tthis.engine.treeReflectsDocument = false\n\n\t\tif (!isNumber(documentVersion)) {\n\t\t\tthrow Error(\"Unable to read document.version\")\n\t\t}\n\n\t\tif (documentVersion > expectedVersion) {\n\t\t\tthis.errorClientNeedsUpdate()\n\t\t\tlog.error(this.treeDataHandler.error(\"Document version is too high.\"))\n\t\t\treturn false\n\t\t}\n\n\t\treturn true\n\t}\n\n\tprivate processBetweenFrames = (task: () => void, callback?: () => void) => {\n\t\tthis.engine.scheduler.processRemoteEditBetweenFrames(() => {\n\t\t\tconst startTime = performance.now()\n\t\t\tperformanceMark(\"remote\")\n\n\t\t\ttry {\n\t\t\t\ttask()\n\t\t\t} finally {\n\t\t\t\tthis.totalTime += performance.now() - startTime\n\t\t\t\tperformanceMeasure(\"RemoteTreeProcessing\", \"remote\")\n\t\t\t\tperformanceClearMarks(\"remote\")\n\t\t\t}\n\t\t}, callback)\n\t}\n\n\tprocessBetweenFramesAsync = (task: () => void): Promise<void> => {\n\t\treturn new Promise<void>(resolve => {\n\t\t\tthis.processBetweenFrames(task, resolve)\n\t\t})\n\t}\n\n\tgetAndResetTotalTime(): number {\n\t\tconst totalTime = this.totalTime\n\t\tthis.totalTime = 0\n\t\treturn totalTime\n\t}\n\n\tloadOneScope(scope: CanvasNode, keepChanges: boolean): CanvasTree {\n\t\treturn this.treeDataHandler.loadOneScope(scope, keepChanges)\n\t}\n\n\thasUnconfirmedChanges() {\n\t\treturn this.treeDataHandler.hasUnconfirmedChanges()\n\t}\n\n\tresetTreesForRecovery(activeScopeId: string) {\n\t\treturn this.treeDataHandler.resetTreesForRecovery(activeScopeId)\n\t}\n\n\tsendAfterFlush(msg: Message): boolean {\n\t\tif (!this.remote) return false\n\n\t\tthis.treeDataHandler.flushUpdates(this.remote)\n\t\tthis.remote.sendMessage(msg)\n\t\treturn true\n\t}\n\n\t#reloadOnDisconnect = false\n\treloadOnDisconnect() {\n\t\tthis.#reloadOnDisconnect = true\n\t}\n}\n", "import { assert, ResolvablePromise, reportableError, schedulerIsInputPending, schedulerYield } from \"@framerjs/shared\"\nimport { noop } from \"@framerjs/shared/src/noop.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport { engineLog, logScheduler } from \"document/EngineLoggers.ts\"\nimport { recoverFromError } from \"document/VekterEngineErrorRecovery.ts\"\nimport { setLoadWasChecked } from \"document/models/CanvasTree/nodes/ScopeNode.ts\"\nimport { getNodeIdFromRenderId } from \"document/utils/RenderId.ts\"\nimport type { ModuleRuntimePhase } from \"modulesRuntime/ModulesRuntime.ts\"\nimport type { RenderingPhase } from \"renderer/DeferredRendering.ts\"\nimport { markLoadingPerf, setInitialModuleLoadStats } from \"utils/performanceTracker.ts\"\nimport type { RenderedUpdate } from \"utils/rpc/shared/definitions.ts\"\nimport { performanceClearMarks, performanceMark, performanceMeasure } from \"utils/userTiming.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { type EngineChangeFlag, EngineChanges } from \"./EngineChanges.ts\"\nimport type { EnsureSync, NonPromiseLike, VekterEngine } from \"./VekterEngine.ts\"\nimport type { BaseEngineScheduler, RunWithFullyLoadedTreeOptions } from \"./base-engine/BaseEngine.ts\"\nimport type { TreeEditHooks } from \"./models/CanvasTree/TreeServices.ts\"\nimport type { CanvasTree, NodeID } from \"./models/CanvasTree/index.ts\"\n\nexport class VekterEngineScheduler implements BaseEngineScheduler, TreeEditHooks {\n\treadonly changes = new EngineChanges()\n\n\t/** Indicates there was a non recoverable error. All timers, callbacks, events, should simply not happen. */\n\thadFatalError = false\n\n\tinToolProcessing = false\n\tinPostProcessing = false\n\tinRendering = false\n\n\t// is used to track if a commit is a user change or something else like updated components\n\teventsHandled = 0\n\tnonUserEventsHandled = 0\n\tprivate currentCommitHasUserTreeEdit = false\n\n\t/** Indicates the number of event handlers running. Handlers may be nested, hence this is a counter. */\n\tinEventHandling = 0\n\n\t/** Indicates the number of non-user event handlers running. */\n\tprivate inNonUserEventHandling = 0\n\n\tprivate hadUncommittedChangesAtEventEntry = false\n\tprivate outermostEventIsUserEvent = false\n\n\t/** Indicates we have scheduled react to re-render. */\n\tneedRendering = false\n\n\t/** Indicates we have scheduled a frame report. */\n\tneedReport = false\n\n\t/** Indicates we have scheduled the tool to start processing. */\n\tneedToolProcessing = false\n\n\t/** Indicates we have scheduled the sandbox to re-render. */\n\tprivate needSandboxRendering = false\n\n\t/** last update that was not back-to-back */\n\tlastIdleUpdate = 0\n\n\t/* every process() or tool.update() does this */\n\tupdate = 0\n\n\t/** Indicates we should render immediately after event handling. */\n\tprivate renderImmediatelyAfterEventHandling = false\n\n\tlastUpdateEndTime = 0\n\n\tprivate lastUpdateSentToSandbox = 0\n\tprivate sandboxUpdateInFlight = false\n\n\tprivate lastAtomicUpdate = 0 // last update that included an atomic handler\n\n\tconstructor(private readonly engine: VekterEngine) {}\n\n\tsignalChanges(flag: EngineChangeFlag): void {\n\t\tif (this.hadFatalError) return\n\t\tthis.changes.addChanges(flag)\n\t\tif (this.needRendering) return\n\t\tthis.enterEventHandling(\"nonUserEvent\")\n\t\tthis.exitEventHandling(\"nonUserEvent\")\n\t}\n\n\tscheduleDocumentUpdateIgnoringUndo(cb: VoidFunction) {\n\t\tif (this.hadFatalError) return\n\t\tthis.runBeforeNextFrame(() => {\n\t\t\ttry {\n\t\t\t\tthis.process(cb, \"nonUserEvent\")\n\t\t\t} finally {\n\t\t\t\tthis.lastAtomicUpdate = this.update\n\t\t\t\tthis.engine.doPostProcessing()\n\t\t\t}\n\t\t})\n\t}\n\n\tscheduleAgentChanges(callback: VoidFunction, options?: { addToHistory?: boolean }): Promise<void> {\n\t\tif (this.hadFatalError) return Promise.resolve()\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.runBeforeNextFrame(() => {\n\t\t\t\tif (this.hadFatalError) {\n\t\t\t\t\tresolve()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst type = options?.addToHistory === true ? undefined : \"nonUserEvent\"\n\n\t\t\t\ttry {\n\t\t\t\t\tthis.enterEventHandling(type)\n\t\t\t\t\tcallback()\n\t\t\t\t\tresolve()\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.exitEventHandling(type)\n\t\t\t\t\tthis.lastAtomicUpdate = this.update\n\t\t\t\t\tthis.engine.doPostProcessing()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\tenterEventHandling(type?: \"nonUserEvent\") {\n\t\tassert(!this.inPostProcessing, \"May not handle events while in post processing\")\n\t\tassert(!this.inRendering, \"May not handle events while in react lifecycle\")\n\n\t\t// If this is the first time handling events after tool processing, start a next engine frame\n\t\tif (!this.needToolProcessing && this.inEventHandling === 0) {\n\t\t\tthis.doStartFrame()\n\t\t\tassert(this.needToolProcessing, \"Must be in tool processing now.\")\n\t\t}\n\n\t\tif (this.inEventHandling === 0) {\n\t\t\tperformanceMark(\"event\")\n\t\t\tthis.hadUncommittedChangesAtEventEntry = this.engine.stores.treeStore.hasUncommittedChanges()\n\t\t\tthis.outermostEventIsUserEvent = type !== \"nonUserEvent\"\n\t\t}\n\n\t\tthis.engine.tree.editClosed = false\n\t\tthis.engine.tree.isViewOnly = getIsViewOnly(this.engine, \"canSendDiffs\")\n\t\tthis.inEventHandling += 1\n\t\tthis.eventsHandled += 1\n\t\tif (type === \"nonUserEvent\") {\n\t\t\tthis.inNonUserEventHandling += 1\n\t\t}\n\t\tif (this.inNonUserEventHandling > 0) {\n\t\t\tthis.nonUserEventsHandled += 1\n\t\t}\n\t}\n\n\texitEventHandling(type?: \"nonUserEvent\") {\n\t\tthis.inEventHandling -= 1\n\n\t\tif (type === \"nonUserEvent\") {\n\t\t\tthis.inNonUserEventHandling -= 1\n\n\t\t\tif (this.inNonUserEventHandling < 0) {\n\t\t\t\tthis.inNonUserEventHandling = 0\n\t\t\t}\n\t\t}\n\n\t\tif (this.inEventHandling > 0) return\n\n\t\tconst didCreateTreeEdit =\n\t\t\t!this.hadUncommittedChangesAtEventEntry && this.engine.stores.treeStore.hasUncommittedChanges()\n\t\tif (this.outermostEventIsUserEvent && didCreateTreeEdit) {\n\t\t\tthis.markCurrentCommitHasUserTreeEdit()\n\t\t}\n\n\t\tif (this.inEventHandling < 0) {\n\t\t\t// Error recovery can cause this to go below zero when called from a stack that does\n\t\t\t// direct error recovery. That will cause a second and thus fatal error down the line.\n\t\t\tthis.inEventHandling = 0\n\t\t}\n\n\t\ttry {\n\t\t\tperformanceMeasure(\"EventProcessing\", \"event\")\n\t\t\tperformanceClearMarks(\"event\")\n\t\t} catch {\n\t\t\t// Ignore. It seems that closing the browser tab, clears all marks. Also error recovery\n\t\t\t// might get inEventHandling become negative and thus run this code more than once.\n\t\t}\n\n\t\tthis.recordEditReason()\n\t\tthis.engine.tree.editClosed = true\n\n\t\tif (this.renderImmediatelyAfterEventHandling) {\n\t\t\tthis.renderImmediatelyAfterEventHandling = false\n\t\t\tthis.doRenderingByCallback()\n\t\t}\n\t}\n\n\thasCurrentCommitUserTreeEdit(): boolean {\n\t\treturn this.currentCommitHasUserTreeEdit\n\t}\n\n\tmarkCurrentCommitHasUserTreeEdit(): void {\n\t\tthis.currentCommitHasUserTreeEdit = true\n\t}\n\n\tclearCurrentCommitTreeEditState(): void {\n\t\tthis.currentCommitHasUserTreeEdit = false\n\t}\n\n\trecordEditReason(reset = false) {\n\t\t// If the tree has been edited and there is a known reason, pass it to the timeline.\n\t\tconst reason = this.engine.tree.lineage.takeEditReason(reset)\n\t\tif (!reason) return\n\t\tthis.engine.stores.treeStore.timeline.recordEditReasons(reason)\n\t}\n\n\tprivate doRenderingByCallback = () => {\n\t\tif (this.hadFatalError) return\n\t\ttry {\n\t\t\tthis.engine.doToolProcessing()\n\t\t\tthis.engine.doRendering()\n\t\t\tsetTimeout(this.doEndFrameByTimer)\n\t\t} catch (error) {\n\t\t\trecoverFromError(this.engine, reportableError(error))\n\t\t}\n\t}\n\n\t/** An engine assisted debounce. Call once or multiple times in a row to prime. Will then fire\n\t * after not being called for a certain delay. But will also delay firing if the engine or CPU\n\t * were busy. */\n\tdebounce(fn: () => void, millis: number): VoidFunction {\n\t\tconst MINIMUM_DELAY = 60\n\t\tlet scheduledFromUpdate = 0\n\t\tlet timer: any = 0\n\t\tconst handler = () => {\n\t\t\t// at least one idle frame, and at least minimum delay after last update ended\n\t\t\tif (this.lastIdleUpdate >= scheduledFromUpdate && performance.now() - this.lastUpdateEndTime > MINIMUM_DELAY) {\n\t\t\t\tif (this.hadFatalError) return\n\t\t\t\ttimer = 0\n\t\t\t\tfn()\n\t\t\t} else {\n\t\t\t\tif (this.hadFatalError) return\n\t\t\t\ttimer = setTimeout(handler, MINIMUM_DELAY)\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t}\n\t\t\tif (this.hadFatalError) return\n\t\t\tscheduledFromUpdate = this.update\n\t\t\ttimer = setTimeout(handler, millis)\n\t\t}\n\t}\n\n\tprivate inTreeEdit = 0\n\n\tonTreeEditStart() {\n\t\tif (this.inToolProcessing) return\n\t\tif (this.inPostProcessing) return\n\t\tif (this.inTreeEdit++) return\n\t\tthis.enterEventHandling()\n\t}\n\n\tonTreeEditEnd() {\n\t\tif (this.inToolProcessing) return\n\t\tif (this.inPostProcessing) return\n\t\tif (--this.inTreeEdit) return\n\t\tthis.exitEventHandling()\n\t}\n\n\tonTreeEditError(error: unknown) {\n\t\tthis.eventHandlingError ??= reportableError(error)\n\t}\n\n\t/**\n\t * `engine.scheduler.wrapHandler` returns a wrapped event handler that can make changes to nodes or the\n\t * tree.\n\t *\n\t * It marks a document as dirty, to make sure we do post processing afterwards, and tells the\n\t * engine to commit the tree when the handler returns.\n\t *\n\t * It's similar to `scheduler.process`, but it returns a wrapped handler, instead of executing it.\n\t * In fact, you could achieve the same with `scheduler.process` instead:\n\t *\n\t * ```ts\n\t * function myHandler(event) {\n\t *     engine.scheduler.process(() => {\n\t *         // ...myHandler code that makes changes to the tree\n\t *     })\n\t * }\n\t * ```\n\t *\n\t * Note: when calling a wrapped handler from another handler you don't need to wrap the outer\n\t * handler unless it makes additional node or tree changes.\n\t *\n\t * Note: `engine.scheduler.wrapHandler` shouldn't be used with async handlers. Instead use `engine.scheduler.process`,\n\t * `engine.scheduler.processWhenReady`, and `engine.scheduler.processWhenReadAsync` directly. Example:\n\t *\n\t * ```ts\n\t * async function myAsyncHandler(event) {\n\t *     scheduler.process(() => {\n\t *         engine.beginUndoGroup()\n\t *         // make change to the tree\n\t *     })\n\t *     await someAsyncOperation()\n\t *     await scheduler.processWhenReadyAsync(() => {\n\t *         // more changes to the tree\n\t *         engine.endUndoGroup()\n\t *     })\n\t * }\n\t * ```\n\t *\n\t * @see Tech Talk: https://drive.google.com/file/d/1yFn2T_QrRBApN3DcrisvszvHXHwXccZL/view\n\t * @see\n\t * https://www.notion.so/framer/CanvasTree-Golden-Paths-96ec7405df7a4b0b83d4217cb02c269b?source=copy_link#153adf6e8c9680648df1f10e873e73ab\n\t *\n\t * @param handler - The handler to wrap.\n\t * @returns The wrapped handler.\n\t */\n\twrapHandler<This, Args extends unknown[], Return>(\n\t\thandler: (this: This, ...args: Args) => Return,\n\t\ttype?: \"nonUserEvent\",\n\t) {\n\t\t// eslint-disable-next-line @typescript-eslint/no-this-alias\n\t\tconst vekterScheduler = this\n\n\t\treturn function (this: This, ...args: Args): Return {\n\t\t\tif (vekterScheduler.hadFatalError) return undefined as Return\n\t\t\tvekterScheduler.enterEventHandling(type)\n\t\t\ttry {\n\t\t\t\treturn handler.apply(this, args)\n\t\t\t} catch (error) {\n\t\t\t\tvekterScheduler.errorInEventHandler(reportableError(error))\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tvekterScheduler.exitEventHandling(type)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Do an event-like task, e.g. make changes to the tree.\n\t *\n\t * It can be used in most react-event handlers, except in blur/focus/change handlers because\n\t * they can also be fired as a side effect of DOM changes that happen during rendering.\n\t *\n\t * Also, it can't be used inside of useEffect.\n\t *\n\t * You can use @link{processWhenReady} or @link{processWhenReadyAsync} in those situations.\n\t */\n\tprocess<T extends () => unknown>(task: EnsureSync<T, void>, type?: \"nonUserEvent\") {\n\t\tif (this.hadFatalError) return\n\t\tthis.enterEventHandling(type)\n\t\ttry {\n\t\t\ttask()\n\t\t} catch (error) {\n\t\t\tthis.errorInEventHandler(reportableError(error))\n\t\t\tthrow error\n\t\t} finally {\n\t\t\tthis.exitEventHandling(type)\n\t\t}\n\t}\n\n\t/**\n\t * Do an event-like task, unless we are currently rendering, then do it as soon as we stop\n\t * rendering.\n\t *\n\t * Sometimes, this is needed to make edits from a react useEffect, or blur/focus/change\n\t * handlers, and exceptionally (not recommended) in postprocessing.\n\t *\n\t * In most react-event handlers though, `engine.process` can be used instead, except in\n\t * blur/focus/change handlers because they can also be fired as a side effect of DOM changes\n\t * that happen during rendering.\n\t *\n\t * @param task - The function to process.\n\t */\n\tprocessWhenReady<T extends () => unknown>(task: EnsureSync<T, void>, type?: \"nonUserEvent\"): void {\n\t\tif (this.hadFatalError) return\n\t\t// Cannot process when in rendering or in post processing ...\n\t\tif (this.inRendering || this.inPostProcessing) {\n\t\t\tsetTimeout(this.wrapHandler(task, type))\n\t\t\treturn\n\t\t}\n\t\tthis.process(task, type)\n\t}\n\n\t/**\n\t * Promise-based version of processWhenReady. If a value is returned by the\n\t * callback, the promise will resolve with that value.\n\t */\n\tprocessWhenReadyAsync<R>(task: () => NonPromiseLike<R, R>, _type?: \"nonUserEvent\"): Promise<R> {\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tthis.processWhenReady(() => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = task()\n\t\t\t\t\tresolve(result)\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\t/** Process an update and render synchronously. Use with caution because can result in performance issues. */\n\tprocessAndRenderSync<T extends () => unknown>(task: EnsureSync<T, void>) {\n\t\tthis.renderImmediatelyAfterEventHandling = true\n\t\tthis.process(task)\n\t}\n\n\trunWithFullyLoadedTree<T extends () => unknown>(\n\t\ttask: EnsureSync<T, void>,\n\t\toptions: RunWithFullyLoadedTreeOptions,\n\t): () => void {\n\t\treturn this.engine.runWithFullyLoadedTree(task, options)\n\t}\n\n\trunWithFullyLoadedTreeAsync(options: RunWithFullyLoadedTreeOptions): Promise<void>\n\trunWithFullyLoadedTreeAsync<T>(fn: EnsureSync<() => T>, options: RunWithFullyLoadedTreeOptions): Promise<T>\n\trunWithFullyLoadedTreeAsync<T>(\n\t\tfnOrOptions: EnsureSync<() => T> | RunWithFullyLoadedTreeOptions,\n\t\tmaybeOptions?: RunWithFullyLoadedTreeOptions,\n\t) {\n\t\tif (typeof fnOrOptions === \"function\") {\n\t\t\tassert(maybeOptions, \"options required when callback provided\")\n\t\t\treturn this.engine.runWithFullyLoadedTreeAsync(fnOrOptions, maybeOptions)\n\t\t}\n\n\t\treturn this.engine.runWithFullyLoadedTreeAsync(fnOrOptions)\n\t}\n\n\teventHandlingError: Error | null = null\n\terrorInEventHandler(e: Error) {\n\t\tif (this.eventHandlingError) return\n\t\tthis.eventHandlingError = e\n\t}\n\n\tlastUserInput = Number.NEGATIVE_INFINITY\n\tlastUserEdit = Number.NEGATIVE_INFINITY\n\t/** Returns true if the engine is not busy working on a frame. */\n\tisIdle(): boolean {\n\t\tif (this.inEventHandling > 0) return false\n\t\tif (this.inRendering) return false\n\t\tif (this.needToolProcessing || this.needRendering || this.needSandboxRendering || this.needReport) {\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n\n\t/** Returns true if the last user input was a little while ago. */\n\tisUserIdle(): boolean {\n\t\t// Return false if user input is pending according tot the browser.\n\t\tif (schedulerIsInputPending()) return false\n\n\t\t// Otherwise check if the user made recent edits or recently moved the mouse or pressed a\n\t\t// key. Each with their own timeout.\n\t\tconst now = performance.now()\n\t\tif (now - this.lastUserEdit < 500) return false\n\t\tif (now - this.lastUserInput < 250) return false\n\t\treturn true\n\t}\n\n\tprivate idleTasks: Function[] = []\n\tprivate runningIdleTasks = false\n\t/** Schedule a task to be run soon-ish, when the user seems to be idle.\n\t *\n\t * Tasks must use engine.process or equivalent if they want to manipulate any document state.\n\t */\n\trunWhenIdle = (task: Function) => {\n\t\tthis.idleTasks.push(task)\n\t\tvoid this.maybeRunOneIdleTask()\n\t}\n\n\t/** Waited on by the idle task handler, will be resolved by doEndFrameByTimer. */\n\tengineIsIdlePromise: ResolvablePromise<void> | undefined = undefined\n\n\t/** Will run any scheduled idle tasks. Pausing when the user is idle. But otherwise runs tasks\n\t * back to back, yielding the CPU with minimal delay. */\n\tprivate maybeRunOneIdleTask = async () => {\n\t\t// If already running tasks, we early return.\n\t\tif (this.runningIdleTasks) return\n\n\t\t// Otherwise we drop into a loop, processing tasks, until the queue is empty.\n\t\tthis.runningIdleTasks = true\n\t\ttry {\n\t\t\twhile (this.idleTasks.length > 0) {\n\t\t\t\t// If the user is not idle, we wait a bit, and retry the loop.\n\t\t\t\tif (!this.isUserIdle()) {\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 100))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// If the engine is busy, we install a promise and wait for it to resolve, doReport\n\t\t\t\t// will resolve it. Then we try again.\n\t\t\t\tif (!this.isIdle()) {\n\t\t\t\t\tawait (this.engineIsIdlePromise = new ResolvablePromise<void>())\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Make sure to yield between tasks. But also before the first task.\n\t\t\t\tawait schedulerYield()\n\n\t\t\t\tconst task = this.idleTasks.shift()\n\t\t\t\tif (!task) continue\n\n\t\t\t\tconst start = performance.now()\n\t\t\t\ttry {\n\t\t\t\t\t// We call the task, but often it is not much more than a resolve, so the actual\n\t\t\t\t\t// work might not be done inline.\n\t\t\t\t\ttask()\n\t\t\t\t} catch (error) {\n\t\t\t\t\trecoverFromError(this.engine, reportableError(error))\n\t\t\t\t} finally {\n\t\t\t\t\tperformanceMeasure(\"IdleTask\", { start, end: performance.now() })\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.runningIdleTasks = false\n\t\t}\n\t}\n\n\tprivate lastRenderingMillis = 0\n\tprivate backupRenderingInterval = 0\n\tforcedRendering = false\n\n\t// Incase hidden browser tabs, or errors in the sandbox, or other scenarios\n\t// like that, starve or drop postMessages, we force a render if no progress was made\n\t// for 2 seconds.\n\tprivate renderingByBackupTimer = () => {\n\t\tconst millisSinceLastRendering = performance.now() - this.lastRenderingMillis\n\t\tif (millisSinceLastRendering < 2000) return\n\n\t\t// If after 1 second, there is still a sandbox update in flight, reset it and retry.\n\t\tif (this.sandboxUpdateInFlight) {\n\t\t\tlogScheduler.warn(\"Force rendering by backup timer\", this.update, this.lastUpdateSentToSandbox)\n\t\t\tthis.sandboxUpdateInFlight = false\n\t\t\tthis.lastRenderingMillis = performance.now()\n\t\t\tthis.forcedRendering = true\n\t\t\tthis.doSandboxRenderingIfNeeded()\n\t\t\tthis.doRenderingByCallback()\n\t\t\treturn\n\t\t}\n\n\t\t// Remove the backup interval after a while.\n\t\tif (millisSinceLastRendering > 10000) {\n\t\t\twindow.clearInterval(this.backupRenderingInterval)\n\t\t\tthis.backupRenderingInterval = 0\n\t\t}\n\t}\n\n\tprivate restartRenderingBackupTimer() {\n\t\tthis.lastRenderingMillis = performance.now()\n\n\t\t// Make sure there the backup interval is running.\n\t\tif (!this.backupRenderingInterval) {\n\t\t\tthis.backupRenderingInterval = window.setInterval(this.renderingByBackupTimer, 1000)\n\t\t}\n\t}\n\n\tprivate doEndFrameByTimer = () => {\n\t\ttry {\n\t\t\tif (this.needToolProcessing) return\n\t\t\tif (this.needRendering) return\n\t\t\tif (this.needSandboxRendering) return\n\t\t\tthis.engine.doReport(true /* calledByTimer */)\n\t\t\tthis.runTasksScheduledBeforeNextFrame()\n\t\t} catch (error) {\n\t\t\trecoverFromError(this.engine, reportableError(error))\n\t\t}\n\t}\n\n\tprivate scheduleRendering() {\n\t\tlogScheduler.trace(\"scheduleRendering\", this.update)\n\t\tif (!this.needRendering) return\n\t\tsetTimeout(this.doRenderingByCallback)\n\t}\n\n\tprivate canvasSandboxUpdateTime = 0\n\tprivate canvasSandboxRenderTime = 0\n\tcanvasSandboxRenderingPhase: RenderingPhase = \"Unknown\"\n\tprivate hasEmittedRenderingPhaseNormalMark = false\n\tprivate hasEmittedIsLoadingModulesIdleMark = false\n\tcanvasModulesRuntimePhase: ModuleRuntimePhase = \"Waiting\"\n\n\tgetAndResetSandboxTimes(): { updating: number; rendering: number } {\n\t\tconst updating = this.canvasSandboxUpdateTime\n\t\tconst rendering = this.canvasSandboxRenderTime\n\t\tthis.canvasSandboxUpdateTime = 0\n\t\tthis.canvasSandboxRenderTime = 0\n\t\treturn { updating, rendering }\n\t}\n\n\t/**\n\t * Process a remote edit.\n\t * Currently only used by RemoteDocument and should probably not be used elsewhere.\n\t */\n\tprocessRemoteEditBetweenFrames(task: VoidFunction, callback?: VoidFunction) {\n\t\tthis.runBeforeNextFrame(() => {\n\t\t\t// signal to the engine it needs a new frame, and signal it is not a user event\n\t\t\tthis.enterEventHandling(\"nonUserEvent\")\n\t\t\tthis.engine.tree.processingLocalUserEdits = false\n\n\t\t\tlet caughtError: Error | undefined\n\t\t\ttry {\n\t\t\t\ttask()\n\t\t\t} catch (error) {\n\t\t\t\tcaughtError = reportableError(error)\n\t\t\t} finally {\n\t\t\t\tthis.exitEventHandling(\"nonUserEvent\")\n\t\t\t\tthis.engine.tree.processingLocalUserEdits = true\n\t\t\t}\n\n\t\t\tif (caughtError) {\n\t\t\t\trecoverFromError(this.engine, caughtError)\n\t\t\t}\n\n\t\t\tcallback?.()\n\t\t})\n\t}\n\n\tcanvasSandboxDidRender({\n\t\tupdate,\n\t\tupdateTime,\n\t\trenderTime,\n\t\trenderingPhase,\n\t\tmoduleRuntimePhase,\n\t\tlayoutMeasurements,\n\t\tisLoadingModules,\n\t\tinitialModuleLoadStats,\n\t\trepeaterUpdates,\n\t\tvisibilityUpdates,\n\t}: RenderedUpdate) {\n\t\tconst { loadingStore, treeStore, previewStore, layoutCache } = this.engine.stores\n\t\tthis.canvasSandboxUpdateTime += updateTime\n\t\tthis.canvasSandboxRenderTime += renderTime\n\n\t\t// When the deferred rendering phase changes and went to normal, call finishPartialLoad.\n\t\tif (this.canvasSandboxRenderingPhase !== renderingPhase) {\n\t\t\tthis.canvasSandboxRenderingPhase = renderingPhase\n\t\t\tif (renderingPhase === \"Normal\") {\n\t\t\t\tthis.engine.remoteDocument?.finishPartialLoad()\n\t\t\t\tif (!this.hasEmittedRenderingPhaseNormalMark) {\n\t\t\t\t\tthis.hasEmittedRenderingPhaseNormalMark = true\n\t\t\t\t\tmarkLoadingPerf(\"sandboxRenderingPhaseNormal\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// When the module loader state changes, and all modules have loaded, and the rendering\n\t\t// phase is normal, also call finishPartialLoad. (It's ok to call multiple times.)\n\t\tif (!isLoadingModules && initialModuleLoadStats) {\n\t\t\tsetInitialModuleLoadStats(initialModuleLoadStats)\n\t\t}\n\t\tif (loadingStore.isLoadingModules !== isLoadingModules) {\n\t\t\tloadingStore.isLoadingModules = isLoadingModules\n\t\t\tif (!isLoadingModules && !this.hasEmittedIsLoadingModulesIdleMark) {\n\t\t\t\tthis.hasEmittedIsLoadingModulesIdleMark = true\n\t\t\t\tmarkLoadingPerf(\"editorIsLoadingModulesIdle\")\n\t\t\t}\n\t\t\tif (renderingPhase === \"Normal\" && !isLoadingModules) {\n\t\t\t\tthis.engine.remoteDocument?.finishPartialLoad()\n\t\t\t}\n\t\t}\n\n\t\t// Inform the preview that it is ready to load, now that the sandbox is ready.\n\t\tif (renderingPhase === \"Normal\" && !isLoadingModules) {\n\t\t\tpreviewStore.shouldStartPreloading = true\n\t\t}\n\n\t\tthis.canvasModulesRuntimePhase = moduleRuntimePhase\n\t\tif (moduleRuntimePhase === \"EagerDone\") {\n\t\t\tloadingStore.allModulesLoadedAndEvaluated = true\n\t\t}\n\n\t\tconst updatedNodeIds = new Set<NodeID>()\n\n\t\tif (repeaterUpdates) {\n\t\t\tconst updatedRenderIds = treeStore.sandboxRepeaterData.import(repeaterUpdates)\n\n\t\t\tfor (const renderId of updatedRenderIds) {\n\t\t\t\tconst nodeId = getNodeIdFromRenderId(renderId)\n\t\t\t\tupdatedNodeIds.add(nodeId)\n\t\t\t}\n\t\t}\n\n\t\tif (visibilityUpdates) {\n\t\t\tconst updatedRenderIds = treeStore.sandboxVisibility.import(visibilityUpdates)\n\n\t\t\tfor (const renderId of updatedRenderIds) {\n\t\t\t\tconst nodeId = getNodeIdFromRenderId(renderId)\n\t\t\t\tupdatedNodeIds.add(nodeId)\n\t\t\t}\n\t\t}\n\n\t\ttreeStore.updateTreeCacheForNodes(updatedNodeIds, this.engine.componentLoader.activeBundleHash)\n\n\t\t// TODO: Do we need to run this if we just called `updateTreeCacheForVekter` inside\n\t\t// `updateTreeCacheForNodes`?\n\t\tif (layoutMeasurements.length > 0) {\n\t\t\tconst changedNodeIds = layoutCache.processLayoutMeasurements(layoutMeasurements)\n\t\t\tif (changedNodeIds.size > 0) {\n\t\t\t\tengineLog.debug(\"layoutMeasurements:\", changedNodeIds.size)\n\t\t\t\ttreeStore.syncNodeCacheWithDOMLayout(changedNodeIds)\n\t\t\t}\n\t\t}\n\n\t\tlogScheduler.trace(\n\t\t\t\"canvasSandboxDidRender\",\n\t\t\tthis.update,\n\t\t\tthis.lastUpdateSentToSandbox,\n\t\t\tupdate,\n\t\t\t\"in flight:\",\n\t\t\tthis.sandboxUpdateInFlight,\n\t\t)\n\n\t\t// FIXME: for now just flip the clause, but update should never be ahead of lastUpdateSentToSandbox?\n\t\tif (update >= this.lastUpdateSentToSandbox) {\n\t\t\tthis.sandboxUpdateInFlight = false\n\n\t\t\t// If measurements arrive while the canvas does a zoom animation, make sure that we\n\t\t\t// render when we are ready (e.g. animation finishes).\n\t\t\tif (!this.needRendering && layoutMeasurements.length > 0) {\n\t\t\t\tthis.processWhenReady(noop, \"nonUserEvent\")\n\t\t\t}\n\n\t\t\t// If a new frame was started since the last sandbox render request (e.g. atomic event coming in),\n\t\t\t// immediately update the sandbox again for the next update...\n\t\t\tthis.doSandboxRenderingIfNeeded()\n\n\t\t\t// ...but also render the UI for the current update.\n\t\t\tthis.doRenderingByCallback()\n\t\t} else {\n\t\t\t// Otherwise, we probably still updated the layout cache and need to\n\t\t\t// process that.\n\t\t\tthis.processWhenReady(noop, \"nonUserEvent\")\n\t\t}\n\n\t\t// Render secondary (lower priority) sandboxes\n\t\tthis.engine.doSecondarySandboxRenderingIfNeeded()\n\t}\n\n\tprivate scheduleSandboxRendering() {\n\t\tif (this.hadFatalError) return\n\t\tlogScheduler.trace(\"scheduleSandboxRendering\", this.update, this.sandboxUpdateInFlight)\n\t\tif (!this.needSandboxRendering) return\n\t\tif (this.sandboxUpdateInFlight) return\n\t\tsetTimeout(this.doSandboxRenderingIfNeeded)\n\t}\n\n\t// will do a postmessage to iframe, and setup that we listen for the postMessage back\n\tprivate doSandboxRenderingIfNeeded = () => {\n\t\tif (this.hadFatalError) return\n\t\tlogScheduler.trace(\"doSandboxRenderingIfNeeded\", this.update, this.sandboxUpdateInFlight)\n\t\tif (!this.needSandboxRendering) return\n\t\tif (this.sandboxUpdateInFlight) return\n\n\t\ttry {\n\t\t\tthis.engine.doToolProcessing()\n\n\t\t\tthis.needSandboxRendering = false\n\t\t\tthis.lastUpdateSentToSandbox = this.update\n\t\t\tthis.restartRenderingBackupTimer()\n\n\t\t\tif (!this.engine.loadWasCalled || !this.engine.canvasSandbox) {\n\t\t\t\tthis.doRenderingByCallback()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst willRender = this.engine.canvasSandbox.update(this.engine.stores.canvasStore.isInteractive)\n\t\t\tlogScheduler.trace(\"canvasSandbox.update\", this.update, willRender)\n\t\t\tif (willRender) {\n\t\t\t\tthis.sandboxUpdateInFlight = true\n\t\t\t} else {\n\t\t\t\tthis.doRenderingByCallback()\n\t\t\t}\n\t\t} catch (error) {\n\t\t\trecoverFromError(this.engine, reportableError(error))\n\t\t}\n\t}\n\n\t/**\n\t * An engine frame is basically:\n\t * - zero to many UI events\n\t * - zero to many expired timers\n\t * - then tool processing + post processing\n\t * - optionally sending data the sandbox\n\t * - optionally rendering\n\t * - then reporting\n\t */\n\tprivate doStartFrame() {\n\t\tif (this.hadFatalError) return\n\t\tassert(!this.engine.tree.hasUncommittedChanges(), \"tree must be clean\")\n\t\tassert(!this.needToolProcessing, \"must not have started an update yet\")\n\n\t\t// finish last frame, if relevant\n\t\tthis.engine.doReport()\n\n\t\t// Run tasks that the engine must do between frame. Those tasks might indirectly call\n\t\t// doStartFrame, in which case we need to bail.\n\t\tthis.runTasksScheduledBeforeNextFrame()\n\t\tif (this.needToolProcessing) return\n\n\t\t// prepare the next frame\n\t\tperformanceMark(\"frame\")\n\t\tthis.update += 1\n\t\tthis.engine.updateStartTime = performance.now()\n\t\tthis.needToolProcessing = true\n\t\tthis.needRendering = true\n\t\tthis.needSandboxRendering = !!this.engine.canvasSandbox\n\t\tthis.needReport = true\n\n\t\tthis.engine.stores.debugStore.update = this.update\n\t\tthis.documentHidden = document.hidden\n\t\tthis.engine.didScopeChange = false\n\t\tthis.forcedRendering = false\n\n\t\tlogScheduler.trace(\"doStartFrame\", this.update)\n\n\t\tthis.engine.tree.lineage.enablePartialScopeAccessChecks = experiments.isOn(\"debugEditWhileLoadingRuntimeChecks\")\n\t\tsetLoadWasChecked(this.engine.tree.get(this.engine.stores.scopeStore.activeId))\n\n\t\tif (this.engine.runningUnderTest) {\n\t\t\t// nothing\n\t\t} else if (this.engine.canvasSandbox) {\n\t\t\t// If there is a sandbox, it must be updated via postMessage, which\n\t\t\t// is async in a way that the browser might not composite all paints\n\t\t\t// in one compositing frame. Worse, because postMessages are placed\n\t\t\t// in the global event queue behind all already scheduled events, we\n\t\t\t// cannot use requestAnimationFrame, because that forces the\n\t\t\t// postMessage to be processed in the next frame.\n\t\t\t//\n\t\t\t// TODO react animation/effects interfere, we should intercept them\n\t\t\tthis.scheduleSandboxRendering()\n\t\t} else {\n\t\t\tthis.scheduleRendering()\n\t\t}\n\t}\n\n\tprivate doIntermediateFrameIfNeededForAtomicBoundary() {\n\t\tif (this.hadFatalError) return\n\t\tif (!this.needToolProcessing) return\n\t\tif (this.lastAtomicUpdate !== this.update) return\n\n\t\tassert(this.inEventHandling === 0, \"must not be in event handling\")\n\t\tthis.engine.doToolProcessing(false)\n\t\tassert(!this.engine.tree.hasUncommittedChanges(), \"tree must be clean\")\n\n\t\t// report the last frame\n\t\tthis.engine.doReport(false, true /* forced */)\n\n\t\t// prepare the next frame\n\t\tperformanceMark(\"frame\")\n\t\tthis.update += 1\n\t\tthis.engine.updateStartTime = performance.now()\n\t\tthis.needToolProcessing = true\n\t\tthis.needRendering = true\n\t\tthis.needSandboxRendering = !!this.engine.canvasSandbox\n\t\tthis.needReport = true\n\n\t\tthis.engine.stores.debugStore.update = this.update\n\t\tthis.documentHidden = document.hidden\n\t\tthis.engine.didScopeChange = false\n\t\tthis.forcedRendering = false\n\n\t\tlogScheduler.trace(\"doIntermediateFrameIfNeededForAtomicBoundary\", this.update)\n\t}\n\n\t/**\n\t * Atomic handlers ensure the event is handled separately by finishing up\n\t * the last frame, running a light-weight version of tool processing and\n\t * post-processing before the event handler if needed. This is useful for\n\t * things like mouse down/up in quick succession, because the engine's\n\t * default behavior is to merge input events if they come in during the same\n\t * frame.\n\t */\n\twrapAtomicHandler<T extends unknown[]>(handler: (...args: T) => void): (...args: T) => void {\n\t\tconst standardHandler = this.wrapHandler(handler)\n\t\treturn (...args: T) => {\n\t\t\tif (this.hadFatalError) return\n\t\t\tthis.doIntermediateFrameIfNeededForAtomicBoundary()\n\t\t\tconst res = standardHandler(...args)\n\t\t\tthis.lastAtomicUpdate = this.update\n\t\t\treturn res\n\t\t}\n\t}\n\n\tdocumentHidden = false\n\n\tprivate tasksScheduledAtEndOfFrame: Function[] | null = null\n\n\t/** Schedule a task to be run at the very end of a frame.\n\t *\n\t * Tasks must not use wrapHandler or equivalent!\n\t */\n\trunAtEndOfFrame(cb: Function) {\n\t\tif (this.hadFatalError) return\n\t\tif (!this.tasksScheduledAtEndOfFrame) {\n\t\t\tthis.tasksScheduledAtEndOfFrame = []\n\t\t}\n\t\tthis.tasksScheduledAtEndOfFrame.push(cb)\n\t}\n\n\t// called at endFrame()\n\trunTasksScheduledAtEndOfFrame() {\n\t\tif (this.hadFatalError) return\n\t\tif (!this.tasksScheduledAtEndOfFrame) return\n\n\t\tconst tasks = this.tasksScheduledAtEndOfFrame\n\t\tthis.tasksScheduledAtEndOfFrame = null\n\n\t\ttasks.forEach(task => {\n\t\t\ttry {\n\t\t\t\tperformanceMark(\"EndOfFrameTask\")\n\t\t\t\ttask()\n\t\t\t} catch (e) {\n\t\t\t\tengineLog.warnOncePerMinute(\"error in end of frame task:\", e)\n\t\t\t} finally {\n\t\t\t\tperformanceMeasure(\"EndOfFrameTask\", \"EndOfFrameTask\")\n\t\t\t\tperformanceClearMarks(\"EndOfFrameTask\")\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Allow the code-generation store to schedule an update that can't be\n\t * undone, won't trigger another code-generation pass, but also that waits\n\t * for the frame to be closed before continuing.\n\t */\n\tscheduleUpdateBypassingModuleRevisionHints<T>(task: (tree: CanvasTree) => T): Promise<T | undefined> {\n\t\tif (this.hadFatalError) return Promise.resolve(undefined)\n\t\treturn new Promise<T | undefined>((resolve, reject) => {\n\t\t\tlet result: T | undefined = undefined\n\t\t\tthis.runBeforeNextFrame(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.process(() => {\n\t\t\t\t\t\t// Disable the flag to ensure that we don't calculate revision hints.\n\t\t\t\t\t\tthis.engine.tree.processingLocalUserEdits = false\n\t\t\t\t\t\tresult = task(this.engine.tree)\n\t\t\t\t\t}, \"nonUserEvent\")\n\t\t\t\t\tresolve(result)\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.lastAtomicUpdate = this.update\n\t\t\t\t\tthis.engine.doPostProcessing()\n\t\t\t\t\t// Restore the flag after the tree is committed.\n\t\t\t\t\tthis.engine.tree.processingLocalUserEdits = true\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\t/**\n\t * Allow the code-generation store to schedule an update that can't be\n\t * undone, won't trigger another code-generation pass, but also that waits\n\t * for the frame to be closed before continuing.\n\t */\n\tscheduleUpdateWithDataTreeBypassingModuleRevisionHints<T>(task: (tree: CanvasTree) => T): Promise<T | undefined> {\n\t\tif (this.hadFatalError) return Promise.resolve(undefined)\n\t\treturn new Promise<T | undefined>((resolve, reject) => {\n\t\t\tlet result: T | undefined = undefined\n\t\t\tthis.runBeforeNextFrame(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.process(() => {\n\t\t\t\t\t\t// Disable the flag to ensure that we don't calculate revision hints.\n\t\t\t\t\t\tthis.engine.tree.processingLocalUserEdits = false\n\t\t\t\t\t\tresult = task(this.engine.stores.treeStore.getDataTreeOrPartialTree())\n\t\t\t\t\t}, \"nonUserEvent\")\n\t\t\t\t\tresolve(result)\n\t\t\t\t} catch (error) {\n\t\t\t\t\treject(error)\n\t\t\t\t} finally {\n\t\t\t\t\tthis.lastAtomicUpdate = this.update\n\t\t\t\t\tthis.engine.doPostProcessing()\n\t\t\t\t\t// Restore the flag after the tree is committed.\n\t\t\t\t\tthis.engine.tree.processingLocalUserEdits = true\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n\n\tprivate tasksScheduledBeforeNextFrameTimer: ReturnType<typeof setTimeout> | undefined\n\tprivate tasksScheduledBeforeNextFrame: Function[] | null = null\n\n\t/** Schedule a task to be run immediately after this frame, but before any\n\t * next frame starts.\n\t *\n\t * Tasks must use wrapHandler or equivalent if they manipulate document\n\t * state.\n\t */\n\trunBeforeNextFrame(task: Function) {\n\t\tif (this.hadFatalError) return\n\t\tif (!this.tasksScheduledBeforeNextFrame) {\n\t\t\tthis.tasksScheduledBeforeNextFrame = []\n\t\t}\n\t\tthis.tasksScheduledBeforeNextFrame.push(task)\n\n\t\t// if idle, make sure something will go run the tasks\n\t\tif (this.isIdle() && !this.tasksScheduledBeforeNextFrameTimer) {\n\t\t\tthis.tasksScheduledBeforeNextFrameTimer = setTimeout(this.runTasksScheduledBeforeNextFrame)\n\t\t}\n\t}\n\n\t// called with a timer of zero, or first time enterEventHandling() is called\n\tprivate runTasksScheduledBeforeNextFrame = () => {\n\t\tif (this.hadFatalError) return\n\t\tif (!this.tasksScheduledBeforeNextFrame) return\n\n\t\tclearTimeout(this.tasksScheduledBeforeNextFrameTimer)\n\t\tthis.tasksScheduledBeforeNextFrameTimer = undefined\n\n\t\tassert(!this.needToolProcessing, \"must be in idle state for runTasksScheduledAtNextFrame\")\n\t\tconst tasks = this.tasksScheduledBeforeNextFrame\n\t\tthis.tasksScheduledBeforeNextFrame = null\n\n\t\ttasks.forEach(task => {\n\t\t\tconst start = performance.now()\n\t\t\ttry {\n\t\t\t\ttask()\n\t\t\t} catch (e) {\n\t\t\t\tengineLog.warnOncePerMinute(\"error in out of frame task:\", e)\n\t\t\t} finally {\n\t\t\t\tperformanceMeasure(\"BeforeFrameTask\", { start, end: performance.now() })\n\t\t\t}\n\t\t})\n\t}\n}\n", "import { localPackageFallbackIdentifier } from \"@framerjs/framer-runtime/crossorigin\"\nimport type { CanvasTree } from \"document/models/CanvasTree/index.ts\"\nimport { getColorStyleTokensByPackageIdMap } from \"document/models/CanvasTree/utils/tokenMap.ts\"\nimport { isEqual } from \"library/index.ts\"\nimport type { ColorPickerTokenPackages } from \"./types.ts\"\n\nconst localTokensDisplayName = \"Styles\"\n\n// Cache the previously computed tokenPackages() result to enable us to return\n// the same object each time if nothing has changed.\n// TODO: We should likely move this into a store.\nlet prevTokenPackages: ColorPickerTokenPackages | undefined\n\nexport function tokenPackages(tree: CanvasTree): ColorPickerTokenPackages {\n\tconst result: ColorPickerTokenPackages = {}\n\n\tconst tokensByPackage = getColorStyleTokensByPackageIdMap(tree)\n\tlet pkgTokenOrderDidChange = false\n\n\tfor (const pkgId in tokensByPackage) {\n\t\tconst isLocalPackage = pkgId === localPackageFallbackIdentifier\n\t\tconst tokens = tokensByPackage[pkgId] || {}\n\n\t\tif (prevTokenPackages?.[pkgId]) {\n\t\t\tconst previousTokens = prevTokenPackages[pkgId].tokens\n\t\t\tpkgTokenOrderDidChange = pkgTokenOrderDidChange || !equalKeyOrder(tokens, previousTokens)\n\t\t}\n\t\tif (isLocalPackage) continue\n\t}\n\n\t// Create entity for local color tokens\n\tconst tokens = tokensByPackage[localPackageFallbackIdentifier] || {}\n\tresult[localPackageFallbackIdentifier] = {\n\t\tpackageIdentifier: localPackageFallbackIdentifier,\n\t\tdisplayName: localTokensDisplayName,\n\t\ttokens,\n\t\ttokensCount: Object.keys(tokens).length,\n\t\tisEditable: true,\n\t\tisLocal: true,\n\t}\n\n\tif (!pkgTokenOrderDidChange && prevTokenPackages && isEqual(result, prevTokenPackages, true)) {\n\t\treturn prevTokenPackages\n\t}\n\n\treturn (prevTokenPackages = result)\n}\n\n/** This can be used to clean up the cache used by `getTokenPackages`. Useful to release some\n * resources, like after we loaded a new tree. */\nexport function resetTokenPackagesCache() {\n\tprevTokenPackages = undefined\n}\n\nfunction equalKeyOrder(a: { [key: string]: any }, b: { [key: string]: any }) {\n\tconst aKeys = Object.keys(a)\n\tconst bKeys = Object.keys(b)\n\treturn isEqual(aKeys, bKeys)\n}\n", "import { assert } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { type CanvasTree, CustomCodeScopeNode, type NodeID } from \"document/models/CanvasTree/index.ts\" /**\n\n/**\n * Deletes all occurrences of the given pageId from the custom code nodes.\n *\n * If after the removal, the node has no pageIds, the node is removed.\n *\n * Example:\n * Before: [page1, page2, page3] -> remove page2 -> [page1, page3]\n * Before: [page2] -> remove page2 -> [] -> remove node\n */\nexport function deletePageFromCustomCode(engine: VekterEngine, pageId: NodeID) {\n\tconst { treeStore } = engine.stores\n\tconst scope = CustomCodeScopeNode.get(treeStore.getDataTreeOrPartialTree())\n\tif (treeStore.getDataTree()) {\n\t\tif (!scope) return\n\t\tassert(scope.isLoaded())\n\t\tclearPageIdsFromScope(treeStore.getDataTreeOrPartialTree(), scope, pageId)\n\t} else {\n\t\tengine.loadScopesThenProcess([scope], ([loadedScope]) => {\n\t\t\tif (!loadedScope) return\n\t\t\tclearPageIdsFromScope(engine.tree, loadedScope, pageId)\n\t\t})\n\t}\n}\n\nfunction clearPageIdsFromScope(tree: CanvasTree, scope: CustomCodeScopeNode, pageId: string) {\n\tfor (const node of scope.children) {\n\t\tif (!node.pageIds?.includes(pageId)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconst pageIds = node.pageIds.filter(id => id !== pageId)\n\t\tif (pageIds.length === 0) {\n\t\t\ttree.removeNode(node)\n\t\t} else {\n\t\t\ttree.current(node)?.set({ pageIds })\n\t\t}\n\t}\n}\n", "import type { LocalModuleBareIdentifierString } from \"@framerjs/shared\"\nimport { assertNever } from \"@framerjs/shared\"\nimport { getScopeTypeForScope } from \"document/base-engine/BaseScopeStore.ts\"\nimport { ScopeType } from \"document/utils/scopeType.ts\"\nimport type { ScopeNode } from \"../../index.ts\"\n\nexport interface ModuleBackedScope {\n\treadonly instanceIdentifier: LocalModuleBareIdentifierString\n}\n\nexport function isModuleBackedScope<T extends ScopeNode>(scope: T): scope is T & ModuleBackedScope {\n\tconst scopeType = getScopeTypeForScope(scope)\n\tswitch (scopeType) {\n\t\tcase ScopeType.Analytics:\n\t\tcase ScopeType.CanvasPage:\n\t\tcase ScopeType.ContentManagement:\n\t\tcase ScopeType.DesignPage:\n\t\tcase ScopeType.LocalizationGlossary:\n\t\tcase ScopeType.Routes:\n\t\tcase ScopeType.CustomCode:\n\t\t\treturn false\n\t\tcase ScopeType.SmartComponent:\n\t\tcase ScopeType.WebPage:\n\t\tcase ScopeType.LayoutTemplate:\n\t\tcase ScopeType.VectorSet:\n\t\t\treturn true\n\t\tdefault:\n\t\t\tassertNever(scopeType, \"isModuleBackedScope should handle all scope types\")\n\t}\n}\n", "import { assert, getLogger } from \"@framerjs/shared\"\nimport type { VekterEngine } from \"document/VekterEngine.ts\"\nimport { fetchWithRetry } from \"utils/fetch.ts\"\nimport { getMultiplayerServiceURL } from \"web/lib/multiplayerService.ts\"\nimport { xRequestedByHeader } from \"web/lib/xRequestedByHeader.ts\"\nimport { getIsViewOnly } from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { ModalType } from \"./ModalType.ts\"\n\nconst FOREGROUND_INTERVAL_MS = 25\nconst BACKGROUND_INTERVAL_MS = 1000\n\nconst MAX_BATCH_MS = 20\nconst TIME_BETWEEN_BACKGROUND_WORK_MS = 2_000\n\nconst log = getLogger(\"document-upgrade-manager\")\n\nasync function requestServerSnapshot(projectId: string, isMPSSocket: boolean): Promise<void> {\n\tconst path = `/projects/${projectId}/tree/latest`\n\t// TODO: Remove the conditional once we've fully migrated to FramerMultiplayerService\n\tconst url = isMPSSocket ? getMultiplayerServiceURL(path) : path\n\tconst response = await fetchWithRetry(url, {\n\t\tmethod: \"POST\",\n\t\tcredentials: \"include\",\n\t\theaders: xRequestedByHeader,\n\t})\n\tif (!response.ok) {\n\t\tlog.reportError(\"Error requesting server snapshot after document upgrade.\", {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t})\n\t}\n}\n\nexport interface UpgradeTask<T> {\n\t/** Called by the upgrade manager, should return the numbers of work items left to do, should\n\t * not return a number higher that the amount of times addWorkItem was called. */\n\tworkItemsRemaining(): number\n\n\t/** Add a work item to the task. */\n\taddWorkItem(workItem: T): void\n\n\t/**\n\t * Called by the upgrade manager when everything is ready for the task to do some work. The task\n\t * should do a small bit of work when this is called. The upgrade manager will batch work for a\n\t * fixed amount of time. So this method might get called multiple times per batch. But only one\n\t * task will run per batch. At the start of a batch the tree will be clean. And at the end of\n\t * the batch the tree will be committed. So a task can have full control over the engine, the\n\t * tree timeline, and the diffs being created.\n\t */\n\tdoSomeWork(engine: VekterEngine): void\n}\n\ntype UpgradeTaskClass<T> = new () => UpgradeTask<T>\n\ntype ProgressListener = (running: boolean, todo: number, total: number) => void\n\nexport class DocumentUpgradeManager {\n\t/** If set to true, and there are tasks to run, the upgrade manager will automatically run in\n\t * the background after the user makes an edit. */\n\tstartAfterUserEdit = false\n\n\t/** If set to true, and there are tasks to run, the upgrade manager will show a modal dialog\n\t * after the document has fully loaded, the dialog will then start the upgrade manager. */\n\tstartAfterFullyLoaded = true\n\n\tprivate interval = 0\n\tprivate foreground = false\n\tprivate needsServerSnapshot = false\n\n\t/** All the work items scheduled. */\n\tprivate totalWorkItems = 0\n\n\t/** All the work items to be done. Computed from the individual tasks. */\n\tprivate workItemsRemaining = 0\n\n\tprivate progressListeners = new Set<ProgressListener>()\n\n\t// track tasks to run\n\tprivate lastWorkTimestamp = 0\n\tprivate tasksSignalled = new Map<UpgradeTaskClass<unknown>, UpgradeTask<unknown>>()\n\tprivate tasksToRun: UpgradeTask<unknown>[] = []\n\n\tconstructor(readonly engine: VekterEngine) {}\n\n\taddProgressListener(listener: ProgressListener): () => void {\n\t\tthis.progressListeners.add(listener)\n\t\treturn () => this.progressListeners.delete(listener)\n\t}\n\n\tpublic schedule<T>(taskClass: UpgradeTaskClass<T>, workItem: T) {\n\t\tlet scheduled: UpgradeTask<T> | undefined = this.tasksSignalled.get(taskClass)\n\t\tif (!scheduled) {\n\t\t\tscheduled = new taskClass()\n\t\t\tthis.tasksToRun.push(scheduled)\n\t\t\tthis.tasksSignalled.set(taskClass, scheduled)\n\t\t}\n\n\t\tthis.totalWorkItems += 1\n\t\tthis.workItemsRemaining += 1\n\t\tscheduled.addWorkItem(workItem)\n\n\t\tif (!this.needsServerSnapshot) {\n\t\t\tthis.totalWorkItems += 1\n\t\t\tthis.workItemsRemaining += 1\n\t\t\tthis.needsServerSnapshot = true\n\t\t}\n\t}\n\n\tprivate removeTaskWhenDone(task: UpgradeTask<unknown>): void {\n\t\tassert(task.workItemsRemaining() === 0, \"Should not remove tasks that have work left to do.\")\n\n\t\tfor (let i = 0; i < this.tasksToRun.length; i++) {\n\t\t\tif (this.tasksToRun[i] === task) {\n\t\t\t\tthis.tasksToRun.splice(i, 1)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfor (const entry of this.tasksSignalled) {\n\t\t\tif (entry[1] === task) {\n\t\t\t\tthis.tasksSignalled.delete(entry[0])\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getTaskToRun(): UpgradeTask<unknown> | undefined {\n\t\treturn this.tasksToRun[0]\n\t}\n\n\t// After tasks had a chance to run, we recompute how much work is left to do.\n\tprivate recomputeWorkItemsToDo(): void {\n\t\tthis.workItemsRemaining = 0\n\t\tif (this.needsServerSnapshot) {\n\t\t\tthis.workItemsRemaining += 1\n\t\t}\n\t\tfor (const task of this.tasksToRun) {\n\t\t\tthis.workItemsRemaining += task.workItemsRemaining()\n\t\t}\n\t}\n\n\t/** Check if the user can edit, all data was loaded, the network is good, the tree is clean. */\n\tprivate userCanEditAndIsIdle(): boolean {\n\t\tif (this.engine.scheduler.eventsHandled > 0) return false\n\t\tif (!this.engine.scheduler.isIdle()) return false\n\t\tif (this.engine.remoteDocument && !this.engine.remoteDocument.networkReady) return false\n\t\tif (!this.engine.stores.loadingStore.hasMinimalEditableData) return false\n\t\tif (this.engine.tree.hasUncommittedChanges()) return false\n\t\tif (getIsViewOnly(this.engine, \"canEditContent\")) return false\n\n\t\tif (this.foreground) return true\n\n\t\t// If we are setup to run in the background, we additionally check all diffs are confirmed\n\t\t// by the server. And there is nothing queued in the code generation store or modules\n\t\t// storage.\n\t\tif (this.engine.remoteDocument?.hasUnconfirmedChanges()) return false\n\t\tif (!this.engine.stores.codeGenerationStore.isIdle()) return false\n\t\tif (this.engine.stores.modulesStore.isProcessingModules()) return false\n\t\treturn true\n\t}\n\n\t/** If any upgrade tasks were scheduled, this call will start the upgrading process in the\n\t * foreground with a modal dialog. */\n\tdocumentLoaded() {\n\t\tif (!this.startAfterFullyLoaded) return\n\t\tif (this.workItemsRemaining === 0) return\n\n\t\t// Only show modal and start if the user can edit.\n\t\tif (!this.engine.remoteDocument?.networkReady) return\n\t\tif (getIsViewOnly(this.engine, \"canEditContent\")) return\n\n\t\tthis.engine.stores.modalStore.set({ type: ModalType.UpgradeDocument, source: \"automatic\" })\n\t}\n\n\t/** If any upgrade tasks were scheduled, this call will start the upgrading process in the\n\t * background, waiting for the user to be idle, modules processing to be idle, etc. */\n\tdocumentEditedByUser(): void {\n\t\tif (!this.startAfterUserEdit) return\n\n\t\t// If already running, don't start again.\n\t\tif (this.interval) return\n\n\t\t// If there is no work to do, don't start.\n\t\tif (this.workItemsRemaining === 0) return\n\n\t\tthis.startInBackground()\n\t}\n\n\tstartInForeground() {\n\t\tthis.stop()\n\t\tlog.info(\"starting in foreground ...\")\n\t\tthis.foreground = true\n\t\tthis.interval = window.setInterval(this.tick, FOREGROUND_INTERVAL_MS)\n\t\tthis.signalProgressListeners()\n\t}\n\n\tstartInBackground(): void {\n\t\tthis.stop()\n\t\tlog.info(\"starting in background ...\")\n\t\tthis.foreground = false\n\t\tthis.interval = window.setInterval(this.tick, BACKGROUND_INTERVAL_MS)\n\t\tthis.signalProgressListeners()\n\t}\n\n\tprivate stop(): void {\n\t\tif (!this.interval) return\n\n\t\tlog.info(\"... stopping\")\n\t\twindow.clearInterval(this.interval)\n\t\tthis.interval = 0\n\t}\n\n\tprivate waitingForServerSnapshotRequest = false\n\tmakeServerSnapshot(): void {\n\t\t// Notice, makeSnapshot will be repeatedly called on a timer. What we are going to do\n\t\t// depends on confirmed changes on the server and if we already did a fetch. If we are\n\t\t// waiting for the request to finish, return.\n\t\tif (this.waitingForServerSnapshotRequest) return\n\n\t\t// If we don't need to make a snapshot, return.\n\t\tif (!this.needsServerSnapshot) return\n\n\t\tlog.debug(\"make server snapshot\")\n\n\t\t// Wait for the server to confirm all our changes.\n\t\tif (this.engine.remoteDocument?.hasUnconfirmedChanges()) return\n\n\t\tconst projectId = this.engine.remoteDocument?.projectId\n\t\tif (!projectId) {\n\t\t\tthis.needsServerSnapshot = false\n\t\t\treturn\n\t\t}\n\n\t\tvoid this.requestServerSnapshot(projectId)\n\t}\n\n\tprivate async requestServerSnapshot(projectId: string) {\n\t\t// While makeServerSnapshot is called repeatedly on a timer, this will only be called once\n\t\t// due to the checks makeServerSnapshot does.\n\t\ttry {\n\t\t\tlog.debug(\"make server snapshot: fetch\")\n\t\t\tthis.waitingForServerSnapshotRequest = true\n\t\t\tawait requestServerSnapshot(projectId, this.engine.stores.treeStore.isMPSSocket)\n\t\t} finally {\n\t\t\tthis.needsServerSnapshot = false\n\t\t\tthis.waitingForServerSnapshotRequest = false\n\t\t}\n\t}\n\n\t/** Returns the progress of the upgrading process as a number between 0 and 1. */\n\tprogress(): number {\n\t\tif (this.totalWorkItems === 0) return 1\n\t\treturn (this.totalWorkItems - this.workItemsRemaining) / this.totalWorkItems\n\t}\n\n\tprivate signalProgressListeners(): void {\n\t\tfor (const listener of this.progressListeners) {\n\t\t\tlistener(Boolean(this.interval), this.workItemsRemaining, this.totalWorkItems)\n\t\t}\n\t}\n\n\tprivate tick = (): void => {\n\t\tif (!this.foreground) {\n\t\t\tif (performance.now() - this.lastWorkTimestamp < TIME_BETWEEN_BACKGROUND_WORK_MS) return\n\t\t}\n\n\t\ttry {\n\t\t\tconst engine = this.engine\n\t\t\tconst task = this.getTaskToRun()\n\n\t\t\tif (!task) {\n\t\t\t\tif (this.needsServerSnapshot) {\n\t\t\t\t\tthis.makeServerSnapshot()\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tthis.stop()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (!this.userCanEditAndIsIdle()) return\n\n\t\t\tthis.lastWorkTimestamp = performance.now()\n\n\t\t\t// At this point we know the engine is in a clean state and we can work in private.\n\t\t\ttry {\n\t\t\t\tengine.scheduler.enterEventHandling(\"nonUserEvent\")\n\n\t\t\t\tengine.setEditReason(\"document_upgrade\")\n\t\t\t\tthis.runOneTask(task)\n\t\t\t\tif (task.workItemsRemaining() <= 0) {\n\t\t\t\t\tthis.removeTaskWhenDone(task)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlog.reportError(error, { context: \"Error in upgrade task processing\" })\n\t\t\t} finally {\n\t\t\t\tengine.scheduler.exitEventHandling(\"nonUserEvent\")\n\t\t\t}\n\n\t\t\tengine.doToolProcessing()\n\t\t\tengine.doRendering()\n\t\t\tengine.doReport()\n\t\t} finally {\n\t\t\tthis.recomputeWorkItemsToDo()\n\t\t\tthis.signalProgressListeners()\n\t\t}\n\t}\n\n\tprivate runOneTask(task: UpgradeTask<unknown>) {\n\t\tlog.debug(\"running task\", task)\n\n\t\tconst start = performance.now()\n\t\twhile (task.workItemsRemaining() > 0) {\n\t\t\ttask.doSomeWork(this.engine)\n\t\t\tif (performance.now() - start >= MAX_BATCH_MS) break\n\t\t}\n\t}\n}\n", "import { setupTreeLibrary, throttledSetupLibrary } from \"@framer/tree-library\"\nimport { dismissToolFallbackToast, setToolFallbackToast } from \"@framerjs/app-shared\"\nimport { createAssetReferenceForImage } from \"@framerjs/assets\"\nimport { MAIN_BRANCH_ID } from \"@framerjs/crdtree2\"\nimport { triggerLayoutFrameHierarchyEvent } from \"@framerjs/framer-events\"\nimport { ComponentLoader } from \"@framerjs/framer-runtime\"\nimport type { ModuleExportIdentifierString } from \"@framerjs/shared\"\nimport {\n\tResolvablePromise,\n\tassert,\n\tgetLogReplayBuffer,\n\tisDependenciesFileId,\n\tparseModuleIdentifier,\n\tunhandledError,\n} from \"@framerjs/shared\"\nimport { isMobile } from \"@framerjs/shared/src/environment.ts\"\nimport { noop } from \"@framerjs/shared/src/noop.ts\"\nimport { Dictionary } from \"app/dictionary.ts\"\nimport { employeesOnlySettings } from \"app/employeesOnlySettings.ts\"\nimport { experiments } from \"app/experiments.ts\"\nimport * as ipc from \"app/ipc.ts\"\nimport { loadDocumentMetrics } from \"app/trackDocumentLoad.ts\"\nimport type { SandboxRPC } from \"canvas-sandbox-renderer/SandboxRPC.ts\"\nimport type { SandboxRenderer } from \"canvas-sandbox-renderer/SandboxRenderer.ts\"\nimport type { SandboxCommandInterface } from \"canvas-sandbox/SandboxCommand.ts\"\nimport { cloneNodePropsAndStripLocalizedValues } from \"code-generation/utils/stripLocalizedValues.ts\"\nimport type { EngineChangeFlag } from \"document/EngineChanges.ts\"\nimport { EngineChange } from \"document/EngineChanges.ts\"\nimport { engineLog, logScheduler } from \"document/EngineLoggers.ts\"\nimport type { VekterTool } from \"document/VekterTool.ts\"\nimport {\n\ttype LoadedWebPageNode,\n\ttype MaybeNodeID,\n\ttype NodeID,\n\ttype CanvasTree,\n\tBooleanShapeNode,\n\tCanvasNode,\n\tFrameNode,\n\tNullID,\n\tOvalShapeNode,\n\tPathNode,\n\tPolygonShapeNode,\n\tRectangleShapeNode,\n\tRichTextNode,\n\tScopeNode,\n\tShapeContainerNode,\n\tShapeGroupNode,\n\tStarShapeNode,\n} from \"document/models/CanvasTree/index.ts\"\nimport { RootNode } from \"document/models/CanvasTree/nodes/RootNode.ts\"\nimport { TemplateHelper, createDuplicatedFromIfAllowed } from \"document/models/CanvasTree/nodes/TemplateHelper.ts\"\nimport { withChildren } from \"document/models/CanvasTree/traits/WithChildren.ts\"\nimport type { ShapeType } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport { shapeSupportsCenteredAttribute, withShape } from \"document/models/CanvasTree/traits/WithShape.ts\"\nimport type { IsMaster } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { isMaster, isReplica, isReplicaChild } from \"document/models/CanvasTree/traits/WithTemplate.ts\"\nimport { acceptsChild } from \"document/models/CanvasTree/traits/utils/acceptsChild.ts\"\nimport { inspect } from \"document/models/CanvasTree/utils/inspect.ts\"\nimport { verifyHomeNodePostProcess } from \"document/models/CanvasTree/utils/verifyHomeNodePostProcess.ts\"\nimport type { FramePoint } from \"document/models/FramePoint.ts\"\nimport { newToolFor } from \"document/newToolFor.ts\"\nimport type { FrameStats } from \"document/stores/DebugStore.ts\"\nimport type { ActiveNode } from \"document/stores/DocumentSettingsStore.ts\"\nimport { LoadingState } from \"document/stores/LoadingStore.ts\"\nimport { PopoverType } from \"document/stores/PopoverStore.ts\"\nimport {\n\tTools,\n\tassertCanUseToolInMode,\n\tisToolAllowedInMode,\n\tisToolAllowedInScopeType,\n\tisToolAllowedInViewOnly,\n\tisToolAllowedWhenCollectionOverlayActive,\n\tisToolWithHandle,\n\tisZoomTool,\n} from \"document/stores/ToolStore.ts\"\nimport { ModalType } from \"document/utils/ModalType.ts\"\nimport { environment } from \"environment/index.ts\"\nimport { DimensionType, isEqual } from \"library/index.ts\"\nimport { Point } from \"library/render/types/Point.ts\"\nimport { DisconnectReason } from \"socket/types.ts\"\nimport { markLoadingPerf } from \"utils/performanceTracker.ts\"\nimport { getParentDataRepeater, isRepeatedItem, resetRepeatedItemOfDataRepeater } from \"utils/repeaterUtils.ts\"\nimport type { RenderedUpdate } from \"utils/rpc/shared/definitions.ts\"\nimport { isNumber, isUndefined } from \"utils/typeChecks.ts\"\nimport { getViewParamsFromURL } from \"utils/urlParams.ts\"\nimport {\n\tperformanceClearMarks,\n\tperformanceClearMeasures,\n\tperformanceMark,\n\tperformanceMeasure,\n} from \"utils/userTiming.ts\"\nimport { withClassDiscriminator } from \"utils/withClassDiscriminator.ts\"\nimport { toast } from \"web/lib/toaster.ts\"\nimport { record } from \"web/lib/tracker.ts\"\nimport {\n\ttype PermissionStateWithIsReady,\n\tgetIsViewOnly,\n\tgetPermissionStateWithIsReady,\n\tgetPermissionStateWithIsReadyDependencies,\n\tisViewOnly,\n\tsubscribeToPermissionStateWithIsReadyChanges,\n} from \"web/pages/project/permissions/isViewOnly.ts\"\nimport { getIpcRenderer } from \"wrappers/ipcRenderer.ts\"\nimport type { EnginePerformanceReporter } from \"./EnginePerformance.ts\"\nimport { EnginePerformance } from \"./EnginePerformance.ts\"\nimport { EngineStores } from \"./EngineStores.ts\"\nimport { EngineTesting } from \"./EngineTesting.ts\"\nimport { RemoteDocument } from \"./RemoteDocument.ts\"\nimport type { RemoteDocumentHandler } from \"./RemoteDocumentHandler.ts\"\nimport { VekterEngineScheduler } from \"./VekterEngineScheduler.ts\"\nimport type { BaseEngine, RunWithFullyLoadedTreeOptions } from \"./base-engine/BaseEngine.ts\"\nimport { editPageTitle } from \"./components/chrome/Pages/utils/editPageRow.ts\"\nimport { getRouteSegmentNodeByWebPageId } from \"./components/chrome/Pages/utils/getRouteSegmentNodeByWebPageId.ts\"\nimport { resetTokenPackagesCache } from \"./components/chrome/shared/ColorPicker/tokenPackages.ts\"\nimport type { LoadingFullDocumentModalProps } from \"./components/chrome/shared/LoadingFullDocumentModal.tsx\"\nimport type { PopoutNavigation } from \"./components/chrome/shared/PopoutNavigation.tsx\"\nimport { deletePageFromCustomCode } from \"./components/chrome/siteSettings/CustomCode/utils/deletePageFromCustomCode.ts\"\nimport type { AgentDragSelectToolOptions, AgentSelectToolOptions } from \"./components/tools/AgentSelectTool.ts\"\nimport type { CollectionReferenceVariableEditToolOptions } from \"./components/tools/CollectionReferenceVariableEditTool.ts\"\nimport type { DateVariableEditToolOptions } from \"./components/tools/DateVariableEditTool.ts\"\nimport type { EnumVariableEditToolOptions } from \"./components/tools/EnumVariableEditTool.ts\"\nimport type { HighlightStackItemToolOptions } from \"./components/tools/HighlightStackItem.tsx\"\nimport type { MoveToolOptions } from \"./components/tools/MoveTool.ts\"\nimport { isMoveTool } from \"./components/tools/MoveTool.ts\"\nimport { PaddingTool } from \"./components/tools/Padding.tsx\"\nimport { RadiusTool } from \"./components/tools/RadiusTool.ts\"\nimport { ResizeTool } from \"./components/tools/ResizeTool.ts\"\nimport type { RichTextVariableEditToolOptions } from \"./components/tools/RichTextVariableEditTool.ts\"\nimport type { StringVariableEditToolOptions } from \"./components/tools/StringVariableEditTool.ts\"\nimport type { TextEditToolOptions } from \"./components/tools/TextEditTool.ts\"\nimport type { ViewportResizeToolOptions } from \"./components/tools/ViewportResize.tsx\"\nimport { desktopBreakpointVariantDefault } from \"./components/utils/breakpointVariantDefaults.ts\"\nimport { ContextAction } from \"./components/utils/contextActions.ts\"\nimport {\n\tcreateWebPage,\n\tcreateWebPageWithoutTemplate,\n\tgetLoadedWebPageTemplate,\n} from \"./components/utils/createWebPage.ts\"\nimport { getUniquePagePath } from \"./components/utils/getUniquePagePath.ts\"\nimport { isCrdtTreeCommitter, type CrdtTreeCommitter } from \"./crdt/sync/CrdtTreeCommitter.ts\"\nimport { CrdtDocumentLoader, CrdtRemoteDocumentDataHandler } from \"./crdt/sync/index.ts\"\nimport { setGlobalEngine } from \"./getEngine.ts\"\nimport { DocumentLoader } from \"./loader/DocumentLoader.ts\"\nimport type { MapArrayToLoadedOptionalScopeNodes } from \"./models/CanvasTree/CanvasTree.ts\"\nimport { treeLibrary } from \"./models/CanvasTree/FastTreeLibrary.ts\"\nimport { getOrRegisterDriverBasedOnExperiment } from \"./models/CanvasTree/drivers/NodeTreeDriverSelector.ts\"\nimport type { CanvasNodeCache } from \"./models/CanvasTree/nodes/CanvasNodeCache.ts\"\nimport { CanvasChildList, type ChildList } from \"./models/CanvasTree/nodes/ChildList.ts\"\nimport { CONTENT_MANAGEMENT_ID } from \"./models/CanvasTree/nodes/ContentManagementNode.ts\"\nimport { randomBranchID, randomID } from \"./models/CanvasTree/nodes/NodeID.ts\"\nimport { getDefaultPresets } from \"./models/CanvasTree/nodes/RichTextNode.utils.ts\"\nimport { isScopeNode, resetLoadedWasChecked } from \"./models/CanvasTree/nodes/ScopeNode.ts\"\nimport { getShapeContainerNodeFor } from \"./models/CanvasTree/nodes/ShapeContainerNode.ts\"\nimport { isContentNode } from \"./models/CanvasTree/nodes/TreeNode.ts\"\nimport {\n\tBRANCH_DELETED_AT_KEY,\n\ttype BranchNode,\n\tisBranchContributor,\n} from \"./models/CanvasTree/nodes/branches/BranchNode.ts\"\nimport { isImportableComponentNode } from \"./models/CanvasTree/nodes/isImportableComponentNode.ts\"\nimport { isModuleBackedScope } from \"./models/CanvasTree/nodes/utils/isModuleBackedScope.ts\"\nimport {\n\tisCanvasPageNode,\n\tisCodeComponentNode,\n\tisCollectionItemNode,\n\tisCollectionNode,\n\tisRouteSegmentRootNode,\n\tisWebPageNode,\n} from \"./models/CanvasTree/nodes/utils/nodeCheck.ts\"\nimport { isFixedOrRelativeOverlay } from \"./models/CanvasTree/nodes/utils/overlayHelpers.ts\"\nimport { withIntrinsicSize } from \"./models/CanvasTree/traits/WithIntrinsicSize.ts\"\nimport { hasItemsOrderOverride } from \"./models/CanvasTree/traits/WithItemsOrder.ts\"\nimport type { LocaleId } from \"./models/CanvasTree/traits/WithLocales.ts\"\nimport { isPinnable } from \"./models/CanvasTree/traits/WithPins.ts\"\nimport type { BaseShallowType } from \"./models/CanvasTree/traits/WithScopeLoader.ts\"\nimport {\n\tisBreakpointVariant,\n\tisPrimaryVariant,\n\tisReplicaVariantOrReplicaVariantChild,\n\tisTopLevelVariant,\n} from \"./models/CanvasTree/traits/WithVariant.ts\"\nimport { isVisibleNode } from \"./models/CanvasTree/traits/WithVisibility.ts\"\nimport type { WithFormContainer } from \"./models/CanvasTree/traits/forms/WithFormContainer.ts\"\nimport { isFormContainer } from \"./models/CanvasTree/traits/forms/WithFormContainer.ts\"\nimport type { MasksByNodeId } from \"./models/CanvasTree/traits/utils/reduceMasks.ts\"\nimport { convertFrameToCanvas, getCanvasBoundingRectCached } from \"./models/CanvasTree/utils/geometry.ts\"\nimport { shouldGuessPinToBottom } from \"./models/shouldGuessPinToBottom.ts\"\nimport { updateTreeCacheForVekter } from \"./models/updateTreeCacheForVekter.ts\"\nimport { togglePreviewVisible } from \"./preview/togglePreviewVisible.ts\"\nimport { createFormConfigSource } from \"./stores/FormsStore.ts\"\nimport type { TreeEditUndoEntry } from \"./stores/UndoRedoManager.ts\"\nimport { ActiveContentPanelTab, ActiveMainView } from \"./utils/ActiveEditorType.ts\"\nimport { DocumentUpgradeManager } from \"./utils/DocumentUpgradeManager.ts\"\nimport type { EffectPreviewState } from \"./utils/EffectPreviewType.ts\"\nimport { isLocalesUndoRedoEntry, isRedirectUndoRedoEntry } from \"./utils/undoRedoEntryChecks.ts\"\n\ninterface MainSandboxRenderer extends SandboxCommandInterface {\n\tsandbox: SandboxRPC\n\n\tupdate(interactive: boolean): boolean\n\trenderUpdates(updates: VoidFunction): Promise<void>\n}\n\n// The VekterEngine tries to keep the flow of events and rendering going. The\n// general flow looks like this:\n\n// external:  \\ timer, network, ipc /\n// user:        \\ key, mouse  /\n// engine:  idle |   event   | tool | post process | send update |-> render | report\n// tree:  closed |       open       |    commit    |  closed\n// sandbox (iframe):                               |-> render    | send status\n\n// Where rendering is done immediately when the sandbox receives a postMessage,\n// or the main renderer receives a postMessages from the sandbox. However,\n// in between those two postMessages, the browser might handle more user or\n// external events. For events that cannot be stacking up, we run a lightweight\n// tool processing step.\n\n// The engine can also be asked to process two kinds of tasks outside of this\n// normal event loop: tasks to be done after processing this frame is done. Or a\n// task to be done outside of processing frame. All multi-user processing uses\n// that last task queue.\n\nexport interface VekterEngineUpdateState {\n\tupdate: number\n}\n\n/** `NonPromiseLike<T, Expected>` enforces a type not to be a promise, it's primary use is to  to\n * make sure a function is synchronous. If possible, prefer using `EnsureSync<T, ExpectedReturn>` to\n * wrap the whole function instead of making its return type `NonPromiseLike<T, Expected>`.\n * `NonPromiseLike` is exposed seperately, because there are cases (e.g. inside the ModulesStore)\n * where we need to express that function that returns a non-promise is also a sync function, and\n * that seems to be impossible with `EnsureSync<T, ExpectedReturn>`. The second generic parameter is\n * used to specify the expected return type, which is especially useful if the function should not\n * return anything, so you can enforce a `void` return type.\n */\nexport type NonPromiseLike<T, Expected = unknown> = [T] extends [PromiseLike<unknown>]\n\t? never\n\t: [T] extends [Expected]\n\t\t? // biome-ignore lint/suspicious/noExplicitAny: We're using any here because we care about the type restriction, not the type itself\n\t\t\tExpected\n\t\t: never\n\n/** `EnsureSync<F>` is a type that restricts a function to be synchronous. It is used in in the\n * various `process` function of the VekterEngine to make sure that a function is not async, by\n * restricting its ReturnType to a non-Promise() => unknown type. Optionally the expected return type can be\n * specified, which is especially useful if the function should not return anything, so you can\n * enforce a `void` return type.\n */\nexport type EnsureSync<F extends () => ExpectedReturn, ExpectedReturn = unknown> =\n\tNonPromiseLike<ReturnType<F>, ExpectedReturn> extends never ? never : F\n\n/** Thrown when the user cancels a full document load via the modal Cancel button. */\nexport class FullDocumentLoadCancelledError extends Error {\n\tconstructor() {\n\t\tsuper(\"Full document load was cancelled by user\")\n\t\tthis.name = \"FullDocumentLoadCancelledError\"\n\t}\n}\n\nexport class VekterEngine implements BaseEngine {\n\t// TODO: useful for debugging, remove once GC has been used for a while\n\tstatic #instanceCount = 0\n\treadonly instanceId = ++VekterEngine.#instanceCount\n\treadonly name = \"VekterEngine\"\n\n\treadonly componentLoader = new ComponentLoader()\n\n\t/**\n\t * Call `this.eventListenerAbortController.abort()` to remove all listeners at once.\n\t * Introduced since patching creates a temporal instance of the engine.\n\t */\n\treadonly eventListenerAbortController = new AbortController()\n\n\trunningUnderTest = process.env.NODE_ENV === \"test\"\n\n\t/** used for debugging only */\n\tperf: EnginePerformance | null = null\n\n\t// control and state of tree\n\t// FIXME: the ! is unsafe here: tree will actually be undefined until VekterEngine.prototype.load() is called.\n\t// However, too much code relies on engine.tree being `CanvasTree` and not `CanvasTree | undefined`.\n\t// One way to fix this is to make `tree` a getter that will assert `tree !== undefined`.\n\t// However, it's unclear what the performance impact of this is.\n\ttree!: CanvasTree\n\ttreeReflectsDocument = true // Becomes false when the tree can't be loaded from data\n\thandle: FramePoint | null = null\n\n\t// Document.tsx and engine work together to manage the engine + react life-cycle\n\treactComponent?: {\n\t\tstate: VekterEngineUpdateState\n\t\tsetStateSync: (state: VekterEngineUpdateState) => void\n\t}\n\n\t// tool control\n\ttool: VekterTool\n\n\tfloatingWindowPopoutNavigation?: PopoutNavigation\n\n\tupgradeManager?: DocumentUpgradeManager\n\n\t// tracking lifetime of events\n\tprivate changesLastUpdate: Set<EngineChangeFlag> = new Set()\n\tupdateStartTime = 0\n\tprivate toolStartTime = 0\n\tprivate processStartTime = 0\n\tprivate processEndTime = 0\n\tprivate reactStartTime = 0\n\tprivate paintStartTime = 0\n\n\tdidScopeChange = false\n\n\t/** The main canvas sandbox, only defined if the sandbox is up and running, can go back to\n\t * undefined if the sandbox stops due to some kind of error, or when debugging. */\n\tcanvasSandbox: MainSandboxRenderer | undefined = undefined\n\n\t/** A promise that resolves when the canvas is up and running. */\n\tcanvasSandboxPromise = new ResolvablePromise<MainSandboxRenderer>()\n\n\treadonly scheduler = new VekterEngineScheduler(this)\n\n\t// All stores managed by VekterStores\n\treadonly stores = new EngineStores(this, this.scheduler)\n\n\taddSandbox(sandbox: SandboxRenderer | MainSandboxRenderer) {\n\t\tassert(!this.sandboxes.includes(sandbox), \"Cannot add the same SandboxRenderer more than once\")\n\t\tthis.sandboxes.push(sandbox)\n\t}\n\n\tremoveSandbox(sandbox: SandboxRenderer | MainSandboxRenderer | undefined) {\n\t\tif (!sandbox) return\n\t\tthis.sandboxes = this.sandboxes.filter(s => s !== sandbox)\n\t}\n\n\t/** Signal that a new canvas is being started. */\n\tcanvasSandboxRestart() {\n\t\tthis.removeSandbox(this.canvasSandbox)\n\t\tthis.canvasSandbox = undefined\n\t\tthis.stores.loadingStore.resetCanvasSandboxLoadingState()\n\t\tif (this.canvasSandboxPromise.isResolved()) {\n\t\t\tthis.canvasSandboxPromise = new ResolvablePromise<MainSandboxRenderer>()\n\t\t}\n\t}\n\n\t/** Signal that the canvas is up and running. */\n\tcanvasSandboxStarted(sandbox: MainSandboxRenderer) {\n\t\tthis.removeSandbox(this.canvasSandbox)\n\t\tthis.canvasSandbox = sandbox\n\t\tthis.canvasSandboxPromise.resolve(sandbox)\n\t}\n\n\t/** Signal that the canvas failed and won't be restarted automatically. */\n\tcanvasSandboxFailed(error: Error | string) {\n\t\t// Reflect the failure on the load-state contract so consumers\n\t\t// (`isUserInteractionsDisabled`, `HeadlessAPI.readyFlags.noCanvasFailure`,\n\t\t// awaiters of the load-state) see the controller-level failure cases\n\t\t// (`InstallTimeout`, `ConnectTimeout`, `PermanentHeartbeatTimeout`,\n\t\t// catastrophic IPC errors). `SandboxRenderer.fail` writes the same\n\t\t// field directly via `onSandboxStateChange`; this write covers the\n\t\t// path that goes through the controller instead.\n\t\tthis.stores.loadingStore.canvasSandboxLoadingState = LoadingState.failed(\n\t\t\terror instanceof Error ? error : new Error(error),\n\t\t)\n\t\tthis.removeSandbox(this.canvasSandbox)\n\t\tthis.canvasSandbox = undefined\n\t\t// Make sure future users of the promise get a rejected promise.\n\t\tif (this.canvasSandboxPromise.isResolved()) {\n\t\t\tthis.canvasSandboxPromise = new ResolvablePromise<MainSandboxRenderer>()\n\t\t}\n\t\tthis.canvasSandboxPromise.reject(error)\n\t\tassert(this.canvasSandboxPromise.isResolved(), \"bug\")\n\t}\n\n\tdoSecondarySandboxRenderingIfNeeded = () => {\n\t\t// Don't do secondary rendering while live panning/zooming\n\t\tif (!this.stores.canvasStore.isInteractive) return\n\n\t\t// FIXME: already filter non-document updates here? Secondary renderers should only update with real changes\n\t\tlogScheduler.trace(\"doSecondarySandboxRenderingIfNeeded\", this.scheduler.update)\n\t\tfor (const sandbox of this.sandboxes) {\n\t\t\tif (sandbox === this.canvasSandbox) continue\n\t\t\tsandbox.update(true)\n\t\t}\n\t}\n\n\t/** Secondary (lower priority) sandboxes. */\n\tprivate sandboxes: (SandboxRenderer | MainSandboxRenderer)[] = []\n\n\tgetControlsVisibility() {\n\t\treturn this.canvasSandbox?.sandbox.controlsVisibility\n\t}\n\n\tconstructor() {\n\t\tsetupTreeLibrary(treeLibrary, {\n\t\t\texclude: getOrRegisterDriverBasedOnExperiment().treeLibraryExclude,\n\t\t})\n\t\tthis.updateTreeState()\n\t\tthis.tool = new InitialTool(this)\n\n\t\t// uncomment this line to start with performance tracking enabled\n\t\t// this.installPerformanceDebugging()\n\n\t\tthis.handleUrlSearchParams()\n\n\t\t// TODO: we always had this event listener in engine, but ideally engine should not use DOM APIs\n\t\tdocument.addEventListener(\n\t\t\t\"visibilitychange\",\n\t\t\t() => {\n\t\t\t\t// If the document was visible at the start of a frame, but changes in the middle of a frame, we still want to\n\t\t\t\t// record the frame as hidden.\n\t\t\t\tif (document.hidden) {\n\t\t\t\t\tthis.scheduler.documentHidden = true\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ signal: this.eventListenerAbortController.signal },\n\t\t)\n\t}\n\n\tprivate generateWebPageWithQuery(prompt: string) {\n\t\tconst { chromeStore, insertSidebarStore, aiGenerationStore, documentSettingsStore } = this.stores\n\n\t\tif (!experiments.isOn(\"wireframerKits\")) {\n\t\t\tchromeStore.showInsertSidebar()\n\t\t\tinsertSidebarStore.activeCategoryType = \"wireframer\"\n\t\t} else {\n\t\t\tchromeStore.showAiSidebar()\n\t\t}\n\n\t\tconst controller = new AbortController()\n\n\t\tconst observer = (state: PermissionStateWithIsReady) => {\n\t\t\t// Just to be extra safe we make sure to start only once. Technically not necessary as\n\t\t\t// every observer runs only once and we unregister after we start.\n\t\t\tif (controller.signal.aborted) return\n\t\t\tif (isViewOnly(state, \"canDesign\")) {\n\t\t\t\tif (state.isReady) {\n\t\t\t\t\tengineLog.debug(\"trying to start generateWebPage from query param, but waiting on canDesign\")\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcontroller.abort()\n\t\t\tconst node = this.tree.get(documentSettingsStore.activeNode?.id)\n\t\t\tif (!isWebPageNode(node)) return\n\n\t\t\tthis.scheduler.processWhenReady(() => void aiGenerationStore.generate(this, prompt, \"query_parameters\"))\n\t\t}\n\n\t\tconst dependencies = getPermissionStateWithIsReadyDependencies(this.stores)\n\t\tconst currentState = getPermissionStateWithIsReady(dependencies)\n\t\tobserver(currentState)\n\n\t\tif (controller.signal.aborted) return\n\n\t\tsubscribeToPermissionStateWithIsReadyChanges(this.stores, this.scheduler, observer, {\n\t\t\tsignal: controller.signal,\n\t\t})\n\t}\n\n\tprivate handleUrlSearchParams() {\n\t\tconst {\n\t\t\tdocumentSettingsStore,\n\t\t\tmodalStore,\n\t\t\tinsertSidebarStore,\n\t\t\tpluginStore,\n\t\t\tsiteSettingsStore,\n\t\t\tanalyticsStore,\n\t\t\tcodeEditorStore,\n\t\t\tmodulesStore,\n\t\t\tchromeStore,\n\t\t\tpopoverStore,\n\t\t\tpersistedUserDefaults,\n\t\t} = this.stores\n\t\tconst pageURL = new URL(window.top!.location.href)\n\t\tdocumentSettingsStore.isNewlyCreatedProject =\n\t\t\tpageURL.searchParams.has(\"startScreen\") ||\n\t\t\tpageURL.searchParams.has(\"fromFramer\") ||\n\t\t\tpageURL.searchParams.has(\"fromFigma\")\n\n\t\tif (pageURL.searchParams.has(\"fromFramer\")) {\n\t\t\tpageURL.searchParams.delete(\"fromFramer\")\n\t\t}\n\t\tif (pageURL.searchParams.has(\"fromFigma\")) {\n\t\t\tmodalStore.set({ type: ModalType.ImportFigma, source: \"url_param\" })\n\t\t\tpageURL.searchParams.delete(\"fromFigma\")\n\t\t}\n\n\t\tlet forcedInsertSidebarState: \"show\" | \"hide\" | undefined = undefined\n\n\t\tif (pageURL.searchParams.has(\"kit\")) {\n\t\t\tconst kitModuleId = pageURL.searchParams.get(\"kit\")\n\t\t\tif (kitModuleId) {\n\t\t\t\tmodalStore.set({ type: ModalType.KitRemix, source: \"url_param\" })\n\t\t\t\tforcedInsertSidebarState = \"hide\"\n\t\t\t\tthis.stores.chromeStore.showAiSidebar()\n\t\t\t}\n\t\t\tpageURL.searchParams.delete(\"kit\")\n\t\t} else if (\n\t\t\tpageURL.searchParams.has(\"templates\") &&\n\t\t\texperiments.isOn(\"templatesModal\") &&\n\t\t\t!isMobile() &&\n\t\t\tpersistedUserDefaults.templatesModalOnNewProject\n\t\t) {\n\t\t\tpageURL.searchParams.delete(\"welcome\") // When generating, we never want to show a welcome modal\n\t\t\tif (!experiments.isOn(\"agent\")) {\n\t\t\t\tmodalStore.set({ type: ModalType.Templates, source: \"url_param\" })\n\t\t\t}\n\t\t\tforcedInsertSidebarState = \"hide\"\n\t\t\tpageURL.searchParams.delete(\"templates\")\n\t\t\t// Templates intentionally hides the insert sidebar, so consume this startup intent too.\n\t\t\tpageURL.searchParams.delete(\"insertPanel\")\n\t\t} else if (pageURL.searchParams.has(\"insertPanel\")) {\n\t\t\tforcedInsertSidebarState = \"show\"\n\t\t\tpageURL.searchParams.delete(\"insertPanel\")\n\t\t}\n\n\t\tconst pluginKey = \"plugin\"\n\t\tconst pluginVersionKey = \"pluginVersion\"\n\t\tif (pageURL.searchParams.has(pluginKey)) {\n\t\t\tconst pluginId = pageURL.searchParams.get(pluginKey)\n\t\t\tconst pluginVersion = pageURL.searchParams.get(pluginVersionKey)\n\n\t\t\tif (pluginId && pluginVersion) {\n\t\t\t\tforcedInsertSidebarState = \"hide\"\n\t\t\t}\n\n\t\t\tif (pluginId) {\n\t\t\t\tvoid pluginStore.preparePluginToOpen(this, pluginId, pluginVersion)\n\t\t\t}\n\n\t\t\t// The plugin version is meant for testing new plugin versions by the Framer team. In\n\t\t\t// that case we don't want to delete the plugin URL params so you can refresh your\n\t\t\t// document and still test the same plugin.\n\t\t\tif (!pluginVersion) {\n\t\t\t\tpageURL.searchParams.delete(pluginKey)\n\t\t\t}\n\t\t}\n\n\t\tinsertSidebarStore.determineStateOnLoad(forcedInsertSidebarState)\n\n\t\tif (pageURL.searchParams.has(\"generate\")) {\n\t\t\tconst prompt = pageURL.searchParams.get(\"generate\")\n\t\t\tif (prompt) this.generateWebPageWithQuery(prompt)\n\n\t\t\tpageURL.searchParams.delete(\"generate\")\n\t\t\tpageURL.searchParams.delete(\"welcome\") // When generating, we never want to show a welcome modal\n\t\t\t// Remove the `continue` param that is deprecated, but used for AI\n\t\t\t// launch to jump people into generation after team creation flow.\n\t\t\t// See context here:\n\t\t\t// https://framer-team.slack.com/archives/C04J3AADDHA/p1686568371900399?thread_ts=1686566454.572639&cid=C04J3AADDHA\n\t\t\t// and here: https://github.com/framer/company/issues/27666\n\t\t\tpageURL.searchParams.delete(\"continue\")\n\t\t}\n\n\t\tif (pageURL.searchParams.has(\"ownership-transfer-complete\")) {\n\t\t\tthis.stores.chromeStore.hasCompletedOwnershipTransfer = true\n\t\t\tpageURL.searchParams.delete(\"ownership-transfer-complete\")\n\t\t}\n\n\t\tconst {\n\t\t\tnodeId: activeNodeId,\n\t\t\tlocaleId,\n\t\t\tcodeModuleLocalId,\n\t\t\tcollectionItemInCanvasId,\n\t\t\tsiteSettingsTab,\n\t\t\tanalyticsTab,\n\t\t\ttutorialId,\n\t\t\tmainView,\n\t\t\tfullscreen,\n\t\t\tpublishModal,\n\t\t} = getViewParamsFromURL(pageURL.searchParams)\n\n\t\tif (activeNodeId) {\n\t\t\tconst activeNode: ActiveNode = {\n\t\t\t\tid: activeNodeId,\n\t\t\t\tdeepLinked: true,\n\t\t\t}\n\t\t\tif (localeId) {\n\t\t\t\tactiveNode.localeId = localeId\n\t\t\t}\n\t\t\tif (collectionItemInCanvasId) {\n\t\t\t\t// If we have collectionItemInCanvasId, then activeNodeId must be a WebPageNode\n\t\t\t\t// If it isn't, it means we have a bad URL. That would be fine; it just means\n\t\t\t\t// we'd add an irrelevant entry to the map.\n\t\t\t\tthis.stores.scopeStore.setSelectedCollectionItemForWebPage(activeNodeId, collectionItemInCanvasId)\n\t\t\t}\n\t\t\tdocumentSettingsStore.activeNode = activeNode\n\t\t}\n\n\t\tif (siteSettingsTab) {\n\t\t\tsiteSettingsStore.setActiveTab(siteSettingsTab).catch(unhandledError)\n\t\t}\n\n\t\tif (analyticsTab) {\n\t\t\tanalyticsStore.setActiveTab(analyticsTab).catch(unhandledError)\n\t\t}\n\n\t\tif (codeModuleLocalId) {\n\t\t\tmodulesStore\n\t\t\t\t.whenInitialized()\n\t\t\t\t.then(() => {\n\t\t\t\t\tconst activeModuleEntry = modulesStore.getModuleEntryByLocalId(codeModuleLocalId)\n\t\t\t\t\tif (activeModuleEntry) {\n\t\t\t\t\t\tcodeEditorStore.editFile(activeModuleEntry.name)\n\t\t\t\t\t} else if (employeesOnlySettings.isOn(\"showImportMap\") && isDependenciesFileId(codeModuleLocalId)) {\n\t\t\t\t\t\tcodeEditorStore.editFile(codeModuleLocalId)\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttoast({\n\t\t\t\t\t\t\ttype: \"add\",\n\t\t\t\t\t\t\tvariant: \"error\",\n\t\t\t\t\t\t\tkey: \"invalid-deep-code-link\",\n\t\t\t\t\t\t\tprimaryText: \"Primary code component\",\n\t\t\t\t\t\t\tsecondaryText: \"has been deleted.\",\n\t\t\t\t\t\t\ticon: \"error\",\n\t\t\t\t\t\t\tduration: 10_000,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(unhandledError)\n\t\t}\n\t\tif (tutorialId) {\n\t\t\tchromeStore.isTutorialActive = true\n\t\t}\n\n\t\tif (pageURL.searchParams.has(\"acceptTos\")) {\n\t\t\tmodalStore.set({ type: ModalType.CompleteSignup, source: \"url_param\" })\n\t\t\tpageURL.searchParams.delete(\"acceptTos\")\n\t\t}\n\n\t\tif (mainView === ActiveMainView.Localizations) {\n\t\t\tchromeStore.setLocalizationsVisible(true)\n\t\t}\n\n\t\tif (mainView === ActiveMainView.Preview) {\n\t\t\tthis.stores.previewStore.shouldShowPreviewOnLoad = true\n\t\t\tthis.stores.previewStore.isFullScreen = fullscreen === \"true\"\n\n\t\t\t// Without this, preview wouldn't be rendered in mobile even if the view=preview is set in the URL\n\t\t\tthis.stores.previewStore.forceOverCanvasPreviewRender = true\n\t\t}\n\n\t\tif (publishModal) {\n\t\t\tpopoverStore.active = PopoverType.Publish\n\t\t\tpageURL.searchParams.delete(\"view\")\n\t\t}\n\n\t\t// We need to remove the fromFigma search params since otherwise the\n\t\t// import dialog would start again when the user refreshes the page. Any\n\t\t// other searchParams should be preserved, as should be the history\n\t\t// state object.\n\t\twindow.top!.history.replaceState(window.top!.history.state, \"\", pageURL.href)\n\t}\n\n\tstatic shared(): VekterEngine {\n\t\tif (!_VekterEngine_shared) {\n\t\t\tconst engine = new VekterEngine()\n\t\t\tsetGlobalEngine(engine)\n\t\t\t_VekterEngine_shared = engine\n\t\t\t// The shared engine calls preInit on the modules store, to start loading the modules\n\t\t\t// list from the backend asap, this is just an optimization, done here, so otherwise\n\t\t\t// constructed engines don't do this.\n\t\t\tengine.stores.modulesStore.preInit()\n\t\t}\n\t\treturn _VekterEngine_shared\n\t}\n\n\t// TODO: useful for debugging, remove once GC has been used for a while\n\tdisposed = false\n\n\tdispose() {\n\t\tthis.disposed = true\n\t\tthis.eventListenerAbortController.abort()\n\t\tresetLoadedWasChecked()\n\t}\n\n\t// do a React lifecycle\n\tinDoRendering = false\n\tdoRendering() {\n\t\tif (!this.scheduler.needRendering) return\n\t\tassert(this.scheduler.needReport, \"Engine should need reporting.\")\n\t\tassert(!this.scheduler.inRendering, \"Engine should not be rendering.\")\n\t\tassert(!this.tree.hasUncommittedChanges(), \"Engine.tree should be clean.\")\n\t\tconst firstGroundNode: CanvasNode | null = this.stores.treeStore.visibleGroundNodesInActiveScope[0] ?? null\n\t\tconst firstGroundNodeTree = this.tree.get(firstGroundNode?.id)\n\t\tassert(\n\t\t\tfirstGroundNode === firstGroundNodeTree,\n\t\t\t\"First groundnode out of sync.\",\n\t\t\tfirstGroundNode?.id,\n\t\t\tfirstGroundNodeTree?.id,\n\t\t)\n\n\t\tthis.reactStartTime = performance.now()\n\t\tthis.scheduler.inRendering = true\n\n\t\tif (!this.reactComponent || environment.benchmarkSkipRendering) {\n\t\t\tthis.beginRendering()\n\t\t\tthis.endRendering()\n\t\t\tthis.afterRendering()\n\t\t\treturn\n\t\t}\n\n\t\tperformanceMark(\"rendering\")\n\n\t\tconst update = this.reactComponent.state.update\n\t\tassert(update < this.scheduler.update, \"React component misbehaving: !\", update, \"<\", this.scheduler.update)\n\n\t\t// This will start a full react lifecycle, react will call\n\t\t// beginRendering(), endRendering(). For error recovery, `Document.tsx`\n\t\t// sometimes needs to if react is working because of this call, or some\n\t\t// external event, or startup. That is what inDoRendering is for.\n\t\tthis.inDoRendering = true\n\t\ttry {\n\t\t\tthis.reactComponent.setStateSync({ update: this.scheduler.update })\n\t\t} finally {\n\t\t\tthis.inDoRendering = false\n\t\t}\n\n\t\tperformanceMeasure(\"UIRendering \" + this.scheduler.update, \"rendering\")\n\t\tperformanceClearMarks(\"rendering\")\n\n\t\tthis.afterRendering()\n\t\tlogScheduler.trace(\"doRendering\", this.scheduler.update)\n\t}\n\n\t// called after React has done a full lifecycle, usually from a microtask\n\tafterRendering = () => {\n\t\tassert(this.scheduler.inRendering, \"Engine should be rendering.\")\n\t\tassert(this.scheduler.needRendering, \"Engine should need rendering.\")\n\t\tassert(this.scheduler.needReport, \"Engine should need reporting.\")\n\t\tthis.scheduler.inRendering = false\n\t\tthis.scheduler.needRendering = false\n\n\t\t// Reset load was checked soon after.\n\t\tqueueMicrotask(() => resetLoadedWasChecked())\n\n\t\t// if any tasks were scheduled to run at end of frame, do them now\n\t\tthis.scheduler.runTasksScheduledAtEndOfFrame()\n\n\t\t// at this point, the browser is going to paint, by scheduling a next task, we can measure how long that took\n\t\tthis.paintStartTime = performance.now()\n\n\t\tif (this.isRemountingUI()) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis.resetIsRemountingUI()\n\t\t\t})\n\t\t}\n\t}\n\n\t// called by React via document.tsx render()\n\tbeginRendering() {\n\t\tassert(this.scheduler.inRendering, \"Engine should be rendering.\")\n\t\tassert(this.scheduler.needRendering, \"Engine should need rendering.\")\n\t\tassert(this.scheduler.needReport, \"Engine should need reporting.\")\n\n\t\tif (!this.stores.canvasStore.isInteractive) {\n\t\t\tthis.scheduler.changes.signalObserversFor(EngineChange.CanvasLiveTransform)\n\t\t} else {\n\t\t\tthis.scheduler.changes.signalAllObservers()\n\t\t}\n\t}\n\t// called by React via document.tsx componentDidUpdate()\n\tendRendering() {\n\t\tassert(this.scheduler.inRendering, \"Engine should be rendering.\")\n\t\tassert(this.scheduler.needRendering, \"Engine should need rendering.\")\n\t\tassert(this.scheduler.needReport, \"Engine should need reporting.\")\n\t}\n\n\t/** Tracks every time the document is reloaded. This is used to workaround react holding on to\n\t * old trees via __reactProps$[RANDOM].children.props that potentially contain references to\n\t * older trees. But also event handlers, or callbacks, that are closures that can indirectly\n\t * reference an old tree. Also see https://github.com/facebook/react/issues/31744 */\n\tpublic documentReloadKey = 1\n\tprivate documentReloadKeyAfterRendering = 1\n\n\t/** Check if the current render or effect is happening because the UI is remounting. We remount\n\t * the whole UI after error recovery, or after the document was reloaded from the server. This\n\t * can be used to prevent double tracking statistics, or to suppress animations. */\n\tisRemountingUI() {\n\t\treturn this.documentReloadKey !== this.documentReloadKeyAfterRendering\n\t}\n\n\tprivate resetIsRemountingUI() {\n\t\tthis.documentReloadKeyAfterRendering = this.documentReloadKey\n\t}\n\n\tloadWasCalled = false\n\tload(tree: CanvasTree) {\n\t\tconst { treeStore, scopeStore, historyStore, documentSettingsStore, modulesStore, chromeStore, localizationStore } =\n\t\t\tthis.stores\n\t\tassert(tree.isLatest(), \"loaded tree must be latest\")\n\t\tassert(!tree.hasUncommittedChanges(), \"loaded tree must not have any edits already\")\n\t\tengineLog.debug(\"engine.load: tree.size:\", tree.size(), \"first time:\", !this.loadWasCalled)\n\n\t\tif (this.loadWasCalled) {\n\t\t\tthis.documentReloadKey += 1\n\t\t}\n\n\t\tthis.loadWasCalled = true\n\t\tthis.scheduler.canvasSandboxRenderingPhase = Dictionary.Unknown\n\t\tthis.tree = tree\n\t\ttreeStore.setTree(tree)\n\n\t\t// When loading historic documents using the history panel, we don't want to switch scopes\n\t\t// unless we have to.\n\t\tconst activeScopeFromHistory = tree.get(historyStore.activeScopeIdToPreserveOnLoad)\n\t\thistoryStore.activeScopeIdToPreserveOnLoad = null\n\n\t\tif (activeScopeFromHistory && isScopeNode(activeScopeFromHistory) && activeScopeFromHistory.isLoaded()) {\n\t\t\tscopeStore.resetActiveScope(tree, activeScopeFromHistory.id)\n\t\t} else {\n\t\t\tconst activeNode = documentSettingsStore.activeNode\n\t\t\tscopeStore.resetActiveScope(tree, activeNode?.id)\n\t\t\tif (activeNode?.localeId) {\n\t\t\t\tchromeStore.setLocalizationsVisible(true)\n\t\t\t\tlocalizationStore.selectedLocaleId = activeNode.localeId\n\t\t\t}\n\t\t}\n\n\t\tthis.updateTreeState()\n\t\tthis.didLoad()\n\t\tmodulesStore.initialize().catch(engineLog.error)\n\t}\n\n\tget activeBranchId(): string {\n\t\tconst committer = this.stores.treeStore.timeline\n\t\tif (!isCrdtTreeCommitter(committer)) return MAIN_BRANCH_ID\n\t\treturn committer.branches.activeBranchId\n\t}\n\n\tprivate get crdtTimeline(): CrdtTreeCommitter {\n\t\treturn this.stores.treeStore.crdtTimeline\n\t}\n\n\tswitchActiveBranch(branchId: string): void {\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tconst committer = this.crdtTimeline\n\t\t\tif (branchId === this.activeBranchId) return\n\n\t\t\tthis.processTreeChanges()\n\n\t\t\tconst fromBranchId = this.activeBranchId\n\t\t\tthis.stores.undoRedoManager.addUndoEntry({\n\t\t\t\tkind: \"branchSwitch\",\n\t\t\t\tchanges: [],\n\t\t\t\tfromBranchId,\n\t\t\t\ttoBranchId: branchId,\n\t\t\t\tselection: this.stores.selectionStore.ids,\n\t\t\t\tscopeId: this.stores.scopeStore.active.id,\n\t\t\t\tlocaleId: this.getLocaleIdForUndoRedoEntry(),\n\t\t\t})\n\t\t\tthis.switchVisibleBranch(committer, branchId)\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tprivate syncBranchViewOnlyState(): void {\n\t\tconst branchId = this.activeBranchId\n\t\tconst isViewing = branchId !== MAIN_BRANCH_ID && !this.isUserBranchContributor(branchId)\n\t\tthis.stores.chromeStore.isViewingBranchFromOtherUser = isViewing\n\t\tthis.tree.isViewOnly = getIsViewOnly(this, \"canSendDiffs\")\n\t}\n\n\tprivate isUserBranchContributor(branchId: string): boolean {\n\t\tconst branchNode = this.tree.get<BranchNode>(branchId)\n\t\tif (!branchNode) return true\n\t\treturn isBranchContributor(branchNode, this.stores.sessionStore.user.id)\n\t}\n\n\tjoinBranchAsContributor(): void {\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tconst currentState = getPermissionStateWithIsReady(getPermissionStateWithIsReadyDependencies(this.stores))\n\t\t\tconst stateAsContributor = { ...currentState, isViewingBranchFromOtherUser: false }\n\t\t\t// Simulate the user is a contributor and check if it's view-only with the rest of the permissions\n\t\t\tif (isViewOnly(stateAsContributor, \"canSendDiffs\")) return\n\n\t\t\tthis.processTreeChanges()\n\t\t\tconst committer = this.stores.treeStore.timeline\n\t\t\tassert(isCrdtTreeCommitter(committer), \"Joining a branch requires a CRDT timeline\")\n\t\t\tconst userId = this.stores.sessionStore.user.id\n\t\t\tthis.stores.chromeStore.isViewingBranchFromOtherUser = false\n\t\t\tthis.tree.isViewOnly = false\n\t\t\tcommitter.addBranchContributor(this.activeBranchId, userId)\n\t\t\tthis.remoteDocument?.afterCommit(committer.tree)\n\t\t\tthis.processTreeHasChanged(committer.tree)\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tcreateBranchAndSwitch(branchId: string = randomBranchID(), sourceBranchId?: string, createdByUserId?: string): void {\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tthis.processTreeChanges()\n\n\t\t\tconst committer = this.crdtTimeline\n\n\t\t\tthis.assertCanSwitchVisibleBranch()\n\n\t\t\tconst branchOwnerId = createdByUserId ?? this.stores.sessionStore.user.id\n\t\t\tcommitter.createBranch(branchId, branchOwnerId, sourceBranchId)\n\t\t\tthis.remoteDocument?.afterCommit(committer.tree)\n\t\t\tconst fromBranchId = this.activeBranchId\n\t\t\tthis.stores.undoRedoManager.addUndoEntry({\n\t\t\t\tkind: \"branchSwitch\",\n\t\t\t\tchanges: [],\n\t\t\t\tfromBranchId,\n\t\t\t\ttoBranchId: branchId,\n\t\t\t\tselection: this.stores.selectionStore.ids,\n\t\t\t\tscopeId: this.stores.scopeStore.active.id,\n\t\t\t\tlocaleId: this.getLocaleIdForUndoRedoEntry(),\n\t\t\t})\n\t\t\t// We don't install committer.tree as the new tree, because we immediately switch to the\n\t\t\t// new branch, which reloads the tree anyway.\n\t\t\tthis.switchVisibleBranch(committer, branchId)\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tcreateBranchFromBaseAndSwitch(baseBranchId: string): void {\n\t\tthis.createBranchAndSwitch(undefined, baseBranchId)\n\t}\n\n\tdeleteBranch(branchId: string): void {\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tif (!this.isUserBranchContributor(branchId)) return\n\n\t\t\tthis.processTreeChanges()\n\n\t\t\tconst committer = this.crdtTimeline\n\n\t\t\tcommitter.deleteBranch(branchId)\n\t\t\tthis.remoteDocument?.afterCommit(committer.tree)\n\t\t\tif (branchId === this.activeBranchId) {\n\t\t\t\tconst baseId = committer.tree.get<BranchNode>(branchId)?.baseId ?? MAIN_BRANCH_ID\n\t\t\t\tthis.switchVisibleBranch(committer, baseId)\n\t\t\t} else {\n\t\t\t\tthis.processTreeHasChanged(committer.tree)\n\t\t\t}\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tmergeBranchToBase(branchId?: string): void {\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tconst targetBranchId = branchId ?? this.activeBranchId\n\t\t\tif (!this.isUserBranchContributor(targetBranchId)) return\n\n\t\t\tconst targetBranchNode = this.tree.get<BranchNode>(targetBranchId)\n\t\t\tconst baseBranchId = targetBranchNode?.baseId\n\t\t\tif (baseBranchId && baseBranchId !== MAIN_BRANCH_ID && !this.isUserBranchContributor(baseBranchId)) return\n\n\t\t\tthis.processTreeChanges()\n\n\t\t\tconst committer = this.crdtTimeline\n\n\t\t\tthis.assertCanSwitchVisibleBranch()\n\n\t\t\tconst baseId = committer.mergeBranchToBase(branchId)\n\t\t\tthis.remoteDocument?.afterCommit(committer.tree)\n\t\t\t// We don't install committer.tree as the new tree, because we immediately switch to the\n\t\t\t// new branch, which reloads the tree anyway.\n\t\t\tthis.switchVisibleBranch(committer, baseId)\n\t\t\tthis.stores.undoRedoManager.clearUndoStack()\n\t\t}, \"nonUserEvent\")\n\t}\n\n\trenameBranch(branchId: string, name: string): void {\n\t\tconst trimmed = name.trim()\n\t\tif (!trimmed) return\n\n\t\tthis.scheduler.processWhenReady(() => {\n\t\t\tif (!this.isUserBranchContributor(branchId)) return\n\n\t\t\tthis.processTreeChanges()\n\n\t\t\tconst committer = this.crdtTimeline\n\n\t\t\tconst updatedTree = committer.renameBranch(branchId, trimmed)\n\t\t\tthis.remoteDocument?.afterCommit(updatedTree)\n\t\t\tthis.recordTreeChange(updatedTree)\n\t\t}, \"nonUserEvent\")\n\t}\n\n\tprivate assertCanSwitchVisibleBranch(): void {\n\t\t// Readonly mode is used for history and error states, we're not expected to be switching\n\t\t// branches in these states. Note that this is different from a read-only tree, which keeps\n\t\t// the modules in the read-write mode, and check specifically for the tree being read-only.\n\t\t//\n\t\t// Not allowing branch switching in read-only mode is mostly to reduce complexity, it means\n\t\t// we don't need to worry about readonly <=> readwrite / readwrite-detached transitions, see\n\t\t// resetModuleStateAndPermissions in switchVisibleBranch.\n\t\tassert(!this.stores.modulesStore.isReadOnly(), \"Cannot switch branches while modules store is read only\")\n\t}\n\n\tprivate switchVisibleBranch(committer: CrdtTreeCommitter, branchId: string): void {\n\t\tconst { loadingStore, treeStore } = this.stores\n\t\tthis.assertCanSwitchVisibleBranch()\n\t\tconst mainStore = committer.branches.getStore(MAIN_BRANCH_ID)\n\t\tassert(\n\t\t\tbranchId === MAIN_BRANCH_ID || !mainStore.getObjectKey<number>(branchId, BRANCH_DELETED_AT_KEY),\n\t\t\t\"Cannot switch to deleted branch\",\n\t\t\tbranchId,\n\t\t)\n\n\t\tconst remoteDocument = this.remoteDocument\n\t\tassert(remoteDocument instanceof RemoteDocument, \"Branch switching requires a remote document\")\n\t\tconst treeDataHandler = remoteDocument.treeDataHandler\n\t\tassert(treeDataHandler instanceof CrdtRemoteDocumentDataHandler, \"Branch switching requires a CRDT remote document\")\n\n\t\ttreeDataHandler.cancelAndClearLoader()\n\n\t\tconst store = committer.switchActiveBranch(branchId)\n\t\tconst loader = new CrdtDocumentLoader(\n\t\t\tstore,\n\t\t\tremoteDocument.projectId,\n\t\t\tthis.componentLoader,\n\t\t\ttreeDataHandler.treeVersion,\n\t\t\t\"\",\n\t\t\t{\n\t\t\t\tactiveNodeId: this.stores.scopeStore.active.id,\n\t\t\t\tpartialParsing: true,\n\t\t\t\tloadInBackground: true,\n\t\t\t\ttreeServices: {\n\t\t\t\t\tupgradeManager: this.upgradeManager,\n\t\t\t\t\teditHooks: this.scheduler,\n\t\t\t\t},\n\t\t\t\tasyncEventWrapper: remoteDocument.processBetweenFramesAsync,\n\t\t\t\trequestIdleCallback: remoteDocument.requestIdleCallback,\n\t\t\t},\n\t\t)\n\t\ttreeDataHandler.loader = loader\n\t\tloader.on(\"loadedScope\", scope => {\n\t\t\tif (loader !== treeDataHandler.loader) return\n\t\t\ttreeDataHandler.loadOneScope(scope, false)\n\t\t\tthis.newTreeAfterRemoteUpdate(committer.tree)\n\t\t})\n\t\tloader.on(\"loadedAllData\", () => {\n\t\t\tif (loader !== treeDataHandler.loader) return\n\t\t\ttreeDataHandler.loadedAllScopes()\n\t\t\ttreeDataHandler.finishLoading()\n\t\t\tloadingStore.busyLoadingFullData = false\n\t\t\tthis.newTreeAfterRemoteUpdate(committer.tree)\n\t\t})\n\t\tloader.on(\"error\", error => {\n\t\t\tif (loader !== treeDataHandler.loader) return\n\t\t\tloadingStore.hasError = true\n\t\t\tremoteDocument.onError(treeDataHandler.error(error.message, error))\n\t\t})\n\n\t\tconst tree = loader.startFromStore()\n\t\tloadingStore.busyLoadingFullData = true\n\n\t\ttreeStore.setTree(tree, { isBranchSwitch: true })\n\t\tthis.resetModulesStateForBranch(branchId)\n\t\tthis.newTreeAfterRemoteUpdate(tree)\n\t}\n\n\tprivate resetModulesStateForBranch(branchId: string): void {\n\t\tconst { modulesStore } = this.stores\n\t\tmodulesStore.resetModuleStateAndPermissions(branchId === MAIN_BRANCH_ID ? \"readwrite\" : \"readwrite-detached\")\n\t}\n\n\t// TODO callers are responsible for proper use of handlers, this becomes untestable and has unexpected effects\n\tdidLoad = this.scheduler.wrapHandler(() => {\n\t\tconst {\n\t\t\tloadingStore,\n\t\t\tpreviewStore,\n\t\t\tchromeStore,\n\t\t\twebFontStore,\n\t\t\tfeedbackStore,\n\t\t\tpropertiesPanelStore,\n\t\t\tpublishStore,\n\t\t\tpluginStore,\n\t\t\thistoryStore,\n\t\t\tcodeGenerationStore,\n\t\t\tinsertSidebarStore,\n\t\t\tshaderFallbackImageStore,\n\t\t} = this.stores\n\n\t\tloadingStore.documentLoaded = true\n\t\tloadingStore.busyLoadingFirstData = false\n\t\tpreviewStore.shouldStartPreloading = false\n\n\t\tthis.scheduler.changes.addChanges(EngineChange.Tree)\n\t\tthis.scheduler.changes.addChanges(EngineChange.ColorStyleTokens)\n\t\tthis.scheduler.changes.addChanges(EngineChange.TextStylePresets)\n\t\tcodeGenerationStore.documentDidLoad()\n\t\tfeedbackStore.documentDidLoad(this)\n\t\tchromeStore.documentDidLoad()\n\t\tpropertiesPanelStore.documentDidLoad(this)\n\t\tpublishStore.documentDidLoad()\n\t\tinsertSidebarStore.loadIfNeeded()\n\t\tpluginStore.documentDidLoad()\n\t\tshaderFallbackImageStore.documentDidLoad()\n\t\thistoryStore.loadFinish()\n\n\t\tif (previewStore.shouldShowPreviewOnLoad) {\n\t\t\tpreviewStore.shouldShowPreviewOnLoad = false\n\t\t\ttogglePreviewVisible(this, {\n\t\t\t\tvisible: true,\n\t\t\t\tfullscreen: previewStore.isFullScreen,\n\t\t\t})\n\t\t}\n\n\t\t// Reset package token cache to release memory. Otherwise the cache will retain references\n\t\t// to the old tree. Which can be a huge amount of memory.\n\t\tresetTokenPackagesCache()\n\n\t\t// TODO remove; engine cannot be responsible for integrations into DOM and/or IPC etc.\n\t\tgetIpcRenderer().send(ipc.DocumentLoaded)\n\t\tvoid Promise.all([webFontStore.importFonts(), webFontStore.loadFontsFromTree()]).finally(() =>\n\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\tloadingStore.webFontsLoaded = true\n\t\t\t\tmarkLoadingPerf(\"fontsLoad\")\n\t\t\t}, \"nonUserEvent\"),\n\t\t)\n\t\tassert(!this.tree.hasUncommittedChanges(), \"after loading, the tree should have any edits\")\n\t}, \"nonUserEvent\")\n\n\tdidLoadCompleteDocument = () => {\n\t\tconst { loadingStore } = this.stores\n\t\tloadingStore.busyLoadingFullData = false\n\t\tthis.upgradeManager?.documentLoaded()\n\t}\n\n\tprivate onInitialLoad(startLoadingTime: number) {\n\t\tloadDocumentMetrics.trackNormalLoad({\n\t\t\tstartLoadingTime,\n\t\t\ttreeSize: this.tree.size(),\n\t\t})\n\t\tthis.stores.scopeStore.documentDidLoad()\n\t\tthis.stores.canvasStore.zoomToActiveNode()\n\t}\n\n\tcurrentToolName(): string {\n\t\tif ((this.tool as any).pathTool) {\n\t\t\treturn (this.tool as any).pathTool.__class\n\t\t}\n\t\treturn this.tool.__class\n\t}\n\n\t/** Returns true if the document is fully loaded, the user is allowed to edit, and we have a\n\t * good network connection to the backend. */\n\tisDocumentEditable(): boolean {\n\t\treturn this.isDocumentReady() && !this.stores.chromeStore.isViewOnly\n\t}\n\n\t/** Returns true if the document is fully loaded and the user permissions have loaded. */\n\tisDocumentReady(): boolean {\n\t\tif (!this.stores.loadingStore.isReady) return false\n\t\tif (!this.stores.chromeStore.hasReceivedUserPermissions) return false\n\t\treturn true\n\t}\n\n\tassertStateMutable() {\n\t\tassert(this.scheduler.inEventHandling > 0, \"Must be in event handling.\")\n\t}\n\n\tassertReactRendering() {\n\t\tif (!this.reactComponent) return\n\t\tconst isRendering = this.scheduler.inRendering\n\t\tassert(isRendering, \"Must be in react rendering.\")\n\t}\n\n\treadonly testing = new EngineTesting(this)\n\n\tprivate previousCachedTree: CanvasTree | null = null\n\tprivate previousCachedScopeId: NodeID | null = null\n\tprivate previousActiveOverlays: ReadonlySet<NodeID> | undefined\n\tprivate previousActiveLocaleId: LocaleId | undefined\n\tprivate previousEffectPreviewState: EffectPreviewState | undefined\n\tprivate updateTreeState() {\n\t\tconst { treeStore, scopeStore, chromeStore, layoutCache, effectStore, overlayStore } = this.stores\n\t\tassert(\n\t\t\t!this.tree || !this.tree.hasUncommittedChanges(),\n\t\t\t\"Tree must not exist or it must not have uncommitted changes\",\n\t\t)\n\t\tthis.previousTree = this.tree\n\t\tthis.tree = treeStore.tree\n\t\tthis.tree.editClosed = true\n\n\t\tassert(!this.tree.hasUncommittedChanges(), \"Tree must not have uncommitted changes\")\n\t\tassert(this.tree.inEditor, \"tree must be marked as being inEditor\")\n\n\t\t// Update the cache if we need to.\n\t\tconst activeId = scopeStore.active.id\n\t\tconst scopeChanged = this.previousCachedScopeId !== activeId\n\t\tconst activeOverlaysChanged = this.previousActiveOverlays !== overlayStore.activeOverlays\n\t\tconst activeLocaleChanged = this.previousActiveLocaleId !== chromeStore.canvasLocaleId\n\t\tconst effectPreviewState = effectStore.getState()\n\t\tconst effectPreviewStateChanged = !isEqual(this.previousEffectPreviewState, effectPreviewState)\n\t\tif (\n\t\t\tthis.previousCachedTree !== this.tree ||\n\t\t\tscopeChanged ||\n\t\t\tactiveOverlaysChanged ||\n\t\t\tactiveLocaleChanged ||\n\t\t\teffectPreviewStateChanged\n\t\t) {\n\t\t\tthis.previousCachedTree = this.tree\n\t\t\tthis.previousCachedScopeId = activeId\n\t\t\tthis.previousActiveOverlays = overlayStore.activeOverlays\n\t\t\tthis.previousActiveLocaleId = chromeStore.canvasLocaleId\n\t\t\tthis.previousEffectPreviewState = effectPreviewState\n\n\t\t\tif (scopeChanged) {\n\t\t\t\tthis.scheduler.canvasSandboxRenderingPhase = Dictionary.Unknown\n\t\t\t\tthis.didScopeChange = true\n\t\t\t}\n\t\t\tengineLog.trace(\"update tree cache:\", activeId)\n\n\t\t\tupdateTreeCacheForVekter(\n\t\t\t\tthis.tree,\n\t\t\t\tlayoutCache,\n\t\t\t\ttreeStore.sandboxRepeaterData,\n\t\t\t\ttreeStore.sandboxVisibility,\n\t\t\t\tthis.componentLoader,\n\t\t\t\tthis.componentLoader.activeBundleHash,\n\t\t\t\tchromeStore.canvasLocaleId,\n\t\t\t\teffectPreviewState,\n\t\t\t\tactiveId,\n\t\t\t)\n\t\t}\n\t}\n\n\tcanvasSandboxDidRender(update: RenderedUpdate) {\n\t\tthis.scheduler.canvasSandboxDidRender(update)\n\t}\n\n\t/** Clears the tree cache in engine and sandbox. */\n\tdebugClearCache() {\n\t\tthis.previousCachedTree = null\n\t\tthis.tree.resetDraftNodesAndCache()\n\t\tthis.canvasSandbox?.command?.(\"clearCache\", undefined)\n\t}\n\n\tprivate updateToolState() {\n\t\tthis.handle = this.stores.toolStore.handle\n\t\tthis.stores.feedbackStore.setFeedbackModeActive(this.stores.toolStore.feedbackModeActive)\n\t}\n\n\tprivate loadingFullDocumentModalsCount = 0\n\n\tprivate maybeOpenLoadingFullDocumentModal(props: LoadingFullDocumentModalProps) {\n\t\tif (this.loadingFullDocumentModalsCount === 0) {\n\t\t\tthis.stores.modalStore.push({\n\t\t\t\ttype: ModalType.LoadingFullDocument,\n\t\t\t\tsource: \"automatic\",\n\t\t\t\t...props,\n\t\t\t})\n\t\t}\n\t\tthis.loadingFullDocumentModalsCount++\n\t}\n\n\tprivate maybeCloseLoadingFullDocumentModal() {\n\t\tthis.loadingFullDocumentModalsCount = Math.max(0, this.loadingFullDocumentModalsCount - 1)\n\t\tif (this.loadingFullDocumentModalsCount === 0) {\n\t\t\tthis.stores.modalStore.dismissModal(ModalType.LoadingFullDocument)\n\t\t}\n\t}\n\n\t/**\n\t * Loads the full document, blocking work, without being visible to the user. Use the `signal`\n\t * to abort the full document load.\n\t */\n\tasync prioritizedFullDocumentLoad({\n\t\toperationName,\n\t\tsignal,\n\t}: {\n\t\toperationName: string\n\t\tsignal: AbortSignal\n\t}): Promise<void> {\n\t\tconst loader = this.tree.getService(\"loader\")\n\t\tif (!loader) return\n\n\t\tconst shallowScopesToLoad = loader.numberOfScopesToLoad()\n\t\tif (!shallowScopesToLoad) return\n\n\t\tconst cancel = loader.prioritizeLoadingAllData({ operationInBackground: true, operationName })\n\n\t\tsignal.addEventListener(\"abort\", cancel, { once: true })\n\n\t\tawait loader.afterAllDataLoaded()\n\n\t\tsignal.removeEventListener(\"abort\", cancel)\n\t}\n\n\t/**\n\t * Ensures all document scopes are loaded, then runs the task.\n\t * Shows a progress modal unless `runInBackground` is set.\n\t *\n\t * @param task - Synchronous callback to run after loading completes.\n\t * @param options - Configuration for the loading operation.\n\t * @returns Cleanup function to cancel the operation.\n\t *\n\t * @example\n\t * ```ts\n\t * engine.runWithFullyLoadedTree(\n\t *   () => { performTreeEdit() },\n\t *   { name: \"my_operation\" }\n\t * )\n\t * ```\n\t */\n\trunWithFullyLoadedTree(\n\t\ttask: EnsureSync<VoidFunction>,\n\t\toptions: RunWithFullyLoadedTreeOptions,\n\t\tonCancelledByUser?: () => void,\n\t): VoidFunction {\n\t\tconst loader = this.tree.getService(\"loader\")\n\t\tengineLog.info(\"fullTreeOperation: scheduling\", options.name, \"; loader:\", !!loader)\n\t\tconst taskWrappedWithLogs = () => {\n\t\t\tengineLog.info(\"fullTreeOperation: start\", options.name, \"background\")\n\t\t\ttask()\n\t\t\tengineLog.info(\"fullTreeOperation: end\", options.name)\n\t\t}\n\n\t\tlet taskWrappedWithScheduling: VoidFunction | undefined\n\t\tif (options.runInBackground) {\n\t\t\ttaskWrappedWithScheduling = () => {\n\t\t\t\tthis.scheduler.scheduleDocumentUpdateIgnoringUndo(taskWrappedWithLogs)\n\t\t\t}\n\t\t} else if (loader || this.scheduler.inEventHandling <= 0) {\n\t\t\ttaskWrappedWithScheduling = () => {\n\t\t\t\tthis.scheduler.processWhenReady(taskWrappedWithLogs)\n\t\t\t}\n\t\t} else {\n\t\t\ttaskWrappedWithScheduling = taskWrappedWithLogs\n\t\t}\n\n\t\tif (!loader) {\n\t\t\ttaskWrappedWithScheduling()\n\t\t\treturn noop\n\t\t}\n\n\t\tconst unsubs: VoidFunction[] = []\n\t\tlet cancelledOrDone = false\n\t\tlet debugDelayTimeout: ReturnType<typeof setTimeout> | undefined\n\n\t\t// If not in the background, open the modal. The dialog itself will delay showing, and will\n\t\t// be on screen for at least a minimum amount of time. Then will dismiss itself.\n\t\tconst cleanup = () => {\n\t\t\tcancelledOrDone = true\n\t\t\tif (debugDelayTimeout) clearTimeout(debugDelayTimeout)\n\t\t\tunsubs.forEach(unsub => unsub())\n\t\t\tunsubs.length = 0\n\t\t}\n\n\t\tif (!options.runInBackground) {\n\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\tif (cancelledOrDone) return\n\t\t\t\tthis.maybeOpenLoadingFullDocumentModal({\n\t\t\t\t\ttitle: options.modalTitle,\n\t\t\t\t\tdescription: options.modalDescription,\n\t\t\t\t\tincludeLocalizationState: options.modalIncludeLocalizationState,\n\t\t\t\t\tonCancel: options.cancellable\n\t\t\t\t\t\t? () => {\n\t\t\t\t\t\t\t\tcleanup()\n\t\t\t\t\t\t\t\tonCancelledByUser?.()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t})\n\t\t\t}, \"nonUserEvent\")\n\t\t\tunsubs.push(() => this.maybeCloseLoadingFullDocumentModal())\n\t\t}\n\n\t\tconst startTime = performance.now()\n\n\t\tunsubs.push(\n\t\t\tloader.prioritizeLoadingAllData({\n\t\t\t\toperationName: options.name,\n\t\t\t\toperationInBackground: Boolean(options.runInBackground),\n\t\t\t\tdoNotTrack: options.doNotTrack,\n\t\t\t}),\n\t\t\tloader.afterAllDataLoaded(() => {\n\t\t\t\tconst runTaskAndCleanup = () => {\n\t\t\t\t\ttaskWrappedWithScheduling()\n\t\t\t\t\tcleanup()\n\t\t\t\t}\n\n\t\t\t\t// Default 2s delay in dev when modal is shown, so developers notice it\n\t\t\t\tconst defaultDevDelay = !options.runInBackground ? 2000 : 0\n\t\t\t\tconst debugDelay = options.debugMinProgressModalTime ?? defaultDevDelay\n\t\t\t\tif (debugDelay && environment.isDebugBuild) {\n\t\t\t\t\tconst elapsed = performance.now() - startTime\n\t\t\t\t\tconst remaining = debugDelay - elapsed\n\t\t\t\t\tif (remaining > 0) {\n\t\t\t\t\t\tdebugDelayTimeout = setTimeout(runTaskAndCleanup, remaining)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\trunTaskAndCleanup()\n\t\t\t}),\n\t\t)\n\n\t\treturn cleanup\n\t}\n\n\t/**\n\t * Promise-based version of runWithFullyLoadedTree.\n\t *\n\t * @example Just await loading (shows modal):\n\t * ```ts\n\t * await engine.runWithFullyLoadedTreeAsync({ name: \"my_operation\" })\n\t * ```\n\t *\n\t * @example With callback:\n\t * ```ts\n\t * const result = await engine.runWithFullyLoadedTreeAsync(\n\t *   () => computeSomething(),\n\t *   { name: \"my_operation\" }\n\t * )\n\t * ```\n\t *\n\t * @example Background (no modal):\n\t * ```ts\n\t * await engine.runWithFullyLoadedTreeAsync({ name: \"op\", runInBackground: true })\n\t * ```\n\t *\n\t * @example Debug with minimum modal time (dev only):\n\t * ```ts\n\t * await engine.runWithFullyLoadedTreeAsync({ name: \"op\", debugMinProgressModalTime: 5000 })\n\t * ```\n\t */\n\trunWithFullyLoadedTreeAsync(options: RunWithFullyLoadedTreeOptions): Promise<void>\n\trunWithFullyLoadedTreeAsync<T>(fn: EnsureSync<() => T>, options: RunWithFullyLoadedTreeOptions): Promise<T>\n\trunWithFullyLoadedTreeAsync<T>(\n\t\tfnOrOptions: EnsureSync<() => T> | RunWithFullyLoadedTreeOptions,\n\t\tmaybeOptions?: RunWithFullyLoadedTreeOptions,\n\t) {\n\t\tif (typeof fnOrOptions === \"function\") {\n\t\t\tassert(maybeOptions, \"options required when callback provided\")\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tthis.runWithFullyLoadedTree(\n\t\t\t\t\t() => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresolve(fnOrOptions())\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\treject(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tmaybeOptions,\n\t\t\t\t\tmaybeOptions.cancellable ? () => reject(new FullDocumentLoadCancelledError()) : undefined,\n\t\t\t\t)\n\t\t\t})\n\t\t}\n\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tthis.runWithFullyLoadedTree(\n\t\t\t\t() => resolve(),\n\t\t\t\tfnOrOptions,\n\t\t\t\tfnOrOptions.cancellable ? () => reject(new FullDocumentLoadCancelledError()) : undefined,\n\t\t\t)\n\t\t})\n\t}\n\n\tprivate lastSeenLog?: any\n\n\tdoReport(calledByTimer = false, atomicFrame = false) {\n\t\tconst { debugStore, loadingStore, selectionStore, mouseStore } = this.stores\n\t\tthis.scheduler.engineIsIdlePromise?.resolve()\n\t\tthis.scheduler.engineIsIdlePromise = undefined\n\n\t\tif (!this.scheduler.needReport) return\n\t\tthis.scheduler.needReport = false\n\n\t\t// Keep track of frames that are not back-to-back event processing.\n\t\tif (calledByTimer) {\n\t\t\tthis.scheduler.lastIdleUpdate = this.scheduler.update\n\t\t}\n\n\t\t// Report to dev tools performance tab.\n\t\ttry {\n\t\t\tperformanceMeasure(\"Update \" + this.scheduler.update, \"frame\")\n\t\t\tperformanceClearMarks(\"frame\")\n\t\t} catch {\n\t\t\t// nothing\n\t\t}\n\n\t\t// We have to regularly empty all measurements or they keep on accumulating in\n\t\t// performance.getEntries().\n\t\tperformanceClearMeasures()\n\n\t\t// Collect frame information for the debug store, which might send it to a tracking server.\n\t\tconst now = performance.now()\n\t\tthis.scheduler.lastUpdateEndTime = now\n\n\t\t// Check if the user has not been editing for a minute\n\t\tconst userIdle = this.scheduler.lastUserEdit > 0 && now - this.scheduler.lastUserEdit > 60 * 1000\n\n\t\tconst remoteDocument = this.remoteDocument?.getAndResetTotalTime() ?? 0\n\t\tconst sandbox = this.scheduler.getAndResetSandboxTimes()\n\n\t\t// Compute the times of the various tasks.\n\t\tconst totalTime = now - this.updateStartTime\n\n\t\t// Times that are older than this.updateStartTime indicate these tasks\n\t\t// didn't run this frame, and timings from a previous frame.\n\n\t\tlet eventProcessing = 0\n\t\tif (this.toolStartTime > this.updateStartTime) {\n\t\t\teventProcessing = this.toolStartTime - this.updateStartTime\n\t\t\t// Subtract remote document processing, as that is always running in event processing time.\n\t\t\teventProcessing = Math.max(0, eventProcessing - remoteDocument)\n\t\t}\n\n\t\tlet toolUpdate = 0\n\t\tif (this.processStartTime > this.updateStartTime) {\n\t\t\ttoolUpdate = this.processStartTime - this.toolStartTime\n\t\t} else {\n\t\t\ttoolUpdate = now - this.toolStartTime\n\t\t}\n\n\t\tlet postProcessing = 0\n\t\tif (this.processEndTime > this.updateStartTime) {\n\t\t\tpostProcessing = this.processEndTime - this.processStartTime\n\t\t}\n\n\t\tlet reactUpdate = 0\n\t\tlet browserPaint = 0\n\t\tif (this.paintStartTime > this.updateStartTime) {\n\t\t\treactUpdate = this.paintStartTime - this.reactStartTime\n\t\t\tbrowserPaint = now - this.paintStartTime\n\t\t}\n\n\t\tconst replayBuffer = getLogReplayBuffer()\n\t\tconst last = replayBuffer.indexOf(this.lastSeenLog)\n\t\tconst logs = replayBuffer.slice(last + 1).map(entry => entry.toString())\n\t\tthis.lastSeenLog = replayBuffer[replayBuffer.length - 1]\n\n\t\tconst stats = this.remoteDocument?.socket?.getSocketStats()?.read()\n\t\tconst [bytesSent, bytesReceived, rtt, socketId] = stats ?? [0, 0, 0, 0]\n\n\t\tconst mainMemory = (performance as any)?.memory?.usedJSHeapSize\n\n\t\tconst frame: FrameStats = {\n\t\t\ttimestamp: performance.now(),\n\t\t\tisInitialLoad:\n\t\t\t\t!loadingStore.documentLoaded ||\n\t\t\t\t!loadingStore.assetMapLoaded ||\n\t\t\t\t!loadingStore.canvasSandboxResourcesLoadingState.isFinished,\n\n\t\t\tupdate: this.scheduler.update,\n\t\t\tupdateStartTime: this.updateStartTime,\n\t\t\ttoolName: this.currentToolName(),\n\n\t\t\tdidScopeChange: this.didScopeChange,\n\t\t\tdidLoadScript: this.changesLastUpdate.has(EngineChange.ActiveBundle),\n\t\t\tdidZoom: this.changesLastUpdate.has(EngineChange.CanvasZoom),\n\t\t\tdocumentWasHidden: this.scheduler.documentHidden,\n\t\t\tdocumentWasFocused: document.hasFocus(),\n\t\t\tuserIdle,\n\t\t\tmouseDown: !!mouseStore.latest.canvasMouseDownPosition,\n\t\t\tselectionCount: selectionStore.ids.length,\n\t\t\ttreeSize: this.tree.size(),\n\t\t\tzoom: this.stores.canvasStore.zoom,\n\n\t\t\ttotalTime,\n\t\t\teventProcessing,\n\t\t\ttoolUpdate,\n\t\t\tpostProcessing,\n\t\t\treactUpdate,\n\t\t\tbrowserPaint,\n\t\t\tsandboxUpdating: sandbox.updating,\n\t\t\tsandboxRendering: sandbox.rendering,\n\t\t\tremoteDocument,\n\t\t\trenderingPhase: this.scheduler.canvasSandboxRenderingPhase,\n\t\t\tmainMemory,\n\t\t\tsandboxMemory: debugStore.getSandboxMemoryUse(),\n\n\t\t\tbytesSent,\n\t\t\tbytesReceived,\n\t\t\trtt,\n\t\t\tsocketId,\n\t\t\tconcurrentEditors: this.getConcurrentEditors(),\n\n\t\t\tforcedRendering: this.scheduler.forcedRendering,\n\t\t\tatomicFrame,\n\t\t\tlongFrame: false,\n\t\t\tlogs,\n\t\t}\n\n\t\tif (this.perf) {\n\t\t\tframe.perf = { ...this.perf }\n\t\t\tthis.perf.reset()\n\t\t}\n\t\tdebugStore.addFrameReport(frame)\n\t}\n\n\tgetConcurrentEditors() {\n\t\tif (!this.remoteDocument?.remote) return 0\n\t\treturn this.stores.remoteUsers.getRemoteUserCount()\n\t}\n\n\tgetLastReport(): FrameStats {\n\t\tif (!this.scheduler.needToolProcessing && !this.scheduler.needRendering) {\n\t\t\tthis.doReport()\n\t\t}\n\t\treturn this.stores.debugStore.getLastReport()\n\t}\n\n\t/**\n\t * Load a set of scopes and then process them in an event-like task\n\t * Please note that while loading the scopes, they might be deleted from the tree in multiplayer\n\t * In case of deletion they will be resolved to null\n\t */\n\tloadScopesThenProcess<\n\t\tT extends (BaseShallowType | null | undefined)[],\n\t\tRT extends MapArrayToLoadedOptionalScopeNodes<T>,\n\t>(scopes: [...T]): Promise<RT>\n\tloadScopesThenProcess<\n\t\tT extends (BaseShallowType | null | undefined)[],\n\t\tRT extends MapArrayToLoadedOptionalScopeNodes<T>,\n\t>(scopes: [...T], callback: (scopes: RT) => void): void\n\tloadScopesThenProcess<\n\t\tT extends (BaseShallowType | null | undefined)[],\n\t\tRT extends MapArrayToLoadedOptionalScopeNodes<T>,\n\t>(scopes: [...T], callback?: (scopes: RT) => void) {\n\t\tlet resolvedCallback: (scopes: RT) => void\n\t\tlet promise: Promise<RT> | undefined\n\n\t\tif (callback) {\n\t\t\tresolvedCallback = callback\n\t\t} else {\n\t\t\tpromise = new Promise<RT>(resolve => (resolvedCallback = resolve))\n\t\t}\n\n\t\tthis.tree.loadScopes<T, RT>(scopes, loadedScopes => {\n\t\t\tthis.scheduler.processWhenReady(() => resolvedCallback(loadedScopes))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\t/** Set the reason why the tree might change. If it results in an actual change it will be\n\t * recorded in the changes sent to the server. */\n\tsetEditReason(source: string | null | undefined) {\n\t\tthis.tree.lineage.setEditReason(source)\n\t}\n\n\t/** Some events we are sending to our backends can also be used as edit reasons. */\n\tsetEditReasonFromEvent(event: string) {\n\t\t// If there already is a reason don't overwrite it.\n\t\tif (this.tree.lineage.hasEditReason()) return\n\n\t\t// Filter out some events that are definitely not edit reasons.\n\t\tif (event === \"app_background\") return\n\t\tif (event === \"app_foreground\") return\n\t\tif (event === \"ui_long_frame\") return\n\t\tif (event === \"active_60_30\") return\n\t\tif (event === \"vekter_statistics\") return\n\t\tthis.tree.lineage.setEditReason(event)\n\t}\n\n\tprivate previousCanvasVisibilityState: {\n\t\tmainView: ActiveMainView | null\n\t\tisCollectionOverlayVisibleInCanvas: boolean\n\t} = {\n\t\tmainView: null,\n\t\tisCollectionOverlayVisibleInCanvas: false,\n\t}\n\n\t/**\n\t * This function is used to switch tools based on the canvas visibility and the type of the overlay.\n\t * This is being called in the tool processing step.\n\t */\n\tprivate switchToolsOnCanvasVisibilityChanges() {\n\t\tconst currentMainView = this.stores.chromeStore.mainView\n\t\tconst previousMainView = this.previousCanvasVisibilityState.mainView ?? ActiveMainView.Canvas\n\t\tconst currentViewIsCanvas = currentMainView === ActiveMainView.Canvas\n\n\t\tconst isCollectionOverlayVisibleInCanvas =\n\t\t\tthis.stores.chromeStore.overlay?.type === \"collectionItem\" && currentViewIsCanvas\n\t\tconst hasCollectionOverlayVisibleInCanvasChanged =\n\t\t\tthis.previousCanvasVisibilityState.isCollectionOverlayVisibleInCanvas !== isCollectionOverlayVisibleInCanvas\n\n\t\tthis.previousCanvasVisibilityState.isCollectionOverlayVisibleInCanvas = isCollectionOverlayVisibleInCanvas\n\t\tthis.previousCanvasVisibilityState.mainView = currentMainView\n\n\t\tif (hasCollectionOverlayVisibleInCanvasChanged) {\n\t\t\tthis.setTool(isCollectionOverlayVisibleInCanvas ? Tools.Pan : Tools.Highlight)\n\t\t\treturn\n\t\t}\n\n\t\tconst canvasBecomesVisible = currentViewIsCanvas && previousMainView !== ActiveMainView.Canvas\n\t\tif (canvasBecomesVisible && this.tool.enum !== Tools.Highlight) {\n\t\t\tthis.setTool(Tools.Highlight)\n\t\t\treturn\n\t\t}\n\n\t\tconst canvasBecomesHidden = !currentViewIsCanvas && previousMainView === ActiveMainView.Canvas\n\t\tif (canvasBecomesHidden && this.tool.enum !== Tools.Highlight) {\n\t\t\tthis.setTool(Tools.Highlight)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdoToolProcessing = (fullFrame = true) => {\n\t\tthis.scheduler.inToolProcessing = true\n\n\t\ttry {\n\t\t\tlogScheduler.trace(\"doToolProcessing\", this.scheduler.update, this.scheduler.needToolProcessing)\n\t\t\tif (!this.scheduler.needToolProcessing) return\n\t\t\tthis.scheduler.needToolProcessing = false\n\n\t\t\tassert(this.scheduler.needReport, \"Engine should need reporting.\")\n\n\t\t\tperformanceMark(\"tool\")\n\t\t\tthis.toolStartTime = performance.now()\n\n\t\t\tconst { canvasStore, scopeStore, mouseStore } = this.stores\n\n\t\t\t// In non-interactive (smooth zoom) mode, skip all actual tool, processing and signalling\n\t\t\tif (!canvasStore.isInteractive && !this.inPanTool()) {\n\t\t\t\treturn this.doNonInteractivePostProcessing()\n\t\t\t}\n\n\t\t\tassert(this.scheduler.inEventHandling === 0, \"Engine must not be handling events\")\n\t\t\tassert(this.tree.editClosed, \"Tree must be closed for editing\")\n\t\t\tthis.scheduler.inEventHandling += 1\n\t\t\tthis.tree.editClosed = false\n\t\t\tthis.tree.isViewOnly = getIsViewOnly(this, \"canSendDiffs\")\n\n\t\t\ttry {\n\t\t\t\tengineLog.trace(\"TOOL UPDATE:\", this.currentToolName(), mouseStore.latest.canvasMousePosition)\n\n\t\t\t\tthis.switchToolsOnCanvasVisibilityChanges()\n\t\t\t\tmouseStore.updateInputState()\n\t\t\t\tthis.updateToolState()\n\n\t\t\t\t// If the current tool is not allowed the active mode or scope, exit the tool.\n\t\t\t\tif (\n\t\t\t\t\t!isToolAllowedInMode(this, this.tool.enum) ||\n\t\t\t\t\t!isToolAllowedInScopeType(this.tool.enum, scopeStore.scopeType)\n\t\t\t\t) {\n\t\t\t\t\tthis.exitTool()\n\t\t\t\t}\n\n\t\t\t\t// Don't overwrite edit reasons of some async task with tools like the highlight tool.\n\t\t\t\tconst shouldRecordEditReason = Tools.canEditTree(this.tool.enum)\n\t\t\t\tif (shouldRecordEditReason) {\n\t\t\t\t\tthis.setEditReason(String(this.tool.enum))\n\t\t\t\t}\n\n\t\t\t\tconst hadUncommittedChangesBeforeToolUpdate = this.stores.treeStore.hasUncommittedChanges()\n\n\t\t\t\tthis.tool.update()\n\n\t\t\t\tif (\n\t\t\t\t\tshouldRecordEditReason &&\n\t\t\t\t\t!hadUncommittedChangesBeforeToolUpdate &&\n\t\t\t\t\tthis.stores.treeStore.hasUncommittedChanges()\n\t\t\t\t) {\n\t\t\t\t\tthis.scheduler.markCurrentCommitHasUserTreeEdit()\n\t\t\t\t}\n\n\t\t\t\tif (shouldRecordEditReason) {\n\t\t\t\t\t// Tools are never async so we always reset the edit reason even if no event will be\n\t\t\t\t\t// recorded because there was no tree change.\n\t\t\t\t\tthis.scheduler.recordEditReason(true /* reset */)\n\t\t\t\t}\n\n\t\t\t\t// Perform autoscrolling for the current event, and optionally enable it for the current tool\n\t\t\t\tconst autoscrolls = mouseStore.latest.canvasMouseDownPosition !== null && this.tool.wantsAutoscrolling === true\n\t\t\t\tif (autoscrolls) canvasStore.beginAutoscrolling()\n\t\t\t\tcanvasStore.autoscrollIfNeeded()\n\t\t\t\tif (autoscrolls) canvasStore.endAutoscrolling()\n\t\t\t} finally {\n\t\t\t\tthis.scheduler.inEventHandling -= 1\n\t\t\t}\n\n\t\t\tassert(this.scheduler.inEventHandling === 0, \"Engine must not be handling events\")\n\n\t\t\tperformanceMeasure(\"ToolProcessing\", \"tool\")\n\t\t\tperformanceClearMarks(\"tool\")\n\n\t\t\t// One of the tools (read: the zoom tool) might have put the canvas in non-interactive mode, which is fine\n\t\t\tif (!canvasStore.isInteractive) {\n\t\t\t\treturn this.doNonInteractivePostProcessing()\n\t\t\t}\n\n\t\t\t// Avoid tree changes if the document isn't in an editable state\n\t\t\tif (this.isDocumentEditable() && this.tree.hasUncommittedChanges()) {\n\t\t\t\tfor (const node of this.tree.root.children) {\n\t\t\t\t\tif (!node.mutable) continue\n\t\t\t\t\t// TODO Check and handle shallow/fully loaded scope state when `editWhileLoading` experiment is enabled\n\t\t\t\t\tif (!isCanvasPageNode(node) || !node.isLoaded()) continue\n\t\t\t\t\tverifyHomeNodePostProcess(this.tree, node, this.tool)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.doPostProcessing(fullFrame)\n\t\t} finally {\n\t\t\tthis.scheduler.inToolProcessing = false\n\t\t}\n\t}\n\n\t/* This does the essential part of processing tree changes. For multi-user editing, we cannot\n    leave the tree with uncommitted changes, not even when in non-interactive processing. Will\n    return true if there was an actual commit. */\n\tprivate processTreeChanges(): boolean {\n\t\tif (!this.stores.treeStore.hasUncommittedChanges()) return false\n\n\t\tthrottledSetupLibrary(treeLibrary)\n\t\tperformanceMark(\"tree\")\n\n\t\t// Always make sure the tree is editable when doing a commit.\n\t\tthis.tree.editClosed = false\n\t\tif (this.stores.treeStore.mode === \"crdt\" && !this.stores.modulesStore.isReadOnly()) {\n\t\t\tconst committer = this.crdtTimeline\n\t\t\tcommitter.setFlagsForNextCommit({\n\t\t\t\t...committer.flagsForNextCommit,\n\t\t\t\tisUserEdit: this.scheduler.hasCurrentCommitUserTreeEdit(),\n\t\t\t\tuserId: this.stores.sessionStore.user.id,\n\t\t\t})\n\t\t}\n\t\tconst { tree, autoCreatedBranchId } = this.stores.treeStore.commit()\n\t\tif (autoCreatedBranchId) {\n\t\t\tthis.resetModulesStateForBranch(autoCreatedBranchId)\n\t\t\tconst branchNode = tree.get<BranchNode>(autoCreatedBranchId)\n\t\t\tassert(branchNode, \"Auto created branch node must be defined\")\n\t\t\ttoast({\n\t\t\t\ttype: \"add\",\n\t\t\t\tvariant: \"success\",\n\t\t\t\tprimaryText: `Created branch \"${branchNode.title}\" for your edits.`,\n\t\t\t\tduration: 2000,\n\t\t\t})\n\t\t}\n\t\tif (this.remoteDocument) {\n\t\t\tthis.remoteDocument.afterCommit(tree)\n\t\t\tassert(this.stores.treeStore.timeline.tree === tree, \"TreeSync must take latest tree\")\n\t\t}\n\n\t\tthis.processTreeHasChanged(tree)\n\t\tthis.scheduler.clearCurrentCommitTreeEditState()\n\n\t\tperformanceMeasure(\"TreeProcessing\", \"tree\")\n\t\tperformanceClearMarks(\"tree\")\n\t\treturn true\n\t}\n\n\tprivate processTreeHasChanged(tree: CanvasTree) {\n\t\ttree = this.loadScopeIfNeeded(tree)\n\t\tthis.recordTreeChange(tree)\n\t\tthis.syncBranchViewOnlyState()\n\t\treturn tree\n\t}\n\n\tprivate loadScopeIfNeeded(tree: CanvasTree): CanvasTree {\n\t\tconst [scope] = this.stores.scopeStore.findNextActiveScope(tree)\n\t\tif (!scope) return tree\n\t\tif (scope.isLoaded()) return tree\n\n\t\tconst loader = tree.getService(\"loader\")\n\t\tassert(loader instanceof DocumentLoader, \"Loader must be an instance of DocumentLoader\")\n\n\t\tconst loadedScope = loader.loadScope(scope.id)\n\t\tassert(loadedScope, \"Loaded scope must be defined\")\n\n\t\tassert(this.remoteDocument, \"Document not initialized\")\n\t\treturn this.remoteDocument.loadOneScope(loadedScope, true)\n\t}\n\n\tprivate recordTreeChange(tree: CanvasTree) {\n\t\tthis.scheduler.changes.addChanges(EngineChange.Tree)\n\t\tthis.previousTree = this.tree\n\t\tthis.tree = tree\n\t\tthis.previousTree.editClosed = true\n\t\tthis.tree.editClosed = true\n\t}\n\n\t/** This will run a reduced post processing step, used when canvasStore.isInteractive is false,\n\t * which helps to keep zooming and panning smooth. */\n\tprivate doNonInteractivePostProcessing() {\n\t\tthis.doPostProcessing(false)\n\t}\n\n\tprivate getLocaleIdForUndoRedoEntry(optionalTree?: CanvasTree): LocaleId | undefined {\n\t\tif (this.stores.chromeStore.mainView !== ActiveMainView.Localizations) return\n\t\tconst tree = optionalTree ?? this.tree\n\t\treturn tree.root.getNonDefaultLocale(this.stores.localizationStore.selectedLocaleId)?.id\n\t}\n\n\tprivate previousMainView: ActiveMainView = this.stores.chromeStore.mainView\n\n\tdoPostProcessing(fullFrame = true) {\n\t\tconst {\n\t\t\tscopeStore,\n\t\t\ttreeStore,\n\t\t\tselectionStore,\n\t\t\tcontentManagementStore,\n\t\t\tmodulesStore,\n\t\t\tcodeGenerationStore,\n\t\t\tkitScreenshotStore,\n\t\t\tshaderFallbackImageStore,\n\t\t\tformsStore,\n\t\t\toverlayStore,\n\t\t\trepeaterStore,\n\t\t\ttoolStore,\n\t\t\tfeedbackStore,\n\t\t\tselectionOutlineTracker,\n\t\t\tpathSelectionStore,\n\t\t\tpersistedUserDefaults,\n\t\t\tcanvasStore,\n\t\t\tpreviewStore,\n\t\t\tfullsizePreviewStore,\n\t\t\tpluginStore,\n\t\t\thistoryStore,\n\t\t\tlocalizationStore,\n\t\t\tchromeStore,\n\t\t\tmodalStore,\n\t\t\tloadingStore,\n\t\t\tdocumentSettingsStore,\n\t\t\tpublishStore,\n\t\t} = this.stores\n\t\tthis.scheduler.inPostProcessing = true\n\t\tperformanceMark(\"postProcessing\")\n\t\tthis.processStartTime = performance.now()\n\n\t\tconst treeDidCommit = this.processTreeChanges()\n\t\tconst treeChanged = this.scheduler.changes.has(EngineChange.Tree)\n\n\t\tconst userEdit = this.scheduler.nonUserEventsHandled < this.scheduler.eventsHandled\n\t\tthis.scheduler.nonUserEventsHandled = 0\n\t\tthis.scheduler.eventsHandled = 0\n\n\t\tif (userEdit) {\n\t\t\tthis.scheduler.lastUserInput = performance.now()\n\n\t\t\t// Track when the user most recently changed the tree.\n\t\t\tif (treeDidCommit) {\n\t\t\t\tthis.scheduler.lastUserEdit = performance.now()\n\t\t\t\tthis.upgradeManager?.documentEditedByUser()\n\t\t\t}\n\t\t}\n\n\t\tconst activeScope = scopeStore.validateActiveScope(this.tree)\n\n\t\t// Update the current highlight if feedback store is active\n\t\t// and the tools haven't already applied one.\n\t\tif (toolStore.feedbackModeActive) {\n\t\t\tfeedbackStore.postProcess(id => {\n\t\t\t\t// NOTE: This will disable highlighting frames via the layers\n\t\t\t\t// panel at the moment, because we can't distinguish between\n\t\t\t\t// clearing a previously selected thread highlight and the\n\t\t\t\t// highlight on mouseover set by the layers panel.\n\t\t\t\tif (id === null) return treeStore.setHighlight(null)\n\n\t\t\t\tconst node = this.tree.getNode(id)\n\t\t\t\t// We need to verify the node still exists in the tree before attempting to highlight it.\n\t\t\t\tif (node === null) return\n\n\t\t\t\tconst isValid = this.tree.isGroundNode(node) && this.tree.isAncestorOfNode(node, activeScope.id)\n\t\t\t\tif (isValid) return treeStore.setHighlight(id)\n\t\t\t})\n\t\t}\n\n\t\t// update tree store, when userEdit is true it will capture an undo diff\n\t\tselectionStore.postProcess(this.tree, activeScope, this.previousTree)\n\t\ttreeStore.postProcess(\n\t\t\tthis.tree,\n\t\t\tselectionStore.ids,\n\t\t\tuserEdit,\n\t\t\tactiveScope.id,\n\t\t\tthis.getLocaleIdForUndoRedoEntry(),\n\t\t\tselectionStore.gradientStopId,\n\t\t)\n\t\tif (treeDidCommit) {\n\t\t\tpublishStore.postProcess()\n\t\t}\n\t\tmodulesStore.postProcess({ writeTreeData: true })\n\t\tthis.tree.beginAllowPartialScopeAccess()\n\t\tcodeGenerationStore.postProcess(this.stores.treeStore.getDataTreeOrPartialTree(), activeScope, false)\n\t\tkitScreenshotStore.postProcess(this.tree, false)\n\t\tshaderFallbackImageStore.postProcess(this.tree, false)\n\t\tformsStore.postProcess(this.tree)\n\t\tlocalizationStore.postProcessAutoTranslation(this, this.tree, false)\n\t\tthis.tree.endAllowPartialScopeAccess()\n\t\toverlayStore.postProcess(this.tree)\n\t\trepeaterStore.postProcess(this.tree)\n\t\tthis.updateTreeState()\n\n\t\t// Do the least amount of work, if this is not a full frame\n\t\tif (!fullFrame) {\n\t\t\tthis.scheduler.inPostProcessing = false\n\t\t\tthis.processEndTime = performance.now()\n\t\t\treturn\n\t\t}\n\n\t\tpreviewStore.postProcess(this.scheduler.changes)\n\t\tfullsizePreviewStore.postProcess()\n\t\tpluginStore.postProcess(this)\n\n\t\tselectionOutlineTracker.afterCommit(selectionStore.nodes, this.tool.enum)\n\n\t\tif (treeChanged) {\n\t\t\ttoolStore.postProcess(this.scheduler.update)\n\t\t\tpathSelectionStore.validateSegmentSelection(this.tree)\n\t\t}\n\n\t\tif (this.scheduler.changes.has(EngineChange.UserDefaultsStore)) {\n\t\t\ttreeStore.setShowAllArrows(persistedUserDefaults.displayAllLinks, selectionStore.ids)\n\t\t}\n\n\t\tif (this.scheduler.changes.has(selectionStore)) {\n\t\t\t// Update the shape container id when selection changes and we can get the container\n\t\t\t// from the selection.\n\t\t\tconst shapeContainer = getShapeContainerNodeFor(this.tree, selectionStore.nodes[0])\n\t\t\tif (shapeContainer) {\n\t\t\t\tconst offset = convertFrameToCanvas(this.tree, shapeContainer)\n\t\t\t\ttoolStore.nodeInPathEditorOffset = {\n\t\t\t\t\tx: offset.x - Math.round(offset.x),\n\t\t\t\t\ty: offset.y - Math.round(offset.y),\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttoolStore.nodeInPathEditorOffset = null\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tthis.scheduler.changes.has(\n\t\t\t\tEngineChange.CanvasStore,\n\t\t\t\tEngineChange.Tree,\n\t\t\t\tEngineChange.CanvasZoom,\n\t\t\t\tEngineChange.CanvasLiveTransform,\n\t\t\t)\n\t\t) {\n\t\t\ttreeStore.updateGroundNodesInViewport(canvasStore.getCanvasVisibleRect())\n\n\t\t\t// If there is content in the active scope but nothing in the viewport\n\t\t\tif (treeStore.groundNodesInViewport.size === 0 && activeScope.getGroundNodes(isVisibleNode).length > 0) {\n\t\t\t\tcanvasStore.contentOutOfView = true\n\t\t\t} else {\n\t\t\t\tcanvasStore.contentOutOfView = false\n\t\t\t}\n\t\t}\n\n\t\tconst externalDataSourcesToLoad = treeStore.treeIndex.getAndClearExternalDataSourcesToLoad()\n\t\tif (externalDataSourcesToLoad) {\n\t\t\tconst identifiers = externalDataSourcesToLoad.map(id => parseModuleIdentifier(id))\n\t\t\tmodulesStore.preloadExternalModules(identifiers).catch(unhandledError)\n\t\t}\n\n\t\t// We only set the selection to the active node id after finishing the\n\t\t// initial load, so don't override the url before then, otherwise the\n\t\t// project will land on the wrong node.\n\t\t// https://github.com/framer/company/issues/22130\n\t\tconst remoteDocumentDidLoad = !!this.remoteDocument && !this.remoteDocument.initialLoad\n\t\tif (remoteDocumentDidLoad && this.scheduler.changes.has(EngineChange.Tree, selectionStore, scopeStore)) {\n\t\t\t// Update active node id\n\t\t\tconst newActiveNodeId = this.getActiveNodeIdFromSelection()\n\t\t\tif (newActiveNodeId !== documentSettingsStore.activeNode?.id) {\n\t\t\t\tdocumentSettingsStore.activeNode = { id: newActiveNodeId }\n\t\t\t}\n\t\t}\n\n\t\tconst previousMainView = this.previousMainView\n\t\tconst activeMainView = chromeStore.mainView\n\t\tthis.previousMainView = activeMainView\n\t\tif (chromeStore.isHistoryModeActive && activeMainView !== previousMainView) {\n\t\t\tif (activeMainView === ActiveMainView.Canvas && !historyStore.isLatestTreeVersion()) {\n\t\t\t\thistoryStore.showHistoryViewOnlyToast()\n\t\t\t} else {\n\t\t\t\thistoryStore.removeHistoryViewOnlyToast()\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tthis.scheduler.changes.has(EngineChange.Tree) ||\n\t\t\tthis.scheduler.changes.has(chromeStore) ||\n\t\t\tthis.scheduler.changes.has(modalStore) ||\n\t\t\tthis.scheduler.changes.has(localizationStore) ||\n\t\t\tthis.scheduler.changes.has(EngineChange.ActiveBundle) ||\n\t\t\tthis.scheduler.changes.has(loadingStore)\n\t\t) {\n\t\t\tlocalizationStore.postProcess(this)\n\t\t}\n\n\t\tcontentManagementStore.postProcess(this)\n\n\t\tif (\n\t\t\tthis.scheduler.changes.has(EngineChange.Tree) ||\n\t\t\tthis.scheduler.changes.has(chromeStore) ||\n\t\t\tthis.scheduler.changes.has(modalStore) ||\n\t\t\tthis.scheduler.changes.has(selectionStore)\n\t\t) {\n\t\t\tchromeStore.postProcess(this)\n\t\t}\n\n\t\t// When exiting the localization view, make sure everything is code\n\t\t// generated and persisted.\n\t\tif (previousMainView === ActiveMainView.Localizations && activeMainView !== ActiveMainView.Localizations) {\n\t\t\tcodeGenerationStore.generateAndPersistAllQueuedComponents().catch(unhandledError)\n\t\t}\n\n\t\tthis.changesLastUpdate = this.scheduler.changes.flags\n\n\t\ttry {\n\t\t\tperformanceMeasure(\"PostProcessing\", \"postProcessing\")\n\t\t\tperformanceClearMarks(\"postProcessing\")\n\t\t} catch {\n\t\t\t// ignore, it seems that closing the browser tab, clears all marks\n\t\t}\n\n\t\tthis.scheduler.inPostProcessing = false\n\t\tthis.processEndTime = performance.now()\n\t}\n\n\tprivate getActiveNodeIdFromSelection(): NodeID {\n\t\tconst { scopeStore, selectionStore } = this.stores\n\t\tconst nodes = selectionStore.nodes\n\t\tconst singleNode = nodes.length === 1 ? nodes[0] : null\n\t\t// You can directly link to a content node within the CMS\n\t\tif (singleNode && isContentNode(singleNode)) {\n\t\t\treturn singleNode.id\n\t\t}\n\t\tconst commonGroundNode = this.tree.getCommonGroundNode(selectionStore.nodes)\n\t\treturn commonGroundNode?.id ?? scopeStore.active.id\n\t}\n\n\t// multi user editing support\n\tremoteDocument: RemoteDocumentHandler | null = null\n\n\t/** Install a remote tree sync, get back the local tree sync, after this,\n\t * can call .handleRemoteUpdate() on it for all buffered updates */\n\tcreateRemoteDocumentHandler(projectId: string, userId: string): RemoteDocumentHandler {\n\t\tif (this.remoteDocument) {\n\t\t\tassert(this.remoteDocument.engine === this, \"engine changed\")\n\t\t\tassert(this.remoteDocument.projectId === projectId, \"project id changed\")\n\t\t\tassert(this.remoteDocument.userId === userId, \"user id changed\")\n\t\t\treturn this.remoteDocument\n\t\t}\n\n\t\tconst { remoteUsers, historyStore } = this.stores\n\n\t\tremoteUsers.setLocalUserId(userId)\n\t\tthis.remoteDocument = new RemoteDocument(\n\t\t\tthis,\n\t\t\tprojectId,\n\t\t\tuserId,\n\t\t\terror => {\n\t\t\t\tthis.scheduler.processWhenReady(() => {\n\t\t\t\t\tthis.scheduler.errorInEventHandler(error)\n\t\t\t\t})\n\t\t\t},\n\t\t\tthis.onInitialLoad.bind(this),\n\t\t\treason => {\n\t\t\t\tif (reason === DisconnectReason.ClientNeedsUpdate) {\n\t\t\t\t\t// Trigger the load, so the spinner goes away\n\t\t\t\t\tthis.didLoad()\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.scheduler.runWhenIdle.bind(this),\n\t\t)\n\n\t\tthis.upgradeManager = new DocumentUpgradeManager(this)\n\t\thistoryStore.setRemoteDocument(this.remoteDocument)\n\t\treturn this.remoteDocument\n\t}\n\n\tprivate switchToBaseIfDeleted(committer: CrdtTreeCommitter, tree: CanvasTree): boolean {\n\t\tconst activeBranchId = committer.branches.activeBranchId\n\t\tif (activeBranchId === MAIN_BRANCH_ID) return false\n\t\tconst branchNode = tree.get<BranchNode>(activeBranchId)\n\t\tif (!branchNode?.deletedAt) return false\n\n\t\tthis.assertCanSwitchVisibleBranch()\n\n\t\t// Walk the ancestor chain to find the first non-deleted base. A remote update can delete\n\t\t// both a branch and its base before this client processes either change, so naively jumping\n\t\t// to branchNode.baseId would hit switchVisibleBranch's \"Cannot switch to deleted branch\"\n\t\t// assert. MAIN_BRANCH_ID is always the ultimate fallback since it can never be deleted.\n\t\tlet baseId = branchNode.baseId ?? MAIN_BRANCH_ID\n\t\twhile (baseId !== MAIN_BRANCH_ID) {\n\t\t\tconst baseNode = tree.get<BranchNode>(baseId)\n\t\t\tif (!baseNode?.deletedAt) break\n\t\t\tbaseId = baseNode.baseId ?? MAIN_BRANCH_ID\n\t\t}\n\n\t\tconst baseTitle = baseId === MAIN_BRANCH_ID ? \"main\" : (tree.get<BranchNode>(baseId)?.title ?? baseId)\n\t\ttoast({\n\t\t\ttype: \"add\",\n\t\t\ticonOverride: \"branch\",\n\t\t\tvariant: \"info\",\n\t\t\tprimaryText: `Switched to`,\n\t\t\tsecondaryText: `branch \"${baseTitle}\".`,\n\t\t\tduration: 4000,\n\t\t})\n\t\tthis.switchVisibleBranch(committer, baseId)\n\t\treturn true\n\t}\n\n\t/** Called by treeSync, as an event handler, will ultimately do doInteractiveProcessing */\n\tnewTreeAfterRemoteUpdate(tree: CanvasTree) {\n\t\tassert(tree.isLatest(), \"new tree must be latest\")\n\t\tassert(!tree.hasUncommittedChanges(), \"should be clean\")\n\n\t\tif (this.stores.treeStore.mode === \"crdt\") {\n\t\t\tif (this.switchToBaseIfDeleted(this.crdtTimeline, tree)) return\n\t\t}\n\n\t\ttree = this.processTreeHasChanged(tree)\n\t\tassert(this.tree === tree, \"should have updated tree to latest\")\n\n\t\tconst {\n\t\t\tselectionStore,\n\t\t\tscopeStore,\n\t\t\ttreeStore,\n\t\t\tmodulesStore,\n\t\t\tcodeGenerationStore,\n\t\t\tkitScreenshotStore,\n\t\t\tshaderFallbackImageStore,\n\t\t\toverlayStore,\n\t\t\trepeaterStore,\n\t\t\tlocalizationStore,\n\t\t\tpublishStore,\n\t\t} = this.stores\n\n\t\tconst page = scopeStore.validateActiveScope(tree)\n\t\tselectionStore.postProcess(tree, page, this.previousTree)\n\t\ttreeStore.postProcess(\n\t\t\ttree,\n\t\t\tselectionStore.ids,\n\t\t\tfalse,\n\t\t\tpage.id,\n\t\t\tthis.getLocaleIdForUndoRedoEntry(tree),\n\t\t\tselectionStore.gradientStopId,\n\t\t)\n\t\tpublishStore.postProcess()\n\t\tmodulesStore.postProcess({ writeTreeData: false })\n\t\tcodeGenerationStore.postProcess(this.stores.treeStore.getDataTreeOrPartialTree(), page, true)\n\t\tkitScreenshotStore.postProcess(tree, true)\n\t\tshaderFallbackImageStore.postProcess(tree, true)\n\t\tlocalizationStore.postProcessAutoTranslation(this, tree, true)\n\t\toverlayStore.postProcess(tree)\n\t\trepeaterStore.postProcess(tree)\n\t\tthis.updateTreeState()\n\t}\n\n\tnewTreeAfterPatching(tree: CanvasTree) {\n\t\tassert(tree.isLatest(), \"new tree must be latest\")\n\t\tassert(!tree.hasUncommittedChanges(), \"should be clean\")\n\t\ttree = this.processTreeHasChanged(tree)\n\t\tassert(this.tree === tree, \"should have updated tree to latest\")\n\n\t\tconst { selectionStore, scopeStore, treeStore, codeGenerationStore, localizationStore, publishStore } = this.stores\n\n\t\tconst page = scopeStore.validateActiveScope(tree)\n\t\ttreeStore.postProcess(\n\t\t\ttree,\n\t\t\tselectionStore.ids,\n\t\t\tfalse,\n\t\t\tpage.id,\n\t\t\tthis.getLocaleIdForUndoRedoEntry(tree),\n\t\t\tselectionStore.gradientStopId,\n\t\t)\n\t\tpublishStore.postProcess()\n\t\tcodeGenerationStore.postProcess(treeStore.getDataTreeOrPartialTree(), page, false)\n\t\tlocalizationStore.postProcessAutoTranslation(this, tree, true)\n\t\tthis.updateTreeState()\n\t}\n\n\tprivate static readonly defaultCanvasTool = Tools.Highlight\n\n\tsetTool(tool: Tools.HighlightStackItem, arg?: HighlightStackItemToolOptions): void\n\tsetTool(tool: Tools.AgentDragSelect, arg: AgentDragSelectToolOptions): void\n\tsetTool(tool: Tools.Move, arg?: MoveToolOptions): void\n\tsetTool(tool: Tools.TextEdit | Tools.RichTextEdit, arg?: TextEditToolOptions): void\n\tsetTool(tool: Tools.RichTextVariableEdit, arg?: RichTextVariableEditToolOptions): void\n\tsetTool(tool: Tools.StringVariableEdit, arg?: StringVariableEditToolOptions): void\n\tsetTool(tool: Tools.DateVariableEdit, arg?: DateVariableEditToolOptions): void\n\tsetTool(tool: Tools.EnumVariableEdit, arg?: EnumVariableEditToolOptions): void\n\tsetTool(tool: Tools.CollectionReferenceVariableEdit, arg?: CollectionReferenceVariableEditToolOptions): void\n\tsetTool(tool: Tools.MaskGradient, arg?: MasksByNodeId): void\n\tsetTool(tool: Tools.ViewportResize, arg?: ViewportResizeToolOptions): void\n\tsetTool(tool: Tools, arg?: never): void\n\tsetTool(tool: Tools, arg: never) {\n\t\tthis.setNewTool(tool, undefined, arg)\n\t}\n\n\tsetToolWithHandle(\n\t\ttool: Tools.Rotate | Tools.Resize | Tools.Scale | Tools.Padding | Tools.Gap,\n\t\thandle: FramePoint | null,\n\t\trestart: boolean = true,\n\t) {\n\t\tif (restart === false) {\n\t\t\tthis.setToolHandle(handle)\n\t\t\treturn\n\t\t}\n\t\tthis.setNewTool(tool, handle)\n\t}\n\n\tprivate setNewTool(tool: Tools.HighlightStackItem, handle?: undefined, arg?: HighlightStackItemToolOptions): void\n\tprivate setNewTool(\n\t\ttool: Tools.AgentPanel | Tools.AgentDragSelect,\n\t\thandle?: undefined,\n\t\targ?: AgentSelectToolOptions,\n\t): void\n\tprivate setNewTool(tool: Tools.Move, handle?: undefined, arg?: MoveToolOptions): void\n\tprivate setNewTool(tool: Tools.TextEdit | Tools.RichTextEdit, handle?: undefined, arg?: TextEditToolOptions): void\n\tprivate setNewTool(tool: Tools.RichTextVariableEdit, handle?: undefined, arg?: RichTextVariableEditToolOptions): void\n\tprivate setNewTool(tool: Tools.EnumVariableEdit, handle?: undefined, arg?: EnumVariableEditToolOptions): void\n\tprivate setNewTool(tool: Tools.MaskGradient, handle?: undefined, arg?: MasksByNodeId): void\n\tprivate setNewTool(tool: Tools.ViewportResize, handle?: undefined, arg?: ViewportResizeToolOptions): void\n\tprivate setNewTool(tool: Tools, handle?: FramePoint | null, arg?: never): void\n\tprivate setNewTool(tool: Tools, handle?: FramePoint | null, arg?: never) {\n\t\tconst { chromeStore, historyStore, scopeStore, loadingStore } = this.stores\n\t\tif (loadingStore.isUserInteractionsDisabled) return\n\t\tif (chromeStore.mainView !== ActiveMainView.Canvas && tool !== VekterEngine.defaultCanvasTool) return\n\t\tif (historyStore.isLoadingDocument && tool !== Tools.LoadingShield) return\n\t\tif (chromeStore.isPreviewingLocaleOnCanvas && !isToolAllowedInViewOnly(tool)) return\n\t\tif (!isToolAllowedInScopeType(tool, scopeStore.scopeType)) return\n\t\tif (chromeStore.overlay?.type === \"collectionItem\" && !isToolAllowedWhenCollectionOverlayActive(tool)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (!this.scheduler.inPostProcessing) {\n\t\t\tthis.assertStateMutable()\n\t\t}\n\n\t\tassertCanUseToolInMode(this, tool)\n\n\t\tif (isToolWithHandle(tool) && !isUndefined(handle)) {\n\t\t\tthis.setToolHandle(handle)\n\t\t}\n\n\t\tconst newTool = newToolFor(this, tool, arg)\n\t\tthis.stopStartTool(newTool)\n\t}\n\n\tprivate setToolHandle(handle: FramePoint | null) {\n\t\tthis.handle = handle\n\t\tthis.stores.toolStore.handle = handle\n\t}\n\n\tprivate stopStartTool(tool: VekterTool) {\n\t\tconst { chromeStore, feedbackStore, toolStore } = this.stores\n\t\tengineLog.debug(\"setTool():\", this.tool.__class, this.tool.enum, \"->\", tool.__class, tool.enum)\n\t\tthis.tool.stop()\n\n\t\tif (returnToPreviousToolOnExit(this.tool, tool)) {\n\t\t\tconst prevTool = this.tool.enum\n\t\t\tthis.setExit(() => {\n\t\t\t\tthis.setExit(null)\n\t\t\t\tthis.setTool(prevTool)\n\t\t\t})\n\t\t} else {\n\t\t\tthis.setExit(null)\n\t\t}\n\n\t\tchromeStore.onToolChange(tool.enum)\n\n\t\tif (tool.enum === Tools.Comment) {\n\t\t\tfeedbackStore.setFeedbackModeActive(true)\n\t\t}\n\n\t\ttoolStore.setTool(tool.enum)\n\t\tthis.tool = tool\n\n\t\ttool.start()\n\t}\n\n\tcancelTool = () => {\n\t\tif (this.tool.cancel) {\n\t\t\tthis.tool.cancel()\n\t\t}\n\n\t\tthis.stores.mouseStore.setMouseDown(false)\n\t\tthis.exitTool()\n\t}\n\n\tprivate exit: Function | null = null\n\n\t// Exits commenting mode\n\texitMode = () => {\n\t\tconst { feedbackStore, selectionStore } = this.stores\n\t\tfeedbackStore.setFeedbackModeActive(false)\n\t\tthis.exitTool()\n\n\t\t// Shapes are not allowed to be selected when exiting shape mode\n\t\tconst newSelection = selectionStore.ids.filter(id => {\n\t\t\tconst n = this.tree.getNode(id)\n\t\t\treturn !!n && !withShape(n)\n\t\t})\n\t\tconst selectionDidChange = newSelection.length !== selectionStore.ids.length\n\t\tif (selectionDidChange) {\n\t\t\tselectionStore.set(newSelection)\n\t\t}\n\t}\n\n\texitTool = () => {\n\t\tif (this.exit) {\n\t\t\tthis.exit()\n\t\t\treturn\n\t\t}\n\t\tthis.setNewTool(VekterEngine.defaultCanvasTool)\n\t}\n\n\tsetExit(cb: Function | null) {\n\t\tthis.exit = cb\n\t}\n\n\tshouldShowArrows(): boolean {\n\t\t// Hide the arrows at higher zoom levels because vektor shapes always have to be drawn entirely\n\t\t// which can take up to a full second when zoomed 32x, at which point the utility of the arrow\n\t\t// is very low because you typically 1) can't see it at all and definitely 2) can't see what\n\t\t// it is pointing at anyway. So not worth waiting on for a second (or even one frame).\n\t\tif (this.stores.canvasStore.zoom > 4) return false\n\n\t\t// Hide arrows when we hide the main selection.\n\t\tif (!this.shouldShowSelection()) return false\n\n\t\t// Hide arrows when the move tool is dragging.\n\t\tif (this.inMoveToolAndHasMoved()) return false\n\n\t\t// Hide arrows when the resize tool is dragging.\n\t\tif (this.inResizeToolAndHasMoved()) return false\n\n\t\t// Hide arrows when the padding tool is dragging.\n\t\tif (this.inPaddingToolAndHasMoved()) return false\n\n\t\t// Hide arrows when the radius tool is dragging.\n\t\tif (this.inRadiusToolAndHasMoved()) return false\n\n\t\tswitch (this.tool.enum) {\n\t\t\tcase Tools.Move:\n\t\t\tcase Tools.Pan:\n\t\t\tcase Tools.Zoom:\n\t\t\tcase Tools.Highlight:\n\t\t\tcase Tools.DirectSelect:\n\t\t\tcase Tools.Resize:\n\t\t\tcase Tools.Scale:\n\t\t\tcase Tools.Radius:\n\t\t\t\treturn true\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t}\n\n\tshouldShowSelection(): boolean {\n\t\tconst { chromeStore, selectionStore } = this.stores\n\t\t// Temporary hack to hide the selection box while detaching, should be removed when\n\t\t// inserting nodes no longer requires these temporary nodes to be visible on the canvas\n\t\tif (\n\t\t\tchromeStore.autoDetachingNodeId &&\n\t\t\tselectionStore.ids.length === 1 &&\n\t\t\tselectionStore.ids[0] === chromeStore.autoDetachingNodeId\n\t\t) {\n\t\t\treturn false\n\t\t}\n\n\t\tswitch (this.tool.enum) {\n\t\t\tcase Tools.Pan:\n\t\t\tcase Tools.Zoom:\n\t\t\tcase Tools.Rotate:\n\t\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n\n\t// FIXME: the ! is unsafe here: tree will actually be undefined until a tree is updated at least once.\n\t// However, too much code relies on previousTree being `CanvasTree` and not `CanvasTree | undefined`,\n\t// and I'm not sure what's the best way to fix it.\n\tprivate previousTree!: CanvasTree\n\n\tsetMouseStore(\n\t\tx: number,\n\t\ty: number,\n\t\tdown = false,\n\t\taltKey = false,\n\t\tcmdKey = false,\n\t\tshiftKey = false,\n\t\tctrlKey = false,\n\t\tdoubleClick = false,\n\t) {\n\t\tconst { mouseStore } = this.stores\n\t\tconst point = Point(x, y)\n\t\tmouseStore.setMousePosition(point, point, altKey, cmdKey, shiftKey, ctrlKey)\n\t\tif (down !== !!mouseStore.canvasMouseDownPosition) {\n\t\t\tmouseStore.setMouseDown(down)\n\t\t}\n\t\tif (doubleClick !== !!mouseStore.canvasDoubleClickPosition) {\n\t\t\tmouseStore.setDoubleClick(doubleClick)\n\t\t}\n\t}\n\n\t// control document\n\n\t/**\n\t * Legacy temporary collection items aren't part of the tree, so undo/redo should be disabled.\n\t */\n\tprivate get isEditingTemporaryCollectionItem() {\n\t\treturn this.stores.chromeStore.contentManagementOverlayStack.some(element => element.type === \"temporary\")\n\t}\n\n\tcanUndo() {\n\t\tconst { undoRedoManager, modalStore, siteSettingsStore } = this.stores\n\t\tconst undoEntry = undoRedoManager.peekUndo()\n\t\tif (siteSettingsStore.getIsRedirectsVisible()) {\n\t\t\treturn isRedirectUndoRedoEntry(undoEntry, this.tree)\n\t\t}\n\t\tif (modalStore.shouldBlockUndoRedo(undoEntry, this.tree)) return false\n\t\tif (this.isEditingTemporaryCollectionItem) return false\n\t\tif (this.tool.undo) return true\n\t\treturn undoRedoManager.canUndo()\n\t}\n\n\tcanRedo() {\n\t\tconst { undoRedoManager, modalStore, siteSettingsStore } = this.stores\n\t\tconst redoEntry = undoRedoManager.peekRedo()\n\t\tif (siteSettingsStore.getIsRedirectsVisible()) {\n\t\t\treturn isRedirectUndoRedoEntry(redoEntry, this.tree)\n\t\t}\n\t\tif (modalStore.shouldBlockUndoRedo(redoEntry, this.tree)) return false\n\t\tif (this.isEditingTemporaryCollectionItem) return false\n\t\tif (this.tool.redo) return true\n\t\treturn undoRedoManager.canRedo()\n\t}\n\n\tprivate updateLocalizationViewIfNeeded(entry: TreeEditUndoEntry): boolean /* Did update */ {\n\t\tconst { chromeStore, localizationStore } = this.stores\n\t\tconst shouldShowLocalizationView = !!entry.localeId || isLocalesUndoRedoEntry(entry, this.tree)\n\t\tif (shouldShowLocalizationView) {\n\t\t\tlet didChangeLocalizationView = false\n\t\t\tif (chromeStore.mainView !== ActiveMainView.Localizations) {\n\t\t\t\tchromeStore.setLocalizationsVisible(true)\n\t\t\t\tdidChangeLocalizationView = true\n\t\t\t}\n\t\t\tif (entry.localeId && localizationStore.selectedLocaleId !== entry.localeId) {\n\t\t\t\tconst localeExists = Boolean(this.tree.root.locales?.some(localization => localization.id === entry.localeId))\n\t\t\t\tif (localeExists) didChangeLocalizationView = true\n\t\t\t\tlocalizationStore.selectedLocaleId = entry.localeId\n\t\t\t}\n\t\t\treturn didChangeLocalizationView\n\t\t}\n\t\tif (chromeStore.mainView === ActiveMainView.Localizations) {\n\t\t\tchromeStore.setLocalizationsVisible(false)\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tundo() {\n\t\tconst { undoRedoManager, selectionStore, scopeStore, treeStore } = this.stores\n\n\t\tif (this.isEditingTemporaryCollectionItem) return\n\n\t\tif (this.tool.undo) {\n\t\t\tthis.tool.undo()\n\t\t\treturn\n\t\t}\n\n\t\tthis.assertStateMutable()\n\n\t\tconst undoEntry = undoRedoManager.peekUndo()\n\t\tif (!undoEntry) return\n\n\t\tif (undoEntry.kind === \"branchSwitch\") {\n\t\t\tconst committer = treeStore.timeline\n\t\t\tassert(isCrdtTreeCommitter(committer), \"Branch switch undo requires a CRDT timeline\")\n\t\t\tundoRedoManager.undo(committer)\n\t\t\tthis.switchVisibleBranch(committer, undoEntry.fromBranchId)\n\t\t\t// TODO: restore undoEntry.selection/scopeId/localeId after switching, falling back when\n\t\t\t// they no longer exist on the target branch (e.g. scopes/nodes deleted on that branch).\n\t\t\treturn\n\t\t}\n\n\t\t// If the change of the undo is on another scope go to that scope.\n\t\tconst currentScope = scopeStore.active\n\n\t\tconst isDeletingCurrentScope = undoEntry.changes.some(change => {\n\t\t\treturn change.id === currentScope.id && change.added\n\t\t})\n\n\t\tif (currentScope.id !== undoEntry.scopeId && treeStore.tree.has(undoEntry.scopeId) && !isDeletingCurrentScope) {\n\t\t\tscopeStore.select(undoEntry.scopeId, { keepHistory: false })\n\t\t\treturn\n\t\t}\n\n\t\tif (this.updateLocalizationViewIfNeeded(undoEntry)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst entry = undoRedoManager.undo(this.stores.treeStore.timeline, {\n\t\t\tkind: \"treeEdit\",\n\t\t\tselection: selectionStore.ids,\n\t\t\tscopeId: currentScope.id,\n\t\t\tlocaleId: this.getLocaleIdForUndoRedoEntry(),\n\t\t})\n\t\tthis.scheduler.recordEditReason()\n\t\tif (!entry) return\n\t\tassert(entry.kind === \"treeEdit\", \"Undoing a tree edit must return a tree edit entry\")\n\n\t\tthis.postUndoRedo(entry, currentScope)\n\t}\n\n\tredo() {\n\t\tconst { undoRedoManager, selectionStore, scopeStore, treeStore } = this.stores\n\n\t\tif (this.isEditingTemporaryCollectionItem) return\n\n\t\tif (this.tool.redo) {\n\t\t\tthis.tool.redo()\n\t\t\treturn\n\t\t}\n\n\t\tthis.assertStateMutable()\n\n\t\tconst redoEntry = undoRedoManager.peekRedo()\n\t\tif (!redoEntry) return\n\n\t\tif (redoEntry?.kind === \"branchSwitch\") {\n\t\t\tconst committer = treeStore.timeline\n\t\t\tassert(isCrdtTreeCommitter(committer), \"Branch switch redo requires a CRDT timeline\")\n\t\t\tundoRedoManager.redo(committer)\n\t\t\tthis.switchVisibleBranch(committer, redoEntry.toBranchId)\n\t\t\t// TODO: restore redoEntry.selection/scopeId/localeId after switching, falling back when\n\t\t\t// they no longer exist on the target branch (e.g. scopes/nodes deleted on that branch).\n\t\t\treturn\n\t\t}\n\n\t\t// If the change of the redo is on another scope go to that scope.\n\t\tconst currentScope = scopeStore.active\n\n\t\tif (currentScope.id !== redoEntry.scopeId && treeStore.tree.has(redoEntry.scopeId)) {\n\t\t\tscopeStore.select(redoEntry.scopeId, { keepHistory: false })\n\t\t\treturn\n\t\t}\n\n\t\tif (this.updateLocalizationViewIfNeeded(redoEntry)) {\n\t\t\treturn\n\t\t}\n\n\t\tconst entry = undoRedoManager.redo(this.stores.treeStore.timeline, {\n\t\t\tkind: \"treeEdit\",\n\t\t\tselection: selectionStore.ids,\n\t\t\tscopeId: currentScope.id,\n\t\t\tlocaleId: this.getLocaleIdForUndoRedoEntry(),\n\t\t})\n\t\tthis.scheduler.recordEditReason()\n\t\tif (!entry) return\n\t\tassert(entry.kind === \"treeEdit\", \"Redoing a tree edit must return a tree edit entry\")\n\n\t\tthis.postUndoRedo(entry, currentScope)\n\t}\n\n\tprivate postUndoRedo(entry: TreeEditUndoEntry, prevScope: ScopeNode) {\n\t\tconst {\n\t\t\tguidesStore,\n\t\t\tchromeStore,\n\t\t\tlocalizationStore,\n\t\t\tscopeStore,\n\t\t\ttreeStore,\n\t\t\tselectionStore,\n\t\t\tcodeGenerationStore,\n\t\t\tkitScreenshotStore,\n\t\t\tshaderFallbackImageStore,\n\t\t\tformsStore,\n\t\t\tpublishStore,\n\t\t} = this.stores\n\t\t// Undoing a scope deletion should switch to the scope afterwards.\n\t\tlet didSwitchScope = false\n\n\t\t// When we create a node which requires a scope change via a `redo`, there is a difference in\n\t\t// the amount of prevScopes and changedScopes since it touches both the scope where the node is used,\n\t\t// and the scope where the node is created. For example, \"redoing\" a \"Create smart component\" will affect the canvas\n\t\t// where it's used, and the isolation scope where it's created. This also applies to redoing CMS collection creation.\n\t\t// Because of this, there is a mismatch in size between prevScopes (generally 1) and changedScopes (generally 2).\n\t\t// If that difference is there, we should update the selected scope.\n\t\tif (entry.scopeId !== prevScope.id && treeStore.tree.has(entry.scopeId)) {\n\t\t\tdidSwitchScope = true\n\t\t\tscopeStore.select(entry.scopeId, { keepHistory: false })\n\t\t}\n\n\t\tif (entry.localeId) {\n\t\t\tif (chromeStore.mainView !== ActiveMainView.Localizations) {\n\t\t\t\tchromeStore.setLocalizationsVisible(true)\n\t\t\t}\n\t\t\tif (localizationStore.selectedLocaleId !== entry.localeId) {\n\t\t\t\tlocalizationStore.selectedLocaleId = entry.localeId\n\t\t\t}\n\t\t} else if (chromeStore.mainView === ActiveMainView.Localizations) {\n\t\t\tchromeStore.setLocalizationsVisible(false)\n\t\t}\n\n\t\t// At this point, the treeStore has updated the tree\n\t\tconst { tree } = treeStore.commit()\n\t\tconst scope = scopeStore.validateActiveScope(tree)\n\n\t\t// When the undo/redo switches the scope, we should restore the selection stored in the ScopeStore,\n\t\t// instead of using entry.selection (which is on the previous page). But undoing creating Smart Component or\n\t\t// Web Page is an exception, because the selection stored in the ScopeStore is the swapped component instance,\n\t\t// which does not exist anymore after the undo, so we actually want to restore the selection in the undo entry.\n\t\tconst prevScopeIsModuleBacked = isModuleBackedScope(prevScope)\n\t\tconst keepScopeStoreSelection = didSwitchScope && !prevScopeIsModuleBacked\n\t\tselectionStore.postProcess(\n\t\t\ttree,\n\t\t\tscope,\n\t\t\tthis.previousTree,\n\t\t\tentry.selectedGradientStopId,\n\t\t\tkeepScopeStoreSelection ? selectionStore.ids : entry.selection,\n\t\t)\n\t\tconst activeScopeId = entry.scopeId ?? prevScope.id\n\t\tthis.stores.treeStore.postProcess(\n\t\t\ttree,\n\t\t\tselectionStore.ids,\n\t\t\tfalse,\n\t\t\tactiveScopeId,\n\t\t\tthis.getLocaleIdForUndoRedoEntry(tree),\n\t\t)\n\t\tpublishStore.postProcess()\n\t\tcodeGenerationStore.postProcess(this.stores.treeStore.getDataTreeOrPartialTree(), scope, false)\n\t\tkitScreenshotStore.postProcess(tree, false)\n\t\tshaderFallbackImageStore.postProcess(tree, false)\n\t\tformsStore.postProcess(tree)\n\t\tthis.updateTreeState()\n\n\t\tif (this.previousTree !== this.tree) {\n\t\t\tthis.previousTree.editClosed = true\n\t\t}\n\t\tthis.previousTree = this.tree\n\t\tif (this.remoteDocument) {\n\t\t\tthis.remoteDocument.afterCommit(this.tree)\n\t\t}\n\n\t\t// a quick fix for cleaning the ruler display\n\t\tguidesStore.clearSelected()\n\n\t\t// Force regenerate collection modules when they are changed from the canvas\n\t\tif (activeScopeId !== CONTENT_MANAGEMENT_ID) {\n\t\t\tconst updatedCollectionNodeIds: Set<NodeID> = new Set()\n\n\t\t\tfor (const change of entry.changes) {\n\t\t\t\tconst node = tree.get(change.id)\n\t\t\t\tif (!node) continue\n\n\t\t\t\tif (isCollectionNode(node)) {\n\t\t\t\t\tupdatedCollectionNodeIds.add(node.id)\n\t\t\t\t}\n\n\t\t\t\tif (isCollectionItemNode(node)) {\n\t\t\t\t\tconst parent = tree.getParent(node.id)\n\t\t\t\t\tif (isCollectionNode(parent)) {\n\t\t\t\t\t\tupdatedCollectionNodeIds.add(parent.id)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdatedCollectionNodeIds.forEach(id => {\n\t\t\t\tcodeGenerationStore.updateComponent(id).catch(unhandledError)\n\t\t\t})\n\t\t}\n\t}\n\n\tbeginUndoGroup() {\n\t\tthis.assertStateMutable()\n\t\tthis.stores.undoRedoManager.beginUndoGroup()\n\t}\n\n\tendUndoGroup() {\n\t\tthis.assertStateMutable()\n\t\tthis.stores.undoRedoManager.scheduleEndUndoGroup()\n\t}\n\n\tdiscardUndoGroup() {\n\t\tthis.assertStateMutable()\n\t\tconst entry = this.stores.undoRedoManager.discardUndoGroup(this.stores.treeStore.timeline)\n\t\tif (!entry) return\n\t\tassert(entry.kind === \"treeEdit\", \"Discarding an undo group must return a tree edit entry\")\n\n\t\tthis.postUndoRedo(entry, this.stores.scopeStore.active)\n\t}\n\n\tcreateNode<T extends CanvasNode>(\n\t\tnodeClass: { new (properties?: Record<string, unknown>, cache?: CanvasNodeCache): T },\n\t\tattributes: Partial<T> = {},\n\t\tparentId: MaybeNodeID = NullID,\n\t\tsourceNodeId?: NodeID /* If provided, the node will be positioned right after the source node (in each replicas) */,\n\t\tposition?: number,\n\t): T {\n\t\tthis.assertStateMutable()\n\n\t\tlet id = attributes.id\n\t\tif (!id) {\n\t\t\tid = randomID()\n\t\t\tattributes = { ...attributes, id }\n\t\t}\n\n\t\tconst node = new nodeClass()\n\t\tassert(node instanceof CanvasNode)\n\n\t\tnode.set(attributes)\n\t\tthis.stores.scopeStore.insertNode(node, parentId, position, sourceNodeId)\n\n\t\trecord(\"layout_instance\", { instanceType: node.__class })\n\n\t\tconst latestNode = this.tree.get<T>(id)\n\t\tassert(latestNode)\n\t\treturn latestNode\n\t}\n\n\tasync createWebPage({\n\t\tdataIdentifier,\n\t\tpreferredPath,\n\t\tstartEditingPageTitle = true,\n\t\tid,\n\t\tprimaryBreakpointTemplateId,\n\t\tshouldRemovePanelOverrides = true,\n\t\tisWireframerKitPage = false,\n\t\tshouldSetPanelTab = true,\n\t\tshouldOpenPage = true,\n\t\tname,\n\t}: {\n\t\tdataIdentifier?: ModuleExportIdentifierString\n\t\tpreferredPath?: string\n\t\tstartEditingPageTitle?: boolean\n\t\tid?: NodeID\n\t\tprimaryBreakpointTemplateId?: NodeID\n\t\tshouldRemovePanelOverrides?: boolean\n\t\tisWireframerKitPage?: boolean\n\t\tshouldSetPanelTab?: boolean\n\t\tshouldOpenPage?: boolean\n\t\tname?: string\n\t} = {}): Promise<LoadedWebPageNode> {\n\t\tconst { chromeStore, scopeStore, treeStore } = this.stores\n\t\tif (shouldRemovePanelOverrides) {\n\t\t\tchromeStore.removePanelOverrides()\n\t\t}\n\n\t\tif (shouldSetPanelTab) {\n\t\t\tchromeStore.contentPanelTab = ActiveContentPanelTab.Pages\n\t\t\tchromeStore.chromeIsVisible = true\n\t\t\tchromeStore.pagesExpanded = true\n\t\t}\n\n\t\tconst webPages = scopeStore.getWebPageNodes()\n\t\tif (webPages.length === 0) {\n\t\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\t\tconst homePage = createWebPageWithoutTemplate({\n\t\t\t\t\tengine: this,\n\t\t\t\t\tname: name ?? Dictionary.Home,\n\t\t\t\t\tpagePath: undefined,\n\t\t\t\t\tdataIdentifier,\n\t\t\t\t\tid,\n\t\t\t\t\tprimaryBreakpointTemplateId,\n\t\t\t\t\tshouldOpenPage,\n\t\t\t\t})\n\t\t\t\tconst rootNode = treeStore.tree.get<RootNode>(treeStore.tree.root.id)\n\t\t\t\tassert(rootNode)\n\t\t\t\trootNode.set({ homePageNodeId: homePage.id })\n\t\t\t\treturn homePage\n\t\t\t})\n\t\t}\n\t\tconst { path: pagePath, suggestedName } = getUniquePagePath(\n\t\t\tpreferredPath ?? \"/page\",\n\t\t\tthis.tree,\n\t\t\tthis.componentLoader,\n\t\t\tnull,\n\t\t)\n\n\t\tconst loadedTemplate = await getLoadedWebPageTemplate(this)\n\t\treturn this.scheduler.processWhenReadyAsync(() => {\n\t\t\tconst newPage = createWebPage({\n\t\t\t\tengine: this,\n\t\t\t\tname: name ?? suggestedName,\n\t\t\t\tpagePath: pagePath,\n\t\t\t\tdataIdentifier,\n\t\t\t\tloadedTemplate,\n\t\t\t\tid,\n\t\t\t\tprimaryBreakpointTemplateId,\n\t\t\t\tisWireframerKitPage,\n\t\t\t\tshouldOpenPage,\n\t\t\t})\n\n\t\t\tconst routeSegmentNode = getRouteSegmentNodeByWebPageId(treeStore.tree, newPage.id)\n\t\t\tif (!routeSegmentNode) return newPage\n\n\t\t\tif (startEditingPageTitle) {\n\t\t\t\t// Run after React has rendered the row\n\t\t\t\tthis.scheduler.runAtEndOfFrame(() => {\n\t\t\t\t\teditPageTitle(routeSegmentNode.id)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn newPage\n\t\t})\n\t}\n\n\t/** Tracks frame creation so we can emit events and set or remove user hints via toasts. */\n\tprocessFrameCreation(parent?: MaybeNodeID, attributes?: Partial<FrameNode>) {\n\t\tconst { chromeStore, treeStore } = this.stores\n\t\tif (treeStore.tree.has(parent)) {\n\t\t\ttriggerLayoutFrameHierarchyEvent({})\n\t\t}\n\n\t\tif (attributes?.isScreen) {\n\t\t\t// Dismiss the Screen toast when a Screen is created\n\t\t\tdismissToolFallbackToast(\"toolCreateScreen\", toast)\n\n\t\t\tif (localStorage.getItem(\"createdScreen\") !== \"true\" && !chromeStore.isViewOnly) {\n\t\t\t\t// Trigger the Rectangle toast if a Screen was first created\n\t\t\t\tsetToolFallbackToast(\"toolCreateRectangleShape\", toast)\n\t\t\t\tlocalStorage.setItem(\"createdScreen\", \"true\")\n\t\t\t}\n\t\t} else {\n\t\t\t// Dismiss the Rectangle toast when a Frame is created\n\t\t\tdismissToolFallbackToast(\"toolCreateRectangleShape\", toast)\n\t\t}\n\t}\n\n\tcreateFrame(parent?: MaybeNodeID, attributes: Partial<FrameNode> = {}, sourceNodeId?: NodeID) {\n\t\tthis.processFrameCreation(parent, attributes)\n\t\treturn this.createNode(FrameNode, attributes, parent, sourceNodeId)\n\t}\n\n\tcreateShapeContainer(parent?: MaybeNodeID, attributes: Partial<ShapeContainerNode> = {}) {\n\t\treturn this.createNode(ShapeContainerNode, attributes, parent)\n\t}\n\n\tcreatePath(parent?: MaybeNodeID, attributes: Partial<PathNode> = {}) {\n\t\tthis.createNode(PathNode, attributes, parent)\n\t}\n\n\tcreateBooleanPath(parent?: MaybeNodeID, attributes: Partial<BooleanShapeNode> = {}, position?: number) {\n\t\tthis.createNode(BooleanShapeNode, attributes, parent, undefined, position)\n\t}\n\n\tcreateShapeGroup(parent?: MaybeNodeID, attributes: Partial<ShapeGroupNode> = {}, position?: number) {\n\t\tthis.createNode(ShapeGroupNode, attributes, parent, undefined, position)\n\t}\n\n\tcreateRichText(parentId?: MaybeNodeID, attributes: Partial<RichTextNode> = {}) {\n\t\tconst defaultPresets = getDefaultPresets(this.tree)\n\t\tlet key: keyof typeof defaultPresets\n\t\tfor (key in defaultPresets) {\n\t\t\tattributes[key] ??= defaultPresets[key]\n\t\t}\n\n\t\treturn this.createNode(RichTextNode, attributes, parentId)\n\t}\n\n\tcreateShape(\n\t\ttype: ShapeType,\n\t\tparent?: MaybeNodeID,\n\t\tattributes: Partial<OvalShapeNode | PolygonShapeNode | StarShapeNode | RectangleShapeNode> = {},\n\t) {\n\t\tlet nodeClass:\n\t\t\t| typeof OvalShapeNode\n\t\t\t| typeof PolygonShapeNode\n\t\t\t| typeof StarShapeNode\n\t\t\t| typeof RectangleShapeNode\n\t\t\t| undefined\n\n\t\tswitch (type) {\n\t\t\tcase \"oval\":\n\t\t\t\tnodeClass = OvalShapeNode\n\t\t\t\tbreak\n\t\t\tcase \"polygon\":\n\t\t\t\tnodeClass = PolygonShapeNode\n\t\t\t\tbreak\n\t\t\tcase \"star\":\n\t\t\t\tnodeClass = StarShapeNode\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tnodeClass = RectangleShapeNode\n\t\t\t\tbreak\n\t\t}\n\n\t\t// Visually center newly created shapes needing centering.\n\t\tif (shapeSupportsCenteredAttribute(type, attributes)) {\n\t\t\tattributes.centered = true\n\t\t}\n\n\t\tthis.createNode(nodeClass, attributes, parent)\n\t}\n\n\tcreateImage(\n\t\tfilename: string,\n\t\toriginalFilename: string,\n\t\tintrinsicSize: { width: number; height: number },\n\t\tparent?: MaybeNodeID,\n\t\tattributes: Partial<FrameNode> = {},\n\t\tposition?: number,\n\t) {\n\t\tassert(!this.stores.chromeStore.isViewOnly, \"Creating images is not allowed in view only mode\")\n\n\t\tconst assetReference = createAssetReferenceForImage({\n\t\t\tidentifier: filename,\n\t\t\tintrinsicSize,\n\t\t\toriginalFilename,\n\t\t})\n\n\t\tthis.createNode(\n\t\t\tFrameNode,\n\t\t\t{\n\t\t\t\taspectRatio: aspectRatioFromAttibutes(attributes),\n\t\t\t\tfillImage: assetReference,\n\t\t\t\tfillImageOriginalName: originalFilename,\n\t\t\t\tfillType: \"image\",\n\t\t\t\t...attributes,\n\t\t\t},\n\t\t\tparent,\n\t\t\tundefined,\n\t\t\tposition,\n\t\t)\n\t}\n\n\tcloneNode<T extends CanvasNode>(\n\t\tnode: T,\n\t\tinheritOverrides: boolean = false,\n\t\tshouldInsert = true,\n\t\trenamedIds?: Map<NodeID, NodeID>,\n\t): T {\n\t\tconst { chromeStore, scopeStore } = this.stores\n\t\tassert(!chromeStore.isViewOnly, \"Cloning nodes is not allowed in view only mode\")\n\n\t\tconst tree = this.tree\n\t\tconst clone = deepCloneWithTemplate({\n\t\t\ttree,\n\t\t\tnode,\n\t\t\tinheritOverrides,\n\t\t\trenamedIds,\n\t\t})\n\n\t\tif (!shouldInsert) {\n\t\t\treturn clone\n\t\t}\n\n\t\tconst parent = this.tree.get(node.parentid)\n\n\t\t// a clone replica node cannot be inserted into the original parent\n\t\tif (node.originalid && !clone.originalid) {\n\t\t\tif (parent && isReplicaVariantOrReplicaVariantChild(parent)) {\n\t\t\t\tclone.parentid = parent.originalid\n\t\t\t} else {\n\t\t\t\tclone.parentid = null\n\t\t\t\tscopeStore.insertNode(clone)\n\t\t\t\tconst rect = getCanvasBoundingRectCached(tree, node)\n\n\t\t\t\tclone.set(\n\t\t\t\t\tclone.updateForRect({\n\t\t\t\t\t\trect,\n\t\t\t\t\t\tparentSizeInfo: null,\n\t\t\t\t\t\tconstraintsLocked: false,\n\t\t\t\t\t\tshouldGuessPinToBottom: shouldGuessPinToBottom(tree, node),\n\t\t\t\t\t\tshouldGuessPinToRight: shouldGuessPinToBottom(tree, node),\n\t\t\t\t\t}),\n\t\t\t\t\ttree,\n\t\t\t\t)\n\t\t\t\treturn clone\n\t\t\t}\n\t\t}\n\n\t\t// If the node is from another page, insert the clone in the active page\n\t\tconst fromPage = this.tree.getScopeNodeFor(node)\n\t\tif (fromPage && fromPage.id !== scopeStore.active?.id) {\n\t\t\tscopeStore.insertNode(clone)\n\t\t\treturn clone\n\t\t}\n\n\t\tlet position: number | undefined\n\t\tlet children: CanvasNode[] | ChildList<CanvasNode> | undefined =\n\t\t\tparent && withChildren(parent) ? parent.children : undefined\n\n\t\tif (parent && isReplicaVariantOrReplicaVariantChild(parent) && hasItemsOrderOverride(parent)) {\n\t\t\t// When duplicating in a replica variant stack with items order\n\t\t\t// overrides, the source node's position could be different from the\n\t\t\t// primary node. Use the visual index instead of the source index.\n\t\t\tchildren = parent.getChildrenInVisualOrder()\n\t\t}\n\n\t\tconst nodePosition = children ? children.indexOf(node) : -1\n\t\tif (nodePosition !== -1) position = nodePosition + 1\n\n\t\tscopeStore.insertNode(clone, clone.parentid, position, node.getPrimaryId())\n\t\treturn clone\n\t}\n\n\t// check for masters while removing nodes\n\tprivate removeNodes(ids: Iterable<NodeID>) {\n\t\tconst tree = this.stores.treeStore.getDataTreeOrPartialTree()\n\t\tconst masters: (CanvasNode & IsMaster)[] = []\n\n\t\tfor (const id of ids) {\n\t\t\tthis.removeNode(id, masters)\n\t\t}\n\n\t\t// check again, for all masters we kept, if they still have replica's\n\t\tmasters.forEach(master => {\n\t\t\tif (!TemplateHelper.hasReplicas(tree, master)) {\n\t\t\t\tthis.stores.scopeStore.removeNode(master)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate removeNode(id: NodeID, masters: (CanvasNode & IsMaster)[]) {\n\t\tconst { scopeStore, treeStore, overlayStore, selectionStore } = this.stores\n\t\tconst tree = treeStore.getDataTreeOrPartialTree()\n\t\tconst rootId = tree.root.id\n\n\t\tconst node = tree.get(id)\n\t\tif (!node) return\n\t\tif (isReplicaChild(node)) return\n\n\t\tif (isPrimaryVariant(node)) {\n\t\t\t// Remove all children from the variant.\n\t\t\tif (withChildren(node)) {\n\t\t\t\tfor (const child of node.children) {\n\t\t\t\t\tthis.removeNode(child.id, masters)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Resize the breakpoint to its default height.\n\t\t\tif (isBreakpointVariant(node)) {\n\t\t\t\tassert(isPinnable(node))\n\t\t\t\tnode.set({\n\t\t\t\t\theightType: DimensionType.FixedNumber,\n\t\t\t\t\theight: desktopBreakpointVariantDefault.height,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn\n\t\t}\n\n\t\t// Gesture Variants always inherit from their Top Level Variant,\n\t\t// and are tracked in the Top Level Variant's node.cache.replicaInstances.\n\t\t// This is how we trigger rebuilds to Gesture Variants when Top Level Variants are changed.\n\t\t// So a Top Level Variant is deleted here, we can use this to ensure we also delete it's Gesture Variants.\n\t\tif (isTopLevelVariant(node) && node.cache.replicaInstances) {\n\t\t\tnode.cache.replicaInstances.forEach(replicaId => this.removeNode(replicaId, masters))\n\t\t}\n\n\t\tif (isImportableComponentNode(node)) {\n\t\t\tconst identifier = node.instanceIdentifier\n\n\t\t\t// TODO: by using the partial indexes, this doesn't detach all nodes, likely a bug\n\t\t\tconst treeIndexes = treeStore.getPartialIndexes()\n\t\t\tfor (const codeComponent of treeIndexes.codeComponents) {\n\t\t\t\tif (codeComponent.codeComponentIdentifier === identifier) {\n\t\t\t\t\tContextAction.detachSmartComponentOrWebPageInstance(this, codeComponent, node)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Remove all navigation and variant actions that are targeting this node\n\t\tif (tree.isGroundNode(node)) {\n\t\t\tconst scopeNode = tree.getScopeNodeFor(node)\n\t\t\tif (scopeNode) ContextAction.removeActionsWithTarget(this, scopeNode, node.id)\n\t\t}\n\n\t\t// When deleting an overlay node, also remove the event action that\n\t\t// points to it from the overlay node's parent.\n\t\tif (isFixedOrRelativeOverlay(node)) {\n\t\t\toverlayStore.cleanupOverlay(selectionStore, node.id, node.parentid)\n\t\t}\n\n\t\tif (isRepeatedItem(tree, node)) {\n\t\t\tconst repeater = getParentDataRepeater(tree, node)\n\t\t\tif (repeater) {\n\t\t\t\tresetRepeatedItemOfDataRepeater(repeater)\n\t\t\t}\n\t\t}\n\n\t\tlet movedNode = false\n\t\tfor (const n of node.walk()) {\n\t\t\t// TODO Check and handle shallow/fully loaded scope.\n\t\t\t// This is a list of node ids that may be in other scopes. They\n\t\t\t// may not be fully loaded if they are in shallow scopes, in which case, this is a bug\n\t\t\t// where these slot pointers won't be cleaned up.\n\t\t\tconst links = node.cache.links\n\t\t\tif (links) {\n\t\t\t\tlinks.forEach(linkedId => {\n\t\t\t\t\tconst linkedNode = tree.get(linkedId)\n\t\t\t\t\tif (linkedNode) {\n\t\t\t\t\t\tlinkedNode.asDraft()\n\t\t\t\t\t\tif (isCodeComponentNode(linkedNode) && n.id) {\n\t\t\t\t\t\t\tlinkedNode.removeNodeFromSlotContent(tree, n.id, this.componentLoader)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (!isMaster(n)) continue\n\t\t\t// if there are any masters with replica's move them to the canvas\n\t\t\tif (TemplateHelper.hasReplicas(tree, n)) {\n\t\t\t\tif (node === n) {\n\t\t\t\t\tmovedNode = true\n\t\t\t\t}\n\t\t\t\tconst rect = tree.getRect(n)\n\t\t\t\tTemplateHelper.hideMaster(tree, n)\n\t\t\t\tif (n.parentid !== rootId) {\n\t\t\t\t\ttree.moveNode(n, rootId)\n\t\t\t\t}\n\t\t\t\tmasters.push(\n\t\t\t\t\tn.set(\n\t\t\t\t\t\tn.updateForRect({\n\t\t\t\t\t\t\trect,\n\t\t\t\t\t\t\tparentSizeInfo: null,\n\t\t\t\t\t\t\tconstraintsLocked: false, // Constraints never have to be locked when moving to the canvas level. Will always be top left\n\t\t\t\t\t\t\tshouldGuessPinToBottom: true, // pin guessing doesn't really matter to ground nodes\n\t\t\t\t\t\t\tshouldGuessPinToRight: true, // pin guessing doesn't really matter to ground nodes\n\t\t\t\t\t\t}),\n\t\t\t\t\t\ttree,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (movedNode) return\n\n\t\tif (isWebPageNode(node)) {\n\t\t\tvoid deletePageFromCustomCode(this, node.id)\n\t\t}\n\n\t\tscopeStore.removeNode(node.draftOrCurrent())\n\t}\n\n\tdeleteNode(id: NodeID) {\n\t\tassert(!this.stores.chromeStore.isViewOnly, \"Deleting a node is not allowed in view only mode\")\n\n\t\tthis.removeNodes([id])\n\t}\n\n\tdeleteNodes(ids: Iterable<NodeID>) {\n\t\tassert(!this.stores.chromeStore.isViewOnly, \"Deleting nodes is not allowed in view only mode\")\n\n\t\tthis.removeNodes(ids)\n\t}\n\n\tmoveNode(\n\t\tid: NodeID,\n\t\tparentId: MaybeNodeID = NullID,\n\t\tposition?: number,\n\t\tsourceNodeId?: NodeID,\n\t\ttree: CanvasTree = this.tree,\n\t) {\n\t\tconst { chromeStore, scopeStore } = this.stores\n\t\tassert(!chromeStore.isViewOnly, \"Moving nodes is not allowed in view only mode\")\n\n\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\tconst node = tree.get(id)\n\t\t\tconst parent = tree.get(parentId)\n\t\t\tif (node && parent && !(parent instanceof RootNode) && !(parent instanceof ScopeNode)) {\n\t\t\t\tassert(\n\t\t\t\t\tacceptsChild(tree, parent, node, scopeStore.active.id, this.componentLoader),\n\t\t\t\t\t\"acceptsChild returned false\",\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tconst node = tree.get(id)\n\t\tassert(node, \"Can't find node\", id, \"in tree\")\n\t\tscopeStore.moveNode(node, parentId, position, sourceNodeId, undefined, tree)\n\t}\n\n\t/** used for debugging only */\n\tinspect(filterIds: NodeID[] = [], keys: string[] = []): string {\n\t\treturn inspect(this.tree, filterIds, keys)\n\t}\n\n\t/** used for debugging only */\n\tinstallPerformanceDebugging(reportingFunction: EnginePerformanceReporter | null = null): EnginePerformance {\n\t\tif (this.perf) this.perf.uninstall()\n\t\tthis.perf = new EnginePerformance(reportingFunction).install(this.stores.debugStore)\n\t\treturn this.perf\n\t}\n\n\t/** used for debugging only */\n\tremovePerformanceDebugging() {\n\t\tif (!this.perf) return\n\t\tthis.perf.uninstall()\n\t\tthis.perf = null\n\t}\n\n\tprivate inPanTool(): boolean {\n\t\treturn this.tool.enum === Tools.Pan\n\t}\n\n\tinMoveToolAndHasMoved(): boolean {\n\t\treturn isMoveTool(this.tool) && this.tool.hasMoved\n\t}\n\n\tprivate inResizeToolAndHasMoved(): boolean {\n\t\treturn this.tool instanceof ResizeTool && this.tool.hasMoved\n\t}\n\n\tprivate inPaddingToolAndHasMoved(): boolean {\n\t\treturn this.tool instanceof PaddingTool && this.tool.hasMoved\n\t}\n\n\tprivate inRadiusToolAndHasMoved(): boolean {\n\t\treturn this.tool instanceof RadiusTool && this.tool.mouseHasChanged\n\t}\n\n\tgetStateToken() {\n\t\treturn this.stores.undoRedoManager.getUndoBufferSize()\n\t}\n\n\tgetNodesInMoveToolRootFontSize() {\n\t\treturn isMoveTool(this.tool) && this.tool.hasMoved ? this.tool.nodesInMoveToolBaseFontSize : {}\n\t}\n\n\tresetTreeAndSelectionWithToken(token: number) {\n\t\tconst { treeStore, selectionStore } = this.stores\n\t\tconst selection = treeStore.resetTreeWithToken(token)\n\t\t// Only reset selection if there are changes to reverse\n\t\tif (selection) {\n\t\t\tselectionStore.set(selection)\n\t\t}\n\t\t// Resetting the tree creates edits but we want to ignore those for tracking edit reasons.\n\t\tthis.tree.lineage.ignoreLastEditReason()\n\t}\n}\n\nlet _VekterEngine_shared: VekterEngine | null = null\n\nclass InitialTool extends withClassDiscriminator(\"InitialTool\") implements VekterTool {\n\tenum = Tools.Unknown\n\tengine: VekterEngine\n\n\tconstructor(engine: VekterEngine) {\n\t\tsuper()\n\t\tthis.engine = engine\n\t}\n\n\tstart() {}\n\tupdate() {\n\t\tthis.engine.setTool(Tools.Highlight)\n\t}\n\tstop() {}\n}\n\nconst cloneOverrides = { mutable: true, update: 0, originalid: null }\n\nfunction deepCloneWithTemplate<T extends CanvasNode>({\n\ttree,\n\tnode,\n\tinheritOverrides,\n\tparentid,\n\trenamedIds,\n}: {\n\ttree: CanvasTree\n\tnode: T\n\tinheritOverrides: boolean\n\tparentid?: NodeID\n\trenamedIds?: Map<NodeID, NodeID>\n}): T {\n\tassert(!isRouteSegmentRootNode(node), \"RouteSegmentRootNode is not clonable\", node.id)\n\n\tif (isMaster(node)) {\n\t\tconst replica = TemplateHelper.create(tree, node, {\n\t\t\tinheritsFrom: inheritOverrides ? node.id : undefined,\n\t\t\tduplicatedFrom: createDuplicatedFromIfAllowed(node),\n\t\t})\n\n\t\trenamedIds?.set(node.id, replica.id)\n\n\t\treturn replica\n\t}\n\n\tif (isReplica(node)) {\n\t\tconst master = TemplateHelper.getMaster(tree, node)\n\n\t\tconst replica = TemplateHelper.create(tree, master, {\n\t\t\toverrides: inheritOverrides ? undefined : node.replicaInfo.overrides,\n\t\t\tinheritsFrom: inheritOverrides ? node.id : undefined,\n\t\t\tduplicatedFrom: createDuplicatedFromIfAllowed(node),\n\t\t})\n\n\t\trenamedIds?.set(master.id, replica.id)\n\n\t\t// don't take the master.parentid, which is randomly located\n\t\t// but either use the given parentid, or the original node parentid\n\t\tif (replica.parentid !== node.parentid) {\n\t\t\treplica.parentid = parentid || node.parentid\n\t\t}\n\t\treturn replica as unknown as T\n\t}\n\n\tconst clone = node.cloneEmpty()\n\n\t// Register both the original pair into renamedIds\n\tif (renamedIds) {\n\t\trenamedIds.set(node.originalid ? node.originalid : node.id, clone.id)\n\t}\n\n\t// When cloning a form container, strip the formSaveId from the cloned node and store it in the cache, so we can\n\t// use it during post-processing to copy the form config.\n\tlet stripFormSaveId: Partial<WithFormContainer> | undefined\n\tif (isFormContainer(node) && node.formSaveId) {\n\t\tstripFormSaveId = { formSaveId: undefined }\n\t\t// @NOTE: This is based on the assumption that deepCloneWithTemplate is called locally within the same\n\t\t// project. If this is ever cloning a form from a different project, the source project id needs to be\n\t\t// updated.\n\t\t// @FIXME: we probably need the projectId here for unlinking.\n\t\tclone.cache.formContainerConfigSource = createFormConfigSource(node.getPrimaryId(), node.formSaveId, undefined)\n\t}\n\n\tclone.assign(\n\t\tcloneNodePropsAndStripLocalizedValues(node),\n\t\tcloneOverrides,\n\t\t{\n\t\t\tcache: clone.cache,\n\t\t\tid: clone.id,\n\t\t\tduplicatedFrom: createDuplicatedFromIfAllowed(node),\n\t\t},\n\t\tstripFormSaveId,\n\t)\n\n\tif (parentid) {\n\t\tclone.parentid = parentid\n\t}\n\n\tconst { parentDirected, parentDirectedRect, parentDirectedRowHeightType } = node.cache\n\t// Copying `parentDirected` and `parentDirectedRect` prevents inner autoSized elements\n\t// from breaking when duplicating during the preFreeze phase\n\tif (parentDirected || parentDirectedRect) {\n\t\tclone.cache.parentDirected = parentDirected\n\t\tclone.cache.parentDirectedRect = parentDirectedRect\n\t\tclone.cache.parentDirectedRowHeightType = parentDirectedRowHeightType\n\t}\n\n\tconst children = node.children\n\tif (children) {\n\t\tclone.children = new CanvasChildList(\n\t\t\tchildren.map(child =>\n\t\t\t\tdeepCloneWithTemplate({\n\t\t\t\t\ttree,\n\t\t\t\t\tnode: child,\n\t\t\t\t\tinheritOverrides,\n\t\t\t\t\tparentid: node.id,\n\t\t\t\t\trenamedIds,\n\t\t\t\t}),\n\t\t\t),\n\t\t)\n\t}\n\treturn clone\n}\n\nfunction aspectRatioFromAttibutes(attributes: any) {\n\tif (!withIntrinsicSize(attributes)) return null\n\tconst { intrinsicWidth, intrinsicHeight } = attributes\n\tif (!isNumber(intrinsicWidth) || !isNumber(intrinsicHeight)) return null\n\treturn intrinsicWidth / intrinsicHeight\n}\n\nfunction returnToPreviousToolOnExit(prevTool: VekterTool, newTool: VekterTool) {\n\t// Avoid a circular deps when switching between the zoom tool and the pan tool\n\tif (isZoomTool(newTool.enum)) {\n\t\treturn !isZoomTool(prevTool.enum) && prevTool.enum !== Tools.Pan && prevTool.enum !== Tools.Unknown\n\t}\n\n\tif (newTool.enum === Tools.Pan) {\n\t\treturn prevTool.enum !== Tools.Pan && !isZoomTool(prevTool.enum) && prevTool.enum !== Tools.Unknown\n\t}\n\n\treturn false\n}\n"],
  "mappings": "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",
  "names": ["archy", "chars", "AssetsHelper", "Assets", "onewayMethodTemplate", "voidMethodTemplate", "valueMethodTemplate", "streamMethodTemplate", "ModulesAPIHelper", "ModulesAPI", "onewayMethodTemplate", "voidMethodTemplate", "valueMethodTemplate", "streamMethodTemplate", "UserNotificationsHelper", "UserNotifications", "onewayMethodTemplate", "voidMethodTemplate", "valueMethodTemplate", "streamMethodTemplate", "UserSessionServiceHelper", "UserSessionService", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "meta", "label", "keys", "archy", "style", "import_jsx_runtime", "intersection", "import_jsx_runtime", "update", "assertNever", "textColor", "linkStyleDefaults", "isViewOnly", "cursor", "state", "import_react", "React", "intersection", "update", "withShape", "intersection", "update", "import_react", "React", "import_react", "React", "import_react", "import_jsx_runtime", "import_jsx_runtime", "state", "set", "React", "control", "update", "isViewOnly", "import_react", "import_react", "import_jsx_runtime", "React", "import_react", "closestCurve", "React", "update", "import_react", "withShape", "partOfSelection", "import_react", "import_jsx_runtime", "React", "import_react", "import_jsx_runtime", "React", "closestCurve", "import_jsx_runtime", "closestCurve", "React", "import_react", "import_react", "import_react", "import_jsx_runtime", "React", "withPath", "style", "import_jsx_runtime", "React", "snap", "import_react", "import_react", "import_jsx_runtime", "React", "import_jsx_runtime", "React", "import_jsx_runtime", "React", "import_react", "snap", "React", "snap", "withShape", "import_react", "import_jsx_runtime", "React", "closestCurve", "import_react", "import_react", "import_jsx_runtime", "React", "style", "import_jsx_runtime", "React", "import_react", "import_react", "import_jsx_runtime", "React", "style", "import_react", "import_jsx_runtime", "React", "style", "import_jsx_runtime", "React", "closestCurve", "ignore", "import_react", "import_react", "import_jsx_runtime", "React", "style", "withShape", "import_jsx_runtime", "React", "closestCurve", "intersection", "Constraint", "import_jsx_runtime", "closestCurve", "update", "ignore", "partOfSelection", "React", "set", "placeholder", "timestamp", "cursor", "relativeOffset", "import_jsx_runtime", "state", "Decoration", "DecorationSet", "state", "node", "isViewOnly", "log", "stop", "state", "log", "EventEmitter", "import_react", "update", "React", "isSelectable", "isViewOnly", "action", "withShape", "mouseMoveThreshold", "mouseMoveThreshold", "snap", "frame", "set", "log", "update", "stream", "set", "map", "update", "localId", "handleUpdate", "timestamp", "import_immutable", "ImmutableOrderedMap", "update", "log", "ImmutableMap", "thread", "newComment", "metadata", "map", "numberStrings", "log", "state", "log", "fonts", "cursor", "update", "mouseMoveThreshold", "CommandType", "filter", "res", "res", "map", "schema", "node", "schema", "i", "end", "map", "value", "map", "schema", "stringify", "comment", "str", "schema", "map", "del", "map", "schema", "schema", "del", "seq", "seq", "schema", "float", "float", "intIdentify", "schema", "seq", "schema", "pairs", "keys", "map", "schema", "pairs", "omap", "seq", "floatNaN", "floatExp", "float", "intIdentify", "intResolve", "n", "intStringify", "intOct", "int", "intHex", "schema", "set", "map", "res", "schema", "intOct", "int", "intHex", "floatNaN", "floatExp", "float", "set", "schema", "float", "set", "keys", "tags", "merge", "schema", "res", "BREAK", "SKIP", "REMOVE", "visit", "stringify", "Dictionary", "stringify", "log", "prompt", "stringify", "schema", "isDefaultKit", "log", "breakpoints", "string", "chars", "update", "schema", "text", "repeater", "control", "list", "schema", "state", "update", "log", "fonts", "hasCustomizations", "log", "assert", "stringify", "prompt", "log", "update", "walk", "isDefaultKit", "control", "map", "isDefaultKit", "filter", "collection", "stringify", "log", "insertedNode", "parent", "update", "log", "map", "schema", "stringify", "id", "layoutTemplateNode", "log", "breakpoints", "assert", "assert", "assert", "stringify", "generateUserPrompt", "schema", "generateUserPrompt", "schema", "generateUserPrompt", "schema", "log", "update", "value", "collectionTemplate", "stringify", "generateUserPrompt", "stringify", "log", "systemPrompt", "generateUserPrompt", "schema", "log", "prompt", "jsx", "log", "jsx", "breakpoints", "filter", "shuffle", "collection", "stringify", "meta", "log", "prompt", "setInfo", "item", "stringify", "set", "value", "dictionary", "control", "breakpoints", "set", "stringify", "keys", "prompt", "list", "section", "log", "log", "state", "breakpoints", "log", "togglePreviewVisible", "filter", "filter", "option", "update", "emptyMap", "timestamp", "log", "update", "fetch", "log", "update", "entries", "resolve", "timestamp", "log", "generateScreenshotHTML", "log", "isString", "prompt", "selfClosingTags", "log", "schema", "prompt", "assertNever", "state", "progress", "_previousMainView", "state", "applyToAllGroups", "log", "_nodeChangesReader", "width", "height", "log", "features", "update", "log", "_nodeChangesReader", "_debounce", "meta", "cursor", "log", "log", "keys", "result", "meta", "log", "signal", "keys", "update", "log", "signal", "meta", "update", "log", "requestIdleCallback", "update", "delay", "update", "tokens", "log", "withShape", "prompt", "state", "update", "signal", "node", "keys", "cloneOverrides"]
}
