@shapio/cms 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/assets/{AssetTile-zOf0K0nN.js → AssetTile-B8ftUG4s.js} +2 -2
- package/dist/admin/assets/{AssetTile-zOf0K0nN.js.map → AssetTile-B8ftUG4s.js.map} +1 -1
- package/dist/admin/assets/{AssistError-D_vY2CO0.js → AssistError-BidlzaBY.js} +2 -2
- package/dist/admin/assets/{AssistError-D_vY2CO0.js.map → AssistError-BidlzaBY.js.map} +1 -1
- package/dist/admin/assets/{BlockMenuItems-BEnSpClj.js → BlockMenuItems-DfNBHqVM.js} +2 -2
- package/dist/admin/assets/{BlockMenuItems-BEnSpClj.js.map → BlockMenuItems-DfNBHqVM.js.map} +1 -1
- package/dist/admin/assets/{Body-B_IVN5wp.js → Body-C0oQSX6L.js} +2 -2
- package/dist/admin/assets/{Body-B_IVN5wp.js.map → Body-C0oQSX6L.js.map} +1 -1
- package/dist/admin/assets/{Builder-CnEtRudv.js → Builder-Z_hcyzNW.js} +2 -2
- package/dist/admin/assets/{Builder-CnEtRudv.js.map → Builder-Z_hcyzNW.js.map} +1 -1
- package/dist/admin/assets/{ConfirmDialog-BW-l3Whg.js → ConfirmDialog-DVN-n-tE.js} +2 -2
- package/dist/admin/assets/{ConfirmDialog-BW-l3Whg.js.map → ConfirmDialog-DVN-n-tE.js.map} +1 -1
- package/dist/admin/assets/{CopyButton-CyoUMStc.js → CopyButton--tHegXQr.js} +2 -2
- package/dist/admin/assets/{CopyButton-CyoUMStc.js.map → CopyButton--tHegXQr.js.map} +1 -1
- package/dist/admin/assets/{CursorPager-BW2Dl_hn.js → CursorPager-Cb94mITn.js} +2 -2
- package/dist/admin/assets/{CursorPager-BW2Dl_hn.js.map → CursorPager-Cb94mITn.js.map} +1 -1
- package/dist/admin/assets/{ExternalLink-BCI0q9ib.js → ExternalLink-M1cb1n2n.js} +2 -2
- package/dist/admin/assets/{ExternalLink-BCI0q9ib.js.map → ExternalLink-M1cb1n2n.js.map} +1 -1
- package/dist/admin/assets/{FocalPoint-CxicvlJO.js → FocalPoint-pTq17ngi.js} +2 -2
- package/dist/admin/assets/{FocalPoint-CxicvlJO.js.map → FocalPoint-pTq17ngi.js.map} +1 -1
- package/dist/admin/assets/{Form-DB03drS9.js → Form-4zah109J.js} +2 -2
- package/dist/admin/assets/{Form-DB03drS9.js.map → Form-4zah109J.js.map} +1 -1
- package/dist/admin/assets/FormCheckboxGroup-DAeuGKAU.js +2 -0
- package/dist/admin/assets/FormCheckboxGroup-DAeuGKAU.js.map +1 -0
- package/dist/admin/assets/{FormRadioGroup-BvSC8SRm.js → FormRadioGroup--xx08rw6.js} +2 -2
- package/dist/admin/assets/{FormRadioGroup-BvSC8SRm.js.map → FormRadioGroup--xx08rw6.js.map} +1 -1
- package/dist/admin/assets/{FormSelectField-BDIVhZh6.js → FormSelectField-DNOCQKqc.js} +2 -2
- package/dist/admin/assets/{FormSelectField-BDIVhZh6.js.map → FormSelectField-DNOCQKqc.js.map} +1 -1
- package/dist/admin/assets/{FormSwitchField-OM4F8ln4.js → FormSwitchField-BECl-pzH.js} +2 -2
- package/dist/admin/assets/{FormSwitchField-OM4F8ln4.js.map → FormSwitchField-BECl-pzH.js.map} +1 -1
- package/dist/admin/assets/{FormTextareaField-Bw7EkC4H.js → FormTextareaField-DmRuKDJ_.js} +2 -2
- package/dist/admin/assets/{FormTextareaField-Bw7EkC4H.js.map → FormTextareaField-DmRuKDJ_.js.map} +1 -1
- package/dist/admin/assets/{HintedLabel-BGidukgy.js → HintedLabel-DIEBvftx.js} +2 -2
- package/dist/admin/assets/{HintedLabel-BGidukgy.js.map → HintedLabel-DIEBvftx.js.map} +1 -1
- package/dist/admin/assets/{InfoHint-D3uwei-E.js → InfoHint-BdAadb9U.js} +2 -2
- package/dist/admin/assets/{InfoHint-D3uwei-E.js.map → InfoHint-BdAadb9U.js.map} +1 -1
- package/dist/admin/assets/{InsertMenuItem-DAihGvbw.js → InsertMenuItem-oh0NJrhB.js} +2 -2
- package/dist/admin/assets/{InsertMenuItem-DAihGvbw.js.map → InsertMenuItem-oh0NJrhB.js.map} +1 -1
- package/dist/admin/assets/{LinkTabs-DBXbfzME.js → LinkTabs-EBgHX4Uh.js} +2 -2
- package/dist/admin/assets/{LinkTabs-DBXbfzME.js.map → LinkTabs-EBgHX4Uh.js.map} +1 -1
- package/dist/admin/assets/{Match-CgfZTzqs.js → Match-CvpSNEfi.js} +2 -2
- package/dist/admin/assets/{Match-CgfZTzqs.js.map → Match-CvpSNEfi.js.map} +1 -1
- package/dist/admin/assets/{Panel-DDky5_x9.js → Panel-BV1BpNCn.js} +2 -2
- package/dist/admin/assets/{Panel-DDky5_x9.js.map → Panel-BV1BpNCn.js.map} +1 -1
- package/dist/admin/assets/{QueryView-C2d392ly.js → QueryView-Bbw1eiV2.js} +2 -2
- package/dist/admin/assets/{QueryView-C2d392ly.js.map → QueryView-Bbw1eiV2.js.map} +1 -1
- package/dist/admin/assets/{RadioTile-CcP78eb_.js → RadioTile-CSYW-8gL.js} +2 -2
- package/dist/admin/assets/{RadioTile-CcP78eb_.js.map → RadioTile-CSYW-8gL.js.map} +1 -1
- package/dist/admin/assets/{RichTextField-CeztaFET.js → RichTextField-BDb67rCi.js} +2 -2
- package/dist/admin/assets/{RichTextField-CeztaFET.js.map → RichTextField-BDb67rCi.js.map} +1 -1
- package/dist/admin/assets/{RowTitle-mkKp4yfl.js → RowTitle-Cted2GP8.js} +2 -2
- package/dist/admin/assets/{RowTitle-mkKp4yfl.js.map → RowTitle-Cted2GP8.js.map} +1 -1
- package/dist/admin/assets/SecretReveal-Ccaul96d.js +2 -0
- package/dist/admin/assets/SecretReveal-Ccaul96d.js.map +1 -0
- package/dist/admin/assets/{SharedGlyph-CuDT7OUU.js → SharedGlyph-BrLi3Hug.js} +2 -2
- package/dist/admin/assets/{SharedGlyph-CuDT7OUU.js.map → SharedGlyph-BrLi3Hug.js.map} +1 -1
- package/dist/admin/assets/{StepList-BDO0Q3Wc.js → StepList-BLvElvPV.js} +2 -2
- package/dist/admin/assets/{StepList-BDO0Q3Wc.js.map → StepList-BLvElvPV.js.map} +1 -1
- package/dist/admin/assets/Structure-CRNAuVY7.js +2 -0
- package/dist/admin/assets/{Structure-CL_0hVci.js.map → Structure-CRNAuVY7.js.map} +1 -1
- package/dist/admin/assets/{SubNavLink-C4eSybWd.js → SubNavLink-biGV5ozd.js} +2 -2
- package/dist/admin/assets/{SubNavLink-C4eSybWd.js.map → SubNavLink-biGV5ozd.js.map} +1 -1
- package/dist/admin/assets/{SuggestAltButton-CxYlhwyd.js → SuggestAltButton-CrFiRWGr.js} +2 -2
- package/dist/admin/assets/{SuggestAltButton-CxYlhwyd.js.map → SuggestAltButton-CrFiRWGr.js.map} +1 -1
- package/dist/admin/assets/{TextLink-DzNaAft6.js → TextLink-BPLbXw2n.js} +2 -2
- package/dist/admin/assets/{TextLink-DzNaAft6.js.map → TextLink-BPLbXw2n.js.map} +1 -1
- package/dist/admin/assets/{Thumbnail-DSPArZ9h.js → Thumbnail-B_TWlgEz.js} +2 -2
- package/dist/admin/assets/{Thumbnail-DSPArZ9h.js.map → Thumbnail-B_TWlgEz.js.map} +1 -1
- package/dist/admin/assets/{UnsavedChangesGuard-BPOCBD5T.js → UnsavedChangesGuard-CrzR2boF.js} +2 -2
- package/dist/admin/assets/{UnsavedChangesGuard-BPOCBD5T.js.map → UnsavedChangesGuard-CrzR2boF.js.map} +1 -1
- package/dist/admin/assets/{UserAvatar-BHNWHDVb.js → UserAvatar-W-S3st7E.js} +2 -2
- package/dist/admin/assets/{UserAvatar-BHNWHDVb.js.map → UserAvatar-W-S3st7E.js.map} +1 -1
- package/dist/admin/assets/{auth-BzCgJtgr.js → auth-cXFFyABE.js} +2 -2
- package/dist/admin/assets/{auth-BzCgJtgr.js.map → auth-cXFFyABE.js.map} +1 -1
- package/dist/admin/assets/{badge-DBoaS0nQ.js → badge-DrPwivGk.js} +2 -2
- package/dist/admin/assets/{badge-DBoaS0nQ.js.map → badge-DrPwivGk.js.map} +1 -1
- package/dist/admin/assets/{boxes-DhN0ctLo.js → boxes-CKJ6P9VA.js} +2 -2
- package/dist/admin/assets/{boxes-DhN0ctLo.js.map → boxes-CKJ6P9VA.js.map} +1 -1
- package/dist/admin/assets/{calendar-clock-BEA3tG17.js → calendar-clock-DPyjti63.js} +2 -2
- package/dist/admin/assets/{calendar-clock-BEA3tG17.js.map → calendar-clock-DPyjti63.js.map} +1 -1
- package/dist/admin/assets/{changeSets-C54Ku-X9.js → changeSets-DYGm5j1A.js} +2 -2
- package/dist/admin/assets/{changeSets-C54Ku-X9.js.map → changeSets-DYGm5j1A.js.map} +1 -1
- package/dist/admin/assets/chevron-left-DIp5sJuv.js +2 -0
- package/dist/admin/assets/{chevron-left-BeJdUVAX.js.map → chevron-left-DIp5sJuv.js.map} +1 -1
- package/dist/admin/assets/{circle-check-ktACw37r.js → circle-check-VXPKg4cE.js} +2 -2
- package/dist/admin/assets/{circle-check-ktACw37r.js.map → circle-check-VXPKg4cE.js.map} +1 -1
- package/dist/admin/assets/{clock-BKNNASKp.js → clock-DNhupIko.js} +2 -2
- package/dist/admin/assets/{clock-BKNNASKp.js.map → clock-DNhupIko.js.map} +1 -1
- package/dist/admin/assets/cn-CEPUgFbZ.js +2 -0
- package/dist/admin/assets/cn-CEPUgFbZ.js.map +1 -0
- package/dist/admin/assets/coerce-BxuBjZdf.js +2 -0
- package/dist/admin/assets/{coerce-DDQ1vGLx.js.map → coerce-BxuBjZdf.js.map} +1 -1
- package/dist/admin/assets/{constants-DH7oqfO_.js → constants-B9cNrCXV.js} +2 -2
- package/dist/admin/assets/{constants-DH7oqfO_.js.map → constants-B9cNrCXV.js.map} +1 -1
- package/dist/admin/assets/{content-BptqQO8c.js → content-DjyCdi4c.js} +3 -3
- package/dist/admin/assets/{content-BptqQO8c.js.map → content-DjyCdi4c.js.map} +1 -1
- package/dist/admin/assets/{contentCounts-BpGlmyeZ.js → contentCounts-CX15iYcR.js} +2 -2
- package/dist/admin/assets/{contentCounts-BpGlmyeZ.js.map → contentCounts-CX15iYcR.js.map} +1 -1
- package/dist/admin/assets/{contentTypes-B_mAlIcH.js → contentTypes-FgyxLhlk.js} +2 -2
- package/dist/admin/assets/{contentTypes-B_mAlIcH.js.map → contentTypes-FgyxLhlk.js.map} +1 -1
- package/dist/admin/assets/{context-DyyMW7Md.js → context-FqJXjS5k.js} +2 -2
- package/dist/admin/assets/{context-DyyMW7Md.js.map → context-FqJXjS5k.js.map} +1 -1
- package/dist/admin/assets/{copy-DjzlFY9u.js → copy-CoHbtS-Y.js} +2 -2
- package/dist/admin/assets/{copy-DjzlFY9u.js.map → copy-CoHbtS-Y.js.map} +1 -1
- package/dist/admin/assets/{dateTimeLocal-DFXY779D.js → dateTimeLocal-BxmDLO_H.js} +2 -2
- package/dist/admin/assets/{dateTimeLocal-DFXY779D.js.map → dateTimeLocal-BxmDLO_H.js.map} +1 -1
- package/dist/admin/assets/{develop-DJap_z-1.js → develop-gx8WeWv4.js} +2 -2
- package/dist/admin/assets/{develop-DJap_z-1.js.map → develop-gx8WeWv4.js.map} +1 -1
- package/dist/admin/assets/{dropdown-menu-DGSMTf23.js → dropdown-menu-BG1rctRQ.js} +2 -2
- package/dist/admin/assets/{dropdown-menu-DGSMTf23.js.map → dropdown-menu-BG1rctRQ.js.map} +1 -1
- package/dist/admin/assets/{ellipsis-BMP-j3yO.js → ellipsis-DHfP1Ah2.js} +2 -2
- package/dist/admin/assets/{ellipsis-BMP-j3yO.js.map → ellipsis-DHfP1Ah2.js.map} +1 -1
- package/dist/admin/assets/{external-link-DzOkt97S.js → external-link-itxcNtaX.js} +2 -2
- package/dist/admin/assets/{external-link-DzOkt97S.js.map → external-link-itxcNtaX.js.map} +1 -1
- package/dist/admin/assets/{fileRoute-CG0Dufvt.js → fileRoute-BZ0pGGsh.js} +2 -2
- package/dist/admin/assets/{fileRoute-CG0Dufvt.js.map → fileRoute-BZ0pGGsh.js.map} +1 -1
- package/dist/admin/assets/{folder-plus-C-LhI4a2.js → folder-plus-BgsfY_6i.js} +2 -2
- package/dist/admin/assets/{folder-plus-C-LhI4a2.js.map → folder-plus-BgsfY_6i.js.map} +1 -1
- package/dist/admin/assets/{followPlural-D-8kzFOe.js → followPlural-BqjqhHmz.js} +2 -2
- package/dist/admin/assets/{followPlural-D-8kzFOe.js.map → followPlural-BqjqhHmz.js.map} +1 -1
- package/dist/admin/assets/{globe-DOoGBy23.js → globe-RjXj4P-A.js} +2 -2
- package/dist/admin/assets/{globe-DOoGBy23.js.map → globe-RjXj4P-A.js.map} +1 -1
- package/dist/admin/assets/{image-D9p_gGE2.js → image-4itB4TLl.js} +2 -2
- package/dist/admin/assets/{image-D9p_gGE2.js.map → image-4itB4TLl.js.map} +1 -1
- package/dist/admin/assets/{image-off-G0M2Nh1I.js → image-off-CokIymyg.js} +2 -2
- package/dist/admin/assets/{image-off-G0M2Nh1I.js.map → image-off-CokIymyg.js.map} +1 -1
- package/dist/admin/assets/{inbox-XaM-nvsM.js → inbox-8AAyyM0T.js} +2 -2
- package/dist/admin/assets/{inbox-XaM-nvsM.js.map → inbox-8AAyyM0T.js.map} +1 -1
- package/dist/admin/assets/{inbox-CMzYVMZo.js → inbox-97pzmuus.js} +2 -2
- package/dist/admin/assets/{inbox-CMzYVMZo.js.map → inbox-97pzmuus.js.map} +1 -1
- package/dist/admin/assets/{index-DHmfMpqz.js → index-cpiZvLck.js} +4 -4
- package/dist/admin/assets/{index-DHmfMpqz.js.map → index-cpiZvLck.js.map} +1 -1
- package/dist/admin/assets/{key-round-HBvMrmMo.js → key-round-Dc4_SOi-.js} +2 -2
- package/dist/admin/assets/{key-round-HBvMrmMo.js.map → key-round-Dc4_SOi-.js.map} +1 -1
- package/dist/admin/assets/{languages-BOv0jYhe.js → languages-DR2K97A5.js} +2 -2
- package/dist/admin/assets/{languages-BOv0jYhe.js.map → languages-DR2K97A5.js.map} +1 -1
- package/dist/admin/assets/{layers-CkZyCaeb.js → layers-ZPmcbieN.js} +2 -2
- package/dist/admin/assets/{layers-CkZyCaeb.js.map → layers-ZPmcbieN.js.map} +1 -1
- package/dist/admin/assets/{link-2-off-UUkSmPIL.js → link-2-off-D_5_hkT7.js} +2 -2
- package/dist/admin/assets/{link-2-off-UUkSmPIL.js.map → link-2-off-D_5_hkT7.js.map} +1 -1
- package/dist/admin/assets/{link-Bvqcg7db.js → link-BnDFFyvi.js} +2 -2
- package/dist/admin/assets/{link-Bvqcg7db.js.map → link-BnDFFyvi.js.map} +1 -1
- package/dist/admin/assets/{locales-DbrcdhZi.js → locales-D-21t-l-.js} +2 -2
- package/dist/admin/assets/{locales-DbrcdhZi.js.map → locales-D-21t-l-.js.map} +1 -1
- package/dist/admin/assets/{media-ugEyLgwN.js → media-D7aimjyy.js} +2 -2
- package/dist/admin/assets/{media-ugEyLgwN.js.map → media-D7aimjyy.js.map} +1 -1
- package/dist/admin/assets/{media-CO0HSS3b.js → media-Db0cHYNY.js} +2 -2
- package/dist/admin/assets/{media-CO0HSS3b.js.map → media-Db0cHYNY.js.map} +1 -1
- package/dist/admin/assets/network-l_oLT5fa.js +2 -0
- package/dist/admin/assets/network-l_oLT5fa.js.map +1 -0
- package/dist/admin/assets/{pencil-BLNGNJmL.js → pencil-Cn8c_gtv.js} +2 -2
- package/dist/admin/assets/{pencil-BLNGNJmL.js.map → pencil-Cn8c_gtv.js.map} +1 -1
- package/dist/admin/assets/{plus-BXMBYPoB.js → plus-yxvf4aAT.js} +2 -2
- package/dist/admin/assets/{plus-BXMBYPoB.js.map → plus-yxvf4aAT.js.map} +1 -1
- package/dist/admin/assets/{preload-helper-DEbJbZwX.js → preload-helper-pwSesV5P.js} +2 -2
- package/dist/admin/assets/{preload-helper-DEbJbZwX.js.map → preload-helper-pwSesV5P.js.map} +1 -1
- package/dist/admin/assets/{publishing-DKrATBaj.js → publishing-PQLCOnvu.js} +2 -2
- package/dist/admin/assets/{publishing-DKrATBaj.js.map → publishing-PQLCOnvu.js.map} +1 -1
- package/dist/admin/assets/{radio-group-BIhT_uEK.js → radio-group-Fc2ENIMO.js} +2 -2
- package/dist/admin/assets/{radio-group-BIhT_uEK.js.map → radio-group-Fc2ENIMO.js.map} +1 -1
- package/dist/admin/assets/{rotate-ccw-DqbffhiC.js → rotate-ccw-BHa0BHug.js} +2 -2
- package/dist/admin/assets/{rotate-ccw-DqbffhiC.js.map → rotate-ccw-BHa0BHug.js.map} +1 -1
- package/dist/admin/assets/{schedules-CETl2eLe.js → schedules-B8y_GnqX.js} +2 -2
- package/dist/admin/assets/{schedules-CETl2eLe.js.map → schedules-B8y_GnqX.js.map} +1 -1
- package/dist/admin/assets/{schema-CWHuez0q.js → schema-BJHcYshf.js} +2 -2
- package/dist/admin/assets/{schema-CWHuez0q.js.map → schema-BJHcYshf.js.map} +1 -1
- package/dist/admin/assets/{scroll-text-DlcDEi2k.js → scroll-text-BHLmZpBB.js} +2 -2
- package/dist/admin/assets/{scroll-text-DlcDEi2k.js.map → scroll-text-BHLmZpBB.js.map} +1 -1
- package/dist/admin/assets/{search-Dy2dtwyR.js → search-D3GGSaSL.js} +2 -2
- package/dist/admin/assets/{search-Dy2dtwyR.js.map → search-D3GGSaSL.js.map} +1 -1
- package/dist/admin/assets/{searchSchemas-Cz4P1iku.js → searchSchemas-C4dnYI9a.js} +2 -2
- package/dist/admin/assets/{searchSchemas-Cz4P1iku.js.map → searchSchemas-C4dnYI9a.js.map} +1 -1
- package/dist/admin/assets/{sections-BfG6DTFr.js → sections-BWoTaw2B.js} +2 -2
- package/dist/admin/assets/{sections-BfG6DTFr.js.map → sections-BWoTaw2B.js.map} +1 -1
- package/dist/admin/assets/{sections-EgXyXN3-.js → sections-eeTU636D.js} +2 -2
- package/dist/admin/assets/{sections-EgXyXN3-.js.map → sections-eeTU636D.js.map} +1 -1
- package/dist/admin/assets/{select--mePTdz8.js → select-BMi4G1Ib.js} +2 -2
- package/dist/admin/assets/{select--mePTdz8.js.map → select-BMi4G1Ib.js.map} +1 -1
- package/dist/admin/assets/{send-DVgq5Iwg.js → send-Bqhmg9HP.js} +2 -2
- package/dist/admin/assets/{send-DVgq5Iwg.js.map → send-Bqhmg9HP.js.map} +1 -1
- package/dist/admin/assets/{seo-Zhb62Ojz.js → seo-BL9C7Yt3.js} +2 -2
- package/dist/admin/assets/{seo-Zhb62Ojz.js.map → seo-BL9C7Yt3.js.map} +1 -1
- package/dist/admin/assets/settings-D-nW3wQb.js +2 -0
- package/dist/admin/assets/settings-D-nW3wQb.js.map +1 -0
- package/dist/admin/assets/skeleton-BPLAzyDo.js +42 -0
- package/dist/admin/assets/skeleton-BPLAzyDo.js.map +1 -0
- package/dist/admin/assets/{snapshots-BpLhILlt.js → snapshots-COSUeZBP.js} +2 -2
- package/dist/admin/assets/{snapshots-BpLhILlt.js.map → snapshots-COSUeZBP.js.map} +1 -1
- package/dist/admin/assets/{sparkles-Dd6S_roX.js → sparkles-CykwtKTd.js} +2 -2
- package/dist/admin/assets/{sparkles-Dd6S_roX.js.map → sparkles-CykwtKTd.js.map} +1 -1
- package/dist/admin/assets/{stableId-DFVM13gJ.js → stableId-DfJkQUV3.js} +2 -2
- package/dist/admin/assets/{stableId-DFVM13gJ.js.map → stableId-DfJkQUV3.js.map} +1 -1
- package/dist/admin/assets/{store-BP-xStwU.js → store-GOGeP63I.js} +2 -2
- package/dist/admin/assets/{store-BP-xStwU.js.map → store-GOGeP63I.js.map} +1 -1
- package/dist/admin/assets/{switch-skVypg5O.js → switch-XRU_EOoM.js} +2 -2
- package/dist/admin/assets/{switch-skVypg5O.js.map → switch-XRU_EOoM.js.map} +1 -1
- package/dist/admin/assets/{table-BMbbRUK9.js → table-CLVW6uJB.js} +2 -2
- package/dist/admin/assets/{table-BMbbRUK9.js.map → table-CLVW6uJB.js.map} +1 -1
- package/dist/admin/assets/{tabs-C1lgOg1B.js → tabs-DB42Xljn.js} +3 -3
- package/dist/admin/assets/{tabs-C1lgOg1B.js.map → tabs-DB42Xljn.js.map} +1 -1
- package/dist/admin/assets/{textarea-CffBBxoQ.js → textarea-DcsLGCkq.js} +2 -2
- package/dist/admin/assets/{textarea-CffBBxoQ.js.map → textarea-DcsLGCkq.js.map} +1 -1
- package/dist/admin/assets/{theme-RHTVnR9j.js → theme-CnSar6tt.js} +2 -2
- package/dist/admin/assets/{theme-RHTVnR9j.js.map → theme-CnSar6tt.js.map} +1 -1
- package/dist/admin/assets/{titles-DWiPmNvn.js → titles-DluirfBO.js} +2 -2
- package/dist/admin/assets/{titles-DWiPmNvn.js.map → titles-DluirfBO.js.map} +1 -1
- package/dist/admin/assets/{tokens-BqyeN1D-.js → tokens-CQooB8Sf.js} +2 -2
- package/dist/admin/assets/{tokens-BqyeN1D-.js.map → tokens-CQooB8Sf.js.map} +1 -1
- package/dist/admin/assets/{tooltip-BfSF6EyR.js → tooltip-xfZn0Fla.js} +2 -2
- package/dist/admin/assets/{tooltip-BfSF6EyR.js.map → tooltip-xfZn0Fla.js.map} +1 -1
- package/dist/admin/assets/{undo-2-p4YlNhBp.js → undo-2-B_QjuGmR.js} +2 -2
- package/dist/admin/assets/{undo-2-p4YlNhBp.js.map → undo-2-B_QjuGmR.js.map} +1 -1
- package/dist/admin/assets/{useAuditLabels-DV5gcaaG.js → useAuditLabels-BZPAj3wG.js} +2 -2
- package/dist/admin/assets/{useAuditLabels-DV5gcaaG.js.map → useAuditLabels-BZPAj3wG.js.map} +1 -1
- package/dist/admin/assets/{useConfirmTarget-DCvnxNVg.js → useConfirmTarget-B7iLg66j.js} +2 -2
- package/dist/admin/assets/{useConfirmTarget-DCvnxNVg.js.map → useConfirmTarget-B7iLg66j.js.map} +1 -1
- package/dist/admin/assets/{useContentSchema-z6tNif86.js → useContentSchema-BTyBYURX.js} +2 -2
- package/dist/admin/assets/{useContentSchema-z6tNif86.js.map → useContentSchema-BTyBYURX.js.map} +1 -1
- package/dist/admin/assets/{useCursorPager-CQGX41_L.js → useCursorPager-CTGOzl69.js} +2 -2
- package/dist/admin/assets/{useCursorPager-CQGX41_L.js.map → useCursorPager-CTGOzl69.js.map} +1 -1
- package/dist/admin/assets/{useDiscardGuard-Dhbif7VL.js → useDiscardGuard-CSkPw8iq.js} +2 -2
- package/dist/admin/assets/{useDiscardGuard-Dhbif7VL.js.map → useDiscardGuard-CSkPw8iq.js.map} +1 -1
- package/dist/admin/assets/{useMediaPickerDialog-D-5uKsMG.js → useMediaPickerDialog-W0jhN-hi.js} +2 -2
- package/dist/admin/assets/{useMediaPickerDialog-D-5uKsMG.js.map → useMediaPickerDialog-W0jhN-hi.js.map} +1 -1
- package/dist/admin/assets/{useMediaUploader-BtLoimmQ.js → useMediaUploader-BC5zCkQt.js} +2 -2
- package/dist/admin/assets/{useMediaUploader-BtLoimmQ.js.map → useMediaUploader-BC5zCkQt.js.map} +1 -1
- package/dist/admin/assets/{usePaletteItems-D3PZsW0Q.js → usePaletteItems-CqcKndUT.js} +2 -2
- package/dist/admin/assets/{usePaletteItems-D3PZsW0Q.js.map → usePaletteItems-CqcKndUT.js.map} +1 -1
- package/dist/admin/assets/{usePlaces-Cj5PljTy.js → usePlaces-o4Os5Nbv.js} +2 -2
- package/dist/admin/assets/{usePlaces-Cj5PljTy.js.map → usePlaces-o4Os5Nbv.js.map} +1 -1
- package/dist/admin/assets/{useQueries-CeDzli4Z.js → useQueries-BTnSD0k5.js} +2 -2
- package/dist/admin/assets/{useQueries-CeDzli4Z.js.map → useQueries-BTnSD0k5.js.map} +1 -1
- package/dist/admin/assets/{useResolvedScheme-DHD-zisP.js → useResolvedScheme-SoI-2Faf.js} +2 -2
- package/dist/admin/assets/{useResolvedScheme-DHD-zisP.js.map → useResolvedScheme-SoI-2Faf.js.map} +1 -1
- package/dist/admin/assets/{useSchemaScopeAccess-BNeVslcv.js → useSchemaScopeAccess-B4-31q7m.js} +2 -2
- package/dist/admin/assets/{useSchemaScopeAccess-BNeVslcv.js.map → useSchemaScopeAccess-B4-31q7m.js.map} +1 -1
- package/dist/admin/assets/{users-BRefbzuS.js → users-BVuapb3u.js} +2 -2
- package/dist/admin/assets/{users-BRefbzuS.js.map → users-BVuapb3u.js.map} +1 -1
- package/dist/admin/assets/{users-CppI8ctO.js → users-Oj5V5za_.js} +2 -2
- package/dist/admin/assets/{users-CppI8ctO.js.map → users-Oj5V5za_.js.map} +1 -1
- package/dist/admin/assets/{zod-Dcwk-m8X.js → zod-cTJwCa4E.js} +2 -2
- package/dist/admin/assets/{zod-Dcwk-m8X.js.map → zod-cTJwCa4E.js.map} +1 -1
- package/dist/admin/index.html +55 -55
- package/dist/cli.js +33 -18
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{public-DYR4mtVQ.d.ts → public-C027OJX6.d.ts} +12 -2
- package/dist/{s3Adapter-C8AgFVYw.js → s3Adapter-BipoQiwQ.js} +2 -2
- package/dist/{s3Adapter-C8AgFVYw.js.map → s3Adapter-BipoQiwQ.js.map} +1 -1
- package/dist/{worker-jz_0yAmS.js → worker-BU-V4qbH.js} +174 -60
- package/dist/worker-BU-V4qbH.js.map +1 -0
- package/package.json +5 -5
- package/dist/admin/assets/FormCheckboxGroup-JP1xzReQ.js +0 -2
- package/dist/admin/assets/FormCheckboxGroup-JP1xzReQ.js.map +0 -1
- package/dist/admin/assets/SecretReveal-mYCzxF96.js +0 -2
- package/dist/admin/assets/SecretReveal-mYCzxF96.js.map +0 -1
- package/dist/admin/assets/Structure-CL_0hVci.js +0 -2
- package/dist/admin/assets/chevron-left-BeJdUVAX.js +0 -2
- package/dist/admin/assets/cn-h5ORT3LK.js +0 -2
- package/dist/admin/assets/cn-h5ORT3LK.js.map +0 -1
- package/dist/admin/assets/coerce-DDQ1vGLx.js +0 -2
- package/dist/admin/assets/network-BfDaUb7D.js +0 -2
- package/dist/admin/assets/network-BfDaUb7D.js.map +0 -1
- package/dist/admin/assets/settings-Mscp6tN5.js +0 -2
- package/dist/admin/assets/settings-Mscp6tN5.js.map +0 -1
- package/dist/admin/assets/skeleton-DJVukcn6.js +0 -42
- package/dist/admin/assets/skeleton-DJVukcn6.js.map +0 -1
- package/dist/worker-jz_0yAmS.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Builder-CnEtRudv.js","names":["__iconData","__iconData","Globe2","_Fragment","useRef","AlertCircle","Loader2","useCallback","useId","useState","useId","useState","AlertCircle","useRef","useState","_Fragment","useId","useState","_Fragment","useMemo","Trash2","_Fragment","Trash2","_Fragment","MoreHorizontal","Trash2","useDeferredValue","useMemo","useMemo","useState","_Fragment","_Fragment","_Fragment","useState","useId","useState","Loader2","useState","useRef","__toESM","require_jsx_runtime","useQueryClient","useTranslation","create","LoaderCircle","cn","linkOptions","useNavigate","hasErrorCode","useMe","SubmitButton","Page","Sheet","SheetDescription","SheetFooter","PageHeader","useParams","SheetBody","SheetTitle","StatusChip","EmptyState","SheetHeader","IconTile","Badge","SheetContent","LoadingState","UnsavedChangesGuard","SEO_EDITOR_ID","isCustomEditorId","isCoverEligible","effectiveTitleField","SORT_DIRECTIONS","DATA_TYPES","SETTINGS_SCHEMAS","DEFAULT_EDITORS","SEO_COMPONENT_ID","isCanvasEligible","SCALAR_DATA_TYPES","UNIQUE_CAPABLE_DATA_TYPES","renormalizeDefinition","foldApiKey","validateDefinition","routeKeyOf","listCompatibleEditors","EDITOR_CATALOGUE","validateSchema","RESERVED_FIELD_API_KEYS","canonicalJson","parseDefinition","isDocumentPlaceable","effectiveLayout","useEnsureSeoComponent","seoConflictOf","toast","logError","Trash","FieldDescription","FieldLabel","FieldLegend","FieldError","Field","FieldSet","FieldContent","InfoHint","FieldGroup","Button","describeError","Input","KIND_LABEL_KEYS","PLAN_BUCKET_LABEL_KEYS","KIND_ICONS","DATA_TYPE_ICONS","DATA_TYPE_GROUPS","Earth","useSchemaScopeAccess","SelectValue","SelectTrigger","SelectContent","ChevronUp","SelectItem","ChevronDown","Select","Alert","CircleAlert","FormError","Checkbox","AlertDescription","InlineConfirm","AlertTitle","ConfirmDialog","groupByBucket","valueLabel","GitPullRequest","bucketOfPlan","classifyChange","describeChange","editorLabel","BucketChip","propertyLabel","StepList","Ellipsis","Search","GripVertical","newStableId","DropdownMenuItem","DropdownMenuTrigger","DropdownMenuContent","DropdownMenu","Plus","useSaveDraftToChangeSet","useShipDraftNow","RefreshCw","Undo2","RadioGroup","Switch","describedBy","settle","HintedLabel","SharedGlyph","useDeleteDefinition","useSchemaSummary","FINAL_CHANGE_STATUSES","useChangeScope","usePlanChange","useDefinition","useAllDefinitions","useDefinitions","definitionQueryOptions","useSchemaChange","QueryView","useSaveShortcut","Textarea","Panel","useSchemaLock","LockNotice","deriveApiKey","describeIssue","followPlural","RadioTile","__iconData$2","EyeOff","createLucideIcon","__iconData$1","MousePointerClick","__iconData","Shapes","import_react","require_react","keyOf","category","id","useDefinitionDraftStore","set","key","definition","state","version","selection","field","recipe","fieldId","draftKeyOf","useSharedReadOnly","scope","canShare","import_jsx_runtime","SharedNotice","t","SaveActions","onDiscard","canDiscard","reviewing","canReview","onReview","ActionFooter","props","failureOf","error","ChangeProgress","change","changeId","status","reported","onFinished","failure","onDismiss","same","a","b","isPlainObject","value","merge3","mine","base","theirs","keys","merged","ids","fields","kept","mergeFields","baseById","mineById","theirsById","primary","secondary","original","ours","other","rebaseDraft","baseFields","baseRest","draftFields","draftRest","draft","latestFields","latestRest","latest","useReloadDraft","queryClient","load","rebase","detail","mode","useScopeChange","changeScope","reloadDraft","onConflict","PanelSection","className","titleId","title","Scope","site","hintId","shared","target","siteName","blocked","locked","INITIAL_SETTINGS","createField","raw","input","withKey","next","record","withSetting","isDraftDirty","moveItem","from","to","items","moved","removeField","display","group","pruneLayout","canvasFieldIds","coverFieldId","stripFieldIds","eligible","test","canvas","cover","strip","withCompatibleEditor","compatible","entry","validateDraft","parsed","schema","others","found","issuesUnder","issues","path","fieldPath","index","IssueList","messages","titleFieldCandidates","probe","withAddedField","titled","candidate","documentPlacementOf","layout","model","inDocument","withDocumentPlacement","without","order","position","before","documentLayoutChoices","live","RESERVED","uniqueNewFieldName","labels","apiKeys","number","label","baseLabel","apiKey","folded","withFieldType","current","type","fresh","_defaultValue","placed","isCandidate","withFieldTypeOrSaved","saved","defaultValue","ADD_FIELD_BUTTON_ID","labelInputIdOf","afterRender","run","useNewField","update","select","added","setAdded","SEO_HELP_KEYS","AddFieldButton","helpId","confirming","setConfirming","addButton","onAdd","seo","help","availability","event","handleIdOf","Row","Icon","disabled","selected","dropTarget","onMove","total","onSelect","showLocalized","hasIssues","NO_FIELDS","FieldList","localized","dragFrom","dropIndex","setDropIndex","announcement","setAnnouncement","move","refocus","definitionIssues","count","TEXT_DEFAULT_TYPES","supportsDefaultValue","controlIds","hint","descriptionId","description","errorId","TextControl","onChange","emptyAsUndefined","multiline","monospace","TYPES","isDataType","DataType","labelledBy","unavailable","unavailableReason","notes","limitedNote","parse","text","integer","NumberControl","setText","shownValue","setShownValue","UNSET","SelectControl","known","options","option","unsetLabel","placeholder","DefaultValue","common","enumOptions","describeControl","itemOptions","describeProperties","object","required","property","ChoicesControl","toggle","checked","optionId","SwitchControl","control","LIST_SEPARATOR","PropertyControl","idPrefix","EditorPicker","choices","properties","choice","FLAG_KEYS","availableFlags","isComponent","modelLocalized","indexable","Flags","flag","at","classifyFieldTypeChange","NO_TYPES","useTypeChoices","LOCK_KEYS","Placement","lock","EnumValues","values","replace","patch","listIssues","rowIssues","valueId","labelId","HIDDEN_SETTINGS","FORMAT_HINT_KEYS","SOURCE_FIELD_TYPES","TypeSettings","settings","settingsPath","all","definitions","models","components","toOption","render","formatKey","rendered","otherIssues","CONTROLLED","FieldPanel","updateField","typeChoices","name","renamed","isNew","setLabel","followsLabel","untouched","Header","saveActions","breadcrumb","dirty","issueCount","deleteBlocked","onDelete","SEO_FIELD_LABEL","hasSeoField","createSeoField","useAddSeoField","present","ensure","exists","item","add","conflict","NO_ISSUES","useDraftIssues","deferredDraft","useIsDraftDirty","useRemoteChangeNotice","remote","ownChangeRunning","baseVersion","isVersionConflict","useSaveFlow","plan","apply","setState","runningChangeId","setRunningChangeId","notifyFailure","finishSuccessfully","preview","useSelectedField","DocumentLayout","setDisplay","DIRECTION_LABEL_KEYS","Display","titleField","sort","sortable","direction","DefinitionPanel","pluralRenamed","setApiKey","scopeSection","Summary","KindIcon","isDefinitionIssue","issue","ModelSettings","expanded","setExpanded","bodyId","open","NoFieldSelected","hasFields","RemoteChangeBanner","choose","reason","onKeepEdits","onReload","ChangeList","changes","inGroup","bucket","after","useReviewInChangeSet","navigate","save","SUMMARY_KEYS","ReviewSheet","acknowledgedBreaking","setAcknowledgedBreaking","acknowledgedDestructive","setAcknowledgedDestructive","previewShown","setPreviewShown","busy","applying","saving","resetSave","summary","needsBreaking","needsDestructive","canApply","onClose","onApply","saveError","reviewInChangeSet","Editor","loadedKey","reset","flow","sharedReadOnly","deleteDefinition","newField","seoField","confirmingDelete","setConfirmingDelete","dismissedChangeId","setDismissedChangeId","scopeConflict","setScopeConflict","initial","visibleChangeId","changeRunning","saveBlocked","planOpen","reload","editingDisabled","multiSite","changedElsewhere","acknowledgement","Builder","data"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/eye-off.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/mouse-pointer-click.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/shapes.mjs","../../src/stores/definitionDraft.ts","../../src/features/Models/hooks/useSharedReadOnly.ts","../../src/features/Models/SharedNotice/index.tsx","../../src/features/Models/Builder/SaveActions/index.tsx","../../src/features/Models/Builder/ActionFooter/index.tsx","../../src/features/Models/Builder/ChangeProgress/index.tsx","../../src/features/Models/helpers/rebase.ts","../../src/features/Models/Builder/hooks/useReloadDraft.ts","../../src/features/Models/Builder/hooks/useScopeChange.ts","../../src/features/Models/Builder/PanelSection/index.tsx","../../src/features/Models/Builder/DefinitionPanel/Scope/index.tsx","../../src/features/Models/helpers/draft.ts","../../src/features/Models/helpers/issues.ts","../../src/features/Models/Builder/controls/IssueList/index.tsx","../../src/features/Models/helpers/display.ts","../../src/features/Models/helpers/newField.ts","../../src/features/Models/Builder/hooks/useNewField.ts","../../src/features/Models/Builder/FieldList/AddFieldButton/index.tsx","../../src/features/Models/Builder/FieldList/handleId.ts","../../src/features/Models/Builder/FieldList/Row/index.tsx","../../src/features/Models/Builder/FieldList/index.tsx","../../src/features/Models/helpers/defaultValue.ts","../../src/features/Models/Builder/controls/types.ts","../../src/features/Models/Builder/controls/TextControl/index.tsx","../../src/features/Models/Builder/FieldPanel/DataType/index.tsx","../../src/features/Models/Builder/controls/NumberControl/index.tsx","../../src/features/Models/Builder/controls/SelectControl/index.tsx","../../src/features/Models/Builder/FieldPanel/DefaultValue/index.tsx","../../src/features/Models/helpers/schemaControls.ts","../../src/features/Models/Builder/controls/ChoicesControl/index.tsx","../../src/features/Models/Builder/controls/SwitchControl/index.tsx","../../src/features/Models/Builder/PropertyControl/index.tsx","../../src/features/Models/Builder/FieldPanel/EditorPicker/index.tsx","../../src/features/Models/Builder/FieldPanel/Flags/index.tsx","../../src/features/Models/helpers/typeChange.ts","../../src/features/Models/Builder/FieldPanel/hooks/useTypeChoices.ts","../../src/features/Models/Builder/FieldPanel/Placement/index.tsx","../../src/features/Models/Builder/FieldPanel/EnumValues/index.tsx","../../src/features/Models/Builder/FieldPanel/TypeSettings/index.tsx","../../src/features/Models/Builder/FieldPanel/index.tsx","../../src/features/Models/Builder/Header/index.tsx","../../src/features/Models/helpers/seoField.ts","../../src/features/Models/Builder/hooks/useAddSeoField.ts","../../src/features/Models/Builder/hooks/useDraftIssues.ts","../../src/features/Models/Builder/hooks/useIsDraftDirty.ts","../../src/features/Models/Builder/hooks/useRemoteChangeNotice.ts","../../src/features/Models/Builder/hooks/useSaveFlow.ts","../../src/features/Models/Builder/hooks/useSelectedField.ts","../../src/features/Models/Builder/DefinitionPanel/Display/DocumentLayout/index.tsx","../../src/features/Models/Builder/DefinitionPanel/Display/index.tsx","../../src/features/Models/Builder/DefinitionPanel/index.tsx","../../src/features/Models/Builder/ModelSettings/Summary/index.tsx","../../src/features/Models/Builder/ModelSettings/index.tsx","../../src/features/Models/Builder/NoFieldSelected/index.tsx","../../src/features/Models/Builder/RemoteChangeBanner/index.tsx","../../src/features/Models/Builder/ReviewSheet/ChangeList/index.tsx","../../src/features/Models/Builder/ReviewSheet/hooks/useReviewInChangeSet.ts","../../src/features/Models/Builder/ReviewSheet/index.tsx","../../src/features/Models/Builder/Editor/index.tsx","../../src/features/Models/Builder/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"eye-off\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n ]\n};\n__iconData.node;\nconst EyeOff = createLucideIcon(__iconData);\n\nexport { __iconData, EyeOff as default };\n//# sourceMappingURL=eye-off.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"mouse-pointer-click\",\n size: 24,\n node: [\n [\"path\", { d: \"M14 4.1 12 6\", key: \"ita8i4\" }],\n [\"path\", { d: \"m5.1 8-2.9-.8\", key: \"1go3kf\" }],\n [\"path\", { d: \"m6 12-1.9 2\", key: \"mnht97\" }],\n [\"path\", { d: \"M7.2 2.2 8 5.1\", key: \"1cfko1\" }],\n [\n \"path\",\n {\n d: \"M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z\",\n key: \"s0h3yz\"\n }\n ]\n ]\n};\n__iconData.node;\nconst MousePointerClick = createLucideIcon(__iconData);\n\nexport { __iconData, MousePointerClick as default };\n//# sourceMappingURL=mouse-pointer-click.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"shapes\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z\",\n key: \"1bo67w\"\n }\n ],\n [\"rect\", { x: \"3\", y: \"14\", width: \"7\", height: \"7\", rx: \"1\", key: \"1bkyp8\" }],\n [\"circle\", { cx: \"17.5\", cy: \"17.5\", r: \"3.5\", key: \"w3z12y\" }]\n ]\n};\n__iconData.node;\nconst Shapes = createLucideIcon(__iconData);\n\nexport { __iconData, Shapes as default };\n//# sourceMappingURL=shapes.mjs.map\n","import type { DefinitionCategory } from '@shapio/client';\nimport type { FieldDefinition, SchemaDefinition } from '@shapio/schema';\nimport { create } from 'zustand';\n\n/** What the builder's settings panel shows: the definition's own settings, or one field. */\nexport type DraftSelection = { type: 'definition' } | { type: 'field'; fieldId: string };\n\ntype DraftState = {\n /** `${category}:${id}` of the definition being edited, or null before one is loaded. */\n key: string | null;\n category: DefinitionCategory;\n /** The active definition the draft is based on, and its version (sent as `expectedVersion`). */\n base: SchemaDefinition | null;\n baseVersion: number;\n draft: SchemaDefinition | null;\n selection: DraftSelection;\n /**\n * Starts editing a definition, discarding any previous draft. Reloading the same definition keeps the\n * selected field open if it still exists.\n */\n load: (category: DefinitionCategory, definition: SchemaDefinition, version: number) => void;\n /** Forgets the draft (the builder closed). */\n reset: () => void;\n /** Moves the base to a newer version with the edits re-applied on top (after a conflict, by choice). */\n rebase: (definition: SchemaDefinition, version: number, draft: SchemaDefinition) => void;\n update: (recipe: (draft: SchemaDefinition) => SchemaDefinition) => void;\n updateField: (fieldId: string, recipe: (field: FieldDefinition) => FieldDefinition) => void;\n select: (selection: DraftSelection) => void;\n};\n\nconst keyOf = (category: DefinitionCategory, id: string) => `${category}:${id}`;\n\n/**\n * The model builder's unsaved definition (client-only state). Edits are immutable updates of a normalized\n * definition, which is also what the plan and apply endpoints accept.\n */\nexport const useDefinitionDraftStore = create<DraftState>()((set) => ({\n key: null,\n category: 'model',\n base: null,\n baseVersion: 0,\n draft: null,\n selection: { type: 'definition' },\n load: (category, definition, version) =>\n set((state) => {\n const key = keyOf(category, definition.id);\n const { selection } = state;\n const keepSelection =\n state.key === key &&\n (selection.type === 'definition' ||\n definition.fields.some((field) => field.id === selection.fieldId));\n return {\n key,\n category,\n base: definition,\n baseVersion: version,\n draft: definition,\n selection: keepSelection ? selection : { type: 'definition' },\n };\n }),\n reset: () => set({ key: null, base: null, baseVersion: 0, draft: null, selection: { type: 'definition' } }),\n rebase: (definition, version, draft) => set({ base: definition, baseVersion: version, draft }),\n update: (recipe) => set((state) => (state.draft ? { draft: recipe(state.draft) } : {})),\n updateField: (fieldId, recipe) =>\n set((state) =>\n state.draft\n ? {\n draft: {\n ...state.draft,\n fields: state.draft.fields.map((field) => (field.id === fieldId ? recipe(field) : field)),\n },\n }\n : {},\n ),\n select: (selection) => set({ selection }),\n}));\n\n/** The store key of a definition: drafts are per category and ID. */\nexport const draftKeyOf = keyOf;\n","import type { DefinitionScope } from '@shapio/client';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\n\n/**\n * A definition shared with all sites is read-only for an admin without `schema.create` on every site (the\n * server refuses the change with 403 either way).\n */\nexport const useSharedReadOnly = (scope: DefinitionScope) => {\n const { canShare } = useSchemaScopeAccess();\n return scope === 'network' && !canShare;\n};\n","import { Globe2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\n\n/** Why a shared definition can't be changed here: one line, above the builder. */\nexport const SharedNotice = () => {\n const { t } = useTranslation();\n return (\n <Alert>\n <Globe2 aria-hidden=\"true\" />\n <AlertDescription>{t('models.scope.readOnly')}</AlertDescription>\n </Alert>\n );\n};\n","import { Undo2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\n\nexport type SaveActionsProps = {\n /** Discard is possible (there are unsaved edits). */\n canDiscard: boolean;\n /** Review is possible: edits, no problems, nothing blocking. */\n canReview: boolean;\n reviewing: boolean;\n onReview: () => void;\n /** Runs once the admin confirms the discard. */\n onDiscard: () => void;\n};\n\n/**\n * Discard changes (confirmed in place), then Review (the primary action: the plan, then Ship now or Review in a change set). In the header on xl, the\n * footer below.\n */\nexport const SaveActions = ({ canDiscard, canReview, reviewing, onReview, onDiscard }: SaveActionsProps) => {\n const { t } = useTranslation();\n return (\n <>\n <InlineConfirm\n tone=\"danger\"\n title={t('models.builder.discardTitle')}\n description={t('models.builder.discardDescription')}\n confirmLabel={t('models.builder.discard')}\n onConfirm={onDiscard}\n trigger={\n <Button type=\"button\" variant=\"ghost\" disabled={!canDiscard}>\n <Undo2 aria-hidden=\"true\" />\n {t('models.builder.discard')}\n </Button>\n }\n />\n <SubmitButton\n pending={reviewing}\n pendingLabel={t('models.builder.planning')}\n disabled={!canReview}\n onClick={onReview}\n >\n {t('models.builder.review')}\n </SubmitButton>\n </>\n );\n};\n","import { SaveActions, type SaveActionsProps } from '../SaveActions';\n\n/** Below xl the save actions stay in reach at the bottom of the screen (above the status bar on md+). */\nexport const ActionFooter = (props: SaveActionsProps) => (\n <div className=\"sticky bottom-0 z-20 -mx-4 flex justify-end gap-2 border-t bg-background/95 px-4 py-3 backdrop-blur supports-[backdrop-filter]:bg-background/80 sm:-mx-8 sm:px-8 md:bottom-(--statusbar-h) xl:hidden\">\n <SaveActions {...props} />\n </div>\n);\n","import { AlertCircle, Loader2 } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useSchemaChange } from '@/api/schema';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { FINAL_CHANGE_STATUSES } from '@/constants/schema';\n\ntype ChangeProgressProps = {\n changeId: string;\n onFinished: (status: string) => void;\n onDismiss: () => void;\n};\n\ntype ChangeFailure = { reason?: unknown; invalidCount?: unknown };\n\nconst failureOf = (error: unknown): ChangeFailure =>\n typeof error === 'object' && error !== null ? error : {};\n\n/**\n * A schema change whose prerequisites run as jobs: progress while they run, then either the success\n * (reported to the builder, which reloads) or why it failed, with the previous version still active.\n */\nexport const ChangeProgress = ({ changeId, onFinished, onDismiss }: ChangeProgressProps) => {\n const { t } = useTranslation();\n const change = useSchemaChange(changeId);\n const status = change.data?.status;\n const reported = useRef(false);\n useEffect(() => {\n if (status && FINAL_CHANGE_STATUSES.has(status) && !reported.current) {\n reported.current = true;\n onFinished(status);\n }\n }, [status, onFinished]);\n if (status === 'activated') {\n return null;\n }\n if (status === 'failed' || status === 'cancelled') {\n const failure = failureOf(change.data?.error);\n return (\n <Alert variant=\"destructive\">\n <AlertCircle aria-hidden=\"true\" />\n <AlertTitle>{t('models.progress.failedTitle')}</AlertTitle>\n <AlertDescription>\n <p>{t('models.progress.failedDescription')}</p>\n {typeof failure.invalidCount === 'number' ? (\n <p>{t('models.progress.invalidCount', { count: failure.invalidCount })}</p>\n ) : null}\n {typeof failure.reason === 'string' ? <p>{failure.reason}</p> : null}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"mt-2\" onClick={onDismiss}>\n {t('common.close')}\n </Button>\n </AlertDescription>\n </Alert>\n );\n }\n return (\n <Alert variant=\"info\" role=\"status\">\n <Loader2 className=\"animate-spin\" aria-hidden=\"true\" />\n <AlertTitle>{t('models.progress.runningTitle')}</AlertTitle>\n <AlertDescription>{t('models.progress.runningDescription')}</AlertDescription>\n </Alert>\n );\n};\n","import { canonicalJson, type FieldDefinition, type SchemaDefinition } from '@shapio/schema';\n\nconst same = (a: unknown, b: unknown) => canonicalJson(a ?? null) === canonicalJson(b ?? null);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Three-way merge of JSON values: whatever only one side changed wins; objects merge key by key; where\n * both sides changed the same scalar or list, `mine` wins (the plan review shows it).\n */\nexport const merge3 = (base: unknown, mine: unknown, theirs: unknown): unknown => {\n if (same(mine, base)) {\n return theirs;\n }\n if (same(theirs, base)) {\n return mine;\n }\n if (isPlainObject(base) && isPlainObject(mine) && isPlainObject(theirs)) {\n const keys = new Set([...Object.keys(base), ...Object.keys(mine), ...Object.keys(theirs)]);\n const merged: Record<string, unknown> = {};\n for (const key of keys) {\n const value = merge3(base[key], mine[key], theirs[key]);\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n }\n return mine;\n};\n\nconst ids = (fields: readonly FieldDefinition[], kept: ReadonlyMap<string, unknown>) =>\n fields.filter((field) => kept.has(field.id)).map((field) => field.id);\n\n/** Merges field lists by stable ID: additions and removals from both sides, edits merged per property. */\nconst mergeFields = (\n base: readonly FieldDefinition[],\n mine: readonly FieldDefinition[],\n theirs: readonly FieldDefinition[],\n): FieldDefinition[] => {\n const baseById = new Map(base.map((field) => [field.id, field]));\n const mineById = new Map(mine.map((field) => [field.id, field]));\n const theirsById = new Map(theirs.map((field) => [field.id, field]));\n const reorderedByMe = !same(ids(mine, baseById), ids(base, mineById));\n const [primary, secondary] = reorderedByMe ? [mine, theirs] : [theirs, mine];\n const order = [...new Set([...primary, ...secondary].map((field) => field.id))];\n return order.flatMap((id) => {\n const original = baseById.get(id);\n const ours = mineById.get(id);\n const other = theirsById.get(id);\n if (original && !ours) {\n return [];\n }\n if (original && !other) {\n // They removed it: gone, unless this session edited it.\n return ours && !same(ours, original) ? [ours] : [];\n }\n if (!original) {\n return [(ours ?? other) as FieldDefinition];\n }\n return [merge3(original, ours, other) as FieldDefinition];\n });\n};\n\n/**\n * Re-applies this session's edits (`draft` relative to `base`) on top of a newer active version, like\n * rebasing a branch, so keeping one's edits after a conflict never undoes another admin's changes to\n * properties this session did not touch.\n */\nexport const rebaseDraft = (\n base: SchemaDefinition,\n draft: SchemaDefinition,\n latest: SchemaDefinition,\n): SchemaDefinition => {\n const { fields: baseFields, ...baseRest } = base;\n const { fields: draftFields, ...draftRest } = draft;\n const { fields: latestFields, ...latestRest } = latest;\n const merged = merge3(baseRest, draftRest, latestRest) as Omit<SchemaDefinition, 'fields'>;\n return { ...merged, fields: mergeFields(baseFields, draftFields, latestFields) } as SchemaDefinition;\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useCallback } from 'react';\nimport { definitionQueryOptions } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { rebaseDraft } from '../../helpers/rebase';\n\n/**\n * Fetches the active definition again. `replace` starts over from it (the draft's edits are dropped);\n * `rebase` re-applies the draft's edits on top of it (three-way merge) and moves the expected version\n * forward, so the next review is planned against the latest version.\n */\nexport const useReloadDraft = (category: DefinitionCategory, id: string) => {\n const queryClient = useQueryClient();\n const load = useDefinitionDraftStore((state) => state.load);\n const rebase = useDefinitionDraftStore((state) => state.rebase);\n return useCallback(\n async (mode: 'replace' | 'rebase') => {\n const detail = await queryClient.fetchQuery({ ...definitionQueryOptions(category, id), staleTime: 0 });\n const { base, draft } = useDefinitionDraftStore.getState();\n if (mode === 'rebase' && base && draft) {\n rebase(detail.definition, detail.version, rebaseDraft(base, draft, detail.definition));\n } else {\n load(category, detail.definition, detail.version);\n }\n return detail;\n },\n [queryClient, category, id, load, rebase],\n );\n};\n","import type { DefinitionCategory, DefinitionScope } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { hasErrorCode } from '@/api/errors';\nimport { useChangeScope } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { useReloadDraft } from './useReloadDraft';\n\n/**\n * Shares the definition with all sites, or keeps it on this site, against the version the draft is based\n * on. On success the draft (clean: the action is off while it has edits) starts over from the new version,\n * so the builder doesn't report its own change as a remote one. A version conflict goes to `onConflict`\n * (the builder's reload banner) and closes the confirmation; other failures reject for the confirmation to\n * show (`SCOPE_IN_USE` with the server's message and entry count).\n */\nexport const useScopeChange = (category: DefinitionCategory, id: string, onConflict: () => void) => {\n const { t } = useTranslation();\n const changeScope = useChangeScope();\n const reloadDraft = useReloadDraft(category, id);\n return async (scope: DefinitionScope) => {\n const version = useDefinitionDraftStore.getState().baseVersion;\n try {\n await changeScope.mutateAsync({ category, id, input: { scope, version } });\n } catch (error) {\n if (hasErrorCode(error, 'SCHEMA_VERSION_CONFLICT')) {\n onConflict();\n return;\n }\n throw error;\n }\n await reloadDraft('replace');\n toast.success(t(scope === 'network' ? 'models.scope.shared' : 'models.scope.kept'));\n };\n};\n","import type { ReactNode } from 'react';\nimport { FieldGroup } from '@/components/ui/field';\nimport { cn } from '@/helpers/cn';\n\ntype PanelSectionProps = {\n title: string;\n /** An ID for the heading, to name a control group by it. */\n titleId?: string;\n className?: string;\n children: ReactNode;\n};\n\n/** A titled group of controls inside a builder panel, divided from the one before it. */\nexport const PanelSection = ({ title, titleId, className, children }: PanelSectionProps) => (\n <section className={cn('space-y-4 border-t pt-5 first:border-t-0 first:pt-0', className)}>\n <h3 id={titleId} className=\"text-xs font-semibold tracking-wide text-muted-foreground uppercase\">\n {title}\n </h3>\n <FieldGroup className=\"gap-5\">{children}</FieldGroup>\n </section>\n);\n","import type { DefinitionCategory, DefinitionScope } from '@shapio/client';\nimport { useId } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { InfoHint } from '@/components/InfoHint';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { SharedGlyph } from '@/components/SharedGlyph';\nimport { Button } from '@/components/ui/button';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { useScopeChange } from '../../hooks/useScopeChange';\nimport { PanelSection } from '../../PanelSection';\n\ntype ScopeProps = {\n category: DefinitionCategory;\n id: string;\n label: string;\n scope: DefinitionScope;\n /** Unsaved edits or a change still running: the scope can't change until they are saved or discarded. */\n blocked: boolean;\n /** The schema lock is on (its notice says why). */\n locked: boolean;\n /** The definition moved since the draft loaded: the builder shows its reload banner. */\n onConflict: () => void;\n};\n\n/**\n * \"Available on\": this site or all sites, and for admins with `schema.create` on every site the action that\n * moves it (confirmed in place). Shown only where there is more than one site.\n */\nexport const Scope = ({ category, id, label, scope, blocked, locked, onConflict }: ScopeProps) => {\n const { t } = useTranslation();\n const site = useMe().data?.site;\n const { canShare } = useSchemaScopeAccess();\n const change = useScopeChange(category, id, onConflict);\n const hintId = useId();\n const shared = scope === 'network';\n const target: DefinitionScope = shared ? 'site' : 'network';\n const siteName = site?.name ?? '';\n return (\n <PanelSection title={t('contentTypes.availableOn')}>\n <p className=\"flex items-center gap-1.5 text-sm\" data-scope={scope}>\n {shared ? <SharedGlyph /> : null}\n {shared ? t('contentTypes.sharedWithAllSites') : t('models.scope.onlyOn', { site: siteName })}\n </p>\n {canShare ? (\n <div className=\"flex items-center gap-1\">\n <InlineConfirm\n tone=\"default\"\n title={\n shared\n ? t('models.scope.keepTitle', { label, site: siteName })\n : t('models.scope.shareTitle', { label })\n }\n description={shared ? t('models.scope.keepDescription') : t('models.scope.shareDescription')}\n confirmLabel={shared ? t('models.scope.keep') : t('models.scope.share')}\n pendingLabel={t('common.saving')}\n onConfirm={() => change(target)}\n trigger={\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={blocked || locked}\n aria-describedby={blocked ? hintId : undefined}\n >\n {shared ? t('models.scope.keep') : t('models.scope.share')}\n </Button>\n }\n />\n {blocked ? (\n <InfoHint about={shared ? t('models.scope.keep') : t('models.scope.share')} id={hintId}>\n {t('models.scope.blocked')}\n </InfoHint>\n ) : null}\n </div>\n ) : null}\n </PanelSection>\n );\n};\n","import {\n canonicalJson,\n DEFAULT_EDITORS,\n effectiveTitleField,\n isCoverEligible,\n isDocumentPlaceable,\n isCustomEditorId,\n listCompatibleEditors,\n renormalizeDefinition,\n type DataType,\n type FieldDefinition,\n type JsonValue,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { newStableId } from '@/helpers/stableId';\n\n/** Required settings a new field starts with; the user fills them in (inline errors until then). */\nconst INITIAL_SETTINGS: Partial<Record<DataType, Record<string, JsonValue>>> = {\n enum: { values: [] },\n relation: { target: '', cardinality: 'one' },\n component: { component: '' },\n dynamiczone: { components: [] },\n};\n\n/** A new field with Shapio's defaults (public, optional, default editor), normalized like the server does. */\nexport const createField = (\n definition: SchemaDefinition,\n input: {\n type: DataType;\n label: string;\n apiKey: string;\n /** Replaces the type's initial settings (defaults still apply to what's left out). */\n settings?: Record<string, JsonValue>;\n editorId?: string;\n localized?: boolean;\n },\n): FieldDefinition => {\n const raw = {\n id: newStableId(),\n apiKey: input.apiKey,\n label: input.label,\n type: input.type,\n settings: input.settings ?? INITIAL_SETTINGS[input.type] ?? {},\n ...(input.editorId === undefined ? {} : { editor: { id: input.editorId } }),\n ...(input.localized === undefined ? {} : { localized: input.localized }),\n };\n const normalized = renormalizeDefinition({\n ...definition,\n fields: [raw],\n } as unknown as SchemaDefinition);\n return normalized.fields[0] as FieldDefinition;\n};\n\n/** Sets (or, with `undefined`, removes) one key of a record, immutably. */\nexport const withKey = <T extends Record<string, unknown>>(record: T, key: string, value: unknown): T => {\n const next: Record<string, unknown> = { ...record };\n if (value === undefined) {\n delete next[key];\n } else {\n next[key] = value;\n }\n return next as T;\n};\n\nexport const withSetting = (field: FieldDefinition, key: string, value: unknown): FieldDefinition =>\n ({ ...field, settings: withKey(field.settings as Record<string, unknown>, key, value) }) as FieldDefinition;\n\n/** Whether the draft means something different from the active definition (compared normalized). */\nexport const isDraftDirty = (draft: SchemaDefinition, base: SchemaDefinition): boolean =>\n canonicalJson(renormalizeDefinition(draft)) !== canonicalJson(renormalizeDefinition(base));\n\n/** Moves the item at `from` to `to`, immutably. */\nexport const moveItem = <T>(items: readonly T[], from: number, to: number): T[] => {\n if (from === to || from < 0 || to < 0 || from >= items.length || to >= items.length) {\n return [...items];\n }\n const next = [...items];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved as T);\n return next;\n};\n\n/** Removes a field and every reference to it (display settings, slug sources), so the draft stays valid. */\nexport const removeField = (definition: SchemaDefinition, fieldId: string): SchemaDefinition => {\n const fields = definition.fields\n .filter((field) => field.id !== fieldId)\n .map((field) =>\n field.type === 'slug' && field.settings.sourceFieldId === fieldId\n ? withSetting(field, 'sourceFieldId', undefined)\n : field,\n );\n const display: Record<string, unknown> = { ...definition.display };\n if (display.titleFieldId === fieldId) {\n delete display.titleFieldId;\n }\n if ('listFieldIds' in definition.display && definition.display.listFieldIds) {\n display.listFieldIds = definition.display.listFieldIds.filter((id) => id !== fieldId);\n }\n if ('defaultSort' in definition.display && definition.display.defaultSort?.fieldId === fieldId) {\n delete display.defaultSort;\n }\n if (definition.display.groups) {\n display.groups = definition.display.groups.map((group) => ({\n ...group,\n fieldIds: group.fieldIds.filter((id) => id !== fieldId),\n }));\n }\n return pruneLayout({ ...definition, fields, display });\n};\n\n/**\n * Drops document-layout references (`canvasFieldIds`, `coverFieldId`, `stripFieldIds`) that no longer\n * point at an eligible field, after a field is removed, changes type or settings, moves, or becomes the\n * title (the title is the document's heading, never a field in it). Keeps the draft valid without a trip to\n * Display.\n */\nexport const pruneLayout = (definition: SchemaDefinition): SchemaDefinition => {\n if (definition.kind === 'component') {\n return definition;\n }\n const { canvasFieldIds, coverFieldId, stripFieldIds } = definition.display;\n if (canvasFieldIds === undefined && coverFieldId === undefined && stripFieldIds === undefined) {\n return definition;\n }\n const fields = new Map(definition.fields.map((field) => [field.id, field]));\n const eligible = (id: string, test: (field: FieldDefinition) => boolean) => {\n const field = fields.get(id);\n return field !== undefined && test(field);\n };\n const title = effectiveTitleField(definition);\n const canvas = canvasFieldIds?.filter((id) => eligible(id, (field) => isDocumentPlaceable(field, title)));\n const cover =\n coverFieldId !== undefined && eligible(coverFieldId, isCoverEligible) && !canvas?.includes(coverFieldId)\n ? coverFieldId\n : undefined;\n const strip = stripFieldIds?.filter((id) => fields.has(id) && id !== cover && !(canvas ?? []).includes(id));\n let display = withKey(definition.display, 'canvasFieldIds', canvas);\n display = withKey(display, 'coverFieldId', cover);\n display = withKey(display, 'stripFieldIds', strip);\n return { ...definition, display };\n};\n\n/**\n * Keeps the field's editor usable after a settings change (e.g. radio buttons cannot edit a multi-value\n * enum): an incompatible built-in editor is replaced by the first compatible one. Custom editors are kept.\n */\nexport const withCompatibleEditor = (field: FieldDefinition): FieldDefinition => {\n if (isCustomEditorId(field.editor.id)) {\n return field;\n }\n const compatible = listCompatibleEditors(field);\n if (compatible.some((entry) => entry.id === field.editor.id)) {\n return field;\n }\n return { ...field, editor: { id: compatible[0]?.id ?? DEFAULT_EDITORS[field.type], options: {} } };\n};\n","import { parseDefinition, validateSchema, type SchemaDefinition, type ValidationIssue } from '@shapio/schema';\n\n/**\n * Validates a draft with the same validators the server runs (`parseDefinition` per definition, then\n * `validateSchema` over the whole proposed schema), so problems show inline before the plan is requested.\n * Only issues about the draft itself are returned.\n */\nexport const validateDraft = (\n draft: SchemaDefinition,\n base: SchemaDefinition,\n others: readonly SchemaDefinition[],\n): ValidationIssue[] => {\n const parsed = parseDefinition(draft, { previous: base });\n if (!parsed.ok) {\n return parsed.issues;\n }\n // The draft goes last: collisions are reported on the later definition, which should be the draft.\n const schema = [...others.filter((definition) => definition.id !== draft.id), parsed.definition];\n return validateSchema(schema).filter(\n (found) => found.definitionId === undefined || found.definitionId === draft.id,\n );\n};\n\n/** Issues at `path` or below it (`/fields/2` matches `/fields/2/apiKey`). */\nexport const issuesUnder = (issues: readonly ValidationIssue[], path: string): ValidationIssue[] =>\n issues.filter((found) => found.path === path || found.path.startsWith(`${path}/`));\n\n/** The JSON-pointer prefix of the field at `index`. */\nexport const fieldPath = (index: number) => `/fields/${index}`;\n","import type { ValidationIssue } from '@shapio/schema';\nimport { FieldError } from '@/components/ui/field';\nimport { describeIssue } from '../../../helpers/describeIssue';\n\ntype IssueListProps = { id?: string; issues: readonly ValidationIssue[] };\n\n/** A control's validation problems, translated, under the control (announced via aria-describedby). */\nexport const IssueList = ({ id, issues }: IssueListProps) => {\n if (issues.length === 0) {\n return null;\n }\n const messages = [...new Set(issues.map(describeIssue))];\n return <FieldError id={id} errors={messages.map((message) => ({ message }))} />;\n};\n","import {\n effectiveLayout,\n isCanvasEligible,\n isCoverEligible,\n validateDefinition,\n type FieldDefinition,\n type ModelDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { pruneLayout, withKey } from './draft';\n\n/**\n * Fields that may label entries (`display.titleFieldId`). Asks the definition validator rather than\n * duplicating its rule: each field is checked alone, as the only field of a minimal definition.\n */\nexport const titleFieldCandidates = (definition: SchemaDefinition): FieldDefinition[] =>\n definition.fields.filter((field) => {\n const probe = {\n ...definition,\n fields: [field],\n display: { titleFieldId: field.id },\n } as SchemaDefinition;\n return !validateDefinition(probe).some((found) => found.path === '/display/titleFieldId');\n });\n\n/**\n * Appends a new field. The first field that can label entries also becomes the title field while none is\n * set, so entries get a readable title without a trip to the model settings. A title field left unset on\n * purpose next to existing candidates stays unset. A new block field (rich text, a zone, a repeatable list,\n * a gallery) joins the document's configured fields, as it would join the automatic ones.\n */\nexport const withAddedField = (definition: SchemaDefinition, field: FieldDefinition): SchemaDefinition => {\n const next = { ...definition, fields: [...definition.fields, field] };\n const becomesTitle =\n definition.display.titleFieldId === undefined &&\n titleFieldCandidates(definition).length === 0 &&\n titleFieldCandidates(next).some((candidate) => candidate.id === field.id);\n const titled = becomesTitle ? { ...next, display: { ...next.display, titleFieldId: field.id } } : next;\n if (\n titled.kind === 'component' ||\n titled.display.canvasFieldIds === undefined ||\n !isCanvasEligible(field)\n ) {\n return titled;\n }\n return {\n ...titled,\n display: { ...titled.display, canvasFieldIds: [...titled.display.canvasFieldIds, field.id] },\n };\n};\n\n/** Why a field's \"Show in document\" switch can't change: it is the title, the chosen cover, or the last one. */\nexport type PlacementLock = 'title' | 'cover' | 'last';\n\nexport type DocumentPlacement = { inDocument: boolean; lock: PlacementLock | undefined };\n\n/**\n * Whether the entry document shows the field (`effectiveLayout`), and why that can't be switched: the title\n * is the document's heading, the cover chosen in Display sits above it, and the last document field stays\n * because an empty list means the automatic layout.\n */\nexport const documentPlacementOf = (model: ModelDefinition, field: FieldDefinition): DocumentPlacement => {\n const layout = effectiveLayout(model);\n const inDocument = layout.canvas.some((candidate) => candidate.id === field.id);\n const lock: PlacementLock | undefined =\n layout.title?.id === field.id\n ? 'title'\n : model.display.coverFieldId === field.id && layout.cover?.id === field.id\n ? 'cover'\n : inDocument && layout.canvas.length === 1\n ? 'last'\n : undefined;\n return { inDocument, lock };\n};\n\n/**\n * Puts the field in the document or takes it out. The automatic layout becomes an explicit list first; a\n * field put in goes before the first listed field that follows it in field order. Taking a field out keeps\n * the others, and `pruneLayout` keeps the strip and cover consistent.\n */\nexport const withDocumentPlacement = (\n model: ModelDefinition,\n fieldId: string,\n inDocument: boolean,\n): ModelDefinition => {\n const current = effectiveLayout(model).canvas.map((field) => field.id);\n const without = current.filter((id) => id !== fieldId);\n let next = without;\n if (inDocument) {\n const order = new Map(model.fields.map((field, index) => [field.id, index]));\n const position = order.get(fieldId) ?? model.fields.length;\n const before = without.findIndex((id) => (order.get(id) ?? 0) > position);\n next =\n before === -1\n ? [...without, fieldId]\n : [...without.slice(0, before), fieldId, ...without.slice(before)];\n }\n const display = withKey(model.display, 'canvasFieldIds', next.length > 0 ? next : undefined);\n return pruneLayout({ ...model, display }) as ModelDefinition;\n};\n\nexport type DocumentLayoutChoices = {\n /** Single image fields that can be the cover. */\n coverOptions: FieldDefinition[];\n /** Canvas-eligible fields: the current canvas in its order, then the others in field order. */\n canvasOptions: FieldDefinition[];\n /** The canvas as the document shows it (configured, or the default). */\n canvas: string[];\n /** Fields the strip can show (the document's properties). */\n stripOptions: FieldDefinition[];\n};\n\n/** What the Display section offers for the entry document, from the definition being edited. */\nexport const documentLayoutChoices = (model: ModelDefinition): DocumentLayoutChoices => {\n const live = model.fields.filter((field) => !field.deprecated);\n const layout = effectiveLayout(model);\n const canvas = layout.canvas.map((field) => field.id);\n const others = live.filter((field) => isCanvasEligible(field) && !canvas.includes(field.id));\n return {\n coverOptions: live.filter(isCoverEligible),\n canvasOptions: [...layout.canvas, ...others],\n canvas,\n stripOptions: layout.properties,\n };\n};\n","import {\n foldApiKey,\n RESERVED_FIELD_API_KEYS,\n type DataType,\n type FieldDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { deriveApiKey } from './deriveApiKey';\nimport { titleFieldCandidates } from './display';\nimport { createField } from './draft';\n\nconst RESERVED: ReadonlySet<string> = new Set(RESERVED_FIELD_API_KEYS.map(foldApiKey));\n\n/**\n * A label and API ID for a field added with one click: `baseLabel` (\"New field\"), then \"New field 2\",\n * \"New field 3\"... until neither the label nor its API ID (case-folded) is taken or reserved.\n */\nexport const uniqueNewFieldName = (\n definition: SchemaDefinition,\n baseLabel: string,\n): { label: string; apiKey: string } => {\n const labels = new Set(definition.fields.map((field) => field.label));\n const apiKeys = new Set(definition.fields.map((field) => foldApiKey(field.apiKey)));\n for (let number = 1; ; number += 1) {\n const label = number === 1 ? baseLabel : `${baseLabel} ${number}`;\n const apiKey = deriveApiKey(label);\n const folded = foldApiKey(apiKey);\n if (!labels.has(label) && !apiKeys.has(folded) && !RESERVED.has(folded)) {\n return { label, apiKey };\n }\n }\n};\n\n/**\n * Changes a field's data type: its type-specific settings, editor and default value start over with the new\n * type's defaults; its ID, position, names, help text and options are kept. A title field that can no\n * longer label entries is unset, and the title-field rule of `withAddedField` applies again. Other\n * references that no longer fit show as draft issues.\n */\nexport const withFieldType = (\n definition: SchemaDefinition,\n fieldId: string,\n type: DataType,\n): SchemaDefinition => {\n const current = definition.fields.find((field) => field.id === fieldId);\n if (!current || current.type === type) {\n return definition;\n }\n const fresh = createField(definition, { type, label: current.label, apiKey: current.apiKey });\n const { defaultValue: _defaultValue, ...kept } = current as FieldDefinition & { defaultValue?: unknown };\n const next = { ...kept, type, settings: fresh.settings, editor: fresh.editor } as FieldDefinition;\n const fields = definition.fields.map((field) => (field.id === fieldId ? next : field));\n const others = { ...definition, fields: definition.fields.filter((field) => field.id !== fieldId) };\n const display: Record<string, unknown> = { ...definition.display };\n const placed = { ...definition, fields, display };\n const isCandidate = titleFieldCandidates(placed).some((candidate) => candidate.id === fieldId);\n if (display.titleFieldId === fieldId && !isCandidate) {\n delete display.titleFieldId;\n } else if (display.titleFieldId === undefined && isCandidate && titleFieldCandidates(others).length === 0) {\n display.titleFieldId = fieldId;\n }\n return placed;\n};\n\n/**\n * `withFieldType`, except that going back to the saved field's own type restores its saved settings,\n * editor and default value, so trying another type and returning leaves nothing changed.\n */\nexport const withFieldTypeOrSaved = (\n definition: SchemaDefinition,\n fieldId: string,\n type: DataType,\n saved: FieldDefinition | undefined,\n): SchemaDefinition => {\n const next = withFieldType(definition, fieldId, type);\n if (saved?.type !== type) {\n return next;\n }\n const { settings, editor } = saved;\n const defaultValue = (saved as { defaultValue?: unknown }).defaultValue;\n return {\n ...next,\n fields: next.fields.map((field) =>\n field.id === fieldId\n ? ({\n ...field,\n settings,\n editor,\n ...(defaultValue === undefined ? {} : { defaultValue }),\n } as FieldDefinition)\n : field,\n ),\n };\n};\n","import { canonicalJson, type FieldDefinition } from '@shapio/schema';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { withAddedField } from '../../helpers/display';\nimport { createField, removeField } from '../../helpers/draft';\nimport { uniqueNewFieldName } from '../../helpers/newField';\n\n/** The field list's \"Add field\" button (focus goes back there when a new field is discarded). */\nexport const ADD_FIELD_BUTTON_ID = 'add-field-button';\n\n/** The DOM ID of a field's label input in the properties panel (see `FieldPanel`). */\nexport const labelInputIdOf = (fieldId: string) => `field-${fieldId}-label`;\n\nconst afterRender = (run: () => void) => requestAnimationFrame(run);\n\n/**\n * \"Add field\" adds a short-text field named \"New field\" (numbered when taken) to the draft at once, selects\n * it and puts the cursor in its label, text selected, so typing names it. A new field left exactly as it was\n * added can be discarded again (Escape in its panel). Nothing is saved until the plan is reviewed and applied.\n */\nexport const useNewField = () => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const [added, setAdded] = useState<FieldDefinition | null>(null);\n\n const add = () => {\n const { draft } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n const field = createField(draft, {\n type: 'string',\n ...uniqueNewFieldName(draft, t('models.builder.newField')),\n });\n update((current) => withAddedField(current, field));\n select({ type: 'field', fieldId: field.id });\n setAdded(field);\n afterRender(() => {\n const input = document.getElementById(labelInputIdOf(field.id));\n if (input instanceof HTMLInputElement) {\n input.scrollIntoView({ block: 'center' });\n input.focus({ preventScroll: true });\n input.select();\n }\n });\n };\n\n /** Whether `field` is the field just added, still untouched. */\n const isUntouched = (field: FieldDefinition) =>\n added !== null && field.id === added.id && canonicalJson(field) === canonicalJson(added);\n\n const discard = (fieldId: string) => {\n update((current) => removeField(current, fieldId));\n select({ type: 'definition' });\n setAdded(null);\n afterRender(() => document.getElementById(ADD_FIELD_BUTTON_ID)?.focus());\n };\n\n return { add, isUntouched, discard };\n};\n","import { ChevronDown, Plus, Search } from 'lucide-react';\nimport { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport type { useAddSeoField } from '../../hooks/useAddSeoField';\nimport { ADD_FIELD_BUTTON_ID } from '../../hooks/useNewField';\n\ntype AddFieldButtonProps = {\n disabled: boolean;\n onAdd: () => void;\n /** \"SEO fields\" in the menu; absent for components (the SEO group belongs on content types). */\n seo?: ReturnType<typeof useAddSeoField>;\n};\n\nconst SEO_HELP_KEYS = {\n askAdmin: 'seo.builder.askAdmin',\n present: 'seo.builder.present',\n} as const;\n\n/**\n * \"Add field\" as a split button: the main half adds a field at once (as before), the chevron opens a menu\n * with Field and SEO fields. Enabling SEO for the network asks first, anchored to the chevron.\n */\nexport const AddFieldButton = ({ disabled, onAdd, seo }: AddFieldButtonProps) => {\n const { t } = useTranslation();\n const helpId = useId();\n const [confirming, setConfirming] = useState(false);\n const addButton = (\n <Button\n id={ADD_FIELD_BUTTON_ID}\n type=\"button\"\n size=\"sm\"\n onClick={onAdd}\n disabled={disabled}\n className={seo ? 'rounded-r-none' : undefined}\n >\n <Plus aria-hidden=\"true\" />\n {t('models.builder.addField')}\n </Button>\n );\n if (!seo) {\n return addButton;\n }\n const { availability } = seo;\n const help = availability === 'askAdmin' || availability === 'present' ? SEO_HELP_KEYS[availability] : null;\n return (\n <div className=\"flex\">\n {addButton}\n <DropdownMenu>\n <InlineConfirm\n tone=\"default\"\n open={confirming}\n onOpenChange={setConfirming}\n title={t('seo.builder.enableTitle')}\n description={t('seo.builder.enableDescription')}\n confirmLabel={t('seo.builder.enable')}\n pendingLabel={t('seo.builder.enabling')}\n onConfirm={seo.enableAndAdd}\n >\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n size=\"icon-sm\"\n disabled={disabled}\n aria-label={t('seo.builder.menu')}\n className=\"rounded-l-none border-l border-primary-foreground/25\"\n >\n <ChevronDown aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </InlineConfirm>\n <DropdownMenuContent\n align=\"end\"\n className=\"w-64\"\n onCloseAutoFocus={(event) => confirming && event.preventDefault()}\n >\n <DropdownMenuItem onSelect={onAdd}>\n <Plus aria-hidden=\"true\" />\n {t('seo.builder.field')}\n </DropdownMenuItem>\n <DropdownMenuItem\n disabled={availability !== 'ready' && availability !== 'enable'}\n aria-describedby={help ? helpId : undefined}\n onSelect={() => (availability === 'enable' ? setConfirming(true) : seo.add())}\n >\n <Search aria-hidden=\"true\" />\n {t('seo.builder.seoFields')}\n </DropdownMenuItem>\n {help ? (\n <p id={helpId} className=\"px-2 pb-1.5 pl-8 text-meta text-muted-foreground\">\n {t(help)}\n </p>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n","/** The DOM ID of a field row's reorder handle (focus returns to it after a keyboard move). */\nexport const handleIdOf = (fieldId: string) => `field-handle-${fieldId}`;\n","import type { FieldDefinition } from '@shapio/schema';\nimport { AlertCircle, ChevronDown, ChevronUp, EyeOff, GripVertical } from 'lucide-react';\nimport type { DragEvent, KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\nimport { DATA_TYPE_ICONS } from '../../../constants';\nimport { handleIdOf } from '../handleId';\n\ntype RowProps = {\n field: FieldDefinition;\n index: number;\n total: number;\n selected: boolean;\n hasIssues: boolean;\n showLocalized: boolean;\n dropTarget: boolean;\n disabled: boolean;\n onSelect: () => void;\n onMove: (to: number) => void;\n onDragStart: (event: DragEvent) => void;\n onDragOver: (event: DragEvent) => void;\n onDrop: (event: DragEvent) => void;\n onDragEnd: () => void;\n};\n\n/**\n * One field in the builder's list (44px): drag, the arrow keys on the handle, or the chevrons shown on\n * hover reorder it; click to edit. The chevrons are for the mouse (the handle already moves with the\n * keyboard), so they are not extra Tab stops.\n */\nexport const Row = ({\n field,\n index,\n total,\n selected,\n hasIssues,\n showLocalized,\n dropTarget,\n disabled,\n onSelect,\n onMove,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n}: RowProps) => {\n const { t } = useTranslation();\n const Icon = DATA_TYPE_ICONS[field.type];\n const onHandleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowUp' && index > 0) {\n event.preventDefault();\n onMove(index - 1);\n } else if (event.key === 'ArrowDown' && index < total - 1) {\n event.preventDefault();\n onMove(index + 1);\n }\n };\n return (\n <li\n draggable={!disabled}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDrop={onDrop}\n onDragEnd={onDragEnd}\n data-selected={selected || undefined}\n className={cn(\n 'group/row flex h-11 items-center gap-0.5 rounded-lg border border-transparent pr-1 transition-colors hover:bg-muted/50 data-[selected]:bg-accent',\n dropTarget && 'border-dashed border-primary',\n )}\n >\n <button\n type=\"button\"\n id={handleIdOf(field.id)}\n aria-label={t('models.builder.reorder', { label: field.label })}\n aria-describedby=\"field-reorder-help\"\n onKeyDown={onHandleKeyDown}\n disabled={disabled}\n className=\"flex h-9 w-6 shrink-0 cursor-grab items-center justify-center rounded-md text-muted-foreground outline-none hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed\"\n >\n <GripVertical className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n onClick={onSelect}\n aria-current={selected || undefined}\n className=\"flex h-9 min-w-0 flex-1 items-center gap-2.5 rounded-md px-1.5 text-left outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n >\n <Icon\n className={cn('size-4 shrink-0 text-muted-foreground', selected && 'text-accent-foreground')}\n aria-hidden=\"true\"\n />\n <span className=\"min-w-0 flex-1 leading-tight\">\n <span className=\"block truncate text-sm font-medium\">{field.label}</span>\n <span className=\"block truncate font-mono text-2xs text-muted-foreground\">{field.apiKey}</span>\n </span>\n <span className=\"flex shrink-0 items-center gap-1\">\n {field.required ? <Badge variant=\"outline\">{t('models.builder.requiredBadge')}</Badge> : null}\n {showLocalized && field.localized ? (\n <Badge variant=\"outline\">{t('models.builder.localizedBadge')}</Badge>\n ) : null}\n {field.public ? null : (\n <span title={t('models.builder.hiddenBadge')}>\n <EyeOff className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"sr-only\">{t('models.builder.hiddenBadge')}</span>\n </span>\n )}\n {hasIssues ? (\n <span title={t('models.builder.hasProblems')}>\n <AlertCircle className=\"size-4 text-destructive\" aria-hidden=\"true\" />\n <span className=\"sr-only\">{t('models.builder.hasProblems')}</span>\n </span>\n ) : null}\n </span>\n </button>\n <span className=\"hidden shrink-0 items-center group-focus-within/row:flex group-hover/row:flex\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n tabIndex={-1}\n disabled={disabled || index === 0}\n aria-label={t('models.builder.moveUp', { label: field.label })}\n onClick={() => onMove(index - 1)}\n >\n <ChevronUp aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n tabIndex={-1}\n disabled={disabled || index === total - 1}\n aria-label={t('models.builder.moveDown', { label: field.label })}\n onClick={() => onMove(index + 1)}\n >\n <ChevronDown aria-hidden=\"true\" />\n </Button>\n </span>\n </li>\n );\n};\n","import type { FieldDefinition, ValidationIssue } from '@shapio/schema';\nimport { useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { moveItem, pruneLayout } from '../../helpers/draft';\nimport { fieldPath, issuesUnder } from '../../helpers/issues';\nimport { IssueList } from '../controls/IssueList';\nimport type { useAddSeoField } from '../hooks/useAddSeoField';\nimport { AddFieldButton } from './AddFieldButton';\nimport { handleIdOf } from './handleId';\nimport { Row } from './Row';\n\ntype FieldListProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onAdd: () => void;\n /** \"Add field → SEO fields\" (models only). */\n seo?: ReturnType<typeof useAddSeoField>;\n};\n\nconst NO_FIELDS: FieldDefinition[] = [];\n\n/** The draft's fields in order: select one to edit it, reorder by drag, arrow keys or chevrons. */\nexport const FieldList = ({ issues, disabled, onAdd, seo }: FieldListProps) => {\n const { t } = useTranslation();\n const fields = useDefinitionDraftStore((state) => state.draft?.fields ?? NO_FIELDS);\n const localized = useDefinitionDraftStore(\n (state) => state.draft?.kind !== 'component' && state.draft?.localized === true,\n );\n const selection = useDefinitionDraftStore((state) => state.selection);\n const select = useDefinitionDraftStore((state) => state.select);\n const update = useDefinitionDraftStore((state) => state.update);\n const dragFrom = useRef<number | null>(null);\n const [dropIndex, setDropIndex] = useState<number | null>(null);\n const [announcement, setAnnouncement] = useState('');\n\n const move = (from: number, to: number, refocus: boolean) => {\n const moved = fields[from];\n if (!moved || from === to) {\n return;\n }\n // A move can change the automatic title field, which then leaves the document (`pruneLayout`).\n update((draft) => pruneLayout({ ...draft, fields: moveItem(draft.fields, from, to) }));\n setAnnouncement(\n t('models.builder.moved', { label: moved.label, position: to + 1, total: fields.length }),\n );\n if (refocus) {\n // The row's DOM node moves; put focus back on its handle so arrow keys keep working.\n requestAnimationFrame(() => document.getElementById(handleIdOf(moved.id))?.focus());\n }\n };\n const definitionIssues = issuesUnder(issues, '/fields').filter(\n (found) => !/^\\/fields\\/\\d+/.test(found.path),\n );\n\n const count = t('models.builder.fields', { count: fields.length });\n return (\n <Panel\n title={t('models.builder.fieldsTitle')}\n flush\n actions={\n <>\n <Badge variant=\"secondary\" aria-hidden=\"true\">\n {fields.length}\n </Badge>\n <AddFieldButton disabled={disabled} onAdd={onAdd} seo={seo} />\n </>\n }\n bodyClassName=\"p-2\"\n >\n {definitionIssues.length > 0 ? (\n <div className=\"px-3 py-2\">\n <IssueList issues={definitionIssues} />\n </div>\n ) : null}\n {fields.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-meta text-muted-foreground\">\n {t('models.builder.noFields')}\n </p>\n ) : (\n <ol className=\"space-y-0.5\" aria-label={count}>\n {fields.map((field, index) => (\n <Row\n key={field.id}\n field={field}\n index={index}\n total={fields.length}\n selected={selection.type === 'field' && selection.fieldId === field.id}\n hasIssues={issuesUnder(issues, fieldPath(index)).length > 0}\n showLocalized={localized}\n dropTarget={dropIndex === index}\n disabled={disabled}\n onSelect={() => select({ type: 'field', fieldId: field.id })}\n onMove={(to) => move(index, to, true)}\n onDragStart={(event) => {\n dragFrom.current = index;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field.id);\n }}\n onDragOver={(event) => {\n if (dragFrom.current !== null) {\n event.preventDefault();\n setDropIndex(index);\n }\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (dragFrom.current !== null) {\n move(dragFrom.current, index, false);\n }\n dragFrom.current = null;\n setDropIndex(null);\n }}\n onDragEnd={() => {\n dragFrom.current = null;\n setDropIndex(null);\n }}\n />\n ))}\n </ol>\n )}\n <p id=\"field-reorder-help\" className=\"sr-only\">\n {t('models.builder.reorderHelp')}\n </p>\n <p aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </Panel>\n );\n};\n","import type { FieldDefinition } from '@shapio/schema';\n\n/** Types stored as JSON strings whose default is typed as text (the validator checks the format). */\nconst TEXT_DEFAULT_TYPES: ReadonlySet<string> = new Set([\n 'string',\n 'text',\n 'slug',\n 'email',\n 'url',\n 'uid',\n 'date',\n 'datetime',\n 'time',\n 'decimal',\n 'biginteger',\n]);\n\n/** Whether the builder offers a default value for this field (single scalar values only). */\nexport const supportsDefaultValue = (field: FieldDefinition) =>\n TEXT_DEFAULT_TYPES.has(field.type) ||\n field.type === 'number' ||\n field.type === 'integer' ||\n field.type === 'boolean' ||\n (field.type === 'enum' && !field.settings.multiple);\n","import type { ValidationIssue } from '@shapio/schema';\nimport { describedBy } from '@/helpers/describedBy';\n\n/** What every builder control takes besides its value: a label, an optional hint and its issues. */\nexport type ControlBaseProps = {\n id: string;\n label: string;\n /** An explanation behind an info icon beside the label (DESIGN.md, helper-text rule). */\n hint?: string;\n /** One visible line under the control, only when it changes what the person does (a warning). */\n description?: string;\n issues?: readonly ValidationIssue[];\n disabled?: boolean;\n};\n\n/** The IDs of a control's hint, description and error elements, and the `aria-describedby` joining them. */\nexport const controlIds = (\n id: string,\n { hint, description, issues = [] }: Pick<ControlBaseProps, 'hint' | 'description' | 'issues'>,\n) => {\n const hintId = hint ? `${id}-hint` : undefined;\n const descriptionId = description ? `${id}-description` : undefined;\n const errorId = issues.length > 0 ? `${id}-error` : undefined;\n return { hintId, descriptionId, errorId, describedBy: describedBy(hintId, descriptionId, errorId) };\n};\n","import { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport { cn } from '@/helpers/cn';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype TextControlProps = ControlBaseProps & {\n value: string | undefined;\n /** Receives `undefined` when the input is emptied and `emptyAsUndefined` is set. */\n onChange: (value: string | undefined) => void;\n emptyAsUndefined?: boolean;\n multiline?: boolean;\n monospace?: boolean;\n maxLength?: number;\n};\n\nexport const TextControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n onChange,\n emptyAsUndefined = false,\n multiline = false,\n monospace = false,\n maxLength,\n}: TextControlProps) => {\n const ids = controlIds(id, { hint, description, issues });\n const shared = {\n id,\n value: value ?? '',\n disabled,\n maxLength,\n 'aria-invalid': issues.length > 0 || undefined,\n 'aria-describedby': ids.describedBy,\n onChange: (event: { target: { value: string } }) =>\n onChange(emptyAsUndefined && event.target.value === '' ? undefined : event.target.value),\n };\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n {multiline ? (\n <Textarea {...shared} rows={2} />\n ) : (\n <Input\n {...shared}\n autoComplete=\"off\"\n spellCheck={!monospace}\n className={cn(monospace && 'font-mono')}\n />\n )}\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import { DATA_TYPES, type DataType as DataTypeName } from '@shapio/schema';\nimport { useId } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { RadioTile } from '@/components/RadioTile';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport { DATA_TYPE_GROUPS, DATA_TYPE_ICONS } from '../../../constants';\n\ntype DataTypeProps = {\n /** The section heading that names the radio group. */\n labelledBy: string;\n value: DataTypeName;\n /** Types shown but not selectable (a saved field can only take the types Shapio can convert it to). */\n unavailable: ReadonlySet<DataTypeName>;\n unavailableReason: (type: DataTypeName) => string;\n /** What saving the chosen type does, one short sentence each. */\n notes: readonly string[];\n /** Why some types aren't offered. */\n limitedNote?: string;\n disabled: boolean;\n onChange: (type: DataTypeName) => void;\n};\n\nconst TYPES = DATA_TYPE_GROUPS.flatMap((group) => group.types);\n\nconst isDataType = (value: string): value is DataTypeName =>\n (DATA_TYPES as readonly string[]).includes(value);\n\n/**\n * Every data type as an icon tile, in group order (text, numbers, choices, dates, structure), six to a row\n * where the panel is wide enough, then the selected type in one line and what changing a saved field's\n * type does. A radio group: Tab enters at the selected type, arrow keys choose another.\n */\nexport const DataType = ({\n labelledBy,\n value,\n unavailable,\n unavailableReason,\n notes,\n limitedNote,\n disabled,\n onChange,\n}: DataTypeProps) => {\n const { t } = useTranslation();\n const descriptionId = useId();\n return (\n <div className=\"@container space-y-3\">\n <RadioGroup\n value={value}\n disabled={disabled}\n onValueChange={(next) => isDataType(next) && onChange(next)}\n aria-labelledby={labelledBy}\n aria-describedby={descriptionId}\n className=\"grid-cols-4 gap-2 @xl:grid-cols-6\"\n >\n {TYPES.map((type) => (\n <RadioTile\n key={type}\n value={type}\n variant=\"tile\"\n icon={DATA_TYPE_ICONS[type]}\n label={t(`models.dataTypes.${type}.name`)}\n disabled={unavailable.has(type)}\n description={\n unavailable.has(type) ? unavailableReason(type) : t(`models.dataTypes.${type}.description`)\n }\n />\n ))}\n </RadioGroup>\n <p id={descriptionId} className=\"text-meta text-muted-foreground\">\n <span className=\"font-semibold text-foreground\">{t(`models.dataTypes.${value}.name`)}</span>\n {' · '}\n {t(`models.dataTypes.${value}.description`)}\n </p>\n {notes.length > 0 ? (\n <p role=\"status\" className=\"text-meta font-medium text-warning\">\n {notes.join(' ')}\n </p>\n ) : null}\n {limitedNote ? <p className=\"text-meta text-muted-foreground\">{limitedNote}</p> : null}\n </div>\n );\n};\n","import { useState } from 'react';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype NumberControlProps = ControlBaseProps & {\n value: number | undefined;\n onChange: (value: number | undefined) => void;\n integer?: boolean;\n min?: number;\n max?: number;\n};\n\nconst parse = (text: string, integer: boolean): number | undefined => {\n if (text.trim() === '') {\n return undefined;\n }\n const parsed = Number(text);\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n return integer ? Math.trunc(parsed) : parsed;\n};\n\n/** A number input whose empty state means \"not set\" (`undefined`). */\nexport const NumberControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n onChange,\n integer = false,\n min,\n max,\n}: NumberControlProps) => {\n // Keep the typed text (e.g. \"1.\" or \"-\") while it is not yet a number.\n const [text, setText] = useState(value === undefined ? '' : String(value));\n const [shownValue, setShownValue] = useState(value);\n // The value changed from outside (reload, discard): show it, unless the text already means it.\n if (value !== shownValue) {\n setShownValue(value);\n if (parse(text, integer) !== value) {\n setText(value === undefined ? '' : String(value));\n }\n }\n const ids = controlIds(id, { hint, description, issues });\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n <Input\n id={id}\n type=\"number\"\n inputMode={integer ? 'numeric' : 'decimal'}\n step={integer ? 1 : 'any'}\n min={min}\n max={max}\n value={text}\n disabled={disabled}\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n onChange={(event) => {\n const next = parse(event.target.value, integer);\n setText(event.target.value);\n setShownValue(next);\n onChange(next);\n }}\n />\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\n/** Radix Select can't hold an empty value; this stands for \"not set\". */\nconst UNSET = '__unset__';\n\ntype SelectControlProps = ControlBaseProps & {\n value: string | undefined;\n options: readonly { value: string; label: string }[];\n onChange: (value: string | undefined) => void;\n /** Label of the \"not set\" choice; when absent, a value must be chosen. */\n unsetLabel?: string;\n placeholder?: string;\n};\n\nexport const SelectControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n options,\n onChange,\n unsetLabel,\n placeholder,\n}: SelectControlProps) => {\n const { t } = useTranslation();\n const ids = controlIds(id, { hint, description, issues });\n const known = value !== undefined && options.some((option) => option.value === value);\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n <Select\n value={known ? value : unsetLabel ? UNSET : ''}\n onValueChange={(next) => onChange(next === UNSET ? undefined : next)}\n disabled={disabled}\n >\n <SelectTrigger\n id={id}\n className=\"w-full\"\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n >\n <SelectValue placeholder={placeholder ?? t('models.choose')} />\n </SelectTrigger>\n <SelectContent>\n {unsetLabel ? <SelectItem value={UNSET}>{unsetLabel}</SelectItem> : null}\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import type { FieldDefinition, JsonValue, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { NumberControl } from '../../controls/NumberControl';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { TextControl } from '../../controls/TextControl';\n\ntype DefaultValueProps = {\n field: FieldDefinition;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (value: JsonValue | undefined) => void;\n};\n\n/** The value new entries start with, also used to fill existing entries when the field becomes required. */\nexport const DefaultValue = ({ field, issues, disabled, onChange }: DefaultValueProps) => {\n const { t } = useTranslation();\n const common = {\n id: `field-${field.id}-default`,\n label: t('models.builder.defaultValue'),\n hint: t('models.builder.defaultValueHint'),\n issues,\n disabled,\n };\n const value = field.defaultValue;\n if (field.type === 'number' || field.type === 'integer') {\n return (\n <NumberControl\n {...common}\n integer={field.type === 'integer'}\n value={typeof value === 'number' ? value : undefined}\n onChange={onChange}\n />\n );\n }\n if (field.type === 'boolean') {\n return (\n <SelectControl\n {...common}\n value={typeof value === 'boolean' ? String(value) : undefined}\n options={[\n { value: 'true', label: t('models.builder.booleanTrue') },\n { value: 'false', label: t('models.builder.booleanFalse') },\n ]}\n unsetLabel={t('models.notSet')}\n onChange={(next) => onChange(next === undefined ? undefined : next === 'true')}\n />\n );\n }\n if (field.type === 'enum') {\n return (\n <SelectControl\n {...common}\n value={typeof value === 'string' ? value : undefined}\n options={field.settings.values\n .filter((entry) => entry.value !== '')\n .map((entry) => ({ value: entry.value, label: entry.label || entry.value }))}\n unsetLabel={t('models.notSet')}\n onChange={onChange}\n />\n );\n }\n return (\n <TextControl\n {...common}\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n emptyAsUndefined\n />\n );\n};\n","/**\n * Turns the JSON Schema of a settings or editor-options object (TypeBox, from @shapio/schema) into form\n * controls, so the builder renders exactly the properties the server validates and never redefines them.\n */\ntype JsonSchema = {\n type?: string;\n enum?: readonly unknown[];\n items?: JsonSchema;\n properties?: Record<string, JsonSchema>;\n required?: readonly string[];\n minimum?: number;\n maximum?: number;\n exclusiveMinimum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n minItems?: number;\n};\n\nexport type PropertyControl =\n | { kind: 'boolean' }\n | { kind: 'integer'; minimum?: number; maximum?: number }\n | { kind: 'number'; minimum?: number }\n | { kind: 'text'; maxLength?: number }\n | { kind: 'choice'; options: string[] }\n | { kind: 'choices'; options: string[] }\n | { kind: 'textList' }\n | { kind: 'other' };\n\nexport type DescribedProperty = { key: string; control: PropertyControl; required: boolean };\n\nconst enumOptions = (schema: JsonSchema | undefined): string[] | undefined =>\n schema?.enum?.every((value) => typeof value === 'string') ? (schema.enum as string[]) : undefined;\n\nexport const describeControl = (schema: JsonSchema): PropertyControl => {\n const options = enumOptions(schema);\n if (options) {\n return { kind: 'choice', options };\n }\n switch (schema.type) {\n case 'boolean':\n return { kind: 'boolean' };\n case 'integer':\n return {\n kind: 'integer',\n ...(schema.minimum !== undefined ? { minimum: schema.minimum } : {}),\n ...(schema.maximum !== undefined ? { maximum: schema.maximum } : {}),\n };\n case 'number':\n return { kind: 'number', ...(schema.minimum !== undefined ? { minimum: schema.minimum } : {}) };\n case 'string':\n return { kind: 'text', ...(schema.maxLength !== undefined ? { maxLength: schema.maxLength } : {}) };\n case 'array': {\n const itemOptions = enumOptions(schema.items);\n if (itemOptions) {\n return { kind: 'choices', options: itemOptions };\n }\n return schema.items?.type === 'string' ? { kind: 'textList' } : { kind: 'other' };\n }\n default:\n return { kind: 'other' };\n }\n};\n\n/** The properties of an object schema, in declaration order. */\nexport const describeProperties = (schema: unknown): DescribedProperty[] => {\n const object = schema as JsonSchema;\n const required = new Set(object.required ?? []);\n return Object.entries(object.properties ?? {}).map(([key, property]) => ({\n key,\n control: describeControl(property),\n required: required.has(key),\n }));\n};\n","import { InfoHint } from '@/components/InfoHint';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Field, FieldDescription, FieldLabel, FieldLegend, FieldSet } from '@/components/ui/field';\nimport { IssueList } from '../IssueList';\nimport type { ControlBaseProps } from '../types';\n\ntype ChoicesControlProps = ControlBaseProps & {\n value: readonly string[];\n options: readonly { value: string; label: string }[];\n onChange: (value: string[]) => void;\n /** Options that can't be toggled (e.g. the last one of a list that may not be empty). */\n locked?: readonly string[];\n};\n\n/** A set of checkboxes; the value keeps the options' order. */\nexport const ChoicesControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n options,\n onChange,\n locked = [],\n}: ChoicesControlProps) => {\n const toggle = (option: string, checked: boolean) => {\n const next = new Set(value);\n if (checked) {\n next.add(option);\n } else {\n next.delete(option);\n }\n onChange(options.map((entry) => entry.value).filter((entry) => next.has(entry)));\n };\n return (\n <FieldSet data-invalid={issues.length > 0 || undefined} className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {label}\n {hint ? <InfoHint about={label}>{hint}</InfoHint> : null}\n </FieldLegend>\n {description ? <FieldDescription>{description}</FieldDescription> : null}\n <div data-slot=\"checkbox-group\" className=\"grid gap-3 @sm/field-group:grid-cols-2\">\n {options.map((option) => {\n const optionId = `${id}-${option.value}`;\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={optionId}\n checked={value.includes(option.value)}\n onCheckedChange={(checked) => toggle(option.value, checked === true)}\n disabled={disabled || locked.includes(option.value)}\n />\n <FieldLabel htmlFor={optionId} className=\"font-normal\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </div>\n <IssueList issues={issues} />\n </FieldSet>\n );\n};\n","import { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldContent, FieldDescription } from '@/components/ui/field';\nimport { Switch } from '@/components/ui/switch';\nimport { cn } from '@/helpers/cn';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype SwitchControlProps = ControlBaseProps & {\n checked: boolean;\n onChange: (checked: boolean) => void;\n /**\n * `row`: label on the left, switch on the right (settings lists). `compact`: switch first, then the\n * label, for the two-column grid of field options.\n */\n layout?: 'row' | 'compact';\n};\n\nexport const SwitchControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n checked,\n onChange,\n layout = 'row',\n}: SwitchControlProps) => {\n const ids = controlIds(id, { hint, description, issues });\n const control = (\n <Switch\n id={id}\n checked={checked}\n onCheckedChange={onChange}\n disabled={disabled}\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n className={cn(layout === 'compact' && 'mt-0.5 self-start')}\n />\n );\n return (\n <Field orientation=\"horizontal\" data-invalid={issues.length > 0 || undefined}>\n {layout === 'compact' ? control : null}\n <FieldContent>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </FieldContent>\n {layout === 'row' ? control : null}\n </Field>\n );\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { propertyLabel, valueLabel } from '../../helpers/labels';\nimport type { DescribedProperty } from '../../helpers/schemaControls';\nimport { ChoicesControl } from '../controls/ChoicesControl';\nimport { NumberControl } from '../controls/NumberControl';\nimport { SelectControl } from '../controls/SelectControl';\nimport { SwitchControl } from '../controls/SwitchControl';\nimport { TextControl } from '../controls/TextControl';\n\ntype PropertyControlProps = {\n idPrefix: string;\n property: DescribedProperty;\n value: unknown;\n onChange: (value: unknown) => void;\n issues: readonly ValidationIssue[];\n /** One visible line under the control: the text format to type. */\n description?: string;\n /** An explanation behind an info icon. */\n hint?: string;\n disabled?: boolean;\n};\n\nconst LIST_SEPARATOR = /\\s*,\\s*/;\n\n/**\n * One property of a settings or editor-options schema, rendered from its JSON Schema description. Labels\n * and choice names come from `models.properties.*` and `models.values.*`.\n */\nexport const PropertyControl = ({\n idPrefix,\n property: { key, control, required },\n value,\n onChange,\n issues,\n description,\n hint,\n disabled,\n}: PropertyControlProps) => {\n const { t } = useTranslation();\n const id = `${idPrefix}-${key}`;\n const label = propertyLabel(key);\n const base = { id, label, issues, disabled, description, hint };\n switch (control.kind) {\n case 'boolean':\n return (\n <SwitchControl\n {...base}\n checked={value === true}\n onChange={(checked) => onChange(checked || undefined)}\n />\n );\n case 'integer':\n case 'number':\n return (\n <NumberControl\n {...base}\n integer={control.kind === 'integer'}\n min={control.minimum}\n max={control.kind === 'integer' ? control.maximum : undefined}\n value={typeof value === 'number' ? value : undefined}\n onChange={onChange}\n />\n );\n case 'choice':\n return (\n <SelectControl\n {...base}\n value={typeof value === 'string' ? value : undefined}\n options={control.options.map((option) => ({ value: option, label: valueLabel(option) }))}\n onChange={onChange}\n {...(required ? {} : { unsetLabel: t('models.notSet') })}\n />\n );\n case 'choices':\n return (\n <ChoicesControl\n {...base}\n value={Array.isArray(value) ? (value as string[]) : []}\n options={control.options.map((option) => ({ value: option, label: valueLabel(option) }))}\n onChange={(next) => onChange(next.length > 0 ? next : undefined)}\n />\n );\n case 'textList':\n return (\n <TextControl\n {...base}\n description={description ?? t('models.commaSeparated')}\n value={Array.isArray(value) ? (value as string[]).join(', ') : ''}\n onChange={(text) => {\n const items = (text ?? '').split(LIST_SEPARATOR).filter(Boolean);\n onChange(items.length > 0 ? items : undefined);\n }}\n />\n );\n case 'text':\n return (\n <TextControl\n {...base}\n maxLength={control.maxLength}\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n emptyAsUndefined={!required}\n />\n );\n default:\n return null;\n }\n};\n","import {\n EDITOR_CATALOGUE,\n isCustomEditorId,\n listCompatibleEditors,\n type FieldDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { withKey } from '../../../helpers/draft';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { editorLabel } from '../../../helpers/labels';\nimport { describeProperties } from '../../../helpers/schemaControls';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { PropertyControl } from '../../PropertyControl';\n\ntype EditorPickerProps = {\n field: FieldDefinition;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (editor: FieldDefinition['editor']) => void;\n};\n\n/**\n * The editor (input control) for a field, from the catalogue's editors compatible with its data type, and\n * that editor's options, rendered from its option schema. Changing it never changes stored data.\n */\nexport const EditorPicker = ({ field, path, issues, disabled, onChange }: EditorPickerProps) => {\n const { t } = useTranslation();\n const { id, options } = field.editor;\n const compatible = listCompatibleEditors(field).map((entry) => entry.id);\n const choices = isCustomEditorId(id) || !compatible.includes(id) ? [...compatible, id] : compatible;\n const entry = EDITOR_CATALOGUE.get(id);\n const properties = entry ? describeProperties(entry.optionsSchema) : [];\n return (\n <>\n <SelectControl\n id={`field-${field.id}-editor`}\n label={t('models.builder.editor')}\n hint={t('models.builder.editorHint')}\n value={id}\n options={choices.map((choice) => ({ value: choice, label: editorLabel(choice) }))}\n onChange={(next) => next && onChange({ id: next, options: {} })}\n issues={issuesUnder(issues, `${path}/editor/id`)}\n disabled={disabled}\n />\n {properties.map((property) => (\n <PropertyControl\n key={`${id}-${property.key}`}\n idPrefix={`field-${field.id}-editor-options`}\n property={property}\n value={options[property.key]}\n onChange={(value) => onChange({ id, options: withKey(options, property.key, value) })}\n issues={issuesUnder(issues, `${path}/editor/options/${property.key}`)}\n disabled={disabled}\n />\n ))}\n </>\n );\n};\n","import {\n SCALAR_DATA_TYPES,\n UNIQUE_CAPABLE_DATA_TYPES,\n type FieldDefinition,\n type SchemaDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { SwitchControl } from '../../controls/SwitchControl';\n\ntype FlagKey = 'required' | 'unique' | 'localized' | 'public' | 'filterable' | 'sortable' | 'deprecated';\n\ntype FlagsProps = {\n field: FieldDefinition;\n draft: SchemaDefinition;\n /** The issues on one of the field's properties. */\n at: (property: string) => readonly ValidationIssue[];\n disabled: boolean;\n onChange: (patch: Partial<Pick<FieldDefinition, FlagKey>>) => void;\n};\n\nconst FLAG_KEYS = {\n required: { label: 'models.builder.required', hint: 'models.builder.requiredHint' },\n unique: { label: 'models.builder.unique', hint: 'models.builder.uniqueHint' },\n localized: { label: 'models.builder.fieldLocalized', hint: 'models.builder.fieldLocalizedHint' },\n public: { label: 'models.builder.public', hint: 'models.builder.publicHint' },\n filterable: { label: 'models.builder.filterable', hint: 'models.builder.indexHint' },\n sortable: { label: 'models.builder.sortable', hint: 'models.builder.indexHint' },\n deprecated: { label: 'models.builder.deprecated', hint: 'models.builder.deprecatedHint' },\n} as const satisfies Record<FlagKey, { label: string; hint: string }>;\n\n/** The on/off options a field of this type supports here (components have no indexes or uniqueness). */\nconst availableFlags = (field: FieldDefinition, draft: SchemaDefinition): FlagKey[] => {\n const isComponent = draft.kind === 'component';\n const modelLocalized = draft.kind !== 'component' && draft.localized;\n const indexable =\n !isComponent && SCALAR_DATA_TYPES.has(field.type) && !(field.type === 'enum' && field.settings.multiple);\n return [\n 'required',\n ...(UNIQUE_CAPABLE_DATA_TYPES.has(field.type) && !isComponent ? (['unique'] as const) : []),\n ...(modelLocalized ? (['localized'] as const) : []),\n 'public',\n ...(indexable ? (['filterable', 'sortable'] as const) : []),\n 'deprecated',\n ];\n};\n\n/** A field's switches, two columns wide: each with its label and an info hint. */\nexport const Flags = ({ field, draft, at, disabled, onChange }: FlagsProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"grid gap-x-6 gap-y-4 @md/field-group:grid-cols-2\">\n {availableFlags(field, draft).map((flag) => (\n <SwitchControl\n key={flag}\n id={`field-${field.id}-${flag}`}\n layout=\"compact\"\n label={t(FLAG_KEYS[flag].label)}\n hint={t(FLAG_KEYS[flag].hint)}\n checked={field[flag]}\n onChange={(checked) => onChange({ [flag]: checked })}\n issues={at(flag)}\n disabled={disabled}\n />\n ))}\n </div>\n );\n};\n","import {\n classifyChange,\n type ClassifiedChange,\n type DataType,\n type FieldDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { withFieldType } from './newField';\n\n/**\n * How the planner would classify changing a saved field to `to` (null for its own type), asked of the\n * same classifier the server uses, on the definition as the change would leave it, so the type grid and\n * the review agree on what is supported, breaking or destructive.\n */\nexport const classifyFieldTypeChange = (\n saved: SchemaDefinition,\n field: FieldDefinition,\n to: DataType,\n): ClassifiedChange | null =>\n field.type === to\n ? null\n : classifyChange(\n { kind: 'field.type', definitionId: saved.id, fieldId: field.id, from: field.type, to },\n { before: saved, after: withFieldType(saved, field.id, to) },\n );\n","import { DATA_TYPES, type DataType, type FieldDefinition, type SchemaDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { classifyFieldTypeChange } from '../../../helpers/typeChange';\n\nconst NO_TYPES: ReadonlySet<DataType> = new Set();\n\n/**\n * The data types a field may take and what changing it means. A new field may take any type. A saved field\n * may take the types the planner can convert it to (its own included), the others are `unavailable`;\n * `notes` says what saving the chosen type does to existing values and the API.\n */\nexport const useTypeChoices = (\n base: SchemaDefinition | null,\n saved: FieldDefinition | undefined,\n type: DataType,\n) => {\n const { t } = useTranslation();\n const unavailable = useMemo(\n () =>\n base && saved\n ? new Set(DATA_TYPES.filter((to) => classifyFieldTypeChange(base, saved, to)?.supported === false))\n : NO_TYPES,\n [base, saved],\n );\n const change = useMemo(\n () => (base && saved ? classifyFieldTypeChange(base, saved, type) : null),\n [base, saved, type],\n );\n const notes: string[] = [];\n if (change?.category === 'conversion') {\n notes.push(t('models.builder.typeConverted'));\n } else if (change?.category === 'validation') {\n notes.push(t('models.builder.typeChecked'));\n }\n if (change?.breaking) {\n notes.push(t('models.builder.typeBreaking'));\n }\n if (change?.destructive) {\n notes.push(t('models.builder.typeDestructive'));\n }\n const from = saved ? t(`models.dataTypes.${saved.type}.name`) : '';\n const limitedNote = unavailable.size > 0 ? t('models.builder.typeLimited', { type: from }) : undefined;\n /** Why a type is unavailable, announced with its tile. */\n const unavailableReason = (to: DataType) =>\n t('models.builder.typeUnsupported', { from, to: t(`models.dataTypes.${to}.name`) });\n return { unavailable, unavailableReason, notes, limitedNote };\n};\n","import type { FieldDefinition, ModelDefinition, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { documentPlacementOf, withDocumentPlacement, type PlacementLock } from '../../../helpers/display';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { SwitchControl } from '../../controls/SwitchControl';\n\ntype PlacementProps = {\n model: ModelDefinition;\n field: FieldDefinition;\n /** All of the draft's issues; the switch shows the ones on this field's `canvasFieldIds` entry. */\n issues: readonly ValidationIssue[];\n disabled: boolean;\n};\n\nconst LOCK_KEYS = {\n title: 'models.builder.placement.lockedTitle',\n cover: 'models.builder.placement.lockedCover',\n last: 'models.builder.placement.lockedLast',\n} as const satisfies Record<PlacementLock, string>;\n\n/**\n * \"Show in document\": a view over `display.canvasFieldIds` for one field. On, the entry document shows the\n * field under its heading among the blocks; off, it is a property in the strip and the Settings panel.\n */\nexport const Placement = ({ model, field, issues, disabled }: PlacementProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const { inDocument, lock } = documentPlacementOf(model, field);\n const index = model.display.canvasFieldIds?.indexOf(field.id) ?? -1;\n return (\n <SwitchControl\n id={`field-${field.id}-in-document`}\n label={t('models.builder.placement.label')}\n hint={t('models.builder.placement.hint')}\n description={lock ? t(LOCK_KEYS[lock]) : undefined}\n issues={index === -1 ? [] : issuesUnder(issues, `/display/canvasFieldIds/${index}`)}\n checked={inDocument}\n disabled={disabled || lock !== undefined}\n onChange={(checked) =>\n update((current) =>\n current.kind === 'component' ? current : withDocumentPlacement(current, field.id, checked),\n )\n }\n />\n );\n};\n","import type { FieldDefinition, ValidationIssue } from '@shapio/schema';\nimport { Plus, Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Button } from '@/components/ui/button';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { IssueList } from '../../controls/IssueList';\n\ntype EnumValue = { value: string; label: string };\n\ntype EnumValuesProps = {\n idPrefix: string;\n field: FieldDefinition<'enum'>;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (values: EnumValue[]) => void;\n};\n\n/** The choices of an enum field: a stable value (a GraphQL name) and a label editors see. */\nexport const EnumValues = ({ idPrefix, field, path, issues, disabled, onChange }: EnumValuesProps) => {\n const { t } = useTranslation();\n const values = field.settings.values;\n const replace = (index: number, patch: Partial<EnumValue>) =>\n onChange(values.map((entry, position) => (position === index ? { ...entry, ...patch } : entry)));\n const listIssues = issues.filter((found) => found.path === path);\n return (\n <FieldSet className=\"gap-3\" data-invalid={listIssues.length > 0 || undefined}>\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {t('models.properties.values')}\n <InfoHint about={t('models.properties.values')}>{t('models.builder.enumValuesHint')}</InfoHint>\n </FieldLegend>\n {values.length > 0 ? (\n <ol className=\"space-y-2\">\n {values.map((entry, index) => {\n const rowIssues = issuesUnder(issues, `${path}/${index}`);\n const valueId = `${idPrefix}-value-${index}`;\n const labelId = `${idPrefix}-label-${index}`;\n return (\n <li key={index} className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <label htmlFor={labelId} className=\"sr-only\">\n {t('models.builder.enumLabel', { position: index + 1 })}\n </label>\n <Input\n id={labelId}\n value={entry.label}\n placeholder={t('models.builder.enumLabelPlaceholder')}\n disabled={disabled}\n onChange={(event) => replace(index, { label: event.target.value })}\n />\n <label htmlFor={valueId} className=\"sr-only\">\n {t('models.builder.enumValue', { position: index + 1 })}\n </label>\n <Input\n id={valueId}\n value={entry.value}\n placeholder={t('models.builder.enumValuePlaceholder')}\n className=\"font-mono\"\n spellCheck={false}\n disabled={disabled}\n aria-invalid={rowIssues.length > 0 || undefined}\n onChange={(event) => replace(index, { value: event.target.value })}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n disabled={disabled}\n aria-label={t('models.builder.enumRemove', { position: index + 1 })}\n onClick={() => onChange(values.filter((_, position) => position !== index))}\n >\n <Trash2 aria-hidden=\"true\" />\n </Button>\n </div>\n <IssueList issues={rowIssues} />\n </li>\n );\n })}\n </ol>\n ) : null}\n <IssueList issues={listIssues} />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-fit\"\n disabled={disabled}\n onClick={() => onChange([...values, { value: '', label: '' }])}\n >\n <Plus aria-hidden=\"true\" />\n {t('models.builder.enumAdd')}\n </Button>\n </FieldSet>\n );\n};\n","import {\n SETTINGS_SCHEMAS,\n type FieldDefinition,\n type SchemaDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useAllDefinitions } from '@/api/schema';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { describeProperties, type DescribedProperty } from '../../../helpers/schemaControls';\nimport { ChoicesControl } from '../../controls/ChoicesControl';\nimport { IssueList } from '../../controls/IssueList';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { PropertyControl } from '../../PropertyControl';\nimport { EnumValues } from '../EnumValues';\n\ntype TypeSettingsProps = {\n field: FieldDefinition;\n draft: SchemaDefinition;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (key: string, value: unknown) => void;\n};\n\n/** Settings managed elsewhere or not user-facing. */\nconst HIDDEN_SETTINGS: ReadonlySet<string> = new Set(['formatVersion']);\n\n/** Types whose bounds are text in a canonical format (ADR 0001); the hint shows the format. */\nconst FORMAT_HINT_KEYS = {\n date: 'models.formats.date',\n datetime: 'models.formats.datetime',\n time: 'models.formats.time',\n decimal: 'models.formats.decimal',\n biginteger: 'models.formats.biginteger',\n} as const;\n\nconst SOURCE_FIELD_TYPES: ReadonlySet<string> = new Set(['string', 'text']);\n\n/**\n * The data type's settings, rendered from `SETTINGS_SCHEMAS[type]` (the schema the server validates), with\n * pickers for the settings that reference other definitions or fields.\n */\nexport const TypeSettings = ({ field, draft, path, issues, disabled, onChange }: TypeSettingsProps) => {\n const { t } = useTranslation();\n const { definitions } = useAllDefinitions();\n const settings = field.settings as Record<string, unknown>;\n const settingsPath = `${path}/settings`;\n const idPrefix = `field-${field.id}-settings`;\n const all = [\n ...(definitions ?? []).map(({ definition }) => definition).filter((entry) => entry.id !== draft.id),\n draft,\n ];\n const models = all.filter((entry) => entry.kind !== 'component');\n const components = all.filter((entry) => entry.kind === 'component' && entry.id !== draft.id);\n const toOption = (entry: SchemaDefinition) => ({ value: entry.id, label: entry.label });\n const at = (key: string) => issuesUnder(issues, `${settingsPath}/${key}`);\n\n const render = (property: DescribedProperty) => {\n const { key } = property;\n const common = { id: `${idPrefix}-${key}`, issues: at(key), disabled };\n if (field.type === 'enum' && key === 'values') {\n return (\n <EnumValues\n key={key}\n idPrefix={common.id}\n field={field}\n path={`${settingsPath}/values`}\n issues={issues}\n disabled={disabled}\n onChange={(values) => onChange('values', values)}\n />\n );\n }\n if (key === 'target') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.target')}\n value={settings.target as string}\n options={models.map(toOption)}\n onChange={(value) => onChange('target', value ?? '')}\n placeholder={t('models.builder.chooseModel')}\n />\n );\n }\n if (key === 'component') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.component')}\n value={settings.component as string}\n options={components.map(toOption)}\n onChange={(value) => onChange('component', value ?? '')}\n placeholder={t('models.builder.chooseComponent')}\n {...(components.length === 0 ? { description: t('models.builder.noComponents') } : {})}\n />\n );\n }\n if (key === 'components') {\n return (\n <ChoicesControl\n key={key}\n {...common}\n label={t('models.properties.components')}\n value={(settings.components as string[] | undefined) ?? []}\n options={components.map(toOption)}\n onChange={(value) => onChange('components', value)}\n {...(components.length === 0 ? { description: t('models.builder.noComponents') } : {})}\n />\n );\n }\n if (key === 'sourceFieldId') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.sourceFieldId')}\n hint={t('models.builder.sourceFieldHint')}\n value={settings.sourceFieldId as string | undefined}\n options={draft.fields\n .filter((candidate) => candidate.id !== field.id && SOURCE_FIELD_TYPES.has(candidate.type))\n .map((candidate) => ({ value: candidate.id, label: candidate.label }))}\n onChange={(value) => onChange('sourceFieldId', value)}\n unsetLabel={t('models.notSet')}\n />\n );\n }\n const formatKey =\n property.control.kind === 'text' && field.type in FORMAT_HINT_KEYS\n ? FORMAT_HINT_KEYS[field.type as keyof typeof FORMAT_HINT_KEYS]\n : undefined;\n return (\n <PropertyControl\n key={key}\n idPrefix={idPrefix}\n property={property}\n value={settings[key]}\n onChange={(value) => onChange(key, value)}\n issues={common.issues}\n disabled={disabled}\n description={formatKey === undefined ? undefined : t(formatKey)}\n hint={key === 'pattern' ? t('models.builder.patternHint') : undefined}\n />\n );\n };\n\n const properties = describeProperties(SETTINGS_SCHEMAS[field.type]).filter(\n (property) => !HIDDEN_SETTINGS.has(property.key),\n );\n const rendered = new Set(properties.map((property) => property.key));\n const otherIssues = issuesUnder(issues, settingsPath).filter(\n (found) => !rendered.has(found.path.slice(settingsPath.length + 1).split('/')[0] ?? ''),\n );\n if (properties.length === 0) {\n return <p className=\"text-meta text-muted-foreground\">{t('models.builder.noSettings')}</p>;\n }\n return (\n <>\n {properties.map(render)}\n <IssueList issues={otherIssues} />\n </>\n );\n};\n","import { type FieldDefinition, type ValidationIssue } from '@shapio/schema';\nimport { Trash2 } from 'lucide-react';\nimport type { KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { IconTile } from '@/components/IconTile';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { DATA_TYPE_ICONS } from '../../constants';\nimport { supportsDefaultValue } from '../../helpers/defaultValue';\nimport { deriveApiKey } from '../../helpers/deriveApiKey';\nimport { pruneLayout, removeField, withCompatibleEditor, withSetting } from '../../helpers/draft';\nimport { fieldPath, issuesUnder } from '../../helpers/issues';\nimport { withFieldTypeOrSaved } from '../../helpers/newField';\nimport { IssueList } from '../controls/IssueList';\nimport { TextControl } from '../controls/TextControl';\nimport { labelInputIdOf } from '../hooks/useNewField';\nimport { PanelSection } from '../PanelSection';\nimport { DataType } from './DataType';\nimport { DefaultValue } from './DefaultValue';\nimport { EditorPicker } from './EditorPicker';\nimport { Flags } from './Flags';\nimport { useTypeChoices } from './hooks/useTypeChoices';\nimport { Placement } from './Placement';\nimport { TypeSettings } from './TypeSettings';\n\ntype FieldPanelProps = {\n field: FieldDefinition;\n index: number;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** The field was just added and is still untouched: Escape discards it. */\n untouched: boolean;\n onDiscard: () => void;\n};\n\n/** Field properties that have their own control; issues anywhere else are listed at the top. */\nconst CONTROLLED = new Set([\n 'label',\n 'apiKey',\n 'description',\n 'required',\n 'unique',\n 'filterable',\n 'sortable',\n 'public',\n 'localized',\n 'deprecated',\n 'defaultValue',\n 'editor',\n 'settings',\n]);\n\n/**\n * Everything about one field: data type, naming, options, type settings and editor. A field that isn't\n * saved yet can take any type and its API ID follows its label until edited; a saved one can change to the\n * types Shapio can convert it to.\n */\nexport const FieldPanel = ({ field, index, issues, disabled, untouched, onDiscard }: FieldPanelProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const updateField = useDefinitionDraftStore((state) => state.updateField);\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const saved = base?.fields.find((candidate) => candidate.id === field.id);\n const typeChoices = useTypeChoices(base, saved, field.type);\n if (!draft) {\n return null;\n }\n const path = fieldPath(index);\n const at = (property: string) => issuesUnder(issues, `${path}/${property}`);\n const otherIssues = issuesUnder(issues, path).filter(\n (found) => !CONTROLLED.has(found.path.slice(path.length + 1).split('/')[0] ?? ''),\n );\n const set = (patch: Partial<FieldDefinition>) =>\n updateField(field.id, (current) => ({ ...current, ...patch }) as FieldDefinition);\n const id = (name: string) => `field-${field.id}-${name}`;\n const renamed = saved !== undefined && saved.apiKey !== field.apiKey;\n const isNew = base !== null && saved === undefined;\n const label = field.label || t('models.builder.untitled');\n const setLabel = (next: string) => {\n const followsLabel = isNew && field.apiKey === deriveApiKey(field.label);\n set({ label: next, ...(followsLabel ? { apiKey: deriveApiKey(next) } : {}) });\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n // Escape in something the panel opened (a select, an info popover) is that layer's to handle.\n if (event.key !== 'Escape' || event.nativeEvent.defaultPrevented || !untouched) {\n return;\n }\n if (event.target instanceof Node && event.currentTarget.contains(event.target)) {\n event.preventDefault();\n onDiscard();\n }\n };\n\n return (\n // Keyboard handling only: Escape discards an untouched new field (focus is on a control inside).\n <div onKeyDown={onKeyDown}>\n <Panel aria-label={t('models.builder.fieldProperties', { label })} flush>\n <div className=\"flex flex-wrap items-center gap-3 border-b px-5 py-4\">\n <IconTile icon={DATA_TYPE_ICONS[field.type]} />\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-x-2.5 gap-y-1\">\n <h2 className=\"min-w-0 truncate text-base font-semibold\">{label}</h2>\n <Badge variant=\"secondary\">{t(`models.dataTypes.${field.type}.name`)}</Badge>\n </div>\n <Button\n type=\"button\"\n variant=\"destructive-ghost\"\n size=\"sm\"\n disabled={disabled}\n onClick={() => {\n update((current) => removeField(current, field.id));\n select({ type: 'definition' });\n }}\n >\n <Trash2 aria-hidden=\"true\" />\n {t('models.builder.removeField')}\n </Button>\n </div>\n <div className=\"space-y-5 p-5\">\n <IssueList issues={otherIssues} />\n\n <PanelSection title={t('models.builder.dataType')} titleId={id('type-heading')}>\n <DataType\n labelledBy={id('type-heading')}\n value={field.type}\n {...typeChoices}\n disabled={disabled}\n onChange={(type) =>\n update((current) => pruneLayout(withFieldTypeOrSaved(current, field.id, type, saved)))\n }\n />\n </PanelSection>\n\n <PanelSection title={t('models.builder.general')}>\n <div className=\"grid items-start gap-5 @lg/field-group:grid-cols-2\">\n <TextControl\n id={labelInputIdOf(field.id)}\n label={t('models.label')}\n value={field.label}\n onChange={(next) => setLabel(next ?? '')}\n issues={at('label')}\n disabled={disabled}\n />\n <TextControl\n id={id('apiKey')}\n label={t('models.apiKey')}\n hint={t('models.fieldApiKeyHint')}\n description={renamed ? t('models.builder.apiKeyRenameWarning') : undefined}\n value={field.apiKey}\n onChange={(apiKey) => set({ apiKey: apiKey ?? '' })}\n issues={at('apiKey')}\n disabled={disabled}\n monospace\n />\n </div>\n <TextControl\n id={id('description')}\n label={t('models.builder.helpText')}\n value={field.description}\n onChange={(description) => set({ description })}\n issues={at('description')}\n disabled={disabled}\n emptyAsUndefined\n multiline\n />\n {draft.kind !== 'component' && !field.deprecated ? (\n <Placement model={draft} field={field} issues={issues} disabled={disabled} />\n ) : null}\n </PanelSection>\n\n <PanelSection title={t('models.builder.options')}>\n <Flags field={field} draft={draft} at={at} disabled={disabled} onChange={set} />\n </PanelSection>\n\n <PanelSection title={t('models.builder.settings')}>\n <TypeSettings\n field={field}\n draft={draft}\n path={path}\n issues={issues}\n disabled={disabled}\n onChange={(key, value) =>\n update((current) =>\n pruneLayout({\n ...current,\n fields: current.fields.map((candidate) =>\n candidate.id === field.id\n ? withCompatibleEditor(withSetting(candidate, key, value))\n : candidate,\n ),\n }),\n )\n }\n />\n {supportsDefaultValue(field) ? (\n <DefaultValue\n field={field}\n issues={at('defaultValue')}\n disabled={disabled}\n onChange={(defaultValue) =>\n updateField(field.id, (current) => {\n const next: Record<string, unknown> = { ...current, defaultValue };\n if (defaultValue === undefined) {\n delete next.defaultValue;\n }\n return next as FieldDefinition;\n })\n }\n />\n ) : null}\n </PanelSection>\n\n <PanelSection title={t('models.builder.editorSection')}>\n <EditorPicker\n field={field}\n path={path}\n issues={issues}\n disabled={disabled}\n onChange={(editor) => set({ editor })}\n />\n </PanelSection>\n </div>\n </Panel>\n </div>\n );\n};\n","import { routeKeyOf, type SchemaDefinition } from '@shapio/schema';\nimport { linkOptions, useParams } from '@tanstack/react-router';\nimport { MoreHorizontal, Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { PageHeader } from '@/components/PageHeader';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { SaveActions, type SaveActionsProps } from '../SaveActions';\n\ntype HeaderProps = SaveActionsProps & {\n draft: SchemaDefinition;\n version: number;\n dirty: boolean;\n issueCount: number;\n /** Deleting is not possible right now (locked, a change running). */\n deleteBlocked: boolean;\n onDelete: () => void;\n};\n\n/** Breadcrumb, title with the draft's state, API IDs and version, and the save actions (xl and up). */\nexport const Header = ({\n draft,\n version,\n dirty,\n issueCount,\n deleteBlocked,\n onDelete,\n ...saveActions\n}: HeaderProps) => {\n const { t } = useTranslation();\n // The place this builder is the Structure tab of (its saved API ID, from the URL), or Components.\n const { modelKey = draft.apiKey } = useParams({ strict: false });\n const breadcrumb =\n draft.kind === 'component'\n ? [{ label: t('shell.nav.components'), link: linkOptions({ to: '/develop/components' }) }]\n : [\n { label: draft.label, link: linkOptions({ to: '/content/$modelKey', params: { modelKey } }) },\n { label: t('place.tabs.structure') },\n ];\n return (\n <PageHeader\n sticky\n breadcrumb={breadcrumb}\n title={draft.label || t('models.builder.untitled')}\n badge={\n dirty || issueCount > 0 ? (\n <span className=\"flex flex-wrap items-center gap-2\">\n {dirty ? <StatusChip tone=\"warning\" label={t('models.builder.unsaved')} /> : null}\n {issueCount > 0 ? (\n <StatusChip tone=\"danger\" label={t('models.builder.problems', { count: issueCount })} />\n ) : null}\n </span>\n ) : null\n }\n meta={\n draft.kind === 'collection'\n ? t('models.builder.subtitleCollection', {\n apiKey: draft.apiKey,\n pluralApiKey: routeKeyOf(draft),\n version,\n })\n : t('models.builder.subtitle', { apiKey: draft.apiKey, version })\n }\n actions={\n <>\n <div className=\"hidden items-center gap-2 xl:flex\">\n <SaveActions {...saveActions} />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={t('models.builder.more')}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem variant=\"destructive\" disabled={deleteBlocked} onSelect={onDelete}>\n <Trash2 aria-hidden=\"true\" />\n {t('models.builder.delete')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n }\n />\n );\n};\n","import { SEO_COMPONENT_ID, SEO_EDITOR_ID, type SchemaDefinition } from '@shapio/schema';\nimport { createField } from './draft';\nimport { uniqueNewFieldName } from './newField';\n\n/**\n * The SEO field's label as stored in the schema (data, like the component's own label): its API ID derives\n * from it (`seo`, then `seo2`...), and must not change with the admin's language.\n */\nconst SEO_FIELD_LABEL = 'SEO';\n\n/** Whether the definition already has a field holding the SEO component (by stable ID, never API ID). */\nexport const hasSeoField = (definition: SchemaDefinition): boolean =>\n definition.fields.some(\n (field) => field.type === 'component' && field.settings.component === SEO_COMPONENT_ID,\n );\n\n/**\n * A single (non-repeatable) field holding the shared SEO component, with the SEO editor, localized when the\n * model is (the person can still change that in the field's properties).\n */\nexport const createSeoField = (definition: SchemaDefinition) =>\n createField(definition, {\n type: 'component',\n ...uniqueNewFieldName(definition, SEO_FIELD_LABEL),\n settings: { component: SEO_COMPONENT_ID, repeatable: false },\n editorId: SEO_EDITOR_ID,\n localized: definition.kind !== 'component' && definition.localized,\n });\n","import { SEO_COMPONENT_ID } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useDefinitions } from '@/api/schema';\nimport { seoConflictOf, useEnsureSeoComponent } from '@/api/seo';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { withAddedField } from '../../helpers/display';\nimport { createSeoField, hasSeoField } from '../../helpers/seoField';\nimport { labelInputIdOf } from './useNewField';\n\n/**\n * What \"SEO fields\" can do for this draft:\n * - `ready`: the shared SEO component exists, the field is added at once;\n * - `enable`: it doesn't, and this admin may create it for every site (asks first);\n * - `askAdmin`: it doesn't, and only a network admin can create it;\n * - `present`: the draft already holds the SEO component;\n * - `loading`: the site's components aren't known yet.\n */\nexport type SeoFieldAvailability = 'ready' | 'enable' | 'askAdmin' | 'present' | 'loading';\n\n/**\n * \"Add field → SEO fields\" (plan seo-fields): adds a field holding the shared SEO component to the draft,\n * creating the component first when this admin may (network `schema.create`). The field then goes through\n * the normal review like any other; nothing else is saved here except the component itself.\n */\nexport const useAddSeoField = () => {\n const { t } = useTranslation();\n const components = useDefinitions('component');\n const { canShare } = useSchemaScopeAccess();\n const present = useDefinitionDraftStore((state) => (state.draft ? hasSeoField(state.draft) : false));\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const ensure = useEnsureSeoComponent();\n\n const exists = components.data?.some((item) => item.definition.id === SEO_COMPONENT_ID);\n const availability: SeoFieldAvailability = present\n ? 'present'\n : exists === undefined\n ? 'loading'\n : exists\n ? 'ready'\n : canShare\n ? 'enable'\n : 'askAdmin';\n\n const add = () => {\n const { draft } = useDefinitionDraftStore.getState();\n if (!draft || hasSeoField(draft)) {\n return;\n }\n const field = createSeoField(draft);\n update((current) => withAddedField(current, field));\n select({ type: 'field', fieldId: field.id });\n requestAnimationFrame(() => {\n document.getElementById(labelInputIdOf(field.id))?.scrollIntoView({ block: 'center' });\n });\n toast.success(t('seo.builder.added'));\n };\n\n /** Creates the shared component, then adds the field. Failures are toasted (the conflict names the culprit). */\n const enableAndAdd = async () => {\n try {\n await ensure.mutateAsync();\n } catch (error) {\n logError(error, 'enabling the SEO component');\n const conflict = seoConflictOf(error);\n toast.error(\n conflict\n ? t('seo.builder.conflict', { label: conflict.label, apiKey: conflict.apiKey })\n : describeError(error),\n );\n return;\n }\n add();\n };\n\n return { availability, add, enableAndAdd, enabling: ensure.isPending };\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { useDeferredValue, useMemo } from 'react';\nimport { useAllDefinitions } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { validateDraft } from '../../helpers/issues';\n\nconst NO_ISSUES: readonly ValidationIssue[] = [];\n\n/** The draft's validation problems (the server's own validators, run in the browser while typing). */\nexport const useDraftIssues = () => {\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const { definitions } = useAllDefinitions();\n // Validation runs over the whole schema; let typing stay responsive while it catches up.\n const deferredDraft = useDeferredValue(draft);\n const issues = useMemo(\n () =>\n deferredDraft && base\n ? validateDraft(\n deferredDraft,\n base,\n (definitions ?? []).map(({ definition }) => definition),\n )\n : NO_ISSUES,\n [deferredDraft, base, definitions],\n );\n return { issues };\n};\n","import { useMemo } from 'react';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { isDraftDirty } from '../../helpers/draft';\n\n/** Whether the draft differs from the active definition it is based on. */\nexport const useIsDraftDirty = () => {\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n return useMemo(() => Boolean(draft && base && isDraftDirty(draft, base)), [draft, base]);\n};\n","import { useSchemaSummary } from '@/api/schema';\n\n/**\n * Whether another session activated a newer version of this definition than the one the draft is based\n * on. The summary is polled (there is no push channel), so this shows within a few seconds. Changes this\n * session is applying itself are ignored while they run.\n */\nexport const useRemoteChangeNotice = (id: string, baseVersion: number, ownChangeRunning: boolean) => {\n const summary = useSchemaSummary();\n const remote = summary.data?.definitions.find((definition) => definition.id === id);\n const changedElsewhere = !ownChangeRunning && remote !== undefined && remote.version > baseVersion;\n return { changedElsewhere, remoteVersion: remote?.version };\n};\n","import type { Acknowledgement, DefinitionCategory, PlanPreview } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useShipDraftNow } from '@/api/changeSets';\nimport { hasErrorCode } from '@/api/errors';\nimport { definitionQueryOptions, usePlanChange } from '@/api/schema';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport type { useReloadDraft } from './useReloadDraft';\n\ntype ReloadDraft = ReturnType<typeof useReloadDraft>;\n\nexport type SaveFlowState =\n { step: 'idle' } | { step: 'review'; preview: PlanPreview } | { step: 'conflict' };\n\nconst isVersionConflict = (error: unknown) => hasErrorCode(error, 'SCHEMA_VERSION_CONFLICT');\n\n/**\n * Saving a model (brief §5, plan developer-face §5): plan the draft against the version it was based on,\n * show the impact, then ship it as a one-item change set with the acknowledgements the plan needs (or put\n * it in a change set from the review sheet). A stale version at either step shows the conflict banner;\n * changes with prerequisites ship in the background and show as the definition's pending change.\n */\nexport const useSaveFlow = (category: DefinitionCategory, id: string, reloadDraft: ReloadDraft) => {\n const { t } = useTranslation();\n const plan = usePlanChange();\n const queryClient = useQueryClient();\n const apply = useShipDraftNow();\n const [state, setState] = useState<SaveFlowState>({ step: 'idle' });\n /** A change this session started that is still running its prerequisites. */\n const [runningChangeId, setRunningChangeId] = useState<string | undefined>(undefined);\n\n const notifyFailure = (error: unknown) => {\n if (isVersionConflict(error)) {\n setState({ step: 'conflict' });\n return;\n }\n toast.error(describeError(error));\n };\n\n const finishSuccessfully = async () => {\n toast.success(t('models.updated'));\n try {\n // Rebase rather than replace: edits made while a change was running are kept on the new version.\n await reloadDraft('rebase');\n } catch (error) {\n logError(error, 'reloading the definition after a schema change');\n toast.error(describeError(error));\n }\n };\n\n const review = async () => {\n const { draft, baseVersion } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n apply.reset();\n try {\n const preview = await plan.mutateAsync({\n category,\n id,\n definition: draft,\n expectedVersion: baseVersion,\n });\n setState({ step: 'review', preview });\n } catch (error) {\n notifyFailure(error);\n }\n };\n\n const confirm = async (acknowledgement: Acknowledgement) => {\n const { draft, baseVersion } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n try {\n const set = await apply.mutateAsync({\n definitionId: id,\n input: { category, definition: draft, baseVersion },\n acknowledgement,\n title: t('changes.builderSetTitle', { label: draft.label }),\n });\n setState({ step: 'idle' });\n if (set.status === 'shipping') {\n // Prerequisites run first; the definition's pending change tracks them (ChangeProgress).\n const detail = await queryClient.fetchQuery(definitionQueryOptions(category, id));\n setRunningChangeId(detail.pendingChange?.id);\n toast.info(t('models.builder.changeStarted'));\n } else {\n await finishSuccessfully();\n }\n } catch (error) {\n // Anything but a stale version stays in the review sheet, which shows the error.\n if (isVersionConflict(error)) {\n setState({ step: 'conflict' });\n }\n }\n };\n\n /** The running change ended: reload on success; keep showing a failure until it is dismissed. */\n const onChangeFinished = async (status: string) => {\n if (status === 'activated') {\n setRunningChangeId(undefined);\n await finishSuccessfully();\n }\n };\n\n return {\n state,\n review,\n reviewing: plan.isPending,\n confirm,\n applying: apply.isPending,\n applyError: apply.error,\n /** Leave the review or the conflict without doing anything. */\n resetStep: () => setState({ step: 'idle' }),\n runningChangeId,\n dismissChange: () => setRunningChangeId(undefined),\n onChangeFinished,\n };\n};\n","import { useDefinitionDraftStore } from '@/stores/definitionDraft';\n\n/** The field open in the settings panel and its position, or nothing when the definition is selected. */\nexport const useSelectedField = () => {\n const selection = useDefinitionDraftStore((state) => state.selection);\n const fields = useDefinitionDraftStore((state) => state.draft?.fields);\n if (selection.type !== 'field' || !fields) {\n return { field: undefined, index: -1 };\n }\n const index = fields.findIndex((candidate) => candidate.id === selection.fieldId);\n return { field: fields[index], index };\n};\n","import type { ModelDefinition, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { documentLayoutChoices } from '../../../../helpers/display';\nimport { pruneLayout, withKey } from '../../../../helpers/draft';\nimport { issuesUnder } from '../../../../helpers/issues';\nimport { ChoicesControl } from '../../../controls/ChoicesControl';\nimport { SelectControl } from '../../../controls/SelectControl';\n\ntype DocumentLayoutProps = { model: ModelDefinition; issues: readonly ValidationIssue[]; disabled: boolean };\n\nconst option = (field: { id: string; label: string }) => ({ value: field.id, label: field.label });\n\n/**\n * How an entry opens as a document (`effectiveLayout`): the cover image, the fields written in the canvas,\n * and the properties shown as chips. Unset keys follow the defaults, so new fields join automatically.\n */\nexport const DocumentLayout = ({ model, issues, disabled }: DocumentLayoutProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const setDisplay = (key: string, value: unknown) =>\n update((draft) => pruneLayout({ ...draft, display: withKey(draft.display, key, value) }));\n const at = (key: string) => issuesUnder(issues, `/display/${key}`);\n const choices = documentLayoutChoices(model);\n return (\n <>\n {choices.coverOptions.length > 0 ? (\n <SelectControl\n id=\"definition-cover-field\"\n label={t('models.builder.coverField')}\n hint={t('models.builder.coverFieldHint')}\n value={model.display.coverFieldId}\n options={choices.coverOptions.map(option)}\n onChange={(value) => setDisplay('coverFieldId', value)}\n unsetLabel={t('models.builder.automatic')}\n issues={at('coverFieldId')}\n disabled={disabled}\n />\n ) : null}\n {choices.canvasOptions.length > 0 ? (\n <ChoicesControl\n id=\"definition-canvas-fields\"\n label={t('models.builder.canvasFields')}\n hint={t('models.builder.canvasFieldsHint')}\n value={choices.canvas}\n options={choices.canvasOptions.map(option)}\n // An empty list means \"the defaults\", so the last block can't be unticked.\n locked={choices.canvas.length === 1 ? choices.canvas : []}\n onChange={(ids) => setDisplay('canvasFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('canvasFieldIds')}\n disabled={disabled}\n />\n ) : null}\n {choices.stripOptions.length > 0 ? (\n <ChoicesControl\n id=\"definition-strip-fields\"\n label={t('models.builder.stripFields')}\n hint={t('models.builder.stripFieldsHint')}\n value={model.display.stripFieldIds ?? []}\n options={choices.stripOptions.map(option)}\n onChange={(ids) => setDisplay('stripFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('stripFieldIds')}\n disabled={disabled}\n />\n ) : null}\n </>\n );\n};\n","import { SORT_DIRECTIONS, type SchemaDefinition, type ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { titleFieldCandidates } from '../../../helpers/display';\nimport { pruneLayout, withKey } from '../../../helpers/draft';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { ChoicesControl } from '../../controls/ChoicesControl';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { DocumentLayout } from './DocumentLayout';\n\ntype DisplayProps = { definition: SchemaDefinition; issues: readonly ValidationIssue[]; disabled: boolean };\n\nconst DIRECTION_LABEL_KEYS = {\n asc: 'models.builder.sortAscending',\n desc: 'models.builder.sortDescending',\n} as const;\n\n/** How entries are labelled, listed and laid out: title, order, list columns and the entry document. */\nexport const Display = ({ definition, issues, disabled }: DisplayProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const setDisplay = (key: string, value: unknown) =>\n update((draft) => pruneLayout({ ...draft, display: withKey(draft.display, key, value) }));\n const at = (key: string) => issuesUnder(issues, `/display/${key}`);\n const option = (field: { id: string; label: string }) => ({ value: field.id, label: field.label });\n const { display } = definition;\n const titleField = (\n <SelectControl\n id=\"definition-title-field\"\n label={t('models.builder.titleField')}\n hint={t('models.builder.titleFieldHint')}\n value={display.titleFieldId}\n options={titleFieldCandidates(definition).map(option)}\n onChange={(value) => setDisplay('titleFieldId', value)}\n unsetLabel={t('models.notSet')}\n issues={at('titleFieldId')}\n disabled={disabled}\n />\n );\n if (definition.kind === 'component') {\n return titleField;\n }\n const sort = definition.display.defaultSort;\n const sortable = definition.fields.filter((field) => field.sortable);\n return (\n <>\n {titleField}\n <SelectControl\n id=\"definition-sort-field\"\n label={t('models.builder.sortField')}\n hint={t('models.builder.sortFieldHint')}\n value={sort?.fieldId}\n options={sortable.map(option)}\n onChange={(fieldId) =>\n setDisplay('defaultSort', fieldId ? { fieldId, direction: sort?.direction ?? 'asc' } : undefined)\n }\n unsetLabel={t('models.builder.sortNewest')}\n issues={at('defaultSort')}\n disabled={disabled}\n />\n {sort ? (\n <SelectControl\n id=\"definition-sort-direction\"\n label={t('models.builder.sortDirection')}\n value={sort.direction}\n options={SORT_DIRECTIONS.map((direction) => ({\n value: direction,\n label: t(DIRECTION_LABEL_KEYS[direction]),\n }))}\n onChange={(direction) => direction && setDisplay('defaultSort', { ...sort, direction })}\n disabled={disabled}\n />\n ) : null}\n <ChoicesControl\n id=\"definition-list-fields\"\n label={t('models.builder.listColumns')}\n value={definition.display.listFieldIds ?? []}\n options={definition.fields.map(option)}\n onChange={(ids) => setDisplay('listFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('listFieldIds')}\n disabled={disabled}\n />\n <DocumentLayout model={definition} issues={issues} disabled={disabled} />\n </>\n );\n};\n","import { routeKeyOf, type ValidationIssue } from '@shapio/schema';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { followPlural } from '../../helpers/followPlural';\nimport { issuesUnder } from '../../helpers/issues';\nimport { SwitchControl } from '../controls/SwitchControl';\nimport { TextControl } from '../controls/TextControl';\nimport { PanelSection } from '../PanelSection';\nimport { Display } from './Display';\n\ntype DefinitionPanelProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** Where the definition is available (the `Scope` section), first; absent on a single-site instance. */\n scopeSection?: ReactNode;\n};\n\n/** The definition's own settings (the expanded Model settings panel): naming, content and display. */\nexport const DefinitionPanel = ({ issues, disabled, scopeSection }: DefinitionPanelProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const update = useDefinitionDraftStore((state) => state.update);\n if (!draft) {\n return null;\n }\n const set = (patch: Record<string, unknown>) => update((current) => ({ ...current, ...patch }));\n const at = (property: string) => issuesUnder(issues, `/${property}`);\n const renamed = base !== null && base.apiKey !== draft.apiKey;\n const pluralRenamed =\n base?.kind === 'collection' && draft.kind === 'collection' && routeKeyOf(base) !== routeKeyOf(draft);\n // A collection's plural follows the API ID until it has been edited by hand (decision 8).\n const setApiKey = (apiKey: string) =>\n update((current) =>\n current.kind === 'collection'\n ? { ...current, apiKey, pluralApiKey: followPlural(current.apiKey, apiKey, current.pluralApiKey) }\n : { ...current, apiKey },\n );\n return (\n <div className=\"space-y-6\">\n {scopeSection}\n <PanelSection title={t('models.builder.general')}>\n <TextControl\n id=\"definition-label\"\n label={t('models.label')}\n value={draft.label}\n onChange={(label) => set({ label: label ?? '' })}\n issues={at('label')}\n disabled={disabled}\n />\n <TextControl\n id=\"definition-apiKey\"\n label={t('models.apiKey')}\n hint={t('models.apiKeyHint')}\n description={renamed ? t('models.builder.apiKeyRenameWarning') : undefined}\n value={draft.apiKey}\n onChange={(apiKey) => setApiKey(apiKey ?? '')}\n issues={at('apiKey')}\n disabled={disabled}\n monospace\n />\n {draft.kind === 'collection' ? (\n <TextControl\n id=\"definition-pluralApiKey\"\n label={t('models.pluralApiKey')}\n hint={t('models.pluralApiKeyHint')}\n description={pluralRenamed ? t('models.builder.pluralApiKeyRenameWarning') : undefined}\n value={draft.pluralApiKey}\n onChange={(pluralApiKey) => set({ pluralApiKey })}\n issues={at('pluralApiKey')}\n disabled={disabled}\n emptyAsUndefined\n monospace\n />\n ) : null}\n <TextControl\n id=\"definition-description\"\n label={t('models.descriptionLabel')}\n value={draft.description}\n onChange={(description) => set({ description })}\n issues={at('description')}\n disabled={disabled}\n emptyAsUndefined\n multiline\n />\n {draft.kind === 'component' ? (\n <TextControl\n id=\"definition-category\"\n label={t('models.builder.category')}\n hint={t('models.builder.categoryHint')}\n value={draft.category}\n onChange={(category) => set({ category })}\n issues={at('category')}\n disabled={disabled}\n emptyAsUndefined\n />\n ) : null}\n </PanelSection>\n {draft.kind === 'component' ? null : (\n <PanelSection title={t('models.builder.content')}>\n <SwitchControl\n id=\"definition-localized\"\n label={t('models.localized')}\n hint={t('models.builder.modelLocalizedHint')}\n checked={draft.localized}\n onChange={(localized) => set({ localized })}\n issues={at('localized')}\n disabled={disabled}\n />\n <SwitchControl\n id=\"definition-draftAndPublish\"\n label={t('models.builder.draftAndPublish')}\n hint={t('models.builder.draftAndPublishHint')}\n checked={draft.draftAndPublish}\n onChange={(draftAndPublish) => set({ draftAndPublish })}\n issues={at('draftAndPublish')}\n disabled={disabled}\n />\n </PanelSection>\n )}\n <PanelSection title={t('models.builder.display')}>\n <Display definition={draft} issues={issues} disabled={disabled} />\n </PanelSection>\n </div>\n );\n};\n","import { routeKeyOf } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { KIND_ICONS, KIND_LABEL_KEYS } from '../../../constants';\n\ntype SummaryProps = { hasIssues: boolean };\n\n/** The collapsed Model settings: kind, localization, drafts and the plural API ID, in one row. */\nexport const Summary = ({ hasIssues }: SummaryProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n if (!draft) {\n return null;\n }\n const KindIcon = KIND_ICONS[draft.kind];\n return (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Badge variant=\"outline\">\n <KindIcon aria-hidden=\"true\" />\n {t(KIND_LABEL_KEYS[draft.kind])}\n </Badge>\n {draft.kind === 'component' ? null : (\n <>\n <Badge variant=\"outline\">\n {t(draft.localized ? 'models.builder.summaryLocalized' : 'models.builder.summaryNotLocalized')}\n </Badge>\n <Badge variant=\"outline\">\n {t(draft.draftAndPublish ? 'models.builder.summaryDrafts' : 'models.builder.summaryNoDrafts')}\n </Badge>\n </>\n )}\n {draft.kind === 'collection' ? (\n <Badge variant=\"outline\" className=\"font-mono font-medium\">\n <span className=\"sr-only\">{t('models.pluralApiKey')} </span>\n {routeKeyOf(draft)}\n </Badge>\n ) : null}\n {hasIssues ? <StatusChip tone=\"danger\" size=\"sm\" label={t('models.builder.hasProblems')} /> : null}\n </div>\n );\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { ChevronDown } from 'lucide-react';\nimport { useId, useState, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\nimport { DefinitionPanel } from '../DefinitionPanel';\nimport { Summary } from './Summary';\n\ntype ModelSettingsProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** Passed to `DefinitionPanel`. */\n scopeSection?: ReactNode;\n};\n\n/** Issues about the definition itself, not one of its fields (those show on the field). */\nconst isDefinitionIssue = (issue: ValidationIssue) => !/^\\/fields(\\/|$)/.test(issue.path);\n\n/** The definition's own settings: a one-row summary until expanded to edit. */\nexport const ModelSettings = ({ issues, disabled, scopeSection }: ModelSettingsProps) => {\n const { t } = useTranslation();\n const [expanded, setExpanded] = useState(false);\n const bodyId = useId();\n return (\n <Panel\n title={t('models.builder.definitionSettings')}\n actions={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-expanded={expanded}\n aria-controls={bodyId}\n aria-label={t('models.builder.definitionSettings')}\n onClick={() => setExpanded((open) => !open)}\n >\n <ChevronDown aria-hidden=\"true\" className={cn('transition-transform', expanded && 'rotate-180')} />\n </Button>\n }\n >\n <div id={bodyId}>\n {expanded ? (\n <DefinitionPanel issues={issues} disabled={disabled} scopeSection={scopeSection} />\n ) : (\n <Summary hasIssues={issues.some(isDefinitionIssue)} />\n )}\n </div>\n </Panel>\n );\n};\n","import { MousePointerClick, Shapes } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\n\ntype NoFieldSelectedProps = { hasFields: boolean };\n\n/** The properties column before a field is chosen (xl only: below it, the field list is right above). */\nexport const NoFieldSelected = ({ hasFields }: NoFieldSelectedProps) => {\n const { t } = useTranslation();\n return (\n <Panel aria-label={t('models.builder.propertiesLabel')} className=\"hidden xl:block\">\n {hasFields ? (\n <EmptyState size=\"panel\" icon={MousePointerClick} title={t('models.builder.selectField')} />\n ) : (\n <EmptyState size=\"panel\" icon={Shapes} title={t('models.builder.startTitle')} />\n )}\n </Panel>\n );\n};\n","import { RefreshCw } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\n\ntype RemoteChangeBannerProps = {\n /**\n * Why it shows: `remote`, another session activated a newer version (noticed by polling); `conflict`,\n * this session's own review or save was refused because the version moved (a rejected non-fast-forward).\n */\n reason: 'remote' | 'conflict';\n /** There are unsaved edits, so the admin chooses what happens to them. */\n dirty: boolean;\n /** Start over from the latest version (unsaved edits are dropped). */\n onReload: () => void;\n /** Keep the edits on top of the latest version and review again. */\n onKeepEdits: () => void;\n};\n\n/**\n * The definition moved on while this admin was editing. Nothing is discarded silently: with unsaved edits\n * the admin takes the latest version or keeps their edits on top of it; without, they reload. A conflict\n * from their own save is announced at once (alert); a change noticed in the background politely (status).\n */\nexport const RemoteChangeBanner = ({ reason, dirty, onReload, onKeepEdits }: RemoteChangeBannerProps) => {\n const { t } = useTranslation();\n const choose = dirty || reason === 'conflict';\n return (\n <Alert\n variant=\"warning\"\n role={reason === 'conflict' ? 'alert' : 'status'}\n className=\"flex flex-wrap items-center justify-between gap-3\"\n >\n <div className=\"flex items-start gap-3\">\n <RefreshCw className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div>\n <AlertTitle>{t('models.remote.title')}</AlertTitle>\n <AlertDescription>\n {t(choose ? 'models.remote.chooseDescription' : 'models.remote.description')}\n </AlertDescription>\n </div>\n </div>\n {choose ? (\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onKeepEdits}>\n {t('models.remote.keepEdits')}\n </Button>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReload}>\n {t('models.remote.reloadLatest')}\n </Button>\n </div>\n ) : (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReload}>\n {t('models.remote.reload')}\n </Button>\n )}\n </Alert>\n );\n};\n","import type { ClassifiedChange, SchemaDefinition } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { PLAN_BUCKET_LABEL_KEYS } from '../../../constants';\nimport { describeChange } from '../../../helpers/describeChange';\nimport { groupByBucket } from '../../../helpers/planBuckets';\nimport { BucketChip } from '../../BucketChip';\n\ntype ChangeListProps = {\n changes: readonly ClassifiedChange[];\n before: SchemaDefinition | null;\n after: SchemaDefinition | null;\n};\n\n/** Every change in the plan, grouped by how it is applied, most demanding group first. */\nexport const ChangeList = ({ changes, before, after }: ChangeListProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"space-y-4\">\n {groupByBucket(changes).map(({ bucket, changes: inGroup }) => (\n <div key={bucket} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <BucketChip bucket={bucket} />\n <span className=\"text-meta text-muted-foreground tabular-nums\">{inGroup.length}</span>\n </div>\n <ul aria-label={t(PLAN_BUCKET_LABEL_KEYS[bucket])} className=\"divide-y rounded-lg border\">\n {inGroup.map((change, index) => (\n <li\n key={`${change.kind}-${change.fieldId ?? ''}-${change.property ?? ''}-${index}`}\n className=\"px-3 py-2.5 text-sm\"\n >\n {describeChange(change, before, after)}\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n};\n","import type { PlanPreview } from '@shapio/client';\nimport type { SchemaDefinition } from '@shapio/schema';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useSaveDraftToChangeSet } from '@/api/changeSets';\nimport { settle } from '@/helpers/settle';\n\n/**\n * \"Review in a change set\" (plan developer-face §5): the reviewed draft goes into the newest open change\n * set (or a new one), then its review opens. The draft is saved there, so leaving the builder skips the\n * unsaved-changes guard.\n */\nexport const useReviewInChangeSet = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const save = useSaveDraftToChangeSet();\n const reviewInChangeSet = async (preview: PlanPreview, draft: SchemaDefinition) => {\n const { plan } = preview;\n const saved = await settle(\n save.mutateAsync({\n definitionId: plan.definitionId,\n newSetTitle: t('changes.builderSetTitle', { label: draft.label }),\n input: {\n category: plan.kind === 'component' ? 'component' : 'model',\n definition: draft,\n baseVersion: plan.fromVersion,\n },\n }),\n );\n if (saved.ok) {\n await navigate({\n to: '/changes/$changeSetId',\n params: { changeSetId: saved.value },\n ignoreBlocker: true,\n });\n }\n };\n return { reviewInChangeSet, saving: save.isPending, saveError: save.error, resetSave: save.reset };\n};\n","import type { Acknowledgement, PlanPreview } from '@shapio/client';\nimport type { SchemaDefinition } from '@shapio/schema';\nimport { GitPullRequest, Loader2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { InfoHint } from '@/components/InfoHint';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Field, FieldLabel } from '@/components/ui/field';\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from '@/components/ui/sheet';\nimport { bucketOfPlan, type PlanBucket } from '../../helpers/planBuckets';\nimport { BucketChip } from '../BucketChip';\nimport { ChangeList } from './ChangeList';\nimport { useReviewInChangeSet } from './hooks/useReviewInChangeSet';\nimport { StepList } from './StepList';\n\ntype ReviewSheetProps = {\n preview: PlanPreview | undefined;\n before: SchemaDefinition | null;\n after: SchemaDefinition | null;\n applying: boolean;\n error: unknown;\n onApply: (acknowledgement: Acknowledgement) => void;\n onClose: () => void;\n};\n\nconst SUMMARY_KEYS = {\n breaking: 'models.plan.summary.breaking',\n prerequisites: 'models.plan.summary.prerequisites',\n live: 'models.plan.summary.live',\n metadata: 'models.plan.summary.metadata',\n} as const satisfies Record<PlanBucket, string>;\n\n/**\n * The plan preview (brief §5 step 5), in a wide sheet so the builder stays in view: every change classified,\n * the entries affected, the prerequisite jobs that run before activation, and explicit acknowledgement for\n * breaking or destructive changes. From here the draft either ships now (the primary action) or goes into\n * a change set to be reviewed and shipped with other work (\"Review in a change set\"). It can't be closed\n * while either is in progress.\n */\nexport const ReviewSheet = ({\n preview,\n before,\n after,\n applying,\n error,\n onApply,\n onClose,\n}: ReviewSheetProps) => {\n const { t } = useTranslation();\n const [acknowledgedBreaking, setAcknowledgedBreaking] = useState(false);\n const [acknowledgedDestructive, setAcknowledgedDestructive] = useState(false);\n const [previewShown, setPreviewShown] = useState(preview);\n const { reviewInChangeSet, saving, saveError, resetSave } = useReviewInChangeSet();\n const busy = applying || saving;\n // A new preview starts with nothing acknowledged. The last one stays rendered while the sheet closes.\n if (preview !== undefined && preview !== previewShown) {\n setPreviewShown(preview);\n setAcknowledgedBreaking(false);\n setAcknowledgedDestructive(false);\n resetSave();\n }\n const plan = previewShown?.plan;\n const summary = plan?.summary;\n const bucket = summary ? bucketOfPlan(summary) : 'metadata';\n const needsBreaking = summary?.breaking ?? false;\n const needsDestructive = summary?.destructive ?? false;\n const canApply = (!needsBreaking || acknowledgedBreaking) && (!needsDestructive || acknowledgedDestructive);\n return (\n <Sheet open={preview !== undefined} onOpenChange={(open) => !open && !busy && onClose()}>\n <SheetContent size=\"lg\">\n <SheetHeader className=\"pr-14\">\n <SheetTitle>{t('models.plan.title', { label: after?.label ?? '' })}</SheetTitle>\n <SheetDescription>{t(SUMMARY_KEYS[bucket])}</SheetDescription>\n </SheetHeader>\n {plan && previewShown ? (\n <form\n noValidate\n className=\"flex min-h-0 flex-1 flex-col\"\n onSubmit={(event) => {\n event.preventDefault();\n onApply({\n ...(needsBreaking ? { acknowledgeBreaking: true } : {}),\n ...(needsDestructive ? { acknowledgeDestructive: true } : {}),\n });\n }}\n >\n <SheetBody className=\"space-y-6 pt-1\">\n <div className=\"flex flex-wrap items-center gap-3 rounded-lg bg-muted px-3 py-2.5\">\n <BucketChip bucket={bucket} />\n <span className=\"text-meta text-muted-foreground\">\n {t('models.plan.affected', { count: previewShown.impact.affectedHeads })}\n </span>\n </div>\n <section className=\"space-y-3\" aria-labelledby=\"plan-changes\">\n <h3 id=\"plan-changes\" className=\"text-sm font-semibold\">\n {t('models.plan.changes', { count: plan.changes.length })}\n </h3>\n <ChangeList changes={plan.changes} before={before} after={after} />\n </section>\n {plan.prerequisites.length > 0 ? (\n <section className=\"space-y-3\" aria-labelledby=\"plan-prerequisites\">\n <div className=\"flex items-center gap-1\">\n <h3 id=\"plan-prerequisites\" className=\"text-sm font-semibold\">\n {t('models.plan.prerequisites')}\n </h3>\n <InfoHint about={t('models.plan.prerequisites')}>\n {t('models.plan.prerequisitesHint')}\n </InfoHint>\n </div>\n <StepList\n phase=\"before\"\n steps={plan.prerequisites}\n impacts={previewShown.impact.steps}\n before={before}\n after={after}\n />\n </section>\n ) : null}\n {plan.followUps.length > 0 ? (\n <section className=\"space-y-3\" aria-labelledby=\"plan-follow-ups\">\n <h3 id=\"plan-follow-ups\" className=\"text-sm font-semibold\">\n {t('models.plan.followUps')}\n </h3>\n <StepList phase=\"after\" steps={plan.followUps} before={before} after={after} />\n </section>\n ) : null}\n {needsBreaking || needsDestructive ? (\n <fieldset className=\"space-y-3 rounded-lg border border-warning/40 bg-warning-muted/40 p-4\">\n <legend className=\"px-1 text-sm font-semibold text-warning\">\n {t('models.plan.acknowledge')}\n </legend>\n {needsBreaking ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"plan-ack-breaking\"\n checked={acknowledgedBreaking}\n onCheckedChange={(checked) => setAcknowledgedBreaking(checked === true)}\n />\n <FieldLabel htmlFor=\"plan-ack-breaking\" className=\"font-normal\">\n {t('models.plan.acknowledgeBreaking')}\n </FieldLabel>\n </Field>\n ) : null}\n {needsDestructive ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"plan-ack-destructive\"\n checked={acknowledgedDestructive}\n onCheckedChange={(checked) => setAcknowledgedDestructive(checked === true)}\n />\n <FieldLabel htmlFor=\"plan-ack-destructive\" className=\"font-normal\">\n {t('models.plan.acknowledgeDestructive')}\n </FieldLabel>\n </Field>\n ) : null}\n </fieldset>\n ) : null}\n <FormError error={error ?? saveError} />\n </SheetBody>\n <SheetFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={busy}>\n {t('common.cancel')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={busy || !after}\n aria-busy={saving || undefined}\n onClick={() => after && void reviewInChangeSet(previewShown, after)}\n >\n {saving ? (\n <Loader2 className=\"animate-spin motion-reduce:animate-none\" aria-hidden=\"true\" />\n ) : (\n <GitPullRequest aria-hidden=\"true\" />\n )}\n {saving ? t('common.saving') : t('changes.reviewInChangeSet')}\n </Button>\n <SubmitButton\n pending={applying}\n pendingLabel={t('models.plan.applying')}\n disabled={!canApply || saving}\n >\n {t('models.plan.apply')}\n </SubmitButton>\n </SheetFooter>\n </form>\n ) : null}\n </SheetContent>\n </Sheet>\n );\n};\n","import type { DefinitionCategory, DefinitionDetail } from '@shapio/client';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useDeleteDefinition } from '@/api/schema';\nimport { ConfirmDialog } from '@/components/ConfirmDialog';\nimport { LoadingState } from '@/components/LoadingState';\nimport { Page } from '@/components/Page';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useSaveShortcut } from '@/hooks/useSaveShortcut';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { draftKeyOf, useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { useSchemaLock } from '../../hooks/useSchemaLock';\nimport { useSharedReadOnly } from '../../hooks/useSharedReadOnly';\nimport { LockNotice } from '../../LockNotice';\nimport { SharedNotice } from '../../SharedNotice';\nimport { ActionFooter } from '../ActionFooter';\nimport { ChangeProgress } from '../ChangeProgress';\nimport { Scope } from '../DefinitionPanel/Scope';\nimport { FieldList } from '../FieldList';\nimport { FieldPanel } from '../FieldPanel';\nimport { Header } from '../Header';\nimport { useAddSeoField } from '../hooks/useAddSeoField';\nimport { useDraftIssues } from '../hooks/useDraftIssues';\nimport { useIsDraftDirty } from '../hooks/useIsDraftDirty';\nimport { useNewField } from '../hooks/useNewField';\nimport { useReloadDraft } from '../hooks/useReloadDraft';\nimport { useRemoteChangeNotice } from '../hooks/useRemoteChangeNotice';\nimport { useSaveFlow } from '../hooks/useSaveFlow';\nimport { useSelectedField } from '../hooks/useSelectedField';\nimport { ModelSettings } from '../ModelSettings';\nimport { NoFieldSelected } from '../NoFieldSelected';\nimport { RemoteChangeBanner } from '../RemoteChangeBanner';\nimport { ReviewSheet } from '../ReviewSheet';\n\ntype EditorProps = { category: DefinitionCategory; id: string; detail: DefinitionDetail };\n\n/** Edits a draft of the definition; nothing changes on the server until the plan is reviewed and applied. */\nexport const Editor = ({ category, id, detail }: EditorProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const key = draftKeyOf(category, id);\n const loadedKey = useDefinitionDraftStore((state) => state.key);\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const baseVersion = useDefinitionDraftStore((state) => state.baseVersion);\n const load = useDefinitionDraftStore((state) => state.load);\n const reset = useDefinitionDraftStore((state) => state.reset);\n const reloadDraft = useReloadDraft(category, id);\n const flow = useSaveFlow(category, id, reloadDraft);\n const dirty = useIsDraftDirty();\n const { issues } = useDraftIssues();\n const { field, index } = useSelectedField();\n const { locked, reason } = useSchemaLock();\n const sharedReadOnly = useSharedReadOnly(detail.scope);\n const { multiSite } = useSchemaScopeAccess();\n const deleteDefinition = useDeleteDefinition();\n const newField = useNewField();\n const seoField = useAddSeoField();\n const [confirmingDelete, setConfirmingDelete] = useState(false);\n const [dismissedChangeId, setDismissedChangeId] = useState<string | undefined>(undefined);\n const [scopeConflict, setScopeConflict] = useState(false);\n\n // A fresh draft each time the builder opens; it is forgotten when the builder closes.\n const initial = useRef(detail);\n useEffect(() => {\n load(category, initial.current.definition, initial.current.version);\n return reset;\n }, [key, category, load, reset]);\n\n const changeId = flow.runningChangeId ?? detail.pendingChange?.id;\n const visibleChangeId = changeId === dismissedChangeId ? undefined : changeId;\n const changeRunning = visibleChangeId !== undefined;\n const { changedElsewhere } = useRemoteChangeNotice(id, baseVersion, changeRunning || flow.applying);\n const saveBlocked = locked || sharedReadOnly || changeRunning;\n const canReview = dirty && issues.length === 0 && !saveBlocked && !flow.reviewing;\n const planOpen = flow.state.step === 'review';\n const conflict = flow.state.step === 'conflict' || scopeConflict;\n useSaveShortcut(() => void flow.review(), canReview && !planOpen);\n\n if (loadedKey !== key || !draft) {\n return <LoadingState />;\n }\n\n const reload = (mode: 'replace' | 'rebase') =>\n void reloadDraft(mode).catch((error: unknown) => {\n logError(error, 'reloading the definition');\n toast.error(describeError(error));\n });\n const editingDisabled = locked || sharedReadOnly;\n\n const scopeSection = multiSite ? (\n <Scope\n category={category}\n id={id}\n label={draft.label}\n scope={detail.scope}\n blocked={dirty || changeRunning || flow.applying}\n locked={locked}\n onConflict={() => setScopeConflict(true)}\n />\n ) : null;\n\n const saveActions = {\n canDiscard: dirty,\n canReview,\n reviewing: flow.reviewing,\n onReview: () => void flow.review(),\n onDiscard: () => {\n if (base) {\n load(category, base, baseVersion);\n }\n },\n };\n\n return (\n <Page width=\"full\">\n <UnsavedChangesGuard when={dirty} />\n <Header\n {...saveActions}\n draft={draft}\n version={baseVersion}\n dirty={dirty}\n issueCount={issues.length}\n deleteBlocked={saveBlocked}\n onDelete={() => setConfirmingDelete(true)}\n />\n {locked ? <LockNotice reason={reason} /> : null}\n {sharedReadOnly ? <SharedNotice /> : null}\n {changedElsewhere || conflict ? (\n <RemoteChangeBanner\n key={conflict ? 'conflict' : 'remote'}\n reason={conflict ? 'conflict' : 'remote'}\n dirty={dirty}\n onReload={() => {\n flow.resetStep();\n setScopeConflict(false);\n reload('replace');\n }}\n onKeepEdits={() => {\n flow.resetStep();\n setScopeConflict(false);\n reload('rebase');\n }}\n />\n ) : null}\n {visibleChangeId ? (\n <ChangeProgress\n key={visibleChangeId}\n changeId={visibleChangeId}\n onFinished={(status) => void flow.onChangeFinished(status)}\n onDismiss={() => {\n setDismissedChangeId(visibleChangeId);\n flow.dismissChange();\n }}\n />\n ) : null}\n {/*\n One column below xl: settings, fields, then the properties pane (shown for a selected field).\n Locked (or shared and not ours to change): every control is disabled individually, so fields can\n still be selected and read.\n */}\n <div className=\"grid min-w-0 gap-6 xl:grid-cols-[22.5rem_minmax(0,1fr)] xl:items-start\">\n <div className=\"min-w-0 space-y-6\">\n <ModelSettings issues={issues} disabled={editingDisabled} scopeSection={scopeSection} />\n <FieldList\n issues={issues}\n disabled={editingDisabled}\n onAdd={newField.add}\n seo={draft.kind === 'component' ? undefined : seoField}\n />\n </div>\n {field ? (\n <FieldPanel\n key={field.id}\n field={field}\n index={index}\n issues={issues}\n disabled={editingDisabled}\n untouched={newField.isUntouched(field)}\n onDiscard={() => newField.discard(field.id)}\n />\n ) : (\n <NoFieldSelected hasFields={draft.fields.length > 0} />\n )}\n </div>\n <ActionFooter {...saveActions} />\n <ReviewSheet\n preview={flow.state.step === 'review' ? flow.state.preview : undefined}\n before={base}\n after={draft}\n applying={flow.applying}\n error={flow.applyError}\n onApply={(acknowledgement) => void flow.confirm(acknowledgement)}\n onClose={flow.resetStep}\n />\n <ConfirmDialog\n open={confirmingDelete}\n onOpenChange={setConfirmingDelete}\n title={t('models.builder.deleteTitle', { label: draft.label })}\n description={t('models.builder.deleteDescription')}\n confirmLabel={t('common.delete')}\n destructive\n onConfirm={() =>\n deleteDefinition.mutate(\n { category, id, expectedVersion: baseVersion },\n {\n onSuccess: () => {\n reset();\n toast.success(t('models.deleted'));\n void navigate({ to: '/models' });\n },\n },\n )\n }\n />\n </Page>\n );\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport { useDefinition } from '@/api/schema';\nimport { QueryView } from '@/components/QueryView';\nimport { Editor } from './Editor';\n\ntype BuilderProps = { category: DefinitionCategory; id: string };\n\n/** The model (or component) builder: loads the definition, then edits a draft of it. */\nexport const Builder = ({ category, id }: BuilderProps) => {\n const detail = useDefinition(category, id);\n return (\n <QueryView query={detail}>\n {(data) => <Editor key={id} category={category} id={id} detail={data} />}\n </QueryView>\n );\n};\n"],"ignoreList":[0,1,2],"mappings":"k0EASA,IAAMA,GAAa,CACjB,KAAM,UACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,iGACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAS,CAAC,EACrE,CACE,OACA,CACE,EAAG,+FACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAS,CAAC,CAC7C,CACF,EACAA,GAAW,KACX,IAAMoL,GAASC,EAAiBrL,EAAU,ECvBpCC,GAAa,CACjB,KAAM,sBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,eAAgB,IAAK,QAAS,CAAC,EAC7C,CAAC,OAAQ,CAAE,EAAG,gBAAiB,IAAK,QAAS,CAAC,EAC9C,CAAC,OAAQ,CAAE,EAAG,cAAe,IAAK,QAAS,CAAC,EAC5C,CAAC,OAAQ,CAAE,EAAG,iBAAkB,IAAK,QAAS,CAAC,EAC/C,CACE,OACA,CACE,EAAG,gIACH,IAAK,QACP,CACF,CACF,CACF,EACAA,GAAW,KACX,IAAMsL,GAAoBF,EAAiBpL,EAAU,EClB/CuL,GAAa,CACjB,KAAM,SACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,2FACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,IAAK,EAAG,KAAM,MAAO,IAAK,OAAQ,IAAK,GAAI,IAAK,IAAK,QAAS,CAAC,EAC7E,CAAC,SAAU,CAAE,GAAI,OAAQ,GAAI,OAAQ,EAAG,MAAO,IAAK,QAAS,CAAC,CAChE,CACF,EACAA,GAAW,KACX,IAAMC,GAASJ,EAAiBG,EAAU,aCKpCI,IAAS,EAA8B,IAAe,GAAGC,EAAS,GAAGC,IAM9DC,EAA0BpJ,EAAmB,CAAC,CAAE,IAAS,CACpE,IAAK,KACL,SAAU,QACV,KAAM,KACN,YAAa,EACb,MAAO,KACP,UAAW,CAAE,KAAM,YAAa,EAChC,MAAO,EAAU,EAAY,IAC3BqJ,EAAK,GAAU,CACb,IAAMC,EAAML,GAAMC,EAAUK,EAAW,EAAE,EACnC,CAAE,aAAcC,EAKtB,MAAO,CACL,MACA,WACA,KAAMD,EACN,YAAaE,EACb,MAAOF,EACP,UATAC,EAAM,MAAQF,IACbI,EAAU,OAAS,cAClBH,EAAW,OAAO,KAAM,GAAUI,EAAM,KAAOD,EAAU,OAAO,GAOvCA,EAAY,CAAE,KAAM,YAAa,CAC9D,CACF,CAAC,EACH,UAAaL,EAAI,CAAE,IAAK,KAAM,KAAM,KAAM,YAAa,EAAG,MAAO,KAAM,UAAW,CAAE,KAAM,YAAa,CAAE,CAAC,EAC1G,QAAS,EAAY,EAAS,IAAUA,EAAI,CAAE,KAAME,EAAY,YAAaE,EAAS,OAAM,CAAC,EAC7F,OAAS,GAAWJ,EAAK,GAAWG,EAAM,MAAQ,CAAE,MAAOI,EAAOJ,EAAM,KAAK,CAAE,EAAI,CAAC,CAAE,EACtF,aAAc,EAAS,IACrBH,EAAK,GACHG,EAAM,MACF,CACE,MAAO,CACL,GAAGA,EAAM,MACT,OAAQA,EAAM,MAAM,OAAO,IAAK,GAAWG,EAAM,KAAOE,EAAUD,EAAOD,CAAK,EAAIA,CAAM,CAC1F,CACF,EACA,CAAC,CACP,EACF,OAAS,GAAcN,EAAI,CAAE,WAAU,CAAC,CAC1C,EAAE,EAGWS,GAAab,GCvEbc,GAAqB,GAA2B,CAC3D,GAAM,CAAE,YAAaxF,EAAqB,EAC1C,OAAOyF,IAAU,WAAa,CAACC,CACjC,aCLaE,OAAqB,CAChC,GAAM,CAAE,KAAMpK,EAAe,EAC7B,OACE,EAAAmK,EAAA,KAAA,CAACnF,GAAD,CAAA,SAAA,EACE,EAAAmF,EAAA,IAAA,CAAC3M,GAAD,CAAQ,cAAY,MAAQ,CAAA,GAC5B,EAAA2M,EAAA,IAAA,CAAC/E,GAAD,CAAA,SAAmBiF,EAAE,uBAAuB,CAAoB,CAAA,CAC3D,CAAA,CAAA,CAEX,ECQaC,IAAe,CAAE,aAAY,YAAW,YAAW,WAAU,eAAkC,CAC1G,GAAM,CAAE,KAAMtK,EAAe,EAC7B,OACE,EAAAmK,EAAA,KAAA,CAAA1M,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA0M,EAAA,IAAA,CAAC9E,GAAD,CACE,KAAK,SACL,MAAOgF,EAAE,6BAA6B,EACtC,YAAaA,EAAE,mCAAmC,EAClD,aAAcA,EAAE,wBAAwB,EACxC,UAAWE,EACX,SACE,EAAAJ,EAAA,KAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,QAAQ,QAAQ,SAAU,CAACyG,EAAjD,SAAA,EACE,EAAAL,EAAA,IAAA,CAACrD,GAAD,CAAO,cAAY,MAAQ,CAAA,EAC1BuD,EAAE,wBAAwB,CACrB,GAEX,CAAA,GACD,EAAAF,EAAA,IAAA,CAAC3J,EAAD,CACE,QAASiK,EACT,aAAcJ,EAAE,yBAAyB,EACzC,SAAU,CAACK,EACX,QAASC,EAER,SAAAN,EAAE,uBAAuB,CACd,CAAA,CACd,CAAA,CAAA,CAEN,EC7CaO,GAAgB,IAC3B,EAAAT,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,uMACb,UAAA,EAAAA,EAAA,IAAA,CAACG,GAAD,CAAa,GAAIO,CAAQ,CAAA,CACtB,CAAA,ECUDC,GAAa,GACjB,OAAOC,GAAU,UAAYA,EAAiBA,EAAQ,CAAC,EAM5CC,IAAkB,CAAE,WAAU,aAAY,eAAqC,CAC1F,GAAM,CAAE,KAAMhL,EAAe,EACvBiL,EAASnD,GAAgBoD,CAAQ,EACjCC,EAASF,EAAO,MAAM,OACtBG,GAAA,EAAW1N,EAAAA,OAAAA,CAAO,EAAK,EAO7B,IANA,EAAAsL,EAAA,UAAA,KAAgB,CACVmC,GAAU5D,GAAsB,IAAI4D,CAAM,GAAK,CAACC,EAAS,UAC3D,EAAS,QAAU,GACnBC,EAAWF,CAAM,EAErB,EAAG,CAACA,EAAQE,CAAU,CAAC,EACnBF,IAAW,YACb,OAAO,KAET,GAAIA,IAAW,UAAYA,IAAW,YAAa,CACjD,IAAMG,EAAUR,GAAUG,EAAO,MAAM,KAAK,EAC5C,OACE,EAAAd,EAAA,KAAA,CAACnF,GAAD,CAAO,QAAQ,cAAf,SAAA,EACE,EAAAmF,EAAA,IAAA,CAACxM,GAAD,CAAa,cAAY,MAAQ,CAAA,GACjC,EAAAwM,EAAA,IAAA,CAAC7E,GAAD,CAAA,SAAa+E,EAAE,6BAA6B,CAAc,CAAA,GAC1D,EAAAF,EAAA,KAAA,CAAC/E,GAAD,CAAA,SAAA,EACE,EAAA+E,EAAA,IAAA,CAAC,IAAD,CAAA,SAAIE,EAAE,mCAAmC,CAAK,CAAA,EAC7C,OAAOiB,EAAQ,cAAiB,UAC/B,EAAAnB,EAAA,IAAA,CAAC,IAAD,CAAA,SAAIE,EAAE,+BAAgC,CAAE,MAAOiB,EAAQ,YAAa,CAAC,CAAK,CAAA,EACxE,KACH,OAAOA,EAAQ,QAAW,UAAW,EAAAnB,EAAA,IAAA,CAAC,IAAD,CAAA,SAAImB,EAAQ,MAAU,CAAA,EAAI,MAChE,EAAAnB,EAAA,IAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,UAAU,OAAO,QAASwH,EACzE,SAAAlB,EAAE,cAAc,CACX,CAAA,CACQ,CAAA,CAAA,CACb,GAEX,CACA,OACE,EAAAF,EAAA,KAAA,CAACnF,GAAD,CAAO,QAAQ,OAAO,KAAK,SAA3B,SAAA,EACE,EAAAmF,EAAA,IAAA,CAACvM,EAAD,CAAS,UAAU,eAAe,cAAY,MAAQ,CAAA,GACtD,EAAAuM,EAAA,IAAA,CAAC7E,GAAD,CAAA,SAAa+E,EAAE,8BAA8B,CAAc,CAAA,GAC3D,EAAAF,EAAA,IAAA,CAAC/E,GAAD,CAAA,SAAmBiF,EAAE,oCAAoC,CAAoB,CAAA,CACxE,GAEX,EC7DMmB,IAAQ,EAAY,IAAe3I,EAAc4I,GAAK,IAAI,IAAM5I,EAAc6I,GAAK,IAAI,EAEvFC,GAAiB,GACrB,OAAOC,GAAU,YAAYA,GAAkB,CAAC,MAAM,QAAQA,CAAK,EAMxDC,IAAU,EAAe,EAAe,IAA6B,CAChF,GAAIL,GAAKM,EAAMC,CAAI,EACjB,OAAOC,EAET,GAAIR,GAAKQ,EAAQD,CAAI,EACnB,OAAOD,EAET,GAAIH,GAAcI,CAAI,GAAKJ,GAAcG,CAAI,GAAKH,GAAcK,CAAM,EAAG,CACvE,IAAMC,EAAO,IAAI,IAAI,CAAC,GAAG,OAAO,KAAKF,CAAI,EAAG,GAAG,OAAO,KAAKD,CAAI,EAAG,GAAG,OAAO,KAAKE,CAAM,CAAC,CAAC,EACnFE,EAAkC,CAAC,EACzC,IAAK,IAAM3C,KAAO0C,EAAM,CACtB,IAAML,EAAQC,GAAOE,EAAKxC,GAAMuC,EAAKvC,GAAMyC,EAAOzC,EAAI,EAClDqC,IAAU,IAAA,KACZ,EAAOrC,GAAOqC,EAElB,CACA,OAAOM,CACT,CACA,OAAOJ,CACT,EAEMK,IAAO,EAAoC,IAC/CC,EAAO,OAAQ,GAAUC,EAAK,IAAIzC,EAAM,EAAE,CAAC,CAAC,CAAC,IAAK,GAAUA,EAAM,EAAE,EAGhE0C,IACJ,EACA,EACA,IACsB,CACtB,IAAMC,EAAW,IAAI,IAAIR,EAAK,IAAK,GAAU,CAACnC,EAAM,GAAIA,CAAK,CAAC,CAAC,EACzD4C,EAAW,IAAI,IAAIV,EAAK,IAAK,GAAU,CAAClC,EAAM,GAAIA,CAAK,CAAC,CAAC,EACzD6C,EAAa,IAAI,IAAIT,EAAO,IAAK,GAAU,CAACpC,EAAM,GAAIA,CAAK,CAAC,CAAC,EAE7D,CAAC8C,EAASC,GADOnB,GAAKW,GAAIL,EAAMS,CAAQ,EAAGJ,GAAIJ,EAAMS,CAAQ,CAAC,EACN,CAACR,EAAQF,CAAI,EAA9B,CAACA,EAAME,CAAM,EAE1D,MAAO,CADQ,GAAG,IAAI,IAAI,CAAC,GAAGU,EAAS,GAAGC,CAAS,CAAC,CAAC,IAAK,GAAU/C,EAAM,EAAE,CAAC,CACtE,CAAA,CAAM,QAAS,GAAO,CAC3B,IAAMgD,EAAWL,EAAS,IAAInD,CAAE,EAC1ByD,EAAOL,EAAS,IAAIpD,CAAE,EACtB0D,EAAQL,EAAW,IAAIrD,CAAE,EAW/B,OAVIwD,GAAY,CAACC,EACR,CAAC,EAEND,GAAY,CAACE,EAERD,GAAQ,CAACrB,GAAKqB,EAAMD,CAAQ,EAAI,CAACC,CAAI,EAAI,CAAC,EAE9CD,EAGE,CAACf,GAAOe,EAAUC,EAAMC,CAAK,CAAoB,EAF/C,CAAED,GAAQC,CAAyB,CAG9C,CAAC,CACH,EAOaC,IACX,EACA,EACA,IACqB,CACrB,GAAM,CAAE,OAAQC,EAAY,GAAGC,GAAalB,EACtC,CAAE,OAAQmB,EAAa,GAAGC,GAAcC,EACxC,CAAE,OAAQC,EAAc,GAAGC,GAAeC,EAEhD,MAAO,CAAE,GADM1B,GAAOoB,EAAUE,EAAWG,CAC/B,EAAQ,OAAQhB,GAAYU,EAAYE,EAAaG,CAAY,CAAE,CACjF,ECpEaG,IAAkB,EAA8B,IAAe,CAC1E,IAAMC,EAAc1N,EAAe,EAC7B2N,EAAOrE,EAAyB,GAAUI,EAAM,IAAI,EACpDkE,EAAStE,EAAyB,GAAUI,EAAM,MAAM,EAC9D,OAAA,EAAO5L,EAAAA,YAAAA,CACL,KAAO,IAA+B,CACpC,IAAM+P,EAAS,MAAMH,EAAY,WAAW,CAAE,GAAG5F,GAAuBsB,EAAUC,CAAE,EAAG,UAAW,CAAE,CAAC,EAC/F,CAAE,OAAM,SAAUC,EAAwB,SAAS,EAMzD,OALIwE,IAAS,UAAY9B,GAAQqB,EAC/BO,EAAOC,EAAO,WAAYA,EAAO,QAASb,GAAYhB,EAAMqB,EAAOQ,EAAO,UAAU,CAAC,EAErFF,EAAKvE,EAAUyE,EAAO,WAAYA,EAAO,OAAO,EAE3CA,CACT,EACA,CAACH,EAAatE,EAAUC,EAAIsE,EAAMC,CAAM,CAC1C,CACF,ECdaG,IAAkB,EAA8B,EAAY,IAA2B,CAClG,GAAM,CAAE,KAAM9N,EAAe,EACvB+N,EAAcvG,GAAe,EAC7BwG,EAAcR,GAAerE,EAAUC,CAAE,EAC/C,OAAO,KAAO,IAA2B,CACvC,IAAMM,EAAUL,EAAwB,SAAS,CAAC,CAAC,YACnD,GAAI,CACF,MAAM0E,EAAY,YAAY,CAAE,WAAU,KAAI,MAAO,CAAE,QAAO,SAAQ,CAAE,CAAC,CAC3E,OAAShD,EAAO,CACd,GAAIzK,EAAayK,EAAO,yBAAyB,EAAG,CAClDkD,EAAW,EACX,MACF,CACA,MAAMlD,CACR,CACA,MAAMiD,EAAY,SAAS,EAC3B7K,EAAM,QAAQkH,EAAEJ,IAAU,UAAY,sBAAwB,mBAAmB,CAAC,CACpF,CACF,ECpBaiE,GAAgB,CAAE,QAAO,UAAS,YAAW,eACxD,EAAA/D,EAAA,KAAA,CAAC,UAAD,CAAS,UAAWhK,EAAG,sDAAuDgO,CAAS,EAAvF,SAAA,EACE,EAAAhE,EAAA,IAAA,CAAC,KAAD,CAAI,GAAIiE,EAAS,UAAU,sEACxB,SAAAC,CACC,CAAA,GACJ,EAAAlE,EAAA,IAAA,CAACrG,GAAD,CAAY,UAAU,QAAS,UAAqB,CAAA,CAC7C,ICUEwK,IAAS,CAAE,WAAU,KAAI,QAAO,QAAO,UAAS,SAAQ,gBAA6B,CAChG,GAAM,CAAE,KAAMtO,EAAe,EACvBuO,EAAOhO,EAAM,CAAC,CAAC,MAAM,KACrB,CAAE,YAAaiE,EAAqB,EACpCyG,EAAS6C,GAAe3E,EAAUC,EAAI6E,CAAU,EAChDO,GAAA,EAAS1Q,EAAAA,MAAAA,CAAM,EACf2Q,EAASxE,IAAU,UACnByE,EAA0BD,EAAS,OAAS,UAC5CE,EAAWJ,GAAM,MAAQ,GAC/B,OACE,EAAApE,EAAA,KAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,0BAA0B,EAAjD,SAAA,EACE,EAAAF,EAAA,KAAA,CAAC,IAAD,CAAG,UAAU,oCAAoC,aAAYF,EAA7D,SAAA,CACGwE,GAAS,EAAAtE,EAAA,IAAA,CAAC/C,GAAD,CAAc,CAAA,EAAI,KAC3BqH,EAASpE,EAAE,iCAAiC,EAAIA,EAAE,sBAAuB,CAAE,KAAMsE,CAAS,CAAC,CAC3F,CACF,CAAA,EAAAzE,GACC,EAAAC,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC9E,GAAD,CACE,KAAK,UACL,MACEoJ,EACIpE,EAAE,yBAA0B,CAAE,QAAO,KAAMsE,CAAS,CAAC,EACrDtE,EAAE,0BAA2B,CAAE,OAAM,CAAC,EAE5C,YAAsBA,EAAToE,EAAW,+BAAoC,+BAA+B,EAC3F,aAAuBpE,EAAToE,EAAW,oBAAyB,oBAAoB,EACtE,aAAcpE,EAAE,eAAe,EAC/B,cAAiBY,EAAOyD,CAAM,EAC9B,SACE,EAAAvE,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,UACR,KAAK,KACL,SAAU6K,GAAWC,EACrB,mBAAkBD,EAAUJ,EAAS,IAAA,GAEpC,SAASnE,EAAToE,EAAW,oBAAyB,oBAAoB,CACnD,CAAA,CAEX,CAAA,EACAG,GACC,EAAAzE,EAAA,IAAA,CAACtG,GAAD,CAAU,MAAgBwG,EAAToE,EAAW,oBAAyB,oBAAoB,EAAG,GAAID,EAC7E,SAAAnE,EAAE,sBAAsB,CACjB,CAAA,EACR,IACD,CACH,CAAA,EAAA,IACQ,GAElB,EC7DMyE,GAAyE,CAC7E,KAAM,CAAE,OAAQ,CAAC,CAAE,EACnB,SAAU,CAAE,OAAQ,GAAI,YAAa,KAAM,EAC3C,UAAW,CAAE,UAAW,EAAG,EAC3B,YAAa,CAAE,WAAY,CAAC,CAAE,CAChC,EAGaC,IACX,EACA,IASoB,CACpB,IAAMC,EAAM,CACV,GAAI3I,GAAY,EAChB,OAAQ4I,EAAM,OACd,MAAOA,EAAM,MACb,KAAMA,EAAM,KACZ,SAAUA,EAAM,UAAYH,GAAiBG,EAAM,OAAS,CAAC,EAC7D,GAAIA,EAAM,WAAa,IAAA,GAAY,CAAC,EAAI,CAAE,OAAQ,CAAE,GAAIA,EAAM,QAAS,CAAE,EACzE,GAAIA,EAAM,YAAc,IAAA,GAAY,CAAC,EAAI,CAAE,UAAWA,EAAM,SAAU,CACxE,EAKA,OAJmB5M,EAAsB,CACvC,GAAGmH,EACH,OAAQ,CAACwF,CAAG,CACd,CACO,CAAA,CAAW,OAAO,EAC3B,EAGaE,GAA8C,EAAW,EAAa,IAAsB,CACvG,IAAMC,EAAgC,CAAE,GAAGC,CAAO,EAMlD,OALIxD,IAAU,IAAA,GACZ,OAAOuD,EAAK5F,GAEZ,EAAKA,GAAOqC,EAEPuD,CACT,EAEaE,IAAe,EAAwB,EAAa,KAC9D,CAAE,GAAGzF,EAAO,SAAUsF,EAAQtF,EAAM,SAAqCL,EAAKqC,CAAK,CAAE,GAG3E0D,IAAgB,EAAyB,IACpDzM,EAAcR,EAAsB+K,CAAK,CAAC,IAAMvK,EAAcR,EAAsB0J,CAAI,CAAC,EAG9EwD,IAAe,EAAqB,EAAc,IAAoB,CACjF,GAAIC,IAASC,GAAMD,EAAO,GAAKC,EAAK,GAAKD,GAAQE,EAAM,QAAUD,GAAMC,EAAM,OAC3E,MAAO,CAAC,GAAGA,CAAK,EAElB,IAAMP,EAAO,CAAC,GAAGO,CAAK,EAChB,CAACC,GAASR,EAAK,OAAOK,EAAM,CAAC,EAEnC,OADAL,EAAK,OAAOM,EAAI,EAAGE,CAAU,EACtBR,CACT,EAGaS,IAAe,EAA8B,IAAsC,CAC9F,IAAMxD,EAAS5C,EAAW,OACvB,OAAQ,GAAUI,EAAM,KAAOE,CAAO,CAAC,CACvC,IAAK,GACJF,EAAM,OAAS,QAAUA,EAAM,SAAS,gBAAkBE,EACtDuF,GAAYzF,EAAO,gBAAiB,IAAA,EAAS,EAC7CA,CACN,EACIiG,EAAmC,CAAE,GAAGrG,EAAW,OAAQ,EAgBjE,OAfIqG,EAAQ,eAAiB/F,GAC3B,OAAO+F,EAAQ,aAEb,iBAAkBrG,EAAW,SAAWA,EAAW,QAAQ,eAC7D,EAAQ,aAAeA,EAAW,QAAQ,aAAa,OAAQ,GAAOJ,IAAOU,CAAO,GAElF,gBAAiBN,EAAW,SAAWA,EAAW,QAAQ,aAAa,UAAYM,GACrF,OAAO+F,EAAQ,YAEbrG,EAAW,QAAQ,SACrB,EAAQ,OAASA,EAAW,QAAQ,OAAO,IAAK,IAAW,CACzD,GAAGsG,EACH,SAAUA,EAAM,SAAS,OAAQ,GAAO1G,IAAOU,CAAO,CACxD,EAAE,GAEGiG,EAAY,CAAE,GAAGvG,EAAY,SAAQ,SAAQ,CAAC,CACvD,EAQauG,EAAe,GAAmD,CAC7E,GAAIvG,EAAW,OAAS,YACtB,OAAOA,EAET,GAAM,CAAE,iBAAgB,eAAc,iBAAkBA,EAAW,QACnE,GAAIwG,IAAmB,IAAA,IAAaC,IAAiB,IAAA,IAAaC,IAAkB,IAAA,GAClF,OAAO1G,EAET,IAAM4C,EAAS,IAAI,IAAI5C,EAAW,OAAO,IAAK,GAAU,CAACI,EAAM,GAAIA,CAAK,CAAC,CAAC,EACpEuG,GAAY,EAAY,IAA8C,CAC1E,IAAMvG,EAAQwC,EAAO,IAAIhD,CAAE,EAC3B,OAAOQ,IAAU,IAAA,IAAawG,EAAKxG,CAAK,CAC1C,EACMyE,EAAQzM,EAAoB4H,CAAU,EACtC6G,EAASL,GAAgB,OAAQ,GAAOG,EAAS/G,EAAK,GAAUrG,GAAoB6G,EAAOyE,CAAK,CAAC,CAAC,EAClGiC,EACJL,IAAiB,IAAA,IAAaE,EAASF,EAActO,CAAe,GAAK,CAAC0O,GAAQ,SAASJ,CAAY,EACnGA,EACA,IAAA,GACAM,EAAQL,GAAe,OAAQ,GAAO9D,EAAO,IAAIhD,CAAE,GAAKA,IAAOkH,GAAS,EAAED,GAAU,CAAC,EAAA,CAAG,SAASjH,CAAE,CAAC,EACtGyG,EAAUX,EAAQ1F,EAAW,QAAS,iBAAkB6G,CAAM,EAGlE,MAFA,GAAUnB,EAAQW,EAAS,eAAgBS,CAAK,EAChD,EAAUpB,EAAQW,EAAS,gBAAiBU,CAAK,EAC1C,CAAE,GAAG/G,EAAY,SAAQ,CAClC,EAMagH,GAAwB,GAA4C,CAC/E,GAAI9O,EAAiBkI,EAAM,OAAO,EAAE,EAClC,OAAOA,EAET,IAAM6G,EAAahO,EAAsBmH,CAAK,EAI9C,OAHI6G,EAAW,KAAM,GAAUC,EAAM,KAAO9G,EAAM,OAAO,EAAE,EAClDA,EAEF,CAAE,GAAGA,EAAO,OAAQ,CAAE,GAAI6G,EAAW,EAAE,EAAE,IAAMzO,GAAgB4H,EAAM,MAAO,QAAS,CAAC,CAAE,CAAE,CACnG,ECpJa+G,IACX,EACA,EACA,IACsB,CACtB,IAAMC,EAAS9N,GAAgBsK,EAAO,CAAE,SAAUrB,CAAK,CAAC,EACxD,GAAI,CAAC6E,EAAO,GACV,OAAOA,EAAO,OAGhB,IAAMC,EAAS,CAAC,GAAGC,EAAO,OAAQ,GAAetH,EAAW,KAAO4D,EAAM,EAAE,EAAGwD,EAAO,UAAU,EAC/F,OAAOjO,GAAekO,CAAM,CAAC,CAAC,OAC3B,GAAUE,EAAM,eAAiB,IAAA,IAAaA,EAAM,eAAiB3D,EAAM,EAC9E,CACF,EAGa4D,GAAe,EAAoC,IAC9DC,EAAO,OAAQ,GAAUF,EAAM,OAASG,GAAQH,EAAM,KAAK,WAAW,GAAGG,EAAK,EAAE,CAAC,EAGtEC,GAAa,GAAkB,WAAWC,ICrB1CC,GAAa,CAAE,KAAI,YAA6B,CAC3D,GAAIJ,EAAO,SAAW,EACpB,OAAO,KAET,IAAMK,EAAW,CAAC,GAAG,IAAI,IAAIL,EAAO,IAAI3I,EAAa,CAAC,CAAC,EACvD,OAAO,EAAA6B,EAAA,IAAA,CAAC1G,GAAD,CAAgB,KAAI,OAAQ6N,EAAS,IAAK,IAAa,CAAE,SAAQ,EAAE,CAAI,CAAA,CAChF,ECEaC,EAAwB,GACnC/H,EAAW,OAAO,OAAQ,GAAU,CAClC,IAAMgI,EAAQ,CACZ,GAAGhI,EACH,OAAQ,CAACI,CAAK,EACd,QAAS,CAAE,aAAcA,EAAM,EAAG,CACpC,EACA,MAAO,CAACrH,GAAmBiP,CAAK,CAAC,CAAC,KAAM,GAAUT,EAAM,OAAS,uBAAuB,CAC1F,CAAC,EAQUU,IAAkB,EAA8B,IAA6C,CACxG,IAAMtC,EAAO,CAAE,GAAG3F,EAAY,OAAQ,CAAC,GAAGA,EAAW,OAAQI,CAAK,CAAE,EAK9D8H,EAHJlI,EAAW,QAAQ,eAAiB,IAAA,IACpC+H,EAAqB/H,CAAU,CAAC,CAAC,SAAW,GAC5C+H,EAAqBpC,CAAI,CAAC,CAAC,KAAM,GAAcwC,EAAU,KAAO/H,EAAM,EAAE,EAC5C,CAAE,GAAGuF,EAAM,QAAS,CAAE,GAAGA,EAAK,QAAS,aAAcvF,EAAM,EAAG,CAAE,EAAIuF,EAQlG,OANEuC,EAAO,OAAS,aAChBA,EAAO,QAAQ,iBAAmB,IAAA,IAClC,CAACxP,EAAiB0H,CAAK,EAEhB8H,EAEF,CACL,GAAGA,EACH,QAAS,CAAE,GAAGA,EAAO,QAAS,eAAgB,CAAC,GAAGA,EAAO,QAAQ,eAAgB9H,EAAM,EAAE,CAAE,CAC7F,CACF,EAYagI,IAAuB,EAAwB,IAA8C,CACxG,IAAMC,EAAS7O,GAAgB8O,CAAK,EAC9BC,EAAaF,EAAO,OAAO,KAAM,GAAcF,EAAU,KAAO/H,EAAM,EAAE,EAS9E,MAAO,CAAE,aAAY,KAPnBiI,EAAO,OAAO,KAAOjI,EAAM,GACvB,QACAkI,EAAM,QAAQ,eAAiBlI,EAAM,IAAMiI,EAAO,OAAO,KAAOjI,EAAM,GACpE,QACAmI,GAAcF,EAAO,OAAO,SAAW,EACrC,OACA,IAAA,EACgB,CAC5B,EAOaG,IACX,EACA,EACA,IACoB,CAEpB,IAAMC,EADUjP,GAAgB8O,CAAK,CAAC,CAAC,OAAO,IAAK,GAAUlI,EAAM,EACnD,CAAA,CAAQ,OAAQ,GAAOR,IAAOU,CAAO,EACjDqF,EAAO8C,EACX,GAAIF,EAAY,CACd,IAAMG,EAAQ,IAAI,IAAIJ,EAAM,OAAO,KAAK,EAAO,IAAU,CAAClI,EAAM,GAAIwH,CAAK,CAAC,CAAC,EACrEe,EAAWD,EAAM,IAAIpI,CAAO,GAAKgI,EAAM,OAAO,OAC9CM,EAASH,EAAQ,UAAW,IAAQC,EAAM,IAAI9I,CAAE,GAAK,GAAK+I,CAAQ,EACxE,EACEC,IAAW,GACP,CAAC,GAAGH,EAASnI,CAAO,EACpB,CAAC,GAAGmI,EAAQ,MAAM,EAAGG,CAAM,EAAGtI,EAAS,GAAGmI,EAAQ,MAAMG,CAAM,CAAC,CACvE,CACA,IAAMvC,EAAUX,EAAQ4C,EAAM,QAAS,iBAAkB3C,EAAK,OAAS,EAAIA,EAAO,IAAA,EAAS,EAC3F,OAAOY,EAAY,CAAE,GAAG+B,EAAO,SAAQ,CAAC,CAC1C,EAcaO,GAAyB,GAAkD,CACtF,IAAMC,EAAOR,EAAM,OAAO,OAAQ,GAAU,CAAClI,EAAM,UAAU,EACvDiI,EAAS7O,GAAgB8O,CAAK,EAC9BzB,EAASwB,EAAO,OAAO,IAAK,GAAUjI,EAAM,EAAE,EAC9CkH,EAASwB,EAAK,OAAQ,GAAUpQ,EAAiB0H,CAAK,GAAK,CAACyG,EAAO,SAASzG,EAAM,EAAE,CAAC,EAC3F,MAAO,CACL,aAAc0I,EAAK,OAAO3Q,CAAe,EACzC,cAAe,CAAC,GAAGkQ,EAAO,OAAQ,GAAGf,CAAM,EAC3C,SACA,aAAce,EAAO,UACvB,CACF,ECjHMU,GAAgC,IAAI,IAAI3P,GAAwB,IAAIN,EAAU,CAAC,EAMxEkQ,IACX,EACA,IACsC,CACtC,IAAMC,EAAS,IAAI,IAAIjJ,EAAW,OAAO,IAAK,GAAUI,EAAM,KAAK,CAAC,EAC9D8I,EAAU,IAAI,IAAIlJ,EAAW,OAAO,IAAK,GAAUlH,GAAWsH,EAAM,MAAM,CAAC,CAAC,EAClF,IAAK,IAAI+I,EAAS,GAAK,GAAU,EAAG,CAClC,IAAMC,EAAQD,IAAW,EAAIE,EAAY,GAAGA,EAAU,GAAGF,IACnDG,EAASzK,GAAauK,CAAK,EAC3BG,EAASzQ,GAAWwQ,CAAM,EAChC,GAAI,CAACL,EAAO,IAAIG,CAAK,GAAK,CAACF,EAAQ,IAAIK,CAAM,GAAK,CAACR,GAAS,IAAIQ,CAAM,EACpE,MAAO,CAAE,QAAO,QAAO,CAE3B,CACF,EAQaC,IACX,EACA,EACA,IACqB,CACrB,IAAMC,EAAUzJ,EAAW,OAAO,KAAM,GAAUI,EAAM,KAAOE,CAAO,EACtE,GAAI,CAACmJ,GAAWA,EAAQ,OAASC,EAC/B,OAAO1J,EAET,IAAM2J,EAAQpE,GAAYvF,EAAY,CAAE,OAAM,MAAOyJ,EAAQ,MAAO,OAAQA,EAAQ,MAAO,CAAC,EACtF,CAAE,aAAcG,EAAe,GAAG/G,GAAS4G,EAC3C9D,EAAO,CAAE,GAAG9C,EAAM,OAAM,SAAU8G,EAAM,SAAU,OAAQA,EAAM,MAAO,EACvE/G,EAAS5C,EAAW,OAAO,IAAK,GAAWI,EAAM,KAAOE,EAAUqF,EAAOvF,CAAM,EAC/EkH,EAAS,CAAE,GAAGtH,EAAY,OAAQA,EAAW,OAAO,OAAQ,GAAUI,EAAM,KAAOE,CAAO,CAAE,EAC5F+F,EAAmC,CAAE,GAAGrG,EAAW,OAAQ,EAC3D6J,EAAS,CAAE,GAAG7J,EAAY,SAAQ,SAAQ,EAC1C8J,EAAc/B,EAAqB8B,CAAM,CAAC,CAAC,KAAM,GAAc1B,EAAU,KAAO7H,CAAO,EAM7F,OALI+F,EAAQ,eAAiB/F,GAAW,CAACwJ,EACvC,OAAOzD,EAAQ,aACNA,EAAQ,eAAiB,IAAA,IAAayD,GAAe/B,EAAqBT,CAAM,CAAC,CAAC,SAAW,IACtG,EAAQ,aAAehH,GAElBuJ,CACT,EAMaE,IACX,EACA,EACA,EACA,IACqB,CACrB,IAAMpE,EAAO6D,GAAcxJ,EAAYM,EAASoJ,CAAI,EACpD,GAAIM,GAAO,OAASN,EAClB,OAAO/D,EAET,GAAM,CAAE,WAAU,UAAWqE,EACvBC,EAAgBD,EAAqC,aAC3D,MAAO,CACL,GAAGrE,EACH,OAAQA,EAAK,OAAO,IAAK,GACvBvF,EAAM,KAAOE,EACR,CACC,GAAGF,EACH,WACA,SACA,GAAI6J,IAAiB,IAAA,GAAY,CAAC,EAAI,CAAE,cAAa,CACvD,EACA7J,CACN,CACF,CACF,ECpFa8J,GAAsB,mBAGtBC,GAAkB,GAAoB,SAAS7J,EAAQ,QAE9D8J,GAAe,GAAoB,sBAAsBC,CAAG,EAOrDC,OAAoB,CAC/B,GAAM,CAAE,KAAM9T,EAAe,EACvB+T,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDuK,EAAS3K,EAAyB,GAAUI,EAAM,MAAM,EACxD,CAACwK,EAAOC,IAAA,EAAYnW,EAAAA,SAAAA,CAAiC,IAAI,EAmC/D,MAAO,CAAE,QAjCS,CAChB,GAAM,CAAE,SAAUsL,EAAwB,SAAS,EACnD,GAAI,CAAC+D,EACH,OAEF,IAAMxD,EAAQmF,GAAY3B,EAAO,CAC/B,KAAM,SACN,GAAGoF,GAAmBpF,EAAO/C,EAAE,yBAAyB,CAAC,CAC3D,CAAC,EACD0J,EAAQ,GAAYtC,GAAewB,EAASrJ,CAAK,CAAC,EAClDoK,EAAO,CAAE,KAAM,QAAS,QAASpK,EAAM,EAAG,CAAC,EAC3CsK,EAAStK,CAAK,EACdgK,OAAkB,CAChB,IAAM3E,EAAQ,SAAS,eAAe0E,GAAe/J,EAAM,EAAE,CAAC,EAC1DqF,aAAiB,mBACnBA,EAAM,eAAe,CAAE,MAAO,QAAS,CAAC,EACxCA,EAAM,MAAM,CAAE,cAAe,EAAK,CAAC,EACnCA,EAAM,OAAO,EAEjB,CAAC,CACH,EAac,YAVO,GACnBgF,IAAU,MAAQrK,EAAM,KAAOqK,EAAM,IAAMpR,EAAc+G,CAAK,IAAM/G,EAAcoR,CAAK,EAS9D,QAPV,GAAoB,CACnCF,EAAQ,GAAYnE,GAAYqD,EAASnJ,CAAO,CAAC,EACjDkK,EAAO,CAAE,KAAM,YAAa,CAAC,EAC7BE,EAAS,IAAI,EACbN,OAAkB,SAAS,eAAeF,EAAmB,CAAC,EAAE,MAAM,CAAC,CACzE,CAEmC,CACrC,ECxCMS,GAAgB,CACpB,SAAU,uBACV,QAAS,qBACX,EAMaC,IAAkB,CAAE,WAAU,QAAO,SAA+B,CAC/E,GAAM,CAAE,KAAMpU,EAAe,EACvBqU,GAAA,EAASrW,EAAAA,MAAAA,CAAM,EACf,CAACsW,EAAYC,IAAA,EAAiBtW,EAAAA,SAAAA,CAAS,EAAK,EAC5CuW,GACJ,EAAArK,EAAA,KAAA,CAACpG,EAAD,CACE,GAAI2P,GACJ,KAAK,SACL,KAAK,KACL,QAASe,EACC,WACV,UAAWC,EAAM,iBAAmB,IAAA,GANtC,SAAA,EAQE,EAAAvK,EAAA,IAAA,CAACzD,GAAD,CAAM,cAAY,MAAQ,CAAA,EACzB2D,EAAE,yBAAyB,CACtB,IAEV,GAAI,CAACqK,EACH,OAAOF,EAET,GAAM,CAAE,gBAAiBE,EACnBC,EAAOC,IAAiB,YAAcA,IAAiB,UAAYT,GAAcS,GAAgB,KACvG,OACE,EAAAzK,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,OAAf,SAAA,CACGqK,GACD,EAAArK,EAAA,KAAA,CAAC1D,GAAD,CAAA,SAAA,EACE,EAAA0D,EAAA,IAAA,CAAC9E,GAAD,CACE,KAAK,UACL,KAAMiP,EACN,aAAcC,EACd,MAAOlK,EAAE,yBAAyB,EAClC,YAAaA,EAAE,+BAA+B,EAC9C,aAAcA,EAAE,oBAAoB,EACpC,aAAcA,EAAE,sBAAsB,EACtC,UAAWqK,EAAI,aAEf,UAAA,EAAAvK,EAAA,IAAA,CAAC5D,GAAD,CAAqB,QAAA,GACnB,UAAA,EAAA4D,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,KAAK,UACK,WACV,aAAYsG,EAAE,kBAAkB,EAChC,UAAU,uDAEV,UAAA,EAAAF,EAAA,IAAA,CAACrF,GAAD,CAAa,cAAY,MAAQ,CAAA,CAC3B,CAAA,CACW,CAAA,CACR,CAAA,GACf,EAAAqF,EAAA,KAAA,CAAC3D,GAAD,CACE,MAAM,MACN,UAAU,OACV,iBAAmB,GAAU8N,GAAcO,EAAM,eAAe,EAHlE,SAAA,EAKE,EAAA1K,EAAA,KAAA,CAAC7D,GAAD,CAAkB,SAAUmO,EAA5B,SAAA,EACE,EAAAtK,EAAA,IAAA,CAACzD,GAAD,CAAM,cAAY,MAAQ,CAAA,EACzB2D,EAAE,mBAAmB,CACN,KAClB,EAAAF,EAAA,KAAA,CAAC7D,GAAD,CACE,SAAUsO,IAAiB,SAAWA,IAAiB,SACvD,mBAAkBD,EAAON,EAAS,IAAA,GAClC,aAAiBO,IAAiB,SAAWL,EAAc,EAAI,EAAIG,EAAI,IAAI,EAH7E,SAAA,EAKE,EAAAvK,EAAA,IAAA,CAAChE,GAAD,CAAQ,cAAY,MAAQ,CAAA,EAC3BkE,EAAE,uBAAuB,CACV,IACjBsK,GACC,EAAAxK,EAAA,IAAA,CAAC,IAAD,CAAG,GAAIkK,EAAQ,UAAU,mDACtB,SAAAhK,EAAEsK,CAAI,CACN,CAAA,EACD,IACe,CACT,CAAA,CAAA,CAAA,CAAA,CACX,GAET,ECvGaG,GAAc,GAAoB,gBAAgBhL,IC+BlDiL,IAAO,CAClB,QACA,QACA,QACA,WACA,YACA,gBACA,aACA,WACA,WACA,SACA,cACA,aACA,SACA,eACc,CACd,GAAM,CAAE,KAAM/U,EAAe,EACvBgV,EAAO3Q,GAAgBuF,EAAM,MAUnC,OACE,EAAAO,EAAA,KAAA,CAAC,KAAD,CACE,UAAW,CAAC8K,EACC,cACD,aACJ,SACG,YACX,gBAAeC,GAAY,IAAA,GAC3B,UAAW/U,EACT,mJACAgV,GAAc,8BAChB,EAVF,SAAA,EAYE,EAAAhL,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,GAAI2K,GAAWlL,EAAM,EAAE,EACvB,aAAYS,EAAE,yBAA0B,CAAE,MAAOT,EAAM,KAAM,CAAC,EAC9D,mBAAiB,qBACjB,UA3BmB,GAAyB,CAC5CiL,EAAM,MAAQ,WAAazD,EAAQ,GACrCyD,EAAM,eAAe,EACrBO,EAAOhE,EAAQ,CAAC,GACPyD,EAAM,MAAQ,aAAezD,EAAQiE,EAAQ,IACtDR,EAAM,eAAe,EACrBO,EAAOhE,EAAQ,CAAC,EAEpB,EAoBgB,WACV,UAAU,oNAEV,UAAA,EAAAjH,EAAA,IAAA,CAAC/D,GAAD,CAAc,UAAU,SAAS,cAAY,MAAQ,CAAA,CAC/C,CAAA,GACR,EAAA+D,EAAA,KAAA,CAAC,SAAD,CACE,KAAK,SACL,QAASmL,EACT,eAAcJ,GAAY,IAAA,GAC1B,UAAU,4IAJZ,SAAA,EAME,EAAA/K,EAAA,IAAA,CAAC6K,EAAD,CACE,UAAW7U,EAAG,wCAAyC+U,GAAY,wBAAwB,EAC3F,cAAY,MACb,CAAA,GACD,EAAA/K,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,+BAAhB,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,qCAAsC,SAAAP,EAAM,KAAY,CAAA,GACxE,EAAAO,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,0DAA2D,SAAAP,EAAM,MAAa,CAAA,CAC1F,KACN,EAAAO,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,mCAAhB,SAAA,CACGP,EAAM,UAAW,EAAAO,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,UAAW,SAAAgJ,EAAE,8BAA8B,CAAS,CAAA,EAAI,KACxFkL,GAAiB3L,EAAM,WACtB,EAAAO,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,UAAW,SAAAgJ,EAAE,+BAA+B,CAAS,CAAA,EAClE,KACHT,EAAM,OAAS,MACd,EAAAO,EAAA,KAAA,CAAC,OAAD,CAAM,MAAOE,EAAE,4BAA4B,EAA3C,SAAA,EACE,EAAAF,EAAA,IAAA,CAACzB,GAAD,CAAQ,UAAU,+BAA+B,cAAY,MAAQ,CAAA,GACrE,EAAAyB,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,UAAW,SAAAE,EAAE,4BAA4B,CAAQ,CAAA,CAC7D,IAEPmL,GACC,EAAArL,EAAA,KAAA,CAAC,OAAD,CAAM,MAAOE,EAAE,4BAA4B,EAA3C,SAAA,EACE,EAAAF,EAAA,IAAA,CAACjM,GAAD,CAAa,UAAU,0BAA0B,cAAY,MAAQ,CAAA,GACrE,EAAAiM,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,UAAW,SAAAE,EAAE,4BAA4B,CAAQ,CAAA,CAC7D,CACJ,CAAA,EAAA,IACA,GACA,KACR,EAAAF,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,gFAAhB,SAAA,EACE,EAAAA,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,UACL,SAAU,GACV,SAAUkR,GAAY7D,IAAU,EAChC,aAAY/G,EAAE,wBAAyB,CAAE,MAAOT,EAAM,KAAM,CAAC,EAC7D,YAAewL,EAAOhE,EAAQ,CAAC,EAE/B,UAAA,EAAAjH,EAAA,IAAA,CAACvF,GAAD,CAAW,cAAY,MAAQ,CAAA,CACzB,CAAA,GACR,EAAAuF,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,UACL,SAAU,GACV,SAAUkR,GAAY7D,IAAUiE,EAAQ,EACxC,aAAYhL,EAAE,0BAA2B,CAAE,MAAOT,EAAM,KAAM,CAAC,EAC/D,YAAewL,EAAOhE,EAAQ,CAAC,EAE/B,UAAA,EAAAjH,EAAA,IAAA,CAACrF,GAAD,CAAa,cAAY,MAAQ,CAAA,CAC3B,CAAA,CACJ,GACJ,GAER,ECxHM2Q,GAA+B,CAAC,EAGzBC,IAAa,CAAE,SAAQ,WAAU,QAAO,SAA0B,CAC7E,GAAM,CAAE,KAAM1V,EAAe,EACvBoM,EAAS/C,EAAyB,GAAUI,EAAM,OAAO,QAAUgM,EAAS,EAC5EE,EAAYtM,EACf,GAAUI,EAAM,OAAO,OAAS,aAAeA,EAAM,OAAO,YAAc,EAC7E,EACME,EAAYN,EAAyB,GAAUI,EAAM,SAAS,EAC9DuK,EAAS3K,EAAyB,GAAUI,EAAM,MAAM,EACxDsK,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDmM,GAAA,EAAWzX,EAAAA,OAAAA,CAAsB,IAAI,EACrC,CAAC0X,EAAWC,IAAA,EAAgB1X,EAAAA,SAAAA,CAAwB,IAAI,EACxD,CAAC2X,EAAcC,IAAA,EAAmB5X,EAAAA,SAAAA,CAAS,EAAE,EAE7C6X,GAAQ,EAAc,EAAY,IAAqB,CAC3D,IAAMtG,EAAQvD,EAAOoD,GAChBG,GAASH,IAASC,IAIvBsE,EAAQ,GAAUhE,EAAY,CAAE,GAAG3C,EAAO,OAAQmC,GAASnC,EAAM,OAAQoC,EAAMC,CAAE,CAAE,CAAC,CAAC,EACrFuG,EACE3L,EAAE,uBAAwB,CAAE,MAAOsF,EAAM,MAAO,SAAUF,EAAK,EAAG,MAAOrD,EAAO,MAAO,CAAC,CAC1F,EACI8J,GAEF,0BAA4B,SAAS,eAAepB,GAAWnF,EAAM,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,EAEtF,EACMwG,EAAmBnF,EAAYC,EAAQ,SAAS,CAAC,CAAC,OACrD,GAAU,CAAC,iBAAiB,KAAKF,EAAM,IAAI,CAC9C,EAEMqF,EAAQ/L,EAAE,wBAAyB,CAAE,MAAO+B,EAAO,MAAO,CAAC,EACjE,OACE,EAAAjC,EAAA,KAAA,CAACjC,GAAD,CACE,MAAOmC,EAAE,4BAA4B,EACrC,MAAA,GACA,SACE,EAAAF,EAAA,KAAA,CAAA9L,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA8L,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,YAAY,cAAY,OACpC,SAAA+K,EAAO,MACH,CAAA,GACP,EAAAjC,EAAA,IAAA,CAACiK,GAAD,CAA0B,WAAiB,QAAY,KAAM,CAAA,CAC7D,CAAA,CAAA,EAEJ,cAAc,MAXhB,SAAA,CAaG+B,EAAiB,OAAS,GACzB,EAAAhM,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,YACb,UAAA,EAAAA,EAAA,IAAA,CAACkH,EAAD,CAAW,OAAQ8E,CAAmB,CAAA,CACnC,CAAA,EACH,KACH/J,EAAO,SAAW,GACjB,EAAAjC,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,wDACV,SAAAE,EAAE,yBAAyB,CAC3B,CAAA,GAEH,EAAAF,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,cAAc,aAAYiM,EACrC,SAAAhK,EAAO,KAAK,EAAO,KAClB,EAAAjC,EAAA,IAAA,CAAC4K,GAAD,CAES,QACA,QACP,MAAO3I,EAAO,OACd,SAAUzC,EAAU,OAAS,SAAWA,EAAU,UAAYC,EAAM,GACpE,UAAWoH,EAAYC,EAAQE,GAAUC,CAAK,CAAC,CAAC,CAAC,OAAS,EAC1D,cAAeuE,EACf,WAAYE,IAAczE,EAChB,WACV,aAAgB4C,EAAO,CAAE,KAAM,QAAS,QAASpK,EAAM,EAAG,CAAC,EAC3D,OAAS,GAAOqM,EAAK7E,EAAO3B,EAAI,EAAI,EACpC,YAAc,GAAU,CACtB,EAAS,QAAU2B,EACnB,EAAM,aAAa,cAAgB,OACnCyD,EAAM,aAAa,QAAQ,aAAcjL,EAAM,EAAE,CACnD,EACA,WAAa,GAAU,CACjBgM,EAAS,UAAY,OACvBf,EAAM,eAAe,EACrBiB,EAAa1E,CAAK,EAEtB,EACA,OAAS,GAAU,CACjByD,EAAM,eAAe,EACjBe,EAAS,UAAY,MACvBK,EAAKL,EAAS,QAASxE,EAAO,EAAK,EAErC,EAAS,QAAU,KACnB0E,EAAa,IAAI,CACnB,EACA,cAAiB,CACf,EAAS,QAAU,KACnBA,EAAa,IAAI,CACnB,CACD,EAlCMlM,EAAM,EAkCZ,CACF,CACC,CAAA,GAEN,EAAAO,EAAA,IAAA,CAAC,IAAD,CAAG,GAAG,qBAAqB,UAAU,UAClC,SAAAE,EAAE,4BAA4B,CAC9B,CAAA,GACH,EAAAF,EAAA,IAAA,CAAC,IAAD,CAAG,YAAU,SAAS,UAAU,UAC7B,SAAA4L,CACA,CAAA,CACE,GAEX,EChIMM,GAA0C,IAAI,IAAI,CACtD,SACA,OACA,OACA,QACA,MACA,MACA,OACA,WACA,OACA,UACA,YACF,CAAC,EAGYC,GAAwB,GACnCD,GAAmB,IAAIzM,EAAM,IAAI,GACjCA,EAAM,OAAS,UACfA,EAAM,OAAS,WACfA,EAAM,OAAS,WACdA,EAAM,OAAS,QAAU,CAACA,EAAM,SAAS,SCP/B2M,IACX,EACA,CAAE,OAAM,cAAa,SAAS,CAAC,KAC5B,CACH,IAAM/H,EAASgI,EAAO,GAAGpN,EAAG,OAAS,IAAA,GAC/BqN,EAAgBC,EAAc,GAAGtN,EAAG,cAAgB,IAAA,GACpDuN,EAAU1F,EAAO,OAAS,EAAI,GAAG7H,EAAG,QAAU,IAAA,GACpD,MAAO,CAAE,SAAQ,gBAAe,UAAS,YAAanC,GAAYuH,EAAQiI,EAAeE,CAAO,CAAE,CACpG,ECNaC,GAAe,CAC1B,KACA,QACA,OACA,cACA,SAAS,CAAC,EACV,WACA,QACA,WACA,mBAAmB,GACnB,YAAY,GACZ,YAAY,GACZ,eACsB,CACtB,IAAMzK,EAAMoK,GAAWnN,EAAI,CAAE,OAAM,cAAa,QAAO,CAAC,EAClDqF,EAAS,CACb,KACA,MAAO7C,GAAS,GAChB,WACA,YACA,eAAgBqF,EAAO,OAAS,GAAK,IAAA,GACrC,mBAAoB9E,EAAI,YACxB,SAAW,GACT0K,EAASC,GAAoBjC,EAAM,OAAO,QAAU,GAAK,IAAA,GAAYA,EAAM,OAAO,KAAK,CAC3F,EACA,OACE,EAAA1K,EAAA,KAAA,CAACzG,EAAD,CAAO,eAAcuN,EAAO,OAAS,GAAK,IAAA,GAA1C,SAAA,EACE,EAAA9G,EAAA,IAAA,CAAChD,GAAD,CAAa,QAASiC,EAAW,QAAa,OAAM,OAAQ+C,EAAI,MAAS,CAAA,EACxE4K,GACC,EAAA5M,EAAA,IAAA,CAAClC,GAAD,CAAU,GAAIwG,EAAQ,KAAM,CAAI,CAAA,GAEhC,EAAAtE,EAAA,IAAA,CAAClG,GAAD,CACE,GAAIwK,EACJ,aAAa,MACb,WAAY,CAACuI,EACb,UAAW7W,EAAG6W,GAAa,WAAW,CACvC,CAAA,EAEFN,GAAc,EAAAvM,EAAA,IAAA,CAAC7G,EAAD,CAAkB,GAAI6I,EAAI,cAAgB,SAAAuK,CAA8B,CAAA,EAAI,MAC3F,EAAAvM,EAAA,IAAA,CAACkH,EAAD,CAAW,GAAIlF,EAAI,QAAiB,QAAS,CAAA,CACxC,GAEX,ECtCM8K,GAAQ3S,GAAiB,QAAS,GAAUwL,EAAM,KAAK,EAEvDoH,GAAc,GACjBpV,EAAiC,SAAS8J,CAAK,EAOrCuL,IAAY,CACvB,aACA,QACA,cACA,oBACA,QACA,cACA,WACA,cACmB,CACnB,GAAM,CAAE,KAAMnX,EAAe,EACvByW,GAAA,EAAgBnY,EAAAA,MAAAA,CAAM,EAC5B,OACE,EAAA6L,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACpD,GAAD,CACS,QACG,WACV,cAAgB,GAASmQ,GAAW/H,CAAI,GAAK0H,EAAS1H,CAAI,EAC1D,kBAAiBiI,EACjB,mBAAkBX,EAClB,UAAU,oCAET,SAAAQ,GAAM,IAAK,IACV,EAAA9M,EAAA,IAAA,CAAC3B,GAAD,CAEE,MAAO0K,EACP,QAAQ,OACR,KAAM7O,GAAgB6O,GACtB,MAAO7I,EAAE,oBAAoB6I,EAAK,MAAM,EACxC,SAAUmE,EAAY,IAAInE,CAAI,EAC9B,YACEmE,EAAY,IAAInE,CAAI,EAAIoE,EAAkBpE,CAAI,EAAI7I,EAAE,oBAAoB6I,EAAK,aAAa,CAE7F,EATMA,CASN,CACF,CACS,CAAA,GACZ,EAAA/I,EAAA,KAAA,CAAC,IAAD,CAAG,GAAIsM,EAAe,UAAU,kCAAhC,SAAA,EACE,EAAAtM,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,gCAAiC,SAAAE,EAAE,oBAAoBuB,EAAM,MAAM,CAAQ,CAAA,EAC1F,MACAvB,EAAE,oBAAoBuB,EAAM,aAAa,CACzC,IACF2L,EAAM,OAAS,GACd,EAAApN,EAAA,IAAA,CAAC,IAAD,CAAG,KAAK,SAAS,UAAU,qCACxB,SAAAoN,EAAM,KAAK,GAAG,CACd,CAAA,EACD,KACHC,GAAc,EAAArN,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,kCAAmC,SAAAqN,CAAe,CAAA,EAAI,IAC/E,GAET,EClEMC,IAAS,EAAc,IAAyC,CACpE,GAAIC,EAAK,KAAK,IAAM,GAClB,OAEF,IAAM9G,EAAS,OAAO8G,CAAI,EAC1B,GAAK,OAAO,SAAS9G,CAAM,EAG3B,OAAO+G,EAAU,KAAK,MAAM/G,CAAM,EAAIA,CACxC,EAGagH,IAAiB,CAC5B,KACA,QACA,OACA,cACA,SAAS,CAAC,EACV,WACA,QACA,WACA,UAAU,GACV,MACA,SACwB,CAExB,GAAM,CAACF,EAAMG,IAAA,EAAWtZ,EAAAA,SAAAA,CAASqN,IAAU,IAAA,GAAY,GAAK,OAAOA,CAAK,CAAC,EACnE,CAACkM,EAAYC,IAAA,EAAiBxZ,EAAAA,SAAAA,CAASqN,CAAK,EAE9CA,IAAUkM,IACZC,EAAcnM,CAAK,EACf6L,GAAMC,EAAMC,CAAO,IAAM/L,GAC3BiM,EAAQjM,IAAU,IAAA,GAAY,GAAK,OAAOA,CAAK,CAAC,GAGpD,IAAMO,EAAMoK,GAAWnN,EAAI,CAAE,OAAM,cAAa,QAAO,CAAC,EACxD,OACE,EAAAe,EAAA,KAAA,CAACzG,EAAD,CAAO,eAAcuN,EAAO,OAAS,GAAK,IAAA,GAA1C,SAAA,EACE,EAAA9G,EAAA,IAAA,CAAChD,GAAD,CAAa,QAASiC,EAAW,QAAa,OAAM,OAAQ+C,EAAI,MAAS,CAAA,GACzE,EAAAhC,EAAA,IAAA,CAAClG,GAAD,CACM,KACJ,KAAK,SACL,UAAW0T,EAAU,UAAY,UACjC,KAAMA,EAAU,EAAI,MACf,MACA,MACL,MAAOD,EACG,WACV,eAAczG,EAAO,OAAS,GAAK,IAAA,GACnC,mBAAkB9E,EAAI,YACtB,SAAW,GAAU,CACnB,IAAMgD,EAAOsI,GAAM5C,EAAM,OAAO,MAAO8C,CAAO,EAC9CE,EAAQhD,EAAM,OAAO,KAAK,EAC1BkD,EAAc5I,CAAI,EAClB0H,EAAS1H,CAAI,CACf,CACD,CAAA,EACAuH,GAAc,EAAAvM,EAAA,IAAA,CAAC7G,EAAD,CAAkB,GAAI6I,EAAI,cAAgB,SAAAuK,CAA8B,CAAA,EAAI,MAC3F,EAAAvM,EAAA,IAAA,CAACkH,EAAD,CAAW,GAAIlF,EAAI,QAAiB,QAAS,CAAA,CACxC,GAEX,ECpEM6L,GAAQ,YAWDC,GAAiB,CAC5B,KACA,QACA,OACA,cACA,SAAS,CAAC,EACV,WACA,QACA,UACA,WACA,aACA,iBACwB,CACxB,GAAM,CAAE,KAAMjY,EAAe,EACvBmM,EAAMoK,GAAWnN,EAAI,CAAE,OAAM,cAAa,QAAO,CAAC,EAClD8O,EAAQtM,IAAU,IAAA,IAAauM,EAAQ,KAAM,GAAWC,EAAO,QAAUxM,CAAK,EACpF,OACE,EAAAzB,EAAA,KAAA,CAACzG,EAAD,CAAO,eAAcuN,EAAO,OAAS,GAAK,IAAA,GAA1C,SAAA,EACE,EAAA9G,EAAA,IAAA,CAAChD,GAAD,CAAa,QAASiC,EAAW,QAAa,OAAM,OAAQ+C,EAAI,MAAS,CAAA,GACzE,EAAAhC,EAAA,KAAA,CAACpF,GAAD,CACE,MAAOmT,EAAQtM,EAAQyM,EAAaL,GAAQ,GAC5C,cAAgB,GAASnB,EAAS1H,IAAS6I,GAAQ,IAAA,GAAY7I,CAAI,EACzD,WAHZ,SAAA,EAKE,EAAAhF,EAAA,IAAA,CAACzF,GAAD,CACM,KACJ,UAAU,SACV,eAAcuM,EAAO,OAAS,GAAK,IAAA,GACnC,mBAAkB9E,EAAI,YAEtB,UAAA,EAAAhC,EAAA,IAAA,CAAC1F,GAAD,CAAa,YAAa6T,GAAejO,EAAE,eAAe,CAAI,CAAA,CACjD,CAAA,GACf,EAAAF,EAAA,KAAA,CAACxF,GAAD,CAAA,SAAA,CACG0T,GAAa,EAAAlO,EAAA,IAAA,CAACtF,GAAD,CAAY,MAAOmT,GAAQ,SAAAK,CAAuB,CAAA,EAAI,KACnEF,EAAQ,IAAK,IACZ,EAAAhO,EAAA,IAAA,CAACtF,GAAD,CAA+B,MAAOuT,EAAO,MAC1C,SAAAA,EAAO,KACE,EAFKA,EAAO,KAEZ,CACb,CACY,CAAA,CAAA,CACT,IACP1B,GAAc,EAAAvM,EAAA,IAAA,CAAC7G,EAAD,CAAkB,GAAI6I,EAAI,cAAgB,SAAAuK,CAA8B,CAAA,EAAI,MAC3F,EAAAvM,EAAA,IAAA,CAACkH,EAAD,CAAW,GAAIlF,EAAI,QAAiB,QAAS,CAAA,CACxC,GAEX,EClDaoM,IAAgB,CAAE,QAAO,SAAQ,WAAU,cAAkC,CACxF,GAAM,CAAE,KAAMvY,EAAe,EACvBwY,EAAS,CACb,GAAI,SAAS5O,EAAM,GAAG,UACtB,MAAOS,EAAE,6BAA6B,EACtC,KAAMA,EAAE,iCAAiC,EACzC,SACA,UACF,EACMuB,EAAQhC,EAAM,aAsCpB,OArCIA,EAAM,OAAS,UAAYA,EAAM,OAAS,WAE1C,EAAAO,EAAA,IAAA,CAACyN,GAAD,CACE,GAAIY,EACJ,QAAS5O,EAAM,OAAS,UACxB,MAAO,OAAOgC,GAAU,SAAWA,EAAQ,IAAA,GACjC,UACX,CAAA,EAGDhC,EAAM,OAAS,WAEf,EAAAO,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAIO,EACJ,MAAO,OAAO5M,GAAU,UAAY,OAAOA,CAAK,EAAI,IAAA,GACpD,QAAS,CACP,CAAE,MAAO,OAAQ,MAAOvB,EAAE,4BAA4B,CAAE,EACxD,CAAE,MAAO,QAAS,MAAOA,EAAE,6BAA6B,CAAE,CAC5D,EACA,WAAYA,EAAE,eAAe,EAC7B,SAAW,GAASwM,EAAS1H,IAAS,IAAA,GAAY,IAAA,GAAYA,IAAS,MAAM,CAC9E,CAAA,EAGDvF,EAAM,OAAS,QAEf,EAAAO,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAIO,EACJ,MAAO,OAAO5M,GAAU,SAAWA,EAAQ,IAAA,GAC3C,QAAShC,EAAM,SAAS,OACrB,OAAQ,GAAU8G,EAAM,QAAU,EAAE,CAAC,CACrC,IAAK,IAAW,CAAE,MAAOA,EAAM,MAAO,MAAOA,EAAM,OAASA,EAAM,KAAM,EAAE,EAC7E,WAAYrG,EAAE,eAAe,EACnB,UACX,CAAA,GAIH,EAAAF,EAAA,IAAA,CAACyM,EAAD,CACE,GAAI4B,EACJ,MAAO,OAAO5M,GAAU,SAAWA,EAAQ,IAAA,GACjC,WACV,iBAAA,EACD,CAAA,CAEL,ECtCM6M,GAAe,GACnB5H,GAAQ,MAAM,MAAO,GAAU,OAAOjF,GAAU,QAAQ,EAAKiF,EAAO,KAAoB,IAAA,GAE7E6H,GAAmB,GAAwC,CACtE,IAAMP,EAAUM,GAAY5H,CAAM,EAClC,GAAIsH,EACF,MAAO,CAAE,KAAM,SAAU,SAAQ,EAEnC,OAAQtH,EAAO,KAAf,CACE,IAAK,UACH,MAAO,CAAE,KAAM,SAAU,EAC3B,IAAK,UACH,MAAO,CACL,KAAM,UACN,GAAIA,EAAO,UAAY,IAAA,GAA0C,CAAC,EAA/B,CAAE,QAASA,EAAO,OAAQ,EAC7D,GAAIA,EAAO,UAAY,IAAA,GAA0C,CAAC,EAA/B,CAAE,QAASA,EAAO,OAAQ,CAC/D,EACF,IAAK,SACH,MAAO,CAAE,KAAM,SAAU,GAAIA,EAAO,UAAY,IAAA,GAA0C,CAAC,EAA/B,CAAE,QAASA,EAAO,OAAQ,CAAQ,EAChG,IAAK,SACH,MAAO,CAAE,KAAM,OAAQ,GAAIA,EAAO,YAAc,IAAA,GAA8C,CAAC,EAAnC,CAAE,UAAWA,EAAO,SAAU,CAAQ,EACpG,IAAK,QAAS,CACZ,IAAM8H,EAAcF,GAAY5H,EAAO,KAAK,EAI5C,OAHI8H,EACK,CAAE,KAAM,UAAW,QAASA,CAAY,EAE1C9H,EAAO,OAAO,OAAS,SAAW,CAAE,KAAM,UAAW,EAAI,CAAE,KAAM,OAAQ,CAClF,CACA,QACE,MAAO,CAAE,KAAM,OAAQ,CAC3B,CACF,EAGa+H,GAAsB,GAAyC,CAC1E,IAAMC,EAAShI,EACTiI,EAAW,IAAI,IAAID,EAAO,UAAY,CAAC,CAAC,EAC9C,OAAO,OAAO,QAAQA,EAAO,YAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAACtP,EAAKwP,MAAe,CACvE,MACA,QAASL,GAAgBK,CAAQ,EACjC,SAAUD,EAAS,IAAIvP,CAAG,CAC5B,EAAE,CACJ,EC1DayP,GAAkB,CAC7B,KACA,QACA,OACA,cACA,SAAS,CAAC,EACV,WACA,QACA,UACA,WACA,SAAS,CAAC,KACe,CACzB,IAAMC,GAAU,EAAgB,IAAqB,CACnD,IAAM9J,EAAO,IAAI,IAAIvD,CAAK,EACtBsN,EACF/J,EAAK,IAAIiJ,CAAM,EAEfjJ,EAAK,OAAOiJ,CAAM,EAEpBvB,EAASsB,EAAQ,IAAK,GAAUzH,EAAM,KAAK,CAAC,CAAC,OAAQ,GAAUvB,EAAK,IAAIuB,CAAK,CAAC,CAAC,CACjF,EACA,OACE,EAAAvG,EAAA,KAAA,CAACxG,GAAD,CAAU,eAAcsN,EAAO,OAAS,GAAK,IAAA,GAAW,UAAU,QAAlE,SAAA,EACE,EAAA9G,EAAA,KAAA,CAAC3G,GAAD,CAAa,QAAQ,QAAQ,UAAU,+BAAvC,SAAA,CACGoP,EACA4D,GAAO,EAAArM,EAAA,IAAA,CAACtG,GAAD,CAAU,MAAO+O,EAAQ,SAAA4D,CAAe,CAAA,EAAI,IACzC,IACZE,GAAc,EAAAvM,EAAA,IAAA,CAAC7G,EAAD,CAAA,SAAmBoT,CAA8B,CAAA,EAAI,MACpE,EAAAvM,EAAA,IAAA,CAAC,MAAD,CAAK,YAAU,iBAAiB,UAAU,yCACvC,SAAAgO,EAAQ,IAAK,GAAW,CACvB,IAAMgB,EAAW,GAAG/P,EAAG,GAAGgP,EAAO,QACjC,OACE,EAAAjO,EAAA,KAAA,CAACzG,EAAD,CAA0B,YAAY,aAAtC,SAAA,EACE,EAAAyG,EAAA,IAAA,CAAChF,GAAD,CACE,GAAIgU,EACJ,QAASvN,EAAM,SAASwM,EAAO,KAAK,EACpC,gBAAkB,GAAYa,EAAOb,EAAO,MAAOc,IAAY,EAAI,EACnE,SAAUjE,GAAYpG,EAAO,SAASuJ,EAAO,KAAK,CACnD,CAAA,GACD,EAAAjO,EAAA,IAAA,CAAC5G,GAAD,CAAY,QAAS4V,EAAU,UAAU,cACtC,SAAAf,EAAO,KACE,CAAA,CACP,CAVK,EAAAA,EAAO,KAUZ,CAEX,CAAC,CACE,CAAA,GACL,EAAAjO,EAAA,IAAA,CAACkH,EAAD,CAAmB,QAAS,CAAA,CACpB,GAEd,EC/Ca+H,GAAiB,CAC5B,KACA,QACA,OACA,cACA,SAAS,CAAC,EACV,WACA,UACA,WACA,SAAS,SACe,CACxB,IAAMjN,EAAMoK,GAAWnN,EAAI,CAAE,OAAM,cAAa,QAAO,CAAC,EAClDiQ,GACJ,EAAAlP,EAAA,IAAA,CAACnD,GAAD,CACM,KACK,UACT,gBAAiB6P,EACP,WACV,eAAc5F,EAAO,OAAS,GAAK,IAAA,GACnC,mBAAkB9E,EAAI,YACtB,UAAWhM,EAAG0R,IAAW,WAAa,mBAAmB,CAC1D,CAAA,EAEH,OACE,EAAA1H,EAAA,KAAA,CAACzG,EAAD,CAAO,YAAY,aAAa,eAAcuN,EAAO,OAAS,GAAK,IAAA,GAAnE,SAAA,CACGY,IAAW,UAAYwH,EAAU,MAClC,EAAAlP,EAAA,KAAA,CAACvG,GAAD,CAAA,SAAA,EACE,EAAAuG,EAAA,IAAA,CAAChD,GAAD,CAAa,QAASiC,EAAW,QAAa,OAAM,OAAQ+C,EAAI,MAAS,CAAA,EACxEuK,GAAc,EAAAvM,EAAA,IAAA,CAAC7G,EAAD,CAAkB,GAAI6I,EAAI,cAAgB,SAAAuK,CAA8B,CAAA,EAAI,MAC3F,EAAAvM,EAAA,IAAA,CAACkH,EAAD,CAAW,GAAIlF,EAAI,QAAiB,QAAS,CAAA,CACjC,CAAA,CAAA,EACb0F,IAAW,MAAQwH,EAAU,IACzB,GAEX,EC5BMC,GAAiB,UAMVC,IAAmB,CAC9B,WACA,SAAU,CAAE,MAAK,UAAS,YAC1B,QACA,WACA,SACA,cACA,OACA,cAC0B,CAC1B,GAAM,CAAE,KAAMvZ,EAAe,EAGvB+L,EAAO,CAAE,GAAA,GAFDyN,EAAS,GAAGjQ,IAEP,MADLvD,GAAcuD,CACT,EAAO,SAAQ,WAAU,cAAa,MAAK,EAC9D,OAAQ8P,EAAQ,KAAhB,CACE,IAAK,UACH,OACE,EAAAlP,EAAA,IAAA,CAACiP,EAAD,CACE,GAAIrN,EACJ,QAASH,IAAU,GACnB,SAAW,GAAYiL,EAASqC,GAAW,IAAA,EAAS,CACrD,CAAA,EAEL,IAAK,UACL,IAAK,SACH,OACE,EAAA/O,EAAA,IAAA,CAACyN,GAAD,CACE,GAAI7L,EACJ,QAASsN,EAAQ,OAAS,UAC1B,IAAKA,EAAQ,QACb,IAAKA,EAAQ,OAAS,UAAYA,EAAQ,QAAU,IAAA,GACpD,MAAO,OAAOzN,GAAU,SAAWA,EAAQ,IAAA,GACjC,UACX,CAAA,EAEL,IAAK,SACH,OACE,EAAAzB,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAIlM,EACJ,MAAO,OAAOH,GAAU,SAAWA,EAAQ,IAAA,GAC3C,QAASyN,EAAQ,QAAQ,IAAK,IAAY,CAAE,MAAOjB,EAAQ,MAAO3S,GAAW2S,CAAM,CAAE,EAAE,EAC7E,WACV,GAAKU,EAAW,CAAC,EAAI,CAAE,WAAYzO,EAAE,eAAe,CAAE,CACvD,CAAA,EAEL,IAAK,UACH,OACE,EAAAF,EAAA,IAAA,CAAC6O,EAAD,CACE,GAAIjN,EACJ,MAAO,MAAM,QAAQH,CAAK,EAAKA,EAAqB,CAAC,EACrD,QAASyN,EAAQ,QAAQ,IAAK,IAAY,CAAE,MAAOjB,EAAQ,MAAO3S,GAAW2S,CAAM,CAAE,EAAE,EACvF,SAAW,GAASvB,EAAS1H,EAAK,OAAS,EAAIA,EAAO,IAAA,EAAS,CAChE,CAAA,EAEL,IAAK,WACH,OACE,EAAAhF,EAAA,IAAA,CAACyM,EAAD,CACE,GAAI7K,EACJ,YAAa2K,GAAerM,EAAE,uBAAuB,EACrD,MAAO,MAAM,QAAQuB,CAAK,EAAKA,EAAmB,KAAK,IAAI,EAAI,GAC/D,SAAW,GAAS,CAClB,IAAM8D,GAASgI,GAAQ,GAAA,CAAI,MAAM4B,EAAc,CAAC,CAAC,OAAO,OAAO,EAC/DzC,EAASnH,EAAM,OAAS,EAAIA,EAAQ,IAAA,EAAS,CAC/C,CACD,CAAA,EAEL,IAAK,OACH,OACE,EAAAvF,EAAA,IAAA,CAACyM,EAAD,CACE,GAAI7K,EACJ,UAAWsN,EAAQ,UACnB,MAAO,OAAOzN,GAAU,SAAWA,EAAQ,IAAA,GACjC,WACV,iBAAkB,CAACkN,CACpB,CAAA,EAEL,QACE,OAAO,IACX,CACF,ECjFaW,IAAgB,CAAE,QAAO,OAAM,SAAQ,WAAU,cAAkC,CAC9F,GAAM,CAAE,KAAMzZ,EAAe,EACvB,CAAE,KAAI,WAAY4J,EAAM,OACxB6G,EAAahO,EAAsBmH,CAAK,CAAC,CAAC,IAAK,GAAU8G,EAAM,EAAE,EACjEgJ,EAAUhY,EAAiB0H,CAAE,GAAK,CAACqH,EAAW,SAASrH,CAAE,EAAI,CAAC,GAAGqH,EAAYrH,CAAE,EAAIqH,EACnFC,EAAQhO,GAAiB,IAAI0G,CAAE,EAC/BuQ,EAAajJ,EAAQkI,GAAmBlI,EAAM,aAAa,EAAI,CAAC,EACtE,OACE,EAAAvG,EAAA,KAAA,CAAA3L,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA2L,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAI,SAASrO,EAAM,GAAG,SACtB,MAAOS,EAAE,uBAAuB,EAChC,KAAMA,EAAE,2BAA2B,EACnC,MAAOjB,EACP,QAASsQ,EAAQ,IAAK,IAAY,CAAE,MAAOE,EAAQ,MAAO9T,GAAY8T,CAAM,CAAE,EAAE,EAChF,SAAW,GAASzK,GAAQ0H,EAAS,CAAE,GAAI1H,EAAM,QAAS,CAAC,CAAE,CAAC,EAC9D,OAAQ6B,EAAYC,EAAQ,GAAGC,EAAK,WAAW,EACrC,UACX,CAAA,EACAyI,EAAW,IAAK,IACf,EAAAxP,EAAA,IAAA,CAACoP,GAAD,CAEE,SAAU,SAAS3P,EAAM,GAAG,iBAClB,WACV,MAAOuO,EAAQY,EAAS,KACxB,SAAW,GAAUlC,EAAS,CAAE,KAAI,QAAS3H,EAAQiJ,EAASY,EAAS,IAAKnN,CAAK,CAAE,CAAC,EACpF,OAAQoF,EAAYC,EAAQ,GAAGC,EAAK,kBAAkB6H,EAAS,KAAK,EAC1D,UACX,EAPM,GAAG3P,EAAG,GAAG2P,EAAS,KAOxB,CACF,CACD,CAAA,CAAA,CAEN,ECtCMc,GAAY,CAChB,SAAU,CAAE,MAAO,0BAA2B,KAAM,6BAA8B,EAClF,OAAQ,CAAE,MAAO,wBAAyB,KAAM,2BAA4B,EAC5E,UAAW,CAAE,MAAO,gCAAiC,KAAM,mCAAoC,EAC/F,OAAQ,CAAE,MAAO,wBAAyB,KAAM,2BAA4B,EAC5E,WAAY,CAAE,MAAO,4BAA6B,KAAM,0BAA2B,EACnF,SAAU,CAAE,MAAO,0BAA2B,KAAM,0BAA2B,EAC/E,WAAY,CAAE,MAAO,4BAA6B,KAAM,+BAAgC,CAC1F,EAGMC,IAAkB,EAAwB,IAAuC,CACrF,IAAMC,EAAc3M,EAAM,OAAS,YAC7B4M,EAAiB5M,EAAM,OAAS,aAAeA,EAAM,UACrD6M,EACJ,CAACF,GAAe5X,GAAkB,IAAIyH,EAAM,IAAI,GAAK,EAAEA,EAAM,OAAS,QAAUA,EAAM,SAAS,UACjG,MAAO,CACL,WACA,GAAIxH,GAA0B,IAAIwH,EAAM,IAAI,GAAK,CAACmQ,EAAe,CAAC,QAAQ,EAAc,CAAC,EACzF,GAAIC,EAAkB,CAAC,WAAW,EAAc,CAAC,EACjD,SACA,GAAIC,EAAa,CAAC,aAAc,UAAU,EAAc,CAAC,EACzD,YACF,CACF,EAGaC,IAAS,CAAE,QAAO,QAAO,KAAI,WAAU,cAA2B,CAC7E,GAAM,CAAE,KAAMla,EAAe,EAC7B,OACE,EAAAmK,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,mDACZ,SAAA2P,GAAelQ,EAAOwD,CAAK,CAAC,CAAC,IAAK,IACjC,EAAAjD,EAAA,IAAA,CAACiP,EAAD,CAEE,GAAI,SAASxP,EAAM,GAAG,GAAGuQ,IACzB,OAAO,UACP,MAAO9P,EAAEwP,GAAUM,EAAK,CAAC,KAAK,EAC9B,KAAM9P,EAAEwP,GAAUM,EAAK,CAAC,IAAI,EAC5B,QAASvQ,EAAMuQ,GACf,SAAW,GAAYtD,EAAS,EAAGsD,GAAOjB,CAAQ,CAAC,EACnD,OAAQkB,EAAGD,CAAI,EACL,UACX,EATMA,CASN,CACF,CACE,CAAA,CAET,ECrDaE,IACX,EACA,EACA,IAEAzQ,EAAM,OAAS6F,EACX,KACA7J,GACE,CAAE,KAAM,aAAc,aAAc4N,EAAM,GAAI,QAAS5J,EAAM,GAAI,KAAMA,EAAM,KAAM,IAAG,EACtF,CAAE,OAAQ4J,EAAO,MAAOR,GAAcQ,EAAO5J,EAAM,GAAI6F,CAAE,CAAE,CAC7D,ECnBA6K,GAAkC,IAAI,IAO/BC,IACX,EACA,EACA,IACG,CACH,GAAM,CAAE,KAAMva,EAAe,EACvBqX,GAAA,EAAc5Y,EAAAA,QAAAA,KAEhBsN,GAAQyH,EACJ,IAAI,IAAI1R,EAAW,OAAQ,GAAOuY,GAAwBtO,EAAMyH,EAAO/D,CAAE,CAAC,EAAE,YAAc,EAAK,CAAC,EAChG6K,GACN,CAACvO,EAAMyH,CAAK,CACd,EACMvI,GAAA,EAASxM,EAAAA,QAAAA,KACNsN,GAAQyH,EAAQ6G,GAAwBtO,EAAMyH,EAAON,CAAI,EAAI,KACpE,CAACnH,EAAMyH,EAAON,CAAI,CACpB,EACMqE,EAAkB,CAAC,EACrBtM,GAAQ,WAAa,aACvBsM,EAAM,KAAKlN,EAAE,8BAA8B,CAAC,EACnCY,GAAQ,WAAa,cAC9BsM,EAAM,KAAKlN,EAAE,4BAA4B,CAAC,EAExCY,GAAQ,UACVsM,EAAM,KAAKlN,EAAE,6BAA6B,CAAC,EAEzCY,GAAQ,aACVsM,EAAM,KAAKlN,EAAE,gCAAgC,CAAC,EAEhD,IAAMmF,EAAOgE,EAAQnJ,EAAE,oBAAoBmJ,EAAM,KAAK,MAAM,EAAI,GAKhE,MAAO,CAAE,cAAa,kBAFK,GACzBnJ,EAAE,iCAAkC,CAAE,OAAM,GAAIA,EAAE,oBAAoBoF,EAAG,MAAM,CAAE,CAAC,EAC3C,QAAO,YAJ5B4H,EAAY,KAAO,EAAIhN,EAAE,6BAA8B,CAAE,KAAMmF,CAAK,CAAC,EAAI,IAAA,EAIjC,CAC9D,EChCMgL,GAAY,CAChB,MAAO,uCACP,MAAO,uCACP,KAAM,qCACR,EAMaC,IAAa,CAAE,QAAO,QAAO,SAAQ,cAA+B,CAC/E,GAAM,CAAE,KAAMza,EAAe,EACvB+T,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxD,CAAE,aAAY,QAASmI,GAAoBE,EAAOlI,CAAK,EACvDwH,EAAQU,EAAM,QAAQ,gBAAgB,QAAQlI,EAAM,EAAE,GAAK,GACjE,OACE,EAAAO,EAAA,IAAA,CAACiP,EAAD,CACE,GAAI,SAASxP,EAAM,GAAG,cACtB,MAAOS,EAAE,gCAAgC,EACzC,KAAMA,EAAE,+BAA+B,EACvC,YAAaqQ,EAAOrQ,EAAEmQ,GAAUE,EAAK,EAAI,IAAA,GACzC,OAAQtJ,IAAU,GAAK,CAAC,EAAIJ,EAAYC,EAAQ,2BAA2BG,GAAO,EAClF,QAASW,EACT,SAAUkD,GAAYyF,IAAS,IAAA,GAC/B,SAAW,GACT3G,EAAQ,GACNd,EAAQ,OAAS,YAAcA,EAAUjB,GAAsBiB,EAASrJ,EAAM,GAAIsP,CAAO,CAC3F,CAEH,CAAA,CAEL,ECxBayB,IAAc,CAAE,WAAU,QAAO,OAAM,SAAQ,WAAU,cAAgC,CACpG,GAAM,CAAE,KAAM3a,EAAe,EACvB4a,EAAShR,EAAM,SAAS,OACxBiR,GAAW,EAAe,IAC9BhE,EAAS+D,EAAO,KAAK,EAAO,IAAczI,IAAaf,EAAQ,CAAE,GAAGV,EAAO,GAAGoK,CAAM,EAAIpK,CAAM,CAAC,EAC3FqK,EAAa9J,EAAO,OAAQ,GAAUF,EAAM,OAASG,CAAI,EAC/D,OACE,EAAA/G,EAAA,KAAA,CAACxG,GAAD,CAAU,UAAU,QAAQ,eAAcoX,EAAW,OAAS,GAAK,IAAA,GAAnE,SAAA,EACE,EAAA5Q,EAAA,KAAA,CAAC3G,GAAD,CAAa,QAAQ,QAAQ,UAAU,+BAAvC,SAAA,CACG6G,EAAE,0BAA0B,GAC7B,EAAAF,EAAA,IAAA,CAACtG,GAAD,CAAU,MAAOwG,EAAE,0BAA0B,EAAI,SAAAA,EAAE,+BAA+B,CAAY,CAAA,CACnF,IACZuQ,EAAO,OAAS,GACf,EAAAzQ,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,YACX,SAAAyQ,EAAO,KAAK,EAAO,IAAU,CAC5B,IAAMI,EAAYhK,EAAYC,EAAQ,GAAGC,EAAK,GAAGE,GAAO,EAClD6J,EAAU,GAAGzB,EAAS,SAASpI,IAC/B8J,EAAU,GAAG1B,EAAS,SAASpI,IACrC,OACE,EAAAjH,EAAA,KAAA,CAAC,KAAD,CAAgB,UAAU,YAA1B,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,QAAD,CAAO,QAAS+Q,EAAS,UAAU,UAChC,SAAA7Q,EAAE,2BAA4B,CAAE,SAAU+G,EAAQ,CAAE,CAAC,CACjD,CAAA,GACP,EAAAjH,EAAA,IAAA,CAAClG,GAAD,CACE,GAAIiX,EACJ,MAAOxK,EAAM,MACb,YAAarG,EAAE,qCAAqC,EAC1C,WACV,SAAW,GAAUwQ,EAAQzJ,EAAO,CAAE,MAAOyD,EAAM,OAAO,KAAM,CAAC,CAClE,CAAA,GACD,EAAA1K,EAAA,IAAA,CAAC,QAAD,CAAO,QAAS8Q,EAAS,UAAU,UAChC,SAAA5Q,EAAE,2BAA4B,CAAE,SAAU+G,EAAQ,CAAE,CAAC,CACjD,CAAA,GACP,EAAAjH,EAAA,IAAA,CAAClG,GAAD,CACE,GAAIgX,EACJ,MAAOvK,EAAM,MACb,YAAarG,EAAE,qCAAqC,EACpD,UAAU,YACV,WAAY,GACF,WACV,eAAc2Q,EAAU,OAAS,GAAK,IAAA,GACtC,SAAW,GAAUH,EAAQzJ,EAAO,CAAE,MAAOyD,EAAM,OAAO,KAAM,CAAC,CAClE,CAAA,GACD,EAAA1K,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,UACK,WACV,aAAYsG,EAAE,4BAA6B,CAAE,SAAU+G,EAAQ,CAAE,CAAC,EAClE,YAAeyF,EAAS+D,EAAO,QAAQ,EAAG,IAAazI,IAAaf,CAAK,CAAC,EAE1E,UAAA,EAAAjH,EAAA,IAAA,CAACzL,GAAD,CAAQ,cAAY,MAAQ,CAAA,CACtB,CAAA,CACL,CACL,CAAA,GAAA,EAAAyL,EAAA,IAAA,CAACkH,EAAD,CAAW,OAAQ2J,CAAY,CAAA,CAC7B,CArCK,EAAA5J,CAqCL,CAER,CAAC,CACC,CAAA,EACF,MACJ,EAAAjH,EAAA,IAAA,CAACkH,EAAD,CAAW,OAAQ0J,CAAa,CAAA,GAChC,EAAA5Q,EAAA,KAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,UACR,KAAK,KACL,UAAU,QACA,WACV,YAAe8S,EAAS,CAAC,GAAG+D,EAAQ,CAAE,MAAO,GAAI,MAAO,EAAG,CAAC,CAAC,EAN/D,SAAA,EAQE,EAAAzQ,EAAA,IAAA,CAACzD,GAAD,CAAM,cAAY,MAAQ,CAAA,EACzB2D,EAAE,wBAAwB,CACrB,GACA,GAEd,ECvEM8Q,GAAuC,IAAI,IAAI,CAAC,eAAe,CAAC,EAGhEC,GAAmB,CACvB,KAAM,sBACN,SAAU,0BACV,KAAM,sBACN,QAAS,yBACT,WAAY,2BACd,EAEMC,GAA0C,IAAI,IAAI,CAAC,SAAU,MAAM,CAAC,EAM7DC,IAAgB,CAAE,QAAO,QAAO,OAAM,SAAQ,WAAU,cAAkC,CACrG,GAAM,CAAE,KAAMtb,EAAe,EACvB,CAAE,eAAgB2H,GAAkB,EACpC4T,EAAW3R,EAAM,SACjB4R,EAAe,GAAGtK,EAAK,WACvBsI,EAAW,SAAS5P,EAAM,GAAG,WAC7B6R,EAAM,CACV,IAAIC,GAAe,CAAC,EAAA,CAAG,KAAK,CAAE,gBAAiBlS,CAAU,CAAC,CAAC,OAAQ,GAAUkH,EAAM,KAAOtD,EAAM,EAAE,EAClGA,CACF,EACMuO,EAASF,EAAI,OAAQ,GAAU/K,EAAM,OAAS,WAAW,EACzDkL,EAAaH,EAAI,OAAQ,GAAU/K,EAAM,OAAS,aAAeA,EAAM,KAAOtD,EAAM,EAAE,EACtFyO,EAAY,IAA6B,CAAE,MAAOnL,EAAM,GAAI,MAAOA,EAAM,KAAM,GAC/E0J,EAAM,GAAgBpJ,EAAYC,EAAQ,GAAGuK,EAAa,GAAGjS,GAAK,EAElEuS,EAAU,GAAgC,CAC9C,GAAM,CAAE,OAAQ/C,EACVP,EAAS,CAAE,GAAI,GAAGgB,EAAS,GAAGjQ,IAAO,OAAQ6Q,EAAG7Q,CAAG,EAAG,UAAS,EACrE,GAAIK,EAAM,OAAS,QAAUL,IAAQ,SACnC,OACE,EAAAY,EAAA,IAAA,CAACwQ,GAAD,CAEE,SAAUnC,EAAO,GACV,QACP,KAAM,GAAGgD,EAAa,SACd,SACE,WACV,SAAW,GAAW3E,EAAS,SAAU+D,CAAM,CAChD,EAPMrR,CAON,EAGL,GAAIA,IAAQ,SACV,OACE,EAAAY,EAAA,IAAA,CAAC8N,EAAD,CAEE,GAAIO,EACJ,MAAOnO,EAAE,0BAA0B,EACnC,MAAOkR,EAAS,OAChB,QAASI,EAAO,IAAIE,CAAQ,EAC5B,SAAW,GAAUhF,EAAS,SAAUjL,GAAS,EAAE,EACnD,YAAavB,EAAE,4BAA4B,CAC5C,EAPMd,CAON,EAGL,GAAIA,IAAQ,YACV,OACE,EAAAY,EAAA,IAAA,CAAC8N,EAAD,CAEE,GAAIO,EACJ,MAAOnO,EAAE,6BAA6B,EACtC,MAAOkR,EAAS,UAChB,QAASK,EAAW,IAAIC,CAAQ,EAChC,SAAW,GAAUhF,EAAS,YAAajL,GAAS,EAAE,EACtD,YAAavB,EAAE,gCAAgC,EAC/C,GAAKuR,EAAW,SAAW,EAAI,CAAE,YAAavR,EAAE,6BAA6B,CAAE,EAAI,CAAC,CACrF,EARMd,CAQN,EAGL,GAAIA,IAAQ,aACV,OACE,EAAAY,EAAA,IAAA,CAAC6O,EAAD,CAEE,GAAIR,EACJ,MAAOnO,EAAE,8BAA8B,EACvC,MAAQkR,EAAS,YAAuC,CAAC,EACzD,QAASK,EAAW,IAAIC,CAAQ,EAChC,SAAW,GAAUhF,EAAS,aAAcjL,CAAK,EACjD,GAAKgQ,EAAW,SAAW,EAAI,CAAE,YAAavR,EAAE,6BAA6B,CAAE,EAAI,CAAC,CACrF,EAPMd,CAON,EAGL,GAAIA,IAAQ,gBACV,OACE,EAAAY,EAAA,IAAA,CAAC8N,EAAD,CAEE,GAAIO,EACJ,MAAOnO,EAAE,iCAAiC,EAC1C,KAAMA,EAAE,gCAAgC,EACxC,MAAOkR,EAAS,cAChB,QAASnO,EAAM,OACZ,OAAQ,GAAcuE,EAAU,KAAO/H,EAAM,IAAMyR,GAAmB,IAAI1J,EAAU,IAAI,CAAC,CAAC,CAC1F,IAAK,IAAe,CAAE,MAAOA,EAAU,GAAI,MAAOA,EAAU,KAAM,EAAE,EACvE,SAAW,GAAUkF,EAAS,gBAAiBjL,CAAK,EACpD,WAAYvB,EAAE,eAAe,CAC9B,EAVMd,CAUN,EAGL,IAAMwS,EACJhD,EAAS,QAAQ,OAAS,QAAUnP,EAAM,QAAQwR,GAC9CA,GAAiBxR,EAAM,MACvB,IAAA,GACN,OACE,EAAAO,EAAA,IAAA,CAACoP,GAAD,CAEY,WACA,WACV,MAAOgC,EAAShS,GAChB,SAAW,GAAUsN,EAAStN,EAAKqC,CAAK,EACxC,OAAQ4M,EAAO,OACL,WACV,YAAauD,IAAc,IAAA,GAAY,IAAA,GAAY1R,EAAE0R,CAAS,EAC9D,KAAMxS,IAAQ,UAAYc,EAAE,4BAA4B,EAAI,IAAA,EAC7D,EATMd,CASN,CAEL,EAEMoQ,EAAaf,GAAmB7W,GAAiB6H,EAAM,KAAK,CAAC,CAAC,OACjE,GAAa,CAACuR,GAAgB,IAAIpC,EAAS,GAAG,CACjD,EACMiD,EAAW,IAAI,IAAIrC,EAAW,IAAK,GAAaZ,EAAS,GAAG,CAAC,EAC7DkD,GAAcjL,EAAYC,EAAQuK,CAAY,CAAC,CAAC,OACnD,GAAU,CAACQ,EAAS,IAAIjL,EAAM,KAAK,MAAMyK,EAAa,OAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAM,EAAE,CACxF,EAIA,OAHI7B,EAAW,SAAW,GACjB,EAAAxP,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,kCAAmC,SAAAE,EAAE,2BAA2B,CAAK,CAAA,GAGzF,EAAAF,EAAA,KAAA,CAAAxL,EAAAA,SAAA,CAAA,SAAA,CACGgb,EAAW,IAAImC,CAAM,GACtB,EAAA3R,EAAA,IAAA,CAACkH,EAAD,CAAW,OAAQ4K,EAAc,CAAA,CACjC,CAAA,CAAA,CAEN,EC/HMC,GAAa,IAAI,IAAI,CACzB,QACA,SACA,cACA,WACA,SACA,aACA,WACA,SACA,YACA,aACA,eACA,SACA,UACF,CAAC,EAOYC,IAAc,CAAE,QAAO,QAAO,SAAQ,WAAU,YAAW,eAAiC,CACvG,GAAM,CAAE,KAAMnc,EAAe,EACvBoN,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EACtDsC,EAAO1C,EAAyB,GAAUI,EAAM,IAAI,EACpD2S,EAAc/S,EAAyB,GAAUI,EAAM,WAAW,EAClEsK,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDuK,EAAS3K,EAAyB,GAAUI,EAAM,MAAM,EACxD+J,EAAQzH,GAAM,OAAO,KAAM,GAAc4F,EAAU,KAAO/H,EAAM,EAAE,EAClEyS,EAAc9B,GAAexO,EAAMyH,EAAO5J,EAAM,IAAI,EAC1D,GAAI,CAACwD,EACH,OAAO,KAET,IAAM8D,EAAOC,GAAUC,CAAK,EACtBgJ,EAAM,GAAqBpJ,EAAYC,EAAQ,GAAGC,EAAK,GAAG6H,GAAU,EACpEkD,EAAcjL,EAAYC,EAAQC,CAAI,CAAC,CAAC,OAC3C,GAAU,CAACgL,GAAW,IAAInL,EAAM,KAAK,MAAMG,EAAK,OAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAM,EAAE,CAClF,EACM5H,EAAO,GACX8S,EAAYxS,EAAM,GAAK,IAAa,CAAE,GAAGqJ,EAAS,GAAG6H,CAAM,EAAqB,EAC5E1R,EAAM,GAAiB,SAASQ,EAAM,GAAG,GAAG0S,IAC5CC,GAAU/I,IAAU,IAAA,IAAaA,EAAM,SAAW5J,EAAM,OACxD4S,EAAQzQ,IAAS,MAAQyH,IAAU,IAAA,GACnCZ,EAAQhJ,EAAM,OAASS,EAAE,yBAAyB,EAClDoS,EAAY,GAAiB,CACjC,IAAMC,EAAeF,GAAS5S,EAAM,SAAWvB,GAAauB,EAAM,KAAK,EACvEN,EAAI,CAAE,MAAO6F,EAAM,GAAIuN,EAAe,CAAE,OAAQrU,GAAa8G,CAAI,CAAE,EAAI,CAAC,CAAG,CAAC,CAC9E,EAYA,OAEE,EAAAhF,EAAA,IAAA,CAAC,MAAD,CAAgB,UAbC,GAAyC,CAEtD0K,EAAM,MAAQ,UAAY,GAAM,YAAY,kBAAqB8H,GAGjE9H,EAAM,kBAAkB,MAAQA,EAAM,cAAc,SAASA,EAAM,MAAM,IAC3EA,EAAM,eAAe,EACrBtK,EAAU,EAEd,EAKI,UAAA,EAAAJ,EAAA,KAAA,CAACjC,GAAD,CAAO,aAAYmC,EAAE,iCAAkC,CAAE,OAAM,CAAC,EAAG,MAAA,GAAnE,SAAA,EACE,EAAAF,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uDAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC/I,GAAD,CAAU,KAAMiD,GAAgBuF,EAAM,KAAQ,CAAA,GAC9C,EAAAO,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,+DAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAU,2CAA4C,SAAAyI,CAAU,CAAA,GACpE,EAAAzI,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,YAAa,SAAAgJ,EAAE,oBAAoBT,EAAM,KAAK,MAAM,CAAS,CAAA,CACzE,KACL,EAAAO,EAAA,KAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,oBACR,KAAK,KACK,WACV,YAAe,CACbgQ,EAAQ,GAAYnE,GAAYqD,EAASrJ,EAAM,EAAE,CAAC,EAClDoK,EAAO,CAAE,KAAM,YAAa,CAAC,CAC/B,EARF,SAAA,EAUE,EAAA7J,EAAA,IAAA,CAACvL,GAAD,CAAQ,cAAY,MAAQ,CAAA,EAC3ByL,EAAE,4BAA4B,CACzB,GACL,CACL,CAAA,GAAA,EAAAF,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,gBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACkH,EAAD,CAAW,OAAQ4K,CAAc,CAAA,GAEjC,EAAA9R,EAAA,IAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,yBAAyB,EAAG,QAASjB,EAAG,cAAc,EAC3E,UAAA,EAAAe,EAAA,IAAA,CAACgN,GAAD,CACE,WAAY/N,EAAG,cAAc,EAC7B,MAAOQ,EAAM,KACb,GAAIyS,EACM,WACV,SAAW,GACTtI,EAAQ,GAAYhE,EAAYwD,GAAqBN,EAASrJ,EAAM,GAAIsJ,EAAMM,CAAK,CAAC,CAAC,CAExF,CAAA,CACW,CAAA,GAEd,EAAArJ,EAAA,KAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,wBAAwB,EAA/C,SAAA,EACE,EAAAF,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,qDAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACyM,EAAD,CACE,GAAIjD,GAAe/J,EAAM,EAAE,EAC3B,MAAOS,EAAE,cAAc,EACvB,MAAOT,EAAM,MACb,SAAW,GAAS6S,EAAStN,GAAQ,EAAE,EACvC,OAAQiL,EAAG,OAAO,EACR,UACX,CAAA,GACD,EAAAjQ,EAAA,IAAA,CAACyM,EAAD,CACE,GAAIxN,EAAG,QAAQ,EACf,MAAOiB,EAAE,eAAe,EACxB,KAAMA,EAAE,wBAAwB,EAChC,YAAakS,GAAUlS,EAAE,oCAAoC,EAAI,IAAA,GACjE,MAAOT,EAAM,OACb,SAAW,GAAWN,EAAI,CAAE,OAAQwJ,GAAU,EAAG,CAAC,EAClD,OAAQsH,EAAG,QAAQ,EACT,WACV,UAAA,EACD,CAAA,CACE,KACL,EAAAjQ,EAAA,IAAA,CAACyM,EAAD,CACE,GAAIxN,EAAG,aAAa,EACpB,MAAOiB,EAAE,yBAAyB,EAClC,MAAOT,EAAM,YACb,SAAW,GAAgBN,EAAI,CAAE,aAAY,CAAC,EAC9C,OAAQ8Q,EAAG,aAAa,EACd,WACV,iBAAA,GACA,UAAA,EACD,CAAA,EACAhN,EAAM,OAAS,aAAe,CAACxD,EAAM,YACpC,EAAAO,EAAA,IAAA,CAACsQ,GAAD,CAAW,MAAOrN,EAAc,QAAe,SAAkB,UAAW,CAAA,EAC1E,IACQ,KAEd,EAAAjD,EAAA,IAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,wBAAwB,EAC7C,UAAA,EAAAF,EAAA,IAAA,CAAC+P,GAAD,CAAc,QAAc,QAAW,KAAc,WAAU,SAAU5Q,CAAM,CAAA,CACnE,CAAA,GAEd,EAAAa,EAAA,KAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,yBAAyB,EAAhD,SAAA,EACE,EAAAF,EAAA,IAAA,CAACmR,GAAD,CACS,QACA,QACD,OACE,SACE,WACV,UAAW,EAAK,IACdvH,EAAQ,GACNhE,EAAY,CACV,GAAGkD,EACH,OAAQA,EAAQ,OAAO,IAAK,GAC1BtB,EAAU,KAAO/H,EAAM,GACnB4G,GAAqBnB,GAAYsC,EAAWpI,EAAKqC,CAAK,CAAC,EACvD+F,CACN,CACF,CAAC,CACH,CAEH,CAAA,EACA2E,GAAqB1M,CAAK,GACzB,EAAAO,EAAA,IAAA,CAACoO,GAAD,CACS,QACP,OAAQ6B,EAAG,cAAc,EACf,WACV,SAAW,GACTgC,EAAYxS,EAAM,GAAK,GAAY,CACjC,IAAMuF,EAAgC,CAAE,GAAG8D,EAAS,cAAa,EAIjE,OAHIQ,IAAiB,IAAA,IACnB,OAAOtE,EAAK,aAEPA,CACT,CAAC,CAEJ,CAAA,EACC,IACQ,KAEd,EAAAhF,EAAA,IAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,8BAA8B,EACnD,UAAA,EAAAF,EAAA,IAAA,CAACsP,GAAD,CACS,QACD,OACE,SACE,WACV,SAAW,GAAWnQ,EAAI,CAAE,QAAO,CAAC,CACrC,CAAA,CACW,CAAA,CACX,CACA,CAAA,CAAA,GACJ,CAAA,CAET,EC1MasT,IAAU,CACrB,QACA,UACA,QACA,aACA,gBACA,WACA,GAAGC,KACc,CACjB,GAAM,CAAE,KAAM7c,EAAe,EAEvB,CAAE,WAAWoN,EAAM,QAAWtM,EAAU,CAAE,OAAQ,EAAM,CAAC,EACzDgc,EACJ1P,EAAM,OAAS,YACX,CAAC,CAAE,MAAO/C,EAAE,sBAAsB,EAAG,KAAMjK,EAAY,CAAE,GAAI,qBAAsB,CAAC,CAAE,CAAC,EACvF,CACE,CAAE,MAAOgN,EAAM,MAAO,KAAMhN,EAAY,CAAE,GAAI,qBAAsB,OAAQ,CAAE,UAAS,CAAE,CAAC,CAAE,EAC5F,CAAE,MAAOiK,EAAE,sBAAsB,CAAE,CACrC,EACN,OACE,EAAAF,EAAA,IAAA,CAACtJ,EAAD,CACE,OAAA,GACY,aACZ,MAAOuM,EAAM,OAAS/C,EAAE,yBAAyB,EACjD,MACE0S,GAASC,EAAa,GACpB,EAAA7S,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,oCAAhB,SAAA,CACG4S,GAAQ,EAAA5S,EAAA,IAAA,CAAClJ,EAAD,CAAY,KAAK,UAAU,MAAOoJ,EAAE,wBAAwB,CAAI,CAAA,EAAI,KAC5E2S,EAAa,GACZ,EAAA7S,EAAA,IAAA,CAAClJ,EAAD,CAAY,KAAK,SAAS,MAAOoJ,EAAE,0BAA2B,CAAE,MAAO2S,CAAW,CAAC,CAAI,CAAA,EACrF,IACA,CACJ,CAAA,EAAA,KAEN,KACE5P,EAAM,OAAS,aACX/C,EAAE,oCAAqC,CACrC,OAAQ+C,EAAM,OACd,aAAc5K,EAAW4K,CAAK,EAC9B,SACF,CAAC,EACD/C,EAAE,0BAA2B,CAAE,OAAQ+C,EAAM,OAAQ,SAAQ,CAAC,EAEpE,SACE,EAAAjD,EAAA,KAAA,CAAAtL,EAAAA,SAAA,CAAA,SAAA,EACE,EAAAsL,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,oCACb,UAAA,EAAAA,EAAA,IAAA,CAACG,GAAD,CAAa,GAAIuS,CAAc,CAAA,CAC5B,CAAA,GACL,EAAA1S,EAAA,KAAA,CAAC1D,GAAD,CAAA,SAAA,EACE,EAAA0D,EAAA,IAAA,CAAC5D,GAAD,CAAqB,QAAA,GACnB,UAAA,EAAA4D,EAAA,IAAA,CAACpG,EAAD,CAAQ,QAAQ,QAAQ,KAAK,OAAO,aAAYsG,EAAE,qBAAqB,EACrE,UAAA,EAAAF,EAAA,IAAA,CAACrL,GAAD,CAAgB,cAAY,MAAQ,CAAA,CAC9B,CAAA,CACW,CAAA,GACrB,EAAAqL,EAAA,IAAA,CAAC3D,GAAD,CAAqB,MAAM,MACzB,UAAA,EAAA2D,EAAA,KAAA,CAAC7D,GAAD,CAAkB,QAAQ,cAAc,SAAU2W,EAAe,SAAUC,EAA3E,SAAA,EACE,EAAA/S,EAAA,IAAA,CAACpL,GAAD,CAAQ,cAAY,MAAQ,CAAA,EAC3BsL,EAAE,uBAAuB,CACV,GACC,CAAA,CACT,CAAA,CAAA,CACd,CAAA,CAAA,CAEL,CAAA,CAEL,ECnFM8S,GAAkB,MAGXC,GAAe,GAC1B5T,EAAW,OAAO,KACf,GAAUI,EAAM,OAAS,aAAeA,EAAM,SAAS,YAAA,sCAC1D,EAMWyT,GAAkB,GAC7BtO,GAAYvF,EAAY,CACtB,KAAM,YACN,GAAGgJ,GAAmBhJ,EAAY2T,EAAe,EACjD,SAAU,CAAE,UAAWlb,EAAkB,WAAY,EAAM,EAC3D,SAAUR,EACV,UAAW+H,EAAW,OAAS,aAAeA,EAAW,SAC3D,CAAC,ECCU8T,OAAuB,CAClC,GAAM,CAAE,KAAMtd,EAAe,EACvB4b,EAAahU,GAAe,WAAW,EACvC,CAAE,YAAapD,EAAqB,EACpC+Y,EAAUlU,EAAyB,GAAWI,EAAM,MAAQ2T,GAAY3T,EAAM,KAAK,EAAI,EAAM,EAC7FsK,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDuK,EAAS3K,EAAyB,GAAUI,EAAM,MAAM,EACxD+T,EAASva,GAAsB,EAE/Bwa,EAAS7B,EAAW,MAAM,KAAM,GAAS8B,EAAK,WAAW,KAAOzb,CAAgB,EAChF2S,EAAqC2I,EACvC,UACAE,IAAW,IAAA,GACT,UACAA,EACE,QACAvT,EACE,SACA,WAEJyT,MAAY,CAChB,GAAM,CAAE,SAAUtU,EAAwB,SAAS,EACnD,GAAI,CAAC+D,GAASgQ,GAAYhQ,CAAK,EAC7B,OAEF,IAAMxD,EAAQyT,GAAejQ,CAAK,EAClC2G,EAAQ,GAAYtC,GAAewB,EAASrJ,CAAK,CAAC,EAClDoK,EAAO,CAAE,KAAM,QAAS,QAASpK,EAAM,EAAG,CAAC,EAC3C,0BAA4B,CAC1B,SAAS,eAAe+J,GAAe/J,EAAM,EAAE,CAAC,CAAC,EAAE,eAAe,CAAE,MAAO,QAAS,CAAC,CACvF,CAAC,EACDzG,EAAM,QAAQkH,EAAE,mBAAmB,CAAC,CACtC,EAmBA,MAAO,CAAE,eAAc,MAAK,sBAhBK,CAC/B,GAAI,CACF,MAAMmT,EAAO,YAAY,CAC3B,OAASzS,EAAO,CACd3H,GAAS2H,EAAO,4BAA4B,EAC5C,IAAM6S,EAAW1a,GAAc6H,CAAK,EACpC5H,EAAM,MACJya,EACIvT,EAAE,uBAAwB,CAAE,MAAOuT,EAAS,MAAO,OAAQA,EAAS,MAAO,CAAC,EAC5E5Z,GAAc+G,CAAK,CACzB,EACA,MACF,CACA4S,EAAI,CACN,EAE0C,SAAUH,EAAO,SAAU,CACvE,EC1EMK,GAAwC,CAAC,EAGlCC,OAAuB,CAClC,IAAM1Q,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EACtDsC,EAAO1C,EAAyB,GAAUI,EAAM,IAAI,EACpD,CAAE,eAAgB9B,GAAkB,EAEpCoW,GAAA,EAAgB/e,EAAAA,iBAAAA,CAAiBoO,CAAK,EAY5C,MAAO,CAAE,QAAA,EAXMnO,EAAAA,QAAAA,KAEX8e,GAAiBhS,EACb4E,GACEoN,EACAhS,GACC2P,GAAe,CAAC,EAAA,CAAG,KAAK,CAAE,gBAAiBlS,CAAU,CACxD,EACAqU,GACN,CAACE,EAAehS,EAAM2P,CAAW,CAE1B,CAAO,CAClB,ECtBasC,OAAwB,CACnC,IAAM5Q,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EACtDsC,EAAO1C,EAAyB,GAAUI,EAAM,IAAI,EAC1D,OAAA,EAAOvK,EAAAA,QAAAA,KAAc,GAAQkO,GAASrB,GAAQuD,GAAalC,EAAOrB,CAAI,GAAI,CAACqB,EAAOrB,CAAI,CAAC,CACzF,ECFakS,IAAyB,EAAY,EAAqB,IAA8B,CAEnG,IAAMC,EADU5W,GACD,CAAA,CAAQ,MAAM,YAAY,KAAM,GAAekC,EAAW,KAAOJ,CAAE,EAElF,MAAO,CAAE,iBADgB,CAAC+U,GAAoBD,IAAW,IAAA,IAAaA,EAAO,QAAUE,EAC5D,cAAeF,GAAQ,OAAQ,CAC5D,ECMMG,GAAqB,GAAmB/d,EAAayK,EAAO,yBAAyB,EAQ9EuT,IAAe,EAA8B,EAAY,IAA6B,CACjG,GAAM,CAAE,KAAMte,EAAe,EACvBue,EAAO9W,GAAc,EACrBgG,EAAc1N,EAAe,EAC7Bye,EAAQ5X,GAAgB,EACxB,CAAC6C,EAAOgV,IAAA,EAAYtf,EAAAA,SAAAA,CAAwB,CAAE,KAAM,MAAO,CAAC,EAE5D,CAACuf,EAAiBC,IAAA,EAAsBxf,EAAAA,SAAAA,CAA6B,IAAA,EAAS,EAE9Eyf,EAAiB,GAAmB,CACxC,GAAIP,GAAkBtT,CAAK,EAAG,CAC5B0T,EAAS,CAAE,KAAM,UAAW,CAAC,EAC7B,MACF,CACAtb,EAAM,MAAMa,GAAc+G,CAAK,CAAC,CAClC,EAEM8T,EAAqB,SAAY,CACrC1b,EAAM,QAAQkH,EAAE,gBAAgB,CAAC,EACjC,GAAI,CAEF,MAAM2D,EAAY,QAAQ,CAC5B,OAASjD,EAAO,CACd3H,GAAS2H,EAAO,gDAAgD,EAChE5H,EAAM,MAAMa,GAAc+G,CAAK,CAAC,CAClC,CACF,EA0DA,MAAO,CACL,QACA,gBA1DyB,CACzB,GAAM,CAAE,QAAO,eAAgB1B,EAAwB,SAAS,EAChE,GAAK+D,EAGL,GAAM,MAAM,EACZ,GAAI,CACF,IAAM0R,EAAU,MAAMP,EAAK,YAAY,CACrC,WACA,KACA,WAAYnR,EACZ,gBAAiBgR,CACnB,CAAC,EACDK,EAAS,CAAE,KAAM,SAAU,SAAQ,CAAC,CACtC,OAAS1T,EAAO,CACd6T,EAAc7T,CAAK,CACrB,CAXY,CAYd,EA0CE,UAAWwT,EAAK,UAChB,aAzCqB,IAAqC,CAC1D,GAAM,CAAE,QAAO,eAAgBlV,EAAwB,SAAS,EAChE,GAAK+D,EAGL,GAAI,CACF,IAAM9D,EAAM,MAAMkV,EAAM,YAAY,CAClC,aAAcpV,EACd,MAAO,CAAE,WAAU,WAAYgE,EAAO,aAAY,EAClD,kBACA,MAAO/C,EAAE,0BAA2B,CAAE,MAAO+C,EAAM,KAAM,CAAC,CAC5D,CAAC,EAED,GADAqR,EAAS,CAAE,KAAM,MAAO,CAAC,EACrBnV,EAAI,SAAW,WAAY,CAE7B,IAAMsE,EAAS,MAAMH,EAAY,WAAW5F,GAAuBsB,EAAUC,CAAE,CAAC,EAChFuV,EAAmB/Q,EAAO,eAAe,EAAE,EAC3CzK,EAAM,KAAKkH,EAAE,8BAA8B,CAAC,CAC9C,MACE,MAAMwU,EAAmB,CAE7B,OAAS9T,EAAO,CAEVsT,GAAkBtT,CAAK,GACzB0T,EAAS,CAAE,KAAM,UAAW,CAAC,CAEjC,CACF,EAeE,SAAUD,EAAM,UAChB,WAAYA,EAAM,MAElB,cAAiBC,EAAS,CAAE,KAAM,MAAO,CAAC,EAC1C,kBACA,kBAAqBE,EAAmB,IAAA,EAAS,EACjD,sBAlB8B,IAAmB,CAC7CxT,IAAW,cACbwT,EAAmB,IAAA,EAAS,EAC5B,MAAME,EAAmB,EAE7B,CAcA,CACF,ECxHaE,OAAyB,CACpC,IAAMpV,EAAYN,EAAyB,GAAUI,EAAM,SAAS,EAC9D2C,EAAS/C,EAAyB,GAAUI,EAAM,OAAO,MAAM,EACrE,GAAIE,EAAU,OAAS,SAAW,CAACyC,EACjC,MAAO,CAAE,MAAO,IAAA,GAAW,MAAO,EAAG,EAEvC,IAAMgF,EAAQhF,EAAO,UAAW,GAAcuF,EAAU,KAAOhI,EAAU,OAAO,EAChF,MAAO,CAAE,MAAOyC,EAAOgF,GAAQ,OAAM,CACvC,ECAMgH,GAAU,IAA0C,CAAE,MAAOxO,EAAM,GAAI,MAAOA,EAAM,KAAM,GAMnFoV,IAAkB,CAAE,QAAO,SAAQ,cAAoC,CAClF,GAAM,CAAE,KAAMhf,EAAe,EACvB+T,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDwV,GAAc,EAAa,IAC/BlL,EAAQ,GAAUhE,EAAY,CAAE,GAAG3C,EAAO,QAAS8B,EAAQ9B,EAAM,QAAS7D,EAAKqC,CAAK,CAAE,CAAC,CAAC,EACpFwO,EAAM,GAAgBpJ,EAAYC,EAAQ,YAAY1H,GAAK,EAC3DmQ,EAAUrH,GAAsBP,CAAK,EAC3C,OACE,EAAA3H,EAAA,KAAA,CAAA/K,EAAAA,SAAA,CAAA,SAAA,CACGsa,EAAQ,aAAa,OAAS,GAC7B,EAAAvP,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAG,yBACH,MAAO5N,EAAE,2BAA2B,EACpC,KAAMA,EAAE,+BAA+B,EACvC,MAAOyH,EAAM,QAAQ,aACrB,QAAS4H,EAAQ,aAAa,IAAItB,EAAM,EACxC,SAAW,GAAU6G,EAAW,eAAgBrT,CAAK,EACrD,WAAYvB,EAAE,0BAA0B,EACxC,OAAQ+P,EAAG,cAAc,EACf,UACX,CAAA,EACC,KACHV,EAAQ,cAAc,OAAS,GAC9B,EAAAvP,EAAA,IAAA,CAAC6O,EAAD,CACE,GAAG,2BACH,MAAO3O,EAAE,6BAA6B,EACtC,KAAMA,EAAE,iCAAiC,EACzC,MAAOqP,EAAQ,OACf,QAASA,EAAQ,cAAc,IAAItB,EAAM,EAEzC,OAAQsB,EAAQ,OAAO,SAAW,EAAIA,EAAQ,OAAS,CAAC,EACxD,SAAW,GAAQuF,EAAW,iBAAkB9S,EAAI,OAAS,EAAIA,EAAM,IAAA,EAAS,EAChF,OAAQiO,EAAG,gBAAgB,EACjB,UACX,CAAA,EACC,KACHV,EAAQ,aAAa,OAAS,GAC7B,EAAAvP,EAAA,IAAA,CAAC6O,EAAD,CACE,GAAG,0BACH,MAAO3O,EAAE,4BAA4B,EACrC,KAAMA,EAAE,gCAAgC,EACxC,MAAOyH,EAAM,QAAQ,eAAiB,CAAC,EACvC,QAAS4H,EAAQ,aAAa,IAAItB,EAAM,EACxC,SAAW,GAAQ6G,EAAW,gBAAiB9S,EAAI,OAAS,EAAIA,EAAM,IAAA,EAAS,EAC/E,OAAQiO,EAAG,eAAe,EAChB,UACX,CAAA,EACC,IACJ,CAAA,CAAA,CAEN,ECvDM8E,GAAuB,CAC3B,IAAK,+BACL,KAAM,+BACR,EAGaC,IAAW,CAAE,aAAY,SAAQ,cAA6B,CACzE,GAAM,CAAE,KAAMnf,EAAe,EACvB+T,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EACxDwV,GAAc,EAAa,IAC/BlL,EAAQ,GAAUhE,EAAY,CAAE,GAAG3C,EAAO,QAAS8B,EAAQ9B,EAAM,QAAS7D,EAAKqC,CAAK,CAAE,CAAC,CAAC,EACpFwO,EAAM,GAAgBpJ,EAAYC,EAAQ,YAAY1H,GAAK,EAC3D6O,EAAU,IAA0C,CAAE,MAAOxO,EAAM,GAAI,MAAOA,EAAM,KAAM,GAC1F,CAAE,WAAYJ,EACd4V,GACJ,EAAAjV,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAG,yBACH,MAAO5N,EAAE,2BAA2B,EACpC,KAAMA,EAAE,+BAA+B,EACvC,MAAOwF,EAAQ,aACf,QAAS0B,EAAqB/H,CAAU,CAAC,CAAC,IAAI4O,CAAM,EACpD,SAAW,GAAU6G,EAAW,eAAgBrT,CAAK,EACrD,WAAYvB,EAAE,eAAe,EAC7B,OAAQ+P,EAAG,cAAc,EACf,UACX,CAAA,EAEH,GAAI5Q,EAAW,OAAS,YACtB,OAAO4V,EAET,IAAMC,EAAO7V,EAAW,QAAQ,YAC1B8V,EAAW9V,EAAW,OAAO,OAAQ,GAAUI,EAAM,QAAQ,EACnE,OACE,EAAAO,EAAA,KAAA,CAAA9K,EAAAA,SAAA,CAAA,SAAA,CACG+f,GACD,EAAAjV,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAG,wBACH,MAAO5N,EAAE,0BAA0B,EACnC,KAAMA,EAAE,8BAA8B,EACtC,MAAOgV,GAAM,QACb,QAASC,EAAS,IAAIlH,CAAM,EAC5B,SAAW,GACT6G,EAAW,cAAenV,EAAU,CAAE,UAAS,UAAWuV,GAAM,WAAa,KAAM,EAAI,IAAA,EAAS,EAElG,WAAYhV,EAAE,2BAA2B,EACzC,OAAQ+P,EAAG,aAAa,EACd,UACX,CAAA,EACAiF,GACC,EAAAlV,EAAA,IAAA,CAAC8N,EAAD,CACE,GAAG,4BACH,MAAO5N,EAAE,8BAA8B,EACvC,MAAOgV,EAAK,UACZ,QAASxd,GAAgB,IAAK,IAAe,CAC3C,MAAO0d,EACP,MAAOlV,EAAE6U,GAAqBK,EAAU,CAC1C,EAAE,EACF,SAAW,GAAcA,GAAaN,EAAW,cAAe,CAAE,GAAGI,EAAM,WAAU,CAAC,EAC5E,UACX,CAAA,EACC,MACJ,EAAAlV,EAAA,IAAA,CAAC6O,EAAD,CACE,GAAG,yBACH,MAAO3O,EAAE,4BAA4B,EACrC,MAAOb,EAAW,QAAQ,cAAgB,CAAC,EAC3C,QAASA,EAAW,OAAO,IAAI4O,CAAM,EACrC,SAAW,GAAQ6G,EAAW,eAAgB9S,EAAI,OAAS,EAAIA,EAAM,IAAA,EAAS,EAC9E,OAAQiO,EAAG,cAAc,EACf,UACX,CAAA,GACD,EAAAjQ,EAAA,IAAA,CAAC6U,GAAD,CAAgB,MAAOxV,EAAoB,SAAkB,UAAW,CAAA,CACxE,CAAA,CAAA,CAEN,EClEagW,IAAmB,CAAE,SAAQ,WAAU,kBAAyC,CAC3F,GAAM,CAAE,KAAMxf,EAAe,EACvBoN,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EACtDsC,EAAO1C,EAAyB,GAAUI,EAAM,IAAI,EACpDsK,EAAS1K,EAAyB,GAAUI,EAAM,MAAM,EAC9D,GAAI,CAAC2D,EACH,OAAO,KAET,IAAM9D,EAAO,GAAmCyK,EAAQ,IAAa,CAAE,GAAGd,EAAS,GAAG6H,CAAM,EAAE,EACxFV,EAAM,GAAqBpJ,EAAYC,EAAQ,IAAI8H,GAAU,EAC7DwD,EAAUxQ,IAAS,MAAQA,EAAK,SAAWqB,EAAM,OACjDqS,EACJ1T,GAAM,OAAS,cAAgBqB,EAAM,OAAS,cAAgB5K,EAAWuJ,CAAI,IAAMvJ,EAAW4K,CAAK,EAE/FsS,EAAa,GACjB3L,EAAQ,GACNd,EAAQ,OAAS,aACb,CAAE,GAAGA,EAAS,SAAQ,aAAc1K,GAAa0K,EAAQ,OAAQH,EAAQG,EAAQ,YAAY,CAAE,EAC/F,CAAE,GAAGA,EAAS,QAAO,CAC3B,EACF,OACE,EAAA9I,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,YAAf,SAAA,CACGwV,GACD,EAAAxV,EAAA,KAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,wBAAwB,EAA/C,SAAA,EACE,EAAAF,EAAA,IAAA,CAACyM,EAAD,CACE,GAAG,mBACH,MAAOvM,EAAE,cAAc,EACvB,MAAO+C,EAAM,MACb,SAAW,GAAU9D,EAAI,CAAE,MAAOsJ,GAAS,EAAG,CAAC,EAC/C,OAAQwH,EAAG,OAAO,EACR,UACX,CAAA,GACD,EAAAjQ,EAAA,IAAA,CAACyM,EAAD,CACE,GAAG,oBACH,MAAOvM,EAAE,eAAe,EACxB,KAAMA,EAAE,mBAAmB,EAC3B,YAAakS,EAAUlS,EAAE,oCAAoC,EAAI,IAAA,GACjE,MAAO+C,EAAM,OACb,SAAW,GAAWsS,EAAU5M,GAAU,EAAE,EAC5C,OAAQsH,EAAG,QAAQ,EACT,WACV,UAAA,EACD,CAAA,EACAhN,EAAM,OAAS,cACd,EAAAjD,EAAA,IAAA,CAACyM,EAAD,CACE,GAAG,0BACH,MAAOvM,EAAE,qBAAqB,EAC9B,KAAMA,EAAE,yBAAyB,EACjC,YAAaoV,EAAgBpV,EAAE,0CAA0C,EAAI,IAAA,GAC7E,MAAO+C,EAAM,aACb,SAAW,GAAiB9D,EAAI,CAAE,cAAa,CAAC,EAChD,OAAQ8Q,EAAG,cAAc,EACf,WACV,iBAAA,GACA,UAAA,EACD,CAAA,EACC,MACJ,EAAAjQ,EAAA,IAAA,CAACyM,EAAD,CACE,GAAG,yBACH,MAAOvM,EAAE,yBAAyB,EAClC,MAAO+C,EAAM,YACb,SAAW,GAAgB9D,EAAI,CAAE,aAAY,CAAC,EAC9C,OAAQ8Q,EAAG,aAAa,EACd,WACV,iBAAA,GACA,UAAA,EACD,CAAA,EACAhN,EAAM,OAAS,aACd,EAAAjD,EAAA,IAAA,CAACyM,EAAD,CACE,GAAG,sBACH,MAAOvM,EAAE,yBAAyB,EAClC,KAAMA,EAAE,6BAA6B,EACrC,MAAO+C,EAAM,SACb,SAAW,GAAa9D,EAAI,CAAE,UAAS,CAAC,EACxC,OAAQ8Q,EAAG,UAAU,EACX,WACV,iBAAA,EACD,CAAA,EACC,IACQ,IACbhN,EAAM,OAAS,YAAc,MAC5B,EAAAjD,EAAA,KAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,wBAAwB,EAA/C,SAAA,EACE,EAAAF,EAAA,IAAA,CAACiP,EAAD,CACE,GAAG,uBACH,MAAO/O,EAAE,kBAAkB,EAC3B,KAAMA,EAAE,mCAAmC,EAC3C,QAAS+C,EAAM,UACf,SAAW,GAAc9D,EAAI,CAAE,WAAU,CAAC,EAC1C,OAAQ8Q,EAAG,WAAW,EACZ,UACX,CAAA,GACD,EAAAjQ,EAAA,IAAA,CAACiP,EAAD,CACE,GAAG,6BACH,MAAO/O,EAAE,gCAAgC,EACzC,KAAMA,EAAE,oCAAoC,EAC5C,QAAS+C,EAAM,gBACf,SAAW,GAAoB9D,EAAI,CAAE,iBAAgB,CAAC,EACtD,OAAQ8Q,EAAG,iBAAiB,EAClB,UACX,CAAA,CACW,KAEhB,EAAAjQ,EAAA,IAAA,CAAC+D,EAAD,CAAc,MAAO7D,EAAE,wBAAwB,EAC7C,UAAA,EAAAF,EAAA,IAAA,CAACgV,GAAD,CAAS,WAAY/R,EAAe,SAAkB,UAAW,CAAA,CACrD,CAAA,CACX,GAET,ECpHawS,IAAW,CAAE,eAA8B,CACtD,GAAM,CAAE,GAAM5f,EAAe,EACvBoN,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EAC5D,GAAI,CAAC2D,EACH,OAAO,KAET,IAAMyS,EAAWzb,GAAWgJ,EAAM,MAClC,OACE,EAAAjD,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,sCAAf,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC9I,EAAD,CAAO,QAAQ,UAAf,SAAA,EACE,EAAA8I,EAAA,IAAA,CAAC0V,EAAD,CAAU,cAAY,MAAQ,CAAA,EAC7B,EAAE3b,GAAgBkJ,EAAM,KAAK,CACzB,IACNA,EAAM,OAAS,YAAc,MAC5B,EAAAjD,EAAA,KAAA,CAAA7K,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA6K,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,UACZ,SAAA,EAAE+L,EAAM,UAAY,kCAAoC,oCAAoC,CACxF,CAAA,GACP,EAAAjD,EAAA,IAAA,CAAC9I,EAAD,CAAO,QAAQ,UACZ,SAAA,EAAE+L,EAAM,gBAAkB,+BAAiC,gCAAgC,CACvF,CAAA,CACP,CAAA,CAAA,EAEHA,EAAM,OAAS,cACd,EAAAjD,EAAA,KAAA,CAAC9I,EAAD,CAAO,QAAQ,UAAU,UAAU,wBAAnC,SAAA,EACE,EAAA8I,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,UAAhB,SAAA,CAA2B,EAAE,qBAAqB,EAAE,GAAO,CAC1D,CAAA,EAAA3H,EAAW4K,CAAK,CACZ,CACL,CAAA,EAAA,KACHoI,GAAY,EAAArL,EAAA,IAAA,CAAClJ,EAAD,CAAY,KAAK,SAAS,KAAK,KAAK,MAAO,EAAE,4BAA4B,CAAI,CAAA,EAAI,IAC3F,GAET,ECxBM6e,GAAqB,GAA2B,CAAC,kBAAkB,KAAKC,EAAM,IAAI,EAG3EC,IAAiB,CAAE,SAAQ,WAAU,kBAAuC,CACvF,GAAM,CAAE,KAAMhgB,EAAe,EACvB,CAACigB,EAAUC,IAAA,EAAe3gB,EAAAA,SAAAA,CAAS,EAAK,EACxC4gB,GAAA,EAAS3gB,EAAAA,MAAAA,CAAM,EACrB,OACE,EAAA2K,EAAA,IAAA,CAACjC,GAAD,CACE,MAAOmC,EAAE,mCAAmC,EAC5C,SACE,EAAAF,EAAA,IAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,UACL,gBAAekc,EACf,gBAAeE,EACf,aAAY9V,EAAE,mCAAmC,EACjD,YAAe6V,EAAa,GAAS,CAACE,CAAI,EAE1C,UAAA,EAAAjW,EAAA,IAAA,CAACrF,GAAD,CAAa,cAAY,OAAO,UAAW3E,EAAG,uBAAwB8f,GAAY,YAAY,CAAI,CAAA,CAC5F,CAAA,EAGV,UAAA,EAAA9V,EAAA,IAAA,CAAC,MAAD,CAAK,GAAIgW,EACN,SAAAF,GACC,EAAA9V,EAAA,IAAA,CAACqV,GAAD,CAAyB,SAAkB,WAAwB,cAAe,CAAA,GAElF,EAAArV,EAAA,IAAA,CAACyV,GAAD,CAAS,UAAW3O,EAAO,KAAK6O,EAAiB,CAAI,CAAA,CAEpD,CAAA,CACA,CAAA,CAEX,EC3CaO,IAAmB,CAAE,eAAsC,CACtE,GAAM,CAAE,GAAMrgB,EAAe,EAC7B,OACE,EAAAmK,EAAA,IAAA,CAACjC,GAAD,CAAO,aAAY,EAAE,gCAAgC,EAAG,UAAU,kBAC/D,SAAAoY,GACC,EAAAnW,EAAA,IAAA,CAACjJ,EAAD,CAAY,KAAK,QAAQ,KAAM2H,GAAmB,MAAO,EAAE,4BAA4B,CAAI,CAAA,GAE3F,EAAAsB,EAAA,IAAA,CAACjJ,EAAD,CAAY,KAAK,QAAQ,KAAM6H,GAAQ,MAAO,EAAE,2BAA2B,CAAI,CAAA,CAE5E,CAAA,CAEX,ECKawX,IAAsB,CAAE,SAAQ,QAAO,WAAU,iBAA2C,CACvG,GAAM,CAAE,KAAMvgB,EAAe,EACvBwgB,EAASzD,GAAS0D,IAAW,WACnC,OACE,EAAAtW,EAAA,KAAA,CAACnF,GAAD,CACE,QAAQ,UACR,KAAMyb,IAAW,WAAa,QAAU,SACxC,UAAU,oDAHZ,SAAA,EAKE,EAAAtW,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,yBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACtD,GAAD,CAAW,UAAU,yBAAyB,cAAY,MAAQ,CAAA,GAClE,EAAAsD,EAAA,KAAA,CAAC,MAAD,CAAA,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC7E,GAAD,CAAA,SAAa+E,EAAE,qBAAqB,CAAc,CAAA,GAClD,EAAAF,EAAA,IAAA,CAAC/E,GAAD,CAAA,SACGiF,EAAEmW,EAAS,kCAAoC,2BAA2B,CAC3D,CAAA,CACf,CAAA,CAAA,CACF,CACJ,CAAA,EAAAA,GACC,EAAArW,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,uBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,QAAS2c,EACxD,SAAArW,EAAE,yBAAyB,CACtB,CAAA,GACR,EAAAF,EAAA,IAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,QAAS4c,EACxD,SAAAtW,EAAE,4BAA4B,CACzB,CAAA,CACL,CAEL,CAAA,GAAA,EAAAF,EAAA,IAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,QAAS4c,EACxD,SAAAtW,EAAE,sBAAsB,CACnB,CAAA,CAEL,GAEX,EC5CauW,IAAc,CAAE,UAAS,SAAQ,WAA6B,CACzE,GAAM,CAAE,KAAM5gB,EAAe,EAC7B,OACE,EAAAmK,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,YACZ,SAAA3E,GAAcqb,CAAO,CAAC,CAAC,KAAK,CAAE,SAAQ,QAASC,MAC9C,EAAA3W,EAAA,KAAA,CAAC,MAAD,CAAkB,UAAU,YAA5B,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACpE,GAAD,CAAoB,QAAS,CAAA,GAC7B,EAAAoE,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,+CAAgD,SAAA2W,EAAQ,MAAa,CAAA,CAClF,CACL,CAAA,GAAA,EAAA3W,EAAA,IAAA,CAAC,KAAD,CAAI,aAAYE,EAAElG,GAAuB4c,EAAO,EAAG,UAAU,6BAC1D,SAAAD,EAAQ,KAAK,EAAQ,KACpB,EAAA3W,EAAA,IAAA,CAAC,KAAD,CAEE,UAAU,sBAET,SAAAtE,GAAeoF,EAAQmH,EAAQ4O,CAAK,CACnC,EAJG,GAAG/V,EAAO,KAAK,GAAGA,EAAO,SAAW,GAAG,GAAGA,EAAO,UAAY,GAAG,GAAGmG,GAItE,CACL,CACC,CAAA,CACD,CAfK,EAAA2P,CAeL,CACN,CACE,CAAA,CAET,EC1BaE,OAA6B,CACxC,GAAM,CAAE,KAAMjhB,EAAe,EACvBkhB,EAAW7gB,EAAY,EACvB8gB,EAAOxa,GAAwB,EAsBrC,MAAO,CAAE,wBArBwB,EAAsB,IAA4B,CACjF,GAAM,CAAE,QAASmY,EACXtL,EAAQ,MAAMtM,GAClBia,EAAK,YAAY,CACf,aAAc5C,EAAK,aACnB,YAAalU,EAAE,0BAA2B,CAAE,MAAO+C,EAAM,KAAM,CAAC,EAChE,MAAO,CACL,SAAUmR,EAAK,OAAS,YAAc,YAAc,QACpD,WAAYnR,EACZ,YAAamR,EAAK,WACpB,CACF,CAAC,CACH,EACI/K,EAAM,IACR,MAAM0N,EAAS,CACb,GAAI,wBACJ,OAAQ,CAAE,YAAa1N,EAAM,KAAM,EACnC,cAAe,EACjB,CAAC,CAEL,EAC4B,OAAQ2N,EAAK,UAAW,UAAWA,EAAK,MAAO,UAAWA,EAAK,KAAM,CACnG,ECFMC,GAAe,CACnB,SAAU,+BACV,cAAe,oCACf,KAAM,2BACN,SAAU,8BACZ,EASaC,IAAe,CAC1B,UACA,SACA,QACA,WACA,QACA,UACA,aACsB,CACtB,GAAM,CAAE,KAAMrhB,EAAe,EACvB,CAACshB,EAAsBC,IAAA,EAA2B9hB,EAAAA,SAAAA,CAAS,EAAK,EAChE,CAAC+hB,EAAyBC,IAAA,EAA8BhiB,EAAAA,SAAAA,CAAS,EAAK,EACtE,CAACiiB,EAAcC,IAAA,EAAmBliB,EAAAA,SAAAA,CAASqf,CAAO,EAClD,CAAE,oBAAmB,SAAQ,aAAW,aAAcmC,GAAqB,EAC3EW,GAAOC,GAAYC,EAErBhD,IAAY,IAAA,IAAaA,IAAY4C,IACvCC,EAAgB7C,CAAO,EACvByC,EAAwB,EAAK,EAC7BE,EAA2B,EAAK,EAChCM,EAAU,GAEZ,IAAMxD,EAAOmD,GAAc,KACrBM,EAAUzD,GAAM,QAChBwC,EAASiB,EAAUrc,GAAaqc,CAAO,EAAI,WAC3CC,EAAgBD,GAAS,UAAY,GACrCE,EAAmBF,GAAS,aAAe,GAC3CG,IAAY,CAACF,GAAiBX,KAA0B,CAACY,GAAoBV,GACnF,OACE,EAAArX,EAAA,IAAA,CAACzJ,EAAD,CAAO,KAAMoe,IAAY,IAAA,GAAW,aAAe,GAAS,CAACsB,GAAQ,CAACwB,IAAQQ,EAAQ,EACpF,UAAA,EAAAjY,EAAA,KAAA,CAAC7I,GAAD,CAAc,KAAK,KAAnB,SAAA,EACE,EAAA6I,EAAA,KAAA,CAAChJ,GAAD,CAAa,UAAU,QAAvB,SAAA,EACE,EAAAgJ,EAAA,IAAA,CAACnJ,EAAD,CAAA,SAAaqJ,EAAE,oBAAqB,CAAE,MAAO2W,GAAO,OAAS,EAAG,CAAC,CAAc,CAAA,GAC/E,EAAA7W,EAAA,IAAA,CAACxJ,EAAD,CAAA,SAAmB0J,EAAE+W,GAAaL,EAAO,CAAoB,CAAA,CAClD,CACZ,CAAA,EAAAxC,GAAQmD,GACP,EAAAvX,EAAA,KAAA,CAAC,OAAD,CACE,WAAA,GACA,UAAU,+BACV,SAAW,GAAU,CACnB0K,EAAM,eAAe,EACrBwN,EAAQ,CACN,GAAIJ,EAAgB,CAAE,oBAAqB,EAAK,EAAI,CAAC,EACrD,GAAIC,EAAmB,CAAE,uBAAwB,EAAK,EAAI,CAAC,CAC7D,CAAC,CACH,EATF,SAAA,EAWE,EAAA/X,EAAA,KAAA,CAACpJ,GAAD,CAAW,UAAU,iBAArB,SAAA,EACE,EAAAoJ,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oEAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACpE,GAAD,CAAoB,QAAS,CAAA,GAC7B,EAAAoE,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,kCACb,SAAAE,EAAE,uBAAwB,CAAE,MAAOqX,EAAa,OAAO,aAAc,CAAC,CACnE,CAAA,CACH,KACL,EAAAvX,EAAA,KAAA,CAAC,UAAD,CAAS,UAAU,YAAY,kBAAgB,eAA/C,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,KAAD,CAAI,GAAG,eAAe,UAAU,wBAC7B,SAAAE,EAAE,sBAAuB,CAAE,MAAOkU,EAAK,QAAQ,MAAO,CAAC,CACtD,CAAA,GACJ,EAAApU,EAAA,IAAA,CAACyW,GAAD,CAAY,QAASrC,EAAK,QAAiB,SAAe,OAAQ,CAAA,CAC3D,IACRA,EAAK,cAAc,OAAS,GAC3B,EAAApU,EAAA,KAAA,CAAC,UAAD,CAAS,UAAU,YAAY,kBAAgB,qBAA/C,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,0BAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,KAAD,CAAI,GAAG,qBAAqB,UAAU,wBACnC,SAAAE,EAAE,2BAA2B,CAC5B,CAAA,GACJ,EAAAF,EAAA,IAAA,CAACtG,GAAD,CAAU,MAAOwG,EAAE,2BAA2B,EAC3C,SAAAA,EAAE,+BAA+B,CAC1B,CAAA,CACP,CACL,CAAA,GAAA,EAAAF,EAAA,IAAA,CAAClE,GAAD,CACE,MAAM,SACN,MAAOsY,EAAK,cACZ,QAASmD,EAAa,OAAO,MACrB,SACD,OACR,CAAA,CACM,CACP,CAAA,EAAA,KACHnD,EAAK,UAAU,OAAS,GACvB,EAAApU,EAAA,KAAA,CAAC,UAAD,CAAS,UAAU,YAAY,kBAAgB,kBAA/C,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,KAAD,CAAI,GAAG,kBAAkB,UAAU,wBAChC,SAAAE,EAAE,uBAAuB,CACxB,CAAA,GACJ,EAAAF,EAAA,IAAA,CAAClE,GAAD,CAAU,MAAM,QAAQ,MAAOsY,EAAK,UAAmB,SAAe,OAAQ,CAAA,CACvE,CACP,CAAA,EAAA,KACH0D,GAAiBC,GAChB,EAAA/X,EAAA,KAAA,CAAC,WAAD,CAAU,UAAU,wEAApB,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,UAAU,0CACf,SAAAE,EAAE,yBAAyB,CACtB,CAAA,EACP4X,GACC,EAAA9X,EAAA,KAAA,CAACzG,EAAD,CAAO,YAAY,aAAnB,SAAA,EACE,EAAAyG,EAAA,IAAA,CAAChF,GAAD,CACE,GAAG,oBACH,QAASmc,EACT,gBAAkB,GAAYC,EAAwBrI,IAAY,EAAI,CACvE,CAAA,GACD,EAAA/O,EAAA,IAAA,CAAC5G,GAAD,CAAY,QAAQ,oBAAoB,UAAU,cAC/C,SAAA8G,EAAE,iCAAiC,CAC1B,CAAA,CACP,CACL,CAAA,EAAA,KACH6X,GACC,EAAA/X,EAAA,KAAA,CAACzG,EAAD,CAAO,YAAY,aAAnB,SAAA,EACE,EAAAyG,EAAA,IAAA,CAAChF,GAAD,CACE,GAAG,uBACH,QAASqc,EACT,gBAAkB,GAAYC,EAA2BvI,IAAY,EAAI,CAC1E,CAAA,GACD,EAAA/O,EAAA,IAAA,CAAC5G,GAAD,CAAY,QAAQ,uBAAuB,UAAU,cAClD,SAAA8G,EAAE,oCAAoC,CAC7B,CAAA,CACP,CACL,CAAA,EAAA,IACI,CACR,CAAA,EAAA,MACJ,EAAAF,EAAA,IAAA,CAACjF,GAAD,CAAW,MAAO6F,GAASuX,EAAY,CAAA,CAC9B,CACX,CAAA,GAAA,EAAAnY,EAAA,KAAA,CAACvJ,EAAD,CAAA,SAAA,EACE,EAAAuJ,EAAA,IAAA,CAACpG,EAAD,CAAQ,KAAK,SAAS,QAAQ,UAAU,QAASqe,EAAS,SAAUR,GACjE,SAAAvX,EAAE,eAAe,CACZ,CAAA,GACR,EAAAF,EAAA,KAAA,CAACpG,EAAD,CACE,KAAK,SACL,QAAQ,UACR,SAAU6d,IAAQ,CAACZ,EACnB,YAAWc,GAAU,IAAA,GACrB,YAAed,GAAS,KAAKuB,EAAkBb,EAAcV,CAAK,EALpE,SAAA,CAOGc,GACC,EAAA3X,EAAA,IAAA,CAACzK,EAAD,CAAS,UAAU,0CAA0C,cAAY,MAAQ,CAAA,GAEjF,EAAAyK,EAAA,IAAA,CAACzE,GAAD,CAAgB,cAAY,MAAQ,CAAA,EAE5B2E,EAATyX,EAAW,gBAAqB,2BAA2B,CACtD,KACR,EAAA3X,EAAA,IAAA,CAAC3J,EAAD,CACE,QAASqhB,EACT,aAAcxX,EAAE,sBAAsB,EACtC,SAAU,CAAC8X,IAAYL,EAEtB,SAAAzX,EAAE,mBAAmB,CACV,CAAA,CACH,CAAA,CAAA,CACT,CACJ,CAAA,EAAA,IACQ,GACT,CAAA,CAEX,EChKamY,IAAU,CAAE,WAAU,KAAI,YAA0B,CAC/D,GAAM,CAAE,KAAMxiB,EAAe,EACvBkhB,EAAW7gB,EAAY,EACvBkJ,EAAMQ,GAAWZ,EAAUC,CAAE,EAC7BqZ,EAAYpZ,EAAyB,GAAUI,EAAM,GAAG,EACxD2D,EAAQ/D,EAAyB,GAAUI,EAAM,KAAK,EACtDsC,EAAO1C,EAAyB,GAAUI,EAAM,IAAI,EACpD2U,EAAc/U,EAAyB,GAAUI,EAAM,WAAW,EAClEiE,EAAOrE,EAAyB,GAAUI,EAAM,IAAI,EACpDiZ,EAAQrZ,EAAyB,GAAUI,EAAM,KAAK,EACtDuE,EAAcR,GAAerE,EAAUC,CAAE,EACzCuZ,EAAOrE,GAAYnV,EAAUC,EAAI4E,CAAW,EAC5C+O,EAAQiB,GAAgB,EACxB,CAAE,UAAWF,GAAe,EAC5B,CAAE,QAAO,UAAUiB,GAAiB,EACpC,CAAE,SAAQ,UAAW5W,GAAc,EACnCya,EAAiB5Y,GAAkB4D,EAAO,KAAK,EAC/C,CAAE,cAAcpJ,EAAqB,EACrCqe,GAAmBxb,GAAoB,EACvCyb,EAAWhP,GAAY,EACvBiP,GAAWzF,GAAe,EAC1B,CAAC0F,EAAkBC,IAAA,EAAuBtjB,EAAAA,SAAAA,CAAS,EAAK,EACxD,CAACujB,EAAmBC,IAAA,EAAwBxjB,EAAAA,SAAAA,CAA6B,IAAA,EAAS,EAClF,CAACyjB,GAAeC,IAAA,EAAoB1jB,EAAAA,SAAAA,CAAS,EAAK,EAGlD2jB,IAAA,EAAU1jB,EAAAA,OAAAA,CAAOgO,CAAM,GAC7B,EAAA5E,EAAA,UAAA,MACE0E,EAAKvE,EAAUma,GAAQ,QAAQ,WAAYA,GAAQ,QAAQ,OAAO,EAC3DZ,GACN,CAACnZ,EAAKJ,EAAUuE,EAAMgV,CAAK,CAAC,EAE/B,IAAMxX,GAAWyX,EAAK,iBAAmB/U,EAAO,eAAe,GACzD2V,EAAkBrY,KAAagY,EAAoB,IAAA,GAAYhY,GAC/DsY,EAAgBD,IAAoB,IAAA,GACpC,CAAE,qBAAqBtF,GAAsB7U,EAAIgV,EAAaoF,GAAiBb,EAAK,QAAQ,EAC5Fc,GAAc5U,GAAU+T,GAAkBY,EAC1C9Y,EAAYqS,GAAS9L,EAAO,SAAW,GAAK,CAACwS,IAAe,CAACd,EAAK,UAClEe,GAAWf,EAAK,MAAM,OAAS,SAC/B/E,GAAW+E,EAAK,MAAM,OAAS,YAAcS,GAGnD,GAFApb,OAAsB,KAAK2a,EAAK,OAAO,EAAGjY,GAAa,CAACgZ,EAAQ,EAE5DjB,IAAclZ,GAAO,CAAC6D,EACxB,OAAO,EAAAjD,EAAA,IAAA,CAAC5I,GAAD,CAAe,CAAA,EAGxB,IAAMoiB,EAAU,GACd,KAAK3V,EAAYH,CAAI,CAAC,CAAC,MAAO,GAAmB,CAC/CzK,GAAS2H,EAAO,0BAA0B,EAC1C5H,EAAM,MAAMa,GAAc+G,CAAK,CAAC,CAClC,CAAC,EACG6Y,EAAkB/U,GAAU+T,EAE5BjD,GAAekE,IACnB,EAAA1Z,EAAA,IAAA,CAACmE,GAAD,CACY,WACN,KACJ,MAAOlB,EAAM,MACb,MAAOQ,EAAO,MACd,QAASmP,GAASyG,GAAiBb,EAAK,SAChC,SACR,eAAkBU,EAAiB,EAAI,CACxC,CAAA,EACC,KAEExG,GAAc,CAClB,WAAYE,EACZ,YACA,UAAW4F,EAAK,UAChB,aAAgB,KAAKA,EAAK,OAAO,EACjC,cAAiB,CACX5W,GACF2B,EAAKvE,EAAU4C,EAAMqS,CAAW,CAEpC,CACF,EAEA,OACE,EAAAjU,EAAA,KAAA,CAAC1J,EAAD,CAAM,MAAM,OAAZ,SAAA,EACE,EAAA0J,EAAA,IAAA,CAAC3I,EAAD,CAAqB,KAAMub,CAAQ,CAAA,GACnC,EAAA5S,EAAA,IAAA,CAACyS,GAAD,CACE,GAAIC,GACG,QACP,QAASuB,EACF,QACP,WAAYnN,EAAO,OACnB,cAAewS,GACf,aAAgBR,EAAoB,EAAI,CACzC,CAAA,EACApU,GAAS,EAAA1E,EAAA,IAAA,CAAC/B,GAAD,CAAoB,QAAS,CAAA,EAAI,KAC1Cwa,GAAiB,EAAAzY,EAAA,IAAA,CAACC,GAAD,CAAe,CAAA,EAAI,KACpC0Z,IAAoBlG,IACnB,EAAAzT,EAAA,IAAA,CAACoW,GAAD,CAEE,OAAQ3C,GAAW,WAAa,SACzB,QACP,aAAgB,CACd+E,EAAK,UAAU,EACfU,EAAiB,EAAK,EACtBM,EAAO,SAAS,CAClB,EACA,gBAAmB,CACjBhB,EAAK,UAAU,EACfU,EAAiB,EAAK,EACtBM,EAAO,QAAQ,CACjB,CACD,EAbM/F,GAAW,WAAa,QAa9B,EACC,KACH2F,GACC,EAAApZ,EAAA,IAAA,CAACa,GAAD,CAEE,SAAUuY,EACV,WAAa,GAAW,KAAKZ,EAAK,iBAAiBxX,CAAM,EACzD,cAAiB,CACfgY,EAAqBI,CAAe,EACpCZ,EAAK,cAAc,CACrB,CACD,EAPMY,CAON,EACC,MAMJ,EAAApZ,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,yEAAf,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,oBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC6V,GAAD,CAAuB,SAAQ,SAAU4D,EAA+B,eAAe,CAAA,GACvF,EAAAzZ,EAAA,IAAA,CAACuL,GAAD,CACU,SACR,SAAUkO,EACV,MAAOd,EAAS,IAChB,IAAK1V,EAAM,OAAS,YAAc,IAAA,GAAY2V,EAC/C,CAAA,CACE,CACJ,CAAA,EAAAnZ,GACC,EAAAO,EAAA,IAAA,CAACgS,GAAD,CAES,QACA,SACC,SACR,SAAUyH,EACV,UAAWd,EAAS,YAAYlZ,CAAK,EACrC,cAAiBkZ,EAAS,QAAQlZ,EAAM,EAAE,CAC3C,EAPMA,EAAM,EAOZ,GAED,EAAAO,EAAA,IAAA,CAACkW,GAAD,CAAiB,UAAWjT,EAAM,OAAO,OAAS,CAAI,CAAA,CAErD,KACL,EAAAjD,EAAA,IAAA,CAACS,GAAD,CAAc,GAAIiS,EAAc,CAAA,GAChC,EAAA1S,EAAA,IAAA,CAACkX,GAAD,CACE,QAASsB,EAAK,MAAM,OAAS,SAAWA,EAAK,MAAM,QAAU,IAAA,GAC7D,OAAQ5W,EACR,MAAOqB,EACP,SAAUuV,EAAK,SACf,MAAOA,EAAK,WACZ,QAAU,GAAoB,KAAKA,EAAK,QAAQoB,CAAe,EAC/D,QAASpB,EAAK,SACf,CAAA,GACD,EAAAxY,EAAA,IAAA,CAAC5E,GAAD,CACE,KAAMyd,EACN,aAAcC,EACd,MAAO5Y,EAAE,6BAA8B,CAAE,MAAO+C,EAAM,KAAM,CAAC,EAC7D,YAAa/C,EAAE,kCAAkC,EACjD,aAAcA,EAAE,eAAe,EAC/B,YAAA,GACA,cACEwY,GAAiB,OACf,CAAE,WAAU,KAAI,gBAAiBzE,CAAY,EAC7C,CACE,cAAiB,CACfsE,EAAM,EACNvf,EAAM,QAAQkH,EAAE,gBAAgB,CAAC,EACjC6W,EAAc,CAAE,GAAI,SAAU,CAAC,CACjC,CACF,CACF,CAEH,CAAA,CACG,GAEV,ECrNa8C,IAAW,CAAE,WAAU,QAAuB,CACzD,IAAMpW,EAASlG,GAAcyB,EAAUC,CAAE,EACzC,OACE,EAAAe,EAAA,IAAA,CAACpC,GAAD,CAAW,MAAO6F,EACd,SAAA,IAAS,EAAAzD,EAAA,IAAA,CAACqY,GAAD,CAA2B,WAAc,KAAI,OAAQyB,CAAO,EAA/C7a,CAA+C,CAC9D,CAAA,CAEf"}
|
|
1
|
+
{"version":3,"file":"Builder-Z_hcyzNW.js","names":["__iconData","__iconData","Globe2","_Fragment","useRef","AlertCircle","Loader2","useCallback","useId","useState","useId","useState","AlertCircle","useRef","useState","_Fragment","useId","useState","_Fragment","useMemo","Trash2","_Fragment","Trash2","_Fragment","MoreHorizontal","Trash2","useDeferredValue","useMemo","useMemo","useState","_Fragment","_Fragment","_Fragment","useState","useId","useState","Loader2","useState","useRef","__toESM","require_jsx_runtime","useQueryClient","useTranslation","create","LoaderCircle","cn","linkOptions","useNavigate","hasErrorCode","useMe","SubmitButton","Page","Sheet","SheetDescription","SheetFooter","PageHeader","useParams","SheetBody","SheetTitle","StatusChip","EmptyState","SheetHeader","IconTile","Badge","SheetContent","LoadingState","UnsavedChangesGuard","SEO_EDITOR_ID","isCustomEditorId","isCoverEligible","effectiveTitleField","SORT_DIRECTIONS","DATA_TYPES","SETTINGS_SCHEMAS","DEFAULT_EDITORS","SEO_COMPONENT_ID","isCanvasEligible","SCALAR_DATA_TYPES","UNIQUE_CAPABLE_DATA_TYPES","renormalizeDefinition","foldApiKey","validateDefinition","routeKeyOf","listCompatibleEditors","EDITOR_CATALOGUE","validateSchema","RESERVED_FIELD_API_KEYS","canonicalJson","parseDefinition","isDocumentPlaceable","effectiveLayout","useEnsureSeoComponent","seoConflictOf","toast","logError","Trash","FieldDescription","FieldLabel","FieldLegend","FieldError","Field","FieldSet","FieldContent","InfoHint","FieldGroup","Button","describeError","Input","KIND_LABEL_KEYS","PLAN_BUCKET_LABEL_KEYS","KIND_ICONS","DATA_TYPE_ICONS","DATA_TYPE_GROUPS","Earth","useSchemaScopeAccess","SelectValue","SelectTrigger","SelectContent","ChevronUp","SelectItem","ChevronDown","Select","Alert","CircleAlert","FormError","Checkbox","AlertDescription","InlineConfirm","AlertTitle","ConfirmDialog","groupByBucket","valueLabel","GitPullRequest","bucketOfPlan","classifyChange","describeChange","editorLabel","BucketChip","propertyLabel","StepList","Ellipsis","Search","GripVertical","newStableId","DropdownMenuItem","DropdownMenuTrigger","DropdownMenuContent","DropdownMenu","Plus","useSaveDraftToChangeSet","useShipDraftNow","RefreshCw","Undo2","RadioGroup","Switch","describedBy","settle","HintedLabel","SharedGlyph","useDeleteDefinition","useSchemaSummary","FINAL_CHANGE_STATUSES","useChangeScope","usePlanChange","useDefinition","useAllDefinitions","useDefinitions","definitionQueryOptions","useSchemaChange","QueryView","useSaveShortcut","Textarea","Panel","useSchemaLock","LockNotice","deriveApiKey","describeIssue","followPlural","RadioTile","__iconData$2","EyeOff","createLucideIcon","__iconData$1","MousePointerClick","__iconData","Shapes","import_react","require_react","keyOf","category","id","useDefinitionDraftStore","set","key","definition","state","version","selection","field","recipe","fieldId","draftKeyOf","useSharedReadOnly","scope","canShare","import_jsx_runtime","SharedNotice","t","SaveActions","onDiscard","canDiscard","reviewing","canReview","onReview","ActionFooter","props","failureOf","error","ChangeProgress","change","changeId","status","reported","onFinished","failure","onDismiss","same","a","b","isPlainObject","value","merge3","mine","base","theirs","keys","merged","ids","fields","kept","mergeFields","baseById","mineById","theirsById","primary","secondary","original","ours","other","rebaseDraft","baseFields","baseRest","draftFields","draftRest","draft","latestFields","latestRest","latest","useReloadDraft","queryClient","load","rebase","detail","mode","useScopeChange","changeScope","reloadDraft","onConflict","PanelSection","className","titleId","title","Scope","site","hintId","shared","target","siteName","blocked","locked","INITIAL_SETTINGS","createField","raw","input","withKey","next","record","withSetting","isDraftDirty","moveItem","from","to","items","moved","removeField","display","group","pruneLayout","canvasFieldIds","coverFieldId","stripFieldIds","eligible","test","canvas","cover","strip","withCompatibleEditor","compatible","entry","validateDraft","parsed","schema","others","found","issuesUnder","issues","path","fieldPath","index","IssueList","messages","titleFieldCandidates","probe","withAddedField","titled","candidate","documentPlacementOf","layout","model","inDocument","withDocumentPlacement","without","order","position","before","documentLayoutChoices","live","RESERVED","uniqueNewFieldName","labels","apiKeys","number","label","baseLabel","apiKey","folded","withFieldType","current","type","fresh","_defaultValue","placed","isCandidate","withFieldTypeOrSaved","saved","defaultValue","ADD_FIELD_BUTTON_ID","labelInputIdOf","afterRender","run","useNewField","update","select","added","setAdded","SEO_HELP_KEYS","AddFieldButton","helpId","confirming","setConfirming","addButton","onAdd","seo","help","availability","event","handleIdOf","Row","Icon","disabled","selected","dropTarget","onMove","total","onSelect","showLocalized","hasIssues","NO_FIELDS","FieldList","localized","dragFrom","dropIndex","setDropIndex","announcement","setAnnouncement","move","refocus","definitionIssues","count","TEXT_DEFAULT_TYPES","supportsDefaultValue","controlIds","hint","descriptionId","description","errorId","TextControl","onChange","emptyAsUndefined","multiline","monospace","TYPES","isDataType","DataType","labelledBy","unavailable","unavailableReason","notes","limitedNote","parse","text","integer","NumberControl","setText","shownValue","setShownValue","UNSET","SelectControl","known","options","option","unsetLabel","placeholder","DefaultValue","common","enumOptions","describeControl","itemOptions","describeProperties","object","required","property","ChoicesControl","toggle","checked","optionId","SwitchControl","control","LIST_SEPARATOR","PropertyControl","idPrefix","EditorPicker","choices","properties","choice","FLAG_KEYS","availableFlags","isComponent","modelLocalized","indexable","Flags","flag","at","classifyFieldTypeChange","NO_TYPES","useTypeChoices","LOCK_KEYS","Placement","lock","EnumValues","values","replace","patch","listIssues","rowIssues","valueId","labelId","HIDDEN_SETTINGS","FORMAT_HINT_KEYS","SOURCE_FIELD_TYPES","TypeSettings","settings","settingsPath","all","definitions","models","components","toOption","render","formatKey","rendered","otherIssues","CONTROLLED","FieldPanel","updateField","typeChoices","name","renamed","isNew","setLabel","followsLabel","untouched","Header","saveActions","breadcrumb","dirty","issueCount","deleteBlocked","onDelete","SEO_FIELD_LABEL","hasSeoField","createSeoField","useAddSeoField","present","ensure","exists","item","add","conflict","NO_ISSUES","useDraftIssues","deferredDraft","useIsDraftDirty","useRemoteChangeNotice","remote","ownChangeRunning","baseVersion","isVersionConflict","useSaveFlow","plan","apply","setState","runningChangeId","setRunningChangeId","notifyFailure","finishSuccessfully","preview","useSelectedField","DocumentLayout","setDisplay","DIRECTION_LABEL_KEYS","Display","titleField","sort","sortable","direction","DefinitionPanel","pluralRenamed","setApiKey","scopeSection","Summary","KindIcon","isDefinitionIssue","issue","ModelSettings","expanded","setExpanded","bodyId","open","NoFieldSelected","hasFields","RemoteChangeBanner","choose","reason","onKeepEdits","onReload","ChangeList","changes","inGroup","bucket","after","useReviewInChangeSet","navigate","save","SUMMARY_KEYS","ReviewSheet","acknowledgedBreaking","setAcknowledgedBreaking","acknowledgedDestructive","setAcknowledgedDestructive","previewShown","setPreviewShown","busy","applying","saving","resetSave","summary","needsBreaking","needsDestructive","canApply","onClose","onApply","saveError","reviewInChangeSet","Editor","loadedKey","reset","flow","sharedReadOnly","deleteDefinition","newField","seoField","confirmingDelete","setConfirmingDelete","dismissedChangeId","setDismissedChangeId","scopeConflict","setScopeConflict","initial","visibleChangeId","changeRunning","saveBlocked","planOpen","reload","editingDisabled","multiSite","changedElsewhere","acknowledgement","Builder","data"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/eye-off.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/mouse-pointer-click.mjs","../../../../node_modules/.pnpm/lucide-react@1.49.0_@types+react@19.3.0_react@19.3.0/node_modules/lucide-react/dist/esm/icons/shapes.mjs","../../src/stores/definitionDraft.ts","../../src/features/Models/hooks/useSharedReadOnly.ts","../../src/features/Models/SharedNotice/index.tsx","../../src/features/Models/Builder/SaveActions/index.tsx","../../src/features/Models/Builder/ActionFooter/index.tsx","../../src/features/Models/Builder/ChangeProgress/index.tsx","../../src/features/Models/helpers/rebase.ts","../../src/features/Models/Builder/hooks/useReloadDraft.ts","../../src/features/Models/Builder/hooks/useScopeChange.ts","../../src/features/Models/Builder/PanelSection/index.tsx","../../src/features/Models/Builder/DefinitionPanel/Scope/index.tsx","../../src/features/Models/helpers/draft.ts","../../src/features/Models/helpers/issues.ts","../../src/features/Models/Builder/controls/IssueList/index.tsx","../../src/features/Models/helpers/display.ts","../../src/features/Models/helpers/newField.ts","../../src/features/Models/Builder/hooks/useNewField.ts","../../src/features/Models/Builder/FieldList/AddFieldButton/index.tsx","../../src/features/Models/Builder/FieldList/handleId.ts","../../src/features/Models/Builder/FieldList/Row/index.tsx","../../src/features/Models/Builder/FieldList/index.tsx","../../src/features/Models/helpers/defaultValue.ts","../../src/features/Models/Builder/controls/types.ts","../../src/features/Models/Builder/controls/TextControl/index.tsx","../../src/features/Models/Builder/FieldPanel/DataType/index.tsx","../../src/features/Models/Builder/controls/NumberControl/index.tsx","../../src/features/Models/Builder/controls/SelectControl/index.tsx","../../src/features/Models/Builder/FieldPanel/DefaultValue/index.tsx","../../src/features/Models/helpers/schemaControls.ts","../../src/features/Models/Builder/controls/ChoicesControl/index.tsx","../../src/features/Models/Builder/controls/SwitchControl/index.tsx","../../src/features/Models/Builder/PropertyControl/index.tsx","../../src/features/Models/Builder/FieldPanel/EditorPicker/index.tsx","../../src/features/Models/Builder/FieldPanel/Flags/index.tsx","../../src/features/Models/helpers/typeChange.ts","../../src/features/Models/Builder/FieldPanel/hooks/useTypeChoices.ts","../../src/features/Models/Builder/FieldPanel/Placement/index.tsx","../../src/features/Models/Builder/FieldPanel/EnumValues/index.tsx","../../src/features/Models/Builder/FieldPanel/TypeSettings/index.tsx","../../src/features/Models/Builder/FieldPanel/index.tsx","../../src/features/Models/Builder/Header/index.tsx","../../src/features/Models/helpers/seoField.ts","../../src/features/Models/Builder/hooks/useAddSeoField.ts","../../src/features/Models/Builder/hooks/useDraftIssues.ts","../../src/features/Models/Builder/hooks/useIsDraftDirty.ts","../../src/features/Models/Builder/hooks/useRemoteChangeNotice.ts","../../src/features/Models/Builder/hooks/useSaveFlow.ts","../../src/features/Models/Builder/hooks/useSelectedField.ts","../../src/features/Models/Builder/DefinitionPanel/Display/DocumentLayout/index.tsx","../../src/features/Models/Builder/DefinitionPanel/Display/index.tsx","../../src/features/Models/Builder/DefinitionPanel/index.tsx","../../src/features/Models/Builder/ModelSettings/Summary/index.tsx","../../src/features/Models/Builder/ModelSettings/index.tsx","../../src/features/Models/Builder/NoFieldSelected/index.tsx","../../src/features/Models/Builder/RemoteChangeBanner/index.tsx","../../src/features/Models/Builder/ReviewSheet/ChangeList/index.tsx","../../src/features/Models/Builder/ReviewSheet/hooks/useReviewInChangeSet.ts","../../src/features/Models/Builder/ReviewSheet/index.tsx","../../src/features/Models/Builder/Editor/index.tsx","../../src/features/Models/Builder/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"eye-off\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n ]\n};\n__iconData.node;\nconst EyeOff = createLucideIcon(__iconData);\n\nexport { __iconData, EyeOff as default };\n//# sourceMappingURL=eye-off.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"mouse-pointer-click\",\n size: 24,\n node: [\n [\"path\", { d: \"M14 4.1 12 6\", key: \"ita8i4\" }],\n [\"path\", { d: \"m5.1 8-2.9-.8\", key: \"1go3kf\" }],\n [\"path\", { d: \"m6 12-1.9 2\", key: \"mnht97\" }],\n [\"path\", { d: \"M7.2 2.2 8 5.1\", key: \"1cfko1\" }],\n [\n \"path\",\n {\n d: \"M9.037 9.69a.498.498 0 0 1 .653-.653l11 4.5a.5.5 0 0 1-.074.949l-4.349 1.041a1 1 0 0 0-.74.739l-1.04 4.35a.5.5 0 0 1-.95.074z\",\n key: \"s0h3yz\"\n }\n ]\n ]\n};\n__iconData.node;\nconst MousePointerClick = createLucideIcon(__iconData);\n\nexport { __iconData, MousePointerClick as default };\n//# sourceMappingURL=mouse-pointer-click.mjs.map\n","/**\n * @license lucide-react v1.49.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"shapes\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M8.3 10a.7.7 0 0 1-.626-1.079L11.4 3a.7.7 0 0 1 1.198-.043L16.3 8.9a.7.7 0 0 1-.572 1.1Z\",\n key: \"1bo67w\"\n }\n ],\n [\"rect\", { x: \"3\", y: \"14\", width: \"7\", height: \"7\", rx: \"1\", key: \"1bkyp8\" }],\n [\"circle\", { cx: \"17.5\", cy: \"17.5\", r: \"3.5\", key: \"w3z12y\" }]\n ]\n};\n__iconData.node;\nconst Shapes = createLucideIcon(__iconData);\n\nexport { __iconData, Shapes as default };\n//# sourceMappingURL=shapes.mjs.map\n","import type { DefinitionCategory } from '@shapio/client';\nimport type { FieldDefinition, SchemaDefinition } from '@shapio/schema';\nimport { create } from 'zustand';\n\n/** What the builder's settings panel shows: the definition's own settings, or one field. */\nexport type DraftSelection = { type: 'definition' } | { type: 'field'; fieldId: string };\n\ntype DraftState = {\n /** `${category}:${id}` of the definition being edited, or null before one is loaded. */\n key: string | null;\n category: DefinitionCategory;\n /** The active definition the draft is based on, and its version (sent as `expectedVersion`). */\n base: SchemaDefinition | null;\n baseVersion: number;\n draft: SchemaDefinition | null;\n selection: DraftSelection;\n /**\n * Starts editing a definition, discarding any previous draft. Reloading the same definition keeps the\n * selected field open if it still exists.\n */\n load: (category: DefinitionCategory, definition: SchemaDefinition, version: number) => void;\n /** Forgets the draft (the builder closed). */\n reset: () => void;\n /** Moves the base to a newer version with the edits re-applied on top (after a conflict, by choice). */\n rebase: (definition: SchemaDefinition, version: number, draft: SchemaDefinition) => void;\n update: (recipe: (draft: SchemaDefinition) => SchemaDefinition) => void;\n updateField: (fieldId: string, recipe: (field: FieldDefinition) => FieldDefinition) => void;\n select: (selection: DraftSelection) => void;\n};\n\nconst keyOf = (category: DefinitionCategory, id: string) => `${category}:${id}`;\n\n/**\n * The model builder's unsaved definition (client-only state). Edits are immutable updates of a normalized\n * definition, which is also what the plan and apply endpoints accept.\n */\nexport const useDefinitionDraftStore = create<DraftState>()((set) => ({\n key: null,\n category: 'model',\n base: null,\n baseVersion: 0,\n draft: null,\n selection: { type: 'definition' },\n load: (category, definition, version) =>\n set((state) => {\n const key = keyOf(category, definition.id);\n const { selection } = state;\n const keepSelection =\n state.key === key &&\n (selection.type === 'definition' ||\n definition.fields.some((field) => field.id === selection.fieldId));\n return {\n key,\n category,\n base: definition,\n baseVersion: version,\n draft: definition,\n selection: keepSelection ? selection : { type: 'definition' },\n };\n }),\n reset: () => set({ key: null, base: null, baseVersion: 0, draft: null, selection: { type: 'definition' } }),\n rebase: (definition, version, draft) => set({ base: definition, baseVersion: version, draft }),\n update: (recipe) => set((state) => (state.draft ? { draft: recipe(state.draft) } : {})),\n updateField: (fieldId, recipe) =>\n set((state) =>\n state.draft\n ? {\n draft: {\n ...state.draft,\n fields: state.draft.fields.map((field) => (field.id === fieldId ? recipe(field) : field)),\n },\n }\n : {},\n ),\n select: (selection) => set({ selection }),\n}));\n\n/** The store key of a definition: drafts are per category and ID. */\nexport const draftKeyOf = keyOf;\n","import type { DefinitionScope } from '@shapio/client';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\n\n/**\n * A definition shared with all sites is read-only for an admin without `schema.create` on every site (the\n * server refuses the change with 403 either way).\n */\nexport const useSharedReadOnly = (scope: DefinitionScope) => {\n const { canShare } = useSchemaScopeAccess();\n return scope === 'network' && !canShare;\n};\n","import { Globe2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\n\n/** Why a shared definition can't be changed here: one line, above the builder. */\nexport const SharedNotice = () => {\n const { t } = useTranslation();\n return (\n <Alert>\n <Globe2 aria-hidden=\"true\" />\n <AlertDescription>{t('models.scope.readOnly')}</AlertDescription>\n </Alert>\n );\n};\n","import { Undo2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\n\nexport type SaveActionsProps = {\n /** Discard is possible (there are unsaved edits). */\n canDiscard: boolean;\n /** Review is possible: edits, no problems, nothing blocking. */\n canReview: boolean;\n reviewing: boolean;\n onReview: () => void;\n /** Runs once the admin confirms the discard. */\n onDiscard: () => void;\n};\n\n/**\n * Discard changes (confirmed in place), then Review (the primary action: the plan, then Ship now or Review in a change set). In the header on xl, the\n * footer below.\n */\nexport const SaveActions = ({ canDiscard, canReview, reviewing, onReview, onDiscard }: SaveActionsProps) => {\n const { t } = useTranslation();\n return (\n <>\n <InlineConfirm\n tone=\"danger\"\n title={t('models.builder.discardTitle')}\n description={t('models.builder.discardDescription')}\n confirmLabel={t('models.builder.discard')}\n onConfirm={onDiscard}\n trigger={\n <Button type=\"button\" variant=\"ghost\" disabled={!canDiscard}>\n <Undo2 aria-hidden=\"true\" />\n {t('models.builder.discard')}\n </Button>\n }\n />\n <SubmitButton\n pending={reviewing}\n pendingLabel={t('models.builder.planning')}\n disabled={!canReview}\n onClick={onReview}\n >\n {t('models.builder.review')}\n </SubmitButton>\n </>\n );\n};\n","import { SaveActions, type SaveActionsProps } from '../SaveActions';\n\n/** Below xl the save actions stay in reach at the bottom of the screen (above the status bar on md+). */\nexport const ActionFooter = (props: SaveActionsProps) => (\n <div className=\"sticky bottom-0 z-20 -mx-4 flex justify-end gap-2 border-t bg-background/95 px-4 py-3 backdrop-blur supports-[backdrop-filter]:bg-background/80 sm:-mx-8 sm:px-8 md:bottom-(--statusbar-h) xl:hidden\">\n <SaveActions {...props} />\n </div>\n);\n","import { AlertCircle, Loader2 } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useSchemaChange } from '@/api/schema';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { FINAL_CHANGE_STATUSES } from '@/constants/schema';\n\ntype ChangeProgressProps = {\n changeId: string;\n onFinished: (status: string) => void;\n onDismiss: () => void;\n};\n\ntype ChangeFailure = { reason?: unknown; invalidCount?: unknown };\n\nconst failureOf = (error: unknown): ChangeFailure =>\n typeof error === 'object' && error !== null ? error : {};\n\n/**\n * A schema change whose prerequisites run as jobs: progress while they run, then either the success\n * (reported to the builder, which reloads) or why it failed, with the previous version still active.\n */\nexport const ChangeProgress = ({ changeId, onFinished, onDismiss }: ChangeProgressProps) => {\n const { t } = useTranslation();\n const change = useSchemaChange(changeId);\n const status = change.data?.status;\n const reported = useRef(false);\n useEffect(() => {\n if (status && FINAL_CHANGE_STATUSES.has(status) && !reported.current) {\n reported.current = true;\n onFinished(status);\n }\n }, [status, onFinished]);\n if (status === 'activated') {\n return null;\n }\n if (status === 'failed' || status === 'cancelled') {\n const failure = failureOf(change.data?.error);\n return (\n <Alert variant=\"destructive\">\n <AlertCircle aria-hidden=\"true\" />\n <AlertTitle>{t('models.progress.failedTitle')}</AlertTitle>\n <AlertDescription>\n <p>{t('models.progress.failedDescription')}</p>\n {typeof failure.invalidCount === 'number' ? (\n <p>{t('models.progress.invalidCount', { count: failure.invalidCount })}</p>\n ) : null}\n {typeof failure.reason === 'string' ? <p>{failure.reason}</p> : null}\n <Button type=\"button\" size=\"sm\" variant=\"outline\" className=\"mt-2\" onClick={onDismiss}>\n {t('common.close')}\n </Button>\n </AlertDescription>\n </Alert>\n );\n }\n return (\n <Alert variant=\"info\" role=\"status\">\n <Loader2 className=\"animate-spin\" aria-hidden=\"true\" />\n <AlertTitle>{t('models.progress.runningTitle')}</AlertTitle>\n <AlertDescription>{t('models.progress.runningDescription')}</AlertDescription>\n </Alert>\n );\n};\n","import { canonicalJson, type FieldDefinition, type SchemaDefinition } from '@shapio/schema';\n\nconst same = (a: unknown, b: unknown) => canonicalJson(a ?? null) === canonicalJson(b ?? null);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Three-way merge of JSON values: whatever only one side changed wins; objects merge key by key; where\n * both sides changed the same scalar or list, `mine` wins (the plan review shows it).\n */\nexport const merge3 = (base: unknown, mine: unknown, theirs: unknown): unknown => {\n if (same(mine, base)) {\n return theirs;\n }\n if (same(theirs, base)) {\n return mine;\n }\n if (isPlainObject(base) && isPlainObject(mine) && isPlainObject(theirs)) {\n const keys = new Set([...Object.keys(base), ...Object.keys(mine), ...Object.keys(theirs)]);\n const merged: Record<string, unknown> = {};\n for (const key of keys) {\n const value = merge3(base[key], mine[key], theirs[key]);\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n }\n return mine;\n};\n\nconst ids = (fields: readonly FieldDefinition[], kept: ReadonlyMap<string, unknown>) =>\n fields.filter((field) => kept.has(field.id)).map((field) => field.id);\n\n/** Merges field lists by stable ID: additions and removals from both sides, edits merged per property. */\nconst mergeFields = (\n base: readonly FieldDefinition[],\n mine: readonly FieldDefinition[],\n theirs: readonly FieldDefinition[],\n): FieldDefinition[] => {\n const baseById = new Map(base.map((field) => [field.id, field]));\n const mineById = new Map(mine.map((field) => [field.id, field]));\n const theirsById = new Map(theirs.map((field) => [field.id, field]));\n const reorderedByMe = !same(ids(mine, baseById), ids(base, mineById));\n const [primary, secondary] = reorderedByMe ? [mine, theirs] : [theirs, mine];\n const order = [...new Set([...primary, ...secondary].map((field) => field.id))];\n return order.flatMap((id) => {\n const original = baseById.get(id);\n const ours = mineById.get(id);\n const other = theirsById.get(id);\n if (original && !ours) {\n return [];\n }\n if (original && !other) {\n // They removed it: gone, unless this session edited it.\n return ours && !same(ours, original) ? [ours] : [];\n }\n if (!original) {\n return [(ours ?? other) as FieldDefinition];\n }\n return [merge3(original, ours, other) as FieldDefinition];\n });\n};\n\n/**\n * Re-applies this session's edits (`draft` relative to `base`) on top of a newer active version, like\n * rebasing a branch, so keeping one's edits after a conflict never undoes another admin's changes to\n * properties this session did not touch.\n */\nexport const rebaseDraft = (\n base: SchemaDefinition,\n draft: SchemaDefinition,\n latest: SchemaDefinition,\n): SchemaDefinition => {\n const { fields: baseFields, ...baseRest } = base;\n const { fields: draftFields, ...draftRest } = draft;\n const { fields: latestFields, ...latestRest } = latest;\n const merged = merge3(baseRest, draftRest, latestRest) as Omit<SchemaDefinition, 'fields'>;\n return { ...merged, fields: mergeFields(baseFields, draftFields, latestFields) } as SchemaDefinition;\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useCallback } from 'react';\nimport { definitionQueryOptions } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { rebaseDraft } from '../../helpers/rebase';\n\n/**\n * Fetches the active definition again. `replace` starts over from it (the draft's edits are dropped);\n * `rebase` re-applies the draft's edits on top of it (three-way merge) and moves the expected version\n * forward, so the next review is planned against the latest version.\n */\nexport const useReloadDraft = (category: DefinitionCategory, id: string) => {\n const queryClient = useQueryClient();\n const load = useDefinitionDraftStore((state) => state.load);\n const rebase = useDefinitionDraftStore((state) => state.rebase);\n return useCallback(\n async (mode: 'replace' | 'rebase') => {\n const detail = await queryClient.fetchQuery({ ...definitionQueryOptions(category, id), staleTime: 0 });\n const { base, draft } = useDefinitionDraftStore.getState();\n if (mode === 'rebase' && base && draft) {\n rebase(detail.definition, detail.version, rebaseDraft(base, draft, detail.definition));\n } else {\n load(category, detail.definition, detail.version);\n }\n return detail;\n },\n [queryClient, category, id, load, rebase],\n );\n};\n","import type { DefinitionCategory, DefinitionScope } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { hasErrorCode } from '@/api/errors';\nimport { useChangeScope } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { useReloadDraft } from './useReloadDraft';\n\n/**\n * Shares the definition with all sites, or keeps it on this site, against the version the draft is based\n * on. On success the draft (clean: the action is off while it has edits) starts over from the new version,\n * so the builder doesn't report its own change as a remote one. A version conflict goes to `onConflict`\n * (the builder's reload banner) and closes the confirmation; other failures reject for the confirmation to\n * show (`SCOPE_IN_USE` with the server's message and entry count).\n */\nexport const useScopeChange = (category: DefinitionCategory, id: string, onConflict: () => void) => {\n const { t } = useTranslation();\n const changeScope = useChangeScope();\n const reloadDraft = useReloadDraft(category, id);\n return async (scope: DefinitionScope) => {\n const version = useDefinitionDraftStore.getState().baseVersion;\n try {\n await changeScope.mutateAsync({ category, id, input: { scope, version } });\n } catch (error) {\n if (hasErrorCode(error, 'SCHEMA_VERSION_CONFLICT')) {\n onConflict();\n return;\n }\n throw error;\n }\n await reloadDraft('replace');\n toast.success(t(scope === 'network' ? 'models.scope.shared' : 'models.scope.kept'));\n };\n};\n","import type { ReactNode } from 'react';\nimport { FieldGroup } from '@/components/ui/field';\nimport { cn } from '@/helpers/cn';\n\ntype PanelSectionProps = {\n title: string;\n /** An ID for the heading, to name a control group by it. */\n titleId?: string;\n className?: string;\n children: ReactNode;\n};\n\n/** A titled group of controls inside a builder panel, divided from the one before it. */\nexport const PanelSection = ({ title, titleId, className, children }: PanelSectionProps) => (\n <section className={cn('space-y-4 border-t pt-5 first:border-t-0 first:pt-0', className)}>\n <h3 id={titleId} className=\"text-xs font-semibold tracking-wide text-muted-foreground uppercase\">\n {title}\n </h3>\n <FieldGroup className=\"gap-5\">{children}</FieldGroup>\n </section>\n);\n","import type { DefinitionCategory, DefinitionScope } from '@shapio/client';\nimport { useId } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useMe } from '@/api/auth';\nimport { InfoHint } from '@/components/InfoHint';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { SharedGlyph } from '@/components/SharedGlyph';\nimport { Button } from '@/components/ui/button';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { useScopeChange } from '../../hooks/useScopeChange';\nimport { PanelSection } from '../../PanelSection';\n\ntype ScopeProps = {\n category: DefinitionCategory;\n id: string;\n label: string;\n scope: DefinitionScope;\n /** Unsaved edits or a change still running: the scope can't change until they are saved or discarded. */\n blocked: boolean;\n /** The schema lock is on (its notice says why). */\n locked: boolean;\n /** The definition moved since the draft loaded: the builder shows its reload banner. */\n onConflict: () => void;\n};\n\n/**\n * \"Available on\": this site or all sites, and for admins with `schema.create` on every site the action that\n * moves it (confirmed in place). Shown only where there is more than one site.\n */\nexport const Scope = ({ category, id, label, scope, blocked, locked, onConflict }: ScopeProps) => {\n const { t } = useTranslation();\n const site = useMe().data?.site;\n const { canShare } = useSchemaScopeAccess();\n const change = useScopeChange(category, id, onConflict);\n const hintId = useId();\n const shared = scope === 'network';\n const target: DefinitionScope = shared ? 'site' : 'network';\n const siteName = site?.name ?? '';\n return (\n <PanelSection title={t('contentTypes.availableOn')}>\n <p className=\"flex items-center gap-1.5 text-sm\" data-scope={scope}>\n {shared ? <SharedGlyph /> : null}\n {shared ? t('contentTypes.sharedWithAllSites') : t('models.scope.onlyOn', { site: siteName })}\n </p>\n {canShare ? (\n <div className=\"flex items-center gap-1\">\n <InlineConfirm\n tone=\"default\"\n title={\n shared\n ? t('models.scope.keepTitle', { label, site: siteName })\n : t('models.scope.shareTitle', { label })\n }\n description={shared ? t('models.scope.keepDescription') : t('models.scope.shareDescription')}\n confirmLabel={shared ? t('models.scope.keep') : t('models.scope.share')}\n pendingLabel={t('common.saving')}\n onConfirm={() => change(target)}\n trigger={\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n disabled={blocked || locked}\n aria-describedby={blocked ? hintId : undefined}\n >\n {shared ? t('models.scope.keep') : t('models.scope.share')}\n </Button>\n }\n />\n {blocked ? (\n <InfoHint about={shared ? t('models.scope.keep') : t('models.scope.share')} id={hintId}>\n {t('models.scope.blocked')}\n </InfoHint>\n ) : null}\n </div>\n ) : null}\n </PanelSection>\n );\n};\n","import {\n canonicalJson,\n DEFAULT_EDITORS,\n effectiveTitleField,\n isCoverEligible,\n isDocumentPlaceable,\n isCustomEditorId,\n listCompatibleEditors,\n renormalizeDefinition,\n type DataType,\n type FieldDefinition,\n type JsonValue,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { newStableId } from '@/helpers/stableId';\n\n/** Required settings a new field starts with; the user fills them in (inline errors until then). */\nconst INITIAL_SETTINGS: Partial<Record<DataType, Record<string, JsonValue>>> = {\n enum: { values: [] },\n relation: { target: '', cardinality: 'one' },\n component: { component: '' },\n dynamiczone: { components: [] },\n};\n\n/** A new field with Shapio's defaults (public, optional, default editor), normalized like the server does. */\nexport const createField = (\n definition: SchemaDefinition,\n input: {\n type: DataType;\n label: string;\n apiKey: string;\n /** Replaces the type's initial settings (defaults still apply to what's left out). */\n settings?: Record<string, JsonValue>;\n editorId?: string;\n localized?: boolean;\n },\n): FieldDefinition => {\n const raw = {\n id: newStableId(),\n apiKey: input.apiKey,\n label: input.label,\n type: input.type,\n settings: input.settings ?? INITIAL_SETTINGS[input.type] ?? {},\n ...(input.editorId === undefined ? {} : { editor: { id: input.editorId } }),\n ...(input.localized === undefined ? {} : { localized: input.localized }),\n };\n const normalized = renormalizeDefinition({\n ...definition,\n fields: [raw],\n } as unknown as SchemaDefinition);\n return normalized.fields[0] as FieldDefinition;\n};\n\n/** Sets (or, with `undefined`, removes) one key of a record, immutably. */\nexport const withKey = <T extends Record<string, unknown>>(record: T, key: string, value: unknown): T => {\n const next: Record<string, unknown> = { ...record };\n if (value === undefined) {\n delete next[key];\n } else {\n next[key] = value;\n }\n return next as T;\n};\n\nexport const withSetting = (field: FieldDefinition, key: string, value: unknown): FieldDefinition =>\n ({ ...field, settings: withKey(field.settings as Record<string, unknown>, key, value) }) as FieldDefinition;\n\n/** Whether the draft means something different from the active definition (compared normalized). */\nexport const isDraftDirty = (draft: SchemaDefinition, base: SchemaDefinition): boolean =>\n canonicalJson(renormalizeDefinition(draft)) !== canonicalJson(renormalizeDefinition(base));\n\n/** Moves the item at `from` to `to`, immutably. */\nexport const moveItem = <T>(items: readonly T[], from: number, to: number): T[] => {\n if (from === to || from < 0 || to < 0 || from >= items.length || to >= items.length) {\n return [...items];\n }\n const next = [...items];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved as T);\n return next;\n};\n\n/** Removes a field and every reference to it (display settings, slug sources), so the draft stays valid. */\nexport const removeField = (definition: SchemaDefinition, fieldId: string): SchemaDefinition => {\n const fields = definition.fields\n .filter((field) => field.id !== fieldId)\n .map((field) =>\n field.type === 'slug' && field.settings.sourceFieldId === fieldId\n ? withSetting(field, 'sourceFieldId', undefined)\n : field,\n );\n const display: Record<string, unknown> = { ...definition.display };\n if (display.titleFieldId === fieldId) {\n delete display.titleFieldId;\n }\n if ('listFieldIds' in definition.display && definition.display.listFieldIds) {\n display.listFieldIds = definition.display.listFieldIds.filter((id) => id !== fieldId);\n }\n if ('defaultSort' in definition.display && definition.display.defaultSort?.fieldId === fieldId) {\n delete display.defaultSort;\n }\n if (definition.display.groups) {\n display.groups = definition.display.groups.map((group) => ({\n ...group,\n fieldIds: group.fieldIds.filter((id) => id !== fieldId),\n }));\n }\n return pruneLayout({ ...definition, fields, display });\n};\n\n/**\n * Drops document-layout references (`canvasFieldIds`, `coverFieldId`, `stripFieldIds`) that no longer\n * point at an eligible field, after a field is removed, changes type or settings, moves, or becomes the\n * title (the title is the document's heading, never a field in it). Keeps the draft valid without a trip to\n * Display.\n */\nexport const pruneLayout = (definition: SchemaDefinition): SchemaDefinition => {\n if (definition.kind === 'component') {\n return definition;\n }\n const { canvasFieldIds, coverFieldId, stripFieldIds } = definition.display;\n if (canvasFieldIds === undefined && coverFieldId === undefined && stripFieldIds === undefined) {\n return definition;\n }\n const fields = new Map(definition.fields.map((field) => [field.id, field]));\n const eligible = (id: string, test: (field: FieldDefinition) => boolean) => {\n const field = fields.get(id);\n return field !== undefined && test(field);\n };\n const title = effectiveTitleField(definition);\n const canvas = canvasFieldIds?.filter((id) => eligible(id, (field) => isDocumentPlaceable(field, title)));\n const cover =\n coverFieldId !== undefined && eligible(coverFieldId, isCoverEligible) && !canvas?.includes(coverFieldId)\n ? coverFieldId\n : undefined;\n const strip = stripFieldIds?.filter((id) => fields.has(id) && id !== cover && !(canvas ?? []).includes(id));\n let display = withKey(definition.display, 'canvasFieldIds', canvas);\n display = withKey(display, 'coverFieldId', cover);\n display = withKey(display, 'stripFieldIds', strip);\n return { ...definition, display };\n};\n\n/**\n * Keeps the field's editor usable after a settings change (e.g. radio buttons cannot edit a multi-value\n * enum): an incompatible built-in editor is replaced by the first compatible one. Custom editors are kept.\n */\nexport const withCompatibleEditor = (field: FieldDefinition): FieldDefinition => {\n if (isCustomEditorId(field.editor.id)) {\n return field;\n }\n const compatible = listCompatibleEditors(field);\n if (compatible.some((entry) => entry.id === field.editor.id)) {\n return field;\n }\n return { ...field, editor: { id: compatible[0]?.id ?? DEFAULT_EDITORS[field.type], options: {} } };\n};\n","import { parseDefinition, validateSchema, type SchemaDefinition, type ValidationIssue } from '@shapio/schema';\n\n/**\n * Validates a draft with the same validators the server runs (`parseDefinition` per definition, then\n * `validateSchema` over the whole proposed schema), so problems show inline before the plan is requested.\n * Only issues about the draft itself are returned.\n */\nexport const validateDraft = (\n draft: SchemaDefinition,\n base: SchemaDefinition,\n others: readonly SchemaDefinition[],\n): ValidationIssue[] => {\n const parsed = parseDefinition(draft, { previous: base });\n if (!parsed.ok) {\n return parsed.issues;\n }\n // The draft goes last: collisions are reported on the later definition, which should be the draft.\n const schema = [...others.filter((definition) => definition.id !== draft.id), parsed.definition];\n return validateSchema(schema).filter(\n (found) => found.definitionId === undefined || found.definitionId === draft.id,\n );\n};\n\n/** Issues at `path` or below it (`/fields/2` matches `/fields/2/apiKey`). */\nexport const issuesUnder = (issues: readonly ValidationIssue[], path: string): ValidationIssue[] =>\n issues.filter((found) => found.path === path || found.path.startsWith(`${path}/`));\n\n/** The JSON-pointer prefix of the field at `index`. */\nexport const fieldPath = (index: number) => `/fields/${index}`;\n","import type { ValidationIssue } from '@shapio/schema';\nimport { FieldError } from '@/components/ui/field';\nimport { describeIssue } from '../../../helpers/describeIssue';\n\ntype IssueListProps = { id?: string; issues: readonly ValidationIssue[] };\n\n/** A control's validation problems, translated, under the control (announced via aria-describedby). */\nexport const IssueList = ({ id, issues }: IssueListProps) => {\n if (issues.length === 0) {\n return null;\n }\n const messages = [...new Set(issues.map(describeIssue))];\n return <FieldError id={id} errors={messages.map((message) => ({ message }))} />;\n};\n","import {\n effectiveLayout,\n isCanvasEligible,\n isCoverEligible,\n validateDefinition,\n type FieldDefinition,\n type ModelDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { pruneLayout, withKey } from './draft';\n\n/**\n * Fields that may label entries (`display.titleFieldId`). Asks the definition validator rather than\n * duplicating its rule: each field is checked alone, as the only field of a minimal definition.\n */\nexport const titleFieldCandidates = (definition: SchemaDefinition): FieldDefinition[] =>\n definition.fields.filter((field) => {\n const probe = {\n ...definition,\n fields: [field],\n display: { titleFieldId: field.id },\n } as SchemaDefinition;\n return !validateDefinition(probe).some((found) => found.path === '/display/titleFieldId');\n });\n\n/**\n * Appends a new field. The first field that can label entries also becomes the title field while none is\n * set, so entries get a readable title without a trip to the model settings. A title field left unset on\n * purpose next to existing candidates stays unset. A new block field (rich text, a zone, a repeatable list,\n * a gallery) joins the document's configured fields, as it would join the automatic ones.\n */\nexport const withAddedField = (definition: SchemaDefinition, field: FieldDefinition): SchemaDefinition => {\n const next = { ...definition, fields: [...definition.fields, field] };\n const becomesTitle =\n definition.display.titleFieldId === undefined &&\n titleFieldCandidates(definition).length === 0 &&\n titleFieldCandidates(next).some((candidate) => candidate.id === field.id);\n const titled = becomesTitle ? { ...next, display: { ...next.display, titleFieldId: field.id } } : next;\n if (\n titled.kind === 'component' ||\n titled.display.canvasFieldIds === undefined ||\n !isCanvasEligible(field)\n ) {\n return titled;\n }\n return {\n ...titled,\n display: { ...titled.display, canvasFieldIds: [...titled.display.canvasFieldIds, field.id] },\n };\n};\n\n/** Why a field's \"Show in document\" switch can't change: it is the title, the chosen cover, or the last one. */\nexport type PlacementLock = 'title' | 'cover' | 'last';\n\nexport type DocumentPlacement = { inDocument: boolean; lock: PlacementLock | undefined };\n\n/**\n * Whether the entry document shows the field (`effectiveLayout`), and why that can't be switched: the title\n * is the document's heading, the cover chosen in Display sits above it, and the last document field stays\n * because an empty list means the automatic layout.\n */\nexport const documentPlacementOf = (model: ModelDefinition, field: FieldDefinition): DocumentPlacement => {\n const layout = effectiveLayout(model);\n const inDocument = layout.canvas.some((candidate) => candidate.id === field.id);\n const lock: PlacementLock | undefined =\n layout.title?.id === field.id\n ? 'title'\n : model.display.coverFieldId === field.id && layout.cover?.id === field.id\n ? 'cover'\n : inDocument && layout.canvas.length === 1\n ? 'last'\n : undefined;\n return { inDocument, lock };\n};\n\n/**\n * Puts the field in the document or takes it out. The automatic layout becomes an explicit list first; a\n * field put in goes before the first listed field that follows it in field order. Taking a field out keeps\n * the others, and `pruneLayout` keeps the strip and cover consistent.\n */\nexport const withDocumentPlacement = (\n model: ModelDefinition,\n fieldId: string,\n inDocument: boolean,\n): ModelDefinition => {\n const current = effectiveLayout(model).canvas.map((field) => field.id);\n const without = current.filter((id) => id !== fieldId);\n let next = without;\n if (inDocument) {\n const order = new Map(model.fields.map((field, index) => [field.id, index]));\n const position = order.get(fieldId) ?? model.fields.length;\n const before = without.findIndex((id) => (order.get(id) ?? 0) > position);\n next =\n before === -1\n ? [...without, fieldId]\n : [...without.slice(0, before), fieldId, ...without.slice(before)];\n }\n const display = withKey(model.display, 'canvasFieldIds', next.length > 0 ? next : undefined);\n return pruneLayout({ ...model, display }) as ModelDefinition;\n};\n\nexport type DocumentLayoutChoices = {\n /** Single image fields that can be the cover. */\n coverOptions: FieldDefinition[];\n /** Canvas-eligible fields: the current canvas in its order, then the others in field order. */\n canvasOptions: FieldDefinition[];\n /** The canvas as the document shows it (configured, or the default). */\n canvas: string[];\n /** Fields the strip can show (the document's properties). */\n stripOptions: FieldDefinition[];\n};\n\n/** What the Display section offers for the entry document, from the definition being edited. */\nexport const documentLayoutChoices = (model: ModelDefinition): DocumentLayoutChoices => {\n const live = model.fields.filter((field) => !field.deprecated);\n const layout = effectiveLayout(model);\n const canvas = layout.canvas.map((field) => field.id);\n const others = live.filter((field) => isCanvasEligible(field) && !canvas.includes(field.id));\n return {\n coverOptions: live.filter(isCoverEligible),\n canvasOptions: [...layout.canvas, ...others],\n canvas,\n stripOptions: layout.properties,\n };\n};\n","import {\n foldApiKey,\n RESERVED_FIELD_API_KEYS,\n type DataType,\n type FieldDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { deriveApiKey } from './deriveApiKey';\nimport { titleFieldCandidates } from './display';\nimport { createField } from './draft';\n\nconst RESERVED: ReadonlySet<string> = new Set(RESERVED_FIELD_API_KEYS.map(foldApiKey));\n\n/**\n * A label and API ID for a field added with one click: `baseLabel` (\"New field\"), then \"New field 2\",\n * \"New field 3\"... until neither the label nor its API ID (case-folded) is taken or reserved.\n */\nexport const uniqueNewFieldName = (\n definition: SchemaDefinition,\n baseLabel: string,\n): { label: string; apiKey: string } => {\n const labels = new Set(definition.fields.map((field) => field.label));\n const apiKeys = new Set(definition.fields.map((field) => foldApiKey(field.apiKey)));\n for (let number = 1; ; number += 1) {\n const label = number === 1 ? baseLabel : `${baseLabel} ${number}`;\n const apiKey = deriveApiKey(label);\n const folded = foldApiKey(apiKey);\n if (!labels.has(label) && !apiKeys.has(folded) && !RESERVED.has(folded)) {\n return { label, apiKey };\n }\n }\n};\n\n/**\n * Changes a field's data type: its type-specific settings, editor and default value start over with the new\n * type's defaults; its ID, position, names, help text and options are kept. A title field that can no\n * longer label entries is unset, and the title-field rule of `withAddedField` applies again. Other\n * references that no longer fit show as draft issues.\n */\nexport const withFieldType = (\n definition: SchemaDefinition,\n fieldId: string,\n type: DataType,\n): SchemaDefinition => {\n const current = definition.fields.find((field) => field.id === fieldId);\n if (!current || current.type === type) {\n return definition;\n }\n const fresh = createField(definition, { type, label: current.label, apiKey: current.apiKey });\n const { defaultValue: _defaultValue, ...kept } = current as FieldDefinition & { defaultValue?: unknown };\n const next = { ...kept, type, settings: fresh.settings, editor: fresh.editor } as FieldDefinition;\n const fields = definition.fields.map((field) => (field.id === fieldId ? next : field));\n const others = { ...definition, fields: definition.fields.filter((field) => field.id !== fieldId) };\n const display: Record<string, unknown> = { ...definition.display };\n const placed = { ...definition, fields, display };\n const isCandidate = titleFieldCandidates(placed).some((candidate) => candidate.id === fieldId);\n if (display.titleFieldId === fieldId && !isCandidate) {\n delete display.titleFieldId;\n } else if (display.titleFieldId === undefined && isCandidate && titleFieldCandidates(others).length === 0) {\n display.titleFieldId = fieldId;\n }\n return placed;\n};\n\n/**\n * `withFieldType`, except that going back to the saved field's own type restores its saved settings,\n * editor and default value, so trying another type and returning leaves nothing changed.\n */\nexport const withFieldTypeOrSaved = (\n definition: SchemaDefinition,\n fieldId: string,\n type: DataType,\n saved: FieldDefinition | undefined,\n): SchemaDefinition => {\n const next = withFieldType(definition, fieldId, type);\n if (saved?.type !== type) {\n return next;\n }\n const { settings, editor } = saved;\n const defaultValue = (saved as { defaultValue?: unknown }).defaultValue;\n return {\n ...next,\n fields: next.fields.map((field) =>\n field.id === fieldId\n ? ({\n ...field,\n settings,\n editor,\n ...(defaultValue === undefined ? {} : { defaultValue }),\n } as FieldDefinition)\n : field,\n ),\n };\n};\n","import { canonicalJson, type FieldDefinition } from '@shapio/schema';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { withAddedField } from '../../helpers/display';\nimport { createField, removeField } from '../../helpers/draft';\nimport { uniqueNewFieldName } from '../../helpers/newField';\n\n/** The field list's \"Add field\" button (focus goes back there when a new field is discarded). */\nexport const ADD_FIELD_BUTTON_ID = 'add-field-button';\n\n/** The DOM ID of a field's label input in the properties panel (see `FieldPanel`). */\nexport const labelInputIdOf = (fieldId: string) => `field-${fieldId}-label`;\n\nconst afterRender = (run: () => void) => requestAnimationFrame(run);\n\n/**\n * \"Add field\" adds a short-text field named \"New field\" (numbered when taken) to the draft at once, selects\n * it and puts the cursor in its label, text selected, so typing names it. A new field left exactly as it was\n * added can be discarded again (Escape in its panel). Nothing is saved until the plan is reviewed and applied.\n */\nexport const useNewField = () => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const [added, setAdded] = useState<FieldDefinition | null>(null);\n\n const add = () => {\n const { draft } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n const field = createField(draft, {\n type: 'string',\n ...uniqueNewFieldName(draft, t('models.builder.newField')),\n });\n update((current) => withAddedField(current, field));\n select({ type: 'field', fieldId: field.id });\n setAdded(field);\n afterRender(() => {\n const input = document.getElementById(labelInputIdOf(field.id));\n if (input instanceof HTMLInputElement) {\n input.scrollIntoView({ block: 'center' });\n input.focus({ preventScroll: true });\n input.select();\n }\n });\n };\n\n /** Whether `field` is the field just added, still untouched. */\n const isUntouched = (field: FieldDefinition) =>\n added !== null && field.id === added.id && canonicalJson(field) === canonicalJson(added);\n\n const discard = (fieldId: string) => {\n update((current) => removeField(current, fieldId));\n select({ type: 'definition' });\n setAdded(null);\n afterRender(() => document.getElementById(ADD_FIELD_BUTTON_ID)?.focus());\n };\n\n return { add, isUntouched, discard };\n};\n","import { ChevronDown, Plus, Search } from 'lucide-react';\nimport { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport type { useAddSeoField } from '../../hooks/useAddSeoField';\nimport { ADD_FIELD_BUTTON_ID } from '../../hooks/useNewField';\n\ntype AddFieldButtonProps = {\n disabled: boolean;\n onAdd: () => void;\n /** \"SEO fields\" in the menu; absent for components (the SEO group belongs on content types). */\n seo?: ReturnType<typeof useAddSeoField>;\n};\n\nconst SEO_HELP_KEYS = {\n askAdmin: 'seo.builder.askAdmin',\n present: 'seo.builder.present',\n} as const;\n\n/**\n * \"Add field\" as a split button: the main half adds a field at once (as before), the chevron opens a menu\n * with Field and SEO fields. Enabling SEO for the network asks first, anchored to the chevron.\n */\nexport const AddFieldButton = ({ disabled, onAdd, seo }: AddFieldButtonProps) => {\n const { t } = useTranslation();\n const helpId = useId();\n const [confirming, setConfirming] = useState(false);\n const addButton = (\n <Button\n id={ADD_FIELD_BUTTON_ID}\n type=\"button\"\n size=\"sm\"\n onClick={onAdd}\n disabled={disabled}\n className={seo ? 'rounded-r-none' : undefined}\n >\n <Plus aria-hidden=\"true\" />\n {t('models.builder.addField')}\n </Button>\n );\n if (!seo) {\n return addButton;\n }\n const { availability } = seo;\n const help = availability === 'askAdmin' || availability === 'present' ? SEO_HELP_KEYS[availability] : null;\n return (\n <div className=\"flex\">\n {addButton}\n <DropdownMenu>\n <InlineConfirm\n tone=\"default\"\n open={confirming}\n onOpenChange={setConfirming}\n title={t('seo.builder.enableTitle')}\n description={t('seo.builder.enableDescription')}\n confirmLabel={t('seo.builder.enable')}\n pendingLabel={t('seo.builder.enabling')}\n onConfirm={seo.enableAndAdd}\n >\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n size=\"icon-sm\"\n disabled={disabled}\n aria-label={t('seo.builder.menu')}\n className=\"rounded-l-none border-l border-primary-foreground/25\"\n >\n <ChevronDown aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n </InlineConfirm>\n <DropdownMenuContent\n align=\"end\"\n className=\"w-64\"\n onCloseAutoFocus={(event) => confirming && event.preventDefault()}\n >\n <DropdownMenuItem onSelect={onAdd}>\n <Plus aria-hidden=\"true\" />\n {t('seo.builder.field')}\n </DropdownMenuItem>\n <DropdownMenuItem\n disabled={availability !== 'ready' && availability !== 'enable'}\n aria-describedby={help ? helpId : undefined}\n onSelect={() => (availability === 'enable' ? setConfirming(true) : seo.add())}\n >\n <Search aria-hidden=\"true\" />\n {t('seo.builder.seoFields')}\n </DropdownMenuItem>\n {help ? (\n <p id={helpId} className=\"px-2 pb-1.5 pl-8 text-meta text-muted-foreground\">\n {t(help)}\n </p>\n ) : null}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n};\n","/** The DOM ID of a field row's reorder handle (focus returns to it after a keyboard move). */\nexport const handleIdOf = (fieldId: string) => `field-handle-${fieldId}`;\n","import type { FieldDefinition } from '@shapio/schema';\nimport { AlertCircle, ChevronDown, ChevronUp, EyeOff, GripVertical } from 'lucide-react';\nimport type { DragEvent, KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\nimport { DATA_TYPE_ICONS } from '../../../constants';\nimport { handleIdOf } from '../handleId';\n\ntype RowProps = {\n field: FieldDefinition;\n index: number;\n total: number;\n selected: boolean;\n hasIssues: boolean;\n showLocalized: boolean;\n dropTarget: boolean;\n disabled: boolean;\n onSelect: () => void;\n onMove: (to: number) => void;\n onDragStart: (event: DragEvent) => void;\n onDragOver: (event: DragEvent) => void;\n onDrop: (event: DragEvent) => void;\n onDragEnd: () => void;\n};\n\n/**\n * One field in the builder's list (44px): drag, the arrow keys on the handle, or the chevrons shown on\n * hover reorder it; click to edit. The chevrons are for the mouse (the handle already moves with the\n * keyboard), so they are not extra Tab stops.\n */\nexport const Row = ({\n field,\n index,\n total,\n selected,\n hasIssues,\n showLocalized,\n dropTarget,\n disabled,\n onSelect,\n onMove,\n onDragStart,\n onDragOver,\n onDrop,\n onDragEnd,\n}: RowProps) => {\n const { t } = useTranslation();\n const Icon = DATA_TYPE_ICONS[field.type];\n const onHandleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowUp' && index > 0) {\n event.preventDefault();\n onMove(index - 1);\n } else if (event.key === 'ArrowDown' && index < total - 1) {\n event.preventDefault();\n onMove(index + 1);\n }\n };\n return (\n <li\n draggable={!disabled}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDrop={onDrop}\n onDragEnd={onDragEnd}\n data-selected={selected || undefined}\n className={cn(\n 'group/row flex h-11 items-center gap-0.5 rounded-lg border border-transparent pr-1 transition-colors hover:bg-muted/50 data-[selected]:bg-accent',\n dropTarget && 'border-dashed border-primary',\n )}\n >\n <button\n type=\"button\"\n id={handleIdOf(field.id)}\n aria-label={t('models.builder.reorder', { label: field.label })}\n aria-describedby=\"field-reorder-help\"\n onKeyDown={onHandleKeyDown}\n disabled={disabled}\n className=\"flex h-9 w-6 shrink-0 cursor-grab items-center justify-center rounded-md text-muted-foreground outline-none hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed\"\n >\n <GripVertical className=\"size-4\" aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n onClick={onSelect}\n aria-current={selected || undefined}\n className=\"flex h-9 min-w-0 flex-1 items-center gap-2.5 rounded-md px-1.5 text-left outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n >\n <Icon\n className={cn('size-4 shrink-0 text-muted-foreground', selected && 'text-accent-foreground')}\n aria-hidden=\"true\"\n />\n <span className=\"min-w-0 flex-1 leading-tight\">\n <span className=\"block truncate text-sm font-medium\">{field.label}</span>\n <span className=\"block truncate font-mono text-2xs text-muted-foreground\">{field.apiKey}</span>\n </span>\n <span className=\"flex shrink-0 items-center gap-1\">\n {field.required ? <Badge variant=\"outline\">{t('models.builder.requiredBadge')}</Badge> : null}\n {showLocalized && field.localized ? (\n <Badge variant=\"outline\">{t('models.builder.localizedBadge')}</Badge>\n ) : null}\n {field.public ? null : (\n <span title={t('models.builder.hiddenBadge')}>\n <EyeOff className=\"size-4 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"sr-only\">{t('models.builder.hiddenBadge')}</span>\n </span>\n )}\n {hasIssues ? (\n <span title={t('models.builder.hasProblems')}>\n <AlertCircle className=\"size-4 text-destructive\" aria-hidden=\"true\" />\n <span className=\"sr-only\">{t('models.builder.hasProblems')}</span>\n </span>\n ) : null}\n </span>\n </button>\n <span className=\"hidden shrink-0 items-center group-focus-within/row:flex group-hover/row:flex\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n tabIndex={-1}\n disabled={disabled || index === 0}\n aria-label={t('models.builder.moveUp', { label: field.label })}\n onClick={() => onMove(index - 1)}\n >\n <ChevronUp aria-hidden=\"true\" />\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-xs\"\n tabIndex={-1}\n disabled={disabled || index === total - 1}\n aria-label={t('models.builder.moveDown', { label: field.label })}\n onClick={() => onMove(index + 1)}\n >\n <ChevronDown aria-hidden=\"true\" />\n </Button>\n </span>\n </li>\n );\n};\n","import type { FieldDefinition, ValidationIssue } from '@shapio/schema';\nimport { useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { moveItem, pruneLayout } from '../../helpers/draft';\nimport { fieldPath, issuesUnder } from '../../helpers/issues';\nimport { IssueList } from '../controls/IssueList';\nimport type { useAddSeoField } from '../hooks/useAddSeoField';\nimport { AddFieldButton } from './AddFieldButton';\nimport { handleIdOf } from './handleId';\nimport { Row } from './Row';\n\ntype FieldListProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onAdd: () => void;\n /** \"Add field → SEO fields\" (models only). */\n seo?: ReturnType<typeof useAddSeoField>;\n};\n\nconst NO_FIELDS: FieldDefinition[] = [];\n\n/** The draft's fields in order: select one to edit it, reorder by drag, arrow keys or chevrons. */\nexport const FieldList = ({ issues, disabled, onAdd, seo }: FieldListProps) => {\n const { t } = useTranslation();\n const fields = useDefinitionDraftStore((state) => state.draft?.fields ?? NO_FIELDS);\n const localized = useDefinitionDraftStore(\n (state) => state.draft?.kind !== 'component' && state.draft?.localized === true,\n );\n const selection = useDefinitionDraftStore((state) => state.selection);\n const select = useDefinitionDraftStore((state) => state.select);\n const update = useDefinitionDraftStore((state) => state.update);\n const dragFrom = useRef<number | null>(null);\n const [dropIndex, setDropIndex] = useState<number | null>(null);\n const [announcement, setAnnouncement] = useState('');\n\n const move = (from: number, to: number, refocus: boolean) => {\n const moved = fields[from];\n if (!moved || from === to) {\n return;\n }\n // A move can change the automatic title field, which then leaves the document (`pruneLayout`).\n update((draft) => pruneLayout({ ...draft, fields: moveItem(draft.fields, from, to) }));\n setAnnouncement(\n t('models.builder.moved', { label: moved.label, position: to + 1, total: fields.length }),\n );\n if (refocus) {\n // The row's DOM node moves; put focus back on its handle so arrow keys keep working.\n requestAnimationFrame(() => document.getElementById(handleIdOf(moved.id))?.focus());\n }\n };\n const definitionIssues = issuesUnder(issues, '/fields').filter(\n (found) => !/^\\/fields\\/\\d+/.test(found.path),\n );\n\n const count = t('models.builder.fields', { count: fields.length });\n return (\n <Panel\n title={t('models.builder.fieldsTitle')}\n flush\n actions={\n <>\n <Badge variant=\"secondary\" aria-hidden=\"true\">\n {fields.length}\n </Badge>\n <AddFieldButton disabled={disabled} onAdd={onAdd} seo={seo} />\n </>\n }\n bodyClassName=\"p-2\"\n >\n {definitionIssues.length > 0 ? (\n <div className=\"px-3 py-2\">\n <IssueList issues={definitionIssues} />\n </div>\n ) : null}\n {fields.length === 0 ? (\n <p className=\"px-3 py-6 text-center text-meta text-muted-foreground\">\n {t('models.builder.noFields')}\n </p>\n ) : (\n <ol className=\"space-y-0.5\" aria-label={count}>\n {fields.map((field, index) => (\n <Row\n key={field.id}\n field={field}\n index={index}\n total={fields.length}\n selected={selection.type === 'field' && selection.fieldId === field.id}\n hasIssues={issuesUnder(issues, fieldPath(index)).length > 0}\n showLocalized={localized}\n dropTarget={dropIndex === index}\n disabled={disabled}\n onSelect={() => select({ type: 'field', fieldId: field.id })}\n onMove={(to) => move(index, to, true)}\n onDragStart={(event) => {\n dragFrom.current = index;\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', field.id);\n }}\n onDragOver={(event) => {\n if (dragFrom.current !== null) {\n event.preventDefault();\n setDropIndex(index);\n }\n }}\n onDrop={(event) => {\n event.preventDefault();\n if (dragFrom.current !== null) {\n move(dragFrom.current, index, false);\n }\n dragFrom.current = null;\n setDropIndex(null);\n }}\n onDragEnd={() => {\n dragFrom.current = null;\n setDropIndex(null);\n }}\n />\n ))}\n </ol>\n )}\n <p id=\"field-reorder-help\" className=\"sr-only\">\n {t('models.builder.reorderHelp')}\n </p>\n <p aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </p>\n </Panel>\n );\n};\n","import type { FieldDefinition } from '@shapio/schema';\n\n/** Types stored as JSON strings whose default is typed as text (the validator checks the format). */\nconst TEXT_DEFAULT_TYPES: ReadonlySet<string> = new Set([\n 'string',\n 'text',\n 'slug',\n 'email',\n 'url',\n 'uid',\n 'date',\n 'datetime',\n 'time',\n 'decimal',\n 'biginteger',\n]);\n\n/** Whether the builder offers a default value for this field (single scalar values only). */\nexport const supportsDefaultValue = (field: FieldDefinition) =>\n TEXT_DEFAULT_TYPES.has(field.type) ||\n field.type === 'number' ||\n field.type === 'integer' ||\n field.type === 'boolean' ||\n (field.type === 'enum' && !field.settings.multiple);\n","import type { ValidationIssue } from '@shapio/schema';\nimport { describedBy } from '@/helpers/describedBy';\n\n/** What every builder control takes besides its value: a label, an optional hint and its issues. */\nexport type ControlBaseProps = {\n id: string;\n label: string;\n /** An explanation behind an info icon beside the label (DESIGN.md, helper-text rule). */\n hint?: string;\n /** One visible line under the control, only when it changes what the person does (a warning). */\n description?: string;\n issues?: readonly ValidationIssue[];\n disabled?: boolean;\n};\n\n/** The IDs of a control's hint, description and error elements, and the `aria-describedby` joining them. */\nexport const controlIds = (\n id: string,\n { hint, description, issues = [] }: Pick<ControlBaseProps, 'hint' | 'description' | 'issues'>,\n) => {\n const hintId = hint ? `${id}-hint` : undefined;\n const descriptionId = description ? `${id}-description` : undefined;\n const errorId = issues.length > 0 ? `${id}-error` : undefined;\n return { hintId, descriptionId, errorId, describedBy: describedBy(hintId, descriptionId, errorId) };\n};\n","import { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport { cn } from '@/helpers/cn';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype TextControlProps = ControlBaseProps & {\n value: string | undefined;\n /** Receives `undefined` when the input is emptied and `emptyAsUndefined` is set. */\n onChange: (value: string | undefined) => void;\n emptyAsUndefined?: boolean;\n multiline?: boolean;\n monospace?: boolean;\n maxLength?: number;\n};\n\nexport const TextControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n onChange,\n emptyAsUndefined = false,\n multiline = false,\n monospace = false,\n maxLength,\n}: TextControlProps) => {\n const ids = controlIds(id, { hint, description, issues });\n const shared = {\n id,\n value: value ?? '',\n disabled,\n maxLength,\n 'aria-invalid': issues.length > 0 || undefined,\n 'aria-describedby': ids.describedBy,\n onChange: (event: { target: { value: string } }) =>\n onChange(emptyAsUndefined && event.target.value === '' ? undefined : event.target.value),\n };\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n {multiline ? (\n <Textarea {...shared} rows={2} />\n ) : (\n <Input\n {...shared}\n autoComplete=\"off\"\n spellCheck={!monospace}\n className={cn(monospace && 'font-mono')}\n />\n )}\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import { DATA_TYPES, type DataType as DataTypeName } from '@shapio/schema';\nimport { useId } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { RadioTile } from '@/components/RadioTile';\nimport { RadioGroup } from '@/components/ui/radio-group';\nimport { DATA_TYPE_GROUPS, DATA_TYPE_ICONS } from '../../../constants';\n\ntype DataTypeProps = {\n /** The section heading that names the radio group. */\n labelledBy: string;\n value: DataTypeName;\n /** Types shown but not selectable (a saved field can only take the types Shapio can convert it to). */\n unavailable: ReadonlySet<DataTypeName>;\n unavailableReason: (type: DataTypeName) => string;\n /** What saving the chosen type does, one short sentence each. */\n notes: readonly string[];\n /** Why some types aren't offered. */\n limitedNote?: string;\n disabled: boolean;\n onChange: (type: DataTypeName) => void;\n};\n\nconst TYPES = DATA_TYPE_GROUPS.flatMap((group) => group.types);\n\nconst isDataType = (value: string): value is DataTypeName =>\n (DATA_TYPES as readonly string[]).includes(value);\n\n/**\n * Every data type as an icon tile, in group order (text, numbers, choices, dates, structure), six to a row\n * where the panel is wide enough, then the selected type in one line and what changing a saved field's\n * type does. A radio group: Tab enters at the selected type, arrow keys choose another.\n */\nexport const DataType = ({\n labelledBy,\n value,\n unavailable,\n unavailableReason,\n notes,\n limitedNote,\n disabled,\n onChange,\n}: DataTypeProps) => {\n const { t } = useTranslation();\n const descriptionId = useId();\n return (\n <div className=\"@container space-y-3\">\n <RadioGroup\n value={value}\n disabled={disabled}\n onValueChange={(next) => isDataType(next) && onChange(next)}\n aria-labelledby={labelledBy}\n aria-describedby={descriptionId}\n className=\"grid-cols-4 gap-2 @xl:grid-cols-6\"\n >\n {TYPES.map((type) => (\n <RadioTile\n key={type}\n value={type}\n variant=\"tile\"\n icon={DATA_TYPE_ICONS[type]}\n label={t(`models.dataTypes.${type}.name`)}\n disabled={unavailable.has(type)}\n description={\n unavailable.has(type) ? unavailableReason(type) : t(`models.dataTypes.${type}.description`)\n }\n />\n ))}\n </RadioGroup>\n <p id={descriptionId} className=\"text-meta text-muted-foreground\">\n <span className=\"font-semibold text-foreground\">{t(`models.dataTypes.${value}.name`)}</span>\n {' · '}\n {t(`models.dataTypes.${value}.description`)}\n </p>\n {notes.length > 0 ? (\n <p role=\"status\" className=\"text-meta font-medium text-warning\">\n {notes.join(' ')}\n </p>\n ) : null}\n {limitedNote ? <p className=\"text-meta text-muted-foreground\">{limitedNote}</p> : null}\n </div>\n );\n};\n","import { useState } from 'react';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype NumberControlProps = ControlBaseProps & {\n value: number | undefined;\n onChange: (value: number | undefined) => void;\n integer?: boolean;\n min?: number;\n max?: number;\n};\n\nconst parse = (text: string, integer: boolean): number | undefined => {\n if (text.trim() === '') {\n return undefined;\n }\n const parsed = Number(text);\n if (!Number.isFinite(parsed)) {\n return undefined;\n }\n return integer ? Math.trunc(parsed) : parsed;\n};\n\n/** A number input whose empty state means \"not set\" (`undefined`). */\nexport const NumberControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n onChange,\n integer = false,\n min,\n max,\n}: NumberControlProps) => {\n // Keep the typed text (e.g. \"1.\" or \"-\") while it is not yet a number.\n const [text, setText] = useState(value === undefined ? '' : String(value));\n const [shownValue, setShownValue] = useState(value);\n // The value changed from outside (reload, discard): show it, unless the text already means it.\n if (value !== shownValue) {\n setShownValue(value);\n if (parse(text, integer) !== value) {\n setText(value === undefined ? '' : String(value));\n }\n }\n const ids = controlIds(id, { hint, description, issues });\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n <Input\n id={id}\n type=\"number\"\n inputMode={integer ? 'numeric' : 'decimal'}\n step={integer ? 1 : 'any'}\n min={min}\n max={max}\n value={text}\n disabled={disabled}\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n onChange={(event) => {\n const next = parse(event.target.value, integer);\n setText(event.target.value);\n setShownValue(next);\n onChange(next);\n }}\n />\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldDescription } from '@/components/ui/field';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\n/** Radix Select can't hold an empty value; this stands for \"not set\". */\nconst UNSET = '__unset__';\n\ntype SelectControlProps = ControlBaseProps & {\n value: string | undefined;\n options: readonly { value: string; label: string }[];\n onChange: (value: string | undefined) => void;\n /** Label of the \"not set\" choice; when absent, a value must be chosen. */\n unsetLabel?: string;\n placeholder?: string;\n};\n\nexport const SelectControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n options,\n onChange,\n unsetLabel,\n placeholder,\n}: SelectControlProps) => {\n const { t } = useTranslation();\n const ids = controlIds(id, { hint, description, issues });\n const known = value !== undefined && options.some((option) => option.value === value);\n return (\n <Field data-invalid={issues.length > 0 || undefined}>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n <Select\n value={known ? value : unsetLabel ? UNSET : ''}\n onValueChange={(next) => onChange(next === UNSET ? undefined : next)}\n disabled={disabled}\n >\n <SelectTrigger\n id={id}\n className=\"w-full\"\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n >\n <SelectValue placeholder={placeholder ?? t('models.choose')} />\n </SelectTrigger>\n <SelectContent>\n {unsetLabel ? <SelectItem value={UNSET}>{unsetLabel}</SelectItem> : null}\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </Field>\n );\n};\n","import type { FieldDefinition, JsonValue, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { NumberControl } from '../../controls/NumberControl';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { TextControl } from '../../controls/TextControl';\n\ntype DefaultValueProps = {\n field: FieldDefinition;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (value: JsonValue | undefined) => void;\n};\n\n/** The value new entries start with, also used to fill existing entries when the field becomes required. */\nexport const DefaultValue = ({ field, issues, disabled, onChange }: DefaultValueProps) => {\n const { t } = useTranslation();\n const common = {\n id: `field-${field.id}-default`,\n label: t('models.builder.defaultValue'),\n hint: t('models.builder.defaultValueHint'),\n issues,\n disabled,\n };\n const value = field.defaultValue;\n if (field.type === 'number' || field.type === 'integer') {\n return (\n <NumberControl\n {...common}\n integer={field.type === 'integer'}\n value={typeof value === 'number' ? value : undefined}\n onChange={onChange}\n />\n );\n }\n if (field.type === 'boolean') {\n return (\n <SelectControl\n {...common}\n value={typeof value === 'boolean' ? String(value) : undefined}\n options={[\n { value: 'true', label: t('models.builder.booleanTrue') },\n { value: 'false', label: t('models.builder.booleanFalse') },\n ]}\n unsetLabel={t('models.notSet')}\n onChange={(next) => onChange(next === undefined ? undefined : next === 'true')}\n />\n );\n }\n if (field.type === 'enum') {\n return (\n <SelectControl\n {...common}\n value={typeof value === 'string' ? value : undefined}\n options={field.settings.values\n .filter((entry) => entry.value !== '')\n .map((entry) => ({ value: entry.value, label: entry.label || entry.value }))}\n unsetLabel={t('models.notSet')}\n onChange={onChange}\n />\n );\n }\n return (\n <TextControl\n {...common}\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n emptyAsUndefined\n />\n );\n};\n","/**\n * Turns the JSON Schema of a settings or editor-options object (TypeBox, from @shapio/schema) into form\n * controls, so the builder renders exactly the properties the server validates and never redefines them.\n */\ntype JsonSchema = {\n type?: string;\n enum?: readonly unknown[];\n items?: JsonSchema;\n properties?: Record<string, JsonSchema>;\n required?: readonly string[];\n minimum?: number;\n maximum?: number;\n exclusiveMinimum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n minItems?: number;\n};\n\nexport type PropertyControl =\n | { kind: 'boolean' }\n | { kind: 'integer'; minimum?: number; maximum?: number }\n | { kind: 'number'; minimum?: number }\n | { kind: 'text'; maxLength?: number }\n | { kind: 'choice'; options: string[] }\n | { kind: 'choices'; options: string[] }\n | { kind: 'textList' }\n | { kind: 'other' };\n\nexport type DescribedProperty = { key: string; control: PropertyControl; required: boolean };\n\nconst enumOptions = (schema: JsonSchema | undefined): string[] | undefined =>\n schema?.enum?.every((value) => typeof value === 'string') ? (schema.enum as string[]) : undefined;\n\nexport const describeControl = (schema: JsonSchema): PropertyControl => {\n const options = enumOptions(schema);\n if (options) {\n return { kind: 'choice', options };\n }\n switch (schema.type) {\n case 'boolean':\n return { kind: 'boolean' };\n case 'integer':\n return {\n kind: 'integer',\n ...(schema.minimum !== undefined ? { minimum: schema.minimum } : {}),\n ...(schema.maximum !== undefined ? { maximum: schema.maximum } : {}),\n };\n case 'number':\n return { kind: 'number', ...(schema.minimum !== undefined ? { minimum: schema.minimum } : {}) };\n case 'string':\n return { kind: 'text', ...(schema.maxLength !== undefined ? { maxLength: schema.maxLength } : {}) };\n case 'array': {\n const itemOptions = enumOptions(schema.items);\n if (itemOptions) {\n return { kind: 'choices', options: itemOptions };\n }\n return schema.items?.type === 'string' ? { kind: 'textList' } : { kind: 'other' };\n }\n default:\n return { kind: 'other' };\n }\n};\n\n/** The properties of an object schema, in declaration order. */\nexport const describeProperties = (schema: unknown): DescribedProperty[] => {\n const object = schema as JsonSchema;\n const required = new Set(object.required ?? []);\n return Object.entries(object.properties ?? {}).map(([key, property]) => ({\n key,\n control: describeControl(property),\n required: required.has(key),\n }));\n};\n","import { InfoHint } from '@/components/InfoHint';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Field, FieldDescription, FieldLabel, FieldLegend, FieldSet } from '@/components/ui/field';\nimport { IssueList } from '../IssueList';\nimport type { ControlBaseProps } from '../types';\n\ntype ChoicesControlProps = ControlBaseProps & {\n value: readonly string[];\n options: readonly { value: string; label: string }[];\n onChange: (value: string[]) => void;\n /** Options that can't be toggled (e.g. the last one of a list that may not be empty). */\n locked?: readonly string[];\n};\n\n/** A set of checkboxes; the value keeps the options' order. */\nexport const ChoicesControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n value,\n options,\n onChange,\n locked = [],\n}: ChoicesControlProps) => {\n const toggle = (option: string, checked: boolean) => {\n const next = new Set(value);\n if (checked) {\n next.add(option);\n } else {\n next.delete(option);\n }\n onChange(options.map((entry) => entry.value).filter((entry) => next.has(entry)));\n };\n return (\n <FieldSet data-invalid={issues.length > 0 || undefined} className=\"gap-3\">\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {label}\n {hint ? <InfoHint about={label}>{hint}</InfoHint> : null}\n </FieldLegend>\n {description ? <FieldDescription>{description}</FieldDescription> : null}\n <div data-slot=\"checkbox-group\" className=\"grid gap-3 @sm/field-group:grid-cols-2\">\n {options.map((option) => {\n const optionId = `${id}-${option.value}`;\n return (\n <Field key={option.value} orientation=\"horizontal\">\n <Checkbox\n id={optionId}\n checked={value.includes(option.value)}\n onCheckedChange={(checked) => toggle(option.value, checked === true)}\n disabled={disabled || locked.includes(option.value)}\n />\n <FieldLabel htmlFor={optionId} className=\"font-normal\">\n {option.label}\n </FieldLabel>\n </Field>\n );\n })}\n </div>\n <IssueList issues={issues} />\n </FieldSet>\n );\n};\n","import { HintedLabel } from '@/components/HintedLabel';\nimport { Field, FieldContent, FieldDescription } from '@/components/ui/field';\nimport { Switch } from '@/components/ui/switch';\nimport { cn } from '@/helpers/cn';\nimport { IssueList } from '../IssueList';\nimport { controlIds, type ControlBaseProps } from '../types';\n\ntype SwitchControlProps = ControlBaseProps & {\n checked: boolean;\n onChange: (checked: boolean) => void;\n /**\n * `row`: label on the left, switch on the right (settings lists). `compact`: switch first, then the\n * label, for the two-column grid of field options.\n */\n layout?: 'row' | 'compact';\n};\n\nexport const SwitchControl = ({\n id,\n label,\n hint,\n description,\n issues = [],\n disabled,\n checked,\n onChange,\n layout = 'row',\n}: SwitchControlProps) => {\n const ids = controlIds(id, { hint, description, issues });\n const control = (\n <Switch\n id={id}\n checked={checked}\n onCheckedChange={onChange}\n disabled={disabled}\n aria-invalid={issues.length > 0 || undefined}\n aria-describedby={ids.describedBy}\n className={cn(layout === 'compact' && 'mt-0.5 self-start')}\n />\n );\n return (\n <Field orientation=\"horizontal\" data-invalid={issues.length > 0 || undefined}>\n {layout === 'compact' ? control : null}\n <FieldContent>\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={ids.hintId} />\n {description ? <FieldDescription id={ids.descriptionId}>{description}</FieldDescription> : null}\n <IssueList id={ids.errorId} issues={issues} />\n </FieldContent>\n {layout === 'row' ? control : null}\n </Field>\n );\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { propertyLabel, valueLabel } from '../../helpers/labels';\nimport type { DescribedProperty } from '../../helpers/schemaControls';\nimport { ChoicesControl } from '../controls/ChoicesControl';\nimport { NumberControl } from '../controls/NumberControl';\nimport { SelectControl } from '../controls/SelectControl';\nimport { SwitchControl } from '../controls/SwitchControl';\nimport { TextControl } from '../controls/TextControl';\n\ntype PropertyControlProps = {\n idPrefix: string;\n property: DescribedProperty;\n value: unknown;\n onChange: (value: unknown) => void;\n issues: readonly ValidationIssue[];\n /** One visible line under the control: the text format to type. */\n description?: string;\n /** An explanation behind an info icon. */\n hint?: string;\n disabled?: boolean;\n};\n\nconst LIST_SEPARATOR = /\\s*,\\s*/;\n\n/**\n * One property of a settings or editor-options schema, rendered from its JSON Schema description. Labels\n * and choice names come from `models.properties.*` and `models.values.*`.\n */\nexport const PropertyControl = ({\n idPrefix,\n property: { key, control, required },\n value,\n onChange,\n issues,\n description,\n hint,\n disabled,\n}: PropertyControlProps) => {\n const { t } = useTranslation();\n const id = `${idPrefix}-${key}`;\n const label = propertyLabel(key);\n const base = { id, label, issues, disabled, description, hint };\n switch (control.kind) {\n case 'boolean':\n return (\n <SwitchControl\n {...base}\n checked={value === true}\n onChange={(checked) => onChange(checked || undefined)}\n />\n );\n case 'integer':\n case 'number':\n return (\n <NumberControl\n {...base}\n integer={control.kind === 'integer'}\n min={control.minimum}\n max={control.kind === 'integer' ? control.maximum : undefined}\n value={typeof value === 'number' ? value : undefined}\n onChange={onChange}\n />\n );\n case 'choice':\n return (\n <SelectControl\n {...base}\n value={typeof value === 'string' ? value : undefined}\n options={control.options.map((option) => ({ value: option, label: valueLabel(option) }))}\n onChange={onChange}\n {...(required ? {} : { unsetLabel: t('models.notSet') })}\n />\n );\n case 'choices':\n return (\n <ChoicesControl\n {...base}\n value={Array.isArray(value) ? (value as string[]) : []}\n options={control.options.map((option) => ({ value: option, label: valueLabel(option) }))}\n onChange={(next) => onChange(next.length > 0 ? next : undefined)}\n />\n );\n case 'textList':\n return (\n <TextControl\n {...base}\n description={description ?? t('models.commaSeparated')}\n value={Array.isArray(value) ? (value as string[]).join(', ') : ''}\n onChange={(text) => {\n const items = (text ?? '').split(LIST_SEPARATOR).filter(Boolean);\n onChange(items.length > 0 ? items : undefined);\n }}\n />\n );\n case 'text':\n return (\n <TextControl\n {...base}\n maxLength={control.maxLength}\n value={typeof value === 'string' ? value : undefined}\n onChange={onChange}\n emptyAsUndefined={!required}\n />\n );\n default:\n return null;\n }\n};\n","import {\n EDITOR_CATALOGUE,\n isCustomEditorId,\n listCompatibleEditors,\n type FieldDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { withKey } from '../../../helpers/draft';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { editorLabel } from '../../../helpers/labels';\nimport { describeProperties } from '../../../helpers/schemaControls';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { PropertyControl } from '../../PropertyControl';\n\ntype EditorPickerProps = {\n field: FieldDefinition;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (editor: FieldDefinition['editor']) => void;\n};\n\n/**\n * The editor (input control) for a field, from the catalogue's editors compatible with its data type, and\n * that editor's options, rendered from its option schema. Changing it never changes stored data.\n */\nexport const EditorPicker = ({ field, path, issues, disabled, onChange }: EditorPickerProps) => {\n const { t } = useTranslation();\n const { id, options } = field.editor;\n const compatible = listCompatibleEditors(field).map((entry) => entry.id);\n const choices = isCustomEditorId(id) || !compatible.includes(id) ? [...compatible, id] : compatible;\n const entry = EDITOR_CATALOGUE.get(id);\n const properties = entry ? describeProperties(entry.optionsSchema) : [];\n return (\n <>\n <SelectControl\n id={`field-${field.id}-editor`}\n label={t('models.builder.editor')}\n hint={t('models.builder.editorHint')}\n value={id}\n options={choices.map((choice) => ({ value: choice, label: editorLabel(choice) }))}\n onChange={(next) => next && onChange({ id: next, options: {} })}\n issues={issuesUnder(issues, `${path}/editor/id`)}\n disabled={disabled}\n />\n {properties.map((property) => (\n <PropertyControl\n key={`${id}-${property.key}`}\n idPrefix={`field-${field.id}-editor-options`}\n property={property}\n value={options[property.key]}\n onChange={(value) => onChange({ id, options: withKey(options, property.key, value) })}\n issues={issuesUnder(issues, `${path}/editor/options/${property.key}`)}\n disabled={disabled}\n />\n ))}\n </>\n );\n};\n","import {\n SCALAR_DATA_TYPES,\n UNIQUE_CAPABLE_DATA_TYPES,\n type FieldDefinition,\n type SchemaDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { SwitchControl } from '../../controls/SwitchControl';\n\ntype FlagKey = 'required' | 'unique' | 'localized' | 'public' | 'filterable' | 'sortable' | 'deprecated';\n\ntype FlagsProps = {\n field: FieldDefinition;\n draft: SchemaDefinition;\n /** The issues on one of the field's properties. */\n at: (property: string) => readonly ValidationIssue[];\n disabled: boolean;\n onChange: (patch: Partial<Pick<FieldDefinition, FlagKey>>) => void;\n};\n\nconst FLAG_KEYS = {\n required: { label: 'models.builder.required', hint: 'models.builder.requiredHint' },\n unique: { label: 'models.builder.unique', hint: 'models.builder.uniqueHint' },\n localized: { label: 'models.builder.fieldLocalized', hint: 'models.builder.fieldLocalizedHint' },\n public: { label: 'models.builder.public', hint: 'models.builder.publicHint' },\n filterable: { label: 'models.builder.filterable', hint: 'models.builder.indexHint' },\n sortable: { label: 'models.builder.sortable', hint: 'models.builder.indexHint' },\n deprecated: { label: 'models.builder.deprecated', hint: 'models.builder.deprecatedHint' },\n} as const satisfies Record<FlagKey, { label: string; hint: string }>;\n\n/** The on/off options a field of this type supports here (components have no indexes or uniqueness). */\nconst availableFlags = (field: FieldDefinition, draft: SchemaDefinition): FlagKey[] => {\n const isComponent = draft.kind === 'component';\n const modelLocalized = draft.kind !== 'component' && draft.localized;\n const indexable =\n !isComponent && SCALAR_DATA_TYPES.has(field.type) && !(field.type === 'enum' && field.settings.multiple);\n return [\n 'required',\n ...(UNIQUE_CAPABLE_DATA_TYPES.has(field.type) && !isComponent ? (['unique'] as const) : []),\n ...(modelLocalized ? (['localized'] as const) : []),\n 'public',\n ...(indexable ? (['filterable', 'sortable'] as const) : []),\n 'deprecated',\n ];\n};\n\n/** A field's switches, two columns wide: each with its label and an info hint. */\nexport const Flags = ({ field, draft, at, disabled, onChange }: FlagsProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"grid gap-x-6 gap-y-4 @md/field-group:grid-cols-2\">\n {availableFlags(field, draft).map((flag) => (\n <SwitchControl\n key={flag}\n id={`field-${field.id}-${flag}`}\n layout=\"compact\"\n label={t(FLAG_KEYS[flag].label)}\n hint={t(FLAG_KEYS[flag].hint)}\n checked={field[flag]}\n onChange={(checked) => onChange({ [flag]: checked })}\n issues={at(flag)}\n disabled={disabled}\n />\n ))}\n </div>\n );\n};\n","import {\n classifyChange,\n type ClassifiedChange,\n type DataType,\n type FieldDefinition,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport { withFieldType } from './newField';\n\n/**\n * How the planner would classify changing a saved field to `to` (null for its own type), asked of the\n * same classifier the server uses, on the definition as the change would leave it, so the type grid and\n * the review agree on what is supported, breaking or destructive.\n */\nexport const classifyFieldTypeChange = (\n saved: SchemaDefinition,\n field: FieldDefinition,\n to: DataType,\n): ClassifiedChange | null =>\n field.type === to\n ? null\n : classifyChange(\n { kind: 'field.type', definitionId: saved.id, fieldId: field.id, from: field.type, to },\n { before: saved, after: withFieldType(saved, field.id, to) },\n );\n","import { DATA_TYPES, type DataType, type FieldDefinition, type SchemaDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { classifyFieldTypeChange } from '../../../helpers/typeChange';\n\nconst NO_TYPES: ReadonlySet<DataType> = new Set();\n\n/**\n * The data types a field may take and what changing it means. A new field may take any type. A saved field\n * may take the types the planner can convert it to (its own included), the others are `unavailable`;\n * `notes` says what saving the chosen type does to existing values and the API.\n */\nexport const useTypeChoices = (\n base: SchemaDefinition | null,\n saved: FieldDefinition | undefined,\n type: DataType,\n) => {\n const { t } = useTranslation();\n const unavailable = useMemo(\n () =>\n base && saved\n ? new Set(DATA_TYPES.filter((to) => classifyFieldTypeChange(base, saved, to)?.supported === false))\n : NO_TYPES,\n [base, saved],\n );\n const change = useMemo(\n () => (base && saved ? classifyFieldTypeChange(base, saved, type) : null),\n [base, saved, type],\n );\n const notes: string[] = [];\n if (change?.category === 'conversion') {\n notes.push(t('models.builder.typeConverted'));\n } else if (change?.category === 'validation') {\n notes.push(t('models.builder.typeChecked'));\n }\n if (change?.breaking) {\n notes.push(t('models.builder.typeBreaking'));\n }\n if (change?.destructive) {\n notes.push(t('models.builder.typeDestructive'));\n }\n const from = saved ? t(`models.dataTypes.${saved.type}.name`) : '';\n const limitedNote = unavailable.size > 0 ? t('models.builder.typeLimited', { type: from }) : undefined;\n /** Why a type is unavailable, announced with its tile. */\n const unavailableReason = (to: DataType) =>\n t('models.builder.typeUnsupported', { from, to: t(`models.dataTypes.${to}.name`) });\n return { unavailable, unavailableReason, notes, limitedNote };\n};\n","import type { FieldDefinition, ModelDefinition, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { documentPlacementOf, withDocumentPlacement, type PlacementLock } from '../../../helpers/display';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { SwitchControl } from '../../controls/SwitchControl';\n\ntype PlacementProps = {\n model: ModelDefinition;\n field: FieldDefinition;\n /** All of the draft's issues; the switch shows the ones on this field's `canvasFieldIds` entry. */\n issues: readonly ValidationIssue[];\n disabled: boolean;\n};\n\nconst LOCK_KEYS = {\n title: 'models.builder.placement.lockedTitle',\n cover: 'models.builder.placement.lockedCover',\n last: 'models.builder.placement.lockedLast',\n} as const satisfies Record<PlacementLock, string>;\n\n/**\n * \"Show in document\": a view over `display.canvasFieldIds` for one field. On, the entry document shows the\n * field under its heading among the blocks; off, it is a property in the strip and the Settings panel.\n */\nexport const Placement = ({ model, field, issues, disabled }: PlacementProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const { inDocument, lock } = documentPlacementOf(model, field);\n const index = model.display.canvasFieldIds?.indexOf(field.id) ?? -1;\n return (\n <SwitchControl\n id={`field-${field.id}-in-document`}\n label={t('models.builder.placement.label')}\n hint={t('models.builder.placement.hint')}\n description={lock ? t(LOCK_KEYS[lock]) : undefined}\n issues={index === -1 ? [] : issuesUnder(issues, `/display/canvasFieldIds/${index}`)}\n checked={inDocument}\n disabled={disabled || lock !== undefined}\n onChange={(checked) =>\n update((current) =>\n current.kind === 'component' ? current : withDocumentPlacement(current, field.id, checked),\n )\n }\n />\n );\n};\n","import type { FieldDefinition, ValidationIssue } from '@shapio/schema';\nimport { Plus, Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Button } from '@/components/ui/button';\nimport { FieldLegend, FieldSet } from '@/components/ui/field';\nimport { Input } from '@/components/ui/input';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { IssueList } from '../../controls/IssueList';\n\ntype EnumValue = { value: string; label: string };\n\ntype EnumValuesProps = {\n idPrefix: string;\n field: FieldDefinition<'enum'>;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (values: EnumValue[]) => void;\n};\n\n/** The choices of an enum field: a stable value (a GraphQL name) and a label editors see. */\nexport const EnumValues = ({ idPrefix, field, path, issues, disabled, onChange }: EnumValuesProps) => {\n const { t } = useTranslation();\n const values = field.settings.values;\n const replace = (index: number, patch: Partial<EnumValue>) =>\n onChange(values.map((entry, position) => (position === index ? { ...entry, ...patch } : entry)));\n const listIssues = issues.filter((found) => found.path === path);\n return (\n <FieldSet className=\"gap-3\" data-invalid={listIssues.length > 0 || undefined}>\n <FieldLegend variant=\"label\" className=\"mb-0 flex items-center gap-1\">\n {t('models.properties.values')}\n <InfoHint about={t('models.properties.values')}>{t('models.builder.enumValuesHint')}</InfoHint>\n </FieldLegend>\n {values.length > 0 ? (\n <ol className=\"space-y-2\">\n {values.map((entry, index) => {\n const rowIssues = issuesUnder(issues, `${path}/${index}`);\n const valueId = `${idPrefix}-value-${index}`;\n const labelId = `${idPrefix}-label-${index}`;\n return (\n <li key={index} className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <label htmlFor={labelId} className=\"sr-only\">\n {t('models.builder.enumLabel', { position: index + 1 })}\n </label>\n <Input\n id={labelId}\n value={entry.label}\n placeholder={t('models.builder.enumLabelPlaceholder')}\n disabled={disabled}\n onChange={(event) => replace(index, { label: event.target.value })}\n />\n <label htmlFor={valueId} className=\"sr-only\">\n {t('models.builder.enumValue', { position: index + 1 })}\n </label>\n <Input\n id={valueId}\n value={entry.value}\n placeholder={t('models.builder.enumValuePlaceholder')}\n className=\"font-mono\"\n spellCheck={false}\n disabled={disabled}\n aria-invalid={rowIssues.length > 0 || undefined}\n onChange={(event) => replace(index, { value: event.target.value })}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n disabled={disabled}\n aria-label={t('models.builder.enumRemove', { position: index + 1 })}\n onClick={() => onChange(values.filter((_, position) => position !== index))}\n >\n <Trash2 aria-hidden=\"true\" />\n </Button>\n </div>\n <IssueList issues={rowIssues} />\n </li>\n );\n })}\n </ol>\n ) : null}\n <IssueList issues={listIssues} />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"w-fit\"\n disabled={disabled}\n onClick={() => onChange([...values, { value: '', label: '' }])}\n >\n <Plus aria-hidden=\"true\" />\n {t('models.builder.enumAdd')}\n </Button>\n </FieldSet>\n );\n};\n","import {\n SETTINGS_SCHEMAS,\n type FieldDefinition,\n type SchemaDefinition,\n type ValidationIssue,\n} from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useAllDefinitions } from '@/api/schema';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { describeProperties, type DescribedProperty } from '../../../helpers/schemaControls';\nimport { ChoicesControl } from '../../controls/ChoicesControl';\nimport { IssueList } from '../../controls/IssueList';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { PropertyControl } from '../../PropertyControl';\nimport { EnumValues } from '../EnumValues';\n\ntype TypeSettingsProps = {\n field: FieldDefinition;\n draft: SchemaDefinition;\n path: string;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n onChange: (key: string, value: unknown) => void;\n};\n\n/** Settings managed elsewhere or not user-facing. */\nconst HIDDEN_SETTINGS: ReadonlySet<string> = new Set(['formatVersion']);\n\n/** Types whose bounds are text in a canonical format (ADR 0001); the hint shows the format. */\nconst FORMAT_HINT_KEYS = {\n date: 'models.formats.date',\n datetime: 'models.formats.datetime',\n time: 'models.formats.time',\n decimal: 'models.formats.decimal',\n biginteger: 'models.formats.biginteger',\n} as const;\n\nconst SOURCE_FIELD_TYPES: ReadonlySet<string> = new Set(['string', 'text']);\n\n/**\n * The data type's settings, rendered from `SETTINGS_SCHEMAS[type]` (the schema the server validates), with\n * pickers for the settings that reference other definitions or fields.\n */\nexport const TypeSettings = ({ field, draft, path, issues, disabled, onChange }: TypeSettingsProps) => {\n const { t } = useTranslation();\n const { definitions } = useAllDefinitions();\n const settings = field.settings as Record<string, unknown>;\n const settingsPath = `${path}/settings`;\n const idPrefix = `field-${field.id}-settings`;\n const all = [\n ...(definitions ?? []).map(({ definition }) => definition).filter((entry) => entry.id !== draft.id),\n draft,\n ];\n const models = all.filter((entry) => entry.kind !== 'component');\n const components = all.filter((entry) => entry.kind === 'component' && entry.id !== draft.id);\n const toOption = (entry: SchemaDefinition) => ({ value: entry.id, label: entry.label });\n const at = (key: string) => issuesUnder(issues, `${settingsPath}/${key}`);\n\n const render = (property: DescribedProperty) => {\n const { key } = property;\n const common = { id: `${idPrefix}-${key}`, issues: at(key), disabled };\n if (field.type === 'enum' && key === 'values') {\n return (\n <EnumValues\n key={key}\n idPrefix={common.id}\n field={field}\n path={`${settingsPath}/values`}\n issues={issues}\n disabled={disabled}\n onChange={(values) => onChange('values', values)}\n />\n );\n }\n if (key === 'target') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.target')}\n value={settings.target as string}\n options={models.map(toOption)}\n onChange={(value) => onChange('target', value ?? '')}\n placeholder={t('models.builder.chooseModel')}\n />\n );\n }\n if (key === 'component') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.component')}\n value={settings.component as string}\n options={components.map(toOption)}\n onChange={(value) => onChange('component', value ?? '')}\n placeholder={t('models.builder.chooseComponent')}\n {...(components.length === 0 ? { description: t('models.builder.noComponents') } : {})}\n />\n );\n }\n if (key === 'components') {\n return (\n <ChoicesControl\n key={key}\n {...common}\n label={t('models.properties.components')}\n value={(settings.components as string[] | undefined) ?? []}\n options={components.map(toOption)}\n onChange={(value) => onChange('components', value)}\n {...(components.length === 0 ? { description: t('models.builder.noComponents') } : {})}\n />\n );\n }\n if (key === 'sourceFieldId') {\n return (\n <SelectControl\n key={key}\n {...common}\n label={t('models.properties.sourceFieldId')}\n hint={t('models.builder.sourceFieldHint')}\n value={settings.sourceFieldId as string | undefined}\n options={draft.fields\n .filter((candidate) => candidate.id !== field.id && SOURCE_FIELD_TYPES.has(candidate.type))\n .map((candidate) => ({ value: candidate.id, label: candidate.label }))}\n onChange={(value) => onChange('sourceFieldId', value)}\n unsetLabel={t('models.notSet')}\n />\n );\n }\n const formatKey =\n property.control.kind === 'text' && field.type in FORMAT_HINT_KEYS\n ? FORMAT_HINT_KEYS[field.type as keyof typeof FORMAT_HINT_KEYS]\n : undefined;\n return (\n <PropertyControl\n key={key}\n idPrefix={idPrefix}\n property={property}\n value={settings[key]}\n onChange={(value) => onChange(key, value)}\n issues={common.issues}\n disabled={disabled}\n description={formatKey === undefined ? undefined : t(formatKey)}\n hint={key === 'pattern' ? t('models.builder.patternHint') : undefined}\n />\n );\n };\n\n const properties = describeProperties(SETTINGS_SCHEMAS[field.type]).filter(\n (property) => !HIDDEN_SETTINGS.has(property.key),\n );\n const rendered = new Set(properties.map((property) => property.key));\n const otherIssues = issuesUnder(issues, settingsPath).filter(\n (found) => !rendered.has(found.path.slice(settingsPath.length + 1).split('/')[0] ?? ''),\n );\n if (properties.length === 0) {\n return <p className=\"text-meta text-muted-foreground\">{t('models.builder.noSettings')}</p>;\n }\n return (\n <>\n {properties.map(render)}\n <IssueList issues={otherIssues} />\n </>\n );\n};\n","import { type FieldDefinition, type ValidationIssue } from '@shapio/schema';\nimport { Trash2 } from 'lucide-react';\nimport type { KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { IconTile } from '@/components/IconTile';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { DATA_TYPE_ICONS } from '../../constants';\nimport { supportsDefaultValue } from '../../helpers/defaultValue';\nimport { deriveApiKey } from '../../helpers/deriveApiKey';\nimport { pruneLayout, removeField, withCompatibleEditor, withSetting } from '../../helpers/draft';\nimport { fieldPath, issuesUnder } from '../../helpers/issues';\nimport { withFieldTypeOrSaved } from '../../helpers/newField';\nimport { IssueList } from '../controls/IssueList';\nimport { TextControl } from '../controls/TextControl';\nimport { labelInputIdOf } from '../hooks/useNewField';\nimport { PanelSection } from '../PanelSection';\nimport { DataType } from './DataType';\nimport { DefaultValue } from './DefaultValue';\nimport { EditorPicker } from './EditorPicker';\nimport { Flags } from './Flags';\nimport { useTypeChoices } from './hooks/useTypeChoices';\nimport { Placement } from './Placement';\nimport { TypeSettings } from './TypeSettings';\n\ntype FieldPanelProps = {\n field: FieldDefinition;\n index: number;\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** The field was just added and is still untouched: Escape discards it. */\n untouched: boolean;\n onDiscard: () => void;\n};\n\n/** Field properties that have their own control; issues anywhere else are listed at the top. */\nconst CONTROLLED = new Set([\n 'label',\n 'apiKey',\n 'description',\n 'required',\n 'unique',\n 'filterable',\n 'sortable',\n 'public',\n 'localized',\n 'deprecated',\n 'defaultValue',\n 'editor',\n 'settings',\n]);\n\n/**\n * Everything about one field: data type, naming, options, type settings and editor. A field that isn't\n * saved yet can take any type and its API ID follows its label until edited; a saved one can change to the\n * types Shapio can convert it to.\n */\nexport const FieldPanel = ({ field, index, issues, disabled, untouched, onDiscard }: FieldPanelProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const updateField = useDefinitionDraftStore((state) => state.updateField);\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const saved = base?.fields.find((candidate) => candidate.id === field.id);\n const typeChoices = useTypeChoices(base, saved, field.type);\n if (!draft) {\n return null;\n }\n const path = fieldPath(index);\n const at = (property: string) => issuesUnder(issues, `${path}/${property}`);\n const otherIssues = issuesUnder(issues, path).filter(\n (found) => !CONTROLLED.has(found.path.slice(path.length + 1).split('/')[0] ?? ''),\n );\n const set = (patch: Partial<FieldDefinition>) =>\n updateField(field.id, (current) => ({ ...current, ...patch }) as FieldDefinition);\n const id = (name: string) => `field-${field.id}-${name}`;\n const renamed = saved !== undefined && saved.apiKey !== field.apiKey;\n const isNew = base !== null && saved === undefined;\n const label = field.label || t('models.builder.untitled');\n const setLabel = (next: string) => {\n const followsLabel = isNew && field.apiKey === deriveApiKey(field.label);\n set({ label: next, ...(followsLabel ? { apiKey: deriveApiKey(next) } : {}) });\n };\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n // Escape in something the panel opened (a select, an info popover) is that layer's to handle.\n if (event.key !== 'Escape' || event.nativeEvent.defaultPrevented || !untouched) {\n return;\n }\n if (event.target instanceof Node && event.currentTarget.contains(event.target)) {\n event.preventDefault();\n onDiscard();\n }\n };\n\n return (\n // Keyboard handling only: Escape discards an untouched new field (focus is on a control inside).\n <div onKeyDown={onKeyDown}>\n <Panel aria-label={t('models.builder.fieldProperties', { label })} flush>\n <div className=\"flex flex-wrap items-center gap-3 border-b px-5 py-4\">\n <IconTile icon={DATA_TYPE_ICONS[field.type]} />\n <div className=\"flex min-w-0 flex-1 flex-wrap items-center gap-x-2.5 gap-y-1\">\n <h2 className=\"min-w-0 truncate text-base font-semibold\">{label}</h2>\n <Badge variant=\"secondary\">{t(`models.dataTypes.${field.type}.name`)}</Badge>\n </div>\n <Button\n type=\"button\"\n variant=\"destructive-ghost\"\n size=\"sm\"\n disabled={disabled}\n onClick={() => {\n update((current) => removeField(current, field.id));\n select({ type: 'definition' });\n }}\n >\n <Trash2 aria-hidden=\"true\" />\n {t('models.builder.removeField')}\n </Button>\n </div>\n <div className=\"space-y-5 p-5\">\n <IssueList issues={otherIssues} />\n\n <PanelSection title={t('models.builder.dataType')} titleId={id('type-heading')}>\n <DataType\n labelledBy={id('type-heading')}\n value={field.type}\n {...typeChoices}\n disabled={disabled}\n onChange={(type) =>\n update((current) => pruneLayout(withFieldTypeOrSaved(current, field.id, type, saved)))\n }\n />\n </PanelSection>\n\n <PanelSection title={t('models.builder.general')}>\n <div className=\"grid items-start gap-5 @lg/field-group:grid-cols-2\">\n <TextControl\n id={labelInputIdOf(field.id)}\n label={t('models.label')}\n value={field.label}\n onChange={(next) => setLabel(next ?? '')}\n issues={at('label')}\n disabled={disabled}\n />\n <TextControl\n id={id('apiKey')}\n label={t('models.apiKey')}\n hint={t('models.fieldApiKeyHint')}\n description={renamed ? t('models.builder.apiKeyRenameWarning') : undefined}\n value={field.apiKey}\n onChange={(apiKey) => set({ apiKey: apiKey ?? '' })}\n issues={at('apiKey')}\n disabled={disabled}\n monospace\n />\n </div>\n <TextControl\n id={id('description')}\n label={t('models.builder.helpText')}\n value={field.description}\n onChange={(description) => set({ description })}\n issues={at('description')}\n disabled={disabled}\n emptyAsUndefined\n multiline\n />\n {draft.kind !== 'component' && !field.deprecated ? (\n <Placement model={draft} field={field} issues={issues} disabled={disabled} />\n ) : null}\n </PanelSection>\n\n <PanelSection title={t('models.builder.options')}>\n <Flags field={field} draft={draft} at={at} disabled={disabled} onChange={set} />\n </PanelSection>\n\n <PanelSection title={t('models.builder.settings')}>\n <TypeSettings\n field={field}\n draft={draft}\n path={path}\n issues={issues}\n disabled={disabled}\n onChange={(key, value) =>\n update((current) =>\n pruneLayout({\n ...current,\n fields: current.fields.map((candidate) =>\n candidate.id === field.id\n ? withCompatibleEditor(withSetting(candidate, key, value))\n : candidate,\n ),\n }),\n )\n }\n />\n {supportsDefaultValue(field) ? (\n <DefaultValue\n field={field}\n issues={at('defaultValue')}\n disabled={disabled}\n onChange={(defaultValue) =>\n updateField(field.id, (current) => {\n const next: Record<string, unknown> = { ...current, defaultValue };\n if (defaultValue === undefined) {\n delete next.defaultValue;\n }\n return next as FieldDefinition;\n })\n }\n />\n ) : null}\n </PanelSection>\n\n <PanelSection title={t('models.builder.editorSection')}>\n <EditorPicker\n field={field}\n path={path}\n issues={issues}\n disabled={disabled}\n onChange={(editor) => set({ editor })}\n />\n </PanelSection>\n </div>\n </Panel>\n </div>\n );\n};\n","import { routeKeyOf, type SchemaDefinition } from '@shapio/schema';\nimport { linkOptions, useParams } from '@tanstack/react-router';\nimport { MoreHorizontal, Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { PageHeader } from '@/components/PageHeader';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { SaveActions, type SaveActionsProps } from '../SaveActions';\n\ntype HeaderProps = SaveActionsProps & {\n draft: SchemaDefinition;\n version: number;\n dirty: boolean;\n issueCount: number;\n /** Deleting is not possible right now (locked, a change running). */\n deleteBlocked: boolean;\n onDelete: () => void;\n};\n\n/** Breadcrumb, title with the draft's state, API IDs and version, and the save actions (xl and up). */\nexport const Header = ({\n draft,\n version,\n dirty,\n issueCount,\n deleteBlocked,\n onDelete,\n ...saveActions\n}: HeaderProps) => {\n const { t } = useTranslation();\n // The place this builder is the Structure tab of (its saved API ID, from the URL), or Components.\n const { modelKey = draft.apiKey } = useParams({ strict: false });\n const breadcrumb =\n draft.kind === 'component'\n ? [{ label: t('shell.nav.components'), link: linkOptions({ to: '/develop/components' }) }]\n : [\n { label: draft.label, link: linkOptions({ to: '/content/$modelKey', params: { modelKey } }) },\n { label: t('place.tabs.structure') },\n ];\n return (\n <PageHeader\n sticky\n breadcrumb={breadcrumb}\n title={draft.label || t('models.builder.untitled')}\n badge={\n dirty || issueCount > 0 ? (\n <span className=\"flex flex-wrap items-center gap-2\">\n {dirty ? <StatusChip tone=\"warning\" label={t('models.builder.unsaved')} /> : null}\n {issueCount > 0 ? (\n <StatusChip tone=\"danger\" label={t('models.builder.problems', { count: issueCount })} />\n ) : null}\n </span>\n ) : null\n }\n meta={\n draft.kind === 'collection'\n ? t('models.builder.subtitleCollection', {\n apiKey: draft.apiKey,\n pluralApiKey: routeKeyOf(draft),\n version,\n })\n : t('models.builder.subtitle', { apiKey: draft.apiKey, version })\n }\n actions={\n <>\n <div className=\"hidden items-center gap-2 xl:flex\">\n <SaveActions {...saveActions} />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" aria-label={t('models.builder.more')}>\n <MoreHorizontal aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem variant=\"destructive\" disabled={deleteBlocked} onSelect={onDelete}>\n <Trash2 aria-hidden=\"true\" />\n {t('models.builder.delete')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </>\n }\n />\n );\n};\n","import { SEO_COMPONENT_ID, SEO_EDITOR_ID, type SchemaDefinition } from '@shapio/schema';\nimport { createField } from './draft';\nimport { uniqueNewFieldName } from './newField';\n\n/**\n * The SEO field's label as stored in the schema (data, like the component's own label): its API ID derives\n * from it (`seo`, then `seo2`...), and must not change with the admin's language.\n */\nconst SEO_FIELD_LABEL = 'SEO';\n\n/** Whether the definition already has a field holding the SEO component (by stable ID, never API ID). */\nexport const hasSeoField = (definition: SchemaDefinition): boolean =>\n definition.fields.some(\n (field) => field.type === 'component' && field.settings.component === SEO_COMPONENT_ID,\n );\n\n/**\n * A single (non-repeatable) field holding the shared SEO component, with the SEO editor, localized when the\n * model is (the person can still change that in the field's properties).\n */\nexport const createSeoField = (definition: SchemaDefinition) =>\n createField(definition, {\n type: 'component',\n ...uniqueNewFieldName(definition, SEO_FIELD_LABEL),\n settings: { component: SEO_COMPONENT_ID, repeatable: false },\n editorId: SEO_EDITOR_ID,\n localized: definition.kind !== 'component' && definition.localized,\n });\n","import { SEO_COMPONENT_ID } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useDefinitions } from '@/api/schema';\nimport { seoConflictOf, useEnsureSeoComponent } from '@/api/seo';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { withAddedField } from '../../helpers/display';\nimport { createSeoField, hasSeoField } from '../../helpers/seoField';\nimport { labelInputIdOf } from './useNewField';\n\n/**\n * What \"SEO fields\" can do for this draft:\n * - `ready`: the shared SEO component exists, the field is added at once;\n * - `enable`: it doesn't, and this admin may create it for every site (asks first);\n * - `askAdmin`: it doesn't, and only a network admin can create it;\n * - `present`: the draft already holds the SEO component;\n * - `loading`: the site's components aren't known yet.\n */\nexport type SeoFieldAvailability = 'ready' | 'enable' | 'askAdmin' | 'present' | 'loading';\n\n/**\n * \"Add field → SEO fields\" (plan seo-fields): adds a field holding the shared SEO component to the draft,\n * creating the component first when this admin may (network `schema.create`). The field then goes through\n * the normal review like any other; nothing else is saved here except the component itself.\n */\nexport const useAddSeoField = () => {\n const { t } = useTranslation();\n const components = useDefinitions('component');\n const { canShare } = useSchemaScopeAccess();\n const present = useDefinitionDraftStore((state) => (state.draft ? hasSeoField(state.draft) : false));\n const update = useDefinitionDraftStore((state) => state.update);\n const select = useDefinitionDraftStore((state) => state.select);\n const ensure = useEnsureSeoComponent();\n\n const exists = components.data?.some((item) => item.definition.id === SEO_COMPONENT_ID);\n const availability: SeoFieldAvailability = present\n ? 'present'\n : exists === undefined\n ? 'loading'\n : exists\n ? 'ready'\n : canShare\n ? 'enable'\n : 'askAdmin';\n\n const add = () => {\n const { draft } = useDefinitionDraftStore.getState();\n if (!draft || hasSeoField(draft)) {\n return;\n }\n const field = createSeoField(draft);\n update((current) => withAddedField(current, field));\n select({ type: 'field', fieldId: field.id });\n requestAnimationFrame(() => {\n document.getElementById(labelInputIdOf(field.id))?.scrollIntoView({ block: 'center' });\n });\n toast.success(t('seo.builder.added'));\n };\n\n /** Creates the shared component, then adds the field. Failures are toasted (the conflict names the culprit). */\n const enableAndAdd = async () => {\n try {\n await ensure.mutateAsync();\n } catch (error) {\n logError(error, 'enabling the SEO component');\n const conflict = seoConflictOf(error);\n toast.error(\n conflict\n ? t('seo.builder.conflict', { label: conflict.label, apiKey: conflict.apiKey })\n : describeError(error),\n );\n return;\n }\n add();\n };\n\n return { availability, add, enableAndAdd, enabling: ensure.isPending };\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { useDeferredValue, useMemo } from 'react';\nimport { useAllDefinitions } from '@/api/schema';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { validateDraft } from '../../helpers/issues';\n\nconst NO_ISSUES: readonly ValidationIssue[] = [];\n\n/** The draft's validation problems (the server's own validators, run in the browser while typing). */\nexport const useDraftIssues = () => {\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const { definitions } = useAllDefinitions();\n // Validation runs over the whole schema; let typing stay responsive while it catches up.\n const deferredDraft = useDeferredValue(draft);\n const issues = useMemo(\n () =>\n deferredDraft && base\n ? validateDraft(\n deferredDraft,\n base,\n (definitions ?? []).map(({ definition }) => definition),\n )\n : NO_ISSUES,\n [deferredDraft, base, definitions],\n );\n return { issues };\n};\n","import { useMemo } from 'react';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { isDraftDirty } from '../../helpers/draft';\n\n/** Whether the draft differs from the active definition it is based on. */\nexport const useIsDraftDirty = () => {\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n return useMemo(() => Boolean(draft && base && isDraftDirty(draft, base)), [draft, base]);\n};\n","import { useSchemaSummary } from '@/api/schema';\n\n/**\n * Whether another session activated a newer version of this definition than the one the draft is based\n * on. The summary is polled (there is no push channel), so this shows within a few seconds. Changes this\n * session is applying itself are ignored while they run.\n */\nexport const useRemoteChangeNotice = (id: string, baseVersion: number, ownChangeRunning: boolean) => {\n const summary = useSchemaSummary();\n const remote = summary.data?.definitions.find((definition) => definition.id === id);\n const changedElsewhere = !ownChangeRunning && remote !== undefined && remote.version > baseVersion;\n return { changedElsewhere, remoteVersion: remote?.version };\n};\n","import type { Acknowledgement, DefinitionCategory, PlanPreview } from '@shapio/client';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useShipDraftNow } from '@/api/changeSets';\nimport { hasErrorCode } from '@/api/errors';\nimport { definitionQueryOptions, usePlanChange } from '@/api/schema';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport type { useReloadDraft } from './useReloadDraft';\n\ntype ReloadDraft = ReturnType<typeof useReloadDraft>;\n\nexport type SaveFlowState =\n { step: 'idle' } | { step: 'review'; preview: PlanPreview } | { step: 'conflict' };\n\nconst isVersionConflict = (error: unknown) => hasErrorCode(error, 'SCHEMA_VERSION_CONFLICT');\n\n/**\n * Saving a model (brief §5, plan developer-face §5): plan the draft against the version it was based on,\n * show the impact, then ship it as a one-item change set with the acknowledgements the plan needs (or put\n * it in a change set from the review sheet). A stale version at either step shows the conflict banner;\n * changes with prerequisites ship in the background and show as the definition's pending change.\n */\nexport const useSaveFlow = (category: DefinitionCategory, id: string, reloadDraft: ReloadDraft) => {\n const { t } = useTranslation();\n const plan = usePlanChange();\n const queryClient = useQueryClient();\n const apply = useShipDraftNow();\n const [state, setState] = useState<SaveFlowState>({ step: 'idle' });\n /** A change this session started that is still running its prerequisites. */\n const [runningChangeId, setRunningChangeId] = useState<string | undefined>(undefined);\n\n const notifyFailure = (error: unknown) => {\n if (isVersionConflict(error)) {\n setState({ step: 'conflict' });\n return;\n }\n toast.error(describeError(error));\n };\n\n const finishSuccessfully = async () => {\n toast.success(t('models.updated'));\n try {\n // Rebase rather than replace: edits made while a change was running are kept on the new version.\n await reloadDraft('rebase');\n } catch (error) {\n logError(error, 'reloading the definition after a schema change');\n toast.error(describeError(error));\n }\n };\n\n const review = async () => {\n const { draft, baseVersion } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n apply.reset();\n try {\n const preview = await plan.mutateAsync({\n category,\n id,\n definition: draft,\n expectedVersion: baseVersion,\n });\n setState({ step: 'review', preview });\n } catch (error) {\n notifyFailure(error);\n }\n };\n\n const confirm = async (acknowledgement: Acknowledgement) => {\n const { draft, baseVersion } = useDefinitionDraftStore.getState();\n if (!draft) {\n return;\n }\n try {\n const set = await apply.mutateAsync({\n definitionId: id,\n input: { category, definition: draft, baseVersion },\n acknowledgement,\n title: t('changes.builderSetTitle', { label: draft.label }),\n });\n setState({ step: 'idle' });\n if (set.status === 'shipping') {\n // Prerequisites run first; the definition's pending change tracks them (ChangeProgress).\n const detail = await queryClient.fetchQuery(definitionQueryOptions(category, id));\n setRunningChangeId(detail.pendingChange?.id);\n toast.info(t('models.builder.changeStarted'));\n } else {\n await finishSuccessfully();\n }\n } catch (error) {\n // Anything but a stale version stays in the review sheet, which shows the error.\n if (isVersionConflict(error)) {\n setState({ step: 'conflict' });\n }\n }\n };\n\n /** The running change ended: reload on success; keep showing a failure until it is dismissed. */\n const onChangeFinished = async (status: string) => {\n if (status === 'activated') {\n setRunningChangeId(undefined);\n await finishSuccessfully();\n }\n };\n\n return {\n state,\n review,\n reviewing: plan.isPending,\n confirm,\n applying: apply.isPending,\n applyError: apply.error,\n /** Leave the review or the conflict without doing anything. */\n resetStep: () => setState({ step: 'idle' }),\n runningChangeId,\n dismissChange: () => setRunningChangeId(undefined),\n onChangeFinished,\n };\n};\n","import { useDefinitionDraftStore } from '@/stores/definitionDraft';\n\n/** The field open in the settings panel and its position, or nothing when the definition is selected. */\nexport const useSelectedField = () => {\n const selection = useDefinitionDraftStore((state) => state.selection);\n const fields = useDefinitionDraftStore((state) => state.draft?.fields);\n if (selection.type !== 'field' || !fields) {\n return { field: undefined, index: -1 };\n }\n const index = fields.findIndex((candidate) => candidate.id === selection.fieldId);\n return { field: fields[index], index };\n};\n","import type { ModelDefinition, ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { documentLayoutChoices } from '../../../../helpers/display';\nimport { pruneLayout, withKey } from '../../../../helpers/draft';\nimport { issuesUnder } from '../../../../helpers/issues';\nimport { ChoicesControl } from '../../../controls/ChoicesControl';\nimport { SelectControl } from '../../../controls/SelectControl';\n\ntype DocumentLayoutProps = { model: ModelDefinition; issues: readonly ValidationIssue[]; disabled: boolean };\n\nconst option = (field: { id: string; label: string }) => ({ value: field.id, label: field.label });\n\n/**\n * How an entry opens as a document (`effectiveLayout`): the cover image, the fields written in the canvas,\n * and the properties shown as chips. Unset keys follow the defaults, so new fields join automatically.\n */\nexport const DocumentLayout = ({ model, issues, disabled }: DocumentLayoutProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const setDisplay = (key: string, value: unknown) =>\n update((draft) => pruneLayout({ ...draft, display: withKey(draft.display, key, value) }));\n const at = (key: string) => issuesUnder(issues, `/display/${key}`);\n const choices = documentLayoutChoices(model);\n return (\n <>\n {choices.coverOptions.length > 0 ? (\n <SelectControl\n id=\"definition-cover-field\"\n label={t('models.builder.coverField')}\n hint={t('models.builder.coverFieldHint')}\n value={model.display.coverFieldId}\n options={choices.coverOptions.map(option)}\n onChange={(value) => setDisplay('coverFieldId', value)}\n unsetLabel={t('models.builder.automatic')}\n issues={at('coverFieldId')}\n disabled={disabled}\n />\n ) : null}\n {choices.canvasOptions.length > 0 ? (\n <ChoicesControl\n id=\"definition-canvas-fields\"\n label={t('models.builder.canvasFields')}\n hint={t('models.builder.canvasFieldsHint')}\n value={choices.canvas}\n options={choices.canvasOptions.map(option)}\n // An empty list means \"the defaults\", so the last block can't be unticked.\n locked={choices.canvas.length === 1 ? choices.canvas : []}\n onChange={(ids) => setDisplay('canvasFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('canvasFieldIds')}\n disabled={disabled}\n />\n ) : null}\n {choices.stripOptions.length > 0 ? (\n <ChoicesControl\n id=\"definition-strip-fields\"\n label={t('models.builder.stripFields')}\n hint={t('models.builder.stripFieldsHint')}\n value={model.display.stripFieldIds ?? []}\n options={choices.stripOptions.map(option)}\n onChange={(ids) => setDisplay('stripFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('stripFieldIds')}\n disabled={disabled}\n />\n ) : null}\n </>\n );\n};\n","import { SORT_DIRECTIONS, type SchemaDefinition, type ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { titleFieldCandidates } from '../../../helpers/display';\nimport { pruneLayout, withKey } from '../../../helpers/draft';\nimport { issuesUnder } from '../../../helpers/issues';\nimport { ChoicesControl } from '../../controls/ChoicesControl';\nimport { SelectControl } from '../../controls/SelectControl';\nimport { DocumentLayout } from './DocumentLayout';\n\ntype DisplayProps = { definition: SchemaDefinition; issues: readonly ValidationIssue[]; disabled: boolean };\n\nconst DIRECTION_LABEL_KEYS = {\n asc: 'models.builder.sortAscending',\n desc: 'models.builder.sortDescending',\n} as const;\n\n/** How entries are labelled, listed and laid out: title, order, list columns and the entry document. */\nexport const Display = ({ definition, issues, disabled }: DisplayProps) => {\n const { t } = useTranslation();\n const update = useDefinitionDraftStore((state) => state.update);\n const setDisplay = (key: string, value: unknown) =>\n update((draft) => pruneLayout({ ...draft, display: withKey(draft.display, key, value) }));\n const at = (key: string) => issuesUnder(issues, `/display/${key}`);\n const option = (field: { id: string; label: string }) => ({ value: field.id, label: field.label });\n const { display } = definition;\n const titleField = (\n <SelectControl\n id=\"definition-title-field\"\n label={t('models.builder.titleField')}\n hint={t('models.builder.titleFieldHint')}\n value={display.titleFieldId}\n options={titleFieldCandidates(definition).map(option)}\n onChange={(value) => setDisplay('titleFieldId', value)}\n unsetLabel={t('models.notSet')}\n issues={at('titleFieldId')}\n disabled={disabled}\n />\n );\n if (definition.kind === 'component') {\n return titleField;\n }\n const sort = definition.display.defaultSort;\n const sortable = definition.fields.filter((field) => field.sortable);\n return (\n <>\n {titleField}\n <SelectControl\n id=\"definition-sort-field\"\n label={t('models.builder.sortField')}\n hint={t('models.builder.sortFieldHint')}\n value={sort?.fieldId}\n options={sortable.map(option)}\n onChange={(fieldId) =>\n setDisplay('defaultSort', fieldId ? { fieldId, direction: sort?.direction ?? 'asc' } : undefined)\n }\n unsetLabel={t('models.builder.sortNewest')}\n issues={at('defaultSort')}\n disabled={disabled}\n />\n {sort ? (\n <SelectControl\n id=\"definition-sort-direction\"\n label={t('models.builder.sortDirection')}\n value={sort.direction}\n options={SORT_DIRECTIONS.map((direction) => ({\n value: direction,\n label: t(DIRECTION_LABEL_KEYS[direction]),\n }))}\n onChange={(direction) => direction && setDisplay('defaultSort', { ...sort, direction })}\n disabled={disabled}\n />\n ) : null}\n <ChoicesControl\n id=\"definition-list-fields\"\n label={t('models.builder.listColumns')}\n value={definition.display.listFieldIds ?? []}\n options={definition.fields.map(option)}\n onChange={(ids) => setDisplay('listFieldIds', ids.length > 0 ? ids : undefined)}\n issues={at('listFieldIds')}\n disabled={disabled}\n />\n <DocumentLayout model={definition} issues={issues} disabled={disabled} />\n </>\n );\n};\n","import { routeKeyOf, type ValidationIssue } from '@shapio/schema';\nimport type { ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { followPlural } from '../../helpers/followPlural';\nimport { issuesUnder } from '../../helpers/issues';\nimport { SwitchControl } from '../controls/SwitchControl';\nimport { TextControl } from '../controls/TextControl';\nimport { PanelSection } from '../PanelSection';\nimport { Display } from './Display';\n\ntype DefinitionPanelProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** Where the definition is available (the `Scope` section), first; absent on a single-site instance. */\n scopeSection?: ReactNode;\n};\n\n/** The definition's own settings (the expanded Model settings panel): naming, content and display. */\nexport const DefinitionPanel = ({ issues, disabled, scopeSection }: DefinitionPanelProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const update = useDefinitionDraftStore((state) => state.update);\n if (!draft) {\n return null;\n }\n const set = (patch: Record<string, unknown>) => update((current) => ({ ...current, ...patch }));\n const at = (property: string) => issuesUnder(issues, `/${property}`);\n const renamed = base !== null && base.apiKey !== draft.apiKey;\n const pluralRenamed =\n base?.kind === 'collection' && draft.kind === 'collection' && routeKeyOf(base) !== routeKeyOf(draft);\n // A collection's plural follows the API ID until it has been edited by hand (decision 8).\n const setApiKey = (apiKey: string) =>\n update((current) =>\n current.kind === 'collection'\n ? { ...current, apiKey, pluralApiKey: followPlural(current.apiKey, apiKey, current.pluralApiKey) }\n : { ...current, apiKey },\n );\n return (\n <div className=\"space-y-6\">\n {scopeSection}\n <PanelSection title={t('models.builder.general')}>\n <TextControl\n id=\"definition-label\"\n label={t('models.label')}\n value={draft.label}\n onChange={(label) => set({ label: label ?? '' })}\n issues={at('label')}\n disabled={disabled}\n />\n <TextControl\n id=\"definition-apiKey\"\n label={t('models.apiKey')}\n hint={t('models.apiKeyHint')}\n description={renamed ? t('models.builder.apiKeyRenameWarning') : undefined}\n value={draft.apiKey}\n onChange={(apiKey) => setApiKey(apiKey ?? '')}\n issues={at('apiKey')}\n disabled={disabled}\n monospace\n />\n {draft.kind === 'collection' ? (\n <TextControl\n id=\"definition-pluralApiKey\"\n label={t('models.pluralApiKey')}\n hint={t('models.pluralApiKeyHint')}\n description={pluralRenamed ? t('models.builder.pluralApiKeyRenameWarning') : undefined}\n value={draft.pluralApiKey}\n onChange={(pluralApiKey) => set({ pluralApiKey })}\n issues={at('pluralApiKey')}\n disabled={disabled}\n emptyAsUndefined\n monospace\n />\n ) : null}\n <TextControl\n id=\"definition-description\"\n label={t('models.descriptionLabel')}\n value={draft.description}\n onChange={(description) => set({ description })}\n issues={at('description')}\n disabled={disabled}\n emptyAsUndefined\n multiline\n />\n {draft.kind === 'component' ? (\n <TextControl\n id=\"definition-category\"\n label={t('models.builder.category')}\n hint={t('models.builder.categoryHint')}\n value={draft.category}\n onChange={(category) => set({ category })}\n issues={at('category')}\n disabled={disabled}\n emptyAsUndefined\n />\n ) : null}\n </PanelSection>\n {draft.kind === 'component' ? null : (\n <PanelSection title={t('models.builder.content')}>\n <SwitchControl\n id=\"definition-localized\"\n label={t('models.localized')}\n hint={t('models.builder.modelLocalizedHint')}\n checked={draft.localized}\n onChange={(localized) => set({ localized })}\n issues={at('localized')}\n disabled={disabled}\n />\n <SwitchControl\n id=\"definition-draftAndPublish\"\n label={t('models.builder.draftAndPublish')}\n hint={t('models.builder.draftAndPublishHint')}\n checked={draft.draftAndPublish}\n onChange={(draftAndPublish) => set({ draftAndPublish })}\n issues={at('draftAndPublish')}\n disabled={disabled}\n />\n </PanelSection>\n )}\n <PanelSection title={t('models.builder.display')}>\n <Display definition={draft} issues={issues} disabled={disabled} />\n </PanelSection>\n </div>\n );\n};\n","import { routeKeyOf } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { KIND_ICONS, KIND_LABEL_KEYS } from '../../../constants';\n\ntype SummaryProps = { hasIssues: boolean };\n\n/** The collapsed Model settings: kind, localization, drafts and the plural API ID, in one row. */\nexport const Summary = ({ hasIssues }: SummaryProps) => {\n const { t } = useTranslation();\n const draft = useDefinitionDraftStore((state) => state.draft);\n if (!draft) {\n return null;\n }\n const KindIcon = KIND_ICONS[draft.kind];\n return (\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <Badge variant=\"outline\">\n <KindIcon aria-hidden=\"true\" />\n {t(KIND_LABEL_KEYS[draft.kind])}\n </Badge>\n {draft.kind === 'component' ? null : (\n <>\n <Badge variant=\"outline\">\n {t(draft.localized ? 'models.builder.summaryLocalized' : 'models.builder.summaryNotLocalized')}\n </Badge>\n <Badge variant=\"outline\">\n {t(draft.draftAndPublish ? 'models.builder.summaryDrafts' : 'models.builder.summaryNoDrafts')}\n </Badge>\n </>\n )}\n {draft.kind === 'collection' ? (\n <Badge variant=\"outline\" className=\"font-mono font-medium\">\n <span className=\"sr-only\">{t('models.pluralApiKey')} </span>\n {routeKeyOf(draft)}\n </Badge>\n ) : null}\n {hasIssues ? <StatusChip tone=\"danger\" size=\"sm\" label={t('models.builder.hasProblems')} /> : null}\n </div>\n );\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { ChevronDown } from 'lucide-react';\nimport { useId, useState, type ReactNode } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\nimport { DefinitionPanel } from '../DefinitionPanel';\nimport { Summary } from './Summary';\n\ntype ModelSettingsProps = {\n issues: readonly ValidationIssue[];\n disabled: boolean;\n /** Passed to `DefinitionPanel`. */\n scopeSection?: ReactNode;\n};\n\n/** Issues about the definition itself, not one of its fields (those show on the field). */\nconst isDefinitionIssue = (issue: ValidationIssue) => !/^\\/fields(\\/|$)/.test(issue.path);\n\n/** The definition's own settings: a one-row summary until expanded to edit. */\nexport const ModelSettings = ({ issues, disabled, scopeSection }: ModelSettingsProps) => {\n const { t } = useTranslation();\n const [expanded, setExpanded] = useState(false);\n const bodyId = useId();\n return (\n <Panel\n title={t('models.builder.definitionSettings')}\n actions={\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-expanded={expanded}\n aria-controls={bodyId}\n aria-label={t('models.builder.definitionSettings')}\n onClick={() => setExpanded((open) => !open)}\n >\n <ChevronDown aria-hidden=\"true\" className={cn('transition-transform', expanded && 'rotate-180')} />\n </Button>\n }\n >\n <div id={bodyId}>\n {expanded ? (\n <DefinitionPanel issues={issues} disabled={disabled} scopeSection={scopeSection} />\n ) : (\n <Summary hasIssues={issues.some(isDefinitionIssue)} />\n )}\n </div>\n </Panel>\n );\n};\n","import { MousePointerClick, Shapes } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\n\ntype NoFieldSelectedProps = { hasFields: boolean };\n\n/** The properties column before a field is chosen (xl only: below it, the field list is right above). */\nexport const NoFieldSelected = ({ hasFields }: NoFieldSelectedProps) => {\n const { t } = useTranslation();\n return (\n <Panel aria-label={t('models.builder.propertiesLabel')} className=\"hidden xl:block\">\n {hasFields ? (\n <EmptyState size=\"panel\" icon={MousePointerClick} title={t('models.builder.selectField')} />\n ) : (\n <EmptyState size=\"panel\" icon={Shapes} title={t('models.builder.startTitle')} />\n )}\n </Panel>\n );\n};\n","import { RefreshCw } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\n\ntype RemoteChangeBannerProps = {\n /**\n * Why it shows: `remote`, another session activated a newer version (noticed by polling); `conflict`,\n * this session's own review or save was refused because the version moved (a rejected non-fast-forward).\n */\n reason: 'remote' | 'conflict';\n /** There are unsaved edits, so the admin chooses what happens to them. */\n dirty: boolean;\n /** Start over from the latest version (unsaved edits are dropped). */\n onReload: () => void;\n /** Keep the edits on top of the latest version and review again. */\n onKeepEdits: () => void;\n};\n\n/**\n * The definition moved on while this admin was editing. Nothing is discarded silently: with unsaved edits\n * the admin takes the latest version or keeps their edits on top of it; without, they reload. A conflict\n * from their own save is announced at once (alert); a change noticed in the background politely (status).\n */\nexport const RemoteChangeBanner = ({ reason, dirty, onReload, onKeepEdits }: RemoteChangeBannerProps) => {\n const { t } = useTranslation();\n const choose = dirty || reason === 'conflict';\n return (\n <Alert\n variant=\"warning\"\n role={reason === 'conflict' ? 'alert' : 'status'}\n className=\"flex flex-wrap items-center justify-between gap-3\"\n >\n <div className=\"flex items-start gap-3\">\n <RefreshCw className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <div>\n <AlertTitle>{t('models.remote.title')}</AlertTitle>\n <AlertDescription>\n {t(choose ? 'models.remote.chooseDescription' : 'models.remote.description')}\n </AlertDescription>\n </div>\n </div>\n {choose ? (\n <div className=\"flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onKeepEdits}>\n {t('models.remote.keepEdits')}\n </Button>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReload}>\n {t('models.remote.reloadLatest')}\n </Button>\n </div>\n ) : (\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={onReload}>\n {t('models.remote.reload')}\n </Button>\n )}\n </Alert>\n );\n};\n","import type { ClassifiedChange, SchemaDefinition } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { PLAN_BUCKET_LABEL_KEYS } from '../../../constants';\nimport { describeChange } from '../../../helpers/describeChange';\nimport { groupByBucket } from '../../../helpers/planBuckets';\nimport { BucketChip } from '../../BucketChip';\n\ntype ChangeListProps = {\n changes: readonly ClassifiedChange[];\n before: SchemaDefinition | null;\n after: SchemaDefinition | null;\n};\n\n/** Every change in the plan, grouped by how it is applied, most demanding group first. */\nexport const ChangeList = ({ changes, before, after }: ChangeListProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"space-y-4\">\n {groupByBucket(changes).map(({ bucket, changes: inGroup }) => (\n <div key={bucket} className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <BucketChip bucket={bucket} />\n <span className=\"text-meta text-muted-foreground tabular-nums\">{inGroup.length}</span>\n </div>\n <ul aria-label={t(PLAN_BUCKET_LABEL_KEYS[bucket])} className=\"divide-y rounded-lg border\">\n {inGroup.map((change, index) => (\n <li\n key={`${change.kind}-${change.fieldId ?? ''}-${change.property ?? ''}-${index}`}\n className=\"px-3 py-2.5 text-sm\"\n >\n {describeChange(change, before, after)}\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n );\n};\n","import type { PlanPreview } from '@shapio/client';\nimport type { SchemaDefinition } from '@shapio/schema';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useSaveDraftToChangeSet } from '@/api/changeSets';\nimport { settle } from '@/helpers/settle';\n\n/**\n * \"Review in a change set\" (plan developer-face §5): the reviewed draft goes into the newest open change\n * set (or a new one), then its review opens. The draft is saved there, so leaving the builder skips the\n * unsaved-changes guard.\n */\nexport const useReviewInChangeSet = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const save = useSaveDraftToChangeSet();\n const reviewInChangeSet = async (preview: PlanPreview, draft: SchemaDefinition) => {\n const { plan } = preview;\n const saved = await settle(\n save.mutateAsync({\n definitionId: plan.definitionId,\n newSetTitle: t('changes.builderSetTitle', { label: draft.label }),\n input: {\n category: plan.kind === 'component' ? 'component' : 'model',\n definition: draft,\n baseVersion: plan.fromVersion,\n },\n }),\n );\n if (saved.ok) {\n await navigate({\n to: '/changes/$changeSetId',\n params: { changeSetId: saved.value },\n ignoreBlocker: true,\n });\n }\n };\n return { reviewInChangeSet, saving: save.isPending, saveError: save.error, resetSave: save.reset };\n};\n","import type { Acknowledgement, PlanPreview } from '@shapio/client';\nimport type { SchemaDefinition } from '@shapio/schema';\nimport { GitPullRequest, Loader2 } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { InfoHint } from '@/components/InfoHint';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Field, FieldLabel } from '@/components/ui/field';\nimport {\n Sheet,\n SheetBody,\n SheetContent,\n SheetDescription,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n} from '@/components/ui/sheet';\nimport { bucketOfPlan, type PlanBucket } from '../../helpers/planBuckets';\nimport { BucketChip } from '../BucketChip';\nimport { ChangeList } from './ChangeList';\nimport { useReviewInChangeSet } from './hooks/useReviewInChangeSet';\nimport { StepList } from './StepList';\n\ntype ReviewSheetProps = {\n preview: PlanPreview | undefined;\n before: SchemaDefinition | null;\n after: SchemaDefinition | null;\n applying: boolean;\n error: unknown;\n onApply: (acknowledgement: Acknowledgement) => void;\n onClose: () => void;\n};\n\nconst SUMMARY_KEYS = {\n breaking: 'models.plan.summary.breaking',\n prerequisites: 'models.plan.summary.prerequisites',\n live: 'models.plan.summary.live',\n metadata: 'models.plan.summary.metadata',\n} as const satisfies Record<PlanBucket, string>;\n\n/**\n * The plan preview (brief §5 step 5), in a wide sheet so the builder stays in view: every change classified,\n * the entries affected, the prerequisite jobs that run before activation, and explicit acknowledgement for\n * breaking or destructive changes. From here the draft either ships now (the primary action) or goes into\n * a change set to be reviewed and shipped with other work (\"Review in a change set\"). It can't be closed\n * while either is in progress.\n */\nexport const ReviewSheet = ({\n preview,\n before,\n after,\n applying,\n error,\n onApply,\n onClose,\n}: ReviewSheetProps) => {\n const { t } = useTranslation();\n const [acknowledgedBreaking, setAcknowledgedBreaking] = useState(false);\n const [acknowledgedDestructive, setAcknowledgedDestructive] = useState(false);\n const [previewShown, setPreviewShown] = useState(preview);\n const { reviewInChangeSet, saving, saveError, resetSave } = useReviewInChangeSet();\n const busy = applying || saving;\n // A new preview starts with nothing acknowledged. The last one stays rendered while the sheet closes.\n if (preview !== undefined && preview !== previewShown) {\n setPreviewShown(preview);\n setAcknowledgedBreaking(false);\n setAcknowledgedDestructive(false);\n resetSave();\n }\n const plan = previewShown?.plan;\n const summary = plan?.summary;\n const bucket = summary ? bucketOfPlan(summary) : 'metadata';\n const needsBreaking = summary?.breaking ?? false;\n const needsDestructive = summary?.destructive ?? false;\n const canApply = (!needsBreaking || acknowledgedBreaking) && (!needsDestructive || acknowledgedDestructive);\n return (\n <Sheet open={preview !== undefined} onOpenChange={(open) => !open && !busy && onClose()}>\n <SheetContent size=\"lg\">\n <SheetHeader className=\"pr-14\">\n <SheetTitle>{t('models.plan.title', { label: after?.label ?? '' })}</SheetTitle>\n <SheetDescription>{t(SUMMARY_KEYS[bucket])}</SheetDescription>\n </SheetHeader>\n {plan && previewShown ? (\n <form\n noValidate\n className=\"flex min-h-0 flex-1 flex-col\"\n onSubmit={(event) => {\n event.preventDefault();\n onApply({\n ...(needsBreaking ? { acknowledgeBreaking: true } : {}),\n ...(needsDestructive ? { acknowledgeDestructive: true } : {}),\n });\n }}\n >\n <SheetBody className=\"space-y-6 pt-1\">\n <div className=\"flex flex-wrap items-center gap-3 rounded-lg bg-muted px-3 py-2.5\">\n <BucketChip bucket={bucket} />\n <span className=\"text-meta text-muted-foreground\">\n {t('models.plan.affected', { count: previewShown.impact.affectedHeads })}\n </span>\n </div>\n <section className=\"space-y-3\" aria-labelledby=\"plan-changes\">\n <h3 id=\"plan-changes\" className=\"text-sm font-semibold\">\n {t('models.plan.changes', { count: plan.changes.length })}\n </h3>\n <ChangeList changes={plan.changes} before={before} after={after} />\n </section>\n {plan.prerequisites.length > 0 ? (\n <section className=\"space-y-3\" aria-labelledby=\"plan-prerequisites\">\n <div className=\"flex items-center gap-1\">\n <h3 id=\"plan-prerequisites\" className=\"text-sm font-semibold\">\n {t('models.plan.prerequisites')}\n </h3>\n <InfoHint about={t('models.plan.prerequisites')}>\n {t('models.plan.prerequisitesHint')}\n </InfoHint>\n </div>\n <StepList\n phase=\"before\"\n steps={plan.prerequisites}\n impacts={previewShown.impact.steps}\n before={before}\n after={after}\n />\n </section>\n ) : null}\n {plan.followUps.length > 0 ? (\n <section className=\"space-y-3\" aria-labelledby=\"plan-follow-ups\">\n <h3 id=\"plan-follow-ups\" className=\"text-sm font-semibold\">\n {t('models.plan.followUps')}\n </h3>\n <StepList phase=\"after\" steps={plan.followUps} before={before} after={after} />\n </section>\n ) : null}\n {needsBreaking || needsDestructive ? (\n <fieldset className=\"space-y-3 rounded-lg border border-warning/40 bg-warning-muted/40 p-4\">\n <legend className=\"px-1 text-sm font-semibold text-warning\">\n {t('models.plan.acknowledge')}\n </legend>\n {needsBreaking ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"plan-ack-breaking\"\n checked={acknowledgedBreaking}\n onCheckedChange={(checked) => setAcknowledgedBreaking(checked === true)}\n />\n <FieldLabel htmlFor=\"plan-ack-breaking\" className=\"font-normal\">\n {t('models.plan.acknowledgeBreaking')}\n </FieldLabel>\n </Field>\n ) : null}\n {needsDestructive ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"plan-ack-destructive\"\n checked={acknowledgedDestructive}\n onCheckedChange={(checked) => setAcknowledgedDestructive(checked === true)}\n />\n <FieldLabel htmlFor=\"plan-ack-destructive\" className=\"font-normal\">\n {t('models.plan.acknowledgeDestructive')}\n </FieldLabel>\n </Field>\n ) : null}\n </fieldset>\n ) : null}\n <FormError error={error ?? saveError} />\n </SheetBody>\n <SheetFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={busy}>\n {t('common.cancel')}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={busy || !after}\n aria-busy={saving || undefined}\n onClick={() => after && void reviewInChangeSet(previewShown, after)}\n >\n {saving ? (\n <Loader2 className=\"animate-spin motion-reduce:animate-none\" aria-hidden=\"true\" />\n ) : (\n <GitPullRequest aria-hidden=\"true\" />\n )}\n {saving ? t('common.saving') : t('changes.reviewInChangeSet')}\n </Button>\n <SubmitButton\n pending={applying}\n pendingLabel={t('models.plan.applying')}\n disabled={!canApply || saving}\n >\n {t('models.plan.apply')}\n </SubmitButton>\n </SheetFooter>\n </form>\n ) : null}\n </SheetContent>\n </Sheet>\n );\n};\n","import type { DefinitionCategory, DefinitionDetail } from '@shapio/client';\nimport { useNavigate } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useDeleteDefinition } from '@/api/schema';\nimport { ConfirmDialog } from '@/components/ConfirmDialog';\nimport { LoadingState } from '@/components/LoadingState';\nimport { Page } from '@/components/Page';\nimport { UnsavedChangesGuard } from '@/components/UnsavedChangesGuard';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport { useSaveShortcut } from '@/hooks/useSaveShortcut';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { draftKeyOf, useDefinitionDraftStore } from '@/stores/definitionDraft';\nimport { useSchemaLock } from '../../hooks/useSchemaLock';\nimport { useSharedReadOnly } from '../../hooks/useSharedReadOnly';\nimport { LockNotice } from '../../LockNotice';\nimport { SharedNotice } from '../../SharedNotice';\nimport { ActionFooter } from '../ActionFooter';\nimport { ChangeProgress } from '../ChangeProgress';\nimport { Scope } from '../DefinitionPanel/Scope';\nimport { FieldList } from '../FieldList';\nimport { FieldPanel } from '../FieldPanel';\nimport { Header } from '../Header';\nimport { useAddSeoField } from '../hooks/useAddSeoField';\nimport { useDraftIssues } from '../hooks/useDraftIssues';\nimport { useIsDraftDirty } from '../hooks/useIsDraftDirty';\nimport { useNewField } from '../hooks/useNewField';\nimport { useReloadDraft } from '../hooks/useReloadDraft';\nimport { useRemoteChangeNotice } from '../hooks/useRemoteChangeNotice';\nimport { useSaveFlow } from '../hooks/useSaveFlow';\nimport { useSelectedField } from '../hooks/useSelectedField';\nimport { ModelSettings } from '../ModelSettings';\nimport { NoFieldSelected } from '../NoFieldSelected';\nimport { RemoteChangeBanner } from '../RemoteChangeBanner';\nimport { ReviewSheet } from '../ReviewSheet';\n\ntype EditorProps = { category: DefinitionCategory; id: string; detail: DefinitionDetail };\n\n/** Edits a draft of the definition; nothing changes on the server until the plan is reviewed and applied. */\nexport const Editor = ({ category, id, detail }: EditorProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const key = draftKeyOf(category, id);\n const loadedKey = useDefinitionDraftStore((state) => state.key);\n const draft = useDefinitionDraftStore((state) => state.draft);\n const base = useDefinitionDraftStore((state) => state.base);\n const baseVersion = useDefinitionDraftStore((state) => state.baseVersion);\n const load = useDefinitionDraftStore((state) => state.load);\n const reset = useDefinitionDraftStore((state) => state.reset);\n const reloadDraft = useReloadDraft(category, id);\n const flow = useSaveFlow(category, id, reloadDraft);\n const dirty = useIsDraftDirty();\n const { issues } = useDraftIssues();\n const { field, index } = useSelectedField();\n const { locked, reason } = useSchemaLock();\n const sharedReadOnly = useSharedReadOnly(detail.scope);\n const { multiSite } = useSchemaScopeAccess();\n const deleteDefinition = useDeleteDefinition();\n const newField = useNewField();\n const seoField = useAddSeoField();\n const [confirmingDelete, setConfirmingDelete] = useState(false);\n const [dismissedChangeId, setDismissedChangeId] = useState<string | undefined>(undefined);\n const [scopeConflict, setScopeConflict] = useState(false);\n\n // A fresh draft each time the builder opens; it is forgotten when the builder closes.\n const initial = useRef(detail);\n useEffect(() => {\n load(category, initial.current.definition, initial.current.version);\n return reset;\n }, [key, category, load, reset]);\n\n const changeId = flow.runningChangeId ?? detail.pendingChange?.id;\n const visibleChangeId = changeId === dismissedChangeId ? undefined : changeId;\n const changeRunning = visibleChangeId !== undefined;\n const { changedElsewhere } = useRemoteChangeNotice(id, baseVersion, changeRunning || flow.applying);\n const saveBlocked = locked || sharedReadOnly || changeRunning;\n const canReview = dirty && issues.length === 0 && !saveBlocked && !flow.reviewing;\n const planOpen = flow.state.step === 'review';\n const conflict = flow.state.step === 'conflict' || scopeConflict;\n useSaveShortcut(() => void flow.review(), canReview && !planOpen);\n\n if (loadedKey !== key || !draft) {\n return <LoadingState />;\n }\n\n const reload = (mode: 'replace' | 'rebase') =>\n void reloadDraft(mode).catch((error: unknown) => {\n logError(error, 'reloading the definition');\n toast.error(describeError(error));\n });\n const editingDisabled = locked || sharedReadOnly;\n\n const scopeSection = multiSite ? (\n <Scope\n category={category}\n id={id}\n label={draft.label}\n scope={detail.scope}\n blocked={dirty || changeRunning || flow.applying}\n locked={locked}\n onConflict={() => setScopeConflict(true)}\n />\n ) : null;\n\n const saveActions = {\n canDiscard: dirty,\n canReview,\n reviewing: flow.reviewing,\n onReview: () => void flow.review(),\n onDiscard: () => {\n if (base) {\n load(category, base, baseVersion);\n }\n },\n };\n\n return (\n <Page width=\"full\">\n <UnsavedChangesGuard when={dirty} />\n <Header\n {...saveActions}\n draft={draft}\n version={baseVersion}\n dirty={dirty}\n issueCount={issues.length}\n deleteBlocked={saveBlocked}\n onDelete={() => setConfirmingDelete(true)}\n />\n {locked ? <LockNotice reason={reason} /> : null}\n {sharedReadOnly ? <SharedNotice /> : null}\n {changedElsewhere || conflict ? (\n <RemoteChangeBanner\n key={conflict ? 'conflict' : 'remote'}\n reason={conflict ? 'conflict' : 'remote'}\n dirty={dirty}\n onReload={() => {\n flow.resetStep();\n setScopeConflict(false);\n reload('replace');\n }}\n onKeepEdits={() => {\n flow.resetStep();\n setScopeConflict(false);\n reload('rebase');\n }}\n />\n ) : null}\n {visibleChangeId ? (\n <ChangeProgress\n key={visibleChangeId}\n changeId={visibleChangeId}\n onFinished={(status) => void flow.onChangeFinished(status)}\n onDismiss={() => {\n setDismissedChangeId(visibleChangeId);\n flow.dismissChange();\n }}\n />\n ) : null}\n {/*\n One column below xl: settings, fields, then the properties pane (shown for a selected field).\n Locked (or shared and not ours to change): every control is disabled individually, so fields can\n still be selected and read.\n */}\n <div className=\"grid min-w-0 gap-6 xl:grid-cols-[22.5rem_minmax(0,1fr)] xl:items-start\">\n <div className=\"min-w-0 space-y-6\">\n <ModelSettings issues={issues} disabled={editingDisabled} scopeSection={scopeSection} />\n <FieldList\n issues={issues}\n disabled={editingDisabled}\n onAdd={newField.add}\n seo={draft.kind === 'component' ? undefined : seoField}\n />\n </div>\n {field ? (\n <FieldPanel\n key={field.id}\n field={field}\n index={index}\n issues={issues}\n disabled={editingDisabled}\n untouched={newField.isUntouched(field)}\n onDiscard={() => newField.discard(field.id)}\n />\n ) : (\n <NoFieldSelected hasFields={draft.fields.length > 0} />\n )}\n </div>\n <ActionFooter {...saveActions} />\n <ReviewSheet\n preview={flow.state.step === 'review' ? flow.state.preview : undefined}\n before={base}\n after={draft}\n applying={flow.applying}\n error={flow.applyError}\n onApply={(acknowledgement) => void flow.confirm(acknowledgement)}\n onClose={flow.resetStep}\n />\n <ConfirmDialog\n open={confirmingDelete}\n onOpenChange={setConfirmingDelete}\n title={t('models.builder.deleteTitle', { label: draft.label })}\n description={t('models.builder.deleteDescription')}\n confirmLabel={t('common.delete')}\n destructive\n onConfirm={() =>\n deleteDefinition.mutate(\n { category, id, expectedVersion: baseVersion },\n {\n onSuccess: () => {\n reset();\n toast.success(t('models.deleted'));\n void navigate({ to: '/models' });\n },\n },\n )\n }\n />\n </Page>\n );\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport { useDefinition } from '@/api/schema';\nimport { QueryView } from '@/components/QueryView';\nimport { Editor } from './Editor';\n\ntype BuilderProps = { category: DefinitionCategory; id: string };\n\n/** The model (or component) builder: loads the definition, then edits a draft of it. */\nexport const Builder = ({ category, id }: BuilderProps) => {\n const detail = useDefinition(category, id);\n return (\n <QueryView query={detail}>\n {(data) => <Editor key={id} category={category} id={id} detail={data} />}\n </QueryView>\n );\n};\n"],"ignoreList":[0,1,2],"mappings":"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"}
|