velloo 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/canvas/assets/index-CSSyvzzo.css +2 -0
  2. package/canvas/assets/index-MXiDRs_Q.js +29 -0
  3. package/canvas/assets/lucide-all-BSrW0hTo.js +1 -0
  4. package/canvas/index.html +2 -2
  5. package/{chunk-bpeezw7w.js → chunk-09385g5r.js} +1 -1
  6. package/{chunk-52hxv18g.js → chunk-0r80246c.js} +1 -1
  7. package/{chunk-k9219kmj.js → chunk-1tdh4h14.js} +1 -1
  8. package/{chunk-as08hzp3.js → chunk-25j8vgpa.js} +1 -1
  9. package/{chunk-3tmsrvaj.js → chunk-33r6266k.js} +1 -1
  10. package/{chunk-d9p6s05n.js → chunk-38ev3cp3.js} +1 -1
  11. package/chunk-3gbmq4jz.js +2 -0
  12. package/{chunk-9nhw49vv.js → chunk-3kqtny5t.js} +1 -1
  13. package/{chunk-td5z2sm4.js → chunk-46xykc71.js} +1 -1
  14. package/chunk-4rvmpsda.js +3 -0
  15. package/{chunk-7bvvbsqy.js → chunk-5qd2ykvw.js} +1 -1
  16. package/{chunk-49cgk5s2.js → chunk-6qfyem23.js} +1 -1
  17. package/{chunk-y5r2w2z3.js → chunk-6z0kpe65.js} +1 -1
  18. package/{chunk-nycs0z7h.js → chunk-7cktk5qr.js} +1 -1
  19. package/chunk-8g5ghy46.js +5 -0
  20. package/chunk-8krqgzny.js +2 -0
  21. package/{chunk-jx11jvq8.js → chunk-8sfx5x8k.js} +1 -1
  22. package/chunk-8yadb6xz.js +5 -0
  23. package/{chunk-k6n249vb.js → chunk-8yz604tw.js} +1 -1
  24. package/{chunk-dsks52m7.js → chunk-c5zjen06.js} +1 -1
  25. package/{chunk-bvmtq0vn.js → chunk-cdxy4xzs.js} +1 -1
  26. package/chunk-cgzhcvsj.js +2 -0
  27. package/{chunk-k7sehkm8.js → chunk-e56eb38j.js} +1 -1
  28. package/{chunk-5ezzc1h2.js → chunk-egccxmed.js} +5 -5
  29. package/chunk-gsne0ap4.js +2 -0
  30. package/chunk-hzjzmkp6.js +6 -0
  31. package/{chunk-wa6qamwh.js → chunk-jtsn41cs.js} +1 -1
  32. package/{chunk-4nqr089t.js → chunk-k10n8na7.js} +1 -1
  33. package/{chunk-1jzhw3p4.js → chunk-n5acf0s3.js} +1 -1
  34. package/chunk-nc5k1ez4.js +2 -0
  35. package/chunk-njhdn9j0.js +4 -0
  36. package/{chunk-kz4423th.js → chunk-q4d60wr3.js} +1 -1
  37. package/{chunk-9g4tr0r6.js → chunk-rsy246re.js} +1 -1
  38. package/{chunk-wzngjjeb.js → chunk-syg6k8m0.js} +1 -1
  39. package/{chunk-wcqqx6tz.js → chunk-t4zss1tk.js} +1 -1
  40. package/{chunk-n9kcxaj7.js → chunk-t8xk4thc.js} +1 -1
  41. package/{chunk-7k7dpj5y.js → chunk-tkvb3wb8.js} +1 -1
  42. package/{chunk-cxzkkn12.js → chunk-tqwe5tc3.js} +1 -1
  43. package/{chunk-7njj1qmq.js → chunk-v0syg2hx.js} +1 -1
  44. package/chunk-va9v9y5m.js +2 -0
  45. package/{chunk-3g3dqej3.js → chunk-vbe2r4kv.js} +1 -1
  46. package/{chunk-qgwhd4n6.js → chunk-vh4144az.js} +1 -1
  47. package/{chunk-m3czg1tt.js → chunk-y0rwf1ze.js} +1 -1
  48. package/{chunk-maz6z7tz.js → chunk-yjmawrv5.js} +1 -1
  49. package/{chunk-yeh9gb5w.js → chunk-ys3s5gaa.js} +1 -1
  50. package/{chunk-qdnb2t6a.js → chunk-z1r0sc3k.js} +1 -1
  51. package/{chunk-1n5kmsxb.js → chunk-zkn1m8tw.js} +1 -1
  52. package/cli.js +1 -1
  53. package/package.json +1 -1
  54. package/canvas/assets/index-CqXW6xA_.js +0 -29
  55. package/canvas/assets/index-gB0StCrx.css +0 -2
  56. package/canvas/assets/lucide-all-C_CNpsMs.js +0 -1
  57. package/chunk-5wv5a52y.js +0 -2
  58. package/chunk-6nzqhfqq.js +0 -5
  59. package/chunk-6zz9kfbd.js +0 -3
  60. package/chunk-788t8y5x.js +0 -2
  61. package/chunk-9f22qnge.js +0 -2
  62. package/chunk-hfzg98c8.js +0 -4
  63. package/chunk-n9t36h0q.js +0 -2
  64. package/chunk-nr3ej3qf.js +0 -5
  65. package/chunk-t5bb30zy.js +0 -3
  66. package/chunk-tbmkq7wy.js +0 -6
  67. package/chunk-tc4mzzfw.js +0 -2
  68. package/chunk-xyfed1j0.js +0 -2
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{clone,normalizeParams,own,installLazyProp,NEVER,$constructor,parse,parseAsync,safeParse,safeParseAsync,$ZodType,$ZodObject,_coercedNumber,toJSONSchema,ZodError,string,url,ZodNumber,number,boolean,_null,any,unknown,array,object,strictObject,looseObject,union,discriminatedUnion,intersection,record,_enum,literal,ZodOptional,optional,custom,preprocess,datetime,exports_iso,AnnotationSchema,CanvasNoteSchema,AssetsFileSchema,EMPTY_ASSETS_FILE,MAX_BOARD_NAME_LENGTH,BoardSchema,isArchived,CommentAnchorSchema,CommentAuthorSchema,CommentThreadSchema,ExtensionPropDescriptorSchema,ExtensionSchema,RepoComponentsManifestSchema,designNameIssue,isDesignName,toDesignName,RepoManifestSchema,REPO_MANIFEST_FILE,normalizeRepoManifest,CURRENT_SCHEMA_VERSION,schemaVersionOf,APP_PATH_PREFIX,ViewportPresetSchema,ConfigSchema,isCssIdent,sanitizeCssTokenValue,neutralizeCssText,sanitizeGoogleFontSpec,pascalizeIconName,isComponentNode,isSnippetInstance,isParamRef,NodeIdSchema,repoImportIssue,isRepoNode,repoKey,parseRepoKey,nodeId,ScreenSchema,SnippetSchema,resolveSnippetArgs,substituteSnippetParams,applySnippetOverrides,applySnippetExtraClassName,svgLooksActive,sanitizeSvgMarkup,ColorsSchema,resolveColors,ThemeSchema,DEFAULT_TYPESET_NAME,isTypesetName,TYPESET_SCALE_NAMES,resolveHeadingLevel,headingClasses,textClasses,headingInlineStyle,textInlineStyle,typesetSafelist,typesetUtilityClasses,typesetV3FontSize,typesetThemeTokens,resolveTypeset,typesetCss,typesetScale,findDuplicateIds,ViewportSchema}from"./chunk-nte0t7v3.js";import{require_react_development,buildBoardComposite,CHROMIUM_INSTALL_CMD,isCaptureTimeout,sessionStatePath,captureDir,listCaptures,readCaptureManifest,deleteCapture,isSafeCaptureId,isSafeCaptureFile,diffPngs,downscalePng,resizePng,pngSize,cropPng,sideBySidePng,unionRegion,HeadedBrowserMissingError,startCaptureSession,resolveSnippetBody,resolveSnippetBodyForEdit,snippetParamPlaceholder,RENDER_ERROR_META,screenshotCompareBuffer,pdfPageBuffer,pdfDeckBuffer,RenderGuardLimitError,collectSerializedRefs,serializeTree,renderBodyGuarded,renderScreen,screenshotBuffer,probeCanvasMount,captureScreenshot,measureRendered,captureUrlScreenshot,classifyCapture}from"./chunk-c4fym47a.js";import{ok,err,map,tryCatchAsync,$,DoAsync,isCloudErrorCode,IntentCatalogResponseSchema,GenerateResponseSchema,FeedbackIssuerResponseSchema,FeedbackSignaturesResponseSchema,unreachable,loggedOut,protocolViolation,insecureCloudUrl,invalidRequest,readFailure,cloudFailure,describeCloudError,cloudJson,cloudFetch,LocatorSchema,AddNodeBody,normalizeAddNode,updatePropsShape,UpdatePropsBody,ApplyClassesBody,removeNodeShape,RemoveNodeBody,moveNodeShape,MoveNodeBody,setNodeIdShape,SetNodeIdBody,addScreenShape,AddScreenBody,removeScreenShape,RemoveScreenBody,SetScreenTreeBody,updateScreenShape,addBoardShape,AddBoardBody,updateBoardShape,UpdateBoardBody,removeBoardShape,RemoveBoardBody,reorderBoardsShape,ReorderBoardsBody,AddBoardGroupBody,UpdateBoardGroupBody,RemoveBoardGroupBody,ReorderBoardGroupsBody,addFrameShape,AddFrameBody,updateFrameShape,UpdateFrameBody,removeFrameShape,RemoveFrameBody,MoveFrameBody,addSnippetShape,AddSnippetBody,updateSnippetShape,UpdateSnippetBody,removeSnippetShape,RemoveSnippetBody,InstantiateSnippetBody,UpdateSnippetArgsBody,updateSnippetInstanceShape,UpdateSnippetInstanceBody,normalizeUpdateSnippetInstance,AddAnnotationBody,UpdateAnnotationBody,RemoveAnnotationBody,AddNoteBody,UpdateNoteBody,RemoveNoteBody,updateViewportPresetsShape,UpdateViewportPresetsBody,UpdateDefaultsBody,UpdateCodegenBody,UpdateDesignNameBody,UpdateFeedbackBody}from"./chunk-n9t36h0q.js";import{__toESM,__commonJS,__require}from"./chunk-2smsg2ct.js";var require_react_jsx_dev_runtime_development=__commonJS(function(exports){var React=__toESM(require_react_development());(function(){function getComponentNameFromType(type){if(type==null)return null;if(typeof type==="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type==="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type==="object")switch(typeof type.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return type.displayName||"Context";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;return type=type.displayName,type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef"),type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload,type=type._init;try{return getComponentNameFromType(type(innerType))}catch(x){}}return null}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=!1}catch(e){JSCompiler_inline_result=!0}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error,JSCompiler_inline_result$jscomp$0=typeof Symbol==="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";return JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0),testStringCoercion(value)}}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type==="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch(x){return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return!1}return config.key!==void 0}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=!0,Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:!0})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);return didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),componentName=this.props.ref,componentName!==void 0?componentName:null}function ReactElement(type,key,props,owner,debugStack,debugTask){var refProp=props.ref;return type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner},(refProp!==void 0?refProp:null)!==null?Object.defineProperty(type,"ref",{enumerable:!1,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:!1,value:null}),type._store={},Object.defineProperty(type._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(type,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(type,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:debugStack}),Object.defineProperty(type,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:debugTask}),Object.freeze&&(Object.freeze(type.props),Object.freeze(type)),type}function jsxDEVImpl(type,config,maybeKey,isStaticChildren,debugStack,debugTask){var children=config.children;if(children!==void 0)if(isStaticChildren)if(isArrayImpl(children)){for(isStaticChildren=0;isStaticChildren<children.length;isStaticChildren++)validateChildKeys(children[isStaticChildren]);Object.freeze&&Object.freeze(children)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else validateChildKeys(children);if(hasOwnProperty.call(config,"key")){children=getComponentNameFromType(type);var keys=Object.keys(config).filter(function(k){return k!=="key"});isStaticChildren=0<keys.length?"{key: someKey, "+keys.join(": ..., ")+": ...}":"{key: someKey}",didWarnAboutKeySpread[children+isStaticChildren]||(keys=0<keys.length?"{"+keys.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ import{clone,normalizeParams,own,installLazyProp,NEVER,$constructor,parse,parseAsync,safeParse,safeParseAsync,$ZodType,$ZodObject,_coercedNumber,toJSONSchema,ZodError,string,url,ZodNumber,number,boolean,_null,any,unknown,array,object,strictObject,looseObject,union,discriminatedUnion,intersection,record,_enum,literal,ZodOptional,optional,custom,preprocess,datetime,exports_iso,AnnotationSchema,CanvasNoteSchema,AssetsFileSchema,EMPTY_ASSETS_FILE,MAX_BOARD_NAME_LENGTH,BoardSchema,isArchived,CommentAnchorSchema,CommentAuthorSchema,CommentThreadSchema,ExtensionPropDescriptorSchema,ExtensionSchema,RepoComponentsManifestSchema,designNameIssue,isDesignName,toDesignName,RepoManifestSchema,REPO_MANIFEST_FILE,normalizeRepoManifest,CURRENT_SCHEMA_VERSION,schemaVersionOf,APP_PATH_PREFIX,ViewportPresetSchema,ConfigSchema,isCssIdent,sanitizeCssTokenValue,neutralizeCssText,sanitizeGoogleFontSpec,pascalizeIconName,isComponentNode,isSnippetInstance,isParamRef,NodeIdSchema,repoImportIssue,isRepoNode,repoKey,parseRepoKey,nodeId,ScreenSchema,SnippetSchema,resolveSnippetArgs,substituteSnippetParams,applySnippetOverrides,applySnippetExtraClassName,svgLooksActive,sanitizeSvgMarkup,ColorsSchema,resolveColors,ThemeSchema,DEFAULT_TYPESET_NAME,isTypesetName,TYPESET_SCALE_NAMES,resolveHeadingLevel,headingClasses,textClasses,headingInlineStyle,textInlineStyle,typesetSafelist,typesetUtilityClasses,typesetV3FontSize,typesetThemeTokens,resolveTypeset,typesetCss,typesetScale,findDuplicateIds,ViewportSchema}from"./chunk-nte0t7v3.js";import{require_react_development,buildBoardComposite,CHROMIUM_INSTALL_CMD,isCaptureTimeout,sessionStatePath,captureDir,listCaptures,readCaptureManifest,deleteCapture,isSafeCaptureId,isSafeCaptureFile,diffPngs,downscalePng,resizePng,pngSize,cropPng,sideBySidePng,unionRegion,HeadedBrowserMissingError,startCaptureSession,resolveSnippetBody,resolveSnippetBodyForEdit,snippetParamPlaceholder,RENDER_ERROR_META,screenshotCompareBuffer,pdfPageBuffer,pdfDeckBuffer,RenderGuardLimitError,collectSerializedRefs,serializeTree,renderBodyGuarded,renderScreen,screenshotBuffer,probeCanvasMount,captureScreenshot,measureRendered,captureUrlScreenshot,classifyCapture}from"./chunk-c4fym47a.js";import{ok,err,map,tryCatchAsync,$,DoAsync,isCloudErrorCode,IntentCatalogResponseSchema,GenerateResponseSchema,FeedbackIssuerResponseSchema,FeedbackSignaturesResponseSchema,unreachable,loggedOut,protocolViolation,insecureCloudUrl,invalidRequest,readFailure,cloudFailure,describeCloudError,cloudJson,cloudFetch,LocatorSchema,AddNodeBody,normalizeAddNode,updatePropsShape,UpdatePropsBody,ApplyClassesBody,removeNodeShape,RemoveNodeBody,moveNodeShape,MoveNodeBody,setNodeIdShape,SetNodeIdBody,addScreenShape,AddScreenBody,removeScreenShape,RemoveScreenBody,SetScreenTreeBody,updateScreenShape,addBoardShape,AddBoardBody,updateBoardShape,UpdateBoardBody,removeBoardShape,RemoveBoardBody,reorderBoardsShape,ReorderBoardsBody,AddBoardGroupBody,UpdateBoardGroupBody,RemoveBoardGroupBody,ReorderBoardGroupsBody,addFrameShape,AddFrameBody,updateFrameShape,UpdateFrameBody,removeFrameShape,RemoveFrameBody,MoveFrameBody,addSnippetShape,AddSnippetBody,updateSnippetShape,UpdateSnippetBody,removeSnippetShape,RemoveSnippetBody,InstantiateSnippetBody,UpdateSnippetArgsBody,updateSnippetInstanceShape,UpdateSnippetInstanceBody,normalizeUpdateSnippetInstance,AddAnnotationBody,UpdateAnnotationBody,RemoveAnnotationBody,AddNoteBody,UpdateNoteBody,RemoveNoteBody,updateViewportPresetsShape,UpdateViewportPresetsBody,UpdateDefaultsBody,UpdateCodegenBody,UpdateDesignNameBody,UpdateFeedbackBody}from"./chunk-gsne0ap4.js";import{__toESM,__commonJS,__require}from"./chunk-2smsg2ct.js";var require_react_jsx_dev_runtime_development=__commonJS(function(exports){var React=__toESM(require_react_development());(function(){function getComponentNameFromType(type){if(type==null)return null;if(typeof type==="function")return type.$$typeof===REACT_CLIENT_REFERENCE?null:type.displayName||type.name||null;if(typeof type==="string")return type;switch(type){case REACT_FRAGMENT_TYPE:return"Fragment";case REACT_PROFILER_TYPE:return"Profiler";case REACT_STRICT_MODE_TYPE:return"StrictMode";case REACT_SUSPENSE_TYPE:return"Suspense";case REACT_SUSPENSE_LIST_TYPE:return"SuspenseList";case REACT_ACTIVITY_TYPE:return"Activity"}if(typeof type==="object")switch(typeof type.tag==="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),type.$$typeof){case REACT_PORTAL_TYPE:return"Portal";case REACT_CONTEXT_TYPE:return type.displayName||"Context";case REACT_CONSUMER_TYPE:return(type._context.displayName||"Context")+".Consumer";case REACT_FORWARD_REF_TYPE:var innerType=type.render;return type=type.displayName,type||(type=innerType.displayName||innerType.name||"",type=type!==""?"ForwardRef("+type+")":"ForwardRef"),type;case REACT_MEMO_TYPE:return innerType=type.displayName||null,innerType!==null?innerType:getComponentNameFromType(type.type)||"Memo";case REACT_LAZY_TYPE:innerType=type._payload,type=type._init;try{return getComponentNameFromType(type(innerType))}catch(x){}}return null}function testStringCoercion(value){return""+value}function checkKeyStringCoercion(value){try{testStringCoercion(value);var JSCompiler_inline_result=!1}catch(e){JSCompiler_inline_result=!0}if(JSCompiler_inline_result){JSCompiler_inline_result=console;var JSCompiler_temp_const=JSCompiler_inline_result.error,JSCompiler_inline_result$jscomp$0=typeof Symbol==="function"&&Symbol.toStringTag&&value[Symbol.toStringTag]||value.constructor.name||"Object";return JSCompiler_temp_const.call(JSCompiler_inline_result,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",JSCompiler_inline_result$jscomp$0),testStringCoercion(value)}}function getTaskName(type){if(type===REACT_FRAGMENT_TYPE)return"<>";if(typeof type==="object"&&type!==null&&type.$$typeof===REACT_LAZY_TYPE)return"<...>";try{var name=getComponentNameFromType(type);return name?"<"+name+">":"<...>"}catch(x){return"<...>"}}function getOwner(){var dispatcher=ReactSharedInternals.A;return dispatcher===null?null:dispatcher.getOwner()}function UnknownOwner(){return Error("react-stack-top-frame")}function hasValidKey(config){if(hasOwnProperty.call(config,"key")){var getter=Object.getOwnPropertyDescriptor(config,"key").get;if(getter&&getter.isReactWarning)return!1}return config.key!==void 0}function defineKeyPropWarningGetter(props,displayName){function warnAboutAccessingKey(){specialPropKeyWarningShown||(specialPropKeyWarningShown=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",displayName))}warnAboutAccessingKey.isReactWarning=!0,Object.defineProperty(props,"key",{get:warnAboutAccessingKey,configurable:!0})}function elementRefGetterWithDeprecationWarning(){var componentName=getComponentNameFromType(this.type);return didWarnAboutElementRef[componentName]||(didWarnAboutElementRef[componentName]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),componentName=this.props.ref,componentName!==void 0?componentName:null}function ReactElement(type,key,props,owner,debugStack,debugTask){var refProp=props.ref;return type={$$typeof:REACT_ELEMENT_TYPE,type,key,props,_owner:owner},(refProp!==void 0?refProp:null)!==null?Object.defineProperty(type,"ref",{enumerable:!1,get:elementRefGetterWithDeprecationWarning}):Object.defineProperty(type,"ref",{enumerable:!1,value:null}),type._store={},Object.defineProperty(type._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(type,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(type,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:debugStack}),Object.defineProperty(type,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:debugTask}),Object.freeze&&(Object.freeze(type.props),Object.freeze(type)),type}function jsxDEVImpl(type,config,maybeKey,isStaticChildren,debugStack,debugTask){var children=config.children;if(children!==void 0)if(isStaticChildren)if(isArrayImpl(children)){for(isStaticChildren=0;isStaticChildren<children.length;isStaticChildren++)validateChildKeys(children[isStaticChildren]);Object.freeze&&Object.freeze(children)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else validateChildKeys(children);if(hasOwnProperty.call(config,"key")){children=getComponentNameFromType(type);var keys=Object.keys(config).filter(function(k){return k!=="key"});isStaticChildren=0<keys.length?"{key: someKey, "+keys.join(": ..., ")+": ...}":"{key: someKey}",didWarnAboutKeySpread[children+isStaticChildren]||(keys=0<keys.length?"{"+keys.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
3
3
  let props = %s;
4
4
  <%s {...props} />
5
5
  React keys must be passed directly to JSX without using spread:
@@ -125,7 +125,7 @@ ${registry}
125
125
  };
126
126
  export { React, createRoot, ErrorBoundary };
127
127
  `}function registryFor(source){let{folder}=source;return(screen)=>registryForScreen(screen,source.providers,source.defaultProvider,folder.config.extensions??{},folder.config.styling?.framework)}function boardsPlacing(folder,screenId){return[...folder.boards.values()].filter((board)=>board.frames.some((frame)=>frame.screen===screenId)).map((board)=>({id:board.id,name:board.name}))}function preflightScreens(source,screens){let registry=registryFor(source),out=[];for(let screen of screens){let where={screenId:screen.id,screenName:screen.name,boards:boardsPlacing(source.folder,screen.id)};try{for(let failure of renderBodyGuarded(screen,registry(screen),source.folder.snippets).failures)out.push({...where,componentId:failure.componentId,reason:failure.reason})}catch(error){if(error instanceof RenderGuardLimitError)for(let failure of error.failures)out.push({...where,componentId:failure.componentId,reason:failure.reason});out.push({...where,componentId:null,reason:error instanceof Error?error.message:String(error)})}}return out}function screenById(folder,id){return id===void 0?void 0:folder.screens.get(id)}function screensForBoards(folder,boardIds){let seen=new Map;for(let boardId of boardIds){let board=folder.boards.get(boardId);if(!board)continue;for(let frame of board.frames){let screen=screenById(folder,frame.screen);if(screen&&!seen.has(screen.id))seen.set(screen.id,screen)}}return[...seen.values()]}function screensForExportTarget(folder,kind,id){if(kind==="board")return screensForBoards(folder,[id]);if(kind==="screen"){let screen=folder.screens.get(id);return screen?[screen]:[]}for(let board of folder.boards.values()){let frame=board.frames.find((f)=>f.id===id);if(!frame)continue;let screen=screenById(folder,frame.screen);return screen?[screen]:[]}return[]}import{existsSync as existsSync5}from"fs";import{dirname as dirname9,join as join13}from"path";import{fileURLToPath}from"url";var here=dirname9(fileURLToPath(import.meta.url));function resolveDir(){return[process.env.VELLOO_HELPERS_SRC,join13(here,"pkgs","helpers","src"),here].filter((p)=>Boolean(p)).find((d)=>existsSync5(join13(d,"heading.tsx")))??here}var helpersComponentsDir=resolveDir(),HELPER_SOURCE_FILES={Box:"box.tsx",Divider:"divider.tsx",Gradient:"gradient.tsx",Heading:"heading.tsx",Icon:"icon.tsx",Image:"image.tsx",Layer:"layer.tsx",Placeholder:"placeholder.tsx",Prose:"prose.tsx",SVG:"svg.tsx",Text:"text.tsx"};function helperSourcePath(id){let file=HELPER_SOURCE_FILES[id];return file?join13(helpersComponentsDir,file):void 0}import{existsSync as existsSync6,readdirSync as readdirSync2,readFileSync as readFileSync5,realpathSync as realpathSync3}from"fs";import{join as join14,relative as relative2,resolve as resolve5,sep as sep2}from"path";var SWITCH_DESIGN_META="velloo/switchDesign",PICK_REASONS=["cwd","only","default","arbitrary"];function parseMcpSessionUrl(url){let params=new URL(url??"/mcp","http://velloo.local").searchParams,pick=params.get("pick");return{switchable:params.get("switch")==="1",pick:PICK_REASONS.find((reason)=>reason===pick)}}function withMcpSessionUrl(url,session){let parsed=new URL(url);if(session.switchable)parsed.searchParams.set("switch","1");else parsed.searchParams.delete("switch");if(session.pick)parsed.searchParams.set("pick",session.pick);else parsed.searchParams.delete("pick");return parsed.toString()}function realOr3(path){return existsSync6(path)?realpathSync3(path):resolve5(path)}function usableDesigns(set){return(set?.designs??[]).filter((d)=>d.exists&&!d.outsideRepo&&set?.byName.get(d.name)===d)}async function sessionDesigns(root,current,options){let set=await designsFor(root).catch(()=>null),here=realOr3(root),others=usableDesigns(set).filter((d)=>realOr3(d.root)!==here);if(others.length===0)return null;let names=[...new Set([current,...others.map((d)=>d.name)])].sort();return{current,names,switchable:options.switchable,pick:options.pick}}function designsInstruction(designs){let{current,names}=designs,list=names.map((n)=>n===current?`\`${n}\` (this session)`:`\`${n}\``),move=designs.switchable?"`switch_design` moves to another":"to work on another, the user reconnects with `velloo mcp <name>`",lines=[`**Design: \`${current}\`** \u2014 one of ${names.length} here: ${list.join(", ")}. Operations target \`${current}\`; ${move}. Tell the user when you switch.`];if(designs.pick==="arbitrary")lines.unshift(`**No design was specified, so this session opened \`${current}\`.** Confirm which design the user means before changing anything.`);return lines}function countJson(dir,skipSuffix){try{return readdirSync2(dir).filter((f)=>f.endsWith(".json")&&!f.endsWith(skipSuffix)).length}catch{return 0}}function defaultLibraryOf(folder){try{let config=JSON.parse(readFileSync5(join14(folder,".design","config.json"),"utf8")),key=typeof config.defaultLibrary==="string"?config.defaultLibrary:void 0,id=key?config.libraries?.[key]?.id:void 0;return typeof id==="string"?id:void 0}catch{return}}async function listDesigns(root){let set=await designsFor(root),here=realOr3(root);return usableDesigns(set).map((d)=>({name:d.name,path:d.local||!set?.repo?d.root:relative2(set.repo.dir,d.root).split(sep2).join("/")||".",current:realOr3(d.root)===here,local:d.local!==null,library:defaultLibraryOf(d.root),boards:countJson(join14(d.root,"boards"),".notes.json"),screens:countJson(join14(d.root,"screens"),".annotations.json")}))}async function switchTarget(root,name){let set=await designsFor(root),target=usableDesigns(set).find((d)=>d.name===name);if(!target)return{ok:!1,error:{kind:"UnknownDesign",name,designs:usableDesigns(set).map((d)=>d.name)}};return{ok:!0,directive:{name:target.name,root:target.root}}}function summarizeIssues(issues,acceptedKeys){let lines=[...new Set(issues.map((issue)=>describe(issue,acceptedKeys)).filter(Boolean))];if(lines.length===0)return;let shown=lines.slice(0,MAX_LINES),rest=lines.length-shown.length;return rest>0?`${shown.join(" ")} (+${rest} more \u2014 see \`issues\`.)`:shown.join(" ")}var MAX_LINES=4;function describe(issue,acceptedKeys){let at=pathOf(issue.path);switch(issue.code){case"unrecognized_keys":{let keys=issue.keys,nested=issue.path.length>0,suggestions=nested?[]:keys.map((key)=>({key,match:closest(key,acceptedKeys)})).filter((s)=>s.match!==void 0).map((s)=>`use \`${s.match}\` instead of \`${s.key}\``);return[`${plural(keys.length,"Unknown argument")} ${list(keys)}${at?` at ${at}`:""}.`,suggestions.length>0?`Did you mean: ${suggestions.join("; ")}?`:"",!nested&&acceptedKeys.length>0?`This operation accepts ${list(acceptedKeys)}.`:""].filter(Boolean).join(" ")}case"invalid_union":{let shapes=[...new Set(unionExpectations(issue))],detail=branchDetail(issue);return`\`${at||"the arguments"}\` doesn't match any accepted shape \u2014 it takes ${list(shapes.length>0?shapes:["one of the documented shapes"])}.${detail?` ${detail}`:""}`}case"invalid_type":return`\`${at||"the arguments"}\` expects ${issue.expected}, got ${received(issue)}.`;default:return issue.message?`${at?`\`${at}\`: `:""}${issue.message}`:""}}function unionExpectations(issue){let out=[];for(let branch of issue.errors)for(let inner of branch){if(inner.path.length>0)continue;if(inner.code==="invalid_type")out.push(String(inner.expected));else if(inner.code==="invalid_value")out.push(...inner.values.map(String))}return out}function branchDetail(issue){for(let branch of issue.errors)for(let inner of branch){if(inner.path.length===0)continue;let at=pathOf([...issue.path,...inner.path]);return inner.code==="invalid_type"?`The closest shape wants \`${at}\` to be ${inner.expected}, got ${received(inner)}.`:`The closest shape wants \`${at}\`: ${inner.message}`}return""}function received(issue){return/received (\w+)/.exec(issue.message)?.[1]??"something else"}function pathOf(path){return path.map(String).join(".")}function list(values){let quoted=values.map((v)=>`\`${v}\``);if(quoted.length<=1)return quoted.join("");return`${quoted.slice(0,-1).join(", ")} and ${quoted.at(-1)}`}function plural(count,word){return count===1?word:`${word}s`}function closest(key,accepted){let lower=key.toLowerCase(),contains=accepted.find((candidate)=>{let other=candidate.toLowerCase();return other.includes(lower)||lower.includes(other)});if(contains)return contains;return accepted.find((candidate)=>editDistance(lower,candidate.toLowerCase())<=2)}function editDistance(a,b){if(Math.abs(a.length-b.length)>2)return 99;let prev=Array.from({length:b.length+1},(_,i)=>i);for(let i=1;i<=a.length;i++){let row=[i];for(let j=1;j<=b.length;j++)row[j]=Math.min((prev[j]??0)+1,(row[j-1]??0)+1,(prev[j-1]??0)+(a[i-1]===b[j-1]?0:1));prev=row}return prev[b.length]??99}function jsonResult(value){return{content:[{type:"text",text:JSON.stringify(value)}]}}function structuredResult(value,...extra){return{content:[{type:"text",text:JSON.stringify(value)},...extra],structuredContent:value}}function errorResult(error){return{isError:!0,content:[{type:"text",text:JSON.stringify(typeof error==="string"?{kind:"Error",message:error}:error)}]}}function toMcp(result){return result.ok?jsonResult(result.value):errorResult(result.error)}var MCP_SURFACE_MODES=["guided","full"],DEFAULT_MCP_SURFACE={mode:"guided"},LEGACY_SURFACE_ALIASES={profile:"full"};function parseMcpSurfaceSelection(modeValue){let raw=modeValue||DEFAULT_MCP_SURFACE.mode,mode=LEGACY_SURFACE_ALIASES[raw]??raw;if(!MCP_SURFACE_MODES.includes(mode))return{ok:!1,error:`unknown MCP surface "${raw}"; expected ${MCP_SURFACE_MODES.join(", ")}`};return{ok:!0,selection:{mode}}}function parseMcpSurfaceUrl(url){let parsed=new URL(url??"/mcp","http://velloo.local");return parseMcpSurfaceSelection(parsed.searchParams.get("surface"))}function withMcpSurfaceUrl(url,selection){let parsed=new URL(url);return parsed.searchParams.set("surface",selection.mode),parsed.searchParams.delete("profile"),parsed.toString()}function schemaJson(tool){if(!tool.inputSchema)return{type:"object",properties:{},additionalProperties:!1};try{return toJSONSchema(tool.inputSchema,{io:"input"})}catch{return{type:"object",description:"Schema is not representable as JSON Schema"}}}function acceptedKeys(schema){let properties=schema.properties;return properties&&typeof properties==="object"?Object.keys(properties):[]}function operationHelp(operation,tool,schema=schemaJson(tool)){return{operation,description:tool.description??"",inputSchema:schema,annotations:tool.annotations??{}}}function errorTextOf(result){return result.content.filter((part)=>part.type==="text").map((part)=>part.text).join(" ").slice(0,400)}function appendSchemaHelp(result,operation,tool){if(result.isError!==!0)return result;return{...result,content:[...result.content,{type:"text",text:JSON.stringify({kind:"OperationSchemaHelp",...operationHelp(operation,tool)})}]}}function applyMcpToolSurface(mcp,selection){let original=mcp.registerTool.bind(mcp),native=new Map,registeringNative=!0,patched=(name,config,cb)=>{let registered=original(name,config,cb);if(registeringNative){if(native.set(name,registered),selection.mode!=="full")registered.disable()}return registered};mcp.registerTool=patched;let invoke=async(operation,args,extra)=>{let tool=native.get(operation);if(!tool)return errorResult({kind:"UnknownOperation",operation});if(tool.inputSchema){let parsed=await tool.inputSchema.safeParseAsync(args);if(!parsed.success){let schema=schemaJson(tool),problem=summarizeIssues(parsed.error.issues,acceptedKeys(schema));return errorResult({kind:"InvalidOperationArguments",operation,...problem?{problem}:{},issues:parsed.error.issues,...operationHelp(operation,tool,schema)})}return appendSchemaHelp(await tool.handler(parsed.data,extra),operation,tool)}return appendSchemaHelp(await tool.handler(extra,void 0),operation,tool)};return{nativeTools:()=>native,finish(){if(registeringNative=!1,selection.mode!=="guided")return;let operation=_enum([...native.keys()]);mcp.registerTool("call_velloo",{description:"Call one native Velloo operation. Failed calls include the exact correction schema.",inputSchema:{operation,arguments:record(string(),unknown()).describe("Arguments object for the native operation")}},async({operation:name,arguments:args},extra)=>invoke(name,args,extra)),mcp.registerTool("run_velloo_plan",{description:"Run up to eight native Velloo calls sequentially, stopping on the first error by default.",inputSchema:{calls:array(object({operation,arguments:record(string(),unknown())})).min(1).max(8),stopOnError:boolean().default(!0)}},async({calls,stopOnError},extra)=>{let content=[],failedAt=null,failures=[];for(let[index,call]of calls.entries()){let result=call.operation==="switch_design"?errorResult({kind:"SwitchDesignInPlan",message:"Call switch_design on its own, then plan against the new design."}):await invoke(call.operation,call.arguments,extra);if(content.push({type:"text",text:JSON.stringify({index,operation:call.operation,isError:result.isError===!0})}),content.push(...result.content),result.isError===!0){if(failures.push({index,operation:call.operation,error:errorTextOf(result)}),stopOnError!==!1){failedAt=index;break}}}let failure=failures.at(-1),summary=failedAt===null?{kind:"PlanCompleted",completed:calls.length-failures.length,...failures.length>0?{failed:failures}:{}}:{kind:"PlanFailed",failedAt,completed:failedAt,operation:failure?.operation,error:failure?.error,remaining:calls.length-failedAt-1};return{...failedAt===null?{}:{isError:!0},content:[{type:"text",text:JSON.stringify(summary)},...content]}}),mcp.registerTool("operation_schema",{description:"Return the exact schema and description for one native operation.",inputSchema:{operation}},async({operation:name})=>{let tool=native.get(name);return tool?jsonResult(operationHelp(name,tool)):errorResult({kind:"UnknownOperation",operation:name})})}}}import{mkdir as mkdir8,readFile as readFile6}from"fs/promises";import{homedir as homedir3}from"os";import{dirname as dirname10,join as join15}from"path";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(message){this.toString=function(){return"CORRUPT: "+this.message},this.message=message},invalid:function(message){this.toString=function(){return"INVALID: "+this.message},this.message=message},bug:function(message){this.toString=function(){return"BUG: "+this.message},this.message=message},notReady:function(message){this.toString=function(){return"NOT READY: "+this.message},this.message=message}}};sjcl.cipher.aes=function(key){if(!this._tables[0][0][0])this._precompute();var i,j,tmp,encKey,decKey,sbox=this._tables[0][4],decTable=this._tables[1],keyLen=key.length,rcon=1;if(keyLen!==4&&keyLen!==6&&keyLen!==8)throw new sjcl.exception.invalid("invalid aes key size");this._key=[encKey=key.slice(0),decKey=[]];for(i=keyLen;i<4*keyLen+28;i++){if(tmp=encKey[i-1],i%keyLen===0||keyLen===8&&i%keyLen===4){if(tmp=sbox[tmp>>>24]<<24^sbox[tmp>>16&255]<<16^sbox[tmp>>8&255]<<8^sbox[tmp&255],i%keyLen===0)tmp=tmp<<8^tmp>>>24^rcon<<24,rcon=rcon<<1^(rcon>>7)*283}encKey[i]=encKey[i-keyLen]^tmp}for(j=0;i;j++,i--)if(tmp=encKey[j&3?i:i-4],i<=4||j<4)decKey[j]=tmp;else decKey[j]=decTable[0][sbox[tmp>>>24]]^decTable[1][sbox[tmp>>16&255]]^decTable[2][sbox[tmp>>8&255]]^decTable[3][sbox[tmp&255]]};sjcl.cipher.aes.prototype={encrypt:function(data){return this._crypt(data,0)},decrypt:function(data){return this._crypt(data,1)},_tables:[[[],[],[],[],[]],[[],[],[],[],[]]],_precompute:function(){var encTable=this._tables[0],decTable=this._tables[1],sbox=encTable[4],sboxInv=decTable[4],i,x,xInv,d=[],th=[],x2,x4,x8,s,tEnc,tDec;for(i=0;i<256;i++)th[(d[i]=i<<1^(i>>7)*283)^i]=i;for(x=xInv=0;!sbox[x];x^=x2||1,xInv=th[xInv]||1){s=xInv^xInv<<1^xInv<<2^xInv<<3^xInv<<4,s=s>>8^s&255^99,sbox[x]=s,sboxInv[s]=x,x8=d[x4=d[x2=d[x]]],tDec=x8*16843009^x4*65537^x2*257^x*16843008,tEnc=d[s]*257^s*16843008;for(i=0;i<4;i++)encTable[i][x]=tEnc=tEnc<<24^tEnc>>>8,decTable[i][s]=tDec=tDec<<24^tDec>>>8}for(i=0;i<5;i++)encTable[i]=encTable[i].slice(0),decTable[i]=decTable[i].slice(0)},_crypt:function(input,dir){if(input.length!==4)throw new sjcl.exception.invalid("invalid aes block size");var key=this._key[dir],a=input[0]^key[0],b=input[dir?3:1]^key[1],c=input[2]^key[2],d=input[dir?1:3]^key[3],a2,b2,c2,nInnerRounds=key.length/4-2,i,kIndex=4,out=[0,0,0,0],table=this._tables[dir],t0=table[0],t1=table[1],t2=table[2],t3=table[3],sbox=table[4];for(i=0;i<nInnerRounds;i++)a2=t0[a>>>24]^t1[b>>16&255]^t2[c>>8&255]^t3[d&255]^key[kIndex],b2=t0[b>>>24]^t1[c>>16&255]^t2[d>>8&255]^t3[a&255]^key[kIndex+1],c2=t0[c>>>24]^t1[d>>16&255]^t2[a>>8&255]^t3[b&255]^key[kIndex+2],d=t0[d>>>24]^t1[a>>16&255]^t2[b>>8&255]^t3[c&255]^key[kIndex+3],kIndex+=4,a=a2,b=b2,c=c2;for(i=0;i<4;i++)out[dir?3&-i:i]=sbox[a>>>24]<<24^sbox[b>>16&255]<<16^sbox[c>>8&255]<<8^sbox[d&255]^key[kIndex++],a2=a,a=b,b=c,c=d,d=a2;return out}};sjcl.bitArray={bitSlice:function(a,bstart,bend){return a=sjcl.bitArray._shiftRight(a.slice(bstart/32),32-(bstart&31)).slice(1),bend===void 0?a:sjcl.bitArray.clamp(a,bend-bstart)},extract:function(a,bstart,blength){var x,sh=Math.floor(-bstart-blength&31);if((bstart+blength-1^bstart)&-32)x=a[bstart/32|0]<<32-sh^a[bstart/32+1|0]>>>sh;else x=a[bstart/32|0]>>>sh;return x&(1<<blength)-1},concat:function(a1,a2){if(a1.length===0||a2.length===0)return a1.concat(a2);var last=a1[a1.length-1],shift=sjcl.bitArray.getPartial(last);if(shift===32)return a1.concat(a2);else return sjcl.bitArray._shiftRight(a2,shift,last|0,a1.slice(0,a1.length-1))},bitLength:function(a){var l=a.length,x;if(l===0)return 0;return x=a[l-1],(l-1)*32+sjcl.bitArray.getPartial(x)},clamp:function(a,len){if(a.length*32<len)return a;a=a.slice(0,Math.ceil(len/32));var l=a.length;if(len=len&31,l>0&&len)a[l-1]=sjcl.bitArray.partial(len,a[l-1]&2147483648>>len-1,1);return a},partial:function(len,x,_end){if(len===32)return x;return(_end?x|0:x<<32-len)+len*1099511627776},getPartial:function(x){return Math.round(x/1099511627776)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var x=0,i;for(i=0;i<a.length;i++)x|=a[i]^b[i];return x===0},_shiftRight:function(a,shift,carry,out){var i,last2=0,shift2;if(out===void 0)out=[];for(;shift>=32;shift-=32)out.push(carry),carry=0;if(shift===0)return out.concat(a);for(i=0;i<a.length;i++)out.push(carry|a[i]>>>shift),carry=a[i]<<32-shift;return last2=a.length?a[a.length-1]:0,shift2=sjcl.bitArray.getPartial(last2),out.push(sjcl.bitArray.partial(shift+shift2&31,shift+shift2>32?carry:out.pop(),1)),out},_xor4:function(x,y){return[x[0]^y[0],x[1]^y[1],x[2]^y[2],x[3]^y[3]]},byteswapM:function(a){var i,v,m=65280;for(i=0;i<a.length;++i)v=a[i],a[i]=v>>>24|v>>>8&m|(v&m)<<8|v<<24;return a}};sjcl.codec.utf8String={fromBits:function(arr){var out="",bl=sjcl.bitArray.bitLength(arr),i,tmp;for(i=0;i<bl/8;i++){if((i&3)===0)tmp=arr[i/4];out+=String.fromCharCode(tmp>>>8>>>8>>>8),tmp<<=8}return decodeURIComponent(escape(out))},toBits:function(str){str=unescape(encodeURIComponent(str));var out=[],i,tmp=0;for(i=0;i<str.length;i++)if(tmp=tmp<<8|str.charCodeAt(i),(i&3)===3)out.push(tmp),tmp=0;if(i&3)out.push(sjcl.bitArray.partial(8*(i&3),tmp));return out}};sjcl.codec.hex={fromBits:function(arr){var out="",i;for(i=0;i<arr.length;i++)out+=((arr[i]|0)+263882790666240).toString(16).substr(4);return out.substr(0,sjcl.bitArray.bitLength(arr)/4)},toBits:function(str){var i,out=[],len;str=str.replace(/\s|0x/g,""),len=str.length,str=str+"00000000";for(i=0;i<str.length;i+=8)out.push(parseInt(str.substr(i,8),16)^0);return sjcl.bitArray.clamp(out,len*4)}};sjcl.codec.base64={_chars:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(arr,_noEquals,_url){var out="",i,bits=0,c=sjcl.codec.base64._chars,ta=0,bl=sjcl.bitArray.bitLength(arr);if(_url)c=c.substr(0,62)+"-_";for(i=0;out.length*6<bl;)if(out+=c.charAt((ta^arr[i]>>>bits)>>>26),bits<6)ta=arr[i]<<6-bits,bits+=26,i++;else ta<<=6,bits-=6;while(out.length&3&&!_noEquals)out+="=";return out},toBits:function(str,_url){str=str.replace(/\s|=/g,"");var out=[],i,bits=0,c=sjcl.codec.base64._chars,ta=0,x;if(_url)c=c.substr(0,62)+"-_";for(i=0;i<str.length;i++){if(x=c.indexOf(str.charAt(i)),x<0)throw new sjcl.exception.invalid("this isn't base64!");if(bits>26)bits-=26,out.push(ta^x>>>bits),ta=x<<32-bits;else bits+=6,ta^=x<<32-bits}if(bits&56)out.push(sjcl.bitArray.partial(bits&56,ta,1));return out}};sjcl.codec.base64url={fromBits:function(arr){return sjcl.codec.base64.fromBits(arr,1,1)},toBits:function(str){return sjcl.codec.base64.toBits(str,1)}};sjcl.codec.bytes={fromBits:function(arr){var out=[],bl=sjcl.bitArray.bitLength(arr),i,tmp;for(i=0;i<bl/8;i++){if((i&3)===0)tmp=arr[i/4];out.push(tmp>>>24),tmp<<=8}return out},toBits:function(bytes){var out=[],i,tmp=0;for(i=0;i<bytes.length;i++)if(tmp=tmp<<8|bytes[i],(i&3)===3)out.push(tmp),tmp=0;if(i&3)out.push(sjcl.bitArray.partial(8*(i&3),tmp));return out}};sjcl.hash.sha256=function(hash){if(!this._key[0])this._precompute();if(hash)this._h=hash._h.slice(0),this._buffer=hash._buffer.slice(0),this._length=hash._length;else this.reset()};sjcl.hash.sha256.hash=function(data){return new sjcl.hash.sha256().update(data).finalize()};sjcl.hash.sha256.prototype={blockSize:512,reset:function(){return this._h=this._init.slice(0),this._buffer=[],this._length=0,this},update:function(data){if(typeof data==="string")data=sjcl.codec.utf8String.toBits(data);var i,b=this._buffer=sjcl.bitArray.concat(this._buffer,data),ol=this._length,nl=this._length=ol+sjcl.bitArray.bitLength(data);if(nl>9007199254740991)throw new sjcl.exception.invalid("Cannot hash more than 2^53 - 1 bits");if(typeof Uint32Array<"u"){var c=new Uint32Array(b),j=0;for(i=512+ol-(512+ol&511);i<=nl;i+=512)this._block(c.subarray(16*j,16*(j+1))),j+=1;b.splice(0,16*j)}else for(i=512+ol-(512+ol&511);i<=nl;i+=512)this._block(b.splice(0,16));return this},finalize:function(){var i,b=this._buffer,h=this._h;b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(i=b.length+2;i&15;i++)b.push(0);b.push(Math.floor(this._length/4294967296)),b.push(this._length|0);while(b.length)this._block(b.splice(0,16));return this.reset(),h},_init:[],_key:[],_precompute:function(){var i=0,prime=2,factor,isPrime;function frac(x){return(x-Math.floor(x))*4294967296|0}for(;i<64;prime++){isPrime=!0;for(factor=2;factor*factor<=prime;factor++)if(prime%factor===0){isPrime=!1;break}if(isPrime){if(i<8)this._init[i]=frac(Math.pow(prime,0.5));this._key[i]=frac(Math.pow(prime,0.3333333333333333)),i++}}},_block:function(w){var i,tmp,a,b,h=this._h,k=this._key,h0=h[0],h1=h[1],h2=h[2],h3=h[3],h4=h[4],h5=h[5],h6=h[6],h7=h[7];for(i=0;i<64;i++){if(i<16)tmp=w[i];else a=w[i+1&15],b=w[i+14&15],tmp=w[i&15]=(a>>>7^a>>>18^a>>>3^a<<25^a<<14)+(b>>>17^b>>>19^b>>>10^b<<15^b<<13)+w[i&15]+w[i+9&15]|0;tmp=tmp+h7+(h4>>>6^h4>>>11^h4>>>25^h4<<26^h4<<21^h4<<7)+(h6^h4&(h5^h6))+k[i],h7=h6,h6=h5,h5=h4,h4=h3+tmp|0,h3=h2,h2=h1,h1=h0,h0=tmp+(h1&h2^h3&(h1^h2))+(h1>>>2^h1>>>13^h1>>>22^h1<<30^h1<<19^h1<<10)|0}h[0]=h[0]+h0|0,h[1]=h[1]+h1|0,h[2]=h[2]+h2|0,h[3]=h[3]+h3|0,h[4]=h[4]+h4|0,h[5]=h[5]+h5|0,h[6]=h[6]+h6|0,h[7]=h[7]+h7|0}};sjcl.mode.ccm={name:"ccm",_progressListeners:[],listenProgress:function(cb){sjcl.mode.ccm._progressListeners.push(cb)},unListenProgress:function(cb){var index=sjcl.mode.ccm._progressListeners.indexOf(cb);if(index>-1)sjcl.mode.ccm._progressListeners.splice(index,1)},_callProgressListener:function(val){var p=sjcl.mode.ccm._progressListeners.slice(),i;for(i=0;i<p.length;i+=1)p[i](val)},encrypt:function(prf,plaintext,iv,adata,tlen){var L,out=plaintext.slice(0),tag,w=sjcl.bitArray,ivl=w.bitLength(iv)/8,ol=w.bitLength(out)/8;if(tlen=tlen||64,adata=adata||[],ivl<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(L=2;L<4&&ol>>>8*L;L++);if(L<15-ivl)L=15-ivl;return iv=w.clamp(iv,8*(15-L)),tag=sjcl.mode.ccm._computeTag(prf,plaintext,iv,adata,tlen,L),out=sjcl.mode.ccm._ctrMode(prf,out,iv,tag,tlen,L),w.concat(out.data,out.tag)},decrypt:function(prf,ciphertext,iv,adata,tlen){tlen=tlen||64,adata=adata||[];var L,w=sjcl.bitArray,ivl=w.bitLength(iv)/8,ol=w.bitLength(ciphertext),out=w.clamp(ciphertext,ol-tlen),tag=w.bitSlice(ciphertext,ol-tlen),tag2;if(ol=(ol-tlen)/8,ivl<7)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(L=2;L<4&&ol>>>8*L;L++);if(L<15-ivl)L=15-ivl;if(iv=w.clamp(iv,8*(15-L)),out=sjcl.mode.ccm._ctrMode(prf,out,iv,tag,tlen,L),tag2=sjcl.mode.ccm._computeTag(prf,out.data,iv,adata,tlen,L),!w.equal(out.tag,tag2))throw new sjcl.exception.corrupt("ccm: tag doesn't match");return out.data},_macAdditionalData:function(prf,adata,iv,tlen,ol,L){var mac,tmp,i,macData=[],w=sjcl.bitArray,xor=w._xor4;if(mac=[w.partial(8,(adata.length?64:0)|tlen-2<<2|L-1)],mac=w.concat(mac,iv),mac[3]|=ol,mac=prf.encrypt(mac),adata.length){if(tmp=w.bitLength(adata)/8,tmp<=65279)macData=[w.partial(16,tmp)];else if(tmp<=4294967295)macData=w.concat([w.partial(16,65534)],[tmp]);macData=w.concat(macData,adata);for(i=0;i<macData.length;i+=4)mac=prf.encrypt(xor(mac,macData.slice(i,i+4).concat([0,0,0])))}return mac},_computeTag:function(prf,plaintext,iv,adata,tlen,L){var mac,i,w=sjcl.bitArray,xor=w._xor4;if(tlen/=8,tlen%2||tlen<4||tlen>16)throw new sjcl.exception.invalid("ccm: invalid tag length");if(adata.length>4294967295||plaintext.length>4294967295)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");mac=sjcl.mode.ccm._macAdditionalData(prf,adata,iv,tlen,w.bitLength(plaintext)/8,L);for(i=0;i<plaintext.length;i+=4)mac=prf.encrypt(xor(mac,plaintext.slice(i,i+4).concat([0,0,0])));return w.clamp(mac,tlen*8)},_ctrMode:function(prf,data,iv,tag,tlen,L){var enc,i,w=sjcl.bitArray,xor=w._xor4,ctr,l=data.length,bl=w.bitLength(data),n=l/50,p=n;if(ctr=w.concat([w.partial(8,L-1)],iv).concat([0,0,0]).slice(0,4),tag=w.bitSlice(xor(tag,prf.encrypt(ctr)),0,tlen),!l)return{tag,data:[]};for(i=0;i<l;i+=4){if(i>n)sjcl.mode.ccm._callProgressListener(i/l),n+=p;ctr[3]++,enc=prf.encrypt(ctr),data[i]^=enc[0],data[i+1]^=enc[1],data[i+2]^=enc[2],data[i+3]^=enc[3]}return{tag,data:w.clamp(data,bl)}}};sjcl.misc.hmac=function(key,Hash){this._hash=Hash=Hash||sjcl.hash.sha256;var exKey=[[],[]],i,bs=Hash.prototype.blockSize/32;if(this._baseHash=[new Hash,new Hash],key.length>bs)key=Hash.hash(key);for(i=0;i<bs;i++)exKey[0][i]=key[i]^909522486,exKey[1][i]=key[i]^1549556828;this._baseHash[0].update(exKey[0]),this._baseHash[1].update(exKey[1]),this._resultHash=new Hash(this._baseHash[0])};sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(data){if(!this._updated)return this.update(data),this.digest(data);else throw new sjcl.exception.invalid("encrypt on already updated hmac called!")};sjcl.misc.hmac.prototype.reset=function(){this._resultHash=new this._hash(this._baseHash[0]),this._updated=!1};sjcl.misc.hmac.prototype.update=function(data){this._updated=!0,this._resultHash.update(data)};sjcl.misc.hmac.prototype.digest=function(){var w=this._resultHash.finalize(),result=new this._hash(this._baseHash[1]).update(w).finalize();return this.reset(),result};sjcl.misc.pbkdf2=function(password,salt,count,length,Prff){if(count=count||1e4,length<0||count<0)throw new sjcl.exception.invalid("invalid params to pbkdf2");if(typeof password==="string")password=sjcl.codec.utf8String.toBits(password);if(typeof salt==="string")salt=sjcl.codec.utf8String.toBits(salt);Prff=Prff||sjcl.misc.hmac;var prf=new Prff(password),u,ui,i,j,k,out=[],b=sjcl.bitArray;for(k=1;32*out.length<(length||1);k++){u=ui=prf.encrypt(b.concat(salt,[k]));for(i=1;i<count;i++){ui=prf.encrypt(ui);for(j=0;j<ui.length;j++)u[j]^=ui[j]}out=out.concat(u)}if(length)out=b.clamp(out,length);return out};sjcl.prng=function(defaultParanoia){this._pools=[new sjcl.hash.sha256],this._poolEntropy=[0],this._reseedCount=0,this._robins={},this._eventId=0,this._collectorIds={},this._collectorIdNext=0,this._strength=0,this._poolStrength=0,this._nextReseed=0,this._key=[0,0,0,0,0,0,0,0],this._counter=[0,0,0,0],this._cipher=void 0,this._defaultParanoia=defaultParanoia,this._collectorsStarted=!1,this._callbacks={progress:{},seeded:{}},this._callbackI=0,this._NOT_READY=0,this._READY=1,this._REQUIRES_RESEED=2,this._MAX_WORDS_PER_BURST=65536,this._PARANOIA_LEVELS=[0,48,64,96,128,192,256,384,512,768,1024],this._MILLISECONDS_PER_RESEED=30000,this._BITS_PER_RESEED=80};sjcl.prng.prototype={randomWords:function(nwords,paranoia){var out=[],i,readiness=this.isReady(paranoia),g;if(readiness===this._NOT_READY)throw new sjcl.exception.notReady("generator isn't seeded");else if(readiness&this._REQUIRES_RESEED)this._reseedFromPools(!(readiness&this._READY));for(i=0;i<nwords;i+=4){if((i+1)%this._MAX_WORDS_PER_BURST===0)this._gate();g=this._gen4words(),out.push(g[0],g[1],g[2],g[3])}return this._gate(),out.slice(0,nwords)},setDefaultParanoia:function(paranoia,allowZeroParanoia){if(paranoia===0&&allowZeroParanoia!=="Setting paranoia=0 will ruin your security; use it only for testing")throw new sjcl.exception.invalid("Setting paranoia=0 will ruin your security; use it only for testing");this._defaultParanoia=paranoia},addEntropy:function(data,estimatedEntropy,source){source=source||"user";var id,i,tmp,t=new Date().valueOf(),robin=this._robins[source],oldReady=this.isReady(),err=0,objName;if(id=this._collectorIds[source],id===void 0)id=this._collectorIds[source]=this._collectorIdNext++;if(robin===void 0)robin=this._robins[source]=0;switch(this._robins[source]=(this._robins[source]+1)%this._pools.length,typeof data){case"number":if(estimatedEntropy===void 0)estimatedEntropy=1;this._pools[robin].update([id,this._eventId++,1,estimatedEntropy,t,1,data|0]);break;case"object":if(objName=Object.prototype.toString.call(data),objName==="[object Uint32Array]"){tmp=[];for(i=0;i<data.length;i++)tmp.push(data[i]);data=tmp}else{if(objName!=="[object Array]")err=1;for(i=0;i<data.length&&!err;i++)if(typeof data[i]!=="number")err=1}if(!err){if(estimatedEntropy===void 0){estimatedEntropy=0;for(i=0;i<data.length;i++){tmp=data[i];while(tmp>0)estimatedEntropy++,tmp=tmp>>>1}}this._pools[robin].update([id,this._eventId++,2,estimatedEntropy,t,data.length].concat(data))}break;case"string":if(estimatedEntropy===void 0)estimatedEntropy=data.length;this._pools[robin].update([id,this._eventId++,3,estimatedEntropy,t,data.length]),this._pools[robin].update(data);break;default:err=1}if(err)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");if(this._poolEntropy[robin]+=estimatedEntropy,this._poolStrength+=estimatedEntropy,oldReady===this._NOT_READY){if(this.isReady()!==this._NOT_READY)this._fireEvent("seeded",Math.max(this._strength,this._poolStrength));this._fireEvent("progress",this.getProgress())}},isReady:function(paranoia){var entropyRequired=this._PARANOIA_LEVELS[paranoia!==void 0?paranoia:this._defaultParanoia];if(this._strength&&this._strength>=entropyRequired)return this._poolEntropy[0]>this._BITS_PER_RESEED&&new Date().valueOf()>this._nextReseed?this._REQUIRES_RESEED|this._READY:this._READY;else return this._poolStrength>=entropyRequired?this._REQUIRES_RESEED|this._NOT_READY:this._NOT_READY},getProgress:function(paranoia){var entropyRequired=this._PARANOIA_LEVELS[paranoia?paranoia:this._defaultParanoia];if(this._strength>=entropyRequired)return 1;else return this._poolStrength>entropyRequired?1:this._poolStrength/entropyRequired},startCollectors:function(){if(this._collectorsStarted)return;if(this._eventListener={loadTimeCollector:this._bind(this._loadTimeCollector),mouseCollector:this._bind(this._mouseCollector),keyboardCollector:this._bind(this._keyboardCollector),accelerometerCollector:this._bind(this._accelerometerCollector),touchCollector:this._bind(this._touchCollector)},window.addEventListener)window.addEventListener("load",this._eventListener.loadTimeCollector,!1),window.addEventListener("mousemove",this._eventListener.mouseCollector,!1),window.addEventListener("keypress",this._eventListener.keyboardCollector,!1),window.addEventListener("devicemotion",this._eventListener.accelerometerCollector,!1),window.addEventListener("touchmove",this._eventListener.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this._eventListener.loadTimeCollector),document.attachEvent("onmousemove",this._eventListener.mouseCollector),document.attachEvent("keypress",this._eventListener.keyboardCollector);else throw new sjcl.exception.bug("can't attach event");this._collectorsStarted=!0},stopCollectors:function(){if(!this._collectorsStarted)return;if(window.removeEventListener)window.removeEventListener("load",this._eventListener.loadTimeCollector,!1),window.removeEventListener("mousemove",this._eventListener.mouseCollector,!1),window.removeEventListener("keypress",this._eventListener.keyboardCollector,!1),window.removeEventListener("devicemotion",this._eventListener.accelerometerCollector,!1),window.removeEventListener("touchmove",this._eventListener.touchCollector,!1);else if(document.detachEvent)document.detachEvent("onload",this._eventListener.loadTimeCollector),document.detachEvent("onmousemove",this._eventListener.mouseCollector),document.detachEvent("keypress",this._eventListener.keyboardCollector);this._collectorsStarted=!1},addEventListener:function(name,callback){this._callbacks[name][this._callbackI++]=callback},removeEventListener:function(name,cb){var i,j,cbs=this._callbacks[name],jsTemp=[];for(j in cbs)if(cbs.hasOwnProperty(j)&&cbs[j]===cb)jsTemp.push(j);for(i=0;i<jsTemp.length;i++)j=jsTemp[i],delete cbs[j]},_bind:function(func){var that=this;return function(){func.apply(that,arguments)}},_gen4words:function(){for(var i=0;i<4;i++)if(this._counter[i]=this._counter[i]+1|0,this._counter[i])break;return this._cipher.encrypt(this._counter)},_gate:function(){this._key=this._gen4words().concat(this._gen4words()),this._cipher=new sjcl.cipher.aes(this._key)},_reseed:function(seedWords){this._key=sjcl.hash.sha256.hash(this._key.concat(seedWords)),this._cipher=new sjcl.cipher.aes(this._key);for(var i=0;i<4;i++)if(this._counter[i]=this._counter[i]+1|0,this._counter[i])break},_reseedFromPools:function(full){var reseedData=[],strength=0,i;this._nextReseed=reseedData[0]=new Date().valueOf()+this._MILLISECONDS_PER_RESEED;for(i=0;i<16;i++)reseedData.push(Math.random()*4294967296|0);for(i=0;i<this._pools.length;i++)if(reseedData=reseedData.concat(this._pools[i].finalize()),strength+=this._poolEntropy[i],this._poolEntropy[i]=0,!full&&this._reseedCount&1<<i)break;if(this._reseedCount>=1<<this._pools.length)this._pools.push(new sjcl.hash.sha256),this._poolEntropy.push(0);if(this._poolStrength-=strength,strength>this._strength)this._strength=strength;this._reseedCount++,this._reseed(reseedData)},_keyboardCollector:function(){this._addCurrentTimeToEntropy(1)},_mouseCollector:function(ev){var x,y;try{x=ev.x||ev.clientX||ev.offsetX||0,y=ev.y||ev.clientY||ev.offsetY||0}catch(err){x=0,y=0}if(x!=0&&y!=0)this.addEntropy([x,y],2,"mouse");this._addCurrentTimeToEntropy(0)},_touchCollector:function(ev){var touch=ev.touches[0]||ev.changedTouches[0],x=touch.pageX||touch.clientX,y=touch.pageY||touch.clientY;this.addEntropy([x,y],1,"touch"),this._addCurrentTimeToEntropy(0)},_loadTimeCollector:function(){this._addCurrentTimeToEntropy(2)},_addCurrentTimeToEntropy:function(estimatedEntropy){if(typeof window<"u"&&window.performance&&typeof window.performance.now==="function")this.addEntropy(window.performance.now(),estimatedEntropy,"loadtime");else this.addEntropy(new Date().valueOf(),estimatedEntropy,"loadtime")},_accelerometerCollector:function(ev){var ac=ev.accelerationIncludingGravity.x||ev.accelerationIncludingGravity.y||ev.accelerationIncludingGravity.z;if(window.orientation){var or=window.orientation;if(typeof or==="number")this.addEntropy(or,1,"accelerometer")}if(ac)this.addEntropy(ac,2,"accelerometer");this._addCurrentTimeToEntropy(0)},_fireEvent:function(name,arg){var j,cbs=sjcl.random._callbacks[name],cbsTemp=[];for(j in cbs)if(cbs.hasOwnProperty(j))cbsTemp.push(cbs[j]);for(j=0;j<cbsTemp.length;j++)cbsTemp[j](arg)}};sjcl.random=new sjcl.prng(6);(function(){function getCryptoModule(){try{return __require("crypto")}catch(e){return null}}try{var buf,crypt,ab;if(typeof module_sjcl<"u"&&exports_sjcl&&(crypt=getCryptoModule())&&crypt.randomBytes)buf=crypt.randomBytes(128),buf=new Uint32Array(new Uint8Array(buf).buffer),sjcl.random.addEntropy(buf,1024,"crypto.randomBytes");else if(typeof window<"u"&&typeof Uint32Array<"u"){if(ab=new Uint32Array(32),window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(ab);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(ab);else return;sjcl.random.addEntropy(ab,1024,"crypto.getRandomValues")}}catch(e){if(typeof window<"u"&&window.console)console.log("There was an error collecting entropy from the browser:"),console.log(e)}})();sjcl.json={defaults:{v:1,iter:1e4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},_encrypt:function(password,plaintext,params,rp){params=params||{},rp=rp||{};var j=sjcl.json,p=j._add({iv:sjcl.random.randomWords(4,0)},j.defaults),tmp,prp,adata;if(j._add(p,params),adata=p.adata,typeof p.salt==="string")p.salt=sjcl.codec.base64.toBits(p.salt);if(typeof p.iv==="string")p.iv=sjcl.codec.base64.toBits(p.iv);if(!sjcl.mode[p.mode]||!sjcl.cipher[p.cipher]||typeof password==="string"&&p.iter<=100||p.ts!==64&&p.ts!==96&&p.ts!==128||p.ks!==128&&p.ks!==192&&p.ks!==256||(p.iv.length<2||p.iv.length>4))throw new sjcl.exception.invalid("json encrypt: invalid parameters");if(typeof password==="string")tmp=sjcl.misc.cachedPbkdf2(password,p),password=tmp.key.slice(0,p.ks/32),p.salt=tmp.salt;else if(sjcl.ecc&&password instanceof sjcl.ecc.elGamal.publicKey)tmp=password.kem(),p.kemtag=tmp.tag,password=tmp.key.slice(0,p.ks/32);if(typeof plaintext==="string")plaintext=sjcl.codec.utf8String.toBits(plaintext);if(typeof adata==="string")p.adata=adata=sjcl.codec.utf8String.toBits(adata);if(prp=new sjcl.cipher[p.cipher](password),j._add(rp,p),rp.key=password,p.mode==="ccm"&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&plaintext instanceof ArrayBuffer)p.ct=sjcl.arrayBuffer.ccm.encrypt(prp,plaintext,p.iv,adata,p.ts);else p.ct=sjcl.mode[p.mode].encrypt(prp,plaintext,p.iv,adata,p.ts);return p},encrypt:function(password,plaintext,params,rp){var j=sjcl.json,p=j._encrypt.apply(j,arguments);return j.encode(p)},_decrypt:function(password,ciphertext,params,rp){params=params||{},rp=rp||{};var j=sjcl.json,p=j._add(j._add(j._add({},j.defaults),ciphertext),params,!0),ct,tmp,prp,adata=p.adata;if(typeof p.salt==="string")p.salt=sjcl.codec.base64.toBits(p.salt);if(typeof p.iv==="string")p.iv=sjcl.codec.base64.toBits(p.iv);if(!sjcl.mode[p.mode]||!sjcl.cipher[p.cipher]||typeof password==="string"&&p.iter<=100||p.ts!==64&&p.ts!==96&&p.ts!==128||p.ks!==128&&p.ks!==192&&p.ks!==256||!p.iv||(p.iv.length<2||p.iv.length>4))throw new sjcl.exception.invalid("json decrypt: invalid parameters");if(typeof password==="string")tmp=sjcl.misc.cachedPbkdf2(password,p),password=tmp.key.slice(0,p.ks/32),p.salt=tmp.salt;else if(sjcl.ecc&&password instanceof sjcl.ecc.elGamal.secretKey)password=password.unkem(sjcl.codec.base64.toBits(p.kemtag)).slice(0,p.ks/32);if(typeof adata==="string")adata=sjcl.codec.utf8String.toBits(adata);if(prp=new sjcl.cipher[p.cipher](password),p.mode==="ccm"&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&p.ct instanceof ArrayBuffer)ct=sjcl.arrayBuffer.ccm.decrypt(prp,p.ct,p.iv,p.tag,adata,p.ts);else ct=sjcl.mode[p.mode].decrypt(prp,p.ct,p.iv,adata,p.ts);if(j._add(rp,p),rp.key=password,params.raw===1)return ct;else return sjcl.codec.utf8String.fromBits(ct)},decrypt:function(password,ciphertext,params,rp){var j=sjcl.json;return j._decrypt(password,j.decode(ciphertext),params,rp)},encode:function(obj){var i,out="{",comma="";for(i in obj)if(obj.hasOwnProperty(i)){if(!i.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");switch(out+=comma+'"'+i+'":',comma=",",typeof obj[i]){case"number":case"boolean":out+=obj[i];break;case"string":out+='"'+escape(obj[i])+'"';break;case"object":out+='"'+sjcl.codec.base64.fromBits(obj[i],0)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type")}}return out+"}"},decode:function(str){if(str=str.replace(/\s/g,""),!str.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");var a=str.replace(/^\{|\}$/g,"").split(/,/),out={},i,m;for(i=0;i<a.length;i++){if(!(m=a[i].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");if(m[3]!=null)out[m[2]]=parseInt(m[3],10);else if(m[4]!=null)out[m[2]]=m[2].match(/^(ct|adata|salt|iv)$/)?sjcl.codec.base64.toBits(m[4]):unescape(m[4]);else if(m[5]!=null)out[m[2]]=m[5]==="true"}return out},_add:function(target,src,requireSame){if(target===void 0)target={};if(src===void 0)return target;var i;for(i in src)if(src.hasOwnProperty(i)){if(requireSame&&target[i]!==void 0&&target[i]!==src[i])throw new sjcl.exception.invalid("required parameter overridden");target[i]=src[i]}return target},_subtract:function(plus,minus){var out={},i;for(i in plus)if(plus.hasOwnProperty(i)&&plus[i]!==minus[i])out[i]=plus[i];return out},_filter:function(src,filter){var out={},i;for(i=0;i<filter.length;i++)if(src[filter[i]]!==void 0)out[filter[i]]=src[filter[i]];return out}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc._pbkdf2Cache={};sjcl.misc.cachedPbkdf2=function(password,obj){var cache=sjcl.misc._pbkdf2Cache,c,cp,str,salt,iter;return obj=obj||{},iter=obj.iter||1000,cp=cache[password]=cache[password]||{},c=cp[iter]=cp[iter]||{firstSalt:obj.salt&&obj.salt.length?obj.salt.slice(0):sjcl.random.randomWords(2,0)},salt=obj.salt===void 0?c.firstSalt:obj.salt,c[salt]=c[salt]||sjcl.misc.pbkdf2(password,salt,obj.iter),{key:c[salt].slice(0),salt:salt.slice(0)}};sjcl.bn=function(it){this.initWith(it)};sjcl.bn.prototype={radix:24,maxMul:8,_class:sjcl.bn,copy:function(){return new this._class(this)},initWith:function(it){var i=0,k;switch(typeof it){case"object":this.limbs=it.limbs.slice(0);break;case"number":this.limbs=[it],this.normalize();break;case"string":it=it.replace(/^0x/,""),this.limbs=[],k=this.radix/4;for(i=0;i<it.length;i+=k)this.limbs.push(parseInt(it.substring(Math.max(it.length-i-k,0),it.length-i),16));break;default:this.limbs=[0]}return this},equals:function(that){if(typeof that==="number")that=new this._class(that);var difference=0,i;this.fullReduce(),that.fullReduce();for(i=0;i<this.limbs.length||i<that.limbs.length;i++)difference|=this.getLimb(i)^that.getLimb(i);return difference===0},getLimb:function(i){return i>=this.limbs.length?0:this.limbs[i]},greaterEquals:function(that){if(typeof that==="number")that=new this._class(that);var less=0,greater=0,i,a,b;i=Math.max(this.limbs.length,that.limbs.length)-1;for(;i>=0;i--)a=this.getLimb(i),b=that.getLimb(i),greater|=b-a&~less,less|=a-b&~greater;return(greater|~less)>>>31},toString:function(){this.fullReduce();var out="",i,s,l=this.limbs;for(i=0;i<this.limbs.length;i++){s=l[i].toString(16);while(i<this.limbs.length-1&&s.length<6)s="0"+s;out=s+out}return"0x"+out},addM:function(that){if(typeof that!=="object")that=new this._class(that);var i,l=this.limbs,ll=that.limbs;for(i=l.length;i<ll.length;i++)l[i]=0;for(i=0;i<ll.length;i++)l[i]+=ll[i];return this},doubleM:function(){var i,carry=0,tmp,r=this.radix,m=this.radixMask,l=this.limbs;for(i=0;i<l.length;i++)tmp=l[i],tmp=tmp+tmp+carry,l[i]=tmp&m,carry=tmp>>r;if(carry)l.push(carry);return this},halveM:function(){var i,carry=0,tmp,r=this.radix,l=this.limbs;for(i=l.length-1;i>=0;i--)tmp=l[i],l[i]=tmp+carry>>1,carry=(tmp&1)<<r;if(!l[l.length-1])l.pop();return this},subM:function(that){if(typeof that!=="object")that=new this._class(that);var i,l=this.limbs,ll=that.limbs;for(i=l.length;i<ll.length;i++)l[i]=0;for(i=0;i<ll.length;i++)l[i]-=ll[i];return this},mod:function(that){var neg=!this.greaterEquals(new sjcl.bn(0));that=new sjcl.bn(that).normalize();var out=new sjcl.bn(this).normalize(),ci=0;if(neg)out=new sjcl.bn(0).subM(out).normalize();for(;out.greaterEquals(that);ci++)that.doubleM();if(neg)out=that.sub(out).normalize();for(;ci>0;ci--)if(that.halveM(),out.greaterEquals(that))out.subM(that).normalize();return out.trim()},inverseMod:function(p){var a=new sjcl.bn(1),b=new sjcl.bn(0),x=new sjcl.bn(this),y=new sjcl.bn(p),tmp,i,nz=1;if(!(p.limbs[0]&1))throw new sjcl.exception.invalid("inverseMod: p must be odd");do{if(x.limbs[0]&1){if(!x.greaterEquals(y))tmp=x,x=y,y=tmp,tmp=a,a=b,b=tmp;if(x.subM(y),x.normalize(),!a.greaterEquals(b))a.addM(p);a.subM(b)}if(x.halveM(),a.limbs[0]&1)a.addM(p);a.normalize(),a.halveM();for(i=nz=0;i<x.limbs.length;i++)nz|=x.limbs[i]}while(nz);if(!y.equals(1))throw new sjcl.exception.invalid("inverseMod: p and x must be relatively prime");return b},add:function(that){return this.copy().addM(that)},sub:function(that){return this.copy().subM(that)},mul:function(that){if(typeof that==="number")that=new this._class(that);else that.normalize();this.normalize();var i,j,a=this.limbs,b=that.limbs,al=a.length,bl=b.length,out=new this._class,c=out.limbs,ai,ii=this.maxMul;for(i=0;i<this.limbs.length+that.limbs.length+1;i++)c[i]=0;for(i=0;i<al;i++){ai=a[i];for(j=0;j<bl;j++)c[i+j]+=ai*b[j];if(!--ii)ii=this.maxMul,out.cnormalize()}return out.cnormalize().reduce()},square:function(){return this.mul(this)},power:function(l){l=new sjcl.bn(l).normalize().trim().limbs;var i,j,out=new this._class(1),pow=this;for(i=0;i<l.length;i++)for(j=0;j<this.radix;j++){if(l[i]&1<<j)out=out.mul(pow);if(i==l.length-1&&l[i]>>j+1==0)break;pow=pow.square()}return out},mulmod:function(that,N){return this.mod(N).mul(that.mod(N)).mod(N)},powermod:function(x,N){if(x=new sjcl.bn(x),N=new sjcl.bn(N),(N.limbs[0]&1)==1){var montOut=this.montpowermod(x,N);if(montOut!=!1)return montOut}var i,j,l=x.normalize().trim().limbs,out=new this._class(1),pow=this;for(i=0;i<l.length;i++)for(j=0;j<this.radix;j++){if(l[i]&1<<j)out=out.mulmod(pow,N);if(i==l.length-1&&l[i]>>j+1==0)break;pow=pow.mulmod(pow,N)}return out},montpowermod:function(x,N){x=new sjcl.bn(x).normalize().trim(),N=new sjcl.bn(N);var i,j,radix=this.radix,out=new this._class(1),pow=this.copy(),R,s,wind,bitsize=x.bitLength();R=new sjcl.bn({limbs:N.copy().normalize().trim().limbs.map(function(){return 0})});for(s=this.radix;s>0;s--)if((N.limbs[N.limbs.length-1]>>s&1)==1){R.limbs[R.limbs.length-1]=1<<s;break}if(bitsize==0)return this;else if(bitsize<18)wind=1;else if(bitsize<48)wind=3;else if(bitsize<144)wind=4;else if(bitsize<768)wind=5;else wind=6;var RR=R.copy(),NN=N.copy(),RP=new sjcl.bn(1),NP=new sjcl.bn(0),RT=R.copy();while(RT.greaterEquals(1))if(RT.halveM(),(RP.limbs[0]&1)==0)RP.halveM(),NP.halveM();else RP.addM(NN),RP.halveM(),NP.halveM(),NP.addM(RR);RP=RP.normalize(),NP=NP.normalize(),RR.doubleM();var R2=RR.mulmod(RR,N);if(!RR.mul(RP).sub(N.mul(NP)).equals(1))return!1;var montIn=function(c){return montMul(c,R2)},montMul=function(a,b){var k,ab,right,abBar,mask=(1<<s+1)-1;if(ab=a.mul(b),right=ab.mul(NP),right.limbs=right.limbs.slice(0,R.limbs.length),right.limbs.length==R.limbs.length)right.limbs[R.limbs.length-1]&=mask;right=right.mul(N),abBar=ab.add(right).normalize().trim(),abBar.limbs=abBar.limbs.slice(R.limbs.length-1);for(k=0;k<abBar.limbs.length;k++){if(k>0)abBar.limbs[k-1]|=(abBar.limbs[k]&mask)<<radix-s-1;abBar.limbs[k]=abBar.limbs[k]>>s+1}if(abBar.greaterEquals(N))abBar.subM(N);return abBar},montOut=function(c){return montMul(c,1)};pow=montIn(pow),out=montIn(out);var h,precomp={},cap=(1<<wind-1)-1;precomp[1]=pow.copy(),precomp[2]=montMul(pow,pow);for(h=1;h<=cap;h++)precomp[2*h+1]=montMul(precomp[2*h-1],precomp[2]);var getBit=function(exp,i){var off=i%exp.radix;return(exp.limbs[Math.floor(i/exp.radix)]&1<<off)>>off};for(i=x.bitLength()-1;i>=0;)if(getBit(x,i)==0)out=montMul(out,out),i=i-1;else{var l=i-wind+1;while(getBit(x,l)==0)l++;var indx=0;for(j=l;j<=i;j++)indx+=getBit(x,j)<<j-l,out=montMul(out,out);out=montMul(out,precomp[indx]),i=l-1}return montOut(out)},trim:function(){var l=this.limbs,p;do p=l.pop();while(l.length&&p===0);return l.push(p),this},reduce:function(){return this},fullReduce:function(){return this.normalize()},normalize:function(){var carry=0,i,pv=this.placeVal,ipv=this.ipv,l,m,limbs=this.limbs,ll=limbs.length,mask=this.radixMask;for(i=0;i<ll||carry!==0&&carry!==-1;i++)l=(limbs[i]||0)+carry,m=limbs[i]=l&mask,carry=(l-m)*ipv;if(carry===-1)limbs[i-1]-=pv;return this.trim(),this},cnormalize:function(){var carry=0,i,ipv=this.ipv,l,m,limbs=this.limbs,ll=limbs.length,mask=this.radixMask;for(i=0;i<ll-1;i++)l=limbs[i]+carry,m=limbs[i]=l&mask,carry=(l-m)*ipv;return limbs[i]+=carry,this},toBits:function(len){this.fullReduce(),len=len||this.exponent||this.bitLength();var i=Math.floor((len-1)/24),w=sjcl.bitArray,e=(len+7&-8)%this.radix||this.radix,out=[w.partial(e,this.getLimb(i))];for(i--;i>=0;i--)out=w.concat(out,[w.partial(Math.min(this.radix,len),this.getLimb(i))]),len-=this.radix;return out},bitLength:function(){this.fullReduce();var out=this.radix*(this.limbs.length-1),b=this.limbs[this.limbs.length-1];for(;b;b>>>=1)out++;return out+7&-8}};sjcl.bn.fromBits=function(bits){var Class=this,out=new Class,words=[],w=sjcl.bitArray,t=this.prototype,l=Math.min(this.bitLength||4294967296,w.bitLength(bits)),e=l%t.radix||t.radix;words[0]=w.extract(bits,0,e);for(;e<l;e+=t.radix)words.unshift(w.extract(bits,e,t.radix));return out.limbs=words,out};sjcl.bn.prototype.ipv=1/(sjcl.bn.prototype.placeVal=Math.pow(2,sjcl.bn.prototype.radix));sjcl.bn.prototype.radixMask=(1<<sjcl.bn.prototype.radix)-1;sjcl.bn.pseudoMersennePrime=function(exponent,coeff){function p(it){this.initWith(it)}var ppr=p.prototype=new sjcl.bn,i,tmp,mo;mo=ppr.modOffset=Math.ceil(tmp=exponent/ppr.radix),ppr.exponent=exponent,ppr.offset=[],ppr.factor=[],ppr.minOffset=mo,ppr.fullMask=0,ppr.fullOffset=[],ppr.fullFactor=[],ppr.modulus=p.modulus=new sjcl.bn(Math.pow(2,exponent)),ppr.fullMask=0|-Math.pow(2,exponent%ppr.radix);for(i=0;i<coeff.length;i++)ppr.offset[i]=Math.floor(coeff[i][0]/ppr.radix-tmp),ppr.fullOffset[i]=Math.floor(coeff[i][0]/ppr.radix)-mo+1,ppr.factor[i]=coeff[i][1]*Math.pow(0.5,exponent-coeff[i][0]+ppr.offset[i]*ppr.radix),ppr.fullFactor[i]=coeff[i][1]*Math.pow(0.5,exponent-coeff[i][0]+ppr.fullOffset[i]*ppr.radix),ppr.modulus.addM(new sjcl.bn(Math.pow(2,coeff[i][0])*coeff[i][1])),ppr.minOffset=Math.min(ppr.minOffset,-ppr.offset[i]);return ppr._class=p,ppr.modulus.cnormalize(),ppr.reduce=function(){var i,k,l,mo=this.modOffset,limbs=this.limbs,off=this.offset,ol=this.offset.length,fac=this.factor,ll;i=this.minOffset;while(limbs.length>mo){l=limbs.pop(),ll=limbs.length;for(k=0;k<ol;k++)limbs[ll+off[k]]-=fac[k]*l;if(i--,!i)limbs.push(0),this.cnormalize(),i=this.minOffset}return this.cnormalize(),this},ppr._strongReduce=ppr.fullMask===-1?ppr.reduce:function(){var limbs=this.limbs,i=limbs.length-1,k,l;if(this.reduce(),i===this.modOffset-1){l=limbs[i]&this.fullMask,limbs[i]-=l;for(k=0;k<this.fullOffset.length;k++)limbs[i+this.fullOffset[k]]-=this.fullFactor[k]*l;this.normalize()}},ppr.fullReduce=function(){var greater,i;this._strongReduce(),this.addM(this.modulus),this.addM(this.modulus),this.normalize(),this._strongReduce();for(i=this.limbs.length;i<this.modOffset;i++)this.limbs[i]=0;greater=this.greaterEquals(this.modulus);for(i=0;i<this.limbs.length;i++)this.limbs[i]-=this.modulus.limbs[i]*greater;return this.cnormalize(),this},ppr.inverse=function(){return this.power(this.modulus.sub(2))},p.fromBits=sjcl.bn.fromBits,p};var sbp=sjcl.bn.pseudoMersennePrime;sjcl.bn.prime={p127:sbp(127,[[0,-1]]),p25519:sbp(255,[[0,-19]]),p192k:sbp(192,[[32,-1],[12,-1],[8,-1],[7,-1],[6,-1],[3,-1],[0,-1]]),p224k:sbp(224,[[32,-1],[12,-1],[11,-1],[9,-1],[7,-1],[4,-1],[1,-1],[0,-1]]),p256k:sbp(256,[[32,-1],[9,-1],[8,-1],[7,-1],[6,-1],[4,-1],[0,-1]]),p192:sbp(192,[[0,-1],[64,-1]]),p224:sbp(224,[[0,1],[96,-1]]),p256:sbp(256,[[0,-1],[96,1],[192,1],[224,-1]]),p384:sbp(384,[[0,-1],[32,1],[96,-1],[128,-1]]),p521:sbp(521,[[0,-1]])};sjcl.bn.random=function(modulus,paranoia){if(typeof modulus!=="object")modulus=new sjcl.bn(modulus);var words,i,l=modulus.limbs.length,m=modulus.limbs[l-1]+1,out=new sjcl.bn;while(!0){do if(words=sjcl.random.randomWords(l,paranoia),words[l-1]<0)words[l-1]+=4294967296;while(Math.floor(words[l-1]/m)===Math.floor(4294967296/m));words[l-1]%=m;for(i=0;i<l-1;i++)words[i]&=modulus.radixMask;if(out.limbs=words,!out.greaterEquals(modulus))return out}};if(typeof ArrayBuffer>"u")(function(globals){globals.ArrayBuffer=function(){},globals.DataView=function(){}})(null);sjcl.codec.arrayBuffer={fromBits:function(arr,padding,padding_count){var out,i,ol,tmp,smallest;if(padding=padding==null?!0:padding,padding_count=padding_count||8,arr.length===0)return new ArrayBuffer(0);if(ol=sjcl.bitArray.bitLength(arr)/8,sjcl.bitArray.bitLength(arr)%8!==0)throw new sjcl.exception.invalid("Invalid bit size, must be divisble by 8 to fit in an arraybuffer correctly");if(padding&&ol%padding_count!==0)ol+=padding_count-ol%padding_count;tmp=new DataView(new ArrayBuffer(arr.length*4));for(i=0;i<arr.length;i++)tmp.setUint32(i*4,arr[i]<<32);if(out=new DataView(new ArrayBuffer(ol)),out.byteLength===tmp.byteLength)return tmp.buffer;smallest=tmp.byteLength<out.byteLength?tmp.byteLength:out.byteLength;for(i=0;i<smallest;i++)out.setUint8(i,tmp.getUint8(i));return out.buffer},toBits:function(buffer){var i,out=[],len,inView,tmp;if(buffer.byteLength===0)return[];inView=new DataView(buffer),len=inView.byteLength-inView.byteLength%4;for(var i=0;i<len;i+=4)out.push(inView.getUint32(i));if(inView.byteLength%4!=0){tmp=new DataView(new ArrayBuffer(4));for(var i=0,l=inView.byteLength%4;i<l;i++)tmp.setUint8(i+4-l,inView.getUint8(len+i));out.push(sjcl.bitArray.partial(inView.byteLength%4*8,tmp.getUint32(0)))}return out},hexDumpBuffer:function(buffer){var stringBufferView=new DataView(buffer),string="",pad=function(n,width){return n=n+"",n.length>=width?n:Array(width-n.length+1).join("0")+n};for(var i=0;i<stringBufferView.byteLength;i+=2){if(i%16==0)string+=`
128
- `+i.toString(16)+"\t";string+=pad(stringBufferView.getUint16(i).toString(16),4)+" "}if(typeof console===void 0)console=console||{log:function(){}};console.log(string.toUpperCase())}};var sjcl_default=sjcl;function assertNever(name,x){throw Error(`unexpected ${name} identifier: ${x}`)}function getHashParams(hash){switch(hash){case"SHA-1":return{name:hash,hLen:20};case"SHA-256":return{name:hash,hLen:32};case"SHA-384":return{name:hash,hLen:48};case"SHA-512":return{name:hash,hLen:64};default:assertNever("Hash",hash)}}function os2ip(bytes){return sjcl_default.bn.fromBits(sjcl_default.codec.bytes.toBits(Array.from(bytes)))}function i2osp(num,byteLength){if(Math.ceil(num.bitLength()/8)>byteLength)throw Error(`number does not fit in ${byteLength} bytes`);let bytes=new Uint8Array(byteLength),unpadded=new Uint8Array(sjcl_default.codec.bytes.fromBits(num.toBits(void 0)));return bytes.set(unpadded,byteLength-unpadded.length),bytes}function joinAll(a){let size=0;for(let ai of a)size+=ai.length;let ret=new Uint8Array(new ArrayBuffer(size)),offset=0;for(let ai of a)ret.set(ai,offset),offset+=ai.length;return ret}function xor(a,b){if(a.length!==b.length||a.length===0)throw Error(`arrays of different length: ${a.length} - ${b.length}`);let ai=a[Symbol.iterator](),bi=b[Symbol.iterator]();return new Uint8Array(a.length).map(()=>ai.next().value^bi.next().value)}function incCounter(c){if(c[3]++,c[3]!=0)return;if(c[2]++,c[2]!=0)return;if(c[1]++,c[1]!=0)return;c[0]++;return}async function mgf1(h,seed,mLen){let n=Math.ceil(mLen/h.hLen);if(n>Math.pow(2,32))throw Error("mask too long");let T=new Uint8Array,counter=new Uint8Array(4);for(let i=0;i<n;i++){let hash=new Uint8Array(await crypto.subtle.digest(h.name,joinAll([seed,counter]).slice().buffer));T=joinAll([T,hash]),incCounter(counter)}return T.subarray(0,mLen)}async function emsa_pss_encode(msg,emBits,opts,mgf=mgf1){let{hash,sLen}=opts,hashParams=getHashParams(hash),{hLen}=hashParams,emLen=Math.ceil(emBits/8),mHash=new Uint8Array(await crypto.subtle.digest(hash,msg.slice().buffer));if(emLen<hLen+sLen+2)throw Error("encoding error");let salt=crypto.getRandomValues(new Uint8Array(sLen)),mPrime=joinAll([new Uint8Array(8),mHash,salt]),h=new Uint8Array(await crypto.subtle.digest(hash,mPrime.slice().buffer)),ps=new Uint8Array(emLen-sLen-hLen-2),db=joinAll([ps,Uint8Array.of(1),salt]),dbMask=await mgf(hashParams,h,emLen-hLen-1),maskedDB=xor(db,dbMask);return maskedDB[0]&=255>>8*emLen-emBits,joinAll([maskedDB,h,Uint8Array.of(188)])}function rsavp1(pkS,s){if(!s.greaterEquals(new sjcl_default.bn(0))||s.greaterEquals(pkS.n))throw Error("signature representative out of range");return s.powermod(pkS.e,pkS.n)}function rsasp1(skS,m){if(!m.greaterEquals(new sjcl_default.bn(0))||m.greaterEquals(skS.n))throw Error("signature representative out of range");return m.powermod(skS.d,skS.n)}function is_coprime(x,n){try{x.inverseMod(n)}catch{return!1}return!0}function random_integer_uniform(n,kLen){for(let i=0;i<128;i++){let r=os2ip(crypto.getRandomValues(new Uint8Array(kLen)));if(!(r.greaterEquals(n)||r.equals(0)))return r}throw Error("reached maximum tries for random integer generation")}var NATIVE_SUPPORT_NAME="RSA-RAW";async function rsaRawBlingSign(privateKey,blindMsg){if(privateKey.algorithm.name!==NATIVE_SUPPORT_NAME)privateKey=await crypto.subtle.importKey("pkcs8",await crypto.subtle.exportKey("pkcs8",privateKey),{...privateKey.algorithm,name:NATIVE_SUPPORT_NAME},privateKey.extractable,privateKey.usages);let signature=await crypto.subtle.sign({name:privateKey.algorithm.name},privateKey,blindMsg.slice().buffer);return new Uint8Array(signature)}var PrepareType;(function(PrepareType){PrepareType[PrepareType.Deterministic=0]="Deterministic",PrepareType[PrepareType.Randomized=32]="Randomized"})(PrepareType||(PrepareType={}));class BlindRSA{params;static NAME="RSA-PSS";constructor(params){switch(this.params=params,params.prepareType){case PrepareType.Deterministic:case PrepareType.Randomized:return;default:assertNever("PrepareType",params.prepareType)}}toString(){let hash=this.params.hash.replace("-",""),pssType="PSS"+(this.params.saltLength===0?"ZERO":""),prepare=PrepareType[this.params.prepareType];return`RSABSSA-${hash}-${pssType}-${prepare}`}prepare(msg){let msg_prefix_len=this.params.prepareType,msg_prefix=crypto.getRandomValues(new Uint8Array(msg_prefix_len));return joinAll([msg_prefix,msg])}async extractKeyParams(key,type){if(key.type!==type||key.algorithm.name!==BlindRSA.NAME)throw Error(`key is not ${BlindRSA.NAME}`);if(!key.extractable)throw Error("key is not extractable");let{modulusLength:modulusLengthBits,hash:hashFn}=key.algorithm,modulusLengthBytes=Math.ceil(modulusLengthBits/8),hash=hashFn.name;if(hash.toLowerCase()!==this.params.hash.toLowerCase())throw Error(`hash is not ${this.params.hash}`);return{jwkKey:await crypto.subtle.exportKey("jwk",key),modulusLengthBits,modulusLengthBytes,hash}}async blind(publicKey,msg){let{jwkKey,modulusLengthBits:modulusLength,modulusLengthBytes:kLen,hash}=await this.extractKeyParams(publicKey,"public");if(!jwkKey.n||!jwkKey.e)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n)),pk={e:sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.e)),n},opts={sLen:this.params.saltLength,hash},encoded_msg=await emsa_pss_encode(msg,modulusLength-1,opts),m=os2ip(encoded_msg);if(!is_coprime(m,n))throw Error("invalid input");let r=random_integer_uniform(n,kLen),inv;try{inv=i2osp(r.inverseMod(n),kLen)}catch(e){throw Error(`blinding error: ${e.toString()}`)}let x=rsavp1(pk,r),z=m.mulmod(x,n);return{blindedMsg:i2osp(z,kLen),inv}}async blindSign(privateKey,blindMsg){if(this.params.supportsRSARAW)return rsaRawBlingSign(privateKey,blindMsg);let{jwkKey,modulusLengthBytes:kLen}=await this.extractKeyParams(privateKey,"private");if(!jwkKey.n||!jwkKey.d||!jwkKey.e)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n)),d=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.d)),e=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.e)),sk={n,d},pk={n,e},m=os2ip(blindMsg),s=rsasp1(sk,m),mp=rsavp1(pk,s);if(!m.equals(mp))throw Error("signing failure");return i2osp(s,kLen)}async finalize(publicKey,msg,blindSig,inv){let{jwkKey,modulusLengthBytes:kLen}=await this.extractKeyParams(publicKey,"public");if(!jwkKey.n)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n));if(inv.length!=kLen)throw Error("unexpected input size");let rInv=os2ip(inv);if(blindSig.length!=kLen)throw Error("unexpected input size");let s=os2ip(blindSig).mulmod(rInv,n),sig=i2osp(s,kLen),algorithm={name:BlindRSA.NAME,saltLength:this.params.saltLength};if(!await crypto.subtle.verify(algorithm,publicKey,sig.slice().buffer,msg.slice().buffer))throw Error("invalid signature");return sig}static generateKey(algorithm){return crypto.subtle.generateKey({...algorithm,name:BlindRSA.NAME},!0,["sign","verify"])}generateKey(algorithm){return BlindRSA.generateKey({...algorithm,hash:this.params.hash})}verify(publicKey,signature,message){return crypto.subtle.verify({name:BlindRSA.NAME,saltLength:this.params.saltLength},publicKey,signature.slice().buffer,message.slice().buffer)}}var Params={RSABSSA_SHA384_PSS_Randomized:{name:"RSABSSA-SHA384-PSS-Randomized",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Randomized},RSABSSA_SHA384_PSS_Deterministic:{name:"RSABSSA-SHA384-PSS-Deterministic",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Deterministic},RSABSSA_SHA384_PSSZERO_Randomized:{name:"RSABSSA-SHA384-PSSZERO-Randomized",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Randomized},RSABSSA_SHA384_PSSZERO_Deterministic:{name:"RSABSSA-SHA384-PSSZERO-Deterministic",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Deterministic},RSAPBSSA_SHA384_PSS_Randomized:{name:"RSAPBSSA-SHA384-PSS-Randomized",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Randomized},RSAPBSSA_SHA384_PSS_Deterministic:{name:"RSAPBSSA-SHA384-PSS-Deterministic",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Deterministic},RSAPBSSA_SHA384_PSSZERO_Randomized:{name:"RSAPBSSA-SHA384-PSSZERO-Randomized",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Randomized},RSAPBSSA_SHA384_PSSZERO_Deterministic:{name:"RSAPBSSA-SHA384-PSSZERO-Deterministic",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Deterministic}},RSABSSA={SHA384:{generateKey:(algorithm)=>BlindRSA.generateKey({...algorithm,hash:"SHA-384"}),PSS:{Randomized:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSS_Randomized,...params}),Deterministic:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSS_Deterministic,...params})},PSSZero:{Randomized:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSSZERO_Randomized,...params}),Deterministic:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSSZERO_Deterministic,...params})}}};var PINNED_ISSUER_KEYS={"https://api.velloo.ai":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs54VddkMfc1b0S+2i8GOouyseMo4mb6+zPYBv/Omu1sZQfTYFVFttZOWO0vw6ObT8EVBC/4qCgZPa1d8To55rNe6ZSWJkvXFuoEeOaVDlfDhxduFnVFa5QelxEwVXAFpVSSdPwcFicoCNxuhHTbezPQl3yKLZVwIUncMNhpwsjXVyrKEtSp+5cAY1SH2axLBpqPT1nReH5HAZmAmUcZFvJND45htig2o2tvFSTkOCurFt6lw9HiCWjNE1L1C3Y/VuGkvIVbQShNipyBvgn1ZtJxFvkY4M4ULUj9G9JMb6pYtUupUddPLfpROXSPFvbDk22JOOP2VWtv5r9mXeTCAIQIDAQAB"};var TOKEN_SCHEME="RSABSSA-SHA384.PSS.Randomized",suite=RSABSSA.SHA384.PSS.Randomized(),KEY_ALG={name:"RSA-PSS",hash:"SHA-384"},BATCH=10,defaultTokenStorePath=()=>join15(homedir3(),".velloo","feedback-tokens.json");async function loadStore(path){try{return JSON.parse(await readFile6(path,"utf8"))}catch{return{}}}async function saveStore(path,store){await mkdir8(dirname10(path),{recursive:!0}),await writeJsonAtomic(path,store)}var originOf=(url)=>new URL(url).origin;async function fetchIssuerKey(cloudUrl,prior){let res=await fetch(`${cloudUrl}/v1/feedback/token-key`,{signal:AbortSignal.timeout(5000)});if(!res.ok)throw new TokenIssueError("rejected",`token key fetch failed (${res.status})`);let parsed=FeedbackIssuerResponseSchema.safeParse(await res.json().catch(()=>null));if(!parsed.success)throw Error("the cloud's feedback token key reply was malformed");let{scheme,publicKey}=parsed.data;if(scheme!==TOKEN_SCHEME)throw Error(`unsupported feedback token scheme ${JSON.stringify(scheme)}`);let pinned=PINNED_ISSUER_KEYS[originOf(cloudUrl)];if(pinned&&publicKey!==pinned)throw Error("the cloud's feedback issuer key does not match the key pinned in this velloo build \u2014 refusing to fetch tokens (a per-user key would deanonymize feedback).");if(!pinned&&prior&&prior.publicKey!==publicKey)throw Error(`the cloud's feedback issuer key changed since tokens were first issued \u2014 refusing to fetch more. If the rotation is expected, delete ${defaultTokenStorePath()} and retry.`);return{publicKey:await crypto.subtle.importKey("spki",Buffer.from(publicKey,"base64"),KEY_ALG,!0,["verify"]),spkiB64:publicKey}}async function topUpTokens(cloud,min=1,storePath=defaultTokenStorePath()){let store=await loadStore(storePath),origin=originOf(cloud.url),entry=store[origin];if((entry?.tokens.length??0)>=min)return;if(!cloud.token)throw new TokenIssueError("signed-out","not signed in \u2014 run `velloo login` to fetch feedback tokens");let issuer=await fetchIssuerKey(cloud.url,entry),blinds=[];for(let i=0;i<BATCH;i++){let prepared=suite.prepare(crypto.getRandomValues(new Uint8Array(32)));blinds.push({prepared,...await suite.blind(issuer.publicKey,prepared)})}let res=await fetch(`${cloud.url}/v1/feedback/tokens`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${cloud.token}`},body:JSON.stringify({blinded:blinds.map((b)=>Buffer.from(b.blindedMsg).toString("base64"))}),signal:AbortSignal.timeout(15000)});if(!res.ok)throw new TokenIssueError(res.status===402||res.status===429?"no-tokens":"rejected",`token issuance failed (${res.status})`);let issued=FeedbackSignaturesResponseSchema.safeParse(await res.json().catch(()=>null));if(!issued.success||issued.data.signatures.length!==blinds.length)throw Error("token issuance returned a malformed signature batch");let{signatures}=issued.data,tokens=[];for(let i=0;i<blinds.length;i++){let b=blinds[i];if(!b)continue;let sig=await suite.finalize(issuer.publicKey,b.prepared,Buffer.from(signatures[i]??"","base64"),b.inv);if(!await suite.verify(issuer.publicKey,sig,b.prepared))throw Error("issued token failed local verification \u2014 not storing it");tokens.push({token:Buffer.from(b.prepared).toString("base64"),sig:Buffer.from(sig).toString("base64")})}store[origin]={scheme:TOKEN_SCHEME,publicKey:issuer.spkiB64,tokens:[...entry?.tokens??[],...tokens]},await saveStore(storePath,store)}async function popToken(cloudUrl,storePath){let store=await loadStore(storePath),entry=store[originOf(cloudUrl)],token=entry?.tokens.shift();if(!entry||!token)return null;return await saveStore(storePath,store),token}function feedbackError(reason,message,retryable){return{kind:"FeedbackNotSent",reason,message,retryable}}class TokenIssueError extends Error{reason;constructor(reason,message){super(message);this.reason=reason}}async function sendAnonymousFeedback(cloud,payload,storePath=defaultTokenStorePath()){for(let attempt=0;attempt<2;attempt++){try{await topUpTokens(cloud,1,storePath)}catch(e){let message=e instanceof Error?e.message:String(e);if(e instanceof TokenIssueError)return err(feedbackError(e.reason,message,e.reason!=="signed-out"));return err(feedbackError("unreachable",message,!0))}let token=await popToken(cloud.url,storePath);if(!token)return err(feedbackError("no-tokens","no anonymous feedback tokens available for this account",!0));try{let res=await fetch(`${cloud.url}/v1/feedback/anonymous`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({body:payload.body,...payload.toolVersion?{toolVersion:payload.toolVersion}:{},...payload.source?{source:payload.source}:{},token:token.token,signature:token.sig}),signal:AbortSignal.timeout(5000)});if(res.status===409)continue;if(!res.ok)return err(feedbackError("rejected",`velloo-cloud refused the message (${res.status}).`,!1));return ok("Thanks \u2014 your feedback was sent (anonymously).")}catch{return err(feedbackError("unreachable","Couldn't reach velloo-cloud; feedback not sent.",!0))}}return err(feedbackError("rejected","feedback tokens kept colliding \u2014 try again later",!0))}import{existsSync as existsSync7}from"fs";import{isAbsolute,resolve as resolve6}from"path";function createServerProviderLoader(folderRoot,hostApp){let hostAppRoot=folderRoot?hostAppRootFrom(folderRoot,hostApp):void 0;return createProviderLoader({none:async()=>(await import("./chunk-49cgk5s2.js")).createProvider(),mui:async()=>(await import("./chunk-n9kcxaj7.js")).createProvider(),antd:async()=>(await import("./chunk-k6n249vb.js")).createProvider(),chakra:async()=>(await import("./chunk-bvmtq0vn.js")).createProvider(),"shadcn-upstream":async(library)=>{let cacheDir=resolveUpstreamCacheDir(library,folderRoot);return(await import("./chunk-dsks52m7.js")).createProvider({version:library.version,...cacheDir?{cacheDir}:{},...hostAppRoot?{hostAppRoot}:{}})}})}function resolveUpstreamCacheDir(library,folderRoot){let path=library.componentsPath;if(!path||path==="binary")return null;if(path.startsWith("~/")){let home=process.env.HOME??process.env.USERPROFILE??"";if(!home)return null;let abs=resolve6(home,path.slice(2));return existsSync7(abs)?abs:null}if(isAbsolute(path))return library.source==="in-repo"||existsSync7(path)?path:null;if(!folderRoot)return null;let abs=resolveAppPath(folderRoot,path);return library.source==="in-repo"||existsSync7(abs)?abs:null}async function resolveProviders(config,folderRoot,loader){let effective=loader??createServerProviderLoader(folderRoot,config.hostApp),providers={};for(let[libraryId,library]of Object.entries(config.libraries))try{providers[libraryId]=await effective(library)}catch(err){if(err instanceof UnknownProviderError)throw Error(`velloo: this binary doesn't know how to load library "${err.id}" (registered as "${libraryId}"). Upgrade velloo or pick a supported provider in .design/config.json.`);throw err}let defaultProvider=providers[config.defaultLibrary];if(!defaultProvider)throw Error(`velloo: defaultLibrary "${config.defaultLibrary}" doesn't match any registered library.`);if(config.styling){let css=config.styling.framework,wanted=CSS_FRAMEWORK_CHANNEL[css];if(!Object.values(providers).some((p)=>styleChannelOf(p,css).kind===wanted)){let libs=Object.values(config.libraries).map((l)=>l.id).join(", ");throw Error(`velloo: config.styling.framework "${css}" isn't supported by any registered library (${libs}). shadcn and MUI carry their own styling; only the no-framework library can pair with "none". Fix the CSS framework or library in .design/config.json.`)}}return{providers,defaultProvider}}import{existsSync as existsSync8}from"fs";import{resolve as resolve7}from"path";var CONFIG_NAMES=["tailwind.config.ts","tailwind.config.js","tailwind.config.cjs","tailwind.config.mjs"];function findHostTailwindConfig(folderRoot,hostApp){let root=hostAppRootFrom(folderRoot,hostApp);for(let name of CONFIG_NAMES){let path=resolve7(root,name);if(existsSync8(path))return path}return null}import{readFile as readFile7}from"fs/promises";import{dirname as dirname11,join as join16}from"path";import{compile}from"@tailwindcss/node";import{Scanner}from"@tailwindcss/oxide";class TailwindJit{pagesDir;extraEntryCss;extraSourceDirs;hostConfigPath;compilerPromise=null;cached=null;cachedCandidates=null;snippetsDir;providers;tailwindProviders;constructor(providers,pagesDir,snippetsDir,extraEntryCss,extraSourceDirs,hostConfigPath,folderCss){this.pagesDir=pagesDir;this.extraEntryCss=extraEntryCss;this.extraSourceDirs=extraSourceDirs;this.hostConfigPath=hostConfigPath;if(this.providers=Array.isArray(providers)?providers:[providers],this.providers.length===0)throw Error("TailwindJit: at least one provider is required.");this.tailwindProviders=this.providers.filter((p)=>styleChannelOf(p,folderCss).needsTailwindJit),this.snippetsDir=snippetsDir??join16(pagesDir,"..","snippets")}invalidate(){this.cached=null,this.cachedCandidates=null,this.compilerPromise=null}async build(extraCandidates){if(this.tailwindProviders.length===0)return"";let hasExtra=extraCandidates!==void 0&&extraCandidates.length>0;if(!hasExtra&&this.cached!==null)return this.cached;let compiler=await this.getCompiler(),candidates=this.scanCandidates();if(!hasExtra)return this.cached=compiler.build(candidates),this.cached;return compiler.build([...candidates,...extraCandidates])}scanCandidates(){if(this.cachedCandidates!==null)return this.cachedCandidates;let dedupedDirs=Array.from(new Set([...this.tailwindProviders.map((p)=>p.componentsDir),helpersComponentsDir])),hostDirs=Array.from(new Set(this.extraSourceDirs?.()??[])),scanner=new Scanner({sources:[...dedupedDirs.map((base)=>({base,pattern:"**/*.tsx",negated:!1})),...hostDirs.map((base)=>({base,pattern:"**/*.tsx",negated:!1})),{base:this.pagesDir,pattern:"**/*.json",negated:!1},{base:this.snippetsDir,pattern:"**/*.json",negated:!1}]});return this.cachedCandidates=scanner.scan(),this.cachedCandidates}entryCss(){return this.mergedEntryCss()}async mergedEntryCss(){let primary=this.tailwindProviders[0];if(!primary)throw Error("TailwindJit: no Tailwind-channel provider, cannot build entry CSS.");let primaryBase=dirname11(primary.styleEntryPath),extra=this.extraEntryCss?.()??"";if(this.tailwindProviders.length===1){let css=await readFile7(primary.styleEntryPath,"utf8");return{css:extra?`${css}
128
+ `+i.toString(16)+"\t";string+=pad(stringBufferView.getUint16(i).toString(16),4)+" "}if(typeof console===void 0)console=console||{log:function(){}};console.log(string.toUpperCase())}};var sjcl_default=sjcl;function assertNever(name,x){throw Error(`unexpected ${name} identifier: ${x}`)}function getHashParams(hash){switch(hash){case"SHA-1":return{name:hash,hLen:20};case"SHA-256":return{name:hash,hLen:32};case"SHA-384":return{name:hash,hLen:48};case"SHA-512":return{name:hash,hLen:64};default:assertNever("Hash",hash)}}function os2ip(bytes){return sjcl_default.bn.fromBits(sjcl_default.codec.bytes.toBits(Array.from(bytes)))}function i2osp(num,byteLength){if(Math.ceil(num.bitLength()/8)>byteLength)throw Error(`number does not fit in ${byteLength} bytes`);let bytes=new Uint8Array(byteLength),unpadded=new Uint8Array(sjcl_default.codec.bytes.fromBits(num.toBits(void 0)));return bytes.set(unpadded,byteLength-unpadded.length),bytes}function joinAll(a){let size=0;for(let ai of a)size+=ai.length;let ret=new Uint8Array(new ArrayBuffer(size)),offset=0;for(let ai of a)ret.set(ai,offset),offset+=ai.length;return ret}function xor(a,b){if(a.length!==b.length||a.length===0)throw Error(`arrays of different length: ${a.length} - ${b.length}`);let ai=a[Symbol.iterator](),bi=b[Symbol.iterator]();return new Uint8Array(a.length).map(()=>ai.next().value^bi.next().value)}function incCounter(c){if(c[3]++,c[3]!=0)return;if(c[2]++,c[2]!=0)return;if(c[1]++,c[1]!=0)return;c[0]++;return}async function mgf1(h,seed,mLen){let n=Math.ceil(mLen/h.hLen);if(n>Math.pow(2,32))throw Error("mask too long");let T=new Uint8Array,counter=new Uint8Array(4);for(let i=0;i<n;i++){let hash=new Uint8Array(await crypto.subtle.digest(h.name,joinAll([seed,counter]).slice().buffer));T=joinAll([T,hash]),incCounter(counter)}return T.subarray(0,mLen)}async function emsa_pss_encode(msg,emBits,opts,mgf=mgf1){let{hash,sLen}=opts,hashParams=getHashParams(hash),{hLen}=hashParams,emLen=Math.ceil(emBits/8),mHash=new Uint8Array(await crypto.subtle.digest(hash,msg.slice().buffer));if(emLen<hLen+sLen+2)throw Error("encoding error");let salt=crypto.getRandomValues(new Uint8Array(sLen)),mPrime=joinAll([new Uint8Array(8),mHash,salt]),h=new Uint8Array(await crypto.subtle.digest(hash,mPrime.slice().buffer)),ps=new Uint8Array(emLen-sLen-hLen-2),db=joinAll([ps,Uint8Array.of(1),salt]),dbMask=await mgf(hashParams,h,emLen-hLen-1),maskedDB=xor(db,dbMask);return maskedDB[0]&=255>>8*emLen-emBits,joinAll([maskedDB,h,Uint8Array.of(188)])}function rsavp1(pkS,s){if(!s.greaterEquals(new sjcl_default.bn(0))||s.greaterEquals(pkS.n))throw Error("signature representative out of range");return s.powermod(pkS.e,pkS.n)}function rsasp1(skS,m){if(!m.greaterEquals(new sjcl_default.bn(0))||m.greaterEquals(skS.n))throw Error("signature representative out of range");return m.powermod(skS.d,skS.n)}function is_coprime(x,n){try{x.inverseMod(n)}catch{return!1}return!0}function random_integer_uniform(n,kLen){for(let i=0;i<128;i++){let r=os2ip(crypto.getRandomValues(new Uint8Array(kLen)));if(!(r.greaterEquals(n)||r.equals(0)))return r}throw Error("reached maximum tries for random integer generation")}var NATIVE_SUPPORT_NAME="RSA-RAW";async function rsaRawBlingSign(privateKey,blindMsg){if(privateKey.algorithm.name!==NATIVE_SUPPORT_NAME)privateKey=await crypto.subtle.importKey("pkcs8",await crypto.subtle.exportKey("pkcs8",privateKey),{...privateKey.algorithm,name:NATIVE_SUPPORT_NAME},privateKey.extractable,privateKey.usages);let signature=await crypto.subtle.sign({name:privateKey.algorithm.name},privateKey,blindMsg.slice().buffer);return new Uint8Array(signature)}var PrepareType;(function(PrepareType){PrepareType[PrepareType.Deterministic=0]="Deterministic",PrepareType[PrepareType.Randomized=32]="Randomized"})(PrepareType||(PrepareType={}));class BlindRSA{params;static NAME="RSA-PSS";constructor(params){switch(this.params=params,params.prepareType){case PrepareType.Deterministic:case PrepareType.Randomized:return;default:assertNever("PrepareType",params.prepareType)}}toString(){let hash=this.params.hash.replace("-",""),pssType="PSS"+(this.params.saltLength===0?"ZERO":""),prepare=PrepareType[this.params.prepareType];return`RSABSSA-${hash}-${pssType}-${prepare}`}prepare(msg){let msg_prefix_len=this.params.prepareType,msg_prefix=crypto.getRandomValues(new Uint8Array(msg_prefix_len));return joinAll([msg_prefix,msg])}async extractKeyParams(key,type){if(key.type!==type||key.algorithm.name!==BlindRSA.NAME)throw Error(`key is not ${BlindRSA.NAME}`);if(!key.extractable)throw Error("key is not extractable");let{modulusLength:modulusLengthBits,hash:hashFn}=key.algorithm,modulusLengthBytes=Math.ceil(modulusLengthBits/8),hash=hashFn.name;if(hash.toLowerCase()!==this.params.hash.toLowerCase())throw Error(`hash is not ${this.params.hash}`);return{jwkKey:await crypto.subtle.exportKey("jwk",key),modulusLengthBits,modulusLengthBytes,hash}}async blind(publicKey,msg){let{jwkKey,modulusLengthBits:modulusLength,modulusLengthBytes:kLen,hash}=await this.extractKeyParams(publicKey,"public");if(!jwkKey.n||!jwkKey.e)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n)),pk={e:sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.e)),n},opts={sLen:this.params.saltLength,hash},encoded_msg=await emsa_pss_encode(msg,modulusLength-1,opts),m=os2ip(encoded_msg);if(!is_coprime(m,n))throw Error("invalid input");let r=random_integer_uniform(n,kLen),inv;try{inv=i2osp(r.inverseMod(n),kLen)}catch(e){throw Error(`blinding error: ${e.toString()}`)}let x=rsavp1(pk,r),z=m.mulmod(x,n);return{blindedMsg:i2osp(z,kLen),inv}}async blindSign(privateKey,blindMsg){if(this.params.supportsRSARAW)return rsaRawBlingSign(privateKey,blindMsg);let{jwkKey,modulusLengthBytes:kLen}=await this.extractKeyParams(privateKey,"private");if(!jwkKey.n||!jwkKey.d||!jwkKey.e)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n)),d=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.d)),e=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.e)),sk={n,d},pk={n,e},m=os2ip(blindMsg),s=rsasp1(sk,m),mp=rsavp1(pk,s);if(!m.equals(mp))throw Error("signing failure");return i2osp(s,kLen)}async finalize(publicKey,msg,blindSig,inv){let{jwkKey,modulusLengthBytes:kLen}=await this.extractKeyParams(publicKey,"public");if(!jwkKey.n)throw Error("key has invalid parameters");let n=sjcl_default.bn.fromBits(sjcl_default.codec.base64url.toBits(jwkKey.n));if(inv.length!=kLen)throw Error("unexpected input size");let rInv=os2ip(inv);if(blindSig.length!=kLen)throw Error("unexpected input size");let s=os2ip(blindSig).mulmod(rInv,n),sig=i2osp(s,kLen),algorithm={name:BlindRSA.NAME,saltLength:this.params.saltLength};if(!await crypto.subtle.verify(algorithm,publicKey,sig.slice().buffer,msg.slice().buffer))throw Error("invalid signature");return sig}static generateKey(algorithm){return crypto.subtle.generateKey({...algorithm,name:BlindRSA.NAME},!0,["sign","verify"])}generateKey(algorithm){return BlindRSA.generateKey({...algorithm,hash:this.params.hash})}verify(publicKey,signature,message){return crypto.subtle.verify({name:BlindRSA.NAME,saltLength:this.params.saltLength},publicKey,signature.slice().buffer,message.slice().buffer)}}var Params={RSABSSA_SHA384_PSS_Randomized:{name:"RSABSSA-SHA384-PSS-Randomized",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Randomized},RSABSSA_SHA384_PSS_Deterministic:{name:"RSABSSA-SHA384-PSS-Deterministic",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Deterministic},RSABSSA_SHA384_PSSZERO_Randomized:{name:"RSABSSA-SHA384-PSSZERO-Randomized",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Randomized},RSABSSA_SHA384_PSSZERO_Deterministic:{name:"RSABSSA-SHA384-PSSZERO-Deterministic",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Deterministic},RSAPBSSA_SHA384_PSS_Randomized:{name:"RSAPBSSA-SHA384-PSS-Randomized",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Randomized},RSAPBSSA_SHA384_PSS_Deterministic:{name:"RSAPBSSA-SHA384-PSS-Deterministic",hash:"SHA-384",saltLength:48,prepareType:PrepareType.Deterministic},RSAPBSSA_SHA384_PSSZERO_Randomized:{name:"RSAPBSSA-SHA384-PSSZERO-Randomized",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Randomized},RSAPBSSA_SHA384_PSSZERO_Deterministic:{name:"RSAPBSSA-SHA384-PSSZERO-Deterministic",hash:"SHA-384",saltLength:0,prepareType:PrepareType.Deterministic}},RSABSSA={SHA384:{generateKey:(algorithm)=>BlindRSA.generateKey({...algorithm,hash:"SHA-384"}),PSS:{Randomized:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSS_Randomized,...params}),Deterministic:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSS_Deterministic,...params})},PSSZero:{Randomized:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSSZERO_Randomized,...params}),Deterministic:(params={supportsRSARAW:!1})=>new BlindRSA({...Params.RSABSSA_SHA384_PSSZERO_Deterministic,...params})}}};var PINNED_ISSUER_KEYS={"https://api.velloo.ai":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs54VddkMfc1b0S+2i8GOouyseMo4mb6+zPYBv/Omu1sZQfTYFVFttZOWO0vw6ObT8EVBC/4qCgZPa1d8To55rNe6ZSWJkvXFuoEeOaVDlfDhxduFnVFa5QelxEwVXAFpVSSdPwcFicoCNxuhHTbezPQl3yKLZVwIUncMNhpwsjXVyrKEtSp+5cAY1SH2axLBpqPT1nReH5HAZmAmUcZFvJND45htig2o2tvFSTkOCurFt6lw9HiCWjNE1L1C3Y/VuGkvIVbQShNipyBvgn1ZtJxFvkY4M4ULUj9G9JMb6pYtUupUddPLfpROXSPFvbDk22JOOP2VWtv5r9mXeTCAIQIDAQAB"};var TOKEN_SCHEME="RSABSSA-SHA384.PSS.Randomized",suite=RSABSSA.SHA384.PSS.Randomized(),KEY_ALG={name:"RSA-PSS",hash:"SHA-384"},BATCH=10,defaultTokenStorePath=()=>join15(homedir3(),".velloo","feedback-tokens.json");async function loadStore(path){try{return JSON.parse(await readFile6(path,"utf8"))}catch{return{}}}async function saveStore(path,store){await mkdir8(dirname10(path),{recursive:!0}),await writeJsonAtomic(path,store)}var originOf=(url)=>new URL(url).origin;async function fetchIssuerKey(cloudUrl,prior){let res=await fetch(`${cloudUrl}/v1/feedback/token-key`,{signal:AbortSignal.timeout(5000)});if(!res.ok)throw new TokenIssueError("rejected",`token key fetch failed (${res.status})`);let parsed=FeedbackIssuerResponseSchema.safeParse(await res.json().catch(()=>null));if(!parsed.success)throw Error("the cloud's feedback token key reply was malformed");let{scheme,publicKey}=parsed.data;if(scheme!==TOKEN_SCHEME)throw Error(`unsupported feedback token scheme ${JSON.stringify(scheme)}`);let pinned=PINNED_ISSUER_KEYS[originOf(cloudUrl)];if(pinned&&publicKey!==pinned)throw Error("the cloud's feedback issuer key does not match the key pinned in this velloo build \u2014 refusing to fetch tokens (a per-user key would deanonymize feedback).");if(!pinned&&prior&&prior.publicKey!==publicKey)throw Error(`the cloud's feedback issuer key changed since tokens were first issued \u2014 refusing to fetch more. If the rotation is expected, delete ${defaultTokenStorePath()} and retry.`);return{publicKey:await crypto.subtle.importKey("spki",Buffer.from(publicKey,"base64"),KEY_ALG,!0,["verify"]),spkiB64:publicKey}}async function topUpTokens(cloud,min=1,storePath=defaultTokenStorePath()){let store=await loadStore(storePath),origin=originOf(cloud.url),entry=store[origin];if((entry?.tokens.length??0)>=min)return;if(!cloud.token)throw new TokenIssueError("signed-out","not signed in \u2014 run `velloo login` to fetch feedback tokens");let issuer=await fetchIssuerKey(cloud.url,entry),blinds=[];for(let i=0;i<BATCH;i++){let prepared=suite.prepare(crypto.getRandomValues(new Uint8Array(32)));blinds.push({prepared,...await suite.blind(issuer.publicKey,prepared)})}let res=await fetch(`${cloud.url}/v1/feedback/tokens`,{method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${cloud.token}`},body:JSON.stringify({blinded:blinds.map((b)=>Buffer.from(b.blindedMsg).toString("base64"))}),signal:AbortSignal.timeout(15000)});if(!res.ok)throw new TokenIssueError(res.status===402||res.status===429?"no-tokens":"rejected",`token issuance failed (${res.status})`);let issued=FeedbackSignaturesResponseSchema.safeParse(await res.json().catch(()=>null));if(!issued.success||issued.data.signatures.length!==blinds.length)throw Error("token issuance returned a malformed signature batch");let{signatures}=issued.data,tokens=[];for(let i=0;i<blinds.length;i++){let b=blinds[i];if(!b)continue;let sig=await suite.finalize(issuer.publicKey,b.prepared,Buffer.from(signatures[i]??"","base64"),b.inv);if(!await suite.verify(issuer.publicKey,sig,b.prepared))throw Error("issued token failed local verification \u2014 not storing it");tokens.push({token:Buffer.from(b.prepared).toString("base64"),sig:Buffer.from(sig).toString("base64")})}store[origin]={scheme:TOKEN_SCHEME,publicKey:issuer.spkiB64,tokens:[...entry?.tokens??[],...tokens]},await saveStore(storePath,store)}async function popToken(cloudUrl,storePath){let store=await loadStore(storePath),entry=store[originOf(cloudUrl)],token=entry?.tokens.shift();if(!entry||!token)return null;return await saveStore(storePath,store),token}function feedbackError(reason,message,retryable){return{kind:"FeedbackNotSent",reason,message,retryable}}class TokenIssueError extends Error{reason;constructor(reason,message){super(message);this.reason=reason}}async function sendAnonymousFeedback(cloud,payload,storePath=defaultTokenStorePath()){for(let attempt=0;attempt<2;attempt++){try{await topUpTokens(cloud,1,storePath)}catch(e){let message=e instanceof Error?e.message:String(e);if(e instanceof TokenIssueError)return err(feedbackError(e.reason,message,e.reason!=="signed-out"));return err(feedbackError("unreachable",message,!0))}let token=await popToken(cloud.url,storePath);if(!token)return err(feedbackError("no-tokens","no anonymous feedback tokens available for this account",!0));try{let res=await fetch(`${cloud.url}/v1/feedback/anonymous`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({body:payload.body,...payload.toolVersion?{toolVersion:payload.toolVersion}:{},...payload.source?{source:payload.source}:{},token:token.token,signature:token.sig}),signal:AbortSignal.timeout(5000)});if(res.status===409)continue;if(!res.ok)return err(feedbackError("rejected",`velloo-cloud refused the message (${res.status}).`,!1));return ok("Thanks \u2014 your feedback was sent (anonymously).")}catch{return err(feedbackError("unreachable","Couldn't reach velloo-cloud; feedback not sent.",!0))}}return err(feedbackError("rejected","feedback tokens kept colliding \u2014 try again later",!0))}import{existsSync as existsSync7}from"fs";import{isAbsolute,resolve as resolve6}from"path";function createServerProviderLoader(folderRoot,hostApp){let hostAppRoot=folderRoot?hostAppRootFrom(folderRoot,hostApp):void 0;return createProviderLoader({none:async()=>(await import("./chunk-6qfyem23.js")).createProvider(),mui:async()=>(await import("./chunk-t8xk4thc.js")).createProvider(),antd:async()=>(await import("./chunk-8yz604tw.js")).createProvider(),chakra:async()=>(await import("./chunk-cdxy4xzs.js")).createProvider(),"shadcn-upstream":async(library)=>{let cacheDir=resolveUpstreamCacheDir(library,folderRoot);return(await import("./chunk-c5zjen06.js")).createProvider({version:library.version,...cacheDir?{cacheDir}:{},...hostAppRoot?{hostAppRoot}:{}})}})}function resolveUpstreamCacheDir(library,folderRoot){let path=library.componentsPath;if(!path||path==="binary")return null;if(path.startsWith("~/")){let home=process.env.HOME??process.env.USERPROFILE??"";if(!home)return null;let abs=resolve6(home,path.slice(2));return existsSync7(abs)?abs:null}if(isAbsolute(path))return library.source==="in-repo"||existsSync7(path)?path:null;if(!folderRoot)return null;let abs=resolveAppPath(folderRoot,path);return library.source==="in-repo"||existsSync7(abs)?abs:null}async function resolveProviders(config,folderRoot,loader){let effective=loader??createServerProviderLoader(folderRoot,config.hostApp),providers={};for(let[libraryId,library]of Object.entries(config.libraries))try{providers[libraryId]=await effective(library)}catch(err){if(err instanceof UnknownProviderError)throw Error(`velloo: this binary doesn't know how to load library "${err.id}" (registered as "${libraryId}"). Upgrade velloo or pick a supported provider in .design/config.json.`);throw err}let defaultProvider=providers[config.defaultLibrary];if(!defaultProvider)throw Error(`velloo: defaultLibrary "${config.defaultLibrary}" doesn't match any registered library.`);if(config.styling){let css=config.styling.framework,wanted=CSS_FRAMEWORK_CHANNEL[css];if(!Object.values(providers).some((p)=>styleChannelOf(p,css).kind===wanted)){let libs=Object.values(config.libraries).map((l)=>l.id).join(", ");throw Error(`velloo: config.styling.framework "${css}" isn't supported by any registered library (${libs}). shadcn and MUI carry their own styling; only the no-framework library can pair with "none". Fix the CSS framework or library in .design/config.json.`)}}return{providers,defaultProvider}}import{existsSync as existsSync8}from"fs";import{resolve as resolve7}from"path";var CONFIG_NAMES=["tailwind.config.ts","tailwind.config.js","tailwind.config.cjs","tailwind.config.mjs"];function findHostTailwindConfig(folderRoot,hostApp){let root=hostAppRootFrom(folderRoot,hostApp);for(let name of CONFIG_NAMES){let path=resolve7(root,name);if(existsSync8(path))return path}return null}import{readFile as readFile7}from"fs/promises";import{dirname as dirname11,join as join16}from"path";import{compile}from"@tailwindcss/node";import{Scanner}from"@tailwindcss/oxide";class TailwindJit{pagesDir;extraEntryCss;extraSourceDirs;hostConfigPath;compilerPromise=null;cached=null;cachedCandidates=null;snippetsDir;providers;tailwindProviders;constructor(providers,pagesDir,snippetsDir,extraEntryCss,extraSourceDirs,hostConfigPath,folderCss){this.pagesDir=pagesDir;this.extraEntryCss=extraEntryCss;this.extraSourceDirs=extraSourceDirs;this.hostConfigPath=hostConfigPath;if(this.providers=Array.isArray(providers)?providers:[providers],this.providers.length===0)throw Error("TailwindJit: at least one provider is required.");this.tailwindProviders=this.providers.filter((p)=>styleChannelOf(p,folderCss).needsTailwindJit),this.snippetsDir=snippetsDir??join16(pagesDir,"..","snippets")}invalidate(){this.cached=null,this.cachedCandidates=null,this.compilerPromise=null}async build(extraCandidates){if(this.tailwindProviders.length===0)return"";let hasExtra=extraCandidates!==void 0&&extraCandidates.length>0;if(!hasExtra&&this.cached!==null)return this.cached;let compiler=await this.getCompiler(),candidates=this.scanCandidates();if(!hasExtra)return this.cached=compiler.build(candidates),this.cached;return compiler.build([...candidates,...extraCandidates])}scanCandidates(){if(this.cachedCandidates!==null)return this.cachedCandidates;let dedupedDirs=Array.from(new Set([...this.tailwindProviders.map((p)=>p.componentsDir),helpersComponentsDir])),hostDirs=Array.from(new Set(this.extraSourceDirs?.()??[])),scanner=new Scanner({sources:[...dedupedDirs.map((base)=>({base,pattern:"**/*.tsx",negated:!1})),...hostDirs.map((base)=>({base,pattern:"**/*.tsx",negated:!1})),{base:this.pagesDir,pattern:"**/*.json",negated:!1},{base:this.snippetsDir,pattern:"**/*.json",negated:!1}]});return this.cachedCandidates=scanner.scan(),this.cachedCandidates}entryCss(){return this.mergedEntryCss()}async mergedEntryCss(){let primary=this.tailwindProviders[0];if(!primary)throw Error("TailwindJit: no Tailwind-channel provider, cannot build entry CSS.");let primaryBase=dirname11(primary.styleEntryPath),extra=this.extraEntryCss?.()??"";if(this.tailwindProviders.length===1){let css=await readFile7(primary.styleEntryPath,"utf8");return{css:extra?`${css}
129
129
 
130
130
  ${extra}`:css,base:primaryBase}}let merged=(await Promise.all(this.tailwindProviders.map(async(p)=>{let css=await readFile7(p.styleEntryPath,"utf8");return`/* === provider: ${p.id} (${p.version}) === */
131
131
  ${css}`}))).join(`
@@ -142,7 +142,7 @@ ${extra}`:merged,base:primaryBase}}warnedHostConfig=!1;getCompiler(){if(this.com
142
142
  `:`[${source[i]}\r
143
143
  ]`;continue}if(pattern+=source[i],source[i]==="\\")isEscaped=!0;else if(inCharGroup&&source[i]==="]")inCharGroup=!1;else if(!inCharGroup&&source[i]==="[")inCharGroup=!0}try{new RegExp(pattern)}catch{return console.warn(`Could not convert regex pattern at ${refs.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`),regex.source}return pattern}function parseRecordDef(def,refs){if(refs.target==="openAi")console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead.");if(refs.target==="openApi3"&&def.keyType?._def.typeName===ZodFirstPartyTypeKind2.ZodEnum)return{type:"object",required:def.keyType._def.values,properties:def.keyType._def.values.reduce((acc,key)=>({...acc,[key]:parseDef(def.valueType._def,{...refs,currentPath:[...refs.currentPath,"properties",key]})??parseAnyDef(refs)}),{}),additionalProperties:refs.rejectedAdditionalProperties};let schema={type:"object",additionalProperties:parseDef(def.valueType._def,{...refs,currentPath:[...refs.currentPath,"additionalProperties"]})??refs.allowedAdditionalProperties};if(refs.target==="openApi3")return schema;if(def.keyType?._def.typeName===ZodFirstPartyTypeKind2.ZodString&&def.keyType._def.checks?.length){let{type,...keyType}=parseStringDef(def.keyType._def,refs);return{...schema,propertyNames:keyType}}else if(def.keyType?._def.typeName===ZodFirstPartyTypeKind2.ZodEnum)return{...schema,propertyNames:{enum:def.keyType._def.values}};else if(def.keyType?._def.typeName===ZodFirstPartyTypeKind2.ZodBranded&&def.keyType._def.type._def.typeName===ZodFirstPartyTypeKind2.ZodString&&def.keyType._def.type._def.checks?.length){let{type,...keyType}=parseBrandedDef(def.keyType._def,refs);return{...schema,propertyNames:keyType}}return schema}function parseMapDef(def,refs){if(refs.mapStrategy==="record")return parseRecordDef(def,refs);let keys=parseDef(def.keyType._def,{...refs,currentPath:[...refs.currentPath,"items","items","0"]})||parseAnyDef(refs),values=parseDef(def.valueType._def,{...refs,currentPath:[...refs.currentPath,"items","items","1"]})||parseAnyDef(refs);return{type:"array",maxItems:125,items:{type:"array",items:[keys,values],minItems:2,maxItems:2}}}function parseNativeEnumDef(def){let object=def.values,actualValues=Object.keys(def.values).filter((key)=>typeof object[object[key]]!=="number").map((key)=>object[key]),parsedTypes=Array.from(new Set(actualValues.map((values)=>typeof values)));return{type:parsedTypes.length===1?parsedTypes[0]==="string"?"string":"number":["string","number"],enum:actualValues}}function parseNeverDef(refs){return refs.target==="openAi"?void 0:{not:parseAnyDef({...refs,currentPath:[...refs.currentPath,"not"]})}}function parseNullDef(refs){return refs.target==="openApi3"?{enum:["null"],nullable:!0}:{type:"null"}}var primitiveMappings={ZodString:"string",ZodNumber:"number",ZodBigInt:"integer",ZodBoolean:"boolean",ZodNull:"null"};function parseUnionDef(def,refs){if(refs.target==="openApi3")return asAnyOf(def,refs);let options=def.options instanceof Map?Array.from(def.options.values()):def.options;if(options.every((x)=>(x._def.typeName in primitiveMappings)&&(!x._def.checks||!x._def.checks.length))){let types=options.reduce((types,x)=>{let type=primitiveMappings[x._def.typeName];return type&&!types.includes(type)?[...types,type]:types},[]);return{type:types.length>1?types:types[0]}}else if(options.every((x)=>x._def.typeName==="ZodLiteral"&&!x.description)){let types=options.reduce((acc,x)=>{let type=typeof x._def.value;switch(type){case"string":case"number":case"boolean":return[...acc,type];case"bigint":return[...acc,"integer"];case"object":if(x._def.value===null)return[...acc,"null"];case"symbol":case"undefined":case"function":default:return acc}},[]);if(types.length===options.length){let uniqueTypes=types.filter((x,i,a)=>a.indexOf(x)===i);return{type:uniqueTypes.length>1?uniqueTypes:uniqueTypes[0],enum:options.reduce((acc,x)=>acc.includes(x._def.value)?acc:[...acc,x._def.value],[])}}}else if(options.every((x)=>x._def.typeName==="ZodEnum"))return{type:"string",enum:options.reduce((acc,x)=>[...acc,...x._def.values.filter((x)=>!acc.includes(x))],[])};return asAnyOf(def,refs)}var asAnyOf=(def,refs)=>{let anyOf=(def.options instanceof Map?Array.from(def.options.values()):def.options).map((x,i)=>parseDef(x._def,{...refs,currentPath:[...refs.currentPath,"anyOf",`${i}`]})).filter((x)=>!!x&&(!refs.strictUnions||typeof x==="object"&&Object.keys(x).length>0));return anyOf.length?{anyOf}:void 0};function parseNullableDef(def,refs){if(["ZodString","ZodNumber","ZodBigInt","ZodBoolean","ZodNull"].includes(def.innerType._def.typeName)&&(!def.innerType._def.checks||!def.innerType._def.checks.length)){if(refs.target==="openApi3")return{type:primitiveMappings[def.innerType._def.typeName],nullable:!0};return{type:[primitiveMappings[def.innerType._def.typeName],"null"]}}if(refs.target==="openApi3"){let base=parseDef(def.innerType._def,{...refs,currentPath:[...refs.currentPath]});if(base&&"$ref"in base)return{allOf:[base],nullable:!0};return base&&{...base,nullable:!0}}let base=parseDef(def.innerType._def,{...refs,currentPath:[...refs.currentPath,"anyOf","0"]});return base&&{anyOf:[base,{type:"null"}]}}function parseNumberDef(def,refs){let res={type:"number"};if(!def.checks)return res;for(let check of def.checks)switch(check.kind){case"int":res.type="integer",addErrorMessage(res,"type",check.message,refs);break;case"min":if(refs.target==="jsonSchema7")if(check.inclusive)setResponseValueAndErrors(res,"minimum",check.value,check.message,refs);else setResponseValueAndErrors(res,"exclusiveMinimum",check.value,check.message,refs);else{if(!check.inclusive)res.exclusiveMinimum=!0;setResponseValueAndErrors(res,"minimum",check.value,check.message,refs)}break;case"max":if(refs.target==="jsonSchema7")if(check.inclusive)setResponseValueAndErrors(res,"maximum",check.value,check.message,refs);else setResponseValueAndErrors(res,"exclusiveMaximum",check.value,check.message,refs);else{if(!check.inclusive)res.exclusiveMaximum=!0;setResponseValueAndErrors(res,"maximum",check.value,check.message,refs)}break;case"multipleOf":setResponseValueAndErrors(res,"multipleOf",check.value,check.message,refs);break}return res}function parseObjectDef(def,refs){let forceOptionalIntoNullable=refs.target==="openAi",result={type:"object",properties:{}},required=[],shape=def.shape();for(let propName in shape){let propDef=shape[propName];if(propDef===void 0||propDef._def===void 0)continue;let propOptional=safeIsOptional(propDef);if(propOptional&&forceOptionalIntoNullable){if(propDef._def.typeName==="ZodOptional")propDef=propDef._def.innerType;if(!propDef.isNullable())propDef=propDef.nullable();propOptional=!1}let parsedDef=parseDef(propDef._def,{...refs,currentPath:[...refs.currentPath,"properties",propName],propertyPath:[...refs.currentPath,"properties",propName]});if(parsedDef===void 0)continue;if(result.properties[propName]=parsedDef,!propOptional)required.push(propName)}if(required.length)result.required=required;let additionalProperties=decideAdditionalProperties(def,refs);if(additionalProperties!==void 0)result.additionalProperties=additionalProperties;return result}function decideAdditionalProperties(def,refs){if(def.catchall._def.typeName!=="ZodNever")return parseDef(def.catchall._def,{...refs,currentPath:[...refs.currentPath,"additionalProperties"]});switch(def.unknownKeys){case"passthrough":return refs.allowedAdditionalProperties;case"strict":return refs.rejectedAdditionalProperties;case"strip":return refs.removeAdditionalStrategy==="strict"?refs.allowedAdditionalProperties:refs.rejectedAdditionalProperties}}function safeIsOptional(schema){try{return schema.isOptional()}catch{return!0}}var parseOptionalDef=(def,refs)=>{if(refs.currentPath.toString()===refs.propertyPath?.toString())return parseDef(def.innerType._def,refs);let innerSchema=parseDef(def.innerType._def,{...refs,currentPath:[...refs.currentPath,"anyOf","1"]});return innerSchema?{anyOf:[{not:parseAnyDef(refs)},innerSchema]}:parseAnyDef(refs)};var parsePipelineDef=(def,refs)=>{if(refs.pipeStrategy==="input")return parseDef(def.in._def,refs);else if(refs.pipeStrategy==="output")return parseDef(def.out._def,refs);let a=parseDef(def.in._def,{...refs,currentPath:[...refs.currentPath,"allOf","0"]}),b=parseDef(def.out._def,{...refs,currentPath:[...refs.currentPath,"allOf",a?"1":"0"]});return{allOf:[a,b].filter((x)=>x!==void 0)}};function parsePromiseDef(def,refs){return parseDef(def.type._def,refs)}function parseSetDef(def,refs){let schema={type:"array",uniqueItems:!0,items:parseDef(def.valueType._def,{...refs,currentPath:[...refs.currentPath,"items"]})};if(def.minSize)setResponseValueAndErrors(schema,"minItems",def.minSize.value,def.minSize.message,refs);if(def.maxSize)setResponseValueAndErrors(schema,"maxItems",def.maxSize.value,def.maxSize.message,refs);return schema}function parseTupleDef(def,refs){if(def.rest)return{type:"array",minItems:def.items.length,items:def.items.map((x,i)=>parseDef(x._def,{...refs,currentPath:[...refs.currentPath,"items",`${i}`]})).reduce((acc,x)=>x===void 0?acc:[...acc,x],[]),additionalItems:parseDef(def.rest._def,{...refs,currentPath:[...refs.currentPath,"additionalItems"]})};else return{type:"array",minItems:def.items.length,maxItems:def.items.length,items:def.items.map((x,i)=>parseDef(x._def,{...refs,currentPath:[...refs.currentPath,"items",`${i}`]})).reduce((acc,x)=>x===void 0?acc:[...acc,x],[])}}function parseUndefinedDef(refs){return{not:parseAnyDef(refs)}}function parseUnknownDef(refs){return parseAnyDef(refs)}var parseReadonlyDef=(def,refs)=>parseDef(def.innerType._def,refs);var selectParser=(def,typeName,refs)=>{switch(typeName){case ZodFirstPartyTypeKind2.ZodString:return parseStringDef(def,refs);case ZodFirstPartyTypeKind2.ZodNumber:return parseNumberDef(def,refs);case ZodFirstPartyTypeKind2.ZodObject:return parseObjectDef(def,refs);case ZodFirstPartyTypeKind2.ZodBigInt:return parseBigintDef(def,refs);case ZodFirstPartyTypeKind2.ZodBoolean:return parseBooleanDef();case ZodFirstPartyTypeKind2.ZodDate:return parseDateDef(def,refs);case ZodFirstPartyTypeKind2.ZodUndefined:return parseUndefinedDef(refs);case ZodFirstPartyTypeKind2.ZodNull:return parseNullDef(refs);case ZodFirstPartyTypeKind2.ZodArray:return parseArrayDef(def,refs);case ZodFirstPartyTypeKind2.ZodUnion:case ZodFirstPartyTypeKind2.ZodDiscriminatedUnion:return parseUnionDef(def,refs);case ZodFirstPartyTypeKind2.ZodIntersection:return parseIntersectionDef(def,refs);case ZodFirstPartyTypeKind2.ZodTuple:return parseTupleDef(def,refs);case ZodFirstPartyTypeKind2.ZodRecord:return parseRecordDef(def,refs);case ZodFirstPartyTypeKind2.ZodLiteral:return parseLiteralDef(def,refs);case ZodFirstPartyTypeKind2.ZodEnum:return parseEnumDef(def);case ZodFirstPartyTypeKind2.ZodNativeEnum:return parseNativeEnumDef(def);case ZodFirstPartyTypeKind2.ZodNullable:return parseNullableDef(def,refs);case ZodFirstPartyTypeKind2.ZodOptional:return parseOptionalDef(def,refs);case ZodFirstPartyTypeKind2.ZodMap:return parseMapDef(def,refs);case ZodFirstPartyTypeKind2.ZodSet:return parseSetDef(def,refs);case ZodFirstPartyTypeKind2.ZodLazy:return()=>def.getter()._def;case ZodFirstPartyTypeKind2.ZodPromise:return parsePromiseDef(def,refs);case ZodFirstPartyTypeKind2.ZodNaN:case ZodFirstPartyTypeKind2.ZodNever:return parseNeverDef(refs);case ZodFirstPartyTypeKind2.ZodEffects:return parseEffectsDef(def,refs);case ZodFirstPartyTypeKind2.ZodAny:return parseAnyDef(refs);case ZodFirstPartyTypeKind2.ZodUnknown:return parseUnknownDef(refs);case ZodFirstPartyTypeKind2.ZodDefault:return parseDefaultDef(def,refs);case ZodFirstPartyTypeKind2.ZodBranded:return parseBrandedDef(def,refs);case ZodFirstPartyTypeKind2.ZodReadonly:return parseReadonlyDef(def,refs);case ZodFirstPartyTypeKind2.ZodCatch:return parseCatchDef(def,refs);case ZodFirstPartyTypeKind2.ZodPipeline:return parsePipelineDef(def,refs);case ZodFirstPartyTypeKind2.ZodFunction:case ZodFirstPartyTypeKind2.ZodVoid:case ZodFirstPartyTypeKind2.ZodSymbol:return;default:return((_)=>{return})(typeName)}};function parseDef(def,refs,forceResolution=!1){let seenItem=refs.seen.get(def);if(refs.override){let overrideResult=refs.override?.(def,refs,seenItem,forceResolution);if(overrideResult!==ignoreOverride)return overrideResult}if(seenItem&&!forceResolution){let seenSchema=get$ref(seenItem,refs);if(seenSchema!==void 0)return seenSchema}let newItem={def,path:refs.currentPath,jsonSchema:void 0};refs.seen.set(def,newItem);let jsonSchemaOrGetter=selectParser(def,def.typeName,refs),jsonSchema=typeof jsonSchemaOrGetter==="function"?parseDef(jsonSchemaOrGetter(),refs):jsonSchemaOrGetter;if(jsonSchema)addMeta(def,refs,jsonSchema);if(refs.postProcess){let postProcessResult=refs.postProcess(jsonSchema,def,refs);return newItem.jsonSchema=jsonSchema,postProcessResult}return newItem.jsonSchema=jsonSchema,jsonSchema}var get$ref=(item,refs)=>{switch(refs.$refStrategy){case"root":return{$ref:item.path.join("/")};case"relative":return{$ref:getRelativePath(refs.currentPath,item.path)};case"none":case"seen":{if(item.path.length<refs.currentPath.length&&item.path.every((value,index)=>refs.currentPath[index]===value))return console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`),parseAnyDef(refs);return refs.$refStrategy==="seen"?parseAnyDef(refs):void 0}}},addMeta=(def,refs,jsonSchema)=>{if(def.description){if(jsonSchema.description=def.description,refs.markdownDescription)jsonSchema.markdownDescription=def.description}return jsonSchema};var zodToJsonSchema=(schema,options)=>{let refs=getRefs(options),definitions=typeof options==="object"&&options.definitions?Object.entries(options.definitions).reduce((acc,[name,schema])=>({...acc,[name]:parseDef(schema._def,{...refs,currentPath:[...refs.basePath,refs.definitionPath,name]},!0)??parseAnyDef(refs)}),{}):void 0,name=typeof options==="string"?options:options?.nameStrategy==="title"?void 0:options?.name,main=parseDef(schema._def,name===void 0?refs:{...refs,currentPath:[...refs.basePath,refs.definitionPath,name]},!1)??parseAnyDef(refs),title=typeof options==="object"&&options.name!==void 0&&options.nameStrategy==="title"?options.name:void 0;if(title!==void 0)main.title=title;if(refs.flags.hasReferencedOpenAiAnyType){if(!definitions)definitions={};if(!definitions[refs.openAiAnyTypeName])definitions[refs.openAiAnyTypeName]={type:["string","number","integer","boolean","array","null"],items:{$ref:refs.$refStrategy==="relative"?"1":[...refs.basePath,refs.definitionPath,refs.openAiAnyTypeName].join("/")}}}let combined=name===void 0?definitions?{...main,[refs.definitionPath]:definitions}:main:{$ref:[...refs.$refStrategy==="relative"?[]:refs.basePath,refs.definitionPath,name].join("/"),[refs.definitionPath]:{...definitions,[name]:main}};if(refs.target==="jsonSchema7")combined.$schema="http://json-schema.org/draft-07/schema#";else if(refs.target==="jsonSchema2019-09"||refs.target==="openAi")combined.$schema="https://json-schema.org/draft/2019-09/schema#";if(refs.target==="openAi"&&(("anyOf"in combined)||("oneOf"in combined)||("allOf"in combined)||("type"in combined)&&Array.isArray(combined.type)))console.warn("Warning: OpenAI may not support schemas with unions as roots! Try wrapping it in an object property.");return combined};function mapMiniTarget(t){if(!t)return"draft-7";if(t==="jsonSchema7"||t==="draft-7")return"draft-7";if(t==="jsonSchema2019-09"||t==="draft-2020-12")return"draft-2020-12";return"draft-7"}function toJsonSchemaCompat(schema,opts){if(isZ4Schema(schema))return toJSONSchema(schema,{target:mapMiniTarget(opts?.target),io:opts?.pipeStrategy??"input"});return zodToJsonSchema(schema,{strictUnions:opts?.strictUnions??!0,pipeStrategy:opts?.pipeStrategy??"input"})}function getMethodLiteral(schema){let methodSchema=getObjectShape(schema)?.method;if(!methodSchema)throw Error("Schema is missing a method literal");let value=getLiteralValue(methodSchema);if(typeof value!=="string")throw Error("Schema method literal must be a string");return value}function parseWithCompat(schema,data){let result=safeParse2(schema,data);if(!result.success)throw result.error;return result.data}var DEFAULT_REQUEST_TIMEOUT_MSEC=60000;class Protocol{constructor(_options){if(this._options=_options,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this._taskProgressTokens=new Map,this._requestResolvers=new Map,this.setNotificationHandler(CancelledNotificationSchema,(notification)=>{this._oncancel(notification)}),this.setNotificationHandler(ProgressNotificationSchema,(notification)=>{this._onprogress(notification)}),this.setRequestHandler(PingRequestSchema,(_request)=>({})),this._taskStore=_options?.taskStore,this._taskMessageQueue=_options?.taskMessageQueue,this._taskStore)this.setRequestHandler(GetTaskRequestSchema,async(request,extra)=>{let task=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,"Failed to retrieve task: Task not found");return{...task}}),this.setRequestHandler(GetTaskPayloadRequestSchema,async(request,extra)=>{let handleTaskResult=async()=>{let taskId=request.params.taskId;if(this._taskMessageQueue){let queuedMessage;while(queuedMessage=await this._taskMessageQueue.dequeue(taskId,extra.sessionId)){if(queuedMessage.type==="response"||queuedMessage.type==="error"){let message=queuedMessage.message,requestId=message.id,resolver=this._requestResolvers.get(requestId);if(resolver)if(this._requestResolvers.delete(requestId),queuedMessage.type==="response")resolver(message);else{let errorMessage=message,error=new McpError(errorMessage.error.code,errorMessage.error.message,errorMessage.error.data);resolver(error)}else{let messageType=queuedMessage.type==="response"?"Response":"Error";this._onerror(Error(`${messageType} handler missing for request ${requestId}`))}continue}await this._transport?.send(queuedMessage.message,{relatedRequestId:extra.requestId})}}let task=await this._taskStore.getTask(taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task not found: ${taskId}`);if(!isTerminal(task.status))return await this._waitForTaskUpdate(taskId,extra.signal),await handleTaskResult();if(isTerminal(task.status)){let result=await this._taskStore.getTaskResult(taskId,extra.sessionId);return this._clearTaskQueue(taskId),{...result,_meta:{...result._meta,[RELATED_TASK_META_KEY]:{taskId}}}}return await handleTaskResult()};return await handleTaskResult()}),this.setRequestHandler(ListTasksRequestSchema,async(request,extra)=>{try{let{tasks,nextCursor}=await this._taskStore.listTasks(request.params?.cursor,extra.sessionId);return{tasks,nextCursor,_meta:{}}}catch(error){throw new McpError(ErrorCode.InvalidParams,`Failed to list tasks: ${error instanceof Error?error.message:String(error)}`)}}),this.setRequestHandler(CancelTaskRequestSchema,async(request,extra)=>{try{let task=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task not found: ${request.params.taskId}`);if(isTerminal(task.status))throw new McpError(ErrorCode.InvalidParams,`Cannot cancel task in terminal status: ${task.status}`);await this._taskStore.updateTaskStatus(request.params.taskId,"cancelled","Client cancelled task execution.",extra.sessionId),this._clearTaskQueue(request.params.taskId);let cancelledTask=await this._taskStore.getTask(request.params.taskId,extra.sessionId);if(!cancelledTask)throw new McpError(ErrorCode.InvalidParams,`Task not found after cancellation: ${request.params.taskId}`);return{_meta:{},...cancelledTask}}catch(error){if(error instanceof McpError)throw error;throw new McpError(ErrorCode.InvalidRequest,`Failed to cancel task: ${error instanceof Error?error.message:String(error)}`)}})}async _oncancel(notification){if(!notification.params.requestId)return;this._requestHandlerAbortControllers.get(notification.params.requestId)?.abort(notification.params.reason)}_setupTimeout(messageId,timeout,maxTotalTimeout,onTimeout,resetTimeoutOnProgress=!1){this._timeoutInfo.set(messageId,{timeoutId:setTimeout(onTimeout,timeout),startTime:Date.now(),timeout,maxTotalTimeout,resetTimeoutOnProgress,onTimeout})}_resetTimeout(messageId){let info=this._timeoutInfo.get(messageId);if(!info)return!1;let totalElapsed=Date.now()-info.startTime;if(info.maxTotalTimeout&&totalElapsed>=info.maxTotalTimeout)throw this._timeoutInfo.delete(messageId),McpError.fromError(ErrorCode.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:info.maxTotalTimeout,totalElapsed});return clearTimeout(info.timeoutId),info.timeoutId=setTimeout(info.onTimeout,info.timeout),!0}_cleanupTimeout(messageId){let info=this._timeoutInfo.get(messageId);if(info)clearTimeout(info.timeoutId),this._timeoutInfo.delete(messageId)}async connect(transport){if(this._transport)throw Error("Already connected to a transport. Call close() before connecting to a new transport, or use a separate Protocol instance per connection.");this._transport=transport;let _onclose=this.transport?.onclose;this._transport.onclose=()=>{_onclose?.(),this._onclose()};let _onerror=this.transport?.onerror;this._transport.onerror=(error)=>{_onerror?.(error),this._onerror(error)};let _onmessage=this._transport?.onmessage;this._transport.onmessage=(message,extra)=>{if(_onmessage?.(message,extra),isJSONRPCResultResponse(message)||isJSONRPCErrorResponse(message))this._onresponse(message);else if(isJSONRPCRequest(message))this._onrequest(message,extra);else if(isJSONRPCNotification(message))this._onnotification(message);else this._onerror(Error(`Unknown message type: ${JSON.stringify(message)}`))},await this._transport.start()}_onclose(){let responseHandlers=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._taskProgressTokens.clear(),this._pendingDebouncedNotifications.clear();for(let info of this._timeoutInfo.values())clearTimeout(info.timeoutId);this._timeoutInfo.clear();for(let controller of this._requestHandlerAbortControllers.values())controller.abort();this._requestHandlerAbortControllers.clear();let error=McpError.fromError(ErrorCode.ConnectionClosed,"Connection closed");this._transport=void 0,this.onclose?.();for(let handler of responseHandlers.values())handler(error)}_onerror(error){this.onerror?.(error)}_onnotification(notification){let handler=this._notificationHandlers.get(notification.method)??this.fallbackNotificationHandler;if(handler===void 0)return;Promise.resolve().then(()=>handler(notification)).catch((error)=>this._onerror(Error(`Uncaught error in notification handler: ${error}`)))}_onrequest(request,extra){let handler=this._requestHandlers.get(request.method)??this.fallbackRequestHandler,capturedTransport=this._transport,relatedTaskId=request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;if(handler===void 0){let errorResponse={jsonrpc:"2.0",id:request.id,error:{code:ErrorCode.MethodNotFound,message:"Method not found"}};if(relatedTaskId&&this._taskMessageQueue)this._enqueueTaskMessage(relatedTaskId,{type:"error",message:errorResponse,timestamp:Date.now()},capturedTransport?.sessionId).catch((error)=>this._onerror(Error(`Failed to enqueue error response: ${error}`)));else capturedTransport?.send(errorResponse).catch((error)=>this._onerror(Error(`Failed to send an error response: ${error}`)));return}let abortController=new AbortController;this._requestHandlerAbortControllers.set(request.id,abortController);let taskCreationParams=isTaskAugmentedRequestParams(request.params)?request.params.task:void 0,taskStore=this._taskStore?this.requestTaskStore(request,capturedTransport?.sessionId):void 0,fullExtra={signal:abortController.signal,sessionId:capturedTransport?.sessionId,_meta:request.params?._meta,sendNotification:async(notification)=>{if(abortController.signal.aborted)return;let notificationOptions={relatedRequestId:request.id};if(relatedTaskId)notificationOptions.relatedTask={taskId:relatedTaskId};await this.notification(notification,notificationOptions)},sendRequest:async(r,resultSchema,options)=>{if(abortController.signal.aborted)throw new McpError(ErrorCode.ConnectionClosed,"Request was cancelled");let requestOptions={...options,relatedRequestId:request.id};if(relatedTaskId&&!requestOptions.relatedTask)requestOptions.relatedTask={taskId:relatedTaskId};let effectiveTaskId=requestOptions.relatedTask?.taskId??relatedTaskId;if(effectiveTaskId&&taskStore)await taskStore.updateTaskStatus(effectiveTaskId,"input_required");return await this.request(r,resultSchema,requestOptions)},authInfo:extra?.authInfo,requestId:request.id,requestInfo:extra?.requestInfo,taskId:relatedTaskId,taskStore,taskRequestedTtl:taskCreationParams?.ttl,closeSSEStream:extra?.closeSSEStream,closeStandaloneSSEStream:extra?.closeStandaloneSSEStream};Promise.resolve().then(()=>{if(taskCreationParams)this.assertTaskHandlerCapability(request.method)}).then(()=>handler(request,fullExtra)).then(async(result)=>{if(abortController.signal.aborted)return;let response={result,jsonrpc:"2.0",id:request.id};if(relatedTaskId&&this._taskMessageQueue)await this._enqueueTaskMessage(relatedTaskId,{type:"response",message:response,timestamp:Date.now()},capturedTransport?.sessionId);else await capturedTransport?.send(response)},async(error)=>{if(abortController.signal.aborted)return;let errorResponse={jsonrpc:"2.0",id:request.id,error:{code:Number.isSafeInteger(error.code)?error.code:ErrorCode.InternalError,message:error.message??"Internal error",...error.data!==void 0&&{data:error.data}}};if(relatedTaskId&&this._taskMessageQueue)await this._enqueueTaskMessage(relatedTaskId,{type:"error",message:errorResponse,timestamp:Date.now()},capturedTransport?.sessionId);else await capturedTransport?.send(errorResponse)}).catch((error)=>this._onerror(Error(`Failed to send response: ${error}`))).finally(()=>{if(this._requestHandlerAbortControllers.get(request.id)===abortController)this._requestHandlerAbortControllers.delete(request.id)})}_onprogress(notification){let{progressToken,...params}=notification.params,messageId=Number(progressToken),handler=this._progressHandlers.get(messageId);if(!handler){this._onerror(Error(`Received a progress notification for an unknown token: ${JSON.stringify(notification)}`));return}let responseHandler=this._responseHandlers.get(messageId),timeoutInfo=this._timeoutInfo.get(messageId);if(timeoutInfo&&responseHandler&&timeoutInfo.resetTimeoutOnProgress)try{this._resetTimeout(messageId)}catch(error){this._responseHandlers.delete(messageId),this._progressHandlers.delete(messageId),this._cleanupTimeout(messageId),responseHandler(error);return}handler(params)}_onresponse(response){let messageId=Number(response.id),resolver=this._requestResolvers.get(messageId);if(resolver){if(this._requestResolvers.delete(messageId),isJSONRPCResultResponse(response))resolver(response);else{let error=new McpError(response.error.code,response.error.message,response.error.data);resolver(error)}return}let handler=this._responseHandlers.get(messageId);if(handler===void 0){this._onerror(Error(`Received a response for an unknown message ID: ${JSON.stringify(response)}`));return}this._responseHandlers.delete(messageId),this._cleanupTimeout(messageId);let isTaskResponse=!1;if(isJSONRPCResultResponse(response)&&response.result&&typeof response.result==="object"){let result=response.result;if(result.task&&typeof result.task==="object"){let task=result.task;if(typeof task.taskId==="string")isTaskResponse=!0,this._taskProgressTokens.set(task.taskId,messageId)}}if(!isTaskResponse)this._progressHandlers.delete(messageId);if(isJSONRPCResultResponse(response))handler(response);else{let error=McpError.fromError(response.error.code,response.error.message,response.error.data);handler(error)}}get transport(){return this._transport}async close(){await this._transport?.close()}async*requestStream(request,resultSchema,options){let{task}=options??{};if(!task){try{yield{type:"result",result:await this.request(request,resultSchema,options)}}catch(error){yield{type:"error",error:error instanceof McpError?error:new McpError(ErrorCode.InternalError,String(error))}}return}let taskId;try{let createResult=await this.request(request,CreateTaskResultSchema,options);if(createResult.task)taskId=createResult.task.taskId,yield{type:"taskCreated",task:createResult.task};else throw new McpError(ErrorCode.InternalError,"Task creation did not return a task");while(!0){let task=await this.getTask({taskId},options);if(yield{type:"taskStatus",task},isTerminal(task.status)){if(task.status==="completed")yield{type:"result",result:await this.getTaskResult({taskId},resultSchema,options)};else if(task.status==="failed")yield{type:"error",error:new McpError(ErrorCode.InternalError,`Task ${taskId} failed`)};else if(task.status==="cancelled")yield{type:"error",error:new McpError(ErrorCode.InternalError,`Task ${taskId} was cancelled`)};return}if(task.status==="input_required"){yield{type:"result",result:await this.getTaskResult({taskId},resultSchema,options)};return}let pollInterval=task.pollInterval??this._options?.defaultTaskPollInterval??1000;await new Promise((resolve)=>setTimeout(resolve,pollInterval)),options?.signal?.throwIfAborted()}}catch(error){yield{type:"error",error:error instanceof McpError?error:new McpError(ErrorCode.InternalError,String(error))}}}request(request,resultSchema,options){let{relatedRequestId,resumptionToken,onresumptiontoken,task,relatedTask}=options??{};return new Promise((resolve,reject)=>{let earlyReject=(error)=>{reject(error)};if(!this._transport){earlyReject(Error("Not connected"));return}if(this._options?.enforceStrictCapabilities===!0)try{if(this.assertCapabilityForMethod(request.method),task)this.assertTaskCapability(request.method)}catch(e){earlyReject(e);return}options?.signal?.throwIfAborted();let messageId=this._requestMessageId++,jsonrpcRequest={...request,jsonrpc:"2.0",id:messageId};if(options?.onprogress)this._progressHandlers.set(messageId,options.onprogress),jsonrpcRequest.params={...request.params,_meta:{...request.params?._meta||{},progressToken:messageId}};if(task)jsonrpcRequest.params={...jsonrpcRequest.params,task};if(relatedTask)jsonrpcRequest.params={...jsonrpcRequest.params,_meta:{...jsonrpcRequest.params?._meta||{},[RELATED_TASK_META_KEY]:relatedTask}};let cancel=(reason)=>{this._responseHandlers.delete(messageId),this._progressHandlers.delete(messageId),this._cleanupTimeout(messageId),this._transport?.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:messageId,reason:String(reason)}},{relatedRequestId,resumptionToken,onresumptiontoken}).catch((error)=>this._onerror(Error(`Failed to send cancellation: ${error}`)));let error=reason instanceof McpError?reason:new McpError(ErrorCode.RequestTimeout,String(reason));reject(error)};this._responseHandlers.set(messageId,(response)=>{if(options?.signal?.aborted)return;if(response instanceof Error)return reject(response);try{let parseResult=safeParse2(resultSchema,response.result);if(!parseResult.success)reject(parseResult.error);else resolve(parseResult.data)}catch(error){reject(error)}}),options?.signal?.addEventListener("abort",()=>{cancel(options?.signal?.reason)});let timeout=options?.timeout??DEFAULT_REQUEST_TIMEOUT_MSEC,timeoutHandler=()=>cancel(McpError.fromError(ErrorCode.RequestTimeout,"Request timed out",{timeout}));this._setupTimeout(messageId,timeout,options?.maxTotalTimeout,timeoutHandler,options?.resetTimeoutOnProgress??!1);let relatedTaskId=relatedTask?.taskId;if(relatedTaskId){let responseResolver=(response)=>{let handler=this._responseHandlers.get(messageId);if(handler)handler(response);else this._onerror(Error(`Response handler missing for side-channeled request ${messageId}`))};this._requestResolvers.set(messageId,responseResolver),this._enqueueTaskMessage(relatedTaskId,{type:"request",message:jsonrpcRequest,timestamp:Date.now()}).catch((error)=>{this._cleanupTimeout(messageId),reject(error)})}else this._transport.send(jsonrpcRequest,{relatedRequestId,resumptionToken,onresumptiontoken}).catch((error)=>{this._cleanupTimeout(messageId),reject(error)})})}async getTask(params,options){return this.request({method:"tasks/get",params},GetTaskResultSchema,options)}async getTaskResult(params,resultSchema,options){return this.request({method:"tasks/result",params},resultSchema,options)}async listTasks(params,options){return this.request({method:"tasks/list",params},ListTasksResultSchema,options)}async cancelTask(params,options){return this.request({method:"tasks/cancel",params},CancelTaskResultSchema,options)}async notification(notification,options){if(!this._transport)throw Error("Not connected");this.assertNotificationCapability(notification.method);let relatedTaskId=options?.relatedTask?.taskId;if(relatedTaskId){let jsonrpcNotification={...notification,jsonrpc:"2.0",params:{...notification.params,_meta:{...notification.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}};await this._enqueueTaskMessage(relatedTaskId,{type:"notification",message:jsonrpcNotification,timestamp:Date.now()});return}if((this._options?.debouncedNotificationMethods??[]).includes(notification.method)&&!notification.params&&!options?.relatedRequestId&&!options?.relatedTask){if(this._pendingDebouncedNotifications.has(notification.method))return;this._pendingDebouncedNotifications.add(notification.method),Promise.resolve().then(()=>{if(this._pendingDebouncedNotifications.delete(notification.method),!this._transport)return;let jsonrpcNotification={...notification,jsonrpc:"2.0"};if(options?.relatedTask)jsonrpcNotification={...jsonrpcNotification,params:{...jsonrpcNotification.params,_meta:{...jsonrpcNotification.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}};this._transport?.send(jsonrpcNotification,options).catch((error)=>this._onerror(error))});return}let jsonrpcNotification={...notification,jsonrpc:"2.0"};if(options?.relatedTask)jsonrpcNotification={...jsonrpcNotification,params:{...jsonrpcNotification.params,_meta:{...jsonrpcNotification.params?._meta||{},[RELATED_TASK_META_KEY]:options.relatedTask}}};await this._transport.send(jsonrpcNotification,options)}setRequestHandler(requestSchema,handler){let method=getMethodLiteral(requestSchema);this.assertRequestHandlerCapability(method),this._requestHandlers.set(method,(request,extra)=>{let parsed=parseWithCompat(requestSchema,request);return Promise.resolve(handler(parsed,extra))})}removeRequestHandler(method){this._requestHandlers.delete(method)}assertCanSetRequestHandler(method){if(this._requestHandlers.has(method))throw Error(`A request handler for ${method} already exists, which would be overridden`)}setNotificationHandler(notificationSchema,handler){let method=getMethodLiteral(notificationSchema);this._notificationHandlers.set(method,(notification)=>{let parsed=parseWithCompat(notificationSchema,notification);return Promise.resolve(handler(parsed))})}removeNotificationHandler(method){this._notificationHandlers.delete(method)}_cleanupTaskProgressHandler(taskId){let progressToken=this._taskProgressTokens.get(taskId);if(progressToken!==void 0)this._progressHandlers.delete(progressToken),this._taskProgressTokens.delete(taskId)}async _enqueueTaskMessage(taskId,message,sessionId){if(!this._taskStore||!this._taskMessageQueue)throw Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");let maxQueueSize=this._options?.maxTaskQueueSize;await this._taskMessageQueue.enqueue(taskId,message,sessionId,maxQueueSize)}async _clearTaskQueue(taskId,sessionId){if(this._taskMessageQueue){let messages=await this._taskMessageQueue.dequeueAll(taskId,sessionId);for(let message of messages)if(message.type==="request"&&isJSONRPCRequest(message.message)){let requestId=message.message.id,resolver=this._requestResolvers.get(requestId);if(resolver)resolver(new McpError(ErrorCode.InternalError,"Task cancelled or completed")),this._requestResolvers.delete(requestId);else this._onerror(Error(`Resolver missing for request ${requestId} during task ${taskId} cleanup`))}}}async _waitForTaskUpdate(taskId,signal){let interval=this._options?.defaultTaskPollInterval??1000;try{let task=await this._taskStore?.getTask(taskId);if(task?.pollInterval)interval=task.pollInterval}catch{}return new Promise((resolve,reject)=>{if(signal.aborted){reject(new McpError(ErrorCode.InvalidRequest,"Request cancelled"));return}let timeoutId=setTimeout(resolve,interval);signal.addEventListener("abort",()=>{clearTimeout(timeoutId),reject(new McpError(ErrorCode.InvalidRequest,"Request cancelled"))},{once:!0})})}requestTaskStore(request,sessionId){let taskStore=this._taskStore;if(!taskStore)throw Error("No task store configured");return{createTask:async(taskParams)=>{if(!request)throw Error("No request provided");return await taskStore.createTask(taskParams,request.id,{method:request.method,params:request.params},sessionId)},getTask:async(taskId)=>{let task=await taskStore.getTask(taskId,sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,"Failed to retrieve task: Task not found");return task},storeTaskResult:async(taskId,status,result)=>{await taskStore.storeTaskResult(taskId,status,result,sessionId);let task=await taskStore.getTask(taskId,sessionId);if(task){let notification=TaskStatusNotificationSchema.parse({method:"notifications/tasks/status",params:task});if(await this.notification(notification),isTerminal(task.status))this._cleanupTaskProgressHandler(taskId)}},getTaskResult:(taskId)=>taskStore.getTaskResult(taskId,sessionId),updateTaskStatus:async(taskId,status,statusMessage)=>{let task=await taskStore.getTask(taskId,sessionId);if(!task)throw new McpError(ErrorCode.InvalidParams,`Task "${taskId}" not found - it may have been cleaned up`);if(isTerminal(task.status))throw new McpError(ErrorCode.InvalidParams,`Cannot update task "${taskId}" from terminal status "${task.status}" to "${status}". Terminal states (completed, failed, cancelled) cannot transition to other states.`);await taskStore.updateTaskStatus(taskId,status,statusMessage,sessionId);let updatedTask=await taskStore.getTask(taskId,sessionId);if(updatedTask){let notification=TaskStatusNotificationSchema.parse({method:"notifications/tasks/status",params:updatedTask});if(await this.notification(notification),isTerminal(updatedTask.status))this._cleanupTaskProgressHandler(taskId)}},listTasks:(cursor)=>taskStore.listTasks(cursor,sessionId)}}}function isPlainObject(value){return value!==null&&typeof value==="object"&&!Array.isArray(value)}function mergeCapabilities(base,additional){let result={...base};for(let key in additional){let k=key,addValue=additional[k];if(addValue===void 0)continue;let baseValue=result[k];if(isPlainObject(baseValue)&&isPlainObject(addValue))result[k]={...baseValue,...addValue};else result[k]=addValue}return result}var import_ajv=__toESM(require_ajv(),1),import_ajv_formats=__toESM(require_dist(),1);function createDefaultAjvInstance(){let ajv=new import_ajv.default({strict:!1,validateFormats:!0,validateSchema:!1,allErrors:!0});return import_ajv_formats.default(ajv),ajv}class AjvJsonSchemaValidator{constructor(ajv){this._ajv=ajv??createDefaultAjvInstance()}getValidator(schema){let ajvValidator="$id"in schema&&typeof schema.$id==="string"?this._ajv.getSchema(schema.$id)??this._ajv.compile(schema):this._ajv.compile(schema);return(input)=>{if(ajvValidator(input))return{valid:!0,data:input,errorMessage:void 0};else return{valid:!1,data:void 0,errorMessage:this._ajv.errorsText(ajvValidator.errors)}}}}class ExperimentalServerTasks{constructor(_server){this._server=_server}requestStream(request,resultSchema,options){return this._server.requestStream(request,resultSchema,options)}createMessageStream(params,options){let clientCapabilities=this._server.getClientCapabilities();if((params.tools||params.toolChoice)&&!clientCapabilities?.sampling?.tools)throw Error("Client does not support sampling tools capability.");if(params.messages.length>0){let lastMessage=params.messages[params.messages.length-1],lastContent=Array.isArray(lastMessage.content)?lastMessage.content:[lastMessage.content],hasToolResults=lastContent.some((c)=>c.type==="tool_result"),previousMessage=params.messages.length>1?params.messages[params.messages.length-2]:void 0,previousContent=previousMessage?Array.isArray(previousMessage.content)?previousMessage.content:[previousMessage.content]:[],hasPreviousToolUse=previousContent.some((c)=>c.type==="tool_use");if(hasToolResults){if(lastContent.some((c)=>c.type!=="tool_result"))throw Error("The last message must contain only tool_result content if any is present");if(!hasPreviousToolUse)throw Error("tool_result blocks are not matching any tool_use from the previous message")}if(hasPreviousToolUse){let toolUseIds=new Set(previousContent.filter((c)=>c.type==="tool_use").map((c)=>c.id)),toolResultIds=new Set(lastContent.filter((c)=>c.type==="tool_result").map((c)=>c.toolUseId));if(toolUseIds.size!==toolResultIds.size||![...toolUseIds].every((id)=>toolResultIds.has(id)))throw Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}return this.requestStream({method:"sampling/createMessage",params},CreateMessageResultSchema,options)}elicitInputStream(params,options){let clientCapabilities=this._server.getClientCapabilities(),mode=params.mode??"form";switch(mode){case"url":{if(!clientCapabilities?.elicitation?.url)throw Error("Client does not support url elicitation.");break}case"form":{if(!clientCapabilities?.elicitation?.form)throw Error("Client does not support form elicitation.");break}}let normalizedParams=mode==="form"&&params.mode===void 0?{...params,mode:"form"}:params;return this.requestStream({method:"elicitation/create",params:normalizedParams},ElicitResultSchema,options)}async getTask(taskId,options){return this._server.getTask({taskId},options)}async getTaskResult(taskId,resultSchema,options){return this._server.getTaskResult({taskId},resultSchema,options)}async listTasks(cursor,options){return this._server.listTasks(cursor?{cursor}:void 0,options)}async cancelTask(taskId,options){return this._server.cancelTask({taskId},options)}}function assertToolsCallTaskCapability(requests,method,entityName){if(!requests)throw Error(`${entityName} does not support task creation (required for ${method})`);switch(method){case"tools/call":if(!requests.tools?.call)throw Error(`${entityName} does not support task creation for tools/call (required for ${method})`);break;default:break}}function assertClientRequestTaskCapability(requests,method,entityName){if(!requests)throw Error(`${entityName} does not support task creation (required for ${method})`);switch(method){case"sampling/createMessage":if(!requests.sampling?.createMessage)throw Error(`${entityName} does not support task creation for sampling/createMessage (required for ${method})`);break;case"elicitation/create":if(!requests.elicitation?.create)throw Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);break;default:break}}class Server extends Protocol{constructor(_serverInfo,options){super(options);if(this._serverInfo=_serverInfo,this._loggingLevels=new Map,this.LOG_LEVEL_SEVERITY=new Map(LoggingLevelSchema.options.map((level,index)=>[level,index])),this.isMessageIgnored=(level,sessionId)=>{let currentLevel=this._loggingLevels.get(sessionId);return currentLevel?this.LOG_LEVEL_SEVERITY.get(level)<this.LOG_LEVEL_SEVERITY.get(currentLevel):!1},this._capabilities=options?.capabilities??{},this._instructions=options?.instructions,this._jsonSchemaValidator=options?.jsonSchemaValidator??new AjvJsonSchemaValidator,this.setRequestHandler(InitializeRequestSchema,(request)=>this._oninitialize(request)),this.setNotificationHandler(InitializedNotificationSchema,()=>this.oninitialized?.()),this._capabilities.logging)this.setRequestHandler(SetLevelRequestSchema,async(request,extra)=>{let transportSessionId=extra.sessionId||extra.requestInfo?.headers["mcp-session-id"]||void 0,{level}=request.params,parseResult=LoggingLevelSchema.safeParse(level);if(parseResult.success)this._loggingLevels.set(transportSessionId,parseResult.data);return{}})}get experimental(){if(!this._experimental)this._experimental={tasks:new ExperimentalServerTasks(this)};return this._experimental}registerCapabilities(capabilities){if(this.transport)throw Error("Cannot register capabilities after connecting to transport");this._capabilities=mergeCapabilities(this._capabilities,capabilities)}setRequestHandler(requestSchema,handler){let methodSchema=getObjectShape(requestSchema)?.method;if(!methodSchema)throw Error("Schema is missing a method literal");let methodValue=getLiteralValue(methodSchema);if(typeof methodValue!=="string")throw Error("Schema method literal must be a string");if(methodValue==="tools/call"){let wrappedHandler=async(request,extra)=>{let validatedRequest=safeParse2(CallToolRequestSchema,request);if(!validatedRequest.success){let errorMessage=validatedRequest.error instanceof Error?validatedRequest.error.message:String(validatedRequest.error);throw new McpError(ErrorCode.InvalidParams,`Invalid tools/call request: ${errorMessage}`)}let{params}=validatedRequest.data,result=await Promise.resolve(handler(request,extra));if(params.task){let taskValidationResult=safeParse2(CreateTaskResultSchema,result);if(!taskValidationResult.success){let errorMessage=taskValidationResult.error instanceof Error?taskValidationResult.error.message:String(taskValidationResult.error);throw new McpError(ErrorCode.InvalidParams,`Invalid task creation result: ${errorMessage}`)}return taskValidationResult.data}let validationResult=safeParse2(CallToolResultSchema,result);if(!validationResult.success){let errorMessage=validationResult.error instanceof Error?validationResult.error.message:String(validationResult.error);throw new McpError(ErrorCode.InvalidParams,`Invalid tools/call result: ${errorMessage}`)}return validationResult.data};return super.setRequestHandler(requestSchema,wrappedHandler)}return super.setRequestHandler(requestSchema,handler)}assertCapabilityForMethod(method){switch(method){case"sampling/createMessage":if(!this._clientCapabilities?.sampling)throw Error(`Client does not support sampling (required for ${method})`);break;case"elicitation/create":if(!this._clientCapabilities?.elicitation)throw Error(`Client does not support elicitation (required for ${method})`);break;case"roots/list":if(!this._clientCapabilities?.roots)throw Error(`Client does not support listing roots (required for ${method})`);break;case"ping":break}}assertNotificationCapability(method){switch(method){case"notifications/message":if(!this._capabilities.logging)throw Error(`Server does not support logging (required for ${method})`);break;case"notifications/resources/updated":case"notifications/resources/list_changed":if(!this._capabilities.resources)throw Error(`Server does not support notifying about resources (required for ${method})`);break;case"notifications/tools/list_changed":if(!this._capabilities.tools)throw Error(`Server does not support notifying of tool list changes (required for ${method})`);break;case"notifications/prompts/list_changed":if(!this._capabilities.prompts)throw Error(`Server does not support notifying of prompt list changes (required for ${method})`);break;case"notifications/elicitation/complete":if(!this._clientCapabilities?.elicitation?.url)throw Error(`Client does not support URL elicitation (required for ${method})`);break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(method){if(!this._capabilities)return;switch(method){case"completion/complete":if(!this._capabilities.completions)throw Error(`Server does not support completions (required for ${method})`);break;case"logging/setLevel":if(!this._capabilities.logging)throw Error(`Server does not support logging (required for ${method})`);break;case"prompts/get":case"prompts/list":if(!this._capabilities.prompts)throw Error(`Server does not support prompts (required for ${method})`);break;case"resources/list":case"resources/templates/list":case"resources/read":if(!this._capabilities.resources)throw Error(`Server does not support resources (required for ${method})`);break;case"tools/call":case"tools/list":if(!this._capabilities.tools)throw Error(`Server does not support tools (required for ${method})`);break;case"tasks/get":case"tasks/list":case"tasks/result":case"tasks/cancel":if(!this._capabilities.tasks)throw Error(`Server does not support tasks capability (required for ${method})`);break;case"ping":case"initialize":break}}assertTaskCapability(method){assertClientRequestTaskCapability(this._clientCapabilities?.tasks?.requests,method,"Client")}assertTaskHandlerCapability(method){if(!this._capabilities)return;assertToolsCallTaskCapability(this._capabilities.tasks?.requests,method,"Server")}async _oninitialize(request){let requestedVersion=request.params.protocolVersion;return this._clientCapabilities=request.params.capabilities,this._clientVersion=request.params.clientInfo,{protocolVersion:SUPPORTED_PROTOCOL_VERSIONS.includes(requestedVersion)?requestedVersion:LATEST_PROTOCOL_VERSION,capabilities:this.getCapabilities(),serverInfo:this._serverInfo,...this._instructions&&{instructions:this._instructions}}}getClientCapabilities(){return this._clientCapabilities}getClientVersion(){return this._clientVersion}getCapabilities(){return this._capabilities}async ping(){return this.request({method:"ping"},EmptyResultSchema)}async createMessage(params,options){if(params.tools||params.toolChoice){if(!this._clientCapabilities?.sampling?.tools)throw Error("Client does not support sampling tools capability.")}if(params.messages.length>0){let lastMessage=params.messages[params.messages.length-1],lastContent=Array.isArray(lastMessage.content)?lastMessage.content:[lastMessage.content],hasToolResults=lastContent.some((c)=>c.type==="tool_result"),previousMessage=params.messages.length>1?params.messages[params.messages.length-2]:void 0,previousContent=previousMessage?Array.isArray(previousMessage.content)?previousMessage.content:[previousMessage.content]:[],hasPreviousToolUse=previousContent.some((c)=>c.type==="tool_use");if(hasToolResults){if(lastContent.some((c)=>c.type!=="tool_result"))throw Error("The last message must contain only tool_result content if any is present");if(!hasPreviousToolUse)throw Error("tool_result blocks are not matching any tool_use from the previous message")}if(hasPreviousToolUse){let toolUseIds=new Set(previousContent.filter((c)=>c.type==="tool_use").map((c)=>c.id)),toolResultIds=new Set(lastContent.filter((c)=>c.type==="tool_result").map((c)=>c.toolUseId));if(toolUseIds.size!==toolResultIds.size||![...toolUseIds].every((id)=>toolResultIds.has(id)))throw Error("ids of tool_result blocks and tool_use blocks from previous message do not match")}}if(params.tools)return this.request({method:"sampling/createMessage",params},CreateMessageResultWithToolsSchema,options);return this.request({method:"sampling/createMessage",params},CreateMessageResultSchema,options)}async elicitInput(params,options){switch(params.mode??"form"){case"url":{if(!this._clientCapabilities?.elicitation?.url)throw Error("Client does not support url elicitation.");let urlParams=params;return this.request({method:"elicitation/create",params:urlParams},ElicitResultSchema,options)}case"form":{if(!this._clientCapabilities?.elicitation?.form)throw Error("Client does not support form elicitation.");let formParams=params.mode==="form"?params:{...params,mode:"form"},result=await this.request({method:"elicitation/create",params:formParams},ElicitResultSchema,options);if(result.action==="accept"&&result.content&&formParams.requestedSchema)try{let validationResult=this._jsonSchemaValidator.getValidator(formParams.requestedSchema)(result.content);if(!validationResult.valid)throw new McpError(ErrorCode.InvalidParams,`Elicitation response content does not match requested schema: ${validationResult.errorMessage}`)}catch(error){if(error instanceof McpError)throw error;throw new McpError(ErrorCode.InternalError,`Error validating elicitation response: ${error instanceof Error?error.message:String(error)}`)}return result}}}createElicitationCompletionNotifier(elicitationId,options){if(!this._clientCapabilities?.elicitation?.url)throw Error("Client does not support URL elicitation (required for notifications/elicitation/complete)");return()=>this.notification({method:"notifications/elicitation/complete",params:{elicitationId}},options)}async listRoots(params,options){return this.request({method:"roots/list",params},ListRootsResultSchema,options)}async sendLoggingMessage(params,sessionId){if(this._capabilities.logging){if(!this.isMessageIgnored(params.level,sessionId))return this.notification({method:"notifications/message",params})}}async sendResourceUpdated(params){return this.notification({method:"notifications/resources/updated",params})}async sendResourceListChanged(){return this.notification({method:"notifications/resources/list_changed"})}async sendToolListChanged(){return this.notification({method:"notifications/tools/list_changed"})}async sendPromptListChanged(){return this.notification({method:"notifications/prompts/list_changed"})}}var COMPLETABLE_SYMBOL=Symbol.for("mcp.completable");function isCompletable(schema){return!!schema&&typeof schema==="object"&&COMPLETABLE_SYMBOL in schema}function getCompleter(schema){return schema[COMPLETABLE_SYMBOL]?.complete}var McpZodTypeKind;(function(McpZodTypeKind){McpZodTypeKind.Completable="McpCompletable"})(McpZodTypeKind||(McpZodTypeKind={}));var TOOL_NAME_REGEX=/^[A-Za-z0-9._-]{1,128}$/;function validateToolName(name){let warnings=[];if(name.length===0)return{isValid:!1,warnings:["Tool name cannot be empty"]};if(name.length>128)return{isValid:!1,warnings:[`Tool name exceeds maximum length of 128 characters (current: ${name.length})`]};if(name.includes(" "))warnings.push("Tool name contains spaces, which may cause parsing issues");if(name.includes(","))warnings.push("Tool name contains commas, which may cause parsing issues");if(name.startsWith("-")||name.endsWith("-"))warnings.push("Tool name starts or ends with a dash, which may cause parsing issues in some contexts");if(name.startsWith(".")||name.endsWith("."))warnings.push("Tool name starts or ends with a dot, which may cause parsing issues in some contexts");if(!TOOL_NAME_REGEX.test(name)){let invalidChars=name.split("").filter((char)=>!/[A-Za-z0-9._-]/.test(char)).filter((char,index,arr)=>arr.indexOf(char)===index);return warnings.push(`Tool name contains invalid characters: ${invalidChars.map((c)=>`"${c}"`).join(", ")}`,"Allowed characters are: A-Z, a-z, 0-9, underscore (_), dash (-), and dot (.)"),{isValid:!1,warnings}}return{isValid:!0,warnings}}function issueToolNameWarning(name,warnings){if(warnings.length>0){console.warn(`Tool name validation warning for "${name}":`);for(let warning of warnings)console.warn(` - ${warning}`);console.warn("Tool registration will proceed, but this may cause compatibility issues."),console.warn("Consider updating the tool name to conform to the MCP tool naming standard."),console.warn("See SEP: Specify Format for Tool Names (https://github.com/modelcontextprotocol/modelcontextprotocol/issues/986) for more details.")}}function validateAndWarnToolName(name){let result=validateToolName(name);return issueToolNameWarning(name,result.warnings),result.isValid}class ExperimentalMcpServerTasks{constructor(_mcpServer){this._mcpServer=_mcpServer}registerToolTask(name,config,handler){let execution={taskSupport:"required",...config.execution};if(execution.taskSupport==="forbidden")throw Error(`Cannot register task-based tool '${name}' with taskSupport 'forbidden'. Use registerTool() instead.`);return this._mcpServer._createRegisteredTool(name,config.title,config.description,config.inputSchema,config.outputSchema,config.annotations,execution,config._meta,handler)}}class McpServer{constructor(serverInfo,options){this._registeredResources={},this._registeredResourceTemplates={},this._registeredTools={},this._registeredPrompts={},this._toolHandlersInitialized=!1,this._completionHandlerInitialized=!1,this._resourceHandlersInitialized=!1,this._promptHandlersInitialized=!1,this.server=new Server(serverInfo,options)}get experimental(){if(!this._experimental)this._experimental={tasks:new ExperimentalMcpServerTasks(this)};return this._experimental}async connect(transport){return await this.server.connect(transport)}async close(){await this.server.close()}setToolRequestHandlers(){if(this._toolHandlersInitialized)return;this.server.assertCanSetRequestHandler(getMethodValue(ListToolsRequestSchema)),this.server.assertCanSetRequestHandler(getMethodValue(CallToolRequestSchema)),this.server.registerCapabilities({tools:{listChanged:!0}}),this.server.setRequestHandler(ListToolsRequestSchema,()=>({tools:Object.entries(this._registeredTools).filter(([,tool])=>tool.enabled).map(([name,tool])=>{let toolDefinition={name,title:tool.title,description:tool.description,inputSchema:(()=>{let obj=normalizeObjectSchema(tool.inputSchema);return obj?toJsonSchemaCompat(obj,{strictUnions:!0,pipeStrategy:"input"}):EMPTY_OBJECT_JSON_SCHEMA})(),annotations:tool.annotations,execution:tool.execution,_meta:tool._meta};if(tool.outputSchema){let obj=normalizeObjectSchema(tool.outputSchema);if(obj)toolDefinition.outputSchema=toJsonSchemaCompat(obj,{strictUnions:!0,pipeStrategy:"output"})}return toolDefinition})})),this.server.setRequestHandler(CallToolRequestSchema,async(request,extra)=>{try{let tool=this._registeredTools[request.params.name];if(!tool)throw new McpError(ErrorCode.InvalidParams,`Tool ${request.params.name} not found`);if(!tool.enabled)throw new McpError(ErrorCode.InvalidParams,`Tool ${request.params.name} disabled`);let isTaskRequest=!!request.params.task,taskSupport=tool.execution?.taskSupport,isTaskHandler="createTask"in tool.handler;if((taskSupport==="required"||taskSupport==="optional")&&!isTaskHandler)throw new McpError(ErrorCode.InternalError,`Tool ${request.params.name} has taskSupport '${taskSupport}' but was not registered with registerToolTask`);if(taskSupport==="required"&&!isTaskRequest)throw new McpError(ErrorCode.MethodNotFound,`Tool ${request.params.name} requires task augmentation (taskSupport: 'required')`);if(taskSupport==="optional"&&!isTaskRequest&&isTaskHandler)return await this.handleAutomaticTaskPolling(tool,request,extra);let args=await this.validateToolInput(tool,request.params.arguments,request.params.name),result=await this.executeToolHandler(tool,args,extra);if(isTaskRequest)return result;return await this.validateToolOutput(tool,result,request.params.name),result}catch(error){if(error instanceof McpError){if(error.code===ErrorCode.UrlElicitationRequired)throw error}return this.createToolError(error instanceof Error?error.message:String(error))}}),this._toolHandlersInitialized=!0}createToolError(errorMessage){return{content:[{type:"text",text:errorMessage}],isError:!0}}async validateToolInput(tool,args,toolName){if(!tool.inputSchema)return;let schemaToParse=normalizeObjectSchema(tool.inputSchema)??tool.inputSchema,parseResult=await safeParseAsync2(schemaToParse,args);if(!parseResult.success){let error="error"in parseResult?parseResult.error:"Unknown error",errorMessage=getParseErrorMessage(error);throw new McpError(ErrorCode.InvalidParams,`Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}`)}return parseResult.data}async validateToolOutput(tool,result,toolName){if(!tool.outputSchema)return;if(!("content"in result))return;if(result.isError)return;if(!result.structuredContent)throw new McpError(ErrorCode.InvalidParams,`Output validation error: Tool ${toolName} has an output schema but no structured content was provided`);let outputObj=normalizeObjectSchema(tool.outputSchema),parseResult=await safeParseAsync2(outputObj,result.structuredContent);if(!parseResult.success){let error="error"in parseResult?parseResult.error:"Unknown error",errorMessage=getParseErrorMessage(error);throw new McpError(ErrorCode.InvalidParams,`Output validation error: Invalid structured content for tool ${toolName}: ${errorMessage}`)}}async executeToolHandler(tool,args,extra){let handler=tool.handler;if("createTask"in handler){if(!extra.taskStore)throw Error("No task store provided.");let taskExtra={...extra,taskStore:extra.taskStore};if(tool.inputSchema)return await Promise.resolve(handler.createTask(args,taskExtra));else return await Promise.resolve(handler.createTask(taskExtra))}if(tool.inputSchema)return await Promise.resolve(handler(args,extra));else return await Promise.resolve(handler(extra))}async handleAutomaticTaskPolling(tool,request,extra){if(!extra.taskStore)throw Error("No task store provided for task-capable tool.");let args=await this.validateToolInput(tool,request.params.arguments,request.params.name),handler=tool.handler,taskExtra={...extra,taskStore:extra.taskStore},createTaskResult=args?await Promise.resolve(handler.createTask(args,taskExtra)):await Promise.resolve(handler.createTask(taskExtra)),taskId=createTaskResult.task.taskId,task=createTaskResult.task,pollInterval=task.pollInterval??5000;while(task.status!=="completed"&&task.status!=="failed"&&task.status!=="cancelled"){await new Promise((resolve)=>setTimeout(resolve,pollInterval));let updatedTask=await extra.taskStore.getTask(taskId);if(!updatedTask)throw new McpError(ErrorCode.InternalError,`Task ${taskId} not found during polling`);task=updatedTask}return await extra.taskStore.getTaskResult(taskId)}setCompletionRequestHandler(){if(this._completionHandlerInitialized)return;this.server.assertCanSetRequestHandler(getMethodValue(CompleteRequestSchema)),this.server.registerCapabilities({completions:{}}),this.server.setRequestHandler(CompleteRequestSchema,async(request)=>{switch(request.params.ref.type){case"ref/prompt":return assertCompleteRequestPrompt(request),this.handlePromptCompletion(request,request.params.ref);case"ref/resource":return assertCompleteRequestResourceTemplate(request),this.handleResourceCompletion(request,request.params.ref);default:throw new McpError(ErrorCode.InvalidParams,`Invalid completion reference: ${request.params.ref}`)}}),this._completionHandlerInitialized=!0}async handlePromptCompletion(request,ref){let prompt=this._registeredPrompts[ref.name];if(!prompt)throw new McpError(ErrorCode.InvalidParams,`Prompt ${ref.name} not found`);if(!prompt.enabled)throw new McpError(ErrorCode.InvalidParams,`Prompt ${ref.name} disabled`);if(!prompt.argsSchema)return EMPTY_COMPLETION_RESULT;let field=getObjectShape(prompt.argsSchema)?.[request.params.argument.name];if(!isCompletable(field))return EMPTY_COMPLETION_RESULT;let completer=getCompleter(field);if(!completer)return EMPTY_COMPLETION_RESULT;let suggestions=await completer(request.params.argument.value,request.params.context);return createCompletionResult(suggestions)}async handleResourceCompletion(request,ref){let template=Object.values(this._registeredResourceTemplates).find((t)=>t.resourceTemplate.uriTemplate.toString()===ref.uri);if(!template){if(this._registeredResources[ref.uri])return EMPTY_COMPLETION_RESULT;throw new McpError(ErrorCode.InvalidParams,`Resource template ${request.params.ref.uri} not found`)}let completer=template.resourceTemplate.completeCallback(request.params.argument.name);if(!completer)return EMPTY_COMPLETION_RESULT;let suggestions=await completer(request.params.argument.value,request.params.context);return createCompletionResult(suggestions)}setResourceRequestHandlers(){if(this._resourceHandlersInitialized)return;this.server.assertCanSetRequestHandler(getMethodValue(ListResourcesRequestSchema)),this.server.assertCanSetRequestHandler(getMethodValue(ListResourceTemplatesRequestSchema)),this.server.assertCanSetRequestHandler(getMethodValue(ReadResourceRequestSchema)),this.server.registerCapabilities({resources:{listChanged:!0}}),this.server.setRequestHandler(ListResourcesRequestSchema,async(request,extra)=>{let resources=Object.entries(this._registeredResources).filter(([_,resource])=>resource.enabled).map(([uri,resource])=>({uri,name:resource.name,...resource.metadata})),templateResources=[];for(let template of Object.values(this._registeredResourceTemplates)){if(!template.resourceTemplate.listCallback)continue;let result=await template.resourceTemplate.listCallback(extra);for(let resource of result.resources)templateResources.push({...template.metadata,...resource})}return{resources:[...resources,...templateResources]}}),this.server.setRequestHandler(ListResourceTemplatesRequestSchema,async()=>({resourceTemplates:Object.entries(this._registeredResourceTemplates).map(([name,template])=>({name,uriTemplate:template.resourceTemplate.uriTemplate.toString(),...template.metadata}))})),this.server.setRequestHandler(ReadResourceRequestSchema,async(request,extra)=>{let uri=new URL(request.params.uri),resource=this._registeredResources[uri.toString()];if(resource){if(!resource.enabled)throw new McpError(ErrorCode.InvalidParams,`Resource ${uri} disabled`);return resource.readCallback(uri,extra)}for(let template of Object.values(this._registeredResourceTemplates)){let variables=template.resourceTemplate.uriTemplate.match(uri.toString());if(variables)return template.readCallback(uri,variables,extra)}throw new McpError(ErrorCode.InvalidParams,`Resource ${uri} not found`)}),this._resourceHandlersInitialized=!0}setPromptRequestHandlers(){if(this._promptHandlersInitialized)return;this.server.assertCanSetRequestHandler(getMethodValue(ListPromptsRequestSchema)),this.server.assertCanSetRequestHandler(getMethodValue(GetPromptRequestSchema)),this.server.registerCapabilities({prompts:{listChanged:!0}}),this.server.setRequestHandler(ListPromptsRequestSchema,()=>({prompts:Object.entries(this._registeredPrompts).filter(([,prompt])=>prompt.enabled).map(([name,prompt])=>({name,title:prompt.title,description:prompt.description,arguments:prompt.argsSchema?promptArgumentsFromSchema(prompt.argsSchema):void 0}))})),this.server.setRequestHandler(GetPromptRequestSchema,async(request,extra)=>{let prompt=this._registeredPrompts[request.params.name];if(!prompt)throw new McpError(ErrorCode.InvalidParams,`Prompt ${request.params.name} not found`);if(!prompt.enabled)throw new McpError(ErrorCode.InvalidParams,`Prompt ${request.params.name} disabled`);if(prompt.argsSchema){let argsObj=normalizeObjectSchema(prompt.argsSchema),parseResult=await safeParseAsync2(argsObj,request.params.arguments);if(!parseResult.success){let error="error"in parseResult?parseResult.error:"Unknown error",errorMessage=getParseErrorMessage(error);throw new McpError(ErrorCode.InvalidParams,`Invalid arguments for prompt ${request.params.name}: ${errorMessage}`)}let args=parseResult.data,cb=prompt.callback;return await Promise.resolve(cb(args,extra))}else{let cb=prompt.callback;return await Promise.resolve(cb(extra))}}),this._promptHandlersInitialized=!0}resource(name,uriOrTemplate,...rest){let metadata;if(typeof rest[0]==="object")metadata=rest.shift();let readCallback=rest[0];if(typeof uriOrTemplate==="string"){if(this._registeredResources[uriOrTemplate])throw Error(`Resource ${uriOrTemplate} is already registered`);let registeredResource=this._createRegisteredResource(name,void 0,uriOrTemplate,metadata,readCallback);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),registeredResource}else{if(this._registeredResourceTemplates[name])throw Error(`Resource template ${name} is already registered`);let registeredResourceTemplate=this._createRegisteredResourceTemplate(name,void 0,uriOrTemplate,metadata,readCallback);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),registeredResourceTemplate}}registerResource(name,uriOrTemplate,config,readCallback){if(typeof uriOrTemplate==="string"){if(this._registeredResources[uriOrTemplate])throw Error(`Resource ${uriOrTemplate} is already registered`);let registeredResource=this._createRegisteredResource(name,config.title,uriOrTemplate,config,readCallback);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),registeredResource}else{if(this._registeredResourceTemplates[name])throw Error(`Resource template ${name} is already registered`);let registeredResourceTemplate=this._createRegisteredResourceTemplate(name,config.title,uriOrTemplate,config,readCallback);return this.setResourceRequestHandlers(),this.sendResourceListChanged(),registeredResourceTemplate}}_createRegisteredResource(name,title,uri,metadata,readCallback){let registeredResource={name,title,metadata,readCallback,enabled:!0,disable:()=>registeredResource.update({enabled:!1}),enable:()=>registeredResource.update({enabled:!0}),remove:()=>registeredResource.update({uri:null}),update:(updates)=>{if(typeof updates.uri<"u"&&updates.uri!==uri){if(delete this._registeredResources[uri],updates.uri)this._registeredResources[updates.uri]=registeredResource}if(typeof updates.name<"u")registeredResource.name=updates.name;if(typeof updates.title<"u")registeredResource.title=updates.title;if(typeof updates.metadata<"u")registeredResource.metadata=updates.metadata;if(typeof updates.callback<"u")registeredResource.readCallback=updates.callback;if(typeof updates.enabled<"u")registeredResource.enabled=updates.enabled;this.sendResourceListChanged()}};return this._registeredResources[uri]=registeredResource,registeredResource}_createRegisteredResourceTemplate(name,title,template,metadata,readCallback){let registeredResourceTemplate={resourceTemplate:template,title,metadata,readCallback,enabled:!0,disable:()=>registeredResourceTemplate.update({enabled:!1}),enable:()=>registeredResourceTemplate.update({enabled:!0}),remove:()=>registeredResourceTemplate.update({name:null}),update:(updates)=>{if(typeof updates.name<"u"&&updates.name!==name){if(delete this._registeredResourceTemplates[name],updates.name)this._registeredResourceTemplates[updates.name]=registeredResourceTemplate}if(typeof updates.title<"u")registeredResourceTemplate.title=updates.title;if(typeof updates.template<"u")registeredResourceTemplate.resourceTemplate=updates.template;if(typeof updates.metadata<"u")registeredResourceTemplate.metadata=updates.metadata;if(typeof updates.callback<"u")registeredResourceTemplate.readCallback=updates.callback;if(typeof updates.enabled<"u")registeredResourceTemplate.enabled=updates.enabled;this.sendResourceListChanged()}};this._registeredResourceTemplates[name]=registeredResourceTemplate;let variableNames=template.uriTemplate.variableNames;if(Array.isArray(variableNames)&&variableNames.some((v)=>!!template.completeCallback(v)))this.setCompletionRequestHandler();return registeredResourceTemplate}_createRegisteredPrompt(name,title,description,argsSchema,callback){let registeredPrompt={title,description,argsSchema:argsSchema===void 0?void 0:objectFromShape(argsSchema),callback,enabled:!0,disable:()=>registeredPrompt.update({enabled:!1}),enable:()=>registeredPrompt.update({enabled:!0}),remove:()=>registeredPrompt.update({name:null}),update:(updates)=>{if(typeof updates.name<"u"&&updates.name!==name){if(delete this._registeredPrompts[name],updates.name)this._registeredPrompts[updates.name]=registeredPrompt}if(typeof updates.title<"u")registeredPrompt.title=updates.title;if(typeof updates.description<"u")registeredPrompt.description=updates.description;if(typeof updates.argsSchema<"u")registeredPrompt.argsSchema=objectFromShape(updates.argsSchema);if(typeof updates.callback<"u")registeredPrompt.callback=updates.callback;if(typeof updates.enabled<"u")registeredPrompt.enabled=updates.enabled;this.sendPromptListChanged()}};if(this._registeredPrompts[name]=registeredPrompt,argsSchema){if(Object.values(argsSchema).some((field)=>{let inner=field instanceof ZodOptional?field._def?.innerType:field;return isCompletable(inner)}))this.setCompletionRequestHandler()}return registeredPrompt}_createRegisteredTool(name,title,description,inputSchema,outputSchema,annotations,execution,_meta,handler){validateAndWarnToolName(name);let registeredTool={title,description,inputSchema:getZodSchemaObject(inputSchema),outputSchema:getZodSchemaObject(outputSchema),annotations,execution,_meta,handler,enabled:!0,disable:()=>registeredTool.update({enabled:!1}),enable:()=>registeredTool.update({enabled:!0}),remove:()=>registeredTool.update({name:null}),update:(updates)=>{if(typeof updates.name<"u"&&updates.name!==name){if(typeof updates.name==="string")validateAndWarnToolName(updates.name);if(delete this._registeredTools[name],updates.name)this._registeredTools[updates.name]=registeredTool}if(typeof updates.title<"u")registeredTool.title=updates.title;if(typeof updates.description<"u")registeredTool.description=updates.description;if(typeof updates.paramsSchema<"u")registeredTool.inputSchema=objectFromShape(updates.paramsSchema);if(typeof updates.outputSchema<"u")registeredTool.outputSchema=objectFromShape(updates.outputSchema);if(typeof updates.callback<"u")registeredTool.handler=updates.callback;if(typeof updates.annotations<"u")registeredTool.annotations=updates.annotations;if(typeof updates._meta<"u")registeredTool._meta=updates._meta;if(typeof updates.enabled<"u")registeredTool.enabled=updates.enabled;this.sendToolListChanged()}};return this._registeredTools[name]=registeredTool,this.setToolRequestHandlers(),this.sendToolListChanged(),registeredTool}tool(name,...rest){if(this._registeredTools[name])throw Error(`Tool ${name} is already registered`);let description,inputSchema,outputSchema,annotations;if(typeof rest[0]==="string")description=rest.shift();if(rest.length>1){let firstArg=rest[0];if(isZodRawShapeCompat(firstArg)){if(inputSchema=rest.shift(),rest.length>1&&typeof rest[0]==="object"&&rest[0]!==null&&!isZodRawShapeCompat(rest[0]))annotations=rest.shift()}else if(typeof firstArg==="object"&&firstArg!==null){if(Object.values(firstArg).some((v)=>typeof v==="object"&&v!==null))throw Error(`Tool ${name} expected a Zod schema or ToolAnnotations, but received an unrecognized object`);annotations=rest.shift()}}let callback=rest[0];return this._createRegisteredTool(name,void 0,description,inputSchema,outputSchema,annotations,{taskSupport:"forbidden"},void 0,callback)}registerTool(name,config,cb){if(this._registeredTools[name])throw Error(`Tool ${name} is already registered`);let{title,description,inputSchema,outputSchema,annotations,_meta}=config;return this._createRegisteredTool(name,title,description,inputSchema,outputSchema,annotations,{taskSupport:"forbidden"},_meta,cb)}prompt(name,...rest){if(this._registeredPrompts[name])throw Error(`Prompt ${name} is already registered`);let description;if(typeof rest[0]==="string")description=rest.shift();let argsSchema;if(rest.length>1)argsSchema=rest.shift();let cb=rest[0],registeredPrompt=this._createRegisteredPrompt(name,void 0,description,argsSchema,cb);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),registeredPrompt}registerPrompt(name,config,cb){if(this._registeredPrompts[name])throw Error(`Prompt ${name} is already registered`);let{title,description,argsSchema}=config,registeredPrompt=this._createRegisteredPrompt(name,title,description,argsSchema,cb);return this.setPromptRequestHandlers(),this.sendPromptListChanged(),registeredPrompt}isConnected(){return this.server.transport!==void 0}async sendLoggingMessage(params,sessionId){return this.server.sendLoggingMessage(params,sessionId)}sendResourceListChanged(){if(this.isConnected())this.server.sendResourceListChanged()}sendToolListChanged(){if(this.isConnected())this.server.sendToolListChanged()}sendPromptListChanged(){if(this.isConnected())this.server.sendPromptListChanged()}}var EMPTY_OBJECT_JSON_SCHEMA={type:"object",properties:{}};function isZodTypeLike(value){return value!==null&&typeof value==="object"&&"parse"in value&&typeof value.parse==="function"&&"safeParse"in value&&typeof value.safeParse==="function"}function isZodSchemaInstance(obj){return"_def"in obj||"_zod"in obj||isZodTypeLike(obj)}function isZodRawShapeCompat(obj){if(typeof obj!=="object"||obj===null)return!1;if(isZodSchemaInstance(obj))return!1;if(Object.keys(obj).length===0)return!0;return Object.values(obj).some(isZodTypeLike)}function getZodSchemaObject(schema){if(!schema)return;if(isZodRawShapeCompat(schema))return objectFromShape(schema);if(!isZodSchemaInstance(schema))throw Error("inputSchema must be a Zod schema or raw shape, received an unrecognized object");return schema}function promptArgumentsFromSchema(schema){let shape=getObjectShape(schema);if(!shape)return[];return Object.entries(shape).map(([name,field])=>{let description=getSchemaDescription(field),isOptional=isSchemaOptional(field);return{name,description,required:!isOptional}})}function getMethodValue(schema){let methodSchema=getObjectShape(schema)?.method;if(!methodSchema)throw Error("Schema is missing a method literal");let value=getLiteralValue(methodSchema);if(typeof value==="string")return value;throw Error("Schema method literal must be a string")}function createCompletionResult(suggestions){return{completion:{values:suggestions.slice(0,100),total:suggestions.length,hasMore:suggestions.length>100}}}var EMPTY_COMPLETION_RESULT={completion:{values:[],hasMore:!1}};import process2 from"process";var STDIO_DEFAULT_MAX_BUFFER_SIZE=10485760;class ReadBuffer{constructor(options){this._maxBufferSize=options?.maxBufferSize??STDIO_DEFAULT_MAX_BUFFER_SIZE}append(chunk){if((this._buffer?.length??0)+chunk.length>this._maxBufferSize)throw this.clear(),Error(`ReadBuffer exceeded maximum size of ${this._maxBufferSize} bytes`);this._buffer=this._buffer?Buffer.concat([this._buffer,chunk]):chunk}readMessage(){if(!this._buffer)return null;let index=this._buffer.indexOf(`
144
144
  `);if(index===-1)return null;let line=this._buffer.toString("utf8",0,index).replace(/\r$/,"");return this._buffer=this._buffer.subarray(index+1),deserializeMessage(line)}clear(){this._buffer=void 0}}function deserializeMessage(line){return JSONRPCMessageSchema.parse(JSON.parse(line))}function serializeMessage(message){return JSON.stringify(message)+`
145
- `}class StdioServerTransport{constructor(_stdin=process2.stdin,_stdout=process2.stdout,options){this._stdin=_stdin,this._stdout=_stdout,this._started=!1,this._ondata=(chunk)=>{try{this._readBuffer.append(chunk),this.processReadBuffer()}catch(error){this.onerror?.(error),this.close().catch(()=>{})}},this._onerror=(error)=>{this.onerror?.(error)},this._readBuffer=new ReadBuffer({maxBufferSize:options?.maxBufferSize})}async start(){if(this._started)throw Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){while(!0)try{let message=this._readBuffer.readMessage();if(message===null)break;this.onmessage?.(message)}catch(error){this.onerror?.(error)}}async close(){if(this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(message){return new Promise((resolve)=>{let json=serializeMessage(message);if(this._stdout.write(json))resolve();else this._stdout.once("drain",resolve)})}}var SERVER_VERSION="0.3.0",MCP_SERVER_INFO={name:"velloo",version:SERVER_VERSION};function gateInstructions(opts){let mismatch=`Velloo could not open the design folder at ${opts.root}: it is on design-folder format v${opts.found}, but this velloo reads v${opts.current}. The canvas and all `+"design tools are unavailable until that is resolved \u2014 this session only carries "+`this notice${opts.upgrade?" and the migration tool":""}.`,fix=opts.upgrade?"To fix it, call the `upgrade_design_folder` tool \u2014 it migrates the folder in "+`place, exactly like running \`velloo upgrade ${opts.root}\` in a shell (which also works, if you prefer). After it succeeds, reconnect this MCP server (restart it in your client) to load the design tools.`:"The folder was written by a NEWER velloo than this one \u2014 nothing here can migrate "+"it backwards. The velloo CLI itself must be updated (e.g. its global install), then reconnect this MCP server.";return`${mismatch}
145
+ `}class StdioServerTransport{constructor(_stdin=process2.stdin,_stdout=process2.stdout,options){this._stdin=_stdin,this._stdout=_stdout,this._started=!1,this._ondata=(chunk)=>{try{this._readBuffer.append(chunk),this.processReadBuffer()}catch(error){this.onerror?.(error),this.close().catch(()=>{})}},this._onerror=(error)=>{this.onerror?.(error)},this._readBuffer=new ReadBuffer({maxBufferSize:options?.maxBufferSize})}async start(){if(this._started)throw Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror)}processReadBuffer(){while(!0)try{let message=this._readBuffer.readMessage();if(message===null)break;this.onmessage?.(message)}catch(error){this.onerror?.(error)}}async close(){if(this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(message){return new Promise((resolve)=>{let json=serializeMessage(message);if(this._stdout.write(json))resolve();else this._stdout.once("drain",resolve)})}}var SERVER_VERSION="0.4.0",MCP_SERVER_INFO={name:"velloo",version:SERVER_VERSION};function gateInstructions(opts){let mismatch=`Velloo could not open the design folder at ${opts.root}: it is on design-folder format v${opts.found}, but this velloo reads v${opts.current}. The canvas and all `+"design tools are unavailable until that is resolved \u2014 this session only carries "+`this notice${opts.upgrade?" and the migration tool":""}.`,fix=opts.upgrade?"To fix it, call the `upgrade_design_folder` tool \u2014 it migrates the folder in "+`place, exactly like running \`velloo upgrade ${opts.root}\` in a shell (which also works, if you prefer). After it succeeds, reconnect this MCP server (restart it in your client) to load the design tools.`:"The folder was written by a NEWER velloo than this one \u2014 nothing here can migrate "+"it backwards. The velloo CLI itself must be updated (e.g. its global install), then reconnect this MCP server.";return`${mismatch}
146
146
 
147
147
  ${fix}
148
148
 
@@ -184,7 +184,7 @@ ${LOADER_MERGE_BODY}`}function buildInlineLoaderModule(bundles){return`const gro
184
184
  ${bundles.map((r)=>` import("data:text/javascript;base64,${Buffer.from(r.code,"utf8").toString("base64")}"),`).join(`
185
185
  `)}
186
186
  ${LOADER_MERGE_BODY}`}function realPath(path){try{return realpathSync4.native(path)}catch{return path}}class LiveBundler{folderRoot;hostAppsFor;liveExtensionsFor;minify;inline;cached=null;cachedApps=null;buildPromise=null;_version=0;constructor(folderRoot,hostAppsFor,liveExtensionsFor,minify=!1,inline=!1){this.folderRoot=folderRoot;this.hostAppsFor=hostAppsFor;this.liveExtensionsFor=liveExtensionsFor;this.minify=minify;this.inline=inline}get version(){return this._version}hostSourceDirs(){let config=this.hostAppsFor(),dirs=new Set;for(let[app,entries]of partitionByApp(this.liveExtensionsFor())){let hostApp=hostAppForExtension(config,app||void 0);if(hostApp===null)continue;let hostRoot=hostAppRootFrom(this.folderRoot,hostApp),realRoot=realPath(hostRoot),nodeModules=join22(realRoot,"node_modules");for(let entry of entries)try{let file=realPath(resolveImport(entry.importPath,hostRoot,aliasPairs(hostApp,hostRoot)));if(file.startsWith(realRoot)&&!file.startsWith(nodeModules))dirs.add(dirname12(file))}catch{}}return Array.from(dirs)}invalidate(){this.cached=null,this.cachedApps=null,this.buildPromise=null,this._version++}async build(){if(this.cached)return this.cached;if(this.buildPromise)return this.buildPromise;return this.buildPromise=this.doBuild().then((result)=>(this.cached=result,this.buildPromise=null,result)).catch((err)=>{this.buildPromise=null;let result={code:EMPTY_MODULE,errors:[{message:err instanceof Error?err.message:String(err)}]};return this.cached=result,result}),this.buildPromise}async buildApp(app){return await this.build(),this.cachedApps?.get(app)??{code:EMPTY_MODULE,errors:[{message:`no live bundle for app "${app}"`}]}}async doBuild(){let groups=partitionByApp(this.liveExtensionsFor());if(groups.size===0)return this.cachedApps=new Map,{code:EMPTY_MODULE,errors:[]};let config=this.hostAppsFor(),apps=new Map;for(let[app,entries]of groups){let hostApp=hostAppForExtension(config,app||void 0);if(hostApp===null){apps.set(app,{code:EMPTY_MODULE,errors:entries.map((e)=>({importPath:e.importPath,message:`${e.id}: extension names app "${app}" but config.hostApps has no such key.`}))});continue}let appRoot=hostAppRootFrom(this.folderRoot,hostApp);apps.set(app,await bundleComponents({hostRoot:appRoot,entries,aliases:aliasPairs(hostApp,appRoot),minify:this.minify,cacheKey:`${this.folderRoot}\x00${app}`}))}this.cachedApps=apps;let errors=[...apps.values()].flatMap((r)=>r.errors);if(apps.size===1)return{code:[...apps.values()][0].code,errors};return{code:this.inline?buildInlineLoaderModule([...apps.values()]):buildLoaderModule([...apps.keys()],this._version),errors}}}var screenNotFound=(screenId)=>({kind:"ScreenNotFound",screenId}),boardNotFound=(boardId)=>({kind:"BoardNotFound",boardId}),frameNotFound=(boardId,frameId)=>({kind:"FrameNotFound",boardId,frameId}),boardGroupNotFound=(groupId)=>({kind:"BoardGroupNotFound",groupId}),unknownComponent2=(ref,suggestions,hint)=>({kind:"UnknownComponent",ref,suggestions,...hint!==void 0?{hint}:{}}),invalidPath=(reason,path,hint)=>({kind:"InvalidPath",reason,...path!==void 0?{path}:{},...hint!==void 0?{hint}:{}}),invalidMove=(reason)=>({kind:"InvalidMove",reason}),lastScreen=(screenId)=>({kind:"LastScreen",screenId}),screenIdConflict=(screenId)=>({kind:"ScreenIdConflict",screenId,hint:`Screen "${screenId}" already exists (a route-scan may have scaffolded it as a placeholder). Build into it instead with compose { screenId: "${screenId}", mode: "replace", jsx: \u2026 }. `+"To replace the screen resource itself, remove_screen then add_screen. To create a separate screen, omit `id` (add_screen auto-suffixes a unique one)."}),screenIdExhausted=(base)=>({kind:"ScreenIdExhausted",base}),boardIdConflict=(boardId)=>({kind:"BoardIdConflict",boardId}),boardIdExhausted=(base)=>({kind:"BoardIdExhausted",base}),frameIdConflict=(boardId,frameId)=>({kind:"FrameIdConflict",boardId,frameId}),badRequest=(message,issues)=>{let hint=scalarChildrenHint(issues);return{kind:"BadRequest",message,...issues!==void 0?{issues}:{},...hint!==void 0?{hint}:{}}};function scalarChildrenHint(issues){return hasScalarChildrenIssue(issues)?'Node-level `children` must be an array of nodes. For scalar text, use `props.children` (e.g. props: { children: "Save" }) \u2014 or wrap it: children: ["Save"].':void 0}function hasScalarChildrenIssue(issues){if(!Array.isArray(issues))return!1;return issues.some((issue)=>{if(typeof issue!=="object"||issue===null)return!1;let i=issue;if(i.code==="invalid_type"&&i.expected==="array"&&Array.isArray(i.path)&&i.path.at(-1)==="children")return!0;return Array.isArray(i.errors)&&i.errors.some((branch)=>hasScalarChildrenIssue(branch))})}var snippetNotFound=(snippetId)=>({kind:"SnippetNotFound",snippetId}),snippetParamMismatch=(snippetId,reason,details)=>({kind:"SnippetParamMismatch",snippetId,reason,...details!==void 0?{details}:{}}),snippetCycle=(snippetId,viaPath)=>({kind:"SnippetCycle",snippetId,viaPath}),snippetInUse=(snippetId,screenIds,snippetIds)=>({kind:"SnippetInUse",snippetId,screenIds,snippetIds}),snippetIdConflict=(snippetId)=>({kind:"SnippetIdConflict",snippetId}),idNotFound=(screenId,id,hint)=>({kind:"IdNotFound",screenId,id,...hint!==void 0?{hint}:{}}),idConflict=(screenId,id,paths)=>({kind:"IdConflict",screenId,id,paths}),annotationConflict=(screenId,locator,existingId)=>({kind:"AnnotationConflict",screenId,locator,existingId}),annotationNotFound=(screenId,annotationId)=>({kind:"AnnotationNotFound",screenId,annotationId}),canvasNoteNotFound=(noteId)=>({kind:"CanvasNoteNotFound",noteId}),extensionIdConflict=(extensionId)=>({kind:"ExtensionIdConflict",message:`Extension "${extensionId}" already exists. Use update_extension to patch it.`,extensionId}),extensionNotFound=(extensionId)=>({kind:"ExtensionNotFound",message:`Extension "${extensionId}" doesn't exist.`,extensionId}),extensionInUse=(extensionId,references)=>({kind:"ExtensionInUse",message:`Extension "${extensionId}" is referenced by ${references.length} node${references.length===1?"":"s"} \u2014 remove the usages first.`,extensionId,references});function levenshtein(a,b){let al=a.length,bl=b.length;if(al===0)return bl;if(bl===0)return al;let dp=Array(bl+1);for(let j=0;j<=bl;j++)dp[j]=j;for(let i=1;i<=al;i++){let prev=i-1;dp[0]=i;for(let j=1;j<=bl;j++){let tmp=dp[j]??0,cost=a[i-1]===b[j-1]?0:1;dp[j]=Math.min((dp[j]??0)+1,(dp[j-1]??0)+1,prev+cost),prev=tmp}}return dp[bl]??0}var normalizeRef=(s)=>s.toLowerCase().replace(/[^a-z0-9]/g,"");function nearestRefs(target,refs,n=3){let t=normalizeRef(target);return refs.map((r)=>({r,d:levenshtein(t,normalizeRef(r))})).sort((a,b)=>a.d-b.d).slice(0,n).map((x)=>x.r)}var SNIPPET_TREE_PREFIX="snippet:";function isSnippetTreeId(screenId){return screenId.startsWith(SNIPPET_TREE_PREFIX)}function snippetIdFromTreeId(screenId){return screenId.slice(SNIPPET_TREE_PREFIX.length)}function getScreen(ctx,screenId){if(isSnippetTreeId(screenId)){let snippetId=snippetIdFromTreeId(screenId),snippet=ctx.folder.snippets.get(snippetId);if(!snippet)return err(snippetNotFound(snippetId));return ok({id:screenId,name:snippet.name,tree:snippet.tree})}let s=ctx.folder.screens.get(screenId);return s?ok(s):err(screenNotFound(screenId))}function getBoard(ctx,boardId){let b=ctx.folder.boards.get(boardId);return b?ok(b):err(boardNotFound(boardId))}function resolve9(root,locator,screenId){let path=resolveLocator(root,locator);if(path!==null)return ok(path);if(isIdLocator(locator)){let id=locator.slice(1);return err(idNotFound(screenId,id,id==="root"?'There is no node with id "root". The root node is the empty path []; tools like screenshot/compare_to_url treat the whole screen as the default when `path` is omitted.':void 0))}return err(invalidPath(`No node at path ${JSON.stringify(locator)}`,locator,'Numeric paths go stale after siblings are added, removed, or moved. Re-locate the node with find_nodes (it returns current paths + ids), or give it a stable @id via set_node_id and address it as "@id".'))}function subtreeHasId(node,id){if(!isComponentNode(node))return!1;if(node.$id===id)return!0;return(node.children??[]).some((c)=>subtreeHasId(c,id))}function findInstanceExposingId(ctx,root,id){let hit=null;function walk(node,path){if(hit)return;if(isSnippetInstance(node)){let def=ctx.folder.snippets.get(node.$snippet);if(def&&subtreeHasId(def.tree,id))hit={instanceLocator:node.$id?`@${node.$id}`:JSON.stringify(path),snippetId:node.$snippet};return}if(!isComponentNode(node))return;let kids=node.children??[];for(let i=0;i<kids.length&&!hit;i++){let child=kids[i];if(child)walk(child,[...path,i])}}return walk(root,[]),hit}function resolveWithSnippetHint(ctx,root,locator,screenId){let r=resolve9(root,locator,screenId);if(r.ok||r.error.kind!=="IdNotFound")return r;let found=findInstanceExposingId(ctx,root,r.error.id);if(!found)return r;let hint=`"${r.error.id}" isn't a top-level node, but a node with that id lives inside snippet instance ${found.instanceLocator} (snippet "${found.snippetId}"), which is opaque to @id addressing. To change its props for just this instance: update_snippet_instance { path: "${found.instanceLocator}", innerPath: "@${r.error.id}", propPatch: {\u2026} }. To change it across all instances, edit the snippet `+"body with update_snippet.";return err(idNotFound(screenId,r.error.id,hint))}function getNode(root,locator,screenId){let r=resolve9(root,locator,screenId);if(!r.ok)return r;let n=pathAt(root,r.value);return n?ok(n):err(invalidPath(`No node at path ${JSON.stringify(r.value)}`,r.value,"Numeric paths go stale after siblings change. Re-locate with find_nodes or address by stable @id."))}function getComponentNode(root,locator,screenId){let r=getNode(root,locator,screenId);if(!r.ok)return r;if(!isComponentNode(r.value)){let r2=resolve9(root,locator,screenId),path=r2.ok?r2.value:[];return err(invalidPath(`Node at ${JSON.stringify(path)} is not a component (got ${describe3(r.value)}). For snippet instances use update_snippet_instance.`,path))}return ok(r.value)}function describe3(node){if(isComponentNode(node))return`$ref=${node.$ref}`;if("$snippet"in node)return`$snippet=${node.$snippet}`;return`$param=${node.$param}`}function getExtensions(ctx){return ctx.folder.config.extensions??{}}function libraryIdForScreen(ctx,screen){let id=screen.library;if(id&&ctx.folder.config.libraries?.[id])return id;return ctx.folder.config.defaultLibrary}function providerForScreen2(ctx,screen){return providerForScreen(screen,ctx.providers,ctx.defaultProvider)}function registryForScreen2(ctx,screen){return registryForScreen(screen,ctx.providers,ctx.defaultProvider,getExtensions(ctx),ctx.folder.config.styling?.framework)}function renderPassForScreen2(ctx,screen,theme,dark=!1){return renderPassForScreen(screen,ctx.providers,ctx.defaultProvider,theme,dark)}function ensureKnownComponent(ctx,ref,screen=null){let provider=screen?providerForScreen2(ctx,screen):ctx.defaultProvider;if(ref in provider.registry)return ok(void 0);let extensions=getExtensions(ctx);if(ref in extensions)return ok(void 0);let snippetMatch=[...ctx.folder.snippets.keys()].find((s)=>normalizeRef(s)===normalizeRef(ref));if(snippetMatch)return err(unknownComponent2(ref,[],`"${ref}" is a snippet, not a library component. In MCP use compose with its PascalCase tag; lower-level callers must use a {"$snippet":"${snippetMatch}"} node. "$ref" is only for library components and registered extensions.`));let known=[...Object.keys(provider.registry),...Object.keys(extensions)];return err(unknownComponent2(ref,nearestRefs(ref,known)))}function getSnippet(ctx,snippetId){let s=ctx.folder.snippets?.get(snippetId);return s?ok(s):err(snippetNotFound(snippetId))}function playwrightMissingMessage(msg){return`screenshot: Playwright is not installed. Run \`${CHROMIUM_INSTALL_CMD}\`, then retry \u2014 no server restart needed. Underlying error: ${msg}`}function captureTimeoutMessage(err,op){if(!isCaptureTimeout(err))return null;let msg=err instanceof Error?err.message:"";if(!/screenshot|setContent/i.test(msg))return null;return`${op} timed out rendering the page (capped at 20s). This is almost always a one-off render `+"stall \u2014 a cold web-font fetch or a first heavy paint \u2014 so retry; it usually clears. If it "+"persists, the page has expensive CSS (a large repeating background, heavy blur/shadow) or is very tall: simplify the heavy styles, or capture a smaller region/viewport."}function browserErrorMessage(err){if(err instanceof Error&&err.name==="BrowserMissingError")return err.message;let msg=err instanceof Error?err.message:String(err);if(/Cannot find package 'playwright'|MODULE_NOT_FOUND|chromium/i.test(msg))return playwrightMissingMessage(msg.split(`
187
- `)[0]??msg);return null}function defaultViewport(folder){let presets=folder.config.viewportPresets,pick=presets.find((p)=>p.name.toLowerCase().includes("desktop"))??presets[0]??{w:1440,h:900};return{w:pick.w,h:pick.h}}function makeLiveUrl(ctx,bundler){return()=>Object.keys(liveExtensions(ctx.folder.config.extensions)).length>0?`/api/live/bundle.js?v=${bundler.version}`:void 0}async function screenMount(ctx,canvasBundler,screen){let refs=collectSerializedRefs(serializeTree(screen.tree,{snippets:ctx.folder.snippets}));if(refs.length===0)return{kind:"none"};let libraryId=libraryIdForScreen(ctx,screen);if(!canvasBundler.canMount(libraryId,refs))return{kind:"none"};let extensionIds=new Set(Object.keys(ctx.folder.config.extensions??{})),extensions=refs.filter((ref)=>extensionIds.has(ref));if(extensions.length>0)return{kind:"server",libraryId,reason:`it uses the extension${extensions.length===1?"":"s"} ${extensions.join(", ")}, which ${extensions.length===1?"has":"have"} no browser-canvas source`};let bundle=await canvasBundler.build(libraryId,refs);if(bundle.usable)return{kind:"mounted",libraryId,refs,bundle};let blocked=bundle.diagnostics.filter((entry)=>entry.status==="unavailable"),reason=blocked.length?`${blocked.map((entry)=>entry.id).join(", ")} ${blocked.length===1?"has":"have"} no source that compiles for the browser`:`the browser bundle failed to build: ${bundle.errors[0]?.message??"no components resolved"}`;return{kind:"server",libraryId,reason,bundle}}function blockingErrors(bundle){return(bundle?.diagnostics??[]).filter((entry)=>entry.status==="unavailable").map((entry)=>{let first=entry.errors?.[0]??entry.note??"no browser source";return`${entry.id}: ${first.length>300?`${first.slice(0,300)}\u2026`:first}`})}async function mountDiagnostics(ctx,canvasBundler,screen){let mount=await screenMount(ctx,canvasBundler,screen).catch(()=>{return});if(mount?.kind!=="server")return[];let errors=blockingErrors(mount.bundle);return[{severity:"warning",code:"render/server-fallback",path:[],message:`This screen renders server-side from Velloo's bundled components, not the app's own, because ${mount.reason}. `+"The browser mount is all-or-nothing, so every component on the screen falls back together \u2014 including ones component_status reports as exact."+(errors.length?` ${errors.join(" | ")}`:""),suggestion:"Fix what blocks the listed component (component_status { screen } has the full errors), or replace it; captures will then show the app's components."}]}function makeCanvasBundle(ctx,canvasBundler){return async(screen,theme,dark)=>{let mount=await screenMount(ctx,canvasBundler,screen);if(mount.kind!=="mounted")return;let provider=providerForScreen2(ctx,screen),hasRepo=mount.refs.some((ref)=>ref.startsWith("repo:"));return{url:`/api/canvas/bundle.js?v=${canvasBundler.version}&lib=${encodeURIComponent(mount.libraryId)}&refs=${encodeURIComponent(mount.refs.join(","))}`,themeOptions:provider.themeToNative?.(theme,dark)??null,...hasRepo&&ctx.repo?{preview:previewInput(ctx.repo,mount.refs,theme,dark)}:{},...mount.bundle.staticRefs?{staticRefs:mount.bundle.staticRefs}:{}}}}function previewInput(repo,refs,theme,dark){let apps=new Set(refs.filter((ref)=>ref.startsWith("repo:")).map((ref)=>parseRepoKey(ref)?.app)),recipeTheme={};for(let app of apps){let entry=repo.preview(app),recipe=entry.kind==="recipe"?entry.recipe:repo.recipes(app)[0];if(recipe)recipeTheme[app??""]=recipe.themeToNative(theme,dark)}return{colorScheme:dark?"dark":"light",theme,recipeTheme}}async function renderForCapture(ctx,screen,opts){let canvasOpt=await opts.canvasBundle(screen,opts.theme,opts.dark),{html}=await renderScreen(screen,opts.theme,{viewport:opts.viewport,snapshotCss:opts.snapshotCss,registry:registryForScreen2(ctx,screen),renderPass:renderPassForScreen2(ctx,screen,opts.theme,opts.dark),snippets:ctx.folder.snippets,customCss:ctx.folder.customCss,baseHref:opts.assetOrigin,liveBundleUrl:opts.liveUrl(),dark:opts.dark,...canvasOpt?{canvasBundle:canvasOpt}:{}});return html}function regionNode(region,rects,scaleFactor,screen){let area=region.w*region.h,best=rects.map((r)=>({path:r.path,x:r.x*scaleFactor,y:r.y*scaleFactor,w:r.w*scaleFactor,h:r.h*scaleFactor})).filter((r)=>{let ix=Math.max(0,Math.min(r.x+r.w,region.x+region.w)-Math.max(r.x,region.x)),iy=Math.max(0,Math.min(r.y+r.h,region.y+region.h)-Math.max(r.y,region.y));return ix*iy>=area*0.5}).sort((a,b)=>a.w*a.h-b.w*b.h)[0];if(!best)return null;let path=best.path===""?[]:best.path.split(".").map(Number),node=pathAt(screen.tree,path);if(!node)return{path};let id=nodeId(node);return{path,...isComponentNode(node)?{ref:node.$ref}:{},...id!==void 0?{id}:{}}}function contentHeightFromRects(rects){let max=0;for(let r of rects)max=Math.max(max,r.y+r.h);return Math.round(max)}function framesShorterThan(ctx,screenId,contentHeight,viewportW){let out=[];for(let board of ctx.folder.boards.values()){if(isArchived(board))continue;for(let frame of board.frames)if(frame.screen===screenId&&frame.w===viewportW&&frame.h<contentHeight)out.push({board:board.id,frame:frame.id,...frame.label?{label:frame.label}:{},frameHeight:frame.h,overflowBy:contentHeight-frame.h})}return out}function mountSummary(canvas){let repo=(canvas?.diagnostics??[]).filter((entry)=>entry.id.startsWith("repo:"));if(!canvas||repo.length===0)return;let fidelity={};for(let entry of repo)fidelity[entry.status]=(fidelity[entry.status]??0)+1;return{mounted:canvas.mounted,fidelity,notExact:repo.filter((entry)=>entry.status!=="exact").map((entry)=>({name:entry.name??entry.id,status:entry.status,...entry.code?{code:entry.code}:{},...entry.note?{note:entry.note}:{}}))}}function recordMount(canvasBundler,canvas){if(canvas?.bundle)canvasBundler.recordRuntime(canvas.bundle,canvas.diagnostics)}function createExportRouter(ctxFor,jit,bundler,canvasBundler){let r=new Hono2,pipeline=(c)=>{let ctx=ctxFor();return{folder:ctx.folder,providers:ctx.providers,defaultProvider:ctx.defaultProvider,snapshotCss:()=>jit.build(),assetOrigin:()=>{let host=c.req.header("host");return host?`http://${host}/`:void 0},liveBundleUrl:()=>Object.keys(liveExtensions(ctx.folder.config.extensions)).length>0?`/api/live/bundle.js?v=${bundler.version}`:void 0,canvasBundleFor:makeCanvasBundle(ctx,canvasBundler)}},parseTarget=(raw)=>{let m=/^(.+)\.(png|pdf|html)$/.exec(raw);return m?.[1]&&m[2]?{id:m[1],ext:m[2]}:null},parseOpts=(c)=>{let mode=c.req.query("mode")??"light";if(!["light","dark","compare"].includes(mode))return null;let scale=Math.min(3,Math.max(0.25,Number(c.req.query("scale"))||1)),theme=c.req.query("theme");return{mode,scale,...theme?{theme}:{}}},send=(c,body,ext,name,warnings=[])=>{let headers={"Content-Type":ext==="png"?"image/png":ext==="pdf"?"application/pdf":"text/html; charset=utf-8","Content-Disposition":`attachment; filename="${exportFilename(name,ext)}"`};if(warnings.length>0)headers["x-velloo-export-warnings"]=encodeURIComponent(JSON.stringify(warnings));return c.body(typeof body==="string"?body:new Uint8Array(body),200,headers)},failed=(c,err)=>{let message=err instanceof Error?err.message:String(err),missing=err instanceof Error&&err.name==="BrowserMissingError";return c.json({error:message},missing?503:500)};return r.get("/frame/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <frameId>.png|pdf|html"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark|compare"},400);let p=pipeline(c),found=findFrame(p.folder,target.id);if(!found)return c.json({error:`frame not found: ${target.id}`},404);if(opts.mode==="compare"&&target.ext!=="png")return c.json({error:'mode "compare" is PNG-only'},400);let screen=p.folder.screens.get(found.frame.screen),name=found.frame.label??screen?.name??target.id;try{if(target.ext==="png")return send(c,await exportFramePng(p,found.board,found.frame,opts),"png",name);if(target.ext==="pdf")return send(c,await exportFramePdf(p,found.board,found.frame,opts),"pdf",name);let out=await exportFrameHtml(p,found.board,found.frame,opts);return send(c,out.html,"html",name,out.warnings)}catch(err){return failed(c,err)}}),r.get("/board/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <boardId>.png|pdf|html"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark|compare"},400);if(opts.mode==="compare")return c.json({error:'mode "compare" is frame-only \u2014 export the board light or dark'},400);let p=pipeline(c),board=p.folder.boards.get(target.id);if(!board)return c.json({error:`board not found: ${target.id}`},404);try{if(target.ext==="png")return send(c,await exportBoardPng(p,board,opts),"png",board.name);if(target.ext==="pdf")return send(c,await exportBoardPdf(p,board,opts),"pdf",board.name);let out=await exportBoardHtml(p,board,opts);return send(c,out.html,"html",board.name,out.warnings)}catch(err){return failed(c,err)}}),r.get("/screen/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <screenId>.html"},400);if(target.ext!=="html")return c.json({error:"screen exports are HTML \u2014 export a frame for PNG/PDF"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark"},400);let p=pipeline(c),screen=p.folder.screens.get(target.id);if(!screen)return c.json({error:`screen not found: ${target.id}`},404);let preset=p.folder.config.viewportPresets[0]??{name:"default",w:1440,h:900},viewport={w:Number(c.req.query("w"))||preset.w,h:Number(c.req.query("h"))||preset.h};try{let out=await exportScreenHtml(p,screen,{dark:opts.mode==="dark",...opts.theme?{theme:opts.theme}:{},viewport});return send(c,out.html,"html",screen.name||screen.id,out.warnings)}catch(err){return failed(c,err)}}),r}import{randomUUID}from"crypto";import{rm as rm2}from"fs/promises";import{join as join23}from"path";function validateScreenIds(screenId,screen){let first=findDuplicateIds(screen.tree)[0];if(first)return err(idConflict(screenId,first.id,first.paths));return ok(void 0)}async function persistScreen(folder,screenId,screen,coalesceKey){let validated=ScreenSchema.parse(screen),prev=folder.screens.get(screenId)??null;return folder.history.push({kind:"screen",screenId,screen:prev,coalesceKey}),await writeJsonAtomic(join23(folder.root,"screens",`${screenId}.json`),validated),folder.screens.set(screenId,validated),validated}function commitScreen(folder,screenId,screen,coalesceKey){return DoAsync(async function*(){if(yield*$(validateScreenIds(screenId,screen)),isSnippetTreeId(screenId)){let snippetId=snippetIdFromTreeId(screenId),prev=folder.snippets.get(snippetId);if(!prev)return yield*$({ok:!1,error:snippetNotFound(snippetId)});let updated=await persistSnippet(folder,snippetId,{...prev,tree:screen.tree},coalesceKey);return{id:screenId,name:updated.name,tree:updated.tree}}return await persistScreen(folder,screenId,screen,coalesceKey)})}async function deletePersistedScreen(folder,screenId){let prev=folder.screens.get(screenId)??null;folder.history.push({kind:"screen",screenId,screen:prev}),await rm2(join23(folder.root,"screens",`${screenId}.json`),{force:!0}),await rm2(join23(folder.root,"screens",`${screenId}.annotations.json`),{force:!0}),folder.screens.delete(screenId),folder.annotations.delete(screenId)}async function persistBoard(folder,boardId,board){let validated=BoardSchema.parse(board),prev=folder.boards.get(boardId)??null;return folder.history.push({kind:"board",boardId,board:prev}),await writeJsonAtomic(join23(folder.root,"boards",`${boardId}.json`),validated),folder.boards.set(boardId,validated),validated}async function persistBoards(folder,writes){let validated=writes.map(({boardId,board})=>({boardId,board:BoardSchema.parse(board)}));folder.history.push({kind:"boards",boards:validated.map(({boardId})=>({boardId,board:folder.boards.get(boardId)??null}))});for(let{boardId,board}of validated)await writeJsonAtomic(join23(folder.root,"boards",`${boardId}.json`),board),folder.boards.set(boardId,board);return validated.map((v)=>v.board)}async function deletePersistedBoard(folder,boardId){let prev=folder.boards.get(boardId)??null;folder.history.push({kind:"board",boardId,board:prev}),await rm2(join23(folder.root,"boards",`${boardId}.json`),{force:!0}),await rm2(join23(folder.root,"boards",`${boardId}.notes.json`),{force:!0}),folder.boards.delete(boardId),folder.notes.delete(boardId)}async function persistTheme(folder,theme,coalesceKey){let validated=ThemeSchema.parse(theme);return folder.history.push({kind:"theme",themeName:"default",theme:folder.theme,...coalesceKey?{coalesceKey}:{}}),await writeJsonAtomic(join23(folder.root,"theme","default.json"),validated),folder.theme=validated,folder.themes.set("default",validated),validated}async function persistNamedTheme(folder,name,theme,coalesceKey){if(name==="default")return persistTheme(folder,theme,coalesceKey);let validated=ThemeSchema.parse({...theme,name});return folder.history.push({kind:"theme",themeName:name,theme:folder.themes.get(name)??null,...coalesceKey?{coalesceKey}:{}}),await writeJsonAtomic(join23(folder.root,"theme",`${name}.json`),validated),folder.themes.set(name,validated),validated}async function persistSnippet(folder,snippetId,snippet,coalesceKey){let validated=SnippetSchema.parse(snippet),prev=folder.snippets.get(snippetId)??null;return folder.history.push({kind:"snippet",snippetId,snippet:prev,coalesceKey}),await writeJsonAtomic(join23(folder.root,"snippets",`${snippetId}.json`),validated),folder.snippets.set(snippetId,validated),validated}async function deletePersistedSnippet(folder,snippetId){let prev=folder.snippets.get(snippetId);if(prev)folder.history.push({kind:"snippet",snippetId,snippet:prev});await rm2(join23(folder.root,"snippets",`${snippetId}.json`),{force:!0}),folder.snippets.delete(snippetId)}async function persistAnnotations(folder,screenId,annotations){let validated=annotations.map((a)=>AnnotationSchema.parse(a)),path=join23(folder.root,"screens",`${screenId}.annotations.json`);if(validated.length===0)await rm2(path,{force:!0});else await writeJsonAtomic(path,validated);return folder.annotations.set(screenId,validated),validated}async function persistConfig(folder,config){let validated=ConfigSchema.parse(config);return await writeJsonAtomic(join23(folder.root,".design","config.json"),validated),folder.config=validated,validated}async function persistCanvasNotes(folder,boardId,notes){let validated=notes.map((n)=>CanvasNoteSchema.parse(n)),path=join23(folder.root,"boards",`${boardId}.notes.json`);if(validated.length===0)await rm2(path,{force:!0});else await writeJsonAtomic(path,validated);return folder.notes.set(boardId,validated),validated}function newAnnotationId(){return`ann_${randomUUID().replace(/-/g,"").slice(0,8)}`}function sameTarget(treeRoot,a,b){let pa=resolveLocator(treeRoot,a),pb=resolveLocator(treeRoot,b);if(!pa||!pb)return!1;return JSON.stringify(pa)===JSON.stringify(pb)}async function addAnnotation(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId));yield*$(resolve9(screen.tree,args.target.locator,args.screenId));let existing=ctx.folder.annotations.get(args.screenId)??[];for(let a of existing)if(sameTarget(screen.tree,a.target.locator,args.target.locator))return yield*$(err(annotationConflict(args.screenId,args.target.locator,a.id)));let annotation={id:newAnnotationId(),target:args.target,position:args.position??"auto",body:args.body,...args.collapsed!==void 0?{collapsed:args.collapsed}:{},author:args.author??"user"},next=[...existing,annotation];return await persistAnnotations(ctx.folder,args.screenId,next),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{annotation}})}async function updateAnnotation(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.annotations.get(args.screenId);if(!existing)return yield*$(err(ctx.folder.screens.has(args.screenId)?annotationNotFound(args.screenId,args.annotationId):screenNotFound(args.screenId)));let idx=existing.findIndex((a)=>a.id===args.annotationId);if(idx===-1)return yield*$(err(annotationNotFound(args.screenId,args.annotationId)));let next={...existing[idx],...args.patch.body!==void 0?{body:args.patch.body}:{},...args.patch.position!==void 0?{position:args.patch.position}:{}};if(args.patch.collapsed===null)delete next.collapsed;else if(args.patch.collapsed!==void 0)next.collapsed=args.patch.collapsed;let updated=[...existing];return updated[idx]=next,await persistAnnotations(ctx.folder,args.screenId,updated),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{annotation:next}})}async function removeAnnotation(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.annotations.get(args.screenId);if(!existing)return yield*$(err(ctx.folder.screens.has(args.screenId)?annotationNotFound(args.screenId,args.annotationId):screenNotFound(args.screenId)));if(!existing.some((a)=>a.id===args.annotationId))return yield*$(err(annotationNotFound(args.screenId,args.annotationId)));let next=existing.filter((a)=>a.id!==args.annotationId);return await persistAnnotations(ctx.folder,args.screenId,next),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{removedId:args.annotationId}})}import{randomUUID as randomUUID2}from"crypto";function newNoteId(){return`note_${randomUUID2().replace(/-/g,"").slice(0,8)}`}var DEFAULT_NOTE_WIDTH=240;function checkAttachment(ctx,board,attachment){let frame=board.frames.find((f)=>f.id===attachment.frameId);if(!frame)return err(frameNotFound(board.id,attachment.frameId));if(frame.screen!==attachment.screenId)return err(invalidPath(`Frame "${attachment.frameId}" shows screen "${frame.screen}", not "${attachment.screenId}"`));let screen=getScreen(ctx,attachment.screenId);if(!screen.ok)return screen;let resolved=resolve9(screen.value.tree,attachment.locator,attachment.screenId);return resolved.ok?ok(void 0):resolved}async function addNote(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(args.attachment)yield*$(checkAttachment(ctx,board,args.attachment));else if(args.x===void 0||args.y===void 0)return yield*$(err(invalidPath("A note without an attachment needs x and y")));let note={id:newNoteId(),...args.x!==void 0?{x:args.x}:{},...args.y!==void 0?{y:args.y}:{},width:args.width??DEFAULT_NOTE_WIDTH,body:args.body,...args.attachment?{attachment:args.attachment}:{}},existing=ctx.folder.notes.get(args.boardId)??[];return await persistCanvasNotes(ctx.folder,args.boardId,[...existing,note]),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{note}})}async function updateNote(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.notes.get(args.boardId)??[],idx=existing.findIndex((n)=>n.id===args.noteId);if(idx===-1)return yield*$(err(canvasNoteNotFound(args.noteId)));let next={...existing[idx],...args.patch.x!==void 0?{x:args.patch.x}:{},...args.patch.y!==void 0?{y:args.patch.y}:{},...args.patch.width!==void 0?{width:args.patch.width}:{},...args.patch.body!==void 0?{body:args.patch.body}:{}},updated=[...existing];return updated[idx]=next,await persistCanvasNotes(ctx.folder,args.boardId,updated),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{note:next}})}async function removeNote(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.notes.get(args.boardId)??[];if(!existing.some((n)=>n.id===args.noteId))return yield*$(err(canvasNoteNotFound(args.noteId)));let next=existing.filter((n)=>n.id!==args.noteId);return await persistCanvasNotes(ctx.folder,args.boardId,next),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{removedId:args.noteId}})}function createLockMap(){let chains=new Map;return{run(key,fn){let next=(chains.get(key)??Promise.resolve()).then(fn,fn),tail=next.then(()=>{return},()=>{return});return chains.set(key,tail),tail.then(()=>{if(chains.get(key)===tail)chains.delete(key)}),next},get size(){return chains.size}}}function broadcastTreeChange(ctx,screenId){if(isSnippetTreeId(screenId))ctx.broadcast({type:"snippet-changed",snippetId:snippetIdFromTreeId(screenId)});else ctx.broadcast({type:"screen-changed",screenId})}var locks=createLockMap(),lockKey=(folder,kind,id)=>`${folder.root}\x00${kind}\x00${id}`;function withScreenLock(folder,screenId,fn){if(isSnippetTreeId(screenId))return locks.run(lockKey(folder,"snippet",snippetIdFromTreeId(screenId)),fn);return locks.run(lockKey(folder,"screen",screenId),fn)}function withSnippetLock(folder,snippetId,fn){return locks.run(lockKey(folder,"snippet",snippetId),fn)}function withConfigLock(folder,fn){return locks.run(lockKey(folder,"config","config"),fn)}function withBoardLock(folder,boardId,fn){return locks.run(lockKey(folder,"board",boardId),fn)}function withBoardLocks(folder,boardIds,fn){let[head,...rest]=[...new Set(boardIds)].sort();if(head===void 0)return fn();return withBoardLock(folder,head,()=>withBoardLocks(folder,rest,fn))}function addAnnotation2(ctx,args){return tracked(ctx,"add_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>addAnnotation(ctx,args)))}function updateAnnotation2(ctx,args){return tracked(ctx,"update_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateAnnotation(ctx,args)))}function removeAnnotation2(ctx,args){return tracked(ctx,"remove_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeAnnotation(ctx,args)))}function addNote2(ctx,args){return tracked(ctx,"add_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>addNote(ctx,args)))}function updateNote2(ctx,args){return tracked(ctx,"update_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateNote(ctx,args)))}function removeNote2(ctx,args){return tracked(ctx,"remove_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeNote(ctx,args)))}function slugify(s,fallback){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||fallback}var MAX_GROUP_NAME_LENGTH=40,GROUP_COLORS=["#8b5cf6","#0ea5e9","#f59e0b","#f43f5e","#10b981","#6366f1","#ec4899","#84cc16"];function nextGroupColor(existing){let used=new Set(existing.map((g)=>g.color));return GROUP_COLORS.find((c)=>!used.has(c))??GROUP_COLORS[existing.length%8]}function boardGroups(config){return config.boardGroups??[]}function nameTooLong(name){if(name.length<=MAX_GROUP_NAME_LENGTH)return null;return badRequest(`group name too long (${name.length} chars) \u2014 max ${MAX_GROUP_NAME_LENGTH} characters`)}function uniqueGroupId(groups,base){let id=base,attempt=2;while(groups.some((g)=>g.id===id))id=`${base}-${attempt++}`;return id}function resolveGroup(config,ref){let trimmed=ref.trim();if(trimmed.length===0)return err(badRequest("group name is empty"));let tooLong=nameTooLong(trimmed);if(tooLong)return err(tooLong);let groups=boardGroups(config),match=groups.find((g)=>g.id===trimmed)??groups.find((g)=>g.name.toLowerCase()===trimmed.toLowerCase());if(match)return ok({config,groupId:match.id});let group={id:uniqueGroupId(groups,slugify(trimmed,"group")),name:trimmed,color:nextGroupColor(groups)};return ok({config:{...config,boardGroups:[...groups,group]},groupId:group.id})}async function addBoardGroup(ctx,args){return DoAsync(async function*(){let name=args.name.trim();if(name.length===0)return yield*$(err(badRequest("group name is empty")));let tooLong=nameTooLong(name);if(tooLong)return yield*$(err(tooLong));let groups=boardGroups(ctx.folder.config),group={id:uniqueGroupId(groups,slugify(name,"group")),name,color:args.color??nextGroupColor(groups)};return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:[...groups,group]}),ctx.broadcast({type:"config-changed"}),{group}})}async function updateBoardGroup(ctx,args){return DoAsync(async function*(){let groups=boardGroups(ctx.folder.config),current=groups.find((g)=>g.id===args.groupId);if(!current)return yield*$(err(boardGroupNotFound(args.groupId)));let next={...current};if(args.patch.name!==void 0){let name=args.patch.name.trim();if(name.length===0)return yield*$(err(badRequest("group name is empty")));let tooLong=nameTooLong(name);if(tooLong)return yield*$(err(tooLong));next.name=name}if(args.patch.color!==void 0)if(args.patch.color===null)delete next.color;else next.color=args.patch.color;return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:groups.map((g)=>g.id===args.groupId?next:g)}),ctx.broadcast({type:"config-changed"}),{group:next}})}async function removeBoardGroup(ctx,args){return DoAsync(async function*(){let groups=boardGroups(ctx.folder.config);if(!groups.some((g)=>g.id===args.groupId))return yield*$(err(boardGroupNotFound(args.groupId)));let ungroupedBoardIds=[];for(let[boardId,board]of ctx.folder.boards){if(board.group!==args.groupId)continue;let{group:_group,...rest}=board;await persistBoard(ctx.folder,boardId,rest),ungroupedBoardIds.push(boardId)}let remaining=groups.filter((g)=>g.id!==args.groupId);await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:remaining.length>0?remaining:void 0});for(let boardId of ungroupedBoardIds)ctx.broadcast({type:"board-changed",boardId});return ctx.broadcast({type:"config-changed"}),{removedGroupId:args.groupId,ungroupedBoardIds}})}async function reorderBoardGroups(ctx,args){let groups=boardGroups(ctx.folder.config),seen=new Set,next=[];for(let id of args.order){let group=groups.find((g)=>g.id===id);if(group&&!seen.has(id))next.push(group),seen.add(id)}for(let group of groups)if(!seen.has(group.id))next.push(group);return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:next}),ctx.broadcast({type:"config-changed"}),ok({order:next.map((g)=>g.id)})}function addBoardGroup2(ctx,args){return tracked(ctx,"add_board_group",{},()=>addBoardGroup(ctx,args))}function updateBoardGroup2(ctx,args){return tracked(ctx,"update_board_group",{},()=>updateBoardGroup(ctx,args))}function removeBoardGroup2(ctx,args){return tracked(ctx,"remove_board_group",{},()=>removeBoardGroup(ctx,args))}function reorderBoardGroups2(ctx,args){return tracked(ctx,"reorder_board_groups",{},()=>reorderBoardGroups(ctx,args))}function screensPlacedOnlyOn(folder,boardId){let board=folder.boards.get(boardId);if(!board)return[];let elsewhere=new Set;for(let[otherId,other]of folder.boards){if(otherId===boardId)continue;for(let frame of other.frames)elsewhere.add(frame.screen)}let only=new Set;for(let frame of board.frames){if(elsewhere.has(frame.screen))continue;if(!folder.screens.has(frame.screen))continue;only.add(frame.screen)}return[...only]}function boardNameTooLong(name){if(name.length<=MAX_BOARD_NAME_LENGTH)return null;return badRequest(`board name too long (${name.length} chars) \u2014 max ${MAX_BOARD_NAME_LENGTH} characters`)}async function addBoard(ctx,args){return DoAsync(async function*(){let tooLong=boardNameTooLong(args.name);if(tooLong)return yield*$(err(tooLong));let baseId=args.id??slugify(args.name,"board");if(args.id!==void 0&&ctx.folder.boards.has(args.id))return yield*$(err(boardIdConflict(args.id)));let boardId=baseId,attempt=2;while(ctx.folder.boards.has(boardId))if(boardId=`${baseId}-${attempt++}`,attempt>100)return yield*$(err(boardIdExhausted(baseId)));let groupId;if(args.group!==void 0){let resolved=yield*$(resolveGroup(ctx.folder.config,args.group));if(groupId=resolved.groupId,resolved.config!==ctx.folder.config)await persistConfig(ctx.folder,resolved.config),ctx.broadcast({type:"config-changed"})}let board={id:boardId,name:args.name,...groupId?{group:groupId}:{},frames:[],groups:[]};return await persistBoard(ctx.folder,boardId,board),ctx.broadcast({type:"board-changed",boardId}),{boardId,board}})}async function updateBoard(ctx,args){return DoAsync(async function*(){if(args.patch.name!==void 0){let tooLong=boardNameTooLong(args.patch.name);if(tooLong)return yield*$(err(tooLong))}let next={...yield*$(getBoard(ctx,args.boardId))};if(args.patch.name!==void 0)next.name=args.patch.name;if(args.patch.theme!==void 0)if(args.patch.theme===null)delete next.theme;else next.theme=args.patch.theme;if(args.patch.group!==void 0)if(args.patch.group===null)delete next.group;else{let resolved=yield*$(resolveGroup(ctx.folder.config,args.patch.group));if(next.group=resolved.groupId,resolved.config!==ctx.folder.config)await persistConfig(ctx.folder,resolved.config),ctx.broadcast({type:"config-changed"})}if(args.patch.archived!==void 0)if(args.patch.archived)next.archivedAt=new Date().toISOString();else delete next.archivedAt;return await persistBoard(ctx.folder,args.boardId,next),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{board:next}})}async function reorderBoards(ctx,args){let seen=new Set,moved=[];for(let id of args.order)if(ctx.folder.boards.has(id)&&!seen.has(id))moved.push(id),seen.add(id);let current=orderedBoards(ctx.folder).map(([id])=>id),next=0,order=current.map((id)=>seen.has(id)?moved[next++]:id);for(let id of moved.slice(next))order.push(id);let nextConfig={...ctx.folder.config,boardOrder:order};return await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),ok({order})}async function removeBoard(ctx,args){return DoAsync(async function*(){yield*$(getBoard(ctx,args.boardId));let orphaned=screensPlacedOnlyOn(ctx.folder,args.boardId),strandedSnippets=snippetsStrandedByRemoving(ctx.folder,orphaned);await deletePersistedBoard(ctx.folder,args.boardId);for(let screenId of orphaned)await withScreenLock(ctx.folder,screenId,()=>deletePersistedScreen(ctx.folder,screenId)),ctx.broadcast({type:"screen-changed",screenId});for(let snippetId of strandedSnippets)await deletePersistedSnippet(ctx.folder,snippetId),ctx.broadcast({type:"snippet-changed",snippetId});let order=ctx.folder.config.boardOrder;if(order?.includes(args.boardId)){let pruned=order.filter((id)=>id!==args.boardId),nextConfig={...ctx.folder.config,boardOrder:pruned.length>0?pruned:void 0};await persistConfig(ctx.folder,nextConfig)}return ctx.broadcast({type:"board-changed",boardId:args.boardId}),{removedBoardId:args.boardId,removedScreenIds:orphaned,removedSnippetIds:strandedSnippets}})}function snippetsStrandedByRemoving(folder,screenIds){if(screenIds.length===0)return[];let going=new Set(screenIds),before=reachableSnippetIds(folder,folder.screens.values()),after=reachableSnippetIds(folder,[...folder.screens].filter(([id])=>!going.has(id)).map(([,screen])=>screen));return[...before].filter((id)=>!after.has(id)&&folder.snippets.has(id)).sort()}function addBoard2(ctx,args){return tracked(ctx,"add_board",(v)=>({boardId:v.boardId}),()=>addBoard(ctx,args))}function updateBoard2(ctx,args){return tracked(ctx,"update_board",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateBoard(ctx,args)))}function removeBoard2(ctx,args){return tracked(ctx,"remove_board",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeBoard(ctx,args)))}function reorderBoards2(ctx,args){return tracked(ctx,"reorder_boards",{},()=>reorderBoards(ctx,args))}async function commit(ctx,next){let saved=await persistConfig(ctx.folder,next);return ctx.broadcast({type:"config-changed"}),saved}async function updateViewportPresets(ctx,args){let parsed=ViewportPresetSchema.array().safeParse(args.presets);if(!parsed.success)return err(badRequest("Each viewport preset needs a name and positive w/h.",parsed.error.issues));let presets=parsed.data.map((p)=>({...p,name:p.name.trim()}));if(presets.length===0)return err(badRequest("A folder needs at least one viewport preset."));if(presets.some((p)=>p.name===""))return err(badRequest("A viewport preset needs a name."));let seen=new Set;for(let p of presets){let key=p.name.toLowerCase();if(seen.has(key))return err(badRequest(`Two viewport presets are both named "${p.name}".`));seen.add(key)}return await commit(ctx,{...ctx.folder.config,viewportPresets:presets}),ok({presets})}async function updateDefaults(ctx,args){let next={...ctx.folder.config};if(args.defaultBoard!==void 0)if(args.defaultBoard===null)delete next.defaultBoard;else{if(!ctx.folder.boards.has(args.defaultBoard))return err(boardNotFound(args.defaultBoard));next.defaultBoard=args.defaultBoard}if(args.defaultScreen!==void 0)if(args.defaultScreen===null)delete next.defaultScreen;else{if(!ctx.folder.screens.has(args.defaultScreen))return err(screenNotFound(args.defaultScreen));next.defaultScreen=args.defaultScreen}let saved=await commit(ctx,next);return ok({defaultBoard:saved.defaultBoard??null,defaultScreen:saved.defaultScreen??null})}async function updateDesignName(ctx,args){let name=args.name.trim(),previous=ctx.folder.config.name;if(name===previous)return ok({name});let conflict=await designRenameConflict(ctx.folder.root,name);if(conflict)return err(badRequest(conflict));let saved=await commit(ctx,{...ctx.folder.config,name});return await followDesignRename(ctx.folder.root,previous,name),ok({name:saved.name})}async function updateCodegen(ctx,args){let next={...ctx.folder.config};if(args.componentsAlias!==void 0){let alias=args.componentsAlias?.trim()??null;if(alias==="")return err(badRequest("The components alias can't be empty \u2014 clear it to use the default."));let codegen={...next.codegen,...alias===null?{}:{componentsAlias:alias}};if(alias===null)delete codegen.componentsAlias;if(Object.keys(codegen).length===0)delete next.codegen;else next.codegen=codegen}let saved=await commit(ctx,next);return ok({componentsAlias:saved.codegen?.componentsAlias??null})}async function updateFeedback(ctx,args){let current=ctx.folder.config.feedback,contactOk=args.contactOk??await readFeedbackContactOk(),feedback={enabled:args.enabled??current?.enabled??!1,contactOk};if(args.contactOk!==void 0)await writeFeedbackContactOk(args.contactOk);if(await writeRepoFeedback(ctx.folder.root,feedback))return ctx.folder.config={...ctx.folder.config,feedback},ctx.broadcast({type:"config-changed"}),ok({enabled:feedback.enabled,contactOk:feedback.contactOk});let saved=await commit(ctx,{...ctx.folder.config,feedback:{enabled:feedback.enabled}});return ok({enabled:saved.feedback?.enabled??!1,contactOk:feedback.contactOk})}function updateViewportPresets2(ctx,args){return tracked(ctx,"update_viewport_presets",{},()=>withConfigLock(ctx.folder,()=>updateViewportPresets(ctx,args)))}function updateDefaults2(ctx,args){return tracked(ctx,"update_defaults",{},()=>withConfigLock(ctx.folder,()=>updateDefaults(ctx,args)))}function updateDesignName2(ctx,args){return tracked(ctx,"update_design_name",{},()=>withConfigLock(ctx.folder,()=>updateDesignName(ctx,args)))}function updateCodegen2(ctx,args){return tracked(ctx,"update_codegen",{},()=>withConfigLock(ctx.folder,()=>updateCodegen(ctx,args)))}function updateFeedback2(ctx,args){return tracked(ctx,"update_feedback",{},()=>withConfigLock(ctx.folder,()=>updateFeedback(ctx,args)))}function autoPosition(frames){if(frames.length===0)return{x:0,y:0};let maxRight=0;for(let f of frames)if(f.x+f.w>maxRight)maxRight=f.x+f.w;return{x:maxRight+80,y:0}}function genFrameId(board,screenId){let existing=new Set(board.frames.map((f)=>f.id)),i=1;while(existing.has(`${screenId}-${i}`))i++;return`${screenId}-${i}`}async function addFrame(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(yield*$(getScreen(ctx,args.screenId)),args.id!==void 0&&board.frames.some((f)=>f.id===args.id))return yield*$(err(frameIdConflict(args.boardId,args.id)));let id=args.id??genFrameId(board,args.screenId),pos=args.x!==void 0&&args.y!==void 0?{x:args.x,y:args.y}:autoPosition(board.frames),frame={id,screen:args.screenId,x:pos.x,y:pos.y,w:args.w,h:args.h,...args.label!==void 0?{label:args.label}:{},...args.group!==void 0?{group:args.group}:{}},nextBoard={...board,frames:[...board.frames,frame]};return await persistBoard(ctx.folder,args.boardId,nextBoard),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frame}})}async function moveFrame(ctx,args){return DoAsync(async function*(){let from=yield*$(getBoard(ctx,args.boardId)),to=yield*$(getBoard(ctx,args.toBoardId));if(args.boardId===args.toBoardId)return yield*$(err(invalidMove(`Frame "${args.frameId}" is already on board "${args.boardId}" \u2014 use update_frame to reposition it.`)));let frame=from.frames.find((f)=>f.id===args.frameId);if(!frame)return yield*$(err(frameNotFound(args.boardId,args.frameId)));let pos=args.x!==void 0&&args.y!==void 0?{x:args.x,y:args.y}:autoPosition(to.frames),taken=to.frames.some((f)=>f.id===frame.id),{group:_dropped,...carried}=frame,moved={...carried,id:taken?genFrameId(to,frame.screen):frame.id,x:pos.x,y:pos.y};return await persistBoards(ctx.folder,[{boardId:args.toBoardId,board:{...to,frames:[...to.frames,moved]}},{boardId:args.boardId,board:{...from,frames:from.frames.filter((f)=>f.id!==args.frameId)}}]),ctx.broadcast({type:"board-changed",boardId:args.toBoardId}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frame:moved,fromBoardId:args.boardId,toBoardId:args.toBoardId}})}async function removeFrame(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(board.frames.findIndex((f)=>f.id===args.frameId)===-1)return yield*$(err(frameNotFound(args.boardId,args.frameId)));let nextFrames=board.frames.filter((f)=>f.id!==args.frameId);return await persistBoard(ctx.folder,args.boardId,{...board,frames:nextFrames}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{removedFrameId:args.frameId}})}function applyPatch2(frame,patch){let next={...frame};if(patch.x!==void 0)next.x=patch.x;if(patch.y!==void 0)next.y=patch.y;if(patch.w!==void 0)next.w=patch.w;if(patch.h!==void 0)next.h=patch.h;if(patch.label!==void 0)if(patch.label===null)delete next.label;else next.label=patch.label;if(patch.group!==void 0)if(patch.group===null)delete next.group;else next.group=patch.group;if(patch.scheme!==void 0)if(patch.scheme===null)delete next.scheme;else next.scheme=patch.scheme;return next}async function updateFrames(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId)),nextFrames=[...board.frames];for(let{frameId,patch}of args.patches){let idx=nextFrames.findIndex((f)=>f.id===frameId);if(idx===-1)return yield*$(err(frameNotFound(args.boardId,frameId)));nextFrames[idx]=applyPatch2(nextFrames[idx],patch)}return await persistBoard(ctx.folder,args.boardId,{...board,frames:nextFrames}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frames:nextFrames}})}function addFrame2(ctx,args){return tracked(ctx,"add_frame",(v)=>({boardId:args.boardId,frameId:v.frame.id,screenId:v.frame.screen}),()=>withBoardLock(ctx.folder,args.boardId,()=>addFrame(ctx,args)))}function updateFrames2(ctx,args){return tracked(ctx,"update_frame",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateFrames(ctx,args)))}function removeFrame2(ctx,args){return tracked(ctx,"remove_frame",{boardId:args.boardId,frameId:args.frameId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeFrame(ctx,args)))}function moveFrame2(ctx,args){return tracked(ctx,"move_frame",(v)=>({boardId:v.toBoardId,frameId:v.frame.id,screenId:v.frame.screen}),()=>withBoardLocks(ctx.folder,[args.boardId,args.toBoardId],()=>moveFrame(ctx,args)))}var import_react4=__toESM(require_react_development(),1);function findNodeById(root,id){if(!isComponentNode(root))return;if(root.$id===id)return root;for(let child of root.children??[]){let hit=findNodeById(child,id);if(hit)return hit}return}function innerPathResolves(body,innerPath){if(innerPath.startsWith("@"))return findNodeById(body,innerPath.slice(1))!==void 0;let segments=innerPath===""?[]:innerPath.split(".").map(Number),cursor=body;for(let i of segments){if(!cursor||!isComponentNode(cursor)||!cursor.children)return!1;cursor=cursor.children[i]}return cursor!==void 0&&isComponentNode(cursor)}function resolveInnerNode(body,innerPath,snippetId){let target;if(innerPath.startsWith("@"))target=findNodeById(body,innerPath.slice(1));else{let segments=innerPath===""?[]:innerPath.split(".").map(Number);target=body;for(let i of segments){if(!target||!isComponentNode(target)||!target.children){target=void 0;break}target=target.children[i]}}if(!target||!isComponentNode(target))return err(invalidPath(`innerPath "${innerPath}" doesn't resolve to a component inside snippet "${snippetId}"`));return ok(target)}var SUBJECT_REF="__vellooInspectSubject",SUBJECT_TAG="velloo-inspect-subject";function Subject({children}){return import_react4.createElement(SUBJECT_TAG,null,children)}function virtualScreen(screen,tree){return{id:`${screen.id}__inspect`,name:`${screen.name} inspect`,library:screen.library,tree}}function renderIsolated(ctx,screen,node){let subScreen=virtualScreen(screen,node);return renderBodyGuarded(subScreen,registryForScreen2(ctx,subScreen),ctx.folder.snippets)}function markSubject(root,path){if(path.length===0)return{$ref:SUBJECT_REF,children:[root]};if(!isComponentNode(root))return null;let[index,...rest]=path,children=root.children;if(index===void 0||!children)return null;let child=children[index];if(!child)return null;let marked=markSubject(child,rest);if(!marked)return null;let next=[...children];return next[index]=marked,{...root,children:next}}function subjectMarkup(html){let open=`<${SUBJECT_TAG}>`,start=html.indexOf(open);if(start===-1)return null;let end=html.indexOf(`</${SUBJECT_TAG}>`,start);return end===-1?null:html.slice(start+open.length,end)}function renderInPlace(ctx,screen,root,path){let marked=markSubject(root,path);if(!marked)return null;let subScreen=virtualScreen(screen,marked),registry={...registryForScreen2(ctx,subScreen),[SUBJECT_REF]:Subject},{html}=renderBodyGuarded(subScreen,registry,ctx.folder.snippets);return subjectMarkup(html)}function inspectComponent(ctx,screen,node,site,note){let isolated=renderIsolated(ctx,screen,node),bodyHtml=isolated.failures.length>0?renderInPlace(ctx,screen,site.root,site.path)??isolated.html:isolated.html,className=node.props?.className??"",classes=typeof className==="string"?className.trim().split(/\s+/).filter(Boolean):[];return{ref:node.$ref,resolvedProps:{...node.props??{}},classes,bodyHtml,...note?{note}:{}}}async function inspect(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),node=yield*$(getNode(screen.tree,args.path,args.screenId));if(isSnippetInstance(node)){let snippet=ctx.folder.snippets.get(node.$snippet);if(!snippet)return yield*$(err(snippetNotFound(node.$snippet)));let innerPath=args.innerPath??"",body=resolveSnippetBody(node,snippet),inner=yield*$(resolveInnerNode(body,innerPath,node.$snippet)),note=innerPath===""?`Node is the body root of snippet instance "${node.$snippet}". Pass innerPath ("@id" or a dotted index like "0.2") to inspect a deeper node inside the body.`:`Node is inside snippet instance "${node.$snippet}" at innerPath "${innerPath}".`,innerSite=resolveLocator(body,innerPath===""?[]:innerPath)??[];return inspectComponent(ctx,screen,inner,{root:body,path:innerSite},note)}if(args.innerPath!==void 0&&args.innerPath!=="")return yield*$(err(invalidPath(`innerPath "${args.innerPath}" was given but the node at ${JSON.stringify(args.path)} is not a snippet instance`)));if(!isComponentNode(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(args.path)} is not inspectable (expected a component or snippet instance)`)));let site=yield*$(resolve9(screen.tree,args.path,args.screenId));return inspectComponent(ctx,screen,node,{root:screen.tree,path:site},void 0)})}function inspect2(ctx,args){return inspect(ctx,args)}function cloneNode(n){return JSON.parse(JSON.stringify(n))}function cloneScreen(s){return JSON.parse(JSON.stringify(s))}async function addScreen(ctx,args){return DoAsync(async function*(){let baseId=args.id??slugify(args.name,"screen");if(args.id!==void 0&&ctx.folder.screens.has(args.id))return yield*$(err(screenIdConflict(args.id)));let screenId=baseId,attempt=2;while(ctx.folder.screens.has(screenId))if(screenId=`${baseId}-${attempt++}`,attempt>100)return yield*$(err(screenIdExhausted(baseId)));let tree;if(args.fromScreenId!==void 0){let src=yield*$(getScreen(ctx,args.fromScreenId));tree=cloneScreen(src).tree}else if(args.tree!==void 0)tree=cloneNode(args.tree);else tree={$ref:"Card",props:{className:"p-6"}};let screen={id:screenId,name:args.name,...args.route!==void 0?{route:args.route}:{},tree};return await persistScreen(ctx.folder,screenId,screen),ctx.broadcast({type:"screen-changed",screenId}),{screenId,screen}})}async function removeScreen(ctx,args){return DoAsync(async function*(){if(yield*$(getScreen(ctx,args.screenId)),ctx.folder.screens.size<=1)return yield*$(err(lastScreen(args.screenId)));let removedFrames=[];for(let[boardId,board]of ctx.folder.boards){let referencing=board.frames.filter((f)=>f.screen===args.screenId);if(referencing.length===0)continue;let nextBoard={...board,frames:board.frames.filter((f)=>f.screen!==args.screenId)};await persistBoard(ctx.folder,boardId,nextBoard),ctx.broadcast({type:"board-changed",boardId}),removedFrames.push({boardId,frameIds:referencing.map((f)=>f.id)})}return await deletePersistedScreen(ctx.folder,args.screenId),ctx.broadcast({type:"screen-changed",screenId:args.screenId}),{removedScreenId:args.screenId,removedFrames}})}async function setScreenTree(ctx,args){let{screenId}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),prevRef="$ref"in screen.tree?screen.tree.$ref:"(root)",next=cloneScreen(screen);return next.tree=cloneNode(args.tree),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{screenId,replacedRootRef:prevRef}})}async function updateScreen(ctx,args){return DoAsync(async function*(){if(isSnippetTreeId(args.screenId))return yield*$(err(badRequest(`${args.screenId} is a snippet body, not a screen \u2014 rename it with update_snippet.`)));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen);if(args.patch.name!==void 0)next.name=args.patch.name;if(args.patch.route===null)delete next.route;else if(args.patch.route!==void 0)next.route=args.patch.route;return await persistScreen(ctx.folder,args.screenId,next),ctx.broadcast({type:"screen-changed",screenId:args.screenId}),{screen:next}})}function addScreen2(ctx,args){return tracked(ctx,"add_screen",(v)=>({screenId:v.screenId}),()=>addScreen(ctx,args))}function removeScreen2(ctx,args){return tracked(ctx,"remove_screen",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeScreen(ctx,args)))}function updateScreen2(ctx,args){return tracked(ctx,"update_screen",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateScreen(ctx,args)))}function setScreenTree2(ctx,args){return tracked(ctx,"set_screen_tree",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>setScreenTree(ctx,args)))}var PARAM_TAG_REF="velloo:param-tag";async function resolveComponentRefs(ctx,value,scope){let walk=async(v)=>{if(v===null||typeof v!=="object")return ok(v);if(Array.isArray(v)){let out=[];for(let item of v){let r=await walk(item);if(!r.ok)return r;out.push(r.value)}return ok(out)}let record={...v},ref=record.$ref;if(typeof ref==="string"&&record.$repo===void 0&&ref!==PARAM_TAG_REF){let known=ensureKnownComponent(ctx,ref,scope);if(!known.ok){let entry=await appComponent(ctx,ref);if(!entry)return known;record.$ref=entry.name,record.$repo=entry.identity}}for(let[key,nested]of Object.entries(record)){if(key==="$repo")continue;let r=await walk(nested);if(!r.ok)return r;record[key]=r.value}return ok(record)},result=await walk(value);return result.ok?ok(result.value):err(result.error)}async function appComponent(ctx,name){if(!ctx.repo)return null;return(await ctx.repo.catalog().catch(()=>null))?.byId.get(name)??await ctx.repo.resolveName(name).catch(()=>null)}function detectSnippetCycle(root,rootId,registry){let stack=[rootId],visited=new Set([rootId]);function walk(node){if(isSnippetInstance(node)){let id=node.$snippet;if(visited.has(id))return[...stack,id];let inner=registry.get(id);if(!inner)return null;visited.add(id),stack.push(id);let found=walk(inner.tree);if(stack.pop(),visited.delete(id),found)return found;return null}if(node.children)for(let child of node.children){let found=walk(child);if(found)return found}return null}return walk(root)}async function addSnippet(ctx,args){let id=args.id??slugify(args.name,"snippet");if(ctx.folder.snippets.has(id))return err(snippetIdConflict(id));let checked=await resolveComponentRefs(ctx,{tree:args.tree,params:args.params??[]},null);if(!checked.ok)return err(checked.error);let snippet={id,name:args.name,params:checked.value.params,tree:checked.value.tree},registry=new Map(ctx.folder.snippets);registry.set(id,snippet);let cycle=detectSnippetCycle(snippet.tree,id,registry);if(cycle)return err(snippetCycle(id,cycle));let persisted=await persistSnippet(ctx.folder,id,snippet);return ctx.broadcast({type:"snippet-changed",snippetId:id}),ok({snippetId:id,snippet:persisted})}async function instantiateSnippet(ctx,args){return DoAsync(async function*(){let snippet=yield*$(getSnippet(ctx,args.snippetId));yield*$(validateArgs(snippet,args.args??{})),yield*$(validateOverrides(snippet,args.overrides));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolvedParent=yield*$(resolve9(next.tree,args.parentPath,args.screenId)),parent=yield*$(getComponentNode(next.tree,resolvedParent,args.screenId));if(!parent.children)parent.children=[];let idx=args.index??parent.children.length;if(idx<0||idx>parent.children.length)return yield*$(err(invalidPath(`index ${idx} out of range for parent with ${parent.children.length} children`,resolvedParent)));let node={$snippet:snippet.id,...args.id!==void 0?{$id:args.id}:{},...args.extraClassName&&args.extraClassName.trim()!==""?{$extraClassName:args.extraClassName.trim()}:{},...args.args&&Object.keys(args.args).length>0?{args:args.args}:{},...args.overrides&&Object.keys(args.overrides).length>0?{$overrides:args.overrides}:{}};return parent.children.splice(idx,0,node),yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:[...resolvedParent,idx]}})}function validateArgs(snippet,passed){let declared=new Set(snippet.params.map((p)=>p.name)),{missing}=resolveSnippetArgs(snippet,passed),extras=Object.keys(passed).filter((k)=>!declared.has(k));if(missing.length===0&&extras.length===0)return{ok:!0,value:void 0};let parts=[];if(missing.length>0)parts.push(`missing required: ${missing.join(", ")}`);if(extras.length>0)parts.push(`unknown: ${extras.join(", ")}`);return{ok:!1,error:snippetParamMismatch(snippet.id,parts.join("; "),{missing,extras})}}function validateOverrides(snippet,overrides){if(!overrides)return{ok:!0,value:void 0};let bad=Object.keys(overrides).filter((key)=>!innerPathResolves(snippet.tree,key));if(bad.length===0)return{ok:!0,value:void 0};return{ok:!1,error:invalidPath(`overrides target nodes not found in snippet "${snippet.id}": ${bad.join(", ")} \u2014 `+'each key must be the "@id" of a body node, a dotted index path like "0.2", or "" for the root')}}async function removeSnippet(ctx,args){return DoAsync(async function*(){yield*$(getSnippet(ctx,args.snippetId));let{screenIds,snippetIds}=snippetReferencers(ctx.folder,args.snippetId);if(screenIds.length>0||snippetIds.length>0)return yield*$(err(snippetInUse(args.snippetId,screenIds,snippetIds)));return await deletePersistedSnippet(ctx.folder,args.snippetId),ctx.broadcast({type:"snippet-changed",snippetId:args.snippetId}),{removedId:args.snippetId}})}async function updateSnippet(ctx,args){return DoAsync(async function*(){let prev=yield*$(getSnippet(ctx,args.snippetId)),{innerPatch}=args.patch,tree=args.patch.tree??prev.tree;if(innerPatch!==void 0){if(!/^$|^\d+(\.\d+)*$|^@[a-zA-Z][a-zA-Z0-9_-]*$/.test(innerPatch.innerPath))return yield*$(err(invalidPath('innerPath must be a dotted index path like "0.2", an "@id" of a body node, or "" for the root')));if(!innerPathResolves(tree,innerPatch.innerPath))return yield*$(err(invalidPath(`innerPath "${innerPatch.innerPath}" doesn't resolve to a component inside snippet "${args.snippetId}"`)));tree=applySnippetOverrides(tree,{[innerPatch.innerPath]:{props:innerPatch.propPatch}})}let treeChanged=args.patch.tree!==void 0||innerPatch!==void 0;if(treeChanged)tree=yield*$(await resolveComponentRefs(ctx,tree,prev));let params=args.patch.params===void 0?void 0:yield*$(await resolveComponentRefs(ctx,args.patch.params,prev)),next={...prev,...args.patch.name!==void 0?{name:args.patch.name}:{},...params!==void 0?{params}:{},...treeChanged?{tree}:{}};if(args.patch.tree!==void 0){let registry=new Map(ctx.folder.snippets);registry.set(next.id,next);let cycle=detectSnippetCycle(next.tree,next.id,registry);if(cycle)return yield*$(err(snippetCycle(next.id,cycle)))}let persisted=await persistSnippet(ctx.folder,next.id,next);return ctx.broadcast({type:"snippet-changed",snippetId:next.id}),{snippet:persisted}})}async function updateSnippetArgs(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=yield*$(getNode(next.tree,resolved,args.screenId));if(!isSnippetInstance(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(resolved)} is not a snippet instance.`,resolved)));let argPatch=yield*$(await resolveComponentRefs(ctx,args.argPatch,screen)),merged={...node.args??{}};for(let[k,v]of Object.entries(argPatch))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete node.args;else node.args=merged;if(args.extraClassName!==void 0)if(args.extraClassName===null||args.extraClassName.trim()==="")delete node.$extraClassName;else node.$extraClassName=args.extraClassName.trim();return yield*$(await commitScreen(ctx.folder,args.screenId,next,args.gesture)),broadcastTreeChange(ctx,args.screenId),{path:resolved}})}function addSnippet2(ctx,args){return tracked(ctx,"add_snippet",(v)=>({snippetId:v.snippetId}),()=>withSnippetLock(ctx.folder,args.id??args.name,()=>addSnippet(ctx,args)))}function updateSnippet2(ctx,args){return tracked(ctx,"update_snippet",{snippetId:args.snippetId},()=>withSnippetLock(ctx.folder,args.snippetId,()=>updateSnippet(ctx,args)))}function removeSnippet2(ctx,args){return tracked(ctx,"remove_snippet",{snippetId:args.snippetId},()=>withSnippetLock(ctx.folder,args.snippetId,()=>removeSnippet(ctx,args)))}function instantiateSnippet2(ctx,args){return tracked(ctx,"instantiate_snippet",(v)=>({screenId:args.screenId,path:v.path,snippetId:args.snippetId}),()=>withScreenLock(ctx.folder,args.screenId,()=>instantiateSnippet(ctx,args)))}function updateSnippetArgs2(ctx,args){return tracked(ctx,"update_snippet_args",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateSnippetArgs(ctx,args)))}async function resolveRepoRef(ctx,ref,explicit){if(explicit){let entry=await catalogEntry(ctx,(e)=>sameIdentity(e.identity,explicit));return{$ref:entry?.name??[explicit.exportName==="default"?ref:explicit.exportName,explicit.member].filter(Boolean).join("."),$repo:withProxy(explicit,entry)}}let entry=await catalogEntry(ctx,(e)=>e.id===ref);return entry?{$ref:entry.name,$repo:withProxy(entry.identity,entry)}:null}async function catalogEntry(ctx,match){if(!ctx.repo)return;try{return(await ctx.repo.catalog()).entries.find(match)}catch{return}}function sameIdentity(a,b){return a.importPath===b.importPath&&a.exportName===b.exportName&&(a.member??"")===(b.member??"")&&(a.app??"")===(b.app??"")}function withProxy(identity,entry){return entry?.proxy&&!identity.proxy?{...identity,proxy:entry.proxy}:identity}async function addNode(ctx,args){let{screenId,parentPath,componentRef}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),known=ensureKnownComponent(ctx,componentRef,screen),repoNode=args.repo||!known.ok?await resolveRepoRef(ctx,componentRef,args.repo):null;if(!repoNode)yield*$(known);let next=cloneScreen(screen),resolvedParent=yield*$(resolve9(next.tree,parentPath,screenId)),parent=yield*$(getComponentNode(next.tree,resolvedParent,screenId));if(!parent.children)parent.children=[];let idx=args.index??parent.children.length;if(idx<0||idx>parent.children.length)return yield*$(err(invalidPath(`index ${idx} out of range for parent with ${parent.children.length} children`,resolvedParent)));let newNode={$ref:repoNode?.$ref??componentRef,...repoNode?.$repo?{$repo:repoNode.$repo}:{},...args.id!==void 0?{$id:args.id}:{},...args.props?{props:args.props}:{},...args.children?{children:args.children}:{},...args.emitAs?{$emitAs:args.emitAs}:{}};return parent.children.splice(idx,0,newNode),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{path:[...resolvedParent,idx]}})}function channelForScreen(ctx,screen){return styleChannelOf(providerForScreen2(ctx,screen),ctx.folder.config.styling?.framework)}function validateStylePayload(channel,style){if(style===null)return ok(null);let wantsString=channel.kind==="tailwind-classname";if(wantsString&&typeof style!=="string")return err(badRequest(`\`style\` on the "${channel.kind}" channel expects a className string (got ${typeof style}).`));if(!wantsString&&(typeof style!=="object"||Array.isArray(style)))return err(badRequest(`\`style\` on the "${channel.kind}" channel expects an object of ${channel.prop} properties (got ${Array.isArray(style)?"array":typeof style}).`));return ok(null)}function applyStyleToProps(channel,props,style){let prop=channel.prop;if(style===null)return delete props[prop],props;if(typeof style==="string"){let trimmed=style.trim();if(trimmed==="")delete props[prop];else props[prop]=trimmed;return props}let current=props[prop],merged=current&&typeof current==="object"&&!Array.isArray(current)?{...current}:{};for(let[k,v]of Object.entries(style))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete props[prop];else props[prop]=merged;return props}function repoStyleChannel(accepted,style,ref){let props=accepted??["className","style"];if(style===null){let prop=props.find((name)=>["className","sx","style"].includes(name))??"style";return ok(STYLE_CHANNELS_BY_PROP[prop]??STYLE_CHANNELS.style)}if(typeof style==="string")return props.includes("className")?ok(STYLE_CHANNELS["tailwind-classname"]):err(badRequest(`${ref} takes no className; set its own props or \`style\` (${props.join(", ")||"none"}).`));if(props.includes("sx"))return ok(STYLE_CHANNELS.sx);if(props.includes("style"))return ok(STYLE_CHANNELS.style);return err(badRequest(`${ref} declares no style prop to take an object; set its own props instead.`))}var STYLE_CHANNELS_BY_PROP={className:STYLE_CHANNELS["tailwind-classname"],sx:STYLE_CHANNELS.sx,style:STYLE_CHANNELS.style};async function updateProps(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),screenChannel=channelForScreen(ctx,screen),catalog=ctx.repo?await ctx.repo.catalog().catch(()=>null):null,channelFor=(node,style)=>node.$repo?repoStyleChannel(catalog?.byKey.get(repoKey(node.$repo))?.styleProps,style,node.$ref):ok(screenChannel);for(let{path,style}of args.patches){if(style===void 0)continue;let located=resolveWithSnippetHint(ctx,screen.tree,path,args.screenId),target=located.ok?getComponentNode(screen.tree,located.value,args.screenId):null,channel=target?.ok?yield*$(channelFor(target.value,style)):screenChannel;yield*$(validateStylePayload(channel,style))}let next=cloneScreen(screen),paths=[];for(let{path,propPatch,style}of args.patches){let resolved=yield*$(resolveWithSnippetHint(ctx,next.tree,path,args.screenId)),node=yield*$(getComponentNode(next.tree,resolved,args.screenId)),channel=style===void 0?screenChannel:yield*$(channelFor(node,style)),checked=yield*$(await resolveComponentRefs(ctx,propPatch??{},screen)),merged={...node.props??{}};for(let[k,v]of Object.entries(checked))if(v===null)delete merged[k];else merged[k]=v;if(style!==void 0)applyStyleToProps(channel,merged,style);if(Object.keys(merged).length===0)delete node.props;else node.props=merged;paths.push(resolved)}return yield*$(await commitScreen(ctx.folder,args.screenId,next,args.gesture)),broadcastTreeChange(ctx,args.screenId),{paths}})}async function applyClasses(ctx,args){let className=args.classes.trim();return updateProps(ctx,{screenId:args.screenId,patches:[{path:args.path,propPatch:{className:className===""?null:className}}],gesture:args.gesture})}function isAncestor(ancestor,descendant){if(ancestor.length>=descendant.length)return!1;return ancestor.every((seg,i)=>descendant[i]===seg)}async function moveNode(ctx,args){let{screenId,fromPath,toParent}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),next=cloneScreen(screen),resolvedFrom=yield*$(resolve9(next.tree,fromPath,screenId)),resolvedTo=yield*$(resolve9(next.tree,toParent,screenId));if(resolvedFrom.length===0)return yield*$(err(invalidMove("Cannot move the screen root.")));if(isAncestor(resolvedFrom,resolvedTo)||JSON.stringify(resolvedFrom)===JSON.stringify(resolvedTo))return yield*$(err(invalidMove("Cannot move a node into itself or its descendant.")));let fromParentInfo=parentOf(resolvedFrom);if(!fromParentInfo)return yield*$(err(invalidPath("no parent",resolvedFrom)));let fromParent=pathAt(next.tree,fromParentInfo.parent);if(!fromParent||!isComponentNode(fromParent)||!fromParent.children)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolvedFrom)}`,resolvedFrom)));if(fromParentInfo.index>=fromParent.children.length)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolvedFrom)}`,resolvedFrom)));let[moved]=fromParent.children.splice(fromParentInfo.index,1);if(fromParent.children.length===0)delete fromParent.children;if(!moved)return yield*$(err(invalidPath("internal: detach lost node during move",resolvedFrom)));let adjustedToParent=resolvedTo,sameParent=JSON.stringify(fromParentInfo.parent)===JSON.stringify(resolvedTo),toIdx=args.toIndex??1/0;if(sameParent&&toIdx>fromParentInfo.index)toIdx=Math.max(0,toIdx-1);else if(resolvedTo.length>fromParentInfo.parent.length&&isAncestor(fromParentInfo.parent,resolvedTo)&&(resolvedTo[fromParentInfo.parent.length]??-1)>fromParentInfo.index)adjustedToParent=[...resolvedTo],adjustedToParent[fromParentInfo.parent.length]=adjustedToParent[fromParentInfo.parent.length]-1;let target=pathAt(next.tree,adjustedToParent);if(!target||!isComponentNode(target))return yield*$(err(invalidPath(`No parent at ${JSON.stringify(adjustedToParent)}`,adjustedToParent)));if(!target.children)target.children=[];if(toIdx=Math.min(toIdx,target.children.length),toIdx<0)toIdx=0;return target.children.splice(toIdx,0,moved),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{newPath:[...adjustedToParent,toIdx]}})}async function overrideSnippetProps(ctx,args){return DoAsync(async function*(){if(!/^$|^\d+(\.\d+)*$|^@[a-zA-Z][a-zA-Z0-9_-]*$/.test(args.innerPath))return yield*$(err(invalidPath('innerPath must be a dotted index path like "0.2", an "@id" of a node inside the body, or "" for the root')));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=pathAt(next.tree,resolved);if(!node||!isSnippetInstance(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(resolved)} is not a snippet instance`,resolved)));let instance=node,snippet=ctx.folder.snippets.get(instance.$snippet);if(!snippet)return yield*$(err(snippetNotFound(instance.$snippet)));if(!innerPathResolves(snippet.tree,args.innerPath))return yield*$(err(invalidPath(`innerPath "${args.innerPath}" doesn't resolve to a component inside snippet "${instance.$snippet}"`)));let overrides={...instance.$overrides??{}},merged={...overrides[args.innerPath]?.props??{}};for(let[k,v]of Object.entries(args.propPatch))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete overrides[args.innerPath];else overrides[args.innerPath]={props:merged};if(Object.keys(overrides).length===0)delete instance.$overrides;else instance.$overrides=overrides;return yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:resolved,innerPath:args.innerPath,overrides}})}async function removeNode(ctx,args){let{screenId,path}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,path,screenId));if(resolved.length===0){if(!isComponentNode(next.tree))return yield*$(err(invalidPath("Cannot remove the screen root.",resolved)));let cleared=next.tree.children?.length??0;return delete next.tree.children,yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{removedRef:`(cleared ${cleared} child node${cleared===1?"":"s"} of the screen root \u2014 the root itself remains)`}}let parentInfo=parentOf(resolved);if(!parentInfo)return yield*$(err(invalidPath("no parent",resolved)));let parent=pathAt(next.tree,parentInfo.parent);if(!parent||!isComponentNode(parent)||!parent.children)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolved)}`,resolved)));if(parentInfo.index>=parent.children.length)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolved)}`,resolved)));let[removed]=parent.children.splice(parentInfo.index,1);if(parent.children.length===0)delete parent.children;return yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{removedRef:describeRemoved(removed)}})}function describeRemoved(node){if(!node)return"?";if(isComponentNode(node))return node.$ref;if("$snippet"in node)return`@${node.$snippet}`;return`$param:${node.$param}`}async function setNodeId(ctx,args){if(args.id!==null){let parsed=NodeIdSchema.safeParse(args.id);if(!parsed.success)return{ok:!1,error:badRequest(`Invalid node id ${JSON.stringify(args.id)}`,parsed.error.issues)}}return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=yield*$(getNode(next.tree,resolved,args.screenId));if(!isComponentNode(node)&&!isSnippetInstance(node))return yield*$({ok:!1,error:invalidPath(`Node at ${JSON.stringify(resolved)} cannot carry an id (param refs are anonymous).`,resolved)});if(args.id===null)delete node.$id;else node.$id=args.id;return yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:resolved,id:args.id}})}function addNode2(ctx,args){return tracked(ctx,"add_node",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>addNode(ctx,args)))}function updateProps2(ctx,args){return tracked(ctx,"update_props",(v)=>({screenId:args.screenId,...v.paths[0]?{path:v.paths[0]}:{}}),()=>withScreenLock(ctx.folder,args.screenId,()=>updateProps(ctx,args)))}function moveNode2(ctx,args){return tracked(ctx,"move_node",(v)=>({screenId:args.screenId,path:v.newPath}),()=>withScreenLock(ctx.folder,args.screenId,()=>moveNode(ctx,args)))}function removeNode2(ctx,args){return tracked(ctx,"remove_node",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeNode(ctx,args)))}function applyClasses2(ctx,args){return tracked(ctx,"apply_classes",(v)=>({screenId:args.screenId,...v.paths[0]?{path:v.paths[0]}:{}}),()=>withScreenLock(ctx.folder,args.screenId,()=>applyClasses(ctx,args)))}function setNodeId2(ctx,args){return tracked(ctx,"set_node_id",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>setNodeId(ctx,args)))}function overrideSnippetProps2(ctx,args){return tracked(ctx,"override_snippet_props",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>overrideSnippetProps(ctx,args)))}function findExtensionReferences(ctx,extensionId){let out=[];function visit(node,screenId,path){if(isComponentNode(node)){if(node.$ref===extensionId)out.push({screenId,path:path.join(".")});if(node.children)for(let i=0;i<node.children.length;i++){let child=node.children[i];if(child)visit(child,screenId,[...path,i])}}}for(let[screenId,screen]of ctx.folder.screens)visit(screen.tree,screenId,[]);for(let[snippetId,snippet]of ctx.folder.snippets)visit(snippet.tree,`snippet:${snippetId}`,[]);return out}function unknownHostApp(ctx,app){if(!app)return null;let known=Object.keys(ctx.folder.config.hostApps??{});if(known.includes(app))return null;return{kind:"BadRequest",message:`app "${app}" is not a key of config.hostApps.`,hint:known.length?`Known apps: ${known.join(", ")}. Omit \`app\` to use the default host app.`:"This folder has no config.hostApps \u2014 omit `app` to use the default host app."}}async function addExtension(ctx,args){let existing=ctx.folder.config.extensions??{};if(args.id in existing)return err(extensionIdConflict(args.id));let badApp=unknownHostApp(ctx,args.app);if(badApp)return err(badApp);for(let p of args.props){let parsed=ExtensionPropDescriptorSchema.safeParse(p);if(!parsed.success)return err({kind:"InvalidExtensionProp",message:`Invalid extension prop schema: ${parsed.error.issues[0]?.message??"unknown"}`,extensionId:args.id,prop:p.name})}let extension=ExtensionSchema.parse({importPath:args.importPath,category:args.category,description:args.description,props:args.props,origin:"agent",render:args.render,app:args.app,fit:args.fit}),shadowed=args.id in ctx.defaultProvider.registry?args.id:void 0,nextConfig={...ctx.folder.config,extensions:{...existing,[args.id]:extension}};await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"add_extension",{extension:args.id});let result={id:args.id,extension};if(shadowed)result.shadowedLibraryComponent=shadowed;if(extension.render==="live"){let warning=resolveLiveImportWarning(ctx.folder.root,ctx.folder.config,args.importPath,extension.app);if(warning)result.liveResolveWarning=warning}return ok(result)}async function updateExtension(ctx,args){let existing=ctx.folder.config.extensions??{},prev=existing[args.id];if(!prev)return err(extensionNotFound(args.id));let badApp=unknownHostApp(ctx,args.patch.app);if(badApp)return err(badApp);if(args.patch.props)for(let p of args.patch.props){let parsed=ExtensionPropDescriptorSchema.safeParse(p);if(!parsed.success)return err({kind:"InvalidExtensionProp",message:`Invalid extension prop schema: ${parsed.error.issues[0]?.message??"unknown"}`,extensionId:args.id,prop:p.name})}let next=ExtensionSchema.parse({...prev,...args.patch.importPath!==void 0?{importPath:args.patch.importPath}:{},...args.patch.props!==void 0?{props:args.patch.props}:{},...args.patch.category!==void 0?{category:args.patch.category}:{},...args.patch.description!==void 0?{description:args.patch.description}:{},...args.patch.render!==void 0?{render:args.patch.render}:{},...args.patch.app!==void 0?{app:args.patch.app}:{},...args.patch.fit!==void 0?{fit:args.patch.fit}:{}}),nextConfig={...ctx.folder.config,extensions:{...existing,[args.id]:next}};await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"update_extension",{extension:args.id});let result={id:args.id,extension:next};if(next.render==="live"){let warning=resolveLiveImportWarning(ctx.folder.root,ctx.folder.config,next.importPath,next.app);if(warning)result.liveResolveWarning=warning}return ok(result)}async function removeExtension(ctx,args){let existing=ctx.folder.config.extensions??{};if(!(args.id in existing))return err(extensionNotFound(args.id));let refs=findExtensionReferences(ctx,args.id);if(refs.length>0)return err(extensionInUse(args.id,refs));let{[args.id]:_,...rest}=existing,extensions=Object.keys(rest).length>0?rest:void 0,nextConfig={...ctx.folder.config,extensions};return await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"remove_extension",{extension:args.id}),ok({id:args.id})}function summarize(node,path){if(isComponentNode(node)){let props=node.props??{},children=props.children;return{path,kind:"component",ref:node.$ref,...nodeId(node)?{id:nodeId(node)}:{},...typeof props.className==="string"?{className:props.className}:{},...typeof children==="string"?{textPreview:children.slice(0,80)}:{},childCount:node.children?.length??0}}if(isSnippetInstance(node))return{path,kind:"snippet",ref:node.$snippet,...nodeId(node)?{id:nodeId(node)}:{},childCount:0};return{path,kind:"param",childCount:0}}async function findNodes(ctx,args){let screenR=getScreen(ctx,args.screenId);if(!screenR.ok)return screenR;let limit=args.limit??50,matches=[],total=0;function consider(node,path){let props=isComponentNode(node)?node.props??{}:{};if(args.ref!==void 0&&(!isComponentNode(node)||node.$ref!==args.ref))return;if(args.snippetId!==void 0&&(!isSnippetInstance(node)||node.$snippet!==args.snippetId))return;if(args.id!==void 0&&nodeId(node)!==args.id)return;if(args.classContains!==void 0){let cls=props.className;if(typeof cls!=="string"||!cls.includes(args.classContains))return}if(args.prop!==void 0){if(!(args.prop in props))return;if(args.propValue!==void 0&&props[args.prop]!==args.propValue)return}if(total+=1,matches.length<limit)matches.push(summarize(node,path))}function walk(node,path){if(consider(node,path),isComponentNode(node)&&node.children)node.children.forEach((child,i)=>{walk(child,[...path,i])})}return walk(screenR.value.tree,[]),ok({matches,total})}async function updateSnippetInstance(ctx,plan){return DoAsync(async function*(){let applied=[],path;if(plan.args)path=(yield*$(await updateSnippetArgs2(ctx,plan.args))).path,applied.push("args");if(plan.override)path=(yield*$(await overrideSnippetProps2(ctx,plan.override))).path,applied.push("override");return{path:path??[],applied}})}var invalidColor=(reason,hint)=>({kind:"InvalidColor",reason,...hint!==void 0?{hint}:{}}),invalidThemePath=(reason,hint)=>({kind:"InvalidThemePath",reason,...hint!==void 0?{hint}:{}}),unknownPreset=(presetName,hint)=>({kind:"UnknownPreset",presetName,...hint!==void 0?{hint}:{}}),themeBadRequest=(message,issues)=>({kind:"BadRequest",message,...issues!==void 0?{issues}:{}});var MUTATION_STATUS={ScreenNotFound:404,BoardNotFound:404,FrameNotFound:404,BoardGroupNotFound:404,SnippetNotFound:404,IdNotFound:404,AnnotationNotFound:404,CanvasNoteNotFound:404,ExtensionNotFound:404,UnknownComponent:422,SnippetParamMismatch:422,SnippetCycle:422,InvalidExtensionProp:422,InvalidPath:400,InvalidMove:400,ScreenIdConflict:400,ScreenIdExhausted:400,BoardIdConflict:400,BoardIdExhausted:400,FrameIdConflict:400,SnippetIdConflict:400,BadRequest:400,LastScreen:409,SnippetInUse:409,IdConflict:409,AnnotationConflict:409,ExtensionIdConflict:409,ExtensionInUse:409},THEME_STATUS={UnknownPreset:404,InvalidColor:400,InvalidThemePath:400,BadRequest:400,BulkTokensInvalid:400};function mutationToHttp(c,error){return c.json({error},MUTATION_STATUS[error.kind])}function themeToHttp(c,error){return c.json({error},THEME_STATUS[error.kind])}async function readBody(c){try{return await c.req.json()}catch{return}}function makeBoundRoute(b){return function(schema,handler){return async(c)=>{let body=await readBody(c),parsed=schema.safeParse(body);if(!parsed.success)return b.toHttp(c,b.badRequest("Request body failed validation.",parsed.error.issues));let result=await withActor({source:"canvas"},()=>handler(parsed.data,b.ctxFor()));return result.ok?c.json(result.value):b.toHttp(c,result.error)}}}function makeRoute(ctxFor){return makeBoundRoute({ctxFor,badRequest,toHttp:mutationToHttp})}function makeThemeRoute(ctxFor){return makeBoundRoute({ctxFor,badRequest:themeBadRequest,toHttp:themeToHttp})}function createAnnotationsRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.get("/:screenId",(c)=>{let ctx=ctxFor(),screenId=c.req.param("screenId"),screen=ctx.folder.screens.get(screenId),list=(ctx.folder.annotations.get(screenId)??[]).map((a)=>{let resolved=screen?resolveLocator(screen.tree,a.target.locator):null;return{...a,resolved}});return c.json({annotations:list})}),r.post("/add",route(AddAnnotationBody,(a,ctx)=>addAnnotation2(ctx,a))),r.post("/update",route(UpdateAnnotationBody,(a,ctx)=>updateAnnotation2(ctx,a))),r.post("/remove",route(RemoveAnnotationBody,(a,ctx)=>removeAnnotation2(ctx,a))),r}function createNotesRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.get("/:boardId",(c)=>{let ctx=ctxFor(),boardId=c.req.param("boardId"),list=(ctx.folder.notes.get(boardId)??[]).map((note)=>{if(!note.attachment)return note;let screen=ctx.folder.screens.get(note.attachment.screenId),resolved=screen?resolveLocator(screen.tree,note.attachment.locator):null;return{...note,resolved}});return c.json({notes:list})}),r.post("/add",route(AddNoteBody,(a,ctx)=>addNote2(ctx,a))),r.post("/update",route(UpdateNoteBody,(a,ctx)=>updateNote2(ctx,a))),r.post("/remove",route(RemoveNoteBody,(a,ctx)=>removeNote2(ctx,a))),r}function createMutateRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.post("/update_props",route(UpdatePropsBody,(a,ctx)=>updateProps2(ctx,a))),r.post("/apply_classes",route(ApplyClassesBody,(a,ctx)=>applyClasses2(ctx,a))),r.post("/set_node_id",route(SetNodeIdBody,(a,ctx)=>setNodeId2(ctx,a))),r.post("/remove_node",route(RemoveNodeBody,(a,ctx)=>removeNode2(ctx,a))),r.post("/add_board",route(AddBoardBody,(a,ctx)=>addBoard2(ctx,a))),r.post("/update_board",route(UpdateBoardBody,(a,ctx)=>updateBoard2(ctx,a))),r.post("/remove_board",route(RemoveBoardBody,(a,ctx)=>removeBoard2(ctx,a))),r.post("/reorder_boards",route(ReorderBoardsBody,(a,ctx)=>reorderBoards2(ctx,a))),r.post("/add_board_group",route(AddBoardGroupBody,(a,ctx)=>addBoardGroup2(ctx,a))),r.post("/update_board_group",route(UpdateBoardGroupBody,(a,ctx)=>updateBoardGroup2(ctx,a))),r.post("/remove_board_group",route(RemoveBoardGroupBody,(a,ctx)=>removeBoardGroup2(ctx,a))),r.post("/reorder_board_groups",route(ReorderBoardGroupsBody,(a,ctx)=>reorderBoardGroups2(ctx,a))),r.post("/update_viewport_presets",route(UpdateViewportPresetsBody,(a,ctx)=>updateViewportPresets2(ctx,a))),r.post("/update_defaults",route(UpdateDefaultsBody,(a,ctx)=>updateDefaults2(ctx,a))),r.post("/update_design_name",route(UpdateDesignNameBody,(a,ctx)=>updateDesignName2(ctx,a))),r.post("/update_codegen",route(UpdateCodegenBody,(a,ctx)=>updateCodegen2(ctx,a))),r.post("/update_feedback",route(UpdateFeedbackBody,(a,ctx)=>updateFeedback2(ctx,a))),r.post("/add_frame",route(AddFrameBody,(a,ctx)=>addFrame2(ctx,a))),r.post("/update_frame",route(UpdateFrameBody,(a,ctx)=>updateFrames2(ctx,a))),r.post("/remove_frame",route(RemoveFrameBody,(a,ctx)=>removeFrame2(ctx,a))),r.post("/move_frame",route(MoveFrameBody,(a,ctx)=>moveFrame2(ctx,a))),r.post("/update_snippet",route(UpdateSnippetBody,(a,ctx)=>updateSnippet2(ctx,a))),r.post("/update_snippet_args",route(UpdateSnippetArgsBody,(a,ctx)=>updateSnippetArgs2(ctx,a))),r}function createPreflightRouter(ctxFor){let r=new Hono2;return r.get("/",(c)=>{let folder=ctxFor().folder,source={folder,providers:ctxFor().providers,defaultProvider:ctxFor().defaultProvider},kind=c.req.query("kind"),id=c.req.query("id");if(kind!==void 0||id!==void 0){if(kind!=="frame"&&kind!=="board"&&kind!=="screen")return c.json({error:"kind must be frame, board, or screen"},400);if(!id)return c.json({error:"id is required with kind"},400);let screens=screensForExportTarget(folder,kind,id);if(screens.length===0)return c.json({error:`no ${kind} with id "${id}"`},404);return c.json({failures:preflightScreens(source,screens)})}let boards=c.req.query("boards"),screens=boards===void 0||boards===""?[...folder.screens.values()]:screensForBoards(folder,boards.split(","));return c.json({failures:preflightScreens(source,screens)})}),r}function createPublishRouter(runner){let app=new Hono2,noPublisher="this server cannot publish \u2014 run the canvas through the velloo CLI",unavailable={error:"this server cannot publish \u2014 run the canvas through the velloo CLI"};app.get("/status",(c)=>{if(!runner)return c.json({state:"unavailable"});return c.json(runner.state())}),app.get("/targets",async(c)=>{let closed=(access)=>c.json({ready:!1,access,teams:[],slots:[]});if(!runner)return closed("signed-out");let access=await runner.access();if(access.state!=="ready")return closed(access.state);let[teams,destinationResult]=await Promise.all([runner.teams().catch(()=>[]),runner.destinations().then((value)=>({value})).catch((error)=>({error:error instanceof Error?error.message:String(error),signInRequired:asSignInRequired(error)}))]);if("error"in destinationResult){if(destinationResult.signInRequired)return closed(destinationResult.signInRequired);return c.json({ready:!0,access:"ready",teams,slots:[],destinationError:destinationResult.error})}return c.json({ready:!0,access:"ready",teams,...destinationResult.value})}),app.post("/",async(c)=>{if(!runner)return c.json(unavailable,503);let body=await c.req.json().catch(()=>({})),boardIds=Array.isArray(body.boardIds)?body.boardIds.filter((id)=>typeof id==="string"):[],visibility=body.visibility==="private"?"private":"public",title=typeof body.title==="string"?body.title:void 0,teamId=typeof body.teamId==="string"&&body.teamId?body.teamId:void 0;if(typeof body.password==="string"&&body.password.length<3)return c.json({error:"password must be at least 3 characters"},400);let password=typeof body.password==="string"?body.password:void 0,rawDestination=body.destination,destination=rawDestination?.mode==="new"?{mode:"new"}:rawDestination?.mode==="update"&&typeof rawDestination.slug==="string"&&(typeof rawDestination.expectedVersionId==="string"||rawDestination.expectedVersionId===null)?{mode:"update",slug:rawDestination.slug,expectedVersionId:rawDestination.expectedVersionId}:null;if(!destination)return c.json({error:"choose a publish destination"},400);let started=runner.start({boardIds,visibility,destination,...title?{title}:{},...password?{password}:{},...teamId?{teamId}:{}});if(!started)return c.json({error:"a publish is already running for this folder"},409);return c.json(started,202)});let cloudFail=(c,error)=>{let message=error instanceof Error?error.message:String(error),kind=asSignInRequired(error)?"LoggedOut":"HttpFailure";return c.json({error:{kind,message}},502)},noPublisherFail=(c)=>c.json({error:{kind:"HttpFailure",message:"this server cannot publish \u2014 run the canvas through the velloo CLI"}},503);return app.get("/published",async(c)=>{if(!runner)return noPublisherFail(c);try{return c.json({boards:await runner.published()})}catch(error){return cloudFail(c,error)}}),app.delete("/published/:slug",async(c)=>{if(!runner)return noPublisherFail(c);try{return await runner.unpublish(c.req.param("slug")),c.json({ok:!0})}catch(error){return cloudFail(c,error)}}),app.post("/reset",(c)=>(runner?.reset(),c.json({ok:!0}))),app}import{randomBytes}from"crypto";var SHOWCASES={Button:()=>({$ref:"Button",props:{children:"Button"}}),Badge:()=>({$ref:"Badge",props:{children:"Badge"}}),Heading:()=>({$ref:"Heading",props:{level:2,children:"Heading"}}),Text:()=>({$ref:"Text",props:{children:"Body text"}}),Label:()=>({$ref:"Card",props:{className:"flex flex-row items-center gap-2 ring-0 shadow-none bg-transparent p-0"},children:[{$ref:"Checkbox",props:{id:"showcase-label-cb",defaultChecked:!0}},{$ref:"Label",props:{htmlFor:"showcase-label-cb",children:"Accept terms"}}]}),Input:()=>({$ref:"Input",props:{placeholder:"you@company.com"}}),Textarea:()=>({$ref:"Textarea",props:{placeholder:"Write a message\u2026"}}),Switch:()=>({$ref:"Switch",props:{defaultChecked:!0}}),Checkbox:()=>({$ref:"Checkbox",props:{defaultChecked:!0}}),Slider:()=>({$ref:"Slider",props:{defaultValue:[40],className:"w-40"}}),Progress:()=>({$ref:"Progress",props:{value:66,className:"w-48"}}),Skeleton:()=>({$ref:"Skeleton",props:{className:"h-6 w-40"}}),Separator:()=>({$ref:"Separator",props:{className:"w-40"}}),Toggle:()=>({$ref:"Toggle",props:{variant:"outline",defaultPressed:!0,children:"Bold"}}),Calendar:()=>({$ref:"Calendar"}),Icon:()=>({$ref:"Icon",props:{name:"Sparkles",size:24}}),Placeholder:()=>({$ref:"Placeholder",props:{kind:"image",aspect:"16/9"}}),Divider:()=>({$ref:"Divider",props:{label:"or"}}),Avatar:()=>({$ref:"Avatar",children:[{$ref:"AvatarFallback",props:{children:"AB"}}]}),Alert:()=>({$ref:"Alert",children:[{$ref:"AlertTitle",props:{children:"Heads up!"}},{$ref:"AlertDescription",props:{children:"You can drop this component on a board."}}]}),Card:()=>({$ref:"Card",props:{className:"p-4 flex flex-col gap-1"},children:[{$ref:"Text",props:{className:"text-sm font-medium",children:"Card title"}},{$ref:"Text",props:{className:"text-xs text-muted-foreground",children:"A flexible container for content."}}]}),Tabs:()=>({$ref:"Tabs",props:{defaultValue:"overview"},children:[{$ref:"TabsList",children:[{$ref:"TabsTrigger",props:{value:"overview",children:"Overview"}},{$ref:"TabsTrigger",props:{value:"activity",children:"Activity"}},{$ref:"TabsTrigger",props:{value:"settings",children:"Settings"}}]}]}),Breadcrumb:()=>({$ref:"Breadcrumb",children:[{$ref:"BreadcrumbList",children:[{$ref:"BreadcrumbItem",children:[{$ref:"BreadcrumbLink",props:{children:"Home"}}]},{$ref:"BreadcrumbSeparator"},{$ref:"BreadcrumbItem",children:[{$ref:"BreadcrumbPage",props:{children:"Library"}}]}]}]}),Pagination:()=>({$ref:"Pagination",children:[{$ref:"PaginationContent",children:[{$ref:"PaginationPrevious"},{$ref:"PaginationItem",children:[{$ref:"PaginationLink",props:{children:"1"}}]},{$ref:"PaginationItem",children:[{$ref:"PaginationLink",props:{isActive:!0,children:"2"}}]},{$ref:"PaginationNext"}]}]}),Accordion:()=>({$ref:"Accordion",props:{type:"single",collapsible:!0,defaultValue:"a"},children:[{$ref:"AccordionItem",props:{value:"a"},children:[{$ref:"AccordionTrigger",props:{children:"What is Velloo?"}},{$ref:"AccordionContent",props:{children:"A local design canvas for solo devs."}}]}]}),RadioGroup:()=>({$ref:"RadioGroup",props:{defaultValue:"a"},children:[{$ref:"Card",props:{className:"flex items-center gap-2 ring-0 shadow-none p-0 bg-transparent"},children:[{$ref:"RadioGroupItem",props:{value:"a",id:"showcase-r1"}},{$ref:"Label",props:{htmlFor:"showcase-r1",children:"Option"}}]}]}),ToggleGroup:()=>({$ref:"ToggleGroup",props:{type:"single",defaultValue:"left"},children:[{$ref:"ToggleGroupItem",props:{value:"left",children:"Left"}},{$ref:"ToggleGroupItem",props:{value:"center",children:"Center"}},{$ref:"ToggleGroupItem",props:{value:"right",children:"Right"}}]}),Select:()=>({$ref:"Select",children:[{$ref:"SelectTrigger",props:{className:"w-40"},children:[{$ref:"SelectValue",props:{placeholder:"Choose\u2026"}}]}]}),Toaster:()=>({$ref:"Toaster",props:{position:"bottom-right"}}),Dialog:()=>({$ref:"Dialog",children:[{$ref:"DialogContent",props:{className:"w-72"},children:[{$ref:"DialogHeader",children:[{$ref:"DialogTitle",props:{children:"Confirm change"}},{$ref:"DialogDescription",props:{children:"Modal dialog content shown when triggered."}}]},{$ref:"DialogFooter",children:[{$ref:"Button",props:{variant:"outline",size:"sm",children:"Cancel"}},{$ref:"Button",props:{size:"sm",children:"Save"}}]}]}]}),AlertDialog:()=>({$ref:"AlertDialog",children:[{$ref:"AlertDialogContent",props:{className:"w-72"},children:[{$ref:"AlertDialogHeader",children:[{$ref:"AlertDialogTitle",props:{children:"Delete file?"}},{$ref:"AlertDialogDescription",props:{children:"This action can't be undone."}}]},{$ref:"AlertDialogFooter",children:[{$ref:"AlertDialogCancel",props:{size:"sm",children:"Cancel"}},{$ref:"AlertDialogAction",props:{variant:"destructive",size:"sm",children:"Delete"}}]}]}]}),Popover:()=>({$ref:"Popover",children:[{$ref:"PopoverContent",props:{className:"w-56"},children:[{$ref:"PopoverHeader",children:[{$ref:"PopoverTitle",props:{children:"Popover content"}},{$ref:"PopoverDescription",props:{children:"Anchored to a trigger."}}]}]}]}),DropdownMenu:()=>({$ref:"DropdownMenu",children:[{$ref:"DropdownMenuContent",props:{className:"w-44"},children:[{$ref:"DropdownMenuItem",props:{children:"Profile"}},{$ref:"DropdownMenuItem",props:{children:"Settings"}},{$ref:"DropdownMenuSeparator"},{$ref:"DropdownMenuItem",props:{variant:"destructive",children:"Log out"}}]}]}),Tooltip:()=>({$ref:"Tooltip",children:[{$ref:"TooltipContent",props:{children:"Helpful hint"}}]}),Sheet:()=>({$ref:"Sheet",children:[{$ref:"SheetContent",props:{side:"right",className:"h-56 w-64 rounded-lg p-4"},children:[{$ref:"SheetHeader",children:[{$ref:"SheetTitle",props:{children:"Slide-in panel"}},{$ref:"SheetDescription",props:{children:"Drawer mounted on a screen edge."}}]}]}]}),Collapsible:()=>({$ref:"Collapsible",props:{defaultOpen:!0},children:[{$ref:"CollapsibleTrigger",children:[{$ref:"Button",props:{variant:"outline",size:"sm",children:"Toggle"}}]},{$ref:"CollapsibleContent",children:[{$ref:"Card",props:{className:"mt-2 p-2 ring-0 shadow-none bg-muted text-xs"},children:[{$ref:"Text",props:{className:"text-xs",children:"Hidden content revealed."}}]}]}]}),Carousel:()=>({$ref:"Carousel",props:{className:"w-56"},children:[{$ref:"CarouselContent",children:[{$ref:"CarouselItem",children:[{$ref:"Card",props:{className:"p-6 bg-primary text-primary-foreground"},children:[{$ref:"Text",props:{className:"text-sm font-medium",children:"Slide 1"}}]}]}]},{$ref:"CarouselPrevious"},{$ref:"CarouselNext"}]}),ScrollArea:()=>({$ref:"ScrollArea",props:{className:"h-24 w-48 rounded-md border border-border p-2"},children:[{$ref:"Card",props:{className:"flex flex-col gap-1 ring-0 shadow-none bg-transparent p-0"},children:Array.from({length:6},(_,i)=>({$ref:"Text",props:{className:"text-xs",children:`Item ${i+1}`}}))}]}),Layer:()=>({$ref:"Card",props:{className:"relative h-24 w-40 bg-muted rounded-md overflow-hidden"},children:[{$ref:"Layer",props:{top:"1rem",left:"1rem"},children:[{$ref:"Card",props:{className:"px-2 py-0.5 rounded-full bg-primary text-primary-foreground ring-0 shadow-none"},children:[{$ref:"Text",props:{className:"text-xs font-medium",children:"Layer"}}]}]}]}),Gradient:()=>({$ref:"Gradient",props:{preset:"sunset",className:"h-20 w-full rounded-md"}}),Image:()=>({$ref:"Image",props:{src:"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 9'><rect width='16' height='9' fill='%23ddd'/></svg>",aspect:"16/9",fill:!1}}),SVG:()=>({$ref:"SVG",props:{viewBox:"0 0 24 24",content:"<circle cx='12' cy='12' r='8' fill='currentColor' opacity='0.2'/><circle cx='12' cy='12' r='4' fill='currentColor'/>",className:"h-12 w-12 text-primary"}}),Chart:()=>({$ref:"Chart",props:{kind:"line",data:[{x:0,y:4},{x:1,y:6},{x:2,y:5},{x:3,y:9},{x:4,y:7},{x:5,y:12}],className:"h-20 w-full"}})};function buildShowcaseTree(componentRef,propOverrides){let isIconSize=typeof propOverrides?.size==="string"&&propOverrides.size.startsWith("icon"),builder=SHOWCASES[componentRef];if(builder){let tree=builder();if(propOverrides&&Object.keys(propOverrides).length>0)tree.props={...tree.props??{},...propOverrides};if(isIconSize&&componentRef==="Button")delete tree.props?.children,tree.children=[{$ref:"Icon",props:{name:"Plus",size:14}}];return tree}return{$ref:componentRef,props:{children:componentRef,...propOverrides??{}}}}var AMBER="#FFAB1F",CORAL="#FF6F4D",DARK={bg:"#0D0C0A",fg:"#F7F2E6",muted:"#A59C8D",border:"#26221C",code:"#15130E"},LIGHT={bg:"#F7F2E6",fg:"#141210",muted:"#6F665A",border:"#E2D8C4",code:"#FFFDF7"};function escapeHtml(value){return value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function renderErrorDocument(page){let c=page.dark?DARK:LIGHT;return`<!doctype html>
187
+ `)[0]??msg);return null}function defaultViewport(folder){let presets=folder.config.viewportPresets,pick=presets.find((p)=>p.name.toLowerCase().includes("desktop"))??presets[0]??{w:1440,h:900};return{w:pick.w,h:pick.h}}function makeLiveUrl(ctx,bundler){return()=>Object.keys(liveExtensions(ctx.folder.config.extensions)).length>0?`/api/live/bundle.js?v=${bundler.version}`:void 0}async function screenMount(ctx,canvasBundler,screen){let refs=collectSerializedRefs(serializeTree(screen.tree,{snippets:ctx.folder.snippets}));if(refs.length===0)return{kind:"none"};let libraryId=libraryIdForScreen(ctx,screen);if(!canvasBundler.canMount(libraryId,refs))return{kind:"none"};let extensionIds=new Set(Object.keys(ctx.folder.config.extensions??{})),extensions=refs.filter((ref)=>extensionIds.has(ref));if(extensions.length>0)return{kind:"server",libraryId,reason:`it uses the extension${extensions.length===1?"":"s"} ${extensions.join(", ")}, which ${extensions.length===1?"has":"have"} no browser-canvas source`};let bundle=await canvasBundler.build(libraryId,refs);if(bundle.usable)return{kind:"mounted",libraryId,refs,bundle};let blocked=bundle.diagnostics.filter((entry)=>entry.status==="unavailable"),reason=blocked.length?`${blocked.map((entry)=>entry.id).join(", ")} ${blocked.length===1?"has":"have"} no source that compiles for the browser`:`the browser bundle failed to build: ${bundle.errors[0]?.message??"no components resolved"}`;return{kind:"server",libraryId,reason,bundle}}function blockingErrors(bundle){return(bundle?.diagnostics??[]).filter((entry)=>entry.status==="unavailable").map((entry)=>{let first=entry.errors?.[0]??entry.note??"no browser source";return`${entry.id}: ${first.length>300?`${first.slice(0,300)}\u2026`:first}`})}async function mountDiagnostics(ctx,canvasBundler,screen){let mount=await screenMount(ctx,canvasBundler,screen).catch(()=>{return});if(mount?.kind!=="server")return[];let errors=blockingErrors(mount.bundle);return[{severity:"warning",code:"render/server-fallback",path:[],message:`This screen renders server-side from Velloo's bundled components, not the app's own, because ${mount.reason}. `+"The browser mount is all-or-nothing, so every component on the screen falls back together \u2014 including ones component_status reports as exact."+(errors.length?` ${errors.join(" | ")}`:""),suggestion:"Fix what blocks the listed component (component_status { screen } has the full errors), or replace it; captures will then show the app's components."}]}function makeCanvasBundle(ctx,canvasBundler){return async(screen,theme,dark)=>{let mount=await screenMount(ctx,canvasBundler,screen);if(mount.kind!=="mounted")return;let provider=providerForScreen2(ctx,screen),hasRepo=mount.refs.some((ref)=>ref.startsWith("repo:"));return{url:`/api/canvas/bundle.js?v=${canvasBundler.version}&lib=${encodeURIComponent(mount.libraryId)}&refs=${encodeURIComponent(mount.refs.join(","))}`,themeOptions:provider.themeToNative?.(theme,dark)??null,...hasRepo&&ctx.repo?{preview:previewInput(ctx.repo,mount.refs,theme,dark)}:{},...mount.bundle.staticRefs?{staticRefs:mount.bundle.staticRefs}:{}}}}function previewInput(repo,refs,theme,dark){let apps=new Set(refs.filter((ref)=>ref.startsWith("repo:")).map((ref)=>parseRepoKey(ref)?.app)),recipeTheme={};for(let app of apps){let entry=repo.preview(app),recipe=entry.kind==="recipe"?entry.recipe:repo.recipes(app)[0];if(recipe)recipeTheme[app??""]=recipe.themeToNative(theme,dark)}return{colorScheme:dark?"dark":"light",theme,recipeTheme}}async function renderForCapture(ctx,screen,opts){let canvasOpt=await opts.canvasBundle(screen,opts.theme,opts.dark),{html}=await renderScreen(screen,opts.theme,{viewport:opts.viewport,snapshotCss:opts.snapshotCss,registry:registryForScreen2(ctx,screen),renderPass:renderPassForScreen2(ctx,screen,opts.theme,opts.dark),snippets:ctx.folder.snippets,customCss:ctx.folder.customCss,baseHref:opts.assetOrigin,liveBundleUrl:opts.liveUrl(),dark:opts.dark,...canvasOpt?{canvasBundle:canvasOpt}:{}});return html}function regionNode(region,rects,scaleFactor,screen){let area=region.w*region.h,best=rects.map((r)=>({path:r.path,x:r.x*scaleFactor,y:r.y*scaleFactor,w:r.w*scaleFactor,h:r.h*scaleFactor})).filter((r)=>{let ix=Math.max(0,Math.min(r.x+r.w,region.x+region.w)-Math.max(r.x,region.x)),iy=Math.max(0,Math.min(r.y+r.h,region.y+region.h)-Math.max(r.y,region.y));return ix*iy>=area*0.5}).sort((a,b)=>a.w*a.h-b.w*b.h)[0];if(!best)return null;let path=best.path===""?[]:best.path.split(".").map(Number),node=pathAt(screen.tree,path);if(!node)return{path};let id=nodeId(node);return{path,...isComponentNode(node)?{ref:node.$ref}:{},...id!==void 0?{id}:{}}}function contentHeightFromRects(rects){let max=0;for(let r of rects)max=Math.max(max,r.y+r.h);return Math.round(max)}function framesShorterThan(ctx,screenId,contentHeight,viewportW){let out=[];for(let board of ctx.folder.boards.values()){if(isArchived(board))continue;for(let frame of board.frames)if(frame.screen===screenId&&frame.w===viewportW&&frame.h<contentHeight)out.push({board:board.id,frame:frame.id,...frame.label?{label:frame.label}:{},frameHeight:frame.h,overflowBy:contentHeight-frame.h})}return out}function mountSummary(canvas){let repo=(canvas?.diagnostics??[]).filter((entry)=>entry.id.startsWith("repo:"));if(!canvas||repo.length===0)return;let fidelity={};for(let entry of repo)fidelity[entry.status]=(fidelity[entry.status]??0)+1;return{mounted:canvas.mounted,fidelity,notExact:repo.filter((entry)=>entry.status!=="exact").map((entry)=>({name:entry.name??entry.id,status:entry.status,...entry.code?{code:entry.code}:{},...entry.note?{note:entry.note}:{}}))}}function recordMount(canvasBundler,canvas){if(canvas?.bundle)canvasBundler.recordRuntime(canvas.bundle,canvas.diagnostics)}function createExportRouter(ctxFor,jit,bundler,canvasBundler){let r=new Hono2,pipeline=(c)=>{let ctx=ctxFor();return{folder:ctx.folder,providers:ctx.providers,defaultProvider:ctx.defaultProvider,snapshotCss:()=>jit.build(),assetOrigin:()=>{let host=c.req.header("host");return host?`http://${host}/`:void 0},liveBundleUrl:()=>Object.keys(liveExtensions(ctx.folder.config.extensions)).length>0?`/api/live/bundle.js?v=${bundler.version}`:void 0,canvasBundleFor:makeCanvasBundle(ctx,canvasBundler)}},parseTarget=(raw)=>{let m=/^(.+)\.(png|pdf|html)$/.exec(raw);return m?.[1]&&m[2]?{id:m[1],ext:m[2]}:null},parseOpts=(c)=>{let mode=c.req.query("mode")??"light";if(!["light","dark","compare"].includes(mode))return null;let scale=Math.min(3,Math.max(0.25,Number(c.req.query("scale"))||1)),theme=c.req.query("theme");return{mode,scale,...theme?{theme}:{}}},send=(c,body,ext,name,warnings=[])=>{let headers={"Content-Type":ext==="png"?"image/png":ext==="pdf"?"application/pdf":"text/html; charset=utf-8","Content-Disposition":`attachment; filename="${exportFilename(name,ext)}"`};if(warnings.length>0)headers["x-velloo-export-warnings"]=encodeURIComponent(JSON.stringify(warnings));return c.body(typeof body==="string"?body:new Uint8Array(body),200,headers)},failed=(c,err)=>{let message=err instanceof Error?err.message:String(err),missing=err instanceof Error&&err.name==="BrowserMissingError";return c.json({error:message},missing?503:500)};return r.get("/frame/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <frameId>.png|pdf|html"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark|compare"},400);let p=pipeline(c),found=findFrame(p.folder,target.id);if(!found)return c.json({error:`frame not found: ${target.id}`},404);if(opts.mode==="compare"&&target.ext!=="png")return c.json({error:'mode "compare" is PNG-only'},400);let screen=p.folder.screens.get(found.frame.screen),name=found.frame.label??screen?.name??target.id;try{if(target.ext==="png")return send(c,await exportFramePng(p,found.board,found.frame,opts),"png",name);if(target.ext==="pdf")return send(c,await exportFramePdf(p,found.board,found.frame,opts),"pdf",name);let out=await exportFrameHtml(p,found.board,found.frame,opts);return send(c,out.html,"html",name,out.warnings)}catch(err){return failed(c,err)}}),r.get("/board/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <boardId>.png|pdf|html"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark|compare"},400);if(opts.mode==="compare")return c.json({error:'mode "compare" is frame-only \u2014 export the board light or dark'},400);let p=pipeline(c),board=p.folder.boards.get(target.id);if(!board)return c.json({error:`board not found: ${target.id}`},404);try{if(target.ext==="png")return send(c,await exportBoardPng(p,board,opts),"png",board.name);if(target.ext==="pdf")return send(c,await exportBoardPdf(p,board,opts),"pdf",board.name);let out=await exportBoardHtml(p,board,opts);return send(c,out.html,"html",board.name,out.warnings)}catch(err){return failed(c,err)}}),r.get("/screen/:file",async(c)=>{let target=parseTarget(c.req.param("file"));if(!target)return c.json({error:"expected <screenId>.html"},400);if(target.ext!=="html")return c.json({error:"screen exports are HTML \u2014 export a frame for PNG/PDF"},400);let opts=parseOpts(c);if(!opts)return c.json({error:"mode must be light|dark"},400);let p=pipeline(c),screen=p.folder.screens.get(target.id);if(!screen)return c.json({error:`screen not found: ${target.id}`},404);let preset=p.folder.config.viewportPresets[0]??{name:"default",w:1440,h:900},viewport={w:Number(c.req.query("w"))||preset.w,h:Number(c.req.query("h"))||preset.h};try{let out=await exportScreenHtml(p,screen,{dark:opts.mode==="dark",...opts.theme?{theme:opts.theme}:{},viewport});return send(c,out.html,"html",screen.name||screen.id,out.warnings)}catch(err){return failed(c,err)}}),r}import{randomUUID}from"crypto";import{rm as rm2}from"fs/promises";import{join as join23}from"path";function validateScreenIds(screenId,screen){let first=findDuplicateIds(screen.tree)[0];if(first)return err(idConflict(screenId,first.id,first.paths));return ok(void 0)}async function persistScreen(folder,screenId,screen,coalesceKey){let validated=ScreenSchema.parse(screen),prev=folder.screens.get(screenId)??null;return folder.history.push({kind:"screen",screenId,screen:prev,coalesceKey}),await writeJsonAtomic(join23(folder.root,"screens",`${screenId}.json`),validated),folder.screens.set(screenId,validated),validated}function commitScreen(folder,screenId,screen,coalesceKey){return DoAsync(async function*(){if(yield*$(validateScreenIds(screenId,screen)),isSnippetTreeId(screenId)){let snippetId=snippetIdFromTreeId(screenId),prev=folder.snippets.get(snippetId);if(!prev)return yield*$({ok:!1,error:snippetNotFound(snippetId)});let updated=await persistSnippet(folder,snippetId,{...prev,tree:screen.tree},coalesceKey);return{id:screenId,name:updated.name,tree:updated.tree}}return await persistScreen(folder,screenId,screen,coalesceKey)})}async function deletePersistedScreen(folder,screenId){let prev=folder.screens.get(screenId)??null;folder.history.push({kind:"screen",screenId,screen:prev}),await rm2(join23(folder.root,"screens",`${screenId}.json`),{force:!0}),await rm2(join23(folder.root,"screens",`${screenId}.annotations.json`),{force:!0}),folder.screens.delete(screenId),folder.annotations.delete(screenId)}async function persistBoard(folder,boardId,board){let validated=BoardSchema.parse(board),prev=folder.boards.get(boardId)??null;return folder.history.push({kind:"board",boardId,board:prev}),await writeJsonAtomic(join23(folder.root,"boards",`${boardId}.json`),validated),folder.boards.set(boardId,validated),validated}async function persistBoards(folder,writes){let validated=writes.map(({boardId,board})=>({boardId,board:BoardSchema.parse(board)}));folder.history.push({kind:"boards",boards:validated.map(({boardId})=>({boardId,board:folder.boards.get(boardId)??null}))});for(let{boardId,board}of validated)await writeJsonAtomic(join23(folder.root,"boards",`${boardId}.json`),board),folder.boards.set(boardId,board);return validated.map((v)=>v.board)}async function deletePersistedBoard(folder,boardId){let prev=folder.boards.get(boardId)??null;folder.history.push({kind:"board",boardId,board:prev}),await rm2(join23(folder.root,"boards",`${boardId}.json`),{force:!0}),await rm2(join23(folder.root,"boards",`${boardId}.notes.json`),{force:!0}),folder.boards.delete(boardId),folder.notes.delete(boardId)}async function persistTheme(folder,theme,coalesceKey){let validated=ThemeSchema.parse(theme);return folder.history.push({kind:"theme",themeName:"default",theme:folder.theme,...coalesceKey?{coalesceKey}:{}}),await writeJsonAtomic(join23(folder.root,"theme","default.json"),validated),folder.theme=validated,folder.themes.set("default",validated),validated}async function persistNamedTheme(folder,name,theme,coalesceKey){if(name==="default")return persistTheme(folder,theme,coalesceKey);let validated=ThemeSchema.parse({...theme,name});return folder.history.push({kind:"theme",themeName:name,theme:folder.themes.get(name)??null,...coalesceKey?{coalesceKey}:{}}),await writeJsonAtomic(join23(folder.root,"theme",`${name}.json`),validated),folder.themes.set(name,validated),validated}async function persistSnippet(folder,snippetId,snippet,coalesceKey){let validated=SnippetSchema.parse(snippet),prev=folder.snippets.get(snippetId)??null;return folder.history.push({kind:"snippet",snippetId,snippet:prev,coalesceKey}),await writeJsonAtomic(join23(folder.root,"snippets",`${snippetId}.json`),validated),folder.snippets.set(snippetId,validated),validated}async function deletePersistedSnippet(folder,snippetId){let prev=folder.snippets.get(snippetId);if(prev)folder.history.push({kind:"snippet",snippetId,snippet:prev});await rm2(join23(folder.root,"snippets",`${snippetId}.json`),{force:!0}),folder.snippets.delete(snippetId)}async function persistAnnotations(folder,screenId,annotations){let validated=annotations.map((a)=>AnnotationSchema.parse(a)),path=join23(folder.root,"screens",`${screenId}.annotations.json`);if(validated.length===0)await rm2(path,{force:!0});else await writeJsonAtomic(path,validated);return folder.annotations.set(screenId,validated),validated}async function persistConfig(folder,config){let validated=ConfigSchema.parse(config);return await writeJsonAtomic(join23(folder.root,".design","config.json"),validated),folder.config=validated,validated}async function persistCanvasNotes(folder,boardId,notes){let validated=notes.map((n)=>CanvasNoteSchema.parse(n)),path=join23(folder.root,"boards",`${boardId}.notes.json`);if(validated.length===0)await rm2(path,{force:!0});else await writeJsonAtomic(path,validated);return folder.notes.set(boardId,validated),validated}function newAnnotationId(){return`ann_${randomUUID().replace(/-/g,"").slice(0,8)}`}function sameTarget(treeRoot,a,b){let pa=resolveLocator(treeRoot,a),pb=resolveLocator(treeRoot,b);if(!pa||!pb)return!1;return JSON.stringify(pa)===JSON.stringify(pb)}async function addAnnotation(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId));yield*$(resolve9(screen.tree,args.target.locator,args.screenId));let existing=ctx.folder.annotations.get(args.screenId)??[];for(let a of existing)if(sameTarget(screen.tree,a.target.locator,args.target.locator))return yield*$(err(annotationConflict(args.screenId,args.target.locator,a.id)));let annotation={id:newAnnotationId(),target:args.target,position:args.position??"auto",body:args.body,...args.collapsed!==void 0?{collapsed:args.collapsed}:{},author:args.author??"user"},next=[...existing,annotation];return await persistAnnotations(ctx.folder,args.screenId,next),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{annotation}})}async function updateAnnotation(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.annotations.get(args.screenId);if(!existing)return yield*$(err(ctx.folder.screens.has(args.screenId)?annotationNotFound(args.screenId,args.annotationId):screenNotFound(args.screenId)));let idx=existing.findIndex((a)=>a.id===args.annotationId);if(idx===-1)return yield*$(err(annotationNotFound(args.screenId,args.annotationId)));let next={...existing[idx],...args.patch.body!==void 0?{body:args.patch.body}:{},...args.patch.position!==void 0?{position:args.patch.position}:{}};if(args.patch.collapsed===null)delete next.collapsed;else if(args.patch.collapsed!==void 0)next.collapsed=args.patch.collapsed;let updated=[...existing];return updated[idx]=next,await persistAnnotations(ctx.folder,args.screenId,updated),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{annotation:next}})}async function removeAnnotation(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.annotations.get(args.screenId);if(!existing)return yield*$(err(ctx.folder.screens.has(args.screenId)?annotationNotFound(args.screenId,args.annotationId):screenNotFound(args.screenId)));if(!existing.some((a)=>a.id===args.annotationId))return yield*$(err(annotationNotFound(args.screenId,args.annotationId)));let next=existing.filter((a)=>a.id!==args.annotationId);return await persistAnnotations(ctx.folder,args.screenId,next),ctx.broadcast({type:"annotations-changed",screenId:args.screenId}),{removedId:args.annotationId}})}import{randomUUID as randomUUID2}from"crypto";function newNoteId(){return`note_${randomUUID2().replace(/-/g,"").slice(0,8)}`}var DEFAULT_NOTE_WIDTH=240;function checkAttachment(ctx,board,attachment){let frame=board.frames.find((f)=>f.id===attachment.frameId);if(!frame)return err(frameNotFound(board.id,attachment.frameId));if(frame.screen!==attachment.screenId)return err(invalidPath(`Frame "${attachment.frameId}" shows screen "${frame.screen}", not "${attachment.screenId}"`));let screen=getScreen(ctx,attachment.screenId);if(!screen.ok)return screen;let resolved=resolve9(screen.value.tree,attachment.locator,attachment.screenId);return resolved.ok?ok(void 0):resolved}async function addNote(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(args.attachment)yield*$(checkAttachment(ctx,board,args.attachment));else if(args.x===void 0||args.y===void 0)return yield*$(err(invalidPath("A note without an attachment needs x and y")));let note={id:newNoteId(),...args.x!==void 0?{x:args.x}:{},...args.y!==void 0?{y:args.y}:{},width:args.width??DEFAULT_NOTE_WIDTH,body:args.body,...args.attachment?{attachment:args.attachment}:{}},existing=ctx.folder.notes.get(args.boardId)??[];return await persistCanvasNotes(ctx.folder,args.boardId,[...existing,note]),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{note}})}async function updateNote(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.notes.get(args.boardId)??[],idx=existing.findIndex((n)=>n.id===args.noteId);if(idx===-1)return yield*$(err(canvasNoteNotFound(args.noteId)));let next={...existing[idx],...args.patch.x!==void 0?{x:args.patch.x}:{},...args.patch.y!==void 0?{y:args.patch.y}:{},...args.patch.width!==void 0?{width:args.patch.width}:{},...args.patch.body!==void 0?{body:args.patch.body}:{}},updated=[...existing];return updated[idx]=next,await persistCanvasNotes(ctx.folder,args.boardId,updated),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{note:next}})}async function removeNote(ctx,args){return DoAsync(async function*(){let existing=ctx.folder.notes.get(args.boardId)??[];if(!existing.some((n)=>n.id===args.noteId))return yield*$(err(canvasNoteNotFound(args.noteId)));let next=existing.filter((n)=>n.id!==args.noteId);return await persistCanvasNotes(ctx.folder,args.boardId,next),ctx.broadcast({type:"notes-changed",boardId:args.boardId}),{removedId:args.noteId}})}function createLockMap(){let chains=new Map;return{run(key,fn){let next=(chains.get(key)??Promise.resolve()).then(fn,fn),tail=next.then(()=>{return},()=>{return});return chains.set(key,tail),tail.then(()=>{if(chains.get(key)===tail)chains.delete(key)}),next},get size(){return chains.size}}}function broadcastTreeChange(ctx,screenId){if(isSnippetTreeId(screenId))ctx.broadcast({type:"snippet-changed",snippetId:snippetIdFromTreeId(screenId)});else ctx.broadcast({type:"screen-changed",screenId})}var locks=createLockMap(),lockKey=(folder,kind,id)=>`${folder.root}\x00${kind}\x00${id}`;function withScreenLock(folder,screenId,fn){if(isSnippetTreeId(screenId))return locks.run(lockKey(folder,"snippet",snippetIdFromTreeId(screenId)),fn);return locks.run(lockKey(folder,"screen",screenId),fn)}function withSnippetLock(folder,snippetId,fn){return locks.run(lockKey(folder,"snippet",snippetId),fn)}function withConfigLock(folder,fn){return locks.run(lockKey(folder,"config","config"),fn)}function withBoardLock(folder,boardId,fn){return locks.run(lockKey(folder,"board",boardId),fn)}function withBoardLocks(folder,boardIds,fn){let[head,...rest]=[...new Set(boardIds)].sort();if(head===void 0)return fn();return withBoardLock(folder,head,()=>withBoardLocks(folder,rest,fn))}function addAnnotation2(ctx,args){return tracked(ctx,"add_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>addAnnotation(ctx,args)))}function updateAnnotation2(ctx,args){return tracked(ctx,"update_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateAnnotation(ctx,args)))}function removeAnnotation2(ctx,args){return tracked(ctx,"remove_annotation",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeAnnotation(ctx,args)))}function addNote2(ctx,args){return tracked(ctx,"add_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>addNote(ctx,args)))}function updateNote2(ctx,args){return tracked(ctx,"update_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateNote(ctx,args)))}function removeNote2(ctx,args){return tracked(ctx,"remove_note",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeNote(ctx,args)))}function slugify(s,fallback){return s.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||fallback}var MAX_GROUP_NAME_LENGTH=40,GROUP_COLORS=["#8b5cf6","#0ea5e9","#f59e0b","#f43f5e","#10b981","#6366f1","#ec4899","#84cc16"];function nextGroupColor(existing){let used=new Set(existing.map((g)=>g.color));return GROUP_COLORS.find((c)=>!used.has(c))??GROUP_COLORS[existing.length%8]}function boardGroups(config){return config.boardGroups??[]}function nameTooLong(name){if(name.length<=MAX_GROUP_NAME_LENGTH)return null;return badRequest(`group name too long (${name.length} chars) \u2014 max ${MAX_GROUP_NAME_LENGTH} characters`)}function uniqueGroupId(groups,base){let id=base,attempt=2;while(groups.some((g)=>g.id===id))id=`${base}-${attempt++}`;return id}function resolveGroup(config,ref){let trimmed=ref.trim();if(trimmed.length===0)return err(badRequest("group name is empty"));let tooLong=nameTooLong(trimmed);if(tooLong)return err(tooLong);let groups=boardGroups(config),match=groups.find((g)=>g.id===trimmed)??groups.find((g)=>g.name.toLowerCase()===trimmed.toLowerCase());if(match)return ok({config,groupId:match.id});let group={id:uniqueGroupId(groups,slugify(trimmed,"group")),name:trimmed,color:nextGroupColor(groups)};return ok({config:{...config,boardGroups:[...groups,group]},groupId:group.id})}async function addBoardGroup(ctx,args){return DoAsync(async function*(){let name=args.name.trim();if(name.length===0)return yield*$(err(badRequest("group name is empty")));let tooLong=nameTooLong(name);if(tooLong)return yield*$(err(tooLong));let groups=boardGroups(ctx.folder.config),group={id:uniqueGroupId(groups,slugify(name,"group")),name,color:args.color??nextGroupColor(groups)};return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:[...groups,group]}),ctx.broadcast({type:"config-changed"}),{group}})}async function updateBoardGroup(ctx,args){return DoAsync(async function*(){let groups=boardGroups(ctx.folder.config),current=groups.find((g)=>g.id===args.groupId);if(!current)return yield*$(err(boardGroupNotFound(args.groupId)));let next={...current};if(args.patch.name!==void 0){let name=args.patch.name.trim();if(name.length===0)return yield*$(err(badRequest("group name is empty")));let tooLong=nameTooLong(name);if(tooLong)return yield*$(err(tooLong));next.name=name}if(args.patch.color!==void 0)if(args.patch.color===null)delete next.color;else next.color=args.patch.color;return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:groups.map((g)=>g.id===args.groupId?next:g)}),ctx.broadcast({type:"config-changed"}),{group:next}})}async function removeBoardGroup(ctx,args){return DoAsync(async function*(){let groups=boardGroups(ctx.folder.config);if(!groups.some((g)=>g.id===args.groupId))return yield*$(err(boardGroupNotFound(args.groupId)));let ungroupedBoardIds=[];for(let[boardId,board]of ctx.folder.boards){if(board.group!==args.groupId)continue;let{group:_group,...rest}=board;await persistBoard(ctx.folder,boardId,rest),ungroupedBoardIds.push(boardId)}let remaining=groups.filter((g)=>g.id!==args.groupId);await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:remaining.length>0?remaining:void 0});for(let boardId of ungroupedBoardIds)ctx.broadcast({type:"board-changed",boardId});return ctx.broadcast({type:"config-changed"}),{removedGroupId:args.groupId,ungroupedBoardIds}})}async function reorderBoardGroups(ctx,args){let groups=boardGroups(ctx.folder.config),seen=new Set,next=[];for(let id of args.order){let group=groups.find((g)=>g.id===id);if(group&&!seen.has(id))next.push(group),seen.add(id)}for(let group of groups)if(!seen.has(group.id))next.push(group);return await persistConfig(ctx.folder,{...ctx.folder.config,boardGroups:next}),ctx.broadcast({type:"config-changed"}),ok({order:next.map((g)=>g.id)})}function addBoardGroup2(ctx,args){return tracked(ctx,"add_board_group",{},()=>addBoardGroup(ctx,args))}function updateBoardGroup2(ctx,args){return tracked(ctx,"update_board_group",{},()=>updateBoardGroup(ctx,args))}function removeBoardGroup2(ctx,args){return tracked(ctx,"remove_board_group",{},()=>removeBoardGroup(ctx,args))}function reorderBoardGroups2(ctx,args){return tracked(ctx,"reorder_board_groups",{},()=>reorderBoardGroups(ctx,args))}function screensPlacedOnlyOn(folder,boardId){let board=folder.boards.get(boardId);if(!board)return[];let elsewhere=new Set;for(let[otherId,other]of folder.boards){if(otherId===boardId)continue;for(let frame of other.frames)elsewhere.add(frame.screen)}let only=new Set;for(let frame of board.frames){if(elsewhere.has(frame.screen))continue;if(!folder.screens.has(frame.screen))continue;only.add(frame.screen)}return[...only]}function boardNameTooLong(name){if(name.length<=MAX_BOARD_NAME_LENGTH)return null;return badRequest(`board name too long (${name.length} chars) \u2014 max ${MAX_BOARD_NAME_LENGTH} characters`)}async function addBoard(ctx,args){return DoAsync(async function*(){let tooLong=boardNameTooLong(args.name);if(tooLong)return yield*$(err(tooLong));let baseId=args.id??slugify(args.name,"board");if(args.id!==void 0&&ctx.folder.boards.has(args.id))return yield*$(err(boardIdConflict(args.id)));let boardId=baseId,attempt=2;while(ctx.folder.boards.has(boardId))if(boardId=`${baseId}-${attempt++}`,attempt>100)return yield*$(err(boardIdExhausted(baseId)));let groupId;if(args.group!==void 0){let resolved=yield*$(resolveGroup(ctx.folder.config,args.group));if(groupId=resolved.groupId,resolved.config!==ctx.folder.config)await persistConfig(ctx.folder,resolved.config),ctx.broadcast({type:"config-changed"})}let board={id:boardId,name:args.name,...groupId?{group:groupId}:{},frames:[],groups:[]};return await persistBoard(ctx.folder,boardId,board),ctx.broadcast({type:"board-changed",boardId}),{boardId,board}})}async function updateBoard(ctx,args){return DoAsync(async function*(){if(args.patch.name!==void 0){let tooLong=boardNameTooLong(args.patch.name);if(tooLong)return yield*$(err(tooLong))}let next={...yield*$(getBoard(ctx,args.boardId))};if(args.patch.name!==void 0)next.name=args.patch.name;if(args.patch.theme!==void 0)if(args.patch.theme===null)delete next.theme;else next.theme=args.patch.theme;if(args.patch.group!==void 0)if(args.patch.group===null)delete next.group;else{let resolved=yield*$(resolveGroup(ctx.folder.config,args.patch.group));if(next.group=resolved.groupId,resolved.config!==ctx.folder.config)await persistConfig(ctx.folder,resolved.config),ctx.broadcast({type:"config-changed"})}if(args.patch.archived!==void 0)if(args.patch.archived)next.archivedAt=new Date().toISOString();else delete next.archivedAt;return await persistBoard(ctx.folder,args.boardId,next),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{board:next}})}async function reorderBoards(ctx,args){let seen=new Set,moved=[];for(let id of args.order)if(ctx.folder.boards.has(id)&&!seen.has(id))moved.push(id),seen.add(id);let current=orderedBoards(ctx.folder).map(([id])=>id),next=0,order=current.map((id)=>seen.has(id)?moved[next++]:id);for(let id of moved.slice(next))order.push(id);let nextConfig={...ctx.folder.config,boardOrder:order};return await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),ok({order})}async function removeBoard(ctx,args){return DoAsync(async function*(){yield*$(getBoard(ctx,args.boardId));let orphaned=screensPlacedOnlyOn(ctx.folder,args.boardId),strandedSnippets=snippetsStrandedByRemoving(ctx.folder,orphaned);await deletePersistedBoard(ctx.folder,args.boardId);for(let screenId of orphaned)await withScreenLock(ctx.folder,screenId,()=>deletePersistedScreen(ctx.folder,screenId)),ctx.broadcast({type:"screen-changed",screenId});for(let snippetId of strandedSnippets)await deletePersistedSnippet(ctx.folder,snippetId),ctx.broadcast({type:"snippet-changed",snippetId});let order=ctx.folder.config.boardOrder;if(order?.includes(args.boardId)){let pruned=order.filter((id)=>id!==args.boardId),nextConfig={...ctx.folder.config,boardOrder:pruned.length>0?pruned:void 0};await persistConfig(ctx.folder,nextConfig)}return ctx.broadcast({type:"board-changed",boardId:args.boardId}),{removedBoardId:args.boardId,removedScreenIds:orphaned,removedSnippetIds:strandedSnippets}})}function snippetsStrandedByRemoving(folder,screenIds){if(screenIds.length===0)return[];let going=new Set(screenIds),before=reachableSnippetIds(folder,folder.screens.values()),after=reachableSnippetIds(folder,[...folder.screens].filter(([id])=>!going.has(id)).map(([,screen])=>screen));return[...before].filter((id)=>!after.has(id)&&folder.snippets.has(id)).sort()}function addBoard2(ctx,args){return tracked(ctx,"add_board",(v)=>({boardId:v.boardId}),()=>addBoard(ctx,args))}function updateBoard2(ctx,args){return tracked(ctx,"update_board",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateBoard(ctx,args)))}function removeBoard2(ctx,args){return tracked(ctx,"remove_board",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeBoard(ctx,args)))}function reorderBoards2(ctx,args){return tracked(ctx,"reorder_boards",{},()=>reorderBoards(ctx,args))}async function commit(ctx,next){let saved=await persistConfig(ctx.folder,next);return ctx.broadcast({type:"config-changed"}),saved}async function updateViewportPresets(ctx,args){let parsed=ViewportPresetSchema.array().safeParse(args.presets);if(!parsed.success)return err(badRequest("Each viewport preset needs a name and positive w/h.",parsed.error.issues));let presets=parsed.data.map((p)=>({...p,name:p.name.trim()}));if(presets.length===0)return err(badRequest("A folder needs at least one viewport preset."));if(presets.some((p)=>p.name===""))return err(badRequest("A viewport preset needs a name."));let seen=new Set;for(let p of presets){let key=p.name.toLowerCase();if(seen.has(key))return err(badRequest(`Two viewport presets are both named "${p.name}".`));seen.add(key)}return await commit(ctx,{...ctx.folder.config,viewportPresets:presets}),ok({presets})}async function updateDefaults(ctx,args){let next={...ctx.folder.config};if(args.defaultBoard!==void 0)if(args.defaultBoard===null)delete next.defaultBoard;else{if(!ctx.folder.boards.has(args.defaultBoard))return err(boardNotFound(args.defaultBoard));next.defaultBoard=args.defaultBoard}if(args.defaultScreen!==void 0)if(args.defaultScreen===null)delete next.defaultScreen;else{if(!ctx.folder.screens.has(args.defaultScreen))return err(screenNotFound(args.defaultScreen));next.defaultScreen=args.defaultScreen}let saved=await commit(ctx,next);return ok({defaultBoard:saved.defaultBoard??null,defaultScreen:saved.defaultScreen??null})}async function updateDesignName(ctx,args){let name=args.name.trim(),previous=ctx.folder.config.name;if(name===previous)return ok({name});let conflict=await designRenameConflict(ctx.folder.root,name);if(conflict)return err(badRequest(conflict));let saved=await commit(ctx,{...ctx.folder.config,name});return await followDesignRename(ctx.folder.root,previous,name),ok({name:saved.name})}async function updateCodegen(ctx,args){let next={...ctx.folder.config};if(args.componentsAlias!==void 0){let alias=args.componentsAlias?.trim()??null;if(alias==="")return err(badRequest("The components alias can't be empty \u2014 clear it to use the default."));let codegen={...next.codegen,...alias===null?{}:{componentsAlias:alias}};if(alias===null)delete codegen.componentsAlias;if(Object.keys(codegen).length===0)delete next.codegen;else next.codegen=codegen}let saved=await commit(ctx,next);return ok({componentsAlias:saved.codegen?.componentsAlias??null})}async function updateFeedback(ctx,args){let current=ctx.folder.config.feedback,contactOk=args.contactOk??await readFeedbackContactOk(),feedback={enabled:args.enabled??current?.enabled??!1,contactOk};if(args.contactOk!==void 0)await writeFeedbackContactOk(args.contactOk);if(await writeRepoFeedback(ctx.folder.root,feedback))return ctx.folder.config={...ctx.folder.config,feedback},ctx.broadcast({type:"config-changed"}),ok({enabled:feedback.enabled,contactOk:feedback.contactOk});let saved=await commit(ctx,{...ctx.folder.config,feedback:{enabled:feedback.enabled}});return ok({enabled:saved.feedback?.enabled??!1,contactOk:feedback.contactOk})}function updateViewportPresets2(ctx,args){return tracked(ctx,"update_viewport_presets",{},()=>withConfigLock(ctx.folder,()=>updateViewportPresets(ctx,args)))}function updateDefaults2(ctx,args){return tracked(ctx,"update_defaults",{},()=>withConfigLock(ctx.folder,()=>updateDefaults(ctx,args)))}function updateDesignName2(ctx,args){return tracked(ctx,"update_design_name",{},()=>withConfigLock(ctx.folder,()=>updateDesignName(ctx,args)))}function updateCodegen2(ctx,args){return tracked(ctx,"update_codegen",{},()=>withConfigLock(ctx.folder,()=>updateCodegen(ctx,args)))}function updateFeedback2(ctx,args){return tracked(ctx,"update_feedback",{},()=>withConfigLock(ctx.folder,()=>updateFeedback(ctx,args)))}function autoPosition(frames){if(frames.length===0)return{x:0,y:0};let maxRight=0;for(let f of frames)if(f.x+f.w>maxRight)maxRight=f.x+f.w;return{x:maxRight+80,y:0}}function genFrameId(board,screenId){let existing=new Set(board.frames.map((f)=>f.id)),i=1;while(existing.has(`${screenId}-${i}`))i++;return`${screenId}-${i}`}async function addFrame(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(yield*$(getScreen(ctx,args.screenId)),args.id!==void 0&&board.frames.some((f)=>f.id===args.id))return yield*$(err(frameIdConflict(args.boardId,args.id)));let id=args.id??genFrameId(board,args.screenId),pos=args.x!==void 0&&args.y!==void 0?{x:args.x,y:args.y}:autoPosition(board.frames),frame={id,screen:args.screenId,x:pos.x,y:pos.y,w:args.w,h:args.h,...args.label!==void 0?{label:args.label}:{},...args.group!==void 0?{group:args.group}:{}},nextBoard={...board,frames:[...board.frames,frame]};return await persistBoard(ctx.folder,args.boardId,nextBoard),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frame}})}async function moveFrame(ctx,args){return DoAsync(async function*(){let from=yield*$(getBoard(ctx,args.boardId)),to=yield*$(getBoard(ctx,args.toBoardId));if(args.boardId===args.toBoardId)return yield*$(err(invalidMove(`Frame "${args.frameId}" is already on board "${args.boardId}" \u2014 use update_frame to reposition it.`)));let frame=from.frames.find((f)=>f.id===args.frameId);if(!frame)return yield*$(err(frameNotFound(args.boardId,args.frameId)));let pos=args.x!==void 0&&args.y!==void 0?{x:args.x,y:args.y}:autoPosition(to.frames),taken=to.frames.some((f)=>f.id===frame.id),{group:_dropped,...carried}=frame,moved={...carried,id:taken?genFrameId(to,frame.screen):frame.id,x:pos.x,y:pos.y};return await persistBoards(ctx.folder,[{boardId:args.toBoardId,board:{...to,frames:[...to.frames,moved]}},{boardId:args.boardId,board:{...from,frames:from.frames.filter((f)=>f.id!==args.frameId)}}]),ctx.broadcast({type:"board-changed",boardId:args.toBoardId}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frame:moved,fromBoardId:args.boardId,toBoardId:args.toBoardId}})}async function removeFrame(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId));if(board.frames.findIndex((f)=>f.id===args.frameId)===-1)return yield*$(err(frameNotFound(args.boardId,args.frameId)));let nextFrames=board.frames.filter((f)=>f.id!==args.frameId);return await persistBoard(ctx.folder,args.boardId,{...board,frames:nextFrames}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{removedFrameId:args.frameId}})}function applyPatch2(frame,patch){let next={...frame};if(patch.x!==void 0)next.x=patch.x;if(patch.y!==void 0)next.y=patch.y;if(patch.w!==void 0)next.w=patch.w;if(patch.h!==void 0)next.h=patch.h;if(patch.label!==void 0)if(patch.label===null)delete next.label;else next.label=patch.label;if(patch.group!==void 0)if(patch.group===null)delete next.group;else next.group=patch.group;if(patch.scheme!==void 0)if(patch.scheme===null)delete next.scheme;else next.scheme=patch.scheme;return next}async function updateFrames(ctx,args){return DoAsync(async function*(){let board=yield*$(getBoard(ctx,args.boardId)),nextFrames=[...board.frames];for(let{frameId,patch}of args.patches){let idx=nextFrames.findIndex((f)=>f.id===frameId);if(idx===-1)return yield*$(err(frameNotFound(args.boardId,frameId)));nextFrames[idx]=applyPatch2(nextFrames[idx],patch)}return await persistBoard(ctx.folder,args.boardId,{...board,frames:nextFrames}),ctx.broadcast({type:"board-changed",boardId:args.boardId}),{frames:nextFrames}})}function addFrame2(ctx,args){return tracked(ctx,"add_frame",(v)=>({boardId:args.boardId,frameId:v.frame.id,screenId:v.frame.screen}),()=>withBoardLock(ctx.folder,args.boardId,()=>addFrame(ctx,args)))}function updateFrames2(ctx,args){return tracked(ctx,"update_frame",{boardId:args.boardId},()=>withBoardLock(ctx.folder,args.boardId,()=>updateFrames(ctx,args)))}function removeFrame2(ctx,args){return tracked(ctx,"remove_frame",{boardId:args.boardId,frameId:args.frameId},()=>withBoardLock(ctx.folder,args.boardId,()=>removeFrame(ctx,args)))}function moveFrame2(ctx,args){return tracked(ctx,"move_frame",(v)=>({boardId:v.toBoardId,frameId:v.frame.id,screenId:v.frame.screen}),()=>withBoardLocks(ctx.folder,[args.boardId,args.toBoardId],()=>moveFrame(ctx,args)))}var import_react4=__toESM(require_react_development(),1);function findNodeById(root,id){if(!isComponentNode(root))return;if(root.$id===id)return root;for(let child of root.children??[]){let hit=findNodeById(child,id);if(hit)return hit}return}function innerPathResolves(body,innerPath){if(innerPath.startsWith("@"))return findNodeById(body,innerPath.slice(1))!==void 0;let segments=innerPath===""?[]:innerPath.split(".").map(Number),cursor=body;for(let i of segments){if(!cursor||!isComponentNode(cursor)||!cursor.children)return!1;cursor=cursor.children[i]}return cursor!==void 0&&isComponentNode(cursor)}function resolveInnerNode(body,innerPath,snippetId){let target;if(innerPath.startsWith("@"))target=findNodeById(body,innerPath.slice(1));else{let segments=innerPath===""?[]:innerPath.split(".").map(Number);target=body;for(let i of segments){if(!target||!isComponentNode(target)||!target.children){target=void 0;break}target=target.children[i]}}if(!target||!isComponentNode(target))return err(invalidPath(`innerPath "${innerPath}" doesn't resolve to a component inside snippet "${snippetId}"`));return ok(target)}var SUBJECT_REF="__vellooInspectSubject",SUBJECT_TAG="velloo-inspect-subject";function Subject({children}){return import_react4.createElement(SUBJECT_TAG,null,children)}function virtualScreen(screen,tree){return{id:`${screen.id}__inspect`,name:`${screen.name} inspect`,library:screen.library,tree}}function renderIsolated(ctx,screen,node){let subScreen=virtualScreen(screen,node);return renderBodyGuarded(subScreen,registryForScreen2(ctx,subScreen),ctx.folder.snippets)}function markSubject(root,path){if(path.length===0)return{$ref:SUBJECT_REF,children:[root]};if(!isComponentNode(root))return null;let[index,...rest]=path,children=root.children;if(index===void 0||!children)return null;let child=children[index];if(!child)return null;let marked=markSubject(child,rest);if(!marked)return null;let next=[...children];return next[index]=marked,{...root,children:next}}function subjectMarkup(html){let open=`<${SUBJECT_TAG}>`,start=html.indexOf(open);if(start===-1)return null;let end=html.indexOf(`</${SUBJECT_TAG}>`,start);return end===-1?null:html.slice(start+open.length,end)}function renderInPlace(ctx,screen,root,path){let marked=markSubject(root,path);if(!marked)return null;let subScreen=virtualScreen(screen,marked),registry={...registryForScreen2(ctx,subScreen),[SUBJECT_REF]:Subject},{html}=renderBodyGuarded(subScreen,registry,ctx.folder.snippets);return subjectMarkup(html)}function inspectComponent(ctx,screen,node,site,note){let isolated=renderIsolated(ctx,screen,node),bodyHtml=isolated.failures.length>0?renderInPlace(ctx,screen,site.root,site.path)??isolated.html:isolated.html,className=node.props?.className??"",classes=typeof className==="string"?className.trim().split(/\s+/).filter(Boolean):[];return{ref:node.$ref,resolvedProps:{...node.props??{}},classes,bodyHtml,...note?{note}:{}}}async function inspect(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),node=yield*$(getNode(screen.tree,args.path,args.screenId));if(isSnippetInstance(node)){let snippet=ctx.folder.snippets.get(node.$snippet);if(!snippet)return yield*$(err(snippetNotFound(node.$snippet)));let innerPath=args.innerPath??"",body=resolveSnippetBody(node,snippet),inner=yield*$(resolveInnerNode(body,innerPath,node.$snippet)),note=innerPath===""?`Node is the body root of snippet instance "${node.$snippet}". Pass innerPath ("@id" or a dotted index like "0.2") to inspect a deeper node inside the body.`:`Node is inside snippet instance "${node.$snippet}" at innerPath "${innerPath}".`,innerSite=resolveLocator(body,innerPath===""?[]:innerPath)??[];return inspectComponent(ctx,screen,inner,{root:body,path:innerSite},note)}if(args.innerPath!==void 0&&args.innerPath!=="")return yield*$(err(invalidPath(`innerPath "${args.innerPath}" was given but the node at ${JSON.stringify(args.path)} is not a snippet instance`)));if(!isComponentNode(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(args.path)} is not inspectable (expected a component or snippet instance)`)));let site=yield*$(resolve9(screen.tree,args.path,args.screenId));return inspectComponent(ctx,screen,node,{root:screen.tree,path:site},void 0)})}function inspect2(ctx,args){return inspect(ctx,args)}function cloneNode(n){return JSON.parse(JSON.stringify(n))}function cloneScreen(s){return JSON.parse(JSON.stringify(s))}async function addScreen(ctx,args){return DoAsync(async function*(){let baseId=args.id??slugify(args.name,"screen");if(args.id!==void 0&&ctx.folder.screens.has(args.id))return yield*$(err(screenIdConflict(args.id)));let screenId=baseId,attempt=2;while(ctx.folder.screens.has(screenId))if(screenId=`${baseId}-${attempt++}`,attempt>100)return yield*$(err(screenIdExhausted(baseId)));let tree;if(args.fromScreenId!==void 0){let src=yield*$(getScreen(ctx,args.fromScreenId));tree=cloneScreen(src).tree}else if(args.tree!==void 0)tree=cloneNode(args.tree);else tree={$ref:"Card",props:{className:"p-6"}};let screen={id:screenId,name:args.name,...args.route!==void 0?{route:args.route}:{},tree};return await persistScreen(ctx.folder,screenId,screen),ctx.broadcast({type:"screen-changed",screenId}),{screenId,screen}})}async function removeScreen(ctx,args){return DoAsync(async function*(){if(yield*$(getScreen(ctx,args.screenId)),ctx.folder.screens.size<=1)return yield*$(err(lastScreen(args.screenId)));let removedFrames=[];for(let[boardId,board]of ctx.folder.boards){let referencing=board.frames.filter((f)=>f.screen===args.screenId);if(referencing.length===0)continue;let nextBoard={...board,frames:board.frames.filter((f)=>f.screen!==args.screenId)};await persistBoard(ctx.folder,boardId,nextBoard),ctx.broadcast({type:"board-changed",boardId}),removedFrames.push({boardId,frameIds:referencing.map((f)=>f.id)})}return await deletePersistedScreen(ctx.folder,args.screenId),ctx.broadcast({type:"screen-changed",screenId:args.screenId}),{removedScreenId:args.screenId,removedFrames}})}async function setScreenTree(ctx,args){let{screenId}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),prevRef="$ref"in screen.tree?screen.tree.$ref:"(root)",next=cloneScreen(screen);return next.tree=cloneNode(args.tree),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{screenId,replacedRootRef:prevRef}})}async function updateScreen(ctx,args){return DoAsync(async function*(){if(isSnippetTreeId(args.screenId))return yield*$(err(badRequest(`${args.screenId} is a snippet body, not a screen \u2014 rename it with update_snippet.`)));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen);if(args.patch.name!==void 0)next.name=args.patch.name;if(args.patch.route===null)delete next.route;else if(args.patch.route!==void 0)next.route=args.patch.route;return await persistScreen(ctx.folder,args.screenId,next),ctx.broadcast({type:"screen-changed",screenId:args.screenId}),{screen:next}})}function addScreen2(ctx,args){return tracked(ctx,"add_screen",(v)=>({screenId:v.screenId}),()=>addScreen(ctx,args))}function removeScreen2(ctx,args){return tracked(ctx,"remove_screen",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeScreen(ctx,args)))}function updateScreen2(ctx,args){return tracked(ctx,"update_screen",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateScreen(ctx,args)))}function setScreenTree2(ctx,args){return tracked(ctx,"set_screen_tree",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>setScreenTree(ctx,args)))}var PARAM_TAG_REF="velloo:param-tag";async function resolveComponentRefs(ctx,value,scope){let walk=async(v)=>{if(v===null||typeof v!=="object")return ok(v);if(Array.isArray(v)){let out=[];for(let item of v){let r=await walk(item);if(!r.ok)return r;out.push(r.value)}return ok(out)}let record={...v},ref=record.$ref;if(typeof ref==="string"&&record.$repo===void 0&&ref!==PARAM_TAG_REF){let known=ensureKnownComponent(ctx,ref,scope);if(!known.ok){let entry=await appComponent(ctx,ref);if(!entry)return known;record.$ref=entry.name,record.$repo=entry.identity}}for(let[key,nested]of Object.entries(record)){if(key==="$repo")continue;let r=await walk(nested);if(!r.ok)return r;record[key]=r.value}return ok(record)},result=await walk(value);return result.ok?ok(result.value):err(result.error)}async function appComponent(ctx,name){if(!ctx.repo)return null;return(await ctx.repo.catalog().catch(()=>null))?.byId.get(name)??await ctx.repo.resolveName(name).catch(()=>null)}function detectSnippetCycle(root,rootId,registry){let stack=[rootId],visited=new Set([rootId]);function walk(node){if(isSnippetInstance(node)){let id=node.$snippet;if(visited.has(id))return[...stack,id];let inner=registry.get(id);if(!inner)return null;visited.add(id),stack.push(id);let found=walk(inner.tree);if(stack.pop(),visited.delete(id),found)return found;return null}if(node.children)for(let child of node.children){let found=walk(child);if(found)return found}return null}return walk(root)}async function addSnippet(ctx,args){let id=args.id??slugify(args.name,"snippet");if(ctx.folder.snippets.has(id))return err(snippetIdConflict(id));let checked=await resolveComponentRefs(ctx,{tree:args.tree,params:args.params??[]},null);if(!checked.ok)return err(checked.error);let snippet={id,name:args.name,params:checked.value.params,tree:checked.value.tree},registry=new Map(ctx.folder.snippets);registry.set(id,snippet);let cycle=detectSnippetCycle(snippet.tree,id,registry);if(cycle)return err(snippetCycle(id,cycle));let persisted=await persistSnippet(ctx.folder,id,snippet);return ctx.broadcast({type:"snippet-changed",snippetId:id}),ok({snippetId:id,snippet:persisted})}async function instantiateSnippet(ctx,args){return DoAsync(async function*(){let snippet=yield*$(getSnippet(ctx,args.snippetId));yield*$(validateArgs(snippet,args.args??{})),yield*$(validateOverrides(snippet,args.overrides));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolvedParent=yield*$(resolve9(next.tree,args.parentPath,args.screenId)),parent=yield*$(getComponentNode(next.tree,resolvedParent,args.screenId));if(!parent.children)parent.children=[];let idx=args.index??parent.children.length;if(idx<0||idx>parent.children.length)return yield*$(err(invalidPath(`index ${idx} out of range for parent with ${parent.children.length} children`,resolvedParent)));let node={$snippet:snippet.id,...args.id!==void 0?{$id:args.id}:{},...args.extraClassName&&args.extraClassName.trim()!==""?{$extraClassName:args.extraClassName.trim()}:{},...args.args&&Object.keys(args.args).length>0?{args:args.args}:{},...args.overrides&&Object.keys(args.overrides).length>0?{$overrides:args.overrides}:{}};return parent.children.splice(idx,0,node),yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:[...resolvedParent,idx]}})}function validateArgs(snippet,passed){let declared=new Set(snippet.params.map((p)=>p.name)),{missing}=resolveSnippetArgs(snippet,passed),extras=Object.keys(passed).filter((k)=>!declared.has(k));if(missing.length===0&&extras.length===0)return{ok:!0,value:void 0};let parts=[];if(missing.length>0)parts.push(`missing required: ${missing.join(", ")}`);if(extras.length>0)parts.push(`unknown: ${extras.join(", ")}`);return{ok:!1,error:snippetParamMismatch(snippet.id,parts.join("; "),{missing,extras})}}function validateOverrides(snippet,overrides){if(!overrides)return{ok:!0,value:void 0};let bad=Object.keys(overrides).filter((key)=>!innerPathResolves(snippet.tree,key));if(bad.length===0)return{ok:!0,value:void 0};return{ok:!1,error:invalidPath(`overrides target nodes not found in snippet "${snippet.id}": ${bad.join(", ")} \u2014 `+'each key must be the "@id" of a body node, a dotted index path like "0.2", or "" for the root')}}async function removeSnippet(ctx,args){return DoAsync(async function*(){yield*$(getSnippet(ctx,args.snippetId));let{screenIds,snippetIds}=snippetReferencers(ctx.folder,args.snippetId);if(screenIds.length>0||snippetIds.length>0)return yield*$(err(snippetInUse(args.snippetId,screenIds,snippetIds)));return await deletePersistedSnippet(ctx.folder,args.snippetId),ctx.broadcast({type:"snippet-changed",snippetId:args.snippetId}),{removedId:args.snippetId}})}async function updateSnippet(ctx,args){return DoAsync(async function*(){let prev=yield*$(getSnippet(ctx,args.snippetId)),{innerPatch}=args.patch,tree=args.patch.tree??prev.tree;if(innerPatch!==void 0){if(!/^$|^\d+(\.\d+)*$|^@[a-zA-Z][a-zA-Z0-9_-]*$/.test(innerPatch.innerPath))return yield*$(err(invalidPath('innerPath must be a dotted index path like "0.2", an "@id" of a body node, or "" for the root')));if(!innerPathResolves(tree,innerPatch.innerPath))return yield*$(err(invalidPath(`innerPath "${innerPatch.innerPath}" doesn't resolve to a component inside snippet "${args.snippetId}"`)));tree=applySnippetOverrides(tree,{[innerPatch.innerPath]:{props:innerPatch.propPatch}})}let treeChanged=args.patch.tree!==void 0||innerPatch!==void 0;if(treeChanged)tree=yield*$(await resolveComponentRefs(ctx,tree,prev));let params=args.patch.params===void 0?void 0:yield*$(await resolveComponentRefs(ctx,args.patch.params,prev)),next={...prev,...args.patch.name!==void 0?{name:args.patch.name}:{},...params!==void 0?{params}:{},...treeChanged?{tree}:{}};if(args.patch.tree!==void 0){let registry=new Map(ctx.folder.snippets);registry.set(next.id,next);let cycle=detectSnippetCycle(next.tree,next.id,registry);if(cycle)return yield*$(err(snippetCycle(next.id,cycle)))}let persisted=await persistSnippet(ctx.folder,next.id,next);return ctx.broadcast({type:"snippet-changed",snippetId:next.id}),{snippet:persisted}})}async function updateSnippetArgs(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=yield*$(getNode(next.tree,resolved,args.screenId));if(!isSnippetInstance(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(resolved)} is not a snippet instance.`,resolved)));let argPatch=yield*$(await resolveComponentRefs(ctx,args.argPatch,screen)),merged={...node.args??{}};for(let[k,v]of Object.entries(argPatch))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete node.args;else node.args=merged;if(args.extraClassName!==void 0)if(args.extraClassName===null||args.extraClassName.trim()==="")delete node.$extraClassName;else node.$extraClassName=args.extraClassName.trim();return yield*$(await commitScreen(ctx.folder,args.screenId,next,args.gesture)),broadcastTreeChange(ctx,args.screenId),{path:resolved}})}function addSnippet2(ctx,args){return tracked(ctx,"add_snippet",(v)=>({snippetId:v.snippetId}),()=>withSnippetLock(ctx.folder,args.id??args.name,()=>addSnippet(ctx,args)))}function updateSnippet2(ctx,args){return tracked(ctx,"update_snippet",{snippetId:args.snippetId},()=>withSnippetLock(ctx.folder,args.snippetId,()=>updateSnippet(ctx,args)))}function removeSnippet2(ctx,args){return tracked(ctx,"remove_snippet",{snippetId:args.snippetId},()=>withSnippetLock(ctx.folder,args.snippetId,()=>removeSnippet(ctx,args)))}function instantiateSnippet2(ctx,args){return tracked(ctx,"instantiate_snippet",(v)=>({screenId:args.screenId,path:v.path,snippetId:args.snippetId}),()=>withScreenLock(ctx.folder,args.screenId,()=>instantiateSnippet(ctx,args)))}function updateSnippetArgs2(ctx,args){return tracked(ctx,"update_snippet_args",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>updateSnippetArgs(ctx,args)))}async function resolveRepoRef(ctx,ref,explicit){if(explicit){let entry=await catalogEntry(ctx,(e)=>sameIdentity(e.identity,explicit));return{$ref:entry?.name??[explicit.exportName==="default"?ref:explicit.exportName,explicit.member].filter(Boolean).join("."),$repo:withProxy(explicit,entry)}}let entry=await catalogEntry(ctx,(e)=>e.id===ref);return entry?{$ref:entry.name,$repo:withProxy(entry.identity,entry)}:null}async function catalogEntry(ctx,match){if(!ctx.repo)return;try{return(await ctx.repo.catalog()).entries.find(match)}catch{return}}function sameIdentity(a,b){return a.importPath===b.importPath&&a.exportName===b.exportName&&(a.member??"")===(b.member??"")&&(a.app??"")===(b.app??"")}function withProxy(identity,entry){return entry?.proxy&&!identity.proxy?{...identity,proxy:entry.proxy}:identity}async function addNode(ctx,args){let{screenId,parentPath,componentRef}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),known=ensureKnownComponent(ctx,componentRef,screen),repoNode=args.repo||!known.ok?await resolveRepoRef(ctx,componentRef,args.repo):null;if(!repoNode)yield*$(known);let next=cloneScreen(screen),resolvedParent=yield*$(resolve9(next.tree,parentPath,screenId)),parent=yield*$(getComponentNode(next.tree,resolvedParent,screenId));if(!parent.children)parent.children=[];let idx=args.index??parent.children.length;if(idx<0||idx>parent.children.length)return yield*$(err(invalidPath(`index ${idx} out of range for parent with ${parent.children.length} children`,resolvedParent)));let newNode={$ref:repoNode?.$ref??componentRef,...repoNode?.$repo?{$repo:repoNode.$repo}:{},...args.id!==void 0?{$id:args.id}:{},...args.props?{props:args.props}:{},...args.children?{children:args.children}:{},...args.emitAs?{$emitAs:args.emitAs}:{}};return parent.children.splice(idx,0,newNode),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{path:[...resolvedParent,idx]}})}function channelForScreen(ctx,screen){return styleChannelOf(providerForScreen2(ctx,screen),ctx.folder.config.styling?.framework)}function validateStylePayload(channel,style){if(style===null)return ok(null);let wantsString=channel.kind==="tailwind-classname";if(wantsString&&typeof style!=="string")return err(badRequest(`\`style\` on the "${channel.kind}" channel expects a className string (got ${typeof style}).`));if(!wantsString&&(typeof style!=="object"||Array.isArray(style)))return err(badRequest(`\`style\` on the "${channel.kind}" channel expects an object of ${channel.prop} properties (got ${Array.isArray(style)?"array":typeof style}).`));return ok(null)}function applyStyleToProps(channel,props,style){let prop=channel.prop;if(style===null)return delete props[prop],props;if(typeof style==="string"){let trimmed=style.trim();if(trimmed==="")delete props[prop];else props[prop]=trimmed;return props}let current=props[prop],merged=current&&typeof current==="object"&&!Array.isArray(current)?{...current}:{};for(let[k,v]of Object.entries(style))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete props[prop];else props[prop]=merged;return props}function repoStyleChannel(accepted,style,ref){let props=accepted??["className","style"];if(style===null){let prop=props.find((name)=>["className","sx","style"].includes(name))??"style";return ok(STYLE_CHANNELS_BY_PROP[prop]??STYLE_CHANNELS.style)}if(typeof style==="string")return props.includes("className")?ok(STYLE_CHANNELS["tailwind-classname"]):err(badRequest(`${ref} takes no className; set its own props or \`style\` (${props.join(", ")||"none"}).`));if(props.includes("sx"))return ok(STYLE_CHANNELS.sx);if(props.includes("style"))return ok(STYLE_CHANNELS.style);return err(badRequest(`${ref} declares no style prop to take an object; set its own props instead.`))}var STYLE_CHANNELS_BY_PROP={className:STYLE_CHANNELS["tailwind-classname"],sx:STYLE_CHANNELS.sx,style:STYLE_CHANNELS.style};async function updateProps(ctx,args){return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),screenChannel=channelForScreen(ctx,screen),catalog=ctx.repo?await ctx.repo.catalog().catch(()=>null):null,channelFor=(node,style)=>node.$repo?repoStyleChannel(catalog?.byKey.get(repoKey(node.$repo))?.styleProps,style,node.$ref):ok(screenChannel);for(let{path,style}of args.patches){if(style===void 0)continue;let located=resolveWithSnippetHint(ctx,screen.tree,path,args.screenId),target=located.ok?getComponentNode(screen.tree,located.value,args.screenId):null,channel=target?.ok?yield*$(channelFor(target.value,style)):screenChannel;yield*$(validateStylePayload(channel,style))}let next=cloneScreen(screen),paths=[];for(let{path,propPatch,style}of args.patches){let resolved=yield*$(resolveWithSnippetHint(ctx,next.tree,path,args.screenId)),node=yield*$(getComponentNode(next.tree,resolved,args.screenId)),channel=style===void 0?screenChannel:yield*$(channelFor(node,style)),checked=yield*$(await resolveComponentRefs(ctx,propPatch??{},screen)),merged={...node.props??{}};for(let[k,v]of Object.entries(checked))if(v===null)delete merged[k];else merged[k]=v;if(style!==void 0)applyStyleToProps(channel,merged,style);if(Object.keys(merged).length===0)delete node.props;else node.props=merged;paths.push(resolved)}return yield*$(await commitScreen(ctx.folder,args.screenId,next,args.gesture)),broadcastTreeChange(ctx,args.screenId),{paths}})}async function applyClasses(ctx,args){let className=args.classes.trim();return updateProps(ctx,{screenId:args.screenId,patches:[{path:args.path,propPatch:{className:className===""?null:className}}],gesture:args.gesture})}function isAncestor(ancestor,descendant){if(ancestor.length>=descendant.length)return!1;return ancestor.every((seg,i)=>descendant[i]===seg)}async function moveNode(ctx,args){let{screenId,fromPath,toParent}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),next=cloneScreen(screen),resolvedFrom=yield*$(resolve9(next.tree,fromPath,screenId)),resolvedTo=yield*$(resolve9(next.tree,toParent,screenId));if(resolvedFrom.length===0)return yield*$(err(invalidMove("Cannot move the screen root.")));if(isAncestor(resolvedFrom,resolvedTo)||JSON.stringify(resolvedFrom)===JSON.stringify(resolvedTo))return yield*$(err(invalidMove("Cannot move a node into itself or its descendant.")));let fromParentInfo=parentOf(resolvedFrom);if(!fromParentInfo)return yield*$(err(invalidPath("no parent",resolvedFrom)));let fromParent=pathAt(next.tree,fromParentInfo.parent);if(!fromParent||!isComponentNode(fromParent)||!fromParent.children)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolvedFrom)}`,resolvedFrom)));if(fromParentInfo.index>=fromParent.children.length)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolvedFrom)}`,resolvedFrom)));let[moved]=fromParent.children.splice(fromParentInfo.index,1);if(fromParent.children.length===0)delete fromParent.children;if(!moved)return yield*$(err(invalidPath("internal: detach lost node during move",resolvedFrom)));let adjustedToParent=resolvedTo,sameParent=JSON.stringify(fromParentInfo.parent)===JSON.stringify(resolvedTo),toIdx=args.toIndex??1/0;if(sameParent&&toIdx>fromParentInfo.index)toIdx=Math.max(0,toIdx-1);else if(resolvedTo.length>fromParentInfo.parent.length&&isAncestor(fromParentInfo.parent,resolvedTo)&&(resolvedTo[fromParentInfo.parent.length]??-1)>fromParentInfo.index)adjustedToParent=[...resolvedTo],adjustedToParent[fromParentInfo.parent.length]=adjustedToParent[fromParentInfo.parent.length]-1;let target=pathAt(next.tree,adjustedToParent);if(!target||!isComponentNode(target))return yield*$(err(invalidPath(`No parent at ${JSON.stringify(adjustedToParent)}`,adjustedToParent)));if(!target.children)target.children=[];if(toIdx=Math.min(toIdx,target.children.length),toIdx<0)toIdx=0;return target.children.splice(toIdx,0,moved),yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{newPath:[...adjustedToParent,toIdx]}})}async function overrideSnippetProps(ctx,args){return DoAsync(async function*(){if(!/^$|^\d+(\.\d+)*$|^@[a-zA-Z][a-zA-Z0-9_-]*$/.test(args.innerPath))return yield*$(err(invalidPath('innerPath must be a dotted index path like "0.2", an "@id" of a node inside the body, or "" for the root')));let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=pathAt(next.tree,resolved);if(!node||!isSnippetInstance(node))return yield*$(err(invalidPath(`Node at ${JSON.stringify(resolved)} is not a snippet instance`,resolved)));let instance=node,snippet=ctx.folder.snippets.get(instance.$snippet);if(!snippet)return yield*$(err(snippetNotFound(instance.$snippet)));if(!innerPathResolves(snippet.tree,args.innerPath))return yield*$(err(invalidPath(`innerPath "${args.innerPath}" doesn't resolve to a component inside snippet "${instance.$snippet}"`)));let overrides={...instance.$overrides??{}},merged={...overrides[args.innerPath]?.props??{}};for(let[k,v]of Object.entries(args.propPatch))if(v===null)delete merged[k];else merged[k]=v;if(Object.keys(merged).length===0)delete overrides[args.innerPath];else overrides[args.innerPath]={props:merged};if(Object.keys(overrides).length===0)delete instance.$overrides;else instance.$overrides=overrides;return yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:resolved,innerPath:args.innerPath,overrides}})}async function removeNode(ctx,args){let{screenId,path}=args;return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,path,screenId));if(resolved.length===0){if(!isComponentNode(next.tree))return yield*$(err(invalidPath("Cannot remove the screen root.",resolved)));let cleared=next.tree.children?.length??0;return delete next.tree.children,yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{removedRef:`(cleared ${cleared} child node${cleared===1?"":"s"} of the screen root \u2014 the root itself remains)`}}let parentInfo=parentOf(resolved);if(!parentInfo)return yield*$(err(invalidPath("no parent",resolved)));let parent=pathAt(next.tree,parentInfo.parent);if(!parent||!isComponentNode(parent)||!parent.children)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolved)}`,resolved)));if(parentInfo.index>=parent.children.length)return yield*$(err(invalidPath(`No node at path ${JSON.stringify(resolved)}`,resolved)));let[removed]=parent.children.splice(parentInfo.index,1);if(parent.children.length===0)delete parent.children;return yield*$(await commitScreen(ctx.folder,screenId,next)),broadcastTreeChange(ctx,screenId),{removedRef:describeRemoved(removed)}})}function describeRemoved(node){if(!node)return"?";if(isComponentNode(node))return node.$ref;if("$snippet"in node)return`@${node.$snippet}`;return`$param:${node.$param}`}async function setNodeId(ctx,args){if(args.id!==null){let parsed=NodeIdSchema.safeParse(args.id);if(!parsed.success)return{ok:!1,error:badRequest(`Invalid node id ${JSON.stringify(args.id)}`,parsed.error.issues)}}return DoAsync(async function*(){let screen=yield*$(getScreen(ctx,args.screenId)),next=cloneScreen(screen),resolved=yield*$(resolve9(next.tree,args.path,args.screenId)),node=yield*$(getNode(next.tree,resolved,args.screenId));if(!isComponentNode(node)&&!isSnippetInstance(node))return yield*$({ok:!1,error:invalidPath(`Node at ${JSON.stringify(resolved)} cannot carry an id (param refs are anonymous).`,resolved)});if(args.id===null)delete node.$id;else node.$id=args.id;return yield*$(await commitScreen(ctx.folder,args.screenId,next)),broadcastTreeChange(ctx,args.screenId),{path:resolved,id:args.id}})}function addNode2(ctx,args){return tracked(ctx,"add_node",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>addNode(ctx,args)))}function updateProps2(ctx,args){return tracked(ctx,"update_props",(v)=>({screenId:args.screenId,...v.paths[0]?{path:v.paths[0]}:{}}),()=>withScreenLock(ctx.folder,args.screenId,()=>updateProps(ctx,args)))}function moveNode2(ctx,args){return tracked(ctx,"move_node",(v)=>({screenId:args.screenId,path:v.newPath}),()=>withScreenLock(ctx.folder,args.screenId,()=>moveNode(ctx,args)))}function removeNode2(ctx,args){return tracked(ctx,"remove_node",{screenId:args.screenId},()=>withScreenLock(ctx.folder,args.screenId,()=>removeNode(ctx,args)))}function applyClasses2(ctx,args){return tracked(ctx,"apply_classes",(v)=>({screenId:args.screenId,...v.paths[0]?{path:v.paths[0]}:{}}),()=>withScreenLock(ctx.folder,args.screenId,()=>applyClasses(ctx,args)))}function setNodeId2(ctx,args){return tracked(ctx,"set_node_id",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>setNodeId(ctx,args)))}function overrideSnippetProps2(ctx,args){return tracked(ctx,"override_snippet_props",(v)=>({screenId:args.screenId,path:v.path}),()=>withScreenLock(ctx.folder,args.screenId,()=>overrideSnippetProps(ctx,args)))}function findExtensionReferences(ctx,extensionId){let out=[];function visit(node,screenId,path){if(isComponentNode(node)){if(node.$ref===extensionId)out.push({screenId,path:path.join(".")});if(node.children)for(let i=0;i<node.children.length;i++){let child=node.children[i];if(child)visit(child,screenId,[...path,i])}}}for(let[screenId,screen]of ctx.folder.screens)visit(screen.tree,screenId,[]);for(let[snippetId,snippet]of ctx.folder.snippets)visit(snippet.tree,`snippet:${snippetId}`,[]);return out}function unknownHostApp(ctx,app){if(!app)return null;let known=Object.keys(ctx.folder.config.hostApps??{});if(known.includes(app))return null;return{kind:"BadRequest",message:`app "${app}" is not a key of config.hostApps.`,hint:known.length?`Known apps: ${known.join(", ")}. Omit \`app\` to use the default host app.`:"This folder has no config.hostApps \u2014 omit `app` to use the default host app."}}async function addExtension(ctx,args){let existing=ctx.folder.config.extensions??{};if(args.id in existing)return err(extensionIdConflict(args.id));let badApp=unknownHostApp(ctx,args.app);if(badApp)return err(badApp);for(let p of args.props){let parsed=ExtensionPropDescriptorSchema.safeParse(p);if(!parsed.success)return err({kind:"InvalidExtensionProp",message:`Invalid extension prop schema: ${parsed.error.issues[0]?.message??"unknown"}`,extensionId:args.id,prop:p.name})}let extension=ExtensionSchema.parse({importPath:args.importPath,category:args.category,description:args.description,props:args.props,origin:"agent",render:args.render,app:args.app,fit:args.fit}),shadowed=args.id in ctx.defaultProvider.registry?args.id:void 0,nextConfig={...ctx.folder.config,extensions:{...existing,[args.id]:extension}};await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"add_extension",{extension:args.id});let result={id:args.id,extension};if(shadowed)result.shadowedLibraryComponent=shadowed;if(extension.render==="live"){let warning=resolveLiveImportWarning(ctx.folder.root,ctx.folder.config,args.importPath,extension.app);if(warning)result.liveResolveWarning=warning}return ok(result)}async function updateExtension(ctx,args){let existing=ctx.folder.config.extensions??{},prev=existing[args.id];if(!prev)return err(extensionNotFound(args.id));let badApp=unknownHostApp(ctx,args.patch.app);if(badApp)return err(badApp);if(args.patch.props)for(let p of args.patch.props){let parsed=ExtensionPropDescriptorSchema.safeParse(p);if(!parsed.success)return err({kind:"InvalidExtensionProp",message:`Invalid extension prop schema: ${parsed.error.issues[0]?.message??"unknown"}`,extensionId:args.id,prop:p.name})}let next=ExtensionSchema.parse({...prev,...args.patch.importPath!==void 0?{importPath:args.patch.importPath}:{},...args.patch.props!==void 0?{props:args.patch.props}:{},...args.patch.category!==void 0?{category:args.patch.category}:{},...args.patch.description!==void 0?{description:args.patch.description}:{},...args.patch.render!==void 0?{render:args.patch.render}:{},...args.patch.app!==void 0?{app:args.patch.app}:{},...args.patch.fit!==void 0?{fit:args.patch.fit}:{}}),nextConfig={...ctx.folder.config,extensions:{...existing,[args.id]:next}};await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"update_extension",{extension:args.id});let result={id:args.id,extension:next};if(next.render==="live"){let warning=resolveLiveImportWarning(ctx.folder.root,ctx.folder.config,next.importPath,next.app);if(warning)result.liveResolveWarning=warning}return ok(result)}async function removeExtension(ctx,args){let existing=ctx.folder.config.extensions??{};if(!(args.id in existing))return err(extensionNotFound(args.id));let refs=findExtensionReferences(ctx,args.id);if(refs.length>0)return err(extensionInUse(args.id,refs));let{[args.id]:_,...rest}=existing,extensions=Object.keys(rest).length>0?rest:void 0,nextConfig={...ctx.folder.config,extensions};return await persistConfig(ctx.folder,nextConfig),ctx.broadcast({type:"config-changed"}),emitActivity(ctx,"remove_extension",{extension:args.id}),ok({id:args.id})}function summarize(node,path){if(isComponentNode(node)){let props=node.props??{},children=props.children;return{path,kind:"component",ref:node.$ref,...nodeId(node)?{id:nodeId(node)}:{},...typeof props.className==="string"?{className:props.className}:{},...typeof children==="string"?{textPreview:children.slice(0,80)}:{},childCount:node.children?.length??0}}if(isSnippetInstance(node))return{path,kind:"snippet",ref:node.$snippet,...nodeId(node)?{id:nodeId(node)}:{},childCount:0};return{path,kind:"param",childCount:0}}async function findNodes(ctx,args){let screenR=getScreen(ctx,args.screenId);if(!screenR.ok)return screenR;let limit=args.limit??50,matches=[],total=0;function consider(node,path){let props=isComponentNode(node)?node.props??{}:{};if(args.ref!==void 0&&(!isComponentNode(node)||node.$ref!==args.ref))return;if(args.snippetId!==void 0&&(!isSnippetInstance(node)||node.$snippet!==args.snippetId))return;if(args.id!==void 0&&nodeId(node)!==args.id)return;if(args.classContains!==void 0){let cls=props.className;if(typeof cls!=="string"||!cls.includes(args.classContains))return}if(args.prop!==void 0){if(!(args.prop in props))return;if(args.propValue!==void 0&&props[args.prop]!==args.propValue)return}if(total+=1,matches.length<limit)matches.push(summarize(node,path))}function walk(node,path){if(consider(node,path),isComponentNode(node)&&node.children)node.children.forEach((child,i)=>{walk(child,[...path,i])})}return walk(screenR.value.tree,[]),ok({matches,total})}async function updateSnippetInstance(ctx,plan){return DoAsync(async function*(){let applied=[],path;if(plan.args)path=(yield*$(await updateSnippetArgs2(ctx,plan.args))).path,applied.push("args");if(plan.override)path=(yield*$(await overrideSnippetProps2(ctx,plan.override))).path,applied.push("override");return{path:path??[],applied}})}var invalidColor=(reason,hint)=>({kind:"InvalidColor",reason,...hint!==void 0?{hint}:{}}),invalidThemePath=(reason,hint)=>({kind:"InvalidThemePath",reason,...hint!==void 0?{hint}:{}}),unknownPreset=(presetName,hint)=>({kind:"UnknownPreset",presetName,...hint!==void 0?{hint}:{}}),themeBadRequest=(message,issues)=>({kind:"BadRequest",message,...issues!==void 0?{issues}:{}});var MUTATION_STATUS={ScreenNotFound:404,BoardNotFound:404,FrameNotFound:404,BoardGroupNotFound:404,SnippetNotFound:404,IdNotFound:404,AnnotationNotFound:404,CanvasNoteNotFound:404,ExtensionNotFound:404,UnknownComponent:422,SnippetParamMismatch:422,SnippetCycle:422,InvalidExtensionProp:422,InvalidPath:400,InvalidMove:400,ScreenIdConflict:400,ScreenIdExhausted:400,BoardIdConflict:400,BoardIdExhausted:400,FrameIdConflict:400,SnippetIdConflict:400,BadRequest:400,LastScreen:409,SnippetInUse:409,IdConflict:409,AnnotationConflict:409,ExtensionIdConflict:409,ExtensionInUse:409},THEME_STATUS={UnknownPreset:404,InvalidColor:400,InvalidThemePath:400,BadRequest:400,BulkTokensInvalid:400};function mutationToHttp(c,error){return c.json({error},MUTATION_STATUS[error.kind])}function themeToHttp(c,error){return c.json({error},THEME_STATUS[error.kind])}async function readBody(c){try{return await c.req.json()}catch{return}}function makeBoundRoute(b){return function(schema,handler){return async(c)=>{let body=await readBody(c),parsed=schema.safeParse(body);if(!parsed.success)return b.toHttp(c,b.badRequest("Request body failed validation.",parsed.error.issues));let result=await withActor({source:"canvas"},()=>handler(parsed.data,b.ctxFor()));return result.ok?c.json(result.value):b.toHttp(c,result.error)}}}function makeRoute(ctxFor){return makeBoundRoute({ctxFor,badRequest,toHttp:mutationToHttp})}function makeThemeRoute(ctxFor){return makeBoundRoute({ctxFor,badRequest:themeBadRequest,toHttp:themeToHttp})}function createAnnotationsRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.get("/:screenId",(c)=>{let ctx=ctxFor(),screenId=c.req.param("screenId"),screen=ctx.folder.screens.get(screenId),list=(ctx.folder.annotations.get(screenId)??[]).map((a)=>{let resolved=screen?resolveLocator(screen.tree,a.target.locator):null;return{...a,resolved}});return c.json({annotations:list})}),r.post("/add",route(AddAnnotationBody,(a,ctx)=>addAnnotation2(ctx,a))),r.post("/update",route(UpdateAnnotationBody,(a,ctx)=>updateAnnotation2(ctx,a))),r.post("/remove",route(RemoveAnnotationBody,(a,ctx)=>removeAnnotation2(ctx,a))),r}function createNotesRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.get("/:boardId",(c)=>{let ctx=ctxFor(),boardId=c.req.param("boardId"),list=(ctx.folder.notes.get(boardId)??[]).map((note)=>{if(!note.attachment)return note;let screen=ctx.folder.screens.get(note.attachment.screenId),resolved=screen?resolveLocator(screen.tree,note.attachment.locator):null;return{...note,resolved}});return c.json({notes:list})}),r.post("/add",route(AddNoteBody,(a,ctx)=>addNote2(ctx,a))),r.post("/update",route(UpdateNoteBody,(a,ctx)=>updateNote2(ctx,a))),r.post("/remove",route(RemoveNoteBody,(a,ctx)=>removeNote2(ctx,a))),r}function createMutateRouter(ctxFor){let r=new Hono2,route=makeRoute(ctxFor);return r.post("/update_props",route(UpdatePropsBody,(a,ctx)=>updateProps2(ctx,a))),r.post("/apply_classes",route(ApplyClassesBody,(a,ctx)=>applyClasses2(ctx,a))),r.post("/set_node_id",route(SetNodeIdBody,(a,ctx)=>setNodeId2(ctx,a))),r.post("/remove_node",route(RemoveNodeBody,(a,ctx)=>removeNode2(ctx,a))),r.post("/add_board",route(AddBoardBody,(a,ctx)=>addBoard2(ctx,a))),r.post("/update_board",route(UpdateBoardBody,(a,ctx)=>updateBoard2(ctx,a))),r.post("/remove_board",route(RemoveBoardBody,(a,ctx)=>removeBoard2(ctx,a))),r.post("/reorder_boards",route(ReorderBoardsBody,(a,ctx)=>reorderBoards2(ctx,a))),r.post("/add_board_group",route(AddBoardGroupBody,(a,ctx)=>addBoardGroup2(ctx,a))),r.post("/update_board_group",route(UpdateBoardGroupBody,(a,ctx)=>updateBoardGroup2(ctx,a))),r.post("/remove_board_group",route(RemoveBoardGroupBody,(a,ctx)=>removeBoardGroup2(ctx,a))),r.post("/reorder_board_groups",route(ReorderBoardGroupsBody,(a,ctx)=>reorderBoardGroups2(ctx,a))),r.post("/update_viewport_presets",route(UpdateViewportPresetsBody,(a,ctx)=>updateViewportPresets2(ctx,a))),r.post("/update_defaults",route(UpdateDefaultsBody,(a,ctx)=>updateDefaults2(ctx,a))),r.post("/update_design_name",route(UpdateDesignNameBody,(a,ctx)=>updateDesignName2(ctx,a))),r.post("/update_codegen",route(UpdateCodegenBody,(a,ctx)=>updateCodegen2(ctx,a))),r.post("/update_feedback",route(UpdateFeedbackBody,(a,ctx)=>updateFeedback2(ctx,a))),r.post("/add_frame",route(AddFrameBody,(a,ctx)=>addFrame2(ctx,a))),r.post("/update_frame",route(UpdateFrameBody,(a,ctx)=>updateFrames2(ctx,a))),r.post("/remove_frame",route(RemoveFrameBody,(a,ctx)=>removeFrame2(ctx,a))),r.post("/move_frame",route(MoveFrameBody,(a,ctx)=>moveFrame2(ctx,a))),r.post("/update_snippet",route(UpdateSnippetBody,(a,ctx)=>updateSnippet2(ctx,a))),r.post("/update_snippet_args",route(UpdateSnippetArgsBody,(a,ctx)=>updateSnippetArgs2(ctx,a))),r}function createPreflightRouter(ctxFor){let r=new Hono2;return r.get("/",(c)=>{let folder=ctxFor().folder,source={folder,providers:ctxFor().providers,defaultProvider:ctxFor().defaultProvider},kind=c.req.query("kind"),id=c.req.query("id");if(kind!==void 0||id!==void 0){if(kind!=="frame"&&kind!=="board"&&kind!=="screen")return c.json({error:"kind must be frame, board, or screen"},400);if(!id)return c.json({error:"id is required with kind"},400);let screens=screensForExportTarget(folder,kind,id);if(screens.length===0)return c.json({error:`no ${kind} with id "${id}"`},404);return c.json({failures:preflightScreens(source,screens)})}let boards=c.req.query("boards"),screens=boards===void 0||boards===""?[...folder.screens.values()]:screensForBoards(folder,boards.split(","));return c.json({failures:preflightScreens(source,screens)})}),r}function createPublishRouter(runner){let app=new Hono2,noPublisher="this server cannot publish \u2014 run the canvas through the velloo CLI",unavailable={error:"this server cannot publish \u2014 run the canvas through the velloo CLI"};app.get("/status",(c)=>{if(!runner)return c.json({state:"unavailable"});return c.json(runner.state())}),app.get("/targets",async(c)=>{let closed=(access)=>c.json({ready:!1,access,teams:[],slots:[]});if(!runner)return closed("signed-out");let access=await runner.access();if(access.state!=="ready")return closed(access.state);let[teams,blocked,destinationResult]=await Promise.all([runner.teams().catch(()=>[]),runner.blocked().catch(()=>null),runner.destinations().then((value)=>({value})).catch((error)=>({error:error instanceof Error?error.message:String(error),signInRequired:asSignInRequired(error)}))]);if("error"in destinationResult){if(destinationResult.signInRequired)return closed(destinationResult.signInRequired);return c.json({ready:!0,access:"ready",teams,...blocked?{blocked}:{},slots:[],destinationError:destinationResult.error})}return c.json({ready:!0,access:"ready",teams,...blocked?{blocked}:{},...destinationResult.value})}),app.post("/",async(c)=>{if(!runner)return c.json(unavailable,503);let body=await c.req.json().catch(()=>({})),boardIds=Array.isArray(body.boardIds)?body.boardIds.filter((id)=>typeof id==="string"):[],teamOnly=body.teamOnly===!0,visibility=teamOnly||body.visibility==="private"?"private":"public",title=typeof body.title==="string"?body.title:void 0,teamId=typeof body.teamId==="string"&&body.teamId?body.teamId:void 0,publicComments=typeof body.publicComments==="boolean"?body.publicComments:void 0;if(typeof body.password==="string"&&body.password.length<3)return c.json({error:"password must be at least 3 characters"},400);let password=typeof body.password==="string"?body.password:void 0,rawDestination=body.destination,destination=rawDestination?.mode==="new"?{mode:"new"}:rawDestination?.mode==="update"&&typeof rawDestination.slug==="string"&&(typeof rawDestination.expectedVersionId==="string"||rawDestination.expectedVersionId===null)?{mode:"update",slug:rawDestination.slug,expectedVersionId:rawDestination.expectedVersionId}:null;if(!destination)return c.json({error:"choose a publish destination"},400);let started=runner.start({boardIds,visibility,destination,...title?{title}:{},...password?{password}:{},...teamId?{teamId}:{},...teamOnly?{teamOnly}:{},...publicComments!==void 0?{publicComments}:{}});if(!started)return c.json({error:"a publish is already running for this folder"},409);return c.json(started,202)});let cloudFail=(c,error)=>{let message=error instanceof Error?error.message:String(error),kind=asSignInRequired(error)?"LoggedOut":"HttpFailure";return c.json({error:{kind,message}},502)},noPublisherFail=(c)=>c.json({error:{kind:"HttpFailure",message:"this server cannot publish \u2014 run the canvas through the velloo CLI"}},503);app.get("/published",async(c)=>{if(!runner)return noPublisherFail(c);try{return c.json({boards:await runner.published()})}catch(error){return cloudFail(c,error)}}),app.delete("/published/:slug",async(c)=>{if(!runner)return noPublisherFail(c);try{return await runner.unpublish(c.req.param("slug")),c.json({ok:!0})}catch(error){return cloudFail(c,error)}});let guestRoute=(handler)=>async(c)=>{if(!runner)return noPublisherFail(c);try{return await handler(c,runner)}catch(error){return cloudFail(c,error)}};return app.get("/published/:slug/guests",guestRoute(async(c,run)=>c.json({guests:await run.guests.list(c.req.param("slug")??"")}))),app.post("/published/:slug/guests",guestRoute(async(c,run)=>{let body=await c.req.json().catch(()=>({})),email=typeof body.email==="string"?body.email.trim():"";if(!email)return c.json({error:{kind:"InvalidRequest",message:"enter an email address"}},400);let name=typeof body.name==="string"?body.name.trim():"",invited=await run.guests.invite(c.req.param("slug")??"",{email,...name?{name}:{}});return c.json(invited,201)})),app.post("/published/:slug/guests/:guestId/resend",guestRoute(async(c,run)=>c.json(await run.guests.resend(c.req.param("slug")??"",c.req.param("guestId")??"")))),app.post("/published/:slug/guests/:guestId/link",guestRoute(async(c,run)=>c.json({guestUrl:await run.guests.link(c.req.param("slug")??"",c.req.param("guestId")??"")}))),app.delete("/published/:slug/guests/:guestId",guestRoute(async(c,run)=>(await run.guests.remove(c.req.param("slug")??"",c.req.param("guestId")??""),c.json({ok:!0})))),app.post("/reset",(c)=>(runner?.reset(),c.json({ok:!0}))),app}import{randomBytes}from"crypto";var SHOWCASES={Button:()=>({$ref:"Button",props:{children:"Button"}}),Badge:()=>({$ref:"Badge",props:{children:"Badge"}}),Heading:()=>({$ref:"Heading",props:{level:2,children:"Heading"}}),Text:()=>({$ref:"Text",props:{children:"Body text"}}),Label:()=>({$ref:"Card",props:{className:"flex flex-row items-center gap-2 ring-0 shadow-none bg-transparent p-0"},children:[{$ref:"Checkbox",props:{id:"showcase-label-cb",defaultChecked:!0}},{$ref:"Label",props:{htmlFor:"showcase-label-cb",children:"Accept terms"}}]}),Input:()=>({$ref:"Input",props:{placeholder:"you@company.com"}}),Textarea:()=>({$ref:"Textarea",props:{placeholder:"Write a message\u2026"}}),Switch:()=>({$ref:"Switch",props:{defaultChecked:!0}}),Checkbox:()=>({$ref:"Checkbox",props:{defaultChecked:!0}}),Slider:()=>({$ref:"Slider",props:{defaultValue:[40],className:"w-40"}}),Progress:()=>({$ref:"Progress",props:{value:66,className:"w-48"}}),Skeleton:()=>({$ref:"Skeleton",props:{className:"h-6 w-40"}}),Separator:()=>({$ref:"Separator",props:{className:"w-40"}}),Toggle:()=>({$ref:"Toggle",props:{variant:"outline",defaultPressed:!0,children:"Bold"}}),Calendar:()=>({$ref:"Calendar"}),Icon:()=>({$ref:"Icon",props:{name:"Sparkles",size:24}}),Placeholder:()=>({$ref:"Placeholder",props:{kind:"image",aspect:"16/9"}}),Divider:()=>({$ref:"Divider",props:{label:"or"}}),Avatar:()=>({$ref:"Avatar",children:[{$ref:"AvatarFallback",props:{children:"AB"}}]}),Alert:()=>({$ref:"Alert",children:[{$ref:"AlertTitle",props:{children:"Heads up!"}},{$ref:"AlertDescription",props:{children:"You can drop this component on a board."}}]}),Card:()=>({$ref:"Card",props:{className:"p-4 flex flex-col gap-1"},children:[{$ref:"Text",props:{className:"text-sm font-medium",children:"Card title"}},{$ref:"Text",props:{className:"text-xs text-muted-foreground",children:"A flexible container for content."}}]}),Tabs:()=>({$ref:"Tabs",props:{defaultValue:"overview"},children:[{$ref:"TabsList",children:[{$ref:"TabsTrigger",props:{value:"overview",children:"Overview"}},{$ref:"TabsTrigger",props:{value:"activity",children:"Activity"}},{$ref:"TabsTrigger",props:{value:"settings",children:"Settings"}}]}]}),Breadcrumb:()=>({$ref:"Breadcrumb",children:[{$ref:"BreadcrumbList",children:[{$ref:"BreadcrumbItem",children:[{$ref:"BreadcrumbLink",props:{children:"Home"}}]},{$ref:"BreadcrumbSeparator"},{$ref:"BreadcrumbItem",children:[{$ref:"BreadcrumbPage",props:{children:"Library"}}]}]}]}),Pagination:()=>({$ref:"Pagination",children:[{$ref:"PaginationContent",children:[{$ref:"PaginationPrevious"},{$ref:"PaginationItem",children:[{$ref:"PaginationLink",props:{children:"1"}}]},{$ref:"PaginationItem",children:[{$ref:"PaginationLink",props:{isActive:!0,children:"2"}}]},{$ref:"PaginationNext"}]}]}),Accordion:()=>({$ref:"Accordion",props:{type:"single",collapsible:!0,defaultValue:"a"},children:[{$ref:"AccordionItem",props:{value:"a"},children:[{$ref:"AccordionTrigger",props:{children:"What is Velloo?"}},{$ref:"AccordionContent",props:{children:"A local design canvas for solo devs."}}]}]}),RadioGroup:()=>({$ref:"RadioGroup",props:{defaultValue:"a"},children:[{$ref:"Card",props:{className:"flex items-center gap-2 ring-0 shadow-none p-0 bg-transparent"},children:[{$ref:"RadioGroupItem",props:{value:"a",id:"showcase-r1"}},{$ref:"Label",props:{htmlFor:"showcase-r1",children:"Option"}}]}]}),ToggleGroup:()=>({$ref:"ToggleGroup",props:{type:"single",defaultValue:"left"},children:[{$ref:"ToggleGroupItem",props:{value:"left",children:"Left"}},{$ref:"ToggleGroupItem",props:{value:"center",children:"Center"}},{$ref:"ToggleGroupItem",props:{value:"right",children:"Right"}}]}),Select:()=>({$ref:"Select",children:[{$ref:"SelectTrigger",props:{className:"w-40"},children:[{$ref:"SelectValue",props:{placeholder:"Choose\u2026"}}]}]}),Toaster:()=>({$ref:"Toaster",props:{position:"bottom-right"}}),Dialog:()=>({$ref:"Dialog",children:[{$ref:"DialogContent",props:{className:"w-72"},children:[{$ref:"DialogHeader",children:[{$ref:"DialogTitle",props:{children:"Confirm change"}},{$ref:"DialogDescription",props:{children:"Modal dialog content shown when triggered."}}]},{$ref:"DialogFooter",children:[{$ref:"Button",props:{variant:"outline",size:"sm",children:"Cancel"}},{$ref:"Button",props:{size:"sm",children:"Save"}}]}]}]}),AlertDialog:()=>({$ref:"AlertDialog",children:[{$ref:"AlertDialogContent",props:{className:"w-72"},children:[{$ref:"AlertDialogHeader",children:[{$ref:"AlertDialogTitle",props:{children:"Delete file?"}},{$ref:"AlertDialogDescription",props:{children:"This action can't be undone."}}]},{$ref:"AlertDialogFooter",children:[{$ref:"AlertDialogCancel",props:{size:"sm",children:"Cancel"}},{$ref:"AlertDialogAction",props:{variant:"destructive",size:"sm",children:"Delete"}}]}]}]}),Popover:()=>({$ref:"Popover",children:[{$ref:"PopoverContent",props:{className:"w-56"},children:[{$ref:"PopoverHeader",children:[{$ref:"PopoverTitle",props:{children:"Popover content"}},{$ref:"PopoverDescription",props:{children:"Anchored to a trigger."}}]}]}]}),DropdownMenu:()=>({$ref:"DropdownMenu",children:[{$ref:"DropdownMenuContent",props:{className:"w-44"},children:[{$ref:"DropdownMenuItem",props:{children:"Profile"}},{$ref:"DropdownMenuItem",props:{children:"Settings"}},{$ref:"DropdownMenuSeparator"},{$ref:"DropdownMenuItem",props:{variant:"destructive",children:"Log out"}}]}]}),Tooltip:()=>({$ref:"Tooltip",children:[{$ref:"TooltipContent",props:{children:"Helpful hint"}}]}),Sheet:()=>({$ref:"Sheet",children:[{$ref:"SheetContent",props:{side:"right",className:"h-56 w-64 rounded-lg p-4"},children:[{$ref:"SheetHeader",children:[{$ref:"SheetTitle",props:{children:"Slide-in panel"}},{$ref:"SheetDescription",props:{children:"Drawer mounted on a screen edge."}}]}]}]}),Collapsible:()=>({$ref:"Collapsible",props:{defaultOpen:!0},children:[{$ref:"CollapsibleTrigger",children:[{$ref:"Button",props:{variant:"outline",size:"sm",children:"Toggle"}}]},{$ref:"CollapsibleContent",children:[{$ref:"Card",props:{className:"mt-2 p-2 ring-0 shadow-none bg-muted text-xs"},children:[{$ref:"Text",props:{className:"text-xs",children:"Hidden content revealed."}}]}]}]}),Carousel:()=>({$ref:"Carousel",props:{className:"w-56"},children:[{$ref:"CarouselContent",children:[{$ref:"CarouselItem",children:[{$ref:"Card",props:{className:"p-6 bg-primary text-primary-foreground"},children:[{$ref:"Text",props:{className:"text-sm font-medium",children:"Slide 1"}}]}]}]},{$ref:"CarouselPrevious"},{$ref:"CarouselNext"}]}),ScrollArea:()=>({$ref:"ScrollArea",props:{className:"h-24 w-48 rounded-md border border-border p-2"},children:[{$ref:"Card",props:{className:"flex flex-col gap-1 ring-0 shadow-none bg-transparent p-0"},children:Array.from({length:6},(_,i)=>({$ref:"Text",props:{className:"text-xs",children:`Item ${i+1}`}}))}]}),Layer:()=>({$ref:"Card",props:{className:"relative h-24 w-40 bg-muted rounded-md overflow-hidden"},children:[{$ref:"Layer",props:{top:"1rem",left:"1rem"},children:[{$ref:"Card",props:{className:"px-2 py-0.5 rounded-full bg-primary text-primary-foreground ring-0 shadow-none"},children:[{$ref:"Text",props:{className:"text-xs font-medium",children:"Layer"}}]}]}]}),Gradient:()=>({$ref:"Gradient",props:{preset:"sunset",className:"h-20 w-full rounded-md"}}),Image:()=>({$ref:"Image",props:{src:"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 9'><rect width='16' height='9' fill='%23ddd'/></svg>",aspect:"16/9",fill:!1}}),SVG:()=>({$ref:"SVG",props:{viewBox:"0 0 24 24",content:"<circle cx='12' cy='12' r='8' fill='currentColor' opacity='0.2'/><circle cx='12' cy='12' r='4' fill='currentColor'/>",className:"h-12 w-12 text-primary"}}),Chart:()=>({$ref:"Chart",props:{kind:"line",data:[{x:0,y:4},{x:1,y:6},{x:2,y:5},{x:3,y:9},{x:4,y:7},{x:5,y:12}],className:"h-20 w-full"}})};function buildShowcaseTree(componentRef,propOverrides){let isIconSize=typeof propOverrides?.size==="string"&&propOverrides.size.startsWith("icon"),builder=SHOWCASES[componentRef];if(builder){let tree=builder();if(propOverrides&&Object.keys(propOverrides).length>0)tree.props={...tree.props??{},...propOverrides};if(isIconSize&&componentRef==="Button")delete tree.props?.children,tree.children=[{$ref:"Icon",props:{name:"Plus",size:14}}];return tree}return{$ref:componentRef,props:{children:componentRef,...propOverrides??{}}}}var AMBER="#FFAB1F",CORAL="#FF6F4D",DARK={bg:"#0D0C0A",fg:"#F7F2E6",muted:"#A59C8D",border:"#26221C",code:"#15130E"},LIGHT={bg:"#F7F2E6",fg:"#141210",muted:"#6F665A",border:"#E2D8C4",code:"#FFFDF7"};function escapeHtml(value){return value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function renderErrorDocument(page){let c=page.dark?DARK:LIGHT;return`<!doctype html>
188
188
  <html lang="en"><head><meta charset="utf-8">
189
189
  <meta name="viewport" content="width=device-width,initial-scale=1">
190
190
  <meta name="${RENDER_ERROR_META}" content="${escapeHtml(page.title)}">
@@ -677,7 +677,7 @@ ${close} );`:" return children;";return[...lines,body,"}",""].join(`
677
677
  `)}catch(err){this.broken=!0,console.error(`velloo trace: recording disabled after write failure: ${String(err)}`)}}writePending(){if(this.broken)return;try{writeFileSync(join41(this.dir,"pending.json"),JSON.stringify([...this.pending.values()]))}catch{}}build(seq,input){let rec={seq,ts:new Date().toISOString(),tool:input.tool,durationMs:Math.round(input.durationMs),ok:!0,params:clampStrings(input.params,MAX_PARAM_STR)};if(input.sessionId)rec.sessionId=input.sessionId;if(input.error!==void 0)return rec.ok=!1,rec.error=serializeError(input.error),rec;let{text,images,isError}=this.splitResult(seq,input.result);if(text!==void 0)rec.text=text;if(images.length)rec.images=images;if(isError)rec.isError=!0,rec.ok=!1;return rec}splitResult(seq,result){let images=[],texts=[],envelope=result,isError=envelope?.isError===!0,content=envelope?.content;if(Array.isArray(content)){let imgIdx=0;for(let item of content){if(!item||typeof item!=="object")continue;let type=item.type;if(type==="text"){let t=item.text;if(typeof t==="string")texts.push(t)}else if(type==="image"){let ref=this.writeImage(seq,imgIdx++,item);if(ref)images.push(ref)}}}return{text:texts.length?texts.join(`
678
678
  `):void 0,images,isError}}writeImage(seq,idx,item){if(typeof item.data!=="string")return null;let mimeType=typeof item.mimeType==="string"?item.mimeType:"image/png",buf=Buffer.from(item.data,"base64"),file=`assets/${seq}-${idx}.${extForMime(mimeType)}`;return mkdirSync(this.assetsDir,{recursive:!0}),writeFileSync(join41(this.dir,file),buf),{file,mimeType,bytes:buf.byteLength}}}function newTapeId(){let d=new Date,p=(n)=>String(n).padStart(2,"0");return`${`${d.getFullYear()}${p(d.getMonth()+1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`}-${randomUUID3().slice(0,4)}`}function createTraceRecorder(folderRoot){if(!traceEnabled())return null;let tapeId=newTapeId(),dir=join41(folderRoot,".velloo","trace",tapeId);try{mkdirSync(dir,{recursive:!0});let meta={tapeId,startedAt:new Date().toISOString(),folder:folderRoot,pid:process.pid};return writeFileSync(join41(dir,"meta.json"),`${JSON.stringify(meta,null,2)}
679
679
  `),console.error(`velloo trace: recording MCP session to ${dir}`),new TraceRecorder(dir)}catch(err){return console.error(`velloo trace: could not start recorder: ${String(err)}`),null}}function withCallRecording(mcp,recorder){let original=mcp.registerTool.bind(mcp),patched=(name,config,cb)=>{let handler=cb;return original(name,config,async(args,extra)=>{let sessionId=extra?.sessionId,seq=recorder.start({tool:name,params:args,sessionId});try{let result=await handler(args,extra);return recorder.end(seq,{result}),result}catch(err){throw recorder.end(seq,{error:err}),err}})};return mcp.registerTool=patched,mcp}var INSTRUCTION_PARTS=["You are working on a Velloo design folder: a code-shaped design canvas whose components are the project's real component library. Designs are static \u2014 click handlers, routing and forms are no-ops.","","**The design folder is tool-owned.** Screens, boards, snippets and the theme live as JSON files inside it, but never read or edit those files by hand \u2014 every operation goes through these tools, which hold the write lock, validation and history. The user can watch the design render live with `velloo run`.","",'**Start by reading, once.** `list_components` (one namespace for components, extensions, and snippets \u2014 the default index groups families by what they are for and carries usage notes; `filter` to a family for its prop names, `mode: "full"` for examples), `component_status` for exact/adapted/fallback canvas fidelity when it matters, `get_theme` for the palette and tokens, `list_boards` for boards and frames. For an existing screen, `get_screen mode: "outline"` before pulling the full JSON.',"","**Use the library's own components \u2014 the catalog is larger than you expect.** Before building a pattern out of `Box` + `Text`, check the index for a family that already is it: a labelled input with help and error text is `Field`, a search box with an inline icon is `InputGroup`, a settings/file row is `Item`, a \"nothing here yet\" panel is `Empty`, joined buttons are `ButtonGroup`. A family listing `pieces` is composed of them (`Field` \u21D2 `FieldLabel` / `FieldDescription` / `FieldError`). Hand-rolling one of these loses the library's spacing, states and dark-mode behavior, and `emit_code` then hands the developer a div stack instead of the component their app already has.","","**Three customization layers** stack additively:"," - **Libraries** are the baseline component palette. A folder registers N (`config.libraries`); each screen pins one via `screen.library`, and component ids resolve against that library only."," - **Extensions** add wholly new components the library doesn't have \u2014 the app's own `DataTable`, a brand `Hero`. Register with `add_extension`; they emit a real import. Additive customization, NOT compositions."," - **Snippets** compose existing components into named subtrees with typed params \u2014 the tool for repeated structure (FeatureCard, NavRow, PricingTier). `compose` resolves their PascalCase names in the same JSX tag namespace as components and extensions.","","**Styling is framework-native.** `update_props`'s `style` channel routes your payload to whatever the screen's framework uses \u2014 a Tailwind `className` string, an `sx` object, or a plain `style` object \u2014 so one verb works everywhere. Prefer theme tokens over hard-coded values in any channel; on a Tailwind folder prefer semantic tokens (`bg-background`, `text-muted-foreground`, `bg-primary`) over raw palette colors, because only semantic tokens theme-flip in dark mode.","","**EFFICIENCY \u2014 build in big strokes, read once.** A screen should take a few dozen tool calls, not hundreds; over-calling is the most common failure. (1) **Compose whole subtrees** \u2014 `compose` accepts familiar nested JSX, so build a whole feature card in ONE call rather than node-by-node. (2) **`batch` groups a sequence of metadata/property mutations into one round-trip**, atomic by default: on the first error every touched resource rolls back and the result reports `rolledBack: true` with the failing call. (3) **Work from memory** \u2014 do NOT re-`get_screen` or re-`list_boards` before every edit; to re-locate a node use `find_nodes`, which returns its path. (4) **Don't thrash** \u2014 plan the structure before building it, and edit a snippet through `update_snippet`'s `innerPatch` rather than redefining its body.","",'**Think in ids, not paths.** Anywhere a tool asks for a `path` (or `parentPath`, `fromPath`, `toParent`), pass a stable id reference like `"@hero-cta"`. Assign ids at creation (`id: "hero-cta"`) for anything you might touch again. Number paths are positional and break when siblings move; treat them as an implementation detail you get from `find_nodes` (`set_node_id` retrofits one).',"",'**Verify before declaring done.** Mutations return focused class, theme, and render diagnostics \u2014 a `render/component-threw` diagnostic at some path means the canvas shows a placeholder there instead of the component you asked for, and the message names what it needs (usually a parent it must sit inside); `screenshot mode: "compare"` renders light and dark side by side and returns a full-screen diagnostic pass. `emit_code` repeats that full check at the handoff boundary. See velloo://guide/verification.',"","**Make it distinctive.** Default library + Inter + one indigo reads as template. Set a display face and a typeset early via `set_theme` \u2014 one call re-proportions every screen \u2014 then reach for real art and confident color. See velloo://guide/art.","","**Read the guide before doing the thing.** The advertised `velloo://guide/*` resources carry the detail this brief deliberately omits; fetch the relevant one before using an unfamiliar capability."],GUIDED_INSTRUCTION_PARTS=["You are working on a Velloo design folder: a code-shaped design canvas backed by the project's real component library.","","**The design folder is tool-owned.** Never read or edit its JSON files by hand. Use `operation_schema` before an unfamiliar operation, `call_velloo` for one native operation, and `run_velloo_plan` for up to eight related calls.","","Build in large strokes with `compose` and `batch`, keep stable node ids, prefer theme tokens, and avoid repeatedly re-reading unchanged state. Use `component_status` before claiming an app component renders exactly. Verify design work with `screenshot`; use `compare_to_url` for code-to-design fidelity and `emit_code` at implementation handoff.","","The operation enum is the whole catalogue available to this session. Failed fa\xE7ade calls include the exact native operation schema needed to correct them.","","**Read the guide before doing the thing.** The `velloo://guide/*` resources carry the detail this brief omits \u2014 verification, theming, porting, art direction, comment threads. Fetch the relevant one before using an unfamiliar capability."],FEEDBACK_INSTRUCTION="**Sending product feedback**: this folder opted into the `send_feedback` tool. Reach for it when you hit friction with **Velloo itself** \u2014 a confusing instruction, a missing capability, a tool that misbehaved, a bug \u2014 or when the user asks to send feedback. ALWAYS show the user the exact `body` and get their go-ahead before calling; never send unprompted, even when you originated the idea. Fire sparingly \u2014 one report per distinct issue, never repeated. NEVER include the user's design content, code, or file/repo paths; describe the issue in your own words. This is feedback about Velloo, not about the design.";function buildInstructions(feedbackEnabled,canvasUrl,intro=[],openComments=0,hostTailwindMajor=null,bareFolder=!1,surface={mode:"full"},designs=null){let parts=[...intro,...surface.mode==="guided"?GUIDED_INSTRUCTION_PARTS:INSTRUCTION_PARTS];if(bareFolder)parts.unshift("**Bare folder.** This design has no boards yet. Setup order before composing UI: (1) style the theme with `set_theme` (or `import_theme` to match an existing app); (2) `add_board`; (3) add screens and frames, then design.","");if(designs)parts.unshift(...designsInstruction(designs),"");if(hostTailwindMajor===3)parts.push("","**The host app is on Tailwind v3** (the canvas itself always compiles v4). Prefer classes spelled the same in both majors; avoid v4-only utilities (`inset-shadow-*`, `text-shadow-*`, `bg-linear-*` angles, container-query variants, `starting:`). Mutations flag incompatible classes at their paths, and `emit_code` returns a `tailwindV3Compat` rename list (e.g. v4 `shadow-sm` \u21D2 v3 `shadow`) to apply when writing app code. `emit_theme` detects the v3 target and emits `velloo-theme.css` + a `velloo.preset` instead of a v4 globals.css.");if(canvasUrl)parts.push("",`**The live canvas** is running at ${canvasUrl} \u2014 give the user this URL up front so they can open it and watch your edits render in real time. (They can also open a canvas any time with \`velloo run\`.)`);if(openComments>0){let one=openComments===1;parts.push("",`**${one?"1 open visual feedback thread is":`${openComments} open visual feedback threads are`} waiting on you.** ${one?"It is a change":"Each one is a change"} the user is expecting. Read ${one?"it":"them"} with the \`list_comment_threads\` operation, make the requested ${one?"change":"changes"}, then reply and resolve with \`update_comment_thread\`. The full loop is velloo://guide/comments.`)}if(feedbackEnabled)parts.push("",FEEDBACK_INSTRUCTION);return parts.join(`
680
- `)}function buildMcpServer(ctx,jit,bundler,canvasBundler,comments,assetOrigin,cloud,surface=DEFAULT_MCP_SURFACE,designs=null){let feedbackEnabled=Boolean(ctx.folder.config.feedback?.enabled&&cloud?.url),channel=styleChannelOf(ctx.defaultProvider,ctx.folder.config.styling?.framework),channelKind=channel.kind,intro=[...ctx.defaultProvider.mcpIntro?.(channelKind)??[],...repoInstruction(ctx)],hostTailwindMajor=channel.needsTailwindJit?detectTailwindMajor(hostAppRootFrom(ctx.folder.root,ctx.folder.config.hostApp)):null,openComments=comments.countOpenSync(),bareFolder=ctx.folder.boards.size===0,mcp=new McpServer(MCP_SERVER_INFO,{instructions:buildInstructions(feedbackEnabled,assetOrigin&&trimTrailingSlashes(assetOrigin),intro,openComments,hostTailwindMajor,bareFolder,surface,designs)}),toolSurface=applyMcpToolSurface(mcp,surface);applyToolPolicy(mcp);let recorder=createTraceRecorder(ctx.folder.root);if(recorder)withCallRecording(mcp,recorder);if(registerDiscoveryTools(mcp,ctx),registerComposeTool(mcp,ctx,jit),registerMutationTools(mcp,ctx,jit),registerInspectTool(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerThemeTools(mcp,ctx),registerEmitTools(mcp,ctx,jit),registerScreenshotTool(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerRepoTools(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerExtensionTools(mcp,ctx),registerNoteTools(mcp,ctx),registerAssetTools(mcp,ctx),registerBatchTool(mcp,ctx,jit),registerCaptureTools(mcp,ctx),feedbackEnabled&&cloud)registerFeedbackTool(mcp,ctx,cloud);if(registerCommentTools(mcp,comments),registerGenerateTools(mcp,ctx,cloud??{url:""}),designs)registerDesignTools(mcp,ctx,designs);return toolSurface.finish(),registerGuideResources(mcp),mcp}async function readBody2(req){let chunks=[];for await(let chunk of req)chunks.push(chunk);if(chunks.length===0)return;let raw=Buffer.concat(chunks).toString("utf8");if(raw.length===0)return;return JSON.parse(raw)}function isInitializeRequest2(body){if(!body||typeof body!=="object")return!1;return(Array.isArray(body)?body:[body]).some((m)=>m&&typeof m==="object"&&m.method==="initialize")}function trimTrailingSlashes(url){let end=url.length;while(end>0&&url[end-1]==="/")end--;return url.slice(0,end)}function sendJson(res,status,value){res.statusCode=status,res.setHeader("Content-Type","application/json"),res.end(JSON.stringify(value))}async function createMcpServer(ctx,opts){let sessions=new Map,httpServer=createHttpServer(async(req,res)=>{if(!requestIsLocal({host:req.headers.host,origin:req.headers.origin})){sendJson(res,403,{error:"forbidden: request is not from a local origin"});return}if(!req.url?.startsWith("/mcp")){sendJson(res,404,{error:"expected /mcp"});return}let sessionId=req.headers["mcp-session-id"],sessionIdStr=Array.isArray(sessionId)?sessionId[0]:sessionId;try{if(req.method==="POST"){let body=await readBody2(req),session=sessionIdStr?sessions.get(sessionIdStr):void 0;if(!session){if(!isInitializeRequest2(body)){sendJson(res,400,{error:"missing or unknown mcp-session-id; send `initialize` first"});return}let transport=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID4(),enableJsonResponse:!0,onsessioninitialized:(id)=>{sessions.set(id,{transport,server})}}),parsedSurface=parseMcpSurfaceUrl(req.url);if(!parsedSurface.ok){sendJson(res,400,{error:parsedSurface.error});return}let server=buildMcpServer(ctx,opts.jit,opts.bundler,opts.canvasBundler,opts.comments,opts.assetOrigin,opts.cloud,parsedSurface.selection,await sessionDesigns(ctx.folder.root,ctx.folder.config.name,parseMcpSessionUrl(req.url)));transport.onclose=()=>{if(transport.sessionId)sessions.delete(transport.sessionId);server.close().catch(()=>{return})},await server.connect(transport),session={transport,server}}let active=session;await withActor({source:"mcp",session:sessionIdStr??active.transport.sessionId},()=>active.transport.handleRequest(req,res,body));return}if(req.method==="GET"||req.method==="DELETE"){if(!sessionIdStr||!sessions.has(sessionIdStr)){sendJson(res,400,{error:"missing or unknown mcp-session-id"});return}let session=sessions.get(sessionIdStr);if(!session){sendJson(res,400,{error:"session lost"});return}await session.transport.handleRequest(req,res);return}sendJson(res,405,{error:`method ${req.method} not allowed`})}catch(err){if(console.error("velloo mcp: handler failed:",err),!res.headersSent)sendJson(res,500,{error:"internal error"})}});await new Promise((resolve,reject)=>{httpServer.once("error",reject),httpServer.listen(opts.port,opts.host,()=>{httpServer.removeListener("error",reject),resolve()})});let addr=httpServer.address(),boundPort=typeof addr==="object"&&addr!==null&&"port"in addr?addr.port:opts.port;return{url:`http://${opts.host}:${boundPort}/mcp`,port:boundPort,sessions:()=>sessions.size,async close(){for(let session of sessions.values())await session.transport.close().catch(()=>{return}),await session.server.close().catch(()=>{return});sessions.clear(),await new Promise((resolve)=>httpServer.close(()=>resolve()))}}}async function createStdioMcpServer(ctx,opts){let server=buildMcpServer(ctx,opts.jit,opts.bundler,opts.canvasBundler,opts.comments,opts.assetOrigin,opts.cloud,opts.surface??DEFAULT_MCP_SURFACE,await sessionDesigns(ctx.folder.root,ctx.folder.config.name,{switchable:!1,pick:void 0})),transport=new StdioServerTransport;return await server.connect(transport),{async close(){await transport.close().catch(()=>{return}),await server.close().catch(()=>{return})}}}function repoInstruction(ctx){let repo=ctx.repo;if(!repo)return[];let hostRoot=repo.host(void 0).hostRoot;if(!existsSync14(join42(hostRoot,"package.json")))return[];return["**The app's own components are placeable.** `list_components` shelves them first, under Repo, from what the app's routes render. Compose them by id (`<Tabs>`, `<Tabs.List>`; a name that collides with a Velloo primitive is qualified, e.g. `<Mantine.Button>`) rather than rebuilding them from primitives. They render for real inside the folder's preview entry \u2014 run `preview_status` once before designing; `set_preview_entry` fixes a missing provider or stylesheet. Style one through the props it declares, and fill a `slot` prop with an element (`leftSection={<IconBolt />}`); `emit_code` returns their exact `repoImports`.",...repo.recipes(void 0).flatMap((recipe)=>recipe.notes),""]}class PublishRunner{publisher;host;current={state:"idle"};warnings=[];constructor(publisher,host){this.publisher=publisher;this.host=host}state(){return this.current}running(){return this.current.state==="running"}teams(){return this.publisher.teams()}destinations(){return this.publisher.destinations(this.host())}access(){return this.publisher.access()}published(){return this.publisher.published()}unpublish(slug){return this.publisher.unpublish(slug)}start(request){if(this.current.state==="running")return null;let startedAt=new Date().toISOString();return this.warnings=[],this.current={state:"running",step:"start",message:"starting",startedAt,warnings:this.warnings},this.publisher.run(this.host(),request,({step,message,capture})=>{if(this.current.state!=="running"||this.current.startedAt!==startedAt)return;this.current={state:"running",step,message,startedAt,warnings:this.warnings,...capture?{capture}:{}}},(message)=>{this.warnings.push(message)}).then((result)=>{this.current={state:"done",result,warnings:this.warnings,finishedAt:new Date().toISOString()}}).catch((err)=>{let access=asSignInRequired(err),boardLimit=asBoardLimit(err);this.current={state:"error",message:err instanceof Error?err.message:String(err),...access?{signInRequired:access}:{},...boardLimit?{boardLimit}:{},warnings:this.warnings,finishedAt:new Date().toISOString()}}),this.current}reset(){if(this.current.state!=="running")this.current={state:"idle"}}}import{resolve as resolve11,sep as sep9}from"path";import{existsSync as existsSync16,readFileSync as readFileSync16,statSync as statSync3}from"fs";import{dirname as dirname19,join as join44}from"path";import{existsSync as existsSync15,readFileSync as readFileSync14,statSync as statSync2}from"fs";import{dirname as dirname18,join as join43}from"path";var UNION_MEMBER=String.raw`(?:'[^']*'|"[^"]*"|-?\d+(?:\.\d+)?)`,LITERAL_ALIAS=new RegExp(String.raw`type\s+([A-Z][\w$]*)\s*=\s*\|?\s*(${UNION_MEMBER}(?:\s*\|\s*${UNION_MEMBER})*)\s*;`,"g"),MAX_DECLARATION_FILES=1200,MAX_DECLARATION_BYTES=1e6;function emptyIndex(){return{props:new Map,literalAliases:new Map,staticMembers:new Map,variantTables:new Map}}function indexDeclarations(source,index){let code=keepDocComments(source);for(let match of code.matchAll(/(?:export\s+)?(?:declare\s+)?interface\s+([A-Z][\w$]*Props)\b(?:<[^>{]*>)?\s*(?:extends\s+([^{]+))?\{/g)){let open=(match.index??0)+match[0].length-1,close=matchBrace3(code,open);if(close===-1)continue;let name=match[1]??"";if(!index.props.has(name))index.props.set(name,{body:code.slice(open+1,close),extends:splitTopLevel(match[2]??"",",").map((s)=>s.trim().replace(/<[\s\S]*$/,"")).filter(Boolean)})}for(let match of code.matchAll(/(?:export\s+)?(?:declare\s+)?type\s+([A-Z][\w$]*Props)\b(?:<[^>=]*>)?\s*=\s*\{/g)){let open=(match.index??0)+match[0].length-1,close=matchBrace3(code,open);if(close===-1)continue;let name=match[1]??"";if(!index.props.has(name))index.props.set(name,{body:code.slice(open+1,close),extends:[]})}for(let match of code.matchAll(/(?:function\s+([A-Z][\w$]*)\s*(?:<[^>(]*>)?\s*|const\s+([A-Z][\w$]*)\s*=\s*(?:(?:React\.)?(?:memo|forwardRef)\s*\(\s*)?(?:function\s*[\w$]*\s*)?)\(/g)){let name=`${match[1]??match[2]??""}Props`;if(index.props.has(name))continue;let annotation=parameterType(code,(match.index??0)+match[0].length);if(annotation?.body!==void 0)index.props.set(name,{body:annotation.body,extends:annotation.extends??[]});else if(annotation?.named&&annotation.named!==name)index.props.set(name,{body:"",extends:[annotation.named]})}for(let match of code.matchAll(LITERAL_ALIAS)){let values=literalUnion(match[2]??"");if(values)index.literalAliases.set(match[1]??"",values)}for(let match of code.matchAll(/(?:const|let)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:cva|tv|cx?Variants?)\s*\(/g)){let call=code.slice(match.index??0,(match.index??0)+20000),variantsAt=call.search(/\bvariants\s*:\s*\{/);if(variantsAt<0)continue;let open=call.indexOf("{",variantsAt),close=matchBrace3(call,open);if(close<0)continue;let variants=new Map;for(let[name,body]of topLevelObjectKeys(call.slice(open+1,close))){let keys=body?topLevelObjectKeys(body).map(([key])=>key):[];if(keys.length>0)variants.set(name,keys)}let defaults=new Map,defaultsAt=call.search(/\bdefaultVariants\s*:\s*\{/);if(defaultsAt>=0){let dOpen=call.indexOf("{",defaultsAt),dClose=matchBrace3(call,dOpen);for(let m of call.slice(dOpen+1,dClose).matchAll(/([A-Za-z_$][\w$]*)\s*:\s*['"]([^'"]+)['"]/g))defaults.set(m[1]??"",m[2]??"")}if(variants.size>0)index.variantTables.set(match[1]??"",{variants,defaults})}for(let match of code.matchAll(/staticComponents:\s*\{([^}]*)\}/g)){let owner=[...code.slice(Math.max(0,(match.index??0)-4000),match.index).matchAll(/declare\s+const\s+([A-Z][\w$]*)\s*:/g)].at(-1)?.[1],members=[...(match[1]??"").matchAll(/([A-Z][\w$]*)\s*:/g)].map((m)=>m[1]??"");if(owner&&members.length>0&&!index.staticMembers.has(owner))index.staticMembers.set(owner,members)}}function indexPackageDeclarations(packageName,hostRoot){let index=emptyIndex(),entry=packageTypesEntry(packageName,hostRoot);if(!entry)return index;let queue=[entry],seen=new Set;while(queue.length>0&&seen.size<MAX_DECLARATION_FILES){let file=queue.shift();if(seen.has(file))continue;seen.add(file);let source;try{if(statSync2(file).size>MAX_DECLARATION_BYTES)continue;source=readFileSync14(file,"utf8")}catch{continue}indexDeclarations(source,index);for(let match of source.matchAll(/(?:export|import)[^'"]*?from\s*['"](\.[^'"]+)['"]/g)){let next=resolveDeclaration(dirname18(file),match[1]??"");if(next)queue.push(next)}}return index}function packageExportNames(packageName,hostRoot){let names=new Set,entry=packageTypesEntry(packageName,hostRoot);if(!entry)return names;let queue=[entry],seen=new Set;while(queue.length>0&&seen.size<MAX_DECLARATION_FILES){let file=queue.shift();if(seen.has(file))continue;seen.add(file);let source;try{source=readFileSync14(file,"utf8")}catch{continue}for(let match of source.matchAll(/export\s+(?:declare\s+)?(?:const|function|class|let|var)\s+([A-Z][\w$]*)/g))names.add(match[1]??"");for(let match of source.matchAll(/export\s*(?:type\s*)?\{([^}]*)\}/g))for(let part of(match[1]??"").split(",")){let exported=part.trim().split(/\s+as\s+/).at(-1)?.trim()??"";if(/^[A-Z][\w$]*$/.test(exported))names.add(exported)}for(let match of source.matchAll(/export\s*\*\s*from\s*['"](\.[^'"]+)['"]/g)){let next=resolveDeclaration(dirname18(file),match[1]??"");if(next)queue.push(next)}}return names}function packageTypesEntry(packageName,hostRoot){let pkgJsonPath;try{pkgJsonPath=Bun.resolveSync(`${packageName}/package.json`,hostRoot)}catch{return null}let root=dirname18(pkgJsonPath);try{let pkg=JSON.parse(readFileSync14(pkgJsonPath,"utf8")),candidates=[pkg.types,pkg.typings],dot=pkg.exports?.["."];if(dot&&typeof dot==="object"){let d=dot;candidates.push(d.types,d.import?.types,d.require?.types)}for(let candidate of candidates)if(typeof candidate==="string"&&existsSync15(join43(root,candidate)))return join43(root,candidate)}catch{return null}for(let guess of["index.d.ts","dist/index.d.ts","lib/index.d.ts"])if(existsSync15(join43(root,guess)))return join43(root,guess);return null}function resolveDeclaration(dir,specifier){let base=join43(dir,specifier.replace(/\.(m|c)?js$/,""));for(let candidate of[`${base}.d.ts`,`${base}.d.mts`,`${base}.d.cts`,`${base}.ts`,`${base}.tsx`,join43(base,"index.d.ts"),join43(base,"index.d.mts"),join43(base,"index.ts")])if(existsSync15(candidate))return candidate;return null}function propsFor(name,index){let interfaceName=`${name.replace(/\./g,"")}Props`,root=index.props.get(interfaceName);if(!root)return null;let own=new Map(parseMembers(root.body,index).map((prop)=>[prop.name,prop])),inherited=new Map,visit=(decl,depth)=>{for(let parent of decl.extends){let base=index.props.get(parent);if(!base||depth>=4)continue;visit(base,depth+1);for(let prop of parseMembers(base.body,index))if(!own.has(prop.name))inherited.set(prop.name,{...prop,inherited:!0})}};visit(root,0);let variants=index.literalAliases.get(`${name.replace(/\./g,"")}Variant`);if(variants)inherited.delete("variant"),own.set("variant",{name:"variant",type:variants.map((v)=>JSON.stringify(v)).join(" | "),optional:!0,control:"enum",enumValues:variants,serializable:!0});return[...own.values(),...inherited.values()]}function parseMembers(body,index){let out=[];for(let raw of memberChunks(body)){let text=raw.trim();if(!text)continue;let doc=/\/\*\*([\s\S]*?)\*\//.exec(text)?.[1],member=text.replace(/\/\*\*[\s\S]*?\*\//g,"").trim(),match=/^(?:readonly\s+)?(['"]?)([A-Za-z_$][\w$-]*)\1(\?)?\s*:\s*([\s\S]+?)[,;]?$/.exec(member);if(!match){let method=/^([A-Za-z_$][\w$]*)(\?)?\s*(?:<[^>]*>)?\s*(\([\s\S]*\))\s*:\s*([\s\S]+?)[,;]?$/.exec(member);if(method){let type=`${method[3]} => ${method[4]}`.replace(/\s+/g," ").trim();out.push(describe4(method[1]??"",type,Boolean(method[2]),doc,index))}continue}let name=match[2]??"",type=(match[4]??"").replace(/\s+/g," ").trim();out.push(describe4(name,type,Boolean(match[3]),doc,index))}return out}var MEMBER_START=/^(?:\/\*\*[\s\S]*?\*\/\s*)?(?:readonly\s+)?(?:['"]?[A-Za-z_$][\w$-]*['"]?\??\s*:|[A-Za-z_$][\w$]*\??\s*(?=[(<]))/;function memberChunks(body){let starts=[],depth=0,quote=null,boundary=!0;for(let i=0;i<body.length;i++){let ch=body[i]??"";if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}let head=depth===0&&boundary&&!/\s/.test(ch)?MEMBER_START.exec(body.slice(i,i+400)):null;if(head){starts.push(i),boundary=!1,i+=head[0].length-1;continue}if(body.startsWith("/*",i)){let end=body.indexOf("*/",i+2);i=end===-1?body.length:end+1;continue}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if("([{<".includes(ch))depth++;else if(")]}>".includes(ch)&&!(ch===">"&&body[i-1]==="="))depth=Math.max(0,depth-1);if(depth===0&&(ch===";"||ch===","||ch===`
680
+ `)}function buildMcpServer(ctx,jit,bundler,canvasBundler,comments,assetOrigin,cloud,surface=DEFAULT_MCP_SURFACE,designs=null){let feedbackEnabled=Boolean(ctx.folder.config.feedback?.enabled&&cloud?.url),channel=styleChannelOf(ctx.defaultProvider,ctx.folder.config.styling?.framework),channelKind=channel.kind,intro=[...ctx.defaultProvider.mcpIntro?.(channelKind)??[],...repoInstruction(ctx)],hostTailwindMajor=channel.needsTailwindJit?detectTailwindMajor(hostAppRootFrom(ctx.folder.root,ctx.folder.config.hostApp)):null,openComments=comments.countOpenSync(),bareFolder=ctx.folder.boards.size===0,mcp=new McpServer(MCP_SERVER_INFO,{instructions:buildInstructions(feedbackEnabled,assetOrigin&&trimTrailingSlashes(assetOrigin),intro,openComments,hostTailwindMajor,bareFolder,surface,designs)}),toolSurface=applyMcpToolSurface(mcp,surface);applyToolPolicy(mcp);let recorder=createTraceRecorder(ctx.folder.root);if(recorder)withCallRecording(mcp,recorder);if(registerDiscoveryTools(mcp,ctx),registerComposeTool(mcp,ctx,jit),registerMutationTools(mcp,ctx,jit),registerInspectTool(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerThemeTools(mcp,ctx),registerEmitTools(mcp,ctx,jit),registerScreenshotTool(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerRepoTools(mcp,ctx,jit,bundler,canvasBundler,assetOrigin),registerExtensionTools(mcp,ctx),registerNoteTools(mcp,ctx),registerAssetTools(mcp,ctx),registerBatchTool(mcp,ctx,jit),registerCaptureTools(mcp,ctx),feedbackEnabled&&cloud)registerFeedbackTool(mcp,ctx,cloud);if(registerCommentTools(mcp,comments),registerGenerateTools(mcp,ctx,cloud??{url:""}),designs)registerDesignTools(mcp,ctx,designs);return toolSurface.finish(),registerGuideResources(mcp),mcp}async function readBody2(req){let chunks=[];for await(let chunk of req)chunks.push(chunk);if(chunks.length===0)return;let raw=Buffer.concat(chunks).toString("utf8");if(raw.length===0)return;return JSON.parse(raw)}function isInitializeRequest2(body){if(!body||typeof body!=="object")return!1;return(Array.isArray(body)?body:[body]).some((m)=>m&&typeof m==="object"&&m.method==="initialize")}function trimTrailingSlashes(url){let end=url.length;while(end>0&&url[end-1]==="/")end--;return url.slice(0,end)}function sendJson(res,status,value){res.statusCode=status,res.setHeader("Content-Type","application/json"),res.end(JSON.stringify(value))}async function createMcpServer(ctx,opts){let sessions=new Map,httpServer=createHttpServer(async(req,res)=>{if(!requestIsLocal({host:req.headers.host,origin:req.headers.origin})){sendJson(res,403,{error:"forbidden: request is not from a local origin"});return}if(!req.url?.startsWith("/mcp")){sendJson(res,404,{error:"expected /mcp"});return}let sessionId=req.headers["mcp-session-id"],sessionIdStr=Array.isArray(sessionId)?sessionId[0]:sessionId;try{if(req.method==="POST"){let body=await readBody2(req),session=sessionIdStr?sessions.get(sessionIdStr):void 0;if(!session){if(!isInitializeRequest2(body)){sendJson(res,400,{error:"missing or unknown mcp-session-id; send `initialize` first"});return}let transport=new StreamableHTTPServerTransport({sessionIdGenerator:()=>randomUUID4(),enableJsonResponse:!0,onsessioninitialized:(id)=>{sessions.set(id,{transport,server})}}),parsedSurface=parseMcpSurfaceUrl(req.url);if(!parsedSurface.ok){sendJson(res,400,{error:parsedSurface.error});return}let server=buildMcpServer(ctx,opts.jit,opts.bundler,opts.canvasBundler,opts.comments,opts.assetOrigin,opts.cloud,parsedSurface.selection,await sessionDesigns(ctx.folder.root,ctx.folder.config.name,parseMcpSessionUrl(req.url)));transport.onclose=()=>{if(transport.sessionId)sessions.delete(transport.sessionId);server.close().catch(()=>{return})},await server.connect(transport),session={transport,server}}let active=session;await withActor({source:"mcp",session:sessionIdStr??active.transport.sessionId},()=>active.transport.handleRequest(req,res,body));return}if(req.method==="GET"||req.method==="DELETE"){if(!sessionIdStr||!sessions.has(sessionIdStr)){sendJson(res,400,{error:"missing or unknown mcp-session-id"});return}let session=sessions.get(sessionIdStr);if(!session){sendJson(res,400,{error:"session lost"});return}await session.transport.handleRequest(req,res);return}sendJson(res,405,{error:`method ${req.method} not allowed`})}catch(err){if(console.error("velloo mcp: handler failed:",err),!res.headersSent)sendJson(res,500,{error:"internal error"})}});await new Promise((resolve,reject)=>{httpServer.once("error",reject),httpServer.listen(opts.port,opts.host,()=>{httpServer.removeListener("error",reject),resolve()})});let addr=httpServer.address(),boundPort=typeof addr==="object"&&addr!==null&&"port"in addr?addr.port:opts.port;return{url:`http://${opts.host}:${boundPort}/mcp`,port:boundPort,sessions:()=>sessions.size,async close(){for(let session of sessions.values())await session.transport.close().catch(()=>{return}),await session.server.close().catch(()=>{return});sessions.clear(),await new Promise((resolve)=>httpServer.close(()=>resolve()))}}}async function createStdioMcpServer(ctx,opts){let server=buildMcpServer(ctx,opts.jit,opts.bundler,opts.canvasBundler,opts.comments,opts.assetOrigin,opts.cloud,opts.surface??DEFAULT_MCP_SURFACE,await sessionDesigns(ctx.folder.root,ctx.folder.config.name,{switchable:!1,pick:void 0})),transport=new StdioServerTransport;return await server.connect(transport),{async close(){await transport.close().catch(()=>{return}),await server.close().catch(()=>{return})}}}function repoInstruction(ctx){let repo=ctx.repo;if(!repo)return[];let hostRoot=repo.host(void 0).hostRoot;if(!existsSync14(join42(hostRoot,"package.json")))return[];return["**The app's own components are placeable.** `list_components` shelves them first, under Repo, from what the app's routes render. Compose them by id (`<Tabs>`, `<Tabs.List>`; a name that collides with a Velloo primitive is qualified, e.g. `<Mantine.Button>`) rather than rebuilding them from primitives. They render for real inside the folder's preview entry \u2014 run `preview_status` once before designing; `set_preview_entry` fixes a missing provider or stylesheet. Style one through the props it declares, and fill a `slot` prop with an element (`leftSection={<IconBolt />}`); `emit_code` returns their exact `repoImports`.",...repo.recipes(void 0).flatMap((recipe)=>recipe.notes),""]}class PublishRunner{publisher;host;current={state:"idle"};warnings=[];constructor(publisher,host){this.publisher=publisher;this.host=host}state(){return this.current}running(){return this.current.state==="running"}teams(){return this.publisher.teams()}blocked(){return this.publisher.blocked?.()??Promise.resolve(null)}destinations(){return this.publisher.destinations(this.host())}access(){return this.publisher.access()}published(){return this.publisher.published()}unpublish(slug){return this.publisher.unpublish(slug)}get guests(){return this.publisher.guests}start(request){if(this.current.state==="running")return null;let startedAt=new Date().toISOString();return this.warnings=[],this.current={state:"running",step:"start",message:"starting",startedAt,warnings:this.warnings},this.publisher.run(this.host(),request,({step,message,capture})=>{if(this.current.state!=="running"||this.current.startedAt!==startedAt)return;this.current={state:"running",step,message,startedAt,warnings:this.warnings,...capture?{capture}:{}}},(message)=>{this.warnings.push(message)}).then((result)=>{this.current={state:"done",result,warnings:this.warnings,finishedAt:new Date().toISOString()}}).catch((err)=>{let access=asSignInRequired(err),boardLimit=asBoardLimit(err);this.current={state:"error",message:err instanceof Error?err.message:String(err),...access?{signInRequired:access}:{},...boardLimit?{boardLimit}:{},warnings:this.warnings,finishedAt:new Date().toISOString()}}),this.current}reset(){if(this.current.state!=="running")this.current={state:"idle"}}}import{resolve as resolve11,sep as sep9}from"path";import{existsSync as existsSync16,readFileSync as readFileSync16,statSync as statSync3}from"fs";import{dirname as dirname19,join as join44}from"path";import{existsSync as existsSync15,readFileSync as readFileSync14,statSync as statSync2}from"fs";import{dirname as dirname18,join as join43}from"path";var UNION_MEMBER=String.raw`(?:'[^']*'|"[^"]*"|-?\d+(?:\.\d+)?)`,LITERAL_ALIAS=new RegExp(String.raw`type\s+([A-Z][\w$]*)\s*=\s*\|?\s*(${UNION_MEMBER}(?:\s*\|\s*${UNION_MEMBER})*)\s*;`,"g"),MAX_DECLARATION_FILES=1200,MAX_DECLARATION_BYTES=1e6;function emptyIndex(){return{props:new Map,literalAliases:new Map,staticMembers:new Map,variantTables:new Map}}function indexDeclarations(source,index){let code=keepDocComments(source);for(let match of code.matchAll(/(?:export\s+)?(?:declare\s+)?interface\s+([A-Z][\w$]*Props)\b(?:<[^>{]*>)?\s*(?:extends\s+([^{]+))?\{/g)){let open=(match.index??0)+match[0].length-1,close=matchBrace3(code,open);if(close===-1)continue;let name=match[1]??"";if(!index.props.has(name))index.props.set(name,{body:code.slice(open+1,close),extends:splitTopLevel(match[2]??"",",").map((s)=>s.trim().replace(/<[\s\S]*$/,"")).filter(Boolean)})}for(let match of code.matchAll(/(?:export\s+)?(?:declare\s+)?type\s+([A-Z][\w$]*Props)\b(?:<[^>=]*>)?\s*=\s*\{/g)){let open=(match.index??0)+match[0].length-1,close=matchBrace3(code,open);if(close===-1)continue;let name=match[1]??"";if(!index.props.has(name))index.props.set(name,{body:code.slice(open+1,close),extends:[]})}for(let match of code.matchAll(/(?:function\s+([A-Z][\w$]*)\s*(?:<[^>(]*>)?\s*|const\s+([A-Z][\w$]*)\s*=\s*(?:(?:React\.)?(?:memo|forwardRef)\s*\(\s*)?(?:function\s*[\w$]*\s*)?)\(/g)){let name=`${match[1]??match[2]??""}Props`;if(index.props.has(name))continue;let annotation=parameterType(code,(match.index??0)+match[0].length);if(annotation?.body!==void 0)index.props.set(name,{body:annotation.body,extends:annotation.extends??[]});else if(annotation?.named&&annotation.named!==name)index.props.set(name,{body:"",extends:[annotation.named]})}for(let match of code.matchAll(LITERAL_ALIAS)){let values=literalUnion(match[2]??"");if(values)index.literalAliases.set(match[1]??"",values)}for(let match of code.matchAll(/(?:const|let)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:cva|tv|cx?Variants?)\s*\(/g)){let call=code.slice(match.index??0,(match.index??0)+20000),variantsAt=call.search(/\bvariants\s*:\s*\{/);if(variantsAt<0)continue;let open=call.indexOf("{",variantsAt),close=matchBrace3(call,open);if(close<0)continue;let variants=new Map;for(let[name,body]of topLevelObjectKeys(call.slice(open+1,close))){let keys=body?topLevelObjectKeys(body).map(([key])=>key):[];if(keys.length>0)variants.set(name,keys)}let defaults=new Map,defaultsAt=call.search(/\bdefaultVariants\s*:\s*\{/);if(defaultsAt>=0){let dOpen=call.indexOf("{",defaultsAt),dClose=matchBrace3(call,dOpen);for(let m of call.slice(dOpen+1,dClose).matchAll(/([A-Za-z_$][\w$]*)\s*:\s*['"]([^'"]+)['"]/g))defaults.set(m[1]??"",m[2]??"")}if(variants.size>0)index.variantTables.set(match[1]??"",{variants,defaults})}for(let match of code.matchAll(/staticComponents:\s*\{([^}]*)\}/g)){let owner=[...code.slice(Math.max(0,(match.index??0)-4000),match.index).matchAll(/declare\s+const\s+([A-Z][\w$]*)\s*:/g)].at(-1)?.[1],members=[...(match[1]??"").matchAll(/([A-Z][\w$]*)\s*:/g)].map((m)=>m[1]??"");if(owner&&members.length>0&&!index.staticMembers.has(owner))index.staticMembers.set(owner,members)}}function indexPackageDeclarations(packageName,hostRoot){let index=emptyIndex(),entry=packageTypesEntry(packageName,hostRoot);if(!entry)return index;let queue=[entry],seen=new Set;while(queue.length>0&&seen.size<MAX_DECLARATION_FILES){let file=queue.shift();if(seen.has(file))continue;seen.add(file);let source;try{if(statSync2(file).size>MAX_DECLARATION_BYTES)continue;source=readFileSync14(file,"utf8")}catch{continue}indexDeclarations(source,index);for(let match of source.matchAll(/(?:export|import)[^'"]*?from\s*['"](\.[^'"]+)['"]/g)){let next=resolveDeclaration(dirname18(file),match[1]??"");if(next)queue.push(next)}}return index}function packageExportNames(packageName,hostRoot){let names=new Set,entry=packageTypesEntry(packageName,hostRoot);if(!entry)return names;let queue=[entry],seen=new Set;while(queue.length>0&&seen.size<MAX_DECLARATION_FILES){let file=queue.shift();if(seen.has(file))continue;seen.add(file);let source;try{source=readFileSync14(file,"utf8")}catch{continue}for(let match of source.matchAll(/export\s+(?:declare\s+)?(?:const|function|class|let|var)\s+([A-Z][\w$]*)/g))names.add(match[1]??"");for(let match of source.matchAll(/export\s*(?:type\s*)?\{([^}]*)\}/g))for(let part of(match[1]??"").split(",")){let exported=part.trim().split(/\s+as\s+/).at(-1)?.trim()??"";if(/^[A-Z][\w$]*$/.test(exported))names.add(exported)}for(let match of source.matchAll(/export\s*\*\s*from\s*['"](\.[^'"]+)['"]/g)){let next=resolveDeclaration(dirname18(file),match[1]??"");if(next)queue.push(next)}}return names}function packageTypesEntry(packageName,hostRoot){let pkgJsonPath;try{pkgJsonPath=Bun.resolveSync(`${packageName}/package.json`,hostRoot)}catch{return null}let root=dirname18(pkgJsonPath);try{let pkg=JSON.parse(readFileSync14(pkgJsonPath,"utf8")),candidates=[pkg.types,pkg.typings],dot=pkg.exports?.["."];if(dot&&typeof dot==="object"){let d=dot;candidates.push(d.types,d.import?.types,d.require?.types)}for(let candidate of candidates)if(typeof candidate==="string"&&existsSync15(join43(root,candidate)))return join43(root,candidate)}catch{return null}for(let guess of["index.d.ts","dist/index.d.ts","lib/index.d.ts"])if(existsSync15(join43(root,guess)))return join43(root,guess);return null}function resolveDeclaration(dir,specifier){let base=join43(dir,specifier.replace(/\.(m|c)?js$/,""));for(let candidate of[`${base}.d.ts`,`${base}.d.mts`,`${base}.d.cts`,`${base}.ts`,`${base}.tsx`,join43(base,"index.d.ts"),join43(base,"index.d.mts"),join43(base,"index.ts")])if(existsSync15(candidate))return candidate;return null}function propsFor(name,index){let interfaceName=`${name.replace(/\./g,"")}Props`,root=index.props.get(interfaceName);if(!root)return null;let own=new Map(parseMembers(root.body,index).map((prop)=>[prop.name,prop])),inherited=new Map,visit=(decl,depth)=>{for(let parent of decl.extends){let base=index.props.get(parent);if(!base||depth>=4)continue;visit(base,depth+1);for(let prop of parseMembers(base.body,index))if(!own.has(prop.name))inherited.set(prop.name,{...prop,inherited:!0})}};visit(root,0);let variants=index.literalAliases.get(`${name.replace(/\./g,"")}Variant`);if(variants)inherited.delete("variant"),own.set("variant",{name:"variant",type:variants.map((v)=>JSON.stringify(v)).join(" | "),optional:!0,control:"enum",enumValues:variants,serializable:!0});return[...own.values(),...inherited.values()]}function parseMembers(body,index){let out=[];for(let raw of memberChunks(body)){let text=raw.trim();if(!text)continue;let doc=/\/\*\*([\s\S]*?)\*\//.exec(text)?.[1],member=text.replace(/\/\*\*[\s\S]*?\*\//g,"").trim(),match=/^(?:readonly\s+)?(['"]?)([A-Za-z_$][\w$-]*)\1(\?)?\s*:\s*([\s\S]+?)[,;]?$/.exec(member);if(!match){let method=/^([A-Za-z_$][\w$]*)(\?)?\s*(?:<[^>]*>)?\s*(\([\s\S]*\))\s*:\s*([\s\S]+?)[,;]?$/.exec(member);if(method){let type=`${method[3]} => ${method[4]}`.replace(/\s+/g," ").trim();out.push(describe4(method[1]??"",type,Boolean(method[2]),doc,index))}continue}let name=match[2]??"",type=(match[4]??"").replace(/\s+/g," ").trim();out.push(describe4(name,type,Boolean(match[3]),doc,index))}return out}var MEMBER_START=/^(?:\/\*\*[\s\S]*?\*\/\s*)?(?:readonly\s+)?(?:['"]?[A-Za-z_$][\w$-]*['"]?\??\s*:|[A-Za-z_$][\w$]*\??\s*(?=[(<]))/;function memberChunks(body){let starts=[],depth=0,quote=null,boundary=!0;for(let i=0;i<body.length;i++){let ch=body[i]??"";if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}let head=depth===0&&boundary&&!/\s/.test(ch)?MEMBER_START.exec(body.slice(i,i+400)):null;if(head){starts.push(i),boundary=!1,i+=head[0].length-1;continue}if(body.startsWith("/*",i)){let end=body.indexOf("*/",i+2);i=end===-1?body.length:end+1;continue}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if("([{<".includes(ch))depth++;else if(")]}>".includes(ch)&&!(ch===">"&&body[i-1]==="="))depth=Math.max(0,depth-1);if(depth===0&&(ch===";"||ch===","||ch===`
681
681
  `))boundary=!0;else if(!/\s/.test(ch))boundary=!1}return starts.map((start,i)=>body.slice(start,starts[i+1]??body.length))}function describe4(name,type,optional,doc,index){let description=doc?.replace(/^\s*\*\s?/gm,"").replace(/@default[\s\S]*$/,"").replace(/\s+/g," ").trim(),defaultRaw=doc?/@default\s+`?([^`\n]+?)`?\s*(?:\*|$)/m.exec(doc)?.[1]?.trim():void 0,base={name,type,optional,...description?{description}:{},...defaultRaw?{defaultValue:defaultRaw.replace(/^['"]|['"]$/g,"")}:{}},union=splitTopLevel(type,"|").map((part)=>part.trim()).filter((part)=>part!==""&&part!=="undefined"&&part!=="null"&&part!=="(string & {})");if(/=>/.test(type)||/^(?:React\.)?(?:Ref|RefObject|ForwardedRef)</.test(type))return{...base,control:"string",serializable:!1,constraint:"Takes a function or ref, which a design can't hold \u2014 the app wires it up."};if(union.some((part)=>/^(?:React\.)?(?:ReactNode|ReactElement|JSX\.Element)\b/.test(part)))return{...base,control:"string",slot:!0,serializable:!0};let values=[],open=!1;for(let part of union){let literal=literalUnion(part),alias=index.literalAliases.get(part);if(literal)values.push(...literal);else if(alias)values.push(...alias);else open=!0}if(values.length>0&&!open)return{...base,control:"enum",enumValues:[...new Set(values)],serializable:!0};if(union.every((part)=>part==="boolean"||part==="true"||part==="false"))return{...base,control:"boolean",serializable:!0};if(union.every((part)=>part==="number"))return{...base,control:"number",serializable:!0};let control=/color/i.test(name)?"color":"string";return{...base,control,serializable:!0,...values.length>0?{enumValues:[...new Set(values)]}:{}}}function parameterType(code,from){let i=from,skip=()=>{while(/\s/.test(code[i]??""))i++};if(skip(),code[i]==="{"){let close=matchBrace3(code,i);if(close===-1)return null;i=close+1}else{let id=/^[A-Za-z_$][\w$]*/.exec(code.slice(i,i+100))?.[0];if(!id)return null;i+=id.length}if(skip(),code[i]!==":")return null;if(i++,skip(),code[i]==="{"){let close=matchBrace3(code,i);return close===-1?null:{body:code.slice(i+1,close)}}let named=/^[A-Z][\w$]*/.exec(code.slice(i,i+100))?.[0];if(!named)return null;let local=new RegExp(`(?:interface\\s+${named}\\b(?:<[^>{]*>)?\\s*(?:extends\\s+([^{]+))?|type\\s+${named}\\b(?:<[^>=]*>)?\\s*=\\s*)\\{`).exec(code);if(local){let open=local.index+local[0].length-1,close=matchBrace3(code,open);if(close!==-1){let bases=splitTopLevel(local[1]??"",",").map((base)=>base.trim().replace(/<[\s\S]*$/,"")).filter(Boolean);return{body:code.slice(open+1,close),extends:bases}}}return{named}}function literalUnion(text){let parts=splitTopLevel(text,"|").map((p)=>p.trim()).filter(Boolean);if(parts.length===0)return null;let out=[];for(let part of parts){let str=/^(['"])(.*)\1$/.exec(part);if(str)out.push(str[2]??"");else if(/^-?\d+(\.\d+)?$/.test(part))out.push(Number(part));else return null}return out}function splitTopLevel(text,seps){let out=[],depth=0,quote=null,start=0;for(let i=0;i<text.length;i++){let ch=text[i]??"";if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}if(text.startsWith("/**",i)){let end=text.indexOf("*/",i+3);i=end===-1?text.length:end+1;continue}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if("([{<".includes(ch))depth++;else if(")]}>".includes(ch)&&!(ch===">"&&text[i-1]==="="))depth=Math.max(0,depth-1);else if(depth===0&&seps.includes(ch))out.push(text.slice(start,i)),start=i+1}return out.push(text.slice(start)),out}function keepDocComments(source){let docs=[],marked=source.replace(/\/\*\*[\s\S]*?\*\//g,(doc)=>(docs.push(doc),`\uE000${docs.length-1}\uE000`));return blankComments(marked).replace(/\ue000(\d+)\ue000/g,(_,i)=>docs[Number(i)]??"")}function matchBrace3(code,open){let depth=0;for(let i=open;i<code.length;i++){let ch=code[i];if(ch==="{")depth++;else if(ch==="}"){if(depth--,depth===0)return i}}return-1}function indexLocalDeclarations(file,index,seen){let queue=[file],budget=60;while(queue.length>0&&budget-- >0){let next=queue.shift();if(seen.has(next))continue;seen.add(next);let source;try{source=readFileSync14(next,"utf8")}catch{continue}indexDeclarations(source,index);for(let match of source.matchAll(/export[^'";]*?from\s*['"](\.[^'"]+)['"]/g)){let target=resolveDeclaration(dirname18(next),match[1]??"");if(target)queue.push(target)}}}function topLevelObjectKeys(body){let out=[],depth=0,quote=null;for(let i=0;i<body.length;i++){let ch=body[i]??"";if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}if(depth===0){let key=/^(?:["']([^"']+)["']|([A-Za-z_$][\w$-]*))\s*:/.exec(body.slice(i));if(key&&(i===0||/[\s,{]/.test(body[i-1]??""))){let name=key[1]??key[2]??"",j=i+key[0].length;while(/\s/.test(body[j]??""))j++;if(body[j]==="{"){let close=matchBrace3(body,j);out.push([name,close<0?null:body.slice(j+1,close)]),i=close<0?body.length:close}else out.push([name,null]),i=j-1;continue}}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if("([{".includes(ch))depth++;else if(")]}".includes(ch))depth--}return out}function variantPropsFor(name,index){let root=(name.split(".")[0]??name).toLowerCase();for(let[table,{variants,defaults}]of index.variantTables){if(table.toLowerCase()!==`${root}variants`)continue;return[...variants].map(([prop,values])=>({name:prop,type:values.map((value)=>JSON.stringify(value)).join(" | "),optional:!0,control:"enum",enumValues:values,serializable:!0,...defaults.get(prop)?{defaultValue:defaults.get(prop)}:{}}))}return[]}import{readFileSync as readFileSync15}from"fs";import{relative as relative8,sep as sep8}from"path";var MAX_STORY_FILES=400;async function collectStoryStates(hostRoot){let out=[],files=await findFiles(hostRoot,(name)=>/\.stories\.[jt]sx?$/.test(name),MAX_STORY_FILES);for(let file of files)try{let parsed=storiesFromSource(readFileSync15(file,"utf8"),file,hostRoot);if(parsed)out.push(parsed)}catch{}return out}function storiesFromSource(source,file,hostRoot){let code=blankComments(source),scan=scanModule(source),at=relative8(hostRoot,file).split(sep8).join("/"),metaBody=objectAfter(code,/export\s+default\s*\{/)??metaVariable(code);if(!metaBody)return null;let component=/\bcomponent\s*:\s*([A-Z][\w$]*)/.exec(metaBody)?.[1];if(!component)return null;let binding=scan.imports.flatMap((decl)=>decl.bindings.map((b)=>({...b,specifier:decl.specifier}))).find((b)=>b.local===component);if(!binding)return null;let local=binding.specifier.startsWith(".")||binding.specifier.startsWith("@/"),exportName=binding.imported==="*"||binding.imported==="default"?component:binding.imported,metaArgs=argsOf(metaBody),states=[];for(let match of code.matchAll(/export\s+const\s+([A-Z][\w$]*)\s*(?::[^=]+)?=\s*\{/g)){let body=objectAt(code,(match.index??0)+match[0].length-1);if(body===null)continue;let own=argsOf(body);states.push({name:humanize(match[1]??"Story"),props:{...metaArgs.props,...own.props},source:"story",at,...own.dropped.length+metaArgs.dropped.length>0?{dropped:[...metaArgs.dropped,...own.dropped]}:{}})}for(let match of code.matchAll(/([A-Z][\w$]*)\.args\s*=\s*\{/g)){let body=objectAt(code,(match.index??0)+match[0].length-1),parsed=body===null?null:parseLiteral(body);if(!parsed?.ok)continue;states.push({name:humanize(match[1]??"Story"),props:{...metaArgs.props,...parsed.value},source:"story",at})}return states.length>0?{key:`${local?"local":binding.specifier}#${exportName}`,states}:null}function argsOf(body){let args=objectAfter(body,/\bargs\s*:\s*\{/);if(!args)return{props:{},dropped:[]};let whole=parseLiteral(args);if(whole.ok)return{props:whole.value,dropped:[]};let props={},dropped=[];for(let entry of topLevelEntries2(args.slice(1,-1))){let colon=entry.indexOf(":"),key=entry.slice(0,colon).trim().replace(/^['"]|['"]$/g,"");if(colon===-1||!key)continue;let value=parseLiteral(entry.slice(colon+1).trim());if(value.ok)props[key]=value.value;else dropped.push(key)}return{props,dropped}}function metaVariable(code){let name=/export\s+default\s+([A-Za-z_$][\w$]*)\s*;?/.exec(code)?.[1];if(!name)return null;return objectAfter(code,new RegExp(`(?:const|let)\\s+${name}\\s*(?::[^=]+)?=\\s*\\{`))}function objectAfter(code,pattern){let match=pattern.exec(code);if(!match)return null;return objectAt(code,(match.index??0)+match[0].length-1)}function objectAt(code,open){let depth=0,quote=null;for(let i=open;i<code.length;i++){let ch=code[i];if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if(ch==="{")depth++;else if(ch==="}"&&--depth===0)return code.slice(open,i+1)}return null}function topLevelEntries2(body){let out=[],depth=0,quote=null,start=0;for(let i=0;i<body.length;i++){let ch=body[i]??"";if(quote){if(ch==="\\")i++;else if(ch===quote)quote=null;continue}if(ch==='"'||ch==="'"||ch==="`")quote=ch;else if("([{".includes(ch))depth++;else if(")]}".includes(ch))depth--;else if(ch===","&&depth===0)out.push(body.slice(start,i)),start=i+1}return out.push(body.slice(start)),out.map((s)=>s.trim()).filter(Boolean)}function humanize(name){return name.replace(/([a-z0-9])([A-Z])/g,"$1 $2")}var OVERRIDES_FILE="repo-components.json";class RepoComponents{opts;cached=null;readFiles=new Set;packageIndexes=new Map;exportNames=new Map;constructor(opts){this.opts=opts}catalog(){if(!this.cached)this.cached=this.build().catch((error)=>{throw this.cached=null,error});return this.cached}invalidate(changed){if(!this.cached)return!1;let relevant=!changed||changed.length===0||changed.some((file)=>this.readFiles.has(pathKey(file))||/(^|[\\/])(package\.json|tsconfig[^\\/]*\.json|repo-components\.json)$/.test(file)||/\.stories\.[jt]sx?$/.test(file)||/[\\/]preview(\.[\w-]+)?\.[jt]sx?$/.test(file));if(relevant)this.cached=null;return relevant}apps(){let config=this.opts.config(),out=[{app:void 0,hostApp:config.hostApp,hostRoot:hostAppRootFrom(this.opts.folderRoot,config.hostApp)}];for(let[app,hostApp]of Object.entries(config.hostApps??{}))out.push({app,hostApp,hostRoot:hostAppRootFrom(this.opts.folderRoot,hostApp)});return out}host(app){let found=this.apps().find((entry)=>entry.app===app)??this.apps()[0],hostApp=found?.hostApp,hostRoot=found?.hostRoot??hostAppRootFrom(this.opts.folderRoot,void 0);return{hostRoot,hostApp,aliases:aliasPairs(hostApp,hostRoot)}}recipes(app){return recipesForHost(this.host(app).hostRoot)}preview(app){let{hostRoot,hostApp}=this.host(app);return resolvePreviewEntry({folderRoot:this.opts.folderRoot,hostRoot,hostApp,app,recipes:this.recipes(app)})}watchDirs(){let dirs=new Set;for(let{hostRoot,hostApp}of this.apps()){for(let dir of["src","app","pages","components","lib"])if(existsSync16(join44(hostRoot,dir)))dirs.add(join44(hostRoot,dir));for(let root of hostApp?.components?.include??[]){let abs=join44(hostRoot,root);if(existsSync16(abs))dirs.add(statSync3(abs).isDirectory()?abs:dirname19(abs))}}return[...dirs]}async build(){let warnings=[],overrides=this.readOverrides(warnings),drafts=[],apps=[],readFiles=new Set;for(let{app,hostApp,hostRoot}of this.apps()){if(!existsSync16(hostRoot))continue;let aliases=aliasPairs(hostApp,hostRoot),discovery=await discoverRepoComponents({hostRoot,aliases,app,include:hostApp?.components?.include,exclude:hostApp?.components?.exclude,owned:this.opts.owned});for(let file of discovery.files)readFiles.add(file);let recipes=recipesForHost(hostRoot),stories=await collectStoryStates(hostRoot),storyStates=new Map(stories.map((entry)=>[entry.key,entry.states])),localIndex=emptyIndex(),indexed=new Set;for(let component of discovery.components)if(component.source==="local"&&component.file)indexLocalDeclarations(component.file,localIndex,indexed);let fileIndexes=new Map,localIndexFor=(file)=>{if(!file)return localIndex;let cached=fileIndexes.get(file);if(cached)return cached;let own=emptyIndex();indexLocalDeclarations(file,own,new Set);let merged={props:new Map([...localIndex.props,...own.props]),literalAliases:new Map([...localIndex.literalAliases,...own.literalAliases]),staticMembers:new Map([...localIndex.staticMembers,...own.staticMembers]),variantTables:new Map([...localIndex.variantTables,...own.variantTables])};return fileIndexes.set(file,merged),merged},scans=new Map,known=new Set(discovery.components.map((c)=>keyOf2(c.identity)));for(let component of discovery.components){let index=component.source==="package"&&component.packageName?this.packageIndex(component.packageName,hostRoot):localIndexFor(component.file),recipe=recipeForSpecifier(component.identity.importPath),activeRecipe=recipe&&recipes.includes(recipe)?recipe:void 0,draft=entryFor(component,index,storyStates,activeRecipe);if(component.source==="local"){let hooks=dataSourcesOf(component,scans,readFiles);if(hooks.length>0)draft.dataSources=hooks}if(drafts.push(draft),!component.identity.member){let parts=index.staticMembers.get(component.identity.exportName)??[];for(let part of parts){let identity={...component.identity,member:part};if(known.has(keyOf2(identity)))continue;known.add(keyOf2(identity));let partComponent={...component,name:`${component.name}.${part}`,identity,usages:[]};drafts.push({...entryFor(partComponent,index,storyStates,activeRecipe),viaFamily:!0})}}}for(let draft of drafts){if(draft.identity.member)continue;let parts=drafts.filter((other)=>other.identity.member&&other.identity.importPath===draft.identity.importPath&&other.identity.exportName===draft.identity.exportName&&other.identity.app===draft.identity.app).map((other)=>other.identity.member);if(parts.length>0)draft.parts=parts}let preview=resolvePreviewEntry({folderRoot:this.opts.folderRoot,hostRoot,hostApp,app,recipes});apps.push({...app?{app}:{},hostRoot,recipes:recipes.map((recipe)=>recipe.id),preview:{kind:preview.kind,label:preview.label},wrappers:discovery.wrappers,globalStyles:discovery.globalStyles,entries:discovery.entries,skipped:discovery.skipped})}let entries=applyOverrides(drafts,overrides,warnings);return assignIds(entries,this.opts.reservedIds()),entries.sort((a,b)=>a.family.localeCompare(b.family)||a.name.localeCompare(b.name)),this.readFiles=new Set([...readFiles].map(pathKey)),{entries,byId:new Map(entries.map((entry)=>[entry.id,entry])),byKey:new Map(entries.map((entry)=>[entry.key,entry])),apps,warnings}}async resolveName(name){let catalog=await this.catalog(),[root,...members]=name.split(".");if(!root||!/^[A-Z]/.test(root))return null;let packages=new Map;for(let entry of catalog.entries){if(entry.source!=="package"||!entry.packageName||packages.has(entry.packageName))continue;let app=catalog.apps.find((summary)=>summary.app===entry.identity.app);if(app)packages.set(entry.packageName,{app:entry.identity.app,hostRoot:app.hostRoot})}let matches=[...packages].filter(([pkg,{hostRoot}])=>this.packageExports(pkg,hostRoot).has(root));if(matches.length!==1)return null;let[packageName,{app,hostRoot}]=matches[0],identity={importPath:packageName,exportName:root,...members.length>0?{member:members.join(".")}:{},...app?{app}:{}},entry=entryFor({name,identity,source:"package",packageName,usages:[]},this.packageIndex(packageName,hostRoot),new Map,recipeForSpecifier(packageName));return entry.id=name,entry}packageExports(packageName,hostRoot){let stamp="";try{let pkgJson=Bun.resolveSync(`${packageName}/package.json`,hostRoot);stamp=`${pkgJson}:${statSync3(pkgJson).mtimeMs}`}catch{return new Set}let cached=this.exportNames.get(stamp);if(cached)return cached;let names=packageExportNames(packageName,hostRoot);return this.exportNames.set(stamp,names),names}packageIndex(packageName,hostRoot){let stamp="";try{let pkgJson=Bun.resolveSync(`${packageName}/package.json`,hostRoot);stamp=`${pkgJson}:${statSync3(pkgJson).mtimeMs}`}catch{return emptyIndex()}let cached=this.packageIndexes.get(stamp);if(cached)return cached.index;let index=indexPackageDeclarations(packageName,hostRoot);return this.packageIndexes.set(stamp,{stamp,index}),index}readOverrides(warnings){let path=join44(this.opts.folderRoot,OVERRIDES_FILE);if(!existsSync16(path))return new Map;try{let parsed=RepoComponentsManifestSchema.safeParse(JSON.parse(readFileSync16(path,"utf8")));if(!parsed.success)return warnings.push(`${OVERRIDES_FILE} is invalid: ${parsed.error.issues[0]?.message??"schema mismatch"}`),new Map;return new Map(Object.entries(parsed.data.components))}catch(error){return warnings.push(`${OVERRIDES_FILE} could not be read: ${error instanceof Error?error.message:String(error)}`),new Map}}}function keyOf2(identity){return`${identity.importPath}#${identity.exportName}${identity.member?`.${identity.member}`:""}`}function dataSourcesOf(component,scans,readFiles){let scanOf=(file)=>{if(scans.has(file))return scans.get(file)??null;let scan=null;try{scan=scanModule(readFileSync16(file,"utf8")),readFiles.add(file)}catch{scan=null}return scans.set(file,scan),scan},wanted=component.identity.exportName,file=component.file;for(let hop=0;file&&hop<6;hop++){let scan=scanOf(file);if(!scan)return[];let local=wanted==="default"?scan.defaultExportName??component.name:component.name,hooks=scan.hooks[local]??scan.hooks[wanted];if(hooks)return hooks;let next=scan.reExports.find((re)=>re.names===null||re.names.some((entry)=>entry.exported===wanted)),resolved=next?resolveDeclaration(dirname19(file),next.specifier):null;if(!resolved)return[];file=resolved}return[]}var REACT_OWN=new Set(["key","ref"]);function entryFor(component,index,stories,recipe){let family=component.name.split(".")[0]??component.name,declared=propsFor(declarationName(component),index)??[],byName=new Map(declared.map((prop)=>[prop.name,prop]));if(!component.identity.member){for(let prop of variantPropsFor(declarationName(component),index))if(byName.get(prop.name)?.control!=="enum")byName.set(prop.name,prop)}for(let usage of component.usages){for(let[name,value]of Object.entries(usage.props)){if(byName.has(name)||REACT_OWN.has(name))continue;byName.set(name,observedProp(name,value))}for(let name of usage.expressions){if(byName.has(name)||REACT_OWN.has(name))continue;byName.set(name,{name,type:"unknown",optional:!0,control:"string",serializable:!1,constraint:"The app passes code here (a handler, variable or element); set a literal value or leave it to the app."})}}let props=[...byName.values()],states=[...component.identity.member?[]:stories.get(`${component.source==="local"?"local":component.identity.importPath}#${component.identity.exportName==="default"?family:component.identity.exportName}`)??[],...component.usages.filter((usage)=>Object.keys(usage.props).length>0||usage.text).map((usage)=>({name:`As used at ${usage.at}`,props:{...Object.fromEntries(Object.entries(usage.props).filter(([name])=>!REACT_OWN.has(name))),...usage.text?{children:usage.text}:{}},source:"usage",at:usage.at,...usage.expressions.length>0?{dropped:usage.expressions}:{}}))],styleProps=recipe?recipe.styleProps:["className","style","sx"].filter((name)=>byName.has(name));return{id:component.name,name:component.name,identity:component.identity,key:repoKey(component.identity),source:component.source,...component.packageName?{packageName:component.packageName}:{},family,group:recipe?.groups?.[family]??groupFor(family),props,acceptsChildren:byName.has("children")||component.usages.some((usage)=>usage.hasChildren),states,provenance:component.usages.map((usage)=>usage.at),...recipe?{recipe:recipe.id}:{},styleProps}}function declarationName(component){return[component.identity.exportName==="default"?component.name.split(".")[0]:component.identity.exportName,component.identity.member].filter(Boolean).join(".")}function observedProp(name,value){return{name,type:`${typeof value} (observed)`,optional:!0,control:typeof value==="boolean"?"boolean":typeof value==="number"?"number":"string",serializable:!0}}function applyOverrides(entries,overrides,warnings){let byKey=new Map(entries.map((entry)=>[keyOf2(entry.identity),entry]));for(let key of overrides.keys())if(!byKey.has(key))warnings.push(`${OVERRIDES_FILE}: "${key}" matches no discovered component`);let out=[];for(let entry of entries){let override=overrides.get(keyOf2(entry.identity));if(!override){out.push(entry);continue}if(override.exclude)continue;let props=new Map(entry.props.map((prop)=>[prop.name,prop]));for(let prop of override.props??[])props.set(prop.name,{...props.get(prop.name),...prop,serializable:!0});let known=new Set(props.keys()),states=Object.entries(override.states??{}).map(([name,stateProps])=>{for(let propName of Object.keys(stateProps))if(!known.has(propName)&&propName!=="children")warnings.push(`${OVERRIDES_FILE}: state "${name}" of ${keyOf2(entry.identity)} sets unknown prop "${propName}"`);return{name,props:stateProps,source:"manifest"}});out.push({...entry,props:[...props.values()],states:[...states,...entry.states],...override.description?{description:override.description}:{},...override.proxy?{proxy:override.proxy}:{}})}return out}function assignIds(entries,reserved){let sourcesByFamily=new Map;for(let entry of entries){let sources=sourcesByFamily.get(entry.family)??new Set;sources.add(`${entry.identity.app??""}:${entry.identity.importPath}#${entry.identity.exportName}`),sourcesByFamily.set(entry.family,sources)}for(let entry of entries){let takenByProvider=reserved.has(entry.family),shared=(sourcesByFamily.get(entry.family)?.size??0)>1;if(!takenByProvider&&!shared)continue;entry.id=`${namespaceOf(entry)}.${entry.name}`,entry.qualifiedBecause=takenByProvider?`"${entry.family}" is also this folder's provider or helper component`:`"${entry.family}" is exported by more than one source`}let byId=new Map;for(let entry of entries)byId.set(entry.id,[...byId.get(entry.id)??[],entry]);for(let group of byId.values()){let sources=new Set(group.map((entry)=>entry.identity.importPath));if(sources.size<2)continue;let segments=new Map(group.map((entry)=>[entry,entry.identity.importPath.split("/").filter((part)=>part&&part!=="."&&part!==".."&&part!=="index")])),longest=Math.max(...[...segments.values()].map((parts)=>parts.length));for(let depth=1;depth<=longest;depth++){let tail=(entry)=>pascal2((segments.get(entry)??[]).slice(-depth).join("-"));if(new Set(group.map(tail)).size<sources.size&&depth<longest)continue;for(let entry of group)entry.id=`${tail(entry)}.${entry.name}`,entry.qualifiedBecause=`"${entry.family}" is exported by more than one module (${entry.identity.importPath})`;break}}}function namespaceOf(entry){let app=entry.identity.app?pascal2(entry.identity.app):"";if(entry.source==="local"||!entry.packageName)return app?`${app}App`:"App";let name=entry.packageName.startsWith("@")?entry.packageName.slice(1).split("/")[0]??entry.packageName:entry.packageName;return pascal2(name)}function pascal2(value){return value.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part)=>`${part[0]?.toUpperCase()??""}${part.slice(1)}`).join("")}var GROUP_RULES=[[/^(Icon|Avatar|Image|Logo|Illustration|Svg)/,"visuals"],[/(Button|Action|Toggle|Fab)$/,"actions"],[/(Input|Select|Checkbox|Radio|Switch|Slider|Field|Form|Textarea|Picker|Autocomplete|Combobox|Rating|Chip)/,"forms"],[/(Alert|Toast|Notification|Progress|Loader|Spinner|Skeleton|Snackbar|Banner)/,"feedback"],[/(Nav|Menu|Tabs|Breadcrumb|Pagination|Stepper|Link|Sidebar|Tab$)/,"navigation"],[/(Modal|Dialog|Drawer|Popover|Tooltip|HoverCard|Sheet|Overlay)/,"overlays"],[/(Grid|Stack|Group|Container|Flex|Box|Center|Shell|Layout|Paper|Card|Space|Divider|Section|Row|Col)/,"layout"],[/^(Text|Title|Heading|Typography|Code|Blockquote|Mark|Highlight|Kbd|Label)$/,"typography"]];function groupFor(family){for(let[pattern,group]of GROUP_RULES)if(pattern.test(family))return group;return"display"}function createRepoComponents(folder,providers){let adapters=Object.values(providers);return new RepoComponents({folderRoot:folder.root,config:()=>folder.config,reservedIds:()=>new Set([...adapters.flatMap((adapter)=>Object.keys(adapter.registry)),...Object.keys(folder.config.extensions??{})]),owned:(specifier,resolved,exportName)=>{let pkg=packageOf(specifier);for(let adapter of adapters){if(!(adapter.ownedModules?.packages?.includes(pkg)===!0||resolved!==null&&(adapter.ownedModules?.dirs?.()??[]).some((dir)=>{let root=resolve11(dir);return resolved===root||resolved.startsWith(root+sep9)})))continue;if(exportName===void 0||exportName in adapter.registry)return!0}return!1}})}import{existsSync as existsSync17,readdirSync as readdirSync3,statSync as statSync4,watch}from"fs";import{join as join45,sep as sep10}from"path";function classifyWatchPath(filename){if(!filename)return null;let parts=filename.split(/[\\/]/);if(parts[0]==="screens"&&parts[1]){let file=parts[1];if(file.endsWith(".annotations.json"))return{type:"annotations-changed",screenId:file.slice(0,-17)};if(file.endsWith(".json")){let stem=file.slice(0,-5);if(!stem.includes("."))return{type:"screen-changed",screenId:stem}}}if(parts[0]==="boards"&&parts[1]){let file=parts[1];if(file.endsWith(".notes.json"))return{type:"notes-changed",boardId:file.slice(0,-11)};if(file.endsWith(".json")){let stem=file.slice(0,-5);if(!stem.includes("."))return{type:"board-changed",boardId:stem}}}if(parts[0]==="theme"&&parts[1]&&/\.(json|css)$/.test(parts[1]))return{type:"theme-changed"};if(parts[0]==="snippets"&&parts[1]&&parts[1].endsWith(".json"))return{type:"snippet-changed",snippetId:parts[1].slice(0,-5)};if(parts.length===1&&parts[0]&&ROOT_CONFIG_FILES.test(parts[0]))return{type:"config-changed"};return null}var ROOT_CONFIG_FILES=/^(preview(\.[\w-]+)?\.(tsx|jsx|ts|js)|repo-components\.json)$/;function watchDesignFolder(root,onEvent,debounceMs=50){let pending=new Map,watchers=[],fingerprint=designFingerprint(root);function schedule(key,ev){let prev=pending.get(key);if(prev)clearTimeout(prev);pending.set(key,setTimeout(()=>{pending.delete(key),onEvent(ev)},debounceMs))}for(let sub of["screens","boards","theme","snippets"])try{let w=watch(join45(root,sub),(_eventType,filename)=>{if(!filename)return;let rel=`${sub}${sep10}${filename}`,ev=classifyWatchPath(rel);if(ev)fingerprint=designFingerprint(root),schedule(rel,ev)});watchers.push(w)}catch{}let poll=setInterval(()=>{let next=designFingerprint(root),paths=new Set([...fingerprint.keys(),...next.keys()]);for(let path of paths){if(fingerprint.get(path)===next.get(path))continue;let event=classifyWatchPath(path);if(event)schedule(path,event)}fingerprint=next},250);return{close(){for(let w of watchers)w.close();clearInterval(poll);for(let t of pending.values())clearTimeout(t);pending.clear()}}}function designFingerprint(root){let out=new Map;try{for(let name of readdirSync3(root)){if(!ROOT_CONFIG_FILES.test(name))continue;let stat=statSync4(join45(root,name));out.set(name,`${stat.mtimeMs}:${stat.size}`)}}catch{}for(let sub of["screens","boards","theme","snippets"]){let dir=join45(root,sub);if(!existsSync17(dir))continue;for(let name of readdirSync3(dir)){let path=join45(dir,name);try{let stat=statSync4(path);if(stat.isFile())out.set(`${sub}${sep10}${name}`,`${stat.mtimeMs}:${stat.size}`)}catch{}}}return out}function watchSourcePaths(paths,onChange,debounceMs=80,pollMs=250){let targets=[...new Set(paths)],watchers=new Map,timer,changed=new Set,unattributed=!1,schedule=(file)=>{if(file)changed.add(file);else unattributed=!0;if(timer)clearTimeout(timer);timer=setTimeout(()=>{timer=void 0;let files=unattributed?[]:[...changed];changed=new Set,unattributed=!1,onChange(files)},debounceMs)},arm=(target)=>{if(watchers.has(target))return;try{if(!statSync4(target).isDirectory())return;watchers.set(target,watch(target,{recursive:!0},(_event,filename)=>{if(filename)schedule(join45(target,String(filename)))}))}catch{}},disarm=(target)=>{watchers.get(target)?.close(),watchers.delete(target)};for(let target of targets)arm(target);let fingerprint=sourceFingerprint(targets),poll=setInterval(()=>{let next=sourceFingerprint(targets);if(next===fingerprint)return;fingerprint=next;for(let target of targets)if(existsSync17(target))arm(target);else disarm(target);schedule()},pollMs);return{close(){for(let watcher of watchers.values())watcher.close();if(watchers.clear(),clearInterval(poll),timer)clearTimeout(timer)}}}function sourceFingerprint(paths){let rows=[],visit=(path)=>{try{if(!existsSync17(path)){rows.push(`${path}:missing`);return}let stat=statSync4(path);if(rows.push(`${path}:${stat.mtimeMs}:${stat.size}`),!stat.isDirectory())return;for(let name of readdirSync3(path).sort())visit(join45(path,name))}catch{rows.push(`${path}:raced`)}};for(let path of paths)visit(path);return rows.join("|")}function createPublishMount(folder,providers,defaultProvider){let repo=createRepoComponents(folder,providers),bundler=new CanvasBundler(folder.root,()=>folder.config.hostApp,(libraryId)=>providers[libraryId]?.canvasBundleSpec,!0,{repo,channelFor:(libraryId)=>{let provider=providers[libraryId];return provider?styleChannelOf(provider,folder.config.styling?.framework).kind:void 0}}),canvasFor=makeCanvasBundle({folder,providers,defaultProvider,canvasBundler:bundler,repo,broadcast:()=>{return}},bundler);return{async forScreen(screen,theme,dark){let mount=await canvasFor(screen,theme,dark);return mount&&new URL(mount.url,"http://publish.local").searchParams.get("refs")?.includes("repo:")?mount:void 0},async serve(url){if(url.pathname!=="/api/canvas/bundle.js")return null;let lib=url.searchParams.get("lib")??folder.config.defaultLibrary,refs=(url.searchParams.get("refs")??"").split(",").filter(Boolean);return(await bundler.build(lib,refs)).code}}}var MIME2={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".mjs":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".woff2":"font/woff2",".ico":"image/x-icon"};async function serveStatic(req,canvasDist){let url=new URL(req.url),requested=url.pathname==="/"?"/index.html":url.pathname,fsPath=join46(canvasDist,requested);if(!(fsPath===canvasDist||fsPath.startsWith(canvasDist+sep11))||!existsSync18(fsPath))return null;let file=Bun.file(fsPath);if(!await file.exists())return null;let type=MIME2[extname4(fsPath)]??"application/octet-stream";return new Response(file,{headers:{"Content-Type":type}})}function extraThemeBlock(folder){let fonts={},palette={},spacing={},shadows={},animation={},keyframes={};for(let theme of folder.themes.values()){for(let[role,stack]of Object.entries(theme.typography.fontFamily??{}))fonts[role]=stack;for(let[name,value]of Object.entries(theme.palette??{}))palette[name]=value;for(let[name,value]of Object.entries(theme.paletteDark??{}))palette[name]??=value;for(let[name,value]of Object.entries(theme.spacing??{})){if(!Number.isNaN(Number(name)))continue;if(typeof value==="string"||typeof value==="number")spacing[name]=String(value)}for(let[name,value]of Object.entries(theme.shadows??{}))if(typeof value==="string"||typeof value==="number")shadows[name]=String(value);for(let[name,value]of Object.entries(theme.animation??{}))animation[name]=value;for(let[name,steps]of Object.entries(theme.keyframes??{}))keyframes[name]=steps}let lines=[...Object.entries(fonts).filter(([role])=>isCssIdent(role)).map(([role,stack])=>` --font-${role}: ${sanitizeCssTokenValue(stack)};`),...Object.entries(palette).map(([name,value])=>` --color-${name}: ${value};`),...Object.entries(spacing).map(([name,value])=>` --spacing-${name}: ${value};`),...Object.entries(shadows).map(([name,value])=>` --shadow-${name}: ${value};`),...Object.entries(animation).map(([name,value])=>` --animate-${name}: ${value};`),...typesetThemeTokens()],keyframesCss=keyframesToCss(Object.keys(keyframes).length>0?keyframes:void 0," "),safelist=typesetSafelist().map((pattern)=>`@source inline("${pattern}");`).join(`
682
682
  `),themeBlock=lines.length===0&&keyframesCss===""?"":`@theme {
683
683
  ${[...lines,keyframesCss].filter(Boolean).join(`