@shapio/cms 0.5.5 → 0.5.7
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-CaYPqR_F.js → AssetTile-H0hABhB2.js} +2 -2
- package/dist/admin/assets/{AssetTile-CaYPqR_F.js.map → AssetTile-H0hABhB2.js.map} +1 -1
- package/dist/admin/assets/AssistError-1s3PuY0X.js +2 -0
- package/dist/admin/assets/{AssistError-drmpXSbS.js.map → AssistError-1s3PuY0X.js.map} +1 -1
- package/dist/admin/assets/{BlockMenuItems-D-jZ0oaU.js → BlockMenuItems-a8zXdfcF.js} +2 -2
- package/dist/admin/assets/{BlockMenuItems-D-jZ0oaU.js.map → BlockMenuItems-a8zXdfcF.js.map} +1 -1
- package/dist/admin/assets/Body-BzZD-TZT.js +2 -0
- package/dist/admin/assets/{Body-Gn_z2KPN.js.map → Body-BzZD-TZT.js.map} +1 -1
- package/dist/admin/assets/Builder-60jO_nbS.js +2 -0
- package/dist/admin/assets/Builder-60jO_nbS.js.map +1 -0
- package/dist/admin/assets/{CodeEditor-CzRU6och.js → CodeEditor-BLbJZE9v.js} +2 -2
- package/dist/admin/assets/{CodeEditor-CzRU6och.js.map → CodeEditor-BLbJZE9v.js.map} +1 -1
- package/dist/admin/assets/{CopyButton-h4HYhnYp.js → CopyButton-BOtR_h1H.js} +2 -2
- package/dist/admin/assets/{CopyButton-h4HYhnYp.js.map → CopyButton-BOtR_h1H.js.map} +1 -1
- package/dist/admin/assets/{CursorPager-H4SpVYw7.js → CursorPager-DwLW13ov.js} +2 -2
- package/dist/admin/assets/{CursorPager-H4SpVYw7.js.map → CursorPager-DwLW13ov.js.map} +1 -1
- package/dist/admin/assets/{ExternalLink-BNq7nAYL.js → ExternalLink-BITMgS1K.js} +2 -2
- package/dist/admin/assets/{ExternalLink-BNq7nAYL.js.map → ExternalLink-BITMgS1K.js.map} +1 -1
- package/dist/admin/assets/{FocalPoint-CSeKI4Iw.js → FocalPoint-n-a_AXKN.js} +2 -2
- package/dist/admin/assets/{FocalPoint-CSeKI4Iw.js.map → FocalPoint-n-a_AXKN.js.map} +1 -1
- package/dist/admin/assets/Form-D_4fhOy0.js +2 -0
- package/dist/admin/assets/Form-D_4fhOy0.js.map +1 -0
- package/dist/admin/assets/{FormCheckboxGroup-V3IKrvzc.js → FormCheckboxGroup-1fYisXrr.js} +2 -2
- package/dist/admin/assets/FormCheckboxGroup-1fYisXrr.js.map +1 -0
- package/dist/admin/assets/{FormRadioGroup-DIv-MYgn.js → FormRadioGroup-B0VZyb1t.js} +2 -2
- package/dist/admin/assets/{FormRadioGroup-DIv-MYgn.js.map → FormRadioGroup-B0VZyb1t.js.map} +1 -1
- package/dist/admin/assets/{FormSelectField-CUhaPIMY.js → FormSelectField-Br8bkwRF.js} +2 -2
- package/dist/admin/assets/{FormSelectField-CUhaPIMY.js.map → FormSelectField-Br8bkwRF.js.map} +1 -1
- package/dist/admin/assets/{FormSwitchField-DW8ysyk_.js → FormSwitchField-d8G-YCSX.js} +2 -2
- package/dist/admin/assets/{FormSwitchField-DW8ysyk_.js.map → FormSwitchField-d8G-YCSX.js.map} +1 -1
- package/dist/admin/assets/{FormTextareaField-DbqZ-MwI.js → FormTextareaField-BSKNeTPW.js} +2 -2
- package/dist/admin/assets/{FormTextareaField-DbqZ-MwI.js.map → FormTextareaField-BSKNeTPW.js.map} +1 -1
- package/dist/admin/assets/{HintedLabel-BlLtqVVz.js → HintedLabel-CiTDE112.js} +2 -2
- package/dist/admin/assets/{HintedLabel-BlLtqVVz.js.map → HintedLabel-CiTDE112.js.map} +1 -1
- package/dist/admin/assets/{InfoHint-bYMd_t0J.js → InfoHint-B3XcXtiN.js} +2 -2
- package/dist/admin/assets/{InfoHint-bYMd_t0J.js.map → InfoHint-B3XcXtiN.js.map} +1 -1
- package/dist/admin/assets/InlineConfirm-BfsNH5S_.js +2 -0
- package/dist/admin/assets/InlineConfirm-BfsNH5S_.js.map +1 -0
- package/dist/admin/assets/InsertMenuItem-BGwDW_Lu.js +2 -0
- package/dist/admin/assets/InsertMenuItem-BGwDW_Lu.js.map +1 -0
- package/dist/admin/assets/{LinkTabs-ByB2eCIr.js → LinkTabs-8SmS1vCd.js} +2 -2
- package/dist/admin/assets/{LinkTabs-ByB2eCIr.js.map → LinkTabs-8SmS1vCd.js.map} +1 -1
- package/dist/admin/assets/{Match-GDx_orOH.js → Match-Dc8bXsKo.js} +2 -2
- package/dist/admin/assets/{Match-GDx_orOH.js.map → Match-Dc8bXsKo.js.map} +1 -1
- package/dist/admin/assets/NoAccess-CKEKPmqD.js +2 -0
- package/dist/admin/assets/NoAccess-CKEKPmqD.js.map +1 -0
- package/dist/admin/assets/Panel-Bcl09TtM.js +2 -0
- package/dist/admin/assets/Panel-Bcl09TtM.js.map +1 -0
- package/dist/admin/assets/{QueryView-UBO-U5Wo.js → QueryView-KFtwko9F.js} +2 -2
- package/dist/admin/assets/{QueryView-UBO-U5Wo.js.map → QueryView-KFtwko9F.js.map} +1 -1
- package/dist/admin/assets/{RadioTile-CJbIIV8t.js → RadioTile-CzfxWgHx.js} +2 -2
- package/dist/admin/assets/{RadioTile-CJbIIV8t.js.map → RadioTile-CzfxWgHx.js.map} +1 -1
- package/dist/admin/assets/{RichTextField-M7HyUhYF.js → RichTextField-BsBoOAP-.js} +5 -5
- package/dist/admin/assets/{RichTextField-M7HyUhYF.js.map → RichTextField-BsBoOAP-.js.map} +1 -1
- package/dist/admin/assets/{RowTitle-DoxDM1XL.js → RowTitle-Cn5mAU58.js} +2 -2
- package/dist/admin/assets/{RowTitle-DoxDM1XL.js.map → RowTitle-Cn5mAU58.js.map} +1 -1
- package/dist/admin/assets/SecretReveal-BCOJAisI.js +2 -0
- package/dist/admin/assets/SecretReveal-BCOJAisI.js.map +1 -0
- package/dist/admin/assets/{SharedGlyph-D1OMHXPf.js → SharedGlyph-CA8tb7UH.js} +2 -2
- package/dist/admin/assets/{SharedGlyph-D1OMHXPf.js.map → SharedGlyph-CA8tb7UH.js.map} +1 -1
- package/dist/admin/assets/StepList-sriwGP1e.js +2 -0
- package/dist/admin/assets/StepList-sriwGP1e.js.map +1 -0
- package/dist/admin/assets/{Structure-CO4aJZVP.js → Structure-B2HZ9UZu.js} +2 -2
- package/dist/admin/assets/{Structure-CO4aJZVP.js.map → Structure-B2HZ9UZu.js.map} +1 -1
- package/dist/admin/assets/{SubNavLink-CPJFIt1j.js → SubNavLink-CiCaVV8U.js} +2 -2
- package/dist/admin/assets/{SubNavLink-CPJFIt1j.js.map → SubNavLink-CiCaVV8U.js.map} +1 -1
- package/dist/admin/assets/{SuggestAltButton-CbRUxD5s.js → SuggestAltButton-CqDLAuoa.js} +2 -2
- package/dist/admin/assets/{SuggestAltButton-CbRUxD5s.js.map → SuggestAltButton-CqDLAuoa.js.map} +1 -1
- package/dist/admin/assets/{TextLink-DnrMaF2F.js → TextLink-HRn66VL1.js} +2 -2
- package/dist/admin/assets/{TextLink-DnrMaF2F.js.map → TextLink-HRn66VL1.js.map} +1 -1
- package/dist/admin/assets/Thumbnail-mFfESZiW.js +2 -0
- package/dist/admin/assets/Thumbnail-mFfESZiW.js.map +1 -0
- package/dist/admin/assets/UnsavedChangesGuard-C8cDQGEA.js +2 -0
- package/dist/admin/assets/UnsavedChangesGuard-C8cDQGEA.js.map +1 -0
- package/dist/admin/assets/{UserAvatar-Bl32IpG_.js → UserAvatar-BItYDTyH.js} +2 -2
- package/dist/admin/assets/{UserAvatar-Bl32IpG_.js.map → UserAvatar-BItYDTyH.js.map} +1 -1
- package/dist/admin/assets/auth-CQO4MBUj.js +2 -0
- package/dist/admin/assets/auth-CQO4MBUj.js.map +1 -0
- package/dist/admin/assets/badge-DNQwGXBl.js +2 -0
- package/dist/admin/assets/{badge-ydvfgE8a.js.map → badge-DNQwGXBl.js.map} +1 -1
- package/dist/admin/assets/{boxes-D6Y4Cenx.js → boxes-CAygw8zF.js} +2 -2
- package/dist/admin/assets/{boxes-D6Y4Cenx.js.map → boxes-CAygw8zF.js.map} +1 -1
- package/dist/admin/assets/{calendar-clock-DFUgXWXg.js → calendar-clock-BZGtAvWR.js} +2 -2
- package/dist/admin/assets/{calendar-clock-DFUgXWXg.js.map → calendar-clock-BZGtAvWR.js.map} +1 -1
- package/dist/admin/assets/changeSets-EMTUJT0M.js +2 -0
- package/dist/admin/assets/changeSets-EMTUJT0M.js.map +1 -0
- package/dist/admin/assets/chevron-left-DGU3HGYG.js +2 -0
- package/dist/admin/assets/{chevron-left-CZXrLV99.js.map → chevron-left-DGU3HGYG.js.map} +1 -1
- package/dist/admin/assets/{circle-check-De27poaB.js → circle-check-C37MSJqX.js} +2 -2
- package/dist/admin/assets/{circle-check-De27poaB.js.map → circle-check-C37MSJqX.js.map} +1 -1
- package/dist/admin/assets/{clock-BGAXsuo4.js → clock-2arjsgZ4.js} +2 -2
- package/dist/admin/assets/{clock-BGAXsuo4.js.map → clock-2arjsgZ4.js.map} +1 -1
- package/dist/admin/assets/{constants-esJAnNTh.js → constants-miV4q1ur.js} +2 -2
- package/dist/admin/assets/{constants-esJAnNTh.js.map → constants-miV4q1ur.js.map} +1 -1
- package/dist/admin/assets/content-CgZS_S7P.js +3 -0
- package/dist/admin/assets/content-CgZS_S7P.js.map +1 -0
- package/dist/admin/assets/contentCounts-DP7YYeZZ.js +2 -0
- package/dist/admin/assets/{contentCounts-DknqJ4kh.js.map → contentCounts-DP7YYeZZ.js.map} +1 -1
- package/dist/admin/assets/{contentTypes-C-AKiYu1.js → contentTypes-CQsHL657.js} +2 -2
- package/dist/admin/assets/{contentTypes-C-AKiYu1.js.map → contentTypes-CQsHL657.js.map} +1 -1
- package/dist/admin/assets/context-IKYdzQJ-.js +2 -0
- package/dist/admin/assets/{context-fImO9k99.js.map → context-IKYdzQJ-.js.map} +1 -1
- package/dist/admin/assets/{copy-B5owk67M.js → copy-CsSRHgKZ.js} +2 -2
- package/dist/admin/assets/{copy-B5owk67M.js.map → copy-CsSRHgKZ.js.map} +1 -1
- package/dist/admin/assets/createLucideIcon-CLmh7Go-.js +2 -0
- package/dist/admin/assets/createLucideIcon-CLmh7Go-.js.map +1 -0
- package/dist/admin/assets/develop-9ZeAjSIw.js +11 -0
- package/dist/admin/assets/develop-9ZeAjSIw.js.map +1 -0
- package/dist/admin/assets/{dropdown-menu-C53v9ioW.js → dropdown-menu-0dyAtBEd.js} +2 -2
- package/dist/admin/assets/{dropdown-menu-C53v9ioW.js.map → dropdown-menu-0dyAtBEd.js.map} +1 -1
- package/dist/admin/assets/{ellipsis-BHtU4ov6.js → ellipsis-F91991on.js} +2 -2
- package/dist/admin/assets/{ellipsis-BHtU4ov6.js.map → ellipsis-F91991on.js.map} +1 -1
- package/dist/admin/assets/entryLink-CVB-TdIn.js +2 -0
- package/dist/admin/assets/entryLink-CVB-TdIn.js.map +1 -0
- package/dist/admin/assets/es2015-BJge4oQL.js +42 -0
- package/dist/admin/assets/es2015-BJge4oQL.js.map +1 -0
- package/dist/admin/assets/{external-link-nZp2VpKw.js → external-link-CdG6kHfA.js} +2 -2
- package/dist/admin/assets/{external-link-nZp2VpKw.js.map → external-link-CdG6kHfA.js.map} +1 -1
- package/dist/admin/assets/{field-W1dB_h6d.js → field-C6NmRYUN.js} +2 -2
- package/dist/admin/assets/{field-W1dB_h6d.js.map → field-C6NmRYUN.js.map} +1 -1
- package/dist/admin/assets/{file-stack-8rRouTJj.js → file-stack-28ZtO1xW.js} +2 -2
- package/dist/admin/assets/{file-stack-8rRouTJj.js.map → file-stack-28ZtO1xW.js.map} +1 -1
- package/dist/admin/assets/{fileRoute-DzWMBrRx.js → fileRoute-Bm90K4UY.js} +2 -2
- package/dist/admin/assets/{fileRoute-DzWMBrRx.js.map → fileRoute-Bm90K4UY.js.map} +1 -1
- package/dist/admin/assets/{folder-plus-B3L3b389.js → folder-plus-DIk0pWkP.js} +2 -2
- package/dist/admin/assets/{folder-plus-B3L3b389.js.map → folder-plus-DIk0pWkP.js.map} +1 -1
- package/dist/admin/assets/followPlural-DEr2kxEc.js +2 -0
- package/dist/admin/assets/followPlural-DEr2kxEc.js.map +1 -0
- package/dist/admin/assets/{globe-DKkjr9MZ.js → globe-DFr3Gd2w.js} +2 -2
- package/dist/admin/assets/{globe-DKkjr9MZ.js.map → globe-DFr3Gd2w.js.map} +1 -1
- package/dist/admin/assets/{image-B6aL7hP8.js → image-DT79QFa_.js} +2 -2
- package/dist/admin/assets/{image-B6aL7hP8.js.map → image-DT79QFa_.js.map} +1 -1
- package/dist/admin/assets/{image-off-TVxEyb74.js → image-off-DFs5upyX.js} +2 -2
- package/dist/admin/assets/{image-off-TVxEyb74.js.map → image-off-DFs5upyX.js.map} +1 -1
- package/dist/admin/assets/inbox-B8XZ8L6s.js +2 -0
- package/dist/admin/assets/inbox-B8XZ8L6s.js.map +1 -0
- package/dist/admin/assets/{inbox-BKqu1EfP.js → inbox-CySnQydm.js} +2 -2
- package/dist/admin/assets/{inbox-BKqu1EfP.js.map → inbox-CySnQydm.js.map} +1 -1
- package/dist/admin/assets/index-DoJsnLI1.js +4 -0
- package/dist/admin/assets/index-DoJsnLI1.js.map +1 -0
- package/dist/admin/assets/index-lxe7WimO.css +2 -0
- package/dist/admin/assets/{key-round-Dmdr1vP5.js → key-round-D36CePnN.js} +2 -2
- package/dist/admin/assets/{key-round-Dmdr1vP5.js.map → key-round-D36CePnN.js.map} +1 -1
- package/dist/admin/assets/{labels-CHE0gg1n.js → labels-B2HIVxXg.js} +2 -2
- package/dist/admin/assets/{labels-CHE0gg1n.js.map → labels-B2HIVxXg.js.map} +1 -1
- package/dist/admin/assets/{languages-BbfFIygP.js → languages-CzbTaQv9.js} +2 -2
- package/dist/admin/assets/{languages-BbfFIygP.js.map → languages-CzbTaQv9.js.map} +1 -1
- package/dist/admin/assets/{layers-B0jT4rc4.js → layers-BmcodiaH.js} +2 -2
- package/dist/admin/assets/{layers-B0jT4rc4.js.map → layers-BmcodiaH.js.map} +1 -1
- package/dist/admin/assets/{link-2-off-DC06jLDj.js → link-2-off-CoJNwrxm.js} +2 -2
- package/dist/admin/assets/{link-2-off-DC06jLDj.js.map → link-2-off-CoJNwrxm.js.map} +1 -1
- package/dist/admin/assets/{link-B3O0VUVT.js → link-Pyr2Y35S.js} +2 -2
- package/dist/admin/assets/{link-B3O0VUVT.js.map → link-Pyr2Y35S.js.map} +1 -1
- package/dist/admin/assets/locales-Bg3htKo8.js +2 -0
- package/dist/admin/assets/{locales-e7B5t6id.js.map → locales-Bg3htKo8.js.map} +1 -1
- package/dist/admin/assets/media-BCnVhaDH.js +2 -0
- package/dist/admin/assets/{media-VCJUbYzJ.js.map → media-BCnVhaDH.js.map} +1 -1
- package/dist/admin/assets/media-CtbfNgc-.js +2 -0
- package/dist/admin/assets/media-CtbfNgc-.js.map +1 -0
- package/dist/admin/assets/network--5X46kWN.js +2 -0
- package/dist/admin/assets/network--5X46kWN.js.map +1 -0
- package/dist/admin/assets/{plus-WfYKHW7G.js → plus-BoDtdLCo.js} +2 -2
- package/dist/admin/assets/{plus-WfYKHW7G.js.map → plus-BoDtdLCo.js.map} +1 -1
- package/dist/admin/assets/publishing-DdmWXRaM.js +2 -0
- package/dist/admin/assets/{publishing-ClNjPLQ9.js.map → publishing-DdmWXRaM.js.map} +1 -1
- package/dist/admin/assets/{radio-group-rFxn7cz2.js → radio-group-BoN9R_3K.js} +2 -2
- package/dist/admin/assets/{radio-group-rFxn7cz2.js.map → radio-group-BoN9R_3K.js.map} +1 -1
- package/dist/admin/assets/{rotate-ccw-Cvc_uA58.js → rotate-ccw-DL6TzcZh.js} +2 -2
- package/dist/admin/assets/{rotate-ccw-Cvc_uA58.js.map → rotate-ccw-DL6TzcZh.js.map} +1 -1
- package/dist/admin/assets/schedules-BmB9Y73z.js +2 -0
- package/dist/admin/assets/{schedules-CBGpjEg7.js.map → schedules-BmB9Y73z.js.map} +1 -1
- package/dist/admin/assets/schema-D-qo7XSF.js +2 -0
- package/dist/admin/assets/schema-D-qo7XSF.js.map +1 -0
- package/dist/admin/assets/{scroll-text-gKYBbibb.js → scroll-text-PqeZm472.js} +2 -2
- package/dist/admin/assets/{scroll-text-gKYBbibb.js.map → scroll-text-PqeZm472.js.map} +1 -1
- package/dist/admin/assets/{search-CW3iBC4k.js → search-BdwIwOzC.js} +2 -2
- package/dist/admin/assets/{search-CW3iBC4k.js.map → search-BdwIwOzC.js.map} +1 -1
- package/dist/admin/assets/searchSchemas-DNjfDxmj.js +2 -0
- package/dist/admin/assets/{searchSchemas-C4qp-vCa.js.map → searchSchemas-DNjfDxmj.js.map} +1 -1
- package/dist/admin/assets/{sections-CN5fIoAr.js → sections-BTS683ur.js} +2 -2
- package/dist/admin/assets/{sections-CN5fIoAr.js.map → sections-BTS683ur.js.map} +1 -1
- package/dist/admin/assets/sections-BfxPwK0u.js +2 -0
- package/dist/admin/assets/{sections-C7Z6Xd8r.js.map → sections-BfxPwK0u.js.map} +1 -1
- package/dist/admin/assets/{select-DUhL27UN.js → select-Bp8kO5Ko.js} +2 -2
- package/dist/admin/assets/{select-DUhL27UN.js.map → select-Bp8kO5Ko.js.map} +1 -1
- package/dist/admin/assets/{send-DRA-Pe46.js → send-XPWo3m4u.js} +2 -2
- package/dist/admin/assets/{send-DRA-Pe46.js.map → send-XPWo3m4u.js.map} +1 -1
- package/dist/admin/assets/seo-CceGYTIX.js +2 -0
- package/dist/admin/assets/{seo-l1ZORjtv.js.map → seo-CceGYTIX.js.map} +1 -1
- package/dist/admin/assets/settings-TEbLvC-v.js +2 -0
- package/dist/admin/assets/settings-TEbLvC-v.js.map +1 -0
- package/dist/admin/assets/settle-CFU6YpQ0.js +2 -0
- package/dist/admin/assets/settle-CFU6YpQ0.js.map +1 -0
- package/dist/admin/assets/shapes-WrYO9Spf.js +6 -0
- package/dist/admin/assets/shapes-WrYO9Spf.js.map +1 -0
- package/dist/admin/assets/{skeleton-Dyi_b1wq.js → skeleton-vXOCdnJv.js} +2 -2
- package/dist/admin/assets/{skeleton-Dyi_b1wq.js.map → skeleton-vXOCdnJv.js.map} +1 -1
- package/dist/admin/assets/slugify-rYFum3Sc.js +2 -0
- package/dist/admin/assets/slugify-rYFum3Sc.js.map +1 -0
- package/dist/admin/assets/snapshots-DUI2t-qF.js +2 -0
- package/dist/admin/assets/snapshots-DUI2t-qF.js.map +1 -0
- package/dist/admin/assets/{sparkles-DCRAqbqD.js → sparkles-CvT-jxrW.js} +2 -2
- package/dist/admin/assets/{sparkles-DCRAqbqD.js.map → sparkles-CvT-jxrW.js.map} +1 -1
- package/dist/admin/assets/src-ndgTSYLX.js +7 -0
- package/dist/admin/assets/src-ndgTSYLX.js.map +1 -0
- package/dist/admin/assets/{stableId-iRkUbVIP.js → stableId-BrtQedPy.js} +2 -2
- package/dist/admin/assets/{stableId-iRkUbVIP.js.map → stableId-BrtQedPy.js.map} +1 -1
- package/dist/admin/assets/store-CdIFG90N.js +2 -0
- package/dist/admin/assets/{store-DknnssoQ.js.map → store-CdIFG90N.js.map} +1 -1
- package/dist/admin/assets/{switch-C3dDDUIk.js → switch-B1xClhNG.js} +2 -2
- package/dist/admin/assets/{switch-C3dDDUIk.js.map → switch-B1xClhNG.js.map} +1 -1
- package/dist/admin/assets/theme-65PB8uAu.js +2 -0
- package/dist/admin/assets/{theme-DPe080iG.js.map → theme-65PB8uAu.js.map} +1 -1
- package/dist/admin/assets/titles-CQiqqDw-.js +2 -0
- package/dist/admin/assets/titles-CQiqqDw-.js.map +1 -0
- package/dist/admin/assets/tokens-ixHjAkDK.js +2 -0
- package/dist/admin/assets/{tokens-BlIDIMY9.js.map → tokens-ixHjAkDK.js.map} +1 -1
- package/dist/admin/assets/{tooltip-BEaZkRPK.js → tooltip-CS_8cJu2.js} +2 -2
- package/dist/admin/assets/{tooltip-BEaZkRPK.js.map → tooltip-CS_8cJu2.js.map} +1 -1
- package/dist/admin/assets/{undo-2-Zd1OT6qk.js → undo-2-BiTANHFz.js} +2 -2
- package/dist/admin/assets/{undo-2-Zd1OT6qk.js.map → undo-2-BiTANHFz.js.map} +1 -1
- package/dist/admin/assets/useContentSchema-DtYfhsd2.js +2 -0
- package/dist/admin/assets/{useContentSchema-wLDa2L3f.js.map → useContentSchema-DtYfhsd2.js.map} +1 -1
- package/dist/admin/assets/useCursorPager-0zHjlm-7.js +2 -0
- package/dist/admin/assets/{useCursorPager-Dc-9B67j.js.map → useCursorPager-0zHjlm-7.js.map} +1 -1
- package/dist/admin/assets/useDiscardGuard-CMMJgkI2.js +2 -0
- package/dist/admin/assets/useDiscardGuard-CMMJgkI2.js.map +1 -0
- package/dist/admin/assets/useMediaPickerDialog-xvQ8cofO.js +2 -0
- package/dist/admin/assets/{useMediaPickerDialog-CFN9ZKfe.js.map → useMediaPickerDialog-xvQ8cofO.js.map} +1 -1
- package/dist/admin/assets/useMediaUploader-BVNTeSAU.js +2 -0
- package/dist/admin/assets/{useMediaUploader-B42H_CMG.js.map → useMediaUploader-BVNTeSAU.js.map} +1 -1
- package/dist/admin/assets/useNetworkPermission-Cts98h9d.js +2 -0
- package/dist/admin/assets/{useNetworkPermission-CegwqQXR.js.map → useNetworkPermission-Cts98h9d.js.map} +1 -1
- package/dist/admin/assets/usePaletteItems-DtReWmkd.js +2 -0
- package/dist/admin/assets/{usePaletteItems-B3y2t7Ly.js.map → usePaletteItems-DtReWmkd.js.map} +1 -1
- package/dist/admin/assets/usePlaces-DC47wVeU.js +2 -0
- package/dist/admin/assets/{usePlaces-CAXr-IO9.js.map → usePlaces-DC47wVeU.js.map} +1 -1
- package/dist/admin/assets/useQueries-CirW3Mvp.js +2 -0
- package/dist/admin/assets/{useQueries-CX6eFr24.js.map → useQueries-CirW3Mvp.js.map} +1 -1
- package/dist/admin/assets/{useResolvedScheme-aV0QDPi3.js → useResolvedScheme-CScQpr-P.js} +2 -2
- package/dist/admin/assets/{useResolvedScheme-aV0QDPi3.js.map → useResolvedScheme-CScQpr-P.js.map} +1 -1
- package/dist/admin/assets/{useSchemaScopeAccess-DyfiZnzs.js → useSchemaScopeAccess-ByrxIdKM.js} +2 -2
- package/dist/admin/assets/{useSchemaScopeAccess-DyfiZnzs.js.map → useSchemaScopeAccess-ByrxIdKM.js.map} +1 -1
- package/dist/admin/assets/users-2iJYwlJb.js +2 -0
- package/dist/admin/assets/users-2iJYwlJb.js.map +1 -0
- package/dist/admin/assets/{users-ohHZnBJW.js → users-DM7CXUBJ.js} +2 -2
- package/dist/admin/assets/{users-ohHZnBJW.js.map → users-DM7CXUBJ.js.map} +1 -1
- package/dist/admin/assets/{zod-C-k48Hnc.js → zod-hUh5nXnX.js} +2 -2
- package/dist/admin/assets/{zod-C-k48Hnc.js.map → zod-hUh5nXnX.js.map} +1 -1
- package/dist/admin/index.html +59 -60
- package/dist/cli.js +10 -5689
- package/dist/cli.js.map +1 -1
- package/dist/cliMain-D08HeAd_.js +5771 -0
- package/dist/cliMain-D08HeAd_.js.map +1 -0
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -38
- package/dist/contentDisposition-DOL2Xt0l.js +90 -0
- package/dist/contentDisposition-DOL2Xt0l.js.map +1 -0
- package/dist/index.d.ts +30 -8
- package/dist/index.js +2 -2
- package/dist/public-B57h4F7Y.js +39 -0
- package/dist/public-B57h4F7Y.js.map +1 -0
- package/dist/{public-BO_wneBL.d.ts → public-COKbHR-N.d.ts} +47 -3
- package/dist/{s3Adapter-sL1zP4Zl.js → s3Adapter-U01iEAcK.js} +2 -2
- package/dist/{s3Adapter-sL1zP4Zl.js.map → s3Adapter-U01iEAcK.js.map} +1 -1
- package/dist/{worker-DMES6pqh.js → worker-jspgh10V.js} +6384 -4527
- package/dist/worker-jspgh10V.js.map +1 -0
- package/package.json +5 -5
- package/dist/admin/assets/AssistError-drmpXSbS.js +0 -2
- package/dist/admin/assets/Body-Gn_z2KPN.js +0 -2
- package/dist/admin/assets/Builder-DyCcikfS.js +0 -2
- package/dist/admin/assets/Builder-DyCcikfS.js.map +0 -1
- package/dist/admin/assets/ConfirmDialog-DZRJfdvH.js +0 -2
- package/dist/admin/assets/ConfirmDialog-DZRJfdvH.js.map +0 -1
- package/dist/admin/assets/Form-DF_YmR1G.js +0 -2
- package/dist/admin/assets/Form-DF_YmR1G.js.map +0 -1
- package/dist/admin/assets/FormCheckboxGroup-V3IKrvzc.js.map +0 -1
- package/dist/admin/assets/InsertMenuItem-D2HGERzb.js +0 -2
- package/dist/admin/assets/InsertMenuItem-D2HGERzb.js.map +0 -1
- package/dist/admin/assets/Panel-B1TkcP8V.js +0 -2
- package/dist/admin/assets/Panel-B1TkcP8V.js.map +0 -1
- package/dist/admin/assets/SecretReveal-kCkLH5jg.js +0 -2
- package/dist/admin/assets/SecretReveal-kCkLH5jg.js.map +0 -1
- package/dist/admin/assets/StepList-BIQjDaWQ.js +0 -2
- package/dist/admin/assets/StepList-BIQjDaWQ.js.map +0 -1
- package/dist/admin/assets/Thumbnail-D1XuDElk.js +0 -2
- package/dist/admin/assets/Thumbnail-D1XuDElk.js.map +0 -1
- package/dist/admin/assets/UnsavedChangesGuard-C1n7egF6.js +0 -2
- package/dist/admin/assets/UnsavedChangesGuard-C1n7egF6.js.map +0 -1
- package/dist/admin/assets/auth-C4fHG9Iu.js +0 -2
- package/dist/admin/assets/auth-C4fHG9Iu.js.map +0 -1
- package/dist/admin/assets/badge-ydvfgE8a.js +0 -2
- package/dist/admin/assets/changeSets-DgfCKja3.js +0 -2
- package/dist/admin/assets/changeSets-DgfCKja3.js.map +0 -1
- package/dist/admin/assets/chevron-left-CZXrLV99.js +0 -2
- package/dist/admin/assets/content-DsMSB6Wb.js +0 -3
- package/dist/admin/assets/content-DsMSB6Wb.js.map +0 -1
- package/dist/admin/assets/contentCounts-DknqJ4kh.js +0 -2
- package/dist/admin/assets/context-fImO9k99.js +0 -2
- package/dist/admin/assets/createLucideIcon-CqygG5K6.js +0 -2
- package/dist/admin/assets/createLucideIcon-CqygG5K6.js.map +0 -1
- package/dist/admin/assets/develop-DL-2W9jv.js +0 -11
- package/dist/admin/assets/develop-DL-2W9jv.js.map +0 -1
- package/dist/admin/assets/es2015-DrAA1N2V.js +0 -42
- package/dist/admin/assets/es2015-DrAA1N2V.js.map +0 -1
- package/dist/admin/assets/followPlural-D-5ZJqJF.js +0 -2
- package/dist/admin/assets/followPlural-D-5ZJqJF.js.map +0 -1
- package/dist/admin/assets/inbox-DUqOrFEA.js +0 -2
- package/dist/admin/assets/inbox-DUqOrFEA.js.map +0 -1
- package/dist/admin/assets/index-BEM45u2w.css +0 -2
- package/dist/admin/assets/index-D03RZB7e.js +0 -4
- package/dist/admin/assets/index-D03RZB7e.js.map +0 -1
- package/dist/admin/assets/loader-circle-C-9trZPI.js +0 -2
- package/dist/admin/assets/loader-circle-C-9trZPI.js.map +0 -1
- package/dist/admin/assets/locales-e7B5t6id.js +0 -2
- package/dist/admin/assets/media-BUUEsWxd.js +0 -2
- package/dist/admin/assets/media-BUUEsWxd.js.map +0 -1
- package/dist/admin/assets/media-VCJUbYzJ.js +0 -2
- package/dist/admin/assets/network-Bolr2lmf.js +0 -2
- package/dist/admin/assets/network-Bolr2lmf.js.map +0 -1
- package/dist/admin/assets/pencil-BVSFlU14.js +0 -2
- package/dist/admin/assets/pencil-BVSFlU14.js.map +0 -1
- package/dist/admin/assets/publishing-ClNjPLQ9.js +0 -2
- package/dist/admin/assets/schedules-CBGpjEg7.js +0 -2
- package/dist/admin/assets/schema-D9BgCVzZ.js +0 -2
- package/dist/admin/assets/schema-D9BgCVzZ.js.map +0 -1
- package/dist/admin/assets/searchSchemas-C4qp-vCa.js +0 -2
- package/dist/admin/assets/sections-C7Z6Xd8r.js +0 -2
- package/dist/admin/assets/seo-l1ZORjtv.js +0 -2
- package/dist/admin/assets/settings-DgoG3H8C.js +0 -2
- package/dist/admin/assets/settings-DgoG3H8C.js.map +0 -1
- package/dist/admin/assets/settle-LRKtTN_e.js +0 -2
- package/dist/admin/assets/settle-LRKtTN_e.js.map +0 -1
- package/dist/admin/assets/shapes-BZ87ap5s.js +0 -6
- package/dist/admin/assets/shapes-BZ87ap5s.js.map +0 -1
- package/dist/admin/assets/snapshots-CT-zs6Up.js +0 -2
- package/dist/admin/assets/snapshots-CT-zs6Up.js.map +0 -1
- package/dist/admin/assets/src-BcLeD2-K.js +0 -7
- package/dist/admin/assets/src-BcLeD2-K.js.map +0 -1
- package/dist/admin/assets/store-DknnssoQ.js +0 -2
- package/dist/admin/assets/theme-DPe080iG.js +0 -2
- package/dist/admin/assets/titles-C5PaMgFJ.js +0 -2
- package/dist/admin/assets/titles-C5PaMgFJ.js.map +0 -1
- package/dist/admin/assets/tokens-BlIDIMY9.js +0 -2
- package/dist/admin/assets/useAuditLabels-DWBpLOTB.js +0 -2
- package/dist/admin/assets/useAuditLabels-DWBpLOTB.js.map +0 -1
- package/dist/admin/assets/useContentSchema-wLDa2L3f.js +0 -2
- package/dist/admin/assets/useCursorPager-Dc-9B67j.js +0 -2
- package/dist/admin/assets/useDiscardGuard-WTUINqD5.js +0 -2
- package/dist/admin/assets/useDiscardGuard-WTUINqD5.js.map +0 -1
- package/dist/admin/assets/useMediaPickerDialog-CFN9ZKfe.js +0 -2
- package/dist/admin/assets/useMediaUploader-B42H_CMG.js +0 -2
- package/dist/admin/assets/useNetworkPermission-CegwqQXR.js +0 -2
- package/dist/admin/assets/usePaletteItems-B3y2t7Ly.js +0 -2
- package/dist/admin/assets/usePlaces-CAXr-IO9.js +0 -2
- package/dist/admin/assets/useQueries-CX6eFr24.js +0 -2
- package/dist/admin/assets/users-CDoJRL24.js +0 -2
- package/dist/admin/assets/users-CDoJRL24.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/worker-DMES6pqh.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":";ysHASA,IAAMA,GAAa,CACjB,KAAM,aACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,SAAU,IAAK,QAAS,CAAC,EACvC,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,IAAK,EAAG,IAAK,MAAO,KAAM,OAAQ,KAAM,GAAI,IAAK,IAAK,OAAQ,CAAC,EAC7E,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAS,CAAC,EAC3C,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAS,CAAC,CAC7C,CACF,EACAA,GAAW,KACX,IAAMC,GAAYC,EAAiBF,EAAU,ECbvCA,GAAa,CACjB,KAAM,YACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,iHACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAS,CAAC,EACxD,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,kDAAmD,IAAK,QAAS,CAAC,CAClF,CACF,EACAA,GAAW,KACX,IAAMG,GAAWD,EAAiBF,EAAU,EClBtCA,GAAa,CACjB,KAAM,cACN,KAAM,GACN,KAAM,CACJ,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,EACxD,CAAC,SAAU,CAAE,GAAI,IAAK,GAAI,IAAK,EAAG,IAAK,IAAK,QAAS,CAAC,EACtD,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAS,CAAC,EACxD,CAAC,OAAQ,CAAE,EAAG,2BAA4B,IAAK,QAAS,CAAC,CAC3D,CACF,EACAA,GAAW,KACX,IAAMI,GAAaF,EAAiBF,EAAU,ECXxCA,GAAa,CACjB,KAAM,YACN,KAAM,GACN,KAAM,CACJ,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,EACxD,CAAC,SAAU,CAAE,GAAI,IAAK,GAAI,IAAK,EAAG,IAAK,IAAK,QAAS,CAAC,EACtD,CAAC,OAAQ,CAAE,EAAG,wBAAyB,IAAK,QAAS,CAAC,CACxD,CACF,EACAA,GAAW,KACX,IAAMK,GAAWH,EAAiBF,EAAU,ECVtCA,GAAa,CACjB,KAAM,UACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,2HACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,WAAY,CAAE,OAAQ,uBAAwB,IAAK,QAAS,CAAC,EAC9D,CAAC,OAAQ,CAAE,EAAG,mBAAoB,IAAK,QAAS,CAAC,CACnD,CACF,EACAA,GAAW,KACX,IAAMM,GAAUJ,EAAiBF,EAAU,ECjBrCA,GAAa,CACjB,KAAM,MACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CACE,OACA,CACE,EAAG,6MACH,IAAK,QACP,CACF,CACF,CACF,EACAA,GAAW,KACX,IAAMO,GAAML,EAAiBF,EAAU,ECfjCA,GAAa,CACjB,KAAM,SACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,gdACH,IAAK,QACP,CACF,CACF,CACF,EACAA,GAAW,KACX,IAAMQ,GAASN,EAAiBF,EAAU,ECdpCA,GAAa,CACjB,KAAM,QACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,kCAAmC,IAAK,QAAS,CAAC,EAChE,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAS,CAAC,EACnE,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAS,CAAC,EACnE,CAAC,OAAQ,CAAE,EAAG,kCAAmC,IAAK,QAAS,CAAC,EAChE,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAS,CAAC,CAC1D,CACF,EACAA,GAAW,KACX,IAAMS,GAAQP,EAAiBF,EAAU,ECZnCA,GAAa,CACjB,KAAM,WACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,QAAS,CAAC,EAC5E,CAAC,OAAQ,CAAE,EAAG,0BAA2B,IAAK,QAAS,CAAC,EACxD,CAAC,OAAQ,CAAE,MAAO,IAAK,OAAQ,IAAK,EAAG,KAAM,EAAG,KAAM,GAAI,IAAK,IAAK,QAAS,CAAC,CAChF,CACF,EACAA,GAAW,KACX,IAAMU,GAAWR,EAAiBF,EAAU,ECiBtCW,IAAsB,EAAkB,IAC5CC,EAAO,UAAYC,EAAK,SAAWD,EAAO,OAASC,EAAK,KAEpDC,IACJ,EACA,EACA,IAEID,GAAQE,EAAM,OAASF,EAAK,KACvB,CAAE,OAAQ,OAAQ,OAAQ,kBAAmB,EAEjDD,EAGDA,EAAO,OAASG,EAAM,KACjB,CAAE,OAAQ,OAAQ,OAAQ,gBAAiB,EAE/CF,EAGEF,GAAmBC,EAAQC,CAAI,EAClC,CAAE,OAAQ,SAAU,gBAAiBD,EAAO,OAAQ,EACpD,CAAE,OAAQ,WAAY,OAAQ,eAAgB,EAJzC,CAAE,OAAQ,WAAY,OAAQ,gBAAiB,EAN/CC,EAAO,CAAE,OAAQ,WAAY,OAAQ,iBAAkB,EAAI,CAAE,OAAQ,QAAS,EAa5EG,IAAc,CAAE,QAAO,OAAM,SAAQ,WAC5CD,EACKD,GAAeC,EAAOF,EAAMD,CAAM,EAEtCC,EAGAD,EAGAK,EAGEN,GAAmBC,EAAQC,CAAI,EAClC,CAAE,OAAQ,SAAU,gBAAiBD,EAAO,OAAQ,EACpD,CAAE,OAAQ,WAAY,OAAQ,6BAA8B,EAJvD,CAAE,OAAQ,OAAQ,OAAQ,4BAA6B,EAHvD,CAAE,OAAQ,OAAQ,OAAQ,gBAAiB,EAH3C,CAAE,OAAQ,OAAQ,OAAQ,YAAa,aC9D5CM,GAAS,CAAE,OAAQ,EAAK,EAGxBC,GAAa,CACjB,QAAS,yBACT,WAAY,uBACZ,WAAY,wBACd,EAyBMC,GAAW,CACf,QAAS,CAAC,GAAGC,EAAU,OAAO,IAAK,OAAQ,SAAS,EACpD,WAAY,CAAC,GAAGA,EAAU,OAAO,IAAK,OAAQ,YAAY,EAC1D,WAAY,CAAC,UAAW,mBAAmB,CAC7C,EAEaC,OACXC,EAAS,CACP,SAAUH,GAAS,QACnB,YAAeI,GAAU,QAAyBL,GAAW,OAAO,EACpE,KAAMD,EACR,CAAC,EAKUO,OACXF,EAAS,CACP,SAAUH,GAAS,WACnB,YAAeI,GAAU,QAAgCL,GAAW,UAAU,EAC9E,KAAMD,EACR,CAAC,EAGUQ,OAA6B,IAAI,IAAIP,GAAW,WAAYQ,GAAW,CAAC,CAAC,CAAC,KAG1EC,OACXL,EAAS,CACP,SAAUH,GAAS,WACnB,QAAS,UAEA,MADgB,MAAMM,GAAqB,EAAG,CAAE,OAAQ,OAAQ,YAAa,aAAc,CAAC,GACnF,GAElB,UAAW,IACX,KAAMR,EACR,CAAC,aCxDUW,GAAa,CAAE,OAAM,QAAO,WAAW,GAAM,gBACxD,EAAAC,EAAA,MAAC,MAAD,CAAK,UAAWC,EAAG,oBAAqBC,CAAS,EAAjD,WACE,EAAAF,EAAA,MAAC,MAAD,CAAK,UAAU,kDAAf,WACE,EAAAA,EAAA,KAAC,OAAD,CAAM,UAAU,sEAAuE,SAAAG,CAAY,GAClGC,GAAW,EAAAJ,EAAA,KAACK,GAAD,CAAY,MAAOC,CAAO,GAAI,IACvC,CACL,MAAAN,EAAA,KAAC,MAAD,CACE,KAAK,SACL,aAAYG,EACZ,SAAU,EACV,UAAU,0KAEV,YAAAH,EAAA,KAAC,OAAD,UAAOM,CAAW,EACf,EACF,ICRMC,GAA4B,CACvC,GAAI,GACJ,OAAQ,GACR,SAAU,GACV,OAAQ,GACR,SAAU,GACV,KAAM,GACN,KAAM,GACN,SAAU,GACV,EAAG,GACH,QAAS,CAAC,CACZ,EAEMC,GAAgB,CAAC,SAAU,WAAY,SAAU,WAAY,OAAQ,OAAQ,WAAY,GAAG,EAGrFC,GAAmB,GAKvB,UAJOC,EACX,QAAQ,WAAY,EAAE,CAAC,CACvB,MAAM,SAAS,CAAC,CAChB,OAAQ,GAASC,IAAS,EACZ,EAAM,IAAK,GAAS,IAAIA,EAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAI9CC,IAAe,EAA8B,IAAgC,CACxF,IAAMC,EAAOC,EAAU,KAAK,QAAQ,OAAQC,EAAM,GAAG,KAAK,EAAI,mBAAmBA,EAAM,GAAG,KAAK,CAAC,EAAI,MAAM,EACpGC,EAAQ,IAAI,gBAClB,IAAK,IAAMC,KAAQT,GAAe,CAChC,IAAMU,EAAQH,EAAME,EAAK,CAAC,KAAK,EAC3BC,GAASJ,EAAU,WAAW,KAAM,GAAcK,EAAU,OAASF,CAAI,GAC3ED,EAAM,OAAOC,EAAMC,CAAK,CAE5B,CACA,GAAIJ,EAAU,KACP,QAAMM,KAAOL,EAAM,QAClBK,EAAI,IAAI,KAAK,GAAKA,EAAI,QAAU,IAClCJ,EAAM,OAAOP,GAAgBW,EAAI,IAAI,KAAK,CAAC,EAAGA,EAAI,KAAK,EAI7D,IAAMC,EAASL,EAAM,SAAS,EAC9B,OAAOK,EAAS,GAAGR,EAAK,GAAGQ,IAAWR,CACxC,EAEaS,IAAc,EAA8B,IACvD,CAACR,EAAU,MAAQC,EAAM,GAAG,KAAK,IAAM,GAEnCQ,GAAoB,gBAEbC,IAAe,EAAa,IACvC,CAAC,SAASC,EAAI,QAAQ,KAAM,OAAO,EAAE,GAAI,iCAAiC,CAAC,CACxE,OAAOC,EAAY,CAAC,+BAA+BH,GAAkB,EAAE,EAAI,CAAC,CAAC,CAAC,CAC9E,KAAK;CAAO,EAEJI,IAAgB,EAAa,IAA+B,CACvE,IAAMC,EAAUF,EACZ;;;KACA,iCACJ,MAAO,gCAAgC,KAAK,UAAUD,CAAG,EAAE,kBAAkBG,EAAQ,wDACvF,EClEaC,GAA2B,WAE3BC,GAAqB,GAA+C,CAC/E,IAAMC,EAAS,CACb,GAAI,GAAGF,KAA2BG,EAAM,SACxC,KAAMA,EAAM,OACZ,QAASA,EAAM,GACf,KAAM,EACR,EACA,GAAIA,EAAM,OAAS,aACjB,MAAO,CAACD,CAAM,EAEhB,IAAME,EAAWC,GAAoBF,CAAK,EAC1C,MAAO,CACL,CAAE,GAAI,GAAGH,KAA2BI,IAAY,KAAMA,EAAU,QAASD,EAAM,GAAI,KAAM,EAAK,EAC9FD,CACF,CACF,EAGaI,IACX,EACA,EACA,IAEAC,EAAe,KACZ,GACCC,EAAU,WAAaC,EAAWN,CAAK,IACtClB,EAAU,KAAOuB,EAAU,KAAOL,EAAM,OAAS,aAAeK,EAAU,KAAO,CAACA,EAAU,KACjG,EAMWE,IACX,EACA,EACA,EACA,IACuB,CACvB,GAAIC,IAAW,UAAW,CACxB,IAAMC,EAAOL,EAAe,KAAM,GAAcC,EAAU,KAAOK,CAAW,EACtEV,EAAQS,GAAQE,EAAO,KAAM,GAAcL,EAAWD,CAAS,IAAMI,EAAK,QAAQ,EACxF,OAAOT,GAASF,GAAkBE,CAAK,CAAC,CAAC,KAAM,GAAcK,EAAU,OAASI,EAAK,IAAI,CAAC,EAAE,EAC9F,CACA,IAAK,IAAMT,KAASW,EAAQ,CAC1B,IAAM7B,EAAYgB,GAAkBE,CAAK,CAAC,CAAC,KAAM,GAAcK,EAAU,KAAOK,CAAW,EAC3F,GAAI5B,EACF,OAAOqB,GAAiBH,EAAOlB,EAAWsB,CAAc,CAAC,EAAE,EAE/D,CAEF,EAEMQ,GAAe,GAAmC,CACtD,OAAQC,EAAM,KAAd,CACE,IAAK,WACH,MAAO,GAAGA,EAAM,OAAO,WACzB,IAAK,QACH,MAAO,GAAGA,EAAM,OAAO,cACzB,IAAK,WACH,MAAO,GAAGA,EAAM,OAAO,SACzB,IAAK,YACL,IAAK,cACH,MAAO,GAAGA,EAAM,OAAO,iBACzB,QACE,OAAOA,EAAM,MACjB,CACF,EAEMC,GAAa,GACjB5B,EACG,MAAM,GAAG,CAAC,CACV,IAAK,GAAS6B,EAAK,KAAK,CAAC,CAAC,CAC1B,OAAQ,GAASA,IAAS,EAAE,EAE3BC,GAAS,kBACTC,GAAU,QACVC,GAAoB,IAAI,IAAI,CAAC,KAAM,YAAa,WAAW,CAAC,EAC5DC,GAAY,IAAI,IAAI,CACxB,MACA,MACA,MACA,OACA,MACA,OACA,MACA,OACA,YACA,eACA,aACA,cACA,YACA,QACA,UACF,CAAC,EACKC,GAAiB,IAAI,IAAI,CAAC,MAAO,MAAM,CAAC,EACxCC,GAAoB,IAAI,IAAI,CAAC,QAAS,UAAU,CAAC,EAEjDC,GAAiB,GAAgBC,IAAQ,QAAUA,IAAQ,QAG3DC,IAAW,EAAoC,KAC9CX,GAAO,OAAS,UAAYA,GAAO,OAAS,YAAcG,GAAO,KAAKO,CAAG,GAG1EV,GAAO,OAAS,WAAaS,GAAcC,CAAG,EACzCA,EAEF,KAAK,UAAUA,CAAG,EAUdE,GAAkB,GAAuC,CAEpE,GAAM,CAACxC,EAAMyC,EAAW,MAAOC,EAAO,GAAGlB,GAD3B,CAAC,GAAGhC,GAAgBC,CAAG,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,CAAC,IAAK,GAAUkD,EAAM,IAAM,EAC5C,EACjD,GAAI,GAAC3C,GAAQA,EAAK,WAAW,GAAG,GAAK,CAACkC,GAAU,IAAIO,CAAQ,GAAKjB,EAAK,OAAS,KAG3EkB,IAAU,QAAeP,GAAe,IAAIM,CAAQ,GAAKT,GAAQ,KAAKU,CAAK,GAG/E,MAAO,CAAE,OAAM,UAAS,CAC1B,EAIME,IAAa,EAAkB,CAAE,QAAO,YAAgC,CAC5E,GAAIR,GAAkB,IAAIK,CAAQ,EAAG,CACnC,IAAMxC,EAAQ4C,EAAO,GAAG,EAAE,GAAK,GAC/B,OAAOR,GAAcpC,CAAK,EAAIA,EAAQ,KAAK,UAAUA,CAAK,CAC5D,CAIA,OAHIkC,GAAe,IAAIM,CAAQ,EACtB,IAAII,EAAO,IAAK,GAAUN,GAAQX,EAAO3B,CAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,GAE9DsC,GAAQX,EAAOiB,EAAO,GAAG,EAAE,GAAK,EAAE,CAC3C,EAGMC,IACJ,EACA,IACwD,CACxD,IAAMC,EAAS,IAAI,IACjBhC,EAAM,OAAO,OAAQ,GAAU,CAACa,EAAM,UAAU,CAAC,CAAC,IAAK,GAAU,CAACA,EAAM,OAAQA,CAAK,CAAC,CACxF,EACMoB,EAAa,IAAI,IACjBC,EAAoB,CAAC,EAC3B,IAAK,IAAM9C,KAAOL,EAAM,QAAS,CAC/B,IAAML,EAAMU,EAAI,IAAI,KAAK,EACzB,GAAI,CAACV,GAAOU,EAAI,QAAU,GACxB,SAEF,IAAM+C,EAASV,GAAe/C,CAAG,EAC3BmC,EAAQsB,EAASH,EAAO,IAAIG,EAAO,IAAI,EAAI,OACjD,GAAI,CAACA,GAAW,CAACtB,GAAS,CAACK,GAAkB,IAAIiB,EAAO,IAAI,EAAI,CAC9DD,EAAQ,KAAKzD,GAAgBC,CAAG,CAAC,EACjC,QACF,CACA,IAAM0D,EAAaH,EAAW,IAAIE,EAAO,IAAI,GAAK,IAAI,IACtDF,EAAW,IAAIE,EAAO,KAAMC,CAAU,EACtC,IAAMN,EAASV,GAAe,IAAIe,EAAO,QAAQ,EAAIrB,GAAU1B,EAAI,KAAK,EAAI,CAACA,EAAI,KAAK,EAChFiD,EAAWD,EAAW,IAAID,EAAO,QAAQ,EAC/CC,EAAW,IAAID,EAAO,SAAU,CAC9B,QACA,OAAQE,GAAYjB,GAAe,IAAIe,EAAO,QAAQ,EAAI,CAAC,GAAGE,EAAS,OAAQ,GAAGP,CAAM,EAAIA,CAC9F,CAAC,CACH,CAUA,OATIG,EAAW,OAAS,EACf,CAAE,SAAU,OAAW,SAAQ,EAQjC,CAAE,SAAU,KANH,CAAC,GAAGA,CAAU,CAAC,CAAC,KAAK,CAAChD,EAAMmD,KAInC,GAAGnD,EAAK,MAHE,CAAC,GAAGmD,CAAU,CAAC,CAAC,KAC9B,CAACV,EAAUY,KAAe,GAAGZ,EAAS,MAAM,CAAC,EAAE,IAAIG,GAAUH,EAAUY,CAAS,GAE9D,EAAS,KAAK,IAAI,EAAE,GAEnB,EAAQ,KAAK,IAAI,EAAE,IAAK,SAAQ,CAC1D,EAGMC,IAAgB,EAAwB,IAAqC,CACjF,IAAMC,EAAS,GACbtB,GAAkB,IAAIjC,CAAI,GAAKe,EAAM,OAAO,KAAM,GAAU,CAACa,EAAM,YAAcA,EAAM,SAAW5B,CAAI,EAClGwD,EAAQ3B,GAAU4B,CAAI,CAAC,CAAC,IAAK,GAAS,CAC1C,GAAM,CAACzD,EAAO,GAAI0D,EAAY,MAAOC,GAAS7B,EAAK,MAAM,GAAG,EAC5D,OAAO6B,IAAU,QAAaJ,EAAMvD,CAAI,IAAM0D,IAAc,OAASA,IAAc,QAC/E,KAAK1D,EAAK,IAAI0D,EAAU,YAAY,EAAE,IACtC,MACN,CAAC,EACD,OAAOF,EAAM,OAAS,GAAKA,EAAM,MAAO,GAAS1B,IAAS,MAAS,EAAI,IAAI0B,EAAM,KAAK,IAAI,EAAE,GAAK,MACnG,EAGMI,IAAkB,EAAwB,IAA2C,CACzF,IAAMC,EAAO9C,EAAM,OAAO,OAAQ,GAAU,CAACa,EAAM,UAAU,EACvDkC,EAAQ,IAAI,IAAIjC,GAAU/B,EAAM,MAAM,CAAC,EACvCiE,EAASF,EAAK,OAAQ,GAAUC,EAAM,IAAIlC,EAAM,MAAM,CAAC,EAC7D,OAAOmC,EAAO,OAAS,EAAIA,EAASF,CACtC,EAEMG,IAAa,EAAoC,IACrD,CAAC,KAAM,GAAGjB,EAAO,IAAIpB,EAAW,CAAC,CAAC,CAAC,IAAK,GAAS,GAAGsC,IAASC,GAAM,CAAC,CAAC,KAAK;CAAI,EAE1EC,GAAiB,GAAiD,CACtE,IAAMC,EAAgC,CAAC,EAOvC,OANItE,EAAM,OAAO,KAAK,GACpBsE,EAAK,KAAK,CAAC,SAAU,KAAK,UAAUtE,EAAM,OAAO,KAAK,CAAC,CAAC,CAAC,EAEvDkC,GAAQ,KAAKlC,EAAM,SAAS,KAAK,CAAC,GACpCsE,EAAK,KAAK,CAAC,WAAYtE,EAAM,SAAS,KAAK,CAAC,CAAC,EAExCsE,CACT,EAEMC,IAAiB,EAAwB,EAAqB,IAAsB,CACxF,IAAMD,EAAgC,CAAC,EACjCE,EAASxB,GAAe/B,EAAOjB,CAAK,EAK1C,GAJAmD,EAAQ,KAAK,GAAGqB,EAAO,OAAO,EAC1BA,EAAO,UACTF,EAAK,KAAK,CAAC,SAAUE,EAAO,QAAQ,CAAC,EAEnCxE,EAAM,KAAK,KAAK,EAAG,CACrB,IAAM2D,EAAOH,GAAavC,EAAOjB,EAAM,IAAI,EACvC2D,EACFW,EAAK,KAAK,CAAC,OAAQX,CAAI,CAAC,EAExBR,EAAQ,KAAK,MAAM,CAEvB,CACInD,EAAM,EAAE,KAAK,GACfsE,EAAK,KAAK,CAAC,SAAU,KAAK,UAAUtE,EAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAEtD,IAAK,IAAME,IAAQ,CAAC,OAAQ,UAAU,EAChCgC,GAAQ,KAAKlC,EAAME,EAAK,CAAC,KAAK,CAAC,GACjCoE,EAAK,KAAK,CAACpE,EAAMF,EAAME,EAAK,CAAC,KAAK,CAAC,CAAC,EAGxC,OAAOoE,CACT,EAEMG,IAAQ,EAAc,IAC1BH,EAAK,SAAW,EAAIpE,EAAO,GAAGA,EAAK,GAAGoE,EAAK,KAAK,CAAC3E,EAAKQ,KAAW,GAAGR,EAAI,IAAIQ,GAAO,CAAC,CAAC,KAAK,IAAI,EAAE,GAGrFuE,IACX,EACA,EACA,IACiB,CACjB,IAAMvB,EAAoB,CAAC,EACvBnD,EAAM,SAAS,KAAK,GAEtBmD,EAAQ,KAAK,UAAU,EAEzB,IAAMF,EAASa,GAAe7C,EAAOjB,CAAK,EAC1C,GAAID,EAAU,KAAM,CAClB,IAAMuE,EAAO,CAAC,GAAGC,GAActD,EAAOjB,EAAOmD,CAAO,EAAG,GAAGkB,GAAcrE,CAAK,CAAC,EAE9E,MAAO,CAAE,MAAO,YAAY,KADVyE,GAAK1E,EAAU,KAAMuE,CAAI,EAAE,mCAAmCJ,GAAUjB,EAAQ,QAAQ,EAAE,cAC3E,OAAQ,SAAQ,CACnD,CACA,IAAM0B,EAAK3E,EAAM,GAAG,KAAK,EACnB4E,EAAO3D,EAAM,OAAS,aACtBqD,EAAgC,CACpC,GAAIM,EAAO,CAAC,CAAC,KAAMD,EAAK,KAAK,UAAUA,CAAE,EAAI,KAAK,CAAqB,EAAI,CAAC,EAC5E,GAAGN,GAAcrE,CAAK,CACxB,EAGA,MAAO,CAAE,MAAO,GAFD4E,GAAQ,CAACD,EAAK,qBAAuB,UAE1B,IAAI,KADZF,GAAK1E,EAAU,KAAMuE,CAAI,EAAE,MAAMJ,GAAUjB,EAAQ,MAAM,EAAE,OAC1C,OAAQ,SAAQ,CACrD,EC1Qa4B,IAAc,CAAE,WAAU,iBAAgB,aAA+B,CACpF,GAAM,CAAE,KAAMC,EAAe,EACvB,CAAE,eAAgBC,GAAkB,EACpCC,GAAA,EAASC,gBAEVC,GAAe,CAAC,GACd,KAAK,CAAE,gBAAiBC,CAAU,CAAC,CACnC,OAAOC,CAAiB,CAAC,CACzB,MAAM,EAAG,IAAMC,EAAE,MAAM,cAAcC,EAAE,KAAK,CAAC,CAAC,CAC9C,IAAK,IAA4B,CAAE,QAAO,WAAYvE,GAAkBE,CAAK,CAAE,EAAE,EACtF,CAACiE,CAAW,CACd,EACMK,GAAA,EAAQN,eACND,EAAO,SAAS,CAAE,QAAO,gBAAiBQ,EAAW,IAAK,IAAe,CAAE,QAAO,WAAU,EAAE,CAAC,EACrG,CAACR,CAAM,CACT,EACMS,EAAUF,EAAM,KAAM,GAASG,EAAK,UAAU,KAAOC,CAAQ,GAAKJ,EAAM,GACxEK,GAAA,EAAQX,eAAc,CAC1B,GAAI,CAACQ,EACH,OAEF,IAAM/D,EAAON,GAAiBqE,EAAQ,MAAOA,EAAQ,UAAWpE,CAAc,EAC9E,OAAOqD,GAAae,EAAQ,MAAOA,EAAQ,UAAWI,EAAQnE,GAAM,EAAE,CAAC,CACzE,EAAG,CAAC+D,EAASpE,EAAgBwE,CAAO,CAAC,EACrC,OACE,EAAA5G,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,UACG+F,EAAO,OAAS,GACf,EAAA/F,EAAA,KAAC6G,GAAD,CAAQ,MAAOC,EAAE,gCAAgC,EAC9C,SAAAf,EAAO,KAAK,CAAE,QAAO,iBACpB,EAAA/F,EAAA,KAAC+G,GAAD,CAA4B,MAAO/E,EAAM,MACtC,SAAAuE,EAAW,IAAK,IACf,EAAAvG,EAAA,KAACgH,GAAD,CAEE,GAAG,gBACH,OAAQ,CAAE,IAAK,UAAW,GAAI3E,EAAU,EAAG,EAC3C,eAAcA,EAAU,KAAOmE,GAAS,UAAU,GAAK,OAAS,OAEhE,YAAAxG,EAAA,KAAC,OAAD,CAAM,UAAU,qCAAsC,SAAAqC,EAAU,IAAW,EACjE,EANLA,EAAU,EAML,CACb,CACU,EAXKL,EAAM,EAWX,CACd,CACK,GACN,MACJ,EAAAhC,EAAA,KAAC,MAAD,CAAK,UAAU,iBACZ,SAAAwG,GAAWG,GACV,EAAA3G,EAAA,KAACiH,EAAD,CACE,MAAOH,EAAE,8BAA+B,CAAE,KAAMN,EAAQ,UAAU,IAAK,CAAC,EACxE,YACEG,EAAM,QAAQ,OAAS,EACnBG,EAAE,8BAA+B,CAAE,OAAQH,EAAM,QAAQ,KAAK,IAAI,CAAE,CAAC,EACrEG,EAAE,8BAA8B,EAEtC,SACE,EAAA9G,EAAA,KAACkH,EAAD,CAAQ,WAAQ,QAAQ,UAAU,KAAK,KACrC,YAAAlH,EAAA,MAACmH,EAAD,CAAM,GAAG,mBAAmB,OAAQ,CAAE,MAAOR,EAAM,KAAM,EAAzD,WACE,EAAA3G,EAAA,KAACoH,GAAD,CAAQ,cAAY,MAAQ,GAC3BN,EAAE,sCAAsC,CACrC,GACA,GAGV,YAAA9G,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,2BAA2B,EAAG,KAAMH,EAAM,KAAQ,EACjE,GACL,IACD,EACF,GAET,ECzFaU,GAAkB,gBAkBlBC,GAAsB,GACjC,OAAO,QAAQC,EAAS,KAAK,CAAC,CAAC,SAAS,CAAC1G,EAAM2G,KAAa,CAC1D,IAAM1G,EAAY0G,EAAQ,IAC1B,GAAI,CAAC3G,EAAK,0BAA0B,GAAK,CAACC,GAAW,YACnD,MAAO,CAAC,EAEV,IAAM2G,EAAa3G,EAAU,YAAc,CAAC,EAC5C,MAAO,CACL,CACE,GAAIA,EAAU,YACd,OACA,QAASA,EAAU,SAAWD,EAC9B,IAAKC,EAAU,OAAO,IAAM,GAC5B,SAAUD,EAAK,MAAM,EAAsB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAM,GAC9D,KAAMA,EAAK,SAAS,MAAM,EAC1B,KAAM4G,EAAW,KAAM,GAActG,EAAU,OAAS,SAAS,EACjE,YACF,CACF,CACF,CAAC,EAGUuG,IACX,EACA,IACqB,CACrB,IAAMC,GAASJ,EAAS,MAAQ,CAAC,GAAG,IAAK,GAAQK,EAAI,IAAI,EAEzD,MAAO,CADO,GAAG,IAAI,IAAI,CAAC,GAAGD,EAAO,GAAGpB,EAAW,IAAK,GAAczF,EAAU,GAAG,CAAC,CAAC,CAC7E,EACJ,IAAK,IAAS,CAAE,MAAK,WAAYyF,EAAW,OAAQ,GAAczF,EAAU,MAAQ8G,CAAG,CAAE,EAAE,CAAC,CAC5F,OAAQ,GAAUC,EAAM,WAAW,OAAS,CAAC,CAClD,EAEaC,IAAgB,EAA8B,IACzDhH,EAAU,WAAW,KAAM,GAAcK,EAAU,OAASF,CAAI,EClDrD8G,OAAyB,CACpC,GAAM,CAACC,EAAQC,IAAA,EAAaC,YAAiD,CAAC,CAAC,EAQ/E,MAAO,CAAE,WAPOC,eACb,GAAqCzF,GAAesF,EAAOtF,IAAiBnC,GAC7E,CAACyH,CAAM,CAKA,EAAS,YAHDG,gBAAa,EAAqB,IAAuB,CACxEF,EAAW,IAAa,CAAE,GAAGzB,GAAU9D,GAAc0F,CAAK,EAAE,CAC9D,EAAG,CAAC,CACc,CAAS,CAC7B,ECXMC,GAAQC,GAAY,mBAAmB,EAMhCC,IACX,EACA,IACG,CACH,IAAMC,EAAWH,GAAM,YAAY,EAC7B,CAAE,eAAgBvC,GAAkB,EAC1C,MAAQ,IAAqB,CAE3B,IAAM2C,EAAKlG,GAAuBmG,EAAKhG,GADvBuD,GAAe,CAAC,GAAG,KAAK,CAAE,gBAAiBC,CAAU,CAAC,CAAC,OAAOC,CAC1B,EAAQ/D,CAAc,EAC1EoG,EAAc,CAAE,OAAQ,CAAE,MAAK,GAAIC,EAAK,CAAE,IAAG,EAAI,CAAC,CAAG,EAAG,QAAS,EAAK,CAAC,CACzE,CACF,ECrBaE,OAA2B,CACtC,IAAMC,EAAOC,GAAM,CAAC,CAAC,MAAM,KAC3B,OAAOD,GAAQ,CAACA,EAAK,UAAYA,EAAK,IAAM,MAC9C,ECAME,GAAS,MAKFC,IAAe,CAAE,SAAQ,gBAAmC,CACvE,GAAM,CAAE,KAAMlD,EAAe,EAC7B,OACE,EAAA7F,EAAA,KAAC6G,GAAD,CAAQ,MAAOC,EAAE,uBAAuB,EACrC,SAAAf,EAAO,IAAK,IACX,EAAA/F,EAAA,KAAC+G,GAAD,CAA6B,MAAOc,EAAM,IACvC,SAAAA,EAAM,WAAW,IAAK,IACrB,EAAA7H,EAAA,MAACgH,GAAD,CAEE,GAAG,gBACH,OAAQ,CAAE,IAAK,OAAQ,GAAIlG,EAAU,EAAG,EACxC,MAAOA,EAAU,QACjB,eAAcA,EAAU,KAAOkI,EAAa,OAAS,OALvD,WAOE,EAAAhJ,EAAA,KAAC,OAAD,CAAM,UAAU,yDAA0D,SAAA8I,EAAa,IACvF,EAAA9I,EAAA,KAAC,OAAD,CAAM,UAAU,qCACb,SAAAc,EAAU,KAAK,MAAMuG,GAAgB,OAAS,CAAC,CAC5C,EACI,CAVL,EAAAvG,EAAU,EAUL,CACb,CACU,EAfK+G,EAAM,GAeX,CACd,CACK,EAEZ,ECpBaoB,GAAkB,GAAiB,IAAI,IAAIpI,EAAK,QAAQ,MAAO,EAAE,EAAGhB,GAAW,CAAC,CAAC,CAAC,KAEzFqJ,GAAa,GAA0B,CAC3C,GAAI,CACF,OAAO,KAAK,MAAMC,CAAI,CACxB,MAAQ,CACN,OAAOA,CACT,CACF,EAQaC,OACXC,EAAY,CACV,YAAa,CAAC,UAAW,WAAY,MAAM,EAC3C,WAAY,MAAO,CAAE,OAAM,WAAsD,CAC/E,IAAM5H,EAAMwH,GAAepI,CAAI,EACzByI,EAAU,YAAY,IAAI,EAC1BC,EAAW,MAAM,MAAM9H,EAAK,CAChC,QAAS,CAAE,OAAQ,mBAAoB,GAAI+H,EAAQ,CAAE,cAAe,UAAUA,GAAQ,EAAI,CAAC,CAAG,EAC9F,YAAa,OACb,MAAO,UACT,CAAC,EACKL,EAAO,MAAMI,EAAS,KAAK,EACjC,MAAO,CACL,MACA,OAAQA,EAAS,OACjB,WAAYA,EAAS,WACrB,GAAIA,EAAS,GACb,WAAY,KAAK,MAAM,YAAY,IAAI,EAAID,CAAO,EAClD,KAAMJ,GAAUC,CAAI,EACpB,MACF,CACF,CACF,CAAC,EC3CUM,IAAc,CAAE,OAAM,cAAgC,CACjE,GAAM,CAAE,KAAM5D,EAAe,EACvB6D,GAAU,EAAY,IAC1BC,EAASC,EAAK,IAAK,GAASxI,EAAI,KAAOsE,EAAK,CAAE,GAAGtE,EAAK,GAAGyI,CAAM,EAAIzI,CAAI,CAAC,EAC1E,OACE,EAAApB,EAAA,MAAC,WAAD,CAAU,UAAU,YAApB,WACE,EAAAA,EAAA,KAAC,SAAD,CAAQ,UAAU,wBAAyB,SAAA8G,EAAE,6BAA6B,CAAU,GACnF8C,EAAK,KAAK,EAAK,KACd,EAAA5J,EAAA,MAAC,MAAD,CAAkB,UAAU,0BAA5B,WACE,EAAAA,EAAA,KAAC8J,GAAD,CACE,aAAYhD,EAAE,gCAAiC,CAAE,MAAOnD,EAAQ,CAAE,CAAC,EACnE,YAAamD,EAAE,0CAA0C,EACzD,UAAU,YACV,MAAO1F,EAAI,IACX,SAAW,GAAUsI,EAAOtI,EAAI,GAAI,CAAE,IAAK2I,EAAM,OAAO,KAAM,CAAC,CAChE,IACD,EAAA/J,EAAA,KAAC8J,GAAD,CACE,aAAYhD,EAAE,kCAAmC,CAAE,MAAOnD,EAAQ,CAAE,CAAC,EACrE,YAAamD,EAAE,4CAA4C,EAC3D,MAAO1F,EAAI,MACX,SAAW,GAAUsI,EAAOtI,EAAI,GAAI,CAAE,MAAO2I,EAAM,OAAO,KAAM,CAAC,CAClE,IACD,EAAA/J,EAAA,KAACkH,EAAD,CACE,KAAK,SACL,QAAQ,QACR,KAAK,OACL,aAAYJ,EAAE,mCAAoC,CAAE,MAAOnD,EAAQ,CAAE,CAAC,EACtE,YAAegG,EAASC,EAAK,OAAQ,GAAcvH,EAAU,KAAOjB,EAAI,EAAE,CAAC,EAE3E,YAAApB,EAAA,KAACgK,GAAD,CAAG,cAAY,MAAQ,EACjB,EACL,CAvBK,EAAA5I,EAAI,EAuBT,CACN,GACD,EAAApB,EAAA,MAACkH,EAAD,CACE,KAAK,SACL,QAAQ,UACR,KAAK,KACL,YAAeyC,EAAS,CAAC,GAAGC,EAAM,CAAE,GAAIK,GAAY,EAAG,IAAK,GAAI,MAAO,EAAG,CAAC,CAAC,EAJ9E,WAME,EAAAjK,EAAA,KAACkK,GAAD,CAAM,cAAY,MAAQ,GACzBpD,EAAE,+BAA+B,CAC5B,GACA,GAEd,EC7CaqD,GAAwBC,GAA2B,CAAC,CAAE,IAAS,CAC1E,MAAO,GACP,SAAW,GAAUC,EAAI,CAAE,OAAM,CAAC,CACpC,EAAE,EAGFC,EAAgB,WAAW,EAAO,IAAa,CACzCC,EAAS,YAAc,QAAaC,EAAM,YAAc,QAC1DL,GAAsB,SAAS,CAAE,MAAO,EAAG,CAAC,CAEhD,CAAC,ECLD,IAAaM,GAAa,CAAE,QAAO,OAAM,QAAO,WAAU,OAAO,GAAO,GAAGC,KAAiC,CAC1G,IAAMhF,GAAA,EAAKiF,SAAM,EACXC,EAAS,GAAGlF,EAAG,OACrB,OACE,EAAA1F,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,WACE,EAAAA,EAAA,KAAC6K,GAAD,CAAa,QAASnF,EAAW,QAAa,OAAM,OAAQoF,EAAOF,EAAS,MAAY,IACxF,EAAA5K,EAAA,KAAC8J,GAAD,CACM,KACG,QACP,SAAW,GAAUH,EAASI,EAAM,OAAO,KAAK,EAChD,mBAAkBe,EAAOF,EAAS,OAClC,UAAW3K,EAAG8K,GAAQ,WAAW,EACjC,WAAY,GACZ,GAAIL,CACL,EACE,GAET,ECfMM,GAAiB,cACjBlC,GAAS,MAaFmC,IAAkB,CAC7B,YACA,QACA,gBACA,OACA,WACA,UACA,YACyB,CACzB,GAAM,CAAE,KAAMpF,EAAe,EACvBqF,GAAA,EAAWP,SAAM,EACjBQ,EAAUC,GAAW,CAAC,CAAC,MAAQ,CAAC,EAChC5B,EAAQW,GAAuB,GAAUK,EAAM,KAAK,EACpDa,EAAWlB,GAAuB,GAAUK,EAAM,QAAQ,EAC1DH,EAAO,GAAiCiB,EAAc,CAAE,GAAGvK,EAAO,GAAG8I,CAAM,CAAC,EAOlF,OACE,EAAA7J,EAAA,KAACiH,EAAD,CAAO,MAAOnG,EAAU,QAAS,QAAQ,KACvC,YAAAd,EAAA,MAAC,OAAD,CAAM,UAAU,YAAY,SARhB,GAAqB,CACnC+J,EAAM,eAAe,EACjBwB,GACFC,EAAO,CAEX,EAGI,WACE,EAAAxL,EAAA,MAAC,IAAD,CAAG,UAAU,kCAAb,WACE,EAAAA,EAAA,KAACyL,EAAD,CAAO,QAAQ,UAAU,UAAU,YAChC,SAAA3C,EACI,IACP,EAAA9I,EAAA,KAAC,OAAD,CAAM,UAAU,sCAAuC,SAAAa,CAAW,EACjE,KACH,EAAAb,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,UACGc,EAAU,MACT,EAAAd,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,wBAAwB,EACjC,MAAO/F,EAAM,GACb,SAAW,GAAOsJ,EAAI,CAAE,IAAG,CAAC,EAC5B,YACA,OACD,GACC,KACHvC,GAAahH,EAAW,QAAQ,GAC/B,EAAAd,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,WACE,EAAAA,EAAA,KAAC6K,GAAD,CACE,QAASK,EACT,MAAOpE,EAAE,4BAA4B,EACrC,KAAMA,EAAE,gCAAgC,CACzC,IACD,EAAA9G,EAAA,MAAC0L,GAAD,CACE,MAAO3K,EAAM,QAAUiK,GACvB,cAAgB,GAAUX,EAAI,CAAE,OAAQnJ,IAAU8J,GAAiB,GAAK9J,CAAM,CAAC,EAFjF,WAIE,EAAAlB,EAAA,KAAC2L,GAAD,CAAe,GAAIT,EAAU,UAAU,SACrC,YAAAlL,EAAA,KAAC4L,GAAD,CAAc,EACD,IACf,EAAA5L,EAAA,MAAC6L,GAAD,YACE,EAAA7L,EAAA,KAAC8L,GAAD,CAAY,MAAOd,GAAiB,SAAAlE,EAAE,mCAAmC,CAAc,GACtFqE,EAAQ,IAAK,IACZ,EAAAnL,EAAA,KAAC8L,GAAD,CAA8B,MAAOC,EAAO,KACzC,SAAAjF,EAAE,mCAAoC,CAAE,MAAOiF,EAAO,MAAO,KAAMA,EAAO,IAAK,CAAC,CACvE,EAFKA,EAAO,IAEZ,CACb,CACY,GACT,CACL,GACH,QACHjE,GAAahH,EAAW,UAAU,GACjC,EAAAd,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,8BAA8B,EACvC,KAAMA,EAAE,kCAAkC,EAC1C,MAAO/F,EAAM,SACb,SAAW,GAAasJ,EAAI,CAAE,UAAS,CAAC,EACxC,UAAU,SACX,GACC,MACJ,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,4BAA4B,EACrC,KAAMA,EAAE,gCAAgC,EACxC,MAAO/F,EAAM,OACb,SAAW,GAAWsJ,EAAI,CAAE,QAAO,CAAC,EACpC,OACD,IACD,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,8BAA8B,EACvC,KAAMA,EAAE,kCAAkC,EAC1C,MAAO/F,EAAM,SACb,SAAW,GAAasJ,EAAI,CAAE,UAAS,CAAC,EACxC,OACD,GACAvJ,EAAU,MACT,EAAAd,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,0BAA0B,EACnC,KAAMA,EAAE,8BAA8B,EACtC,MAAO/F,EAAM,KACb,SAAW,GAASsJ,EAAI,CAAE,MAAK,CAAC,EAChC,OACD,IACD,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,4BAA4B,EACrC,MAAO/F,EAAM,EACb,SAAW,GAAMsJ,EAAI,CAAE,GAAE,CAAC,CAC3B,IACD,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,0BAA0B,EACnC,MAAO/F,EAAM,KACb,SAAW,GAASsJ,EAAI,CAAE,MAAK,CAAC,EAChC,UAAU,SACX,IACD,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,8BAA8B,EACvC,MAAO/F,EAAM,SACb,SAAW,GAAasJ,EAAI,CAAE,UAAS,CAAC,EACxC,UAAU,SACX,EACD,IACA,IACD,IACJvJ,EAAU,MAAO,EAAAd,EAAA,KAACyJ,GAAD,CAAY,KAAM1I,EAAM,QAAS,SAAW,GAAYsJ,EAAI,CAAE,SAAQ,CAAC,CAAI,GAAI,MACjG,EAAArK,EAAA,KAACyK,EAAD,CACE,MAAO3D,EAAE,2BAA2B,EACpC,KAAMA,EAAE,+BAA+B,EACvC,MAAO0C,EACP,SAAU6B,EACV,KAAK,WACL,aAAa,MACb,YAAavE,EAAE,sCAAsC,EACrD,OACD,IACD,EAAA9G,EAAA,KAAC,MAAD,CAAK,UAAU,mBACb,YAAAA,EAAA,MAACkH,EAAD,CAAQ,KAAK,SAAS,SAAU,CAACqE,GAAYU,EAA7C,WACE,EAAAjM,EAAA,KAACkM,GAAD,CAAM,cAAY,MAAQ,GACfpF,EAAVmF,EAAY,sBAA2B,kBAAkB,CACpD,GACL,EACD,GACD,EAEX,ECjKME,GAAa,CAAC,QAAS,OAAQ,QAAS,UAAW,MAAM,EAEzDC,GAAY,GAChB,OAAOlL,GAAU,YAAYA,GAAkB,CAAC,MAAM,QAAQA,CAAK,EAE/DmL,GAAW,GAAoC,CACnD,GAAI,CAACD,GAASlL,CAAK,GAAK,OAAOA,EAAM,IAAO,SAC1C,MAAO,CAAC,EAEV,IAAMoL,EAAWH,GAAW,KAAM,GAAQ,OAAOjL,EAAMR,IAAS,UAAYQ,EAAMR,KAAS,EAAE,EAC7F,MAAO,CACL,CACE,GAAIQ,EAAM,GACV,OAAQ,OAAOA,EAAM,QAAW,SAAWA,EAAM,OAAS,OAC1D,MAAOoL,EAAW,OAAOpL,EAAMoL,EAAS,EAAI,MAC9C,CACF,CACF,EAEaC,GAAmB,GACzBH,GAASI,CAAI,EAGX,MAAM,QAAQA,EAAK,IAAI,EAAIA,EAAK,KAAK,QAAQH,EAAO,EAAIA,GAAQG,EAAK,IAAI,EAFvE,CAAC,EClBCC,IAAc,CAAE,UAAS,cAAgC,CACpE,GAAM,CAAE,KAAM5G,EAAe,EAC7B,OACE,EAAA7F,EAAA,KAAC,KAAD,CAAI,aAAY8G,EAAE,8BAA8B,EAAG,UAAU,6BAC1D,SAAA4F,EAAQ,IAAK,IACZ,EAAA1M,EAAA,MAAC,KAAD,CAA8C,UAAU,4CAAxD,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,iBAAf,WACE,EAAAA,EAAA,KAAC,IAAD,CAAG,UAAU,+BAAgC,SAAA2M,EAAM,OAAS7F,EAAE,kBAAkB,CAAK,IACrF,EAAA9G,EAAA,KAAC,IAAD,CAAG,UAAU,oDACV,SAAA2M,EAAM,OACH7F,EAAE,gCAAiC,CAAE,GAAI6F,EAAM,GAAI,OAAQA,EAAM,MAAO,CAAC,EACzEA,EAAM,EACT,EACA,CACL,MAAA3M,EAAA,KAACkH,EAAD,CAAQ,WAAQ,QAAQ,UAAU,KAAK,KACrC,YAAAlH,EAAA,MAACmH,EAAD,CACE,GAAG,8BACH,OAAQ,CAAE,WAAU,QAASwF,EAAM,EAAG,EACtC,OAAQA,EAAM,OAAS,CAAE,OAAQA,EAAM,MAAO,EAAI,CAAC,EACnD,aAAY7F,EAAE,sCAAuC,CAAE,MAAO6F,EAAM,OAASA,EAAM,EAAG,CAAC,EAJzF,WAME,EAAA3M,EAAA,KAAC4M,GAAD,CAAQ,cAAY,MAAQ,GAC3B9F,EAAE,gCAAgC,CAC/B,GACA,EACN,CApBK,KAAG6F,EAAM,GAAG,GAAGA,EAAM,QAAU,IAoBpC,CACL,CACC,EAER,ECxBaE,IAAgB,CAAE,WAAU,cAAkC,CACzE,GAAM,CAAE,KAAMhH,EAAe,EACvB6G,GAAA,EAAU1G,eAAeuD,GAAU,GAAKgD,GAAgBhD,EAAS,IAAI,EAAI,CAAC,EAAI,CAACA,CAAQ,CAAC,EACxFuD,GAAA,EAAS9G,eAEXuD,GAAY,OAAOA,EAAS,MAAS,SAAW,KAAK,UAAUA,EAAS,KAAM,KAAM,CAAC,EAAIA,GAAU,KACrG,CAACA,CAAQ,CACX,EACA,OACE,EAAAvJ,EAAA,KAACiH,EAAD,CACE,MAAOH,EAAE,4BAA4B,EACrC,QACEyC,GACE,EAAAvJ,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC+M,EAAD,CACE,KAAMxD,EAAS,GAAK,UAAY,SAChC,MAAO,GAAGA,EAAS,OAAO,GAAGA,EAAS,aAAa,KAAK,EACxD,KAAK,IACN,IACD,EAAAvJ,EAAA,KAAC,OAAD,CAAM,UAAU,+CACb,SAAA8G,EAAE,gCAAiC,CAAE,GAAIyC,EAAS,UAAW,CAAC,CAC3D,EACN,IACA,KAGL,SAAAA,GACC,EAAAvJ,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,KAAC,IAAD,CAAG,KAAK,SAAS,UAAU,UACxB,SAAA8G,EAAE,gCAAiC,CAAE,OAAQyC,EAAS,OAAQ,GAAIA,EAAS,UAAW,CAAC,CACvF,GACFmD,EAAQ,OAAS,GAAKM,GAAW,EAAAhN,EAAA,KAACyM,GAAD,CAAqB,UAAmB,UAAW,GAAI,MACzF,EAAAzM,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,2BAA2B,EAAG,KAAMgG,GAAU,EAAK,EACpE,CAEL,MAAA9M,EAAA,KAACiN,EAAD,CAAY,KAAK,QAAQ,KAAMtO,GAAO,MAAOmI,EAAE,4BAA4B,CAAI,EAE5E,EAEX,EC7CMoG,IAAqB,EAAiB,KAAkB,CAC5D,SAAU3N,EAAU,QAAQ,MAAM,MAAM4N,EAASC,CAAI,EACrD,YAAeC,EAAS,MAAM,OAAO,CAAE,UAAS,MAAK,CAAC,EACtD,KAAM,CAAE,OAAQ,EAAK,CACvB,GAaMC,GAAc,GAA6D,CAC/E,IAAMC,EAAQ,IAAI,IAClB,IAAK,IAAMC,KAAUC,EAAS,CAC5B,IAAK,IAAMC,KAAWF,EAAO,WAC3BD,EAAM,IAAIG,EAAQ,aAAc,CAAE,GAAGA,EAAS,OAAQH,EAAM,IAAIG,EAAQ,YAAY,CAAC,EAAE,QAAU,CAAC,CAAE,CAAC,EAEvG,IAAK,IAAM7K,KAAS2K,EAAO,OACzB,IAAK,IAAMG,KAAa9K,EAAM,WAC5B0K,EAAM,IAAII,EAAU,YAAY,CAAC,EAAE,OAAO,KAAK,CAC7C,QAASH,EAAO,QAChB,WAAY3K,EAAM,YAAcA,EAAM,UACtC,MAAO8K,EAAU,MACjB,WAAYA,EAAU,WACtB,UAAWA,EAAU,SACvB,CAAC,CAGP,CACA,MAAO,CAAC,GAAGJ,EAAM,OAAO,CAAC,CAAC,CAAC,MAAM,EAAG,IAAMlH,EAAE,SAAWD,EAAE,QAAQ,CACnE,EAMawH,IAAqB,EAA6B,EAAkB,MAC/EC,GAAW,CACT,QAASC,EAAS,IAAK,IAAa,CAAE,GAAGZ,GAAkBC,EAASC,CAAI,EAAG,SAAQ,EAAE,EACrF,QAAU,GAAY,CACpB,IAAMK,EAAUM,EAAQ,QAAS,GAAYC,EAAO,KAAO,CAACA,EAAO,IAAI,EAAI,CAAC,CAAE,EAC9E,MAAO,CACL,WAAYV,GAAWG,CAAO,EAC9B,SAAUA,EAAQ,MAAO,GAAWD,EAAO,QAAQ,EACnD,UAAWS,GAAWF,EAAQ,KAAM,GAAWC,EAAO,SAAS,EAC/D,MAAOD,EAAQ,KAAM,GAAWC,EAAO,KAAK,CAAC,EAAE,OAAS,KACxD,YAAe,QAAQ,IAAID,EAAQ,IAAK,GAAWC,EAAO,QAAQ,CAAC,CAAC,CACtE,CACF,CACF,CAAC,ECtDUE,GAAiB,GAC5BzO,EAAS,CACP,SAAUF,EAAU,QAAQ,MAAM,MAAM4N,EAAA,CAAmB,EAC3D,YAAeE,EAAS,MAAM,OAAO,CAAE,UAAS,MAAiB,CAAC,EAClE,KAAM,CAAE,OAAQ,EAAK,CACvB,CAAC,ECLGc,GAAY,CAChB,SAAU,mCACV,UAAW,oCACX,QAAS,kCACT,OAAQ,iCACR,WAAY,qCACZ,SAAU,kCACZ,EAIMC,GAAW,GACf,CACEvL,EAAM,UAAY,WAClBA,EAAM,WAAa,YACnB,CAACA,EAAM,QAAU,UACjBA,EAAM,QAAU,SAChBA,EAAM,YAAc,aACpBA,EAAM,UAAY,UACpB,CAAC,CAAC,OAAQ,GAAuBwL,IAAS,EAAK,EAG3CC,IAAW,EAAuC,IAAmB,CACzE,IAAMzL,EAAQ0L,GAAO,OAAO,KAAM,GAAclM,EAAU,aAAemM,CAAM,EAC/E,OAAO3L,EAAQ,CAAE,MAAOA,EAAM,MAAO,QAASA,EAAM,UAAW,EAAI,MACrE,EAQa4L,IAAc,CAAE,WAA6B,CACxD,GAAM,CAAE,GAAM5I,EAAe,EACvB0I,EAAQL,GAAclM,EAAM,EAAE,EAC9B0M,GAAc,EAAsB,IACxCC,GACgC,EAA/BC,IAAiB,YAAgB,8BAAmC,4BAA4B,EAC7F5K,EAAShC,EAAM,OAAO,OAAQ,GAAU,CAACa,EAAM,UAAU,EAC/D,OACE,EAAA7C,EAAA,KAACiH,EAAD,CACE,MAAO,EAAE,yBAAyB,EAClC,YAAa,EAAE,gCAAiC,CAAE,MAAOjF,EAAM,MAAO,MAAiB,CAAC,EACxF,SAEA,YAAAhC,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAY,EAAE,yBAAyB,CAAa,IACpD,EAAAhP,EAAA,KAACgP,EAAD,UAAY,EAAE,2BAA2B,CAAa,EAC9C,GACC,IACb,EAAAhP,EAAA,KAACiP,EAAD,UACGjL,EAAO,IAAK,GAAU,CACrB,IAAMkL,EAAQZ,GAAQC,EAAM,KAAM1L,EAAM,MAAM,EAC9C,OACE,EAAA7C,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,MAACmP,EAAD,CAAW,UAAU,wBAArB,WACE,EAAAnP,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA6C,EAAM,MAAU,IAChE,EAAA7C,EAAA,KAAC,IAAD,CAAG,UAAU,kCACV,WAAE,oBAAoB6C,EAAM,KAAwB,MAAM,CAC1D,GACFuL,GAAQvL,CAAK,CAAC,CAAC,OAAS,GACvB,EAAA7C,EAAA,KAAC,MAAD,CAAK,UAAU,4BACZ,SAAAoO,GAAQvL,CAAK,CAAC,CAAC,IAAK,IACnB,EAAA7C,EAAA,KAACyL,EAAD,CAAkB,QAAQ,UAAU,UAAU,WAC3C,WAAE0C,GAAUE,EAAK,CACb,EAFKA,CAEL,CACR,CACE,GACH,IACK,CACX,MAAArO,EAAA,KAACmP,EAAD,CAAW,UAAU,kCAClB,SAAAD,GACC,EAAAlP,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC,IAAD,CAAG,UAAU,eAAgB,WAAE,0BAA2B,CAAE,MAAOkP,EAAM,KAAM,CAAC,CAAK,IACrF,EAAAlP,EAAA,KAAC,IAAD,CAAG,UAAU,wBACV,SAAAkP,EAAM,QACJ,IAAK,GAAWR,EAAWU,EAAO,aAAcA,EAAO,SAAS,CAAC,CAAC,CAClE,KAAK,IAAI,CACX,EACH,KAEF,EAAApP,EAAA,KAAC,OAAD,CAAM,UAAU,wBACb,SAAAuO,EAAM,UACH,EAAE,gBAAgB,EAClBA,EAAM,MAAM,WAAa,GACvB,EAAE,+BAA+B,EACjC,EAAE,2BAA2B,CAC/B,EAEC,EACH,GApCK1L,EAAM,EAoCX,CAEd,CAAC,CACQ,EACN,GACF,EAEX,ECrGawM,IAAY,CAAE,MAAK,eAA+B,CAC7D,GAAM,CAAE,KAAMxJ,EAAe,EAC7B,OACE,EAAA7F,EAAA,MAACsP,GAAD,CAAM,aAAa,OAAnB,WACE,EAAAtP,EAAA,MAACuP,GAAD,CAAU,aAAYzI,EAAE,oBAAoB,EAAG,UAAU,aAAzD,WACE,EAAA9G,EAAA,KAACwP,GAAD,CAAa,MAAM,OAAQ,SAAA1I,EAAE,kBAAkB,CAAe,IAC9D,EAAA9G,EAAA,KAACwP,GAAD,CAAa,MAAM,QAAS,SAAA1I,EAAE,mBAAmB,CAAe,EACxD,KACV,EAAA9G,EAAA,KAACyP,EAAD,CAAa,MAAM,OACjB,YAAAzP,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,uBAAuB,EAAG,KAAMtF,GAAYC,EAAKC,CAAS,CAAI,EACvE,IACb,EAAA1B,EAAA,KAACyP,EAAD,CAAa,MAAM,QACjB,YAAAzP,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,wBAAwB,EAAG,KAAMnF,GAAaF,EAAKC,CAAS,CAAI,EACzE,EACT,GAEV,ECAagO,IAAW,CAAE,SAAQ,YAAW,QAAO,mBAAkC,CACpF,IAAMlG,EAAQW,GAAuB,GAAUK,EAAM,KAAK,EACpDmF,EAAOvG,GAAe,EACtB,CAAE,eAAgBtD,GAAkB,EACpC9D,GAAA,EAAQgE,eAEVC,GACI,KAAK,CAAE,gBAAiBC,CAAU,CAAC,CACpC,OAAOC,CAAiB,CAAC,CACzB,KAAM,GAAc7D,EAAWD,CAAS,IAAMvB,EAAU,QAAQ,EACrE,CAACmF,EAAanF,EAAU,QAAQ,CAClC,EACM8O,EAAUjH,GAAmB,EAE7B9H,EAAOgP,GAAkBjP,GAAYE,EAAWC,CAAK,EAAG6O,CAAO,EAE/DrG,EAAWoG,EAAK,MAAQA,EAAK,WAAW,cAAgB7O,EAAU,GAAK6O,EAAK,KAAO,OACzF,OACE,EAAA3P,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,WACE,EAAAA,EAAA,KAAC+I,GAAD,CAAqB,SAAQ,WAAYjI,EAAU,EAAK,IACxD,EAAAd,EAAA,MAAC,MAAD,CAAK,UAAU,gEAAf,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,WACE,EAAAA,EAAA,KAACiL,GAAD,CACa,YACJ,QACQ,gBACT,OACN,SAAU3J,GAAWR,EAAWC,CAAK,EACrC,QAAS4O,EAAK,UACd,WAAcA,EAAK,OAAO,CAAE,YAAa7O,EAAU,GAAI,OAAM,OAAM,CAAC,CACrE,IACD,EAAAd,EAAA,KAACqP,GAAD,CAAU,IAAKpG,GAAepI,CAAI,EAAG,UAAW2I,IAAU,EAAK,IAC/D,EAAAxJ,EAAA,KAAC6M,GAAD,CAAwB,WAAU,SAAU7K,GAAO,MAAS,EACzD,CACJ,GAAAA,GAAQ,EAAAhC,EAAA,KAACyO,GAAD,CAAmB,OAAQ,GAAI,IACrC,CACF,KAET,EC7CMpG,GAAQC,GAAY,mBAAmB,EAEvCwH,GAAiB,CACrB,KAAM,wBACN,QAAS,uBACX,EAIMC,IAAY,CAAE,cAA8B,CAChD,GAAM,CAAE,GAAMlK,EAAe,EACvB,CAAE,MAAM,OAAQ,MAAOwC,GAAM,UAAU,EACvC9B,GAAA,EAAaP,eAAcsB,GAAmBC,CAAQ,EAAG,CAACA,CAAQ,CAAC,EACnExB,GAAA,EAASC,eAAc0B,GAAgBH,EAAUhB,CAAU,EAAG,CAACgB,EAAUhB,CAAU,CAAC,EACpFzF,EAAYyF,EAAW,KAAM,GAAclE,EAAU,KAAOoG,CAAE,GAAK1C,EAAO,EAAE,EAAE,WAAW,GACzF,CAAE,UAAS,YAAagC,GAAiB,EACzCiI,EAAYzH,GAAahC,EAAYmC,IAAQ,OAAS5H,GAAW,GAAK2H,CAAE,EAC9E,OACE,EAAAzI,EAAA,MAACsP,GAAD,CAAM,MAAO5G,EAAK,cAAgB,GAAUsH,EAAU9O,CAAoB,EAA1E,WACE,EAAAlB,EAAA,KAACiQ,EAAD,CACE,MAAO,EAAE,0BAA0B,EACnC,KAAM,EAAE,mBAAoB,CAAE,QAAS1I,EAAS,KAAK,QAAS,MAAOhB,EAAW,MAAO,CAAC,EACxF,MACE,EAAAvG,EAAA,KAACuP,GAAD,CAAU,QAAQ,YAAY,aAAY,EAAE,wBAAwB,EACjE,SAAAW,GAAc,IAAK,IAClB,EAAAlQ,EAAA,KAACwP,GAAD,CAAgC,QAC7B,WAAEM,GAAe5O,EAAM,CACb,EAFKA,CAEL,CACd,CACO,EAEb,IACD,EAAAlB,EAAA,KAACyP,EAAD,CAAa,MAAM,OAAO,UAAU,OACjC,SAAA3O,GACC,EAAAd,EAAA,KAAC0P,GAAD,CACU,SACG,YACX,MAAO9I,EAAQ9F,EAAU,EAAE,EAC3B,cAAgB,GAASqP,EAASrP,EAAU,GAAIsH,CAAI,CACrD,IAED,EAAApI,EAAA,KAACiN,EAAD,CACE,KAAM7F,GACN,MAAO,EAAE,mBAAmB,EAC5B,YAAa,EAAE,8BAA8B,CAC9C,EAEQ,IACb,EAAApH,EAAA,KAACyP,EAAD,CAAa,MAAM,UAAU,UAAU,OACrC,YAAAzP,EAAA,KAAC4F,GAAD,CAAY,SAAU6C,EAAI,eAAgBlC,EAAqB,SAAU,EAC9D,EACT,GAEV,EAOa6J,OAAoB,CAC/B,IAAMpP,EAAQxB,GAAmB,EACjC,OACE,EAAAQ,EAAA,KAACqQ,EAAD,CAAM,MAAM,OACV,YAAArQ,EAAA,KAACsQ,EAAD,CAAkB,QAAS,aAAa,EAAAtQ,EAAA,KAAC+P,GAAD,CAAoB,UAAW,EAAa,EAChF,EAEV,EC3EMQ,GAAwBC,GAAS,CACrC,MAAOC,GAAa,CAAC,CAAC,IAAI,IAAK,oBAAoB,EACnD,YAAaC,GAAS,CAAC,CAAC,IAAI,IAAM,oBAAoB,CACxD,CAAC,EAIKC,GAA+B,CAAE,MAAO,GAAI,YAAa,EAAG,EAErDC,IAA0B,EAAe,IAAwC,CAC5F,IAAMC,EAAkBC,GAAmB,EACrCC,EAAOC,GAA+B,CAC1C,SAAUC,GAAYV,EAAqB,EAC3C,cAAeI,EACjB,CAAC,EACK,CAAE,SAAUI,EAWlB,OAVAG,GAAeC,EAAMC,EAAOT,GAAOE,EAAgB,KAAK,EAUjD,CAAE,OAAM,SATEE,EAAK,aAAa,MAAO,CAAE,QAAO,iBAAkB,CACnE,IAAMM,EAAU,MAAMC,GACpBT,EAAgB,YAAY,CAAE,MAAOU,EAAM,KAAK,EAAG,YAAaC,EAAY,KAAK,CAAE,CAAC,CACtF,EACIH,EAAQ,KACVD,EAAMT,EAAK,EACXc,EAAUJ,EAAQ,KAAK,EAE3B,CACe,EAAU,iBAAgB,CAC3C,ECrBaK,IAAe,CAAE,OAAM,eAAc,eAAkC,CAClF,GAAM,CAAE,KAAM7L,EAAe,EACvB,CAAE,OAAM,WAAU,mBAAoB+K,GAAuBO,EAAMM,CAAS,EAClF,OACE,EAAAzR,EAAA,MAAC2R,GAAD,CACQ,OACQ,eACd,KAAK,KACL,MAAO7K,EAAE,qBAAqB,EAC9B,MAAOiK,EAAK,UAAU,QACtB,QAASF,EAAgB,UACzB,YAAa/J,EAAE,eAAe,EAC9B,aAAcA,EAAE,eAAe,EAC/B,SAAW,GAAU,KAAK8K,EAAS7H,CAAK,EAT1C,WAWE,EAAA/J,EAAA,KAAC6R,GAAD,CACE,QAASd,EAAK,QACd,KAAK,QACL,MAAOjK,EAAE,sBAAsB,EAC/B,aAAa,KACd,IACD,EAAA9G,EAAA,KAAC8R,GAAD,CACE,QAASf,EAAK,QACd,KAAK,cACL,MAAOjK,EAAE,4BAA4B,EACrC,KAAM,CACP,IACD,EAAA9G,EAAA,KAAC+R,GAAD,CAAW,MAAOlB,EAAgB,KAAQ,EACjC,GAEf,ECzCamB,GAA4B,iBAE5BC,GAA0B,eAC1BC,GAA2B,gBAI3BC,GAA4B,CACvC,KAAM,CAAE,SAAU,wBAAyB,KAAM,SAAU,EAC3D,UAAW,CAAE,SAAU,6BAA8B,KAAM,WAAY,EACvE,SAAU,CAAE,SAAU,4BAA6B,KAAM,UAAW,EACpE,QAAS,CAAE,SAAU,2BAA4B,KAAM,SAAU,EACjE,OAAQ,CAAE,SAAU,0BAA2B,KAAM,QAAS,EAC9D,UAAW,CAAE,SAAU,6BAA8B,KAAM,OAAQ,CACrE,EAGaC,GAAkD,IAAI,IAAI,CAAC,OAAQ,QAAQ,CAAC,ECd5EC,MAA8B,CACzC,IAAMC,EAAiCzJ,GAAM,CAAC,CAAC,MAAM,mBAAqB,CAAC,EAC3E,MAAO,CACL,iBAAkByJ,EAAY,SAASN,EAAyB,EAChE,eAAgBM,EAAY,SAASL,EAAuB,EAC5D,aAAcK,EAAY,SAASJ,EAAwB,EAC3D,oBAAqBI,EAAY,SAAS,mBAAmB,EAC7D,kBAAmBA,EAAY,SAAS,iBAAiB,CAC3D,CACF,ECdMC,GAAkB,CACtB,MAAO,uBACP,MAAO,uBACP,OAAQ,uBACV,EAEMC,GAAe,GAAuDC,KAAQF,GAGvEG,MAAsB,CACjC,GAAM,CAAE,KAAM7M,EAAe,EAC7B,MAAQ,IACD8M,EAGDA,EAAM,KACDA,EAAM,KAERH,GAAYG,EAAM,IAAI,EAAI7L,EAAEyL,GAAgBI,EAAM,KAAK,EAAIA,EAAM,KAL/D7L,EAAE,uBAAuB,CAOtC,ECTa8L,IAAO,CAAE,MAAK,oBAA+B,CACxD,GAAM,CAAE,KAAM/M,EAAe,EACvBgN,EAAaH,EAAc,EAC3BI,EAASX,GAA0B9H,EAAI,QACvC0I,EAAO1I,EAAI,cAAgBA,EAAI,UACrC,OACE,EAAArK,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,MAACmP,EAAD,CAAW,UAAU,WAArB,WACE,EAAAnP,EAAA,KAACgT,GAAD,CAAU,WAAQ,UAAU,iBAC1B,YAAAhT,EAAA,KAACmH,EAAD,CAAM,GAAG,wBAAwB,OAAQ,CAAE,YAAakD,EAAI,EAAG,EAC5D,SAAAA,EAAI,KACD,EACE,GACTA,EAAI,aACH,EAAArK,EAAA,KAAC,OAAD,CAAM,UAAU,iDAAkD,SAAAqK,EAAI,WAAkB,GACtF,IACK,KACX,EAAArK,EAAA,KAACmP,EAAD,WACE,EAAAnP,EAAA,KAAC+M,EAAD,CAAY,KAAM+F,EAAO,KAAM,MAAOhM,EAAEgM,EAAO,QAAQ,CAAI,EAClD,IACX,EAAA9S,EAAA,KAACmP,EAAD,CAAW,UAAU,0BAClB,SAAArI,EAAE,oBAAqB,CAAE,MAAOuD,EAAI,eAAiBA,EAAI,eAAgB,CAAC,CAClE,IACX,EAAArK,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAqB,SAAA0D,EAAWxI,EAAI,SAAS,CAAa,IAC/E,EAAArK,EAAA,MAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAeF,CAAI,EAAnE,UACG1I,EAAI,aACDvD,EAAE,uBAAwB,CAAE,GAAImM,EAAe5I,EAAI,YAAY,CAAE,CAAC,EAClE6I,EAAmBH,CAAI,EAC1BI,GACC,EAAAnT,EAAA,KAAC,OAAD,CAAM,UAAU,wCACb,SAAA8G,EAAE,oBAAqB,CAAE,KAAMqM,CAAe,CAAC,CAC5C,GACJ,IACK,GACH,GAEd,ECtCaC,OAAiB,CAC5B,GAAM,CAAE,KAAMvN,EAAe,EACvBwN,EAAOC,GAAc,EACrBC,EAAcC,GAAyB,EACvCL,EAAkB,GACtBzN,EAAK6N,EAAY,MAAM,KAAM,GAAeE,EAAW,KAAO/N,CAAE,CAAC,EAAE,KAAO,OAC5E,OACE,EAAA1F,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,mBAAmB,EAAG,SACpC,YAAA9G,EAAA,KAACsQ,EAAD,CACE,MAAO+C,EACP,QAAU,GAASK,EAAK,MAAM,SAAW,EACzC,OACE,EAAA1T,EAAA,KAACiN,EAAD,CACE,KAAM0G,GACN,KAAK,QACL,MAAO7M,EAAE,eAAe,EACxB,YAAaA,EAAE,0BAA0B,CAC1C,GAGD,aACA,EAAA9G,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,CAAW,UAAU,aAAc,SAAAlI,EAAE,sBAAsB,CAAa,IACxE,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,qBAAqB,CAAa,EACxC,GACC,IACb,EAAA9G,EAAA,KAACiP,EAAD,UACGyE,EAAK,MAAM,IAAK,IACf,EAAA1T,EAAA,KAAC4S,GAAD,CAAuB,MAAK,eAAgBO,EAAe9I,EAAI,sBAAsB,CAAI,EAA/EA,EAAI,EAA2E,CAC1F,CACQ,EACN,GAEA,EACN,EAEX,ECxCauJ,OAAkB,CAC7B,GAAM,CAAE,KAAM/N,EAAe,EACvBgO,EAAYC,GAAa,CAAE,OAAQ,YAAa,QAA4B,CAAC,EACnF,OACE,EAAA9T,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,+BAA+B,EAAG,SAChD,YAAA9G,EAAA,KAACsQ,EAAD,CACE,MAAOuD,EACP,QAAU,GAASH,EAAK,MAAM,SAAW,EACzC,OAAO,EAAA1T,EAAA,KAACiN,EAAD,CAAY,KAAM8G,GAAe,KAAK,QAAQ,MAAOjN,EAAE,iCAAiC,CAAI,GAEjG,aACA,EAAA9G,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,qBAAqB,CAAa,EACxC,GACC,IACb,EAAA9G,EAAA,KAACiP,EAAD,UACGyE,EAAK,MAAM,IAAK,IACf,EAAA1T,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAClB,SAAA6E,EAAS,UAAYlN,EAAE,gBAAgB,CAC/B,IACX,EAAA9G,EAAA,KAACmP,EAAD,CAAW,UAAU,WACnB,YAAAnP,EAAA,KAAC,OAAD,CAAM,UAAU,mCAAmC,MAAOgU,EAAS,QAChE,SAAAA,EAAS,OACN,EACG,IACX,EAAAhU,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAqB,SAAA6E,EAAS,MAAkB,IACrE,EAAAhU,EAAA,KAACmP,EAAD,UAAYrI,EAAEmN,GAA0BD,EAAS,OAAO,CAAa,IACrE,EAAAhU,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAee,EAAS,KAAK,EAC1E,SAAAd,EAAmBc,EAAS,KAAK,CACzB,EACH,GAdKA,EAAS,EAcd,CACX,CACQ,EACN,GAEA,EACN,EAEX,EChDaE,GAAqB,GAA2B,CAC3D,GAAM,CAAE,GAAMrO,EAAe,EACvBsO,EAAWC,GAAqB,EAChCvD,EAAkBC,GAAmB,EACrCuD,EAAQ,CACZ,SAAU1H,EAAM,UAAY,GAC5B,QAASA,EAAM,QACf,OAAQA,EAAM,OACd,OAAQ,SACV,EACM2H,EAAQ,KAAO,IAAe,CAClC,IAAMjK,EAAM,MAAM8J,EAAS,YAAY,CAAE,KAAI,OAAM,CAAC,EACpDI,EAAM,QAAQ,EAAE,gBAAiB,CAAE,MAAOlK,EAAI,KAAM,CAAC,CAAC,CACxD,EACA,MAAO,CACL,QACA,aAAc,KAAO,IAAkB,CACrC,IAAMA,EAAM,MAAMwG,EAAgB,YAAY,CAAE,OAAM,CAAC,EACvD,MAAMyD,EAAMjK,EAAI,EAAE,CACpB,EACA,QAAS8J,EAAS,WAAatD,EAAgB,UAC/C,MAAOsD,EAAS,OAAStD,EAAgB,MACzC,UAAa,CACXsD,EAAS,MAAM,EACftD,EAAgB,MAAM,CACxB,CACF,CACF,ECpBa2D,IAAgB,CAAE,QAAO,WAA+B,CACnE,GAAM,CAAE,KAAM3O,EAAe,EACvB4O,GAAA,EAAU9J,SAAM,EAChB+J,GAAA,EAAU/J,SAAM,EAChB,CAACwG,EAAMwD,IAAA,EAAWzM,YAAS,EAAK,EAChC,CAAC0M,EAAUC,IAAA,EAAe3M,YAAS,EAAE,EACrCmL,EAAOC,GAAc,MAAM,EAC3B,CAAE,QAAO,eAAc,UAAS,QAAO,SAAUY,GAAkBvH,CAAK,EACxEmI,EAAO,GACX,KAAKC,EAAO,CAAC,CAAC,SACNJ,EAAQ,EAAK,EAClB,GAAmBK,GAASC,EAAO,iCAAiC,CACvE,EACF,OACE,EAAAjV,EAAA,MAACkV,GAAD,CACQ,OACN,aAAe,GAAS,CAClBC,IAGJR,EAAQvM,CAAI,EACRA,IACFgJ,EAAM,EACNyD,EAAY,EAAE,GAElB,EACA,SAZF,WAcE,EAAA7U,EAAA,KAACoV,GAAD,CAAgB,WACd,YAAApV,EAAA,MAACkH,EAAD,CAAQ,QAAQ,UAAU,KAAK,KAAK,aAAY/G,EAAhD,WACE,EAAAH,EAAA,KAACqV,GAAD,CAAY,cAAY,MAAQ,GAC/BvO,EAAE,eAAe,CACZ,GACM,IAChB,EAAA9G,EAAA,MAACsV,GAAD,CAAgB,MAAM,MAAM,kBAAiBb,EAAS,UAAU,iBAAhE,WACE,EAAAzU,EAAA,KAAC,IAAD,CAAG,GAAIyU,EAAS,UAAU,wBACvB,SAAA3N,EAAE,oBAAoB,CACtB,GACFuM,EAAK,MAAQA,EAAK,KAAK,MAAM,OAAS,GACrC,EAAArT,EAAA,KAAC,KAAD,CAAI,UAAU,qCACX,SAAAqT,EAAK,KAAK,MAAM,IAAK,IACpB,EAAArT,EAAA,KAAC,KAAD,WACE,EAAAA,EAAA,KAACkH,EAAD,CACE,QAAQ,QACR,KAAK,KACL,UAAU,gCACV,SAAUiO,EACV,YAAeL,MAAUR,EAAMjK,EAAI,EAAE,CAAC,EAErC,SAAAA,EAAI,KACC,EACN,EAVKA,EAAI,EAUT,CACL,CACC,IAEJ,EAAArK,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,oBAAoB,CAAK,IAE7E,EAAA9G,EAAA,MAAC,OAAD,CACE,cACA,UAAU,0BACV,SAAW,GAAU,CACnB+J,EAAM,eAAe,EACrB,IAAMwH,EAAQqD,EAAS,KAAK,EACxBrD,GACFuD,MAAUS,EAAahE,CAAK,CAAC,CAEjC,EATF,WAWE,EAAAvR,EAAA,KAAC,QAAD,CAAO,QAAS0U,EAAS,UAAU,wBAChC,SAAA5N,EAAE,qBAAqB,CACnB,IACP,EAAA9G,EAAA,MAAC,MAAD,CAAK,UAAU,aAAf,WACE,EAAAA,EAAA,KAAC8J,GAAD,CACE,GAAI4K,EACJ,UAAU,KACV,MAAOE,EACP,UAAW,IACX,aAAa,MACb,SAAW,GAAUC,EAAY9K,EAAM,OAAO,KAAK,CACpD,IACD,EAAA/J,EAAA,KAACwV,GAAD,CACE,KAAK,KACI,UACT,aAAc1O,EAAE,eAAe,EAC/B,SAAU,CAAC8N,EAAS,KAAK,EAExB,SAAA9N,EAAE,eAAe,CACN,EACX,CACD,OACN,EAAA9G,EAAA,KAAC+R,GAAD,CAAkB,OAAQ,EACZ,CACT,KAEb,ECjGM0D,GAAoB,CACxB,MAAO,CAAE,SAAU,oCAAqC,KAAM,SAAU,EACxE,SAAU,CAAE,SAAU,uCAAwC,KAAM,SAAU,CAChF,EAGaC,OAAmB,CAC9B,GAAM,CAAE,KAAM7P,EAAe,EACvB6G,EAAUiJ,GAAqB,EACrC,OACE,EAAA3V,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,0BAA0B,EAAG,SAC3C,YAAA9G,EAAA,KAACsQ,EAAD,CACE,MAAO5D,EACP,QAAU,GAASgH,EAAK,MAAM,SAAW,EACzC,OAAO,EAAA1T,EAAA,KAACiN,EAAD,CAAY,KAAM2I,GAAO,KAAK,QAAQ,MAAO9O,EAAE,0BAA0B,CAAI,GAElF,aACA,EAAA9G,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,wBAAwB,CAAa,IACnD,EAAA9G,EAAA,KAACgP,EAAD,WACE,EAAAhP,EAAA,KAAC,OAAD,CAAM,UAAU,UAAW,SAAA8G,EAAE,gBAAgB,CAAQ,EAC5C,EACH,GACC,IACb,EAAA9G,EAAA,KAACiP,EAAD,UACGyE,EAAK,MAAM,IAAK,GAAU,CACzB,IAAMZ,EAAS2C,GAAkB9I,EAAM,QACjC4E,EAAQ5E,EAAM,OAASA,EAAM,QACnC,OACE,EAAA3M,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,WAClB,SAAAxC,EAAM,UACL,EAAA3M,EAAA,KAACgT,GAAD,CAAU,WAAQ,UAAU,iBAC1B,YAAAhT,EAAA,KAACmH,EAAD,CACE,GAAG,8BACH,OAAQ,CAAE,SAAUwF,EAAM,SAAU,QAASA,EAAM,OAAQ,EAC3D,OAAQ,CAAE,OAAQA,EAAM,MAAO,EAE9B,SAAA4E,CACG,EACE,IAEV,EAAAvR,EAAA,KAACgT,GAAD,CAAU,UAAU,iBAAkB,SAAAzB,CAAgB,EAE/C,IACX,EAAAvR,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAClB,SAAAxC,EAAM,UAAY7F,EAAE,gBAAgB,CAC5B,IACX,EAAA9G,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAqB,SAAAxC,EAAM,MAAkB,IAClE,EAAA3M,EAAA,KAACmP,EAAD,WACE,EAAAnP,EAAA,KAAC+M,EAAD,CAAY,KAAM+F,EAAO,KAAM,MAAOhM,EAAEgM,EAAO,QAAQ,CAAI,EAClD,IACX,EAAA9S,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAetG,EAAM,SAAS,EAC3E,SAAAuG,EAAmBvG,EAAM,SAAS,CAC1B,IACX,EAAA3M,EAAA,KAACmP,EAAD,CAAW,UAAU,aACnB,YAAAnP,EAAA,KAACwU,GAAD,CAAqB,QAAO,MAAO1N,EAAE,qBAAsB,CAAE,OAAM,CAAC,CAAI,EAC/D,EACH,GA7BK,GAAG6F,EAAM,QAAQ,GAAGA,EAAM,QA6B/B,CAEd,CAAC,CACQ,EACN,GAEA,EACN,EAEX,ECvEakJ,OAAgB,CAC3B,GAAM,CAAE,KAAMhQ,EAAe,EACvB2C,EAAWsN,EAAY,EACvB,CAAE,oBAAqBzD,EAAsB,EAC7C,CAAC0D,EAAUC,IAAA,EAAe9N,YAAS,EAAK,EAC9C,OACE,EAAAlI,EAAA,MAACqQ,EAAD,YACE,EAAArQ,EAAA,KAACiQ,EAAD,CACE,MAAOnJ,EAAE,eAAe,EACxB,QACEmP,GACE,EAAAjW,EAAA,MAACkH,EAAD,CAAQ,YAAe8O,EAAY,EAAI,EAAvC,WACE,EAAAhW,EAAA,KAACkK,GAAD,CAAM,cAAY,MAAQ,GACzBpD,EAAE,gBAAgB,CACb,CACN,SAEP,GACAmP,GACC,EAAAjW,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACoT,GAAD,CAAW,IACX,EAAApT,EAAA,KAAC0V,GAAD,CAAa,IACb,EAAA1V,EAAA,KAAC4T,GAAD,CAAY,IACZ,EAAA5T,EAAA,KAAC0R,GAAD,CACE,KAAMqE,EACN,aAAcC,EACd,UAAY,GAAQ,CAClBA,EAAY,EAAK,EACjBxN,EAAc,CAAE,GAAI,wBAAyB,OAAQ,CAAE,YAAa6B,EAAI,EAAG,CAAE,CAAC,CAChF,CACD,EACD,KAEF,EAAArK,EAAA,KAACkW,GAAD,CAAW,EAET,GAEV,ECrCMC,GAAe3F,GAAS,CAAE,aAAcC,GAAa,CAAE,CAAC,EAejD2F,IAAiB,CAAE,OAAM,cAAa,sBAAqB,cAAmC,CACzG,GAAM,CAAE,KAAMvQ,EAAe,EACvB4O,GAAA,EAAU9J,SAAM,EAChB,CAACwG,EAAMwD,IAAA,EAAWzM,YAAS,EAAK,EAChC,CAACmO,EAAOC,IAAA,EAAYpO,YAAkB,IAAI,EAC1CqO,GAAA,EAAWvQ,gBACR,CAAE,aAAcwQ,GAAuBjD,EAAY,EAAE,EAAE,IAAM,EAAG,GACvE,CAACiD,EAAqBjD,CAAW,CACnC,EACMxC,EAAOC,GAAsB,CAAE,SAAUC,GAAYkF,EAAY,EAAG,OAAQI,CAAS,CAAC,EACtF3E,EAAWb,EAAK,aAAa,MAAO,CAAE,kBAAmB,CAC7DuF,EAAS,IAAI,EACb,GAAI,CACF,MAAMG,EAAK,QAAQC,CAAY,EAC/B/B,EAAQ,EAAK,CACf,OAASM,EAAO,CACdqB,EAASrB,CAAK,CAChB,CACF,CAAC,EACD,OACE,EAAAjV,EAAA,MAACkV,GAAD,CAAe,OAAM,aAAe,GAAUuB,EAAK,UAAY,CAACrO,EAAO,OAAYuM,EAAQvM,CAAI,EAAI,SAAnG,WACE,EAAApI,EAAA,KAACoV,GAAD,CAAgB,WACd,YAAApV,EAAA,MAACkH,EAAD,CAAQ,QAAQ,UAAoB,WAApC,WACE,EAAAlH,EAAA,KAAC2W,GAAD,CAAQ,cAAY,MAAQ,GAC3B7P,EAAE,+BAA+B,CAC5B,GACM,IAChB,EAAA9G,EAAA,KAACsV,GAAD,CAAgB,MAAM,MAAM,kBAAiBb,EAAS,UAAU,OAC9D,YAAAzU,EAAA,MAAC,OAAD,CAAM,cAAW,SAAW,GAAU,KAAK4R,EAAS7H,CAAK,EAAG,UAAU,YAAtE,WACE,EAAA/J,EAAA,KAAC,IAAD,CAAG,GAAIyU,EAAS,UAAU,wBACvB,SAAA3N,EAAE,oCAAoC,CACtC,IACH,EAAA9G,EAAA,KAAC4W,GAAD,CACE,QAAS7F,EAAK,QACd,KAAK,eACL,MAAOjK,EAAE,2BAA2B,EACpC,QAASyM,EAAY,IAAK,IAAgB,CAAE,MAAOE,EAAW,GAAI,MAAOA,EAAW,IAAK,EAAE,CAC5F,IACD,EAAAzT,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,mCAAmC,CAAK,IAC1F,EAAA9G,EAAA,KAAC+R,GAAD,CAAkB,OAAQ,IAC1B,EAAA/R,EAAA,MAAC,MAAD,CAAK,UAAU,yBAAf,WACE,EAAAA,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,YAAeyN,EAAQ,EAAK,EAC3E,SAAA7N,EAAE,eAAe,CACZ,IACR,EAAA9G,EAAA,KAACwV,GAAD,CAAc,KAAK,KAAK,QAASiB,EAAK,SAAU,aAAc3P,EAAE,yBAAyB,EACtF,SAAAA,EAAE,+BAA+B,CACtB,EACX,GACD,GACQ,EACT,GAEb,EC9DM+P,GAAiBrG,GAAS,CAAE,GAAIsG,GAAmB,CAAE,CAAC,EAM/CC,IAAmB,CAAE,OAAM,cAAqC,CAC3E,GAAM,CAAE,KAAMlR,EAAe,EACvB4O,GAAA,EAAU9J,SAAM,EAChB,CAACwG,EAAMwD,IAAA,EAAWzM,YAAS,EAAK,EAChCqO,GAAA,EAAWvQ,gBAA+B,CAAE,GAAImL,EAAO6F,GAAqB,EAAI,EAAG,GAAI,CAAC7F,CAAI,CAAC,EAC7FJ,EAAOC,GAAwB,CAAE,SAAUC,GAAY4F,EAAc,EAAG,cAAeN,CAAS,CAAC,EACvGrF,GAAeC,EAAMJ,EAAK,MAAOwF,EAAUE,EAAK,aAAa,EAC7D,IAAM7E,EAAWb,EAAK,aAAa,MAAO,CAAE,QAAS,CACnD,IAAMkG,EAAMC,GAAmBC,CAAE,EAC7BF,IAAQ,MAAM3F,GAAOmF,EAAK,WAAWQ,CAAG,CAAC,GAAG,IAC9CtC,EAAQ,EAAK,CAEjB,CAAC,EACD,OACE,EAAA3U,EAAA,MAACkV,GAAD,CACQ,OACN,aAAe,GAAUuB,EAAK,YAAc,CAACrO,EAAO,OAAYuM,EAAQvM,CAAI,EAC5E,SAHF,WAKE,EAAApI,EAAA,KAACoV,GAAD,CAAgB,WACd,YAAApV,EAAA,MAACkH,EAAD,CAAQ,QAAQ,UAAoB,WAApC,WACE,EAAAlH,EAAA,KAAC+T,GAAD,CAAe,cAAY,MAAQ,GAClCjN,EAAE,yBAAyB,CACtB,GACM,IAChB,EAAA9G,EAAA,KAACsV,GAAD,CAAgB,MAAM,MAAM,kBAAiBb,EAAS,UAAU,OAC9D,YAAAzU,EAAA,MAAC,OAAD,CAAM,cAAW,SAAW,GAAU,KAAK4R,EAAS7H,CAAK,EAAG,UAAU,YAAtE,WACE,EAAA/J,EAAA,KAAC,IAAD,CAAG,GAAIyU,EAAS,UAAU,wBACvB,SAAA3N,EAAE,8BAA8B,CAChC,IACH,EAAA9G,EAAA,KAAC6R,GAAD,CACE,QAASd,EAAK,QACd,KAAK,KACL,KAAK,iBACL,MAAOjK,EAAE,2BAA2B,EACpC,YAAaA,EAAE,kCAAmC,CAChD,SAAU,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC,QACpD,CAAC,CACF,IACD,EAAA9G,EAAA,KAAC+R,GAAD,CAAW,MAAO0E,EAAK,aAAgB,IACvC,EAAAzW,EAAA,MAAC,MAAD,CAAK,UAAU,yBAAf,WACE,EAAAA,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,YAAeyN,EAAQ,EAAK,EAC3E,SAAA7N,EAAE,eAAe,CACZ,IACR,EAAA9G,EAAA,KAACwV,GAAD,CAAc,KAAK,KAAK,QAASiB,EAAK,WAAY,aAAc3P,EAAE,eAAe,EAC9E,SAAAA,EAAE,yBAAyB,CAChB,EACX,GACD,GACQ,EACT,GAEb,ECzDasQ,IAAW,CAAE,MAAK,UAAyB,CACtD,GAAM,CAAE,KAAMvR,EAAe,EACvB2C,EAAWsN,EAAY,EACvBuB,EAAUC,GAAoB,EAC9BC,EAAaC,GAAuB,EACpCjE,EAAcC,GAAyB,EACvC,CAAE,kBAAmBnB,EAAsB,EAC3CoF,GAAsBlE,EAAY,MAAQ,CAAC,GAAG,OAAQ,GAAeE,EAAW,OAAO,EACvFiE,EAAWtF,GAAkB,IAAI/H,EAAI,MAAM,EAC3CsN,EAAe,CAAClB,EAAK,SAAW,CAACA,EAAK,cAAgBA,EAAK,SAC3DmB,EAAYvN,EAAI,eAAiBA,EAAI,gBAI3C,OAHIA,EAAI,SAAW,WAAaA,EAAI,SAAW,aAAeA,EAAI,SAAW,WACpE,MAGP,EAAArK,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC6X,EAAD,CACE,KAAK,SACL,MAAO/Q,EAAE,8BAA+B,CAAE,MAAOuD,EAAI,KAAM,CAAC,EAC5D,YAAavD,EAAE,mCAAmC,EAClD,aAAcA,EAAE,wBAAwB,EACxC,cACEuQ,EAAQ,YAAYhN,EAAI,GAAI,CAC1B,cAAiB,CACfkK,EAAM,QAAQzN,EAAE,0BAA0B,CAAC,EAC3C0B,EAAc,CAAE,GAAI,UAAW,CAAC,CAClC,CACF,CAAC,EAEH,SACE,EAAAxI,EAAA,MAACkH,EAAD,CAAQ,QAAQ,oBAAoB,SAAUuP,EAAK,SAAnD,WACE,EAAAzW,EAAA,KAAC8X,GAAD,CAAQ,cAAY,MAAQ,GAC3BhR,EAAE,wBAAwB,CACrB,GAEX,GACAuD,EAAI,SAAW,aACd,EAAArK,EAAA,MAACkH,EAAD,CACE,QAAQ,UACR,SAAUqQ,EAAW,UACrB,YACEA,EAAW,OAAOlN,EAAI,GAAI,CAAE,cAAiBkK,EAAM,QAAQzN,EAAE,4BAA4B,CAAC,CAAE,CAAC,EAJjG,WAOE,EAAA9G,EAAA,KAAC7B,GAAD,CAAW,cAAY,MAAQ,GAC9B2I,EAAE,2BAA2B,CACxB,CACN,QACH4Q,GAAYK,GACX,EAAA/X,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC+W,GAAD,CAAuB,OAAM,SAAUY,CAAe,GACrDF,EAAmB,OAAS,GAC3B,EAAAzX,EAAA,KAACoW,GAAD,CACQ,OACN,YAAaqB,EACb,oBAAqBpN,EAAI,uBACzB,SAAUsN,CACX,GACC,MACJ,EAAA3X,EAAA,KAAC6X,EAAD,CACE,KAAK,UACL,MAAO/Q,EAAE,2BAA4B,CAAE,MAAOuD,EAAI,KAAM,CAAC,EACzD,YAAavD,EAAE,iCAAkC,CAAE,MAAO8Q,CAAU,CAAC,EACrE,aAAc9Q,EAAE,qBAAqB,EACrC,aAAcA,EAAE,yBAAyB,EACzC,cAAiB2P,EAAK,QAAQ,EAC9B,SACE,EAAAzW,EAAA,MAACkH,EAAD,CAAQ,SAAUyQ,EAAc,YAAWlB,EAAK,UAAY,OAA5D,UACGA,EAAK,UACJ,EAAAzW,EAAA,KAACgY,EAAD,CAAS,cAAY,OAAO,UAAU,yCAA2C,IAEjF,EAAAhY,EAAA,KAACkM,GAAD,CAAM,cAAY,MAAQ,GAE3BuK,EAAK,SAAW3P,EAAE,yBAAyB,EAAIA,EAAE,qBAAqB,CACjE,GAEX,EACD,IACA,IACJ,GAEN,EC5FMmR,GAAc,CAClB,sBAAuB,2CACzB,EAEMC,GAAiB,GAAuDC,KAAUF,GAElFG,GAAe,6DAWRC,IAAW,CAAE,MAAK,OAAM,UAAS,6BAA4C,CACxF,GAAM,CAAE,KAAMxS,EAAe,EACvBgN,EAAaH,EAAc,EACjC,OACE,EAAA1S,EAAA,MAAAgM,WAAA,WACG3B,EAAI,SAAW,WAAaA,EAAI,kBAAoB,MACnD,EAAArK,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAU,KAAK,SAA9B,WACE,EAAAtY,EAAA,KAACuY,GAAD,CAAc,cAAY,MAAQ,IAClC,EAAAvY,EAAA,KAACwY,EAAD,WACE,EAAAxY,EAAA,MAAC,IAAD,WACG8G,EAAE,0BAA0B,EAAG,KAChC,EAAA9G,EAAA,KAACmH,EAAD,CACE,GAAG,kBACH,OAAQ,CAAE,IAAK,OAAOkD,EAAI,eAAe,CAAE,EAC3C,UAAW+N,GAEV,SAAAtR,EAAE,oBAAqB,CAAE,IAAKuD,EAAI,eAAgB,CAAC,CAChD,GAAE,IACPvD,EAAE,6BAA8B,CAC/B,KAAM+L,EAAWxI,EAAI,SAAS,EAC9B,GAAIA,EAAI,UAAY6I,EAAmB7I,EAAI,SAAS,EAAI,EAC1D,CAAC,CACA,GACa,EACb,CACL,QACHA,EAAI,SAAW,UAAYA,EAAI,OAAS,CAACoM,EAAK,OAC7C,EAAAzW,EAAA,MAACsY,EAAD,CAAO,QAAQ,cAAf,WACE,EAAAtY,EAAA,KAACyY,GAAD,CAAe,cAAY,MAAQ,IACnC,EAAAzY,EAAA,KAAC0Y,GAAD,UAAa5R,EAAE,4BAA4B,CAAc,IACzD,EAAA9G,EAAA,KAACwY,EAAD,UAAmBnO,EAAI,MAAM,OAA0B,EAClD,CACL,QACHoM,EAAK,OACJ,EAAAzW,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAU,UAAU,oDAAnC,WACE,EAAAtY,EAAA,MAAC,MAAD,CAAK,UAAU,yBAAf,WACE,EAAAA,EAAA,KAAC2Y,GAAD,CAAW,UAAU,yBAAyB,cAAY,MAAQ,IAClE,EAAA3Y,EAAA,MAAC,MAAD,YACE,EAAAA,EAAA,KAAC0Y,GAAD,UAAa5R,EAAE,2BAA2B,CAAc,IACxD,EAAA9G,EAAA,KAACwY,EAAD,UAAmB1R,EAAE,iCAAiC,CAAoB,EACvE,GACF,CACL,MAAA9G,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,YAAe,KAAKuP,EAAK,QAAQ,EAChF,SAAA3P,EAAE,wBAAwB,CACrB,EACH,CACL,QACH8R,IAA4BnC,EAAK,eAAiBA,EAAK,mBAAqB,CAACA,EAAK,cACjF,EAAAzW,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAU,KAAK,SAA9B,WACE,EAAAtY,EAAA,KAACyY,GAAD,CAAe,cAAY,MAAQ,IACnC,EAAAzY,EAAA,KAACwY,EAAD,WACE,EAAAxY,EAAA,MAAC,IAAD,WACG8G,EAAE,oCAAoC,EAAG,KAC1C,EAAA9G,EAAA,KAACmH,EAAD,CACE,GAAG,wBACH,OAAQ,CAAE,YAAakD,EAAI,EAAG,EAC9B,OAAQ,CAAE,IAAK,QAAS,EACxB,UAAW+N,GAEV,SAAAtR,EAAE,qBAAqB,CACpB,EACL,GACa,EACb,CACL,QACH+R,EAAQ,OAAOX,EAAa,CAAC,CAAC,IAAK,IAClC,EAAAlY,EAAA,MAACsY,EAAD,CAAoB,QAAQ,OAAO,KAAK,SAAxC,WACE,EAAAtY,EAAA,KAAC8Y,GAAD,CAAM,cAAY,MAAQ,IAC1B,EAAA9Y,EAAA,KAACwY,EAAD,UAAmB1R,EAAEmR,GAAYE,EAAO,CAAoB,EACvD,CAHK,EAAAA,CAGL,CACR,CACD,GAEN,ECpGMY,GAAa,IAONC,GAAa,GAA2B,CACnD,GAAI9X,GAAU,KACZ,MAAO,GAET,IAAMiI,EACJ,OAAOjI,GAAU,SACbA,EACA,OAAOA,GAAU,UAAY,OAAOA,GAAU,UAC5C,OAAOA,CAAK,EACZ,KAAK,UAAUA,CAAK,EAC5B,OAAOiI,EAAK,OAAS4P,GAAa,GAAG5P,EAAK,MAAM,EAAG,GAAc,EAAE,GAAKA,CAC1E,ECTM8P,GAA0C,IAAI,IAAc,CAChE,WACA,QACA,WACA,YACA,cACA,OACA,MACF,CAAC,EAcYC,IAAa,CAAE,QAAO,UAAS,OAAM,UAA2B,CAC3E,GAAM,CAAE,KAAMrT,EAAe,EACvBtC,EAAMyV,GAAU9X,CAAK,EACrBiY,EAAoBF,GAAiB,IAAIxG,CAAI,EAAI/E,EAAU,KAC3DvE,EAAOgQ,GAAqB5V,EAClC,OACE,EAAAvD,EAAA,MAACmP,EAAD,CAAW,UAAU,uCAArB,UACGhG,GACC,EAAAnJ,EAAA,KAAC,OAAD,CACE,UAAWC,EAAGmZ,IAAS,UAAY,8DAA8D,EAEhG,SAAAjQ,CACG,IAEN,EAAAnJ,EAAA,KAAC,OAAD,CAAM,UAAU,yCAA0C,SAAA8G,EAAE,sBAAsB,CAAQ,GAE3FqS,GAAqB5V,GACpB,EAAAvD,EAAA,MAAC,UAAD,CAAS,UAAU,aAAnB,WACE,EAAAA,EAAA,MAAC,UAAD,CACE,UAAWC,EACToZ,GAAe,CAAE,QAAS,QAAS,KAAM,IAAK,CAAC,EAC/C,iGACF,EAJF,WAME,EAAArZ,EAAA,KAACsZ,GAAD,CACE,cAAY,OACZ,UAAU,yEACX,GACAxS,EAAE,oBAAoB,CAChB,CACT,MAAA9G,EAAA,KAAC,MAAD,CAAK,UAAU,+EACZ,SAAAuD,CACE,EACE,CACP,OACK,GAEf,ECvDMgW,GAAqB,CACzB,YAAa,CAAE,SAAU,wCAAyC,KAAM,SAAU,EAClF,UAAW,CAAE,SAAU,sCAAuC,KAAM,SAAU,EAC9E,SAAU,CAAE,SAAU,qCAAsC,KAAM,SAAU,EAC5E,QAAS,CAAE,SAAU,oCAAqC,KAAM,QAAS,CAC3E,EAKMC,GAAc,CAClB,KAAM,CAAE,OAAQ,wBAAyB,MAAO,sBAAuB,EACvE,QAAS,CAAE,OAAQ,4BAA6B,MAAO,6BAA8B,CACvF,EAaaC,IAAiB,CAAE,OAAM,OAAM,cAAmC,CAC7E,GAAM,CAAE,KAAM5T,EAAe,EACvB0L,EAAQxO,EAAK,OAASA,EAAK,QAC3B+B,EAAOyU,GAAmBxW,EAAK,WACrC,OACE,EAAA/C,EAAA,MAACiH,EAAD,CACS,QACP,QAAQ,KACR,SACA,SACE,EAAAjH,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,WACE,EAAAA,EAAA,KAACyL,EAAD,CAAO,QAAQ,UAAU,UAAU,YAChC,SAAA1I,EAAK,MACD,IACP,EAAA/C,EAAA,KAACyL,EAAD,CAAO,QAAQ,YAAa,SAAA3E,EAAEmN,GAA0BlR,EAAK,OAAO,CAAS,GAC5E2W,IAAS,QAAS,EAAA1Z,EAAA,KAAC+M,EAAD,CAAY,KAAMjI,EAAK,KAAM,MAAOgC,EAAEhC,EAAK,QAAQ,EAAG,KAAK,IAAM,GAAI,KACvF/B,EAAK,UACJ,EAAA/C,EAAA,KAACkH,EAAD,CAAQ,QAAQ,QAAQ,KAAK,KAAK,WAChC,YAAAlH,EAAA,KAACmH,EAAD,CACE,GAAG,8BACH,OAAQ,CAAE,SAAUpE,EAAK,SAAU,QAASA,EAAK,OAAQ,EACzD,OAAQ,CAAE,OAAQA,EAAK,MAAO,EAE7B,SAAA+D,EAAE,0BAA0B,CACzB,EACA,GACN,KACH6S,GACC,EAAA3Z,EAAA,KAAC6X,EAAD,CACE,KAAK,SACL,MAAO/Q,EAAE,iCAAkC,CAAE,OAAM,CAAC,EACpD,YAAaA,EAAE,sCAAsC,EACrD,aAAcA,EAAE,eAAe,EAC/B,UAAW6S,EACX,SACE,EAAA3Z,EAAA,KAACkH,EAAD,CACE,QAAQ,oBACR,KAAK,UACL,aAAYJ,EAAE,4BAA6B,CAAE,OAAM,CAAC,EAEpD,YAAA9G,EAAA,KAAC8X,GAAD,CAAQ,cAAY,MAAQ,EACtB,EAEX,GACC,IACD,IAxCT,UA2CG4B,IAAS,OAAS,KAAO3W,EAAK,OAAO,SAAW,GAC/C,EAAA/C,EAAA,KAAC,IAAD,CAAG,UAAU,4CAA6C,SAAA8G,EAAE,+BAA+B,CAAK,IAEhG,EAAA9G,EAAA,MAAC6O,EAAD,CAAO,aAAY/H,EAAE,gCAAiC,CAAE,OAAM,CAAC,EAA/D,WACE,EAAA9G,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,sBAAsB,CAAa,IACjD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE0S,GAAYE,EAAK,CAAC,MAAM,CAAa,IACnD,EAAA1Z,EAAA,KAACgP,EAAD,UAAYlI,EAAE0S,GAAYE,EAAK,CAAC,KAAK,CAAa,EAC1C,GACC,IACb,EAAA1Z,EAAA,KAACiP,EAAD,UACGlM,EAAK,OAAO,IAAK,IAChB,EAAA/C,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,MAACmP,EAAD,CAAW,UAAU,YAArB,WACE,EAAAnP,EAAA,KAAC,OAAD,CAAM,UAAU,sBAAuB,SAAA6C,EAAM,KAAY,IACzD,EAAA7C,EAAA,KAAC,OAAD,CAAM,UAAU,kDAAmD,SAAA6C,EAAM,MAAa,EAC7E,KACX,EAAA7C,EAAA,KAACkZ,GAAD,CACE,MAAOrW,EAAM,OACb,QAASA,EAAM,QAAQ,OACvB,KAAMA,EAAM,KACZ,KAAK,QACN,IACD,EAAA7C,EAAA,KAACkZ,GAAD,CAAW,MAAOrW,EAAM,MAAO,QAASA,EAAM,QAAQ,MAAO,KAAMA,EAAM,KAAM,KAAK,OAAS,EACrF,GAZKA,EAAM,OAYX,CACX,CACQ,EACN,CAER,GAAAE,EAAK,OAAO,OAAS,GACpB,EAAA/C,EAAA,KAAC,KAAD,CAAI,UAAU,wDACX,SAAA+C,EAAK,OAAO,IAAK,IAChB,EAAA/C,EAAA,KAAC,KAAD,UAAyC4Z,EAAM,OAAY,EAAlD,GAAGA,EAAM,KAAK,GAAGA,EAAM,MAA2B,CAC5D,CACC,GACF,IACC,GAEX,ECnHMC,GAA6C,IAAI,IAAI,CACzD,gBACA,aACA,aACA,OACF,CAAC,EACKC,GAA2C,IAAI,IAAI,CAAC,WAAY,YAAY,CAAC,EAEtEC,GAAiB,GACxBC,EAAO,UAAYA,EAAO,YACrB,WAELA,EAAO,WAAa,aACf,aAELH,GAAsB,IAAIG,EAAO,QAAQ,EACpC,aAEFF,GAAoB,IAAIE,EAAO,QAAQ,EAAI,WAAa,WAGpDC,GAAuB,CAClC,SAAU,CAAE,SAAU,2BAA4B,KAAM,SAAU,EAClE,WAAY,CAAE,SAAU,6BAA8B,KAAM,SAAU,EACtE,WAAY,CAAE,SAAU,6BAA8B,KAAM,SAAU,EACtE,SAAU,CAAE,SAAU,2BAA4B,KAAM,SAAU,EAClE,SAAU,CAAE,SAAU,2BAA4B,KAAM,OAAQ,CAClE,EAEMC,GAAiC,IAAI,IAAI,CAAC,mBAAoB,aAAa,CAAC,EAC5EC,GAAmC,IAAI,IAAI,CAAC,qBAAsB,eAAe,CAAC,EAG3EC,GAAgB,GACvBF,GAAM,IAAIF,EAAO,IAAI,EAChB,IAEFG,GAAQ,IAAIH,EAAO,IAAI,EAAI,IAAM,ICzC7BK,IAAsB,CAAE,cAAa,UAAoC,CACpF,GAAM,CAAE,KAAMxU,EAAe,EACvByU,EAAUL,GAAqBM,GACrC,OAAO,EAAAva,EAAA,KAAC+M,EAAD,CAAY,KAAMuN,EAAQ,KAAM,MAAOxT,EAAEwT,EAAQ,QAAQ,EAAS,MAAO,EAClF,ECAaE,IAA4B,EAAqB,IAA2B,CACvF,IAAMzZ,EAAQ0Z,GAAeC,EAAa3X,EAAK,YAAY,EACrD4X,EAASlb,EAAS,CACtB,GAAGmb,GAAuB7X,EAAK,SAAUA,EAAK,YAAY,EAC1D,QAASA,EAAK,YAAc,SAC5B,MAAO,EACT,CAAC,EACK8X,EAAUpb,EAAS,CACvB,GAAGqb,GAA+B/X,EAAK,SAAUA,EAAK,aAAcA,EAAK,kBAAoB,EAAE,EAC/F,QAASA,EAAK,mBAAqB,KACnC,MAAO,EACT,CAAC,EAED,MAAO,CACL,QAFaA,EAAK,mBAAqB,KAAO4X,EAAO,MAAM,WAAaE,EAAQ,MAAM,aAEpE,KAClB,MAAO9Z,EAAM,MAAM,YAAc,KACjC,OAAQ4Z,EAAO,KAAOA,EAAO,KAAK,QAAU,UAAa5Z,EAAM,MAAM,QAAU,EACjF,CACF,ECfMga,GAAe,CACnB,IAAK,eACL,IAAK,mBACL,IAAK,uBACP,EAEMC,GAAiB,CACrB,OAAQ,mCACR,OAAQ,mCACR,OAAQ,kCACV,EAQaC,IAAkB,CAAE,cAAa,UAAgC,CAC5E,GAAM,CAAE,KAAMpV,EAAe,EACvB,CAAE,SAAQ,QAAO,UAAW2U,GAAyBE,EAAa3X,CAAI,EACtE,CAAE,aAAcmY,GAAqB,EACrCC,EAAUpY,EAAK,MAAM,SAAW,CAAC,EACjCwO,EAAQ6J,GAAO,OAASC,GAAQ,OAAStY,EAAK,OACpD,OACE,EAAA/C,EAAA,MAACiH,EAAD,CACS,QACP,QAAQ,KACR,SACA,SACE,EAAAjH,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,WACE,EAAAA,EAAA,KAACyL,EAAD,CAAO,QAAQ,UAAW,SAAA3E,EAAEkU,GAAejY,EAAK,UAAU,CAAS,GAClEuY,GAAaC,GACZ,EAAAvb,EAAA,MAACyL,EAAD,CAAO,QAAQ,UAAU,iBAAzB,WACE,EAAAzL,EAAA,KAACwb,GAAD,CAAQ,cAAY,MAAQ,GAC3B1U,EAAE,uBAAuB,CACrB,CACL,SACJ,EAAA9G,EAAA,KAAC,OAAD,CAAM,UAAU,4CAA6C,SAAA+C,EAAK,MAAa,EAC5E,IAdT,UAiBGA,EAAK,OACJ,EAAA/C,EAAA,KAAC,MAAD,CAAK,UAAU,eACb,YAAAA,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAf,WACE,EAAAtY,EAAA,KAACyY,GAAD,CAAe,cAAY,MAAQ,IACnC,EAAAzY,EAAA,KAACwY,EAAD,UACG1R,EAAE,6BAA8B,CAC/B,KAAM/D,EAAK,aAAe,EAC1B,OAAQA,EAAK,eAAiB,CAChC,CAAC,CACe,EACb,GACJ,GACH,KACHA,EAAK,cAAc,OAAS,GAC3B,EAAA/C,EAAA,MAAC,IAAD,CAAG,UAAU,uDAAb,UACG8G,EAAE,8BAA8B,EAAG,IACnC/D,EAAK,cAAc,KAAK,EAAO,KAC9B,EAAA/C,EAAA,MAAC,OAAD,WACG2D,EAAQ,EAAI,KAAO,IACpB,EAAA3D,EAAA,KAACmH,EAAD,CACE,GAAG,wBACH,OAAQ,CAAE,YAAasU,EAAM,EAAG,EAChC,UAAU,+CAET,SAAAA,EAAM,KACH,EACF,GATKA,EAAM,EASX,CACP,CACA,CACD,QACHN,EAAQ,SAAW,GAClB,EAAAnb,EAAA,KAAC,IAAD,CAAG,UAAU,4CAA6C,SAAA8G,EAAE,gCAAgC,CAAK,IAEjG,EAAA9G,EAAA,KAAC,KAAD,CAAI,aAAY8G,EAAE,iCAAkC,CAAE,KAAMyK,CAAM,CAAC,EAAG,UAAU,mBAC7E,SAAA4J,EAAQ,KAAK,EAAQ,IAAU,CAC9B,IAAMO,EAAOtB,GAAaJ,CAAM,EAChC,OACE,EAAAha,EAAA,MAAC,KAAD,CAEE,UAAU,0DAFZ,WAIE,EAAAA,EAAA,KAAC,OAAD,CACE,cAAY,OACZ,UAAWC,EAAG,uCAAwC8a,GAAaW,EAAK,EAEvE,SAAAA,CACG,IACN,EAAA1b,EAAA,KAAC,OAAD,CAAM,UAAU,iBAAkB,SAAA2b,GAAe3B,EAAQqB,EAAQD,CAAK,CAAQ,IAC9E,EAAApb,EAAA,KAACqa,GAAD,CAAoB,YAAaN,GAAcC,CAAM,EAAG,KAAK,IAAM,EACjE,CAXG,KAAGA,EAAO,KAAK,GAAGA,EAAO,SAAW,GAAG,GAAGA,EAAO,UAAY,GAAG,GAAGrW,GAWtE,CAER,CAAC,CACC,EAED,GAEX,ECjGaiY,IAAc,CAAE,SAAQ,cAAgC,CACnE,GAAM,CAAE,KAAM/V,EAAe,EACvBgW,EAAaC,GAAuB,EACpCC,EAAQC,EAAO,UAAU,GAEzBtC,EADUsC,EAAO,UAAU,SAAW,UACXA,EAAO,UAAU,kBAAoB,KAAO,OAAS,UAA9D,OAUxB,OATIA,EAAO,OAAO,SAAW,GAAKA,EAAO,QAAQ,SAAW,GAExD,EAAAhc,EAAA,KAACiN,EAAD,CACE,KAAMzO,GACN,MAAOsI,EAAE,wBAAwB,EACjC,YAAaA,EAAE,mCAAmC,CACnD,IAIH,EAAA9G,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACG0Z,IAAS,QACR,EAAA1Z,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,4BAA4B,CAAK,GACjF,KACHkV,EAAO,OAAO,IAAK,IAClB,EAAAhc,EAAA,KAACib,GAAD,CAAkC,YAAac,EAAa,MAAO,EAA9ChZ,EAAK,MAAyC,CACpE,EACAiZ,EAAO,QAAQ,IAAK,IACnB,EAAAhc,EAAA,KAACyZ,GAAD,CAEQ,OACA,OACN,SACE/B,MAEMmE,EAAW,YACT,CAAE,GAAIE,EAAO,OAAQhZ,EAAK,MAAO,EACjC,CAAE,cAAiBwR,EAAM,QAAQzN,EAAE,4BAA4B,CAAC,CAAE,CACpE,EACF,MAEP,EAZM/D,EAAK,MAYX,CACF,CACE,GAET,ECpDMkZ,GAAmB,CACvB,MAAO,CAAE,SAAU,uBAAwB,KAAM,QAAS,EAC1D,QAAS,CAAE,SAAU,yBAA0B,KAAM,SAAU,CACjE,EAKaC,IAAc,CAAE,cAAgC,CAC3D,GAAM,CAAE,GAAMrW,EAAe,EACvByU,EAAU2B,GAAiBE,GACjC,OAAO,EAAAnc,EAAA,KAAC+M,EAAD,CAAY,KAAMuN,EAAQ,KAAM,MAAO,EAAEA,EAAQ,QAAQ,EAAG,KAAK,IAAM,EAChF,ECVM8B,GAAqB,IAGdC,GAAwB,GAAwC,CAC3E,IAAMC,EAAY,CAAC,GAAG,IAAI,IAAI5P,EAAQ,QAAS,GAAWC,EAAM,SAAW,CAACA,EAAM,QAAQ,EAAI,CAAC,CAAE,CAAC,CAAC,EAC7F4P,EAAW,IAAI,IAAI7P,EAAQ,IAAK,GAAUC,EAAM,OAAO,CAAC,EAC9D,OAAOkB,GAAW,CAChB,QAASyO,EAAU,IAAK,GAAa,CACnC,IAAMtb,EAAQ,CAAE,WAAU,MAAOob,EAAmB,EACpD,MAAO,CACL,SAAU7c,EAAU,QAAQ,kBAAkByB,CAAK,EACnD,YAAeqM,EAAS,cAAc,KAAKrM,CAAK,EAChD,KAAM,CAAE,OAAQ,EAAK,CACvB,CACF,CAAC,EACD,QAAU,IAAa,CACrB,SAAU+M,EAAQ,QAAS,IACxBC,EAAO,MAAM,OAAS,CAAC,GAAG,OAAQ,GAAYuO,EAAS,IAAIC,EAAQ,OAAO,CAAC,CAC9E,EACA,UAAWzO,EAAQ,KAAM,GAAWC,EAAO,SAAS,EACpD,MAAOD,EAAQ,KAAM,GAAWC,EAAO,KAAK,CAAC,EAAE,OAAS,IAC1D,EACF,CAAC,CACH,ECxBayO,IAAa,CAAE,aAC1B,EAAAzc,EAAA,KAAC,KAAD,CAAI,UAAU,2BACX,SAAA0c,EAAO,IAAK,IACX,EAAA1c,EAAA,KAAC,KAAD,UAAyC4Z,EAAM,OAAY,EAAlD,GAAGA,EAAM,KAAK,GAAGA,EAAM,MAA2B,CAC5D,CACC,GCGO+C,IAAgB,CAAE,cAAa,UAA8B,CACxE,GAAM,CAAE,KAAM9W,EAAe,EACvB,CAAE,SAAQ,SAAU2U,GAAyBE,EAAa3X,CAAI,EAC9D6Z,EAAO7Z,EAAK,KAClB,OACE,EAAA/C,EAAA,KAACiH,EAAD,CACE,MAAOH,EAAE,8BAA+B,CAAE,KAAMsU,GAAO,OAASC,GAAQ,OAAStY,EAAK,MAAO,CAAC,EAC9F,QAAQ,KAER,YACEA,EAAK,OAAS+D,EAAE,0BAA2B,CAAE,MAAO/D,EAAK,OAAO,aAAc,CAAC,EAAI,OAGrF,YAAA/C,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACG+C,EAAK,OAAO,OAAS,GACpB,EAAA/C,EAAA,MAACsY,EAAD,CAAO,QAAQ,cAAf,WACE,EAAAtY,EAAA,KAACyY,GAAD,CAAe,cAAY,MAAQ,IACnC,EAAAzY,EAAA,KAACwY,EAAD,WACE,EAAAxY,EAAA,KAACyc,GAAD,CAAW,OAAQ1Z,EAAK,MAAS,EACjB,EACb,CACL,QACH6Z,GAAQA,EAAK,cAAc,OAAS,GACnC,EAAA5c,EAAA,MAAC,UAAD,CAAS,UAAU,YAAY,aAAY8G,EAAE,2BAA2B,EAAxE,WACE,EAAA9G,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,WACE,EAAAA,EAAA,KAAC,KAAD,CAAI,UAAU,wBAAyB,SAAA8G,EAAE,2BAA2B,CAAM,IAC1E,EAAA9G,EAAA,KAAC6c,GAAD,CAAU,MAAO/V,EAAE,2BAA2B,EAAI,SAAAA,EAAE,+BAA+B,CAAY,EAC5F,CACL,MAAA9G,EAAA,KAAC8c,GAAD,CACE,MAAM,SACN,MAAOF,EAAK,cACZ,QAAS7Z,EAAK,QAAQ,MACd,SACD,OACR,EACM,CAET,MAAA/C,EAAA,MAAC,IAAD,CAAG,UAAU,wDAAb,WACE,EAAAA,EAAA,KAACuY,GAAD,CAAc,cAAY,OAAO,UAAU,qBAAuB,GACjEzR,EAAE,gCAAgC,CAClC,IAEJ8V,GAAQA,EAAK,UAAU,OAAS,GAC/B,EAAA5c,EAAA,MAAC,UAAD,CAAS,UAAU,YAAY,aAAY8G,EAAE,uBAAuB,EAApE,WACE,EAAA9G,EAAA,KAAC,KAAD,CAAI,UAAU,wBAAyB,SAAA8G,EAAE,uBAAuB,CAAM,IACtE,EAAA9G,EAAA,KAAC8c,GAAD,CAAU,MAAM,QAAQ,MAAOF,EAAK,UAAmB,SAAe,OAAQ,EACvE,CACP,OACD,GACA,EAEX,EChDMG,GAAsB,CAC1B,cAAe,6CACf,cAAe,6CACf,oBAAqB,mDACrB,qBAAsB,oDACtB,eAAgB,8CAChB,QAAS,uCACT,gBAAiB,8CACnB,EAUaC,IAAa,CAAE,SAAQ,UAA2B,CAC7D,GAAM,CAAE,KAAMnX,EAAe,EACvB,CAAE,YAAawW,GAAqBL,EAAO,OAAO,EAClDiB,EAAiBjB,EAAO,QAAQ,OAAQ,GAAUrP,EAAM,OAAO,OAAS,CAAC,EACzE+K,EAAWtF,GAAkB,IAAI4J,EAAO,UAAU,MAAM,EAC9D,OACE,EAAAhc,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACGgc,EAAO,UAAU,SAAW,WAC3B,EAAAhc,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAU,KAAK,SAA9B,WACE,EAAAtY,EAAA,KAACuY,GAAD,CAAc,cAAY,MAAQ,IAClC,EAAAvY,EAAA,KAACwY,EAAD,UAAmB1R,EAAE,mCAAmC,CAAoB,EACvE,CACL,QACHkV,EAAO,OAAO,SAAS,OAAS,GAC/B,EAAAhc,EAAA,MAACsY,EAAD,CAAO,QAAQ,cAAf,WACE,EAAAtY,EAAA,KAACyY,GAAD,CAAe,cAAY,MAAQ,IACnC,EAAAzY,EAAA,KAAC0Y,GAAD,UAAa5R,EAAE,8BAA8B,CAAc,IAC3D,EAAA9G,EAAA,KAACwY,EAAD,WACE,EAAAxY,EAAA,KAACyc,GAAD,CAAW,OAAQT,EAAO,OAAO,QAAW,EAC5B,EACb,CACL,QACHA,EAAO,OAAO,SAAS,OAAS,GAC/B,EAAAhc,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAf,WACE,EAAAtY,EAAA,KAAC8Y,GAAD,CAAM,cAAY,MAAQ,IAC1B,EAAA9Y,EAAA,KAAC0Y,GAAD,UAAa5R,EAAE,8BAA8B,CAAc,IAC3D,EAAA9G,EAAA,KAACwY,EAAD,WACE,EAAAxY,EAAA,KAACyc,GAAD,CAAW,OAAQT,EAAO,OAAO,QAAW,EAC5B,EACb,CACL,QACHA,EAAO,OAAO,IAAK,IAClB,EAAAhc,EAAA,KAAC2c,GAAD,CAAgC,YAAaX,EAAO,UAAU,GAAU,MAAO,EAA5DjZ,EAAK,MAAuD,CAChF,GACD,EAAA/C,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,gCAAgC,EAAG,QAAQ,KACxD,SAAAmW,EAAe,SAAW,GACzB,EAAAjd,EAAA,MAAC,IAAD,CAAG,UAAU,wDAAb,WACE,EAAAA,EAAA,KAACuY,GAAD,CAAc,cAAY,OAAO,UAAU,qBAAuB,GACjEzR,EAAE,iCAAkC,CAAE,MAAOkV,EAAO,QAAQ,MAAO,CAAC,CACpE,CAEH,MAAAhc,EAAA,KAAC,KAAD,CAAI,UAAU,YACX,SAAAid,EAAe,IAAK,IACnB,EAAAjd,EAAA,MAAC,KAAD,CAAuB,UAAU,oBAAjC,UACG2M,EAAM,UACL,EAAA3M,EAAA,KAACmH,EAAD,CACE,GAAG,8BACH,OAAQ,CAAE,SAAUwF,EAAM,SAAU,QAASA,EAAM,OAAQ,EAC3D,OAAQ,CAAE,OAAQA,EAAM,MAAO,EAC/B,UAAU,6DAET,SAAAA,EAAM,OAASA,EAAM,OAClB,IAEN,EAAA3M,EAAA,KAAC,OAAD,CAAM,UAAU,gBAAiB,SAAA2M,EAAM,OAASA,EAAM,OAAc,IAEtE,EAAA3M,EAAA,KAAC,MAAD,CAAK,UAAU,mBACb,YAAAA,EAAA,KAACyc,GAAD,CAAW,OAAQ9P,EAAM,MAAS,EAC/B,EACH,CAhBK,EAAAA,EAAM,MAgBX,CACL,CACC,EAED,GACNqP,EAAO,cAAc,OAAS,GAC7B,EAAAhc,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,mCAAmC,EAAG,QAAQ,KAC5D,YAAA9G,EAAA,KAAC,KAAD,CAAI,UAAU,oBACX,SAAAgc,EAAO,cAAc,IAAK,IACzB,EAAAhc,EAAA,MAAC,KAAD,YACE,EAAAA,EAAA,MAAC,OAAD,CAAM,UAAU,oBAAhB,UACG2M,EAAM,UAAY7F,EAAE,gBAAgB,EAAE,MAAI6F,EAAM,QAAQ,MAAIA,EAAM,MAC/D,CACN,MAAA3M,EAAA,MAAC,OAAD,CAAM,UAAU,8BAAhB,UACG8G,EAAEiW,GAAoBpQ,EAAM,OAAO,EACnCA,EAAM,OAAS,KAAKA,EAAM,OAAO,GAAK,EACnC,CACJ,KARK,GAAGA,EAAM,QAAQ,GAAGA,EAAM,QAQ/B,CACL,CACC,EACC,GACL,MACJ,EAAA3M,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,4BAA4B,EAAG,QAAQ,KACpD,SAAAoW,EAAS,SAAW,GACnB,EAAAld,EAAA,MAAC,IAAD,CAAG,UAAU,wDAAb,WACE,EAAAA,EAAA,KAACuY,GAAD,CAAc,cAAY,OAAO,UAAU,qBAAuB,GACjEzR,EAAE,iCAAiC,CACnC,CAEH,MAAA9G,EAAA,KAAC,KAAD,CAAI,UAAU,oBACX,SAAAkd,EAAS,IAAK,IACb,EAAAld,EAAA,MAAC,KAAD,CAAqB,UAAU,oCAA/B,WACE,EAAAA,EAAA,KAACkc,GAAD,CAAY,SAAUM,EAAQ,QAAW,IACzC,EAAAxc,EAAA,KAAC,OAAD,CAAM,UAAU,gBAAiB,SAAAwc,EAAQ,YAAcA,EAAQ,OAAc,IAC7E,EAAAxc,EAAA,KAAC,OAAD,CAAM,UAAU,wBAAyB,SAAA8G,EAAEqW,GAAgBX,EAAQ,KAAK,CAAQ,GAC/EA,EAAQ,SAAW,IAAM,MACxB,EAAAxc,EAAA,KAAC,OAAD,CAAM,UAAU,0CAA2C,SAAAwc,EAAQ,MAAa,EAEhF,CAPK,EAAAA,EAAQ,EAOb,CACL,CACC,EAED,GACN9E,IAAajB,EAAK,eAAiBA,EAAK,mBACvC,EAAAzW,EAAA,MAAC,WAAD,CAAU,UAAU,wEAApB,WACE,EAAAA,EAAA,KAAC,SAAD,CAAQ,UAAU,0CAA2C,SAAA8G,EAAE,yBAAyB,CAAU,GACjG2P,EAAK,eACJ,EAAAzW,EAAA,MAACod,GAAD,CAAO,YAAY,aAAnB,WACE,EAAApd,EAAA,KAACqd,GAAD,CACE,GAAG,0BACH,QAAS5G,EAAK,qBACd,gBAAkB,GAAYA,EAAK,wBAAwB6G,IAAY,EAAI,CAC5E,IACD,EAAAtd,EAAA,KAACud,GAAD,CAAY,QAAQ,0BAA0B,UAAU,cACrD,SAAAzW,EAAE,iCAAiC,CAC1B,EACP,CACL,QACH2P,EAAK,kBACJ,EAAAzW,EAAA,MAACod,GAAD,CAAO,YAAY,aAAnB,WACE,EAAApd,EAAA,KAACqd,GAAD,CACE,GAAG,6BACH,QAAS5G,EAAK,wBACd,gBAAkB,GAAYA,EAAK,2BAA2B6G,IAAY,EAAI,CAC/E,IACD,EAAAtd,EAAA,KAACud,GAAD,CAAY,QAAQ,6BAA6B,UAAU,cACxD,SAAAzW,EAAE,oCAAoC,CAC7B,EACP,CACL,OACI,CACR,OACD,GAET,ECpKa0W,OAA0B,CACrC,GAAM,CAAE,KAAM3X,EAAe,EAC7B,OAAQ,EAAsB,IACxB5E,IAGA2N,IAAiB,YACZ9H,EAAE,6BAA6B,EAEpC8H,IAAiB,YACZ9H,EAAE,8BAA8B,EAElC8H,EAAa,WAAW,QAAQ,EAAI9H,EAAE,iCAAiC,EAAI8H,EAEtF,ECAa6O,IAAgB,CAAE,YAAgC,CAC7D,GAAM,CAAE,GAAM5X,EAAe,EACvB6X,EAAiBF,GAAkB,EACnC,CAAE,aAActC,GAAqB,EACrClX,EAASgY,EAAO,UAAU,OAC7B,GAAUnZ,EAAM,UAAU,OAAS,IAAMA,EAAM,YAAY,WAAa,GAAK,CAChF,EAUA,OATImB,EAAO,SAAW,GAElB,EAAAhE,EAAA,KAACiN,EAAD,CACE,KAAM0Q,GACN,MAAO3B,EAAO,OAAO,SAAW,EAAE,wBAAwB,EAAI,EAAE,+BAA+B,EAC/F,YAAa,EAAE,2BAA4B,CAAE,MAAOA,EAAO,SAAU,CAAC,CACvE,IAIH,EAAAhc,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,KAAC,IAAD,CAAG,UAAU,kCACV,WAAE,2BAA4B,CAAE,MAAOgc,EAAO,SAAU,CAAC,CACzD,GACFhY,EAAO,IAAK,IACX,EAAAhE,EAAA,KAACiH,EAAD,CAEE,MAAOpE,EAAM,OACb,QAAQ,KACR,SACA,YAAa,EAAE,4BAA6B,CAAE,MAAOA,EAAM,UAAU,MAAO,CAAC,EAE7E,YAAA7C,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAY,EAAE,0BAA0B,CAAa,GACpDsM,GAAY,EAAAtb,EAAA,KAACgP,EAAD,UAAY,EAAE,wBAAwB,CAAa,GAAI,MACpE,EAAAhP,EAAA,KAACgP,EAAD,CAAW,UAAU,aAAc,WAAE,yBAAyB,CAAa,IAC3E,EAAAhP,EAAA,KAACgP,EAAD,UAAY,EAAE,4BAA4B,CAAa,IACvD,EAAAhP,EAAA,KAACgP,EAAD,UAAY,EAAE,6BAA6B,CAAa,EAChD,GACC,IACb,EAAAhP,EAAA,MAACiP,EAAD,WACGpM,EAAM,UAAU,IAAK,IACpB,EAAA7C,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,gBAClB,SAAAuO,EAAeE,EAAS,aAAcA,EAAS,KAAK,CAC5C,GACVtC,GACC,EAAAtb,EAAA,KAACmP,EAAD,CAAW,UAAU,4CAClB,SAAAyO,EAAS,KAAK,GACN,GACT,MACJ,EAAA5d,EAAA,KAACmP,EAAD,CAAW,UAAU,0BAA2B,SAAAyO,EAAS,MAAM,eAAe,CAAa,IAC3F,EAAA5d,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAe2K,EAAS,UAAU,EAC/E,SAAAA,EAAS,WAAa1K,EAAmB0K,EAAS,UAAU,EAAI,EAAE,cAAc,CACxE,IACX,EAAA5d,EAAA,KAACmP,EAAD,WACE,EAAAnP,EAAA,KAACyL,EAAD,CAAO,QAASmS,EAAS,YAAc,WAAa,YAAc,UAC/D,SAAAA,EAAS,YAAc,WACpB,EAAE,4BAA4B,EAC9B,EAAE,4BAA4B,CAC7B,EACE,EACH,GApBK,GAAGA,EAAS,KAAK,GAAG,GAAGA,EAAS,cAoBrC,CACX,EACA/a,EAAM,YAAcA,EAAM,WAAW,UAAY,GAChD,EAAA7C,EAAA,KAAC+O,EAAD,CAAU,sBACR,YAAA/O,EAAA,KAACmP,EAAD,CAAW,QAASmM,EAAY,EAAI,EAAG,UAAU,wBAC9C,WAAE,+BAAgC,CACjC,MAAOzY,EAAM,WAAW,UACxB,MAAOA,EAAM,WAAW,MAAM,eAAe,CAC/C,CAAC,CACQ,EACH,GACR,IACK,GACN,GACF,EApDA,GAAGA,EAAM,QAAQ,GAAGA,EAAM,SAoD1B,CACR,CACE,GAET,EChFMgb,GAAW,GACfC,GAAazH,EAAO,kBAAkB,GAAKyH,GAAazH,EAAO,kBAAkB,EAEtE0H,IAAe,EAAgB,IAA4C,CACtF,GAAM,CAAE,KAAMlY,EAAe,EACvBmY,EAAOC,GAAiB,EACxBjK,EAAWkK,GAAqB,EAChCxU,EAASyU,GAAmB,EAC5B,CAACC,EAAsBC,IAAA,EAA2BnW,YAAS,EAAK,EAChE,CAACoW,EAAyBC,IAAA,EAA8BrW,YAAS,EAAK,EACtE,CAACsW,EAAcC,IAAA,EAAmBvW,YAAS,EAAK,EAEhD,CAACwW,EAAkBC,IAAA,EAAuBzW,YAAwB,IAAI,EAGtE0W,EACJvU,EAAI,SAAW,UAAYA,EAAI,OAAO,OAAS,oBAAsBqU,IAAqBrU,EAAI,UAC1FwU,EAAQL,GAAgBI,EACxB,CAACE,EAAYC,KAAA,EAAiB7W,YAAS8T,EAAO,aAAa,EAC7DA,EAAO,gBAAkB8C,IAC3BC,GAAc/C,EAAO,aAAa,EAClCqC,EAAwB,EAAK,EAC7BE,EAA2B,EAAK,GAGlC,IAAM7K,EAAOsI,EAAO,KACdgD,GAAStL,GAAM,OACfuL,GAAgBD,IAAQ,UAAY,GACpCE,EAAmBF,IAAQ,aAAe,GAC1CG,IACH,CAACF,IAAiBb,KAA0B,CAACc,GAAoBZ,GAC9D1G,GAAYvN,EAAI,eAAiBA,EAAI,gBACrC+U,IAAWJ,IAAQ,SAAS,QAAU,GAAK,EAC3CK,GACJjN,GAAkB,IAAI/H,EAAI,MAAM,GAAKqJ,IAAS,QAAakE,GAAY,GAAK,CAACwH,IAAW,CAACP,EACrFS,GAAkB,CACtB,GAAIL,GAAgB,CAAE,oBAAqB,EAAK,EAAI,CAAC,EACrD,GAAIC,EAAmB,CAAE,uBAAwB,EAAK,EAAI,CAAC,CAC7D,EAGMK,GAAS,KAAO,IAAkC,CACtD,GAAI,CACF,MAAMC,EAAM,CACd,OAASnJ,EAAO,CAEd,GAAIwH,GAAQxH,CAAK,EAAG,CAClBoI,EAAgB,EAAI,EACpB,MACF,CACA,MAAMpI,CACR,CACF,EA8CA,MAAO,CACL,iBACA,mBACA,uBACA,0BACA,0BACA,6BACA,gBACA,WACA,SAAU2H,EAAK,WAAatU,EAAO,UACnC,QAtDe,GACf6V,GAAO,SAAY,CACjB,GAAI,CAAC7L,EACH,OAEF,IAAI+L,EAAkB/L,EAAK,UAAU,QACjCgM,IAA2B,QAAaA,IAA2BrV,EAAI,yBAKzE,GAAkB,MAJIX,EAAO,YAAY,CACvC,GAAIW,EAAI,GACR,MAAO,CAAE,yBAAwB,iBAAgB,CACnD,CAAC,GACyB,SAE5B,IAAM2D,EAAS,MAAMgQ,EAAK,YAAY,CACpC,GAAI3T,EAAI,GACR,MAAO,CACL,kBACA,GAAGiV,GACH,aAAc5L,EAAK,QAAQ,QAAS,GAClC/G,EAAM,eAAiB,KAAO,CAAC,EAAI,CAAC,CAAE,OAAQA,EAAM,OAAQ,aAAcA,EAAM,YAAa,CAAC,CAChG,CACF,CACF,CAAC,EACGqB,EAAO,SAAW,UACpBuG,EAAM,QAAQzN,EAAE,yBAA0B,CAAE,IAAKkH,EAAO,iBAAmB,EAAG,CAAC,CAAC,EACvEA,EAAO,SAAW,WAC3BuG,EAAM,KAAKzN,EAAE,gCAAgC,CAAC,EAE9CyN,EAAM,MAAMzN,EAAE,2BAA2B,CAAC,CAE9C,CAAC,EAyBD,WAvBkB,GAClByY,GAAO,SAAY,CACZ7L,IAGL,MAAMM,EAAS,YAAY,CACzB,GAAI3J,EAAI,GACR,MAAO,CAAE,KAAI,gBAAiBqJ,EAAK,UAAU,QAAS,GAAG4L,EAAgB,CAC3E,CAAC,EACD/K,EAAM,QAAQzN,EAAE,0BAA0B,CAAC,EAC7C,CAAC,EAcD,cAAekN,EAAS,MACxB,cAAeA,EAAS,MACxB,WAAYA,EAAS,UACrB,QACA,QAAS,SAAY,CAEnB,MAAMgI,EAAO,QAAQ,EACrByC,EAAgB,EAAK,EACrBE,EAAoBtU,EAAI,SAAS,CACnC,CACF,CACF,ECzHasV,IAAiB,CAAE,SAA8B,CAC5D,GAAM,CAAE,GAAM9Z,EAAe,EACvB4O,GAAA,EAAU9J,SAAM,EAChB+J,GAAA,EAAU/J,SAAM,EAChB,CAACwG,EAAMwD,IAAA,EAAWzM,YAAS,EAAK,EAChC,CAACqJ,EAAOqO,IAAA,EAAY1X,YAASmC,EAAI,KAAK,EACtCX,EAASyU,GAAmB,EAClC,OACE,EAAAne,EAAA,MAACkV,GAAD,CACQ,OACN,aAAe,GAAS,CAClBxL,EAAO,YAGXiL,EAAQvM,CAAI,EACRA,IACFwX,EAASvV,EAAI,KAAK,EAClBX,EAAO,MAAM,GAEjB,EACA,SAZF,WAcE,EAAA1J,EAAA,KAACoV,GAAD,CAAgB,WACd,YAAApV,EAAA,KAACkH,EAAD,CAAQ,QAAQ,QAAQ,KAAK,UAAU,aAAY,EAAE,uBAAuB,EAC1E,YAAAlH,EAAA,KAAC4M,GAAD,CAAQ,cAAY,MAAQ,EACtB,EACM,IAChB,EAAA5M,EAAA,KAACsV,GAAD,CAAgB,MAAM,QAAQ,kBAAiBb,EAAS,UAAU,OAChE,YAAAzU,EAAA,MAAC,OAAD,CACE,cACA,UAAU,YACV,SAAW,GAAU,CACnB+J,EAAM,eAAe,EACrB,IAAM3B,EAAOmJ,EAAM,KAAK,EACxB,GAAI,CAACnJ,GAAQA,IAASiC,EAAI,MAAO,CAC/BsK,EAAQ,EAAK,EACb,MACF,CACArD,GACE5H,EAAO,YAAY,CAAE,GAAIW,EAAI,GAAI,MAAO,CAAE,MAAOjC,EAAM,gBAAiBiC,EAAI,OAAQ,CAAE,CAAC,CACzF,CAAC,CAAC,KAAM,GAAW,CACb2D,EAAO,KACT2G,EAAQ,EAAK,EACbJ,EAAM,QAAQ,EAAE,wBAAwB,CAAC,EAE7C,CAAC,CACH,EAlBF,WAoBE,EAAAvU,EAAA,KAAC,QAAD,CAAO,GAAIyU,EAAS,QAASC,EAAS,UAAU,wBAC7C,WAAE,sBAAsB,CACpB,IACP,EAAA1U,EAAA,KAAC8J,GAAD,CACE,GAAI4K,EACJ,MAAOnD,EACP,UAAW,IACX,aAAa,MACb,SAAW,GAAUqO,EAAS7V,EAAM,OAAO,KAAK,CACjD,IACD,EAAA/J,EAAA,KAAC+R,GAAD,CAAW,MAAOrI,EAAO,KAAQ,IACjC,EAAA1J,EAAA,MAAC,MAAD,CAAK,UAAU,yBAAf,WACE,EAAAA,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,YAAeyN,EAAQ,EAAK,EAC3E,WAAE,eAAe,CACZ,IACR,EAAA3U,EAAA,KAACwV,GAAD,CACE,KAAK,KACL,QAAS9L,EAAO,UAChB,aAAc,EAAE,eAAe,EAC/B,SAAU,CAAC6H,EAAM,KAAK,EAErB,WAAE,oBAAoB,CACX,EACX,GACD,GACQ,EACT,GAEb,ECpFMsO,GAAgB,CACpB,QAAS,CAAE,SAAU,2BAA4B,KAAM,SAAU,EACjE,QAAS,CAAE,SAAU,2BAA4B,KAAM,SAAU,EACjE,WAAY,CAAE,SAAU,6BAA8B,KAAM,SAAU,EACtE,aAAc,CAAE,SAAU,+BAAgC,KAAM,OAAQ,EACxE,mBAAoB,CAAE,SAAU,oCAAqC,KAAM,SAAU,EACrF,SAAU,CAAE,SAAU,4BAA6B,KAAM,SAAU,EACnE,UAAW,CAAE,SAAU,6BAA8B,KAAM,WAAY,EACvE,YAAa,CAAE,SAAU,+BAAgC,KAAM,OAAQ,EACvE,SAAU,CAAE,SAAU,4BAA6B,KAAM,UAAW,EACpE,QAAS,CAAE,SAAU,2BAA4B,KAAM,SAAU,EACjE,OAAQ,CAAE,SAAU,0BAA2B,KAAM,QAAS,EAC9D,UAAW,CAAE,SAAU,6BAA8B,KAAM,OAAQ,EACnE,iBAAkB,CAAE,SAAU,mCAAoC,KAAM,UAAW,EACnF,gBAAiB,CAAE,SAAU,kCAAmC,KAAM,UAAW,EACjF,gBAAiB,CAAE,SAAU,kCAAmC,KAAM,SAAU,EAChF,cAAe,CAAE,SAAU,gCAAiC,KAAM,QAAS,CAC7E,EAEMC,GAAe,GAAqDC,KAAQF,GAKrEG,IAAY,CAAE,QAAO,UAA0B,CAC1D,GAAM,CAAE,KAAMna,EAAe,EACvBgN,EAAaH,EAAc,EAC3B4H,EAAUwF,GAAY/V,EAAM,IAAI,EAAI8V,GAAc9V,EAAM,MAAQ,OACtE,OACE,EAAA/J,EAAA,MAAC,KAAD,CAAI,UAAU,aAAd,WACE,EAAAA,EAAA,MAAC,OAAD,CAAM,cAAY,OAAO,UAAU,6BAAnC,WACE,EAAAA,EAAA,KAAC,OAAD,CAAM,UAAU,uEAAyE,GACxFigB,EAAO,MAAO,EAAAjgB,EAAA,KAAC,OAAD,CAAM,UAAU,uBAAyB,EACpD,CACN,MAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,gCAAf,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,WACE,EAAAA,EAAA,KAAC+M,EAAD,CACE,KAAMuN,GAAS,MAAQ,UACvB,MAAOA,EAAUxT,EAAEwT,EAAQ,QAAQ,EAAIvQ,EAAM,KAC7C,KAAM,GACN,KAAK,IACN,GACAA,EAAM,SAAU,EAAA/J,EAAA,KAAC,OAAD,CAAM,UAAU,UAAW,SAAA+J,EAAM,OAAc,GAAI,KACnEA,EAAM,WAAa,KAQhB,MAPF,EAAA/J,EAAA,KAACmH,EAAD,CACE,GAAG,kBACH,OAAQ,CAAE,IAAK,OAAO4C,EAAM,QAAQ,CAAE,EACtC,UAAU,qEAET,SAAAjD,EAAE,oBAAqB,CAAE,IAAKiD,EAAM,QAAS,CAAC,CAC3C,GAEPA,EAAM,iBACL,EAAA/J,EAAA,KAACmH,EAAD,CACE,GAAG,sCACH,OAAQ,CAAE,MAAO4C,EAAM,eAAgB,EACvC,UAAU,uDAET,SAAAjD,EAAE,4BAA4B,CAC3B,GACJ,IACD,CACL,MAAA9G,EAAA,MAAC,IAAD,CAAG,UAAU,kCAAb,UACG6S,EAAW9I,EAAM,KAAK,EAAE,KAAG,KAC5B,EAAA/J,EAAA,KAAC,OAAD,CAAM,SAAU+J,EAAM,GAAI,MAAOkJ,EAAelJ,EAAM,EAAE,EACrD,SAAAmJ,EAAmBnJ,EAAM,EAAE,CACxB,EACL,CACA,GACH,KAER,ECrEamW,IAAe,CAAE,iBAAoC,CAChE,GAAM,CAAE,GAAMra,EAAe,EACvBsa,EAAWC,GAAqB1F,CAAW,EACjD,OACE,EAAA1a,EAAA,KAACsQ,EAAD,CACE,MAAO6P,EACP,QAAU,GAAWE,EAAO,SAAW,EACvC,OAAO,EAAArgB,EAAA,KAACiN,EAAD,CAAY,KAAMqT,GAAS,MAAO,EAAE,wBAAwB,CAAI,GAErE,aACA,EAAAtgB,EAAA,KAAC,KAAD,CAAI,aAAY,EAAE,uBAAuB,EAAG,UAAU,qCACnD,SAAAqgB,EAAO,KAAK,EAAO,KAClB,EAAArgB,EAAA,KAACggB,GAAD,CAES,QACP,KAAMrc,IAAU0c,EAAO,OAAS,CACjC,EAHM,GAAGtW,EAAM,GAAG,GAAGA,EAAM,KAAK,GAAGpG,GAGnC,CACF,CACC,EAEG,EAEf,ECVMmM,GAAiB,CACrB,QAAS,uBACT,OAAQ,sBACR,UAAW,yBACX,SAAU,uBACZ,EAKayQ,IAAQ,CAAE,SAAqB,CAC1C,GAAM,CAAE,GAAM1a,EAAe,EACvBgN,EAAaH,EAAc,EAC3BhK,EAAM8X,GAAU,CAAE,KAAM,2BAA4B,CAAC,CAAC,CAAC,KAAO,UAC9DhY,EAAWsN,EAAY,CAAE,KAAM,uBAAwB,CAAC,EACxDkG,EAASyE,GAAmBpW,CAAG,EAC/BoM,EAAOsH,GAAY1T,EAAK2R,CAAM,EAC9BlJ,EAASX,GAA0B9H,EAAI,QACvCqN,EAAWtF,GAAkB,IAAI/H,EAAI,MAAM,EAC3CuN,EAAYvN,EAAI,eAAiBA,EAAI,gBACrCqW,EAAO,CACX,EAAE,0BAA2B,CAAE,KAAM7N,EAAWxI,EAAI,SAAS,EAAG,GAAI6I,EAAmB7I,EAAI,SAAS,CAAE,CAAC,EACvG,EAAE,oBAAqB,CAAE,MAAOuN,CAAU,CAAC,EAC3CvN,EAAI,SAAW,aAAeA,EAAI,aAC9B,EAAE,uBAAwB,CAAE,GAAI4I,EAAe5I,EAAI,YAAY,CAAE,CAAC,EAClE,EACN,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,KAAK,EACb,OACE,EAAArK,EAAA,KAACqQ,EAAD,WACE,EAAArQ,EAAA,MAACsP,GAAD,CACE,MAAO5G,EACP,cAAgB,GAAU,KAAKF,EAAS,CAAE,OAAQ,CAAE,IAAKtH,CAAsB,EAAG,QAAS,EAAK,CAAC,EACjG,UAAU,QAHZ,WAKE,EAAAlB,EAAA,KAACiQ,EAAD,CACE,UACA,WAAY,CAAC,CAAE,MAAO,EAAE,eAAe,EAAG,KAAM0Q,GAAY,CAAE,GAAI,UAAW,CAAC,CAAE,CAAC,EACjF,MAAOtW,EAAI,MACX,OACE,EAAArK,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC+M,EAAD,CAAY,KAAM+F,EAAO,KAAM,MAAO,EAAEA,EAAO,QAAQ,CAAI,GAC1D4E,GAAW,EAAA1X,EAAA,KAAC2f,GAAD,CAAoB,KAAM,GAAI,IAC1C,IAEE,OACN,SAAS,EAAA3f,EAAA,KAACoX,GAAD,CAAc,MAAW,MAAO,GACzC,MACE,EAAApX,EAAA,KAACuP,GAAD,CAAU,QAAQ,YAAY,aAAY,EAAE,oBAAoB,EAC7D,SAAAqR,GAAgB,IAAK,IACpB,EAAA5gB,EAAA,KAACwP,GAAD,CAAuB,MAAO9O,EAC3B,WAAEoP,GAAepP,EAAI,CACX,EAFKA,CAEL,CACd,CACO,EAEb,IACD,EAAAV,EAAA,KAACqY,GAAD,CACO,MACC,OACN,QAAS2D,EAAO,MAAM,SAAW,CAAC,EAClC,wBAAyBtE,GAAYhP,IAAQ,QAC9C,IACD,EAAA1I,EAAA,KAACsQ,EAAD,CAAW,MAAO0L,EAAQ,YAAa,EACnC,aACA,EAAAhc,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACyP,EAAD,CAAa,MAAM,UACjB,YAAAzP,EAAA,KAAC4b,GAAD,CAAY,OAAQlI,EAAgB,UAAW,EACpC,IACb,EAAA1T,EAAA,KAACyP,EAAD,CAAa,MAAM,SACjB,YAAAzP,EAAA,KAACgd,GAAD,CAAW,OAAQtJ,EAAY,MAAO,EAC3B,IACb,EAAA1T,EAAA,KAACyP,EAAD,CAAa,MAAM,YACjB,YAAAzP,EAAA,KAACyd,GAAD,CAAc,OAAQ/J,CAAO,EAClB,EACb,GAEK,IACX,EAAA1T,EAAA,KAACyP,EAAD,CAAa,MAAM,WACjB,YAAAzP,EAAA,KAACkgB,GAAD,CAAa,YAAa7V,EAAI,EAAK,EACxB,EACT,CACF,IAEV,EClGawW,OAAkB,CAC7B,GAAM,CAAE,eAAgBC,GAAU,CAAE,KAAM,2BAA4B,CAAC,EACjE,CAAE,oBAAqBzO,EAAsB,EAC7ChI,EAAM0W,GAAarG,CAAW,EAQpC,OAPKzE,GAQH,EAAAjW,EAAA,KAACsQ,EAAD,CAAW,MAAOjG,EAAK,YAAa,EAChC,aAAS,EAAArK,EAAA,KAACugB,GAAD,CAAM,IAAK7M,CAAO,EACpB,IART,EAAA1T,EAAA,KAACqQ,EAAD,WACE,EAAArQ,EAAA,KAACkW,GAAD,CAAW,EACP,EAQZ,ECjBa8K,IAAiB,EAAc,CAAE,UAAS,QAAO,WAA0C,CACtG,IAAMvf,EAAM,IAAI,IAAI1C,CAAI,EAQxB,OAPI6Q,GACFnO,EAAI,aAAa,IAAI,OAAQmO,CAAO,EAElC5O,GAAO,KAAK,GACdS,EAAI,aAAa,IAAI,QAAST,CAAK,EAErCS,EAAI,aAAa,IAAI,QAASwf,CAAK,EAC5Bxf,EAAI,IACb,ECZayf,GAAoB,GAA8B,CAC7D,IAAMtR,EAAUjH,GAAmB,EAC7BsY,EAAQE,GAAkB,EAChC,OAAOH,GAAcphB,GAAqB,EAAG,CAAE,UAAS,QAAO,OAAM,CAAC,CACxE,ECCMyI,GAAQC,GAAY,sBAAsB,EAOnC8Y,OAAgB,CAC3B,GAAM,CAAE,KAAMvb,EAAe,EACvB,CAAE,SAAUwC,GAAM,UAAU,EAC5BgZ,EAAMH,GAAiBlgB,CAAK,EAC5BsgB,EAAYxhB,GAA8B,EAC1CyR,EAAQzK,EAAE,uBAAuB,EACvC,OACE,EAAA9G,EAAA,MAACqQ,EAAD,CAAM,MAAM,OAAZ,WACE,EAAArQ,EAAA,KAACiQ,EAAD,CAAmB,QAAO,OAAO,EAAAjQ,EAAA,KAAC6c,GAAD,CAAU,MAAOtL,EAAQ,SAAAzK,EAAE,sBAAsB,CAAY,EAAI,GACjGwa,EAAU,WACT,EAAAthB,EAAA,KAACuhB,GAAD,CAAc,KAAM,CAAI,GACtBD,EAAU,MACZ,EAAAthB,EAAA,KAAC,SAAD,CACE,MAAO8G,EAAE,uBAAuB,EAC3B,MACL,UAAU,yIACX,IAED,EAAA9G,EAAA,KAACiN,EAAD,CACE,KAAMrO,GACN,MAAOkI,EAAE,6BAA6B,EACtC,YAAaA,EAAE,wCAAwC,CACxD,EAEC,GAEV,ECtCM1H,GAAS,CAAE,OAAQ,EAAK,EAEjBoiB,GAAW,GACtB/hB,EAAS,CACP,SAAUF,EAAU,WAAW,KAAK,KAAKyB,CAAK,EAC9C,YAAeqM,EAAS,KAAK,KAAKrM,CAAK,EACvC,gBAAiBygB,GACjB,KAAMriB,EACR,CAAC,EAGUsiB,OACXjiB,EAAS,CACP,SAAUF,EAAU,WAAW,KAAK,QACpC,YAAe8N,EAAS,KAAK,QAAQ,EACrC,KAAMjO,EACR,CAAC,EAGUuiB,OAAoB,CAC/B,IAAMC,EAAcC,EAAe,EACnC,OAAOxY,EAAY,CACjB,YAAa,CAAC,OAAQ,OAAO,EAC7B,WAAa,GAAeyY,OAAezU,EAAS,KAAK,MAAM3H,CAAE,CAAC,EAClE,cAAiBkc,EAAY,kBAAkB,CAAE,SAAUriB,EAAU,WAAW,KAAK,GAAI,CAAC,CAC5F,CAAC,CACH,ECxBMwiB,GAAoB,GAGbC,OAAa,CACxB,GAAM,CAAE,KAAMnc,EAAe,EACvBoc,EAAOT,GAAQ,CAAE,OAAQ,OAAQ,MAAOO,EAAkB,CAAC,EAC3DG,EAAWP,GAAY,EACvBQ,EAAS,GACbD,EAAS,OAAOE,EAAI,GAAI,CACtB,cAAiB7N,EAAM,QAAQzN,EAAE,0BAA2B,CAAE,KAAMsb,EAAI,IAAK,CAAC,CAAC,CACjF,CAAC,EACH,OACE,EAAApiB,EAAA,KAACsQ,EAAD,CAAW,MAAO2R,EAAM,YAAa,EACjC,aACA,EAAAjiB,EAAA,KAAC,KAAD,CAAI,aAAY8G,EAAE,8BAA8B,EAAG,UAAU,yBAC1D,SAAA4M,EAAK,MAAM,IAAK,IACf,EAAA1T,EAAA,MAAC,KAAD,CAAiB,UAAU,8CAA3B,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,UAAf,WACE,EAAAA,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAAoiB,EAAI,IAAQ,GAC3DA,EAAI,WACH,EAAApiB,EAAA,KAAC,IAAD,CAAG,UAAU,0CAA0C,MAAOoiB,EAAI,UAC/D,SAAAA,EAAI,SACJ,GACD,IACD,CACL,MAAApiB,EAAA,KAACkH,EAAD,CACE,QAAQ,UACR,KAAK,KACL,SAAUgb,EAAS,UACnB,aAAYpb,EAAE,6BAA8B,CAAE,KAAMsb,EAAI,IAAK,CAAC,EAC9D,YAAeD,EAAMC,CAAG,EAEvB,SAAAtb,EAAE,uBAAuB,CACpB,EACN,CAlBK,EAAAsb,EAAI,EAkBT,CACL,CACC,EAEG,EAEf,ECpCaC,OAAmB,CAC9B,GAAM,CAAE,KAAMxc,EAAe,EACvB6H,EAAUgU,GAAc,EACxB,CAACY,EAAQC,IAAA,EAAara,YAAS,EAAK,EACpCsa,EAAO9U,EAAQ,MAAM,OAAO,MAAQ,EAI1C,OAHI8U,IAAS,EACJ,MAGP,EAAAxiB,EAAA,MAACiH,EAAD,CAAO,MAAOH,EAAE,8BAA8B,EAA9C,WACE,EAAA9G,EAAA,MAAC,MAAD,CAAK,UAAU,oDAAf,WACE,EAAAA,EAAA,KAAC+M,EAAD,CAAY,KAAK,SAAS,MAAOjG,EAAE,0BAA2B,CAAE,MAAO0b,CAAK,CAAC,EAAG,KAAK,IAAM,IAC3F,EAAAxiB,EAAA,KAACkH,EAAD,CAAQ,QAAQ,OAAO,KAAK,KAAK,gBAAeob,EAAQ,YAAeC,EAAW,GAAS,CAACpR,CAAI,EAC7F,SAASrK,EAATwb,EAAW,8BAAmC,6BAA6B,CACtE,EACL,CACJ,GAAAA,GAAS,EAAAtiB,EAAA,KAACgiB,GAAD,CAAO,GAAI,IAChB,GAEX,ECtBaS,OAAmB,CAC9B,GAAM,CAAE,KAAM5c,EAAe,EACvB6c,EAASC,GAAwB,EACvC,OACE,EAAA3iB,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,0BAA0B,EACxC,YAAA9G,EAAA,KAACsQ,EAAD,CAAW,MAAOoS,EAAQ,YAAa,EACnC,YAAS,CACT,IAAME,EAAS,IAAI,IAAIlP,EAAK,MAAM,KAAK,CAAE,OAAM,WAAY,CAACmP,EAAMC,CAAK,CAAC,CAAC,EACnE3R,EAAO4R,GAAW,OAAQ,IAAUH,EAAO,IAAIC,CAAI,GAAK,GAAK,CAAC,EAC9DG,EAAQ7R,EAAK,QAAQ,EAAK,IAAS8R,GAAOL,EAAO,IAAIC,CAAI,GAAK,GAAI,CAAC,EACzE,OACE,EAAA7iB,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,oCAAf,WACE,EAAAA,EAAA,KAAC+M,EAAD,CACE,KAAMiW,EAAQ,EAAI,UAAY,UAC9B,MAAOlc,EAAE,0BAA2B,CAAE,MAAOkc,CAAM,CAAC,CACrD,IACD,EAAAhjB,EAAA,KAACmH,EAAD,CAAM,GAAG,IAAI,UAAU,uDACpB,SAAAL,EAAE,wBAAwB,CACvB,EACH,CACJ,GAAAqK,EAAK,OAAS,GACb,EAAAnR,EAAA,KAAC,KAAD,CAAI,UAAU,oBACX,SAAAmR,EAAK,IAAK,IACT,EAAAnR,EAAA,MAAC,KAAD,CAAe,UAAU,6BAAzB,WACE,EAAAA,EAAA,KAAC,OAAD,UAAO8G,EAAEqW,GAAgB0F,EAAK,CAAQ,IACtC,EAAA7iB,EAAA,KAAC,OAAD,CAAM,UAAU,eAAgB,SAAA4iB,EAAO,IAAIC,CAAI,CAAQ,EACrD,CAHK,EAAAA,CAGL,CACL,CACC,IAEJ,EAAA7iB,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,0BAA0B,CAAK,EAEhF,GAET,CACS,EACN,EAEX,EC1Caoc,OAAoB,CAC/B,GAAM,CAAE,KAAMrd,EAAe,EACvBsd,EAAWC,GAAY,EAC7B,GAAI,CAACD,EAAS,KACZ,OAAO,KAET,IAAMlV,EAAUkV,EAAS,KAAK,OAAQ,GAAYE,EAAQ,OAAO,EAC3DC,EAAUrV,EAAQ,OAAQ,GAAYoV,EAAQ,cAAc,SAAW,MAAM,CAAC,CAAC,OACrF,OACE,EAAArjB,EAAA,MAAC,MAAD,CAAK,UAAU,oDAAf,WACE,EAAAA,EAAA,KAAC,KAAD,WACE,EAAAA,EAAA,KAACmH,EAAD,CACE,GAAG,uBACH,UAAU,qEAET,SAAAL,EAAE,uBAAuB,CACtB,EACJ,IACJ,EAAA9G,EAAA,MAAC,KAAD,CAAI,UAAU,yBAAd,WACE,EAAAA,EAAA,KAAC+M,EAAD,CACE,KAAK,UACL,MAAOjG,EAAE,+BAAgC,CAAE,MAAOmH,EAAQ,MAAO,CAAC,EAClE,KAAK,IACN,IACD,EAAAjO,EAAA,KAAC+M,EAAD,CACE,KAAMuW,EAAU,EAAI,SAAW,QAC/B,MAAOxc,EAAE,+BAAgC,CAAE,MAAOwc,CAAQ,CAAC,EAC3D,KAAK,IACN,EACC,CACD,KAET,EChCaC,OAAuB,CAClC,GAAM,CAAE,KAAM1d,EAAe,EACvB,CAAE,qBAAsBwM,EAAsB,EAIpD,OAHKmR,GAIH,EAAAxjB,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,uBAAuB,EACrC,YAAA9G,EAAA,KAAC,KAAD,CAAI,UAAU,YACZ,YAAAA,EAAA,KAACkjB,GAAD,CAAc,EACZ,EACC,GAPA,IASX,ECdaO,GAAc,GAAqB,CAC9C,IAAM9gB,EAAS+gB,GAAe,OAAO,EAE/BnV,EAAQX,IADR,EAAW5H,gBAAerD,EAAO,MAAQ,CAAC,GAAG,KAAK,CAAE,gBAAiBuD,EAAW,EAAE,EAAG,CAACvD,EAAO,IAAI,CACvE,EAAUsL,GAAWtL,EAAO,SAAS,EAC/D2Z,GAAA,EAAYtW,eACV,IAAI,KAAKrD,EAAO,MAAQ,CAAC,GAAG,KAAK,CAAE,gBAAiB,CAACuD,EAAW,GAAIA,EAAW,MAAM,CAAC,CAAC,EAC7F,CAACvD,EAAO,IAAI,CACd,EACA,MAAO,CACL,GAAG4L,EACH,UAAW5L,EAAO,WAAa4L,EAAM,UACrC,MAAO5L,EAAO,OAAS4L,EAAM,MAC7B,WAAa,GAAoB+N,EAAU,IAAInP,CAAO,GAAKA,EAC3D,YAAaoB,EAAM,WAAW,QAAQ,EAAK,IAAc0U,EAAMtV,EAAU,SAAU,CAAC,CACtF,CACF,ECXagW,IAAa,CAAE,SAAQ,gBAAiC,CACnE,GAAM,CAAE,KAAM9d,EAAe,EACvB+d,EAAU,IAAI,IACpB,IAAK,IAAM/gB,KAASmB,EAClB4f,EAAQ,IAAI/gB,EAAM,QAAS,CAAC,GAAI+gB,EAAQ,IAAI/gB,EAAM,OAAO,GAAK,CAAC,EAAIA,CAAK,CAAC,EAE3E,IAAMghB,EAAQ,CAAC,GAAGD,EAAQ,QAAQ,CAAC,CAAC,CAAC,SAAS,CAACzW,EAAS+B,KAAW,CACjE,IAAMlC,EAAW8W,EAAW3W,CAAO,EACnC,OAAO+B,EAAM,MAAO,GAAS6U,EAAK,YAAc,UAAU,EACtD,CAACjd,EAAE,0BAA2B,CAAE,MAAOkG,CAAS,CAAC,CAAC,EAClDkC,EAAM,OAAQ,GAAS6U,EAAK,YAAc,UAAU,CAAC,CAAC,IAAK,GAAS,GAAG/W,EAAS,GAAG+W,EAAK,YAAY,CAC1G,CAAC,EACD,OACE,EAAA/jB,EAAA,KAAC,OAAD,CAAM,UAAU,mCAAmC,MAAO6jB,EAAM,KAAK,IAAI,EACtE,SAAAA,EAAM,KAAK,IAAI,CACZ,EAEV,ECXaG,OAAqB,CAChC,GAAM,CAAE,KAAMne,EAAe,EACvB6X,EAAiBF,GAAkB,EACnCyG,EAAUR,GAAW,EAAI,EAwD/B,OACE,EAAAzjB,EAAA,MAACiH,EAAD,CACE,MAAOH,EAAE,2BAA2B,EACpC,YAAaA,EAAE,2BAA4B,CAAE,MAAOmd,EAAQ,YAAa,MAAiB,CAAC,EAC3F,SAHF,UAKGA,EAAQ,SAAW,MAClB,EAAAjkB,EAAA,KAAC,IAAD,CAAG,UAAU,uDACV,SAAA8G,EAAE,0BAA0B,CAC5B,GA/DHmd,EAAQ,WACH,EAAAjkB,EAAA,KAACuhB,GAAD,CAAc,KAAM,CAAI,GAE7B0C,EAAQ,OACH,EAAAjkB,EAAA,KAACkkB,GAAD,CAAY,MAAOD,EAAQ,MAAO,YAAe,KAAKA,EAAQ,QAAQ,CAAI,GAE/EA,EAAQ,WAAW,SAAW,GAE9B,EAAAjkB,EAAA,KAACiN,EAAD,CAAY,KAAM0Q,GAAO,KAAK,QAAQ,MAAO7W,EAAE,yBAA0B,CAAE,OAAkB,CAAC,CAAI,IAIpG,EAAA9G,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,0BAA0B,CAAa,IACrD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,qBAAqB,CAAa,IAChD,EAAA9G,EAAA,KAACgP,EAAD,CAAW,UAAU,aAAc,SAAAlI,EAAE,uBAAuB,CAAa,IACzE,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,4BAA4B,CAAa,IACvD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,qBAAqB,CAAa,EACxC,GACC,IACb,EAAA9G,EAAA,KAACiP,EAAD,UACGgV,EAAQ,WAAW,IAAK,IACvB,EAAAjkB,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,kCAClB,SAAAuO,EAAe/P,EAAU,aAAcA,EAAU,SAAS,CAClD,IACX,EAAA3N,EAAA,KAACmP,EAAD,CAAW,UAAU,WACnB,YAAAnP,EAAA,KAAC2jB,GAAD,CAAW,OAAQhW,EAAU,OAAQ,WAAYsW,EAAQ,UAAa,EAC7D,IACX,EAAAjkB,EAAA,KAACmP,EAAD,CAAW,UAAU,0BAA2B,SAAAxB,EAAU,SAAS,eAAe,CAAa,IAC/F,EAAA3N,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAetF,EAAU,UAAU,EAChF,SAAAuF,EAAmBvF,EAAU,UAAU,CAC/B,IACX,EAAA3N,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAClB,SAAAxB,EAAU,eAAiB,KAC1B7G,EAAE,0BAA0B,GAE5B,EAAA9G,EAAA,KAACmH,EAAD,CACE,GAAG,kBACH,OAAQ,CAAE,IAAK,OAAOwG,EAAU,YAAY,CAAE,EAC9C,UAAU,+CAET,SAAA7G,EAAE,oBAAqB,CAAE,IAAK6G,EAAU,YAAa,CAAC,CACnD,EAEC,EACH,GAxBKA,EAAU,YAwBf,CACX,CACQ,EACN,GAeF,GAEX,ECrFawW,GAAuB,CAClC,QAAS,4BACT,UAAW,8BACX,OAAQ,2BACR,SAAU,6BACV,WAAY,+BACZ,OAAQ,2BACR,WAAY,+BACZ,OAAQ,2BACR,OAAQ,0BACV,EAGaC,GAAuB,CAClC,OAAQ,CAAE,SAAU,yCAA0C,KAAM,SAAU,EAC9E,UAAW,CAAE,SAAU,4CAA6C,KAAM,UAAW,EACrF,SAAU,CAAE,SAAU,2CAA4C,KAAM,UAAW,EACnF,SAAU,CAAE,SAAU,2CAA4C,KAAM,SAAU,EAClF,OAAQ,CAAE,SAAU,yCAA0C,KAAM,QAAS,EAC7E,QAAS,CAAE,SAAU,0CAA2C,KAAM,OAAQ,CAChF,ECZaC,OAAqB,CAChC,GAAM,CAAE,KAAMxe,EAAe,EACvBgN,EAAaH,EAAc,EAC3B4R,EAAYC,GAAa,MAAS,EACxC,OACE,EAAAvkB,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,4BAA4B,EAC1C,YAAA9G,EAAA,KAACsQ,EAAD,CAAW,MAAOgU,EAAW,YAAa,EACtC,YAAS,CACT,IAAME,EAAS9Q,EAAK,MAAM,KAAM,GAAQtS,EAAI,MAAQsS,EAAK,OAAO,EAChE,OACE,EAAA1T,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,KAACmH,EAAD,CACE,GAAG,kBACH,OAAQ,CAAE,IAAK,OAAOuM,EAAK,OAAO,CAAE,EACpC,UAAU,0DAET,SAAA5M,EAAE,oBAAqB,CAAE,IAAK4M,EAAK,OAAQ,CAAC,CACzC,GACL8Q,GACC,EAAAxkB,EAAA,MAAC,MAAD,CAAK,UAAU,oEAAf,WACE,EAAAA,EAAA,KAACyL,EAAD,CAAO,QAAQ,YAAa,SAAA3E,EAAEqd,GAAqBK,EAAO,OAAO,CAAS,IAC1E,EAAAxkB,EAAA,KAAC,OAAD,CAAM,MAAOiT,EAAeuR,EAAO,SAAS,EACzC,SAAA1d,EAAE,qBAAsB,CACvB,GAAIoM,EAAmBsR,EAAO,SAAS,EACvC,KAAM3R,EAAW,CAAE,KAAM2R,EAAO,MAAM,IAAK,CAAC,CAC9C,CAAC,CACG,GACLA,EAAO,gBAAkB,KAAO,MAC/B,EAAAxkB,EAAA,KAAC,OAAD,UAAO8G,EAAE,0BAA2B,CAAE,QAAS0d,EAAO,aAAc,CAAC,CAAQ,EAE5E,CACH,OACD,GAET,CACS,EACN,EAEX,ECjCaC,OAAa,CACxB,GAAM,CAAE,KAAM5e,EAAe,EACvB,CAAE,mBAAkB,eAAc,sBAAqB,qBAAsBwM,EAAsB,EACnGqS,EAAWzO,GAAoB0O,GAAgBC,GAAuBpB,EAC5E,OACE,EAAAxjB,EAAA,MAACqQ,EAAD,YACE,EAAArQ,EAAA,KAACiQ,EAAD,CAAY,MAAOnJ,EAAE,oBAAoB,CAAI,GAC5C4d,EAAW,MAAO,EAAA1kB,EAAA,KAACkW,GAAD,CAAW,GAC7BD,GACC,EAAAjW,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,WACE,EAAAA,EAAA,KAACqkB,GAAD,CAAe,IACf,EAAArkB,EAAA,KAACyiB,GAAD,CAAa,EACV,CACH,QACHkC,GAAe,EAAA3kB,EAAA,KAACgkB,GAAD,CAAe,GAAI,KAClCY,GAAsB,EAAA5kB,EAAA,KAACqiB,GAAD,CAAa,GAAI,MACxC,EAAAriB,EAAA,KAACujB,GAAD,CAAiB,EACb,GAEV,EClBMsB,GAAc,CAClB,cAAe,iDACf,gBAAiB,mDACjB,eAAgB,kDAChB,4BAA6B,8DAC/B,EAIMC,IAAc,CAAE,QAAO,SAAQ,WAA6B,CAChE,IAAM3J,EAAU4J,GAAgBC,GAAgB3J,EAAQD,CAAK,EAAG,CAAE,SAAQ,OAAM,CAAC,EACjF,OACE,EAAApb,EAAA,MAAC,MAAD,CAAK,UAAU,oBAAf,WACE,EAAAA,EAAA,KAAC,KAAD,CAAI,UAAU,sEAAuE,SAAAG,CAAU,IAC/F,EAAAH,EAAA,KAAC,KAAD,CAAI,UAAU,mCACX,SAAAmb,EAAQ,KAAK,EAAQ,KACpB,EAAAnb,EAAA,KAAC,KAAD,UACG2b,GAAe3B,EAAQqB,EAAQD,CAAK,CACnC,EAFK,GAAGpB,EAAO,KAAK,GAAGA,EAAO,SAAW,GAAG,GAAGA,EAAO,UAAY,GAAG,GAAGrW,GAExE,CACL,CACC,EACD,GAET,EAcashB,IAAa,CAAE,YAAW,SAAQ,eAAc,iBAAkC,CAC7F,GAAM,CAAE,KAAMpf,EAAe,EAC7B,OACE,EAAA7F,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,MAACsY,EAAD,CAAO,QAAQ,UAAf,WACE,EAAAtY,EAAA,KAACzB,GAAD,CAAU,cAAY,MAAQ,IAC9B,EAAAyB,EAAA,KAAC0Y,GAAD,UAAa5R,EAAE,iCAAkC,CAAE,MAAOoe,EAAU,MAAO,CAAC,CAAc,IAC1F,EAAAllB,EAAA,KAACwY,EAAD,UAAmB1R,EAAE,sCAAsC,CAAoB,EAC1E,CACN,GAAAoe,EAAU,IAAK,GAAa,CAC3B,GAAM,CAAE,OAAM,QAAO,UAAWC,EAChC,OACE,EAAAnlB,EAAA,MAACiH,EAAD,CAEE,MAAOH,EAAE,qCAAsC,CAAE,KAAMse,EAAK,IAAK,CAAC,EAClE,YAAate,EAAE+d,GAAYM,EAAS,OAAO,EAC3C,SAAS,EAAAnlB,EAAA,KAACK,GAAD,CAAY,MAAOglB,EAAOF,CAAQ,CAAI,GAJjD,WAME,EAAAnlB,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,WACE,EAAAA,EAAA,KAAC8kB,GAAD,CACE,MAAOhe,EAAE,iCAAiC,EAC1C,OAAQse,EAAK,KAAK,WAClB,MAAOtmB,GAAQ,YAAc,IAC9B,IACD,EAAAkB,EAAA,KAAC8kB,GAAD,CACE,MAAOhe,EAAE,gCAAgC,EACzC,OAAQse,EAAK,KAAK,WAClB,MAAOnmB,EAAM,UACd,EACE,CACJ,GAAAH,GACC,EAAAkB,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,WACE,EAAAA,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UAAU,YAAeoe,EAAYxmB,CAAM,EAChF,SAAAgI,EAAE,oCAAoC,CACjC,IACR,EAAA9G,EAAA,KAAC6X,EAAD,CACE,KAAK,SACL,MAAO/Q,EAAE,0CAA0C,EACnD,YAAaA,EAAE,gDAAgD,EAC/D,aAAcA,EAAE,qCAAqC,EACrD,cAAiBye,EAAazmB,CAAM,EACpC,SACE,EAAAkB,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,UACrC,SAAAJ,EAAE,qCAAqC,CAClC,EAEX,EACE,CACH,OACC,CApCA,EAAAse,EAAK,YAoCL,CAEX,CAAC,CACE,GAET,EC5FaI,GAAa,SAabC,GAAc,GACzBvf,EAAW,OAAS,YAAc,YAAc,QAErCwf,GAAsB,GACjC,GAAGF,GAAW,GAAGtf,EAAW,OAAS,YAAc,aAAe,SAAS,GAAGA,EAAW,OAAO,OAE5Fyf,GAAiB,CAAE,MAAO,EAAG,UAAW,CAAE,EAGnCC,GAAc,GACzBC,EAAS,YACN,KAAK,CAAE,aAAY,UAAS,WAAY,CACvC,KAAMH,GAAmBxf,CAAU,EACnC,aAAcA,EAAW,GACzB,SAAUuf,GAAWvf,CAAU,EAC/B,OAAQA,EAAW,OACnB,KAAM,CAAE,UAAS,OAAM,aAAY,KAAM4f,GAAoB5f,CAAU,CAAE,CAC3E,EAAE,CAAC,CACF,MAAM,EAAG,IAAMyf,GAAevf,EAAE,UAAYuf,GAAetf,EAAE,WAAaD,EAAE,KAAK,cAAcC,EAAE,IAAI,CAAC,EAE9F0f,EAAYC,EAGZC,GAAiB,IAAsC,CAClE,gBACA,cAAeJ,EAAS,cACxB,YAAa,OAAO,YAClBA,EAAS,YAAY,KAAK,CAAE,aAAY,UAAS,UAAW,CAC1D3f,EAAW,GACX,CAAE,KAAMA,EAAW,KAAM,OAAQA,EAAW,OAAQ,UAAS,MAAK,CACpE,CAAC,CACH,CACF,GAEaggB,GAAiB,GAAmCC,GAAkBF,GAAcJ,CAAQ,CAAC,ECvDpGO,IAAY,CAAE,OAAM,QAAO,OAAM,KAAMC,KAA0B,CACrE,GAAM,CAAE,KAAMxgB,EAAe,EACvB5E,EAAOJ,EAAK,MAAMA,EAAK,YAAY,GAAG,EAAI,CAAC,EACjD,OACE,EAAAb,EAAA,MAACgH,GAAD,CAAY,GAAG,UAAU,OAAQ,CAAE,KAAMnG,CAAK,EAAG,MAAOA,EAAM,eAAcsQ,EAAO,OAAS,OAA5F,WACE,EAAAnR,EAAA,KAACqmB,EAAD,CAAM,cAAY,MAAQ,IAC1B,EAAArmB,EAAA,KAAC,OAAD,CAAM,UAAU,qCAAsC,SAAAiB,CAAW,GAChEqlB,GACC,EAAAtmB,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC,OAAD,CAAM,cAAY,OAAO,UAAU,iDAAmD,IACtF,EAAAA,EAAA,KAAC,OAAD,CAAM,UAAU,UAAW,SAAA8G,EAAE,yBAAyB,CAAQ,EAC9D,IACA,IACM,GAEhB,EAUayf,IAAW,CAAE,QAAO,WAAU,aAA4B,CACrE,GAAM,CAAE,KAAM1gB,EAAe,EACvBlD,EAAS6jB,EAAM,OAAQ,GAASpB,EAAK,WAAa,OAAO,EACzDqB,EAAaD,EAAM,OAAQ,GAASpB,EAAK,WAAa,WAAW,EACvE,OACE,EAAAplB,EAAA,MAAC6G,GAAD,CAAQ,MAAOC,EAAE,sBAAsB,EAAvC,UACGnE,EAAO,OAAS,GACf,EAAA3C,EAAA,KAAC+G,GAAD,CAAa,MAAOD,EAAE,0BAA0B,EAC7C,SAAAnE,EAAO,IAAK,IACX,EAAA3C,EAAA,KAAComB,GAAD,CAEE,KAAMhB,EAAK,KACX,MAAOsB,EAAQtB,CAAI,EACnB,KAAMA,EAAK,OAASuB,EACpB,KAAMvf,EACP,EALMge,EAAK,YAKX,CACF,CACU,GACX,KACHqB,EAAW,OAAS,GACnB,EAAAzmB,EAAA,KAAC+G,GAAD,CAAa,MAAOD,EAAE,8BAA8B,EACjD,SAAA2f,EAAW,IAAK,IACf,EAAAzmB,EAAA,KAAComB,GAAD,CAEE,KAAMhB,EAAK,KACX,MAAOsB,EAAQtB,CAAI,EACnB,KAAMA,EAAK,OAASuB,EACpB,KAAMjoB,EACP,EALM0mB,EAAK,YAKX,CACF,CACU,GACX,MACJ,EAAAplB,EAAA,KAAC+G,GAAD,CAAa,MAAOD,EAAE,wBAAwB,EAC5C,YAAA9G,EAAA,KAAComB,GAAD,CAAU,KAAML,EAAW,MAAO,GAAO,KAAMY,IAAaZ,EAAW,KAAMa,EAAO,EACzE,EACP,GAEZ,EChEMxnB,GAAS,CAAE,OAAQ,EAAK,EAGxBynB,GAAqB,2BAMrBC,GAAkB,CAAC,GAAGvnB,EAAU,OAAO,IAAK,QAAQ,EAG7CwnB,GAA2BC,GAAa,CACnD,SAAUF,GACV,YAAepnB,GAAU,QAAsBmnB,EAAkB,EACjE,UAAW,EACX,KAAMznB,EACR,CAAC,EAEY6nB,OAAwBxnB,EAAS,CAAE,GAAGsnB,GAA0B,qBAAsB,EAAM,CAAC,ECJpGG,GAAa,GAA8E,CAC/F,GAAI,CACF,MAAO,CAAE,GAAI,GAAM,IAAK,KAAK,MAAM/d,CAAI,CAAE,CAC3C,OAASkN,EAAO,CACd,MAAO,CAAE,GAAI,GAAO,QAASA,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,CAAE,CACtF,CACF,EAEa8Q,IAAe,EAAc,CAAE,WAAU,YAA2C,CAC/F,IAAMC,EAAOF,GAAU/d,CAAI,EAC3B,GAAI,CAACie,EAAK,GACR,MAAO,CAAE,OAAQ,cAAe,QAASA,EAAK,OAAQ,EAGxD,IAAMjjB,EAASkjB,EAAgBD,EAAK,IAAK,CAAE,SAAUnd,GAAa,GAAIM,EAAW,CAAE,UAAS,EAAI,CAAC,CAAG,CAAC,EACrG,GAAI,CAACpG,EAAO,GACV,MAAO,CAAE,OAAQ,UAAW,IAAKijB,EAAK,IAAK,OAAQjjB,EAAO,MAAO,EAEnE,GAAM,CAAE,cAAeA,EACjBmjB,EAAQC,GAAe,CAAC,GAAGC,EAAO,OAAQ,GAAU/L,EAAM,KAAOvV,EAAW,EAAE,EAAGA,CAAU,CAAC,CAAC,CAAC,OACjG,GAAUuhB,EAAM,eAAiB,QAAaA,EAAM,eAAiBvhB,EAAW,EACnF,EACA,OAAOohB,EAAM,OAAS,EAClB,CAAE,OAAQ,UAAW,IAAKF,EAAK,IAAK,OAAQE,CAAM,EAClD,CAAE,OAAQ,QAAS,IAAKF,EAAK,IAAK,YAAW,CACnD,EAGaM,GAAY,GACvBC,EAAS,SAAW,UAAYA,EAAS,OAAS,CAAC,EChB/C/gB,IACJ,EACA,KACsB,CACtB,aAAc7D,EAAK,KAAK,aACxB,SAAUA,EAAK,KAAK,SACpB,WAAYA,EAAK,MAAM,WACvB,YAAa6kB,EAAS,SAAW,SAAWA,EAAS,gBAAkB,IACzE,GAEaC,IAAc,EAA6B,IAAsC,CAC5F,IAAMC,EAAa,IAAI,IAAIhpB,EAAO,YAAY,IAAK,GAAU,CAAC6N,EAAM,WAAW,GAAIA,CAAK,CAAC,CAAC,EACpFuY,EAA6B,CAAC,EAC9Bld,EAA6B,CAAC,EAChC9D,EAAU,EACd,IAAK,IAAMnB,KAAQ0B,EAAO,CACxB,IAAMjC,EAASslB,EAAW,IAAI/kB,EAAK,KAAK,YAAY,EAC9C6kB,EAAW1oB,GAAW,CAC1B,MAAO,CAAE,WAAY6D,EAAK,MAAM,WAAY,KAAM+iB,GAAoB/iB,EAAK,MAAM,UAAU,CAAE,EAC7F,KAAM,CAAE,QAASA,EAAK,KAAK,KAAK,QAAS,KAAMA,EAAK,KAAK,KAAK,IAAK,EACnE,OAAQP,EACJ,CACE,QAASA,EAAO,QAChB,KAAMsjB,GAAoBtjB,EAAO,UAAU,EAC3C,WAAYA,EAAO,UACrB,EACA,OACJ,MAAO,EACT,CAAC,EACD,OAAQolB,EAAS,OAAjB,CACE,IAAK,WACH1C,EAAU,KAAK,CAAE,KAAMniB,EAAK,KAAM,MAAOA,EAAK,MAAO,OAAQP,EAAQ,OAAQolB,EAAS,MAAO,CAAC,EAC9F,MACF,IAAK,SACL,IAAK,SACH5f,EAAO,KAAKpB,GAAQ7D,EAAM6kB,CAAQ,CAAC,EACnC,MACF,QACE,GAAW,CACf,CACF,CACA,OAAO1C,EAAU,OAAS,EAAI,CAAE,OAAQ,WAAY,WAAU,EAAI,CAAE,OAAQ,QAAS,SAAQ,SAAQ,CACvG,ECvDM6C,GAAc,GAAiF,CACnG,IAAMtjB,EAAqB,CAAC,EAC5B,IAAK,IAAM2gB,KAAQ4C,EAAU,WAAY,CACvC,IAAML,EAAWR,GAAYa,EAAU,OAAO5C,CAAI,EAAG,CACnD,SAAUA,EAAK,KAAK,WACpB,OAAQ4C,EAAU,YAAY,OAAQ,GAAe9hB,EAAW,KAAOkf,EAAK,YAAY,CAC1F,CAAC,EACD,GAAIuC,EAAS,SAAW,QACtB,MAAO,CAAE,QAASvC,CAAK,EAEzB3gB,EAAM,KAAK,CAAE,OAAM,MAAO,CAAE,WAAYkjB,EAAS,UAAW,CAAE,CAAC,CACjE,CACA,MAAO,CAAE,OAAM,CACjB,EAOaM,IAAiB,CAAE,YAAW,aAAY,eAAmC,CACxF,GAAM,CAAE,KAAMpiB,EAAe,EACvB+b,EAAcC,EAAe,EAC7BqG,EAAYC,GAAwB,EACpC,CAACC,EAAUC,IAAA,EAAengB,YAAS,EAAK,EAGxCogB,EAAa,KAAO,IAAwC,CAChE,IAAI5N,EAAc,GAClB,IAAK,GAAM,CAAE,eAAc,GAAGrG,KAAWrM,EACvC,EAAc,MAAMkgB,EAAU,YAAY,CACxC,eACA,QACA,YAAaphB,EAAE,kCAAkC,CACnD,CAAC,EAEH,OAAO4T,CACT,EA6BA,MAAO,CAAE,WA3BY,IAA+B,CAClD2N,EAAY,EAAI,EAChB,GAAI,CACF,IAAMppB,EAAQ8oB,GAAWC,CAAS,EAClC,GAAI,YAAa/oB,EAAO,CACtBsV,EAAM,MAAMzN,EAAE,+BAAgC,CAAE,KAAM7H,EAAM,QAAQ,IAAK,CAAC,CAAC,EAC3EspB,EAAUtpB,EAAM,OAAO,EACvB,MACF,CACA,IAAMH,EAAS,MAAM8iB,EAAY,WAAWmF,EAAwB,EAC9D/Y,EAAS6Z,GAAW5oB,EAAM,MAAOH,CAAM,EAC7C,GAAIkP,EAAO,SAAW,WAAY,CAChCwa,EAAWxa,EAAO,SAAS,EAC3B,MACF,CACA,GAAIA,EAAO,OAAO,SAAW,EAAG,CAC9BuG,EAAM,KAAKzN,EAAE,8BAA8B,CAAC,EAC5C,MACF,CACA2hB,EAAU,MAAMH,EAAWta,EAAO,MAAM,CAAC,CAC3C,OAASqI,EAAO,CACdqS,GAAYrS,EAAO,oBAAoB,CACzC,QAAU,CACRgS,EAAY,EAAK,CACnB,CACF,EAEgB,QAASD,CAAS,CACpC,EC7DMO,IAAqB,EAAsB,KAA8C,CAC7F,GAAGC,EACH,YAAaA,EAAO,YAAY,IAAK,GACnCjc,EAAM,WAAW,KAAO7N,EAAO,WAAW,GAAKA,EAAS6N,CAC1D,CACF,GAEakc,OAA2B,CACtC,IAAM7nB,EAAQimB,GAAgB,EACxB,CAAC6B,EAAQC,IAAA,EAAa7gB,YAAmC,EACzD,CAAC8gB,EAAOC,IAAA,EAAY/gB,YAA2C,CAAC,CAAC,EACjE0gB,EAASE,GAAU9nB,EAAM,KAEzBwlB,GAAA,EAAQxgB,eAAe4iB,EAAShD,GAAWgD,CAAM,EAAI,CAAC,EAAI,CAACA,CAAM,CAAC,EAClEM,GAAA,EAAWljB,eAAe4iB,EAAS1C,GAAc0C,CAAM,EAAI,GAAK,CAACA,CAAM,CAAC,EACxE3iB,GAAA,EAAcD,eAAcwgB,EAAM,IAAK,GAASpB,EAAK,KAAK,UAAU,EAAG,CAACoB,CAAK,CAAC,EAE9EnB,GAAA,EAASld,eAAa,GAAqB6gB,EAAM5D,EAAK,eAAiBA,EAAK,KAAK,KAAM,CAAC4D,CAAK,CAAC,EAC9FtC,GAAA,EAAUve,eACb,GAAqB,CACpB,IAAMgB,EAAO6f,EAAM5D,EAAK,cACxB,OAAOjc,IAAS,QAAaA,IAASic,EAAK,KAAK,IAClD,EACA,CAAC4D,CAAK,CACR,EACMG,GAAA,EAAUhhB,gBACb,EAAkB,IAAiB,CAClC4gB,EAAW,GAAYviB,GAAWoiB,CAAM,EACxCK,EAAU,IAAa,CAAE,GAAGziB,GAAU4e,EAAK,cAAejc,CAAK,EAAE,CACnE,EACA,CAACyf,CAAM,CACT,EACMQ,GAAA,EAAajhB,eAAa,GAA+B,CAC7D4gB,EAAW,GAAaviB,GAAUmiB,GAAkBniB,EAAS1H,CAAM,CAAY,EAC/EmqB,GAAU,EAAGnqB,EAAO,WAAW,IAAKuqB,EAAU,GAAG5mB,KAAWA,CAAI,CAClE,EAAG,CAAC,CAAC,EACC6mB,GAAA,EAAYnhB,eAAa,GAA+B,CAC5D4gB,EAAW,GAAaviB,GAAUmiB,GAAkBniB,EAAS1H,CAAM,CAAY,CACjF,EAAG,CAAC,CAAC,EACC,CAAE,WAAYkC,EACduoB,GAAA,EAASphB,eAAY,UACzB4gB,EAAU,MAAS,EACnBE,EAAS,CAAC,CAAC,EACJO,EAAQ,GACd,CAACA,CAAO,CAAC,EAENC,GAAA,EAAazjB,eAAcwgB,EAAM,OAAOE,CAAO,EAAG,CAACF,EAAOE,CAAO,CAAC,EAgCxE,MAAO,CAAE,QAAO,aA/BE1gB,eAEd4iB,EACI,CACE,cAAeA,EAAO,cACtB,QACA,WACA,cACA,SACA,UACA,aACA,UACA,aACA,YACA,QACF,EACA,OACN,CACEA,EACApC,EACA0C,EACAjjB,EACAof,EACA8D,EACAM,EACA/C,EACA0C,EACAE,EACAC,CACF,CAEc,CAAU,CAC5B,ECpGMhJ,MAAOmJ,mBAAW,OAAO,qBAAS,CAAC,KAAM,IAAY,CAAE,QAASC,EAAO,IAAK,EAAE,4DAAC,EAKxEC,IAAc,CAAE,YAAW,GAAGC,MACzC,EAAA7pB,EAAA,KAAC,MAAD,CACE,UAAWC,EACT,+HACAC,CACF,EAEA,YAAAF,EAAA,KAAC8pB,WAAD,CAAU,UAAU,EAAA9pB,EAAA,KAACuhB,GAAD,CAAc,KAAM,EAAG,UAAU,KAAO,GAC1D,YAAAvhB,EAAA,KAACugB,GAAD,CAAM,GAAIsJ,CAAQ,EACV,EACP,GCdDE,OAAiB,CAAC,EAGXC,IAAY,CAAE,UAA0B,CACnD,GAAM,CAAE,GAAMnkB,EAAe,EAC7B,OACE,EAAA7F,EAAA,KAACiH,EAAD,CAAO,MAAO8e,EAAW,YAAa,EAAE,gCAAgC,EAAG,SACzE,YAAA/lB,EAAA,KAAC4pB,GAAD,CACE,UAAU,+CACV,MAAOzgB,EACP,SAAU4gB,GACV,MAAO,EAAE,6BAA8B,CAAE,KAAMhE,CAAU,CAAC,EAC1D,YACA,OAAQ,OACR,KAAMgE,EACP,EACI,EAEX,ECEME,GAAS,GAAiC,KAAK,MAAM,KAAK,UAAUC,CAAM,CAAC,EAE3EC,GAAqB,GAAqC,CAC9D,IAAMtnB,EAAQqnB,EAAO,YAAY,QAAQ,MAOzC,OANIrnB,GAAS,CAAC,MAAM,QAAQA,CAAK,IAC/B,EAAM,MAAQ,OAAO,QAAQunB,CAAgB,CAAC,CAAC,KAAK,CAAC3X,EAAM4X,MAAe,CACxE,GAAI,CAAE,WAAY,CAAE,KAAM,CAAE,MAAO5X,CAAK,CAAE,EAAG,SAAU,CAAC,MAAM,CAAE,EAChE,KAAM,CAAE,WAAY,CAAE,SAAUwX,GAAMI,CAAQ,CAAE,CAAE,CACpD,EAAE,GAEGH,CACT,EAEMI,GAAmD,CACvD,MAAOH,GAAkBF,GAAMM,CAA0B,CAAC,EAC1D,UAAWJ,GAAkBF,GAAMO,EAA8B,CAAC,CACpE,EAEaC,GAAmB,GAA8CH,GAAQI,GCtChFC,GAAsB,IAMfC,IACX,EACA,EACA,IACG,CACH,IAAMC,GAAA,EAAU7kB,eAEZof,EACI,CACE,SAAUA,EAAK,KAAK,WACpB,OAAQnf,EAAY,OAAQ,GAAeC,EAAW,KAAOkf,EAAK,YAAY,CAChF,EACA,OACN,CAACA,EAAMnf,CAAW,CACpB,EACM6kB,EAAgBC,GAAkB5hB,EAAMwhB,EAAmB,EASjE,MAAO,CAAE,YARQ3kB,eACR6kB,EAAU1D,GAAY2D,EAAeD,CAAO,EAAI,OACvD,CAACA,EAASC,CAAa,CAMhB,EAAU,QAJN3iB,eACV,GAAiD0iB,EAAUnD,GAASP,GAAY3gB,EAASqkB,CAAO,CAAC,EAAI,CAAC,EACvG,CAACA,CAAO,CAES,CAAK,CAC1B,EC7BapO,IAAa,CAAE,SAAQ,QAAyB,CAC3D,GAAM,CAAE,KAAM5W,EAAe,EAI7B,OAHI6W,EAAO,SAAW,EACb,MAGP,EAAA1c,EAAA,MAAC,MAAD,CACM,KACJ,KAAK,SACL,UAAU,+EAHZ,WAKE,EAAAA,EAAA,KAAC,IAAD,CAAG,UAAU,yCACV,SAAA8G,EAAE,0BAA2B,CAAE,MAAO4V,EAAO,MAAO,CAAC,CACrD,IACH,EAAA1c,EAAA,KAAC,KAAD,CAAI,UAAU,sCACX,SAAA0c,EAAO,IAAK,IACX,EAAA1c,EAAA,MAAC,KAAD,CAAyD,UAAU,cAAnE,WACE,EAAAA,EAAA,KAAC,OAAD,CAAM,UAAU,oBAAqB,SAAA4Z,EAAM,MAAQ,GAAU,GAAC,IAAEA,EAAM,OACpE,CAFK,KAAGA,EAAM,KAAK,GAAGA,EAAM,KAAK,GAAGA,EAAM,SAE1C,CACL,CACC,EACD,GAET,ECVaoR,GAAmB,GAA6C,CAC3E,GAAIC,GAAcjpB,CAAK,IAAM,OAC3B,OAAOkpB,EAAoBlpB,CAAK,CAAC,CAAC,SAAS,IAAK,IAAa,CAC3D,GAAI,SAASmpB,EAAQ,KACrB,KAAM,aACN,MAAOA,EAAQ,MACf,OAAQA,EAAQ,MAClB,EAAE,EAEJ,IAAMC,EAASC,EAAgBrpB,CAAK,EAIpC,MAAO,CACL,CAAE,GAAI,WAAY,KAAM,WAAqB,MAAO,OAAW,OAJhD,CAACopB,EAAO,YAAcA,EAAO,MAAQ,OAAWA,EAAO,MAAO,GAAGA,EAAO,MAAM,CAAC,CAAC,OAC9F,GAAoCvoB,IAAU,MAGwB,CAAS,EAChF,GAAGuoB,EAAO,eAAe,IAAK,IAAW,CACvC,GAAI,SAASvjB,EAAM,KACnB,KAAM,aACN,MAAOA,EAAM,MACb,OAAQA,EAAM,MAChB,EAAE,CACJ,CAAC,CAAC,OAAQ,GAAYsjB,EAAQ,OAAO,OAAS,CAAC,CACjD,EAMaG,GAAiB,IAAqD,CACjF,GAAIC,EAAU,GACd,KAAM,YACN,OAAQA,EAAU,OAClB,MAAOA,EAAU,MACjB,UAAW,GACX,gBAAiB,GACjB,OAAQA,EAAU,OAClB,QAAS,CAAE,GAAIA,EAAU,QAAQ,OAAS,CAAE,OAAQA,EAAU,QAAQ,MAAO,EAAI,CAAC,CAAG,CACvF,GCxCMC,OAAoB,QAAQ,QAAQ,IAAI,EAMjCC,IAAe,CAAE,aAAY,iBAAoC,CAC5E,GAAM,CAAE,KAAM5lB,EAAe,EACvB6lB,EAAUC,GAAkB,EAC5B3pB,GAAA,EAAQgE,eACLG,EAAkBD,CAAU,EAAIA,EAAaolB,GAAcplB,CAAU,EAC5E,CAACA,CAAU,CACb,EACM0lB,GAAA,EAAc5lB,eAAiC,CACnD,IAAM6lB,EAAM,CAAC,GAAG5lB,EAAY,OAAQ,GAAUwV,EAAM,KAAOvV,EAAW,EAAE,EAAGA,CAAU,EACrF,MAAO,CACL,SAAU,kBACV,QACA,OAAQ,IAAI,IAAI2lB,EAAI,OAAO1lB,CAAiB,CAAC,CAAC,IAAK,GAAU,CAACwG,EAAM,GAAIA,CAAK,CAAC,CAAC,EAC/E,WAAY,IAAI,IAAIkf,EAAI,OAAOC,CAAqB,CAAC,CAAC,IAAK,GAAU,CAACnf,EAAM,GAAIA,CAAK,CAAC,CAAC,EACvF,OAAQ,KACR,QAAS,KACT,SAAU,GACV,SAAU,GACV,eAAgB+e,EAAQ,QACxB,UAAWF,EACb,CACF,EAAG,CAACtlB,EAAYD,EAAajE,EAAO0pB,EAAQ,OAAO,CAAC,EAC9CK,GAAA,EAAQ/lB,eAAcgmB,GAAqBC,GAAkBjqB,EAAM,MAAM,CAAC,EAAG,CAACA,CAAK,CAAC,EAE1F,GAAI0pB,EAAQ,UACV,OAAO,EAAA1rB,EAAA,KAACuhB,GAAD,CAAc,KAAM,CAAI,GAEjC,IAAM2K,EAAWlB,GAAgBhpB,CAAK,EAItC,OAHIkqB,EAAS,SAAW,GACf,EAAAlsB,EAAA,KAAC,IAAD,CAAG,UAAU,gCAAiC,SAAA8G,EAAE,iCAAiC,CAAK,IAG7F,EAAA9G,EAAA,KAACmsB,GAAD,CAA6B,cAAoB,QAC/C,YAAAnsB,EAAA,KAAC,MAAD,CAAK,UAAU,YACZ,SAAAksB,EAAS,IAAK,IACb,EAAAlsB,EAAA,MAAC,UAAD,CAA0B,kBAAiB,kBAAkBmrB,EAAQ,KAAM,UAAU,YAArF,WACE,EAAAnrB,EAAA,KAAC,KAAD,CACE,GAAI,kBAAkBmrB,EAAQ,KAC9B,UAAU,sEAET,SAAAA,EAAQ,QACNA,EAAQ,OAAS,WACdrkB,EAAE,iCAAiC,EACnCA,EAAE,mCAAmC,EACzC,IACJ,EAAA9G,EAAA,KAACosB,GAAD,CAAa,OAAQjB,EAAQ,OAAQ,KAAMkB,GAAgBrqB,CAAK,CAAI,EAC7D,CAXK,EAAAmpB,EAAQ,EAWb,CACV,CACE,EACS,EAEpB,ECnEamB,IAAgB,CAAE,aAAY,YAAgC,CACzE,GAAM,CAAE,KAAMzmB,EAAe,EACvB0mB,GAAA,EAAMvmB,eAAcwmB,GAAWtmB,EAAYumB,CAAM,EAAG,CAACvmB,EAAYumB,CAAM,CAAC,EAC9E,OAAO,EAAAzsB,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,4BAA4B,EAAG,KAAMylB,CAAM,EACxE,ECIaG,IAAQ,CAAE,SAAQ,WAAuB,CACpD,GAAM,CAAE,KAAM7mB,EAAe,EACvBsV,GAAA,EAAUnV,eACR+e,GAAgBC,GAAgB3J,EAAQD,CAAK,EAAG,CAAE,SAAQ,OAAM,CAAC,EACvE,CAACC,EAAQD,CAAK,CAChB,EACA,GAAID,EAAQ,SAAW,EACrB,OAAO,EAAAnb,EAAA,KAACiN,EAAD,CAAY,KAAK,QAAQ,KAAM0f,GAAa,MAAO7lB,EAAE,0BAA0B,CAAI,GAE5F,IAAM4G,EAAUkf,GAAiBzR,CAAO,EACxC,OACE,EAAAnb,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACG0N,EAAQ,UAAYA,EAAQ,aAC3B,EAAA1N,EAAA,KAACsY,EAAD,CAAO,QAAQ,UACb,YAAAtY,EAAA,KAACwY,EAAD,UACG9K,EAAQ,YAAc5G,EAAE,iCAAiC,EAAIA,EAAE,8BAA8B,CAC9E,EACb,GACL,KACF4G,EAAQ,UAIN,MAHF,EAAA1N,EAAA,KAACsY,EAAD,CAAO,QAAQ,cACb,YAAAtY,EAAA,KAACwY,EAAD,UAAmB1R,EAAE,iCAAiC,CAAoB,EACrE,GAER+lB,GAAc1R,CAAO,CAAC,CAAC,IAAK,IAC3B,EAAAnb,EAAA,MAAC,MAAD,CAAwB,UAAU,YAAlC,WACE,EAAAA,EAAA,KAAC8sB,GAAD,CAAY,OAAQjlB,EAAM,MAAS,IACnC,EAAA7H,EAAA,KAAC,KAAD,CAAI,UAAU,mCACX,SAAA6H,EAAM,QAAQ,KAAK,EAAQ,KAC1B,EAAA7H,EAAA,KAAC,KAAD,UACG2b,GAAe3B,EAAQqB,EAAQD,CAAK,CACnC,EAFK,GAAGpB,EAAO,KAAK,GAAGA,EAAO,SAAW,GAAG,GAAGA,EAAO,UAAY,GAAG,GAAGrW,GAExE,CACL,CACC,EACD,CATK,EAAAkE,EAAM,MASX,CACN,GACD,EAAA7H,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,kCAAkC,CAAK,EACtF,GAET,EC9CaimB,IAAa,CAAE,aAAY,YAA6B,CACnE,GAAM,CAAE,KAAMlnB,EAAe,EACvBmnB,EAAYC,GAAc/mB,CAAU,EACpCgnB,GAAA,EAASlnB,eAAcmnB,GAAmBjnB,EAAYumB,CAAM,EAAG,CAACvmB,EAAYumB,CAAM,CAAC,EACzF,OACE,EAAAzsB,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACGmG,EAAkBD,CAAU,GAC3B,EAAAlG,EAAA,KAAC,KAAD,CAAI,aAAY8G,EAAE,kCAAkC,EAAG,UAAU,cAC9D,SAAAkmB,EAAU,IAAK,IACd,EAAAhtB,EAAA,MAAC,KAAD,CAAgD,UAAU,kCAA1D,WACE,EAAAA,EAAA,KAACyL,EAAD,CAAO,QAAQ,UAAU,UAAU,gCAChC,SAAA2hB,EAAS,MACL,IACP,EAAAptB,EAAA,KAAC,OAAD,CAAM,UAAU,qCAAsC,SAAAotB,EAAS,IAAW,GACzEA,EAAS,QAAU,SAClB,EAAAptB,EAAA,KAACyL,EAAD,CAAO,QAAQ,YAAY,UAAU,mBAClC,SAAA3E,EAAE,8BAA8B,CAC5B,GACL,IACF,CAVK,KAAGsmB,EAAS,OAAO,GAAGA,EAAS,MAUpC,CACL,CACC,IAEJ,EAAAptB,EAAA,KAAC,IAAD,CAAG,UAAU,gCAAiC,SAAA8G,EAAE,2CAA2C,CAAK,IAElG,EAAA9G,EAAA,KAACD,EAAD,CACE,MACEoG,EAAkBD,CAAU,EACxBY,EAAE,uCAAuC,EACzCA,EAAE,wCAAwC,EAEhD,KAAMomB,CACP,EACE,GAET,ECvCMG,IAAiB,EAAgB,IAAqC,CAC1E,IAAMC,EAAQC,EAAO,QAAQ,eAAetsB,EAAK,IAAI,EACrD,GAAIqsB,EAAQ,EACV,OAEF,IAAME,EAAeD,EAAO,YAAY,MAAOD,CAAK,EAC9CG,EAAaF,EAAO,YAAY,KAAMD,CAAK,EAE3CI,EACJF,GAAgB,GAAKC,EAAaD,GAAgBD,EAAO,MAAME,EAAa,EAAGH,CAAK,CAAC,CAAC,KAAK,IAAM,GAC7FE,EACAF,EACAK,EAAMJ,EAAO,QAAQ;;EAAUD,CAAK,EAC1C,OAAOK,EAAM,EAAI,OAAYJ,EAAO,MAAMG,EAAMC,EAAM,CAAC,CACzD,EAEaC,IAAkB,EAAgB,IAA2B,CACxE,IAAM3sB,EAAO4sB,EAAWrf,CAAM,EAC9B,MAAO,CAAC6e,GAAcE,EAAQtsB,CAAI,EAAGosB,GAAcE,EAAQ,GAAGtsB,EAAK,MAAM,CAAC,CAAC,CACxE,OAAQ,GAAyBN,IAAS,MAAS,CAAC,CACpD,KAAK;CAAI,CACd,ECZamtB,IAAS,CAAE,SAAQ,YAAyB,CACvD,GAAM,CAAE,KAAMjoB,EAAe,EACvB7E,EAAQrB,GAA0B,EACxC,OACE,EAAAK,EAAA,KAACsQ,EAAD,CAAkB,QACd,WAAE,SAAQ,mBAAoB,CAC9B,IAAMhQ,EAAOstB,GAAeL,EAAQ/e,CAAM,EAC1C,OACE,EAAAxO,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,UACG+tB,GACC,EAAA/tB,EAAA,KAACsY,EAAD,CAAO,QAAQ,OACb,YAAAtY,EAAA,KAACwY,EAAD,UACG1R,EAAE,qCAAsC,CAAE,QAASknB,CAAc,CAAC,CACnD,EACb,GACL,KACH1tB,GACC,EAAAN,EAAA,KAACD,EAAD,CAAW,MAAO+G,EAAE,mCAAmC,EAAS,MAAO,IAEvE,EAAA9G,EAAA,KAACiN,EAAD,CAAY,KAAK,QAAQ,KAAM5O,GAAU,MAAOyI,EAAE,gCAAgC,CAAI,EAErF,GAET,CACS,EAEf,EC1BMmnB,GAAe,CAAC,OAAQ,OAAQ,UAAW,QAAS,MAAM,EAG1Dne,GAAiB,CACrB,KAAM,mCACN,KAAM,mCACN,QAAS,sCACT,MAAO,oCACP,KAAM,kCACR,EAUaoe,IAAW,CAAE,OAAM,WAAU,SAAQ,iBAAgC,CAChF,GAAM,CAAE,KAAMroB,EAAe,EACvB,CAAC6C,EAAKylB,IAAA,EAAUjmB,YAAqB,MAAM,EAC3ChC,EAAayhB,GAAU,SAAW,QAAUA,EAAS,WAAa,OAClE8E,GAAA,EAASzmB,eAEX,IAAI,IACF,CACE,GAAGC,EAAY,OAAQ,GAAUwV,EAAM,KAAO2J,EAAK,YAAY,EAC/D,GAAIlf,EAAa,CAACA,CAAU,EAAI,CAAC,CACnC,CAAC,CAAC,IAAK,GAAU,CAACyG,EAAM,GAAIA,CAAK,CAAC,CACpC,EACF,CAAC1G,EAAaC,EAAYkf,EAAK,YAAY,CAC7C,EACMgJ,GACJ,EAAApuB,EAAA,KAACiN,EAAD,CACE,KAAK,QACL,KAAMohB,GACN,MAAOvnB,EAAE,qCAAqC,EAC9C,YAAaA,EAAE,2CAA2C,CAC3D,GAEH,OACE,EAAA9G,EAAA,KAACiH,EAAD,CAAO,MAAOH,EAAE,8BAA8B,EAAG,QAAQ,KACvD,YAAA9G,EAAA,MAACsP,GAAD,CAAM,MAAO5G,EAAK,cAAgB,GAAUylB,EAAOjtB,CAAmB,EAAtE,WACE,EAAAlB,EAAA,KAACuP,GAAD,CAAU,QAAQ,YAAY,UAAU,uCACrC,SAAA0e,GAAa,IAAK,IACjB,EAAAjuB,EAAA,KAACwP,GAAD,CAAgC,QAC7B,SAAA1I,EAAEgJ,GAAe5O,EAAM,CACb,EAFKA,CAEL,CACd,CACO,IACV,EAAAlB,EAAA,KAACyP,EAAD,CAAa,MAAM,OAAO,UAAU,OACjC,SAAAvJ,GAAa,EAAAlG,EAAA,KAACyrB,GAAD,CAAyB,aAAyB,aAAc,GAAI2C,CACvE,IACb,EAAApuB,EAAA,KAACyP,EAAD,CAAa,MAAM,OAAO,UAAU,OACjC,SAAAvJ,GAAa,EAAAlG,EAAA,KAAC+sB,GAAD,CAAuB,aAAoB,QAAS,GAAIqB,CAC3D,IACb,EAAApuB,EAAA,KAACyP,EAAD,CAAa,MAAM,UAAU,UAAU,OACpC,SAAAvJ,GAAa,EAAAlG,EAAA,KAACssB,GAAD,CAA0B,aAAoB,QAAS,GAAI8B,CAC9D,IACb,EAAApuB,EAAA,KAACyP,EAAD,CAAa,MAAM,QAAQ,UAAU,OACnC,YAAAzP,EAAA,KAAC8tB,GAAD,CAAO,OAAQ1I,EAAK,OAAgB,QAAS,EAClC,IACb,EAAAplB,EAAA,KAACyP,EAAD,CAAa,MAAM,OAAO,UAAU,OACjC,SAAAvJ,GAAa,EAAAlG,EAAA,KAAC0sB,GAAD,CAAM,OAAQtH,EAAK,KAAK,WAAY,MAAOlf,CAAa,GAAIkoB,CAC/D,EACT,GACD,EAEX,EClEaE,IAAa,CAAE,OAAM,eAAgC,CAChE,GAAM,CAAE,KAAMzoB,EAAe,EACvB0oB,GAAA,EAAW5jB,SAAM,EACjB,CAAE,UAAS,SAAQ,UAAS,eAAgBqd,EAC5C7e,EAAOkc,EAAOD,CAAI,EAClB2I,EAASrH,EAAQtB,CAAI,EACrB,CAAE,WAAU,QAASwF,GAAuBxF,EAAMjc,EAAMlD,CAAW,EACnE0D,GAAA,EAAWxB,eAAa,GAAiBghB,EAAQ/D,EAAMhd,CAAI,EAAG,CAAC+gB,EAAS/D,CAAI,CAAC,EAC7E1I,EAASiL,EAAWD,GAASC,CAAQ,EAAI,CAAC,EAChD,OACE,EAAA3nB,EAAA,MAAC,MAAD,CAAK,UAAU,4BAAf,WACE,EAAAA,EAAA,MAACiH,EAAD,CACE,MAAOme,EAAK,KAAK,MAAMA,EAAK,KAAK,YAAY,GAAG,EAAI,CAAC,EACrD,YAAaA,EAAK,KAClB,SACA,QACE2I,GACE,EAAA/tB,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAAC+M,EAAD,CAAY,KAAK,UAAU,MAAOjG,EAAE,yBAAyB,EAAG,KAAK,IAAM,IAC3E,EAAA9G,EAAA,KAAC6X,EAAD,CACE,KAAK,SACL,MAAO/Q,EAAE,4BAA4B,EACrC,YAAaA,EAAE,kCAAkC,EACjD,aAAcA,EAAE,uBAAuB,EACvC,cAAiBqiB,EAAQ/D,EAAMA,EAAK,KAAK,IAAI,EAC7C,SACE,EAAAplB,EAAA,KAACkH,EAAD,CAAQ,KAAK,SAAS,KAAK,KAAK,QAAQ,QACrC,SAAAJ,EAAE,uBAAuB,CACpB,EAEX,EACD,IACA,KArBR,WAwBE,EAAA9G,EAAA,KAAC4pB,GAAD,CACE,UAAU,+CACV,MAAOzgB,EACG,WACV,MAAOrC,EAAE,6BAA8B,CAAE,KAAMse,EAAK,IAAK,CAAC,EAC1D,YAAamJ,EACb,SAAU,GACV,OAAQ9D,GAAgBrF,EAAK,QAAQ,EAC/B,MACP,GACAuC,GAAU,SAAW,eACpB,EAAA3nB,EAAA,KAAC,IAAD,CAAG,KAAK,SAAS,UAAU,gDACxB,SAAA8G,EAAE,6BAA8B,CAAE,QAAS6gB,EAAS,OAAQ,CAAC,CAC7D,GACD,KACHjL,EAAO,OAAS,GACf,EAAA1c,EAAA,KAAC,MAAD,CAAK,UAAU,eACb,YAAAA,EAAA,KAACyc,GAAD,CAAW,GAAI8R,EAAkB,QAAS,EACvC,GACH,IACC,CACP,MAAAvuB,EAAA,KAACkuB,GAAD,CAAe,OAAgB,WAAkB,SAAqB,aAAc,EACjF,GAET,ECvDM7lB,GAAQC,GAAY,aAAa,EAGjCkmB,IAAgB,CAAE,cAAa,cAAkCC,IAAgBC,EAO1EC,OAAe,CAC1B,GAAM,CAAE,KAAM9oB,EAAe,EACvB,CAAE,QAAO,aAAcgjB,GAAmB,EAChD,OACE,EAAA7oB,EAAA,KAACqQ,EAAD,CAAM,MAAM,OACV,YAAArQ,EAAA,KAACsQ,EAAD,CAAkB,QAEd,aAAA0X,GACE,EAAAhoB,EAAA,KAAC4uB,GAAD,CAAwB,WAAY,IAEpC,EAAA5uB,EAAA,KAACiN,EAAD,CAAY,KAAM4hB,GAAW,MAAO/nB,EAAE,qBAAqB,CAAI,EAG1D,EACP,EAEV,EAIM8nB,IAAe,CAAE,eAAkC,CACvD,GAAM,CAAE,GAAM/oB,EAAe,EACvB2C,EAAWsN,EAAY,EACvB,CAAE,KAAM6Q,GAAate,GAAM,UAAU,EACrCymB,EAAcC,GAAiB,CAAC,CAAC,KACjC,CAAC7J,EAAW8J,IAAA,EAAgB9mB,YAA0B,CAAC,CAAC,EACxD,CAAC+mB,EAAWC,IAAA,EAAgBhnB,YAAiB,EAC7C,CAAE,QAAO,cAAe8f,EACxB1B,EAAQmD,EAAW,OAAS,GAAKwF,IAAc,OAC/CE,EAAalH,GAAc,CAC/B,UAAY,GAAS,KAAKzf,EAAS,CAAE,GAAI,UAAW,OAAQ,CAAE,KAAM4c,EAAK,IAAK,CAAE,CAAC,EACjF,WAAY4J,EACZ,UAAWE,CACb,CAAC,GAGD,EAAAE,EAAA,eAAgB,CACVH,GACFzmB,EAAc,CAAE,GAAI,wBAAyB,OAAQ,CAAE,YAAaymB,CAAU,CAAE,CAAC,CAErF,EAAG,CAACA,EAAWzmB,CAAQ,CAAC,EAExB,IAAM6mB,EACJ7I,EAAM,KAAM,GAASpB,EAAK,OAASuB,CAAQ,IAAMA,IAAaZ,EAAY,OAAYS,EAAM,IACxF8I,EAAW3I,IAAaZ,GAAaS,EAAM,SAAW,EACtD+I,EAAQT,IAAgB,QAAaA,IAAgB9G,EAAU,cAC/DwH,EAAgB,GAA4BxH,EAAU,OAAO7C,EAAS,IAAI,EAC1EsK,GAAW,GACfT,EAAc,GAAYxoB,EAAQ,OAAQ,GAAa2e,EAAS,KAAK,eAAiBuK,CAAY,CAAC,EAE/FC,GACJ,EAAA3vB,EAAA,MAACkH,EAAD,CAAQ,KAAK,SAAS,QAAQ,UAAU,SAAUioB,EAAW,QAA7D,WACE,EAAAnvB,EAAA,KAAC2Y,GAAD,CAAW,cAAY,MAAQ,GAC9B,EAAE,uBAAuB,CACpB,IAEV,OACE,EAAA3Y,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACiQ,EAAD,CACE,MAAO,EAAE,qBAAqB,EAC9B,KAAM,EAAE,sBAAuB,CAAE,QAAS+X,EAAU,cAAe,MAAOxB,EAAM,MAAO,CAAC,EACxF,SACE,EAAAxmB,EAAA,MAAAgM,WAAA,WACGsa,GACC,EAAAtmB,EAAA,KAAC6X,EAAD,CACE,KAAK,SACL,MAAO,EAAE,4BAA4B,EACrC,YAAa,EAAE,kCAAkC,EACjD,aAAc,EAAE,uBAAuB,EACvC,eACEmX,EAAa,CAAC,CAAC,EACRhH,EAAU,OAAO,GAE1B,QAAS2H,CACV,IAED,EAAA3vB,EAAA,MAACkH,EAAD,CACE,KAAK,SACL,QAAQ,UACR,SAAUioB,EAAW,QACrB,YAAe,CACbH,EAAa,CAAC,CAAC,EACfhH,EAAe,OAAO,CACxB,EAPF,WASE,EAAAhoB,EAAA,KAAC2Y,GAAD,CAAW,cAAY,MAAQ,GAC9B,EAAE,uBAAuB,CACpB,CAEV,MAAA3Y,EAAA,KAACkH,EAAD,CACE,KAAK,SACL,SAAU,CAACof,GAAS6I,EAAW,QAC/B,YAAe,CACbH,EAAa,CAAC,CAAC,EACfG,EAAgB,MAAMnH,CAAS,CACjC,EAEC,SAAAmH,EAAW,QACR,EAAE,yBAAyB,EAC3B,EAAE,6BAA8B,CAAE,MAAO1F,EAAW,MAAO,CAAC,CAC1D,EACR,GAEL,GACA8F,GACC,EAAAvvB,EAAA,KAACsY,EAAD,CAAO,QAAQ,OAAO,KAAK,SACzB,YAAAtY,EAAA,KAACwY,EAAD,UACG,EAAE,uBAAwB,CAAE,OAAQwP,EAAU,cAAe,KAAM8G,CAAY,CAAC,CACjE,EACb,GACL,KACH5J,EAAU,OAAS,GAClB,EAAAllB,EAAA,KAACilB,GAAD,CACa,YACX,OAAQuK,EACR,aAAe,GAAW,CACxBxH,EAAU,WAAWlpB,CAAM,EAC3B2wB,GAAQ3wB,EAAO,WAAW,EAAE,CAC9B,EACA,YAAc,GAAW,CACvBkpB,EAAU,UAAUlpB,CAAM,EAC1B2wB,GAAQ3wB,EAAO,WAAW,EAAE,CAC9B,CACD,GACC,MACJ,EAAAkB,EAAA,MAAC,MAAD,CAAK,UAAU,kCAAf,WACE,EAAAA,EAAA,KAACumB,GAAD,CACS,QACP,SAAU+I,GAAY,CAACD,EAAWtJ,EAAYsJ,EAAS,KACvD,QAASrH,EAAU,OACpB,IACD,EAAAhoB,EAAA,KAAC,MAAD,CAAK,UAAU,iBACZ,SAAAsvB,GAAY,CAACD,GACZ,EAAArvB,EAAA,KAACgqB,GAAD,CAAU,KAAMhC,EAAU,QAAW,IAErC,EAAAhoB,EAAA,KAACsuB,GAAD,CAAuC,KAAMe,EAAqB,WAAY,EAA9DA,EAAS,YAAqD,CAE7E,EACF,KACL,EAAArvB,EAAA,KAAC4vB,GAAD,CAAqB,KAAMtJ,EAAO,YAAakI,EAAe,EAC9D,GAEN,ECpKaqB,OAAoB,CAC/B,GAAM,CAAE,gBAAiBxd,EAAsB,EACzCqL,EAAiBF,GAAkB,EACnC7a,EAAS+gB,GAAe,OAAO,EAE/B,CAAE,cAAe9V,IADjB,EAAW5H,gBAAerD,EAAO,MAAQ,CAAC,GAAG,KAAK,CAAE,gBAAiBuD,EAAW,EAAE,EAAG,CAACvD,EAAO,IAAI,CAC9D,EAAUgiB,CAAY,EACzDmL,EAAQ,IAAI,IAClB,IAAK,IAAMniB,KAAaoiB,EACtB,GAAIpiB,EAAU,eAAiB,KAAM,CACnC,IAAM5I,EAAQ+qB,EAAM,IAAIniB,EAAU,YAAY,GAAK,CAAC,EACpD5I,EAAM,KAAK2Y,EAAe/P,EAAU,aAAcA,EAAU,SAAS,CAAC,EACtEmiB,EAAM,IAAIniB,EAAU,aAAc5I,CAAK,CACzC,CAEF,MAAO,CAAE,eAAc,SAAW,GAAgB+qB,EAAM,IAAIE,CAAG,GAAK,CAAC,CAAE,CACzE,ECFaC,IAAc,CAAE,MAAK,QAAO,UAAU,WAA+B,CAChF,GAAM,CAAE,KAAMpqB,EAAe,EACvB4O,GAAA,EAAU9J,SAAM,EAChBulB,GAAA,EAAWvlB,SAAM,EACjB,CAACwG,EAAMwD,IAAA,EAAWzM,YAAS,EAAK,EAChC,CAACioB,EAASC,IAAA,EAAcloB,YAA6B,MAAS,EAC9DmoB,EAASC,GAAa,EACtB1gB,EAAUjH,GAAmB,EAC7BgS,GAAU0V,EAAO,MAAQ,CAAC,GAAG,OAAQ,GAAU7mB,EAAM,YAAc,IAAI,EACvEA,EAAQmR,EAAO,KAAM,GAActY,EAAU,KAAO8tB,CAAO,GAAKxV,EAAO,GACvE9Z,EAAOgP,GAAkB,gCAAgCmgB,IAAOpgB,CAAO,EACvE2gB,EAAU,kCAAkC/mB,EAAQ,GAAGA,EAAM,YAAY,GAAK,UAAU,KAAK3J,GAAW,IAAIgB,EAAK,GACvH,OACE,EAAAb,EAAA,MAACkV,GAAD,CAAe,OAAM,aAAcP,EAAS,SAA5C,WACE,EAAA3U,EAAA,KAACoV,GAAD,CAAgB,WACd,YAAApV,EAAA,MAACkH,EAAD,CAAiB,UAAS,KAAK,KAAK,aAAY/G,EAAQ,OAAY2G,EAAE,qBAAsB,CAAE,KAAI,CAAC,EAAnG,WACE,EAAA9G,EAAA,KAACvB,GAAD,CAAK,cAAY,MAAQ,GACxB0B,GAAS2G,EAAE,eAAe,CACrB,GACM,IAChB,EAAA9G,EAAA,MAACsV,GAAD,CACE,MAAM,MACN,kBAAiBb,EACjB,UAAU,0CAHZ,WAKE,EAAAzU,EAAA,KAAC,IAAD,CAAG,GAAIyU,EAAS,UAAU,wBACvB,SAAA3N,EAAE,qBAAsB,CAAE,KAAI,CAAC,CAC/B,IACH,EAAA9G,EAAA,KAAC,IAAD,CAAG,UAAU,kCAAmC,SAAA8G,EAAE,0BAA0B,CAAK,GAChF6T,EAAO,OAAS,GACf,EAAA3a,EAAA,MAAC,MAAD,CAAK,UAAU,cAAf,WACE,EAAAA,EAAA,KAAC,QAAD,CAAO,QAASkwB,EAAU,UAAU,wBACjC,SAAAppB,EAAE,oBAAoB,CAClB,IACP,EAAA9G,EAAA,MAAC0L,GAAD,CAAQ,MAAOlC,GAAO,GAAI,cAAe4mB,EAAzC,WACE,EAAApwB,EAAA,KAAC2L,GAAD,CAAe,GAAIukB,EAAU,KAAK,KAAK,UAAU,SAC/C,YAAAlwB,EAAA,KAAC4L,GAAD,CAAc,EACD,IACf,EAAA5L,EAAA,KAAC6L,GAAD,UACG8O,EAAO,IAAK,IACX,EAAA3a,EAAA,KAAC8L,GAAD,CAA+B,MAAOzJ,EAAU,GAC7C,SAAAA,EAAU,IACD,EAFKA,EAAU,EAEf,CACb,CACY,EACT,CACL,GACH,SACJ,EAAArC,EAAA,KAAC,MAAD,CAAK,UAAU,0FACZ,SAAAuwB,CACE,IACL,EAAAvwB,EAAA,KAAC,MAAD,CAAK,UAAU,mBACb,YAAAA,EAAA,KAACK,GAAD,CAAY,MAAOkwB,CAAU,EAC1B,EACS,CACT,KAEb,EC9DaC,IAAiB,CAAE,MAAK,OAAO,KAAM,WAAgC,CAChF,GAAM,CAAE,KAAM3qB,EAAe,EACvB2C,EAAWsN,EAAY,EACvB2a,EAAUC,GAAmB,EACnC,OACE,EAAA1wB,EAAA,KAAC6X,EAAD,CACE,KAAK,UACL,MAAO/Q,EAAE,yBAA0B,CAAE,KAAI,CAAC,EAC1C,YAAaA,EAAE,+BAAgC,CAAE,KAAI,CAAC,EACtD,aAAcA,EAAE,mBAAmB,EACnC,aAAcA,EAAE,eAAe,EAC/B,cACE2pB,EAAQ,YAAYT,EAAK,CACvB,UAAY,GAAQ,KAAKxnB,EAAS,CAAE,GAAI,wBAAyB,OAAQ,CAAE,YAAa6B,EAAI,EAAG,CAAE,CAAC,CACpG,CAAC,EAEH,SACE,EAAArK,EAAA,MAACkH,EAAD,CACE,QAAQ,UACF,OACN,aAAY/G,EAAQ,OAAY2G,EAAE,yBAA0B,CAAE,KAAI,CAAC,EAHrE,WAKE,EAAA9G,EAAA,KAAC2wB,GAAD,CAAW,cAAY,MAAQ,GAC9BxwB,GAAS2G,EAAE,mBAAmB,CACzB,GAEX,EAEL,EChBa+H,IAAS,CAAE,YAAW,UAAS,WAAU,cAA2B,CAC/E,GAAM,CAAE,KAAMhJ,EAAe,EACvBgN,EAAaH,EAAc,EAC3Bke,EAAO9pB,EAAE,aAAa,EAC5B,OACE,EAAA9G,EAAA,MAAC6wB,EAAD,YACE,EAAA7wB,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAYlI,EAAE,0BAA0B,CAAa,IACrD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,uBAAuB,CAAa,IAClD,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,yBAAyB,CAAa,IACpD,EAAA9G,EAAA,KAACgP,EAAD,CAAW,UAAU,aAAc,SAAAlI,EAAE,0BAA0B,CAAa,IAC5E,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,yBAAyB,CAAa,GACnDgqB,GAAW,EAAA9wB,EAAA,KAACgP,EAAD,UAAYlI,EAAE,2BAA2B,CAAa,GAAI,MACtE,EAAA9G,EAAA,KAACgP,EAAD,UAAYlI,EAAE,yBAAyB,CAAa,IACpD,EAAA9G,EAAA,KAACgP,EAAD,WACE,EAAAhP,EAAA,KAAC,OAAD,CAAM,UAAU,UAAW,SAAA8G,EAAE,gBAAgB,CAAQ,EAC5C,EACH,GACC,IACb,EAAA9G,EAAA,KAACiP,EAAD,UACGqV,EAAU,IAAK,GAAa,CAC3B,IAAMyM,EAAOC,EAASC,EAAS,GAAG,EAC5Bnc,EAAMmc,EAAS,eAAe,GAAG,EAAE,EACnCC,EAAapc,EAAMsP,GAAqBtP,EAAI,QAAU,OAC5D,OACE,EAAA9U,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,oBACnB,YAAAnP,EAAA,MAAC,MAAD,CAAK,UAAU,0BAAf,WACE,EAAAA,EAAA,KAACgT,GAAD,CAAU,WACR,YAAAhT,EAAA,KAACmH,EAAD,CAAM,GAAG,kBAAkB,OAAQ,CAAE,IAAK,OAAO8pB,EAAS,GAAG,CAAE,EAC5D,SAAAnqB,EAAE,oBAAqB,CAAE,IAAKmqB,EAAS,GAAI,CAAC,CACzC,EACE,GACTA,EAAS,MAAQzqB,GAChB,EAAAxG,EAAA,KAAC+M,EAAD,CAAY,KAAK,UAAU,MAAOjG,EAAE,gBAAgB,EAAG,KAAK,IAAM,GAChE,IACD,GACI,IACX,EAAA9G,EAAA,MAACmP,EAAD,CAAW,UAAU,oBAAoB,MAAO8D,EAAege,EAAS,SAAS,EAAjF,UACG/d,EAAmB+d,EAAS,SAAS,GACtC,EAAAjxB,EAAA,KAAC,OAAD,CAAM,UAAU,wCAAyC,SAAA6S,EAAWoe,EAAS,KAAK,CAAQ,EACjF,KACX,EAAAjxB,EAAA,MAACmP,EAAD,CAAW,UAAU,WAArB,WACE,EAAAnP,EAAA,KAACyL,EAAD,CAAO,QAAQ,YAAa,SAAA3E,EAAEqd,GAAqB8M,EAAS,OAAO,CAAS,GAC3EA,EAAS,aAAeA,EAAS,gBAChC,EAAAjxB,EAAA,KAACmH,EAAD,CACE,GAAG,wBACH,OAAQ,CAAE,YAAa8pB,EAAS,WAAY,EAC5C,UAAU,wEAET,SAAAA,EAAS,cACN,GACJ,IACK,KACX,EAAAjxB,EAAA,KAACmP,EAAD,CAAW,UAAU,0BAA2B,SAAA8hB,EAAS,cAA0B,IACnF,EAAAjxB,EAAA,KAACmP,EAAD,CAAW,UAAU,iCAClB,SAAA8hB,EAAS,gBAAkB,KACxBL,EACA9pB,EAAE,0BAA2B,CAAE,QAASmqB,EAAS,aAAc,CAAC,CAC3D,GACVH,GACC,EAAA9wB,EAAA,KAACmP,EAAD,CAAW,UAAU,WAClB,SAAA4hB,EAAK,OAAS,GAAI,EAAA/wB,EAAA,KAAC,OAAD,CAAM,UAAU,iBAAkB,SAAA+wB,EAAK,KAAK,IAAI,CAAQ,GAAIH,CACtE,GACT,MACJ,EAAA5wB,EAAA,KAACmP,EAAD,UACG2F,GAAOoc,GACN,EAAAlxB,EAAA,KAACmH,EAAD,CACE,GAAG,sCACH,OAAQ,CAAE,MAAO2N,EAAI,EAAG,EACxB,UAAU,eAEV,YAAA9U,EAAA,KAAC+M,EAAD,CAAY,KAAMmkB,EAAW,KAAM,MAAOpqB,EAAEoqB,EAAW,QAAQ,EAAG,KAAK,IAAM,EACzE,GAENN,CAEO,IACX,EAAA5wB,EAAA,KAACmP,EAAD,CAAW,UAAU,aACnB,YAAAnP,EAAA,MAAC,MAAD,CAAK,UAAU,yBAAf,UACGixB,EAAS,MAAQzqB,EAYd,MAXF,EAAAxG,EAAA,KAACkH,EAAD,CAAQ,QAAQ,QAAQ,KAAK,KAAK,WAChC,YAAAlH,EAAA,MAACmH,EAAD,CACE,GAAG,kBACH,OAAQ,CAAE,IAAK,OAAOX,CAAO,CAAE,EAC/B,OAAQ,CAAE,KAAMyqB,EAAS,GAAI,EAC7B,aAAYnqB,EAAE,yBAA0B,CAAE,IAAKmqB,EAAS,IAAK,SAAQ,CAAC,EAJxE,WAME,EAAAjxB,EAAA,KAAC1B,GAAD,CAAY,cAAY,MAAQ,GAC/BwI,EAAE,mBAAmB,CAClB,GACA,IAEV,EAAA9G,EAAA,KAACiwB,GAAD,CAAY,IAAKgB,EAAS,GAAM,GAC/BA,EAAS,MAAQzqB,EAAiD,MAAvC,EAAAxG,EAAA,KAACwwB,GAAD,CAAe,IAAKS,EAAS,GAAM,EAC5D,GACI,EACH,GAxEKA,EAAS,GAwEd,CAEd,CAAC,CACQ,EACF,GAEf,ECrHaE,OAAkB,CAC7B,GAAM,CAAE,KAAMtrB,EAAe,EACvB,CAAE,oBAAqBwM,EAAsB,EAC7C,CAAE,UAAWmO,GAAU,CAAE,KAAM,gBAAiB,CAAC,EACjDhY,EAAWsN,EAAY,CAAE,KAAM,YAAa,CAAC,EAC7C,CAAE,cAAesb,GAAeC,EAAS,GAAS,KAAK7oB,EAAS,CAAE,OAAQ,CAAE,OAAQJ,CAAK,CAAE,CAAC,CAAC,EAC7Fkc,EAAYC,GAAa8M,CAAM,EAC/B,CAAE,eAAc,YAAaxB,GAAY,EAS/C,OARK5Z,GASH,EAAAjW,EAAA,MAACqQ,EAAD,CAAM,MAAM,OAAZ,WACE,EAAArQ,EAAA,KAACiQ,EAAD,CACE,MAAOnJ,EAAE,iBAAiB,EAC1B,KAAMwd,EAAU,KAAOxd,EAAE,oBAAqB,CAAE,IAAKwd,EAAU,KAAK,OAAQ,CAAC,EAAI,MAClF,IACD,EAAAtkB,EAAA,KAACsQ,EAAD,CACE,MAAOgU,EACP,YAAa,EACb,QAAU,GAAS5Q,EAAK,MAAM,SAAW,GAAK2d,IAAW,OACzD,OAAO,EAAArxB,EAAA,KAACiN,EAAD,CAAY,KAAMqkB,GAAQ,MAAOxqB,EAAE,iBAAiB,CAAI,GAE7D,aACA,EAAA9G,EAAA,KAACuxB,GAAD,CAAW,QAAQ,EAAAvxB,EAAA,KAACwxB,GAAD,CAAa,GAAIC,EAAW/d,EAAK,UAAU,CAAI,GAChE,YAAA1T,EAAA,KAAC6O,GAAD,CACE,UAAW6E,EAAK,MAChB,QAASA,EAAK,QACJ,WACV,SAAUiR,CACX,EACQ,EAEJ,EACP,KA7BJ,EAAA3kB,EAAA,MAACqQ,EAAD,CAAM,MAAM,OAAZ,WACE,EAAArQ,EAAA,KAACiQ,EAAD,CAAY,MAAOnJ,EAAE,iBAAiB,CAAI,IAC1C,EAAA9G,EAAA,KAACkW,GAAD,CAAW,EACP,GA4BZ,EC5Cawb,IAAU,CAAE,MAAK,MAAK,WAAU,kBAAgC,CAC3E,GAAM,CAAE,KAAM7rB,EAAe,EACvBgN,EAAaH,EAAc,EAC3BmR,EAAQ,CACZ/c,EAAE,oBAAqB,CAAE,KAAI,CAAC,EAC9B1F,EAAM6R,EAAe7R,EAAI,SAAS,EAAI,GACtCA,EAAM0F,EAAE,+BAAgC,CAAE,KAAM+L,EAAWzR,EAAI,KAAK,CAAE,CAAC,EAAI,GAC3EA,GAAK,eAAiB,KAAsE,GAA/D0F,EAAE,0BAA2B,CAAE,QAAS1F,EAAI,aAAc,CAAC,EACxFmJ,IAAa,QAAaonB,IAAiB,OACvC7qB,EAAE,kCAAmC,CAAE,MAAO6qB,EAAc,IAAKpnB,CAAS,CAAC,EAC3E,EACN,CAAC,CAAC,OAAO,OAAO,EAChB,OACE,EAAAvK,EAAA,KAAC,IAAD,CAAG,YAAU,SAAS,UAAU,qCAC7B,SAAA6jB,EAAM,KAAK,KAAK,CAChB,EAEP,ECvBM+N,IAAW,EAAwB,IAAwC,CAC/E,IAAMrgB,EAAQsgB,GAAoB7vB,CAAK,EACjC8vB,EAAQzG,EAAgBrpB,CAAK,CAAC,CAAC,MACrC,MAAO,CACL,QAASA,EAAM,GACf,SAAUA,EAAM,OAChB,SAAUM,EAAWN,CAAK,EAC1B,MAAOA,EAAM,MACb,UAAWA,EAAM,OAAS,YAC1B,SAAUuP,GAAO,QAAU,KAC3B,SAAUugB,GAAO,QAAU,KAC3B,SACF,CACF,EAMaC,OAA0B,CACrC,IAAMpvB,EAAS+gB,GAAe,OAAO,EAC/BvY,EAAUC,GAAW,EAa3B,MAAO,CAAE,UAZMpF,eAAc,CAC3B,GAAI,CAACrD,EAAO,MAAQ,CAACwI,EAAQ,KAC3B,OAEF,IAAM6mB,EAAQ7mB,EAAQ,KAAK,IAAK,GAAWY,EAAO,IAAI,EAChDkmB,EAAgB9mB,EAAQ,KAAK,KAAM,GAAWY,EAAO,SAAS,CAAC,EAAE,MAAQimB,EAAM,IAAM,KAC3F,OAAOrvB,EAAO,KAAK,SAAS,CAAE,gBAC5BuD,EAAW,OAAS,YAChB,CAAC,EACD,CAAC0rB,GAAQ1rB,EAAYA,EAAW,UAAY8rB,EAAQ,CAACC,CAAa,CAAC,CAAC,CAC1E,CACF,EAAG,CAACtvB,EAAO,KAAMwI,EAAQ,IAAI,CACpB,EAAQ,MAAOxI,EAAO,OAASwI,EAAQ,KAAM,CACxD,ECxBM+mB,IAAU,EAAsC,IAC/CptB,EAGDqtB,EAAM,OAAS,GAAKA,EAAM,MAAO,GAASpS,IAAS,WAAW,EACzD,QAEFoS,EAAM,OAAS,EAAI,UAAY,YAL7B,UAcEC,IAAc,EAA2B,IAAuD,CAC3G,IAAMzsB,EAAO,IAAI,IACjB,IAAK,IAAM5C,KAAQ+B,EAAM,CACvB,IAAMutB,EAAO1sB,EAAK,IAAI5C,EAAK,EAAE,EAC7B,GAAIsvB,EAAM,CACHA,EAAK,QAAQ,SAAStvB,EAAK,MAAM,GACpCsvB,EAAK,QAAQ,KAAKtvB,EAAK,MAAM,EAE/B,EAAK,QAAUA,EAAK,MACpB,EAAK,WAAaA,EAAK,SACvB,QACF,CACA4C,EAAK,IAAI5C,EAAK,GAAI,CAChB,GAAIA,EAAK,GACT,MAAOA,EAAK,MACZ,SAAUA,EAAK,SACf,QAAS,CAACA,EAAK,MAAM,EACrB,KAAM,YACN,YAAa,CAAC,CAChB,CAAC,CACH,CACA,IAAMuvB,EAA0B,CAAC,EACjC,IAAK,IAAMtY,KAAUmB,EAAS,CAC5B,IAAMkX,EAAO1sB,EAAK,IAAIqU,EAAO,EAAE,EACzBuY,EAAc,OAAO,YACzBvY,EAAO,QAAQ,SAAS,CAAE,SAAQ,gBAAkBwY,EAAa,CAAC,CAACzmB,EAAQymB,CAAU,CAAC,EAAI,CAAC,CAAE,CAC/F,EACMC,EAAOP,GACXlY,EAAO,QAAQ,KAAK,CAAE,OAAQ+F,KAAWA,CAAI,EAC7CsS,IAAS,MACX,EACIA,GACF,EAAK,KAAOI,EACZ,EAAK,YAAcF,EACnB,EAAK,QAAUvY,EAAO,OACbyY,IAAS,WAClBH,EAAQ,KAAK,CACX,GAAItY,EAAO,GACX,MAAOA,EAAO,MACd,SAAU,KACV,QAASA,EAAO,QAAQ,KAAK,CAAE,YAAajO,CAAM,EAClD,OACA,aACF,CAAC,CAEL,CACA,MAAO,CAAC,GAAGpG,EAAK,OAAO,EAAG,GAAG2sB,CAAO,CACtC,EAGaI,IAAY,EAAe,EAAW,KACjD5P,GAAS6P,EAAW,EAAI,KAAK,KAAK7P,EAAQ6P,CAAQ,EC1E9CC,GAAa,GAMNC,IAAU,CAAE,OAAM,QAAO,cAA4B,CAChE,GAAM,CAAE,KAAMhtB,EAAe,EACvB6O,GAAA,EAAU/J,SAAM,EAChBhH,EAAQ,KAAK,IAAImvB,EAAK,QAAQ5xB,CAAK,EAAG,CAAC,EACvC+e,EAAO,KAAK,IAAI6S,EAAK,OAAS,EAAG,CAAC,EAClCC,EAAOL,GAASI,EAAK,MAAM,EAC3BE,EAAM,GAAiB,CAC3B,IAAMhD,EAAM8C,EAAK,KAAK,IAAI,KAAK,IAAI1qB,EAAM,CAAC,EAAG0qB,EAAK,OAAS,CAAC,GACxD9C,IAAQ,QAAaA,IAAQ9uB,GAC/ByI,EAASqmB,CAAG,CAEhB,EAWA,OACE,EAAAhwB,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,MAAC,MAAD,CAAK,UAAU,0CAAf,WACE,EAAAA,EAAA,KAAC,QAAD,CAAO,QAAS0U,EAAS,UAAU,wBAChC,SAAA5N,EAAE,0BAA0B,CACxB,IACP,EAAA9G,EAAA,KAAC,OAAD,CAAM,UAAU,+CACb,SAAA8G,EAAE,2BAA4B,CAAE,IAAKgsB,EAAK,IAAM5xB,EAAO,IAAK4xB,EAAK,GAAG,EAAE,GAAK5xB,CAAM,CAAC,CAC/E,EACH,KACL,EAAAlB,EAAA,KAAC,QAAD,CACE,GAAI0U,EACJ,KAAK,QACL,IAAK,EACL,IAAKoe,EAAK,OAAS,EACnB,KAAM,EACN,MAAOnvB,EACP,iBAAgBmD,EAAE,oBAAqB,CAAE,IAAK5F,CAAM,CAAC,EAC1C,UA5BE,GAA2C,CAC5D,GAAI,CAAC6I,EAAM,SACT,OAEF,IAAMkpB,EAAQ,CAAE,UAAW,GAAI,UAAW,GAAI,WAAY,EAAG,QAAS,CAAE,EAAElpB,EAAM,KAC5EkpB,IAAU,SACZlpB,EAAM,eAAe,EACrBipB,EAAGrvB,EAAQsvB,EAAQL,EAAU,EAEjC,EAoBM,SAAW,GAAUI,EAAG,OAAOjpB,EAAM,OAAO,KAAK,CAAC,EAClD,UAAU,yHACX,IAED,EAAA/J,EAAA,KAAC,MAAD,CAAK,cAAY,OAAO,UAAU,oBAC/B,SAAA8yB,EAAK,KAAK,EAAK,IACdI,EAAWH,IAAS,GAAKG,IAAaJ,EAAK,OAAS,GAClD,EAAA9yB,EAAA,KAAC,SAAD,CAEE,KAAK,SACL,SAAU,GACV,MAAO8G,EAAE,oBAAqB,CAAE,KAAI,CAAC,EACrC,YAAe6C,EAASqmB,CAAG,EAC3B,MAAO,CAAE,SAAU,GAAIkD,EAAWjT,EAAQ,IAAI,EAAG,EACjD,UAAWhgB,EACT,sGACA+vB,IAAQ9uB,GAAS,sBACnB,CACD,EAVM8uB,CAUN,EACC,IACN,CACG,EACF,GAET,EC1EMmD,GAAc,GAAkC,CACpD,GAAI,OAAOjyB,GAAU,WAAYA,EAC/B,OAAO,KAET,IAAM4wB,EAAQ5wB,EACRkyB,EAAYtB,EAAM,UAAU,KAAM,GAAYuB,EAAQ,OAAS,WAAW,CAAC,EAAE,IAInF,OAHI,OAAOD,GAAc,SAChBA,EAEF,OAAOtB,EAAM,KAAQ,SAAWA,EAAM,IAAM,IACrD,EAEMwB,IAAc,EAAyB,IAA4C,CACvF,IAAM/hB,EAAQgiB,EAAM,SAAWxwB,EAAKwwB,EAAM,UAAY,OACtD,MAAO,CACL,GAAI,OAAOxwB,EAAK,EAAE,EAClB,OAAQ,OAAOA,EAAK,MAAM,EAC1B,MACE,OAAOwO,GAAU,UAAYA,EAAM,KAAK,IAAM,GAC1CA,EACA,OAAOA,GAAU,SACf,OAAOA,CAAK,EACZ,KACR,SAAUgiB,EAAM,SAAWJ,GAAWpwB,EAAKwwB,EAAM,SAAS,EAAI,IAChE,CACF,EAIMjlB,IAAW,EAAa,IAC5BklB,EAAO,QAAS,GAAUD,EAAM,QAAQ,IAAK,IAAY,CAAE,QAAO,SAAQ,KAAI,EAAE,CAAC,EAOtEE,IACX,EACA,EACA,EACA,IACG,CACH,IAAM7R,EAAcC,EAAe,EAC7B3S,EAAQZ,GAAQ0hB,EAAKwD,CAAM,EAC3BrY,EAAUuY,GAAmBnpB,GAAY,EAAGylB,EAAKzlB,IAAa,MAAS,EACvEzF,EAAO+I,GAAW,CACtB,QAASqB,EAAM,KAAK,CAAE,QAAO,YAAaykB,GAA0B3D,EAAKuD,EAAOxnB,CAAM,CAAC,EACvF,QAAU,IAAa,CACrB,KAAMgC,EAAQ,IAAK,GAAWC,EAAO,IAAI,EACzC,UAAWD,EAAQ,KAAM,GAAWC,EAAO,SAAS,EACpD,MAAOD,EAAQ,KAAM,GAAWC,EAAO,KAAK,CAAC,EAAE,OAAS,KACxD,YAAe,QAAQ,IAAID,EAAQ,IAAK,GAAWC,EAAO,QAAQ,CAAC,CAAC,CACtE,EACF,CAAC,GAED,EAAAohB,EAAA,eAAgB,CACd,IAAK,IAAMwE,KAAaC,EACtB,IAAK,IAAM9P,KAAQzV,GAAQslB,EAAWJ,CAAM,EAC1C5R,EAAiB,cAAc+R,GAA0BC,EAAW7P,EAAK,MAAOA,EAAK,MAAM,CAAC,CAGlG,EAAG,CAAC8P,EAAYL,EAAQ5R,CAAW,CAAC,EAEpC,IAAMlI,EAAOyB,EAAQ,MAAM,OAAS,CAAC,EAarC,MAAO,CACL,OAb2BqY,EAAO,IAAK,IAIhC,CACL,QACA,MAAOpB,GALKljB,EAAM,SAAS,EAAM,IACjC6U,EAAK,QAAUwP,GAASzuB,EAAK,KAAKnB,IAAU,CAAC,GAAG,IAAK,GAAS2vB,GAAWC,EAAOxwB,CAAI,CAAC,EAAI,CAAC,CAKxF,EACA2W,EAAK,OAAQ,GAAWM,EAAO,UAAYuZ,EAAM,OAAO,CAC1D,CACF,EAGQ,EAAO,OAAQ,GAAU/oB,EAAM,MAAM,OAAS,CAAC,EACvD,UAAW1F,EAAK,WAAcyF,IAAa,QAAa4Q,EAAQ,UAChE,MAAOrW,EAAK,OAASqW,EAAQ,MAC7B,YAAe,QAAQ,IAAI,CAACrW,EAAK,QAAQ,EAAGqW,EAAQ,QAAQ,CAAC,CAAC,CAChE,CACF,ECpFM2Y,GAAe,CACnB,UAAW,CAAE,SAAU,qCAAsC,KAAM,SAAU,EAC7E,MAAO,CAAE,SAAU,iCAAkC,KAAM,SAAU,EACrE,QAAS,CAAE,SAAU,mCAAoC,KAAM,SAAU,EACzE,QAAS,CAAE,SAAU,mCAAoC,KAAM,OAAQ,CACzE,EAGMC,GAAe,CACnB,UAAW,GACX,MAAO,6CACP,QAAS,yDACT,QAAS,2DACX,EAKaC,IAAQ,CAAE,OAAM,YAAwB,CACnD,GAAM,CAAE,KAAMnuB,EAAe,EACvByU,EAAUwZ,GAAazB,EAAK,MAC5B9gB,EAAQ8gB,EAAK,OAASvrB,EAAE,6BAA6B,EAC3D,OACE,EAAA9G,EAAA,MAAC,KAAD,CACE,YAAWqyB,EAAK,KAChB,aAAYvrB,EAAE,+BAAgC,CAAE,QAAO,MAAOA,EAAEwT,EAAQ,QAAQ,CAAE,CAAC,EACnF,UAAWra,EACT,6FACA8zB,GAAa1B,EAAK,KACpB,EANF,WAQE,EAAAryB,EAAA,KAAC,MAAD,CACE,UAAWC,EACT,uHACAoyB,EAAK,OAAS,WAAa,sBAC7B,EAEC,SAAAA,EAAK,UACJ,EAAAryB,EAAA,KAAC,MAAD,CAAK,IAAKqyB,EAAK,SAAU,IAAI,GAAG,QAAQ,OAAO,UAAU,wBAA0B,IAEnF,EAAAryB,EAAA,KAACi0B,GAAD,CAAU,cAAY,OAAO,UAAU,8BAAgC,EAEtE,IACL,EAAAj0B,EAAA,MAAC,MAAD,CAAK,UAAU,iCAAf,WACE,EAAAA,EAAA,KAAC,IAAD,CAAG,UAAWC,EAAG,qCAAsCoyB,EAAK,OAAS,WAAa,cAAc,EAC7F,SAAA9gB,CACA,IACH,EAAAvR,EAAA,MAAC,MAAD,CAAK,UAAU,sCAAf,WACE,EAAAA,EAAA,KAAC+M,EAAD,CAAY,KAAMuN,EAAQ,KAAM,MAAOxT,EAAEwT,EAAQ,QAAQ,EAAG,KAAK,KAAK,KAAM,EAAQ,GACnF+X,EAAK,QAAQ,IAAK,IACjB,EAAAryB,EAAA,KAACyL,EAAD,CAAoB,QAAQ,UAAU,UAAU,YAC7C,SAAAM,CACI,EAFKA,CAEL,CACR,CACE,KACL,EAAA/L,EAAA,MAACkH,EAAD,CACE,QAAQ,QACR,KAAK,KACL,UAAU,qBACV,aAAYJ,EAAE,mCAAoC,CAAE,OAAM,CAAC,EAC3D,YAAeotB,EAAO7B,CAAI,EAL5B,WAOE,EAAAryB,EAAA,KAACsgB,GAAD,CAAS,cAAY,MAAQ,GAC5BxZ,EAAE,gCAAgC,CAC7B,GACL,CACH,KAER,EClEMqtB,GAA0C,IAAI,IAAI,CAAC,UAAW,SAAS,CAAC,EAOjEC,IAAkB,EAAkB,IAA0C,CACzF,IAAM5rB,EAAWsN,EAAY,EACvB8L,EAAcC,EAAe,EAC7BwS,EAAa,MAAO,EAAiB,IAAmB,CAK5D,IAAMhZ,GAAS,MAJSuG,EAAY,WAAW,CAC7C,SAAUriB,EAAU,QAAQ,UAAUyN,EAAUsnB,EAASvoB,CAAM,EAC/D,YAAesB,EAAS,QAAQ,UAAUL,EAAUsnB,EAAS,CAAE,QAAO,CAAC,CACzE,CAAC,GACwB,OACtB,GAAaC,IAAsB,QAAaC,EAAS,WAAaD,CACzE,EACME,EAAU,GACd,CAAC,GAAGC,CAAI,CAAC,CAAC,MAAM,EAAG,IAAMruB,EAAE,UAAU,cAAcD,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,GACvE,OAAOquB,EAAOpZ,EAAO,OAAQ,GAAa8Y,GAAmB,IAAIK,EAAS,MAAM,CAAC,CAAC,GAAKC,EAAOpZ,CAAM,CACtG,EACA,OAAO,KAAO,IAAuB,CACnC,IAAMtP,EAASsmB,EAAK,QAAQ,GAC5B,GAAI,CACF,IAAMmC,GACHzoB,EAASsmB,EAAK,YAAYtmB,GAAU,UACpCA,EAAS,MAAMsoB,EAAWhC,EAAK,GAAItmB,CAAM,EAAI,QAChD,MAAMvD,EAAS,CACb,GAAI,8BACJ,OAAQ,CAAE,WAAU,QAAS6pB,EAAK,EAAG,EACrC,OAAQ,CAAE,GAAItmB,EAAS,CAAE,QAAO,EAAI,CAAC,EAAI,GAAIyoB,EAAW,CAAE,UAAS,EAAI,CAAC,CAAG,CAC7E,CAAC,CACH,OAASne,EAAO,CACdrB,GAASqB,EAAO,4CAA4C,EAC5D9B,EAAM,MAAMogB,GAActe,CAAK,CAAC,CAClC,CACF,CACF,ECxCaue,IAAgB,CAAE,QAAO,MAAK,uBAA2C,CACpF,GAAM,CAAE,KAAM/uB,EAAe,EACvBgvB,EAAcT,GAAe5pB,EAAM,MAAM,SAAU+pB,CAAiB,EACpEzvB,EAAO0F,EAAM,MAAM,OAAQ,GAAS6nB,EAAK,OAAS,SAAS,CAAC,CAAC,OACnE,OACE,EAAAryB,EAAA,MAAC,UAAD,CAAS,aAAYwK,EAAM,MAAM,MAAO,UAAU,YAAlD,WACE,EAAAxK,EAAA,MAAC,KAAD,CAAI,UAAU,oDAAd,UACGwK,EAAM,MAAM,OACb,EAAAxK,EAAA,KAAC,OAAD,CAAM,UAAU,8CACb,SAAA8G,EAAE,+BAAgC,CAAE,MAAOhC,CAAK,CAAC,CAC9C,EACJ,CACJ,MAAA9E,EAAA,KAAC,KAAD,CAAI,UAAU,uDACX,SAAAwK,EAAM,MAAM,IAAK,IAEhB,EAAAxK,EAAA,KAACg0B,GAAD,CAEQ,OACN,OAAS,GAAW,KAAKa,EAAYC,CAAM,CAC5C,EAHMzC,EAAK,OAAS,YAAcA,EAAK,GAAK,GAAGA,EAAK,GAAG,GAAGrC,GAG1D,CACF,CACC,EACG,GAEb,ECZa+E,IAAS,CAAE,MAAK,OAAM,WAAU,SAAQ,eAA4B,CAC/E,GAAM,CAAE,KAAMlvB,EAAe,EACvBlC,EAAQmvB,EAAK,QAAQ9C,CAAG,EACxB3U,EAASyX,EAAKnvB,EAAQ,GACtByX,EAAQ0X,EAAKnvB,EAAQ,GAKrB6G,EAAQipB,GAAWzD,EAAKzlB,GAJxB,EAAavE,eACX,CAACqV,EAAQD,CAAK,CAAC,CAAC,OAAQ,GAAmCwY,IAAc,MAAS,EACxF,CAACvY,EAAQD,CAAK,CAEwB,EAAYoY,CAAM,EAU1D,OATIhpB,EAAM,OACD,EAAAxK,EAAA,KAACkkB,GAAD,CAAY,MAAO1Z,EAAM,MAAO,YAAe,KAAKA,EAAM,QAAQ,CAAI,GAE3EA,EAAM,WAAaA,EAAM,OAAO,SAAW,GACtC,EAAAxK,EAAA,KAACuhB,GAAD,CAAc,KAAM,CAAI,GAE7B/W,EAAM,OAAO,SAAW,GACnB,EAAAxK,EAAA,KAACiN,EAAD,CAAY,KAAM+nB,GAAO,MAAOluB,EAAE,iCAAkC,CAAE,KAAI,CAAC,CAAI,IAGtF,EAAA9G,EAAA,KAAC,MAAD,CAAK,YAAWwK,EAAM,WAAa,OAAW,UAAU,YACrD,SAAAA,EAAM,OAAO,IAAK,IACjB,EAAAxK,EAAA,KAAC40B,GAAD,CAEE,MAAOK,EACF,MACL,kBAAmBC,CACpB,EAJMD,EAAW,MAAM,OAIvB,CACF,CACE,EAET,ECpCME,GAAmB,IAcZC,IAAY,CAAE,KAAI,gBAAgC,CAC7D,GAAM,CAAE,KAAMvvB,EAAe,EACvBwvB,EAASC,GAAkB,EAC3B,CAAE,SAAQ,MAAOC,GAAgBxD,GAAkB,EACnD,CAACmB,EAAUsC,IAAA,EAAettB,YAASiP,CAAE,EACrCse,EAAU1K,GAAkBmI,EAAUiC,EAAgB,EACtDrC,GAAA,EAAO9sB,eACJqvB,EAAO,KAAOA,EAAO,KAAK,MAAM,IAAK,GAAQj0B,EAAI,GAAG,CAAC,CAAC,MAAM,EAAG,IAAMgF,EAAIC,CAAC,EAAI,CAAC,EACtF,CAACgvB,EAAO,IAAI,CACd,GACA,EAAAjG,EAAA,eAAgB,CACVqG,IAAYte,GACdue,EAAWD,CAAO,CAEtB,EAAG,CAACA,EAASte,EAAIue,CAAU,CAAC,EAG5B,IAAMC,EAAc,GAAgB7C,EAAKA,EAAK,QAAQ9C,CAAG,EAAI,KAAOA,EAAM,EAAIA,EAAM,EAAI,QAClF4F,EAAkBD,EAAWF,CAAO,EAEpCI,EAAiBnC,GAAmBkC,GAAmB,EAAGH,EAASG,IAAoB,MAAS,EAEtG,GAAIP,EAAO,SAAWE,EACpB,OAAO,EAAAv1B,EAAA,KAACkkB,GAAD,CAAY,MAAOmR,EAAO,OAASE,EAAa,YAAe,KAAKF,EAAO,QAAQ,CAAI,GAEhG,GAAI,CAACA,EAAO,MAAQ,CAAC7B,EACnB,OAAO,EAAAxzB,EAAA,KAACuhB,GAAD,CAAc,KAAM,CAAI,GAEjC,IAAMngB,EAAMi0B,EAAO,KAAK,MAAM,KAAM,GAAStyB,EAAK,MAAQmwB,CAAQ,EAC5D4C,EAAaT,EAAO,KAAK,MAAM,KAAM,GAAStyB,EAAK,MAAQ0yB,CAAO,EAClEjvB,EAAU6uB,EAAO,KAAK,QAC5B,OACE,EAAAr1B,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,KAACiH,EAAD,CAAO,aAAYH,EAAE,0BAA0B,EAC7C,YAAA9G,EAAA,MAAC,MAAD,CAAK,UAAU,YAAf,WACE,EAAAA,EAAA,KAAC0xB,GAAD,CACE,IAAKwB,EACA,MACL,SAAUyC,EAAWzC,CAAQ,EAC7B,aAAcA,IAAauC,EAAUI,EAAe,MAAM,MAAM,OAAS,MAC1E,IACD,EAAA71B,EAAA,KAAC6yB,GAAD,CAAc,OAAM,MAAOK,EAAU,SAAUsC,CAAc,IAC7D,EAAAx1B,EAAA,MAAC,MAAD,CAAK,UAAU,uBAAf,UACGkzB,IAAa1sB,EAAU,MACtB,EAAAxG,EAAA,KAACwwB,GAAD,CAAe,IAAK0C,EAAU,KAAK,UAAU,MAAOpsB,EAAE,gCAAgC,CAAI,IAE5F,EAAA9G,EAAA,KAACiwB,GAAD,CAAY,IAAKiD,EAAU,QAAQ,UAAU,MAAOpsB,EAAE,4BAA4B,CAAI,EACnF,GACF,GACA,IACP,EAAA9G,EAAA,KAAC+0B,GAAD,CACE,IAAKU,EACC,OACN,SAAUG,EACF,SACR,UAAWE,GAAY,SACxB,EACE,GAET,EC9EMC,GAAiB,CACrB,UAAW,CAAE,SAAU,8BAA+B,KAAM,SAAU,EACtE,QAAS,CAAE,SAAU,4BAA6B,KAAM,SAAU,EAClE,YAAa,CAAE,SAAU,gCAAiC,KAAM,OAAQ,CAC1E,EAKajR,IAAc,CAAE,UAA4B,CACvD,GAAM,CAAE,GAAMjf,EAAe,EACvB,CAAE,kBAAmBmwB,EACrBC,EAAcC,EAAe,OAASA,EAAe,GAC3D,OACE,EAAAl2B,EAAA,KAACuxB,GAAD,CACE,SACE,EAAAvxB,EAAA,MAAC,IAAD,CAAG,UAAU,kCAAb,UACG,EAAEg2B,EAAK,WAAa,4BAA8B,wBAAyB,CAC1E,KAAMA,EAAK,KACX,GAAIA,EAAK,GACT,MAAOA,EAAK,MAAM,MACpB,CAAC,EACAC,EACG,MAAM,EAAE,wBAAyB,CAAE,KAAMC,EAAe,MAAQ,IAAK,GAAIA,EAAe,IAAM,GAAI,CAAC,IACnG,EACH,IAGJ,SAAAF,EAAK,MAAM,SAAW,GACrB,EAAAh2B,EAAA,KAACiN,EAAD,CAAY,KAAMkpB,GAAW,KAAK,QAAQ,MAAO,EAAE,qBAAqB,CAAI,IAE5E,EAAAn2B,EAAA,MAAC6O,EAAD,YACE,EAAA7O,EAAA,KAAC8O,EAAD,WACE,EAAA9O,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACgP,EAAD,UAAY,EAAE,sBAAsB,CAAa,IACjD,EAAAhP,EAAA,KAACgP,EAAD,UAAY,EAAE,sBAAsB,CAAa,IACjD,EAAAhP,EAAA,KAACgP,EAAD,UAAY,EAAE,0BAA0B,CAAa,EAC7C,GACC,IACb,EAAAhP,EAAA,KAACiP,EAAD,UACG+mB,EAAK,MAAM,IAAK,IACf,EAAAh2B,EAAA,MAAC+O,EAAD,YACE,EAAA/O,EAAA,KAACmP,EAAD,CAAW,UAAU,WACnB,YAAAnP,EAAA,KAACgT,GAAD,CAAU,WAAQ,UAAU,mCAC1B,YAAAhT,EAAA,KAACmH,EAAD,CACE,GAAG,8BACH,OAAQ,CAAE,SAAUwF,EAAM,SAAU,QAASA,EAAM,EAAG,EAErD,SAAAA,EAAM,EACH,EACE,EACD,IACX,EAAA3M,EAAA,KAACmP,EAAD,CAAW,UAAU,oBAAqB,SAAAxC,EAAM,QAAoB,IACpE,EAAA3M,EAAA,KAACmP,EAAD,WACE,EAAAnP,EAAA,KAAC,KAAD,CAAI,UAAU,yBACX,SAAA2M,EAAM,QAAQ,IAAK,GAAW,CAC7B,IAAM2N,EAAUyb,GAAehqB,EAAO,QACtC,OACE,EAAA/L,EAAA,KAAC,KAAD,WACE,EAAAA,EAAA,KAAC+M,EAAD,CACE,KAAMuN,EAAQ,KACd,KAAK,KACL,MAAO,EAAE,yBAA0B,CACjC,OAAQvO,EAAO,OACf,OAAQ,EAAEuO,EAAQ,QAAQ,CAC5B,CAAC,CACF,EACC,EATKvO,EAAO,MASZ,CAER,CAAC,CACC,EACK,EACH,GA/BKY,EAAM,EA+BX,CACX,CACQ,EACN,GAEA,EAEf,ECrEMmD,GAAiB,CACrB,KAAM,sBACN,SAAU,yBACZ,EAIayQ,IAAQ,CAAE,cAA0B,CAC/C,GAAM,CAAE,GAAM1a,EAAe,EACvBgN,EAAaH,EAAc,EAC3BrR,EAASmf,GAAU,CAAE,KAAM,qBAAsB,CAAC,EAClDhY,EAAWsN,EAAY,CAAE,KAAM,iBAAkB,CAAC,EAClDpN,EAAMrH,EAAO,KAAO,OACpBq0B,GAAA,EAAavtB,eAChB,GAAe,KAAKK,EAAS,CAAE,OAAS,IAAU,CAAE,GAAG4tB,EAAM,IAAG,GAAI,QAAS,EAAK,CAAC,EACpF,CAAC5tB,CAAQ,CACX,EACMklB,EAAOrsB,EAAO,OAAS,QAAaA,EAAO,KAAO4vB,EAAS,IAAM5vB,EAAO,KAAO4vB,EAAS,IAAM,EAE9FzqB,EADS+d,GAAa,MACZ,EAAO,MAAM,QACvBpJ,EAAUuY,GAAmBhG,EAAMuD,EAAS,IAAKvoB,IAAQ,MAAM,EAC/DgY,EAAO,CACXzN,EAAege,EAAS,SAAS,EACjCpe,EAAWoe,EAAS,KAAK,EACzBA,EAAS,gBAAkB,KAAO,GAAK,EAAE,0BAA2B,CAAE,QAASA,EAAS,aAAc,CAAC,CACzG,CAAC,CACE,OAAO,OAAO,CAAC,CACf,KAAK,KAAK,EACb,OACE,EAAAjxB,EAAA,KAACqQ,EAAD,WACE,EAAArQ,EAAA,MAACsP,GAAD,CACE,MAAO5G,EACP,cAAgB,GACd,KAAKF,EAAS,CAAE,OAAS,IAAU,CAAE,GAAG4tB,EAAM,IAAKl1B,CAAqB,GAAI,QAAS,EAAK,CAAC,EAE7F,UAAU,QALZ,WAOE,EAAAlB,EAAA,KAACiQ,EAAD,CACE,WAAY,CAAC,CAAE,MAAO,EAAE,iBAAiB,EAAG,KAAM0Q,GAAY,CAAE,GAAI,YAAa,CAAC,CAAE,CAAC,EACrF,MAAO,EAAE,oBAAqB,CAAE,IAAKsQ,EAAS,GAAI,CAAC,EACnD,OACE,EAAAjxB,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACyL,EAAD,CAAO,QAAQ,YAAa,WAAE0Y,GAAqB8M,EAAS,OAAO,CAAS,GAC3EA,EAAS,MAAQzqB,GAAU,EAAAxG,EAAA,KAAC+M,EAAD,CAAY,KAAK,UAAU,MAAO,EAAE,gBAAgB,CAAI,GAAI,IACxF,IAEE,OACN,SACE,EAAA/M,EAAA,MAAAgM,WAAA,YACE,EAAAhM,EAAA,KAACiwB,GAAD,CAAY,IAAKgB,EAAS,GAAM,GAC/BzqB,IAAY,QAAayqB,EAAS,MAAQzqB,GACzC,EAAAxG,EAAA,KAACwwB,GAAD,CAAe,IAAKS,EAAS,IAAK,KAAK,SAAW,GAChD,IACJ,IAEJ,MACE,EAAAjxB,EAAA,KAACuP,GAAD,CAAU,QAAQ,YAAY,aAAY,EAAE,sBAAsB,EAC/D,SAAA8mB,GAAc,IAAK,IAClB,EAAAr2B,EAAA,KAACwP,GAAD,CAAuB,MAAO9O,EAC3B,WAAEoP,GAAepP,EAAI,CACX,EAFKA,CAEL,CACd,CACO,EAEb,IACD,EAAAV,EAAA,KAACyP,EAAD,CAAa,MAAM,OACjB,YAAAzP,EAAA,KAACsQ,EAAD,CAAW,MAAO6K,EAAS,YAAa,EACpC,aAAS,EAAAnb,EAAA,KAAC8kB,GAAD,CAAkB,MAAO,EAC3B,EACA,IACb,EAAA9kB,EAAA,KAACyP,EAAD,CAAa,MAAM,WACjB,YAAAzP,EAAA,KAACo1B,GAAD,CAAU,GAAI/zB,EAAO,IAAM4vB,EAAS,IAAiB,YAAa,EACvD,EACT,CACF,IAEV,ECrFaqF,GAAoB,CAC/B,QAASC,EAAgB,cAAc,CAAC,CAAC,CAAE,UAAW1gB,EAAQ,CAAC,EAC/D,UAAW0gB,EAAgB,2BAA2B,CAAC,CAAC,CAAE,UAAW1V,EAAU,CAAC,EAChF,UAAW0V,EAAgB,gBAAgB,CAAC,CAAC,CAAE,UAAWpF,EAAU,CAAC,EACrE,SAAUoF,EAAgB,qBAAqB,CAAC,CAAC,CAAE,cCNzB,CAC1B,GAAM,CAAE,OAAQzV,GAAU,CAAE,KAAM,qBAAsB,CAAC,EACnD,CAAE,oBAAqBzO,EAAsB,EAC7C4e,EAAWuF,GAAY,OAAOxG,CAAG,CAAC,EAQxC,OAPK/Z,GAQH,EAAAjW,EAAA,KAACsQ,EAAD,CAAW,MAAO2gB,EAAU,YAAa,EACrC,aAAS,EAAAjxB,EAAA,KAACugB,GAAD,CAAM,SAAU7M,CAAO,EACzB,IART,EAAA1T,EAAA,KAACqQ,EAAD,WACE,EAAArQ,EAAA,KAACkW,GAAD,CAAW,EACP,EAQZ,CDV+E,CAAC,EAC9E,KAAMqgB,EAAgB,WAAW,CAAC,CAAC,CAAE,UAAW9R,EAAK,CAAC,EACtD,OAAQ8R,EAAgB,aAAa,CAAC,CAAC,CAAE,UAAW5H,EAAO,CAAC,EAC5D,YAAa4H,EAAgB,mBAAmB,CAAC,CAAC,CAAE,UAAWnmB,EAAY,CAAC,EAC5E,QAASmmB,EAAgB,sBAAsB,CAAC,CAAC,CAAE,UAAWnV,EAAQ,CAAC,CACzE","names":["__iconData","CalendarX","createLucideIcon","FileType","GitCompare","GitMerge","Package","Pin","Puzzle","Radio","Workflow","unchangedSinceBase","remote","base","decideForLocal","local","decideSync","prune","silent","DOCS_PATHS","docsKeys","queryKeys","useOpenApiDocument","useQuery","apiClient","useTypeScriptDeclarations","graphqlPlaygroundUrl","apiBaseUrl","useGraphqlPlaygroundAvailable","CodeBlock","import_jsx_runtime","cn","className","label","copyable","CopyButton","code","EMPTY_DRAFT","SCALAR_PARAMS","filterParamName","key","part","requestPath","path","operation","draft","query","name","value","parameter","row","search","isSendable","TOKEN_PLACEHOLDER","curlSnippet","url","withToken","fetchSnippet","headers","GRAPHQL_OPERATION_PREFIX","graphqlOperations","single","model","listName","collectionQueryName","restOperationFor","restOperations","candidate","routeKeyOf","counterpartOperationId","target","rest","operationId","models","selectionOf","field","splitList","item","NUMBER","INTEGER","SYSTEM_ATTRIBUTES","OPERATORS","LIST_OPERATORS","BOOLEAN_OPERATORS","isBooleanText","raw","literal","parseFilterKey","operator","index","match","operandOf","values","filterArgument","fields","conditions","skipped","parsed","byOperator","existing","condition","sortArgument","known","items","sort","direction","extra","selectedFields","live","names","chosen","selection","indent","line","readArguments","args","listArguments","filter","call","graphqlQuery","id","byId","GraphqlTab","useTranslation","useAllDefinitions","groups","useMemo","definitions","definition","isModelDefinition","a","b","pairs","operations","current","pair","selected","built","draftOf","SubNav","t","SubNavGroup","SubNavLink","Panel","Button","Link","Braces","DELIVERY_PREFIX","deliveryOperations","document","methods","parameters","groupOperations","order","tag","group","hasParameter","useRequestDrafts","drafts","setDrafts","useState","useCallback","next","route","getRouteApi","useSwitchTab","navigate","op","tab","useDeliverySiteKey","site","useMe","METHOD","EndpointNav","selectedId","absoluteApiUrl","parseBody","text","useSendRequest","useMutation","started","response","token","FilterRows","update","onChange","rows","patch","Input","event","X","newStableId","Plus","useExplorerTokenStore","create","set","useSessionStore","previous","state","TextParam","inputProps","useId","hintId","HintedLabel","hint","mono","DEFAULT_LOCALE","RequestBuilder","localeId","locales","useLocales","setToken","onDraftChange","sendable","onSend","Badge","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","locale","_Fragment","sending","Send","LABEL_KEYS","isRecord","toEntry","labelKey","responseEntries","body","EntryLinks","entries","entry","Pencil","ResponseView","pretty","StatusChip","modelKey","EmptyState","modelUsageOptions","modelId","days","adminApi","mergeUsage","byKey","report","reports","summary","principal","usePrincipalUsage","useQueries","modelIds","results","result","enabled","useFieldUsage","FLAG_KEYS","flagsOf","flag","readsOf","usage","apiKey","ShapePanel","readerName","tokenName","principalKey","Table","TableHeader","TableRow","TableHead","TableBody","reads","TableCell","reader","Snippets","Tabs","TabsList","TabsTrigger","TabsContent","RestTab","send","siteKey","withSiteParameter","TAB_LABEL_KEYS","Explorer","switchTab","PageHeader","EXPLORER_TABS","setDraft","ApiExplorer","Page","QueryView","createChangeSetSchema","z.object","requiredText","z.string","EMPTY","useCreateChangeSetForm","createChangeSet","useCreateChangeSet","form","useForm","zodResolver","useResetOnOpen","open","reset","created","settle","title","description","onCreated","CreateSheet","FormSheet","onSubmit","FormTextField","FormTextareaField","FormError","CHANGES_MANAGE_PERMISSION","CHANGES_SHIP_PERMISSION","TOKENS_MANAGE_PERMISSION","CHANGE_SET_STATUS_DISPLAY","EDITABLE_STATUSES","useDevelopPermissions","permissions","ACTOR_TYPE_KEYS","isKnownType","type","useActorLabel","actor","Row","actorLabel","status","when","RowTitle","formatDateTime","formatRelativeTime","connectionName","OpenSets","sets","useChangeSets","connections","useDeploymentConnections","connection","data","GitPullRequest","Scheduled","schedules","useSchedules","CalendarClock","schedule","PUBLICATION_ACTION_LABELS","useAddToChangeSet","addEntry","useAddChangeSetEntry","input","addTo","toast","AddToPopover","titleId","inputId","setOpen","newTitle","setNewTitle","run","action","logError","cause","Popover","pending","PopoverTrigger","FolderPlus","PopoverContent","createAndAdd","SubmitButton","UNASSIGNED_STATUS","Unassigned","useUnassignedEntries","Inbox","Changes","useNavigate","creating","setCreating","canManageChanges","NoAccess","deploySchema","DeployPopover","error","setError","defaults","currentConnectionId","flow","connectionId","Rocket","FormSelectField","scheduleSchema","dateTimeLocalField","SchedulePopover","defaultScheduleValue","iso","dateTimeLocalToIso","at","Actions","discard","useDiscardChangeSet","unschedule","useUnscheduleChangeSet","enabledConnections","editable","shipDisabled","itemCount","InlineConfirm","Trash2","canShipChanges","Loader2","NOTICE_KEYS","isKnownNotice","notice","LINK_CLASSES","Banners","Alert","CheckCircle2","AlertDescription","AlertTriangle","AlertTitle","RefreshCw","showAcknowledgementHint","notices","Info","MAX_LENGTH","valueText","STRUCTURED_TYPES","ValueCell","structuredSummary","side","buttonVariants","ChevronRight","LIVE_STATE_DISPLAY","COLUMN_KEYS","EntryDiffCard","diff","onRemove","issue","VALIDATION_CATEGORIES","METADATA_CATEGORIES","classOfChange","change","CHANGE_CLASS_DISPLAY","ADDED","REMOVED","signOfChange","ClassificationChip","display","changeClass","useSchemaItemDefinitions","useSchemaDraft","changeSetId","active","definitionQueryOptions","shipped","definitionRevisionQueryOptions","SIGN_CLASSES","OPERATION_KEYS","SchemaDiffCard","useSchemaScopeAccess","changes","after","before","multiSite","shared","Globe2","other","sign","describeChange","ChangesTab","removeItem","useRemoveChangeSetItem","setId","review","SEVERITY_DISPLAY","HealthChip","severity","FINDINGS_PER_MODEL","useSetHealthFindings","modelKeys","entryIds","finding","IssueList","issues","PlannerPanel","plan","InfoHint","StepList","NOT_RESTORABLE_KEYS","ChecksTab","invalidEntries","findings","RULE_TITLE_KEYS","Field","Checkbox","checked","FieldLabel","usePrincipalLabel","ConsumersTab","principalLabel","Users","consumer","isStale","hasErrorCode","useShipFlow","ship","useShipChangeSet","useScheduleChangeSet","useUpdateChangeSet","acknowledgedBreaking","setAcknowledgedBreaking","acknowledgedDestructive","setAcknowledgedDestructive","refusedStale","setRefusedStale","refreshedFailure","setRefreshedFailure","failedStale","stale","reviewedAt","setReviewedAt","checks","needsBreaking","needsDestructive","acknowledged","blocked","canShip","acknowledgement","strict","write","expectedVersion","deploymentConnectionId","RenamePopover","setTitle","EVENT_DISPLAY","isKnownKind","kind","EventRow","last","TimelineTab","timeline","useChangeSetTimeline","events","History","View","useSearch","useChangeSetReview","meta","linkOptions","CHANGE_SET_TABS","ChangeSet","useParams","useChangeSet","playgroundUrl","theme","usePlaygroundUrl","useResolvedScheme","Graphql","src","available","LoadingState","useJobs","keepPreviousData","useJobSummary","useRetryJob","queryClient","useQueryClient","withCsrf","FAILED_JOBS_LIMIT","List","jobs","retryJob","retry","job","FailedJobs","isOpen","setIsOpen","dead","HealthCard","health","useContentHealthSummary","counts","rule","count","RULE_ORDER","total","sum","WebhooksRow","webhooks","useWebhooks","webhook","failing","OperationsCard","canManageWebhooks","useReaders","useDefinitions","FieldList","byModel","parts","modelKeyOf","read","ReadersTable","readers","ErrorState","SNAPSHOT_SOURCE_KEYS","SNAPSHOT_RUN_DISPLAY","SnapshotCard","snapshots","useSnapshots","latest","Live","anything","canReadUsage","canManagePublishing","REASON_KEYS","ChangeList","classifyChanges","diffDefinitions","Conflicts","conflicts","conflict","file","textOf","onKeepLocal","onTakeRemote","SCHEMA_DIR","categoryOf","definitionFilePath","CATEGORY_ORDER","buildFiles","exported","serializeDefinition","LOCK_PATH","LOCK_FILE_PATH","buildLockFile","buildLockText","serializeLockFile","FileLink","Icon","dirty","FileNav","files","components","isDirty","openPath","Lock","SCHEMA_EXPORT_PATH","schemaExportKey","schemaExportQueryOptions","queryOptions","useSchemaExport","parseJson","analyzeFile","json","parseDefinition","cross","validateSchema","others","found","issuesOf","analysis","decision","guardApply","remoteById","localItems","workspace","useApplyFiles","saveDraft","useSaveDraftToChangeSet","checking","setChecking","saveDrafts","onInvalid","onConflict","onApplied","reportError","replaceDefinition","loaded","useSchemaWorkspace","pinned","setPinned","texts","setTexts","lockText","setText","takeRemote","_dropped","keepLocal","reload","refetch","dirtyFiles","lazy","module","CodeEditor","props","Suspense","noIssues","LockFile","plain","schema","withTypedSettings","SETTINGS_SCHEMAS","settings","SCHEMAS","ModelDefinitionInputSchema","ComponentDefinitionInputSchema","editorSchemaFor","category","PREVIEW_DEBOUNCE_MS","useFileAnalysisAndLint","context","debouncedText","useDebouncedValue","previewSections","entryLayoutOf","effectiveFormLayout","section","layout","effectiveLayout","previewHostOf","component","pickNothing","FormPreview","runtime","useRuntimeEditors","environment","all","isComponentDefinition","store","createEntryFormStore","defaultFormValues","sections","FieldsProvider","EntryFields","fieldGridModeOf","GraphqlShape","sdl","graphqlSdl","lookup","Plan","CircleCheck","summarizeChanges","groupByBucket","BucketChip","RestShape","endpoints","restEndpoints","sample","restResponseSample","endpoint","declarationOf","start","source","commentStart","commentEnd","from","end","declarationsOf","toTypeName","Types","edited","schemaVersion","PREVIEW_TABS","Preview","setTab","invalid","FileWarning","Workbench","issuesId","leavesScreen","currentPath","nextPath","Schema","SchemaFiles","FileCode2","liveVersion","useSchemaVersion","setConflicts","appliedTo","setAppliedTo","applyFiles","import_react","openFile","showLock","moved","conflictText","resolve","definitionId","reloadButton","UnsavedChangesGuard","usePinnedBy","bySeq","principals","seq","PinPopover","selectId","tokenId","setTokenId","tokens","useApiTokens","snippet","RestoreButton","restore","useRestoreSnapshot","RotateCcw","none","TableRoot","showPins","pins","pinnedBy","snapshot","runDisplay","Snapshots","useCursorPager","cursor","Camera","TableCard","CursorPager","pagerProps","Header","changedCount","placeOf","effectiveTitleField","cover","useTimelinePlaces","codes","defaultLocale","markOf","kinds","buildCards","card","removed","revisionIds","revisionId","mark","tickStep","maxTicks","SHIFT_STEP","Slider","seqs","step","go","delta","position","coverUrlOf","thumbnail","variant","liveItemOf","place","places","useStateAt","useSnapshotChanges","snapshotPlaceQueryOptions","neighbour","neighbours","MARK_DISPLAY","MARK_CLASSES","Card","ImageOff","onOpen","PUBLISHING_REASONS","useOpenVersion","revisionAt","entryId","snapshotCreatedAt","revision","newest","list","describeError","PlaceSection","openVersion","opened","Stage","Clock","placeState","createdAt","DRAG_DEBOUNCE_MS","Timeline","ledger","useSnapshotLedger","placesError","setPosition","settled","onAtChange","previousOf","settledPrevious","settledChanges","settledRow","CHANGE_DISPLAY","page","schemaMoved","schemaVersions","FileStack","prev","SNAPSHOT_TABS","developLazyRoutes","createLazyRoute","useSnapshot"],"ignoreList":[0,1,2,3,4,5,6,7,8],"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/calendar-x.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/file-type.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/git-compare.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/git-merge.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/package.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/pin.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/puzzle.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/radio.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/workflow.mjs","../../../../packages/schema/src/sync/threeWay.ts","../../src/api/apiDocs.ts","../../src/components/CodeBlock/index.tsx","../../src/features/Develop/ApiExplorer/helpers/request.ts","../../src/features/Develop/ApiExplorer/helpers/graphqlQuery.ts","../../src/features/Develop/ApiExplorer/GraphqlTab/index.tsx","../../src/features/Develop/ApiExplorer/helpers/operations.ts","../../src/features/Develop/ApiExplorer/hooks/useRequestDrafts.ts","../../src/features/Develop/ApiExplorer/hooks/useSwitchTab.ts","../../src/hooks/useDeliverySiteKey.ts","../../src/features/Develop/ApiExplorer/EndpointNav/index.tsx","../../src/features/Develop/ApiExplorer/hooks/useSendRequest.ts","../../src/features/Develop/ApiExplorer/FilterRows/index.tsx","../../src/features/Develop/ApiExplorer/stores/token.ts","../../src/features/Develop/ApiExplorer/RequestBuilder/TextParam/index.tsx","../../src/features/Develop/ApiExplorer/RequestBuilder/index.tsx","../../src/features/Develop/ApiExplorer/helpers/entries.ts","../../src/features/Develop/ApiExplorer/ResponseView/EntryLinks/index.tsx","../../src/features/Develop/ApiExplorer/ResponseView/index.tsx","../../src/api/usage.ts","../../src/features/Develop/ApiExplorer/hooks/useFieldUsage.ts","../../src/features/Develop/ApiExplorer/ShapePanel/index.tsx","../../src/features/Develop/ApiExplorer/Snippets/index.tsx","../../src/features/Develop/ApiExplorer/RestTab/index.tsx","../../src/features/Develop/ApiExplorer/index.tsx","../../src/features/Develop/Changes/hooks/useCreateChangeSetForm.ts","../../src/features/Develop/Changes/CreateSheet/index.tsx","../../src/features/Develop/Changes/constants.ts","../../src/features/Develop/Changes/hooks/useDevelopPermissions.ts","../../src/features/Develop/Changes/hooks/useActorLabel.ts","../../src/features/Develop/Changes/OpenSets/Row/index.tsx","../../src/features/Develop/Changes/OpenSets/index.tsx","../../src/features/Develop/Changes/Scheduled/index.tsx","../../src/features/Develop/Changes/hooks/useAddToChangeSet.ts","../../src/features/Develop/Changes/AddToPopover/index.tsx","../../src/features/Develop/Changes/Unassigned/index.tsx","../../src/features/Develop/Changes/index.tsx","../../src/features/Develop/ChangeSet/DeployPopover/index.tsx","../../src/features/Develop/ChangeSet/SchedulePopover/index.tsx","../../src/features/Develop/ChangeSet/Actions/index.tsx","../../src/features/Develop/ChangeSet/Banners/index.tsx","../../src/features/Develop/ChangeSet/helpers/valueText.ts","../../src/features/Develop/ChangeSet/EntryDiffCard/ValueCell/index.tsx","../../src/features/Develop/ChangeSet/EntryDiffCard/index.tsx","../../src/features/Develop/ChangeSet/helpers/classification.ts","../../src/features/Develop/ChangeSet/ClassificationChip/index.tsx","../../src/features/Develop/ChangeSet/hooks/useSchemaItemDefinitions.ts","../../src/features/Develop/ChangeSet/SchemaDiffCard/index.tsx","../../src/features/Develop/ChangeSet/ChangesTab/index.tsx","../../src/features/Develop/Changes/HealthChip/index.tsx","../../src/features/Develop/ChangeSet/hooks/useSetHealthFindings.ts","../../src/features/Develop/ChangeSet/IssueList/index.tsx","../../src/features/Develop/ChangeSet/ChecksTab/PlannerPanel/index.tsx","../../src/features/Develop/ChangeSet/ChecksTab/index.tsx","../../src/features/Develop/Changes/hooks/usePrincipalLabel.ts","../../src/features/Develop/ChangeSet/ConsumersTab/index.tsx","../../src/features/Develop/ChangeSet/hooks/useShipFlow.ts","../../src/features/Develop/ChangeSet/RenamePopover/index.tsx","../../src/features/Develop/ChangeSet/TimelineTab/EventRow/index.tsx","../../src/features/Develop/ChangeSet/TimelineTab/index.tsx","../../src/features/Develop/ChangeSet/View/index.tsx","../../src/features/Develop/ChangeSet/index.tsx","../../src/features/Develop/Graphql/helpers/playgroundUrl.ts","../../src/features/Develop/Graphql/hooks/usePlaygroundUrl.ts","../../src/features/Develop/Graphql/index.tsx","../../src/api/jobs.ts","../../src/features/Develop/Live/FailedJobs/List/index.tsx","../../src/features/Develop/Live/FailedJobs/index.tsx","../../src/features/Develop/Live/HealthCard/index.tsx","../../src/features/Develop/Live/OperationsCard/WebhooksRow/index.tsx","../../src/features/Develop/Live/OperationsCard/index.tsx","../../src/features/Develop/Live/hooks/useReaders.ts","../../src/features/Develop/Live/ReadersTable/FieldList/index.tsx","../../src/features/Develop/Live/ReadersTable/index.tsx","../../src/features/Develop/Snapshots/helpers/display.ts","../../src/features/Develop/Live/SnapshotCard/index.tsx","../../src/features/Develop/Live/index.tsx","../../src/features/Develop/Schema/Conflicts/index.tsx","../../src/features/Develop/Schema/helpers/files.ts","../../src/features/Develop/Schema/FileNav/index.tsx","../../src/api/schemaFiles.ts","../../src/features/Develop/Schema/helpers/analyze.ts","../../src/features/Develop/Schema/helpers/guard.ts","../../src/features/Develop/Schema/hooks/useApplyFiles.ts","../../src/features/Develop/Schema/hooks/useSchemaWorkspace.ts","../../src/features/Develop/Schema/CodeEditor/index.tsx","../../src/features/Develop/Schema/LockFile/index.tsx","../../src/features/Develop/Schema/CodeEditor/helpers/editorSchema.ts","../../src/features/Develop/Schema/hooks/useFileAnalysisAndLint.ts","../../src/features/Develop/Schema/IssueList/index.tsx","../../src/features/Develop/Schema/helpers/previewSections.ts","../../src/features/Develop/Schema/Preview/FormPreview/index.tsx","../../src/features/Develop/Schema/Preview/GraphqlShape/index.tsx","../../src/features/Develop/Schema/Preview/Plan/index.tsx","../../src/features/Develop/Schema/Preview/RestShape/index.tsx","../../src/features/Develop/Schema/helpers/declarations.ts","../../src/features/Develop/Schema/Preview/Types/index.tsx","../../src/features/Develop/Schema/Preview/index.tsx","../../src/features/Develop/Schema/Workbench/index.tsx","../../src/features/Develop/Schema/index.tsx","../../src/features/Develop/Snapshots/hooks/usePinnedBy.ts","../../src/features/Develop/Snapshots/PinPopover/index.tsx","../../src/features/Develop/Snapshots/RestoreButton/index.tsx","../../src/features/Develop/Snapshots/Table/index.tsx","../../src/features/Develop/Snapshots/index.tsx","../../src/features/Develop/Snapshots/Timeline/Header/index.tsx","../../src/features/Develop/Snapshots/Timeline/hooks/useTimelinePlaces.ts","../../src/features/Develop/Snapshots/Timeline/helpers/cards.ts","../../src/features/Develop/Snapshots/Timeline/Slider/index.tsx","../../src/features/Develop/Snapshots/Timeline/hooks/useStateAt.ts","../../src/features/Develop/Snapshots/Timeline/Card/index.tsx","../../src/features/Develop/Snapshots/Timeline/hooks/useOpenVersion.ts","../../src/features/Develop/Snapshots/Timeline/PlaceSection/index.tsx","../../src/features/Develop/Snapshots/Timeline/Stage/index.tsx","../../src/features/Develop/Snapshots/Timeline/index.tsx","../../src/features/Develop/Snapshots/Detail/ChangeList/index.tsx","../../src/features/Develop/Snapshots/Detail/View/index.tsx","../../src/app/lazyRoutes/develop.tsx","../../src/features/Develop/Snapshots/Detail/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: \"calendar-x\",\n size: 24,\n node: [\n [\"path\", { d: \"M8 2v3\", key: \"1ioesn\" }],\n [\"path\", { d: \"M16 2v3\", key: \"otl347\" }],\n [\"rect\", { x: \"3\", y: \"3\", width: \"18\", height: \"18\", rx: \"2\", key: \"h1oib\" }],\n [\"path\", { d: \"M3 9h18\", key: \"1pudct\" }],\n [\"path\", { d: \"m14 13-4 4\", key: \"1gib57\" }],\n [\"path\", { d: \"m10 13 4 4\", key: \"153uiq\" }]\n ]\n};\n__iconData.node;\nconst CalendarX = createLucideIcon(__iconData);\n\nexport { __iconData, CalendarX as default };\n//# sourceMappingURL=calendar-x.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: \"file-type\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M14 2v5a1 1 0 0 0 1 1h5\", key: \"wfsgrz\" }],\n [\"path\", { d: \"M11 18h2\", key: \"12mj7e\" }],\n [\"path\", { d: \"M12 12v6\", key: \"3ahymv\" }],\n [\"path\", { d: \"M9 13v-.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 .5.5v.5\", key: \"qbrxap\" }]\n ]\n};\n__iconData.node;\nconst FileType = createLucideIcon(__iconData);\n\nexport { __iconData, FileType as default };\n//# sourceMappingURL=file-type.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: \"git-compare\",\n size: 24,\n node: [\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }],\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M13 6h3a2 2 0 0 1 2 2v7\", key: \"1yeb86\" }],\n [\"path\", { d: \"M11 18H8a2 2 0 0 1-2-2V9\", key: \"19pyzm\" }]\n ]\n};\n__iconData.node;\nconst GitCompare = createLucideIcon(__iconData);\n\nexport { __iconData, GitCompare as default };\n//# sourceMappingURL=git-compare.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: \"git-merge\",\n size: 24,\n node: [\n [\"circle\", { cx: \"18\", cy: \"18\", r: \"3\", key: \"1xkwt0\" }],\n [\"circle\", { cx: \"6\", cy: \"6\", r: \"3\", key: \"1lh9wr\" }],\n [\"path\", { d: \"M6 21V9a9 9 0 0 0 9 9\", key: \"7kw0sc\" }]\n ]\n};\n__iconData.node;\nconst GitMerge = createLucideIcon(__iconData);\n\nexport { __iconData, GitMerge as default };\n//# sourceMappingURL=git-merge.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: \"package\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z\",\n key: \"1a0edw\"\n }\n ],\n [\"path\", { d: \"M12 22V12\", key: \"d0xqtd\" }],\n [\"polyline\", { points: \"3.29 7 12 12 20.71 7\", key: \"ousv84\" }],\n [\"path\", { d: \"m7.5 4.27 9 5.15\", key: \"1c824w\" }]\n ]\n};\n__iconData.node;\nconst Package = createLucideIcon(__iconData);\n\nexport { __iconData, Package as default };\n//# sourceMappingURL=package.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: \"pin\",\n size: 24,\n node: [\n [\"path\", { d: \"M12 17v5\", key: \"bb1du9\" }],\n [\n \"path\",\n {\n d: \"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z\",\n key: \"1nkz8b\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Pin = createLucideIcon(__iconData);\n\nexport { __iconData, Pin as default };\n//# sourceMappingURL=pin.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: \"puzzle\",\n size: 24,\n node: [\n [\n \"path\",\n {\n d: \"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z\",\n key: \"w46dr5\"\n }\n ]\n ]\n};\n__iconData.node;\nconst Puzzle = createLucideIcon(__iconData);\n\nexport { __iconData, Puzzle as default };\n//# sourceMappingURL=puzzle.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: \"radio\",\n size: 24,\n node: [\n [\"path\", { d: \"M16.247 7.761a6 6 0 0 1 0 8.478\", key: \"1fwjs5\" }],\n [\"path\", { d: \"M19.075 4.933a10 10 0 0 1 0 14.134\", key: \"ehdyv1\" }],\n [\"path\", { d: \"M4.925 19.067a10 10 0 0 1 0-14.134\", key: \"1q22gi\" }],\n [\"path\", { d: \"M7.753 16.239a6 6 0 0 1 0-8.478\", key: \"r2q7qm\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n ]\n};\n__iconData.node;\nconst Radio = createLucideIcon(__iconData);\n\nexport { __iconData, Radio as default };\n//# sourceMappingURL=radio.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: \"workflow\",\n size: 24,\n node: [\n [\"rect\", { width: \"8\", height: \"8\", x: \"3\", y: \"3\", rx: \"2\", key: \"by2w9f\" }],\n [\"path\", { d: \"M7 11v4a2 2 0 0 0 2 2h4\", key: \"xkn7yn\" }],\n [\"rect\", { width: \"8\", height: \"8\", x: \"13\", y: \"13\", rx: \"2\", key: \"1cgmvn\" }]\n ]\n};\n__iconData.node;\nconst Workflow = createLucideIcon(__iconData);\n\nexport { __iconData, Workflow as default };\n//# sourceMappingURL=workflow.mjs.map\n","import type { SchemaDefinition } from '../types/definitions.js';\n\n/**\n * Per-definition three-way decision for `shapio schema apply` (ADR 0002). The base is what the lock file\n * recorded at pull time; local is the file in the repository; remote is the target instance now.\n *\n * - unchanged locally → skip, even if the target changed it since (no silent revert of production edits);\n * - changed locally and unchanged on the target → apply, guarded by the target's current version;\n * - changed on both → refuse and show the diff, like a rejected non-fast-forward push.\n *\n * Deletions need `prune`. Identical content on both sides is never a conflict.\n */\nexport type SyncSide = { version: number; hash: string };\nexport type SyncLocal = { definition: SchemaDefinition; hash: string };\nexport type SyncRemote = SyncSide & { definition: SchemaDefinition };\n\nexport type SyncInput = {\n local?: SyncLocal;\n base?: SyncSide;\n remote?: SyncRemote;\n prune: boolean;\n};\n\nexport type SyncSkipReason =\n 'unchangedLocally' | 'alreadyApplied' | 'remoteOnly' | 'deletedLocallyWithoutPrune' | 'alreadyDeleted';\n\nexport type SyncConflictReason =\n 'changedOnBoth' | 'deletedOnTarget' | 'existsOnTarget' | 'changedOnTargetBeforeDelete';\n\nexport type SyncDecision =\n | { action: 'skip'; reason: SyncSkipReason }\n | { action: 'create' }\n | { action: 'update'; expectedVersion: number }\n | { action: 'delete'; expectedVersion: number }\n | { action: 'conflict'; reason: SyncConflictReason };\n\nconst unchangedSinceBase = (remote: SyncSide, base: SyncSide) =>\n remote.version === base.version || remote.hash === base.hash;\n\nconst decideForLocal = (\n local: SyncLocal,\n base: SyncSide | undefined,\n remote: SyncRemote | undefined,\n): SyncDecision => {\n if (base && local.hash === base.hash) {\n return { action: 'skip', reason: 'unchangedLocally' };\n }\n if (!remote) {\n return base ? { action: 'conflict', reason: 'deletedOnTarget' } : { action: 'create' };\n }\n if (remote.hash === local.hash) {\n return { action: 'skip', reason: 'alreadyApplied' };\n }\n if (!base) {\n return { action: 'conflict', reason: 'existsOnTarget' };\n }\n return unchangedSinceBase(remote, base)\n ? { action: 'update', expectedVersion: remote.version }\n : { action: 'conflict', reason: 'changedOnBoth' };\n};\n\nexport const decideSync = ({ local, base, remote, prune }: SyncInput): SyncDecision => {\n if (local) {\n return decideForLocal(local, base, remote);\n }\n if (!base) {\n return { action: 'skip', reason: 'remoteOnly' };\n }\n if (!remote) {\n return { action: 'skip', reason: 'alreadyDeleted' };\n }\n if (!prune) {\n return { action: 'skip', reason: 'deletedLocallyWithoutPrune' };\n }\n return unchangedSinceBase(remote, base)\n ? { action: 'delete', expectedVersion: remote.version }\n : { action: 'conflict', reason: 'changedOnTargetBeforeDelete' };\n};\n","import { useQuery } from '@tanstack/react-query';\nimport { apiBaseUrl, apiClient } from './client';\nimport { queryKeys } from './queryKeys';\n\nconst silent = { silent: true } as const;\n\n/** The generated contracts (`/api/docs`), rebuilt by the server whenever the schema version moves. */\nconst DOCS_PATHS = {\n openApi: '/api/docs/openapi.json',\n typescript: '/api/docs/typescript',\n playground: 'api/graphql/playground',\n} as const;\n\n/** The parts of the OpenAPI document the explorer reads (generated by `schema/codegen/openapi.ts`). */\nexport type OpenApiParameter = {\n name: string;\n in: 'path' | 'query' | 'header' | 'cookie';\n required?: boolean;\n description?: string;\n schema?: Record<string, unknown>;\n};\n\nexport type OpenApiOperation = {\n operationId?: string;\n summary?: string;\n tags?: string[];\n parameters?: OpenApiParameter[];\n};\n\nexport type OpenApiDocument = {\n info: { title: string; version: string };\n tags?: Array<{ name: string; description?: string }>;\n paths: Record<string, Partial<Record<'get' | 'post' | 'put' | 'patch' | 'delete', OpenApiOperation>>>;\n};\n\n/** Under `schema.all`: the documents are derived from the schema snapshot. */\nconst docsKeys = {\n openApi: [...queryKeys.schema.all, 'docs', 'openapi'] as const,\n typescript: [...queryKeys.schema.all, 'docs', 'typescript'] as const,\n playground: ['develop', 'graphqlPlayground'] as const,\n};\n\nexport const useOpenApiDocument = () =>\n useQuery({\n queryKey: docsKeys.openApi,\n queryFn: () => apiClient.request<OpenApiDocument>(DOCS_PATHS.openApi),\n meta: silent,\n });\n\nexport type TypeScriptDeclarations = { schemaVersion: number; source: string };\n\n/** `shapio types generate`'s output for the active schema. */\nexport const useTypeScriptDeclarations = () =>\n useQuery({\n queryKey: docsKeys.typescript,\n queryFn: () => apiClient.request<TypeScriptDeclarations>(DOCS_PATHS.typescript),\n meta: silent,\n });\n\n/** The vendored GraphiQL page's URL (same origin, so the admin session and CSRF bootstrap apply). */\nexport const graphqlPlaygroundUrl = () => new URL(DOCS_PATHS.playground, apiBaseUrl()).href;\n\n/** Whether GraphiQL is served (`GRAPHQL_PLAYGROUND_ENABLED`, `GRAPHQL_ENABLED`): 404 when turned off. */\nexport const useGraphqlPlaygroundAvailable = () =>\n useQuery({\n queryKey: docsKeys.playground,\n queryFn: async () => {\n const response = await fetch(graphqlPlaygroundUrl(), { method: 'HEAD', credentials: 'same-origin' });\n return response.ok;\n },\n staleTime: Infinity,\n meta: silent,\n });\n","import { CopyButton } from '@/components/CopyButton';\nimport { cn } from '@/helpers/cn';\n\ntype CodeBlockProps = {\n code: string;\n /** Names the block (a visible caption and the scrollable region's accessible name). */\n label: string;\n /** Show a copy button beside the caption. */\n copyable?: boolean;\n className?: string;\n};\n\n/**\n * Read-only code (JSON, SDL, TypeScript, curl) in a scrollable, keyboard-focusable block with a caption\n * and an optional copy button.\n */\nexport const CodeBlock = ({ code, label, copyable = true, className }: CodeBlockProps) => (\n <div className={cn('min-w-0 space-y-2', className)}>\n <div className=\"flex min-h-9 items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold tracking-wide text-muted-foreground uppercase\">{label}</span>\n {copyable ? <CopyButton value={code} /> : null}\n </div>\n <pre\n role=\"region\"\n aria-label={label}\n tabIndex={0}\n className=\"max-h-[28rem] overflow-auto rounded-lg border bg-muted p-3 font-mono text-xs leading-5 text-foreground outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n >\n <code>{code}</code>\n </pre>\n </div>\n);\n","import type { DeliveryOperation } from './operations';\n\n/**\n * The request the builder describes, and the URL and code snippets it becomes. The token is never part\n * of the URL; snippets reference it as `$SHAPIO_TOKEN` so copying one never copies the secret.\n */\nexport type FilterRow = { id: string; key: string; value: string };\n\nexport type RequestDraft = {\n id: string;\n locale: string;\n snapshot: string;\n fields: string;\n populate: string;\n sort: string;\n page: string;\n pageSize: string;\n q: string;\n /** `filters[field][$op]=value` rows; `key` is the part inside `filters[…]`, e.g. `title][$contains`. */\n filters: FilterRow[];\n};\n\nexport const EMPTY_DRAFT: RequestDraft = {\n id: '',\n locale: '',\n snapshot: '',\n fields: '',\n populate: '',\n sort: '',\n page: '',\n pageSize: '',\n q: '',\n filters: [],\n};\n\nconst SCALAR_PARAMS = ['locale', 'snapshot', 'fields', 'populate', 'sort', 'page', 'pageSize', 'q'] as const;\n\n/** `title][$contains` or `title.$contains` → `filters[title][$contains]`. */\nexport const filterParamName = (key: string): string => {\n const parts = key\n .replace(/^filters/, '')\n .split(/[[\\].]+/)\n .filter((part) => part !== '');\n return `filters${parts.map((part) => `[${part}]`).join('')}`;\n};\n\n/** The path and query (relative to the API base) for a draft; `{id}` stays visible when not filled. */\nexport const requestPath = (operation: DeliveryOperation, draft: RequestDraft): string => {\n const path = operation.path.replace('{id}', draft.id.trim() ? encodeURIComponent(draft.id.trim()) : '{id}');\n const query = new URLSearchParams();\n for (const name of SCALAR_PARAMS) {\n const value = draft[name].trim();\n if (value && operation.parameters.some((parameter) => parameter.name === name)) {\n query.append(name, value);\n }\n }\n if (operation.list) {\n for (const row of draft.filters) {\n if (row.key.trim() && row.value !== '') {\n query.append(filterParamName(row.key.trim()), row.value);\n }\n }\n }\n const search = query.toString();\n return search ? `${path}?${search}` : path;\n};\n\nexport const isSendable = (operation: DeliveryOperation, draft: RequestDraft) =>\n !operation.byId || draft.id.trim() !== '';\n\nconst TOKEN_PLACEHOLDER = '$SHAPIO_TOKEN';\n\nexport const curlSnippet = (url: string, withToken: boolean): string =>\n [`curl '${url.replace(/'/g, \"'\\\\''\")}'`, ` -H 'accept: application/json'`]\n .concat(withToken ? [` -H \"authorization: Bearer ${TOKEN_PLACEHOLDER}\"`] : [])\n .join(' \\\\\\n');\n\nexport const fetchSnippet = (url: string, withToken: boolean): string => {\n const headers = withToken\n ? `{\\n accept: 'application/json',\\n authorization: \\`Bearer \\${process.env.SHAPIO_TOKEN}\\`,\\n }`\n : `{ accept: 'application/json' }`;\n return `const response = await fetch(${JSON.stringify(url)}, {\\n headers: ${headers},\\n});\\nconst { data, meta } = await response.json();\\n`;\n};\n","import { collectionQueryName, routeKeyOf, type FieldDefinition, type ModelDefinition } from '@shapio/schema';\nimport type { DeliveryOperation } from './operations';\nimport { filterParamName, type RequestDraft } from './request';\n\n/**\n * The GraphQL tab's operations per model and the query each one sends, built from the REST tab's request\n * for the same endpoint (same filters, sort, search, page, locale, snapshot and fields), so the two read\n * the same rows. Field selections follow the server's types: scalars as they are, rich text as `html`,\n * media as `url alt`, relations as `id`, components and zones as `__typename`.\n */\nexport type GraphqlOperation = { id: string; name: string; modelId: string; list: boolean };\n\n/** The query, and the REST parameters it could not carry over (`populate`, `$or` filters, nested paths). */\nexport type GraphqlQuery = { query: string; skipped: string[] };\n\n/** The GraphQL tab's operation IDs are prefixed so they never collide with REST operation IDs. */\nexport const GRAPHQL_OPERATION_PREFIX = 'graphql:';\n\nexport const graphqlOperations = (model: ModelDefinition): GraphqlOperation[] => {\n const single = {\n id: `${GRAPHQL_OPERATION_PREFIX}${model.apiKey}`,\n name: model.apiKey,\n modelId: model.id,\n list: false,\n };\n if (model.kind !== 'collection') {\n return [single];\n }\n const listName = collectionQueryName(model);\n return [\n { id: `${GRAPHQL_OPERATION_PREFIX}${listName}`, name: listName, modelId: model.id, list: true },\n single,\n ];\n};\n\n/** The REST endpoint a GraphQL operation mirrors: the list, the read by ID, or the singleton's read. */\nexport const restOperationFor = (\n model: ModelDefinition,\n operation: GraphqlOperation,\n restOperations: readonly DeliveryOperation[],\n): DeliveryOperation | undefined =>\n restOperations.find(\n (candidate) =>\n candidate.routeKey === routeKeyOf(model) &&\n (operation.list ? candidate.list : model.kind === 'collection' ? candidate.byId : !candidate.byId),\n );\n\n/**\n * The operation to show after switching tabs, so the endpoint stays the same: the REST endpoint's GraphQL\n * operation, or the GraphQL operation's REST endpoint (undefined: the tab's first).\n */\nexport const counterpartOperationId = (\n target: 'rest' | 'graphql',\n operationId: string | undefined,\n models: readonly ModelDefinition[],\n restOperations: readonly DeliveryOperation[],\n): string | undefined => {\n if (target === 'graphql') {\n const rest = restOperations.find((candidate) => candidate.id === operationId);\n const model = rest && models.find((candidate) => routeKeyOf(candidate) === rest.routeKey);\n return model && graphqlOperations(model).find((candidate) => candidate.list === rest.list)?.id;\n }\n for (const model of models) {\n const operation = graphqlOperations(model).find((candidate) => candidate.id === operationId);\n if (operation) {\n return restOperationFor(model, operation, restOperations)?.id;\n }\n }\n return undefined;\n};\n\nconst selectionOf = (field: FieldDefinition): string => {\n switch (field.type) {\n case 'richtext':\n return `${field.apiKey} { html }`;\n case 'media':\n return `${field.apiKey} { url alt }`;\n case 'relation':\n return `${field.apiKey} { id }`;\n case 'component':\n case 'dynamiczone':\n return `${field.apiKey} { __typename }`;\n default:\n return field.apiKey;\n }\n};\n\nconst splitList = (value: string) =>\n value\n .split(',')\n .map((item) => item.trim())\n .filter((item) => item !== '');\n\nconst NUMBER = /^-?\\d+(\\.\\d+)?$/;\nconst INTEGER = /^\\d+$/;\nconst SYSTEM_ATTRIBUTES = new Set(['id', 'createdAt', 'updatedAt']);\nconst OPERATORS = new Set([\n '$eq',\n '$ne',\n '$in',\n '$nin',\n '$lt',\n '$lte',\n '$gt',\n '$gte',\n '$contains',\n '$notContains',\n '$containsi',\n '$startsWith',\n '$endsWith',\n '$null',\n '$notNull',\n]);\nconst LIST_OPERATORS = new Set(['$in', '$nin']);\nconst BOOLEAN_OPERATORS = new Set(['$null', '$notNull']);\n\nconst isBooleanText = (raw: string) => raw === 'true' || raw === 'false';\n\n/** A GraphQL literal for a REST value: numbers and booleans where the field's type takes them. */\nconst literal = (field: FieldDefinition | undefined, raw: string): string => {\n if ((field?.type === 'number' || field?.type === 'integer') && NUMBER.test(raw)) {\n return raw;\n }\n if (field?.type === 'boolean' && isBooleanText(raw)) {\n return raw;\n }\n return JSON.stringify(raw);\n};\n\ntype FilterKey = { name: string; operator: string };\n\n/**\n * `title][$contains` (any spelling `filterParamName` accepts) → `title`, `$contains`; a bare field is `$eq`,\n * a list operator may carry an index (`tags][$in][0`). Logical (`$or`) and nested (`author.name`) keys are\n * not translated.\n */\nexport const parseFilterKey = (key: string): FilterKey | undefined => {\n const parts = [...filterParamName(key).matchAll(/\\[([^\\]]*)\\]/g)].map((match) => match[1] ?? '');\n const [name, operator = '$eq', index, ...rest] = parts;\n if (!name || name.startsWith('$') || !OPERATORS.has(operator) || rest.length > 0) {\n return undefined;\n }\n if (index !== undefined && !(LIST_OPERATORS.has(operator) && INTEGER.test(index))) {\n return undefined;\n }\n return { name, operator };\n};\n\ntype Condition = { field: FieldDefinition | undefined; values: string[] };\n\nconst operandOf = (operator: string, { field, values }: Condition): string => {\n if (BOOLEAN_OPERATORS.has(operator)) {\n const value = values.at(-1) ?? '';\n return isBooleanText(value) ? value : JSON.stringify(value);\n }\n if (LIST_OPERATORS.has(operator)) {\n return `[${values.map((value) => literal(field, value)).join(', ')}]`;\n }\n return literal(field, values.at(-1) ?? '');\n};\n\n/** The `filter` argument for the draft's rows, and the rows it could not translate. */\nconst filterArgument = (\n model: ModelDefinition,\n draft: RequestDraft,\n): { argument: string | undefined; skipped: string[] } => {\n const fields = new Map(\n model.fields.filter((field) => !field.deprecated).map((field) => [field.apiKey, field]),\n );\n const conditions = new Map<string, Map<string, Condition>>();\n const skipped: string[] = [];\n for (const row of draft.filters) {\n const key = row.key.trim();\n if (!key || row.value === '') {\n continue;\n }\n const parsed = parseFilterKey(key);\n const field = parsed ? fields.get(parsed.name) : undefined;\n if (!parsed || (!field && !SYSTEM_ATTRIBUTES.has(parsed.name))) {\n skipped.push(filterParamName(key));\n continue;\n }\n const byOperator = conditions.get(parsed.name) ?? new Map<string, Condition>();\n conditions.set(parsed.name, byOperator);\n const values = LIST_OPERATORS.has(parsed.operator) ? splitList(row.value) : [row.value];\n const existing = byOperator.get(parsed.operator);\n byOperator.set(parsed.operator, {\n field,\n values: existing && LIST_OPERATORS.has(parsed.operator) ? [...existing.values, ...values] : values,\n });\n }\n if (conditions.size === 0) {\n return { argument: undefined, skipped };\n }\n const entries = [...conditions].map(([name, byOperator]) => {\n const operands = [...byOperator].map(\n ([operator, condition]) => `${operator.slice(1)}: ${operandOf(operator, condition)}`,\n );\n return `${name}: { ${operands.join(', ')} }`;\n });\n return { argument: `{ ${entries.join(', ')} }`, skipped };\n};\n\n/** `title:asc,createdAt:desc` → `[{ title: ASC }, { createdAt: DESC }]`. */\nconst sortArgument = (model: ModelDefinition, sort: string): string | undefined => {\n const known = (name: string) =>\n SYSTEM_ATTRIBUTES.has(name) || model.fields.some((field) => !field.deprecated && field.apiKey === name);\n const items = splitList(sort).map((item) => {\n const [name = '', direction = 'asc', extra] = item.split(':');\n return extra === undefined && known(name) && (direction === 'asc' || direction === 'desc')\n ? `{ ${name}: ${direction.toUpperCase()} }`\n : undefined;\n });\n return items.length > 0 && items.every((item) => item !== undefined) ? `[${items.join(', ')}]` : undefined;\n};\n\n/** The fields the draft's `fields` names (all live fields when empty or naming none of them). */\nconst selectedFields = (model: ModelDefinition, draft: RequestDraft): FieldDefinition[] => {\n const live = model.fields.filter((field) => !field.deprecated);\n const names = new Set(splitList(draft.fields));\n const chosen = live.filter((field) => names.has(field.apiKey));\n return chosen.length > 0 ? chosen : live;\n};\n\nconst selection = (fields: readonly FieldDefinition[], indent: string) =>\n ['id', ...fields.map(selectionOf)].map((line) => `${indent}${line}`).join('\\n');\n\nconst readArguments = (draft: RequestDraft): Array<[string, string]> => {\n const args: Array<[string, string]> = [];\n if (draft.locale.trim()) {\n args.push(['locale', JSON.stringify(draft.locale.trim())]);\n }\n if (INTEGER.test(draft.snapshot.trim())) {\n args.push(['snapshot', draft.snapshot.trim()]);\n }\n return args;\n};\n\nconst listArguments = (model: ModelDefinition, draft: RequestDraft, skipped: string[]) => {\n const args: Array<[string, string]> = [];\n const filter = filterArgument(model, draft);\n skipped.push(...filter.skipped);\n if (filter.argument) {\n args.push(['filter', filter.argument]);\n }\n if (draft.sort.trim()) {\n const sort = sortArgument(model, draft.sort);\n if (sort) {\n args.push(['sort', sort]);\n } else {\n skipped.push('sort');\n }\n }\n if (draft.q.trim()) {\n args.push(['search', JSON.stringify(draft.q.trim())]);\n }\n for (const name of ['page', 'pageSize'] as const) {\n if (INTEGER.test(draft[name].trim())) {\n args.push([name, draft[name].trim()]);\n }\n }\n return args;\n};\n\nconst call = (name: string, args: ReadonlyArray<[string, string]>) =>\n args.length === 0 ? name : `${name}(${args.map(([key, value]) => `${key}: ${value}`).join(', ')})`;\n\n/** The query for one operation, carrying over what the REST draft for the same endpoint sets. */\nexport const graphqlQuery = (\n model: ModelDefinition,\n operation: GraphqlOperation,\n draft: RequestDraft,\n): GraphqlQuery => {\n const skipped: string[] = [];\n if (draft.populate.trim()) {\n // GraphQL expands relations by selecting them; there is no populate argument.\n skipped.push('populate');\n }\n const fields = selectedFields(model, draft);\n if (operation.list) {\n const args = [...listArguments(model, draft, skipped), ...readArguments(draft)];\n const body = ` ${call(operation.name, args)} {\\n totalCount\\n nodes {\\n${selection(fields, ' ')}\\n }\\n }`;\n return { query: `query {\\n${body}\\n}\\n`, skipped };\n }\n const id = draft.id.trim();\n const byId = model.kind === 'collection';\n const args: Array<[string, string]> = [\n ...(byId ? [['id', id ? JSON.stringify(id) : '$id'] as [string, string]] : []),\n ...readArguments(draft),\n ];\n const header = byId && !id ? 'query ($id: ID!) {' : 'query {';\n const body = ` ${call(operation.name, args)} {\\n${selection(fields, ' ')}\\n }`;\n return { query: `${header}\\n${body}\\n}\\n`, skipped };\n};\n","import { isModelDefinition, type ModelDefinition } from '@shapio/schema';\nimport { Link } from '@tanstack/react-router';\nimport { Braces } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useAllDefinitions } from '@/api/schema';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { Panel } from '@/components/Panel';\nimport { SubNav, SubNavGroup } from '@/components/SubNav';\nimport { SubNavLink } from '@/components/SubNavLink';\nimport { Button } from '@/components/ui/button';\nimport { graphqlOperations, graphqlQuery, restOperationFor } from '../helpers/graphqlQuery';\nimport type { DeliveryOperation } from '../helpers/operations';\nimport type { RequestDraft } from '../helpers/request';\n\ntype GraphqlTabProps = {\n selected: string | undefined;\n /** The REST endpoints, to find the one each GraphQL operation mirrors. */\n restOperations: readonly DeliveryOperation[];\n /** The REST tab's request for an endpoint (empty when it was never edited). */\n draftOf: (operationId: string | undefined) => RequestDraft;\n};\n\n/**\n * GraphQL: the root query fields per place, and the selected one as a query that reads what the REST tab's\n * request for the same endpoint reads, to copy or open in the GraphQL page (the vendored GraphiQL).\n */\nexport const GraphqlTab = ({ selected, restOperations, draftOf }: GraphqlTabProps) => {\n const { t } = useTranslation();\n const { definitions } = useAllDefinitions();\n const groups = useMemo(\n () =>\n (definitions ?? [])\n .map(({ definition }) => definition)\n .filter(isModelDefinition)\n .sort((a, b) => a.label.localeCompare(b.label))\n .map((model: ModelDefinition) => ({ model, operations: graphqlOperations(model) })),\n [definitions],\n );\n const pairs = useMemo(\n () => groups.flatMap(({ model, operations }) => operations.map((operation) => ({ model, operation }))),\n [groups],\n );\n const current = pairs.find((pair) => pair.operation.id === selected) ?? pairs[0];\n const built = useMemo(() => {\n if (!current) {\n return undefined;\n }\n const rest = restOperationFor(current.model, current.operation, restOperations);\n return graphqlQuery(current.model, current.operation, draftOf(rest?.id));\n }, [current, restOperations, draftOf]);\n return (\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n {groups.length > 0 ? (\n <SubNav label={t('develop.api.graphql.operations')}>\n {groups.map(({ model, operations }) => (\n <SubNavGroup key={model.id} label={model.label}>\n {operations.map((candidate) => (\n <SubNavLink\n key={candidate.id}\n to=\"/api-explorer\"\n search={{ tab: 'graphql', op: candidate.id }}\n aria-current={candidate.id === current?.operation.id ? 'page' : undefined}\n >\n <span className=\"min-w-0 truncate font-mono text-xs\">{candidate.name}</span>\n </SubNavLink>\n ))}\n </SubNavGroup>\n ))}\n </SubNav>\n ) : null}\n <div className=\"min-w-0 flex-1\">\n {current && built ? (\n <Panel\n title={t('develop.api.graphql.example', { name: current.operation.name })}\n description={\n built.skipped.length > 0\n ? t('develop.api.graphql.skipped', { params: built.skipped.join(', ') })\n : t('develop.api.graphql.fromRest')\n }\n actions={\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link to=\"/develop/graphql\" search={{ query: built.query }}>\n <Braces aria-hidden=\"true\" />\n {t('develop.api.graphql.openInPlayground')}\n </Link>\n </Button>\n }\n >\n <CodeBlock label={t('develop.api.graphql.query')} code={built.query} />\n </Panel>\n ) : null}\n </div>\n </div>\n );\n};\n","import type { OpenApiDocument, OpenApiParameter } from '@/api/apiDocs';\n\n/**\n * Delivery endpoints from the live OpenAPI document (`/api/docs/openapi.json`, generated from the\n * registry): every `GET /api/content/…` operation, grouped by the model (OpenAPI tag) it belongs to.\n */\nexport const DELIVERY_PREFIX = '/api/content/';\n\nexport type DeliveryOperation = {\n id: string;\n path: string;\n summary: string;\n tag: string;\n /** The model's route key (`articles`): the first path segment after `/api/content/`. */\n routeKey: string;\n /** Reads one entry by ID (`/{id}` in the path). */\n byId: boolean;\n /** Has list parameters (filters, sort, pages). */\n list: boolean;\n parameters: OpenApiParameter[];\n};\n\nexport type OperationGroup = { tag: string; operations: DeliveryOperation[] };\n\nexport const deliveryOperations = (document: OpenApiDocument): DeliveryOperation[] =>\n Object.entries(document.paths).flatMap(([path, methods]) => {\n const operation = methods.get;\n if (!path.startsWith(DELIVERY_PREFIX) || !operation?.operationId) {\n return [];\n }\n const parameters = operation.parameters ?? [];\n return [\n {\n id: operation.operationId,\n path,\n summary: operation.summary ?? path,\n tag: operation.tags?.[0] ?? '',\n routeKey: path.slice(DELIVERY_PREFIX.length).split('/')[0] ?? '',\n byId: path.includes('{id}'),\n list: parameters.some((parameter) => parameter.name === 'filters'),\n parameters,\n },\n ];\n });\n\n/** Operations by tag, in the document's tag order (models by label). */\nexport const groupOperations = (\n document: OpenApiDocument,\n operations: readonly DeliveryOperation[],\n): OperationGroup[] => {\n const order = (document.tags ?? []).map((tag) => tag.name);\n const tags = [...new Set([...order, ...operations.map((operation) => operation.tag)])];\n return tags\n .map((tag) => ({ tag, operations: operations.filter((operation) => operation.tag === tag) }))\n .filter((group) => group.operations.length > 0);\n};\n\nexport const hasParameter = (operation: DeliveryOperation, name: string) =>\n operation.parameters.some((parameter) => parameter.name === name);\n","import { useCallback, useState } from 'react';\nimport { EMPTY_DRAFT, type RequestDraft } from '../helpers/request';\n\n/**\n * The request builder's values per REST operation, kept while switching endpoints and tabs (in memory, this\n * visit only): the REST tab edits them, the GraphQL tab builds the same request as a query. The token is\n * not part of a draft: it lives in the explorer's token store.\n */\nexport const useRequestDrafts = () => {\n const [drafts, setDrafts] = useState<Readonly<Record<string, RequestDraft>>>({});\n const draftOf = useCallback(\n (operationId: string | undefined) => (operationId && drafts[operationId]) || EMPTY_DRAFT,\n [drafts],\n );\n const setDraft = useCallback((operationId: string, next: RequestDraft) => {\n setDrafts((current) => ({ ...current, [operationId]: next }));\n }, []);\n return { draftOf, setDraft };\n};\n","import { isModelDefinition } from '@shapio/schema';\nimport { getRouteApi } from '@tanstack/react-router';\nimport { useAllDefinitions } from '@/api/schema';\nimport { counterpartOperationId } from '../helpers/graphqlQuery';\nimport type { DeliveryOperation } from '../helpers/operations';\nimport type { ExplorerTab } from '../searchSchema';\n\nconst route = getRouteApi('/app/api-explorer');\n\n/**\n * Switches between REST and GraphQL on the same endpoint: the list stays the list, the read by ID the read\n * by ID, so the GraphQL tab shows the request just built in the REST tab.\n */\nexport const useSwitchTab = (\n restOperations: readonly DeliveryOperation[],\n operationId: string | undefined,\n) => {\n const navigate = route.useNavigate();\n const { definitions } = useAllDefinitions();\n return (tab: ExplorerTab) => {\n const models = (definitions ?? []).map(({ definition }) => definition).filter(isModelDefinition);\n const op = counterpartOperationId(tab, operationId, models, restOperations);\n void navigate({ search: { tab, ...(op ? { op } : {}) }, replace: true });\n };\n};\n","import { useMe } from '@/api/auth';\n\n/** The key delivery requests name this site by (`?site=`); undefined on the primary site, which needs none. */\nexport const useDeliverySiteKey = () => {\n const site = useMe().data?.site;\n return site && !site.isPrimary ? site.key : undefined;\n};\n","import { useTranslation } from 'react-i18next';\nimport { SubNav, SubNavGroup } from '@/components/SubNav';\nimport { SubNavLink } from '@/components/SubNavLink';\nimport { DELIVERY_PREFIX, type OperationGroup } from '../helpers/operations';\n\n/** Delivery endpoints are reads; the method is code, not text to translate. */\nconst METHOD = 'GET';\n\ntype EndpointNavProps = { groups: readonly OperationGroup[]; selectedId: string | undefined };\n\n/** Delivery endpoints per place (model), from the live OpenAPI document. */\nexport const EndpointNav = ({ groups, selectedId }: EndpointNavProps) => {\n const { t } = useTranslation();\n return (\n <SubNav label={t('develop.api.endpoints')}>\n {groups.map((group) => (\n <SubNavGroup key={group.tag} label={group.tag}>\n {group.operations.map((operation) => (\n <SubNavLink\n key={operation.id}\n to=\"/api-explorer\"\n search={{ tab: 'rest', op: operation.id }}\n title={operation.summary}\n aria-current={operation.id === selectedId ? 'page' : undefined}\n >\n <span className=\"font-mono text-2xs font-semibold text-muted-foreground\">{METHOD}</span>\n <span className=\"min-w-0 truncate font-mono text-xs\">\n {operation.path.slice(DELIVERY_PREFIX.length - 1)}\n </span>\n </SubNavLink>\n ))}\n </SubNavGroup>\n ))}\n </SubNav>\n );\n};\n","import { useMutation } from '@tanstack/react-query';\nimport { apiBaseUrl } from '@/api/client';\n\nexport type ExplorerResponse = {\n url: string;\n status: number;\n statusText: string;\n ok: boolean;\n durationMs: number;\n /** The parsed JSON body, or the text when it is not JSON. */\n body: unknown;\n text: string;\n};\n\n/** An absolute URL on this Shapio instance for a path like `/api/content/articles?locale=en`. */\nexport const absoluteApiUrl = (path: string) => new URL(path.replace(/^\\//, ''), apiBaseUrl()).href;\n\nconst parseBody = (text: string): unknown => {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n};\n\ntype SendVariables = { operationId: string; path: string; token: string };\n\n/**\n * Sends a delivery request the way a site would: no admin cookie (`credentials: 'omit'`), the pasted token\n * as a bearer token when there is one (anonymous otherwise), nothing cached.\n */\nexport const useSendRequest = () =>\n useMutation({\n mutationKey: ['develop', 'explorer', 'send'],\n mutationFn: async ({ path, token }: SendVariables): Promise<ExplorerResponse> => {\n const url = absoluteApiUrl(path);\n const started = performance.now();\n const response = await fetch(url, {\n headers: { accept: 'application/json', ...(token ? { authorization: `Bearer ${token}` } : {}) },\n credentials: 'omit',\n cache: 'no-store',\n });\n const text = await response.text();\n return {\n url,\n status: response.status,\n statusText: response.statusText,\n ok: response.ok,\n durationMs: Math.round(performance.now() - started),\n body: parseBody(text),\n text,\n };\n },\n });\n","import { Plus, X } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { newStableId } from '@/helpers/stableId';\nimport type { FilterRow } from '../helpers/request';\n\ntype FilterRowsProps = { rows: readonly FilterRow[]; onChange: (rows: FilterRow[]) => void };\n\n/** `filters[…]` as key/value rows: `title[$contains]` → `filters[title][$contains]=…`. */\nexport const FilterRows = ({ rows, onChange }: FilterRowsProps) => {\n const { t } = useTranslation();\n const update = (id: string, patch: Partial<FilterRow>) =>\n onChange(rows.map((row) => (row.id === id ? { ...row, ...patch } : row)));\n return (\n <fieldset className=\"space-y-2\">\n <legend className=\"text-sm font-semibold\">{t('develop.api.request.filters')}</legend>\n {rows.map((row, index) => (\n <div key={row.id} className=\"flex items-center gap-2\">\n <Input\n aria-label={t('develop.api.request.filterKey', { index: index + 1 })}\n placeholder={t('develop.api.request.filterKeyPlaceholder')}\n className=\"font-mono\"\n value={row.key}\n onChange={(event) => update(row.id, { key: event.target.value })}\n />\n <Input\n aria-label={t('develop.api.request.filterValue', { index: index + 1 })}\n placeholder={t('develop.api.request.filterValuePlaceholder')}\n value={row.value}\n onChange={(event) => update(row.id, { value: event.target.value })}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={t('develop.api.request.removeFilter', { index: index + 1 })}\n onClick={() => onChange(rows.filter((candidate) => candidate.id !== row.id))}\n >\n <X aria-hidden=\"true\" />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onChange([...rows, { id: newStableId(), key: '', value: '' }])}\n >\n <Plus aria-hidden=\"true\" />\n {t('develop.api.request.addFilter')}\n </Button>\n </fieldset>\n );\n};\n","import { create } from 'zustand';\nimport { useSessionStore } from '@/stores/session';\n\ntype ExplorerTokenState = {\n /** A pasted API token: in memory only (never persisted, never in a URL), gone on reload or sign-out. */\n token: string;\n setToken: (token: string) => void;\n};\n\nexport const useExplorerTokenStore = create<ExplorerTokenState>()((set) => ({\n token: '',\n setToken: (token) => set({ token }),\n}));\n\n// The admin session ended or changed (its CSRF token is cleared): forget the pasted token too.\nuseSessionStore.subscribe((state, previous) => {\n if (previous.csrfToken !== undefined && state.csrfToken === undefined) {\n useExplorerTokenStore.setState({ token: '' });\n }\n});\n","import { useId, type ComponentProps } from 'react';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Input } from '@/components/ui/input';\nimport { cn } from '@/helpers/cn';\n\ntype TextParamProps = {\n label: string;\n hint?: string;\n value: string;\n onChange: (value: string) => void;\n mono?: boolean;\n} & Pick<ComponentProps<typeof Input>, 'type' | 'inputMode' | 'placeholder' | 'required' | 'autoComplete'>;\n\n/** One request parameter: a labelled input, with the parameter's explanation behind an info icon. */\nexport const TextParam = ({ label, hint, value, onChange, mono = false, ...inputProps }: TextParamProps) => {\n const id = useId();\n const hintId = `${id}-hint`;\n return (\n <div className=\"min-w-0 space-y-2\">\n <HintedLabel htmlFor={id} label={label} hint={hint} hintId={hint ? hintId : undefined} />\n <Input\n id={id}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n aria-describedby={hint ? hintId : undefined}\n className={cn(mono && 'font-mono')}\n spellCheck={false}\n {...inputProps}\n />\n </div>\n );\n};\n","import { Send } from 'lucide-react';\nimport { useId, type FormEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocales } from '@/api/locales';\nimport { HintedLabel } from '@/components/HintedLabel';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { FilterRows } from '../FilterRows';\nimport { hasParameter, type DeliveryOperation } from '../helpers/operations';\nimport type { RequestDraft } from '../helpers/request';\nimport { useExplorerTokenStore } from '../stores/token';\nimport { TextParam } from './TextParam';\n\n/** Radix Select has no empty value: this stands for \"no `locale` parameter\" (the default locale). */\nconst DEFAULT_LOCALE = '__default__';\nconst METHOD = 'GET';\n\ntype RequestBuilderProps = {\n operation: DeliveryOperation;\n draft: RequestDraft;\n onDraftChange: (draft: RequestDraft) => void;\n path: string;\n sendable: boolean;\n sending: boolean;\n onSend: () => void;\n};\n\n/** Path parameter, locale, snapshot, projection, filters and the token, then Send. */\nexport const RequestBuilder = ({\n operation,\n draft,\n onDraftChange,\n path,\n sendable,\n sending,\n onSend,\n}: RequestBuilderProps) => {\n const { t } = useTranslation();\n const localeId = useId();\n const locales = useLocales().data ?? [];\n const token = useExplorerTokenStore((state) => state.token);\n const setToken = useExplorerTokenStore((state) => state.setToken);\n const set = (patch: Partial<RequestDraft>) => onDraftChange({ ...draft, ...patch });\n const submit = (event: FormEvent) => {\n event.preventDefault();\n if (sendable) {\n onSend();\n }\n };\n return (\n <Panel title={operation.summary} titleAs=\"h2\">\n <form className=\"space-y-5\" onSubmit={submit}>\n <p className=\"flex min-w-0 items-center gap-2\">\n <Badge variant=\"outline\" className=\"font-mono\">\n {METHOD}\n </Badge>\n <code className=\"min-w-0 font-mono text-xs break-all\">{path}</code>\n </p>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {operation.byId ? (\n <TextParam\n label={t('develop.api.request.id')}\n value={draft.id}\n onChange={(id) => set({ id })}\n required\n mono\n />\n ) : null}\n {hasParameter(operation, 'locale') ? (\n <div className=\"min-w-0 space-y-2\">\n <HintedLabel\n htmlFor={localeId}\n label={t('develop.api.request.locale')}\n hint={t('develop.api.request.localeHint')}\n />\n <Select\n value={draft.locale || DEFAULT_LOCALE}\n onValueChange={(value) => set({ locale: value === DEFAULT_LOCALE ? '' : value })}\n >\n <SelectTrigger id={localeId} className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={DEFAULT_LOCALE}>{t('develop.api.request.defaultLocale')}</SelectItem>\n {locales.map((locale) => (\n <SelectItem key={locale.code} value={locale.code}>\n {t('develop.api.request.localeOption', { label: locale.label, code: locale.code })}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n {hasParameter(operation, 'snapshot') ? (\n <TextParam\n label={t('develop.api.request.snapshot')}\n hint={t('develop.api.request.snapshotHint')}\n value={draft.snapshot}\n onChange={(snapshot) => set({ snapshot })}\n inputMode=\"numeric\"\n />\n ) : null}\n <TextParam\n label={t('develop.api.request.fields')}\n hint={t('develop.api.request.fieldsHint')}\n value={draft.fields}\n onChange={(fields) => set({ fields })}\n mono\n />\n <TextParam\n label={t('develop.api.request.populate')}\n hint={t('develop.api.request.populateHint')}\n value={draft.populate}\n onChange={(populate) => set({ populate })}\n mono\n />\n {operation.list ? (\n <>\n <TextParam\n label={t('develop.api.request.sort')}\n hint={t('develop.api.request.sortHint')}\n value={draft.sort}\n onChange={(sort) => set({ sort })}\n mono\n />\n <TextParam\n label={t('develop.api.request.search')}\n value={draft.q}\n onChange={(q) => set({ q })}\n />\n <TextParam\n label={t('develop.api.request.page')}\n value={draft.page}\n onChange={(page) => set({ page })}\n inputMode=\"numeric\"\n />\n <TextParam\n label={t('develop.api.request.pageSize')}\n value={draft.pageSize}\n onChange={(pageSize) => set({ pageSize })}\n inputMode=\"numeric\"\n />\n </>\n ) : null}\n </div>\n {operation.list ? <FilterRows rows={draft.filters} onChange={(filters) => set({ filters })} /> : null}\n <TextParam\n label={t('develop.api.request.token')}\n hint={t('develop.api.request.tokenHint')}\n value={token}\n onChange={setToken}\n type=\"password\"\n autoComplete=\"off\"\n placeholder={t('develop.api.request.tokenPlaceholder')}\n mono\n />\n <div className=\"flex justify-end\">\n <Button type=\"submit\" disabled={!sendable || sending}>\n <Send aria-hidden=\"true\" />\n {sending ? t('develop.api.sending') : t('develop.api.send')}\n </Button>\n </div>\n </form>\n </Panel>\n );\n};\n","/**\n * The entries in a delivery response body (`data` is one entry or a list), with what an \"Edit entry\" link\n * needs: the ID, the locale it was served in, and a short label (a `title`-like field when present).\n */\nexport type ResponseEntry = { id: string; locale: string | undefined; label: string | undefined };\n\nconst LABEL_KEYS = ['title', 'name', 'label', 'heading', 'slug'] as const;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst toEntry = (value: unknown): ResponseEntry[] => {\n if (!isRecord(value) || typeof value.id !== 'string') {\n return [];\n }\n const labelKey = LABEL_KEYS.find((key) => typeof value[key] === 'string' && value[key] !== '');\n return [\n {\n id: value.id,\n locale: typeof value.locale === 'string' ? value.locale : undefined,\n label: labelKey ? String(value[labelKey]) : undefined,\n },\n ];\n};\n\nexport const responseEntries = (body: unknown): ResponseEntry[] => {\n if (!isRecord(body)) {\n return [];\n }\n return Array.isArray(body.data) ? body.data.flatMap(toEntry) : toEntry(body.data);\n};\n","import { Link } from '@tanstack/react-router';\nimport { Pencil } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport type { ResponseEntry } from '../../helpers/entries';\n\ntype EntryLinksProps = { entries: readonly ResponseEntry[]; modelKey: string };\n\n/** One row per returned entry with a link to edit it in the admin. */\nexport const EntryLinks = ({ entries, modelKey }: EntryLinksProps) => {\n const { t } = useTranslation();\n return (\n <ul aria-label={t('develop.api.response.entries')} className=\"divide-y rounded-lg border\">\n {entries.map((entry) => (\n <li key={`${entry.id}:${entry.locale ?? ''}`} className=\"flex min-w-0 items-center gap-3 px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\">{entry.label ?? t('content.untitled')}</p>\n <p className=\"truncate font-mono text-2xs text-muted-foreground\">\n {entry.locale\n ? t('develop.api.response.idLocale', { id: entry.id, locale: entry.locale })\n : entry.id}\n </p>\n </div>\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link\n to=\"/content/$modelKey/$entryId\"\n params={{ modelKey, entryId: entry.id }}\n search={entry.locale ? { locale: entry.locale } : {}}\n aria-label={t('develop.api.response.editEntryLabel', { entry: entry.label ?? entry.id })}\n >\n <Pencil aria-hidden=\"true\" />\n {t('develop.api.response.editEntry')}\n </Link>\n </Button>\n </li>\n ))}\n </ul>\n );\n};\n","import { Radio } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { StatusChip } from '@/components/StatusChip';\nimport { responseEntries } from '../helpers/entries';\nimport type { ExplorerResponse } from '../hooks/useSendRequest';\nimport { EntryLinks } from './EntryLinks';\n\ntype ResponseViewProps = { response: ExplorerResponse | undefined; modelKey: string | undefined };\n\n/** The live response: status and timing, the returned entries (with \"Edit entry\"), and the JSON. */\nexport const ResponseView = ({ response, modelKey }: ResponseViewProps) => {\n const { t } = useTranslation();\n const entries = useMemo(() => (response?.ok ? responseEntries(response.body) : []), [response]);\n const pretty = useMemo(\n () =>\n response && typeof response.body !== 'string' ? JSON.stringify(response.body, null, 2) : response?.text,\n [response],\n );\n return (\n <Panel\n title={t('develop.api.response.title')}\n actions={\n response ? (\n <>\n <StatusChip\n tone={response.ok ? 'success' : 'danger'}\n label={`${response.status} ${response.statusText}`.trim()}\n size=\"sm\"\n />\n <span className=\"text-meta text-muted-foreground tabular-nums\">\n {t('develop.api.response.duration', { ms: response.durationMs })}\n </span>\n </>\n ) : null\n }\n >\n {response ? (\n <div className=\"space-y-4\">\n <p role=\"status\" className=\"sr-only\">\n {t('develop.api.response.announce', { status: response.status, ms: response.durationMs })}\n </p>\n {entries.length > 0 && modelKey ? <EntryLinks entries={entries} modelKey={modelKey} /> : null}\n <CodeBlock label={t('develop.api.response.body')} code={pretty ?? ''} />\n </div>\n ) : (\n <EmptyState size=\"panel\" icon={Radio} title={t('develop.api.response.empty')} />\n )}\n </Panel>\n );\n};\n","import type { FieldUsageResponse, PrincipalUsageSummary, UsageSelection } from '@shapio/client';\nimport { useQueries } from '@tanstack/react-query';\nimport { adminApi } from './client';\nimport { queryKeys } from './queryKeys';\n\n/** The window the developer pages count reads over. */\nexport const USAGE_DAYS = 7;\n\nconst modelUsageOptions = (modelId: string, days: number) => ({\n queryKey: queryKeys.develop.usage.model(modelId, days),\n queryFn: () => adminApi.usage.fields({ modelId, days }),\n meta: { silent: true },\n});\n\nexport type PrincipalFieldRead = {\n modelId: string;\n apiKeyPath: string;\n reads: number;\n lastReadAt: string;\n selection: UsageSelection;\n};\n\n/** One reader across every model: totals, its pin and the fields it read. */\nexport type PrincipalUsage = PrincipalUsageSummary & { fields: PrincipalFieldRead[] };\n\nconst mergeUsage = (reports: readonly FieldUsageResponse[]): PrincipalUsage[] => {\n const byKey = new Map<string, PrincipalUsage>();\n for (const report of reports) {\n for (const summary of report.principals) {\n byKey.set(summary.principalKey, { ...summary, fields: byKey.get(summary.principalKey)?.fields ?? [] });\n }\n for (const field of report.fields) {\n for (const principal of field.principals) {\n byKey.get(principal.principalKey)?.fields.push({\n modelId: report.modelId,\n apiKeyPath: field.apiKeyPath ?? field.fieldPath,\n reads: principal.reads,\n lastReadAt: principal.lastReadAt,\n selection: principal.selection,\n });\n }\n }\n }\n return [...byKey.values()].sort((a, b) => b.requests - a.requests);\n};\n\n/**\n * Who reads what across the given models (`GET /api/admin/usage/fields` once per model, cached per model).\n * `enabled` is false without `tokens.manage`. `tracking` is false when the server counts nothing new.\n */\nexport const usePrincipalUsage = (modelIds: readonly string[], enabled: boolean, days: number = USAGE_DAYS) =>\n useQueries({\n queries: modelIds.map((modelId) => ({ ...modelUsageOptions(modelId, days), enabled })),\n combine: (results) => {\n const reports = results.flatMap((result) => (result.data ? [result.data] : []));\n return {\n principals: mergeUsage(reports),\n tracking: reports.every((report) => report.tracking),\n isPending: enabled && results.some((result) => result.isPending),\n error: results.find((result) => result.error)?.error ?? null,\n refetch: () => Promise.all(results.map((result) => result.refetch())),\n };\n },\n });\n","import { useQuery } from '@tanstack/react-query';\nimport { adminApi } from '@/api/client';\nimport { queryKeys } from '@/api/queryKeys';\nimport { USAGE_DAYS } from '@/api/usage';\n\n/**\n * Who read a model's fields (`GET /api/admin/usage/fields`), on the same cache entry the Live page uses.\n * Needs `tokens.manage`; without it the query fails quietly and the shape shows no readers.\n */\nexport const useFieldUsage = (modelId: string) =>\n useQuery({\n queryKey: queryKeys.develop.usage.model(modelId, USAGE_DAYS),\n queryFn: () => adminApi.usage.fields({ modelId, days: USAGE_DAYS }),\n meta: { silent: true },\n });\n","import type { FieldUsageResponse } from '@shapio/client';\nimport type { DataType, ModelDefinition } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\nimport { USAGE_DAYS } from '@/api/usage';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { useFieldUsage } from '../hooks/useFieldUsage';\n\nconst FLAG_KEYS = {\n required: 'develop.api.shape.flags.required',\n localized: 'develop.api.shape.flags.localized',\n private: 'develop.api.shape.flags.private',\n unique: 'develop.api.shape.flags.unique',\n filterable: 'develop.api.shape.flags.filterable',\n sortable: 'develop.api.shape.flags.sortable',\n} as const;\n\ntype Flag = keyof typeof FLAG_KEYS;\n\nconst flagsOf = (field: ModelDefinition['fields'][number]): Flag[] =>\n [\n field.required && 'required',\n field.localized && 'localized',\n !field.public && 'private',\n field.unique && 'unique',\n field.filterable && 'filterable',\n field.sortable && 'sortable',\n ].filter((flag): flag is Flag => flag !== false);\n\n/** Reads of a top-level field and its readers' names (tokens by name), most reads first. */\nconst readsOf = (usage: FieldUsageResponse | undefined, apiKey: string) => {\n const field = usage?.fields.find((candidate) => candidate.apiKeyPath === apiKey);\n return field ? { reads: field.reads, readers: field.principals } : undefined;\n};\n\ntype ShapePanelProps = { model: ModelDefinition };\n\n/**\n * The fields the endpoint returns, with their types and flags from the registry and who reads them\n * (delivery usage over the last days, when the admin may see it).\n */\nexport const ShapePanel = ({ model }: ShapePanelProps) => {\n const { t } = useTranslation();\n const usage = useFieldUsage(model.id);\n const readerName = (principalKey: string, tokenName: string | undefined) =>\n tokenName ??\n (principalKey === 'anonymous' ? t('develop.api.shape.anonymous') : t('develop.api.shape.appUsers'));\n const fields = model.fields.filter((field) => !field.deprecated);\n return (\n <Panel\n title={t('develop.api.shape.title')}\n description={t('develop.api.shape.description', { model: model.label, days: USAGE_DAYS })}\n flush\n >\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('develop.api.shape.field')}</TableHead>\n <TableHead>{t('develop.api.shape.readers')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {fields.map((field) => {\n const reads = readsOf(usage.data, field.apiKey);\n return (\n <TableRow key={field.id}>\n <TableCell className=\"h-auto py-2 align-top\">\n <p className=\"font-mono text-xs font-semibold\">{field.apiKey}</p>\n <p className=\"text-meta text-muted-foreground\">\n {t(`models.dataTypes.${field.type satisfies DataType}.name`)}\n </p>\n {flagsOf(field).length > 0 ? (\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {flagsOf(field).map((flag) => (\n <Badge key={flag} variant=\"outline\" className=\"text-2xs\">\n {t(FLAG_KEYS[flag])}\n </Badge>\n ))}\n </div>\n ) : null}\n </TableCell>\n <TableCell className=\"h-auto py-2 align-top text-meta\">\n {reads ? (\n <>\n <p className=\"tabular-nums\">{t('develop.api.shape.reads', { count: reads.reads })}</p>\n <p className=\"text-muted-foreground\">\n {reads.readers\n .map((reader) => readerName(reader.principalKey, reader.tokenName))\n .join(', ')}\n </p>\n </>\n ) : (\n <span className=\"text-muted-foreground\">\n {usage.isPending\n ? t('common.loading')\n : usage.data?.tracking === false\n ? t('develop.api.shape.trackingOff')\n : t('develop.api.shape.noReads')}\n </span>\n )}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </Panel>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { curlSnippet, fetchSnippet } from '../helpers/request';\n\ntype SnippetsProps = { url: string; withToken: boolean };\n\n/** The request as curl and fetch, to copy (the token appears as `$SHAPIO_TOKEN`, never its value). */\nexport const Snippets = ({ url, withToken }: SnippetsProps) => {\n const { t } = useTranslation();\n return (\n <Tabs defaultValue=\"curl\">\n <TabsList aria-label={t('develop.api.copyAs')} className=\"self-start\">\n <TabsTrigger value=\"curl\">{t('develop.api.curl')}</TabsTrigger>\n <TabsTrigger value=\"fetch\">{t('develop.api.fetch')}</TabsTrigger>\n </TabsList>\n <TabsContent value=\"curl\">\n <CodeBlock label={t('develop.api.curlLabel')} code={curlSnippet(url, withToken)} />\n </TabsContent>\n <TabsContent value=\"fetch\">\n <CodeBlock label={t('develop.api.fetchLabel')} code={fetchSnippet(url, withToken)} />\n </TabsContent>\n </Tabs>\n );\n};\n","import { isModelDefinition, routeKeyOf } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useAllDefinitions } from '@/api/schema';\nimport { withSiteParameter } from '@/helpers/sites';\nimport { useDeliverySiteKey } from '@/hooks/useDeliverySiteKey';\nimport { EndpointNav } from '../EndpointNav';\nimport type { DeliveryOperation, OperationGroup } from '../helpers/operations';\nimport { isSendable, requestPath, type RequestDraft } from '../helpers/request';\nimport { absoluteApiUrl, useSendRequest } from '../hooks/useSendRequest';\nimport { RequestBuilder } from '../RequestBuilder';\nimport { ResponseView } from '../ResponseView';\nimport { ShapePanel } from '../ShapePanel';\nimport { Snippets } from '../Snippets';\nimport { useExplorerTokenStore } from '../stores/token';\n\ntype RestTabProps = {\n groups: readonly OperationGroup[];\n operation: DeliveryOperation;\n /** The operation's request builder values (kept by the explorer, shared with the GraphQL tab). */\n draft: RequestDraft;\n onDraftChange: (draft: RequestDraft) => void;\n};\n\n/** REST: endpoints per place, the request builder, the snippets, the live response and the shape. */\nexport const RestTab = ({ groups, operation, draft, onDraftChange }: RestTabProps) => {\n const token = useExplorerTokenStore((state) => state.token);\n const send = useSendRequest();\n const { definitions } = useAllDefinitions();\n const model = useMemo(\n () =>\n definitions\n ?.map(({ definition }) => definition)\n .filter(isModelDefinition)\n .find((candidate) => routeKeyOf(candidate) === operation.routeKey),\n [definitions, operation.routeKey],\n );\n const siteKey = useDeliverySiteKey();\n // A site other than the primary one is named in the URL, as a site's own requests would (sites plan §H).\n const path = withSiteParameter(requestPath(operation, draft), siteKey);\n // The last response belongs to the operation it was sent for.\n const response = send.data && send.variables?.operationId === operation.id ? send.data : undefined;\n return (\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n <EndpointNav groups={groups} selectedId={operation.id} />\n <div className=\"grid min-w-0 flex-1 gap-6 2xl:grid-cols-[minmax(0,1fr)_24rem]\">\n <div className=\"min-w-0 space-y-6\">\n <RequestBuilder\n operation={operation}\n draft={draft}\n onDraftChange={onDraftChange}\n path={path}\n sendable={isSendable(operation, draft)}\n sending={send.isPending}\n onSend={() => send.mutate({ operationId: operation.id, path, token })}\n />\n <Snippets url={absoluteApiUrl(path)} withToken={token !== ''} />\n <ResponseView response={response} modelKey={model?.apiKey} />\n </div>\n {model ? <ShapePanel model={model} /> : null}\n </div>\n </div>\n );\n};\n","import { getRouteApi } from '@tanstack/react-router';\nimport { Braces } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useOpenApiDocument, type OpenApiDocument } from '@/api/apiDocs';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { GraphqlTab } from './GraphqlTab';\nimport { deliveryOperations, groupOperations } from './helpers/operations';\nimport { useRequestDrafts } from './hooks/useRequestDrafts';\nimport { useSwitchTab } from './hooks/useSwitchTab';\nimport { RestTab } from './RestTab';\nimport { EXPLORER_TABS, type ExplorerTab } from './searchSchema';\n\nconst route = getRouteApi('/app/api-explorer');\n\nconst TAB_LABEL_KEYS = {\n rest: 'develop.api.tabs.rest',\n graphql: 'develop.graphql.title',\n} as const satisfies Record<ExplorerTab, string>;\n\ntype ExplorerProps = { document: OpenApiDocument };\n\nconst Explorer = ({ document }: ExplorerProps) => {\n const { t } = useTranslation();\n const { tab = 'rest', op } = route.useSearch();\n const operations = useMemo(() => deliveryOperations(document), [document]);\n const groups = useMemo(() => groupOperations(document, operations), [document, operations]);\n const operation = operations.find((candidate) => candidate.id === op) ?? groups[0]?.operations[0];\n const { draftOf, setDraft } = useRequestDrafts();\n const switchTab = useSwitchTab(operations, tab === 'rest' ? operation?.id : op);\n return (\n <Tabs value={tab} onValueChange={(value) => switchTab(value as ExplorerTab)}>\n <PageHeader\n title={t('develop.apiExplorerTitle')}\n meta={t('develop.api.meta', { version: document.info.version, count: operations.length })}\n tabs={\n <TabsList variant=\"underline\" aria-label={t('develop.api.tabs.label')}>\n {EXPLORER_TABS.map((value) => (\n <TabsTrigger key={value} value={value}>\n {t(TAB_LABEL_KEYS[value])}\n </TabsTrigger>\n ))}\n </TabsList>\n }\n />\n <TabsContent value=\"rest\" className=\"pt-4\">\n {operation ? (\n <RestTab\n groups={groups}\n operation={operation}\n draft={draftOf(operation.id)}\n onDraftChange={(next) => setDraft(operation.id, next)}\n />\n ) : (\n <EmptyState\n icon={Braces}\n title={t('develop.api.empty')}\n description={t('develop.api.emptyDescription')}\n />\n )}\n </TabsContent>\n <TabsContent value=\"graphql\" className=\"pt-4\">\n <GraphqlTab selected={op} restOperations={operations} draftOf={draftOf} />\n </TabsContent>\n </Tabs>\n );\n};\n\n/**\n * The API explorer (plan developer-face §2): delivery endpoints from the live OpenAPI document, a request\n * builder that calls the API as a site would (anonymous or with a pasted token), the live response and the\n * shape; GraphQL as the same request in a query, opened in the GraphQL page's vendored GraphiQL.\n */\nexport const ApiExplorer = () => {\n const query = useOpenApiDocument();\n return (\n <Page width=\"full\">\n <QueryView query={query}>{(document) => <Explorer document={document} />}</QueryView>\n </Page>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { ChangeSet } from '@shapio/client';\nimport { useForm } from 'react-hook-form';\nimport { z } from 'zod';\nimport { useCreateChangeSet } from '@/api/changeSets';\nimport { useResetOnOpen } from '@/features/Publishing/hooks/useResetOnOpen';\nimport { settle } from '@/helpers/settle';\nimport { requiredText } from '@/helpers/validation';\n\nconst createChangeSetSchema = z.object({\n title: requiredText().max(200, 'validation.tooLong'),\n description: z.string().max(5000, 'validation.tooLong'),\n});\n\ntype CreateChangeSetValues = z.infer<typeof createChangeSetSchema>;\n\nconst EMPTY: CreateChangeSetValues = { title: '', description: '' };\n\nexport const useCreateChangeSetForm = (open: boolean, onCreated: (set: ChangeSet) => void) => {\n const createChangeSet = useCreateChangeSet();\n const form = useForm<CreateChangeSetValues>({\n resolver: zodResolver(createChangeSetSchema),\n defaultValues: EMPTY,\n });\n const { reset } = form;\n useResetOnOpen(open, reset, EMPTY, createChangeSet.reset);\n const onSubmit = form.handleSubmit(async ({ title, description }) => {\n const created = await settle(\n createChangeSet.mutateAsync({ title: title.trim(), description: description.trim() }),\n );\n if (created.ok) {\n reset(EMPTY);\n onCreated(created.value);\n }\n });\n return { form, onSubmit, createChangeSet };\n};\n","import type { ChangeSet } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { FormError } from '@/components/FormError';\nimport { FormSheet } from '@/components/FormSheet';\nimport { FormTextareaField } from '@/components/FormTextareaField';\nimport { FormTextField } from '@/components/FormTextField';\nimport { useCreateChangeSetForm } from '../hooks/useCreateChangeSetForm';\n\ntype CreateSheetProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onCreated: (set: ChangeSet) => void;\n};\n\n/** \"New change set\": a title and an optional description, in a sheet beside the list. */\nexport const CreateSheet = ({ open, onOpenChange, onCreated }: CreateSheetProps) => {\n const { t } = useTranslation();\n const { form, onSubmit, createChangeSet } = useCreateChangeSetForm(open, onCreated);\n return (\n <FormSheet\n open={open}\n onOpenChange={onOpenChange}\n size=\"md\"\n title={t('changes.createTitle')}\n dirty={form.formState.isDirty}\n pending={createChangeSet.isPending}\n submitLabel={t('common.create')}\n pendingLabel={t('common.saving')}\n onSubmit={(event) => void onSubmit(event)}\n >\n <FormTextField\n control={form.control}\n name=\"title\"\n label={t('changes.fields.title')}\n autoComplete=\"off\"\n />\n <FormTextareaField\n control={form.control}\n name=\"description\"\n label={t('changes.fields.description')}\n rows={3}\n />\n <FormError error={createChangeSet.error} />\n </FormSheet>\n );\n};\n","import type { ChangeSetStatus } from '@shapio/client';\nimport type { StatusTone } from '@/components/StatusChip';\n\n/** D0 renamed `releases.manage` to this in the change-sets migration. */\nexport const CHANGES_MANAGE_PERMISSION = 'changes.manage';\n/** Shipping and scheduling a ship (split from `changes.manage`, agentic plan §I). */\nexport const CHANGES_SHIP_PERMISSION = 'changes.ship';\nexport const TOKENS_MANAGE_PERMISSION = 'tokens.manage';\n\ntype Display = { labelKey: string; tone: StatusTone };\n\nexport const CHANGE_SET_STATUS_DISPLAY = {\n open: { labelKey: 'changes.statuses.open', tone: 'neutral' },\n scheduled: { labelKey: 'changes.statuses.scheduled', tone: 'scheduled' },\n shipping: { labelKey: 'changes.statuses.shipping', tone: 'progress' },\n shipped: { labelKey: 'changes.statuses.shipped', tone: 'success' },\n failed: { labelKey: 'changes.statuses.failed', tone: 'danger' },\n discarded: { labelKey: 'changes.statuses.discarded', tone: 'muted' },\n} as const satisfies Record<ChangeSetStatus, Display>;\n\n/** Sets whose items and title can still change. */\nexport const EDITABLE_STATUSES: ReadonlySet<ChangeSetStatus> = new Set(['open', 'failed']);\n","import { useMe } from '@/api/auth';\nimport { CHANGES_MANAGE_PERMISSION, CHANGES_SHIP_PERMISSION, TOKENS_MANAGE_PERMISSION } from '../constants';\n\n/**\n * What the signed-in admin may see on the developer pages. The UI hides what they can't; the server\n * enforces it. Permissions are compared as strings: `changes.manage` arrives with D0's client types.\n */\nexport const useDevelopPermissions = () => {\n const permissions: readonly string[] = useMe().data?.globalPermissions ?? [];\n return {\n canManageChanges: permissions.includes(CHANGES_MANAGE_PERMISSION),\n canShipChanges: permissions.includes(CHANGES_SHIP_PERMISSION),\n canReadUsage: permissions.includes(TOKENS_MANAGE_PERMISSION),\n canManagePublishing: permissions.includes('publishing.manage'),\n canManageWebhooks: permissions.includes('webhooks.manage'),\n };\n};\n","import { useTranslation } from 'react-i18next';\n\nconst ACTOR_TYPE_KEYS = {\n admin: 'develop.actors.admin',\n token: 'develop.actors.token',\n system: 'develop.actors.system',\n} as const;\n\nconst isKnownType = (type: string): type is keyof typeof ACTOR_TYPE_KEYS => type in ACTOR_TYPE_KEYS;\n\n/** Who did something: the admin's or token's name, else what kind of actor it was. */\nexport const useActorLabel = () => {\n const { t } = useTranslation();\n return (actor: { type: string; name?: string | null } | null): string => {\n if (!actor) {\n return t('develop.actors.system');\n }\n if (actor.name) {\n return actor.name;\n }\n return isKnownType(actor.type) ? t(ACTOR_TYPE_KEYS[actor.type]) : actor.type;\n };\n};\n","import type { ChangeSetSummary } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { TableCell, TableRow } from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { CHANGE_SET_STATUS_DISPLAY } from '../../constants';\nimport { useActorLabel } from '../../hooks/useActorLabel';\n\ntype RowProps = { set: ChangeSetSummary; connectionName: string | undefined };\n\n/** One set: title (→ review), status, items, author, and when it ships or last changed. */\nexport const Row = ({ set, connectionName }: RowProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const status = CHANGE_SET_STATUS_DISPLAY[set.status];\n const when = set.scheduledFor ?? set.updatedAt;\n return (\n <TableRow>\n <TableCell className=\"max-w-80\">\n <RowTitle asChild className=\"block truncate\">\n <Link to=\"/changes/$changeSetId\" params={{ changeSetId: set.id }}>\n {set.title}\n </Link>\n </RowTitle>\n {set.description ? (\n <span className=\"block truncate text-meta text-muted-foreground\">{set.description}</span>\n ) : null}\n </TableCell>\n <TableCell>\n <StatusChip tone={status.tone} label={t(status.labelKey)} />\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">\n {t('changes.itemCount', { count: set.entryItemCount + set.schemaItemCount })}\n </TableCell>\n <TableCell className=\"whitespace-nowrap\">{actorLabel(set.createdBy)}</TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(when)}>\n {set.scheduledFor\n ? t('changes.scheduledFor', { at: formatDateTime(set.scheduledFor) })\n : formatRelativeTime(when)}\n {connectionName ? (\n <span className=\"block text-meta text-muted-foreground\">\n {t('changes.deploysTo', { name: connectionName })}\n </span>\n ) : null}\n </TableCell>\n </TableRow>\n );\n};\n","import { GitPullRequest } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useChangeSets } from '@/api/changeSets';\nimport { useDeploymentConnections } from '@/api/deployments';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { Table, TableBody, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { Row } from './Row';\n\n/** Sets still in flight: open, scheduled, shipping or failed. */\nexport const OpenSets = () => {\n const { t } = useTranslation();\n const sets = useChangeSets();\n const connections = useDeploymentConnections();\n const connectionName = (id: string | null) =>\n id ? connections.data?.find((connection) => connection.id === id)?.name : undefined;\n return (\n <Panel title={t('changes.openTitle')} flush>\n <QueryView\n query={sets}\n isEmpty={(data) => data.items.length === 0}\n empty={\n <EmptyState\n icon={GitPullRequest}\n size=\"panel\"\n title={t('changes.empty')}\n description={t('changes.emptyDescription')}\n />\n }\n >\n {(data) => (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.fields.title')}</TableHead>\n <TableHead>{t('changes.fields.status')}</TableHead>\n <TableHead className=\"text-right\">{t('changes.fields.items')}</TableHead>\n <TableHead>{t('changes.fields.author')}</TableHead>\n <TableHead>{t('changes.fields.when')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.items.map((set) => (\n <Row key={set.id} set={set} connectionName={connectionName(set.deploymentConnectionId)} />\n ))}\n </TableBody>\n </Table>\n )}\n </QueryView>\n </Panel>\n );\n};\n","import { CalendarClock } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useSchedules } from '@/api/schedules';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { PUBLISHING_PAGE_SIZE } from '@/constants/publishing';\nimport { PUBLICATION_ACTION_LABELS } from '@/features/Publishing/constants';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\n\n/** Single-entry scheduled publications, read-only here (they are managed under Publishing → Scheduled). */\nexport const Scheduled = () => {\n const { t } = useTranslation();\n const schedules = useSchedules({ status: 'scheduled', limit: PUBLISHING_PAGE_SIZE });\n return (\n <Panel title={t('changes.scheduledPublications')} flush>\n <QueryView\n query={schedules}\n isEmpty={(data) => data.items.length === 0}\n empty={<EmptyState icon={CalendarClock} size=\"panel\" title={t('changes.noScheduledPublications')} />}\n >\n {(data) => (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.fields.model')}</TableHead>\n <TableHead>{t('changes.fields.entry')}</TableHead>\n <TableHead>{t('changes.fields.locale')}</TableHead>\n <TableHead>{t('changes.fields.action')}</TableHead>\n <TableHead>{t('changes.fields.when')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.items.map((schedule) => (\n <TableRow key={schedule.id}>\n <TableCell className=\"font-mono text-xs\">\n {schedule.modelKey ?? t('common.unknown')}\n </TableCell>\n <TableCell className=\"max-w-48\">\n <span className=\"block truncate font-mono text-xs\" title={schedule.entryId}>\n {schedule.entryId}\n </span>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{schedule.locale}</TableCell>\n <TableCell>{t(PUBLICATION_ACTION_LABELS[schedule.action])}</TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(schedule.runAt)}>\n {formatRelativeTime(schedule.runAt)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </QueryView>\n </Panel>\n );\n};\n","import type { UnassignedEntry } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useAddChangeSetEntry, useCreateChangeSet } from '@/api/changeSets';\n\n/**\n * Adds an unassigned entry draft to a set (to publish it when the set ships), or to a new set created\n * with `title` first. Resolves when done; errors stay with the mutations for the popover to show.\n */\nexport const useAddToChangeSet = (entry: UnassignedEntry) => {\n const { t } = useTranslation();\n const addEntry = useAddChangeSetEntry();\n const createChangeSet = useCreateChangeSet();\n const input = {\n modelKey: entry.modelKey ?? '',\n entryId: entry.entryId,\n locale: entry.locale,\n action: 'publish' as const,\n };\n const addTo = async (id: string) => {\n const set = await addEntry.mutateAsync({ id, input });\n toast.success(t('changes.added', { title: set.title }));\n };\n return {\n addTo,\n createAndAdd: async (title: string) => {\n const set = await createChangeSet.mutateAsync({ title });\n await addTo(set.id);\n },\n pending: addEntry.isPending || createChangeSet.isPending,\n error: addEntry.error ?? createChangeSet.error,\n reset: () => {\n addEntry.reset();\n createChangeSet.reset();\n },\n };\n};\n","import type { UnassignedEntry } from '@shapio/client';\nimport { FolderPlus } from 'lucide-react';\nimport { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useChangeSets } from '@/api/changeSets';\nimport { FormError } from '@/components/FormError';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { logError } from '@/helpers/reportError';\nimport { useAddToChangeSet } from '../hooks/useAddToChangeSet';\n\ntype AddToPopoverProps = { entry: UnassignedEntry; label: string };\n\n/** \"Add to…\": pick an open change set, or name a new one, for an entry draft. */\nexport const AddToPopover = ({ entry, label }: AddToPopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const inputId = useId();\n const [open, setOpen] = useState(false);\n const [newTitle, setNewTitle] = useState('');\n const sets = useChangeSets('open');\n const { addTo, createAndAdd, pending, error, reset } = useAddToChangeSet(entry);\n const run = (action: () => Promise<void>) =>\n void action().then(\n () => setOpen(false),\n (cause: unknown) => logError(cause, 'adding an entry to a change set'),\n );\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (pending) {\n return;\n }\n setOpen(next);\n if (next) {\n reset();\n setNewTitle('');\n }\n }}\n modal\n >\n <PopoverTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" aria-label={label}>\n <FolderPlus aria-hidden=\"true\" />\n {t('changes.addTo')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" aria-labelledby={titleId} className=\"w-80 space-y-3\">\n <p id={titleId} className=\"text-sm font-semibold\">\n {t('changes.addToTitle')}\n </p>\n {sets.data && sets.data.items.length > 0 ? (\n <ul className=\"max-h-56 space-y-1 overflow-y-auto\">\n {sets.data.items.map((set) => (\n <li key={set.id}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-start truncate\"\n disabled={pending}\n onClick={() => run(() => addTo(set.id))}\n >\n {set.title}\n </Button>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-meta text-muted-foreground\">{t('changes.noOpenSets')}</p>\n )}\n <form\n noValidate\n className=\"space-y-2 border-t pt-3\"\n onSubmit={(event) => {\n event.preventDefault();\n const title = newTitle.trim();\n if (title) {\n run(() => createAndAdd(title));\n }\n }}\n >\n <label htmlFor={inputId} className=\"text-sm font-semibold\">\n {t('changes.newSetTitle')}\n </label>\n <div className=\"flex gap-2\">\n <Input\n id={inputId}\n inputSize=\"sm\"\n value={newTitle}\n maxLength={200}\n autoComplete=\"off\"\n onChange={(event) => setNewTitle(event.target.value)}\n />\n <SubmitButton\n size=\"sm\"\n pending={pending}\n pendingLabel={t('common.saving')}\n disabled={!newTitle.trim()}\n >\n {t('common.create')}\n </SubmitButton>\n </div>\n </form>\n <FormError error={error} />\n </PopoverContent>\n </Popover>\n );\n};\n","import { Link } from '@tanstack/react-router';\nimport { Inbox } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useUnassignedEntries } from '@/api/changeSets';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { AddToPopover } from '../AddToPopover';\n\nconst UNASSIGNED_STATUS = {\n draft: { labelKey: 'changes.unassigned.statuses.draft', tone: 'neutral' },\n modified: { labelKey: 'changes.unassigned.statuses.modified', tone: 'warning' },\n} as const;\n\n/** Drafts not yet in a change set, each with \"Add to…\". */\nexport const Unassigned = () => {\n const { t } = useTranslation();\n const entries = useUnassignedEntries();\n return (\n <Panel title={t('changes.unassigned.title')} flush>\n <QueryView\n query={entries}\n isEmpty={(data) => data.items.length === 0}\n empty={<EmptyState icon={Inbox} size=\"panel\" title={t('changes.unassigned.empty')} />}\n >\n {(data) => (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.fields.entry')}</TableHead>\n <TableHead>{t('changes.fields.model')}</TableHead>\n <TableHead>{t('changes.fields.locale')}</TableHead>\n <TableHead>{t('changes.fields.status')}</TableHead>\n <TableHead>{t('changes.fields.updated')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {data.items.map((entry) => {\n const status = UNASSIGNED_STATUS[entry.status];\n const title = entry.title ?? entry.entryId;\n return (\n <TableRow key={`${entry.entryId}:${entry.locale}`}>\n <TableCell className=\"max-w-72\">\n {entry.modelKey ? (\n <RowTitle asChild className=\"block truncate\">\n <Link\n to=\"/content/$modelKey/$entryId\"\n params={{ modelKey: entry.modelKey, entryId: entry.entryId }}\n search={{ locale: entry.locale }}\n >\n {title}\n </Link>\n </RowTitle>\n ) : (\n <RowTitle className=\"block truncate\">{title}</RowTitle>\n )}\n </TableCell>\n <TableCell className=\"font-mono text-xs\">\n {entry.modelKey ?? t('common.unknown')}\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{entry.locale}</TableCell>\n <TableCell>\n <StatusChip tone={status.tone} label={t(status.labelKey)} />\n </TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(entry.updatedAt)}>\n {formatRelativeTime(entry.updatedAt)}\n </TableCell>\n <TableCell className=\"text-right\">\n <AddToPopover entry={entry} label={t('changes.addToLabel', { title })} />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n )}\n </QueryView>\n </Panel>\n );\n};\n","import { useNavigate } from '@tanstack/react-router';\nimport { Plus } from 'lucide-react';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { Button } from '@/components/ui/button';\nimport { CreateSheet } from './CreateSheet';\nimport { useDevelopPermissions } from './hooks/useDevelopPermissions';\nimport { OpenSets } from './OpenSets';\nimport { Scheduled } from './Scheduled';\nimport { Unassigned } from './Unassigned';\n\n/** Changes: open change sets (pull-request shaped), drafts not in a set yet, and scheduled publications. */\nexport const Changes = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { canManageChanges } = useDevelopPermissions();\n const [creating, setCreating] = useState(false);\n return (\n <Page>\n <PageHeader\n title={t('changes.title')}\n actions={\n canManageChanges ? (\n <Button onClick={() => setCreating(true)}>\n <Plus aria-hidden=\"true\" />\n {t('changes.create')}\n </Button>\n ) : undefined\n }\n />\n {canManageChanges ? (\n <>\n <OpenSets />\n <Unassigned />\n <Scheduled />\n <CreateSheet\n open={creating}\n onOpenChange={setCreating}\n onCreated={(set) => {\n setCreating(false);\n void navigate({ to: '/changes/$changeSetId', params: { changeSetId: set.id } });\n }}\n />\n </>\n ) : (\n <NoAccess />\n )}\n </Page>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport type { DeploymentConnection } from '@shapio/client';\nimport { Rocket } from 'lucide-react';\nimport { useId, useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FormError } from '@/components/FormError';\nimport { FormSelectField } from '@/components/FormSelectField';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { requiredText } from '@/helpers/validation';\nimport type { ShipFlow } from '../hooks/useShipFlow';\n\nconst deploySchema = z.object({ connectionId: requiredText() });\ntype DeployValues = z.infer<typeof deploySchema>;\n\ntype DeployPopoverProps = {\n flow: ShipFlow;\n connections: readonly DeploymentConnection[];\n /** The connection already chosen for this set, preselected. */\n currentConnectionId: string | null;\n disabled: boolean;\n};\n\n/**\n * \"Ship with deploy\": ship the set as one snapshot, then trigger the chosen connection's build pinned to\n * that snapshot (plan developer-face §5, option A).\n */\nexport const DeployPopover = ({ flow, connections, currentConnectionId, disabled }: DeployPopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const [open, setOpen] = useState(false);\n const [error, setError] = useState<unknown>(null);\n const defaults = useMemo<DeployValues>(\n () => ({ connectionId: currentConnectionId ?? connections[0]?.id ?? '' }),\n [currentConnectionId, connections],\n );\n const form = useForm<DeployValues>({ resolver: zodResolver(deploySchema), values: defaults });\n const onSubmit = form.handleSubmit(async ({ connectionId }) => {\n setError(null);\n try {\n await flow.shipNow(connectionId);\n setOpen(false);\n } catch (cause) {\n setError(cause);\n }\n });\n return (\n <Popover open={open} onOpenChange={(next) => (flow.shipping && !next ? undefined : setOpen(next))} modal>\n <PopoverTrigger asChild>\n <Button variant=\"outline\" disabled={disabled}>\n <Rocket aria-hidden=\"true\" />\n {t('changes.review.shipWithDeploy')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" aria-labelledby={titleId} className=\"w-80\">\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"space-y-4\">\n <p id={titleId} className=\"text-sm font-semibold\">\n {t('changes.review.shipWithDeployTitle')}\n </p>\n <FormSelectField\n control={form.control}\n name=\"connectionId\"\n label={t('changes.review.connection')}\n options={connections.map((connection) => ({ value: connection.id, label: connection.name }))}\n />\n <p className=\"text-meta text-muted-foreground\">{t('changes.review.shipWithDeployHint')}</p>\n <FormError error={error} />\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => setOpen(false)}>\n {t('common.cancel')}\n </Button>\n <SubmitButton size=\"sm\" pending={flow.shipping} pendingLabel={t('changes.review.shipping')}>\n {t('changes.review.shipWithDeploy')}\n </SubmitButton>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n};\n","import { zodResolver } from '@hookform/resolvers/zod';\nimport { CalendarClock } from 'lucide-react';\nimport { useId, useMemo, useState } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { z } from 'zod';\nimport { FormError } from '@/components/FormError';\nimport { FormTextField } from '@/components/FormTextField';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport {\n dateTimeLocalField,\n dateTimeLocalToIso,\n defaultScheduleValue,\n} from '@/features/Publishing/helpers/dateTimeLocal';\nimport { useResetOnOpen } from '@/features/Publishing/hooks/useResetOnOpen';\nimport { settle } from '@/helpers/settle';\nimport type { ShipFlow } from '../hooks/useShipFlow';\n\nconst scheduleSchema = z.object({ at: dateTimeLocalField() });\ntype ScheduleValues = z.infer<typeof scheduleSchema>;\n\ntype SchedulePopoverProps = { flow: ShipFlow; disabled: boolean };\n\n/** \"Schedule…\": when the set ships, picked in a popover beside the button. */\nexport const SchedulePopover = ({ flow, disabled }: SchedulePopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const [open, setOpen] = useState(false);\n const defaults = useMemo<ScheduleValues>(() => ({ at: open ? defaultScheduleValue() : '' }), [open]);\n const form = useForm<ScheduleValues>({ resolver: zodResolver(scheduleSchema), defaultValues: defaults });\n useResetOnOpen(open, form.reset, defaults, flow.resetSchedule);\n const onSubmit = form.handleSubmit(async ({ at }) => {\n const iso = dateTimeLocalToIso(at);\n if (iso && (await settle(flow.scheduleAt(iso))).ok) {\n setOpen(false);\n }\n });\n return (\n <Popover\n open={open}\n onOpenChange={(next) => (flow.scheduling && !next ? undefined : setOpen(next))}\n modal\n >\n <PopoverTrigger asChild>\n <Button variant=\"outline\" disabled={disabled}>\n <CalendarClock aria-hidden=\"true\" />\n {t('changes.review.schedule')}\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" aria-labelledby={titleId} className=\"w-80\">\n <form noValidate onSubmit={(event) => void onSubmit(event)} className=\"space-y-4\">\n <p id={titleId} className=\"text-sm font-semibold\">\n {t('changes.review.scheduleTitle')}\n </p>\n <FormTextField\n control={form.control}\n name=\"at\"\n type=\"datetime-local\"\n label={t('changes.review.scheduleAt')}\n description={t('publishing.fields.localTimeHint', {\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n })}\n />\n <FormError error={flow.scheduleError} />\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => setOpen(false)}>\n {t('common.cancel')}\n </Button>\n <SubmitButton size=\"sm\" pending={flow.scheduling} pendingLabel={t('common.saving')}>\n {t('changes.review.schedule')}\n </SubmitButton>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n};\n","import type { ChangeSet } from '@shapio/client';\nimport { useNavigate } from '@tanstack/react-router';\nimport { CalendarX, Loader2, Send, Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useDiscardChangeSet, useUnscheduleChangeSet } from '@/api/changeSets';\nimport { useDeploymentConnections } from '@/api/deployments';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\nimport { EDITABLE_STATUSES } from '../../Changes/constants';\nimport { useDevelopPermissions } from '../../Changes/hooks/useDevelopPermissions';\nimport { DeployPopover } from '../DeployPopover';\nimport type { ShipFlow } from '../hooks/useShipFlow';\nimport { SchedulePopover } from '../SchedulePopover';\n\ntype ActionsProps = { set: ChangeSet; flow: ShipFlow };\n\n/**\n * Discard, Schedule…, Ship with deploy and Ship (primary, last); each confirmed where it was asked for. The ship\n * actions need `changes.ship` (the server enforces it).\n */\nexport const Actions = ({ set, flow }: ActionsProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const discard = useDiscardChangeSet();\n const unschedule = useUnscheduleChangeSet();\n const connections = useDeploymentConnections();\n const { canShipChanges } = useDevelopPermissions();\n const enabledConnections = (connections.data ?? []).filter((connection) => connection.enabled);\n const editable = EDITABLE_STATUSES.has(set.status);\n const shipDisabled = !flow.canShip || !flow.acknowledged || flow.shipping;\n const itemCount = set.entryItemCount + set.schemaItemCount;\n if (set.status === 'shipped' || set.status === 'discarded' || set.status === 'shipping') {\n return null;\n }\n return (\n <>\n <InlineConfirm\n tone=\"danger\"\n title={t('changes.review.discardTitle', { title: set.title })}\n description={t('changes.review.discardDescription')}\n confirmLabel={t('changes.review.discard')}\n onConfirm={() =>\n discard.mutateAsync(set.id, {\n onSuccess: () => {\n toast.success(t('changes.review.discarded'));\n void navigate({ to: '/changes' });\n },\n })\n }\n trigger={\n <Button variant=\"destructive-ghost\" disabled={flow.shipping}>\n <Trash2 aria-hidden=\"true\" />\n {t('changes.review.discard')}\n </Button>\n }\n />\n {set.status === 'scheduled' ? (\n <Button\n variant=\"outline\"\n disabled={unschedule.isPending}\n onClick={() =>\n unschedule.mutate(set.id, { onSuccess: () => toast.success(t('changes.review.unscheduled')) })\n }\n >\n <CalendarX aria-hidden=\"true\" />\n {t('changes.review.unschedule')}\n </Button>\n ) : null}\n {editable && canShipChanges ? (\n <>\n <SchedulePopover flow={flow} disabled={shipDisabled} />\n {enabledConnections.length > 0 ? (\n <DeployPopover\n flow={flow}\n connections={enabledConnections}\n currentConnectionId={set.deploymentConnectionId}\n disabled={shipDisabled}\n />\n ) : null}\n <InlineConfirm\n tone=\"default\"\n title={t('changes.review.shipTitle', { title: set.title })}\n description={t('changes.review.shipDescription', { count: itemCount })}\n confirmLabel={t('changes.review.ship')}\n pendingLabel={t('changes.review.shipping')}\n onConfirm={() => flow.shipNow()}\n trigger={\n <Button disabled={shipDisabled} aria-busy={flow.shipping || undefined}>\n {flow.shipping ? (\n <Loader2 aria-hidden=\"true\" className=\"animate-spin motion-reduce:animate-none\" />\n ) : (\n <Send aria-hidden=\"true\" />\n )}\n {flow.shipping ? t('changes.review.shipping') : t('changes.review.ship')}\n </Button>\n }\n />\n </>\n ) : null}\n </>\n );\n};\n","import type { ChangeSet } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { AlertTriangle, CheckCircle2, Info, RefreshCw } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { formatRelativeTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../Changes/hooks/useActorLabel';\nimport type { ShipFlow } from '../hooks/useShipFlow';\n\nconst NOTICE_KEYS = {\n NEW_FIELDS_AFTER_SHIP: 'changes.review.notices.newFieldsAfterShip',\n} as const;\n\nconst isKnownNotice = (notice: string): notice is keyof typeof NOTICE_KEYS => notice in NOTICE_KEYS;\n\nconst LINK_CLASSES = 'font-semibold text-link underline-offset-4 hover:underline';\n\ntype BannersProps = {\n set: ChangeSet;\n flow: ShipFlow;\n notices: readonly string[];\n /** Point at the Checks tab when an acknowledgement is still missing (hidden on that tab). */\n showAcknowledgementHint: boolean;\n};\n\n/** In-place notices above the tabs: shipped (→ snapshot), failed, changed since you looked, and the rest. */\nexport const Banners = ({ set, flow, notices, showAcknowledgementHint }: BannersProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n return (\n <>\n {set.status === 'shipped' && set.shippedSnapshot !== null ? (\n <Alert variant=\"success\" role=\"status\">\n <CheckCircle2 aria-hidden=\"true\" />\n <AlertDescription>\n <p>\n {t('changes.review.shippedAs')}{' '}\n <Link\n to=\"/snapshots/$seq\"\n params={{ seq: String(set.shippedSnapshot) }}\n className={LINK_CLASSES}\n >\n {t('snapshots.version', { seq: set.shippedSnapshot })}\n </Link>{' '}\n {t('changes.review.shippedByAt', {\n name: actorLabel(set.shippedBy),\n at: set.shippedAt ? formatRelativeTime(set.shippedAt) : '',\n })}\n </p>\n </AlertDescription>\n </Alert>\n ) : null}\n {set.status === 'failed' && set.error && !flow.stale ? (\n <Alert variant=\"destructive\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertTitle>{t('changes.review.failedTitle')}</AlertTitle>\n <AlertDescription>{set.error.message}</AlertDescription>\n </Alert>\n ) : null}\n {flow.stale ? (\n <Alert variant=\"warning\" className=\"flex flex-wrap items-center justify-between gap-3\">\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('changes.review.staleTitle')}</AlertTitle>\n <AlertDescription>{t('changes.review.staleDescription')}</AlertDescription>\n </div>\n </div>\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => void flow.refresh()}>\n {t('changes.review.refresh')}\n </Button>\n </Alert>\n ) : null}\n {showAcknowledgementHint && (flow.needsBreaking || flow.needsDestructive) && !flow.acknowledged ? (\n <Alert variant=\"warning\" role=\"status\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertDescription>\n <p>\n {t('changes.review.acknowledgeInChecks')}{' '}\n <Link\n to=\"/changes/$changeSetId\"\n params={{ changeSetId: set.id }}\n search={{ tab: 'checks' }}\n className={LINK_CLASSES}\n >\n {t('changes.tabs.checks')}\n </Link>\n </p>\n </AlertDescription>\n </Alert>\n ) : null}\n {notices.filter(isKnownNotice).map((notice) => (\n <Alert key={notice} variant=\"info\" role=\"status\">\n <Info aria-hidden=\"true\" />\n <AlertDescription>{t(NOTICE_KEYS[notice])}</AlertDescription>\n </Alert>\n ))}\n </>\n );\n};\n","const MAX_LENGTH = 240;\n\n/**\n * A stored field value as one line of text for a before/after row: strings as they are, scalars as text,\n * anything structured (rich text, components, relations) as compact JSON, cut at 240 characters.\n * `undefined`/`null` read as empty (the caller shows its \"empty\" placeholder).\n */\nexport const valueText = (value: unknown): string => {\n if (value === null || value === undefined) {\n return '';\n }\n const text =\n typeof value === 'string'\n ? value\n : typeof value === 'number' || typeof value === 'boolean'\n ? String(value)\n : JSON.stringify(value);\n return text.length > MAX_LENGTH ? `${text.slice(0, MAX_LENGTH - 1)}…` : text;\n};\n","import type { DataType } from '@shapio/schema';\nimport { ChevronRight } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { buttonVariants } from '@/components/ui/button';\nimport { TableCell } from '@/components/ui/table';\nimport { cn } from '@/helpers/cn';\nimport { valueText } from '../../helpers/valueText';\n\n/** Types whose stored value reads badly as text: the server's summary is shown, the JSON one click away. */\nconst STRUCTURED_TYPES: ReadonlySet<DataType> = new Set<DataType>([\n 'richtext',\n 'media',\n 'relation',\n 'component',\n 'dynamiczone',\n 'json',\n 'code',\n]);\n\ntype ValueCellProps = {\n value: unknown;\n /** The server's readable form of `value` (null when empty); used for structured types only. */\n summary: string | null;\n type: DataType;\n side: 'before' | 'after';\n};\n\n/**\n * One side of a before/after row: struck through for the old value, \"empty\" when there is none. Structured\n * values show their summary with a \"Raw\" disclosure holding the stored JSON; scalars show the value as is.\n */\nexport const ValueCell = ({ value, summary, type, side }: ValueCellProps) => {\n const { t } = useTranslation();\n const raw = valueText(value);\n const structuredSummary = STRUCTURED_TYPES.has(type) ? summary : null;\n const text = structuredSummary || raw;\n return (\n <TableCell className=\"max-w-80 align-top whitespace-normal\">\n {text ? (\n <span\n className={cn(side === 'before' && 'text-muted-foreground line-through decoration-destructive/60')}\n >\n {text}\n </span>\n ) : (\n <span className=\"text-meta text-muted-foreground italic\">{t('changes.review.empty')}</span>\n )}\n {structuredSummary && raw ? (\n <details className=\"group mt-1\">\n <summary\n className={cn(\n buttonVariants({ variant: 'ghost', size: 'xs' }),\n '-ml-1.5 w-fit cursor-pointer list-none text-muted-foreground [&::-webkit-details-marker]:hidden',\n )}\n >\n <ChevronRight\n aria-hidden=\"true\"\n className=\"transition-transform group-open:rotate-90 motion-reduce:transition-none\"\n />\n {t('changes.review.raw')}\n </summary>\n <pre className=\"mt-1 font-mono text-meta break-all whitespace-pre-wrap text-muted-foreground\">\n {raw}\n </pre>\n </details>\n ) : null}\n </TableCell>\n );\n};\n","import type { ReviewEntryItem } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { Trash2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Panel } from '@/components/Panel';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { PUBLICATION_ACTION_LABELS } from '@/features/Publishing/constants';\nimport { ValueCell } from './ValueCell';\n\nconst LIVE_STATE_DISPLAY = {\n unpublished: { labelKey: 'changes.review.liveStates.unpublished', tone: 'neutral' },\n published: { labelKey: 'changes.review.liveStates.published', tone: 'success' },\n modified: { labelKey: 'changes.review.liveStates.modified', tone: 'warning' },\n missing: { labelKey: 'changes.review.liveStates.missing', tone: 'danger' },\n} as const;\n\n/** Today's live value against what ships, what a shipped set changed, or nothing (not recorded). */\nexport type EntryDiff = 'live' | 'shipped' | 'none';\n\nconst COLUMN_KEYS = {\n live: { before: 'changes.review.before', after: 'changes.review.after' },\n shipped: { before: 'changes.review.beforeShip', after: 'changes.review.shippedValue' },\n} as const;\n\ntype EntryDiffCardProps = {\n item: ReviewEntryItem;\n diff: EntryDiff;\n /** Removes the item after an inline confirmation; undefined when the set can't change. */\n onRemove: (() => Promise<unknown>) | undefined;\n};\n\n/**\n * An entry item as field-level before (live) and after (what ships) rows, for one locale; for a shipped set,\n * what it was before the ship and what shipped (no live-state chip: the action badge says what happened).\n */\nexport const EntryDiffCard = ({ item, diff, onRemove }: EntryDiffCardProps) => {\n const { t } = useTranslation();\n const title = item.title ?? item.entryId;\n const live = LIVE_STATE_DISPLAY[item.liveState];\n return (\n <Panel\n title={title}\n titleAs=\"h3\"\n flush\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\" className=\"font-mono\">\n {item.locale}\n </Badge>\n <Badge variant=\"secondary\">{t(PUBLICATION_ACTION_LABELS[item.action])}</Badge>\n {diff === 'live' ? <StatusChip tone={live.tone} label={t(live.labelKey)} size=\"sm\" /> : null}\n {item.modelKey ? (\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link\n to=\"/content/$modelKey/$entryId\"\n params={{ modelKey: item.modelKey, entryId: item.entryId }}\n search={{ locale: item.locale }}\n >\n {t('changes.review.openEntry')}\n </Link>\n </Button>\n ) : null}\n {onRemove ? (\n <InlineConfirm\n tone=\"danger\"\n title={t('changes.review.removeItemTitle', { title })}\n description={t('changes.review.removeItemDescription')}\n confirmLabel={t('common.remove')}\n onConfirm={onRemove}\n trigger={\n <Button\n variant=\"destructive-ghost\"\n size=\"icon-sm\"\n aria-label={t('changes.review.removeItem', { title })}\n >\n <Trash2 aria-hidden=\"true\" />\n </Button>\n }\n />\n ) : null}\n </div>\n }\n >\n {diff === 'none' ? null : item.fields.length === 0 ? (\n <p className=\"px-5 py-4 text-meta text-muted-foreground\">{t('changes.review.noFieldChanges')}</p>\n ) : (\n <Table aria-label={t('changes.review.fieldChangesOf', { title })}>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.review.field')}</TableHead>\n <TableHead>{t(COLUMN_KEYS[diff].before)}</TableHead>\n <TableHead>{t(COLUMN_KEYS[diff].after)}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {item.fields.map((field) => (\n <TableRow key={field.fieldId}>\n <TableCell className=\"align-top\">\n <span className=\"block font-semibold\">{field.label}</span>\n <span className=\"block font-mono text-meta text-muted-foreground\">{field.apiKey}</span>\n </TableCell>\n <ValueCell\n value={field.before}\n summary={field.summary.before}\n type={field.type}\n side=\"before\"\n />\n <ValueCell value={field.after} summary={field.summary.after} type={field.type} side=\"after\" />\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n {item.issues.length > 0 ? (\n <ul className=\"space-y-1 border-t px-5 py-3 text-sm text-destructive\">\n {item.issues.map((issue) => (\n <li key={`${issue.path}-${issue.code}`}>{issue.message}</li>\n ))}\n </ul>\n ) : null}\n </Panel>\n );\n};\n","import type { ChangeKind, ClassifiedChange } from '@shapio/schema';\nimport type { StatusTone } from '@/components/StatusChip';\n\n/**\n * How a schema change reads in a change set review: additive (live, nothing breaks), validation (existing\n * content is checked first), conversion (stored values are rewritten), breaking (the API contract changes or\n * data is lost; needs acknowledgement), metadata (labels, help text, editors).\n */\nexport const CHANGE_CLASSES = ['breaking', 'conversion', 'validation', 'additive', 'metadata'] as const;\nexport type ChangeClass = (typeof CHANGE_CLASSES)[number];\n\nconst VALIDATION_CATEGORIES: ReadonlySet<string> = new Set([\n 'requiredField',\n 'validation',\n 'constraint',\n 'index',\n]);\nconst METADATA_CATEGORIES: ReadonlySet<string> = new Set(['metadata', 'editorSwap']);\n\nexport const classOfChange = (change: ClassifiedChange): ChangeClass => {\n if (change.breaking || change.destructive) {\n return 'breaking';\n }\n if (change.category === 'conversion') {\n return 'conversion';\n }\n if (VALIDATION_CATEGORIES.has(change.category)) {\n return 'validation';\n }\n return METADATA_CATEGORIES.has(change.category) ? 'metadata' : 'additive';\n};\n\nexport const CHANGE_CLASS_DISPLAY = {\n breaking: { labelKey: 'changes.classes.breaking', tone: 'warning' },\n conversion: { labelKey: 'changes.classes.conversion', tone: 'warning' },\n validation: { labelKey: 'changes.classes.validation', tone: 'neutral' },\n additive: { labelKey: 'changes.classes.additive', tone: 'success' },\n metadata: { labelKey: 'changes.classes.metadata', tone: 'muted' },\n} as const satisfies Record<ChangeClass, { labelKey: string; tone: StatusTone }>;\n\nconst ADDED: ReadonlySet<ChangeKind> = new Set(['definition.added', 'field.added']);\nconst REMOVED: ReadonlySet<ChangeKind> = new Set(['definition.removed', 'field.removed']);\n\n/** The diff gutter: `+` for something added, `−` for something removed, `~` for a change in place. */\nexport const signOfChange = (change: Pick<ClassifiedChange, 'kind'>): '+' | '−' | '~' => {\n if (ADDED.has(change.kind)) {\n return '+';\n }\n return REMOVED.has(change.kind) ? '−' : '~';\n};\n","import { useTranslation } from 'react-i18next';\nimport { StatusChip } from '@/components/StatusChip';\nimport { CHANGE_CLASS_DISPLAY, type ChangeClass } from '../helpers/classification';\n\ntype ClassificationChipProps = { changeClass: ChangeClass; size?: 'default' | 'sm' };\n\n/** Additive, validation, conversion, breaking or metadata: what a schema change does to existing content. */\nexport const ClassificationChip = ({ changeClass, size }: ClassificationChipProps) => {\n const { t } = useTranslation();\n const display = CHANGE_CLASS_DISPLAY[changeClass];\n return <StatusChip tone={display.tone} label={t(display.labelKey)} size={size} />;\n};\n","import type { ReviewSchemaItem } from '@shapio/client';\nimport { useQuery } from '@tanstack/react-query';\nimport { useSchemaDraft } from '@/api/changeSets';\nimport { definitionQueryOptions, definitionRevisionQueryOptions } from '@/api/schema';\n\n/**\n * The definition before (active now; for a shipped set, the revision its draft replaced) and after (the\n * set's draft) a schema item, for naming fields in its diff. Either is null while loading or when it doesn't\n * exist (a new or deleted definition). `shared`: the definition is shared with all sites (the active one's\n * scope, else what the draft of a new one asks for), so shipping it affects every site; false until known.\n */\nexport const useSchemaItemDefinitions = (changeSetId: string, item: ReviewSchemaItem) => {\n const draft = useSchemaDraft(changeSetId, item.definitionId);\n const active = useQuery({\n ...definitionQueryOptions(item.category, item.definitionId),\n enabled: item.operation !== 'create',\n retry: false,\n });\n const shipped = useQuery({\n ...definitionRevisionQueryOptions(item.category, item.definitionId, item.beforeRevisionId ?? ''),\n enabled: item.beforeRevisionId !== null,\n retry: false,\n });\n const before = item.beforeRevisionId === null ? active.data?.definition : shipped.data?.definition;\n return {\n before: before ?? null,\n after: draft.data?.definition ?? null,\n shared: active.data ? active.data.scope === 'network' : (draft.data?.shared ?? false),\n };\n};\n","import type { ReviewSchemaItem } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { AlertTriangle, Globe2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport { Badge } from '@/components/ui/badge';\nimport { describeChange } from '@/features/Models/helpers/describeChange';\nimport { cn } from '@/helpers/cn';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { ClassificationChip } from '../ClassificationChip';\nimport { classOfChange, signOfChange } from '../helpers/classification';\nimport { useSchemaItemDefinitions } from '../hooks/useSchemaItemDefinitions';\n\nconst SIGN_CLASSES = {\n '+': 'text-success',\n '−': 'text-destructive',\n '~': 'text-muted-foreground',\n} as const;\n\nconst OPERATION_KEYS = {\n create: 'changes.review.operations.create',\n update: 'changes.review.operations.update',\n delete: 'changes.review.operations.delete',\n} as const;\n\ntype SchemaDiffCardProps = { changeSetId: string; item: ReviewSchemaItem };\n\n/**\n * A schema item as a diff: one `+`/`−`/`~` line per planned change, each with its classification, and a\n * quiet badge when the definition is shared (shipping it affects every site).\n */\nexport const SchemaDiffCard = ({ changeSetId, item }: SchemaDiffCardProps) => {\n const { t } = useTranslation();\n const { before, after, shared } = useSchemaItemDefinitions(changeSetId, item);\n const { multiSite } = useSchemaScopeAccess();\n const changes = item.plan?.changes ?? [];\n const title = after?.label ?? before?.label ?? item.apiKey;\n return (\n <Panel\n title={title}\n titleAs=\"h3\"\n flush\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{t(OPERATION_KEYS[item.operation])}</Badge>\n {multiSite && shared ? (\n <Badge variant=\"outline\" data-shared>\n <Globe2 aria-hidden=\"true\" />\n {t('changes.review.shared')}\n </Badge>\n ) : null}\n <span className=\"font-mono text-meta text-muted-foreground\">{item.apiKey}</span>\n </div>\n }\n >\n {item.stale ? (\n <div className=\"border-b p-4\">\n <Alert variant=\"warning\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertDescription>\n {t('changes.review.schemaStale', {\n base: item.baseVersion ?? 0,\n active: item.activeVersion ?? 0,\n })}\n </AlertDescription>\n </Alert>\n </div>\n ) : null}\n {item.alsoChangedIn.length > 0 ? (\n <p className=\"border-b px-5 py-2.5 text-meta text-muted-foreground\">\n {t('changes.review.alsoChangedIn')}{' '}\n {item.alsoChangedIn.map((other, index) => (\n <span key={other.id}>\n {index > 0 ? ', ' : ''}\n <Link\n to=\"/changes/$changeSetId\"\n params={{ changeSetId: other.id }}\n className=\"text-link underline-offset-4 hover:underline\"\n >\n {other.title}\n </Link>\n </span>\n ))}\n </p>\n ) : null}\n {changes.length === 0 ? (\n <p className=\"px-5 py-4 text-meta text-muted-foreground\">{t('changes.review.noSchemaChanges')}</p>\n ) : (\n <ul aria-label={t('changes.review.schemaChangesOf', { name: title })} className=\"divide-y text-sm\">\n {changes.map((change, index) => {\n const sign = signOfChange(change);\n return (\n <li\n key={`${change.kind}-${change.fieldId ?? ''}-${change.property ?? ''}-${index}`}\n className=\"flex flex-wrap items-center gap-x-3 gap-y-1 px-5 py-2.5\"\n >\n <span\n aria-hidden=\"true\"\n className={cn('w-3 shrink-0 font-mono font-semibold', SIGN_CLASSES[sign])}\n >\n {sign}\n </span>\n <span className=\"min-w-0 flex-1\">{describeChange(change, before, after)}</span>\n <ClassificationChip changeClass={classOfChange(change)} size=\"sm\" />\n </li>\n );\n })}\n </ul>\n )}\n </Panel>\n );\n};\n","import type { ChangeSetReview } from '@shapio/client';\nimport { Package } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useRemoveChangeSetItem } from '@/api/changeSets';\nimport { EmptyState } from '@/components/EmptyState';\nimport { EntryDiffCard } from '../EntryDiffCard';\nimport { SchemaDiffCard } from '../SchemaDiffCard';\n\ntype ChangesTabProps = { review: ChangeSetReview; editable: boolean };\n\n/**\n * Every item as a diff card: schema first (it decides what the entries may hold), then entries. A shipped\n * set shows what it shipped; one shipped as a release before change sets kept their diff shows none.\n */\nexport const ChangesTab = ({ review, editable }: ChangesTabProps) => {\n const { t } = useTranslation();\n const removeItem = useRemoveChangeSetItem();\n const setId = review.changeSet.id;\n const shipped = review.changeSet.status === 'shipped';\n const diff = !shipped ? 'live' : review.changeSet.shippedSnapshot === null ? 'none' : 'shipped';\n if (review.schema.length === 0 && review.entries.length === 0) {\n return (\n <EmptyState\n icon={Package}\n title={t('changes.review.noItems')}\n description={t('changes.review.noItemsDescription')}\n />\n );\n }\n return (\n <div className=\"space-y-4\">\n {diff === 'none' ? (\n <p className=\"text-meta text-muted-foreground\">{t('changes.review.notRecorded')}</p>\n ) : null}\n {review.schema.map((item) => (\n <SchemaDiffCard key={item.itemId} changeSetId={setId} item={item} />\n ))}\n {review.entries.map((item) => (\n <EntryDiffCard\n key={item.itemId}\n item={item}\n diff={diff}\n onRemove={\n editable\n ? () =>\n removeItem.mutateAsync(\n { id: setId, itemId: item.itemId },\n { onSuccess: () => toast.success(t('changes.review.itemRemoved')) },\n )\n : undefined\n }\n />\n ))}\n </div>\n );\n};\n","import type { CheckSeverity } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip, type StatusTone } from '@/components/StatusChip';\n\nconst SEVERITY_DISPLAY = {\n error: { labelKey: 'develop.health.error', tone: 'danger' },\n warning: { labelKey: 'develop.health.warning', tone: 'warning' },\n} as const satisfies Record<CheckSeverity, { labelKey: string; tone: StatusTone }>;\n\ntype HealthChipProps = { severity: CheckSeverity };\n\n/** A content-health finding's severity. */\nexport const HealthChip = ({ severity }: HealthChipProps) => {\n const { t } = useTranslation();\n const display = SEVERITY_DISPLAY[severity];\n return <StatusChip tone={display.tone} label={t(display.labelKey)} size=\"sm\" />;\n};\n","import type { ReviewEntryItem } from '@shapio/client';\nimport { useQueries } from '@tanstack/react-query';\nimport { adminApi } from '@/api/client';\nimport { queryKeys } from '@/api/queryKeys';\n\n/** Findings read per model: enough for a change set's entries (the endpoint has no entry filter). */\nconst FINDINGS_PER_MODEL = 200;\n\n/** Open content-health findings on the set's entries, read per model and filtered to those entries. */\nexport const useSetHealthFindings = (entries: readonly ReviewEntryItem[]) => {\n const modelKeys = [...new Set(entries.flatMap((entry) => (entry.modelKey ? [entry.modelKey] : [])))];\n const entryIds = new Set(entries.map((entry) => entry.entryId));\n return useQueries({\n queries: modelKeys.map((modelKey) => {\n const query = { modelKey, limit: FINDINGS_PER_MODEL };\n return {\n queryKey: queryKeys.develop.setHealthFindings(query),\n queryFn: () => adminApi.contentHealth.list(query),\n meta: { silent: true },\n };\n }),\n combine: (results) => ({\n findings: results.flatMap((result) =>\n (result.data?.items ?? []).filter((finding) => entryIds.has(finding.entryId)),\n ),\n isPending: results.some((result) => result.isPending),\n error: results.find((result) => result.error)?.error ?? null,\n }),\n });\n};\n","import type { ReviewIssue } from '@shapio/client';\n\ntype IssueListProps = { issues: readonly ReviewIssue[] };\n\n/** Review issues as a bulleted list of their messages. */\nexport const IssueList = ({ issues }: IssueListProps) => (\n <ul className=\"list-disc space-y-1 pl-4\">\n {issues.map((issue) => (\n <li key={`${issue.path}-${issue.code}`}>{issue.message}</li>\n ))}\n </ul>\n);\n","import type { ReviewSchemaItem } from '@shapio/client';\nimport { AlertTriangle, CheckCircle2 } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { InfoHint } from '@/components/InfoHint';\nimport { Panel } from '@/components/Panel';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport { StepList } from '@/features/Models/Builder/ReviewSheet/StepList';\nimport { useSchemaItemDefinitions } from '../../hooks/useSchemaItemDefinitions';\nimport { IssueList } from '../../IssueList';\n\ntype PlannerPanelProps = { changeSetId: string; item: ReviewSchemaItem };\n\n/** One schema item's planner result: entries affected, prerequisite checks and conversions, follow-ups. */\nexport const PlannerPanel = ({ changeSetId, item }: PlannerPanelProps) => {\n const { t } = useTranslation();\n const { before, after } = useSchemaItemDefinitions(changeSetId, item);\n const plan = item.plan;\n return (\n <Panel\n title={t('changes.review.plannerTitle', { name: after?.label ?? before?.label ?? item.apiKey })}\n titleAs=\"h3\"\n // A shipped set's impact counts are not rebuilt (they would be today's, not those it shipped with).\n description={\n item.impact ? t('changes.review.affected', { count: item.impact.affectedHeads }) : undefined\n }\n >\n <div className=\"space-y-4\">\n {item.issues.length > 0 ? (\n <Alert variant=\"destructive\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertDescription>\n <IssueList issues={item.issues} />\n </AlertDescription>\n </Alert>\n ) : null}\n {plan && plan.prerequisites.length > 0 ? (\n <section className=\"space-y-3\" aria-label={t('models.plan.prerequisites')}>\n <div className=\"flex items-center gap-1\">\n <h4 className=\"text-sm font-semibold\">{t('models.plan.prerequisites')}</h4>\n <InfoHint about={t('models.plan.prerequisites')}>{t('models.plan.prerequisitesHint')}</InfoHint>\n </div>\n <StepList\n phase=\"before\"\n steps={plan.prerequisites}\n impacts={item.impact?.steps}\n before={before}\n after={after}\n />\n </section>\n ) : (\n <p className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <CheckCircle2 aria-hidden=\"true\" className=\"size-4 text-success\" />\n {t('changes.review.noPrerequisites')}\n </p>\n )}\n {plan && plan.followUps.length > 0 ? (\n <section className=\"space-y-3\" aria-label={t('models.plan.followUps')}>\n <h4 className=\"text-sm font-semibold\">{t('models.plan.followUps')}</h4>\n <StepList phase=\"after\" steps={plan.followUps} before={before} after={after} />\n </section>\n ) : null}\n </div>\n </Panel>\n );\n};\n","import type { ChangeSetReview } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { AlertTriangle, CheckCircle2, Info } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Checkbox } from '@/components/ui/checkbox';\nimport { Field, FieldLabel } from '@/components/ui/field';\nimport { RULE_TITLE_KEYS } from '@/features/Inbox/constants';\nimport { EDITABLE_STATUSES } from '../../Changes/constants';\nimport { HealthChip } from '../../Changes/HealthChip';\nimport { useSetHealthFindings } from '../hooks/useSetHealthFindings';\nimport type { ShipFlow } from '../hooks/useShipFlow';\nimport { IssueList } from '../IssueList';\nimport { PlannerPanel } from './PlannerPanel';\n\nconst NOT_RESTORABLE_KEYS = {\n entry_deleted: 'changes.review.notRestorable.entry_deleted',\n model_missing: 'changes.review.notRestorable.model_missing',\n publishing_disabled: 'changes.review.notRestorable.publishing_disabled',\n localization_changed: 'changes.review.notRestorable.localization_changed',\n locale_missing: 'changes.review.notRestorable.locale_missing',\n invalid: 'changes.review.notRestorable.invalid',\n unique_conflict: 'changes.review.notRestorable.unique_conflict',\n} as const;\n\ntype ChecksTabProps = { review: ChangeSetReview; flow: ShipFlow };\n\n/**\n * What must hold before the set ships: blocking problems, the planner's results per schema item, entries\n * that fail validation, entries a restore can't bring back, content-health findings, and the\n * acknowledgement breaking or destructive changes need. A shipped set passed them when it shipped, and says\n * so; the acknowledgement is asked only while the set can still ship.\n */\nexport const ChecksTab = ({ review, flow }: ChecksTabProps) => {\n const { t } = useTranslation();\n const { findings } = useSetHealthFindings(review.entries);\n const invalidEntries = review.entries.filter((entry) => entry.issues.length > 0);\n const editable = EDITABLE_STATUSES.has(review.changeSet.status);\n return (\n <div className=\"space-y-4\">\n {review.changeSet.status === 'shipped' ? (\n <Alert variant=\"success\" role=\"status\">\n <CheckCircle2 aria-hidden=\"true\" />\n <AlertDescription>{t('changes.review.checksPassedAtShip')}</AlertDescription>\n </Alert>\n ) : null}\n {review.checks.blocking.length > 0 ? (\n <Alert variant=\"destructive\">\n <AlertTriangle aria-hidden=\"true\" />\n <AlertTitle>{t('changes.review.blockingTitle')}</AlertTitle>\n <AlertDescription>\n <IssueList issues={review.checks.blocking} />\n </AlertDescription>\n </Alert>\n ) : null}\n {review.checks.warnings.length > 0 ? (\n <Alert variant=\"warning\">\n <Info aria-hidden=\"true\" />\n <AlertTitle>{t('changes.review.warningsTitle')}</AlertTitle>\n <AlertDescription>\n <IssueList issues={review.checks.warnings} />\n </AlertDescription>\n </Alert>\n ) : null}\n {review.schema.map((item) => (\n <PlannerPanel key={item.itemId} changeSetId={review.changeSet.id} item={item} />\n ))}\n <Panel title={t('changes.review.validationTitle')} titleAs=\"h3\">\n {invalidEntries.length === 0 ? (\n <p className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <CheckCircle2 aria-hidden=\"true\" className=\"size-4 text-success\" />\n {t('changes.review.allEntriesValid', { count: review.entries.length })}\n </p>\n ) : (\n <ul className=\"space-y-3\">\n {invalidEntries.map((entry) => (\n <li key={entry.itemId} className=\"space-y-1 text-sm\">\n {entry.modelKey ? (\n <Link\n to=\"/content/$modelKey/$entryId\"\n params={{ modelKey: entry.modelKey, entryId: entry.entryId }}\n search={{ locale: entry.locale }}\n className=\"font-semibold text-link underline-offset-4 hover:underline\"\n >\n {entry.title ?? entry.entryId}\n </Link>\n ) : (\n <span className=\"font-semibold\">{entry.title ?? entry.entryId}</span>\n )}\n <div className=\"text-destructive\">\n <IssueList issues={entry.issues} />\n </div>\n </li>\n ))}\n </ul>\n )}\n </Panel>\n {review.notRestorable.length > 0 ? (\n <Panel title={t('changes.review.notRestorableTitle')} titleAs=\"h3\">\n <ul className=\"space-y-2 text-sm\">\n {review.notRestorable.map((entry) => (\n <li key={`${entry.entryId}:${entry.locale}`}>\n <span className=\"font-mono text-xs\">\n {entry.modelKey ?? t('common.unknown')} · {entry.entryId} · {entry.locale}\n </span>\n <span className=\"block text-muted-foreground\">\n {t(NOT_RESTORABLE_KEYS[entry.reason])}\n {entry.detail ? ` (${entry.detail})` : ''}\n </span>\n </li>\n ))}\n </ul>\n </Panel>\n ) : null}\n <Panel title={t('changes.review.healthTitle')} titleAs=\"h3\">\n {findings.length === 0 ? (\n <p className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <CheckCircle2 aria-hidden=\"true\" className=\"size-4 text-success\" />\n {t('changes.review.noHealthFindings')}\n </p>\n ) : (\n <ul className=\"space-y-2 text-sm\">\n {findings.map((finding) => (\n <li key={finding.id} className=\"flex flex-wrap items-center gap-2\">\n <HealthChip severity={finding.severity} />\n <span className=\"font-semibold\">{finding.entryTitle ?? finding.entryId}</span>\n <span className=\"text-muted-foreground\">{t(RULE_TITLE_KEYS[finding.rule])}</span>\n {finding.locale === '*' ? null : (\n <span className=\"font-mono text-xs text-muted-foreground\">{finding.locale}</span>\n )}\n </li>\n ))}\n </ul>\n )}\n </Panel>\n {editable && (flow.needsBreaking || flow.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\">{t('models.plan.acknowledge')}</legend>\n {flow.needsBreaking ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"change-set-ack-breaking\"\n checked={flow.acknowledgedBreaking}\n onCheckedChange={(checked) => flow.setAcknowledgedBreaking(checked === true)}\n />\n <FieldLabel htmlFor=\"change-set-ack-breaking\" className=\"font-normal\">\n {t('models.plan.acknowledgeBreaking')}\n </FieldLabel>\n </Field>\n ) : null}\n {flow.needsDestructive ? (\n <Field orientation=\"horizontal\">\n <Checkbox\n id=\"change-set-ack-destructive\"\n checked={flow.acknowledgedDestructive}\n onCheckedChange={(checked) => flow.setAcknowledgedDestructive(checked === true)}\n />\n <FieldLabel htmlFor=\"change-set-ack-destructive\" className=\"font-normal\">\n {t('models.plan.acknowledgeDestructive')}\n </FieldLabel>\n </Field>\n ) : null}\n </fieldset>\n ) : null}\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\n\n/** A delivery reader's name: the token's name, \"App users\", \"Anonymous\", or the raw key as a last resort. */\nexport const usePrincipalLabel = () => {\n const { t } = useTranslation();\n return (principalKey: string, name: string | null | undefined): string => {\n if (name) {\n return name;\n }\n if (principalKey === 'app_users') {\n return t('develop.principals.appUsers');\n }\n if (principalKey === 'anonymous') {\n return t('develop.principals.anonymous');\n }\n return principalKey.startsWith('token:') ? t('develop.principals.deletedToken') : principalKey;\n };\n};\n","import type { ChangeSetReview } from '@shapio/client';\nimport { Users } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { Badge } from '@/components/ui/badge';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useSchemaScopeAccess } from '@/hooks/useSchemaScopeAccess';\nimport { usePrincipalLabel } from '../../Changes/hooks/usePrincipalLabel';\n\ntype ConsumersTabProps = { review: ChangeSetReview };\n\n/**\n * Who read the fields this set's breaking changes affect, from real delivery traffic: each reader with\n * the site it read on (where there is more than one), and readers on sites the admin can't see as totals.\n */\nexport const ConsumersTab = ({ review }: ConsumersTabProps) => {\n const { t } = useTranslation();\n const principalLabel = usePrincipalLabel();\n const { multiSite } = useSchemaScopeAccess();\n const fields = review.consumers.filter(\n (field) => field.consumers.length > 0 || (field.otherSites?.consumers ?? 0) > 0,\n );\n if (fields.length === 0) {\n return (\n <EmptyState\n icon={Users}\n title={review.checks.breaking ? t('changes.consumers.none') : t('changes.consumers.notBreaking')}\n description={t('changes.consumers.window', { count: review.usageDays })}\n />\n );\n }\n return (\n <div className=\"space-y-4\">\n <p className=\"text-meta text-muted-foreground\">\n {t('changes.consumers.window', { count: review.usageDays })}\n </p>\n {fields.map((field) => (\n <Panel\n key={`${field.modelId}:${field.fieldId}`}\n title={field.apiKey}\n titleAs=\"h3\"\n flush\n description={t('changes.consumers.readers', { count: field.consumers.length })}\n >\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.consumers.reader')}</TableHead>\n {multiSite ? <TableHead>{t('changes.consumers.site')}</TableHead> : null}\n <TableHead className=\"text-right\">{t('changes.consumers.reads')}</TableHead>\n <TableHead>{t('changes.consumers.lastRead')}</TableHead>\n <TableHead>{t('changes.consumers.selection')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {field.consumers.map((consumer) => (\n <TableRow key={`${consumer.site.id}:${consumer.principalKey}`}>\n <TableCell className=\"font-semibold\">\n {principalLabel(consumer.principalKey, consumer.label)}\n </TableCell>\n {multiSite ? (\n <TableCell className=\"font-mono text-meta text-muted-foreground\">\n {consumer.site.key}\n </TableCell>\n ) : null}\n <TableCell className=\"text-right tabular-nums\">{consumer.reads.toLocaleString()}</TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(consumer.lastReadAt)}>\n {consumer.lastReadAt ? formatRelativeTime(consumer.lastReadAt) : t('common.never')}\n </TableCell>\n <TableCell>\n <Badge variant={consumer.selection === 'explicit' ? 'secondary' : 'outline'}>\n {consumer.selection === 'explicit'\n ? t('changes.consumers.explicit')\n : t('changes.consumers.implicit')}\n </Badge>\n </TableCell>\n </TableRow>\n ))}\n {field.otherSites && field.otherSites.consumers > 0 ? (\n <TableRow data-other-sites>\n <TableCell colSpan={multiSite ? 5 : 4} className=\"text-muted-foreground\">\n {t('changes.consumers.otherSites', {\n count: field.otherSites.consumers,\n reads: field.otherSites.reads.toLocaleString(),\n })}\n </TableCell>\n </TableRow>\n ) : null}\n </TableBody>\n </Table>\n </Panel>\n ))}\n </div>\n );\n};\n","import type { ChangeSet, ChangeSetReview } from '@shapio/client';\nimport type { UseQueryResult } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useScheduleChangeSet, useShipChangeSet, useUpdateChangeSet } from '@/api/changeSets';\nimport { hasErrorCode } from '@/api/errors';\nimport { EDITABLE_STATUSES } from '../../Changes/constants';\n\n/**\n * Shipping a reviewed set (plan developer-face §5): breaking and destructive changes must be acknowledged,\n * and an interactive ship is strict: it sends the set version and the entry draft versions this review\n * showed, so anything that moved since makes the server refuse (409) and the page shows \"changed since you\n * looked\" with Refresh. The acknowledgements reset whenever a new review loads.\n */\n/** A draft moved (CHANGE_SET_STALE) or the set itself changed (VERSION_CONFLICT) after the review loaded. */\nconst isStale = (error: unknown) =>\n hasErrorCode(error, 'CHANGE_SET_STALE') || hasErrorCode(error, 'VERSION_CONFLICT');\n\nexport const useShipFlow = (set: ChangeSet, review: UseQueryResult<ChangeSetReview>) => {\n const { t } = useTranslation();\n const ship = useShipChangeSet();\n const schedule = useScheduleChangeSet();\n const update = useUpdateChangeSet();\n const [acknowledgedBreaking, setAcknowledgedBreaking] = useState(false);\n const [acknowledgedDestructive, setAcknowledgedDestructive] = useState(false);\n const [refusedStale, setRefusedStale] = useState(false);\n /** The failure the admin already refreshed after (its `updatedAt`), so it stops reading as stale. */\n const [refreshedFailure, setRefreshedFailure] = useState<string | null>(null);\n // A ship with prerequisites runs in the background and checks the drafts at the end: a moved draft\n // fails the set with CHANGE_SET_STALE instead of refusing the request.\n const failedStale =\n set.status === 'failed' && set.error?.code === 'CHANGE_SET_STALE' && refreshedFailure !== set.updatedAt;\n const stale = refusedStale || failedStale;\n const [reviewedAt, setReviewedAt] = useState(review.dataUpdatedAt);\n if (review.dataUpdatedAt !== reviewedAt) {\n setReviewedAt(review.dataUpdatedAt);\n setAcknowledgedBreaking(false);\n setAcknowledgedDestructive(false);\n }\n\n const data = review.data;\n const checks = data?.checks;\n const needsBreaking = checks?.breaking ?? false;\n const needsDestructive = checks?.destructive ?? false;\n const acknowledged =\n (!needsBreaking || acknowledgedBreaking) && (!needsDestructive || acknowledgedDestructive);\n const itemCount = set.entryItemCount + set.schemaItemCount;\n const blocked = (checks?.blocking.length ?? 0) > 0;\n const canShip =\n EDITABLE_STATUSES.has(set.status) && data !== undefined && itemCount > 0 && !blocked && !stale;\n const acknowledgement = {\n ...(needsBreaking ? { acknowledgeBreaking: true } : {}),\n ...(needsDestructive ? { acknowledgeDestructive: true } : {}),\n };\n\n /** Runs a write that checks what the review saw; a stale answer turns into the banner instead of an error. */\n const strict = async (write: () => Promise<unknown>) => {\n try {\n await write();\n } catch (error) {\n // CHANGE_SET_STALE (a draft moved) or a stale set version: both mean \"changed since you looked\".\n if (isStale(error)) {\n setRefusedStale(true);\n return;\n }\n throw error;\n }\n };\n\n const shipNow = (deploymentConnectionId?: string | null) =>\n strict(async () => {\n if (!data) {\n return;\n }\n let expectedVersion = data.changeSet.version;\n if (deploymentConnectionId !== undefined && deploymentConnectionId !== set.deploymentConnectionId) {\n const updated = await update.mutateAsync({\n id: set.id,\n input: { deploymentConnectionId, expectedVersion },\n });\n expectedVersion = updated.version;\n }\n const result = await ship.mutateAsync({\n id: set.id,\n input: {\n expectedVersion,\n ...acknowledgement,\n itemVersions: data.entries.flatMap((entry) =>\n entry.draftVersion === null ? [] : [{ itemId: entry.itemId, draftVersion: entry.draftVersion }],\n ),\n },\n });\n if (result.status === 'shipped') {\n toast.success(t('changes.review.shipped', { seq: result.shippedSnapshot ?? '' }));\n } else if (result.status === 'shipping') {\n toast.info(t('changes.review.shippingStarted'));\n } else {\n toast.error(t('changes.review.shipFailed'));\n }\n });\n\n const scheduleAt = (at: string) =>\n strict(async () => {\n if (!data) {\n return;\n }\n await schedule.mutateAsync({\n id: set.id,\n input: { at, expectedVersion: data.changeSet.version, ...acknowledgement },\n });\n toast.success(t('changes.review.scheduled'));\n });\n\n return {\n needsBreaking,\n needsDestructive,\n acknowledgedBreaking,\n acknowledgedDestructive,\n setAcknowledgedBreaking,\n setAcknowledgedDestructive,\n acknowledged,\n canShip,\n shipping: ship.isPending || update.isPending,\n shipNow,\n scheduleAt,\n scheduleError: schedule.error,\n resetSchedule: schedule.reset,\n scheduling: schedule.isPending,\n stale,\n refresh: async () => {\n // The banner goes only once the new review is in: it resets the acknowledgements when it lands.\n await review.refetch();\n setRefusedStale(false);\n setRefreshedFailure(set.updatedAt);\n },\n };\n};\n\nexport type ShipFlow = ReturnType<typeof useShipFlow>;\n","import type { ChangeSet } from '@shapio/client';\nimport { Pencil } from 'lucide-react';\nimport { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useUpdateChangeSet } from '@/api/changeSets';\nimport { FormError } from '@/components/FormError';\nimport { SubmitButton } from '@/components/SubmitButton';\nimport { Button } from '@/components/ui/button';\nimport { Input } from '@/components/ui/input';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { settle } from '@/helpers/settle';\n\ntype RenamePopoverProps = { set: ChangeSet };\n\n/** The title, edited in place from a pencil button beside it. */\nexport const RenamePopover = ({ set }: RenamePopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const inputId = useId();\n const [open, setOpen] = useState(false);\n const [title, setTitle] = useState(set.title);\n const update = useUpdateChangeSet();\n return (\n <Popover\n open={open}\n onOpenChange={(next) => {\n if (update.isPending) {\n return;\n }\n setOpen(next);\n if (next) {\n setTitle(set.title);\n update.reset();\n }\n }}\n modal\n >\n <PopoverTrigger asChild>\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label={t('changes.review.rename')}>\n <Pencil aria-hidden=\"true\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" aria-labelledby={titleId} className=\"w-80\">\n <form\n noValidate\n className=\"space-y-3\"\n onSubmit={(event) => {\n event.preventDefault();\n const next = title.trim();\n if (!next || next === set.title) {\n setOpen(false);\n return;\n }\n void settle(\n update.mutateAsync({ id: set.id, input: { title: next, expectedVersion: set.version } }),\n ).then((result) => {\n if (result.ok) {\n setOpen(false);\n toast.success(t('changes.review.renamed'));\n }\n });\n }}\n >\n <label id={titleId} htmlFor={inputId} className=\"text-sm font-semibold\">\n {t('changes.fields.title')}\n </label>\n <Input\n id={inputId}\n value={title}\n maxLength={200}\n autoComplete=\"off\"\n onChange={(event) => setTitle(event.target.value)}\n />\n <FormError error={update.error} />\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => setOpen(false)}>\n {t('common.cancel')}\n </Button>\n <SubmitButton\n size=\"sm\"\n pending={update.isPending}\n pendingLabel={t('common.saving')}\n disabled={!title.trim()}\n >\n {t('common.saveChanges')}\n </SubmitButton>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n};\n","import type { ChangeSetTimelineEvent } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip, type StatusTone } from '@/components/StatusChip';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../../Changes/hooks/useActorLabel';\n\n/** Timeline event kinds (D0's TimelineEventSchema) and how each reads. Unknown kinds show their raw name. */\nconst EVENT_DISPLAY = {\n created: { labelKey: 'changes.timeline.created', tone: 'neutral' },\n updated: { labelKey: 'changes.timeline.updated', tone: 'neutral' },\n item_added: { labelKey: 'changes.timeline.itemAdded', tone: 'neutral' },\n item_removed: { labelKey: 'changes.timeline.itemRemoved', tone: 'muted' },\n schema_draft_saved: { labelKey: 'changes.timeline.schemaDraftSaved', tone: 'neutral' },\n reviewed: { labelKey: 'changes.timeline.reviewed', tone: 'neutral' },\n scheduled: { labelKey: 'changes.timeline.scheduled', tone: 'scheduled' },\n unscheduled: { labelKey: 'changes.timeline.unscheduled', tone: 'muted' },\n shipping: { labelKey: 'changes.timeline.shipping', tone: 'progress' },\n shipped: { labelKey: 'changes.timeline.shipped', tone: 'success' },\n failed: { labelKey: 'changes.timeline.failed', tone: 'danger' },\n discarded: { labelKey: 'changes.timeline.discarded', tone: 'muted' },\n deploy_triggered: { labelKey: 'changes.timeline.deployTriggered', tone: 'progress' },\n deploy_building: { labelKey: 'changes.timeline.deployBuilding', tone: 'progress' },\n deploy_deployed: { labelKey: 'changes.timeline.deployDeployed', tone: 'success' },\n deploy_failed: { labelKey: 'changes.timeline.deployFailed', tone: 'danger' },\n} as const satisfies Record<string, { labelKey: string; tone: StatusTone }>;\n\nconst isKnownKind = (kind: string): kind is keyof typeof EVENT_DISPLAY => kind in EVENT_DISPLAY;\n\ntype EventRowProps = { event: ChangeSetTimelineEvent; last: boolean };\n\n/** One event on the set's timeline, with its snapshot or deploy run when it has one. */\nexport const EventRow = ({ event, last }: EventRowProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const display = isKnownKind(event.kind) ? EVENT_DISPLAY[event.kind] : undefined;\n return (\n <li className=\"flex gap-3\">\n <span aria-hidden=\"true\" className=\"flex flex-col items-center\">\n <span className=\"mt-1.5 size-2.5 shrink-0 rounded-full border-2 border-primary bg-card\" />\n {last ? null : <span className=\"w-px flex-1 bg-border\" />}\n </span>\n <div className=\"min-w-0 flex-1 space-y-1 pb-5\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <StatusChip\n tone={display?.tone ?? 'neutral'}\n label={display ? t(display.labelKey) : event.kind}\n live={false}\n size=\"sm\"\n />\n {event.message ? <span className=\"text-sm\">{event.message}</span> : null}\n {event.snapshot !== null ? (\n <Link\n to=\"/snapshots/$seq\"\n params={{ seq: String(event.snapshot) }}\n className=\"text-sm font-semibold text-link underline-offset-4 hover:underline\"\n >\n {t('snapshots.version', { seq: event.snapshot })}\n </Link>\n ) : null}\n {event.deploymentRunId ? (\n <Link\n to=\"/publishing/deployments/runs/$runId\"\n params={{ runId: event.deploymentRunId }}\n className=\"text-sm text-link underline-offset-4 hover:underline\"\n >\n {t('changes.timeline.deployRun')}\n </Link>\n ) : null}\n </div>\n <p className=\"text-meta text-muted-foreground\">\n {actorLabel(event.actor)} ·{' '}\n <time dateTime={event.at} title={formatDateTime(event.at)}>\n {formatRelativeTime(event.at)}\n </time>\n </p>\n </div>\n </li>\n );\n};\n","import { History } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useChangeSetTimeline } from '@/api/changeSets';\nimport { EmptyState } from '@/components/EmptyState';\nimport { QueryView } from '@/components/QueryView';\nimport { EventRow } from './EventRow';\n\ntype TimelineTabProps = { changeSetId: string };\n\n/** What happened to the set, oldest first: created, items added, scheduled, shipped (→ snapshot), deploys. */\nexport const TimelineTab = ({ changeSetId }: TimelineTabProps) => {\n const { t } = useTranslation();\n const timeline = useChangeSetTimeline(changeSetId);\n return (\n <QueryView\n query={timeline}\n isEmpty={(events) => events.length === 0}\n empty={<EmptyState icon={History} title={t('changes.timeline.empty')} />}\n >\n {(events) => (\n <ol aria-label={t('changes.tabs.timeline')} className=\"rounded-xl border bg-card p-5 pb-0\">\n {events.map((event, index) => (\n <EventRow\n key={`${event.at}-${event.kind}-${index}`}\n event={event}\n last={index === events.length - 1}\n />\n ))}\n </ol>\n )}\n </QueryView>\n );\n};\n","import type { ChangeSet } from '@shapio/client';\nimport { linkOptions, useNavigate, useSearch } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useChangeSetReview } from '@/api/changeSets';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { CHANGE_SET_STATUS_DISPLAY, EDITABLE_STATUSES } from '../../Changes/constants';\nimport { useActorLabel } from '../../Changes/hooks/useActorLabel';\nimport { Actions } from '../Actions';\nimport { Banners } from '../Banners';\nimport { ChangesTab } from '../ChangesTab';\nimport { ChecksTab } from '../ChecksTab';\nimport { ConsumersTab } from '../ConsumersTab';\nimport { useShipFlow } from '../hooks/useShipFlow';\nimport { RenamePopover } from '../RenamePopover';\nimport { CHANGE_SET_TABS, type ChangeSetTab } from '../searchSchema';\nimport { TimelineTab } from '../TimelineTab';\n\nconst TAB_LABEL_KEYS = {\n changes: 'changes.tabs.changes',\n checks: 'changes.tabs.checks',\n consumers: 'changes.tabs.consumers',\n timeline: 'changes.tabs.timeline',\n} as const satisfies Record<ChangeSetTab, string>;\n\ntype ViewProps = { set: ChangeSet };\n\n/** A loaded set: sticky header with the ship actions, banners, then the four review tabs. */\nexport const View = ({ set }: ViewProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const tab = useSearch({ from: '/app/changes/$changeSetId' }).tab ?? 'changes';\n const navigate = useNavigate({ from: '/changes/$changeSetId' });\n const review = useChangeSetReview(set);\n const flow = useShipFlow(set, review);\n const status = CHANGE_SET_STATUS_DISPLAY[set.status];\n const editable = EDITABLE_STATUSES.has(set.status);\n const itemCount = set.entryItemCount + set.schemaItemCount;\n const meta = [\n t('changes.review.openedBy', { name: actorLabel(set.createdBy), at: formatRelativeTime(set.createdAt) }),\n t('changes.itemCount', { count: itemCount }),\n set.status === 'scheduled' && set.scheduledFor\n ? t('changes.scheduledFor', { at: formatDateTime(set.scheduledFor) })\n : '',\n ]\n .filter(Boolean)\n .join(' · ');\n return (\n <Page>\n <Tabs\n value={tab}\n onValueChange={(value) => void navigate({ search: { tab: value as ChangeSetTab }, replace: true })}\n className=\"gap-6\"\n >\n <PageHeader\n sticky\n breadcrumb={[{ label: t('changes.title'), link: linkOptions({ to: '/changes' }) }]}\n title={set.title}\n badge={\n <>\n <StatusChip tone={status.tone} label={t(status.labelKey)} />\n {editable ? <RenamePopover set={set} /> : null}\n </>\n }\n meta={meta}\n actions={<Actions set={set} flow={flow} />}\n tabs={\n <TabsList variant=\"underline\" aria-label={t('changes.tabs.label')}>\n {CHANGE_SET_TABS.map((key) => (\n <TabsTrigger key={key} value={key}>\n {t(TAB_LABEL_KEYS[key])}\n </TabsTrigger>\n ))}\n </TabsList>\n }\n />\n <Banners\n set={set}\n flow={flow}\n notices={review.data?.notices ?? []}\n showAcknowledgementHint={editable && tab !== 'checks'}\n />\n <QueryView query={review} loadingRows={6}>\n {(data) => (\n <>\n <TabsContent value=\"changes\">\n <ChangesTab review={data} editable={editable} />\n </TabsContent>\n <TabsContent value=\"checks\">\n <ChecksTab review={data} flow={flow} />\n </TabsContent>\n <TabsContent value=\"consumers\">\n <ConsumersTab review={data} />\n </TabsContent>\n </>\n )}\n </QueryView>\n <TabsContent value=\"timeline\">\n <TimelineTab changeSetId={set.id} />\n </TabsContent>\n </Tabs>\n </Page>\n );\n};\n","import { useParams } from '@tanstack/react-router';\nimport { useChangeSet } from '@/api/changeSets';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { QueryView } from '@/components/QueryView';\nimport { useDevelopPermissions } from '../Changes/hooks/useDevelopPermissions';\nimport { View } from './View';\n\n/** One change set, reviewed like a pull request: its diffs, checks, consumers and timeline. */\nexport const ChangeSet = () => {\n const { changeSetId } = useParams({ from: '/app/changes/$changeSetId' });\n const { canManageChanges } = useDevelopPermissions();\n const set = useChangeSet(changeSetId);\n if (!canManageChanges) {\n return (\n <Page>\n <NoAccess />\n </Page>\n );\n }\n return (\n <QueryView query={set} loadingRows={6}>\n {(data) => <View set={data} />}\n </QueryView>\n );\n};\n","import type { ThemeVariant } from '@shapio/schema';\n\n/**\n * The GraphiQL page's URL for one site (`?site=`, left out on the primary site), opened on a query\n * (`?query=`) in the admin's light or dark scheme (`?theme=`; GraphiQL 3's `forcedTheme`).\n */\nexport type PlaygroundUrlOptions = { siteKey?: string; query?: string; theme: ThemeVariant };\n\nexport const playgroundUrl = (base: string, { siteKey, query, theme }: PlaygroundUrlOptions): string => {\n const url = new URL(base);\n if (siteKey) {\n url.searchParams.set('site', siteKey);\n }\n if (query?.trim()) {\n url.searchParams.set('query', query);\n }\n url.searchParams.set('theme', theme);\n return url.href;\n};\n","import { graphqlPlaygroundUrl } from '@/api/apiDocs';\nimport { useDeliverySiteKey } from '@/hooks/useDeliverySiteKey';\nimport { useResolvedScheme } from '@/hooks/useResolvedScheme';\nimport { playgroundUrl } from '../helpers/playgroundUrl';\n\n/** GraphiQL's URL for this page's site, in the admin's scheme, opened on `query` when given. */\nexport const usePlaygroundUrl = (query: string | undefined) => {\n const siteKey = useDeliverySiteKey();\n const theme = useResolvedScheme();\n return playgroundUrl(graphqlPlaygroundUrl(), { siteKey, query, theme });\n};\n","import { getRouteApi } from '@tanstack/react-router';\nimport { Workflow } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useGraphqlPlaygroundAvailable } from '@/api/apiDocs';\nimport { EmptyState } from '@/components/EmptyState';\nimport { InfoHint } from '@/components/InfoHint';\nimport { LoadingState } from '@/components/LoadingState';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { usePlaygroundUrl } from './hooks/usePlaygroundUrl';\n\nconst route = getRouteApi('/app/develop/graphql');\n\n/**\n * GraphQL: the vendored GraphiQL (same origin, the admin session, introspection and docs) for this page's\n * site, filling the screen under the header. Opening another site is a full navigation, so the frame always\n * shows the shell's site.\n */\nexport const Graphql = () => {\n const { t } = useTranslation();\n const { query } = route.useSearch();\n const src = usePlaygroundUrl(query);\n const available = useGraphqlPlaygroundAvailable();\n const title = t('develop.graphql.title');\n return (\n <Page width=\"full\">\n <PageHeader title={title} badge={<InfoHint about={title}>{t('develop.graphql.hint')}</InfoHint>} />\n {available.isPending ? (\n <LoadingState rows={6} />\n ) : available.data ? (\n <iframe\n title={t('develop.graphql.frame')}\n src={src}\n className=\"block h-[calc(100dvh-10.25rem)] min-h-[28rem] w-full rounded-xl border bg-card md:h-[calc(100dvh-12.25rem)] lg:h-[calc(100dvh-9.25rem)]\"\n />\n ) : (\n <EmptyState\n icon={Workflow}\n title={t('develop.graphql.unavailable')}\n description={t('develop.graphql.unavailableDescription')}\n />\n )}\n </Page>\n );\n};\n","import type { JobQuery } from '@shapio/client';\nimport { keepPreviousData, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { adminApi } from './client';\nimport { withCsrf } from './csrf';\nimport { queryKeys } from './queryKeys';\n\nconst silent = { silent: true } as const;\n\nexport const useJobs = (query: JobQuery) =>\n useQuery({\n queryKey: queryKeys.publishing.jobs.list(query),\n queryFn: () => adminApi.jobs.list(query),\n placeholderData: keepPreviousData,\n meta: silent,\n });\n\n/** Counts per status (the Live page only shows the dead count). */\nexport const useJobSummary = () =>\n useQuery({\n queryKey: queryKeys.publishing.jobs.summary,\n queryFn: () => adminApi.jobs.summary(),\n meta: silent,\n });\n\n/** Dead jobs only: the server answers 409 JOB_NOT_RETRYABLE otherwise. */\nexport const useRetryJob = () => {\n const queryClient = useQueryClient();\n return useMutation({\n mutationKey: ['jobs', 'retry'],\n mutationFn: (id: string) => withCsrf(() => adminApi.jobs.retry(id)),\n onSettled: () => queryClient.invalidateQueries({ queryKey: queryKeys.publishing.jobs.all }),\n });\n};\n","import type { Job } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useJobs, useRetryJob } from '@/api/jobs';\nimport { QueryView } from '@/components/QueryView';\nimport { Button } from '@/components/ui/button';\n\n/** Enough to clear a burst of failures; the rest show once these are retried. */\nconst FAILED_JOBS_LIMIT = 20;\n\n/** The dead jobs, newest first, each with its last error and a Retry button. */\nexport const List = () => {\n const { t } = useTranslation();\n const jobs = useJobs({ status: 'dead', limit: FAILED_JOBS_LIMIT });\n const retryJob = useRetryJob();\n const retry = (job: Job) =>\n retryJob.mutate(job.id, {\n onSuccess: () => toast.success(t('develop.live.jobRetried', { type: job.type })),\n });\n return (\n <QueryView query={jobs} loadingRows={3}>\n {(data) => (\n <ul aria-label={t('develop.live.failedJobsTitle')} className=\"mt-3 divide-y border-t\">\n {data.items.map((job) => (\n <li key={job.id} className=\"flex items-start justify-between gap-3 py-2\">\n <div className=\"min-w-0\">\n <p className=\"font-mono text-xs font-semibold\">{job.type}</p>\n {job.lastError ? (\n <p className=\"line-clamp-2 text-meta text-destructive\" title={job.lastError}>\n {job.lastError}\n </p>\n ) : null}\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={retryJob.isPending}\n aria-label={t('develop.live.retryJobLabel', { type: job.type })}\n onClick={() => retry(job)}\n >\n {t('develop.live.retryJob')}\n </Button>\n </li>\n ))}\n </ul>\n )}\n </QueryView>\n );\n};\n","import { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useJobSummary } from '@/api/jobs';\nimport { Panel } from '@/components/Panel';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Button } from '@/components/ui/button';\nimport { List } from './List';\n\n/**\n * Background jobs only surface when something broke: the dead count and, on request, the failed jobs to\n * retry (needs `publishing.manage`). Nothing renders while every job succeeds or waits its turn.\n */\nexport const FailedJobs = () => {\n const { t } = useTranslation();\n const summary = useJobSummary();\n const [isOpen, setIsOpen] = useState(false);\n const dead = summary.data?.counts.dead ?? 0;\n if (dead === 0) {\n return null;\n }\n return (\n <Panel title={t('develop.live.failedJobsTitle')}>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <StatusChip tone=\"danger\" label={t('develop.live.jobsFailed', { count: dead })} size=\"sm\" />\n <Button variant=\"link\" size=\"sm\" aria-expanded={isOpen} onClick={() => setIsOpen((open) => !open)}>\n {isOpen ? t('develop.live.hideFailedJobs') : t('develop.live.showFailedJobs')}\n </Button>\n </div>\n {isOpen ? <List /> : null}\n </Panel>\n );\n};\n","import { Link } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useContentHealthSummary } from '@/api/contentHealth';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { StatusChip } from '@/components/StatusChip';\nimport { RULE_ORDER, RULE_TITLE_KEYS } from '@/features/Inbox/constants';\n\n/** Open content-health findings per rule, linking to the Inbox where they are fixed. */\nexport const HealthCard = () => {\n const { t } = useTranslation();\n const health = useContentHealthSummary();\n return (\n <Panel title={t('develop.live.healthTitle')}>\n <QueryView query={health} loadingRows={2}>\n {(data) => {\n const counts = new Map(data.rules.map(({ rule, count }) => [rule, count]));\n const open = RULE_ORDER.filter((rule) => (counts.get(rule) ?? 0) > 0);\n const total = open.reduce((sum, rule) => sum + (counts.get(rule) ?? 0), 0);\n return (\n <div className=\"space-y-3\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <StatusChip\n tone={total > 0 ? 'warning' : 'success'}\n label={t('develop.live.healthOpen', { count: total })}\n />\n <Link to=\"/\" className=\"text-sm text-link underline-offset-4 hover:underline\">\n {t('develop.live.openInbox')}\n </Link>\n </div>\n {open.length > 0 ? (\n <ul className=\"space-y-1 text-sm\">\n {open.map((rule) => (\n <li key={rule} className=\"flex justify-between gap-3\">\n <span>{t(RULE_TITLE_KEYS[rule])}</span>\n <span className=\"tabular-nums\">{counts.get(rule)}</span>\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-meta text-muted-foreground\">{t('develop.live.healthClean')}</p>\n )}\n </div>\n );\n }}\n </QueryView>\n </Panel>\n );\n};\n","import { Link } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useWebhooks } from '@/api/webhooks';\nimport { StatusChip } from '@/components/StatusChip';\n\n/** Webhooks: how many are on, and how many last gave up delivering (needs `webhooks.manage`). */\nexport const WebhooksRow = () => {\n const { t } = useTranslation();\n const webhooks = useWebhooks();\n if (!webhooks.data) {\n return null;\n }\n const enabled = webhooks.data.filter((webhook) => webhook.enabled);\n const failing = enabled.filter((webhook) => webhook.lastDelivery?.status === 'dead').length;\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <dt>\n <Link\n to=\"/publishing/webhooks\"\n className=\"text-sm font-semibold text-link underline-offset-4 hover:underline\"\n >\n {t('develop.live.webhooks')}\n </Link>\n </dt>\n <dd className=\"flex flex-wrap gap-1.5\">\n <StatusChip\n tone=\"success\"\n label={t('develop.live.webhooksEnabled', { count: enabled.length })}\n size=\"sm\"\n />\n <StatusChip\n tone={failing > 0 ? 'danger' : 'muted'}\n label={t('develop.live.webhooksFailing', { count: failing })}\n size=\"sm\"\n />\n </dd>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { useDevelopPermissions } from '../../Changes/hooks/useDevelopPermissions';\nimport { WebhooksRow } from './WebhooksRow';\n\n/** Outgoing webhooks at a glance, linking to their Publishing section. */\nexport const OperationsCard = () => {\n const { t } = useTranslation();\n const { canManageWebhooks } = useDevelopPermissions();\n if (!canManageWebhooks) {\n return null;\n }\n return (\n <Panel title={t('develop.live.webhooks')}>\n <dl className=\"space-y-3\">\n <WebhooksRow />\n </dl>\n </Panel>\n );\n};\n","import { useMemo } from 'react';\nimport { useDefinitions } from '@/api/schema';\nimport { usePrincipalUsage } from '@/api/usage';\n\n/** Who reads what across every model, plus each model's API key for naming the fields. */\nexport const useReaders = (enabled: boolean) => {\n const models = useDefinitions('model');\n const modelIds = useMemo(() => (models.data ?? []).map(({ definition }) => definition.id), [models.data]);\n const usage = usePrincipalUsage(modelIds, enabled && models.isSuccess);\n const modelKeys = useMemo(\n () => new Map((models.data ?? []).map(({ definition }) => [definition.id, definition.apiKey])),\n [models.data],\n );\n return {\n ...usage,\n isPending: models.isPending || usage.isPending,\n error: models.error ?? usage.error,\n modelKeyOf: (modelId: string) => modelKeys.get(modelId) ?? modelId,\n servedReads: usage.principals.reduce((sum, principal) => sum + principal.requests, 0),\n };\n};\n","import { useTranslation } from 'react-i18next';\nimport type { PrincipalFieldRead } from '@/api/usage';\n\ntype FieldListProps = { fields: readonly PrincipalFieldRead[]; modelKeyOf: (modelId: string) => string };\n\n/**\n * The fields one reader read, as `model.field`; a model it only ever read whole (no field selection) reads\n * \"model (whole model)\".\n */\nexport const FieldList = ({ fields, modelKeyOf }: FieldListProps) => {\n const { t } = useTranslation();\n const byModel = new Map<string, PrincipalFieldRead[]>();\n for (const field of fields) {\n byModel.set(field.modelId, [...(byModel.get(field.modelId) ?? []), field]);\n }\n const parts = [...byModel.entries()].flatMap(([modelId, reads]) => {\n const modelKey = modelKeyOf(modelId);\n return reads.every((read) => read.selection === 'implicit')\n ? [t('develop.live.wholeModel', { model: modelKey })]\n : reads.filter((read) => read.selection === 'explicit').map((read) => `${modelKey}.${read.apiKeyPath}`);\n });\n return (\n <span className=\"block truncate font-mono text-xs\" title={parts.join(', ')}>\n {parts.join(', ')}\n </span>\n );\n};\n","import { Link } from '@tanstack/react-router';\nimport { Users } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { USAGE_DAYS } from '@/api/usage';\nimport { EmptyState } from '@/components/EmptyState';\nimport { ErrorState } from '@/components/ErrorState';\nimport { LoadingState } from '@/components/LoadingState';\nimport { Panel } from '@/components/Panel';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { usePrincipalLabel } from '../../Changes/hooks/usePrincipalLabel';\nimport { useReaders } from '../hooks/useReaders';\nimport { FieldList } from './FieldList';\n\n/** Who reads what: each delivery reader, the fields it read, how often, and the snapshot it pins. */\nexport const ReadersTable = () => {\n const { t } = useTranslation();\n const principalLabel = usePrincipalLabel();\n const readers = useReaders(true);\n const body = () => {\n if (readers.isPending) {\n return <LoadingState rows={3} />;\n }\n if (readers.error) {\n return <ErrorState error={readers.error} onRetry={() => void readers.refetch()} />;\n }\n if (readers.principals.length === 0) {\n return (\n <EmptyState icon={Users} size=\"panel\" title={t('develop.live.noReaders', { count: USAGE_DAYS })} />\n );\n }\n return (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.consumers.reader')}</TableHead>\n <TableHead>{t('develop.live.fields')}</TableHead>\n <TableHead className=\"text-right\">{t('develop.live.requests')}</TableHead>\n <TableHead>{t('changes.consumers.lastRead')}</TableHead>\n <TableHead>{t('develop.live.pinned')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {readers.principals.map((principal) => (\n <TableRow key={principal.principalKey}>\n <TableCell className=\"font-semibold whitespace-nowrap\">\n {principalLabel(principal.principalKey, principal.tokenName)}\n </TableCell>\n <TableCell className=\"max-w-96\">\n <FieldList fields={principal.fields} modelKeyOf={readers.modelKeyOf} />\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">{principal.requests.toLocaleString()}</TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(principal.lastReadAt)}>\n {formatRelativeTime(principal.lastReadAt)}\n </TableCell>\n <TableCell className=\"whitespace-nowrap\">\n {principal.lastSnapshot === null ? (\n t('develop.live.followsLive')\n ) : (\n <Link\n to=\"/snapshots/$seq\"\n params={{ seq: String(principal.lastSnapshot) }}\n className=\"text-link underline-offset-4 hover:underline\"\n >\n {t('snapshots.version', { seq: principal.lastSnapshot })}\n </Link>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n );\n };\n return (\n <Panel\n title={t('develop.live.readersTitle')}\n description={t('develop.live.servedReads', { count: readers.servedReads, days: USAGE_DAYS })}\n flush\n >\n {readers.tracking ? null : (\n <p className=\"border-b px-5 py-2.5 text-meta text-muted-foreground\">\n {t('develop.live.notTracking')}\n </p>\n )}\n {body()}\n </Panel>\n );\n};\n","import type { DeploymentRunStatus, SnapshotSource } from '@shapio/client';\nimport type { StatusTone } from '@/components/StatusChip';\n\nexport const SNAPSHOT_SOURCE_KEYS = {\n publish: 'snapshots.sources.publish',\n unpublish: 'snapshots.sources.unpublish',\n delete: 'snapshots.sources.delete',\n schedule: 'snapshots.sources.schedule',\n change_set: 'snapshots.sources.change_set',\n schema: 'snapshots.sources.schema',\n conversion: 'snapshots.sources.conversion',\n import: 'snapshots.sources.import',\n legacy: 'snapshots.sources.legacy',\n} as const satisfies Record<SnapshotSource, string>;\n\n/** A ledger row only knows the run's status (not its provider), so \"triggered\" reads as sent. */\nexport const SNAPSHOT_RUN_DISPLAY = {\n queued: { labelKey: 'publishing.deployments.statuses.queued', tone: 'neutral' },\n triggered: { labelKey: 'publishing.deployments.statuses.triggered', tone: 'progress' },\n building: { labelKey: 'publishing.deployments.statuses.building', tone: 'progress' },\n deployed: { labelKey: 'publishing.deployments.statuses.deployed', tone: 'success' },\n failed: { labelKey: 'publishing.deployments.statuses.failed', tone: 'danger' },\n unknown: { labelKey: 'publishing.deployments.statuses.unknown', tone: 'muted' },\n} as const satisfies Record<DeploymentRunStatus, { labelKey: string; tone: StatusTone }>;\n","import { Link } from '@tanstack/react-router';\nimport { useTranslation } from 'react-i18next';\nimport { useSnapshots } from '@/api/snapshots';\nimport { Panel } from '@/components/Panel';\nimport { QueryView } from '@/components/QueryView';\nimport { Badge } from '@/components/ui/badge';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../Changes/hooks/useActorLabel';\nimport { SNAPSHOT_SOURCE_KEYS } from '../../Snapshots/helpers/display';\n\n/** What is being served right now: the current snapshot, since when, and who made it. */\nexport const SnapshotCard = () => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const snapshots = useSnapshots(undefined);\n return (\n <Panel title={t('develop.live.snapshotTitle')}>\n <QueryView query={snapshots} loadingRows={2}>\n {(data) => {\n const latest = data.items.find((row) => row.seq === data.current);\n return (\n <div className=\"space-y-2\">\n <Link\n to=\"/snapshots/$seq\"\n params={{ seq: String(data.current) }}\n className=\"text-title text-link underline-offset-4 hover:underline\"\n >\n {t('snapshots.version', { seq: data.current })}\n </Link>\n {latest ? (\n <div className=\"flex flex-wrap items-center gap-2 text-meta text-muted-foreground\">\n <Badge variant=\"secondary\">{t(SNAPSHOT_SOURCE_KEYS[latest.source])}</Badge>\n <span title={formatDateTime(latest.createdAt)}>\n {t('develop.live.since', {\n at: formatRelativeTime(latest.createdAt),\n name: actorLabel({ type: latest.actor.type }),\n })}\n </span>\n {latest.schemaVersion === null ? null : (\n <span>{t('snapshots.schemaVersion', { version: latest.schemaVersion })}</span>\n )}\n </div>\n ) : null}\n </div>\n );\n }}\n </QueryView>\n </Panel>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { useDevelopPermissions } from '../Changes/hooks/useDevelopPermissions';\nimport { FailedJobs } from './FailedJobs';\nimport { HealthCard } from './HealthCard';\nimport { OperationsCard } from './OperationsCard';\nimport { ReadersTable } from './ReadersTable';\nimport { SnapshotCard } from './SnapshotCard';\n\n/**\n * Live: what production serves and who reads it. Sections show only with their permission: the snapshot\n * with `changes.manage`, readers with `tokens.manage`, webhooks with theirs, and failed jobs (only when\n * there are any) with `publishing.manage`.\n */\nexport const Live = () => {\n const { t } = useTranslation();\n const { canManageChanges, canReadUsage, canManagePublishing, canManageWebhooks } = useDevelopPermissions();\n const anything = canManageChanges || canReadUsage || canManagePublishing || canManageWebhooks;\n return (\n <Page>\n <PageHeader title={t('develop.live.title')} />\n {anything ? null : <NoAccess />}\n {canManageChanges ? (\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <SnapshotCard />\n <HealthCard />\n </div>\n ) : null}\n {canReadUsage ? <ReadersTable /> : null}\n {canManagePublishing ? <FailedJobs /> : null}\n <OperationsCard />\n </Page>\n );\n};\n","import {\n classifyChanges,\n diffDefinitions,\n type SchemaDefinition,\n type SyncConflictReason,\n} from '@shapio/schema';\nimport { GitMerge } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport type { ExportedDefinition } from '@/api/schemaFiles';\nimport { CopyButton } from '@/components/CopyButton';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Panel } from '@/components/Panel';\nimport { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { describeChange } from '@/features/Models/helpers/describeChange';\nimport type { GuardConflict } from '../helpers/guard';\n\nconst REASON_KEYS = {\n changedOnBoth: 'develop.schema.conflicts.reasons.changedOnBoth',\n deletedOnTarget: 'develop.schema.conflicts.reasons.deletedOnTarget',\n existsOnTarget: 'develop.schema.conflicts.reasons.existsOnTarget',\n changedOnTargetBeforeDelete: 'develop.schema.conflicts.reasons.changedOnTargetBeforeDelete',\n} as const satisfies Record<SyncConflictReason, string>;\n\ntype ChangeListProps = { label: string; before: SchemaDefinition; after: SchemaDefinition | null };\n\nconst ChangeList = ({ label, before, after }: ChangeListProps) => {\n const changes = classifyChanges(diffDefinitions(before, after), { before, after });\n return (\n <div className=\"min-w-0 space-y-2\">\n <h3 className=\"text-xs font-semibold tracking-wide text-muted-foreground uppercase\">{label}</h3>\n <ul className=\"list-disc space-y-1 pl-5 text-sm\">\n {changes.map((change, index) => (\n <li key={`${change.kind}:${change.fieldId ?? ''}:${change.property ?? ''}:${index}`}>\n {describeChange(change, before, after)}\n </li>\n ))}\n </ul>\n </div>\n );\n};\n\ntype ConflictsProps = {\n conflicts: readonly GuardConflict[];\n textOf: (conflict: GuardConflict) => string;\n onTakeRemote: (remote: ExportedDefinition) => void;\n onKeepLocal: (remote: ExportedDefinition) => void;\n};\n\n/**\n * Apply refused, like a rejected non-fast-forward push: these definitions changed on the instance since\n * the files were loaded. Per file, what changed there and here; the admin takes the instance's version or\n * keeps theirs on top of it (rebased), then applies again.\n */\nexport const Conflicts = ({ conflicts, textOf, onTakeRemote, onKeepLocal }: ConflictsProps) => {\n const { t } = useTranslation();\n return (\n <div className=\"space-y-4\">\n <Alert variant=\"warning\">\n <GitMerge aria-hidden=\"true\" />\n <AlertTitle>{t('develop.schema.conflicts.title', { count: conflicts.length })}</AlertTitle>\n <AlertDescription>{t('develop.schema.conflicts.description')}</AlertDescription>\n </Alert>\n {conflicts.map((conflict) => {\n const { file, local, remote } = conflict;\n return (\n <Panel\n key={file.definitionId}\n title={t('develop.schema.conflicts.fileTitle', { path: file.path })}\n description={t(REASON_KEYS[conflict.reason])}\n actions={<CopyButton value={textOf(conflict)} />}\n >\n <div className=\"grid gap-5 md:grid-cols-2\">\n <ChangeList\n label={t('develop.schema.conflicts.theirs')}\n before={file.base.definition}\n after={remote?.definition ?? null}\n />\n <ChangeList\n label={t('develop.schema.conflicts.yours')}\n before={file.base.definition}\n after={local.definition}\n />\n </div>\n {remote ? (\n <div className=\"mt-5 flex flex-wrap gap-2\">\n <Button type=\"button\" size=\"sm\" variant=\"outline\" onClick={() => onKeepLocal(remote)}>\n {t('develop.schema.conflicts.keepLocal')}\n </Button>\n <InlineConfirm\n tone=\"danger\"\n title={t('develop.schema.conflicts.takeRemoteTitle')}\n description={t('develop.schema.conflicts.takeRemoteDescription')}\n confirmLabel={t('develop.schema.conflicts.takeRemote')}\n onConfirm={() => onTakeRemote(remote)}\n trigger={\n <Button type=\"button\" size=\"sm\" variant=\"outline\">\n {t('develop.schema.conflicts.takeRemote')}\n </Button>\n }\n />\n </div>\n ) : null}\n </Panel>\n );\n })}\n </div>\n );\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport {\n LOCK_FILE_FORMAT_VERSION,\n LOCK_FILE_PATH,\n serializeDefinition,\n serializeLockFile,\n type LockFile,\n type SchemaDefinition,\n} from '@shapio/schema';\nimport type { SchemaExport } from '@/api/schemaFiles';\n\n/**\n * The files `shapio schema pull` writes, built from the same export and serializer, so text copied from\n * here and files in a repository are byte-identical. `schema` is the CLI's default `--dir`\n * (`packages/cli/src/commands/schema/options.ts`), the lock file its default `--lock`.\n */\nexport const SCHEMA_DIR = 'schema';\n\n/** What the file was loaded from: the definition's active version on the instance (the lock entry). */\nexport type FileBase = { version: number; hash: string; definition: SchemaDefinition; text: string };\n\nexport type SchemaFile = {\n path: string;\n definitionId: string;\n category: DefinitionCategory;\n apiKey: string;\n base: FileBase;\n};\n\nexport const categoryOf = (definition: Pick<SchemaDefinition, 'kind'>): DefinitionCategory =>\n definition.kind === 'component' ? 'component' : 'model';\n\nexport const definitionFilePath = (definition: Pick<SchemaDefinition, 'kind' | 'apiKey'>) =>\n `${SCHEMA_DIR}/${definition.kind === 'component' ? 'components' : 'models'}/${definition.apiKey}.json`;\n\nconst CATEGORY_ORDER = { model: 0, component: 1 } as const satisfies Record<DefinitionCategory, number>;\n\n/** One file per definition, models first, then components, each by path. */\nexport const buildFiles = (exported: SchemaExport): SchemaFile[] =>\n exported.definitions\n .map(({ definition, version, hash }) => ({\n path: definitionFilePath(definition),\n definitionId: definition.id,\n category: categoryOf(definition),\n apiKey: definition.apiKey,\n base: { version, hash, definition, text: serializeDefinition(definition) },\n }))\n .sort((a, b) => CATEGORY_ORDER[a.category] - CATEGORY_ORDER[b.category] || a.path.localeCompare(b.path));\n\nexport const LOCK_PATH = LOCK_FILE_PATH;\n\n/** The lock file pull records next to the files (formatVersion, schema version, per-definition base). */\nexport const buildLockFile = (exported: SchemaExport): LockFile => ({\n formatVersion: LOCK_FILE_FORMAT_VERSION,\n schemaVersion: exported.schemaVersion,\n definitions: Object.fromEntries(\n exported.definitions.map(({ definition, version, hash }) => [\n definition.id,\n { kind: definition.kind, apiKey: definition.apiKey, version, hash },\n ]),\n ),\n});\n\nexport const buildLockText = (exported: SchemaExport): string => serializeLockFile(buildLockFile(exported));\n","import { Braces, Lock, Puzzle } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { SubNav, SubNavGroup } from '@/components/SubNav';\nimport { SubNavLink } from '@/components/SubNavLink';\nimport { LOCK_PATH, type SchemaFile } from '../helpers/files';\n\ntype FileLinkProps = { path: string; dirty: boolean; open: boolean; icon: typeof Braces };\n\nconst FileLink = ({ path, dirty, open, icon: Icon }: FileLinkProps) => {\n const { t } = useTranslation();\n const name = path.slice(path.lastIndexOf('/') + 1);\n return (\n <SubNavLink to=\"/schema\" search={{ file: path }} title={path} aria-current={open ? 'page' : undefined}>\n <Icon aria-hidden=\"true\" />\n <span className=\"min-w-0 truncate font-mono text-xs\">{name}</span>\n {dirty ? (\n <>\n <span aria-hidden=\"true\" className=\"ml-auto size-2 shrink-0 rounded-full bg-warning\" />\n <span className=\"sr-only\">{t('develop.schema.modified')}</span>\n </>\n ) : null}\n </SubNavLink>\n );\n};\n\ntype FileNavProps = {\n files: readonly SchemaFile[];\n /** The open file's path. */\n openPath: string;\n isDirty: (file: SchemaFile) => boolean;\n};\n\n/** The schema directory as `shapio schema pull` writes it: models, components and the lock file. */\nexport const FileNav = ({ files, openPath, isDirty }: FileNavProps) => {\n const { t } = useTranslation();\n const models = files.filter((file) => file.category === 'model');\n const components = files.filter((file) => file.category === 'component');\n return (\n <SubNav label={t('develop.schema.files')}>\n {models.length > 0 ? (\n <SubNavGroup label={t('develop.schema.modelsDir')}>\n {models.map((file) => (\n <FileLink\n key={file.definitionId}\n path={file.path}\n dirty={isDirty(file)}\n open={file.path === openPath}\n icon={Braces}\n />\n ))}\n </SubNavGroup>\n ) : null}\n {components.length > 0 ? (\n <SubNavGroup label={t('develop.schema.componentsDir')}>\n {components.map((file) => (\n <FileLink\n key={file.definitionId}\n path={file.path}\n dirty={isDirty(file)}\n open={file.path === openPath}\n icon={Puzzle}\n />\n ))}\n </SubNavGroup>\n ) : null}\n <SubNavGroup label={t('develop.schema.lockDir')}>\n <FileLink path={LOCK_PATH} dirty={false} open={openPath === LOCK_PATH} icon={Lock} />\n </SubNavGroup>\n </SubNav>\n );\n};\n","import type { DefinitionCategory, DefinitionPayload } from '@shapio/client';\nimport type { SchemaDefinition } from '@shapio/schema';\nimport { queryOptions, useQuery } from '@tanstack/react-query';\nimport { apiClient } from './client';\nimport { queryKeys } from './queryKeys';\n\nconst silent = { silent: true } as const;\n\n/** `GET /api/admin/schema/export`: what `shapio schema pull` writes (canonical definitions + lock data). */\nconst SCHEMA_EXPORT_PATH = '/api/admin/schema/export';\n\nexport type ExportedDefinition = { definition: SchemaDefinition; version: number; hash: string };\nexport type SchemaExport = { schemaVersion: number; definitions: ExportedDefinition[] };\n\n/** Under `schema.all`, so every schema change refreshes it. */\nconst schemaExportKey = [...queryKeys.schema.all, 'export'] as const;\n\n/** The instance's schema as pull writes it. Always fetched fresh: the three-way guard compares against it. */\nexport const schemaExportQueryOptions = queryOptions({\n queryKey: schemaExportKey,\n queryFn: () => apiClient.request<SchemaExport>(SCHEMA_EXPORT_PATH),\n staleTime: 0,\n meta: silent,\n});\n\nexport const useSchemaExport = () => useQuery({ ...schemaExportQueryOptions, refetchOnWindowFocus: false });\n\nexport type SchemaDraftInput = {\n definitionId: string;\n category: DefinitionCategory;\n definition: DefinitionPayload;\n /** The active version the edit is based on; null for a new definition. */\n baseVersion: number | null;\n};\n","import { parseDefinition, validateSchema, type SchemaDefinition, type ValidationIssue } from '@shapio/schema';\nimport { newStableId } from '@/helpers/stableId';\n\n/**\n * What a schema file's text means: not JSON (the editor's JSON linter points at the syntax error), an\n * invalid definition (issues with JSON-pointer paths into the file), or a valid definition. The checks are\n * the server's own (`parseDefinition`, then `validateSchema` across every definition), so what the editor\n * accepts is what `PUT …/schema/:definitionId` and `shapio schema apply` accept.\n */\nexport type FileAnalysis =\n | { status: 'invalidJson'; message: string }\n | { status: 'invalid'; raw: unknown; issues: ValidationIssue[] }\n | { status: 'valid'; raw: unknown; definition: SchemaDefinition };\n\nexport type AnalyzeContext = {\n /** The file's base definition (fields without an ID keep the ID of the base field with their API key). */\n previous: SchemaDefinition | undefined;\n /** Every other definition as it would be after applying (for cross-definition checks). */\n others: readonly SchemaDefinition[];\n};\n\nconst parseJson = (text: string): { ok: true; raw: unknown } | { ok: false; message: string } => {\n try {\n return { ok: true, raw: JSON.parse(text) };\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) };\n }\n};\n\nexport const analyzeFile = (text: string, { previous, others }: AnalyzeContext): FileAnalysis => {\n const json = parseJson(text);\n if (!json.ok) {\n return { status: 'invalidJson', message: json.message };\n }\n // New fields without an ID get one that works outside secure contexts too (plain-HTTP LAN installs).\n const parsed = parseDefinition(json.raw, { createId: newStableId, ...(previous ? { previous } : {}) });\n if (!parsed.ok) {\n return { status: 'invalid', raw: json.raw, issues: parsed.issues };\n }\n const { definition } = parsed;\n const cross = validateSchema([...others.filter((other) => other.id !== definition.id), definition]).filter(\n (found) => found.definitionId === undefined || found.definitionId === definition.id,\n );\n return cross.length > 0\n ? { status: 'invalid', raw: json.raw, issues: cross }\n : { status: 'valid', raw: json.raw, definition };\n};\n\n/** The issues to show in the editor (none for a JSON syntax error: the JSON linter reports it). */\nexport const issuesOf = (analysis: FileAnalysis): ValidationIssue[] =>\n analysis.status === 'invalid' ? analysis.issues : [];\n","import {\n decideSync,\n serializeDefinition,\n type SchemaDefinition,\n type SyncConflictReason,\n type SyncDecision,\n} from '@shapio/schema';\nimport type { ExportedDefinition, SchemaDraftInput, SchemaExport } from '@/api/schemaFiles';\nimport type { SchemaFile } from './files';\n\n/**\n * The three-way guard of `shapio schema apply` (ADR 0002), run in the browser before anything is written:\n * the base is what the file was loaded from, local is the edited file, remote is the instance now.\n * Unchanged files are skipped, files changed only here become drafts, and a file whose definition also\n * moved on the instance refuses the whole apply, like a rejected non-fast-forward push.\n *\n * Sides are compared by their canonical serialization (what the lock file's hash is a SHA-256 of), so the\n * guard needs no Web Crypto: `crypto.subtle` is missing when the admin is opened over plain HTTP on a LAN.\n */\nexport type LocalDefinition = { definition: SchemaDefinition };\n\nexport type GuardItem = { file: SchemaFile; local: LocalDefinition };\n\nexport type GuardConflict = {\n file: SchemaFile;\n local: LocalDefinition;\n remote: ExportedDefinition | undefined;\n reason: SyncConflictReason;\n};\n\nexport type GuardResult =\n | { status: 'conflict'; conflicts: GuardConflict[] }\n | { status: 'ready'; drafts: SchemaDraftInput[]; skipped: number };\n\nconst draftOf = (\n item: GuardItem,\n decision: Extract<SyncDecision, { action: 'create' | 'update' }>,\n): SchemaDraftInput => ({\n definitionId: item.file.definitionId,\n category: item.file.category,\n definition: item.local.definition,\n baseVersion: decision.action === 'update' ? decision.expectedVersion : null,\n});\n\nexport const guardApply = (items: readonly GuardItem[], remote: SchemaExport): GuardResult => {\n const remoteById = new Map(remote.definitions.map((entry) => [entry.definition.id, entry]));\n const conflicts: GuardConflict[] = [];\n const drafts: SchemaDraftInput[] = [];\n let skipped = 0;\n for (const item of items) {\n const target = remoteById.get(item.file.definitionId);\n const decision = decideSync({\n local: { definition: item.local.definition, hash: serializeDefinition(item.local.definition) },\n base: { version: item.file.base.version, hash: item.file.base.text },\n remote: target\n ? {\n version: target.version,\n hash: serializeDefinition(target.definition),\n definition: target.definition,\n }\n : undefined,\n prune: false,\n });\n switch (decision.action) {\n case 'conflict':\n conflicts.push({ file: item.file, local: item.local, remote: target, reason: decision.reason });\n break;\n case 'create':\n case 'update':\n drafts.push(draftOf(item, decision));\n break;\n default:\n skipped += 1;\n }\n }\n return conflicts.length > 0 ? { status: 'conflict', conflicts } : { status: 'ready', drafts, skipped };\n};\n","import { useQueryClient } from '@tanstack/react-query';\nimport { useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { toast } from 'sonner';\nimport { useSaveDraftToChangeSet } from '@/api/changeSets';\nimport { schemaExportQueryOptions, type SchemaDraftInput } from '@/api/schemaFiles';\nimport { reportError } from '@/helpers/reportError';\nimport { analyzeFile } from '../helpers/analyze';\nimport type { SchemaFile } from '../helpers/files';\nimport { guardApply, type GuardConflict, type GuardItem } from '../helpers/guard';\nimport type { SchemaWorkspace } from './useSchemaWorkspace';\n\ntype ApplyFilesOptions = {\n /** A changed file that does not validate: the screen opens it. */\n onInvalid: (file: SchemaFile) => void;\n onConflict: (conflicts: GuardConflict[]) => void;\n /** The drafts are in the change set: the screen goes to its review. */\n onApplied: (changeSetId: string) => void;\n};\n\n/** Validated local definitions of every changed file, or the first file that does not validate. */\nconst localItems = (workspace: SchemaWorkspace): { items: GuardItem[] } | { invalid: SchemaFile } => {\n const items: GuardItem[] = [];\n for (const file of workspace.dirtyFiles) {\n const analysis = analyzeFile(workspace.textOf(file), {\n previous: file.base.definition,\n others: workspace.definitions.filter((definition) => definition.id !== file.definitionId),\n });\n if (analysis.status !== 'valid') {\n return { invalid: file };\n }\n items.push({ file, local: { definition: analysis.definition } });\n }\n return { items };\n};\n\n/**\n * \"Apply\": validates the changed files, runs the three-way guard against the instance as it is now\n * (refusing with the diff when a definition moved on both sides), then writes the files as schema drafts\n * of the open change set. Nothing goes live until the set ships from its review.\n */\nexport const useApplyFiles = ({ onInvalid, onConflict, onApplied }: ApplyFilesOptions) => {\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n const saveDraft = useSaveDraftToChangeSet();\n const [checking, setChecking] = useState(false);\n\n /** One draft per definition into the newest open set (the first call creates it when none is open). */\n const saveDrafts = async (drafts: readonly SchemaDraftInput[]) => {\n let changeSetId = '';\n for (const { definitionId, ...input } of drafts) {\n changeSetId = await saveDraft.mutateAsync({\n definitionId,\n input,\n newSetTitle: t('develop.schema.apply.newSetTitle'),\n });\n }\n return changeSetId;\n };\n\n const apply = async (workspace: SchemaWorkspace) => {\n setChecking(true);\n try {\n const local = localItems(workspace);\n if ('invalid' in local) {\n toast.error(t('develop.schema.apply.invalid', { path: local.invalid.path }));\n onInvalid(local.invalid);\n return;\n }\n const remote = await queryClient.fetchQuery(schemaExportQueryOptions);\n const result = guardApply(local.items, remote);\n if (result.status === 'conflict') {\n onConflict(result.conflicts);\n return;\n }\n if (result.drafts.length === 0) {\n toast.info(t('develop.schema.apply.nothing'));\n return;\n }\n onApplied(await saveDrafts(result.drafts));\n } catch (error) {\n reportError(error, 'apply schema files');\n } finally {\n setChecking(false);\n }\n };\n\n return { apply, pending: checking };\n};\n","import type { SchemaDefinition } from '@shapio/schema';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useSchemaExport, type ExportedDefinition, type SchemaExport } from '@/api/schemaFiles';\nimport { buildFiles, buildLockText, type SchemaFile } from '../helpers/files';\n\n/**\n * The files on screen and their edits. Until something is edited the files mirror the instance (like a\n * fresh pull); the first edit pins what they were loaded from, which is the base the three-way guard\n * compares against at apply time. `reload` drops every edit and pulls again.\n */\nexport type SchemaWorkspace = {\n schemaVersion: number;\n files: SchemaFile[];\n lockText: string;\n /** Every loaded definition (cross-definition checks run against these). */\n definitions: SchemaDefinition[];\n textOf: (file: SchemaFile) => string;\n setText: (file: SchemaFile, text: string) => void;\n dirtyFiles: SchemaFile[];\n isDirty: (file: SchemaFile) => boolean;\n /** Takes the instance's current version of one definition as the file's new base, dropping its edits. */\n takeRemote: (remote: ExportedDefinition) => void;\n /** Rebases the file's edits onto the instance's current version (they win over the remote changes). */\n keepLocal: (remote: ExportedDefinition) => void;\n reload: () => Promise<unknown>;\n};\n\nconst replaceDefinition = (loaded: SchemaExport, remote: ExportedDefinition): SchemaExport => ({\n ...loaded,\n definitions: loaded.definitions.map((entry) =>\n entry.definition.id === remote.definition.id ? remote : entry,\n ),\n});\n\nexport const useSchemaWorkspace = () => {\n const query = useSchemaExport();\n const [pinned, setPinned] = useState<SchemaExport | undefined>();\n const [texts, setTexts] = useState<Readonly<Record<string, string>>>({});\n const loaded = pinned ?? query.data;\n\n const files = useMemo(() => (loaded ? buildFiles(loaded) : []), [loaded]);\n const lockText = useMemo(() => (loaded ? buildLockText(loaded) : ''), [loaded]);\n const definitions = useMemo(() => files.map((file) => file.base.definition), [files]);\n\n const textOf = useCallback((file: SchemaFile) => texts[file.definitionId] ?? file.base.text, [texts]);\n const isDirty = useCallback(\n (file: SchemaFile) => {\n const text = texts[file.definitionId];\n return text !== undefined && text !== file.base.text;\n },\n [texts],\n );\n const setText = useCallback(\n (file: SchemaFile, text: string) => {\n setPinned((current) => current ?? loaded);\n setTexts((current) => ({ ...current, [file.definitionId]: text }));\n },\n [loaded],\n );\n const takeRemote = useCallback((remote: ExportedDefinition) => {\n setPinned((current) => (current ? replaceDefinition(current, remote) : current));\n setTexts(({ [remote.definition.id]: _dropped, ...rest }) => rest);\n }, []);\n const keepLocal = useCallback((remote: ExportedDefinition) => {\n setPinned((current) => (current ? replaceDefinition(current, remote) : current));\n }, []);\n const { refetch } = query;\n const reload = useCallback(async () => {\n setPinned(undefined);\n setTexts({});\n return refetch();\n }, [refetch]);\n\n const dirtyFiles = useMemo(() => files.filter(isDirty), [files, isDirty]);\n const workspace = useMemo<SchemaWorkspace | undefined>(\n () =>\n loaded\n ? {\n schemaVersion: loaded.schemaVersion,\n files,\n lockText,\n definitions,\n textOf,\n setText,\n dirtyFiles,\n isDirty,\n takeRemote,\n keepLocal,\n reload,\n }\n : undefined,\n [\n loaded,\n files,\n lockText,\n definitions,\n textOf,\n setText,\n dirtyFiles,\n isDirty,\n takeRemote,\n keepLocal,\n reload,\n ],\n );\n return { query, workspace };\n};\n","import { lazy, Suspense } from 'react';\nimport { LoadingState } from '@/components/LoadingState';\nimport { cn } from '@/helpers/cn';\nimport type { CodeMirrorViewProps } from './View';\n\n/** CodeMirror and its JSON-schema support load only when the Schema screen opens an editor. */\nconst View = lazy(() => import('./View').then((module) => ({ default: module.View })));\n\ntype CodeEditorProps = CodeMirrorViewProps & { className?: string };\n\n/** A JSON code editor with completion, hover and lint, framed like an input (focus ring on the frame). */\nexport const CodeEditor = ({ className, ...props }: CodeEditorProps) => (\n <div\n className={cn(\n 'min-h-0 overflow-hidden rounded-xl border bg-card focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50',\n className,\n )}\n >\n <Suspense fallback={<LoadingState rows={8} className=\"p-4\" />}>\n <View {...props} />\n </Suspense>\n </div>\n);\n","import { useTranslation } from 'react-i18next';\nimport { Panel } from '@/components/Panel';\nimport { CodeEditor } from '../CodeEditor';\nimport { LOCK_PATH } from '../helpers/files';\n\ntype LockFileProps = { text: string };\n\nconst noIssues = () => [];\n\n/** The lock file pull writes: what each file was loaded from (the base of the three-way guard). */\nexport const LockFile = ({ text }: LockFileProps) => {\n const { t } = useTranslation();\n return (\n <Panel title={LOCK_PATH} description={t('develop.schema.lockDescription')} flush>\n <CodeEditor\n className=\"h-[28rem] rounded-none border-0 xl:h-[40rem]\"\n value={text}\n onChange={noIssues}\n label={t('develop.schema.editorLabel', { path: LOCK_PATH })}\n readOnly\n schema={undefined}\n lint={noIssues}\n />\n </Panel>\n );\n};\n","import type { DefinitionCategory } from '@shapio/client';\nimport { ComponentDefinitionInputSchema, ModelDefinitionInputSchema, SETTINGS_SCHEMAS } from '@shapio/schema';\n\n/**\n * The JSON Schema behind the editor's completion and hover: the definition input schemas from\n * `@shapio/schema` (TypeBox, so already JSON Schema), with each field's `settings` narrowed to its data\n * type's settings schema. Validation is not taken from here: the semantic linter runs the server's own\n * validators (`parseDefinition`, `validateSchema`), so messages match the API and the CLI.\n */\n/** The subset of JSON Schema the TypeBox definition schemas use (what completion and hover read). */\nexport type JSONSchema7 = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JSONSchema7>;\n required?: string[];\n items?: JSONSchema7 | JSONSchema7[];\n enum?: unknown[];\n const?: unknown;\n anyOf?: JSONSchema7[];\n oneOf?: JSONSchema7[];\n allOf?: JSONSchema7[];\n if?: JSONSchema7;\n then?: JSONSchema7;\n patternProperties?: Record<string, JSONSchema7>;\n additionalProperties?: boolean | JSONSchema7;\n};\n\nconst plain = (schema: unknown): JSONSchema7 => JSON.parse(JSON.stringify(schema)) as JSONSchema7;\n\nconst withTypedSettings = (schema: JSONSchema7): JSONSchema7 => {\n const field = schema.properties?.fields?.items;\n if (field && !Array.isArray(field)) {\n field.allOf = Object.entries(SETTINGS_SCHEMAS).map(([type, settings]) => ({\n if: { properties: { type: { const: type } }, required: ['type'] },\n then: { properties: { settings: plain(settings) } },\n }));\n }\n return schema;\n};\n\nconst SCHEMAS: Record<DefinitionCategory, JSONSchema7> = {\n model: withTypedSettings(plain(ModelDefinitionInputSchema)),\n component: withTypedSettings(plain(ComponentDefinitionInputSchema)),\n};\n\nexport const editorSchemaFor = (category: DefinitionCategory): JSONSchema7 => SCHEMAS[category];\n","import type { SchemaDefinition, ValidationIssue } from '@shapio/schema';\nimport { useCallback, useMemo } from 'react';\nimport { useDebouncedValue } from '@/hooks/useDebouncedValue';\nimport { analyzeFile, issuesOf, type AnalyzeContext, type FileAnalysis } from '../helpers/analyze';\nimport type { SchemaFile } from '../helpers/files';\n\n/** How long typing pauses before the preview pane re-renders the definition. */\nconst PREVIEW_DEBOUNCE_MS = 300;\n\n/**\n * The open file's meaning for the preview pane (debounced while typing) and the editor's semantic lint\n * function. Cross-definition checks run against the other files as loaded.\n */\nexport const useFileAnalysisAndLint = (\n file: SchemaFile | undefined,\n text: string,\n definitions: readonly SchemaDefinition[],\n) => {\n const context = useMemo<AnalyzeContext | undefined>(\n () =>\n file\n ? {\n previous: file.base.definition,\n others: definitions.filter((definition) => definition.id !== file.definitionId),\n }\n : undefined,\n [file, definitions],\n );\n const debouncedText = useDebouncedValue(text, PREVIEW_DEBOUNCE_MS);\n const analysis = useMemo<FileAnalysis | undefined>(\n () => (context ? analyzeFile(debouncedText, context) : undefined),\n [context, debouncedText],\n );\n const lint = useCallback(\n (current: string): readonly ValidationIssue[] => (context ? issuesOf(analyzeFile(current, context)) : []),\n [context],\n );\n return { analysis, lint };\n};\n","import type { ValidationIssue } from '@shapio/schema';\nimport { useTranslation } from 'react-i18next';\n\ntype IssueListProps = { issues: readonly ValidationIssue[]; id?: string };\n\n/**\n * The open file's problems as text outside the editor (the editor marks them inline too), so they are\n * readable without hovering and announced to screen readers.\n */\nexport const IssueList = ({ issues, id }: IssueListProps) => {\n const { t } = useTranslation();\n if (issues.length === 0) {\n return null;\n }\n return (\n <div\n id={id}\n role=\"status\"\n className=\"space-y-1.5 rounded-lg border border-destructive/40 bg-destructive-muted p-3\"\n >\n <p className=\"text-sm font-semibold text-destructive\">\n {t('develop.schema.problems', { count: issues.length })}\n </p>\n <ul className=\"space-y-1 text-meta text-foreground\">\n {issues.map((issue) => (\n <li key={`${issue.path}:${issue.code}:${issue.message}`} className=\"break-words\">\n <code className=\"font-mono text-xs\">{issue.path || '/'}</code> {issue.message}\n </li>\n ))}\n </ul>\n </div>\n );\n};\n","import {\n effectiveFormLayout,\n effectiveLayout,\n entryLayoutOf,\n type ComponentDefinition,\n type FieldDefinition,\n type ModelDefinition,\n} from '@shapio/schema';\n\n/**\n * The form preview's sections, as the entry editor lays them out. A document (`effectiveLayout`): the entry\n * document (inline title, cover, canvas blocks), then the properties by group. A form\n * (`effectiveFormLayout`): one properties section per form section, no document section. `label`\n * undefined: the document, or fields outside any group.\n */\nexport type PreviewSection = {\n id: string;\n kind: 'document' | 'properties';\n label: string | undefined;\n fields: FieldDefinition[];\n};\n\nexport const previewSections = (model: ModelDefinition): PreviewSection[] => {\n if (entryLayoutOf(model) === 'form') {\n return effectiveFormLayout(model).sections.map((section) => ({\n id: `group-${section.id}`,\n kind: 'properties' as const,\n label: section.label,\n fields: section.fields,\n }));\n }\n const layout = effectiveLayout(model);\n const document = [layout.titleInline ? layout.title : undefined, layout.cover, ...layout.canvas].filter(\n (field): field is FieldDefinition => field !== undefined,\n );\n return [\n { id: 'document', kind: 'document' as const, label: undefined, fields: document },\n ...layout.propertyGroups.map((group) => ({\n id: `group-${group.id}`,\n kind: 'properties' as const,\n label: group.label,\n fields: group.fields,\n })),\n ].filter((section) => section.fields.length > 0);\n};\n\n/**\n * A component previewed on its own: its fields in a stand-in singleton (not localized, no drafts), so the\n * entry form's field editors can render it.\n */\nexport const previewHostOf = (component: ComponentDefinition): ModelDefinition => ({\n id: component.id,\n kind: 'singleton',\n apiKey: component.apiKey,\n label: component.label,\n localized: false,\n draftAndPublish: false,\n fields: component.fields,\n display: { ...(component.display.groups ? { groups: component.display.groups } : {}) },\n});\n","import { isComponentDefinition, isModelDefinition, type SchemaDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { LoadingState } from '@/components/LoadingState';\nimport type { FieldsEnvironment } from '@/fields/form/context';\nimport { EntryFields } from '@/fields/form/EntryFields';\nimport { FieldsProvider } from '@/fields/form/FieldsProvider';\nimport { createEntryFormStore } from '@/fields/form/store';\nimport { defaultFormValues } from '@/fields/helpers/formValues';\nimport { fieldGridModeOf } from '@/fields/helpers/widthClasses';\nimport { useRuntimeEditors } from '@/fields/runtime/useRuntimeEditors';\nimport { previewHostOf, previewSections } from '../../helpers/previewSections';\n\ntype FormPreviewProps = {\n definition: SchemaDefinition;\n /** Every loaded definition (relation targets, components); `definition` replaces its loaded version. */\n definitions: readonly SchemaDefinition[];\n};\n\nconst pickNothing = () => Promise.resolve(null);\n\n/**\n * The entry form the definition produces, read-only, with the same field editors and layout the entry\n * editor uses (default values filled in). Components are shown as their own fields.\n */\nexport const FormPreview = ({ definition, definitions }: FormPreviewProps) => {\n const { t } = useTranslation();\n const runtime = useRuntimeEditors();\n const model = useMemo(\n () => (isModelDefinition(definition) ? definition : previewHostOf(definition)),\n [definition],\n );\n const environment = useMemo<FieldsEnvironment>(() => {\n const all = [...definitions.filter((other) => other.id !== definition.id), definition];\n return {\n idPrefix: 'schema-preview-',\n model,\n models: new Map(all.filter(isModelDefinition).map((entry) => [entry.id, entry])),\n components: new Map(all.filter(isComponentDefinition).map((entry) => [entry.id, entry])),\n locale: null,\n entryId: null,\n readOnly: true,\n disabled: false,\n runtimeEditors: runtime.editors,\n pickMedia: pickNothing,\n };\n }, [definition, definitions, model, runtime.editors]);\n const store = useMemo(() => createEntryFormStore(defaultFormValues(model.fields)), [model]);\n\n if (runtime.isLoading) {\n return <LoadingState rows={4} />;\n }\n const sections = previewSections(model);\n if (sections.length === 0) {\n return <p className=\"text-sm text-muted-foreground\">{t('develop.schema.preview.noFields')}</p>;\n }\n return (\n <FieldsProvider environment={environment} store={store}>\n <div className=\"space-y-6\">\n {sections.map((section) => (\n <section key={section.id} aria-labelledby={`schema-preview-${section.id}`} className=\"space-y-3\">\n <h3\n id={`schema-preview-${section.id}`}\n className=\"text-xs font-semibold tracking-wide text-muted-foreground uppercase\"\n >\n {section.label ??\n (section.kind === 'document'\n ? t('develop.schema.preview.document')\n : t('develop.schema.preview.properties'))}\n </h3>\n <EntryFields fields={section.fields} mode={fieldGridModeOf(model)} />\n </section>\n ))}\n </div>\n </FieldsProvider>\n );\n};\n","import type { SchemaDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { graphqlSdl, type DefinitionLookup } from '../../helpers/shapes';\n\ntype GraphqlShapeProps = { definition: SchemaDefinition; lookup: DefinitionLookup };\n\n/** The definition's GraphQL type and root fields, as SDL. */\nexport const GraphqlShape = ({ definition, lookup }: GraphqlShapeProps) => {\n const { t } = useTranslation();\n const sdl = useMemo(() => graphqlSdl(definition, lookup), [definition, lookup]);\n return <CodeBlock label={t('develop.schema.preview.sdl')} code={sdl} />;\n};\n","import { classifyChanges, diffDefinitions, summarizeChanges, type SchemaDefinition } from '@shapio/schema';\nimport { CircleCheck } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport { BucketChip } from '@/features/Models/Builder/BucketChip';\nimport { describeChange } from '@/features/Models/helpers/describeChange';\nimport { groupByBucket } from '@/features/Models/helpers/planBuckets';\n\ntype PlanProps = { before: SchemaDefinition; after: SchemaDefinition };\n\n/**\n * What applying the file would change, classified like the builder's review (`diffDefinitions` +\n * `classifyChanges` against the version the file was loaded from). The server plans it again, with the\n * content checks, in the change set's review.\n */\nexport const Plan = ({ before, after }: PlanProps) => {\n const { t } = useTranslation();\n const changes = useMemo(\n () => classifyChanges(diffDefinitions(before, after), { before, after }),\n [before, after],\n );\n if (changes.length === 0) {\n return <EmptyState size=\"panel\" icon={CircleCheck} title={t('develop.schema.plan.none')} />;\n }\n const summary = summarizeChanges(changes);\n return (\n <div className=\"space-y-5\">\n {summary.breaking || summary.destructive ? (\n <Alert variant=\"warning\">\n <AlertDescription>\n {summary.destructive ? t('develop.schema.plan.destructive') : t('develop.schema.plan.breaking')}\n </AlertDescription>\n </Alert>\n ) : null}\n {!summary.supported ? (\n <Alert variant=\"destructive\">\n <AlertDescription>{t('develop.schema.plan.unsupported')}</AlertDescription>\n </Alert>\n ) : null}\n {groupByBucket(changes).map((group) => (\n <div key={group.bucket} className=\"space-y-2\">\n <BucketChip bucket={group.bucket} />\n <ul className=\"list-disc space-y-1 pl-5 text-sm\">\n {group.changes.map((change, index) => (\n <li key={`${change.kind}:${change.fieldId ?? ''}:${change.property ?? ''}:${index}`}>\n {describeChange(change, before, after)}\n </li>\n ))}\n </ul>\n </div>\n ))}\n <p className=\"text-meta text-muted-foreground\">{t('develop.schema.plan.serverChecks')}</p>\n </div>\n );\n};\n","import { isModelDefinition, type SchemaDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { Badge } from '@/components/ui/badge';\nimport { restEndpoints, restResponseSample, type DefinitionLookup } from '../../helpers/shapes';\n\ntype RestShapeProps = { definition: SchemaDefinition; lookup: DefinitionLookup };\n\n/** The REST endpoints the definition gets and an example delivery response. */\nexport const RestShape = ({ definition, lookup }: RestShapeProps) => {\n const { t } = useTranslation();\n const endpoints = restEndpoints(definition);\n const sample = useMemo(() => restResponseSample(definition, lookup), [definition, lookup]);\n return (\n <div className=\"space-y-5\">\n {isModelDefinition(definition) ? (\n <ul aria-label={t('develop.schema.preview.endpoints')} className=\"space-y-1.5\">\n {endpoints.map((endpoint) => (\n <li key={`${endpoint.method} ${endpoint.path}`} className=\"flex min-w-0 items-center gap-2\">\n <Badge variant=\"outline\" className=\"w-16 justify-center font-mono\">\n {endpoint.method}\n </Badge>\n <code className=\"min-w-0 truncate font-mono text-xs\">{endpoint.path}</code>\n {endpoint.scope === 'admin' ? (\n <Badge variant=\"secondary\" className=\"ml-auto shrink-0\">\n {t('develop.schema.preview.admin')}\n </Badge>\n ) : null}\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('develop.schema.preview.componentEndpoints')}</p>\n )}\n <CodeBlock\n label={\n isModelDefinition(definition)\n ? t('develop.schema.preview.responseSample')\n : t('develop.schema.preview.componentSample')\n }\n code={sample}\n />\n </div>\n );\n};\n","import { toTypeName } from '@shapio/schema';\n\n/**\n * One definition's declarations out of `shapio types generate`'s output (`GET /api/docs/typescript`): the\n * output type and its `…Input` type, each with its doc comment. Empty when the definition is not in it.\n */\nconst declarationOf = (source: string, name: string): string | undefined => {\n const start = source.indexOf(`export type ${name} = `);\n if (start < 0) {\n return undefined;\n }\n const commentStart = source.lastIndexOf('/**', start);\n const commentEnd = source.lastIndexOf('*/', start);\n // The doc comment directly above the declaration (only whitespace between them).\n const from =\n commentStart >= 0 && commentEnd > commentStart && source.slice(commentEnd + 2, start).trim() === ''\n ? commentStart\n : start;\n const end = source.indexOf('\\n};\\n', start);\n return end < 0 ? undefined : source.slice(from, end + 4);\n};\n\nexport const declarationsOf = (source: string, apiKey: string): string => {\n const name = toTypeName(apiKey);\n return [declarationOf(source, name), declarationOf(source, `${name}Input`)]\n .filter((part): part is string => part !== undefined)\n .join('\\n');\n};\n","import { FileType } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useTypeScriptDeclarations } from '@/api/apiDocs';\nimport { CodeBlock } from '@/components/CodeBlock';\nimport { EmptyState } from '@/components/EmptyState';\nimport { QueryView } from '@/components/QueryView';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport { declarationsOf } from '../../helpers/declarations';\n\ntype TypesProps = { apiKey: string; edited: boolean };\n\n/**\n * The definition's declarations from `shapio types generate` (`GET /api/docs/typescript`), i.e. of the\n * active version; edits show here once their change set ships.\n */\nexport const Types = ({ apiKey, edited }: TypesProps) => {\n const { t } = useTranslation();\n const query = useTypeScriptDeclarations();\n return (\n <QueryView query={query}>\n {({ source, schemaVersion }) => {\n const code = declarationsOf(source, apiKey);\n return (\n <div className=\"space-y-4\">\n {edited ? (\n <Alert variant=\"info\">\n <AlertDescription>\n {t('develop.schema.preview.typesActive', { version: schemaVersion })}\n </AlertDescription>\n </Alert>\n ) : null}\n {code ? (\n <CodeBlock label={t('develop.schema.preview.typescript')} code={code} />\n ) : (\n <EmptyState size=\"panel\" icon={FileType} title={t('develop.schema.preview.noTypes')} />\n )}\n </div>\n );\n }}\n </QueryView>\n );\n};\n","import type { SchemaDefinition } from '@shapio/schema';\nimport { FileWarning } from 'lucide-react';\nimport { useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { Panel } from '@/components/Panel';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport type { FileAnalysis } from '../helpers/analyze';\nimport type { SchemaFile } from '../helpers/files';\nimport { FormPreview } from './FormPreview';\nimport { GraphqlShape } from './GraphqlShape';\nimport { Plan } from './Plan';\nimport { RestShape } from './RestShape';\nimport { Types } from './Types';\n\nconst PREVIEW_TABS = ['form', 'rest', 'graphql', 'types', 'plan'] as const;\ntype PreviewTab = (typeof PREVIEW_TABS)[number];\n\nconst TAB_LABEL_KEYS = {\n form: 'develop.schema.preview.tabs.form',\n rest: 'develop.schema.preview.tabs.rest',\n graphql: 'develop.schema.preview.tabs.graphql',\n types: 'develop.schema.preview.tabs.types',\n plan: 'develop.schema.preview.tabs.plan',\n} as const satisfies Record<PreviewTab, string>;\n\ntype PreviewProps = {\n file: SchemaFile;\n analysis: FileAnalysis | undefined;\n edited: boolean;\n definitions: readonly SchemaDefinition[];\n};\n\n/** What the open file produces: the entry form, the REST and GraphQL shapes, the types and the plan. */\nexport const Preview = ({ file, analysis, edited, definitions }: PreviewProps) => {\n const { t } = useTranslation();\n const [tab, setTab] = useState<PreviewTab>('form');\n const definition = analysis?.status === 'valid' ? analysis.definition : undefined;\n const lookup = useMemo(\n () =>\n new Map(\n [\n ...definitions.filter((other) => other.id !== file.definitionId),\n ...(definition ? [definition] : []),\n ].map((entry) => [entry.id, entry]),\n ),\n [definitions, definition, file.definitionId],\n );\n const invalid = (\n <EmptyState\n size=\"panel\"\n icon={FileWarning}\n title={t('develop.schema.preview.invalidTitle')}\n description={t('develop.schema.preview.invalidDescription')}\n />\n );\n return (\n <Panel title={t('develop.schema.preview.title')} titleAs=\"h2\">\n <Tabs value={tab} onValueChange={(value) => setTab(value as PreviewTab)}>\n <TabsList variant=\"underline\" className=\"w-full justify-start overflow-x-auto\">\n {PREVIEW_TABS.map((value) => (\n <TabsTrigger key={value} value={value}>\n {t(TAB_LABEL_KEYS[value])}\n </TabsTrigger>\n ))}\n </TabsList>\n <TabsContent value=\"form\" className=\"pt-4\">\n {definition ? <FormPreview definition={definition} definitions={definitions} /> : invalid}\n </TabsContent>\n <TabsContent value=\"rest\" className=\"pt-4\">\n {definition ? <RestShape definition={definition} lookup={lookup} /> : invalid}\n </TabsContent>\n <TabsContent value=\"graphql\" className=\"pt-4\">\n {definition ? <GraphqlShape definition={definition} lookup={lookup} /> : invalid}\n </TabsContent>\n <TabsContent value=\"types\" className=\"pt-4\">\n <Types apiKey={file.apiKey} edited={edited} />\n </TabsContent>\n <TabsContent value=\"plan\" className=\"pt-4\">\n {definition ? <Plan before={file.base.definition} after={definition} /> : invalid}\n </TabsContent>\n </Tabs>\n </Panel>\n );\n};\n","import { useCallback, useId } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Panel } from '@/components/Panel';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Button } from '@/components/ui/button';\nimport { CodeEditor } from '../CodeEditor';\nimport { editorSchemaFor } from '../CodeEditor/helpers/editorSchema';\nimport { issuesOf } from '../helpers/analyze';\nimport type { SchemaFile } from '../helpers/files';\nimport { useFileAnalysisAndLint } from '../hooks/useFileAnalysisAndLint';\nimport type { SchemaWorkspace } from '../hooks/useSchemaWorkspace';\nimport { IssueList } from '../IssueList';\nimport { Preview } from '../Preview';\n\ntype WorkbenchProps = { file: SchemaFile; workspace: SchemaWorkspace };\n\n/** One open schema file: the editor (with its problems listed below it) and the preview pane. */\nexport const Workbench = ({ file, workspace }: WorkbenchProps) => {\n const { t } = useTranslation();\n const issuesId = useId();\n const { setText, textOf, isDirty, definitions } = workspace;\n const text = textOf(file);\n const edited = isDirty(file);\n const { analysis, lint } = useFileAnalysisAndLint(file, text, definitions);\n const onChange = useCallback((next: string) => setText(file, next), [setText, file]);\n const issues = analysis ? issuesOf(analysis) : [];\n return (\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <Panel\n title={file.path.slice(file.path.lastIndexOf('/') + 1)}\n description={file.path}\n flush\n actions={\n edited ? (\n <>\n <StatusChip tone=\"warning\" label={t('develop.schema.modified')} size=\"sm\" />\n <InlineConfirm\n tone=\"danger\"\n title={t('develop.schema.revertTitle')}\n description={t('develop.schema.revertDescription')}\n confirmLabel={t('develop.schema.revert')}\n onConfirm={() => setText(file, file.base.text)}\n trigger={\n <Button type=\"button\" size=\"sm\" variant=\"ghost\">\n {t('develop.schema.revert')}\n </Button>\n }\n />\n </>\n ) : null\n }\n >\n <CodeEditor\n className=\"h-[28rem] rounded-none border-0 xl:h-[40rem]\"\n value={text}\n onChange={onChange}\n label={t('develop.schema.editorLabel', { path: file.path })}\n describedBy={issuesId}\n readOnly={false}\n schema={editorSchemaFor(file.category)}\n lint={lint}\n />\n {analysis?.status === 'invalidJson' ? (\n <p role=\"status\" className=\"border-t px-5 py-3 text-meta text-destructive\">\n {t('develop.schema.invalidJson', { message: analysis.message })}\n </p>\n ) : null}\n {issues.length > 0 ? (\n <div className=\"border-t p-4\">\n <IssueList id={issuesId} issues={issues} />\n </div>\n ) : null}\n </Panel>\n <Preview file={file} analysis={analysis} edited={edited} definitions={definitions} />\n </div>\n );\n};\n","import { getRouteApi, useNavigate } from '@tanstack/react-router';\nimport { FileCode2, RefreshCw } from 'lucide-react';\nimport { useEffect, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useSchemaVersion } from '@/api/schema';\nimport { EmptyState } from '@/components/EmptyState';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { Alert, AlertDescription } from '@/components/ui/alert';\nimport { Button } from '@/components/ui/button';\nimport { UnsavedChangesGuard, type GuardedNavigation } from '@/components/UnsavedChangesGuard';\nimport { Conflicts } from './Conflicts';\nimport { FileNav } from './FileNav';\nimport { LOCK_PATH } from './helpers/files';\nimport type { GuardConflict } from './helpers/guard';\nimport { useApplyFiles } from './hooks/useApplyFiles';\nimport { useSchemaWorkspace, type SchemaWorkspace } from './hooks/useSchemaWorkspace';\nimport { LockFile } from './LockFile';\nimport { Workbench } from './Workbench';\n\nconst route = getRouteApi('/app/schema');\n\n/** Switching files (`?file=`) keeps the edits in the workspace; only leaving the screen asks. */\nconst leavesScreen = ({ currentPath, nextPath }: GuardedNavigation) => currentPath !== nextPath;\n\n/**\n * Schema as code (plan developer-face §2): the files `shapio schema pull` writes, edited in the browser\n * with completion and the server's own validation, previewed (form, REST, GraphQL, types, plan) and\n * applied as schema drafts of the open change set, behind the same three-way guard as the CLI.\n */\nexport const Schema = () => {\n const { t } = useTranslation();\n const { query, workspace } = useSchemaWorkspace();\n return (\n <Page width=\"full\">\n <QueryView query={query}>\n {() =>\n workspace ? (\n <SchemaFiles workspace={workspace} />\n ) : (\n <EmptyState icon={FileCode2} title={t('develop.schemaTitle')} />\n )\n }\n </QueryView>\n </Page>\n );\n};\n\ntype SchemaFilesProps = { workspace: SchemaWorkspace };\n\nconst SchemaFiles = ({ workspace }: SchemaFilesProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const { file: openPath } = route.useSearch();\n const liveVersion = useSchemaVersion().data;\n const [conflicts, setConflicts] = useState<GuardConflict[]>([]);\n const [appliedTo, setAppliedTo] = useState<string>();\n const { files, dirtyFiles } = workspace;\n const dirty = dirtyFiles.length > 0 && appliedTo === undefined;\n const applyFiles = useApplyFiles({\n onInvalid: (file) => void navigate({ to: '/schema', search: { file: file.path } }),\n onConflict: setConflicts,\n onApplied: setAppliedTo,\n });\n\n // After applying, the edits live in the change set: leave for its review once the guard has let go.\n useEffect(() => {\n if (appliedTo) {\n void navigate({ to: '/changes/$changeSetId', params: { changeSetId: appliedTo } });\n }\n }, [appliedTo, navigate]);\n\n const openFile =\n files.find((file) => file.path === openPath) ?? (openPath === LOCK_PATH ? undefined : files[0]);\n const showLock = openPath === LOCK_PATH || files.length === 0;\n const moved = liveVersion !== undefined && liveVersion !== workspace.schemaVersion;\n const conflictText = (conflict: GuardConflict) => workspace.textOf(conflict.file);\n const resolve = (definitionId: string) =>\n setConflicts((current) => current.filter((conflict) => conflict.file.definitionId !== definitionId));\n\n const reloadButton = (\n <Button type=\"button\" variant=\"outline\" disabled={applyFiles.pending}>\n <RefreshCw aria-hidden=\"true\" />\n {t('develop.schema.reload')}\n </Button>\n );\n return (\n <>\n <PageHeader\n title={t('develop.schemaTitle')}\n meta={t('develop.schema.meta', { version: workspace.schemaVersion, count: files.length })}\n actions={\n <>\n {dirty ? (\n <InlineConfirm\n tone=\"danger\"\n title={t('develop.schema.reloadTitle')}\n description={t('develop.schema.reloadDescription')}\n confirmLabel={t('develop.schema.reload')}\n onConfirm={() => {\n setConflicts([]);\n return workspace.reload();\n }}\n trigger={reloadButton}\n />\n ) : (\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={applyFiles.pending}\n onClick={() => {\n setConflicts([]);\n void workspace.reload();\n }}\n >\n <RefreshCw aria-hidden=\"true\" />\n {t('develop.schema.reload')}\n </Button>\n )}\n <Button\n type=\"button\"\n disabled={!dirty || applyFiles.pending}\n onClick={() => {\n setConflicts([]);\n void applyFiles.apply(workspace);\n }}\n >\n {applyFiles.pending\n ? t('develop.schema.applying')\n : t('develop.schema.apply.label', { count: dirtyFiles.length })}\n </Button>\n </>\n }\n />\n {moved ? (\n <Alert variant=\"info\" role=\"status\">\n <AlertDescription>\n {t('develop.schema.moved', { loaded: workspace.schemaVersion, live: liveVersion })}\n </AlertDescription>\n </Alert>\n ) : null}\n {conflicts.length > 0 ? (\n <Conflicts\n conflicts={conflicts}\n textOf={conflictText}\n onTakeRemote={(remote) => {\n workspace.takeRemote(remote);\n resolve(remote.definition.id);\n }}\n onKeepLocal={(remote) => {\n workspace.keepLocal(remote);\n resolve(remote.definition.id);\n }}\n />\n ) : null}\n <div className=\"flex flex-col gap-6 lg:flex-row\">\n <FileNav\n files={files}\n openPath={showLock || !openFile ? LOCK_PATH : openFile.path}\n isDirty={workspace.isDirty}\n />\n <div className=\"min-w-0 flex-1\">\n {showLock || !openFile ? (\n <LockFile text={workspace.lockText} />\n ) : (\n <Workbench key={openFile.definitionId} file={openFile} workspace={workspace} />\n )}\n </div>\n </div>\n <UnsavedChangesGuard when={dirty} shouldBlock={leavesScreen} />\n </>\n );\n};\n","import { useMemo } from 'react';\nimport { useDefinitions } from '@/api/schema';\nimport { usePrincipalUsage } from '@/api/usage';\nimport { useDevelopPermissions } from '../../Changes/hooks/useDevelopPermissions';\nimport { usePrincipalLabel } from '../../Changes/hooks/usePrincipalLabel';\n\n/**\n * Which readers last pinned each snapshot (`?snapshot=N` in their requests), from the usage counters.\n * Empty without `tokens.manage`.\n */\nexport const usePinnedBy = () => {\n const { canReadUsage } = useDevelopPermissions();\n const principalLabel = usePrincipalLabel();\n const models = useDefinitions('model');\n const modelIds = useMemo(() => (models.data ?? []).map(({ definition }) => definition.id), [models.data]);\n const { principals } = usePrincipalUsage(modelIds, canReadUsage);\n const bySeq = new Map<number, string[]>();\n for (const principal of principals) {\n if (principal.lastSnapshot !== null) {\n const names = bySeq.get(principal.lastSnapshot) ?? [];\n names.push(principalLabel(principal.principalKey, principal.tokenName));\n bySeq.set(principal.lastSnapshot, names);\n }\n }\n return { canReadUsage, pinnedBy: (seq: number) => bySeq.get(seq) ?? [] };\n};\n","import { Pin } from 'lucide-react';\nimport { useId, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { apiBaseUrl } from '@/api/client';\nimport { useApiTokens } from '@/api/tokens';\nimport { CopyButton } from '@/components/CopyButton';\nimport { Button } from '@/components/ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';\nimport { withSiteParameter } from '@/helpers/sites';\nimport { useDeliverySiteKey } from '@/hooks/useDeliverySiteKey';\n\ntype PinPopoverProps = {\n seq: number;\n /** The visible label; \"Pin\" by default. */\n label?: string;\n variant?: 'ghost' | 'outline';\n};\n\n/**\n * \"Pin a token\": pinning is done by the reader (it sends `snapshot=N` with its requests), so this shows the\n * request to make with the chosen token, ready to copy. The Live page then lists the token as pinned.\n */\nexport const PinPopover = ({ seq, label, variant = 'ghost' }: PinPopoverProps) => {\n const { t } = useTranslation();\n const titleId = useId();\n const selectId = useId();\n const [open, setOpen] = useState(false);\n const [tokenId, setTokenId] = useState<string | undefined>(undefined);\n const tokens = useApiTokens();\n const siteKey = useDeliverySiteKey();\n const active = (tokens.data ?? []).filter((token) => token.revokedAt === null);\n const token = active.find((candidate) => candidate.id === tokenId) ?? active[0];\n const path = withSiteParameter(`api/content/<model>?snapshot=${seq}`, siteKey);\n const snippet = `curl -H \"Authorization: Bearer ${token ? `${token.tokenPrefix}…` : '<token>'}\" \"${apiBaseUrl()}${path}\"`;\n return (\n <Popover open={open} onOpenChange={setOpen} modal>\n <PopoverTrigger asChild>\n <Button variant={variant} size=\"sm\" aria-label={label ? undefined : t('snapshots.pinLabel', { seq })}>\n <Pin aria-hidden=\"true\" />\n {label ?? t('snapshots.pin')}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n aria-labelledby={titleId}\n className=\"w-96 max-w-[calc(100vw-2rem)] space-y-3\"\n >\n <p id={titleId} className=\"text-sm font-semibold\">\n {t('snapshots.pinTitle', { seq })}\n </p>\n <p className=\"text-meta text-muted-foreground\">{t('snapshots.pinDescription')}</p>\n {active.length > 0 ? (\n <div className=\"space-y-1.5\">\n <label htmlFor={selectId} className=\"text-sm font-semibold\">\n {t('snapshots.pinToken')}\n </label>\n <Select value={token?.id} onValueChange={setTokenId}>\n <SelectTrigger id={selectId} size=\"sm\" className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {active.map((candidate) => (\n <SelectItem key={candidate.id} value={candidate.id}>\n {candidate.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n <pre className=\"overflow-x-auto rounded-lg bg-muted p-3 font-mono text-xs break-all whitespace-pre-wrap\">\n {snippet}\n </pre>\n <div className=\"flex justify-end\">\n <CopyButton value={snippet} />\n </div>\n </PopoverContent>\n </Popover>\n );\n};\n","import { useNavigate } from '@tanstack/react-router';\nimport { RotateCcw } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useRestoreSnapshot } from '@/api/snapshots';\nimport { InlineConfirm } from '@/components/InlineConfirm';\nimport { Button } from '@/components/ui/button';\n\ntype RestoreButtonProps = {\n seq: number;\n size?: 'sm' | 'default';\n /** A visible label that names the place itself (\"Restore to here\"); otherwise \"Restore\", named \"Restore vN\". */\n label?: string;\n};\n\n/**\n * Restore: creates a reviewable change set that brings live content back to snapshot `seq` (schema is not\n * rolled back), then opens it. Nothing goes live until that set ships.\n */\nexport const RestoreButton = ({ seq, size = 'sm', label }: RestoreButtonProps) => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const restore = useRestoreSnapshot();\n return (\n <InlineConfirm\n tone=\"default\"\n title={t('snapshots.restoreTitle', { seq })}\n description={t('snapshots.restoreDescription', { seq })}\n confirmLabel={t('snapshots.restore')}\n pendingLabel={t('common.saving')}\n onConfirm={() =>\n restore.mutateAsync(seq, {\n onSuccess: (set) => void navigate({ to: '/changes/$changeSetId', params: { changeSetId: set.id } }),\n })\n }\n trigger={\n <Button\n variant=\"outline\"\n size={size}\n aria-label={label ? undefined : t('snapshots.restoreLabel', { seq })}\n >\n <RotateCcw aria-hidden=\"true\" />\n {label ?? t('snapshots.restore')}\n </Button>\n }\n />\n );\n};\n","import type { Snapshot } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { GitCompare } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport {\n Table as TableRoot,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table';\nimport { formatDateTime, formatRelativeTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../Changes/hooks/useActorLabel';\nimport { SNAPSHOT_RUN_DISPLAY, SNAPSHOT_SOURCE_KEYS } from '../helpers/display';\nimport { PinPopover } from '../PinPopover';\nimport { RestoreButton } from '../RestoreButton';\n\ntype TableProps = {\n snapshots: Snapshot[];\n current: number;\n pinnedBy: (seq: number) => string[];\n showPins: boolean;\n};\n\n/** The ledger, newest first, deployments-style: version, when, who, what, pins, deploy, actions. */\nexport const Table = ({ snapshots, current, pinnedBy, showPins }: TableProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const none = t('common.none');\n return (\n <TableRoot>\n <TableHeader>\n <TableRow>\n <TableHead>{t('snapshots.fields.version')}</TableHead>\n <TableHead>{t('snapshots.fields.when')}</TableHead>\n <TableHead>{t('snapshots.fields.source')}</TableHead>\n <TableHead className=\"text-right\">{t('snapshots.fields.entries')}</TableHead>\n <TableHead>{t('snapshots.fields.schema')}</TableHead>\n {showPins ? <TableHead>{t('snapshots.fields.pinnedBy')}</TableHead> : null}\n <TableHead>{t('snapshots.fields.deploy')}</TableHead>\n <TableHead>\n <span className=\"sr-only\">{t('common.actions')}</span>\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {snapshots.map((snapshot) => {\n const pins = pinnedBy(snapshot.seq);\n const run = snapshot.deploymentRuns.at(-1);\n const runDisplay = run ? SNAPSHOT_RUN_DISPLAY[run.status] : undefined;\n return (\n <TableRow key={snapshot.seq}>\n <TableCell className=\"whitespace-nowrap\">\n <div className=\"flex items-center gap-2\">\n <RowTitle asChild>\n <Link to=\"/snapshots/$seq\" params={{ seq: String(snapshot.seq) }}>\n {t('snapshots.version', { seq: snapshot.seq })}\n </Link>\n </RowTitle>\n {snapshot.seq === current ? (\n <StatusChip tone=\"success\" label={t('snapshots.live')} size=\"sm\" />\n ) : null}\n </div>\n </TableCell>\n <TableCell className=\"whitespace-nowrap\" title={formatDateTime(snapshot.createdAt)}>\n {formatRelativeTime(snapshot.createdAt)}\n <span className=\"block text-meta text-muted-foreground\">{actorLabel(snapshot.actor)}</span>\n </TableCell>\n <TableCell className=\"max-w-64\">\n <Badge variant=\"secondary\">{t(SNAPSHOT_SOURCE_KEYS[snapshot.source])}</Badge>\n {snapshot.changeSetId && snapshot.changeSetTitle ? (\n <Link\n to=\"/changes/$changeSetId\"\n params={{ changeSetId: snapshot.changeSetId }}\n className=\"block truncate text-meta text-link underline-offset-4 hover:underline\"\n >\n {snapshot.changeSetTitle}\n </Link>\n ) : null}\n </TableCell>\n <TableCell className=\"text-right tabular-nums\">{snapshot.changedEntries}</TableCell>\n <TableCell className=\"whitespace-nowrap tabular-nums\">\n {snapshot.schemaVersion === null\n ? none\n : t('snapshots.schemaVersion', { version: snapshot.schemaVersion })}\n </TableCell>\n {showPins ? (\n <TableCell className=\"max-w-48\">\n {pins.length > 0 ? <span className=\"block truncate\">{pins.join(', ')}</span> : none}\n </TableCell>\n ) : null}\n <TableCell>\n {run && runDisplay ? (\n <Link\n to=\"/publishing/deployments/runs/$runId\"\n params={{ runId: run.id }}\n className=\"rounded-full\"\n >\n <StatusChip tone={runDisplay.tone} label={t(runDisplay.labelKey)} size=\"sm\" />\n </Link>\n ) : (\n none\n )}\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"flex justify-end gap-1\">\n {snapshot.seq !== current ? (\n <Button variant=\"ghost\" size=\"sm\" asChild>\n <Link\n to=\"/snapshots/$seq\"\n params={{ seq: String(current) }}\n search={{ from: snapshot.seq }}\n aria-label={t('snapshots.compareLabel', { seq: snapshot.seq, current })}\n >\n <GitCompare aria-hidden=\"true\" />\n {t('snapshots.compare')}\n </Link>\n </Button>\n ) : null}\n <PinPopover seq={snapshot.seq} />\n {snapshot.seq !== current ? <RestoreButton seq={snapshot.seq} /> : null}\n </div>\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </TableRoot>\n );\n};\n","import { useNavigate, useSearch } from '@tanstack/react-router';\nimport { Camera } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { useSnapshots } from '@/api/snapshots';\nimport { CursorPager } from '@/components/CursorPager';\nimport { EmptyState } from '@/components/EmptyState';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { TableCard } from '@/components/TableCard';\nimport { useCursorPager } from '@/features/Publishing/hooks/useCursorPager';\nimport { useDevelopPermissions } from '../Changes/hooks/useDevelopPermissions';\nimport { usePinnedBy } from './hooks/usePinnedBy';\nimport { Table } from './Table';\n\n/** Snapshots: every publication snapshot (`?snapshot=N`), deployments-style, with compare, restore and pin. */\nexport const Snapshots = () => {\n const { t } = useTranslation();\n const { canManageChanges } = useDevelopPermissions();\n const { cursor } = useSearch({ from: '/app/snapshots' });\n const navigate = useNavigate({ from: '/snapshots' });\n const { pagerProps } = useCursorPager(cursor, (next) => void navigate({ search: { cursor: next } }));\n const snapshots = useSnapshots(cursor);\n const { canReadUsage, pinnedBy } = usePinnedBy();\n if (!canManageChanges) {\n return (\n <Page width=\"full\">\n <PageHeader title={t('snapshots.title')} />\n <NoAccess />\n </Page>\n );\n }\n return (\n <Page width=\"full\">\n <PageHeader\n title={t('snapshots.title')}\n meta={snapshots.data ? t('snapshots.current', { seq: snapshots.data.current }) : undefined}\n />\n <QueryView\n query={snapshots}\n loadingRows={6}\n isEmpty={(data) => data.items.length === 0 && cursor === undefined}\n empty={<EmptyState icon={Camera} title={t('snapshots.empty')} />}\n >\n {(data) => (\n <TableCard footer={<CursorPager {...pagerProps(data.nextCursor)} />}>\n <Table\n snapshots={data.items}\n current={data.current}\n pinnedBy={pinnedBy}\n showPins={canReadUsage}\n />\n </TableCard>\n )}\n </QueryView>\n </Page>\n );\n};\n","import type { Snapshot } from '@shapio/client';\nimport { useTranslation } from 'react-i18next';\nimport { formatDateTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../../Changes/hooks/useActorLabel';\n\ntype HeaderProps = {\n seq: number;\n row: Snapshot | undefined;\n previous: number | undefined;\n /** Entries whose live content changed since `previous` (known once the thumb rests). */\n changedCount: number | undefined;\n};\n\n/** \"v38 · Sep 28, 14:10 · shipped by Ada · schema v11 · 3 entries changed since v37\", updated as the thumb moves. */\nexport const Header = ({ seq, row, previous, changedCount }: HeaderProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const parts = [\n t('snapshots.version', { seq }),\n row ? formatDateTime(row.createdAt) : '',\n row ? t('snapshots.timeline.shippedBy', { name: actorLabel(row.actor) }) : '',\n row?.schemaVersion != null ? t('snapshots.schemaVersion', { version: row.schemaVersion }) : '',\n previous !== undefined && changedCount !== undefined\n ? t('snapshots.timeline.changedSince', { count: changedCount, seq: previous })\n : '',\n ].filter(Boolean);\n return (\n <p aria-live=\"polite\" className=\"text-sm font-semibold tabular-nums\">\n {parts.join(' · ')}\n </p>\n );\n};\n","import { effectiveLayout, effectiveTitleField, routeKeyOf, type ModelDefinition } from '@shapio/schema';\nimport { useMemo } from 'react';\nimport { useLocales } from '@/api/locales';\nimport { useDefinitions } from '@/api/schema';\nimport type { TimelinePlace } from '@/api/snapshots';\n\nexport type PlaceWithLocales = TimelinePlace & { locales: string[] };\n\nconst placeOf = (model: ModelDefinition, locales: string[]): PlaceWithLocales => {\n const title = effectiveTitleField(model);\n const cover = effectiveLayout(model).cover;\n return {\n modelId: model.id,\n modelKey: model.apiKey,\n routeKey: routeKeyOf(model),\n label: model.label,\n singleton: model.kind === 'singleton',\n titleKey: title?.apiKey ?? null,\n coverKey: cover?.apiKey ?? null,\n locales,\n };\n};\n\n/**\n * The places the timeline reads, with the locales to read each in: every locale for localized models\n * (delivery reports the locale it actually served, so fallbacks merge), the default one otherwise.\n */\nexport const useTimelinePlaces = () => {\n const models = useDefinitions('model');\n const locales = useLocales();\n const places = useMemo(() => {\n if (!models.data || !locales.data) {\n return undefined;\n }\n const codes = locales.data.map((locale) => locale.code);\n const defaultLocale = locales.data.find((locale) => locale.isDefault)?.code ?? codes[0] ?? 'en';\n return models.data.flatMap(({ definition }) =>\n definition.kind === 'component'\n ? []\n : [placeOf(definition, definition.localized ? codes : [defaultLocale])],\n );\n }, [models.data, locales.data]);\n return { places, error: models.error ?? locales.error };\n};\n","import type { SnapshotChange, SnapshotChangeKind } from '@shapio/client';\n\n/** How a card moved between the snapshot before and this one. */\nexport type CardMark = 'unchanged' | 'added' | 'changed' | 'removed';\n\n/** One entry as delivery served it at a snapshot, in one locale (after fallback). */\nexport type LiveItem = { id: string; locale: string; title: string | null; coverUrl: string | null };\n\nexport type TimelineCard = {\n id: string;\n title: string | null;\n coverUrl: string | null;\n /** Locales the entry is live in at this snapshot (a removed card: the ones it was live in). */\n locales: string[];\n mark: CardMark;\n /** Revision per locale, where the diff names it (changed, added, removed locales). */\n revisionIds: Record<string, string>;\n};\n\nconst markOf = (kinds: readonly SnapshotChangeKind[], live: boolean): CardMark => {\n if (!live) {\n return 'removed';\n }\n if (kinds.length > 0 && kinds.every((kind) => kind === 'published')) {\n return 'added';\n }\n return kinds.length > 0 ? 'changed' : 'unchanged';\n};\n\n/**\n * One place's cards at a snapshot: every entry live there (merged across locales), marked against the\n * snapshot before from the diff between the two; entries the diff unpublished and that are no longer live\n * come back as `removed` cards described by the diff. Live cards keep the order delivery served them in;\n * removed ones follow.\n */\nexport const buildCards = (live: readonly LiveItem[], changes: readonly SnapshotChange[]): TimelineCard[] => {\n const byId = new Map<string, TimelineCard>();\n for (const item of live) {\n const card = byId.get(item.id);\n if (card) {\n if (!card.locales.includes(item.locale)) {\n card.locales.push(item.locale);\n }\n card.title ??= item.title;\n card.coverUrl ??= item.coverUrl;\n continue;\n }\n byId.set(item.id, {\n id: item.id,\n title: item.title,\n coverUrl: item.coverUrl,\n locales: [item.locale],\n mark: 'unchanged',\n revisionIds: {},\n });\n }\n const removed: TimelineCard[] = [];\n for (const change of changes) {\n const card = byId.get(change.id);\n const revisionIds = Object.fromEntries(\n change.locales.flatMap(({ locale, revisionId }) => (revisionId ? [[locale, revisionId]] : [])),\n );\n const mark = markOf(\n change.locales.map(({ change: kind }) => kind),\n card !== undefined,\n );\n if (card) {\n card.mark = mark;\n card.revisionIds = revisionIds;\n card.title ??= change.title;\n } else if (mark === 'removed') {\n removed.push({\n id: change.id,\n title: change.title,\n coverUrl: null,\n locales: change.locales.map(({ locale }) => locale),\n mark,\n revisionIds,\n });\n }\n }\n return [...byId.values(), ...removed];\n};\n\n/** Every `step`-th snapshot gets a tick, so a long ledger keeps at most `maxTicks` of them. */\nexport const tickStep = (count: number, maxTicks = 60): number =>\n count <= maxTicks ? 1 : Math.ceil(count / maxTicks);\n","import { useId, type CSSProperties, type KeyboardEvent } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/helpers/cn';\nimport { tickStep } from '../helpers/cards';\n\ntype SliderProps = {\n /** Snapshot numbers, oldest first. */\n seqs: readonly number[];\n value: number;\n onChange: (seq: number) => void;\n};\n\nconst SHIFT_STEP = 10;\n\n/**\n * The time scrubber: a range over every snapshot in the ledger, with ticks (every k-th when the ledger is\n * long) that jump on click. Arrows step one snapshot, Shift+arrows ten, Home/End go to either end.\n */\nexport const Slider = ({ seqs, value, onChange }: SliderProps) => {\n const { t } = useTranslation();\n const inputId = useId();\n const index = Math.max(seqs.indexOf(value), 0);\n const last = Math.max(seqs.length - 1, 1);\n const step = tickStep(seqs.length);\n const go = (next: number) => {\n const seq = seqs[Math.min(Math.max(next, 0), seqs.length - 1)];\n if (seq !== undefined && seq !== value) {\n onChange(seq);\n }\n };\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (!event.shiftKey) {\n return;\n }\n const delta = { ArrowLeft: -1, ArrowDown: -1, ArrowRight: 1, ArrowUp: 1 }[event.key];\n if (delta !== undefined) {\n event.preventDefault();\n go(index + delta * SHIFT_STEP);\n }\n };\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-3\">\n <label htmlFor={inputId} className=\"text-sm font-semibold\">\n {t('snapshots.scrubber.label')}\n </label>\n <span className=\"text-meta text-muted-foreground tabular-nums\">\n {t('snapshots.scrubber.range', { min: seqs[0] ?? value, max: seqs.at(-1) ?? value })}\n </span>\n </div>\n <input\n id={inputId}\n type=\"range\"\n min={0}\n max={seqs.length - 1}\n step={1}\n value={index}\n aria-valuetext={t('snapshots.version', { seq: value })}\n onKeyDown={onKeyDown}\n onChange={(event) => go(Number(event.target.value))}\n className=\"h-2 w-full cursor-pointer accent-primary focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none\"\n />\n {/* Mouse shortcuts only: the slider itself is the keyboard control. */}\n <div aria-hidden=\"true\" className=\"relative mx-2 h-5\">\n {seqs.map((seq, position) =>\n position % step === 0 || position === seqs.length - 1 ? (\n <button\n key={seq}\n type=\"button\"\n tabIndex={-1}\n title={t('snapshots.version', { seq })}\n onClick={() => onChange(seq)}\n style={{ '--tick': `${(position / last) * 100}%` } as CSSProperties}\n className={cn(\n 'absolute top-0 left-(--tick) h-3 w-px -translate-x-1/2 cursor-pointer bg-border hover:bg-foreground',\n seq === value && 'h-4 w-0.5 bg-primary',\n )}\n />\n ) : null,\n )}\n </div>\n </div>\n );\n};\n","import { useQueries, useQueryClient } from '@tanstack/react-query';\nimport { useEffect } from 'react';\nimport { snapshotPlaceQueryOptions, useSnapshotChanges } from '@/api/snapshots';\nimport { buildCards, type LiveItem, type TimelineCard } from '../helpers/cards';\nimport type { PlaceWithLocales } from './useTimelinePlaces';\n\ntype CoverValue = { url?: unknown; variants?: Array<{ name?: unknown; url?: unknown }> };\n\n/** The cover's thumbnail variant when it has one, else its file URL. */\nconst coverUrlOf = (value: unknown): string | null => {\n if (typeof value !== 'object' || value === null) {\n return null;\n }\n const cover = value as CoverValue;\n const thumbnail = cover.variants?.find((variant) => variant.name === 'thumbnail')?.url;\n if (typeof thumbnail === 'string') {\n return thumbnail;\n }\n return typeof cover.url === 'string' ? cover.url : null;\n};\n\nconst liveItemOf = (place: PlaceWithLocales, item: Record<string, unknown>): LiveItem => {\n const title = place.titleKey ? item[place.titleKey] : undefined;\n return {\n id: String(item.id),\n locale: String(item.locale),\n title:\n typeof title === 'string' && title.trim() !== ''\n ? title\n : typeof title === 'number'\n ? String(title)\n : null,\n coverUrl: place.coverKey ? coverUrlOf(item[place.coverKey]) : null,\n };\n};\n\nexport type PlaceState = { place: PlaceWithLocales; cards: TimelineCard[] };\n\nconst readsOf = (seq: number, places: readonly PlaceWithLocales[]) =>\n places.flatMap((place) => place.locales.map((locale) => ({ place, locale, seq })));\n\n/**\n * The content system at snapshot `seq`: each place's live entries (read through delivery, per locale),\n * marked against `previous` with the snapshot diff. The neighbours are prefetched so dragging is smooth;\n * every read is cached per snapshot (a snapshot never changes).\n */\nexport const useStateAt = (\n seq: number,\n previous: number | undefined,\n neighbours: readonly number[],\n places: readonly PlaceWithLocales[],\n) => {\n const queryClient = useQueryClient();\n const reads = readsOf(seq, places);\n const changes = useSnapshotChanges(previous ?? 0, seq, previous !== undefined);\n const live = useQueries({\n queries: reads.map(({ place, locale }) => snapshotPlaceQueryOptions(seq, place, locale)),\n combine: (results) => ({\n data: results.map((result) => result.data),\n isPending: results.some((result) => result.isPending),\n error: results.find((result) => result.error)?.error ?? null,\n refetch: () => Promise.all(results.map((result) => result.refetch())),\n }),\n });\n\n useEffect(() => {\n for (const neighbour of neighbours) {\n for (const read of readsOf(neighbour, places)) {\n void queryClient.prefetchQuery(snapshotPlaceQueryOptions(neighbour, read.place, read.locale));\n }\n }\n }, [neighbours, places, queryClient]);\n\n const diff = changes.data?.items ?? [];\n const states: PlaceState[] = places.map((place) => {\n const items = reads.flatMap((read, index) =>\n read.place === place ? (live.data[index] ?? []).map((item) => liveItemOf(place, item)) : [],\n );\n return {\n place,\n cards: buildCards(\n items,\n diff.filter((change) => change.modelId === place.modelId),\n ),\n };\n });\n return {\n states: states.filter((state) => state.cards.length > 0),\n isPending: live.isPending || (previous !== undefined && changes.isPending),\n error: live.error ?? changes.error,\n refetch: () => Promise.all([live.refetch(), changes.refetch()]),\n };\n};\n","import { History, ImageOff } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { StatusChip, type StatusTone } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/helpers/cn';\nimport type { CardMark, TimelineCard } from '../helpers/cards';\n\nconst MARK_DISPLAY = {\n unchanged: { labelKey: 'snapshots.timeline.marks.unchanged', tone: 'success' },\n added: { labelKey: 'snapshots.timeline.marks.added', tone: 'success' },\n changed: { labelKey: 'snapshots.timeline.marks.changed', tone: 'warning' },\n removed: { labelKey: 'snapshots.timeline.marks.removed', tone: 'muted' },\n} as const satisfies Record<CardMark, { labelKey: string; tone: StatusTone }>;\n\n/** Appear, pulse once, or fade: replayed whenever the card is re-keyed for a new snapshot. No motion when reduced. */\nconst MARK_CLASSES = {\n unchanged: '',\n added: 'animate-in fade-in zoom-in-95 duration-500',\n changed: 'ring-2 ring-warning animate-in zoom-in-95 duration-500',\n removed: 'border-dashed bg-muted/40 animate-in fade-in duration-500',\n} as const satisfies Record<CardMark, string>;\n\ntype CardProps = { card: TimelineCard; onOpen: (card: TimelineCard) => void };\n\n/** One entry as it was at the snapshot: cover, title, live locales, what happened to it, and its version. */\nexport const Card = ({ card, onOpen }: CardProps) => {\n const { t } = useTranslation();\n const display = MARK_DISPLAY[card.mark];\n const title = card.title ?? t('snapshots.timeline.untitled');\n return (\n <li\n data-mark={card.mark}\n aria-label={t('snapshots.timeline.cardLabel', { title, state: t(display.labelKey) })}\n className={cn(\n 'flex min-w-0 flex-col overflow-hidden rounded-xl border bg-card motion-reduce:animate-none',\n MARK_CLASSES[card.mark],\n )}\n >\n <div\n className={cn(\n 'flex aspect-video items-center justify-center bg-muted transition-opacity duration-500 motion-reduce:transition-none',\n card.mark === 'removed' && 'opacity-40 grayscale',\n )}\n >\n {card.coverUrl ? (\n <img src={card.coverUrl} alt=\"\" loading=\"lazy\" className=\"size-full object-cover\" />\n ) : (\n <ImageOff aria-hidden=\"true\" className=\"size-5 text-muted-foreground\" />\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-2 p-3\">\n <p className={cn('line-clamp-2 text-sm font-semibold', card.mark === 'removed' && 'line-through')}>\n {title}\n </p>\n <div className=\"flex flex-wrap items-center gap-1.5\">\n <StatusChip tone={display.tone} label={t(display.labelKey)} size=\"sm\" live={false} />\n {card.locales.map((locale) => (\n <Badge key={locale} variant=\"outline\" className=\"font-mono\">\n {locale}\n </Badge>\n ))}\n </div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"mt-auto self-start\"\n aria-label={t('snapshots.timeline.openVersionOf', { title })}\n onClick={() => onOpen(card)}\n >\n <History aria-hidden=\"true\" />\n {t('snapshots.timeline.openVersion')}\n </Button>\n </div>\n </li>\n );\n};\n","import { useQueryClient } from '@tanstack/react-query';\nimport { useNavigate } from '@tanstack/react-router';\nimport { toast } from 'sonner';\nimport { adminApi } from '@/api/client';\nimport { queryKeys } from '@/api/queryKeys';\nimport { describeError } from '@/helpers/describeError';\nimport { logError } from '@/helpers/reportError';\nimport type { TimelineCard } from '../helpers/cards';\n\n/** Revisions that can have gone live, newest first among those that existed at the snapshot. */\nconst PUBLISHING_REASONS: ReadonlySet<string> = new Set(['publish', 'restore']);\n\n/**\n * \"Open this version\": the entry's history at the revision it served at the snapshot. The diff names that\n * revision for entries that changed at the snapshot; for the others it is the newest published (or\n * restored) revision of the locale from before the snapshot was taken.\n */\nexport const useOpenVersion = (modelKey: string, snapshotCreatedAt: string | undefined) => {\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const revisionAt = async (entryId: string, locale: string) => {\n const revisions = await queryClient.fetchQuery({\n queryKey: queryKeys.content.revisions(modelKey, entryId, locale),\n queryFn: () => adminApi.content.revisions(modelKey, entryId, { locale }),\n });\n const before = revisions.filter(\n (revision) => snapshotCreatedAt === undefined || revision.createdAt <= snapshotCreatedAt,\n );\n const newest = (list: typeof before) =>\n [...list].sort((a, b) => b.createdAt.localeCompare(a.createdAt))[0]?.id;\n return newest(before.filter((revision) => PUBLISHING_REASONS.has(revision.reason))) ?? newest(before);\n };\n return async (card: TimelineCard) => {\n const locale = card.locales[0];\n try {\n const revision =\n (locale ? card.revisionIds[locale] : undefined) ??\n (locale ? await revisionAt(card.id, locale) : undefined);\n await navigate({\n to: '/content/$modelKey/$entryId',\n params: { modelKey, entryId: card.id },\n search: { ...(locale ? { locale } : {}), ...(revision ? { revision } : {}) },\n });\n } catch (error) {\n logError(error, 'opening an entry version from the timeline');\n toast.error(describeError(error));\n }\n };\n};\n","import { useTranslation } from 'react-i18next';\nimport { Card } from '../Card';\nimport { useOpenVersion } from '../hooks/useOpenVersion';\nimport type { PlaceState } from '../hooks/useStateAt';\n\ntype PlaceSectionProps = { state: PlaceState; seq: number; snapshotCreatedAt: string | undefined };\n\n/** One place at the snapshot: its entries as a grid of cards (2-up on phones). */\nexport const PlaceSection = ({ state, seq, snapshotCreatedAt }: PlaceSectionProps) => {\n const { t } = useTranslation();\n const openVersion = useOpenVersion(state.place.modelKey, snapshotCreatedAt);\n const live = state.cards.filter((card) => card.mark !== 'removed').length;\n return (\n <section aria-label={state.place.label} className=\"space-y-3\">\n <h3 className=\"flex items-baseline gap-2 text-base font-semibold\">\n {state.place.label}\n <span className=\"text-meta font-normal text-muted-foreground\">\n {t('snapshots.timeline.liveCount', { count: live })}\n </span>\n </h3>\n <ul className=\"grid grid-cols-2 gap-3 md:grid-cols-3 xl:grid-cols-4\">\n {state.cards.map((card) => (\n // Marked cards are re-keyed per snapshot so their animation plays again.\n <Card\n key={card.mark === 'unchanged' ? card.id : `${card.id}:${seq}`}\n card={card}\n onOpen={(opened) => void openVersion(opened)}\n />\n ))}\n </ul>\n </section>\n );\n};\n","import { Clock } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { ErrorState } from '@/components/ErrorState';\nimport { LoadingState } from '@/components/LoadingState';\nimport { useStateAt } from '../hooks/useStateAt';\nimport type { PlaceWithLocales } from '../hooks/useTimelinePlaces';\nimport { PlaceSection } from '../PlaceSection';\n\ntype StageProps = {\n seq: number;\n /** Every snapshot, oldest first: the stage prefetches the ones beside `seq`. */\n seqs: readonly number[];\n previous: number | undefined;\n places: PlaceWithLocales[];\n createdAt: string | undefined;\n};\n\n/** The content system at one snapshot: a section of cards per place that had entries then. */\nexport const Stage = ({ seq, seqs, previous, places, createdAt }: StageProps) => {\n const { t } = useTranslation();\n const index = seqs.indexOf(seq);\n const before = seqs[index - 1];\n const after = seqs[index + 1];\n const neighbours = useMemo(\n () => [before, after].filter((neighbour): neighbour is number => neighbour !== undefined),\n [before, after],\n );\n const state = useStateAt(seq, previous, neighbours, places);\n if (state.error) {\n return <ErrorState error={state.error} onRetry={() => void state.refetch()} />;\n }\n if (state.isPending && state.states.length === 0) {\n return <LoadingState rows={4} />;\n }\n if (state.states.length === 0) {\n return <EmptyState icon={Clock} title={t('snapshots.timeline.nothingLive', { seq })} />;\n }\n return (\n <div aria-busy={state.isPending || undefined} className=\"space-y-8\">\n {state.states.map((placeState) => (\n <PlaceSection\n key={placeState.place.modelId}\n state={placeState}\n seq={seq}\n snapshotCreatedAt={createdAt}\n />\n ))}\n </div>\n );\n};\n","import { useEffect, useMemo, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useSnapshotChanges, useSnapshotLedger } from '@/api/snapshots';\nimport { ErrorState } from '@/components/ErrorState';\nimport { LoadingState } from '@/components/LoadingState';\nimport { Panel } from '@/components/Panel';\nimport { useDebouncedValue } from '@/hooks/useDebouncedValue';\nimport { PinPopover } from '../PinPopover';\nimport { RestoreButton } from '../RestoreButton';\nimport { Header } from './Header';\nimport { useTimelinePlaces } from './hooks/useTimelinePlaces';\nimport { Slider } from './Slider';\nimport { Stage } from './Stage';\n\n/** While dragging, reads wait this long after the thumb stops (the thumb and header move at once). */\nconst DRAG_DEBOUNCE_MS = 150;\n\ntype TimelineProps = {\n /** The snapshot to start at (`?at=`). */\n at: number;\n /** Remembers the position in the URL, so it can be shared. */\n onAtChange: (seq: number) => void;\n};\n\n/**\n * The time scrubber: drag across every snapshot and see the content as it was then. The thumb and the\n * header follow at once; the cards follow once dragging pauses, marked against the snapshot before\n * (new, changed, removed). Restore to here and Pin a token here act on the position.\n */\nexport const Timeline = ({ at, onAtChange }: TimelineProps) => {\n const { t } = useTranslation();\n const ledger = useSnapshotLedger();\n const { places, error: placesError } = useTimelinePlaces();\n const [position, setPosition] = useState(at);\n const settled = useDebouncedValue(position, DRAG_DEBOUNCE_MS);\n const seqs = useMemo(\n () => (ledger.data ? ledger.data.items.map((row) => row.seq).sort((a, b) => a - b) : []),\n [ledger.data],\n );\n useEffect(() => {\n if (settled !== at) {\n onAtChange(settled);\n }\n }, [settled, at, onAtChange]);\n\n // Before the oldest snapshot in the ledger, compare with the number just before it (0: nothing live).\n const previousOf = (seq: number) => seqs[seqs.indexOf(seq) - 1] ?? (seq > 0 ? seq - 1 : undefined);\n const settledPrevious = previousOf(settled);\n // The same diff the stage marks its cards with (one request, cached per pair).\n const settledChanges = useSnapshotChanges(settledPrevious ?? 0, settled, settledPrevious !== undefined);\n\n if (ledger.isError || placesError) {\n return <ErrorState error={ledger.error ?? placesError} onRetry={() => void ledger.refetch()} />;\n }\n if (!ledger.data || !places) {\n return <LoadingState rows={4} />;\n }\n const row = ledger.data.items.find((item) => item.seq === position);\n const settledRow = ledger.data.items.find((item) => item.seq === settled);\n const current = ledger.data.current;\n return (\n <div className=\"space-y-6\">\n <Panel aria-label={t('snapshots.timeline.label')}>\n <div className=\"space-y-4\">\n <Header\n seq={position}\n row={row}\n previous={previousOf(position)}\n changedCount={position === settled ? settledChanges.data?.items.length : undefined}\n />\n <Slider seqs={seqs} value={position} onChange={setPosition} />\n <div className=\"flex flex-wrap gap-2\">\n {position === current ? null : (\n <RestoreButton seq={position} size=\"default\" label={t('snapshots.timeline.restoreHere')} />\n )}\n <PinPopover seq={position} variant=\"outline\" label={t('snapshots.timeline.pinHere')} />\n </div>\n </div>\n </Panel>\n <Stage\n seq={settled}\n seqs={seqs}\n previous={settledPrevious}\n places={places}\n createdAt={settledRow?.createdAt}\n />\n </div>\n );\n};\n","import type { SnapshotChangeKind, SnapshotChangesPage } from '@shapio/client';\nimport { Link } from '@tanstack/react-router';\nimport { FileStack } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { EmptyState } from '@/components/EmptyState';\nimport { RowTitle } from '@/components/RowTitle';\nimport { StatusChip } from '@/components/StatusChip';\nimport { TableCard } from '@/components/TableCard';\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';\n\nconst CHANGE_DISPLAY = {\n published: { labelKey: 'snapshots.changes.published', tone: 'success' },\n updated: { labelKey: 'snapshots.changes.updated', tone: 'warning' },\n unpublished: { labelKey: 'snapshots.changes.unpublished', tone: 'muted' },\n} as const satisfies Record<SnapshotChangeKind, { labelKey: string; tone: 'success' | 'warning' | 'muted' }>;\n\ntype ChangeListProps = { page: SnapshotChangesPage };\n\n/** Entries whose live content differs between two snapshots, with what happened per locale. */\nexport const ChangeList = ({ page }: ChangeListProps) => {\n const { t } = useTranslation();\n const { schemaVersions } = page;\n const schemaMoved = schemaVersions.from !== schemaVersions.to;\n return (\n <TableCard\n toolbar={\n <p className=\"text-meta text-muted-foreground\">\n {t(page.nextCursor ? 'snapshots.diffSummaryMore' : 'snapshots.diffSummary', {\n from: page.from,\n to: page.to,\n count: page.items.length,\n })}\n {schemaMoved\n ? ` · ${t('snapshots.schemaMoved', { from: schemaVersions.from ?? '?', to: schemaVersions.to ?? '?' })}`\n : ''}\n </p>\n }\n >\n {page.items.length === 0 ? (\n <EmptyState icon={FileStack} size=\"panel\" title={t('snapshots.noChanges')} />\n ) : (\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('changes.fields.entry')}</TableHead>\n <TableHead>{t('changes.fields.model')}</TableHead>\n <TableHead>{t('snapshots.fields.locales')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {page.items.map((entry) => (\n <TableRow key={entry.id}>\n <TableCell className=\"max-w-72\">\n <RowTitle asChild className=\"block truncate font-mono text-xs\">\n <Link\n to=\"/content/$modelKey/$entryId\"\n params={{ modelKey: entry.modelKey, entryId: entry.id }}\n >\n {entry.id}\n </Link>\n </RowTitle>\n </TableCell>\n <TableCell className=\"font-mono text-xs\">{entry.modelKey}</TableCell>\n <TableCell>\n <ul className=\"flex flex-wrap gap-1.5\">\n {entry.locales.map((locale) => {\n const display = CHANGE_DISPLAY[locale.change];\n return (\n <li key={locale.locale}>\n <StatusChip\n tone={display.tone}\n size=\"sm\"\n label={t('snapshots.localeChange', {\n locale: locale.locale,\n change: t(display.labelKey),\n })}\n />\n </li>\n );\n })}\n </ul>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </TableCard>\n );\n};\n","import type { Snapshot } from '@shapio/client';\nimport { linkOptions, useNavigate, useSearch } from '@tanstack/react-router';\nimport { useCallback } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useSnapshotChanges, useSnapshots } from '@/api/snapshots';\nimport { Page } from '@/components/Page';\nimport { PageHeader } from '@/components/PageHeader';\nimport { QueryView } from '@/components/QueryView';\nimport { StatusChip } from '@/components/StatusChip';\nimport { Badge } from '@/components/ui/badge';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { formatDateTime } from '@/helpers/formatDate';\nimport { useActorLabel } from '../../../Changes/hooks/useActorLabel';\nimport { SNAPSHOT_SOURCE_KEYS } from '../../helpers/display';\nimport { PinPopover } from '../../PinPopover';\nimport { RestoreButton } from '../../RestoreButton';\nimport { SNAPSHOT_TABS, type SnapshotTab } from '../../searchSchema';\nimport { Timeline } from '../../Timeline';\nimport { ChangeList } from '../ChangeList';\n\nconst TAB_LABEL_KEYS = {\n diff: 'snapshots.tabs.diff',\n timeline: 'snapshots.tabs.timeline',\n} as const satisfies Record<SnapshotTab, string>;\n\ntype ViewProps = { snapshot: Snapshot };\n\nexport const View = ({ snapshot }: ViewProps) => {\n const { t } = useTranslation();\n const actorLabel = useActorLabel();\n const search = useSearch({ from: '/app/snapshots/$seq' });\n const navigate = useNavigate({ from: '/snapshots/$seq' });\n const tab = search.tab ?? 'diff';\n const onAtChange = useCallback(\n (at: number) => void navigate({ search: (prev) => ({ ...prev, at }), replace: true }),\n [navigate],\n );\n const from = search.from !== undefined && search.from < snapshot.seq ? search.from : snapshot.seq - 1;\n const ledger = useSnapshots(undefined);\n const current = ledger.data?.current;\n const changes = useSnapshotChanges(from, snapshot.seq, tab === 'diff');\n const meta = [\n formatDateTime(snapshot.createdAt),\n actorLabel(snapshot.actor),\n snapshot.schemaVersion === null ? '' : t('snapshots.schemaVersion', { version: snapshot.schemaVersion }),\n ]\n .filter(Boolean)\n .join(' · ');\n return (\n <Page>\n <Tabs\n value={tab}\n onValueChange={(value) =>\n void navigate({ search: (prev) => ({ ...prev, tab: value as SnapshotTab }), replace: true })\n }\n className=\"gap-6\"\n >\n <PageHeader\n breadcrumb={[{ label: t('snapshots.title'), link: linkOptions({ to: '/snapshots' }) }]}\n title={t('snapshots.version', { seq: snapshot.seq })}\n badge={\n <>\n <Badge variant=\"secondary\">{t(SNAPSHOT_SOURCE_KEYS[snapshot.source])}</Badge>\n {snapshot.seq === current ? <StatusChip tone=\"success\" label={t('snapshots.live')} /> : null}\n </>\n }\n meta={meta}\n actions={\n <>\n <PinPopover seq={snapshot.seq} />\n {current !== undefined && snapshot.seq !== current ? (\n <RestoreButton seq={snapshot.seq} size=\"default\" />\n ) : null}\n </>\n }\n tabs={\n <TabsList variant=\"underline\" aria-label={t('snapshots.tabs.label')}>\n {SNAPSHOT_TABS.map((key) => (\n <TabsTrigger key={key} value={key}>\n {t(TAB_LABEL_KEYS[key])}\n </TabsTrigger>\n ))}\n </TabsList>\n }\n />\n <TabsContent value=\"diff\">\n <QueryView query={changes} loadingRows={4}>\n {(page) => <ChangeList page={page} />}\n </QueryView>\n </TabsContent>\n <TabsContent value=\"timeline\">\n <Timeline at={search.at ?? snapshot.seq} onAtChange={onAtChange} />\n </TabsContent>\n </Tabs>\n </Page>\n );\n};\n","import { createLazyRoute } from '@tanstack/react-router';\nimport { ApiExplorer } from '@/features/Develop/ApiExplorer';\nimport { Changes } from '@/features/Develop/Changes';\nimport { ChangeSet } from '@/features/Develop/ChangeSet';\nimport { Graphql } from '@/features/Develop/Graphql';\nimport { Live } from '@/features/Develop/Live';\nimport { Schema } from '@/features/Develop/Schema';\nimport { Snapshots } from '@/features/Develop/Snapshots';\nimport { Detail as SnapshotDetail } from '@/features/Develop/Snapshots/Detail';\n\n/** The developer pages (plan developer-face §2), loaded together on the first visit to one of them. */\nexport const developLazyRoutes = {\n changes: createLazyRoute('/app/changes')({ component: Changes }),\n changeSet: createLazyRoute('/app/changes/$changeSetId')({ component: ChangeSet }),\n snapshots: createLazyRoute('/app/snapshots')({ component: Snapshots }),\n snapshot: createLazyRoute('/app/snapshots/$seq')({ component: SnapshotDetail }),\n live: createLazyRoute('/app/live')({ component: Live }),\n schema: createLazyRoute('/app/schema')({ component: Schema }),\n apiExplorer: createLazyRoute('/app/api-explorer')({ component: ApiExplorer }),\n graphql: createLazyRoute('/app/develop/graphql')({ component: Graphql }),\n};\n","import { useParams } from '@tanstack/react-router';\nimport { useSnapshot } from '@/api/snapshots';\nimport { NoAccess } from '@/components/NoAccess';\nimport { Page } from '@/components/Page';\nimport { QueryView } from '@/components/QueryView';\nimport { useDevelopPermissions } from '../../Changes/hooks/useDevelopPermissions';\nimport { View } from './View';\n\n/** One snapshot: what changed against an earlier one, and a time scrubber over the ledger. */\nexport const Detail = () => {\n const { seq } = useParams({ from: '/app/snapshots/$seq' });\n const { canManageChanges } = useDevelopPermissions();\n const snapshot = useSnapshot(Number(seq));\n if (!canManageChanges) {\n return (\n <Page>\n <NoAccess />\n </Page>\n );\n }\n return (\n <QueryView query={snapshot} loadingRows={6}>\n {(data) => <View snapshot={data} />}\n </QueryView>\n );\n};\n"],"file":"develop-9ZeAjSIw.js"}
|