[{"data":1,"prerenderedAt":2320},["ShallowReactive",2],{"navigation-landing-en":3,"navigation-nuxt-auto-en":180,"navigation-nuxt-protokit-en":365,"navigation-nuxt-cookie-consent-en":507,"\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions-en":549,"\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions-surround-en":2315},[4,8,13,28,41,51,64,77,94,110,134,150,157,172],{"title":5,"path":6,"stem":7},"Overview","\u002Fdocs\u002Flanding","0.docs\u002F1.landing\u002F001.index",{"title":9,"path":10,"stem":11,"badge":12},"Built-in Features","\u002Fdocs\u002Flanding\u002Fbuilt-in-features","0.docs\u002F1.landing\u002F002.built-in-features","New",{"title":14,"path":15,"stem":16,"children":17,"icon":27},"Content Foundation","\u002Fdocs\u002Flanding\u002Fcontent","0.docs\u002F1.landing\u002F02.content\u002F1.index",[18,19,23],{"title":5,"path":15,"stem":16},{"title":20,"path":21,"stem":22},"Details","\u002Fdocs\u002Flanding\u002Fcontent\u002Fdetails","0.docs\u002F1.landing\u002F02.content\u002F2.details",{"title":24,"path":25,"stem":26},"Technical","\u002Fdocs\u002Flanding\u002Fcontent\u002Ftechnical","0.docs\u002F1.landing\u002F02.content\u002F4.technical","i-heroicons-document-text",{"title":29,"path":30,"stem":31,"children":32,"icon":40},"Regional Content","\u002Fdocs\u002Flanding\u002Fregional","0.docs\u002F1.landing\u002F03.regional\u002F1.index",[33,34,37],{"title":5,"path":30,"stem":31},{"title":20,"path":35,"stem":36},"\u002Fdocs\u002Flanding\u002Fregional\u002Fdetails","0.docs\u002F1.landing\u002F03.regional\u002F2.details",{"title":24,"path":38,"stem":39},"\u002Fdocs\u002Flanding\u002Fregional\u002Ftechnical","0.docs\u002F1.landing\u002F03.regional\u002F4.technical","i-heroicons-globe-alt",{"title":42,"path":43,"stem":44,"children":45,"icon":50},"Multi-language","\u002Fdocs\u002Flanding\u002Fmultilang","0.docs\u002F1.landing\u002F04.multilang\u002F1.index",[46,47],{"title":5,"path":43,"stem":44},{"title":20,"path":48,"stem":49},"\u002Fdocs\u002Flanding\u002Fmultilang\u002Fdetails","0.docs\u002F1.landing\u002F04.multilang\u002F2.details","i-heroicons-language",{"title":52,"path":53,"stem":54,"children":55,"icon":63},"Blog","\u002Fdocs\u002Flanding\u002Fblog","0.docs\u002F1.landing\u002F05.blog\u002F1.index",[56,57,60],{"title":5,"path":53,"stem":54},{"title":20,"path":58,"stem":59},"\u002Fdocs\u002Flanding\u002Fblog\u002Fdetails","0.docs\u002F1.landing\u002F05.blog\u002F2.details",{"title":24,"path":61,"stem":62},"\u002Fdocs\u002Flanding\u002Fblog\u002Ftechnical","0.docs\u002F1.landing\u002F05.blog\u002F4.technical","i-heroicons-pencil-square",{"title":65,"path":66,"stem":67,"children":68,"icon":76},"Documentation","\u002Fdocs\u002Flanding\u002Fdocs","0.docs\u002F1.landing\u002F06.docs\u002F1.index",[69,70,73],{"title":5,"path":66,"stem":67},{"title":20,"path":71,"stem":72},"\u002Fdocs\u002Flanding\u002Fdocs\u002Fdetails","0.docs\u002F1.landing\u002F06.docs\u002F2.details",{"title":24,"path":74,"stem":75},"\u002Fdocs\u002Flanding\u002Fdocs\u002Ftechnical","0.docs\u002F1.landing\u002F06.docs\u002F4.technical","i-heroicons-book-open",{"title":78,"path":79,"stem":80,"children":81,"icon":93},"Forms","\u002Fdocs\u002Flanding\u002Fforms","0.docs\u002F1.landing\u002F07.forms\u002F1.index",[82,83,86,90],{"title":5,"path":79,"stem":80},{"title":20,"path":84,"stem":85},"\u002Fdocs\u002Flanding\u002Fforms\u002Fdetails","0.docs\u002F1.landing\u002F07.forms\u002F2.details",{"title":87,"path":88,"stem":89},"Admin","\u002Fdocs\u002Flanding\u002Fforms\u002Fadmin","0.docs\u002F1.landing\u002F07.forms\u002F3.admin",{"title":24,"path":91,"stem":92},"\u002Fdocs\u002Flanding\u002Fforms\u002Ftechnical","0.docs\u002F1.landing\u002F07.forms\u002F4.technical","i-heroicons-clipboard-document-list",{"title":95,"path":96,"stem":97,"children":98,"icon":109},"Email","\u002Fdocs\u002Flanding\u002Femail","0.docs\u002F1.landing\u002F08.email\u002F1.index",[99,100,103,106],{"title":5,"path":96,"stem":97},{"title":20,"path":101,"stem":102},"\u002Fdocs\u002Flanding\u002Femail\u002Fdetails","0.docs\u002F1.landing\u002F08.email\u002F2.details",{"title":87,"path":104,"stem":105},"\u002Fdocs\u002Flanding\u002Femail\u002Fadmin","0.docs\u002F1.landing\u002F08.email\u002F3.admin",{"title":24,"path":107,"stem":108},"\u002Fdocs\u002Flanding\u002Femail\u002Ftechnical","0.docs\u002F1.landing\u002F08.email\u002F4.technical","i-heroicons-envelope",{"title":111,"path":112,"stem":113,"children":114,"icon":133},"Feedback Platform","\u002Fdocs\u002Flanding\u002Ffeedback","0.docs\u002F1.landing\u002F09.feedback\u002F1.index",[115,116,119,122,125,129],{"title":5,"path":112,"stem":113},{"title":20,"path":117,"stem":118},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Fdetails","0.docs\u002F1.landing\u002F09.feedback\u002F2.details",{"title":87,"path":120,"stem":121},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Fadmin","0.docs\u002F1.landing\u002F09.feedback\u002F3.admin",{"title":24,"path":123,"stem":124},"\u002Fdocs\u002Flanding\u002Ffeedback\u002Ftechnical","0.docs\u002F1.landing\u002F09.feedback\u002F4.technical",{"title":126,"path":127,"stem":128},"Compare vs SaaS","\u002Fdocs\u002Flanding\u002Ffeedback\u002Fcompare","0.docs\u002F1.landing\u002F09.feedback\u002F5.compare",{"title":130,"path":131,"stem":132},"FAQ","\u002Fdocs\u002Flanding\u002Ffeedback\u002Ffaq","0.docs\u002F1.landing\u002F09.feedback\u002F6.faq","i-heroicons-chat-bubble-left-right",{"title":135,"path":136,"stem":137,"children":138,"icon":149},"Storage","\u002Fdocs\u002Flanding\u002Fstorage","0.docs\u002F1.landing\u002F10.storage\u002F1.index",[139,140,143,146],{"title":5,"path":136,"stem":137},{"title":20,"path":141,"stem":142},"\u002Fdocs\u002Flanding\u002Fstorage\u002Fdetails","0.docs\u002F1.landing\u002F10.storage\u002F2.details",{"title":87,"path":144,"stem":145},"\u002Fdocs\u002Flanding\u002Fstorage\u002Fadmin","0.docs\u002F1.landing\u002F10.storage\u002F3.admin",{"title":24,"path":147,"stem":148},"\u002Fdocs\u002Flanding\u002Fstorage\u002Ftechnical","0.docs\u002F1.landing\u002F10.storage\u002F4.technical","i-heroicons-circle-stack",{"title":151,"path":152,"stem":153,"children":154,"icon":156},"Offline First","\u002Fdocs\u002Flanding\u002Foffline-first","0.docs\u002F1.landing\u002F11.offline-first\u002F1.index",[155],{"title":151,"path":152,"stem":153},"i-heroicons-users",{"title":158,"path":159,"stem":160,"children":161,"icon":156},"Yjs Sync","\u002Fdocs\u002Flanding\u002Fyjs-sync","0.docs\u002F1.landing\u002F12.yjs-sync\u002F1.index",[162,163,166,169],{"title":5,"path":159,"stem":160},{"title":20,"path":164,"stem":165},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Fdetails","0.docs\u002F1.landing\u002F12.yjs-sync\u002F2.details",{"title":87,"path":167,"stem":168},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Fadmin","0.docs\u002F1.landing\u002F12.yjs-sync\u002F3.admin",{"title":24,"path":170,"stem":171},"\u002Fdocs\u002Flanding\u002Fyjs-sync\u002Ftechnical","0.docs\u002F1.landing\u002F12.yjs-sync\u002F4.technical",{"title":173,"path":174,"stem":175,"children":176,"badge":178,"icon":179},"Newsletter","\u002Fdocs\u002Flanding\u002Fnewsletter","0.docs\u002F1.landing\u002F13.newsletter\u002Findex",[177],{"title":173,"path":174,"stem":175,"badge":178},"Coming Soon","i-lucide-send",[181,184,202,318,358],{"title":5,"path":182,"stem":183},"\u002Fdocs\u002Fnuxt-auto","0.docs\u002F3.nuxt-auto\u002Findex",{"title":185,"path":186,"stem":187,"children":188,"page":201},"Getting Started","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F1.getting-started",[189,193,197],{"title":190,"path":191,"stem":192},"Introduction","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Fintroduction","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F1.introduction",{"title":194,"path":195,"stem":196},"Installation","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Finstallation","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F2.installation",{"title":198,"path":199,"stem":200},"Quick Start","\u002Fdocs\u002Fnuxt-auto\u002Fgetting-started\u002Fquick-start","0.docs\u002F3.nuxt-auto\u002F1.getting-started\u002F3.quick-start",false,{"title":203,"path":204,"stem":205,"children":206,"page":201},"Auto API","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api","0.docs\u002F3.nuxt-auto\u002F2.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,298,302,306,310,314],{"title":185,"path":208,"stem":209},"\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F1.getting-started",{"title":211,"path":212,"stem":213},"Aggregations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Faggregations","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F10.aggregations",{"title":215,"path":216,"stem":217},"Lifecycle Hooks","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Flifecycle-hooks","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F11.lifecycle-hooks",{"title":219,"path":220,"stem":221},"Many-to-Many (M2M) Relationships","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fm2m-relationships","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F12.m2m-relationships",{"title":223,"path":224,"stem":225},"Plugin System","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fplugin-system","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F13.plugin-system",{"title":227,"path":228,"stem":229},"Database Adapters","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fdatabase-adapters","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F14.database-adapters",{"title":231,"path":232,"stem":233},"Custom Endpoints","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fcustom-endpoints","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F15.custom-endpoints",{"title":235,"path":236,"stem":237},"Multi-Tenancy","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fmulti-tenancy","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F16.multi-tenancy",{"title":239,"path":240,"stem":241},"Schema Presets (Cross-engine)","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fschema-presets","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F17.schema-presets",{"title":243,"path":244,"stem":245},"Permissions Cookbook","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fpermissions-cookbook","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F18.permissions-cookbook",{"title":247,"path":248,"stem":249},"Billing & Plan Gating","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbilling","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F19.billing",{"title":251,"path":252,"stem":253},"Validation","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fvalidation","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F2.validation",{"title":255,"path":256,"stem":257},"Rate Limiting","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Frate-limiting","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F20.rate-limiting",{"title":259,"path":260,"stem":261},"Request Metadata Plugin","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Frequest-metadata","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F21.request-metadata",{"title":263,"path":264,"stem":265},"Plugin Catalog","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fplugin-catalog","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F22.plugin-catalog",{"title":267,"path":268,"stem":269},"Configuration Reference","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fconfiguration","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F23.configuration",{"title":271,"path":272,"stem":273},"Handler Overrides","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fhandler-overrides","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F3.handler-overrides",{"title":275,"path":276,"stem":277},"Cloudflare D1","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fcloudflare-d1","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F30.cloudflare-d1",{"title":279,"path":280,"stem":281},"SQLite to D1 Migration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fmigration-sqlite-d1","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F31.migration-sqlite-d1",{"title":283,"path":284,"stem":285},"Frontend Composables","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Ffrontend-composables","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F32.frontend-composables",{"title":287,"path":288,"stem":289},"Testing","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Ftesting","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F33.testing",{"title":291,"path":292,"stem":293},"Pagination","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fpagination","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F4.pagination",{"title":295,"path":296,"stem":297},"Upgrading","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fupgrading","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F40.upgrading",{"title":299,"path":300,"stem":301},"Soft Deletes","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fsoft-deletes","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F5.soft-deletes",{"title":303,"path":304,"stem":305},"Authentication & Authorization","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fauthentication-authorization","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F6.authentication-authorization",{"title":307,"path":308,"stem":309},"Better-Auth Integration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbetter-auth","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F7.better-auth",{"title":311,"path":312,"stem":313},"Nested Relations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fnested-relationships","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F8.nested-relationships",{"title":315,"path":316,"stem":317},"Bulk Operations","\u002Fdocs\u002Fnuxt-auto\u002Fauto-api\u002Fbulk-operations","0.docs\u002F3.nuxt-auto\u002F2.auto-api\u002F9.bulk-operations",{"title":319,"path":320,"stem":321,"children":322,"page":201},"Auto Admin","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin","0.docs\u002F3.nuxt-auto\u002F3.auto-admin",[323,326,330,334,338,342,346,350,354],{"title":185,"path":324,"stem":325},"\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fgetting-started","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F1.getting-started",{"title":327,"path":328,"stem":329},"Configuration & Theming","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fconfiguration-theming","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F2.configuration-theming",{"title":331,"path":332,"stem":333},"Resource Configuration","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fresource-configuration","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F3.resource-configuration",{"title":335,"path":336,"stem":337},"Form Fields & Widgets","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fform-fields-widgets","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F4.form-fields-widgets",{"title":339,"path":340,"stem":341},"Permissions","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fpermissions","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F5.permissions",{"title":343,"path":344,"stem":345},"Custom Pages","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcustom-pages","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F6.custom-pages",{"title":347,"path":348,"stem":349},"M2M Relationships","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fm2m-relationships","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F7.m2m-relationships",{"title":351,"path":352,"stem":353},"Custom Actions","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcustom-actions","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F8.custom-actions",{"title":355,"path":356,"stem":357},"Composables","\u002Fdocs\u002Fnuxt-auto\u002Fauto-admin\u002Fcomposables","0.docs\u002F3.nuxt-auto\u002F3.auto-admin\u002F9.composables",{"title":359,"path":360,"stem":361,"children":362,"icon":364},"Claude Code Skills","\u002Fdocs\u002Fnuxt-auto\u002Fclaude-code-skills","0.docs\u002F3.nuxt-auto\u002F4.claude-code-skills\u002F1.index",[363],{"title":5,"path":360,"stem":361},"i-lucide-bot",[366,369,382,409,427,450,472,502],{"title":5,"path":367,"stem":368},"\u002Fdocs\u002Fnuxt-protokit","0.docs\u002F4.nuxt-protokit\u002Findex",{"title":185,"path":370,"stem":371,"children":372,"icon":381},"\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F1.index",[373,374,378],{"title":190,"path":370,"stem":371},{"title":375,"path":376,"stem":377},"Core Concepts","\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started\u002Fconcepts","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F2.concepts",{"title":198,"path":379,"stem":380},"\u002Fdocs\u002Fnuxt-protokit\u002Fgetting-started\u002Fquick-start","0.docs\u002F4.nuxt-protokit\u002F1.getting-started\u002F3.quick-start","i-lucide-rocket",{"title":383,"path":384,"stem":385,"children":386,"icon":408},"Schemas","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F1.index",[387,388,392,396,400,404],{"title":5,"path":384,"stem":385},{"title":389,"path":390,"stem":391},"Field Types","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Ffields","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F2.fields",{"title":393,"path":394,"stem":395},"Collections","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fcollections","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F3.collections",{"title":397,"path":398,"stem":399},"Derived & Computed","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fderived-computed","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F4.derived-computed",{"title":401,"path":402,"stem":403},"Connections","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fconnections","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F5.connections",{"title":405,"path":406,"stem":407},"Visualizations & Layouts","\u002Fdocs\u002Fnuxt-protokit\u002Fschemas\u002Fvisualizations","0.docs\u002F4.nuxt-protokit\u002F2.schemas\u002F6.visualizations","i-lucide-file-code",{"title":355,"path":410,"stem":411,"children":412,"icon":426},"\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F1.index",[413,414,418,422],{"title":5,"path":410,"stem":411},{"title":415,"path":416,"stem":417},"usePrototype","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-prototype","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F2.use-prototype",{"title":419,"path":420,"stem":421},"useProtoDoc","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-proto-doc","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F3.use-proto-doc",{"title":423,"path":424,"stem":425},"useProtoCollection","\u002Fdocs\u002Fnuxt-protokit\u002Fcomposables\u002Fuse-proto-collection","0.docs\u002F4.nuxt-protokit\u002F3.composables\u002F4.use-proto-collection","i-lucide-layers",{"title":428,"path":429,"stem":430,"children":431,"icon":449},"Components","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F1.index",[432,433,437,441,445],{"title":5,"path":429,"stem":430},{"title":434,"path":435,"stem":436},"ProtoTool","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-tool","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F2.proto-tool",{"title":438,"path":439,"stem":440},"ProtoCrudModal","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-crud-modal","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F3.proto-crud-modal",{"title":442,"path":443,"stem":444},"ProtoCalendar","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-calendar","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F4.proto-calendar",{"title":446,"path":447,"stem":448},"ProtoItemPanel variants","\u002Fdocs\u002Fnuxt-protokit\u002Fcomponents\u002Fproto-item-panels","0.docs\u002F4.nuxt-protokit\u002F4.components\u002F5.proto-item-panels","i-lucide-puzzle",{"title":151,"path":451,"stem":452,"children":453,"icon":471},"\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F1.index",[454,455,459,463,467],{"title":151,"path":451,"stem":452},{"title":456,"path":457,"stem":458},"Corruption Recovery","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fcorruption-recovery","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F2.corruption-recovery",{"title":460,"path":461,"stem":462},"Size & GC","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fdocument-size-and-gc","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F3.document-size-and-gc",{"title":464,"path":465,"stem":466},"Multi-tenant Isolation","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fmulti-tenant-isolation","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F4.multi-tenant-isolation",{"title":468,"path":469,"stem":470},"Encryption at Rest","\u002Fdocs\u002Fnuxt-protokit\u002Foffline-first\u002Fencryption","0.docs\u002F4.nuxt-protokit\u002F5.offline-first\u002F5.encryption","i-lucide-wifi-off",{"title":473,"icon":474,"path":475,"stem":476,"children":477},"Advanced","i-lucide-graduation-cap","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F1.index",[478,479,483,487,491,494,498],{"title":5,"path":475,"stem":476},{"title":480,"path":481,"stem":482},"Multi-Tool Apps","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fbuilding-a-toolkit","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F1.building-a-toolkit",{"title":484,"path":485,"stem":486},"Schema Patterns","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fcustom-schema-patterns","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F2.custom-schema-patterns",{"title":488,"path":489,"stem":490},"Custom Fields & Viz","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fextensibility","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F3.extensibility",{"title":339,"path":492,"stem":493},"\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F4.permissions",{"title":495,"path":496,"stem":497},"Business Logic Guards","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fpermissions-business-logic","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F5.permissions-business-logic",{"title":499,"path":500,"stem":501},"Headless Mode","\u002Fdocs\u002Fnuxt-protokit\u002Fadvanced\u002Fheadless-mode","0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F6.headless-mode",{"title":359,"path":503,"stem":504,"children":505,"icon":364},"\u002Fdocs\u002Fnuxt-protokit\u002Fclaude-code-skills","0.docs\u002F4.nuxt-protokit\u002F7.claude-code-skills\u002F1.index",[506],{"title":5,"path":503,"stem":504},[508,511],{"title":5,"path":509,"stem":510},"\u002Fdocs\u002Fnuxt-cookie-consent","0.docs\u002F5.nuxt-cookie-consent\u002Findex",{"title":512,"icon":513,"path":514,"stem":515,"children":516,"page":201},"Guide","i-lucide-book-open","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide",[517,521,525,530,535,539,544],{"title":190,"path":518,"stem":519,"icon":520},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fintroduction","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F1.introduction","i-lucide-info",{"title":194,"path":522,"stem":523,"icon":524},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Finstallation","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F2.installation","i-lucide-download",{"title":526,"path":527,"stem":528,"icon":529},"Configuration","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fconfiguration","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F3.configuration","i-lucide-settings-2",{"title":531,"path":532,"stem":533,"icon":534},"Usage","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fusage","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F4.usage","i-lucide-play",{"title":355,"path":536,"stem":537,"icon":538},"\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fcomposables","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F5.composables","i-lucide-function-square",{"title":540,"path":541,"stem":542,"icon":543},"Components & overriding","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fcomponents","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F6.components","i-lucide-component",{"title":545,"path":546,"stem":547,"icon":548},"Internationalization","\u002Fdocs\u002Fnuxt-cookie-consent\u002Fguide\u002Fi18n","0.docs\u002F5.nuxt-cookie-consent\u002F1.guide\u002F7.i18n","i-lucide-languages",{"page":550,"fallbackPage":2310},{"id":551,"title":552,"body":553,"description":2308,"extension":2309,"links":2310,"meta":2311,"navigation":2312,"ogImage":2310,"path":492,"seo":2313,"stem":493,"__hash__":2314},"nuxt_protokit\u002F0.docs\u002F4.nuxt-protokit\u002F6.advanced\u002F4.permissions.md","Permissions & Role Guards",{"type":554,"value":555,"toc":2289},"minimark",[556,560,564,580,585,588,604,612,616,619,729,735,738,741,905,912,916,940,1124,1129,1137,1459,1468,1511,1515,1527,1754,1758,1771,1927,1945,1949,1962,2129,2132,2140,2144,2147,2153,2164,2170,2178,2182,2185,2195,2199,2204,2208,2211,2214,2218,2285],[557,558,552],"h1",{"id":559},"permissions-role-guards",[561,562,563],"p",{},"nuxt-protokit includes a lightweight permission system that lets you guard collections and fields based on the current user's roles. The guards drive UI behaviour — hiding collections, disabling controls, and making fields read-only — without requiring you to build this logic into every component by hand.",[565,566,567],"warning",{},[561,568,569,573,574,579],{},[570,571,572],"strong",{},"Frontend guard only."," All permission checks run in the browser. A user who knows the underlying Y.js CRDT API can read and modify document data directly, regardless of what the guards say. Read the ",[575,576,578],"a",{"href":577},"#limitations","Limitations"," section before relying on this system for sensitive data.",[581,582,584],"h2",{"id":583},"how-it-works","How it works",[561,586,587],{},"The permission system has two parts:",[589,590,591,598],"ol",{},[592,593,594,597],"li",{},[570,595,596],{},"A role resolver"," — a function you provide that returns the current user's roles.",[592,599,600,603],{},[570,601,602],{},"Permission guards"," — declarative rules in your schema that reference those roles.",[561,605,606,607,611],{},"The two are connected via ",[608,609,610],"code",{},"configureProtoPermissions()",", which you call once in a Nuxt plugin.",[581,613,615],{"id":614},"setup","Setup",[561,617,618],{},"Register your role resolver before any component that uses permission-aware composables is mounted. A client-side plugin is the right place for this.",[620,621,627],"pre",{"className":622,"code":623,"filename":624,"language":625,"meta":626,"style":626},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtPlugin(() => {\n  configureProtoPermissions({\n    resolveRoles: () => useAuthUser().value?.roles ?? [],\n  })\n})\n","plugins\u002Fpermissions.client.ts","typescript","",[608,628,629,660,672,712,721],{"__ignoreMap":626},[630,631,634,638,641,645,649,653,657],"span",{"class":632,"line":633},"line",1,[630,635,637],{"class":636},"s7zQu","export",[630,639,640],{"class":636}," default",[630,642,644],{"class":643},"s2Zo4"," defineNuxtPlugin",[630,646,648],{"class":647},"sTEyZ","(",[630,650,652],{"class":651},"sMK4o","()",[630,654,656],{"class":655},"spNyl"," =>",[630,658,659],{"class":651}," {\n",[630,661,663,666,669],{"class":632,"line":662},2,[630,664,665],{"class":643},"  configureProtoPermissions",[630,667,648],{"class":668},"swJcz",[630,670,671],{"class":651},"{\n",[630,673,675,678,681,684,686,689,691,694,697,700,703,706,709],{"class":632,"line":674},3,[630,676,677],{"class":643},"    resolveRoles",[630,679,680],{"class":651},":",[630,682,683],{"class":651}," ()",[630,685,656],{"class":655},[630,687,688],{"class":643}," useAuthUser",[630,690,652],{"class":668},[630,692,693],{"class":651},".",[630,695,696],{"class":647},"value",[630,698,699],{"class":651},"?.",[630,701,702],{"class":647},"roles",[630,704,705],{"class":651}," ??",[630,707,708],{"class":668}," []",[630,710,711],{"class":651},",\n",[630,713,715,718],{"class":632,"line":714},4,[630,716,717],{"class":651},"  }",[630,719,720],{"class":668},")\n",[630,722,724,727],{"class":632,"line":723},5,[630,725,726],{"class":651},"}",[630,728,720],{"class":647},[561,730,731,734],{},[608,732,733],{},"resolveRoles"," is called reactively every time a permission is evaluated, so it will always reflect the current authentication state.",[581,736,602],{"id":737},"permission-guards",[561,739,740],{},"A guard can be written in three ways:",[620,742,744],{"className":622,"code":743,"language":625,"meta":626,"style":626},"\u002F\u002F Single role — user must hold this exact role\npermissions: { read: 'admin' }\n\n\u002F\u002F Role array — user must hold at least one of these roles\npermissions: { read: ['admin', 'editor'] }\n\n\u002F\u002F Custom function — full control, receives a PermissionContext\npermissions: {\n  read: (ctx) => ctx.roles.includes('admin') || someOtherCondition,\n}\n",[608,745,746,752,781,787,792,829,834,840,849,900],{"__ignoreMap":626},[630,747,748],{"class":632,"line":633},[630,749,751],{"class":750},"sHwdD","\u002F\u002F Single role — user must hold this exact role\n",[630,753,754,758,760,763,766,768,771,775,778],{"class":632,"line":662},[630,755,757],{"class":756},"sBMFI","permissions",[630,759,680],{"class":651},[630,761,762],{"class":651}," {",[630,764,765],{"class":756}," read",[630,767,680],{"class":651},[630,769,770],{"class":651}," '",[630,772,774],{"class":773},"sfazB","admin",[630,776,777],{"class":651},"'",[630,779,780],{"class":651}," }\n",[630,782,783],{"class":632,"line":674},[630,784,786],{"emptyLinePlaceholder":785},true,"\n",[630,788,789],{"class":632,"line":714},[630,790,791],{"class":750},"\u002F\u002F Role array — user must hold at least one of these roles\n",[630,793,794,796,798,800,802,804,807,809,811,813,816,818,821,823,826],{"class":632,"line":723},[630,795,757],{"class":756},[630,797,680],{"class":651},[630,799,762],{"class":651},[630,801,765],{"class":756},[630,803,680],{"class":651},[630,805,806],{"class":668}," [",[630,808,777],{"class":651},[630,810,774],{"class":773},[630,812,777],{"class":651},[630,814,815],{"class":651},",",[630,817,770],{"class":651},[630,819,820],{"class":773},"editor",[630,822,777],{"class":651},[630,824,825],{"class":668},"] ",[630,827,828],{"class":651},"}\n",[630,830,832],{"class":632,"line":831},6,[630,833,786],{"emptyLinePlaceholder":785},[630,835,837],{"class":632,"line":836},7,[630,838,839],{"class":750},"\u002F\u002F Custom function — full control, receives a PermissionContext\n",[630,841,843,845,847],{"class":632,"line":842},8,[630,844,757],{"class":756},[630,846,680],{"class":651},[630,848,659],{"class":651},[630,850,852,855,857,860,864,867,869,872,874,876,878,881,883,885,887,889,892,895,898],{"class":632,"line":851},9,[630,853,854],{"class":756},"  read",[630,856,680],{"class":651},[630,858,859],{"class":651}," (",[630,861,863],{"class":862},"sHdIc","ctx",[630,865,866],{"class":651},")",[630,868,656],{"class":655},[630,870,871],{"class":647}," ctx",[630,873,693],{"class":651},[630,875,702],{"class":647},[630,877,693],{"class":651},[630,879,880],{"class":643},"includes",[630,882,648],{"class":668},[630,884,777],{"class":651},[630,886,774],{"class":773},[630,888,777],{"class":651},[630,890,891],{"class":668},") ",[630,893,894],{"class":651},"||",[630,896,897],{"class":647}," someOtherCondition",[630,899,711],{"class":651},[630,901,903],{"class":632,"line":902},10,[630,904,828],{"class":651},[561,906,907,908,911],{},"Omitting a guard means ",[570,909,910],{},"allow"," — no guard defined is always open access.",[581,913,915],{"id":914},"collection-permissions","Collection permissions",[561,917,918,919,921,922,925,926,929,930,929,933,936,937,693],{},"Add a ",[608,920,757],{}," key to any ",[608,923,924],{},"CollectionSchema",". The four available actions are ",[608,927,928],{},"read",", ",[608,931,932],{},"create",[608,934,935],{},"update",", and ",[608,938,939],{},"delete",[620,941,944],{"className":622,"code":942,"filename":943,"language":625,"meta":626,"style":626},"defineCollection({\n  key: 'tasks',\n  title: 'Tasks',\n  \u002F\u002F ...\n  permissions: {\n    read:   ['admin', 'editor', 'viewer'],\n    create: ['admin', 'editor'],\n    update: ['admin', 'editor'],\n    delete: ['admin'],\n  },\n})\n","schemas\u002Fmy-tool.ts",[608,945,946,955,971,987,992,1001,1039,1066,1093,1112,1117],{"__ignoreMap":626},[630,947,948,951,953],{"class":632,"line":633},[630,949,950],{"class":643},"defineCollection",[630,952,648],{"class":647},[630,954,671],{"class":651},[630,956,957,960,962,964,967,969],{"class":632,"line":662},[630,958,959],{"class":668},"  key",[630,961,680],{"class":651},[630,963,770],{"class":651},[630,965,966],{"class":773},"tasks",[630,968,777],{"class":651},[630,970,711],{"class":651},[630,972,973,976,978,980,983,985],{"class":632,"line":674},[630,974,975],{"class":668},"  title",[630,977,680],{"class":651},[630,979,770],{"class":651},[630,981,982],{"class":773},"Tasks",[630,984,777],{"class":651},[630,986,711],{"class":651},[630,988,989],{"class":632,"line":714},[630,990,991],{"class":750},"  \u002F\u002F ...\n",[630,993,994,997,999],{"class":632,"line":723},[630,995,996],{"class":668},"  permissions",[630,998,680],{"class":651},[630,1000,659],{"class":651},[630,1002,1003,1006,1008,1011,1013,1015,1017,1019,1021,1023,1025,1027,1029,1032,1034,1037],{"class":632,"line":831},[630,1004,1005],{"class":668},"    read",[630,1007,680],{"class":651},[630,1009,1010],{"class":647},"   [",[630,1012,777],{"class":651},[630,1014,774],{"class":773},[630,1016,777],{"class":651},[630,1018,815],{"class":651},[630,1020,770],{"class":651},[630,1022,820],{"class":773},[630,1024,777],{"class":651},[630,1026,815],{"class":651},[630,1028,770],{"class":651},[630,1030,1031],{"class":773},"viewer",[630,1033,777],{"class":651},[630,1035,1036],{"class":647},"]",[630,1038,711],{"class":651},[630,1040,1041,1044,1046,1048,1050,1052,1054,1056,1058,1060,1062,1064],{"class":632,"line":836},[630,1042,1043],{"class":668},"    create",[630,1045,680],{"class":651},[630,1047,806],{"class":647},[630,1049,777],{"class":651},[630,1051,774],{"class":773},[630,1053,777],{"class":651},[630,1055,815],{"class":651},[630,1057,770],{"class":651},[630,1059,820],{"class":773},[630,1061,777],{"class":651},[630,1063,1036],{"class":647},[630,1065,711],{"class":651},[630,1067,1068,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091],{"class":632,"line":842},[630,1069,1070],{"class":668},"    update",[630,1072,680],{"class":651},[630,1074,806],{"class":647},[630,1076,777],{"class":651},[630,1078,774],{"class":773},[630,1080,777],{"class":651},[630,1082,815],{"class":651},[630,1084,770],{"class":651},[630,1086,820],{"class":773},[630,1088,777],{"class":651},[630,1090,1036],{"class":647},[630,1092,711],{"class":651},[630,1094,1095,1098,1100,1102,1104,1106,1108,1110],{"class":632,"line":851},[630,1096,1097],{"class":668},"    delete",[630,1099,680],{"class":651},[630,1101,806],{"class":647},[630,1103,777],{"class":651},[630,1105,774],{"class":773},[630,1107,777],{"class":651},[630,1109,1036],{"class":647},[630,1111,711],{"class":651},[630,1113,1114],{"class":632,"line":902},[630,1115,1116],{"class":651},"  },\n",[630,1118,1120,1122],{"class":632,"line":1119},11,[630,1121,726],{"class":651},[630,1123,720],{"class":647},[1125,1126,1128],"h3",{"id":1127},"consuming-collection-permissions","Consuming collection permissions",[561,1130,1131,1133,1134,1136],{},[608,1132,423],{}," returns a reactive ",[608,1135,757],{}," object. Use it to show or hide controls in your template:",[620,1138,1143],{"className":1139,"code":1140,"filename":1141,"language":1142,"meta":626,"style":626},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nconst { items, add, remove, permissions } = useProtoCollection(tasksSchema)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv v-if=\"permissions.canRead.value\">\n    \u003Cul>\n      \u003Cli v-for=\"(task, i) in items\" :key=\"i\">\n        {{ task.title }}\n        \u003Cbutton\n          v-if=\"permissions.canDelete.value\"\n          @click=\"remove(i)\"\n        >\n          Delete\n        \u003C\u002Fbutton>\n      \u003C\u002Fli>\n    \u003C\u002Ful>\n    \u003Cbutton\n      v-if=\"permissions.canCreate.value\"\n      @click=\"add({ title: '' })\"\n    >\n      Add task\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","components\u002FTaskList.vue","vue",[608,1144,1145,1173,1209,1218,1222,1231,1253,1263,1296,1301,1309,1324,1339,1345,1351,1362,1372,1382,1389,1404,1419,1425,1431,1440,1450],{"__ignoreMap":626},[630,1146,1147,1150,1153,1156,1159,1162,1165,1168,1170],{"class":632,"line":633},[630,1148,1149],{"class":651},"\u003C",[630,1151,1152],{"class":668},"script",[630,1154,1155],{"class":655}," setup",[630,1157,1158],{"class":655}," lang",[630,1160,1161],{"class":651},"=",[630,1163,1164],{"class":651},"\"",[630,1166,1167],{"class":773},"ts",[630,1169,1164],{"class":651},[630,1171,1172],{"class":651},">\n",[630,1174,1175,1178,1180,1183,1185,1188,1190,1193,1195,1198,1200,1203,1206],{"class":632,"line":662},[630,1176,1177],{"class":655},"const",[630,1179,762],{"class":651},[630,1181,1182],{"class":647}," items",[630,1184,815],{"class":651},[630,1186,1187],{"class":647}," add",[630,1189,815],{"class":651},[630,1191,1192],{"class":647}," remove",[630,1194,815],{"class":651},[630,1196,1197],{"class":647}," permissions ",[630,1199,726],{"class":651},[630,1201,1202],{"class":651}," =",[630,1204,1205],{"class":643}," useProtoCollection",[630,1207,1208],{"class":647},"(tasksSchema)\n",[630,1210,1211,1214,1216],{"class":632,"line":674},[630,1212,1213],{"class":651},"\u003C\u002F",[630,1215,1152],{"class":668},[630,1217,1172],{"class":651},[630,1219,1220],{"class":632,"line":714},[630,1221,786],{"emptyLinePlaceholder":785},[630,1223,1224,1226,1229],{"class":632,"line":723},[630,1225,1149],{"class":651},[630,1227,1228],{"class":668},"template",[630,1230,1172],{"class":651},[630,1232,1233,1236,1239,1242,1244,1246,1249,1251],{"class":632,"line":831},[630,1234,1235],{"class":651},"  \u003C",[630,1237,1238],{"class":668},"div",[630,1240,1241],{"class":655}," v-if",[630,1243,1161],{"class":651},[630,1245,1164],{"class":651},[630,1247,1248],{"class":773},"permissions.canRead.value",[630,1250,1164],{"class":651},[630,1252,1172],{"class":651},[630,1254,1255,1258,1261],{"class":632,"line":836},[630,1256,1257],{"class":651},"    \u003C",[630,1259,1260],{"class":668},"ul",[630,1262,1172],{"class":651},[630,1264,1265,1268,1270,1273,1275,1277,1280,1282,1285,1287,1289,1292,1294],{"class":632,"line":842},[630,1266,1267],{"class":651},"      \u003C",[630,1269,592],{"class":668},[630,1271,1272],{"class":655}," v-for",[630,1274,1161],{"class":651},[630,1276,1164],{"class":651},[630,1278,1279],{"class":773},"(task, i) in items",[630,1281,1164],{"class":651},[630,1283,1284],{"class":655}," :key",[630,1286,1161],{"class":651},[630,1288,1164],{"class":651},[630,1290,1291],{"class":773},"i",[630,1293,1164],{"class":651},[630,1295,1172],{"class":651},[630,1297,1298],{"class":632,"line":851},[630,1299,1300],{"class":647},"        {{ task.title }}\n",[630,1302,1303,1306],{"class":632,"line":902},[630,1304,1305],{"class":651},"        \u003C",[630,1307,1308],{"class":668},"button\n",[630,1310,1311,1314,1316,1318,1321],{"class":632,"line":1119},[630,1312,1313],{"class":655},"          v-if",[630,1315,1161],{"class":651},[630,1317,1164],{"class":651},[630,1319,1320],{"class":773},"permissions.canDelete.value",[630,1322,1323],{"class":651},"\"\n",[630,1325,1327,1330,1332,1334,1337],{"class":632,"line":1326},12,[630,1328,1329],{"class":655},"          @click",[630,1331,1161],{"class":651},[630,1333,1164],{"class":651},[630,1335,1336],{"class":773},"remove(i)",[630,1338,1323],{"class":651},[630,1340,1342],{"class":632,"line":1341},13,[630,1343,1344],{"class":651},"        >\n",[630,1346,1348],{"class":632,"line":1347},14,[630,1349,1350],{"class":647},"          Delete\n",[630,1352,1354,1357,1360],{"class":632,"line":1353},15,[630,1355,1356],{"class":651},"        \u003C\u002F",[630,1358,1359],{"class":668},"button",[630,1361,1172],{"class":651},[630,1363,1365,1368,1370],{"class":632,"line":1364},16,[630,1366,1367],{"class":651},"      \u003C\u002F",[630,1369,592],{"class":668},[630,1371,1172],{"class":651},[630,1373,1375,1378,1380],{"class":632,"line":1374},17,[630,1376,1377],{"class":651},"    \u003C\u002F",[630,1379,1260],{"class":668},[630,1381,1172],{"class":651},[630,1383,1385,1387],{"class":632,"line":1384},18,[630,1386,1257],{"class":651},[630,1388,1308],{"class":668},[630,1390,1392,1395,1397,1399,1402],{"class":632,"line":1391},19,[630,1393,1394],{"class":655},"      v-if",[630,1396,1161],{"class":651},[630,1398,1164],{"class":651},[630,1400,1401],{"class":773},"permissions.canCreate.value",[630,1403,1323],{"class":651},[630,1405,1407,1410,1412,1414,1417],{"class":632,"line":1406},20,[630,1408,1409],{"class":655},"      @click",[630,1411,1161],{"class":651},[630,1413,1164],{"class":651},[630,1415,1416],{"class":773},"add({ title: '' })",[630,1418,1323],{"class":651},[630,1420,1422],{"class":632,"line":1421},21,[630,1423,1424],{"class":651},"    >\n",[630,1426,1428],{"class":632,"line":1427},22,[630,1429,1430],{"class":647},"      Add task\n",[630,1432,1434,1436,1438],{"class":632,"line":1433},23,[630,1435,1377],{"class":651},[630,1437,1359],{"class":668},[630,1439,1172],{"class":651},[630,1441,1443,1446,1448],{"class":632,"line":1442},24,[630,1444,1445],{"class":651},"  \u003C\u002F",[630,1447,1238],{"class":668},[630,1449,1172],{"class":651},[630,1451,1453,1455,1457],{"class":632,"line":1452},25,[630,1454,1213],{"class":651},[630,1456,1228],{"class":668},[630,1458,1172],{"class":651},[561,1460,1461,1462,1464,1465,680],{},"When using ",[608,1463,415],{},", each collection's permissions are available on ",[608,1466,1467],{},"collectionPermissions",[620,1469,1471],{"className":622,"code":1470,"language":625,"meta":626,"style":626},"const { collections, collectionPermissions } = usePrototype(schema)\n\n\u002F\u002F collectionPermissions.tasks.canCreate.value → boolean\n\u002F\u002F collectionPermissions.tasks.canDelete.value → boolean\n",[608,1472,1473,1497,1501,1506],{"__ignoreMap":626},[630,1474,1475,1477,1479,1482,1484,1487,1489,1491,1494],{"class":632,"line":633},[630,1476,1177],{"class":655},[630,1478,762],{"class":651},[630,1480,1481],{"class":647}," collections",[630,1483,815],{"class":651},[630,1485,1486],{"class":647}," collectionPermissions ",[630,1488,726],{"class":651},[630,1490,1202],{"class":651},[630,1492,1493],{"class":643}," usePrototype",[630,1495,1496],{"class":647},"(schema)\n",[630,1498,1499],{"class":632,"line":662},[630,1500,786],{"emptyLinePlaceholder":785},[630,1502,1503],{"class":632,"line":674},[630,1504,1505],{"class":750},"\u002F\u002F collectionPermissions.tasks.canCreate.value → boolean\n",[630,1507,1508],{"class":632,"line":714},[630,1509,1510],{"class":750},"\u002F\u002F collectionPermissions.tasks.canDelete.value → boolean\n",[581,1512,1514],{"id":1513},"field-permissions","Field permissions",[561,1516,918,1517,1519,1520,1522,1523,1526],{},[608,1518,757],{}," key to any field definition. Two actions are available: ",[608,1521,928],{}," (visibility) and ",[608,1524,1525],{},"write"," (editability).",[620,1528,1530],{"className":622,"code":1529,"filename":943,"language":625,"meta":626,"style":626},"definePrototype({\n  key: 'budget-tool',\n  \u002F\u002F ...\n  fields: {\n    name: {\n      type: 'text',\n      label: 'Name',\n      default: '',\n    },\n    internalBudget: {\n      type: 'number',\n      label: 'Internal Budget',\n      default: 0,\n      permissions: {\n        read:  ['admin', 'finance'],\n        write: ['admin'],\n      },\n    },\n  },\n})\n",[608,1531,1532,1541,1556,1560,1569,1578,1594,1610,1622,1627,1636,1651,1666,1678,1687,1716,1735,1740,1744,1748],{"__ignoreMap":626},[630,1533,1534,1537,1539],{"class":632,"line":633},[630,1535,1536],{"class":643},"definePrototype",[630,1538,648],{"class":647},[630,1540,671],{"class":651},[630,1542,1543,1545,1547,1549,1552,1554],{"class":632,"line":662},[630,1544,959],{"class":668},[630,1546,680],{"class":651},[630,1548,770],{"class":651},[630,1550,1551],{"class":773},"budget-tool",[630,1553,777],{"class":651},[630,1555,711],{"class":651},[630,1557,1558],{"class":632,"line":674},[630,1559,991],{"class":750},[630,1561,1562,1565,1567],{"class":632,"line":714},[630,1563,1564],{"class":668},"  fields",[630,1566,680],{"class":651},[630,1568,659],{"class":651},[630,1570,1571,1574,1576],{"class":632,"line":723},[630,1572,1573],{"class":668},"    name",[630,1575,680],{"class":651},[630,1577,659],{"class":651},[630,1579,1580,1583,1585,1587,1590,1592],{"class":632,"line":831},[630,1581,1582],{"class":668},"      type",[630,1584,680],{"class":651},[630,1586,770],{"class":651},[630,1588,1589],{"class":773},"text",[630,1591,777],{"class":651},[630,1593,711],{"class":651},[630,1595,1596,1599,1601,1603,1606,1608],{"class":632,"line":836},[630,1597,1598],{"class":668},"      label",[630,1600,680],{"class":651},[630,1602,770],{"class":651},[630,1604,1605],{"class":773},"Name",[630,1607,777],{"class":651},[630,1609,711],{"class":651},[630,1611,1612,1615,1617,1620],{"class":632,"line":842},[630,1613,1614],{"class":668},"      default",[630,1616,680],{"class":651},[630,1618,1619],{"class":651}," ''",[630,1621,711],{"class":651},[630,1623,1624],{"class":632,"line":851},[630,1625,1626],{"class":651},"    },\n",[630,1628,1629,1632,1634],{"class":632,"line":902},[630,1630,1631],{"class":668},"    internalBudget",[630,1633,680],{"class":651},[630,1635,659],{"class":651},[630,1637,1638,1640,1642,1644,1647,1649],{"class":632,"line":1119},[630,1639,1582],{"class":668},[630,1641,680],{"class":651},[630,1643,770],{"class":651},[630,1645,1646],{"class":773},"number",[630,1648,777],{"class":651},[630,1650,711],{"class":651},[630,1652,1653,1655,1657,1659,1662,1664],{"class":632,"line":1326},[630,1654,1598],{"class":668},[630,1656,680],{"class":651},[630,1658,770],{"class":651},[630,1660,1661],{"class":773},"Internal Budget",[630,1663,777],{"class":651},[630,1665,711],{"class":651},[630,1667,1668,1670,1672,1676],{"class":632,"line":1341},[630,1669,1614],{"class":668},[630,1671,680],{"class":651},[630,1673,1675],{"class":1674},"sbssI"," 0",[630,1677,711],{"class":651},[630,1679,1680,1683,1685],{"class":632,"line":1347},[630,1681,1682],{"class":668},"      permissions",[630,1684,680],{"class":651},[630,1686,659],{"class":651},[630,1688,1689,1692,1694,1697,1699,1701,1703,1705,1707,1710,1712,1714],{"class":632,"line":1353},[630,1690,1691],{"class":668},"        read",[630,1693,680],{"class":651},[630,1695,1696],{"class":647},"  [",[630,1698,777],{"class":651},[630,1700,774],{"class":773},[630,1702,777],{"class":651},[630,1704,815],{"class":651},[630,1706,770],{"class":651},[630,1708,1709],{"class":773},"finance",[630,1711,777],{"class":651},[630,1713,1036],{"class":647},[630,1715,711],{"class":651},[630,1717,1718,1721,1723,1725,1727,1729,1731,1733],{"class":632,"line":1364},[630,1719,1720],{"class":668},"        write",[630,1722,680],{"class":651},[630,1724,806],{"class":647},[630,1726,777],{"class":651},[630,1728,774],{"class":773},[630,1730,777],{"class":651},[630,1732,1036],{"class":647},[630,1734,711],{"class":651},[630,1736,1737],{"class":632,"line":1374},[630,1738,1739],{"class":651},"      },\n",[630,1741,1742],{"class":632,"line":1384},[630,1743,1626],{"class":651},[630,1745,1746],{"class":632,"line":1391},[630,1747,1116],{"class":651},[630,1749,1750,1752],{"class":632,"line":1406},[630,1751,726],{"class":651},[630,1753,720],{"class":647},[1125,1755,1757],{"id":1756},"consuming-field-permissions","Consuming field permissions",[561,1759,1760,1763,1764,1766,1767,1770],{},[608,1761,1762],{},"useProtoMap"," and ",[608,1765,415],{}," return a ",[608,1768,1769],{},"fieldPermissions"," object keyed by field name:",[620,1772,1775],{"className":1139,"code":1773,"filename":1774,"language":1142,"meta":626,"style":626},"\u003Cscript setup lang=\"ts\">\nconst { state, fieldPermissions } = usePrototype(schema)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cinput v-model=\"state.name.value\" \u002F>\n\n  \u003Cinput\n    v-if=\"fieldPermissions.internalBudget.canRead.value\"\n    v-model=\"state.internalBudget.value\"\n    :disabled=\"!fieldPermissions.internalBudget.canWrite.value\"\n  \u002F>\n\u003C\u002Ftemplate>\n","components\u002FBudgetForm.vue",[608,1776,1777,1797,1819,1827,1831,1839,1861,1865,1872,1886,1900,1914,1919],{"__ignoreMap":626},[630,1778,1779,1781,1783,1785,1787,1789,1791,1793,1795],{"class":632,"line":633},[630,1780,1149],{"class":651},[630,1782,1152],{"class":668},[630,1784,1155],{"class":655},[630,1786,1158],{"class":655},[630,1788,1161],{"class":651},[630,1790,1164],{"class":651},[630,1792,1167],{"class":773},[630,1794,1164],{"class":651},[630,1796,1172],{"class":651},[630,1798,1799,1801,1803,1806,1808,1811,1813,1815,1817],{"class":632,"line":662},[630,1800,1177],{"class":655},[630,1802,762],{"class":651},[630,1804,1805],{"class":647}," state",[630,1807,815],{"class":651},[630,1809,1810],{"class":647}," fieldPermissions ",[630,1812,726],{"class":651},[630,1814,1202],{"class":651},[630,1816,1493],{"class":643},[630,1818,1496],{"class":647},[630,1820,1821,1823,1825],{"class":632,"line":674},[630,1822,1213],{"class":651},[630,1824,1152],{"class":668},[630,1826,1172],{"class":651},[630,1828,1829],{"class":632,"line":714},[630,1830,786],{"emptyLinePlaceholder":785},[630,1832,1833,1835,1837],{"class":632,"line":723},[630,1834,1149],{"class":651},[630,1836,1228],{"class":668},[630,1838,1172],{"class":651},[630,1840,1841,1843,1846,1849,1851,1853,1856,1858],{"class":632,"line":831},[630,1842,1235],{"class":651},[630,1844,1845],{"class":668},"input",[630,1847,1848],{"class":655}," v-model",[630,1850,1161],{"class":651},[630,1852,1164],{"class":651},[630,1854,1855],{"class":773},"state.name.value",[630,1857,1164],{"class":651},[630,1859,1860],{"class":651}," \u002F>\n",[630,1862,1863],{"class":632,"line":836},[630,1864,786],{"emptyLinePlaceholder":785},[630,1866,1867,1869],{"class":632,"line":842},[630,1868,1235],{"class":651},[630,1870,1871],{"class":668},"input\n",[630,1873,1874,1877,1879,1881,1884],{"class":632,"line":851},[630,1875,1876],{"class":655},"    v-if",[630,1878,1161],{"class":651},[630,1880,1164],{"class":651},[630,1882,1883],{"class":773},"fieldPermissions.internalBudget.canRead.value",[630,1885,1323],{"class":651},[630,1887,1888,1891,1893,1895,1898],{"class":632,"line":902},[630,1889,1890],{"class":655},"    v-model",[630,1892,1161],{"class":651},[630,1894,1164],{"class":651},[630,1896,1897],{"class":773},"state.internalBudget.value",[630,1899,1323],{"class":651},[630,1901,1902,1905,1907,1909,1912],{"class":632,"line":1119},[630,1903,1904],{"class":655},"    :disabled",[630,1906,1161],{"class":651},[630,1908,1164],{"class":651},[630,1910,1911],{"class":773},"!fieldPermissions.internalBudget.canWrite.value",[630,1913,1323],{"class":651},[630,1915,1916],{"class":632,"line":1326},[630,1917,1918],{"class":651},"  \u002F>\n",[630,1920,1921,1923,1925],{"class":632,"line":1341},[630,1922,1213],{"class":651},[630,1924,1228],{"class":668},[630,1926,1172],{"class":651},[561,1928,1929,1930,1933,1934,1936,1937,1940,1941,1944],{},"The ",[608,1931,1932],{},"ProtoForm"," component reads ",[608,1935,1769],{}," automatically — fields with ",[608,1938,1939],{},"canRead: false"," are hidden, and fields with ",[608,1942,1943],{},"canWrite: false"," are rendered as read-only inputs.",[581,1946,1948],{"id":1947},"ad-hoc-checks","Ad-hoc checks",[561,1950,1951,1954,1955,1763,1958,1961],{},[608,1952,1953],{},"useProtoPermissions()"," exposes the underlying ",[608,1956,1957],{},"can",[608,1959,1960],{},"canField"," helpers for one-off checks outside a schema context:",[620,1963,1965],{"className":622,"code":1964,"language":625,"meta":626,"style":626},"const { can, canField, getRoles } = useProtoPermissions()\n\n\u002F\u002F Check a collection action\nconst allowed = can('delete', myCollectionPermissions, { collection: 'tasks' })\n\n\u002F\u002F Check a field action\nconst visible = canField('read', myFieldPermissions, { field: 'budget' })\n\n\u002F\u002F Inspect current roles\nconst roles = getRoles() \u002F\u002F string[]\n",[608,1966,1967,1996,2000,2005,2049,2053,2058,2102,2106,2111],{"__ignoreMap":626},[630,1968,1969,1971,1973,1976,1978,1981,1983,1986,1988,1990,1993],{"class":632,"line":633},[630,1970,1177],{"class":655},[630,1972,762],{"class":651},[630,1974,1975],{"class":647}," can",[630,1977,815],{"class":651},[630,1979,1980],{"class":647}," canField",[630,1982,815],{"class":651},[630,1984,1985],{"class":647}," getRoles ",[630,1987,726],{"class":651},[630,1989,1202],{"class":651},[630,1991,1992],{"class":643}," useProtoPermissions",[630,1994,1995],{"class":647},"()\n",[630,1997,1998],{"class":632,"line":662},[630,1999,786],{"emptyLinePlaceholder":785},[630,2001,2002],{"class":632,"line":674},[630,2003,2004],{"class":750},"\u002F\u002F Check a collection action\n",[630,2006,2007,2009,2012,2014,2016,2018,2020,2022,2024,2026,2029,2031,2033,2036,2038,2040,2042,2044,2047],{"class":632,"line":714},[630,2008,1177],{"class":655},[630,2010,2011],{"class":647}," allowed ",[630,2013,1161],{"class":651},[630,2015,1975],{"class":643},[630,2017,648],{"class":647},[630,2019,777],{"class":651},[630,2021,939],{"class":773},[630,2023,777],{"class":651},[630,2025,815],{"class":651},[630,2027,2028],{"class":647}," myCollectionPermissions",[630,2030,815],{"class":651},[630,2032,762],{"class":651},[630,2034,2035],{"class":668}," collection",[630,2037,680],{"class":651},[630,2039,770],{"class":651},[630,2041,966],{"class":773},[630,2043,777],{"class":651},[630,2045,2046],{"class":651}," }",[630,2048,720],{"class":647},[630,2050,2051],{"class":632,"line":723},[630,2052,786],{"emptyLinePlaceholder":785},[630,2054,2055],{"class":632,"line":831},[630,2056,2057],{"class":750},"\u002F\u002F Check a field action\n",[630,2059,2060,2062,2065,2067,2069,2071,2073,2075,2077,2079,2082,2084,2086,2089,2091,2093,2096,2098,2100],{"class":632,"line":836},[630,2061,1177],{"class":655},[630,2063,2064],{"class":647}," visible ",[630,2066,1161],{"class":651},[630,2068,1980],{"class":643},[630,2070,648],{"class":647},[630,2072,777],{"class":651},[630,2074,928],{"class":773},[630,2076,777],{"class":651},[630,2078,815],{"class":651},[630,2080,2081],{"class":647}," myFieldPermissions",[630,2083,815],{"class":651},[630,2085,762],{"class":651},[630,2087,2088],{"class":668}," field",[630,2090,680],{"class":651},[630,2092,770],{"class":651},[630,2094,2095],{"class":773},"budget",[630,2097,777],{"class":651},[630,2099,2046],{"class":651},[630,2101,720],{"class":647},[630,2103,2104],{"class":632,"line":842},[630,2105,786],{"emptyLinePlaceholder":785},[630,2107,2108],{"class":632,"line":851},[630,2109,2110],{"class":750},"\u002F\u002F Inspect current roles\n",[630,2112,2113,2115,2118,2120,2123,2126],{"class":632,"line":902},[630,2114,1177],{"class":655},[630,2116,2117],{"class":647}," roles ",[630,2119,1161],{"class":651},[630,2121,2122],{"class":643}," getRoles",[630,2124,2125],{"class":647},"() ",[630,2127,2128],{"class":750},"\u002F\u002F string[]\n",[581,2130,578],{"id":2131},"limitations",[561,2133,2134,2135,2139],{},"Understanding what this system does ",[2136,2137,2138],"em",{},"not"," provide is as important as knowing what it does.",[1125,2141,2143],{"id":2142},"field-level-permissions-are-cosmetic","Field-level permissions are cosmetic",[561,2145,2146],{},"Field guards hide or disable UI elements. The Y.js document itself is always fully loaded in the browser — every field value is present in memory and accessible via the browser console or devtools. A user who understands the Y.js CRDT API can read or write any field directly without going through your Vue components.",[561,2148,2149,2152],{},[570,2150,2151],{},"Treat field permissions as a UX convenience, not a security boundary."," They are appropriate for:",[1260,2154,2155,2158,2161],{},[592,2156,2157],{},"Hiding irrelevant fields from users who should not be concerned with them.",[592,2159,2160],{},"Preventing accidental edits to fields a role should not normally change.",[592,2162,2163],{},"Reducing visual clutter for limited-access roles.",[561,2165,2166,2167,2169],{},"They are ",[570,2168,2138],{}," appropriate for:",[1260,2171,2172,2175],{},[592,2173,2174],{},"Hiding genuinely sensitive values (API keys, private identifiers, confidential figures).",[592,2176,2177],{},"Preventing a motivated user from modifying data.",[1125,2179,2181],{"id":2180},"collection-level-permissions-need-server-enforcement","Collection-level permissions need server enforcement",[561,2183,2184],{},"Collection guards disable the UI controls for adding, editing, and deleting items. The Y.js document is still synced to the server and other peers, so a user who bypasses the UI can still push changes.",[561,2186,2187,2188,2191,2192,2194],{},"For collections that must be protected, implement access control in your server sync handler (e.g. validate the user's role in your ",[608,2189,2190],{},"\u002Fapi\u002Fyjs"," route before applying updates). The ",[608,2193,928],{}," guard hides the collection in the UI, but the underlying data array is still in the document.",[1125,2196,2198],{"id":2197},"the-role-resolver-runs-in-the-browser","The role resolver runs in the browser",[561,2200,2201,2203],{},[608,2202,733],{}," executes client-side. Any role information it returns came from the browser — it can be tampered with. Never use browser-derived role data as the sole gate on a destructive or privileged server operation.",[1125,2205,2207],{"id":2206},"no-encryption","No encryption",[561,2209,2210],{},"Permission guards do not encrypt document data. Restricting what the UI renders does not prevent a user from reading raw IndexedDB entries or inspecting network payloads.",[2212,2213],"hr",{},[581,2215,2217],{"id":2216},"summary","Summary",[2219,2220,2221,2237],"table",{},[2222,2223,2224],"thead",{},[2225,2226,2227,2231,2234],"tr",{},[2228,2229,2230],"th",{},"Scope",[2228,2232,2233],{},"What the guard does",[2228,2235,2236],{},"Enforcement required elsewhere",[2238,2239,2240,2252,2263,2274],"tbody",{},[2225,2241,2242,2246,2249],{},[2243,2244,2245],"td",{},"Collection read",[2243,2247,2248],{},"Hides the collection UI",[2243,2250,2251],{},"Server: validate before syncing",[2225,2253,2254,2257,2260],{},[2243,2255,2256],{},"Collection write",[2243,2258,2259],{},"Disables add \u002F edit \u002F delete controls",[2243,2261,2262],{},"Server: validate before applying update",[2225,2264,2265,2268,2271],{},[2243,2266,2267],{},"Field read",[2243,2269,2270],{},"Hides the field from the form",[2243,2272,2273],{},"Nothing reliable; avoid sensitive data",[2225,2275,2276,2279,2282],{},[2243,2277,2278],{},"Field write",[2243,2280,2281],{},"Renders the field as read-only",[2243,2283,2284],{},"Nothing reliable; treat as UX only",[2286,2287,2288],"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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .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 pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":626,"searchDepth":662,"depth":662,"links":2290},[2291,2292,2293,2294,2297,2300,2301,2307],{"id":583,"depth":662,"text":584},{"id":614,"depth":662,"text":615},{"id":737,"depth":662,"text":602},{"id":914,"depth":662,"text":915,"children":2295},[2296],{"id":1127,"depth":674,"text":1128},{"id":1513,"depth":662,"text":1514,"children":2298},[2299],{"id":1756,"depth":674,"text":1757},{"id":1947,"depth":662,"text":1948},{"id":2131,"depth":662,"text":578,"children":2302},[2303,2304,2305,2306],{"id":2142,"depth":674,"text":2143},{"id":2180,"depth":674,"text":2181},{"id":2197,"depth":674,"text":2198},{"id":2206,"depth":674,"text":2207},{"id":2216,"depth":662,"text":2217},"Control collection and field visibility with role-based permission guards. Understand what is enforced in the UI, what requires server-side protection, and how to wire up your own role resolver.","md",null,{},{"title":339},{"title":552,"description":2308},"Q4Ztfp--fWK5rweAJnRqgjy5_dmly6PgRoT669BeRp0",[2316,2318],{"title":488,"path":489,"stem":490,"description":2317,"children":-1},"Add custom field components and visualization types to nuxt-protokit without modifying the module source, using defineProtokitExtension and the protokit:register-extension hook.",{"title":495,"path":496,"stem":497,"description":2319,"children":-1},"Extend role-based permission guards with reactive application state — project status, ownership, quotas, and other runtime conditions — using Vue's computed().",1792254332682]