[{"data":1,"prerenderedAt":2391},["ShallowReactive",2],{"navigation-landing-en":3,"navigation-nuxt-auto-en":180,"navigation-nuxt-protokit-en":338,"/docs/nuxt-protokit/advanced/extensibility-en":444,"/docs/nuxt-protokit/advanced/extensibility-surround-en":2388},[4,8,13,28,41,51,64,77,94,110,134,150,157,172],{"title":5,"path":6,"stem":7},"Overview","/docs/landing","0.docs/1.landing/001.index",{"title":9,"path":10,"stem":11,"badge":12},"Built-in Features","/docs/landing/built-in-features","0.docs/1.landing/002.built-in-features","New",{"title":14,"path":15,"stem":16,"children":17,"icon":27},"Content Foundation","/docs/landing/content","0.docs/1.landing/02.content/1.index",[18,19,23],{"title":5,"path":15,"stem":16},{"title":20,"path":21,"stem":22},"Details","/docs/landing/content/details","0.docs/1.landing/02.content/2.details",{"title":24,"path":25,"stem":26},"Technical","/docs/landing/content/technical","0.docs/1.landing/02.content/4.technical","i-heroicons-document-text",{"title":29,"path":30,"stem":31,"children":32,"icon":40},"Regional Content","/docs/landing/regional","0.docs/1.landing/03.regional/1.index",[33,34,37],{"title":5,"path":30,"stem":31},{"title":20,"path":35,"stem":36},"/docs/landing/regional/details","0.docs/1.landing/03.regional/2.details",{"title":24,"path":38,"stem":39},"/docs/landing/regional/technical","0.docs/1.landing/03.regional/4.technical","i-heroicons-globe-alt",{"title":42,"path":43,"stem":44,"children":45,"icon":50},"Multi-language","/docs/landing/multilang","0.docs/1.landing/04.multilang/1.index",[46,47],{"title":5,"path":43,"stem":44},{"title":20,"path":48,"stem":49},"/docs/landing/multilang/details","0.docs/1.landing/04.multilang/2.details","i-heroicons-language",{"title":52,"path":53,"stem":54,"children":55,"icon":63},"Blog","/docs/landing/blog","0.docs/1.landing/05.blog/1.index",[56,57,60],{"title":5,"path":53,"stem":54},{"title":20,"path":58,"stem":59},"/docs/landing/blog/details","0.docs/1.landing/05.blog/2.details",{"title":24,"path":61,"stem":62},"/docs/landing/blog/technical","0.docs/1.landing/05.blog/4.technical","i-heroicons-pencil-square",{"title":65,"path":66,"stem":67,"children":68,"icon":76},"Documentation","/docs/landing/docs","0.docs/1.landing/06.docs/1.index",[69,70,73],{"title":5,"path":66,"stem":67},{"title":20,"path":71,"stem":72},"/docs/landing/docs/details","0.docs/1.landing/06.docs/2.details",{"title":24,"path":74,"stem":75},"/docs/landing/docs/technical","0.docs/1.landing/06.docs/4.technical","i-heroicons-book-open",{"title":78,"path":79,"stem":80,"children":81,"icon":93},"Forms","/docs/landing/forms","0.docs/1.landing/07.forms/1.index",[82,83,86,90],{"title":5,"path":79,"stem":80},{"title":20,"path":84,"stem":85},"/docs/landing/forms/details","0.docs/1.landing/07.forms/2.details",{"title":87,"path":88,"stem":89},"Admin","/docs/landing/forms/admin","0.docs/1.landing/07.forms/3.admin",{"title":24,"path":91,"stem":92},"/docs/landing/forms/technical","0.docs/1.landing/07.forms/4.technical","i-heroicons-clipboard-document-list",{"title":95,"path":96,"stem":97,"children":98,"icon":109},"Email","/docs/landing/email","0.docs/1.landing/08.email/1.index",[99,100,103,106],{"title":5,"path":96,"stem":97},{"title":20,"path":101,"stem":102},"/docs/landing/email/details","0.docs/1.landing/08.email/2.details",{"title":87,"path":104,"stem":105},"/docs/landing/email/admin","0.docs/1.landing/08.email/3.admin",{"title":24,"path":107,"stem":108},"/docs/landing/email/technical","0.docs/1.landing/08.email/4.technical","i-heroicons-envelope",{"title":111,"path":112,"stem":113,"children":114,"icon":133},"Feedback Platform","/docs/landing/feedback","0.docs/1.landing/09.feedback/1.index",[115,116,119,122,125,129],{"title":5,"path":112,"stem":113},{"title":20,"path":117,"stem":118},"/docs/landing/feedback/details","0.docs/1.landing/09.feedback/2.details",{"title":87,"path":120,"stem":121},"/docs/landing/feedback/admin","0.docs/1.landing/09.feedback/3.admin",{"title":24,"path":123,"stem":124},"/docs/landing/feedback/technical","0.docs/1.landing/09.feedback/4.technical",{"title":126,"path":127,"stem":128},"Compare vs SaaS","/docs/landing/feedback/compare","0.docs/1.landing/09.feedback/5.compare",{"title":130,"path":131,"stem":132},"FAQ","/docs/landing/feedback/faq","0.docs/1.landing/09.feedback/6.faq","i-heroicons-chat-bubble-left-right",{"title":135,"path":136,"stem":137,"children":138,"icon":149},"Storage","/docs/landing/storage","0.docs/1.landing/10.storage/1.index",[139,140,143,146],{"title":5,"path":136,"stem":137},{"title":20,"path":141,"stem":142},"/docs/landing/storage/details","0.docs/1.landing/10.storage/2.details",{"title":87,"path":144,"stem":145},"/docs/landing/storage/admin","0.docs/1.landing/10.storage/3.admin",{"title":24,"path":147,"stem":148},"/docs/landing/storage/technical","0.docs/1.landing/10.storage/4.technical","i-heroicons-circle-stack",{"title":151,"path":152,"stem":153,"children":154,"icon":156},"Offline First","/docs/landing/offline-first","0.docs/1.landing/11.offline-first/1.index",[155],{"title":151,"path":152,"stem":153},"i-heroicons-users",{"title":158,"path":159,"stem":160,"children":161,"icon":156},"Yjs Sync","/docs/landing/yjs-sync","0.docs/1.landing/12.yjs-sync/1.index",[162,163,166,169],{"title":5,"path":159,"stem":160},{"title":20,"path":164,"stem":165},"/docs/landing/yjs-sync/details","0.docs/1.landing/12.yjs-sync/2.details",{"title":87,"path":167,"stem":168},"/docs/landing/yjs-sync/admin","0.docs/1.landing/12.yjs-sync/3.admin",{"title":24,"path":170,"stem":171},"/docs/landing/yjs-sync/technical","0.docs/1.landing/12.yjs-sync/4.technical",{"title":173,"path":174,"stem":175,"children":176,"badge":178,"icon":179},"Newsletter","/docs/landing/newsletter","0.docs/1.landing/13.newsletter/index",[177],{"title":173,"path":174,"stem":175,"badge":178},"Coming Soon","i-lucide-send",[181,184,202,298],{"title":5,"path":182,"stem":183},"/docs/nuxt-auto","0.docs/3.nuxt-auto/index",{"title":185,"path":186,"stem":187,"children":188,"page":201},"Getting Started","/docs/nuxt-auto/getting-started","0.docs/3.nuxt-auto/1.getting-started",[189,193,197],{"title":190,"path":191,"stem":192},"Introduction","/docs/nuxt-auto/getting-started/introduction","0.docs/3.nuxt-auto/1.getting-started/1.introduction",{"title":194,"path":195,"stem":196},"Installation","/docs/nuxt-auto/getting-started/installation","0.docs/3.nuxt-auto/1.getting-started/2.installation",{"title":198,"path":199,"stem":200},"Quick Start","/docs/nuxt-auto/getting-started/quick-start","0.docs/3.nuxt-auto/1.getting-started/3.quick-start",false,{"title":203,"path":204,"stem":205,"children":206,"page":201},"Auto API","/docs/nuxt-auto/auto-api","0.docs/3.nuxt-auto/2.auto-api",[207,210,214,218,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290,294],{"title":185,"path":208,"stem":209},"/docs/nuxt-auto/auto-api/getting-started","0.docs/3.nuxt-auto/2.auto-api/1.getting-started",{"title":211,"path":212,"stem":213},"Aggregations","/docs/nuxt-auto/auto-api/aggregations","0.docs/3.nuxt-auto/2.auto-api/10.aggregations",{"title":215,"path":216,"stem":217},"Lifecycle Hooks","/docs/nuxt-auto/auto-api/lifecycle-hooks","0.docs/3.nuxt-auto/2.auto-api/11.lifecycle-hooks",{"title":219,"path":220,"stem":221},"Many-to-Many (M2M) Relationships","/docs/nuxt-auto/auto-api/m2m-relationships","0.docs/3.nuxt-auto/2.auto-api/12.m2m-relationships",{"title":223,"path":224,"stem":225},"Plugin System","/docs/nuxt-auto/auto-api/plugin-system","0.docs/3.nuxt-auto/2.auto-api/13.plugin-system",{"title":227,"path":228,"stem":229},"Database Adapters","/docs/nuxt-auto/auto-api/database-adapters","0.docs/3.nuxt-auto/2.auto-api/14.database-adapters",{"title":231,"path":232,"stem":233},"Custom Endpoints","/docs/nuxt-auto/auto-api/custom-endpoints","0.docs/3.nuxt-auto/2.auto-api/15.custom-endpoints",{"title":235,"path":236,"stem":237},"Multi-Tenancy","/docs/nuxt-auto/auto-api/multi-tenancy","0.docs/3.nuxt-auto/2.auto-api/16.multi-tenancy",{"title":239,"path":240,"stem":241},"Validation","/docs/nuxt-auto/auto-api/validation","0.docs/3.nuxt-auto/2.auto-api/2.validation",{"title":243,"path":244,"stem":245},"Rate Limiting","/docs/nuxt-auto/auto-api/rate-limiting","0.docs/3.nuxt-auto/2.auto-api/20.rate-limiting",{"title":247,"path":248,"stem":249},"Request Metadata Plugin","/docs/nuxt-auto/auto-api/request-metadata","0.docs/3.nuxt-auto/2.auto-api/21.request-metadata",{"title":251,"path":252,"stem":253},"Plugin Catalog","/docs/nuxt-auto/auto-api/plugin-catalog","0.docs/3.nuxt-auto/2.auto-api/22.plugin-catalog",{"title":255,"path":256,"stem":257},"Handler Overrides","/docs/nuxt-auto/auto-api/handler-overrides","0.docs/3.nuxt-auto/2.auto-api/3.handler-overrides",{"title":259,"path":260,"stem":261},"Cloudflare D1","/docs/nuxt-auto/auto-api/cloudflare-d1","0.docs/3.nuxt-auto/2.auto-api/30.cloudflare-d1",{"title":263,"path":264,"stem":265},"SQLite to D1 Migration","/docs/nuxt-auto/auto-api/migration-sqlite-d1","0.docs/3.nuxt-auto/2.auto-api/31.migration-sqlite-d1",{"title":267,"path":268,"stem":269},"Frontend Composables","/docs/nuxt-auto/auto-api/frontend-composables","0.docs/3.nuxt-auto/2.auto-api/32.frontend-composables",{"title":271,"path":272,"stem":273},"Testing","/docs/nuxt-auto/auto-api/testing","0.docs/3.nuxt-auto/2.auto-api/33.testing",{"title":275,"path":276,"stem":277},"Pagination","/docs/nuxt-auto/auto-api/pagination","0.docs/3.nuxt-auto/2.auto-api/4.pagination",{"title":279,"path":280,"stem":281},"Soft Deletes","/docs/nuxt-auto/auto-api/soft-deletes","0.docs/3.nuxt-auto/2.auto-api/5.soft-deletes",{"title":283,"path":284,"stem":285},"Authentication & Authorization","/docs/nuxt-auto/auto-api/authentication-authorization","0.docs/3.nuxt-auto/2.auto-api/6.authentication-authorization",{"title":287,"path":288,"stem":289},"Better-Auth Integration","/docs/nuxt-auto/auto-api/better-auth","0.docs/3.nuxt-auto/2.auto-api/7.better-auth",{"title":291,"path":292,"stem":293},"Nested Relations","/docs/nuxt-auto/auto-api/nested-relationships","0.docs/3.nuxt-auto/2.auto-api/8.nested-relationships",{"title":295,"path":296,"stem":297},"Bulk Operations","/docs/nuxt-auto/auto-api/bulk-operations","0.docs/3.nuxt-auto/2.auto-api/9.bulk-operations",{"title":299,"path":300,"stem":301,"children":302,"page":201},"Auto Admin","/docs/nuxt-auto/auto-admin","0.docs/3.nuxt-auto/3.auto-admin",[303,306,310,314,318,322,326,330,334],{"title":185,"path":304,"stem":305},"/docs/nuxt-auto/auto-admin/getting-started","0.docs/3.nuxt-auto/3.auto-admin/1.getting-started",{"title":307,"path":308,"stem":309},"Configuration & Theming","/docs/nuxt-auto/auto-admin/configuration-theming","0.docs/3.nuxt-auto/3.auto-admin/2.configuration-theming",{"title":311,"path":312,"stem":313},"Resource Configuration","/docs/nuxt-auto/auto-admin/resource-configuration","0.docs/3.nuxt-auto/3.auto-admin/3.resource-configuration",{"title":315,"path":316,"stem":317},"Form Fields & Widgets","/docs/nuxt-auto/auto-admin/form-fields-widgets","0.docs/3.nuxt-auto/3.auto-admin/4.form-fields-widgets",{"title":319,"path":320,"stem":321},"Permissions","/docs/nuxt-auto/auto-admin/permissions","0.docs/3.nuxt-auto/3.auto-admin/5.permissions",{"title":323,"path":324,"stem":325},"Custom Pages","/docs/nuxt-auto/auto-admin/custom-pages","0.docs/3.nuxt-auto/3.auto-admin/6.custom-pages",{"title":327,"path":328,"stem":329},"M2M Relationships","/docs/nuxt-auto/auto-admin/m2m-relationships","0.docs/3.nuxt-auto/3.auto-admin/7.m2m-relationships",{"title":331,"path":332,"stem":333},"Custom Actions","/docs/nuxt-auto/auto-admin/custom-actions","0.docs/3.nuxt-auto/3.auto-admin/8.custom-actions",{"title":335,"path":336,"stem":337},"Composables","/docs/nuxt-auto/auto-admin/composables","0.docs/3.nuxt-auto/3.auto-admin/9.composables",[339,342,355,382,400,415,425],{"title":5,"path":340,"stem":341},"/docs/nuxt-protokit","0.docs/4.nuxt-protokit/index",{"title":185,"path":343,"stem":344,"children":345,"icon":354},"/docs/nuxt-protokit/getting-started","0.docs/4.nuxt-protokit/1.getting-started/1.index",[346,347,351],{"title":190,"path":343,"stem":344},{"title":348,"path":349,"stem":350},"Core Concepts","/docs/nuxt-protokit/getting-started/concepts","0.docs/4.nuxt-protokit/1.getting-started/2.concepts",{"title":198,"path":352,"stem":353},"/docs/nuxt-protokit/getting-started/quick-start","0.docs/4.nuxt-protokit/1.getting-started/3.quick-start","i-lucide-rocket",{"title":356,"path":357,"stem":358,"children":359,"icon":381},"Schemas","/docs/nuxt-protokit/schemas","0.docs/4.nuxt-protokit/2.schemas/1.index",[360,361,365,369,373,377],{"title":5,"path":357,"stem":358},{"title":362,"path":363,"stem":364},"Field Types","/docs/nuxt-protokit/schemas/fields","0.docs/4.nuxt-protokit/2.schemas/2.fields",{"title":366,"path":367,"stem":368},"Collections","/docs/nuxt-protokit/schemas/collections","0.docs/4.nuxt-protokit/2.schemas/3.collections",{"title":370,"path":371,"stem":372},"Derived & Computed","/docs/nuxt-protokit/schemas/derived-computed","0.docs/4.nuxt-protokit/2.schemas/4.derived-computed",{"title":374,"path":375,"stem":376},"Connections","/docs/nuxt-protokit/schemas/connections","0.docs/4.nuxt-protokit/2.schemas/5.connections",{"title":378,"path":379,"stem":380},"Visualizations & Layouts","/docs/nuxt-protokit/schemas/visualizations","0.docs/4.nuxt-protokit/2.schemas/6.visualizations","i-lucide-file-code",{"title":335,"path":383,"stem":384,"children":385,"icon":399},"/docs/nuxt-protokit/composables","0.docs/4.nuxt-protokit/3.composables/1.index",[386,387,391,395],{"title":5,"path":383,"stem":384},{"title":388,"path":389,"stem":390},"usePrototype","/docs/nuxt-protokit/composables/use-prototype","0.docs/4.nuxt-protokit/3.composables/2.use-prototype",{"title":392,"path":393,"stem":394},"useProtoDoc","/docs/nuxt-protokit/composables/use-proto-doc","0.docs/4.nuxt-protokit/3.composables/3.use-proto-doc",{"title":396,"path":397,"stem":398},"useProtoCollection","/docs/nuxt-protokit/composables/use-proto-collection","0.docs/4.nuxt-protokit/3.composables/4.use-proto-collection","i-lucide-layers",{"title":401,"path":402,"stem":403,"children":404,"icon":414},"Components","/docs/nuxt-protokit/components","0.docs/4.nuxt-protokit/4.components/1.index",[405,406,410],{"title":5,"path":402,"stem":403},{"title":407,"path":408,"stem":409},"ProtoTool","/docs/nuxt-protokit/components/proto-tool","0.docs/4.nuxt-protokit/4.components/2.proto-tool",{"title":411,"path":412,"stem":413},"ProtoCrudModal","/docs/nuxt-protokit/components/proto-crud-modal","0.docs/4.nuxt-protokit/4.components/3.proto-crud-modal","i-lucide-puzzle",{"title":151,"path":416,"stem":417,"children":418,"icon":424},"/docs/nuxt-protokit/offline-first","0.docs/4.nuxt-protokit/5.offline-first/1.index",[419,420],{"title":151,"path":416,"stem":417},{"title":421,"path":422,"stem":423},"Corruption Recovery","/docs/nuxt-protokit/offline-first/corruption-recovery","0.docs/4.nuxt-protokit/5.offline-first/2.corruption-recovery","i-lucide-wifi-off",{"title":426,"icon":427,"path":428,"stem":429,"children":430},"Advanced","i-lucide-graduation-cap","/docs/nuxt-protokit/advanced","0.docs/4.nuxt-protokit/6.advanced/1.index",[431,432,436,440],{"title":5,"path":428,"stem":429},{"title":433,"path":434,"stem":435},"Multi-Tool Apps","/docs/nuxt-protokit/advanced/building-a-toolkit","0.docs/4.nuxt-protokit/6.advanced/1.building-a-toolkit",{"title":437,"path":438,"stem":439},"Schema Patterns","/docs/nuxt-protokit/advanced/custom-schema-patterns","0.docs/4.nuxt-protokit/6.advanced/2.custom-schema-patterns",{"title":441,"path":442,"stem":443},"Custom Fields & Viz","/docs/nuxt-protokit/advanced/extensibility","0.docs/4.nuxt-protokit/6.advanced/3.extensibility",{"page":445,"fallbackPage":2383},{"id":446,"title":447,"body":448,"description":2381,"extension":2382,"links":2383,"meta":2384,"navigation":2385,"ogImage":2383,"path":442,"seo":2386,"stem":443,"__hash__":2387},"nuxt_protokit/0.docs/4.nuxt-protokit/6.advanced/3.extensibility.md","Custom Fields & Viz Types",{"type":449,"value":450,"toc":2370},"minimark",[451,455,459,464,472,508,515,533,539,550,802,811,817,830,946,949,953,1322,1326,1341,1508,1512,1530,1665,1672,1675,1925,1931,1935,1950,2366],[452,453,447],"h1",{"id":454},"custom-fields-viz-types",[456,457,458],"p",{},"nuxt-protokit's built-in field and visualization types cover the most common use cases, but sometimes you need something the module does not ship — a rich text editor, a date range picker, a specialized chart. The extensibility system lets you register custom components without forking or patching the module.",[460,461,463],"h2",{"id":462},"namespace-convention","Namespace convention",[456,465,466,467,471],{},"All extension types use a ",[468,469,470],"code",{},"namespace:name"," format:",[473,474,475,496],"ul",{},[476,477,478,482,483,486,487,486,490,486,493],"li",{},[479,480,481],"strong",{},"Built-in types"," use bare names: ",[468,484,485],{},"number",", ",[468,488,489],{},"text",[468,491,492],{},"progress",[468,494,495],{},"bar-chart",[476,497,498,501,502,486,505],{},[479,499,500],{},"Extension types must"," use the colon-separated format: ",[468,503,504],{},"myapp:rich-text",[468,506,507],{},"charts:heatmap",[456,509,510,511,514],{},"TypeScript enforces this at compile time via a ",[468,512,513],{},"\\","${string}:${string}`` template literal type — using a bare name for a custom field is a type error.",[456,516,517,520,521,486,524,486,527,486,530],{},[479,518,519],{},"Reserved namespaces:"," ",[468,522,523],{},"proto",[468,525,526],{},"protokit",[468,528,529],{},"nuxt",[468,531,532],{},"vue",[460,534,536],{"id":535},"defineprotokitextension",[468,537,538],{},"defineProtokitExtension()",[456,540,541,542,545,546,549],{},"Creates a typed extension bundle. Pass it a namespace, an optional ",[468,543,544],{},"fields"," map, and an optional ",[468,547,548],{},"vizTypes"," map:",[551,552,557],"pre",{"className":553,"code":554,"language":555,"meta":556,"style":556},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import MyRichText from '~/components/MyRichText.vue'\n\nconst ext = defineProtokitExtension({\n  namespace: 'myapp',\n  fields: {\n    // Registered as 'myapp:rich-text'\n    'rich-text': { component: MyRichText },\n\n    // Async (lazy-loaded on first use)\n    'date-range': { component: () => import('~/components/MyDateRange.vue') },\n  },\n  vizTypes: {\n    // Registered as 'myapp:heatmap'\n    heatmap: { component: () => import('~/components/MyHeatmap.vue') },\n  },\n})\n","typescript","",[468,558,559,586,593,616,637,648,655,681,686,692,733,739,749,755,788,793],{"__ignoreMap":556},[560,561,564,568,572,575,579,583],"span",{"class":562,"line":563},"line",1,[560,565,567],{"class":566},"s7zQu","import",[560,569,571],{"class":570},"sTEyZ"," MyRichText ",[560,573,574],{"class":566},"from",[560,576,578],{"class":577},"sMK4o"," '",[560,580,582],{"class":581},"sfazB","~/components/MyRichText.vue",[560,584,585],{"class":577},"'\n",[560,587,589],{"class":562,"line":588},2,[560,590,592],{"emptyLinePlaceholder":591},true,"\n",[560,594,596,600,603,606,610,613],{"class":562,"line":595},3,[560,597,599],{"class":598},"spNyl","const",[560,601,602],{"class":570}," ext ",[560,604,605],{"class":577},"=",[560,607,609],{"class":608},"s2Zo4"," defineProtokitExtension",[560,611,612],{"class":570},"(",[560,614,615],{"class":577},"{\n",[560,617,619,623,626,628,631,634],{"class":562,"line":618},4,[560,620,622],{"class":621},"swJcz","  namespace",[560,624,625],{"class":577},":",[560,627,578],{"class":577},[560,629,630],{"class":581},"myapp",[560,632,633],{"class":577},"'",[560,635,636],{"class":577},",\n",[560,638,640,643,645],{"class":562,"line":639},5,[560,641,642],{"class":621},"  fields",[560,644,625],{"class":577},[560,646,647],{"class":577}," {\n",[560,649,651],{"class":562,"line":650},6,[560,652,654],{"class":653},"sHwdD","    // Registered as 'myapp:rich-text'\n",[560,656,658,661,664,666,668,671,674,676,678],{"class":562,"line":657},7,[560,659,660],{"class":577},"    '",[560,662,663],{"class":621},"rich-text",[560,665,633],{"class":577},[560,667,625],{"class":577},[560,669,670],{"class":577}," {",[560,672,673],{"class":621}," component",[560,675,625],{"class":577},[560,677,571],{"class":570},[560,679,680],{"class":577},"},\n",[560,682,684],{"class":562,"line":683},8,[560,685,592],{"emptyLinePlaceholder":591},[560,687,689],{"class":562,"line":688},9,[560,690,691],{"class":653},"    // Async (lazy-loaded on first use)\n",[560,693,695,697,700,702,704,706,708,710,713,716,719,721,723,726,728,731],{"class":562,"line":694},10,[560,696,660],{"class":577},[560,698,699],{"class":621},"date-range",[560,701,633],{"class":577},[560,703,625],{"class":577},[560,705,670],{"class":577},[560,707,673],{"class":608},[560,709,625],{"class":577},[560,711,712],{"class":577}," ()",[560,714,715],{"class":598}," =>",[560,717,718],{"class":577}," import",[560,720,612],{"class":570},[560,722,633],{"class":577},[560,724,725],{"class":581},"~/components/MyDateRange.vue",[560,727,633],{"class":577},[560,729,730],{"class":570},") ",[560,732,680],{"class":577},[560,734,736],{"class":562,"line":735},11,[560,737,738],{"class":577},"  },\n",[560,740,742,745,747],{"class":562,"line":741},12,[560,743,744],{"class":621},"  vizTypes",[560,746,625],{"class":577},[560,748,647],{"class":577},[560,750,752],{"class":562,"line":751},13,[560,753,754],{"class":653},"    // Registered as 'myapp:heatmap'\n",[560,756,758,761,763,765,767,769,771,773,775,777,779,782,784,786],{"class":562,"line":757},14,[560,759,760],{"class":621},"    heatmap",[560,762,625],{"class":577},[560,764,670],{"class":577},[560,766,673],{"class":608},[560,768,625],{"class":577},[560,770,712],{"class":577},[560,772,715],{"class":598},[560,774,718],{"class":577},[560,776,612],{"class":570},[560,778,633],{"class":577},[560,780,781],{"class":581},"~/components/MyHeatmap.vue",[560,783,633],{"class":577},[560,785,730],{"class":570},[560,787,680],{"class":577},[560,789,791],{"class":562,"line":790},15,[560,792,738],{"class":577},[560,794,796,799],{"class":562,"line":795},16,[560,797,798],{"class":577},"}",[560,800,801],{"class":570},")\n",[456,803,804,805,807,808,810],{},"Keys inside ",[468,806,544],{}," and ",[468,809,548],{}," are the short names — the namespace is prepended automatically.",[460,812,814],{"id":813},"useprotoextensionregistry",[468,815,816],{},"useProtoExtensionRegistry()",[456,818,819,820,823,824,807,827,625],{},"Call ",[468,821,822],{},"registerExtension"," to make the extension available to ",[468,825,826],{},"ProtoForm",[468,828,829],{},"ProtoViz",[551,831,833],{"className":553,"code":832,"language":555,"meta":556,"style":556},"// plugins/extensions.ts\nexport default defineNuxtPlugin(() => {\n  const ext = defineProtokitExtension({ namespace: 'myapp', fields: { ... } })\n  const { registerExtension } = useProtoExtensionRegistry()\n  registerExtension(ext)\n})\n",[468,834,835,840,860,909,928,940],{"__ignoreMap":556},[560,836,837],{"class":562,"line":563},[560,838,839],{"class":653},"// plugins/extensions.ts\n",[560,841,842,845,848,851,853,856,858],{"class":562,"line":588},[560,843,844],{"class":566},"export",[560,846,847],{"class":566}," default",[560,849,850],{"class":608}," defineNuxtPlugin",[560,852,612],{"class":570},[560,854,855],{"class":577},"()",[560,857,715],{"class":598},[560,859,647],{"class":577},[560,861,862,865,868,871,873,875,878,881,883,885,887,889,892,895,897,899,902,905,907],{"class":562,"line":595},[560,863,864],{"class":598},"  const",[560,866,867],{"class":570}," ext",[560,869,870],{"class":577}," =",[560,872,609],{"class":608},[560,874,612],{"class":621},[560,876,877],{"class":577},"{",[560,879,880],{"class":621}," namespace",[560,882,625],{"class":577},[560,884,578],{"class":577},[560,886,630],{"class":581},[560,888,633],{"class":577},[560,890,891],{"class":577},",",[560,893,894],{"class":621}," fields",[560,896,625],{"class":577},[560,898,670],{"class":577},[560,900,901],{"class":577}," ...",[560,903,904],{"class":577}," }",[560,906,904],{"class":577},[560,908,801],{"class":621},[560,910,911,913,915,918,920,922,925],{"class":562,"line":618},[560,912,864],{"class":598},[560,914,670],{"class":577},[560,916,917],{"class":570}," registerExtension",[560,919,904],{"class":577},[560,921,870],{"class":577},[560,923,924],{"class":608}," useProtoExtensionRegistry",[560,926,927],{"class":621},"()\n",[560,929,930,933,935,938],{"class":562,"line":639},[560,931,932],{"class":608},"  registerExtension",[560,934,612],{"class":621},[560,936,937],{"class":570},"ext",[560,939,801],{"class":621},[560,941,942,944],{"class":562,"line":650},[560,943,798],{"class":577},[560,945,801],{"class":570},[456,947,948],{},"The registry is module-level — all composable calls share the same maps. Registering in a plugin guarantees it runs once before any component renders.",[460,950,952],{"id":951},"using-extension-types-in-a-schema","Using extension types in a schema",[551,954,956],{"className":553,"code":955,"language":555,"meta":556,"style":556},"definePrototype({\n  key: 'my-tool',\n  fields: {\n    body: {\n      type: 'myapp:rich-text',   // namespaced — TypeScript accepts this\n      label: 'Content',\n      default: '',\n      props: {\n        // Keys from props are passed verbatim as component props\n        toolbar: ['bold', 'italic', 'link'],\n        minHeight: 200,\n      },\n    },\n    dates: {\n      type: 'myapp:date-range',\n      label: 'Active Period',\n      default: null,\n    },\n  },\n  visualizations: [\n    {\n      type: 'myapp:heatmap',\n      title: 'Activity Heatmap',\n      config: {\n        // config is passed as a :config prop to the viz component\n        weeks: 16,\n        data: (ctx) => ctx.derived.activityData,\n      },\n    },\n  ],\n})\n",[468,957,958,967,983,991,1000,1018,1034,1046,1055,1060,1100,1113,1118,1123,1132,1147,1162,1172,1177,1182,1193,1199,1215,1232,1242,1248,1261,1297,1302,1307,1315],{"__ignoreMap":556},[560,959,960,963,965],{"class":562,"line":563},[560,961,962],{"class":608},"definePrototype",[560,964,612],{"class":570},[560,966,615],{"class":577},[560,968,969,972,974,976,979,981],{"class":562,"line":588},[560,970,971],{"class":621},"  key",[560,973,625],{"class":577},[560,975,578],{"class":577},[560,977,978],{"class":581},"my-tool",[560,980,633],{"class":577},[560,982,636],{"class":577},[560,984,985,987,989],{"class":562,"line":595},[560,986,642],{"class":621},[560,988,625],{"class":577},[560,990,647],{"class":577},[560,992,993,996,998],{"class":562,"line":618},[560,994,995],{"class":621},"    body",[560,997,625],{"class":577},[560,999,647],{"class":577},[560,1001,1002,1005,1007,1009,1011,1013,1015],{"class":562,"line":639},[560,1003,1004],{"class":621},"      type",[560,1006,625],{"class":577},[560,1008,578],{"class":577},[560,1010,504],{"class":581},[560,1012,633],{"class":577},[560,1014,891],{"class":577},[560,1016,1017],{"class":653},"   // namespaced — TypeScript accepts this\n",[560,1019,1020,1023,1025,1027,1030,1032],{"class":562,"line":650},[560,1021,1022],{"class":621},"      label",[560,1024,625],{"class":577},[560,1026,578],{"class":577},[560,1028,1029],{"class":581},"Content",[560,1031,633],{"class":577},[560,1033,636],{"class":577},[560,1035,1036,1039,1041,1044],{"class":562,"line":657},[560,1037,1038],{"class":621},"      default",[560,1040,625],{"class":577},[560,1042,1043],{"class":577}," ''",[560,1045,636],{"class":577},[560,1047,1048,1051,1053],{"class":562,"line":683},[560,1049,1050],{"class":621},"      props",[560,1052,625],{"class":577},[560,1054,647],{"class":577},[560,1056,1057],{"class":562,"line":688},[560,1058,1059],{"class":653},"        // Keys from props are passed verbatim as component props\n",[560,1061,1062,1065,1067,1070,1072,1075,1077,1079,1081,1084,1086,1088,1090,1093,1095,1098],{"class":562,"line":694},[560,1063,1064],{"class":621},"        toolbar",[560,1066,625],{"class":577},[560,1068,1069],{"class":570}," [",[560,1071,633],{"class":577},[560,1073,1074],{"class":581},"bold",[560,1076,633],{"class":577},[560,1078,891],{"class":577},[560,1080,578],{"class":577},[560,1082,1083],{"class":581},"italic",[560,1085,633],{"class":577},[560,1087,891],{"class":577},[560,1089,578],{"class":577},[560,1091,1092],{"class":581},"link",[560,1094,633],{"class":577},[560,1096,1097],{"class":570},"]",[560,1099,636],{"class":577},[560,1101,1102,1105,1107,1111],{"class":562,"line":735},[560,1103,1104],{"class":621},"        minHeight",[560,1106,625],{"class":577},[560,1108,1110],{"class":1109},"sbssI"," 200",[560,1112,636],{"class":577},[560,1114,1115],{"class":562,"line":741},[560,1116,1117],{"class":577},"      },\n",[560,1119,1120],{"class":562,"line":751},[560,1121,1122],{"class":577},"    },\n",[560,1124,1125,1128,1130],{"class":562,"line":757},[560,1126,1127],{"class":621},"    dates",[560,1129,625],{"class":577},[560,1131,647],{"class":577},[560,1133,1134,1136,1138,1140,1143,1145],{"class":562,"line":790},[560,1135,1004],{"class":621},[560,1137,625],{"class":577},[560,1139,578],{"class":577},[560,1141,1142],{"class":581},"myapp:date-range",[560,1144,633],{"class":577},[560,1146,636],{"class":577},[560,1148,1149,1151,1153,1155,1158,1160],{"class":562,"line":795},[560,1150,1022],{"class":621},[560,1152,625],{"class":577},[560,1154,578],{"class":577},[560,1156,1157],{"class":581},"Active Period",[560,1159,633],{"class":577},[560,1161,636],{"class":577},[560,1163,1165,1167,1169],{"class":562,"line":1164},17,[560,1166,1038],{"class":621},[560,1168,625],{"class":577},[560,1170,1171],{"class":577}," null,\n",[560,1173,1175],{"class":562,"line":1174},18,[560,1176,1122],{"class":577},[560,1178,1180],{"class":562,"line":1179},19,[560,1181,738],{"class":577},[560,1183,1185,1188,1190],{"class":562,"line":1184},20,[560,1186,1187],{"class":621},"  visualizations",[560,1189,625],{"class":577},[560,1191,1192],{"class":570}," [\n",[560,1194,1196],{"class":562,"line":1195},21,[560,1197,1198],{"class":577},"    {\n",[560,1200,1202,1204,1206,1208,1211,1213],{"class":562,"line":1201},22,[560,1203,1004],{"class":621},[560,1205,625],{"class":577},[560,1207,578],{"class":577},[560,1209,1210],{"class":581},"myapp:heatmap",[560,1212,633],{"class":577},[560,1214,636],{"class":577},[560,1216,1218,1221,1223,1225,1228,1230],{"class":562,"line":1217},23,[560,1219,1220],{"class":621},"      title",[560,1222,625],{"class":577},[560,1224,578],{"class":577},[560,1226,1227],{"class":581},"Activity Heatmap",[560,1229,633],{"class":577},[560,1231,636],{"class":577},[560,1233,1235,1238,1240],{"class":562,"line":1234},24,[560,1236,1237],{"class":621},"      config",[560,1239,625],{"class":577},[560,1241,647],{"class":577},[560,1243,1245],{"class":562,"line":1244},25,[560,1246,1247],{"class":653},"        // config is passed as a :config prop to the viz component\n",[560,1249,1251,1254,1256,1259],{"class":562,"line":1250},26,[560,1252,1253],{"class":621},"        weeks",[560,1255,625],{"class":577},[560,1257,1258],{"class":1109}," 16",[560,1260,636],{"class":577},[560,1262,1264,1267,1269,1272,1276,1279,1281,1284,1287,1290,1292,1295],{"class":562,"line":1263},27,[560,1265,1266],{"class":608},"        data",[560,1268,625],{"class":577},[560,1270,1271],{"class":577}," (",[560,1273,1275],{"class":1274},"sHdIc","ctx",[560,1277,1278],{"class":577},")",[560,1280,715],{"class":598},[560,1282,1283],{"class":570}," ctx",[560,1285,1286],{"class":577},".",[560,1288,1289],{"class":570},"derived",[560,1291,1286],{"class":577},[560,1293,1294],{"class":570},"activityData",[560,1296,636],{"class":577},[560,1298,1300],{"class":562,"line":1299},28,[560,1301,1117],{"class":577},[560,1303,1305],{"class":562,"line":1304},29,[560,1306,1122],{"class":577},[560,1308,1310,1313],{"class":562,"line":1309},30,[560,1311,1312],{"class":570},"  ]",[560,1314,636],{"class":577},[560,1316,1318,1320],{"class":562,"line":1317},31,[560,1319,798],{"class":577},[560,1321,801],{"class":570},[460,1323,1325],{"id":1324},"custom-field-component-interface","Custom field component interface",[456,1327,1328,1329,1332,1333,1336,1337,1340],{},"A custom field component receives ",[468,1330,1331],{},"modelValue"," / ",[468,1334,1335],{},"onUpdate:modelValue"," for v-model, plus any keys from ",[468,1338,1339],{},"props"," in the field definition:",[551,1342,1345],{"className":1343,"code":1344,"language":532,"meta":556,"style":556},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- components/MyRichText.vue -->\n\u003Cscript setup lang=\"ts\">\ndefineProps\u003C{\n  modelValue: string\n  toolbar?: string[]\n  minHeight?: number\n}>()\n\nconst emit = defineEmits\u003C{ 'update:modelValue': [value: string] }>()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003C!-- your editor here -->\n\u003C/template>\n",[468,1346,1347,1352,1379,1387,1398,1412,1422,1429,1433,1473,1482,1486,1495,1500],{"__ignoreMap":556},[560,1348,1349],{"class":562,"line":563},[560,1350,1351],{"class":653},"\u003C!-- components/MyRichText.vue -->\n",[560,1353,1354,1357,1360,1363,1366,1368,1371,1374,1376],{"class":562,"line":588},[560,1355,1356],{"class":577},"\u003C",[560,1358,1359],{"class":621},"script",[560,1361,1362],{"class":598}," setup",[560,1364,1365],{"class":598}," lang",[560,1367,605],{"class":577},[560,1369,1370],{"class":577},"\"",[560,1372,1373],{"class":581},"ts",[560,1375,1370],{"class":577},[560,1377,1378],{"class":577},">\n",[560,1380,1381,1384],{"class":562,"line":595},[560,1382,1383],{"class":608},"defineProps",[560,1385,1386],{"class":577},"\u003C{\n",[560,1388,1389,1392,1394],{"class":562,"line":618},[560,1390,1391],{"class":621},"  modelValue",[560,1393,625],{"class":577},[560,1395,1397],{"class":1396},"sBMFI"," string\n",[560,1399,1400,1403,1406,1409],{"class":562,"line":639},[560,1401,1402],{"class":621},"  toolbar",[560,1404,1405],{"class":577},"?:",[560,1407,1408],{"class":1396}," string",[560,1410,1411],{"class":570},"[]\n",[560,1413,1414,1417,1419],{"class":562,"line":650},[560,1415,1416],{"class":621},"  minHeight",[560,1418,1405],{"class":577},[560,1420,1421],{"class":1396}," number\n",[560,1423,1424,1427],{"class":562,"line":657},[560,1425,1426],{"class":577},"}>",[560,1428,927],{"class":570},[560,1430,1431],{"class":562,"line":683},[560,1432,592],{"emptyLinePlaceholder":591},[560,1434,1435,1437,1440,1442,1445,1448,1450,1453,1455,1457,1459,1462,1464,1466,1469,1471],{"class":562,"line":688},[560,1436,599],{"class":598},[560,1438,1439],{"class":570}," emit ",[560,1441,605],{"class":577},[560,1443,1444],{"class":608}," defineEmits",[560,1446,1447],{"class":577},"\u003C{",[560,1449,578],{"class":577},[560,1451,1452],{"class":581},"update:modelValue",[560,1454,633],{"class":577},[560,1456,625],{"class":577},[560,1458,1069],{"class":570},[560,1460,1461],{"class":1396},"value",[560,1463,625],{"class":577},[560,1465,1408],{"class":1396},[560,1467,1468],{"class":570},"] ",[560,1470,1426],{"class":577},[560,1472,927],{"class":570},[560,1474,1475,1478,1480],{"class":562,"line":694},[560,1476,1477],{"class":577},"\u003C/",[560,1479,1359],{"class":621},[560,1481,1378],{"class":577},[560,1483,1484],{"class":562,"line":735},[560,1485,592],{"emptyLinePlaceholder":591},[560,1487,1488,1490,1493],{"class":562,"line":741},[560,1489,1356],{"class":577},[560,1491,1492],{"class":621},"template",[560,1494,1378],{"class":577},[560,1496,1497],{"class":562,"line":751},[560,1498,1499],{"class":653},"  \u003C!-- your editor here -->\n",[560,1501,1502,1504,1506],{"class":562,"line":757},[560,1503,1477],{"class":577},[560,1505,1492],{"class":621},[560,1507,1378],{"class":577},[460,1509,1511],{"id":1510},"custom-viz-component-interface","Custom viz component interface",[456,1513,1514,1515,1518,1519,1521,1522,1525,1526,1529],{},"A custom viz component receives ",[468,1516,1517],{},"config"," (the ",[468,1520,1517],{}," object from the schema) and ",[468,1523,1524],{},"context"," (the full ",[468,1527,1528],{},"ComputeContext","):",[551,1531,1533],{"className":1343,"code":1532,"language":532,"meta":556,"style":556},"\u003C!-- components/MyHeatmap.vue -->\n\u003Cscript setup lang=\"ts\">\nimport type { ComputeContext } from '@websideproject/nuxt-protokit'\n\ndefineProps\u003C{\n  config: Record\u003Cstring, any>\n  context: ComputeContext\n}>()\n\u003C/script>\n\n\u003Ctemplate>\n  \u003C!-- your chart here, driven by config and context -->\n\u003C/template>\n",[468,1534,1535,1540,1560,1584,1588,1594,1616,1626,1632,1640,1644,1652,1657],{"__ignoreMap":556},[560,1536,1537],{"class":562,"line":563},[560,1538,1539],{"class":653},"\u003C!-- components/MyHeatmap.vue -->\n",[560,1541,1542,1544,1546,1548,1550,1552,1554,1556,1558],{"class":562,"line":588},[560,1543,1356],{"class":577},[560,1545,1359],{"class":621},[560,1547,1362],{"class":598},[560,1549,1365],{"class":598},[560,1551,605],{"class":577},[560,1553,1370],{"class":577},[560,1555,1373],{"class":581},[560,1557,1370],{"class":577},[560,1559,1378],{"class":577},[560,1561,1562,1564,1567,1569,1572,1574,1577,1579,1582],{"class":562,"line":595},[560,1563,567],{"class":566},[560,1565,1566],{"class":566}," type",[560,1568,670],{"class":577},[560,1570,1571],{"class":570}," ComputeContext",[560,1573,904],{"class":577},[560,1575,1576],{"class":566}," from",[560,1578,578],{"class":577},[560,1580,1581],{"class":581},"@websideproject/nuxt-protokit",[560,1583,585],{"class":577},[560,1585,1586],{"class":562,"line":618},[560,1587,592],{"emptyLinePlaceholder":591},[560,1589,1590,1592],{"class":562,"line":639},[560,1591,1383],{"class":608},[560,1593,1386],{"class":577},[560,1595,1596,1599,1601,1604,1606,1609,1611,1614],{"class":562,"line":650},[560,1597,1598],{"class":621},"  config",[560,1600,625],{"class":577},[560,1602,1603],{"class":1396}," Record",[560,1605,1356],{"class":577},[560,1607,1608],{"class":1396},"string",[560,1610,891],{"class":577},[560,1612,1613],{"class":1396}," any",[560,1615,1378],{"class":577},[560,1617,1618,1621,1623],{"class":562,"line":657},[560,1619,1620],{"class":621},"  context",[560,1622,625],{"class":577},[560,1624,1625],{"class":1396}," ComputeContext\n",[560,1627,1628,1630],{"class":562,"line":683},[560,1629,1426],{"class":577},[560,1631,927],{"class":570},[560,1633,1634,1636,1638],{"class":562,"line":688},[560,1635,1477],{"class":577},[560,1637,1359],{"class":621},[560,1639,1378],{"class":577},[560,1641,1642],{"class":562,"line":694},[560,1643,592],{"emptyLinePlaceholder":591},[560,1645,1646,1648,1650],{"class":562,"line":735},[560,1647,1356],{"class":577},[560,1649,1492],{"class":621},[560,1651,1378],{"class":577},[560,1653,1654],{"class":562,"line":741},[560,1655,1656],{"class":653},"  \u003C!-- your chart here, driven by config and context -->\n",[560,1658,1659,1661,1663],{"class":562,"line":751},[560,1660,1477],{"class":577},[560,1662,1492],{"class":621},[560,1664,1378],{"class":577},[460,1666,1668,1671],{"id":1667},"protokitregister-extension-hook",[468,1669,1670],{},"protokit:register-extension"," hook",[456,1673,1674],{},"Nuxt module authors who ship companion extension packages can use this hook to add component and import directories at build time, without requiring users to manually configure anything:",[551,1676,1678],{"className":553,"code":1677,"language":555,"meta":556,"style":556},"// modules/my-charts/index.ts\nimport { defineNuxtModule, addComponentsDir, addImportsDir, createResolver } from '@nuxt/kit'\n\nexport default defineNuxtModule({\n  meta: { name: 'my-charts' },\n  setup(_options, nuxt) {\n    const resolver = createResolver(import.meta.url)\n\n    nuxt.hook('protokit:register-extension', ({ addComponentsDir, addImportsDir }) => {\n      // These dirs are registered via nuxt-protokit's own setup,\n      // so components are available globally and composables are auto-imported.\n      addComponentsDir(resolver.resolve('./runtime/components'))\n      addImportsDir(resolver.resolve('./runtime/composables'))\n    })\n  },\n})\n",[468,1679,1680,1685,1720,1724,1736,1760,1779,1807,1811,1847,1852,1857,1884,1908,1915,1919],{"__ignoreMap":556},[560,1681,1682],{"class":562,"line":563},[560,1683,1684],{"class":653},"// modules/my-charts/index.ts\n",[560,1686,1687,1689,1691,1694,1696,1699,1701,1704,1706,1709,1711,1713,1715,1718],{"class":562,"line":588},[560,1688,567],{"class":566},[560,1690,670],{"class":577},[560,1692,1693],{"class":570}," defineNuxtModule",[560,1695,891],{"class":577},[560,1697,1698],{"class":570}," addComponentsDir",[560,1700,891],{"class":577},[560,1702,1703],{"class":570}," addImportsDir",[560,1705,891],{"class":577},[560,1707,1708],{"class":570}," createResolver",[560,1710,904],{"class":577},[560,1712,1576],{"class":566},[560,1714,578],{"class":577},[560,1716,1717],{"class":581},"@nuxt/kit",[560,1719,585],{"class":577},[560,1721,1722],{"class":562,"line":595},[560,1723,592],{"emptyLinePlaceholder":591},[560,1725,1726,1728,1730,1732,1734],{"class":562,"line":618},[560,1727,844],{"class":566},[560,1729,847],{"class":566},[560,1731,1693],{"class":608},[560,1733,612],{"class":570},[560,1735,615],{"class":577},[560,1737,1738,1741,1743,1745,1748,1750,1752,1755,1757],{"class":562,"line":639},[560,1739,1740],{"class":621},"  meta",[560,1742,625],{"class":577},[560,1744,670],{"class":577},[560,1746,1747],{"class":621}," name",[560,1749,625],{"class":577},[560,1751,578],{"class":577},[560,1753,1754],{"class":581},"my-charts",[560,1756,633],{"class":577},[560,1758,1759],{"class":577}," },\n",[560,1761,1762,1765,1767,1770,1772,1775,1777],{"class":562,"line":650},[560,1763,1764],{"class":621},"  setup",[560,1766,612],{"class":577},[560,1768,1769],{"class":1274},"_options",[560,1771,891],{"class":577},[560,1773,1774],{"class":1274}," nuxt",[560,1776,1278],{"class":577},[560,1778,647],{"class":577},[560,1780,1781,1784,1787,1789,1791,1793,1795,1797,1800,1802,1805],{"class":562,"line":657},[560,1782,1783],{"class":598},"    const",[560,1785,1786],{"class":570}," resolver",[560,1788,870],{"class":577},[560,1790,1708],{"class":608},[560,1792,612],{"class":621},[560,1794,567],{"class":566},[560,1796,1286],{"class":577},[560,1798,1799],{"class":570},"meta",[560,1801,1286],{"class":577},[560,1803,1804],{"class":570},"url",[560,1806,801],{"class":621},[560,1808,1809],{"class":562,"line":683},[560,1810,592],{"emptyLinePlaceholder":591},[560,1812,1813,1816,1818,1821,1823,1825,1827,1829,1831,1834,1836,1838,1840,1843,1845],{"class":562,"line":688},[560,1814,1815],{"class":570},"    nuxt",[560,1817,1286],{"class":577},[560,1819,1820],{"class":608},"hook",[560,1822,612],{"class":621},[560,1824,633],{"class":577},[560,1826,1670],{"class":581},[560,1828,633],{"class":577},[560,1830,891],{"class":577},[560,1832,1833],{"class":577}," ({",[560,1835,1698],{"class":1274},[560,1837,891],{"class":577},[560,1839,1703],{"class":1274},[560,1841,1842],{"class":577}," })",[560,1844,715],{"class":598},[560,1846,647],{"class":577},[560,1848,1849],{"class":562,"line":694},[560,1850,1851],{"class":653},"      // These dirs are registered via nuxt-protokit's own setup,\n",[560,1853,1854],{"class":562,"line":735},[560,1855,1856],{"class":653},"      // so components are available globally and composables are auto-imported.\n",[560,1858,1859,1862,1864,1867,1869,1872,1874,1876,1879,1881],{"class":562,"line":741},[560,1860,1861],{"class":608},"      addComponentsDir",[560,1863,612],{"class":621},[560,1865,1866],{"class":570},"resolver",[560,1868,1286],{"class":577},[560,1870,1871],{"class":608},"resolve",[560,1873,612],{"class":621},[560,1875,633],{"class":577},[560,1877,1878],{"class":581},"./runtime/components",[560,1880,633],{"class":577},[560,1882,1883],{"class":621},"))\n",[560,1885,1886,1889,1891,1893,1895,1897,1899,1901,1904,1906],{"class":562,"line":751},[560,1887,1888],{"class":608},"      addImportsDir",[560,1890,612],{"class":621},[560,1892,1866],{"class":570},[560,1894,1286],{"class":577},[560,1896,1871],{"class":608},[560,1898,612],{"class":621},[560,1900,633],{"class":577},[560,1902,1903],{"class":581},"./runtime/composables",[560,1905,633],{"class":577},[560,1907,1883],{"class":621},[560,1909,1910,1913],{"class":562,"line":757},[560,1911,1912],{"class":577},"    }",[560,1914,801],{"class":621},[560,1916,1917],{"class":562,"line":790},[560,1918,738],{"class":577},[560,1920,1921,1923],{"class":562,"line":795},[560,1922,798],{"class":577},[560,1924,801],{"class":570},[456,1926,1927,1928,1930],{},"Users of your companion module can then use ",[468,1929,470],{}," types in their schemas with zero extra configuration.",[460,1932,1934],{"id":1933},"full-example","Full example",[456,1936,1937,1938,1941,1942,1945,1946,1949],{},"The playground includes a working demo at ",[468,1939,1940],{},"/custom-extensions"," that registers a ",[468,1943,1944],{},"demo:priority"," field (a colored priority selector) and a ",[468,1947,1948],{},"demo:gauge"," viz (an SVG gauge chart) entirely at the page level — no plugin, no module config.",[551,1951,1953],{"className":553,"code":1952,"language":555,"meta":556,"style":556},"// pages/custom-extensions.vue\nimport CustomPriorityField from '~/components/CustomPriorityField.vue'\nimport CustomGaugeViz from '~/components/CustomGaugeViz.vue'\n\nconst ext = defineProtokitExtension({\n  namespace: 'demo',\n  fields: {\n    priority: { component: CustomPriorityField },\n  },\n  vizTypes: {\n    gauge: { component: CustomGaugeViz },\n  },\n})\n\nconst { registerExtension } = useProtoExtensionRegistry()\nregisterExtension(ext)\n\nconst schema: PrototypeSchema = {\n  fields: {\n    priority: {\n      type: 'demo:priority',   // custom field\n      label: 'Priority',\n      default: 'medium',\n      props: { options: ['low', 'medium', 'high', 'critical'] },\n    },\n  },\n  visualizations: [\n    {\n      type: 'demo:gauge',      // custom viz\n      title: 'Health Score',\n      config: { value: (ctx) => ctx.derived.healthScore, max: 100 },\n    },\n  ],\n}\n",[468,1954,1955,1960,1976,1992,1996,2010,2025,2033,2050,2054,2062,2079,2083,2089,2093,2110,2117,2121,2137,2145,2153,2170,2185,2200,2252,2256,2260,2268,2272,2289,2304,2348,2353,2360],{"__ignoreMap":556},[560,1956,1957],{"class":562,"line":563},[560,1958,1959],{"class":653},"// pages/custom-extensions.vue\n",[560,1961,1962,1964,1967,1969,1971,1974],{"class":562,"line":588},[560,1963,567],{"class":566},[560,1965,1966],{"class":570}," CustomPriorityField ",[560,1968,574],{"class":566},[560,1970,578],{"class":577},[560,1972,1973],{"class":581},"~/components/CustomPriorityField.vue",[560,1975,585],{"class":577},[560,1977,1978,1980,1983,1985,1987,1990],{"class":562,"line":595},[560,1979,567],{"class":566},[560,1981,1982],{"class":570}," CustomGaugeViz ",[560,1984,574],{"class":566},[560,1986,578],{"class":577},[560,1988,1989],{"class":581},"~/components/CustomGaugeViz.vue",[560,1991,585],{"class":577},[560,1993,1994],{"class":562,"line":618},[560,1995,592],{"emptyLinePlaceholder":591},[560,1997,1998,2000,2002,2004,2006,2008],{"class":562,"line":639},[560,1999,599],{"class":598},[560,2001,602],{"class":570},[560,2003,605],{"class":577},[560,2005,609],{"class":608},[560,2007,612],{"class":570},[560,2009,615],{"class":577},[560,2011,2012,2014,2016,2018,2021,2023],{"class":562,"line":650},[560,2013,622],{"class":621},[560,2015,625],{"class":577},[560,2017,578],{"class":577},[560,2019,2020],{"class":581},"demo",[560,2022,633],{"class":577},[560,2024,636],{"class":577},[560,2026,2027,2029,2031],{"class":562,"line":657},[560,2028,642],{"class":621},[560,2030,625],{"class":577},[560,2032,647],{"class":577},[560,2034,2035,2038,2040,2042,2044,2046,2048],{"class":562,"line":683},[560,2036,2037],{"class":621},"    priority",[560,2039,625],{"class":577},[560,2041,670],{"class":577},[560,2043,673],{"class":621},[560,2045,625],{"class":577},[560,2047,1966],{"class":570},[560,2049,680],{"class":577},[560,2051,2052],{"class":562,"line":688},[560,2053,738],{"class":577},[560,2055,2056,2058,2060],{"class":562,"line":694},[560,2057,744],{"class":621},[560,2059,625],{"class":577},[560,2061,647],{"class":577},[560,2063,2064,2067,2069,2071,2073,2075,2077],{"class":562,"line":735},[560,2065,2066],{"class":621},"    gauge",[560,2068,625],{"class":577},[560,2070,670],{"class":577},[560,2072,673],{"class":621},[560,2074,625],{"class":577},[560,2076,1982],{"class":570},[560,2078,680],{"class":577},[560,2080,2081],{"class":562,"line":741},[560,2082,738],{"class":577},[560,2084,2085,2087],{"class":562,"line":751},[560,2086,798],{"class":577},[560,2088,801],{"class":570},[560,2090,2091],{"class":562,"line":757},[560,2092,592],{"emptyLinePlaceholder":591},[560,2094,2095,2097,2099,2102,2104,2106,2108],{"class":562,"line":790},[560,2096,599],{"class":598},[560,2098,670],{"class":577},[560,2100,2101],{"class":570}," registerExtension ",[560,2103,798],{"class":577},[560,2105,870],{"class":577},[560,2107,924],{"class":608},[560,2109,927],{"class":570},[560,2111,2112,2114],{"class":562,"line":795},[560,2113,822],{"class":608},[560,2115,2116],{"class":570},"(ext)\n",[560,2118,2119],{"class":562,"line":1164},[560,2120,592],{"emptyLinePlaceholder":591},[560,2122,2123,2125,2128,2130,2133,2135],{"class":562,"line":1174},[560,2124,599],{"class":598},[560,2126,2127],{"class":570}," schema",[560,2129,625],{"class":577},[560,2131,2132],{"class":1396}," PrototypeSchema",[560,2134,870],{"class":577},[560,2136,647],{"class":577},[560,2138,2139,2141,2143],{"class":562,"line":1179},[560,2140,642],{"class":621},[560,2142,625],{"class":577},[560,2144,647],{"class":577},[560,2146,2147,2149,2151],{"class":562,"line":1184},[560,2148,2037],{"class":621},[560,2150,625],{"class":577},[560,2152,647],{"class":577},[560,2154,2155,2157,2159,2161,2163,2165,2167],{"class":562,"line":1195},[560,2156,1004],{"class":621},[560,2158,625],{"class":577},[560,2160,578],{"class":577},[560,2162,1944],{"class":581},[560,2164,633],{"class":577},[560,2166,891],{"class":577},[560,2168,2169],{"class":653},"   // custom field\n",[560,2171,2172,2174,2176,2178,2181,2183],{"class":562,"line":1201},[560,2173,1022],{"class":621},[560,2175,625],{"class":577},[560,2177,578],{"class":577},[560,2179,2180],{"class":581},"Priority",[560,2182,633],{"class":577},[560,2184,636],{"class":577},[560,2186,2187,2189,2191,2193,2196,2198],{"class":562,"line":1217},[560,2188,1038],{"class":621},[560,2190,625],{"class":577},[560,2192,578],{"class":577},[560,2194,2195],{"class":581},"medium",[560,2197,633],{"class":577},[560,2199,636],{"class":577},[560,2201,2202,2204,2206,2208,2211,2213,2215,2217,2220,2222,2224,2226,2228,2230,2232,2234,2237,2239,2241,2243,2246,2248,2250],{"class":562,"line":1234},[560,2203,1050],{"class":621},[560,2205,625],{"class":577},[560,2207,670],{"class":577},[560,2209,2210],{"class":621}," options",[560,2212,625],{"class":577},[560,2214,1069],{"class":570},[560,2216,633],{"class":577},[560,2218,2219],{"class":581},"low",[560,2221,633],{"class":577},[560,2223,891],{"class":577},[560,2225,578],{"class":577},[560,2227,2195],{"class":581},[560,2229,633],{"class":577},[560,2231,891],{"class":577},[560,2233,578],{"class":577},[560,2235,2236],{"class":581},"high",[560,2238,633],{"class":577},[560,2240,891],{"class":577},[560,2242,578],{"class":577},[560,2244,2245],{"class":581},"critical",[560,2247,633],{"class":577},[560,2249,1468],{"class":570},[560,2251,680],{"class":577},[560,2253,2254],{"class":562,"line":1244},[560,2255,1122],{"class":577},[560,2257,2258],{"class":562,"line":1250},[560,2259,738],{"class":577},[560,2261,2262,2264,2266],{"class":562,"line":1263},[560,2263,1187],{"class":621},[560,2265,625],{"class":577},[560,2267,1192],{"class":570},[560,2269,2270],{"class":562,"line":1299},[560,2271,1198],{"class":577},[560,2273,2274,2276,2278,2280,2282,2284,2286],{"class":562,"line":1304},[560,2275,1004],{"class":621},[560,2277,625],{"class":577},[560,2279,578],{"class":577},[560,2281,1948],{"class":581},[560,2283,633],{"class":577},[560,2285,891],{"class":577},[560,2287,2288],{"class":653},"      // custom viz\n",[560,2290,2291,2293,2295,2297,2300,2302],{"class":562,"line":1309},[560,2292,1220],{"class":621},[560,2294,625],{"class":577},[560,2296,578],{"class":577},[560,2298,2299],{"class":581},"Health Score",[560,2301,633],{"class":577},[560,2303,636],{"class":577},[560,2305,2306,2308,2310,2312,2315,2317,2319,2321,2323,2325,2327,2329,2331,2333,2336,2338,2341,2343,2346],{"class":562,"line":1317},[560,2307,1237],{"class":621},[560,2309,625],{"class":577},[560,2311,670],{"class":577},[560,2313,2314],{"class":608}," value",[560,2316,625],{"class":577},[560,2318,1271],{"class":577},[560,2320,1275],{"class":1274},[560,2322,1278],{"class":577},[560,2324,715],{"class":598},[560,2326,1283],{"class":570},[560,2328,1286],{"class":577},[560,2330,1289],{"class":570},[560,2332,1286],{"class":577},[560,2334,2335],{"class":570},"healthScore",[560,2337,891],{"class":577},[560,2339,2340],{"class":621}," max",[560,2342,625],{"class":577},[560,2344,2345],{"class":1109}," 100",[560,2347,1759],{"class":577},[560,2349,2351],{"class":562,"line":2350},32,[560,2352,1122],{"class":577},[560,2354,2356,2358],{"class":562,"line":2355},33,[560,2357,1312],{"class":570},[560,2359,636],{"class":577},[560,2361,2363],{"class":562,"line":2362},34,[560,2364,2365],{"class":577},"}\n",[2367,2368,2369],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":556,"searchDepth":588,"depth":588,"links":2371},[2372,2373,2374,2375,2376,2377,2378,2380],{"id":462,"depth":588,"text":463},{"id":535,"depth":588,"text":538},{"id":813,"depth":588,"text":816},{"id":951,"depth":588,"text":952},{"id":1324,"depth":588,"text":1325},{"id":1510,"depth":588,"text":1511},{"id":1667,"depth":588,"text":2379},"protokit:register-extension hook",{"id":1933,"depth":588,"text":1934},"Add custom field components and visualization types to nuxt-protokit without modifying the module source, using defineProtokitExtension and the protokit:register-extension hook.","md",null,{},{"title":441},{"title":447,"description":2381},"UEFTUiK8gR0wT7vFOD1DUwDbU964QNLSLaQNQ8ifiKw",[2389,2383],{"title":437,"path":438,"stem":439,"description":2390,"children":-1},"Real-world schema patterns — multi-threshold badges, null-safe connections, collection-driven charts, linked question responses, tab layouts with badges, and action toolbars.",1772977477729]