From e416df73f164c172e6bc5768ec7f9865c4742cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Sun, 1 Mar 2026 11:40:40 +0000 Subject: [PATCH] Deploy to GitHub pages --- 404.html | 41 + CHANGELOG.html | 41 + CNAME | 1 + CODE_OF_CONDUCT.html | 41 + CONTRIBUTING.html | 47 + LICENSE.html | 41 + SUMMARY.html | 41 + assets/404.html-CRHdR_pJ.js | 1 + assets/CHANGELOG.html-Bnklulr8.js | 1 + assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js | 1 + assets/CONTRIBUTING.html-DoGQ344g.js | 7 + assets/CONTRIBUTING.html-vtvi86EK.js | 100 ++ assets/DataDisplay.html-Sq6mPmsX.js | 1 + assets/DesignTokens.html-BMTgeCjs.js | 1 + assets/GraphQL-Playground.html-KHcgqCNs.js | 50 + assets/Introduction.html-BLSaoncO.js | 1 + assets/KATALOG.html-mRGwYwFN.js | 119 +++ assets/LICENSE.html-BkNHjkmj.js | 1 + assets/Layout.html-47srRE8z.js | 1 + assets/Navigation.html-CYz7rQzP.js | 1 + assets/PROJEKT.html-BZRNQpP2.js | 918 +++++++++++++++++ assets/STATUS.html-BXjDgreh.js | 50 + assets/SUMMARY.html-DlsPW9yB.js | 1 + assets/SearchResult-CRxy2nzi.js | 1 + assets/TODO-next-update.html-Dbd1HQYH.js | 12 + assets/Typography.html-DOSESWuO.js | 1 + assets/app-C6w_Pklu.js | 45 + assets/components.html-eb5EQ5pR.js | 1 + assets/customize-a-KtvxVU.png | Bin 0 -> 305249 bytes assets/demo.html-4tqTFmIl.js | 108 ++ assets/demo.html-6dfjrebI.js | 32 + assets/demo.html-7n0yJEH_.js | 4 + assets/demo.html-B0pnlV6F.js | 19 + assets/demo.html-B9TFHr4o.js | 9 + assets/demo.html-BF4J6jMP.js | 14 + assets/demo.html-BI-OLisc.js | 31 + assets/demo.html-BJe7I_KV.js | 40 + assets/demo.html-B_2DIOaF.js | 5 + assets/demo.html-BiUsynyZ.js | 5 + assets/demo.html-BvyZLl5C.js | 66 ++ assets/demo.html-BycQma2M.js | 32 + assets/demo.html-C19sXN7o.js | 6 + assets/demo.html-C6Qxo9Yj.js | 14 + assets/demo.html-CREqiFsx.js | 3 + assets/demo.html-CW3cD-H7.js | 1 + assets/demo.html-CWpO2OIy.js | 17 + assets/demo.html-Cry2GElr.js | 165 +++ assets/demo.html-D5WfjYVc.js | 150 +++ assets/demo.html-DWLc6gFO.js | 9 + assets/demo.html-DYuC5F42.js | 173 ++++ assets/demo.html-DgTy1wh7.js | 57 ++ assets/demo.html-DiSwsATb.js | 15 + assets/demo.html-DmAuEWx0.js | 14 + assets/demo.html-DtB7qtVV.js | 48 + assets/demo.html-DzDfUj7H.js | 148 +++ assets/demo.html-ESNHpVvJ.js | 40 + assets/demo.html-Kr4R8KpK.js | 3 + assets/demo.html-pp2XB-6I.js | 226 +++++ assets/demo.html-yVAERFv_.js | 14 + assets/deployment-values.html-BuK-P7uz.js | 3 + assets/documentation.html-B-SWCtsa.js | 17 + assets/features.html-jBF7v5Tb.js | 1 + assets/grafik (1)-BTXGtrIV.png | Bin 0 -> 43679 bytes assets/grafik-1 (1)-D9Bz6W0K.png | Bin 0 -> 737701 bytes assets/grafik-4-Cy8h69YF.png | Bin 0 -> 52433 bytes assets/graphql-playground (1)-C_SWrH2M.js | 1 + assets/graphql-playground-Ci-zpEKq.png | Bin 0 -> 75776 bytes assets/graphql.html-hAUzkKsr.js | 1 + assets/html.html-D297kDdJ.js | 1 + assets/index.html-1dvphctW.js | 26 + assets/index.html-2oMIHQ-B.js | 1 + assets/index.html-B2TWVP9L.js | 1 + assets/index.html-B7ltYIGI.js | 1 + assets/index.html-B9A0hIU3.js | 1 + assets/index.html-BC6ChnxU.js | 1 + assets/index.html-BEQOMUJ-.js | 1 + assets/index.html-BOfzPdYe.js | 1 + assets/index.html-BSOluCGA.js | 1 + assets/index.html-BSwbVjcn.js | 1 + assets/index.html-Bbb8AMlW.js | 1 + assets/index.html-Bm1PPhY4.js | 1 + assets/index.html-Bnl9T6N5.js | 1 + assets/index.html-Bo7Ljf3a.js | 1 + assets/index.html-BotCCvmf.js | 21 + assets/index.html-BrAtRvv1.js | 1 + assets/index.html-BrgOXTUr.js | 1 + assets/index.html-BsZpCI8J.js | 1 + assets/index.html-BtnavBbg.js | 1 + assets/index.html-Buh1ncoF.js | 1 + assets/index.html-Bv1cv5QZ.js | 1 + assets/index.html-Bwei2ul_.js | 1 + assets/index.html-CF1IpUUb.js | 1 + assets/index.html-CI2ipqR1.js | 1 + assets/index.html-CKtpFMus.js | 1 + assets/index.html-CMM88C29.js | 1 + assets/index.html-CMfno-Jk.js | 3 + assets/index.html-CT0wGi5f.js | 1 + assets/index.html-CZTXNS31.js | 1 + assets/index.html-Ca3OZ9Wf.js | 1 + assets/index.html-Cc8SuVO9.js | 1 + assets/index.html-Cei9bcC1.js | 1 + assets/index.html-Ch-l52j_.js | 1 + assets/index.html-CrpjDBoX.js | 1 + assets/index.html-CsIJCUeh.js | 1 + assets/index.html-CvqC5bIY.js | 20 + assets/index.html-Cww0Dhaz.js | 1 + assets/index.html-D1cGf28t.js | 66 ++ assets/index.html-D3mIxgfr.js | 1 + assets/index.html-D6JUTu4R.js | 1 + assets/index.html-DA6JIG7N.js | 56 + assets/index.html-DGSGkBMu.js | 1 + assets/index.html-DTeYXEMn.js | 1 + assets/index.html-DVXBW6uR.js | 1 + assets/index.html-DXR7MLPg.js | 1 + assets/index.html-DfhQXQ0d.js | 1 + assets/index.html-DlRSH8xw.js | 1 + assets/index.html-DnBsIglD.js | 1 + assets/index.html-DwrHoA30.js | 1 + assets/index.html-DzJKTok5.js | 1 + assets/index.html-IpTOngCN.js | 1 + assets/index.html-JQc0YsYs.js | 1 + assets/index.html-LVrUA5Ul.js | 1 + assets/index.html-NfLl_DKG.js | 1 + assets/index.html-TA2-vxe5.js | 1 + assets/index.html-TIaxxz0H.js | 1 + assets/index.html-TZE5wDuj.js | 1 + assets/index.html-VtoA8tN6.js | 1 + assets/index.html-cfpWt2jJ.js | 1 + assets/index.html-e225B3G6.js | 49 + assets/index.html-kBh9kVNW.js | 1 + assets/index.html-trrnbNUq.js | 1 + assets/index.html-vLTkaCiA.js | 2 + assets/maintenance-page-D66YmD3C.png | Bin 0 -> 206447 bytes assets/neo4j-graphql-js.html-CoZVYA65.js | 1 + assets/photoswipe.esm-GXRgw7eJ.js | 4 + assets/plugin-vue_export-helper-DlAUqK2U.js | 1 + assets/screenshot-B31RARyu.png | Bin 0 -> 388068 bytes assets/scss.html-B5_5w6uH.js | 14 + assets/setupDevtools-7MC2TMWH-B7E_wV2L.js | 1 + assets/storybook-output-BEe6-GWA.png | Bin 0 -> 50585 bytes assets/style-B3yxn0TC.css | 1 + assets/testing.html-B-yKt6km.js | 1 + assets/testing.html-BI46pcUx.js | 1 + assets/testing.html-DIbeaaFd.js | 1 + assets/vue.html-usvwTHmn.js | 10 + backend/graphql.html | 41 + backend/index.html | 106 ++ backend/neo4j-graphql-js.html | 41 + backend/src/graphql/GraphQL-Playground.html | 90 ++ backend/src/graphql/index.html | 41 + backend/src/index.html | 41 + backend/testing.html | 41 + cypress/features.html | 41 + cypress/index.html | 42 + deployment/TODO-next-update.html | 52 + deployment/deployment-values.html | 43 + deployment/index.html | 41 + deployment/styleguide/index.html | 89 ++ documentation.html | 57 ++ favicon.ico | Bin 0 -> 5558 bytes index.html | 66 ++ logo.svg | 65 ++ neo4j/index.html | 96 ++ packages/index.html | 41 + packages/ui/CONTRIBUTING.html | 140 +++ packages/ui/KATALOG.html | 159 +++ packages/ui/PROJEKT.html | 958 ++++++++++++++++++ packages/ui/index.html | 60 ++ .../ui/src/components/OsButton/STATUS.html | 90 ++ .../ui/src/components/OsButton/index.html | 41 + packages/ui/src/components/index.html | 41 + packages/ui/src/index.html | 41 + search-pro.worker.js | 2 + styleguide/index.html | 41 + styleguide/src/index.html | 41 + .../src/styleguide/docs/DataDisplay.html | 41 + .../src/styleguide/docs/DesignTokens.html | 41 + .../src/styleguide/docs/Introduction.html | 41 + styleguide/src/styleguide/docs/Layout.html | 41 + .../src/styleguide/docs/Navigation.html | 41 + .../src/styleguide/docs/Typography.html | 41 + styleguide/src/styleguide/docs/index.html | 41 + styleguide/src/styleguide/index.html | 41 + .../components/data-display/Avatar/demo.html | 59 ++ .../components/data-display/Avatar/index.html | 41 + .../data-display/CopyField/demo.html | 41 + .../data-display/CopyField/index.html | 41 + .../components/data-display/List/demo.html | 72 ++ .../components/data-display/List/index.html | 41 + .../components/data-display/Number/demo.html | 54 + .../components/data-display/Number/index.html | 41 + .../components/data-display/Table/demo.html | 205 ++++ .../components/data-display/Table/index.html | 41 + .../system/components/data-display/index.html | 41 + .../components/data-input/Form/demo.html | 190 ++++ .../components/data-input/Form/index.html | 41 + .../components/data-input/Input/demo.html | 97 ++ .../components/data-input/Input/index.html | 41 + .../components/data-input/Radio/demo.html | 80 ++ .../components/data-input/Radio/index.html | 41 + .../components/data-input/Select/demo.html | 148 +++ .../components/data-input/Select/index.html | 41 + .../system/components/data-input/index.html | 41 + styleguide/src/system/components/index.html | 41 + .../system/components/layout/Card/demo.html | 213 ++++ .../system/components/layout/Card/index.html | 41 + .../components/layout/Container/demo.html | 54 + .../components/layout/Container/index.html | 41 + .../system/components/layout/Flex/demo.html | 106 ++ .../system/components/layout/Flex/index.html | 41 + .../system/components/layout/Grid/demo.html | 72 ++ .../system/components/layout/Grid/index.html | 41 + .../system/components/layout/Modal/demo.html | 88 ++ .../system/components/layout/Modal/index.html | 41 + .../system/components/layout/Page/demo.html | 188 ++++ .../system/components/layout/Page/index.html | 41 + .../components/layout/PageTitle/demo.html | 46 + .../components/layout/PageTitle/index.html | 41 + .../components/layout/Placeholder/demo.html | 43 + .../components/layout/Placeholder/index.html | 41 + .../components/layout/Section/demo.html | 54 + .../components/layout/Section/index.html | 41 + .../system/components/layout/Space/demo.html | 71 ++ .../system/components/layout/Space/index.html | 41 + .../components/layout/Spinner/demo.html | 49 + .../components/layout/Spinner/index.html | 41 + .../src/system/components/layout/index.html | 41 + .../components/navigation/Button/demo.html | 57 ++ .../components/navigation/Button/index.html | 41 + .../components/navigation/Menu/demo.html | 266 +++++ .../components/navigation/Menu/index.html | 41 + .../system/components/navigation/index.html | 41 + .../components/typography/Chip/demo.html | 80 ++ .../components/typography/Chip/index.html | 41 + .../components/typography/Code/demo.html | 43 + .../components/typography/Code/index.html | 41 + .../components/typography/Heading/demo.html | 55 + .../components/typography/Heading/index.html | 41 + .../components/typography/Icon/demo.html | 44 + .../components/typography/Icon/index.html | 41 + .../components/typography/Logo/demo.html | 45 + .../components/typography/Logo/index.html | 41 + .../components/typography/Tag/demo.html | 49 + .../components/typography/Tag/index.html | 41 + .../components/typography/Text/demo.html | 54 + .../components/typography/Text/index.html | 41 + .../system/components/typography/index.html | 41 + styleguide/src/system/index.html | 41 + testing.html | 41 + webapp/components.html | 41 + webapp/components/Category/index.html | 41 + webapp/components/DateTime/index.html | 41 + webapp/components/Logo/demo.html | 45 + webapp/components/Logo/index.html | 41 + webapp/components/index.html | 41 + webapp/html.html | 41 + webapp/index.html | 61 ++ webapp/maintenance/index.html | 43 + webapp/scss.html | 54 + webapp/static/img/index.html | 41 + webapp/static/img/mapbox/index.html | 41 + .../static/img/mapbox/marker-icons/index.html | 41 + webapp/static/index.html | 41 + webapp/testing.html | 41 + webapp/vue.html | 50 + 265 files changed, 11212 insertions(+) create mode 100644 404.html create mode 100644 CHANGELOG.html create mode 100644 CNAME create mode 100644 CODE_OF_CONDUCT.html create mode 100644 CONTRIBUTING.html create mode 100644 LICENSE.html create mode 100644 SUMMARY.html create mode 100644 assets/404.html-CRHdR_pJ.js create mode 100644 assets/CHANGELOG.html-Bnklulr8.js create mode 100644 assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js create mode 100644 assets/CONTRIBUTING.html-DoGQ344g.js create mode 100644 assets/CONTRIBUTING.html-vtvi86EK.js create mode 100644 assets/DataDisplay.html-Sq6mPmsX.js create mode 100644 assets/DesignTokens.html-BMTgeCjs.js create mode 100644 assets/GraphQL-Playground.html-KHcgqCNs.js create mode 100644 assets/Introduction.html-BLSaoncO.js create mode 100644 assets/KATALOG.html-mRGwYwFN.js create mode 100644 assets/LICENSE.html-BkNHjkmj.js create mode 100644 assets/Layout.html-47srRE8z.js create mode 100644 assets/Navigation.html-CYz7rQzP.js create mode 100644 assets/PROJEKT.html-BZRNQpP2.js create mode 100644 assets/STATUS.html-BXjDgreh.js create mode 100644 assets/SUMMARY.html-DlsPW9yB.js create mode 100644 assets/SearchResult-CRxy2nzi.js create mode 100644 assets/TODO-next-update.html-Dbd1HQYH.js create mode 100644 assets/Typography.html-DOSESWuO.js create mode 100644 assets/app-C6w_Pklu.js create mode 100644 assets/components.html-eb5EQ5pR.js create mode 100644 assets/customize-a-KtvxVU.png create mode 100644 assets/demo.html-4tqTFmIl.js create mode 100644 assets/demo.html-6dfjrebI.js create mode 100644 assets/demo.html-7n0yJEH_.js create mode 100644 assets/demo.html-B0pnlV6F.js create mode 100644 assets/demo.html-B9TFHr4o.js create mode 100644 assets/demo.html-BF4J6jMP.js create mode 100644 assets/demo.html-BI-OLisc.js create mode 100644 assets/demo.html-BJe7I_KV.js create mode 100644 assets/demo.html-B_2DIOaF.js create mode 100644 assets/demo.html-BiUsynyZ.js create mode 100644 assets/demo.html-BvyZLl5C.js create mode 100644 assets/demo.html-BycQma2M.js create mode 100644 assets/demo.html-C19sXN7o.js create mode 100644 assets/demo.html-C6Qxo9Yj.js create mode 100644 assets/demo.html-CREqiFsx.js create mode 100644 assets/demo.html-CW3cD-H7.js create mode 100644 assets/demo.html-CWpO2OIy.js create mode 100644 assets/demo.html-Cry2GElr.js create mode 100644 assets/demo.html-D5WfjYVc.js create mode 100644 assets/demo.html-DWLc6gFO.js create mode 100644 assets/demo.html-DYuC5F42.js create mode 100644 assets/demo.html-DgTy1wh7.js create mode 100644 assets/demo.html-DiSwsATb.js create mode 100644 assets/demo.html-DmAuEWx0.js create mode 100644 assets/demo.html-DtB7qtVV.js create mode 100644 assets/demo.html-DzDfUj7H.js create mode 100644 assets/demo.html-ESNHpVvJ.js create mode 100644 assets/demo.html-Kr4R8KpK.js create mode 100644 assets/demo.html-pp2XB-6I.js create mode 100644 assets/demo.html-yVAERFv_.js create mode 100644 assets/deployment-values.html-BuK-P7uz.js create mode 100644 assets/documentation.html-B-SWCtsa.js create mode 100644 assets/features.html-jBF7v5Tb.js create mode 100644 assets/grafik (1)-BTXGtrIV.png create mode 100644 assets/grafik-1 (1)-D9Bz6W0K.png create mode 100644 assets/grafik-4-Cy8h69YF.png create mode 100644 assets/graphql-playground (1)-C_SWrH2M.js create mode 100644 assets/graphql-playground-Ci-zpEKq.png create mode 100644 assets/graphql.html-hAUzkKsr.js create mode 100644 assets/html.html-D297kDdJ.js create mode 100644 assets/index.html-1dvphctW.js create mode 100644 assets/index.html-2oMIHQ-B.js create mode 100644 assets/index.html-B2TWVP9L.js create mode 100644 assets/index.html-B7ltYIGI.js create mode 100644 assets/index.html-B9A0hIU3.js create mode 100644 assets/index.html-BC6ChnxU.js create mode 100644 assets/index.html-BEQOMUJ-.js create mode 100644 assets/index.html-BOfzPdYe.js create mode 100644 assets/index.html-BSOluCGA.js create mode 100644 assets/index.html-BSwbVjcn.js create mode 100644 assets/index.html-Bbb8AMlW.js create mode 100644 assets/index.html-Bm1PPhY4.js create mode 100644 assets/index.html-Bnl9T6N5.js create mode 100644 assets/index.html-Bo7Ljf3a.js create mode 100644 assets/index.html-BotCCvmf.js create mode 100644 assets/index.html-BrAtRvv1.js create mode 100644 assets/index.html-BrgOXTUr.js create mode 100644 assets/index.html-BsZpCI8J.js create mode 100644 assets/index.html-BtnavBbg.js create mode 100644 assets/index.html-Buh1ncoF.js create mode 100644 assets/index.html-Bv1cv5QZ.js create mode 100644 assets/index.html-Bwei2ul_.js create mode 100644 assets/index.html-CF1IpUUb.js create mode 100644 assets/index.html-CI2ipqR1.js create mode 100644 assets/index.html-CKtpFMus.js create mode 100644 assets/index.html-CMM88C29.js create mode 100644 assets/index.html-CMfno-Jk.js create mode 100644 assets/index.html-CT0wGi5f.js create mode 100644 assets/index.html-CZTXNS31.js create mode 100644 assets/index.html-Ca3OZ9Wf.js create mode 100644 assets/index.html-Cc8SuVO9.js create mode 100644 assets/index.html-Cei9bcC1.js create mode 100644 assets/index.html-Ch-l52j_.js create mode 100644 assets/index.html-CrpjDBoX.js create mode 100644 assets/index.html-CsIJCUeh.js create mode 100644 assets/index.html-CvqC5bIY.js create mode 100644 assets/index.html-Cww0Dhaz.js create mode 100644 assets/index.html-D1cGf28t.js create mode 100644 assets/index.html-D3mIxgfr.js create mode 100644 assets/index.html-D6JUTu4R.js create mode 100644 assets/index.html-DA6JIG7N.js create mode 100644 assets/index.html-DGSGkBMu.js create mode 100644 assets/index.html-DTeYXEMn.js create mode 100644 assets/index.html-DVXBW6uR.js create mode 100644 assets/index.html-DXR7MLPg.js create mode 100644 assets/index.html-DfhQXQ0d.js create mode 100644 assets/index.html-DlRSH8xw.js create mode 100644 assets/index.html-DnBsIglD.js create mode 100644 assets/index.html-DwrHoA30.js create mode 100644 assets/index.html-DzJKTok5.js create mode 100644 assets/index.html-IpTOngCN.js create mode 100644 assets/index.html-JQc0YsYs.js create mode 100644 assets/index.html-LVrUA5Ul.js create mode 100644 assets/index.html-NfLl_DKG.js create mode 100644 assets/index.html-TA2-vxe5.js create mode 100644 assets/index.html-TIaxxz0H.js create mode 100644 assets/index.html-TZE5wDuj.js create mode 100644 assets/index.html-VtoA8tN6.js create mode 100644 assets/index.html-cfpWt2jJ.js create mode 100644 assets/index.html-e225B3G6.js create mode 100644 assets/index.html-kBh9kVNW.js create mode 100644 assets/index.html-trrnbNUq.js create mode 100644 assets/index.html-vLTkaCiA.js create mode 100644 assets/maintenance-page-D66YmD3C.png create mode 100644 assets/neo4j-graphql-js.html-CoZVYA65.js create mode 100644 assets/photoswipe.esm-GXRgw7eJ.js create mode 100644 assets/plugin-vue_export-helper-DlAUqK2U.js create mode 100644 assets/screenshot-B31RARyu.png create mode 100644 assets/scss.html-B5_5w6uH.js create mode 100644 assets/setupDevtools-7MC2TMWH-B7E_wV2L.js create mode 100644 assets/storybook-output-BEe6-GWA.png create mode 100644 assets/style-B3yxn0TC.css create mode 100644 assets/testing.html-B-yKt6km.js create mode 100644 assets/testing.html-BI46pcUx.js create mode 100644 assets/testing.html-DIbeaaFd.js create mode 100644 assets/vue.html-usvwTHmn.js create mode 100644 backend/graphql.html create mode 100644 backend/index.html create mode 100644 backend/neo4j-graphql-js.html create mode 100644 backend/src/graphql/GraphQL-Playground.html create mode 100644 backend/src/graphql/index.html create mode 100644 backend/src/index.html create mode 100644 backend/testing.html create mode 100644 cypress/features.html create mode 100644 cypress/index.html create mode 100644 deployment/TODO-next-update.html create mode 100644 deployment/deployment-values.html create mode 100644 deployment/index.html create mode 100644 deployment/styleguide/index.html create mode 100644 documentation.html create mode 100644 favicon.ico create mode 100644 index.html create mode 100644 logo.svg create mode 100644 neo4j/index.html create mode 100644 packages/index.html create mode 100644 packages/ui/CONTRIBUTING.html create mode 100644 packages/ui/KATALOG.html create mode 100644 packages/ui/PROJEKT.html create mode 100644 packages/ui/index.html create mode 100644 packages/ui/src/components/OsButton/STATUS.html create mode 100644 packages/ui/src/components/OsButton/index.html create mode 100644 packages/ui/src/components/index.html create mode 100644 packages/ui/src/index.html create mode 100644 search-pro.worker.js create mode 100644 styleguide/index.html create mode 100644 styleguide/src/index.html create mode 100644 styleguide/src/styleguide/docs/DataDisplay.html create mode 100644 styleguide/src/styleguide/docs/DesignTokens.html create mode 100644 styleguide/src/styleguide/docs/Introduction.html create mode 100644 styleguide/src/styleguide/docs/Layout.html create mode 100644 styleguide/src/styleguide/docs/Navigation.html create mode 100644 styleguide/src/styleguide/docs/Typography.html create mode 100644 styleguide/src/styleguide/docs/index.html create mode 100644 styleguide/src/styleguide/index.html create mode 100644 styleguide/src/system/components/data-display/Avatar/demo.html create mode 100644 styleguide/src/system/components/data-display/Avatar/index.html create mode 100644 styleguide/src/system/components/data-display/CopyField/demo.html create mode 100644 styleguide/src/system/components/data-display/CopyField/index.html create mode 100644 styleguide/src/system/components/data-display/List/demo.html create mode 100644 styleguide/src/system/components/data-display/List/index.html create mode 100644 styleguide/src/system/components/data-display/Number/demo.html create mode 100644 styleguide/src/system/components/data-display/Number/index.html create mode 100644 styleguide/src/system/components/data-display/Table/demo.html create mode 100644 styleguide/src/system/components/data-display/Table/index.html create mode 100644 styleguide/src/system/components/data-display/index.html create mode 100644 styleguide/src/system/components/data-input/Form/demo.html create mode 100644 styleguide/src/system/components/data-input/Form/index.html create mode 100644 styleguide/src/system/components/data-input/Input/demo.html create mode 100644 styleguide/src/system/components/data-input/Input/index.html create mode 100644 styleguide/src/system/components/data-input/Radio/demo.html create mode 100644 styleguide/src/system/components/data-input/Radio/index.html create mode 100644 styleguide/src/system/components/data-input/Select/demo.html create mode 100644 styleguide/src/system/components/data-input/Select/index.html create mode 100644 styleguide/src/system/components/data-input/index.html create mode 100644 styleguide/src/system/components/index.html create mode 100644 styleguide/src/system/components/layout/Card/demo.html create mode 100644 styleguide/src/system/components/layout/Card/index.html create mode 100644 styleguide/src/system/components/layout/Container/demo.html create mode 100644 styleguide/src/system/components/layout/Container/index.html create mode 100644 styleguide/src/system/components/layout/Flex/demo.html create mode 100644 styleguide/src/system/components/layout/Flex/index.html create mode 100644 styleguide/src/system/components/layout/Grid/demo.html create mode 100644 styleguide/src/system/components/layout/Grid/index.html create mode 100644 styleguide/src/system/components/layout/Modal/demo.html create mode 100644 styleguide/src/system/components/layout/Modal/index.html create mode 100644 styleguide/src/system/components/layout/Page/demo.html create mode 100644 styleguide/src/system/components/layout/Page/index.html create mode 100644 styleguide/src/system/components/layout/PageTitle/demo.html create mode 100644 styleguide/src/system/components/layout/PageTitle/index.html create mode 100644 styleguide/src/system/components/layout/Placeholder/demo.html create mode 100644 styleguide/src/system/components/layout/Placeholder/index.html create mode 100644 styleguide/src/system/components/layout/Section/demo.html create mode 100644 styleguide/src/system/components/layout/Section/index.html create mode 100644 styleguide/src/system/components/layout/Space/demo.html create mode 100644 styleguide/src/system/components/layout/Space/index.html create mode 100644 styleguide/src/system/components/layout/Spinner/demo.html create mode 100644 styleguide/src/system/components/layout/Spinner/index.html create mode 100644 styleguide/src/system/components/layout/index.html create mode 100644 styleguide/src/system/components/navigation/Button/demo.html create mode 100644 styleguide/src/system/components/navigation/Button/index.html create mode 100644 styleguide/src/system/components/navigation/Menu/demo.html create mode 100644 styleguide/src/system/components/navigation/Menu/index.html create mode 100644 styleguide/src/system/components/navigation/index.html create mode 100644 styleguide/src/system/components/typography/Chip/demo.html create mode 100644 styleguide/src/system/components/typography/Chip/index.html create mode 100644 styleguide/src/system/components/typography/Code/demo.html create mode 100644 styleguide/src/system/components/typography/Code/index.html create mode 100644 styleguide/src/system/components/typography/Heading/demo.html create mode 100644 styleguide/src/system/components/typography/Heading/index.html create mode 100644 styleguide/src/system/components/typography/Icon/demo.html create mode 100644 styleguide/src/system/components/typography/Icon/index.html create mode 100644 styleguide/src/system/components/typography/Logo/demo.html create mode 100644 styleguide/src/system/components/typography/Logo/index.html create mode 100644 styleguide/src/system/components/typography/Tag/demo.html create mode 100644 styleguide/src/system/components/typography/Tag/index.html create mode 100644 styleguide/src/system/components/typography/Text/demo.html create mode 100644 styleguide/src/system/components/typography/Text/index.html create mode 100644 styleguide/src/system/components/typography/index.html create mode 100644 styleguide/src/system/index.html create mode 100644 testing.html create mode 100644 webapp/components.html create mode 100644 webapp/components/Category/index.html create mode 100644 webapp/components/DateTime/index.html create mode 100644 webapp/components/Logo/demo.html create mode 100644 webapp/components/Logo/index.html create mode 100644 webapp/components/index.html create mode 100644 webapp/html.html create mode 100644 webapp/index.html create mode 100644 webapp/maintenance/index.html create mode 100644 webapp/scss.html create mode 100644 webapp/static/img/index.html create mode 100644 webapp/static/img/mapbox/index.html create mode 100644 webapp/static/img/mapbox/marker-icons/index.html create mode 100644 webapp/static/index.html create mode 100644 webapp/testing.html create mode 100644 webapp/vue.html diff --git a/404.html b/404.html new file mode 100644 index 000000000..1a9920d99 --- /dev/null +++ b/404.html @@ -0,0 +1,41 @@ + + + + + + + + + + Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/CHANGELOG.html b/CHANGELOG.html new file mode 100644 index 000000000..6614315eb --- /dev/null +++ b/CHANGELOG.html @@ -0,0 +1,41 @@ + + + + + + + + + + Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/CNAME b/CNAME new file mode 100644 index 000000000..8317b7688 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.ocelot.social \ No newline at end of file diff --git a/CODE_OF_CONDUCT.html b/CODE_OF_CONDUCT.html new file mode 100644 index 000000000..0f6a7d509 --- /dev/null +++ b/CODE_OF_CONDUCT.html @@ -0,0 +1,41 @@ + + + + + + + + + + Contributor Covenant Code of Conduct | Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/CONTRIBUTING.html b/CONTRIBUTING.html new file mode 100644 index 000000000..6fb4cfe0d --- /dev/null +++ b/CONTRIBUTING.html @@ -0,0 +1,47 @@ + + + + + + + + + + CONTRIBUTING | Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/LICENSE.html b/LICENSE.html new file mode 100644 index 000000000..1b7366a43 --- /dev/null +++ b/LICENSE.html @@ -0,0 +1,41 @@ + + + + + + + + + + LICENSE | Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/SUMMARY.html b/SUMMARY.html new file mode 100644 index 000000000..bbd6e4611 --- /dev/null +++ b/SUMMARY.html @@ -0,0 +1,41 @@ + + + + + + + + + + Table of contents | Ocelot.Social Documentation + + + + + +
Skip to main content
+ + + diff --git a/assets/404.html-CRHdR_pJ.js b/assets/404.html-CRHdR_pJ.js new file mode 100644 index 000000000..52be63809 --- /dev/null +++ b/assets/404.html-CRHdR_pJ.js @@ -0,0 +1 @@ +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,b as n,o as r}from"./app-C6w_Pklu.js";const a={};function l(s,t){return r(),o("div",null,t[0]||(t[0]=[n("p",null,"404 Not Found",-1)]))}const m=e(a,[["render",l],["__file","404.html.vue"]]),p=JSON.parse('{"path":"/404.html","title":"","lang":"en-US","frontmatter":{"layout":"NotFound"},"headers":[],"git":{},"readingTime":{"minutes":0.01,"words":3},"filePathRelative":null,"excerpt":"

404 Not Found

\\n"}');export{m as comp,p as data}; diff --git a/assets/CHANGELOG.html-Bnklulr8.js b/assets/CHANGELOG.html-Bnklulr8.js new file mode 100644 index 000000000..20c5310ec --- /dev/null +++ b/assets/CHANGELOG.html-Bnklulr8.js @@ -0,0 +1 @@ +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as l,a as t,o as r}from"./app-C6w_Pklu.js";const i={};function c(a,e){return r(),l("div",null,e[0]||(e[0]=[t('

Changelog

All notable changes to this project will be documented in this file. Dates are displayed in UTC.

Generated by auto-changelog.

3.14.1

3.14.0

9 February 2026

3.13.1

1 November 2025

3.13.0

28 October 2025

3.12.2

15 September 2025

3.12.1

13 September 2025

3.12.0

20 August 2025

3.11.0

5 July 2025

3.10.1

19 June 2025

3.10.0

16 June 2025

3.9.0

11 June 2025

3.8.2

4 June 2025

3.8.1

2 June 2025

3.8.0

1 June 2025

3.7.0

25 May 2025

3.6.1

12 May 2025

3.6.0

10 May 2025

3.5.3

7 May 2025

3.5.2

6 May 2025

3.5.1

6 May 2025

3.5.0

6 May 2025

3.4.0

28 April 2025

3.3.0

12 April 2025

3.2.1

3 March 2025

3.2.0

14 February 2024

3.1.2

3 October 2023

3.1.1

27 September 2023

3.1.0

13 September 2023

3.0.4

12 September 2023

3.0.3

4 September 2023

3.0.2

11 August 2023

3.0.1

9 August 2023

3.0.0

7 August 2023

2.7.0

14 June 2023

2.6.0

27 April 2023

2.5.1

23 March 2023

2.5.0

21 March 2023

2.4.0

10 February 2023

2.3.0

5 December 2022

2.2.0

28 October 2022

2.1.0

25 October 2022

2.0.0

23 October 2022

1.1.1

22 September 2022

1.1.0

4 August 2022

1.0.9

20 July 2022

1.0.8

1 July 2022

1.0.7

2 December 2021

1.0.6

4 October 2021

1.0.5

12 August 2021

1.0.4

8 June 2021

1.0.3

19 May 2021

1.0.2

6 April 2021

1.0.1

4 April 2021

1.0.0

31 March 2021

0.6.15

1 March 2021

0.6.14

17 February 2021

0.6.13

17 February 2021

0.6.12

15 February 2021

0.6.11

15 February 2021

0.6.10

12 February 2021

0.6.9

12 February 2021

0.6.8

11 February 2021

0.6.7

10 February 2021

0.6.6

10 February 2021

0.6.5

8 February 2021

0.6.4

8 February 2021

0.6.3

8 February 2021

0.6.0

2 February 2021

v0.6.0

27 March 2020

0.5.19

15 August 2019

0.5.18

15 August 2019

0.5.17

7 May 2019

0.5.16

7 May 2019

0.5.15

12 March 2019

0.5.14

12 March 2019

0.5.13

11 March 2019

0.5.12

11 March 2019

0.5.11

9 March 2019

0.5.10

7 March 2019

0.5.9

7 March 2019

0.5.8

7 March 2019

0.5.7

6 March 2019

0.5.6

6 March 2019

0.5.5

4 March 2019

0.5.4

1 March 2019

0.5.2

26 February 2019

0.5.1

25 February 2019

0.5.0

25 February 2019

v0.5.0

26 March 2020

v0.4.2

13 March 2020

v0.4.1

9 March 2020

v0.4.0

22 February 2020

v0.3.1

10 February 2020

v0.3.0

3 February 2020

0.2.2

21 January 2020

v0.2.2

20 January 2020

0.2.1

20 January 2020

v0.2.1

10 January 2020

0.2.0

23 September 2020

v0.2.0

19 December 2019

0.1.13

23 September 2020

v0.1.13

13 December 2019

0.1.12

23 September 2020

v0.1.12

10 December 2019

0.1.11

23 September 2020

v0.1.11

22 November 2019

0.1.10

23 September 2020

v0.1.10

13 November 2019

0.1.9

23 September 2020

v0.1.9

4 November 2019

0.1.8

23 September 2020

v0.1.8

24 October 2019

0.1.7

23 September 2020

v0.1.7

23 October 2019

0.1.6

23 September 2020

v0.1.6

22 October 2019

0.1.5

23 September 2020

v0.1.5

17 October 2019

0.1.4

23 September 2020

v0.1.4

10 October 2019

0.1.3

23 September 2020

v0.1.3

4 October 2019

0.1.2

23 September 2020

v0.1.2

2 October 2019

0.1.1

23 September 2020

v0.1.1

27 September 2019

0.1.0

23 September 2020

v0.1.0

18 September 2019

',370)]))}const u=o(i,[["render",c],["__file","CHANGELOG.html.vue"]]),m=JSON.parse('{"path":"/CHANGELOG.html","title":"","lang":"en-US","frontmatter":{},"headers":[{"level":3,"title":"Changelog","slug":"changelog","link":"#changelog","children":[]},{"level":3,"title":"3.0.0","slug":"_3-0-0","link":"#_3-0-0","children":[]},{"level":3,"title":"2.0.0","slug":"_2-0-0","link":"#_2-0-0","children":[]},{"level":3,"title":"1.0.0","slug":"_1-0-0","link":"#_1-0-0","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":1026.75,"words":308026},"filePathRelative":"CHANGELOG.md","localizedDate":"March 1, 2026","excerpt":"

Changelog

\\n

All notable changes to this project will be documented in this file. Dates are displayed in UTC.

\\n

Generated by auto-changelog.

\\n

3.14.1

"}');export{u as comp,m as data}; diff --git a/assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js b/assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js new file mode 100644 index 000000000..896954ce6 --- /dev/null +++ b/assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js @@ -0,0 +1 @@ +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,a as n,o as a}from"./app-C6w_Pklu.js";const o={};function r(s,e){return a(),i("div",null,e[0]||(e[0]=[n('

Contributor Covenant Code of Conduct

Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

Our Standards

Examples of behavior that contributes to creating a positive environment include:

Examples of unacceptable behavior by participants include:

Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at devops@ocelot.social. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4

',18)]))}const p=t(o,[["render",r],["__file","CODE_OF_CONDUCT.html.vue"]]),d=JSON.parse('{"path":"/CODE_OF_CONDUCT.html","title":"Contributor Covenant Code of Conduct","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Our Pledge","slug":"our-pledge","link":"#our-pledge","children":[]},{"level":2,"title":"Our Standards","slug":"our-standards","link":"#our-standards","children":[]},{"level":2,"title":"Our Responsibilities","slug":"our-responsibilities","link":"#our-responsibilities","children":[]},{"level":2,"title":"Scope","slug":"scope","link":"#scope","children":[]},{"level":2,"title":"Enforcement","slug":"enforcement","link":"#enforcement","children":[]},{"level":2,"title":"Attribution","slug":"attribution","link":"#attribution","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":1.45,"words":436},"filePathRelative":"CODE_OF_CONDUCT.md","localizedDate":"March 1, 2026","excerpt":"\\n

Our Pledge

\\n

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

"}');export{p as comp,d as data}; diff --git a/assets/CONTRIBUTING.html-DoGQ344g.js b/assets/CONTRIBUTING.html-DoGQ344g.js new file mode 100644 index 000000000..a6247b015 --- /dev/null +++ b/assets/CONTRIBUTING.html-DoGQ344g.js @@ -0,0 +1,7 @@ +import{_ as r}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as l,a as s,b as o,d as i,e as t,f as n,r as h,o as d}from"./app-C6w_Pklu.js";const p={};function c(k,e){const a=h("RouteLink");return d(),l("div",null,[e[7]||(e[7]=s('

CONTRIBUTING

Thank you so much for thinking of contributing to the ocelot.social project! It's awesome you're here, we really appreciate it. :-)

Getting Set Up

',3)),o("p",null,[e[2]||(e[2]=i("Instructions for how to install all the necessary software and some code guidelines can be found in our main ")),t(a,{to:"/"},{default:n(()=>e[0]||(e[0]=[i("Readme")])),_:1}),e[3]||(e[3]=i(" or in our ")),t(a,{to:"/SUMMARY.html"},{default:n(()=>e[1]||(e[1]=[i("documentation")])),_:1}),e[4]||(e[4]=i("."))]),e[8]||(e[8]=s('

To get you started we recommend that you join forces with a regular contributor. Please join our Discord instance to chat with developers or just get in touch directly on an issue on either Github or Zenhub:

We also can have pair programming sessions for you! We feel this is often the best way to get to know both the project and the team. Most developers are also available for spontaneous sessions.

Development Flow

We operate in two week sprints that are planned, estimated and prioritised on Zenhub. All issues are also linked to and synced with Github. Look for the good first issue label if you're not sure where to start!

We try to discuss all questions directly related to a feature or bug in the respective issue, in order to preserve it for the future and for other developers. We use Discord for real-time communication.

This is how we solve bugs and implement features, step by step:

  1. We find an issue we want to work on, usually during the sprint planning but as an open source contributor this can happen at any time.
  2. We communicate with the team to see if the issue is still available. (When you comment on an issue but don't get an answer there within 1-2 days try to mention @Ocelot-Social-Community/core-team to make sure we check in.)
  3. We make sure we understand the issue in detail – what problem is it solving and how should it be implemented?
  4. We assign ourselves to the issue and move it to In Progress on Zenhub.
  5. We start working on it in a new branch and open a pull request prefixed with [WIP] (work in progress) to which we regularly push our changes.
  6. When questions come up we clarify them with the team (directly in the issue on Github).
  7. When we are happy with our work and our PR is passing all tests we remove the [WIP] from the PR description and ask for reviews (if you're not sure who to ask there is @Ocelot-Social-Community/core-team which pings all core developers).
  8. We then incorporate the suggestions from the reviews into our work and once it has been approved it can be merged into master!

Every pull request needs to:

Contribution Flow For Open Source Contributors

',10)),o("p",null,[e[6]||(e[6]=i("See ")),t(a,{to:"/#contributing"},{default:n(()=>e[5]||(e[5]=[i("contributing in main README.md")])),_:1})]),e[9]||(e[9]=s(`

The Team

There are many volunteers all around the world helping us build this network and without their contributions we wouldn't be where we are today. Big thank you to all of you!

You can talk to our core team on Discord. And on Github you will mostly run into our core developers:

Meetings and Pair Programming Sessions

Times below refer to German Time – that's CET (GMT+1) in winter and CEST (GMT+2) in summer – because most ocelot.social Community core team members are living in Germany.

Daily standup

Philosophy

We practice collective code ownership rather than strong code ownership, which means that:

We believe in open source contributions as a learning experience – everyone is welcome to join our team of volunteers and to contribute to the project, no matter their background or level of experience. To support your learning experience we founded the charity association busFaktor() e.V..

We use pair programming sessions as a tool for knowledge sharing. We can learn a lot from each other and only by sharing what we know and overcoming challenges together can we grow as a team and truly own this project collectively.

As a volunteer you have no commitment except your own self development and your awesomeness by contributing to this free and open-source software project. Cheers to you!

Programming

Localization

Quotation Marks

The following characters are different from the programming quotation mark:

" or \\"

Please copy and paste the following quotes for the languages:

Docker – More Closely

Apple Silicon Platform

ATTENTION: For using Docker commands in Apple Silicon environments!

Environment Variable For Apple Silicon Platform (M1, M2 Chips)

If you encounter trouble building the docker containers on an Apple M1 chip you can try to explicitly define the target platform docker builds and pulls images for:

# set env variable for your shell
+$ export DOCKER_DEFAULT_PLATFORM=linux/amd64

Or alternatively use a YAML docker compose overwrite file with platform: linux/amd64.

Analyzing Docker Builds

To analyze a Docker build, there is a wonderful tool called dive. Please sponsor if you're using it!

The dive build command is exactly the right one to fulfill what we are looking for. We can use it just like the docker build command and get an analysis afterwards.

So, in our main folder, we use it in the following way:

# in main folder
+$ dive build --target <layer-name> -t "ocelotsocialnetwork/<app-name>:local-<layer-name>" --build-arg BBUILD_DATE="<build-date>" --build-arg BBUILD_VERSION="<build-version>" --build-arg BBUILD_COMMIT="<build-commit>" <app-folder-name-or-dot>/

The build arguments are optional.

For the specific applications, we use them as follows.

Backend

Production For Backend
# in main folder
+$ dive build --target production -t "ocelotsocialnetwork/backend:local-production" backend/
Development For Backend
# in main folder
+$ dive build --target development -t "ocelotsocialnetwork/backend:local-development" backend/

Webapp

Production For Webapp
# in main folder
+$ dive build --target production -t "ocelotsocialnetwork/webapp:local-production" webapp/
Development For Webapp
# in main folder
+$ dive build --target development -t "ocelotsocialnetwork/webapp:local-development" webapp/
`,45))])}const m=r(p,[["render",c],["__file","CONTRIBUTING.html.vue"]]),b=JSON.parse(`{"path":"/CONTRIBUTING.html","title":"CONTRIBUTING","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Getting Set Up","slug":"getting-set-up","link":"#getting-set-up","children":[]},{"level":2,"title":"Development Flow","slug":"development-flow","link":"#development-flow","children":[]},{"level":2,"title":"Contribution Flow For Open Source Contributors","slug":"contribution-flow-for-open-source-contributors","link":"#contribution-flow-for-open-source-contributors","children":[]},{"level":2,"title":"The Team","slug":"the-team","link":"#the-team","children":[]},{"level":2,"title":"Meetings and Pair Programming Sessions","slug":"meetings-and-pair-programming-sessions","link":"#meetings-and-pair-programming-sessions","children":[]},{"level":2,"title":"Philosophy","slug":"philosophy","link":"#philosophy","children":[]},{"level":2,"title":"Programming","slug":"programming","link":"#programming","children":[{"level":3,"title":"Localization","slug":"localization","link":"#localization","children":[]}]},{"level":2,"title":"Docker – More Closely","slug":"docker-–-more-closely","link":"#docker-–-more-closely","children":[{"level":3,"title":"Apple Silicon Platform","slug":"apple-silicon-platform","link":"#apple-silicon-platform","children":[]},{"level":3,"title":"Analyzing Docker Builds","slug":"analyzing-docker-builds","link":"#analyzing-docker-builds","children":[]}]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":5.68,"words":1703},"filePathRelative":"CONTRIBUTING.md","localizedDate":"March 1, 2026","excerpt":"\\n

Thank you so much for thinking of contributing to the ocelot.social project! It's awesome you're here, we really appreciate it. :-)

\\n

Getting Set Up

\\n

Instructions for how to install all the necessary software and some code guidelines can be found in our main Readme or in our documentation.

"}`);export{m as comp,b as data}; diff --git a/assets/CONTRIBUTING.html-vtvi86EK.js b/assets/CONTRIBUTING.html-vtvi86EK.js new file mode 100644 index 000000000..e709db57a --- /dev/null +++ b/assets/CONTRIBUTING.html-vtvi86EK.js @@ -0,0 +1,100 @@ +import{_ as l}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as e,a as t,b as i,d as a,e as h,f as p,r as k,o as d}from"./app-C6w_Pklu.js";const r={};function c(g,s){const n=k("RouteLink");return d(),e("div",null,[s[5]||(s[5]=t(`

Contributing to @ocelot-social/ui

Thank you for contributing to the ocelot.social UI library!

Development Setup

# Install dependencies
+npm install
+
+# Start development server
+npm run dev
+
+# Run tests
+npm test
+
+# Run linter
+npm run lint

Creating a New Component

File Structure

src/components/
+└── OsButton/
+    ├── OsButton.vue       # Component
+    ├── OsButton.spec.ts   # Tests
+    └── index.ts           # Export

Naming Convention

Component Template

<script setup lang="ts">
+import { computed } from 'vue-demi'
+
+import type { Size, Variant } from '@/types'
+
+interface Props {
+  /** Button size */
+  size?: Size
+  /** Visual variant */
+  variant?: Variant
+}
+
+const props = withDefaults(defineProps<Props>(), {
+  size: 'md',
+  variant: 'primary',
+})
+
+const classes = computed(() => [
+  'os-button',
+  \`os-button--\${props.size}\`,
+  \`os-button--\${props.variant}\`,
+])
+</script>
+
+<template>
+  <button :class="classes">
+    <slot />
+  </button>
+</template>

Code Standards

TypeScript

Props

Use the complete Tailwind-based scales:

PropValues
sizexs, sm, md, lg, xl, 2xl
roundednone, sm, md, lg, xl, 2xl, 3xl, full
shadownone, sm, md, lg, xl, 2xl
variantprimary, secondary, danger, warning, success, info

Styling

<template>
+  <button class="bg-[--button-primary-bg] dark:bg-[--button-primary-bg-dark]">
+    <slot />
+  </button>
+</template>

Vue 2/3 Compatibility

Always import from vue-demi, not vue:

// Correct
+import { ref, computed } from 'vue-demi'
+
+// Wrong
+import { ref, computed } from 'vue'

Testing

Requirements

Writing Tests

import { mount } from '@vue/test-utils'
+import { describe, expect, it } from 'vitest'
+
+import OsButton from './OsButton.vue'
+
+describe('OsButton', () => {
+  it('renders slot content', () => {
+    const wrapper = mount(OsButton, {
+      slots: { default: 'Click me' },
+    })
+    expect(wrapper.text()).toBe('Click me')
+  })
+
+  it('applies size class', () => {
+    const wrapper = mount(OsButton, {
+      props: { size: 'lg' },
+    })
+    expect(wrapper.classes()).toContain('os-button--lg')
+  })
+})

Running Tests

# Run once
+npm test
+
+# Watch mode
+npm run test:watch
+
+# With coverage
+npm run test:coverage

Commit Conventions

We use Conventional Commits for automatic releases:

# Features (minor version bump)
+feat(button): add loading state
+
+# Bug fixes (patch version bump)
+fix(modal): correct focus trap behavior
+
+# Breaking changes (major version bump)
+feat(input)!: rename value prop to modelValue
+
+# Other types
+docs: update README
+test: add button accessibility tests
+chore: update dependencies
+refactor: simplify dropdown logic

Pull Request Checklist

Before submitting a PR, ensure:

Example Apps

Test your changes in the example apps:

# Vue 3 + Tailwind
+cd examples/vue3-tailwind && npm install && npm run dev
+
+# Vue 3 + CSS
+cd examples/vue3-css && npm install && npm run dev
+
+# Vue 2 + Tailwind
+cd examples/vue2-tailwind && npm install && npm run dev
+
+# Vue 2 + CSS
+cd examples/vue2-css && npm install && npm run dev

Questions?

`,40)),i("ul",null,[i("li",null,[s[1]||(s[1]=a("Check the ")),h(n,{to:"/CONTRIBUTING.html"},{default:p(()=>s[0]||(s[0]=[a("main CONTRIBUTING.md")])),_:1}),s[2]||(s[2]=a(" for general guidelines"))]),s[3]||(s[3]=i("li",null,[a("Join the "),i("a",{href:"https://discord.gg/AJSX9DCSUA",target:"_blank",rel:"noopener noreferrer"},"Discord"),a(" for questions")],-1)),s[4]||(s[4]=i("li",null,"Open an issue for bugs or feature requests",-1))])])}const y=l(r,[["render",c],["__file","CONTRIBUTING.html.vue"]]),u=JSON.parse('{"path":"/packages/ui/CONTRIBUTING.html","title":"Contributing to @ocelot-social/ui","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Development Setup","slug":"development-setup","link":"#development-setup","children":[]},{"level":2,"title":"Creating a New Component","slug":"creating-a-new-component","link":"#creating-a-new-component","children":[{"level":3,"title":"File Structure","slug":"file-structure","link":"#file-structure","children":[]},{"level":3,"title":"Naming Convention","slug":"naming-convention","link":"#naming-convention","children":[]},{"level":3,"title":"Component Template","slug":"component-template","link":"#component-template","children":[]}]},{"level":2,"title":"Code Standards","slug":"code-standards","link":"#code-standards","children":[{"level":3,"title":"TypeScript","slug":"typescript","link":"#typescript","children":[]},{"level":3,"title":"Props","slug":"props","link":"#props","children":[]},{"level":3,"title":"Styling","slug":"styling","link":"#styling","children":[]},{"level":3,"title":"Vue 2/3 Compatibility","slug":"vue-2-3-compatibility","link":"#vue-2-3-compatibility","children":[]}]},{"level":2,"title":"Testing","slug":"testing","link":"#testing","children":[{"level":3,"title":"Requirements","slug":"requirements","link":"#requirements","children":[]},{"level":3,"title":"Writing Tests","slug":"writing-tests","link":"#writing-tests","children":[]},{"level":3,"title":"Running Tests","slug":"running-tests","link":"#running-tests","children":[]}]},{"level":2,"title":"Commit Conventions","slug":"commit-conventions","link":"#commit-conventions","children":[]},{"level":2,"title":"Pull Request Checklist","slug":"pull-request-checklist","link":"#pull-request-checklist","children":[]},{"level":2,"title":"Example Apps","slug":"example-apps","link":"#example-apps","children":[]},{"level":2,"title":"Questions?","slug":"questions","link":"#questions","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":1.7,"words":511},"filePathRelative":"packages/ui/CONTRIBUTING.md","localizedDate":"March 1, 2026","excerpt":"\\n

Thank you for contributing to the ocelot.social UI library!

\\n

Development Setup

\\n
# Install dependencies\\nnpm install\\n\\n# Start development server\\nnpm run dev\\n\\n# Run tests\\nnpm test\\n\\n# Run linter\\nnpm run lint
\\n
"}');export{y as comp,u as data}; diff --git a/assets/DataDisplay.html-Sq6mPmsX.js b/assets/DataDisplay.html-Sq6mPmsX.js new file mode 100644 index 000000000..06aea8a79 --- /dev/null +++ b/assets/DataDisplay.html-Sq6mPmsX.js @@ -0,0 +1 @@ +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,b as s,o as r}from"./app-C6w_Pklu.js";const i={};function l(o,e){return r(),t("div",null,e[0]||(e[0]=[s("p",null,"Data Display components are used to present data in an approachable way.",-1)]))}const d=a(i,[["render",l],["__file","DataDisplay.html.vue"]]),p=JSON.parse('{"path":"/styleguide/src/styleguide/docs/DataDisplay.html","title":"","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.04,"words":12},"filePathRelative":"styleguide/src/styleguide/docs/DataDisplay.md","localizedDate":"March 1, 2026","excerpt":"

Data Display components are used to present data in an approachable way.

\\n"}');export{d as comp,p as data}; diff --git a/assets/DesignTokens.html-BMTgeCjs.js b/assets/DesignTokens.html-BMTgeCjs.js new file mode 100644 index 000000000..007e450bd --- /dev/null +++ b/assets/DesignTokens.html-BMTgeCjs.js @@ -0,0 +1 @@ +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,a as i,e as n,o,r}from"./app-C6w_Pklu.js";const l={};function d(c,e){const s=r("design-tokens");return o(),a("div",null,[e[0]||(e[0]=i('

Design tokens are the visual design atoms of the design system — specifically, they are named entities that store visual design attributes. We use them in place of hard-coded values (such as hex values for color or pixel values for spacing) in order to maintain a scalable and consistent visual system for UI development.

You can use tokens as SCSS variables or import them in your JS:

import { tokens } from 'system'
',3)),n(s)])}const u=t(l,[["render",d],["__file","DesignTokens.html.vue"]]),p=JSON.parse('{"path":"/styleguide/src/styleguide/docs/DesignTokens.html","title":"","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.25,"words":74},"filePathRelative":"styleguide/src/styleguide/docs/DesignTokens.md","localizedDate":"March 1, 2026","excerpt":"

Design tokens are the visual design atoms of the design system — specifically, they are named entities that store visual design attributes. We use them in place of hard-coded values (such as hex values for color or pixel values for spacing) in order to maintain a scalable and consistent visual system for UI development.

"}');export{u as comp,p as data}; diff --git a/assets/GraphQL-Playground.html-KHcgqCNs.js b/assets/GraphQL-Playground.html-KHcgqCNs.js new file mode 100644 index 000000000..9628d203b --- /dev/null +++ b/assets/GraphQL-Playground.html-KHcgqCNs.js @@ -0,0 +1,50 @@ +import{_ as h}from"./graphql-playground (1)-C_SWrH2M.js";import{_ as p}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as r,a as e,b as a,d as i,e as t,f as l,r as d,o as k}from"./app-C6w_Pklu.js";const o={};function g(u,s){const n=d("RouteLink");return k(),r("div",null,[s[8]||(s[8]=e('

GraphQL Playground

GraphQL Playground
GraphQL Playground

Attention: For using the GraphQL Playground set DEBUG=true in your backend .env, see .env.template!

To use GraphQL Playground, we need to know some basics:

How To Login?

First, we need to have a user from ocelot.social to log in as. The user can be created by seeding the Neo4j database from the backend or by multiple GraphQL mutations.

Seed The Neo4j Database

',7)),a("p",null,[s[1]||(s[1]=i("In your browser you can reach the GraphQL Playground under ")),s[2]||(s[2]=a("code",null,"http://localhost:4000/",-1)),s[3]||(s[3]=i(", if the database and the backend are running, see ")),t(n,{to:"/backend/"},{default:l(()=>s[0]||(s[0]=[i("backend")])),_:1}),s[4]||(s[4]=i(". There you will also find instructions on how to seed the database."))]),s[9]||(s[9]=e(`

Use GraphQL Mutations To Create A User

TODO: Describe how to create a user using GraphQL mutations!

Login Via GraphQL

You can register a user by sending the query:

mutation {
+  login(email: "user@example.org", password: "1234")
+}

Or use "moderator@example.org" or "admin@example.org" for the roll you need.

If all goes well, you will receive a QGL response like:

{
+  "data": {
+    "login": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InUzIiwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTY2MjAyMzMwNSwiZXhwIjoxNzI1MTM4NTA1LCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.atBS-SOeS784HPeFl_5s8sRWehEAU1BkgcOZFD8d4bU"
+  }
+}

You can use this response to set an HTTP header when you click HTTP HEADERS in the footer. Just set it with the login token you received in response:

{
+  "Authorization": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6InUzIiwibmFtZSI6Ikplbm55IFJvc3RvY2siLCJzbHVnIjoiamVubnktcm9zdG9jayIsImlhdCI6MTY2MjAyMzMwNSwiZXhwIjoxNzI1MTM4NTA1LCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjMwMDAiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQwMDAiLCJzdWIiOiJ1MyJ9.atBS-SOeS784HPeFl_5s8sRWehEAU1BkgcOZFD8d4bU"
+}

This token is used for all other queries and mutations you send to the backend.

Query And Mutate

When you are logged in and open a new playground tab by clicking "+", you can create a new group by sending the following mutation:

mutation {
+  CreateGroup(
+    # id: ""
+    name: "My Group"
+    # slug: ""
+    about: "We will save the world"
+    description: "<p class=\\"\\"><em>English:</em></p><p class=\\"\\">This group is hidden.</p><h3>What is our group for?</h3><p>This group was created to allow investigative journalists to share and collaborate.</p><h3>How does it work?</h3><p>Here you can internally share posts and comments about them.</p><p><br></p><p><em>Deutsch:</em></p><p class=\\"\\">Diese Gruppe ist verborgen.</p><h3>Wofür ist unsere Gruppe?</h3><p class=\\"\\">Diese Gruppe wurde geschaffen, um investigativen Journalisten den Austausch und die Zusammenarbeit zu ermöglichen.</p><h3>Wie funktioniert das?</h3><p class=\\"\\">Hier könnt ihr euch intern über Beiträge und Kommentare zu ihnen austauschen.</p>"
+    groupType: hidden
+    actionRadius: interplanetary
+    categoryIds: ["cat12"]
+  ) {
+    id
+    name
+    slug
+    createdAt
+    updatedAt
+    disabled
+    deleted
+    about
+    description
+    groupType
+    actionRadius
+    myRole
+  }
+}

You will receive the answer:

{
+  "data": {
+    "CreateGroup": {
+      "id": "2e3bbadb-804b-4ebc-a673-2d7c7f05e827",
+      "name": "My Group",
+      "slug": "my-group",
+      "createdAt": "2022-09-01T09:44:47.969Z",
+      "updatedAt": "2022-09-01T09:44:47.969Z",
+      "disabled": false,
+      "deleted": false,
+      "about": "We will save the world",
+      "description": "<p class=\\"\\"><em>English:</em></p><p class=\\"\\">This group is hidden.</p><h3>What is our group for?</h3><p>This group was created to allow investigative journalists to share and collaborate.</p><h3>How does it work?</h3><p>Here you can internally share posts and comments about them.</p><p><br></p><p><em>Deutsch:</em></p><p class=\\"\\">Diese Gruppe ist verborgen.</p><h3>Wofür ist unsere Gruppe?</h3><p class=\\"\\">Diese Gruppe wurde geschaffen, um investigativen Journalisten den Austausch und die Zusammenarbeit zu ermöglichen.</p><h3>Wie funktioniert das?</h3><p class=\\"\\">Hier könnt ihr euch intern über Beiträge und Kommentare zu ihnen austauschen.</p>",
+      "groupType": "hidden",
+      "actionRadius": "interplanetary",
+      "myRole": "owner"
+    }
+  }
+}
`,16)),a("p",null,[s[6]||(s[6]=i("If you look into the Neo4j database with your browser and search the groups, you will now also find your new group. For more details about our Neo4j database read ")),t(n,{to:"/neo4j/"},{default:l(()=>s[5]||(s[5]=[i("here")])),_:1}),s[7]||(s[7]=i("."))])])}const B=p(o,[["render",g],["__file","GraphQL-Playground.html.vue"]]),b=JSON.parse('{"path":"/backend/src/graphql/GraphQL-Playground.html","title":"GraphQL Playground","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"How To Login?","slug":"how-to-login","link":"#how-to-login","children":[{"level":3,"title":"Seed The Neo4j Database","slug":"seed-the-neo4j-database","link":"#seed-the-neo4j-database","children":[]},{"level":3,"title":"Use GraphQL Mutations To Create A User","slug":"use-graphql-mutations-to-create-a-user","link":"#use-graphql-mutations-to-create-a-user","children":[]},{"level":3,"title":"Login Via GraphQL","slug":"login-via-graphql","link":"#login-via-graphql","children":[]}]},{"level":2,"title":"Query And Mutate","slug":"query-and-mutate","link":"#query-and-mutate","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":1.94,"words":581},"filePathRelative":"backend/src/graphql/GraphQL-Playground.md","localizedDate":"March 1, 2026","excerpt":"\\n
GraphQL Playground
\\n

Attention: For using the GraphQL Playground set DEBUG=true in your backend .env, see .env.template!

\\n

To use GraphQL Playground, we need to know some basics:

\\n

How To Login?

"}');export{B as comp,b as data}; diff --git a/assets/Introduction.html-BLSaoncO.js b/assets/Introduction.html-BLSaoncO.js new file mode 100644 index 000000000..9e796d15d --- /dev/null +++ b/assets/Introduction.html-BLSaoncO.js @@ -0,0 +1 @@ +import{_ as n}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,a as o,o as i}from"./app-C6w_Pklu.js";const a={};function s(r,e){return i(),t("div",null,e[0]||(e[0]=[o('

Human Connection - Styleguide

This Design System provides our team with essential components and guidelines to achieve a consistent user experience accross our applications.

Documentation

If you are searching for more technical information for the UI & API, you can find it in the HC Documentation.

How to use it

Use the system's components to solve common UI problems like layout, typography, displaying data or data input.

When no component fits your case, either extend an existing one or create a new one.

Extending existing components

When extending components, make sure not to break existing features. If you really need to, it might be better to create a new one and mark the existing component as deprecated

Creating new components

Keep a few things in mind when creating a new component:

Resources

If you would like to become a component superhero feel free to dive into the Vuejs Component Style Guide.

',14)]))}const d=n(a,[["render",s],["__file","Introduction.html.vue"]]),h=JSON.parse('{"path":"/styleguide/src/styleguide/docs/Introduction.html","title":"","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Human Connection - Styleguide","slug":"human-connection-styleguide","link":"#human-connection-styleguide","children":[{"level":3,"title":"Documentation","slug":"documentation","link":"#documentation","children":[]},{"level":3,"title":"How to use it","slug":"how-to-use-it","link":"#how-to-use-it","children":[]},{"level":3,"title":"Extending existing components","slug":"extending-existing-components","link":"#extending-existing-components","children":[]},{"level":3,"title":"Creating new components","slug":"creating-new-components","link":"#creating-new-components","children":[]},{"level":3,"title":"Resources","slug":"resources","link":"#resources","children":[]}]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.58,"words":174},"filePathRelative":"styleguide/src/styleguide/docs/Introduction.md","localizedDate":"March 1, 2026","excerpt":"

Human Connection - Styleguide

\\n

This Design System provides our team with essential components and guidelines to achieve a consistent user experience accross our applications.

\\n

Documentation

\\n

If you are searching for more technical information for the UI & API, you can find it in the HC Documentation.

"}');export{d as comp,h as data}; diff --git a/assets/KATALOG.html-mRGwYwFN.js b/assets/KATALOG.html-mRGwYwFN.js new file mode 100644 index 000000000..4d736060d --- /dev/null +++ b/assets/KATALOG.html-mRGwYwFN.js @@ -0,0 +1,119 @@ +import{_ as e}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as d,a as s,o as i}from"./app-C6w_Pklu.js";const n={};function a(r,t){return i(),d("div",null,t[0]||(t[0]=[s(`

Komponenten-Katalog

Tracking der Katalogisierung aller bestehenden Komponenten. Diese Datei ermöglicht das Unterbrechen und Fortsetzen der Analyse.


Fortschritt

Übersicht

Phase 0: Analyse       ██████████ 100% (8/8 Schritte) ✅
+Phase 3: OsButton      ██████████ 100% (133/133 Buttons) ✅
+Phase 4: Tier 1        ██████████ 100% (OsButton, OsIcon, OsSpinner, OsCard) ✅
+Phase 4: Tier A → HTML ██████████ 100% (10 ds-* Wrapper → Plain HTML) ✅
+Phase 4: Tier B        ████████░░  80% (ds-chip→OsBadge✅, ds-tag→OsBadge✅, ds-grid✅, ds-number→OsNumber✅, ds-radio⬜)
+Phase 4: Tier B+       ████████░░  75% (ds-table→HTML✅) | Tier 2-3 ausstehend (OsModal, OsInput, OsMenu, OsSelect)

Statistiken

MetrikWert
Webapp Komponenten139
Styleguide Komponenten38 (23 in Webapp genutzt)
Gesamt177
✅ UI-LibraryOsButton, OsIcon, OsSpinner, OsCard, OsBadge, OsNumber (6)
✅ → Plain HTMLSection, Placeholder, List, ListItem, Container, Heading, Text, Space, Flex, FlexItem, Grid, GridItem, Table (13)
✅ → OsBadgeChip (20 Nutzungen → OsBadge), Tag (3 → OsBadge shape="square")
✅ → OsNumberNumber (5 Nutzungen → OsNumber, CountTo.vue gelöscht, vue-count-to entfernt)
⬜ → Plain HTMLRadio (1) — Tier B Rest
⬜ → UI-LibraryModal, Input, Menu, MenuItem, Select (5) — Tier 2-3
⬜ OffenForm (18 Dateien — HTML oder OsForm?)
⬜ Nicht in WebappCode, CopyField, FormItem, InputError, InputLabel, Page, PageTitle, Logo, Avatar, TableCol, TableHeadCol (11)

OsButton Migration (Phase 3) ✅

133 Buttons migriert in 79 Dateien ✅ — BaseButton.vue gelöscht, base-components.js Plugin entfernt.

Erkenntnisse aus der Migration:


Styleguide Komponenten (38)

Quelle: ../../styleguide/src/system/components/ Live: http://styleguide.ocelot.social/

Data Display

#KomponenteStatusNotizen
1Avatar⬜ Nicht genutztWebapp nutzt eigenes ProfileAvatar
2Card✅ UI-Library→ OsCard (BaseCard gelöscht)
3Chip✅ UI-Library→ OsBadge (20 Nutzungen in 5 Dateien)
4Code⬜ Nicht genutztNicht in Webapp verwendet
5Icon✅ UI-Library→ OsIcon (BaseIcon gelöscht, 82 Ocelot-Icons)
6Number✅ UI-Library→ OsNumber (5 Dateien, CountTo.vue gelöscht, vue-count-to entfernt)
7Placeholder✅ → HTMLTier A: <div class="ds-placeholder">
8Spinner✅ UI-Library→ OsSpinner (LoadingSpinner gelöscht)
9Table✅ → HTML7 Dateien → Plain HTML <table> + CSS-Klassen (kein OsTable nötig)
10TableCol✅ → HTMLErsetzt durch native <td class="ds-table-col">
11TableHeadCol✅ → HTMLErsetzt durch native <th class="ds-table-head-col">
12Tag✅ UI-Library→ OsBadge shape="square" (3 Nutzungen in 3 Dateien)

Data Input

#KomponenteStatusNotizen
13Button✅ UI-Library→ OsButton (133 Buttons in 79 Dateien, BaseButton gelöscht)
14CopyField⬜ Nicht genutztNicht in Webapp verwendet
15Form⬜ Offen18 Dateien — HTML <form> oder OsForm?
16FormItem⬜ Nicht genutztNicht in Webapp verwendet
17Input⬜ Tier 223 Dateien → OsInput (gekoppelt mit Form)
18InputError⬜ Nicht genutztIntern von Input genutzt
19InputLabel⬜ Nicht genutztIntern von Input genutzt
20Radio⬜ Tier B1 Datei → native <input type="radio">
21Select⬜ Tier 43 Dateien → OsSelect

Layout

#KomponenteStatusNotizen
22Container✅ → HTMLTier A: <div class="ds-container ds-container-{width}">
23Flex✅ → HTMLTier A: Plain HTML + CSS @media Queries
24FlexItem✅ → HTMLTier A: Plain HTML + CSS @media Queries
25Grid✅ → HTML2 Dateien → CSS Grid (class="ds-grid")
26GridItem✅ → HTML8 Dateien → CSS Grid
27Modal⬜ Tier 27 Dateien → OsModal
28Page⬜ Nicht genutztNicht direkt in Webapp verwendet
29PageTitle⬜ Nicht genutztNicht direkt in Webapp verwendet
30Section✅ → HTMLTier A: <section class="ds-section">
31Space✅ → HTMLTier A: <div class="ds-mb-{size}"> / <div class="ds-my-{size}">
#KomponenteStatusNotizen
32List✅ → HTMLTier A: <ul class="ds-list">
33ListItem✅ → HTMLTier A: <li class="ds-list-item">
34Logo⬜ Nicht genutztWebapp nutzt eigenes Logo
35Menu⬜ Tier 311 Dateien → OsMenu
36MenuItem⬜ Tier 36 Dateien → OsMenuItem

Typography

#KomponenteStatusNotizen
37Heading✅ → HTMLTier A: <h1-h4 class="ds-heading ds-heading-h{n}">
38Text✅ → HTMLTier A: <p class="ds-text ds-text-{color}">

Webapp Komponenten (139)

Quelle: ../../webapp/components/

Status-Legende

A-B

#KomponenteStatusKategorieStyleguide-PendantNotizen
1ActionButton✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton
2ActionRadiusSelect⬜ AusstehendInput
3AddChatRoomByUserSearch⬜ AusstehendFeatureChat-spezifisch
4AddGroupMember⬜ AusstehendFeatureGroup-spezifisch
5AvatarMenu⬜ AusstehendNavigationAvatar + Menu
6AvatarUploader⬜ AusstehendInput
7BadgeSelection⬜ AusstehendInput
8Badges⬜ AusstehendDisplay
9BadgesSection⬜ AusstehendDisplay
10BaseButton✅ GelöschtButtonButton→ OsButton (133 Buttons, Komponente gelöscht)
11BaseCard✅ GelöschtLayoutCard→ OsCard (~30 Dateien, Komponente gelöscht)
12BaseIcon✅ GelöschtDisplayIcon→ OsIcon (131 Nutzungen, Komponente gelöscht)

C

#KomponenteStatusKategorieStyleguide-PendantNotizen
13CategoriesFilter⬜ AusstehendFilter
14CategoriesMenu⬜ AusstehendNavigationMenu
15CategoriesSelect✅ MigriertInputSelectButtons → OsButton (icon)
16ChangePassword⬜ AusstehendFeatureAuth-spezifisch
17Change⬜ AusstehendFeature
18Chat⬜ AusstehendFeatureChat-spezifisch
19ChatNotificationMenu⬜ AusstehendFeatureChat-spezifisch
20CommentCard✅ MigriertDisplayCardButtons → OsButton, BaseCard → OsCard
21CommentForm⬜ AusstehendInputForm
22CommentList⬜ AusstehendDisplayList
23ComponentSlider⬜ AusstehendLayout
24ConfirmModal⬜ AusstehendFeedbackModal🔄 Modal-Familie
25ContentMenu⬜ AusstehendNavigationMenu
26ContentViewer⬜ AusstehendDisplay
27ContextMenu⬜ AusstehendNavigationMenu
28ContributionForm✅ MigriertFeatureFormButtons → OsButton, ds-* → HTML
29CounterIcon⬜ AusstehendDisplayIcon
30CountTo✅ GelöschtDisplayNumber→ OsNumber (Animation eingebaut, vue-count-to entfernt)
31CreateInvitation⬜ AusstehendFeature
32CtaJoinLeaveGroup✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton
33CtaUnblockAuthor✅ MigriertButtonButtonNutzt OsButton (icon, as="nuxt-link")
34CustomButton✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton

D-E

#KomponenteStatusKategorieStyleguide-PendantNotizen
35DateTimeRange⬜ AusstehendInput
36DeleteData⬜ AusstehendFeature
37DeleteUserModal✅ MigriertFeedbackModal🔄 Modal-Familie, Buttons → OsButton
38DisableModal✅ MigriertFeedbackModal🔄 Modal-Familie, Buttons → OsButton
39DonationInfo✅ MigriertDisplayButton → OsButton
40Dropdown⬜ AusstehendInputSelect
41DropdownFilter⬜ AusstehendFilterSelect
42Editor⬜ AusstehendInputRich-Text
43EmailDisplayAndVerify⬜ AusstehendFeature
44EmbedComponent✅ MigriertDisplayButtons → OsButton
45EmotionButton✅ MigriertButtonButtonNutzt OsButton intern
46Emotions⬜ AusstehendFeature
47Empty⬜ AusstehendFeedbackPlaceholder
48EnterNonce✅ MigriertFeatureAuth, Submit → OsButton

F-G

#KomponenteStatusKategorieStyleguide-PendantNotizen
49EventsByFilter⬜ AusstehendFilter
50FiledReportsTable⬜ AusstehendDisplayTable
51FilterMenu⬜ AusstehendNavigationMenu
52FilterMenuComponent⬜ AusstehendNavigationMenu
53FilterMenuSection⬜ AusstehendNavigationMenu
54FollowButton✅ MigriertButtonButtonNutzt OsButton intern
55FollowingFilter⬜ AusstehendFilter
56FollowList⬜ AusstehendDisplayList
57GroupButton✅ MigriertButtonButtonNutzt OsButton intern
58GroupContentMenu⬜ AusstehendNavigationMenu
59GroupForm✅ MigriertInputFormButtons → OsButton
60GroupLink⬜ AusstehendNavigation
61GroupList⬜ AusstehendDisplayList
62GroupMember✅ MigriertDisplayButton → OsButton
63GroupTeaser⬜ AusstehendDisplayCard

H-L

#KomponenteStatusKategorieStyleguide-PendantNotizen
64Hashtag✅ MigriertDisplayTag/Chip🔄 nutzt OsBadge shape="square"
65HashtagsFilter⬜ AusstehendFilter
66HeaderButton✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton
67HeaderMenu⬜ AusstehendNavigationMenu
68ImageUploader✅ MigriertInputCrop-Buttons → OsButton, Spinner → OsSpinner
69index⬜ Ausstehend?Prüfen
70InternalPage⬜ AusstehendLayoutPage
71Invitation⬜ AusstehendFeature
72InvitationList⬜ AusstehendDisplayList
73InviteButton✅ MigriertButtonButtonNutzt OsButton intern
74JoinLeaveButton✅ MigriertButtonButtonNutzt OsButton intern
75LabeledButton✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton
76LinkInput⬜ AusstehendInputInput
77LoadingSpinner✅ GelöschtFeedbackSpinner→ OsSpinner (Komponente gelöscht)
78LocaleSwitch⬜ AusstehendNavigation
79LocationInfo⬜ AusstehendDisplay
80LocationSelect✅ MigriertInputSelectClose-Button → OsButton (icon)
81LocationTeaser⬜ AusstehendDisplayCard
82LoginButton✅ MigriertButtonButtonNutzt OsButton intern
83LoginForm⬜ AusstehendFeatureFormAuth
84Logo⬜ AusstehendDisplayLogo🔗 DUPLIKAT (noch ungelöst)

M-O

#KomponenteStatusKategorieStyleguide-PendantNotizen
85MapButton✅ MigriertButtonButtonNutzt OsButton intern
86MapStylesButtons✅ MigriertButtonButtonButton → OsButton
87MasonryGrid⬜ AusstehendLayoutGrid
88MasonryGridItem⬜ AusstehendLayoutGridItem
89MenuBar⬜ AusstehendNavigationMenu
90MenuBarButton✅ MigriertButtonButton🔄 Button-Familie, nutzt OsButton
91MenuLegend⬜ AusstehendNavigation
92Modal⬜ AusstehendFeedbackModal🔗 DUPLIKAT
93MySomethingList✅ MigriertDisplayListButtons → OsButton
94NotificationMenu✅ MigriertNavigationMenuButtons → OsButton
95NotificationsTable⬜ AusstehendDisplayTable
96ObserveButton✅ MigriertButtonButtonNutzt OsButton intern
97OrderByFilter⬜ AusstehendFilter

P-R

#KomponenteStatusKategorieStyleguide-PendantNotizen
98PageFooter⬜ AusstehendLayout
99PageParamsLink⬜ AusstehendNavigation
100PaginationButtons✅ MigriertNavigation2 Buttons → OsButton (icon, circle)
101PostTeaser⬜ AusstehendDisplayCard
102PostTypeFilter⬜ AusstehendFilter
103ProfileAvatar⬜ AusstehendDisplayAvatar
104ProfileList⬜ AusstehendDisplayList
105ProgressBar⬜ AusstehendFeedback
106RegistrationSlideCreate⬜ AusstehendFeatureAuth
107RegistrationSlideEmail⬜ AusstehendFeatureAuth
108RegistrationSlideInvite⬜ AusstehendFeatureAuth
109RegistrationSlideNonce⬜ AusstehendFeatureAuth
110RegistrationSlideNoPublic⬜ AusstehendFeatureAuth
111RegistrationSlider⬜ AusstehendFeatureAuth
112ReleaseModal✅ MigriertFeedbackModal🔄 Modal-Familie, Buttons → OsButton
113ReportList⬜ AusstehendDisplayList
114ReportModal⬜ AusstehendFeedbackModal🔄 Modal-Familie
115ReportRow✅ MigriertDisplayMore Details → OsButton
116ReportsTable⬜ AusstehendDisplayTable
117Request⬜ AusstehendFeature
118ResponsiveImage⬜ AusstehendDisplay

S

#KomponenteStatusKategorieStyleguide-PendantNotizen
119SearchableInput⬜ AusstehendInputInput
120SearchField⬜ AusstehendInputInput
121SearchGroup⬜ AusstehendFeatureSearch
122SearchHeading⬜ AusstehendDisplayHeading
123SearchPost⬜ AusstehendFeatureSearch
124SearchResults⬜ AusstehendFeatureSearch
125SelectUserSearch⬜ AusstehendInputSelect
126ShoutButton✅ MigriertButtonButtonNutzt OsButton intern
127ShowPassword⬜ AusstehendInput
128Signup⬜ AusstehendFeatureAuth
129SocialMedia⬜ AusstehendDisplay
130SocialMediaListItem⬜ AusstehendDisplayListItem
131Strength⬜ AusstehendFeedbackPassword
132SuggestionList⬜ AusstehendDisplayList

T-Z

#KomponenteStatusKategorieStyleguide-PendantNotizen
133TabNavigation⬜ AusstehendNavigation
134UserTeaser⬜ AusstehendDisplayCard
135UserTeaserHelper⬜ AusstehendDisplay
136UserTeaserNonAnonymous⬜ AusstehendDisplay
137UserTeaserPopover✅ MigriertDisplayButton → OsButton

Identifizierte Duplikate & Konsolidierung

Direkte Duplikate (Webapp ↔ Styleguide)

WebappStyleguideAktionStatus
LogoLogoKonsolidieren zu OsLogo⬜ Ausstehend
ModalModalKonsolidieren zu OsModal⬜ Ausstehend
BaseCardCard→ OsCard✅ Erledigt (BaseCard gelöscht)
BaseIconIcon→ OsIcon✅ Erledigt (BaseIcon gelöscht)
LoadingSpinnerSpinner→ OsSpinner✅ Erledigt (LoadingSpinner gelöscht)

Button-Familie ✅ (alle nutzen OsButton)

KomponenteStatusNotizen
Button (Styleguide)✅ Ersetzt→ OsButton
BaseButton✅ Gelöscht→ OsButton (133 Buttons)
CustomButton✅ Nutzt OsButtonFeature-Wrapper
ActionButton✅ Nutzt OsButtonFeature-Wrapper
HeaderButton✅ Nutzt OsButtonFeature-Wrapper
LabeledButton✅ Nutzt OsButtonFeature-Wrapper
MenuBarButton✅ Nutzt OsButtonFeature-Wrapper
FollowButton✅ Nutzt OsButtonFeature-spezifisch
GroupButton✅ Nutzt OsButtonFeature-spezifisch
InviteButton✅ Nutzt OsButtonFeature-spezifisch
LoginButton✅ Nutzt OsButtonFeature-spezifisch
EmotionButton✅ Nutzt OsButtonFeature-spezifisch
JoinLeaveButton✅ Nutzt OsButtonFeature-spezifisch
MapButton✅ Nutzt OsButtonFeature-spezifisch
MapStylesButtons✅ Nutzt OsButtonFeature-spezifisch
PaginationButtons✅ Nutzt OsButtonFeature-spezifisch
CtaJoinLeaveGroup✅ Nutzt OsButtonFeature-spezifisch
CtaUnblockAuthor✅ Nutzt OsButtonFeature-spezifisch
KomponenteBeschreibungZiel
Modal (Styleguide)Basis-ModalOsModal
Modal (Webapp)Basis-Modal→ OsModal
ConfirmModalBestätigungs-Dialog→ OsModal type="confirm"
DeleteUserModalLöschen-Dialog→ OsModal type="confirm"
DisableModalDeaktivieren-Dialog→ OsModal type="confirm"
ReleaseModalRelease-DialogFeature-spezifisch
ReportModalReport-DialogFeature-spezifisch
KomponenteBeschreibungZiel
Menu (Styleguide)Basis-MenuOsMenu
MenuItem (Styleguide)Menu-ItemOsMenuItem
HeaderMenuHeader-Navigation→ OsMenu
ContentMenuKontext-Menu→ OsMenu variant
ContextMenuKontext-Menu→ OsMenu variant
FilterMenuFilter-Menu→ OsMenu variant
NotificationMenuBenachrichtigungenFeature-spezifisch
CategoriesMenuKategorienFeature-spezifisch
AvatarMenuUser-MenuFeature-spezifisch

Kategorisierung

Basis-Komponenten — UI-Library ✅

Basis-Komponenten — UI-Library (ausstehend)

Layout & Typography — → Plain HTML ✅ (Tier A)

Noch zu migrieren (Tier B Rest)

Feature-Komponenten (bleiben in Webapp)


Analyse-Protokoll

DatumBearbeiterAktionDetails
2026-02-04ClaudeKatalog erstellt177 Komponenten erfasst
2026-02-04ClaudeDuplikate identifiziertButton, Modal, Menu Familien
2026-02-04ClaudeButton-AnalyseProps-Vergleich, Konsolidierungsvorschlag, Token-Extraktion
2026-02-04ClaudeModal-AnalyseArchitektur erkannt: DsModal = Basis, Feature-Modals nutzen DsModal
2026-02-04ClaudeMenu-AnalyseDsMenu, Dropdown, Feature-Menus - 3 separate Patterns identifiziert
2026-02-04ClaudePriorisierung15 Komponenten in 4 Tiers priorisiert
2026-02-04ClaudeKonsolidierungsplan3 Phasen definiert, Token-Liste erstellt
2026-02-04ClaudePhase 0 abgeschlossenBereit für Phase 2 (Projekt-Setup)
2026-02-08ClaudeOsButton entwickeltCVA-Varianten, Vue 2/3 kompatibel via vue-demi
2026-02-08ClaudeWebapp-IntegrationJest Mock, Docker Build, CI-Kompatibilität
2026-02-08Claude16 Buttons migriertAlle ohne icon/circle/loading Props, validiert
2026-02-08ClaudeOsButton erweitertattrs/listeners Forwarding für Vue 2 ($listeners)
2026-02-09ClaudeScope erweitert~90 Buttons identifiziert (16 migriert, 14 ohne Props, ~60 mit Props)
2026-02-09ClaudeMilestone 4a: 8 ButtonsDisableModal, DeleteUserModal, ReleaseModal, ContributionForm, EnterNonce, MySomethingList, ImageUploader (2x)
2026-02-09ClaudeMilestone 4a abgeschlossen6 weitere: donations, profile (2x), badges, notifications/index, ReportRow
2026-02-11ClaudeM4b: icon + circleicon-Slot implementiert, circle-Prop mit CVA
2026-02-11Claude9 icon-Buttons migriert (M4c)DisableModal, DeleteUserModal, CtaUnblockAuthor, LocationSelect, CategoriesSelect, my-email-address, profile Chat, PaginationButtons (2x circle)
2026-02-11→18ClaudeSessions 12-26OsButton M4c abgeschlossen, OsIcon, OsSpinner, OsCard implementiert + Webapp-Migration, BaseButton/BaseCard/BaseIcon/LoadingSpinner gelöscht
2026-02-19ClaudeTier A Migration10 ds-* Vue-Wrapper → Plain HTML + CSS, _ds-compat.scss, ~450 Nutzungen in ~90 Dateien
2026-02-19ClaudeKatalog konsolidiertStyleguide- und Webapp-Tabellen aktualisiert, veraltete Status korrigiert

Nächste Schritte

Phase 0: Analyse ✅

  1. [x] Webapp-Komponenten auflisten
  2. [x] Styleguide-Komponenten auflisten
  3. [x] Duplikate und Familien identifizieren
  4. [x] Button/Modal/Menu im Detail analysieren
  5. [x] Priorisierung und Konsolidierungsplan

Phase 3: OsButton Migration ✅

  1. [x] OsButton entwickeln (CVA, vue-demi)
  2. [x] 133 Buttons in 79 Dateien migriert
  3. [x] BaseButton.vue gelöscht, base-components.js Plugin entfernt

Phase 4: Tier 1 — UI-Library Kern ✅

  1. [x] OsIcon + 82 Ocelot-Icons, BaseIcon gelöscht
  2. [x] OsSpinner + Webapp-Migration, LoadingSpinner gelöscht
  3. [x] OsCard + Webapp-Migration, BaseCard gelöscht

Phase 4: Tier A — ds-* → Plain HTML ✅

  1. [x] _ds-compat.scss Utility-Klassen
  2. [x] 10 ds-* Wrapper → HTML + CSS (~450 Nutzungen, ~90 Dateien)

Phase 4: Tier B — ds-* Migration (60%)

  1. [x] ds-chip (5 Dateien, 20 Nutzungen) → OsBadge (UI-Library)
  2. [x] ds-tag (3 Dateien) → OsBadge shape="square" (UI-Library)
  3. [x] ds-grid / ds-grid-item (10 Dateien) → CSS Grid (Plain HTML)
  4. [ ] ds-number (5 Dateien) → <div class="ds-number">
  5. [ ] ds-radio (1 Datei) → native <input type="radio">

Phase 4: Tier 2-4 — UI-Library (ausstehend)

  1. [ ] OsModal (7 Dateien)
  2. [ ] OsInput (23 Dateien, gekoppelt mit ds-form)
  3. [ ] OsMenu / OsMenuItem (17 Dateien)
  4. [ ] OsSelect (3 Dateien), OsTable (7 Dateien)
  5. [ ] ds-form → HTML <form> oder OsForm (18 Dateien)

✅ Phase 0-3 abgeschlossen. Phase 4: Tier 1 + Tier A ✅, Tier B 60% (Chip→OsBadge, Tag→OsBadge, Grid→HTML), Tier 2-4 ausstehend.


Detailanalyse: Button-Familie

Styleguide Button (DsButton)

Pfad: styleguide/src/system/components/navigation/Button/Button.vue

Props:

PropTypDefaultBeschreibung
pathString|ObjectnullURL oder Vue Router Pfad
sizeStringnullsmall | base | large
linkTagStringautorouter-link | a | button
nameStringnullAccessibility name
primaryBooleanfalsePrimärer Stil (grün)
secondaryBooleanfalseSekundärer Stil (blau)
dangerBooleanfalseDanger Stil (rot)
hoverBooleanfalseHover-State erzwingen
ghostBooleanfalseTransparenter Hintergrund
iconStringnullIcon-Name
rightBooleanfalseIcon rechts positionieren
fullwidthBooleanfalseVolle Breite
loadingBooleanfalseLadezustand

Besonderheiten:


Webapp BaseButton

Pfad: webapp/components/_new/generic/BaseButton/BaseButton.vue

Props:

PropTypDefaultBeschreibung
bulletBooleanfalseKleiner runder Punkt (18px)
circleBooleanfalseRunder Button
dangerBooleanfalseDanger-Farbschema
filledBooleanfalseGefüllter Hintergrund
ghostBooleanfalseOhne Border
iconString-Icon-Name
loadingBooleanfalseLadezustand
sizeString'regular'tiny | small | regular | large
paddingBooleanfalseExtra Padding
typeString'button'button | submit
disabledBooleanfalseDeaktiviert

Besonderheiten:


Vergleich: Styleguide vs Webapp

FeatureStyleguide (DsButton)Webapp (BaseButton)
Sizessmall, base, largetiny, small, regular, large
Variantenprimary, secondary, dangerdanger (+ filled)
Formenicon-only (auto)circle, bullet, icon-only (auto)
Ghost
Loading✅ Spinner✅ LoadingSpinner
Link-Support✅ path prop
Fullwidth
Icon-Position✅ left/right❌ nur links
Submit-Type
CSS-Prefixds-buttonbase-button

Wrapper-Komponenten (nutzen BaseButton)

KomponenteZweckEigene PropsMigration
ActionButtonButton + Counter Badgecount, text, icon, filledEigene Komponente behalten
LabeledButtonButton + Label daruntericon, label, filledEigene Komponente behalten
HeaderButtonFilter-Button + Removetitle, clickButton, titleRemove, clickRemoveFeature-spezifisch
MenuBarButtonEditor-ToolbarisActive, icon, label, onClickFeature-spezifisch
CustomButtonButton mit externem Iconsettings (Object)Feature-spezifisch

Erkenntnis: Diese Wrapper fügen Layout/Logik hinzu, nicht Button-Varianten.


Feature-Buttons (Business-Logik) ✅

Feature-Buttons behalten Business-Logik, nutzen aber intern alle OsButton:

KomponenteStatus
FollowButton✅ Nutzt OsButton
GroupButton✅ Nutzt OsButton
InviteButton✅ Nutzt OsButton
LoginButton✅ Nutzt OsButton
ShoutButton✅ Nutzt OsButton
ObserveButton✅ Nutzt OsButton
EmotionButton✅ Nutzt OsButton
JoinLeaveButton✅ Nutzt OsButton
MapButton✅ Nutzt OsButton
MapStylesButtons✅ Nutzt OsButton
PaginationButtons✅ Nutzt OsButton

Konsolidierungsvorschlag: OsButton ✅ IMPLEMENTIERT

Hinweis: Die tatsächliche API weicht vom ursprünglichen Vorschlag ab. Siehe packages/ui/src/components/OsButton/OsButton.vue für die aktuelle Implementierung.

Implementierte API (CVA-basiert):

interface OsButtonProps {
+  variant?: 'default' | 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info'
+  appearance?: 'filled' | 'outline' | 'ghost'  // statt separate booleans
+  size?: 'sm' | 'md' | 'lg' | 'xl'             // vereinfachte Größen
+  circle?: boolean
+  fullWidth?: boolean
+  loading?: boolean
+  disabled?: boolean
+  as?: 'button' | 'a' | 'nuxt-link' | 'router-link' | Component  // polymorphes Rendering
+  type?: 'button' | 'submit' | 'reset'
+  // Icon: slot-basiert (<template #icon>), nicht prop-basiert
+}

Verwendete Design-Tokens (tatsächlich genutzt)

Farben:

Größen:

Spacing:

Typography:

Border:

Animation:


Offene Fragen ✅ (alle gelöst)

  1. secondary Variante → ✅ Ja, implementiert als variant="secondary"
  2. x-large Size → ✅ Implementiert als size="xl"
  3. bullet Form → ✅ Nicht übernommen, circle + custom CSS reicht

Detailanalyse: Modal-Familie

Architektur-Übersicht

┌─────────────────────────────────────────────────────────────┐
+│  DsModal (Styleguide)                                       │
+│  = Basis-Modal-Komponente                                   │
+├─────────────────────────────────────────────────────────────┤
+│       ↓ wird genutzt von                                    │
+├─────────────────────────────────────────────────────────────┤
+│  ConfirmModal, DisableModal, ReportModal, etc.              │
+│  = Feature-Modals mit Business-Logik                        │
+├─────────────────────────────────────────────────────────────┤
+│       ↓ werden gerendert von                                │
+├─────────────────────────────────────────────────────────────┤
+│  Modal.vue (Webapp)                                         │
+│  = Modal-Manager (Router via Vuex-State)                    │
+└─────────────────────────────────────────────────────────────┘

Erkenntnis: Die Webapp Modal.vue ist KEIN Duplikat von DsModal, sondern ein State-basierter Modal-Router.


Styleguide DsModal

Pfad: styleguide/src/system/components/layout/Modal/Modal.vue

Props:

PropTypDefaultBeschreibung
titleStringnullModal-Titel
isOpenBooleanfalseGeöffnet-Status (v-model)
forceBooleanfalseSchließen verhindern (kein ESC, kein Backdrop-Click)
extendedBooleanfalseBreiterer Modal (600px statt 400px)
cancelLabelString'Cancel'Text für Abbrechen-Button
confirmLabelString'Confirm'Text für Bestätigen-Button

Events:

Slots:

Features:


Feature-Modals (nutzen DsModal)

ModalBusiness-LogikMigration
ConfirmModalGenerischer Confirm-Dialog mit CallbacksBleibt, nutzt OsModal
DisableModalGraphQL Mutation für DisableBleibt, nutzt OsModal
ReportModalReport-LogikBleibt, nutzt OsModal
DeleteUserModalUser-Lösch-LogikBleibt, nutzt OsModal
ReleaseModalRelease-LogikBleibt, nutzt OsModal

Erkenntnis: Alle Feature-Modals nutzen bereits DsModal als Basis und fügen nur spezifische Business-Logik hinzu. Dies ist das gewünschte Pattern!


Webapp Modal.vue (Modal-Manager)

Pfad: webapp/components/Modal.vue

Funktion: Kein UI-Modal, sondern ein State-basierter Modal-Router:

Mögliche Migration:


Konsolidierungsvorschlag: OsModal

interface OsModalProps {
+  // Basis
+  title?: string
+  isOpen: boolean           // v-model:open
+
+  // Verhalten
+  persistent?: boolean      // = force (Schließen verhindern)
+  closeOnBackdrop?: boolean // Default: true
+  closeOnEsc?: boolean      // Default: true
+
+  // Größe
+  size?: 'default' | 'large' | 'fullscreen'
+
+  // Footer
+  showFooter?: boolean
+  cancelLabel?: string
+  confirmLabel?: string
+  confirmVariant?: 'primary' | 'danger'
+}

Slots:

Nicht übernommen:


Verwendete Design-Tokens (tatsächlich genutzt)

Layout:

Farben:

Shadows:

Animation:


Detailanalyse: Menu-Familie

Architektur-Übersicht

┌─────────────────────────────────────────────────────────────┐
+│  DsMenu / DsMenuItem (Styleguide)                           │
+│  = Routen-basierte Navigationskomponenten                   │
+├─────────────────────────────────────────────────────────────┤
+│       ↓ wird genutzt von                                    │
+├─────────────────────────────────────────────────────────────┤
+│  ContentMenu, GroupContentMenu                              │
+│  = Dropdown + DsMenu für Kontext-Menüs                      │
+├─────────────────────────────────────────────────────────────┤
+│  Dropdown (Webapp)                                          │
+│  = Eigenständiger Popover-Wrapper (v-popover)               │
+├─────────────────────────────────────────────────────────────┤
+│  HeaderMenu                                                 │
+│  = Komplexes Layout (DsFlex-basiert), KEIN DsMenu           │
+├─────────────────────────────────────────────────────────────┤
+│  AvatarMenu, NotificationMenu, FilterMenu, etc.             │
+│  = Feature-spezifische Menüs mit eigener Logik              │
+└─────────────────────────────────────────────────────────────┘

Erkenntnis: DsMenu wird nur für strukturierte Routen-Navigation verwendet. Die meisten Webapp-Menüs sind Feature-spezifisch und bauen eigene Strukturen.


Styleguide DsMenu

Pfad: styleguide/src/system/components/navigation/Menu/Menu.vue

Props:

PropTypDefaultBeschreibung
routesArraynullArray von Route-Objekten
inverseBooleanfalseDunkler Hintergrund
navbarBooleanfalseHorizontale Navbar-Darstellung
linkTagString'router-link'Link-Komponente
urlParserFunctiondefaultURL-Parser für Routes
nameParserFunctiondefaultName-Parser für Routes
matcherFunctiondefaultActive-State Matcher
isExactFunctiondefaultExact-Match Checker

Slots:

Features:


Styleguide DsMenuItem

Pfad: styleguide/src/system/components/navigation/Menu/MenuItem.vue

Props:

PropTypDefaultBeschreibung
routeObjectnullRoute-Objekt
parentsArray[]Parent-Routes (für Submenu)
linkTagStringfrom parentLink-Komponente

Features:


Webapp Dropdown

Pfad: webapp/components/Dropdown.vue

Props:

PropTypDefaultBeschreibung
placementString'bottom-end'Popover-Position
disabledBooleanfalseDeaktiviert
offsetString|Number'16'Abstand vom Trigger
noMouseLeaveClosingBooleanfalseVerhindert Schließen bei Mouse-Leave

Slot-Props:

Features:

Erkenntnis: Dies ist das primäre Dropdown-Pattern in der Webapp - nicht DsMenu!


Kategorisierung der Menu-Komponenten

KomponenteTypNutzt DsMenuMigration
ContentMenuKontext-MenüOsDropdown + OsMenu
GroupContentMenuKontext-MenüOsDropdown + OsMenu
HeaderMenuLayoutBleibt Feature-spezifisch
AvatarMenuFeatureBleibt Feature-spezifisch
NotificationMenuFeatureBleibt Feature-spezifisch
FilterMenuFeatureBleibt Feature-spezifisch
CategoriesMenuFeatureBleibt Feature-spezifisch
ChatNotificationMenuFeatureBleibt Feature-spezifisch
MenuBarEditorBleibt Feature-spezifisch
ContextMenu (Editor)EditorBleibt Feature-spezifisch

Konsolidierungsvorschlag

Drei separate Komponenten:

  1. OsMenu (für Navigation)
interface OsMenuProps {
+  routes?: RouteItem[]
+  orientation?: 'vertical' | 'horizontal'
+  inverse?: boolean
+}
  1. OsMenuItem (für Menu-Items)
interface OsMenuItemProps {
+  to?: string | RouteLocationRaw
+  href?: string
+  icon?: string
+  active?: boolean
+}
  1. OsDropdown (für Popover-Menüs) - NEU
interface OsDropdownProps {
+  placement?: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | ...
+  offset?: number
+  disabled?: boolean
+  closeOnClick?: boolean
+  closeOnOutsideClick?: boolean
+}

Erkenntnis: OsDropdown ist wichtiger als OsMenu, da es häufiger verwendet wird!


Verwendete Design-Tokens (tatsächlich genutzt)

Spacing:

Typography:

Farben:


Priorisierung der Komponenten

Tier 1: Kern-Komponenten ✅

#KomponenteStatus
1OsButton✅ 133 Buttons in 79 Dateien, BaseButton gelöscht
2OsIcon✅ 131 Nutzungen, 82 Ocelot-Icons, BaseIcon gelöscht
3OsSpinner✅ 4 Spinner migriert, LoadingSpinner gelöscht
4OsCard✅ ~30 Dateien, BaseCard gelöscht

Tier A: Triviale ds-* → Plain HTML ✅

#KomponenteStatus
ds-section, ds-placeholder, ds-list, ds-list-item✅ → HTML-Elemente + CSS-Klassen
ds-container, ds-heading, ds-text✅ → HTML-Elemente + CSS-Klassen
ds-space✅ → div + Margin-Utility-Klassen
ds-flex, ds-flex-item✅ → HTML + CSS @media Queries

Tier B: Einfache ds-* Migration (60%)

#KomponenteDateienZielStatus
5OsBadgeds-chip (20 Nutzungen, 5 Dateien) + ds-tag (3 Dateien)
ds-grid / ds-grid-item10CSS Grid (Plain HTML)
ds-number5<div class="ds-number">
ds-radio1native <input type="radio">

Tier 2: Layout & Feedback (ausstehend)

#KomponenteDateienAbhängigkeiten
5OsModal7OsButton, OsCard
6OsDropdownOsButton
7OsAvatar-
8OsInput23gekoppelt mit ds-form (18 Dateien)

Tier 3: Navigation (ausstehend)

#KomponenteDateienAbhängigkeiten
9OsMenu11OsMenuItem
10OsMenuItem6-

Tier 4: Spezial-Komponenten (ausstehend)

#KomponenteDateien
11OsSelect3
12OsTable7
13ds-form → HTML <form> oder OsForm18

Hinweis: OsHeading, OsText, OsTag sind nicht mehr geplant — wurden zu Plain HTML migriert (Tier A).


Finaler Konsolidierungsplan

Hinweis: "Tier 1/A/B/2/3/4" bezeichnet die Migrations-Reihenfolge innerhalb von Phase 4.

Tier 1: Kern-Komponenten ✅

1. OsIcon    ✅ Vereint: DsIcon + BaseIcon → 82 Ocelot-Icons
+2. OsSpinner ✅ Vereint: DsSpinner + LoadingSpinner
+3. OsButton  ✅ Vereint: DsButton + BaseButton → 133 Buttons in 79 Dateien
+4. OsCard    ✅ Vereint: DsCard + BaseCard → ~30 Dateien
+5. OsBadge   ✅ Vereint: ds-chip (20 Nutzungen) + ds-tag (3 Dateien)

Tier A: Triviale ds-* Wrapper → Plain HTML ✅

ds-section, ds-placeholder, ds-list, ds-list-item  ✅ → HTML + CSS-Klassen
+ds-container, ds-heading, ds-text                   ✅ → HTML + CSS-Klassen
+ds-space                                             ✅ → div + Margin-Utilities
+ds-flex, ds-flex-item                                ✅ → HTML + CSS @media Queries

Tier B: Einfache ds-* Migration (60%)

ds-chip → OsBadge (UI-Library)               ✅
+ds-tag  → OsBadge shape="square" (UI-Library) ✅
+ds-grid / ds-grid-item → CSS Grid (HTML)     ✅
+ds-number → Plain HTML                       ⬜ (5 Dateien)
+ds-radio  → native <input type="radio">      ⬜ (1 Datei)

Tier 2-4: UI-Library (ausstehend)

5. OsModal    → Basis: DsModal, Feature-Modals bleiben in Webapp
+6. OsDropdown → Basis: Dropdown (Webapp) — wichtiger als gedacht!
+7. OsAvatar   → Vereint: DsAvatar + ProfileAvatar
+8. OsInput    → Basis: DsInput, gekoppelt mit ds-form
+9. OsMenu     → Basis: DsMenu/DsMenuItem
+10. OsSelect  → Basis: DsSelect
+11. OsTable   → Basis: DsTable

Erkenntnisse aus der Analyse

Was funktioniert gut:

  1. DsModal als Basis - Feature-Modals nutzen bereits DsModal → OsModal wird gleich funktionieren
  2. Dropdown-Pattern - Funktioniert gut mit v-popover
  3. Tier A Migration - 10 ds-* Wrapper durch HTML + CSS ersetzt, kein Funktionsverlust

Was gelöst wurde: ✅

  1. Button-Varianten → OsButton mit CVA-Varianten vereinheitlicht
  2. Inkonsistente Naming → os-* Prefix für Library, ds-* CSS-Klassen temporär beibehalten
  3. Doppelte Komponenten → BaseCard, BaseIcon, LoadingSpinner gelöscht (3/5 Duplikate aufgelöst)
  4. Layout-Shift bei ds-flex → CSS @media Queries statt JavaScript window.innerWidth

Noch offen:

  1. Logo - Existiert doppelt (Webapp + Styleguide)
  2. Modal - Existiert doppelt (Webapp Modal.vue ist Modal-Router, DsModal ist UI)
  3. ds-form Kopplung - ds-input und ds-form sind stark gekoppelt (Schema-Validation)

Token-Extraktion (aus Analyse)

Benötigte Design-Tokens für Phase 1

Farben:

// Primär/Sekundär/Danger
+$color-primary, $color-primary-dark, $color-primary-light
+$color-secondary, $color-secondary-dark, $color-secondary-light
+$color-danger, $color-danger-dark, $color-danger-light
+
+// Neutral
+$color-neutral-60, $color-neutral-80, $color-neutral-100
+
+// Semantisch
+$text-color-base, $text-color-inverse
+$background-color-softer, $background-color-soft
+$border-color-base

Größen:

$size-button-tiny: 24px
+$size-button-small: 32px
+$size-button-base: 40px
+$size-button-large: 48px

Spacing:

$space-xx-small: 4px
+$space-x-small: 8px
+$space-small: 16px
+$space-base: 24px

Border:

$border-size-base: 1px
+$border-radius-base: 4px
+$border-radius-x-large: 5px
+$border-radius-rounded: 2em

Animation:

$duration-short: 0.08s

Z-Index:

$z-index-modal: 9999
+$z-index-dropdown: 8888

Shadows:

$box-shadow-x-large: 0 15px 30px 0 rgba(0,0,0,.11), ...
+$box-shadow-small-inset: inset 0 0 0 1px rgba(0,0,0,.05)

Phase 3: Webapp-Integration (Tracking)

OsButton Migration - Abgeschlossen (133/133) ✅

#DateiButtonStatus
1UserTeaserPopover.vueOpen Profile✅ Migriert
2GroupForm.vueCancel✅ Migriert
3EmbedComponent.vueCancel✅ Migriert
4EmbedComponent.vuePlay Now✅ Migriert
5DonationInfo.vueDonate✅ Migriert
6CommentCard.vueShow More✅ Migriert
7MapStylesButtons.vueStyle Toggle✅ Migriert
8GroupMember.vueRemove✅ Migriert
9embeds.vueAllow All✅ Migriert
10embeds.vueDeny All✅ Migriert
11notifications.vueCheck All✅ Migriert
12notifications.vueUncheck All✅ Migriert
13notifications.vueSave✅ Migriert
14privacy.vueSave✅ Migriert
15terms-and-conditions-confirm.vueRead T&C✅ Migriert
16terms-and-conditions-confirm.vueSave✅ Migriert

OsButton Migration - Alle Milestones abgeschlossen ✅

MilestoneStatusDetails
M4a: Buttons ohne neue Props14 Buttons (Modals, Forms, Pages)
M4b: Props implementierenicon (Slot), circle, loading
M4c: Buttons mit icon/circle/loadingAlle verbleibenden Buttons migriert

OsButton Features - Alle implementiert ✅

FeatureStatus
variant (7 Varianten)
appearance (filled/outline/ghost)
size (xs/sm/md/lg/xl)
icon Slot
circle Prop
loading Prop
disabled mit hover/active-Override
fullWidth Prop
type Prop (button/submit/reset)

Status

OsButton Migration: ✅ Vollständig abgeschlossen.

`,295)]))}const h=e(n,[["render",a],["__file","KATALOG.html.vue"]]),p=JSON.parse('{"path":"/packages/ui/KATALOG.html","title":"Komponenten-Katalog","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Fortschritt","slug":"fortschritt","link":"#fortschritt","children":[{"level":3,"title":"Übersicht","slug":"ubersicht","link":"#ubersicht","children":[]},{"level":3,"title":"Statistiken","slug":"statistiken","link":"#statistiken","children":[]},{"level":3,"title":"OsButton Migration (Phase 3) ✅","slug":"osbutton-migration-phase-3-✅","link":"#osbutton-migration-phase-3-✅","children":[]}]},{"level":2,"title":"Styleguide Komponenten (38)","slug":"styleguide-komponenten-38","link":"#styleguide-komponenten-38","children":[{"level":3,"title":"Data Display","slug":"data-display","link":"#data-display","children":[]},{"level":3,"title":"Data Input","slug":"data-input","link":"#data-input","children":[]},{"level":3,"title":"Layout","slug":"layout","link":"#layout","children":[]},{"level":3,"title":"Navigation","slug":"navigation","link":"#navigation","children":[]},{"level":3,"title":"Typography","slug":"typography","link":"#typography","children":[]}]},{"level":2,"title":"Webapp Komponenten (139)","slug":"webapp-komponenten-139","link":"#webapp-komponenten-139","children":[{"level":3,"title":"Status-Legende","slug":"status-legende","link":"#status-legende","children":[]},{"level":3,"title":"A-B","slug":"a-b","link":"#a-b","children":[]},{"level":3,"title":"C","slug":"c","link":"#c","children":[]},{"level":3,"title":"D-E","slug":"d-e","link":"#d-e","children":[]},{"level":3,"title":"F-G","slug":"f-g","link":"#f-g","children":[]},{"level":3,"title":"H-L","slug":"h-l","link":"#h-l","children":[]},{"level":3,"title":"M-O","slug":"m-o","link":"#m-o","children":[]},{"level":3,"title":"P-R","slug":"p-r","link":"#p-r","children":[]},{"level":3,"title":"S","slug":"s","link":"#s","children":[]},{"level":3,"title":"T-Z","slug":"t-z","link":"#t-z","children":[]}]},{"level":2,"title":"Identifizierte Duplikate & Konsolidierung","slug":"identifizierte-duplikate-konsolidierung","link":"#identifizierte-duplikate-konsolidierung","children":[{"level":3,"title":"Direkte Duplikate (Webapp ↔ Styleguide)","slug":"direkte-duplikate-webapp-↔-styleguide","link":"#direkte-duplikate-webapp-↔-styleguide","children":[]},{"level":3,"title":"Button-Familie ✅ (alle nutzen OsButton)","slug":"button-familie-✅-alle-nutzen-osbutton","link":"#button-familie-✅-alle-nutzen-osbutton","children":[]},{"level":3,"title":"Modal-Familie (zur Konsolidierung)","slug":"modal-familie-zur-konsolidierung","link":"#modal-familie-zur-konsolidierung","children":[]},{"level":3,"title":"Menu-Familie (zur Konsolidierung)","slug":"menu-familie-zur-konsolidierung","link":"#menu-familie-zur-konsolidierung","children":[]}]},{"level":2,"title":"Kategorisierung","slug":"kategorisierung","link":"#kategorisierung","children":[{"level":3,"title":"Basis-Komponenten — UI-Library ✅","slug":"basis-komponenten-—-ui-library-✅","link":"#basis-komponenten-—-ui-library-✅","children":[]},{"level":3,"title":"Basis-Komponenten — UI-Library (ausstehend)","slug":"basis-komponenten-—-ui-library-ausstehend","link":"#basis-komponenten-—-ui-library-ausstehend","children":[]},{"level":3,"title":"Layout & Typography — → Plain HTML ✅ (Tier A)","slug":"layout-typography-—-→-plain-html-✅-tier-a","link":"#layout-typography-—-→-plain-html-✅-tier-a","children":[]},{"level":3,"title":"Noch zu migrieren (Tier B Rest)","slug":"noch-zu-migrieren-tier-b-rest","link":"#noch-zu-migrieren-tier-b-rest","children":[]},{"level":3,"title":"Feature-Komponenten (bleiben in Webapp)","slug":"feature-komponenten-bleiben-in-webapp","link":"#feature-komponenten-bleiben-in-webapp","children":[]}]},{"level":2,"title":"Analyse-Protokoll","slug":"analyse-protokoll","link":"#analyse-protokoll","children":[]},{"level":2,"title":"Nächste Schritte","slug":"nachste-schritte","link":"#nachste-schritte","children":[{"level":3,"title":"Phase 0: Analyse ✅","slug":"phase-0-analyse-✅","link":"#phase-0-analyse-✅","children":[]},{"level":3,"title":"Phase 3: OsButton Migration ✅","slug":"phase-3-osbutton-migration-✅","link":"#phase-3-osbutton-migration-✅","children":[]},{"level":3,"title":"Phase 4: Tier 1 — UI-Library Kern ✅","slug":"phase-4-tier-1-—-ui-library-kern-✅","link":"#phase-4-tier-1-—-ui-library-kern-✅","children":[]},{"level":3,"title":"Phase 4: Tier A — ds-* → Plain HTML ✅","slug":"phase-4-tier-a-—-ds-→-plain-html-✅","link":"#phase-4-tier-a-—-ds-→-plain-html-✅","children":[]},{"level":3,"title":"Phase 4: Tier B — ds-* Migration (60%)","slug":"phase-4-tier-b-—-ds-migration-60","link":"#phase-4-tier-b-—-ds-migration-60","children":[]},{"level":3,"title":"Phase 4: Tier 2-4 — UI-Library (ausstehend)","slug":"phase-4-tier-2-4-—-ui-library-ausstehend","link":"#phase-4-tier-2-4-—-ui-library-ausstehend","children":[]}]},{"level":2,"title":"Detailanalyse: Button-Familie","slug":"detailanalyse-button-familie","link":"#detailanalyse-button-familie","children":[{"level":3,"title":"Styleguide Button (DsButton)","slug":"styleguide-button-dsbutton","link":"#styleguide-button-dsbutton","children":[]},{"level":3,"title":"Webapp BaseButton","slug":"webapp-basebutton","link":"#webapp-basebutton","children":[]},{"level":3,"title":"Vergleich: Styleguide vs Webapp","slug":"vergleich-styleguide-vs-webapp","link":"#vergleich-styleguide-vs-webapp","children":[]},{"level":3,"title":"Wrapper-Komponenten (nutzen BaseButton)","slug":"wrapper-komponenten-nutzen-basebutton","link":"#wrapper-komponenten-nutzen-basebutton","children":[]},{"level":3,"title":"Feature-Buttons (Business-Logik) ✅","slug":"feature-buttons-business-logik-✅","link":"#feature-buttons-business-logik-✅","children":[]},{"level":3,"title":"Konsolidierungsvorschlag: OsButton ✅ IMPLEMENTIERT","slug":"konsolidierungsvorschlag-osbutton-✅-implementiert","link":"#konsolidierungsvorschlag-osbutton-✅-implementiert","children":[]},{"level":3,"title":"Verwendete Design-Tokens (tatsächlich genutzt)","slug":"verwendete-design-tokens-tatsachlich-genutzt","link":"#verwendete-design-tokens-tatsachlich-genutzt","children":[]},{"level":3,"title":"Offene Fragen ✅ (alle gelöst)","slug":"offene-fragen-✅-alle-gelost","link":"#offene-fragen-✅-alle-gelost","children":[]}]},{"level":2,"title":"Detailanalyse: Modal-Familie","slug":"detailanalyse-modal-familie","link":"#detailanalyse-modal-familie","children":[{"level":3,"title":"Architektur-Übersicht","slug":"architektur-ubersicht","link":"#architektur-ubersicht","children":[]},{"level":3,"title":"Styleguide DsModal","slug":"styleguide-dsmodal","link":"#styleguide-dsmodal","children":[]},{"level":3,"title":"Feature-Modals (nutzen DsModal)","slug":"feature-modals-nutzen-dsmodal","link":"#feature-modals-nutzen-dsmodal","children":[]},{"level":3,"title":"Webapp Modal.vue (Modal-Manager)","slug":"webapp-modal-vue-modal-manager","link":"#webapp-modal-vue-modal-manager","children":[]},{"level":3,"title":"Konsolidierungsvorschlag: OsModal","slug":"konsolidierungsvorschlag-osmodal","link":"#konsolidierungsvorschlag-osmodal","children":[]},{"level":3,"title":"Verwendete Design-Tokens (tatsächlich genutzt)","slug":"verwendete-design-tokens-tatsachlich-genutzt-1","link":"#verwendete-design-tokens-tatsachlich-genutzt-1","children":[]}]},{"level":2,"title":"Detailanalyse: Menu-Familie","slug":"detailanalyse-menu-familie","link":"#detailanalyse-menu-familie","children":[{"level":3,"title":"Architektur-Übersicht","slug":"architektur-ubersicht-1","link":"#architektur-ubersicht-1","children":[]},{"level":3,"title":"Styleguide DsMenu","slug":"styleguide-dsmenu","link":"#styleguide-dsmenu","children":[]},{"level":3,"title":"Styleguide DsMenuItem","slug":"styleguide-dsmenuitem","link":"#styleguide-dsmenuitem","children":[]},{"level":3,"title":"Webapp Dropdown","slug":"webapp-dropdown","link":"#webapp-dropdown","children":[]},{"level":3,"title":"Kategorisierung der Menu-Komponenten","slug":"kategorisierung-der-menu-komponenten","link":"#kategorisierung-der-menu-komponenten","children":[]},{"level":3,"title":"Konsolidierungsvorschlag","slug":"konsolidierungsvorschlag","link":"#konsolidierungsvorschlag","children":[]},{"level":3,"title":"Verwendete Design-Tokens (tatsächlich genutzt)","slug":"verwendete-design-tokens-tatsachlich-genutzt-2","link":"#verwendete-design-tokens-tatsachlich-genutzt-2","children":[]}]},{"level":2,"title":"Priorisierung der Komponenten","slug":"priorisierung-der-komponenten","link":"#priorisierung-der-komponenten","children":[{"level":3,"title":"Tier 1: Kern-Komponenten ✅","slug":"tier-1-kern-komponenten-✅","link":"#tier-1-kern-komponenten-✅","children":[]},{"level":3,"title":"Tier A: Triviale ds-* → Plain HTML ✅","slug":"tier-a-triviale-ds-→-plain-html-✅","link":"#tier-a-triviale-ds-→-plain-html-✅","children":[]},{"level":3,"title":"Tier B: Einfache ds-* Migration (60%)","slug":"tier-b-einfache-ds-migration-60","link":"#tier-b-einfache-ds-migration-60","children":[]},{"level":3,"title":"Tier 2: Layout & Feedback (ausstehend)","slug":"tier-2-layout-feedback-ausstehend","link":"#tier-2-layout-feedback-ausstehend","children":[]},{"level":3,"title":"Tier 3: Navigation (ausstehend)","slug":"tier-3-navigation-ausstehend","link":"#tier-3-navigation-ausstehend","children":[]},{"level":3,"title":"Tier 4: Spezial-Komponenten (ausstehend)","slug":"tier-4-spezial-komponenten-ausstehend","link":"#tier-4-spezial-komponenten-ausstehend","children":[]}]},{"level":2,"title":"Finaler Konsolidierungsplan","slug":"finaler-konsolidierungsplan","link":"#finaler-konsolidierungsplan","children":[{"level":3,"title":"Tier 1: Kern-Komponenten ✅","slug":"tier-1-kern-komponenten-✅-1","link":"#tier-1-kern-komponenten-✅-1","children":[]},{"level":3,"title":"Tier A: Triviale ds-* Wrapper → Plain HTML ✅","slug":"tier-a-triviale-ds-wrapper-→-plain-html-✅","link":"#tier-a-triviale-ds-wrapper-→-plain-html-✅","children":[]},{"level":3,"title":"Tier B: Einfache ds-* Migration (60%)","slug":"tier-b-einfache-ds-migration-60-1","link":"#tier-b-einfache-ds-migration-60-1","children":[]},{"level":3,"title":"Tier 2-4: UI-Library (ausstehend)","slug":"tier-2-4-ui-library-ausstehend","link":"#tier-2-4-ui-library-ausstehend","children":[]}]},{"level":2,"title":"Erkenntnisse aus der Analyse","slug":"erkenntnisse-aus-der-analyse","link":"#erkenntnisse-aus-der-analyse","children":[{"level":3,"title":"Was funktioniert gut:","slug":"was-funktioniert-gut","link":"#was-funktioniert-gut","children":[]},{"level":3,"title":"Was gelöst wurde: ✅","slug":"was-gelost-wurde-✅","link":"#was-gelost-wurde-✅","children":[]},{"level":3,"title":"Noch offen:","slug":"noch-offen","link":"#noch-offen","children":[]}]},{"level":2,"title":"Token-Extraktion (aus Analyse)","slug":"token-extraktion-aus-analyse","link":"#token-extraktion-aus-analyse","children":[{"level":3,"title":"Benötigte Design-Tokens für Phase 1","slug":"benotigte-design-tokens-fur-phase-1","link":"#benotigte-design-tokens-fur-phase-1","children":[]}]},{"level":2,"title":"Phase 3: Webapp-Integration (Tracking)","slug":"phase-3-webapp-integration-tracking","link":"#phase-3-webapp-integration-tracking","children":[{"level":3,"title":"OsButton Migration - Abgeschlossen (133/133) ✅","slug":"osbutton-migration-abgeschlossen-133-133-✅","link":"#osbutton-migration-abgeschlossen-133-133-✅","children":[]},{"level":3,"title":"OsButton Migration - Alle Milestones abgeschlossen ✅","slug":"osbutton-migration-alle-milestones-abgeschlossen-✅","link":"#osbutton-migration-alle-milestones-abgeschlossen-✅","children":[]},{"level":3,"title":"OsButton Features - Alle implementiert ✅","slug":"osbutton-features-alle-implementiert-✅","link":"#osbutton-features-alle-implementiert-✅","children":[]},{"level":3,"title":"Status","slug":"status","link":"#status","children":[]}]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":15.48,"words":4645},"filePathRelative":"packages/ui/KATALOG.md","localizedDate":"March 1, 2026","excerpt":"\\n
\\n

Tracking der Katalogisierung aller bestehenden Komponenten.\\nDiese Datei ermöglicht das Unterbrechen und Fortsetzen der Analyse.

\\n
\\n
\\n

Fortschritt

\\n

Übersicht

\\n
Phase 0: Analyse       ██████████ 100% (8/8 Schritte) ✅\\nPhase 3: OsButton      ██████████ 100% (133/133 Buttons) ✅\\nPhase 4: Tier 1        ██████████ 100% (OsButton, OsIcon, OsSpinner, OsCard) ✅\\nPhase 4: Tier A → HTML ██████████ 100% (10 ds-* Wrapper → Plain HTML) ✅\\nPhase 4: Tier B        ████████░░  80% (ds-chip→OsBadge✅, ds-tag→OsBadge✅, ds-grid✅, ds-number→OsNumber✅, ds-radio⬜)\\nPhase 4: Tier B+       ████████░░  75% (ds-table→HTML✅) | Tier 2-3 ausstehend (OsModal, OsInput, OsMenu, OsSelect)
\\n
"}');export{h as comp,p as data}; diff --git a/assets/LICENSE.html-BkNHjkmj.js b/assets/LICENSE.html-BkNHjkmj.js new file mode 100644 index 000000000..32da6c5ba --- /dev/null +++ b/assets/LICENSE.html-BkNHjkmj.js @@ -0,0 +1 @@ +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as i,b as e,d as n,o as r}from"./app-C6w_Pklu.js";const a={};function s(l,t){return r(),i("div",null,t[0]||(t[0]=[e("h1",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license"},[e("span",null,"LICENSE")])],-1),e("p",null,"MIT License",-1),e("p",null,[n("Copyright (c) 2018-2021 "),e("a",{href:"https://github.com/Ocelot-Social-Community",target:"_blank",rel:"noopener noreferrer"},"Ocelot.Social Community")],-1),e("p",null,'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:',-1),e("p",null,"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",-1),e("p",null,'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.',-1)]))}const d=o(a,[["render",s],["__file","LICENSE.html.vue"]]),E=JSON.parse('{"path":"/LICENSE.html","title":"LICENSE","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.58,"words":175},"filePathRelative":"LICENSE.md","localizedDate":"March 1, 2026","excerpt":"\\n

MIT License

\\n

Copyright (c) 2018-2021 Ocelot.Social Community

\\n

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \\"Software\\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

"}');export{d as comp,E as data}; diff --git a/assets/Layout.html-47srRE8z.js b/assets/Layout.html-47srRE8z.js new file mode 100644 index 000000000..d1b8e48ae --- /dev/null +++ b/assets/Layout.html-47srRE8z.js @@ -0,0 +1 @@ +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as o,b as a,o as r}from"./app-C6w_Pklu.js";const s={};function n(c,e){return r(),o("div",null,e[0]||(e[0]=[a("p",null,"Layout components are used to group related content together. The also provide consistent spacing for blocks of content.",-1)]))}const d=t(s,[["render",n],["__file","Layout.html.vue"]]),m=JSON.parse('{"path":"/styleguide/src/styleguide/docs/Layout.html","title":"","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.06,"words":18},"filePathRelative":"styleguide/src/styleguide/docs/Layout.md","localizedDate":"March 1, 2026","excerpt":"

Layout components are used to group related content together. The also provide consistent spacing for blocks of content.

\\n"}');export{d as comp,m as data}; diff --git a/assets/Navigation.html-CYz7rQzP.js b/assets/Navigation.html-CYz7rQzP.js new file mode 100644 index 000000000..d0db46207 --- /dev/null +++ b/assets/Navigation.html-CYz7rQzP.js @@ -0,0 +1 @@ +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as i,o}from"./app-C6w_Pklu.js";const n={};function r(l,e){return o(),a("div",null,e[0]||(e[0]=[i("p",null,"Navigation components allow the user to navigate through the application.",-1)]))}const d=t(n,[["render",r],["__file","Navigation.html.vue"]]),m=JSON.parse('{"path":"/styleguide/src/styleguide/docs/Navigation.html","title":"","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.03,"words":10},"filePathRelative":"styleguide/src/styleguide/docs/Navigation.md","localizedDate":"March 1, 2026","excerpt":"

Navigation components allow the user to navigate through the application.

\\n"}');export{d as comp,m as data}; diff --git a/assets/PROJEKT.html-BZRNQpP2.js b/assets/PROJEKT.html-BZRNQpP2.js new file mode 100644 index 000000000..b62aad0ea --- /dev/null +++ b/assets/PROJEKT.html-BZRNQpP2.js @@ -0,0 +1,918 @@ +import{_ as a}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as l,a as e,b as i,d as t,e as d,f as r,r as p,o}from"./app-C6w_Pklu.js";const h={};function k(c,s){const n=p("RouteLink");return o(),l("div",null,[s[2]||(s[2]=e(`

@ocelot-social/ui - Projektdokumentation

Dieses Dokument dient als zentrale Planungs- und Statusübersicht für das UI-Library Subprojekt. Es ermöglicht das Pausieren und Wiederaufnehmen der Arbeit zu jedem Zeitpunkt.


Inhaltsverzeichnis

Schnellzugriff (Status)

AbschnittBeschreibung
FortschrittVisuelle Fortschrittsanzeige
Aktueller StandWas zuletzt erledigt wurde
MeilensteinePhasen 0-5 mit Checklisten

Nach Thema

VISION

#Abschnitt
1Projektziel & Vision

TECHNISCHE GRUNDLAGEN

#Abschnitt
2Tech-Stack
3Build & Distribution
4Icon-Architektur
5Design-Token & Branding

PROZESSE & QUALITÄT

#Abschnitt
6CI/CD & Release
7Dokumentation & DX
8Migrationsstrategie
9Dokumentationsstrategie
10Kompatibilitätstests

REFERENZ & HISTORIE

#Abschnitt
11Entscheidungen
12Arbeitsprotokoll
13Komponenten-Katalog
14Ressourcen & Links
15Dokumentationsstrategie (Details)

ABGRENZUNGEN

#Abschnitt
16Library vs. Webapp
16aWebapp ↔ Maintenance Code-Sharing
16bDaten-Entkopplung (ViewModel/Mapper)
17Externe Abhängigkeiten
18Kompatibilitätstests (Details)
19Komplexitätsanalyse

Wie dieses Dokument verwendet wird

Zum Fortsetzen der Arbeit:

"Lass uns am @ocelot-social/ui Projekt weiterarbeiten" (packages/ui)

Nach jeder Session aktualisieren:


Fortschritt

Gesamtprojekt

Phase 0: ██████████ 100% (6/6 Aufgaben) ✅
+Phase 1: ██████████ 100% (6/6 Aufgaben) ✅
+Phase 2: ██████████ 100% (26/26 Aufgaben) ✅
+Phase 3: ██████████ 100% (24/24 Aufgaben) ✅ - Webapp-Integration komplett
+Phase 4: ██████░░░░  63% (17/27 Aufgaben) - Tier 1 ✅, Tier A ✅, Infra ✅, OsBadge ✅, ds-grid ✅, ds-table→HTML ✅, OsNumber ✅ | Tier B (rest), Tier 2-3 ausstehend
+Phase 5: ░░░░░░░░░░   0% (0/7 Aufgaben)
+───────────────────────────────────────
+Gesamt:  ████████░░  82% (79/96 Aufgaben)

Katalogisierung (Details in KATALOG.md)

Webapp:     ██████████ 100% (139 Komponenten erfasst)
+Styleguide: ██████████ 100% (38 Komponenten erfasst)
+Analyse:    ██████████ 100% (Button, Modal, Menu detailiert)

OsButton Migration (Phase 3) ✅

Scope gesamt:     133 <os-button> Tags in 79 Webapp-Dateien
+├─ Migriert:       133 Buttons (100%) ✅
+├─ <base-button>:    0 verbleibend in Templates
+├─ <ds-button>:      0 verbleibend in Templates
+└─ Cleanup:        Snapshots/Tests müssen aktualisiert werden
+
+OsButton Features:
+├─ variant:     ✅ primary, secondary, danger, warning, success, info, default
+├─ appearance:  ✅ filled, outline, ghost
+├─ size:        ✅ sm, md, lg, xl
+├─ disabled:    ✅ mit hover/active-Override (nur as="button")
+├─ icon:        ✅ slot-basiert (icon-system-agnostisch)
+├─ circle:      ✅ rounded-full, größenabhängig (p-1.5 bis p-3)
+├─ loading:     ✅ animated SVG spinner, aria-busy (Milestone 4b)
+└─ as:          ✅ polymorphes Rendering (button/a/NuxtLink/RouterLink)
+
+as-Prop Migration:  15 <nuxt-link>/<a>-Wrapper in 15 Webapp-Dateien → as="nuxt-link"/as="a"

OsIcon (Phase 4)

OsIcon Features:
+├─ name:       ✅ System-Icon per Name (check, close, plus)
+├─ icon:       ✅ Custom Vue-Komponente (hat Vorrang vor name)
+├─ size:       ✅ xs, sm, md, lg, xl, 2xl (em-basiert)
+├─ a11y:       ✅ decorative (default) / semantic (mit aria-label)
+├─ color:      ✅ fill-current (erbt von Parent)
+└─ svg-plugin: ✅ vite-svg-icon (SVG → Vue Component via ?icon)
+
+System-Icons:
+├─ check.svg   (Checkmark)
+├─ close.svg   (Close/X)
+└─ plus.svg    (Plus/Add)
+
+Ocelot-Icons (separates Entry-Point):
+└─ 82 Icons (Feature-Icons + Kategorie-Icons aus Webapp migriert)
+
+OsSpinner:
+├─ size:       ✅ xs, sm, md, lg, xl, 2xl (em-basiert)
+├─ color:      ✅ currentColor (erbt von Parent)
+├─ a11y:       ✅ role="status", aria-label="Loading" (customizable)
+├─ decorative: ✅ aria-hidden="true" suppresses role/aria-label
+├─ os-button:  ✅ OsButton nutzt OsSpinner als Komponente (decorative)
+├─ vue-compat: ✅ h() Render-Function mit isVue2
+└─ webapp:     ✅ 4 Spinner migriert (DsSpinner + LoadingSpinner → OsSpinner)
+
+BaseCard → OsCard Webapp-Migration: ✅
+├─ ~30 Webapp-Dateien: <base-card> → <os-card> (lokale Imports)
+├─ 3 Template-Dateien: #imageColumn/#topMenu Slots → inline Layout mit --columns CSS
+├─ 16 Spec-Dateien: wrapper.classes('base-card') → wrapper.classes('os-card')
+├─ 4 Story-Dateien: <base-card> → <os-card> mit Import
+├─ 12 Cypress E2E-Dateien: .base-card → .os-card Selektoren
+├─ 2 Cypress-Dateien: .hero-image → .os-card__hero-image
+├─ BaseCard.vue Komponente gelöscht
+├─ base-components.js Plugin gelöscht (keine Base*.vue mehr)
+├─ nuxt.config.js, maintenance config, testSetup.js bereinigt
+├─ main.scss: .os-card Regeln (title, ds-section, hero-image, --columns Layout)
+├─ CSS Fixes: Tailwind p-6 Override (!important), outline statt border (highlight),
+│  child selectors → descendant selectors (hero-image content wrapper)
+├─ ContributionForm: Media-Query Selektoren auf .os-card__content korrigiert
+├─ ProfileList: .profile-list.os-card Spezifität erhöht (0,3,0 vs 0,2,0)
+└─ 0 <base-card> Template-Nutzungen verbleibend
+
+DsSpinner/LoadingSpinner → OsSpinner Webapp-Migration: ✅
+├─ ImageUploader.vue: LoadingSpinner → OsSpinner (size="lg")
+├─ pages/profile: ds-spinner → os-spinner (size="lg")
+├─ pages/groups: ds-spinner → os-spinner (size="lg")
+├─ pages/admin: ds-spinner → os-spinner (size="xl") + ApolloQuery→apollo Option
+├─ LoadingSpinner Komponente gelöscht
+├─ ds-space centered → div+padding (Bugfix in 3 Seiten)
+├─ Admin: ApolloQuery→$apollo.loading (Spinner war wg. SSR-Prefetch unsichtbar)
+└─ infinite-loading: OsSpinner im spinner-Slot (index, profile, groups)
+
+BaseIcon → OsIcon Webapp-Migration: ✅
+├─ 131 <base-icon> in 70+ Dateien → <os-icon :icon="...">
+├─ 82 SVGs in ocelot/icons/svgs/ (inkl. 17 Kategorie-Icons)
+├─ vite-svg-icon Plugin erweitert (rect, circle, polygon, polyline, ellipse, line)
+├─ Kategorie-Icons: DB-String → toCamelCase() → ocelotIcons Lookup
+├─ Jest Mocks: @ocelot-social/ui/ocelot für ocelotIcons in Tests
+├─ Tests aktualisiert: 911/939 Tests bestanden (3 pre-existing failures)
+└─ 0 base-icon/BaseIcon Referenzen verbleibend
+
+Tier A ds-* → Plain HTML + CSS: ✅
+├─ 10 triviale Vue-Wrapper-Komponenten durch HTML-Elemente + CSS-Klassen ersetzt
+├─ ~450 Nutzungen in ~90 Dateien migriert
+├─ _ds-compat.scss: Utility-Klassen für Margins (.ds-mb-*, .ds-mt-*, .ds-my-*),
+│  Flex (.ds-flex, .ds-flex-item, .ds-flex-gap-*), Centered (.ds-space-centered)
+├─ ds-flex/ds-flex-item: JavaScript window.innerWidth → CSS @media Queries
+│  (kein Layout-Shift bei SSR, bessere Performance)
+├─ system.css bleibt geladen — bestehende CSS-Klassen funktionieren weiter
+├─ Verbleibend: 8 ds-* Komponenten (Tier B Rest: 1 einfache, Tier C: 6 komplexe → UI-Library)
+└─ 0 Tier-A ds-* Komponenten-Tags verbleibend
+
+ds-number → OsNumber (UI-Library): ✅
+├─ OsNumber Komponente: h() Render-Function, requestAnimationFrame Animation, inheritAttrs: false
+├─ Props: count (required), label (optional), animated (optional)
+├─ Animation: 1500ms ease-out, watch(count) re-animiert, SSR-safe (onMounted)
+├─ Styling: tabular-nums + min-width für stabile Breite, --color-text-soft Label-Farbe
+├─ ds-number + CountTo: 5 Dateien → <os-number> (UserTeaserPopover, TabNavigation, admin, profile, groups)
+├─ vue-count-to Dependency entfernt, CountTo.vue gelöscht
+├─ CSS-Variable: --color-text-soft in requiredCssVariables + ocelot-ui-variables.scss
+├─ 11 Unit-Tests, 5 Stories, 5 Visual Tests + 1 Keyboard Test
+└─ 0 ds-number/CountTo Nutzungen verbleibend
+
+ds-chip + ds-tag → OsBadge (UI-Library): ✅
+├─ OsBadge Komponente: CVA-Varianten, h() Render-Function, inheritAttrs: false
+├─ Props: variant (default/primary/danger), size (sm/md/lg), shape (pill/square)
+├─ Types: BadgeVariant, BadgeSize, BadgeShape (+ BadgeVariants)
+├─ ds-chip: 20 Nutzungen in 5 Dateien → <os-badge> (Formzähler + Gruppen-Metadaten)
+├─ ds-tag: 3 Nutzungen in 3 Dateien → <os-badge shape="square"> (Category, Hashtag)
+├─ ARIA: role="status" aria-live="polite" auf Form-Zähler (11 Stellen in 2 Dateien)
+├─ CSS-Variable: --color-default + --color-default-contrast (beide in requiredCssVariables)
+├─ 18 Unit-Tests, 6 Stories, 5 Visual Tests + 1 Keyboard Test
+└─ 0 ds-chip/ds-tag Nutzungen verbleibend

Aktueller Stand

Letzte Aktualisierung: 2026-02-20 (Session 32)

Aktuelle Phase: Phase 4 - Tier 1 ✅, Tier A ✅, OsBadge ✅, ds-grid ✅, ds-table→HTML ✅, OsNumber ✅ | Tier B (rest), Tier 2-3 ausstehend

Zuletzt abgeschlossen (Session 32 - OsNumber: ds-number + CountTo → OsNumber):

Zuvor abgeschlossen (Session 31 - ds-table → Plain HTML):

Zuvor abgeschlossen (Session 30 - OsBadge Code-Review Fixes):

Zuvor abgeschlossen (Session 29 - OsBadge: ds-chip + ds-tag Migration):

Zuvor abgeschlossen (Session 27 - Tier A: ds- Komponenten → Plain HTML):*

Verbleibende ds- Komponenten (7 Typen):*

Zuvor abgeschlossen (Session 26 - CodeRabbit Review Fixes):

Zuvor abgeschlossen (Session 25 - BaseCard → OsCard Webapp-Migration):

Zuvor abgeschlossen (Session 24 - OsSpinner Webapp-Migration + Refactoring):

Zuvor abgeschlossen (Session 23 - OsSpinner Komponente):

Zuvor abgeschlossen (Session 22 - BaseIcon → OsIcon Webapp-Migration):

Zuvor abgeschlossen (Session 21 - OsIcon Komponente, System-Icons, Ocelot-Umbenennung):

Zuvor abgeschlossen (Session 20 - as-Prop + nuxt-link Migration):

Zuvor erledigt (auf master gemergt):

Abgeschlossene Phasen:

Zuvor abgeschlossen (Sessions 11-19 — Details im Arbeitsprotokoll §12):

Nächste Schritte:

Manuelle Setup-Aufgaben (außerhalb Code):


Meilensteine

Phase 0: Analyse & Katalogisierung ✅

Phase 1: Vue 2.7 Upgrade ✅

Phase 2: Projekt-Setup ✅

Phase 3: Webapp-Integration (Validierung)

Ziel: OsButton in der Webapp einbinden, ohne visuelle oder funktionale Änderungen.

Ansatz: Integration First - Library einbinden, dann schrittweise OsButton ersetzen, beginnend mit einfachsten Stellen.

Milestone 1: Library-Einbindung

Milestone 2: Erste Integration (Minimaler Aufwand)

Milestone 3: Schrittweise Erweiterung

Milestone 4a: Weitere Buttons migrieren (14 ohne neue Props)

Milestone 4b: OsButton Props erweitern

Milestone 4c: Buttons mit icon/circle/loading migrieren ✅ ABGESCHLOSSEN

Button-Komponenten (Wrapper):

Navigation & Menus:

Editor:

Filter & Input:

Chat:

Forms & Auth:

Modals:

Features:

Filter-Menüs:

Pages:

Milestone 5: Validierung & Dokumentation

Einsatzstellen-Übersicht:

KategorieButtonsStatus
✅ Migriert (gesamt)13379 Dateien
<base-button> verbleibend0Nur BaseButton.vue Definition + Test-Dateien
<ds-button> verbleibend0Alle ersetzt
Gesamt133100% erledigt

Details siehe KATALOG.md (vollständige Tracking-Tabellen)

Erfolgskriterien:

KriteriumPrüfung
Visuell identischManueller Screenshot-Vergleich
Funktional identischClick, Disabled funktionieren
Keine RegressionWebapp Unit-Tests bestehen

Visuelle Validierung (OsButton vs Original):

Jeder migrierte Button muss manuell geprüft werden: Normal, Hover, Focus, Active, Disabled.

DateiButtonPropsValidiert
components/Group/GroupForm.vueCanceldefault
components/Group/GroupMember.vueRemove Memberappearance="outline" variant="primary" size="sm"
components/CommentCard/CommentCard.vueShow more/lessappearance="ghost" variant="primary" size="sm"
components/UserTeaser/UserTeaserPopover.vueOpen Profilevariant="primary"
components/DonationInfo/DonationInfo.vueDonate Nowsize="sm" variant="primary"
components/Map/MapStylesButtons.vueMap Styles:appearance dynamisch + custom CSS
components/Embed/EmbedComponent.vueCancelappearance="outline" variant="danger" + custom CSS
components/Embed/EmbedComponent.vuePlay Nowvariant="primary" + custom CSS
pages/terms-and-conditions-confirm.vueRead T&Cappearance="outline" variant="primary"
pages/terms-and-conditions-confirm.vueSavevariant="primary" + disabled
pages/settings/privacy.vueSavevariant="primary" + disabled
pages/settings/notifications.vueCheck Allappearance="outline" variant="primary" + disabled
pages/settings/notifications.vueUncheck Allappearance="outline" variant="primary" + disabled
pages/settings/notifications.vueSavevariant="primary" + disabled
pages/settings/embeds.vueAllow Allappearance="outline" variant="primary" + disabled
pages/settings/embeds.vueDeny Allvariant="primary" + disabled

Validierung abgeschlossen: 16/16 (100%) ✅

Nach Abschluss aller Validierungen:

Phase 4: Komponenten-Migration

Tier 1: Kern-Komponenten (UI-Library)

Tier A: Triviale ds- Wrapper → Plain HTML + CSS* ✅

Tier B: Einfache ds- → Plain HTML / UI-Library*

Tier 2: Layout & Feedback (UI-Library)

Tier 3: Navigation (UI-Library)

Tier 4: Spezial-Komponenten

Infrastruktur

Hinweis: ds-heading, ds-text, ds-tag wurden zu Plain HTML migriert (Tier A). OsHeading/OsText/OsTag als UI-Library-Komponenten sind daher nicht mehr geplant.

Phase 5: Finalisierung


VISION

1. Projektziel & Vision

Kurzbeschreibung: Neue Vue 3 Komponentenbibliothek aufbauen, die später die Vue 2 Komponenten in der Webapp ersetzen soll.

Hintergrund:

Vision: Ein stark definiertes und flexibles Design-System, das den Branding-Anforderungen von ocelot.social gerecht wird und eine saubere, schrittweise Migration von Vue 2 nach Vue 3 ermöglicht.

Geplanter Ansatz: Migration vorbereiten - schrittweise neue Komponenten in Vue 3 entwickeln, die das bestehende Design-System respektieren und flexible Branding-Optionen bieten.


TECHNISCHE GRUNDLAGEN

2. Tech-Stack

KomponenteEntscheidungNotizen
FrameworkVue 3 + ViteSchnellstes Setup, modernes Tooling
Build-ToolViteSchnelles HMR, einfache Konfiguration
DokumentationStorybook 10Komponenten-Dokumentation mit Vue 3 + Vite
StylingTailwind CSSMit CSS Custom Properties für Branding
TestingVitestVite-nativ, Jest-kompatible API
Paket-Name@ocelot-social/uiUnter ocelot-social npm Org
Komponenten-PrefixOsOsButton, OsCard, etc.
Vue 2 Kompatibilitätvue-demiLibrary funktioniert in Vue 2 und Vue 3
Varianten-SystemCVAclass-variance-authority für typsichere Prop-Varianten
Klassen-Mergecn()clsx + tailwind-merge für Klassen-Kombination
Lintingeslint-config-it4cEnthält: TypeScript, Vue, Prettier, weitere Regeln
Releaserelease-pleaseAutomatische Versionen und Changelogs
IconsHybrid-ArchitekturSystem-Icons in Library, Feature-Icons in App (siehe §4)
Browser-SupportModern onlyChrome, Firefox, Safari, Edge (letzte 2 Versionen)
SSRJaNuxt-kompatibel
Dark ModeJa, von Anfang anAlle Komponenten mit Light/Dark Varianten
LizenzApache 2.0Permissiv mit Patent-Schutz
RepositoryMonorepoOcelot-Social/packages/ui/

Konventionen

AspektEntscheidungNotizen
Vue API<script setup>Composition API mit script setup (erfordert Vue 2.7+)
SpracheEnglischCode, Comments, Dokumentation
Package ManagernpmBereits im Projekt verwendet
Test Coverage100%Vollständige Testabdeckung
DateinamenPascalCaseOsButton.vue, OsCard.vue
i18nNur PropsKeine Default-Texte in Komponenten
BreakpointsTailwind Standardsm:640, md:768, lg:1024, xl:1280, 2xl:1536
Size PropsTailwind-Skalasm, md, lg, xl (komponentenspezifisch)
Rounded PropsTailwind-Skala (vollständig)none, sm, md, lg, xl, 2xl, 3xl, full
Shadow PropsTailwind-Skala (vollständig)none, sm, md, lg, xl, 2xl
Variant PropsSemantisch (vollständig)primary, secondary, danger, warning, success, info
Dark ModeTailwind CSS-KlassenVia dark: Prefix, kein "inverse" Prop
Prop-VollständigkeitAlle oder keineWenn Komponente einen Prop unterstützt, dann die gesamte Skala
CSS VariablesKeine Defaults in LibraryWebapp definiert Default-Branding, spezialisierte Brandings überschreiben
TypeScriptstrict: trueStrikte Typisierung

3. Build & Distribution

Dual-Build Strategie

Die Library bietet zwei Nutzungsmöglichkeiten:

@ocelot-social/ui
+├── dist/
+│   ├── index.js              # Vue Komponenten
+│   ├── style.css             # Vorkompilierte Styles (für Nicht-Tailwind)
+│   └── tailwind.preset.js    # Tailwind Preset (für Tailwind-Nutzer)

Nutzung MIT Tailwind

// tailwind.config.js
+import ocelotPreset from '@ocelot-social/ui/tailwind.preset'
+export default { presets: [ocelotPreset] }
+
+// main.js
+import { OsButton } from '@ocelot-social/ui'

Nutzung OHNE Tailwind

// main.js
+import { OsButton } from '@ocelot-social/ui'
+import '@ocelot-social/ui/style.css'

Branding (funktioniert für beide)

/* branding.css */
+:root {
+  --color-primary: rgb(110, 139, 135);
+  --button-primary-bg: var(--color-secondary);
+}

Beide Varianten nutzen CSS Custom Properties - Branding ist identisch.

Webapp-Integration (Entwicklung)

Lokale Entwicklung mit Nuxt Alias:

// webapp/nuxt.config.js
+export default {
+  alias: {
+    '@ocelot-social/ui': process.env.LOCAL_UI
+      ? path.resolve(__dirname, '../packages/ui/src')
+      : '@ocelot-social/ui'
+  }
+}

Entwickler startet mit:

LOCAL_UI=true yarn dev

Release-Check: Bei Ocelot-Release wird geprüft, ob packages/ui unreleased Änderungen hat:

# Commits seit letztem ui-Tag?
+git log --oneline $(git describe --tags --match "ui-v*" --abbrev=0)..HEAD -- packages/ui/

→ Wenn Output vorhanden: UI muss zuerst released werden.

Webapp-Aufgaben (TODO für Ocelot-Webapp)

Die folgenden Aufgaben müssen in der Webapp umgesetzt werden, nicht in der UI-Library:

AufgabeBeschreibungStatus
Branding-ValidierungTest/Workflow der validateCssVariables() aufruft und sicherstellt, dass das Default-Branding alle von der Library geforderten CSS-Variablen definiert⏳ Offen

Beispiel-Implementierung (Webapp):

// webapp/tests/branding.spec.ts
+import { validateCssVariables, requiredCssVariables } from '@ocelot-social/ui/tailwind.preset'
+
+describe('Default Branding', () => {
+  it('defines all required CSS variables', () => {
+    // Load default branding CSS
+    // ...
+
+    const styles = getComputedStyle(document.documentElement)
+    const missing: string[] = []
+
+    for (const variable of requiredCssVariables) {
+      const value = styles.getPropertyValue(variable).trim()
+      if (!value) {
+        missing.push(variable)
+      }
+    }
+
+    expect(missing).toEqual([])
+  })
+})

4. Icon-Architektur

Entscheidung: Hybrid-Ansatz

Die Library verwendet eine Hybrid-Architektur für Icons:

┌─────────────────────────────────────────────────────────────┐
+│  @ocelot-social/ui (Library)                                │
+├─────────────────────────────────────────────────────────────┤
+│  src/components/OsIcon/icons/svgs/  # System-Icons          │
+│  ├── check.svg           # Bestätigung, Checkboxen          │
+│  ├── close.svg           # Modal, Chip, Dialoge             │
+│  └── plus.svg            # Hinzufügen, Erstellen            │
+│                                                             │
+│  src/ocelot/icons/svgs/             # Ocelot-Icons          │
+│  └── angle-down.svg      # Dropdown-Pfeil                   │
+│                                                             │
+│  (Weitere System-Icons werden bei Bedarf ergänzt)           │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│  Webapp / Konsumierendes Projekt                            │
+├─────────────────────────────────────────────────────────────┤
+│  assets/icons/           # Feature-Icons (beliebig viele)   │
+│  ├── user.svg            │
+│  ├── bell.svg            │
+│  ├── heart.svg           │
+│  ├── settings.svg        │
+│  └── ...                 │
+└─────────────────────────────────────────────────────────────┘

Begründung

  1. Library muss standalone funktionieren - Ein OsModal braucht einen Close-Button ohne zusätzliche Konfiguration
  2. 616 Icons sind zu viel - Der Styleguide hat 616 Icons, die meisten werden nie gebraucht
  3. Feature-Icons gehören zur App - Icons wie user, bell, heart sind Business-Logik
  4. Branding-Flexibilität - Verschiedene Ocelot-Instanzen können unterschiedliche Icon-Sets verwenden

System-Icons (in Library enthalten) ✅

IconVerwendungStatus
checkBestätigung, Checkboxen✅ implementiert
closeModal, Chip, Dialoge✅ implementiert
plusHinzufügen, Erstellen✅ implementiert

Geplant (bei Bedarf ergänzen):

IconVerwendung in Komponenten
chevron-downOsSelect, OsDropdown, OsAccordion
chevron-upOsSelect, OsAccordion
barsOsPage (mobile menu)
searchOsInput (search variant)

API-Design (implementiert)

// OsIcon — System-Icon per Name
+<OsIcon name="close" />
+<OsIcon name="check" size="lg" />
+
+// OsIcon — Custom Vue-Komponente (hat Vorrang vor name)
+<OsIcon :icon="UserIcon" />
+
+// OsIcon — Semantic (mit aria-label)
+<OsIcon name="close" aria-label="Schließen" />
+
+// OsButton — Icon über #icon Slot (icon-system-agnostisch)
+<OsButton variant="primary">
+  <template #icon><OsIcon name="check" /></template>
+  Speichern
+</OsButton>

SVG-Loading (vite-svg-icon Plugin)

// SVGs werden via ?icon Query als Vue-Komponenten geladen
+import CheckIcon from './check.svg?icon'
+
+// Plugin extrahiert viewBox + <path> und transformiert zu:
+// h('svg', { viewBox, ... }, [h('path', { d })])

Ocelot-Icons (separates Entry-Point)

// Dynamisches Loading via import.meta.glob
+import { ocelotIcons } from '@ocelot-social/ui/ocelot'
+
+// Filename → PascalCase: angle-down.svg → IconAngleDown
+// Returns Record<string, () => VNode>

Aktuelle Icon-Statistik

QuelleAnzahlStatus
Styleguide (_all)616Nicht übernehmen (FontAwesome 4 komplett)
Webapp (svgs)238Feature-Icons, bleiben in Webapp
Library (system)3✅ check, close, plus
Ocelot-Icons82✅ Feature-Icons + Kategorie-Icons (separates Entry-Point)

5. Design-Token & Branding

3-Stufen Token-System

┌─────────────────────────────────────────────────────────┐
+│  1. BASE TOKENS (Rohwerte)                              │
+│     --color-green: rgb(23, 181, 63);                    │
+│     --color-teal: rgb(110, 139, 135);                   │
+│     --space-small: 16px;                                │
+└────────────────────────┬────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────┐
+│  2. SEMANTIC TOKENS (Bedeutung)                         │
+│     --color-primary: var(--color-green);                │
+│     --color-secondary: var(--color-teal);               │
+│     --text-color-base: var(--color-neutral-20);         │
+└────────────────────────┬────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────┐
+│  3. COMPONENT TOKENS (Komponenten-spezifisch)           │
+│     --button-primary-bg: var(--color-primary);          │
+│     --button-primary-text: var(--color-primary-inverse);│
+│     --card-bg: var(--background-color-base);            │
+└─────────────────────────────────────────────────────────┘

Branding-Flexibilität

Jedes Branding kann auf jeder Ebene eingreifen:

/* Standard */
+:root {
+  --button-primary-bg: var(--color-primary);
+}
+
+/* Yunite-Branding: Button nutzt Secondary statt Primary */
+:root {
+  --button-primary-bg: var(--color-secondary);
+}

Kompatibilität mit bestehendem System

CVA + Tailwind + CSS-Variablen

Wie CVA funktioniert:

CVA (Class Variance Authority) mappt Props typsicher auf Tailwind-Klassen:

// button.variants.ts
+export const buttonVariants = cva(
+  'inline-flex items-center font-medium',  // Basis-Klassen
+  {
+    variants: {
+      variant: {
+        primary: 'bg-[var(--color-primary)] text-[var(--color-primary-contrast)]',
+        danger: 'bg-[var(--color-danger)] text-[var(--color-danger-contrast)]',
+      },
+      size: {
+        sm: 'h-8 px-3 text-sm',
+        md: 'h-10 px-4 text-base',
+      },
+    },
+    defaultVariants: { variant: 'primary', size: 'md' },
+  }
+)
+
+// Aufruf:
+buttonVariants({ variant: 'primary', size: 'sm' })
+// → 'inline-flex items-center font-medium bg-[var(--color-primary)] ... h-8 px-3 text-sm'

Was ist via Branding überschreibbar?

EbeneÜberschreibbarBeispiel
Farben✅ Ja (CSS-Variablen)--color-primary, --color-danger
Hover-Farben✅ Ja (CSS-Variablen)--color-primary-hover
Kontrast✅ Ja (CSS-Variablen)--color-primary-contrast
Größen❌ Nein (Tailwind-Skala)h-10, px-4, text-base
Abstände❌ Nein (Tailwind-Skala)rounded-md, gap-2
Einzelne Instanz✅ Ja (class-Prop)<OsButton class="h-12" />

Branding-Beispiel:

/* branding/default.css */
+:root {
+  --color-primary: rgb(23, 181, 63);
+  --color-primary-contrast: rgb(255, 255, 255);
+  --color-primary-hover: rgb(18, 140, 49);
+}
+
+/* branding/yunite.css (überschreibt) */
+:root {
+  --color-primary: rgb(110, 139, 135);
+  --color-primary-contrast: rgb(255, 255, 255);
+  --color-primary-hover: rgb(90, 115, 112);
+}

Die Rolle von cn() (clsx + tailwind-merge):

import { clsx } from 'clsx'
+import { twMerge } from 'tailwind-merge'
+
+export function cn(...inputs) {
+  return twMerge(clsx(inputs))
+}
+
+// Beispiel: Custom class überschreibt CVA-Werte
+cn('h-10 px-4', 'h-12 px-8')  // → 'h-12 px-8' (letzte gewinnt)

Architektur-Übersicht:

┌─────────────────────────────────────────────────────────────┐
+│  CSS-Variablen (Branding-überschreibbar)                    │
+│  --color-primary, --color-danger, --color-*-hover, etc.     │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│  CVA-Varianten (nutzen CSS-Variablen)                       │
+│  bg-[var(--color-primary)], text-[var(--color-contrast)]    │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│  Tailwind-Klassen (feste Skala, konsistent)                 │
+│  h-8, h-10, h-12, px-3, px-4, rounded-md, text-sm           │
+└─────────────────────────────────────────────────────────────┘
+
+┌─────────────────────────────────────────────────────────────┐
+│  cn() + class-Prop (Escape-Hatch für Einzelfälle)           │
+│  <OsButton class="h-20 rounded-full" />                     │
+└─────────────────────────────────────────────────────────────┘

Designentscheidung:


PROZESSE & QUALITÄT

6. CI/CD & Release

Release-Workflow (release-please)

Manifest-Modus für Monorepo:

┌─────────────────────────────────────────────────────────────────┐
+│                    RELEASE WORKFLOW                             │
+├─────────────────────────────────────────────────────────────────┤
+│  1. Commit mit Conventional Commits Format                      │
+│  2. release-please erstellt Release-PR                          │
+│  3. PR merge → Version bump + Changelog                         │
+│  4. Automatisch: npm publish + Storybook deploy                  │
+└─────────────────────────────────────────────────────────────────┘

Konfigurationsdateien:

GitHub Workflows

WorkflowTriggerBeschreibung
LintPush/PReslint-config-it4c (TypeScript + Vue + Prettier)
TestPush/PRVitest Unit-Tests
BuildPush/PRVite Build verifizieren
ReleasePush to mainrelease-please PR erstellen
PublishRelease creatednpm publish + Storybook deploy

Qualitätssicherung bei PRs

PR erstellt
+
+┌─────────────┐
+│   Lint      │──→ eslint-config-it4c (TS + Vue + Prettier)
+├─────────────┤
+│   Tests     │──→ Vitest
+├─────────────┤
+│   Build     │──→ Vite
+└─────────────┘
+
+Alle grün → Merge erlaubt

Automatische Deployments

EventAktion
Release erstelltnpm publish
Release erstelltStorybook build + deploy auf Server

Storybook Deploy (Webhook):

  1. GitHub sendet Webhook bei Release-Event
  2. Server empfängt Webhook
  3. Server führt scripts/deploy-storybook.sh aus (Teil des Repos)
  4. Script: git pull → npm ci → storybook build → copy to webroot

GitHub Workflows (vollständige Liste)

WorkflowTriggerToolBeschreibung
lintPush/PReslint-config-it4cCode-Stil prüfen
typecheckPush/PRTypeScriptTyp-Fehler finden
testPush/PRVitestUnit-Tests
test-a11yPush/PRaxe-coreAccessibility-Tests
test-visualPush/PRPlaywrightVisual Regression Screenshots
buildPush/PRViteBuild verifizieren
build-storybookPush/PRStorybookDokumentation bauen
size-checkPush/PRsize-limitBundle-Größe prüfen
releasePush mainrelease-pleaseRelease-PR erstellen
publishReleasenpmAuf npm veröffentlichen
deploy-docsReleaseWebhookStorybook auf Server deployen
check-ui-releaseOcelot ReleaseGitPrüft unreleased UI-Änderungen

Erweiterte Qualitätssicherung

MaßnahmeToolBeschreibung
Visual RegressionPlaywrightScreenshot-Vergleiche bei Änderungen
Accessibility@axe-core/playwrightA11y-Prüfung integriert in Visual Tests
Bundle Sizesize-limitWarnung wenn Library-Größe Schwellwert überschreitet

Migrations-Absicherung

Feature Parity Checklist (pro Komponente):

┌─────────────────────────────────────────────────────────┐
+│  KOMPONENTE: [Name]                                     │
+├─────────────────────────────────────────────────────────┤
+│  [ ] Alle Props der alten Komponente übernommen         │
+│  [ ] Alle Events identisch                              │
+│  [ ] Alle Slots vorhanden                               │
+│  [ ] Default-Werte identisch                            │
+│  [ ] Visuell identisch (Screenshot-Vergleich)           │
+│  [ ] A11y mindestens gleich gut                         │
+│  [ ] Dokumentation vollständig                          │
+└─────────────────────────────────────────────────────────┘

Deprecation Warnings: Nach erfolgreicher Migration einer Komponente werden in der Vue 2 Webapp Warnungen eingebaut:

// In alter Komponente
+if (process.env.NODE_ENV === 'development') {
+  console.warn('[DEPRECATED] Button: Bitte @ocelot-social/ui verwenden')
+}

7. Dokumentation & DX

Storybook als Komponenten-Dokumentation

Die Komponenten werden über Storybook dokumentiert und auf einer öffentlichen Webseite für Entwickler zugänglich gemacht.

Features für Entwickler:

Hosting:

Workflow:

Komponente entwickeln → Storybook Story schreiben → Build → Deploy auf Server

8. Migrationsstrategie

Grundprinzipien

┌─────────────────────────────────────────────────────────────────┐
+│                    MIGRATIONSSTRATEGIE                          │
+├─────────────────────────────────────────────────────────────────┤
+│  1. Library vollständig in Vue 3 schreiben                      │
+│  2. vue-demi für Vue 2 Kompatibilität                           │
+│  3. Komponente für Komponente migrieren                         │
+│  4. Jede Komponente: vollständig getestet + in Storybook         │
+│  5. Nach Migration: Duplikate entfernen, Varianten konsolidieren│
+└─────────────────────────────────────────────────────────────────┘

Ablauf pro Komponente

┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐    ┌──────────────┐
+│   ANALYSE    │ →  │    SPEC      │ →  │   DEVELOP    │ →  │     QA       │ →  │  INTEGRATE   │
+├──────────────┤    ├──────────────┤    ├──────────────┤    ├──────────────┤    ├──────────────┤
+│ Bestehende   │    │ Props        │    │ Vue 3 Code   │    │ Alle Tests   │    │ In Vue 2     │
+│ Varianten    │    │ Varianten    │    │ Unit Tests   │    │ grün         │    │ Projekt      │
+│ identifiz.   │    │ Zustände     │    │ Storybook     │    │ Visual Regr. │    │ einbinden    │
+│ Duplikate    │    │ A11y         │    │ Stories      │    │ A11y Check   │    │              │
+│ finden       │    │ Tokens       │    │              │    │ Review       │    │ Alte Komp.   │
+│              │    │              │    │              │    │              │    │ entfernen    │
+└──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘    └──────────────┘

Komponenten-Protokoll

Pro Komponente wird eine Status-Datei im Komponenten-Ordner geführt (Colocation):

packages/ui/src/components/OsButton/
+├── OsButton.vue
+├── OsButton.spec.ts
+├── button.variants.ts
+├── index.ts
+└── STATUS.md          ← Status-Datei hier

Inhalt:

Begründung für Colocation:

Qualitätsanforderungen pro Komponente

AnforderungBeschreibung
Vollständig getestetUnit-Tests für alle Props, Varianten, Edge-Cases
Storybook StoriesAlle Varianten und Zustände dokumentiert
Detaillierte SpecProps, Events, Slots, A11y vor Implementierung definiert
Token-basiertNutzt ausschließlich Design Tokens, keine hardcoded Werte
Vue 2 kompatibelFunktioniert via vue-demi im bestehenden Projekt
A11y geprüftaxe-core Tests bestanden
Visual RegressionScreenshot-Baseline erstellt
Feature ParityCheckliste abgehakt (alle Props, Events, Slots)

Konsolidierungsziele

Bei der Migration werden:


9. Dokumentationsstrategie

Siehe ausführliche Version in §15 Dokumentationsstrategie (Details). Kurzzusammenfassung: Generierte Docs (vue-component-meta) + Manuell (Storybook).


10. Kompatibilitätstests

Vue 2/3 × Tailwind/CSS Testmatrix. Details siehe §18.

Kurzfassung:


REFERENZ & HISTORIE

11. Entscheidungen

73 Entscheidungen in 9 Kategorien

Vision & Ziele

#FrageEntscheidungBegründung
1HauptzielMigration vorbereitenSchrittweise Vue 2 → Vue 3

Tech-Stack

#FrageEntscheidungBegründung
2FrameworkVue 3 + ViteModern, schnell, gute DX
3DokumentationStorybook 10Storybook 1.0-beta hängt mit Tailwind v4 + Node 25, Storybook funktioniert sofort
4StylingTailwind + CSS VariablesModern + Branding-kompatibel
6TestingVitestVite-nativ, Jest-kompatibel
9Vue 2 Kompatibilitätvue-demiLibrary funktioniert in beiden Vue-Versionen
16Lintingeslint-config-it4cTypeScript + Vue + Prettier + weitere Regeln
34Vue API<script setup>Composition API mit script setup
36Package ManagernpmBereits im Projekt verwendet
41TypeScriptstrict: trueStrikte Typisierung
43Vue 2 MinimumVue 2.7Erforderlich für <script setup> Support
69Varianten-SystemCVA (class-variance-authority)Typsichere Props, Composable, DX wie shadcn/ui
70Klassen-Utilitycn() (clsx + tailwind-merge)Bedingte Klassen + Tailwind-Deduplizierung
71Komponenten-StatusSTATUS.md im Komponenten-OrdnerColocated mit Code, nicht in separatem docs/

Build & Distribution

#FrageEntscheidungBegründung
8Paket-Formatnpm LibraryWiederverwendbar
25Paket-Name@ocelot-social/uiUnter ocelot-social npm Org
31Build-StrategieDual-BuildTailwind Preset + Vorkompilierte CSS
32LizenzApache 2.0Permissiv mit Patent-Schutz
33RepositoryMonorepoOcelot-Social/packages/ui/
42Ordnerstrukturpackages/uiMonorepo-Standard, erweiterbar
44Dev-LinkingNuxt AliasLOCAL_UI=true für lokale Library

CI/CD & Release

#FrageEntscheidungBegründung
15Release-Toolrelease-please (Manifest)Monorepo-kompatibel, nur packages/ui Änderungen
17CI WorkflowsLint, Test, BuildQualitätssicherung bei jedem PR
18npm PublishAutomatisch bei ReleaseNach release-please PR merge
19Doku-DeployAutomatisch bei Releasestorybook build + deploy
45Release-CheckGit-basiertPrüft unreleased UI-Änderungen vor Ocelot-Release
46Storybook DeployWebhook + ScriptServer zieht und baut bei Release
50GitHub Workflows12 WorkflowsVollständige CI/CD Pipeline

Testing & Qualität

#FrageEntscheidungBegründung
20Visual RegressionPlaywright ScreenshotsVisueller Vergleich bei Änderungen
21Accessibility@axe-core/playwrightA11y integriert in Visual Tests
22Bundle Sizesize-limitWarnung bei Größenüberschreitung
23Feature ParityCheckliste pro KomponenteSicherstellen dass alle Features migriert
37Test Coverage100%Vollständige Testabdeckung
57Kompatibilitätstests4er-Matrix + CIVue 2/3 × Tailwind/CSS (siehe §18)

Design-System & Branding

#FrageEntscheidungBegründung
5Token-System3-Stufen (Base/Semantic/Component)Maximale Branding-Flexibilität
29Dark ModeJa, von Anfang anAlle Komponenten mit Light/Dark
30IconsHybrid-ArchitekturSystem-Icons in Library, Feature-Icons in App
51Icon-ArchitekturHybrid~10 System-Icons in Library, Rest in App (siehe §4)
59Size PropsTailwind-Skala (sm, md, lg, xl)Komponentenspezifisch, OsButton nutzt sm-xl
60Rounded PropsTailwind-Skala (none, sm, md, lg, xl, 2xl, 3xl, full)Konsistenz mit Tailwind border-radius
61Shadow PropsTailwind-Skala (none, sm, md, lg, xl, 2xl)Konsistenz mit Tailwind box-shadow
62Variant PropsSemantisch (primary, secondary, danger, warning, success, info)Übliche UI-Farbvarianten
63Dark Mode HandlingCSS-Klassen (dark: Prefix)Standard-Tailwind-Pattern, keine "inverse" Props
64Prop-VollständigkeitAlle Werte einer SkalaKonsistente API, keine Teilmengen pro Komponente
65CSS Variable DefaultsKeine Defaults in LibraryWebapp definiert Branding, Library ist design-agnostisch
66Branding-HierarchieWebapp → Spezialisiertes BrandingDefault-Branding in Webapp, Overrides pro Instanz
67Variable-ValidierungRuntime-Check in DevelopmentvalidateCssVariables() warnt bei fehlenden Variablen
68Branding-Test (Webapp)CI-Test in WebappWebapp testet, dass Default-Branding alle Library-Variablen definiert
72Webapp ↔ Maintenance SharingWebapp als Source of TruthKein separates "shared" Package, maintenance importiert aus webapp/ (siehe §16a)
73Daten-EntkopplungViewModel/Mapper PatternKomponenten kennen nur ViewModels, Mapper transformieren API-Daten (siehe §16b)

Komponenten-API & Konventionen

#FrageEntscheidungBegründung
26Komponenten-PrefixOsOsButton, OsCard, etc.
27Browser-SupportModern onlyLetzte 2 Versionen von Chrome, Firefox, Safari, Edge
28SSRJaNuxt-kompatibel
35SpracheEnglischCode, Comments, Docs
38DateinamenPascalCaseOsButton.vue, OsCard.vue
39i18nNur PropsKeine Default-Texte in Komponenten
40BreakpointsTailwind Standardsm, md, lg, xl, 2xl
55Komponenten-AbgrenzungEntscheidungsbaumLibrary: präsentational, Webapp: Business-Logik (siehe §16)

Dokumentation

#FrageEntscheidungBegründung
13Doku-HostingEigener ServerÖffentlich zugängliche Komponenten-Doku
14Doku-ZugangÖffentlichFür alle Entwickler frei zugänglich
47Komponenten-ProtokollSTATUS.md im Komponenten-OrdnerColocated: src/components/OsButton/STATUS.md
52Docs-Generierungvue-component-metaKomponenten-Tabelle aus Code generiert
53Docs CI-CheckGitHub WorkflowPrüft JSDoc-Coverage und README-Aktualität
54Nach MigrationARCHITECTURE.mdPROJEKT.md → ARCHITECTURE.md, KATALOG.md archivieren

Migration & Prozess

#FrageEntscheidungBegründung
7Komponenten-ReihenfolgeNach BedarfFlexibel, Token-System zuerst
10Migrations-AblaufKomponente für KomponenteKontrolliert, schrittweise
11Vor-AnalyseVollständige AnalyseDuplikate/Probleme vor Migration identifizieren
12SpezifikationDetailliert vor ImplementierungProps, Varianten, A11y vorher definieren
24Deprecation WarningsConsole WarningsHinweise in alter Codebase
48KatalogisierungKATALOG.mdUnterbrechbar, Webapp + Styleguide
49FortschrittBerechenbarPro Phase und Gesamt
56Externe Abhängigkeiten✅ Gelösteslint-config-it4c v0.8.0 ist modular
58KomplexitätsanalyseDokumentiert in §19Risikofaktoren, Parallelisierbarkeit, Aufwandstreiber

12. Arbeitsprotokoll

DatumBeschreibungErgebnis
2026-02-04ProjektstartOrdner und Planungsdokument erstellt
2026-02-04Tech-Stack EntscheidungenAlle Kernentscheidungen getroffen
2026-02-04Migrationsstrategievue-demi, Komponente-für-Komponente, Analyse-First
2026-02-04DokumentationKomponenten-Doku auf eigenem Server, öffentlich zugänglich
2026-02-04CI/CD & Releaserelease-please, GitHub Workflows, automatisches npm publish
2026-02-04Erweiterte QAVisual Regression, A11y Tests, Bundle Size Check
2026-02-04Migrations-AbsicherungFeature Parity Checklist, Deprecation Warnings
2026-02-04Naming & Paket@ocelot-social/ui, Os-Prefix
2026-02-04PlattformModern Browsers, SSR-kompatibel, Dark Mode
2026-02-04Build & IconsDual-Build (Tailwind + CSS), Hybrid-Architektur (~10 System-Icons)
2026-02-04OrganisatorischApache 2.0, bleibt im Monorepo
2026-02-04Konventionenscript setup, Englisch, npm, 100% Coverage, PascalCase
2026-02-04WeitereNur Props (kein i18n), Tailwind Breakpoints, strict TS
2026-02-04Ordnerstrukturpackages/ui statt styleguide-vue3
2026-02-04KonfliktanalyseVue 2.7 Upgrade als Voraussetzung für script setup
2026-02-04Webapp-IntegrationNuxt Alias für lokale Entwicklung, Git-basierter Release-Check
2026-02-04ProzesseQA-Schritt pro Komponente, Komponenten-Protokoll, KATALOG.md
2026-02-04FortschrittBerechenbar für Gesamt und Einzelschritte
2026-02-04Phase 1 abgeschlossenVue 2.7 Upgrade erfolgreich, alle Tests bestanden
2026-02-04Icon-ArchitekturHybrid-Ansatz: ~10 System-Icons in Library, Feature-Icons in App
2026-02-04DokumentationsstrategieHybrid: Generiert (vue-component-meta) + Manuell, CI-geprüft
2026-02-04Abgrenzung Library/WebappEntscheidungsbaum + Checkliste für Komponenten-Zuordnung
2026-02-04Externe Abhängigkeiteslint-config-it4c blockiert Linting-Setup, Workaround dokumentiert
2026-02-04Kompatibilitätstests4er-Matrix (Vue 2/3 × Tailwind/CSS), Example Apps, Playwright E2E
2026-02-07Storybook statt HistoireHistoire 1.0-beta hängt mit Tailwind v4 + Node 25 (kein Output, 100% CPU). Storybook 10 funktioniert sofort.
2026-02-07Storybook Greyscale-ThemeKomponenten in Graustufen - verdeutlicht, dass Farben von der App kommen, nicht von der Library.
2026-02-07CSS Token-SystemrequiredCssVariables mit 18 Farb-Variablen (6 Farben × 3 Werte) befüllt.
2026-02-07Storybook Workflowui-storybook.yml für Build + Artifact Upload.
2026-02-07Docker SetupDockerfile (dev + prod), ui-docker.yml Workflow, docker-compose Services.
2026-02-07Storybook Build FixviteFinal entfernt vite-plugin-dts und build-css für Storybook-Build. Stories aus Coverage ausgeschlossen.
2026-02-07Docs-Check Scriptscripts/check-docs.ts prüft: Story-Existenz, JSDoc für Props, Varianten-Abdeckung. ui-docs.yml Workflow.
2026-02-04Phasen umbenannt0.5→1, 1→2, 2→3, 3→4, 4→5 (nur ganzzahlige Phasen)
2026-02-04Dokument-Konsolidierung§13 Zahlen korrigiert, §14 Link entfernt, §16 Reihenfolge, Terminologie vereinheitlicht
2026-02-04Komplexitätsanalyse§20 hinzugefügt: Risikofaktoren, Parallelisierbarkeit, Aufwandstreiber pro Komponente
2026-02-04Phase 2 gestartetVite + Vue 3 Projekt initialisiert, vue-demi, Vitest, Package-Struktur
2026-02-04Build-Systemvite.config.ts mit Library-Mode, vite-plugin-dts für Types, vite-tsconfig-paths
2026-02-04TestingVitest in vite.config.ts integriert, Plugin-Tests geschrieben
2026-02-04DokumentationREADME.md mit Installation und Usage (Tree-Shaking vs Plugin)
2026-02-04Tailwind-KonventionenSize, Rounded, Shadow, Variant - vollständige Skalen, Dark Mode via CSS
2026-02-04Tailwind v4 Setup@tailwindcss/vite Plugin, Dual-Build (style.css + tailwind.preset)
2026-02-04Prop-Typessrc/types.d.ts mit Size, Rounded, Shadow, Variant
2026-02-04Branding-ArchitekturKeine Defaults in Library, Webapp definiert Branding, validateCssVariables()
2026-02-07ESLint Setupeslint-config-it4c v0.8.0 eingerichtet (Vue 3, Vitest, Prettier)
2026-02-07GitHub Workflowsui-lint.yml, ui-test.yml (100% Coverage), ui-build.yml (Build + Verify)
2026-02-07.tool-versionsNode 25.5.0 zentral definiert, Workflows nutzen node-version-file
2026-02-07Vue 2/3 Matrixvue2 + @vitejs/plugin-vue2, CI Matrix-Tests, .npmrc legacy-peer-deps
2026-02-07Vue 2 Test-Strategie geändertInline-Matrix entfernt (Peer-Dependency-Konflikte), Vue 2 wird via Example Apps getestet
2026-02-07Example Apps erstelltvue2-app und vue3-app mit Vitest, ui-compatibility.yml Workflow
2026-02-07ESLint ExamplesEigene eslint.config.ts + prettier.config.mjs pro Example App, Lint im Compatibility-Workflow
2026-02-07Type Assertionsas unknown as Plugin für CI-Kompatibilität bei verlinkten Packages
2026-02-07Package-Validierungpublint + arethetypeswrong, separate .d.cts für CJS, afterBuild Hook in vite-plugin-dts
2026-02-074er Example Apps Matrixvue3-tailwind, vue3-css, vue2-tailwind, vue2-css; Workflow mit Matrix-Strategie
2026-02-07Release & Publishrelease-please Manifest-Config, ui-release.yml Workflow mit npm publish
2026-02-07CONTRIBUTING.mdEntwickler-Leitfaden mit Setup, Komponenten-Erstellung, Code-Standards, Testing, Commits
2026-02-07DependabotKonfiguration für UI-Package und alle 4 Example Apps hinzugefügt
2026-02-07CSS-BuildTailwind CLI im closeBundle Hook für style.css Generierung
2026-02-07CVA Setupclass-variance-authority, clsx, tailwind-merge als Dependencies
2026-02-07cn() UtilityTailwind-Klassen-Merge Funktion (clsx + tailwind-merge) mit Tests
2026-02-07OsButtonErste Komponente mit CVA-Varianten (variant, size, fullWidth) implementiert
2026-02-07ESLint Fixesvue/max-attributes-per-line off (Prettier), import-x/no-relative-parent-imports off
2026-02-07STATUS.md KonventionKomponenten-Status als STATUS.md im Komponenten-Ordner (Colocation statt docs/)
2026-02-07OsButton STATUS.mdStatus-Datei erstellt mit Feature-Übersicht, fehlenden Features, Test-Coverage, Architektur
2026-02-07CVA-Dokumentation§5 erweitert: CVA + Tailwind + CSS-Variablen Architektur, Branding-Überschreibbarkeit
2026-02-07Accessibility Testsvitest-axe mit axe-core, Custom TypeScript-Declarations, OsButton a11y-Tests
2026-02-07Completeness Checkcheck-docs.ts → check-completeness.ts, docs:check → verify, ui-docs.yml → ui-verify.yml
2026-02-07Visual Regression TestsPlaywright mit colocated Tests (*.visual.spec.ts), ui-visual.yml Workflow
2026-02-07Colocated Screenshotsscreenshots/ im Komponenten-Ordner statt separatem e2e/
2026-02-07Visual Test Coverageverify prüft ob alle Stories Visual Tests haben (--kebab-case URL)
2026-02-07Phase 2 abgeschlossenAlle 26 Aufgaben erledigt, bereit für Phase 3
2026-02-08Keyboard Testsdescribe('keyboard accessibility') mit 4 Tests, verify prüft Existenz
2026-02-08ESLint Pluginseslint-plugin-storybook installiert, flat/recommended Config
2026-02-08A11y Konsolidierungvitest-axe → @axe-core/playwright, checkA11y() in Visual Tests
2026-02-08Greyscale Theme WCAGFarben für 4.5:1 Kontrast angepasst (warning, info, secondary)
2026-02-08Test-Vereinfachung*.a11y.spec.ts entfernt, A11y via checkA11y() in Visual Tests
2026-02-08Completeness Updateverify prüft: Story, Visual, checkA11y(), Keyboard, Varianten
2026-02-08Phase 2 KonsolidierungDependencies aufgeräumt (vitest-axe, axe-core entfernt)
2026-02-08Projekt-Optimierungsrc/test/setup.ts entfernt, @storybook/vue3 entfernt, README.md fix
2026-02-08Package Updatessize-limit 12.0.0, eslint-plugin-jsdoc 62.5.4, vite-tsconfig-paths 6.1.0
2026-02-08TODO: eslint-config-it4cMuss auf ESLint 10 aktualisiert werden (aktuell inkompatibel)
2026-02-08Phase 3: vue-demi Integrationvue-demi zur Webapp hinzugefügt, Webpack-Alias für Vue 2.7 Kompatibilität
2026-02-08Phase 3: Webpack-Alias@ocelot-social/ui$ und style.css$ Aliase für yarn-linked Package
2026-02-08Phase 3: isVue2 RenderOsButton mit isVue2 Check: Vue 2 attrs-Objekt, Vue 3 flat props
2026-02-08Phase 3: CSS-SpezifitätUI-Library CSS nach Styleguide laden (styleguide.js Plugin)
2026-02-08Phase 3: Jest vue-demiCustom Mock (__mocks__/@ocelot-social/ui.js) mit Module._load Patch, defineComponent von Vue.default, vueDemiSetup.js, 979 Tests ✅
2026-02-08Phase 3: Button-StylesVariants angepasst: font-semibold, rounded, box-shadow, h-[37.5px]
2026-02-08Phase 3: Erste IntegrationUserTeaserPopover.vue verwendet <os-button>
2026-02-08Phase 3: Visueller TestManueller Vergleich OsButton vs ds-button erfolgreich ✅
2026-02-08Phase 3: v8 ignoreVue 2 Branch in OsButton mit /* v8 ignore */ für 100% Coverage in Vitest
2026-02-08Phase 3: Docker Buildui-library Stage in Dockerfile + Dockerfile.maintenance, COPY --from=ui-library
2026-02-08Phase 3: CI-FixRelativer Pfad file:../packages/ui statt absolut für yarn install außerhalb Docker
2026-02-08Phase 3: Storybook FixTypeScript-Fehler in Stories behoben (default aus args entfernt)
2026-02-08Phase 3: attrs/listenersOsButton forwarded jetzt attrs + $listeners für Vue 2 (getCurrentInstance)
2026-02-08Phase 3: Jest Mock erweitertAlle Composition API Funktionen (computed, ref, watch, etc.) im Mock
2026-02-08Phase 3: 15 Buttons migriertGroupForm, EmbedComponent, DonationInfo, CommentCard, MapStylesButtons, GroupMember, embeds, notifications, privacy, terms-and-conditions-confirm
2026-02-08Phase 3: Test-Updatesprivacy.spec.js Selektoren, notifications Snapshot, DonationInfo.spec.js
2026-02-08OsButton: appearance PropNeue appearance Prop: filled (default), outline, ghost - ermöglicht base-button Stile
2026-02-08OsButton: xs SizeExakte Pixel-Werte für base-button --small: h-26px, px-8px, text-12px, rounded-5px
2026-02-08OsButton: outline primaryGrüner Rahmen + grüner Text + hellgrüner Hintergrund-Tint (rgba(25,122,49,0.18))
2026-02-08OsButton: ghost primaryTransparenter Hintergrund, grüner Text, Hover füllt grün, Active dunkler
2026-02-08OsButton: Focus Stylefocus:outline-dashed focus:outline-1 statt ring (wie base-button)
2026-02-08OsButton: Active Stateactive:bg-[var(--color-*-hover)] für dunkleren Hintergrund beim Drücken
2026-02-08Visuelle ValidierungTracking-Tabelle in PROJEKT.md für manuelle Button-Vergleiche (4/16 validiert)
2026-02-08Storybook Grayscale ThemeVollständige CSS-Variablen: default, active-states, contrast-inverse
2026-02-08Tailwind Source Filter@import "tailwindcss" source(none) - verhindert Markdown-Scanning
2026-02-08Button Variants KonsistenzAlle 21 compound variants mit korrekten active-states (--color-*-active)
2026-02-08CSS-Variablen erweitert--color-secondary/warning/success/info-active in ocelot-ui-variables.scss
2026-02-08Story Dokumentation"Medium (37.5px)" → "Medium (36px)" korrigiert
2026-02-08Playwright ToleranzmaxDiffPixelRatio: 0.03 für Cross-Platform Font-Rendering
2026-02-09Disabled-Styles korrigiertCSS-Variablen --color-disabled, filled: grauer Hintergrund statt opacity
2026-02-09terms-and-conditions-confirmRead T&C Button → appearance="outline" variant="primary"
2026-02-09Visuelle Validierung10/16 Buttons validiert (terms-and-conditions-confirm.vue abgeschlossen)
2026-02-09Disabled:active/hover FixCSS-Regeln in index.css mit höherer Spezifität für sofortige disabled-Darstellung
2026-02-09notifications.vueCheck All + Uncheck All → appearance="outline" variant="primary"
2026-02-09Visuelle Validierung14/16 Buttons validiert (notifications.vue abgeschlossen)
2026-02-09embeds.vueAllow All → appearance="outline" variant="primary"
2026-02-09Disabled Border-FixCSS-Regeln in index.css: border-style: solid + border-width: 0.8px bei :disabled
2026-02-09Visuelle Validierung abgeschlossen16/16 Buttons validiert (100%) ✅ Milestone 5 erfolgreich
2026-02-09Button-Analyse erweitert14 weitere Buttons identifiziert (ohne icon/circle/loading) → Scope: 16/35
2026-02-09Scope auf ~90 erweitert~60 weitere Buttons mit icon/circle/loading identifiziert
2026-02-09Milestone 4a: 8 ButtonsDisableModal, DeleteUserModal, ReleaseModal, ContributionForm, EnterNonce, MySomethingList, ImageUploader (2x)
2026-02-09ImageUploader CSS-Fixposition: absolute !important für crop-confirm (überschreibt OsButton relative)
2026-02-09§16a hinzugefügtWebapp ↔ Maintenance Code-Sharing: Webapp als Source of Truth (Entscheidung #69)
2026-02-09§16b hinzugefügtDaten-Entkopplung: ViewModel/Mapper Pattern für API-agnostische Komponenten (Entscheidung #70)
2026-02-09NotificationMenu.vue2 Buttons migriert (ghost primary), padding-top Fix für vertical-align Unterschied
2026-02-09Milestone 4a abgeschlossen6 weitere Buttons migriert: donations.vue (Save), profile/_id/_slug.vue (Unblock, Unmute), badges.vue (Remove), notifications/index.vue (Mark All Read), ReportRow.vue (More Details)
2026-02-10Wasserfarben-FarbschemaGreyscale-Theme → Aquarell-Farben (Ultramarin, Dioxazin-Violett, Alizarin, Ocker, Viridian, Cöruleum), WCAG AA konform
2026-02-10Stories konsolidiertPrimary/Secondary/Danger/Default entfernt → AllVariants; AllSizes/AllAppearances/Disabled/FullWidth zeigen alle 7 Varianten
2026-02-10Appearance: Filled/Outline/GhostEinzelne Stories umbenannt und mit allen 7 Varianten erweitert
2026-02-10Playground-StoryInteraktive Controls (argTypes nur in Playground, nicht global)
2026-02-10Einheitlicher Borderborder-[0.8px] border-solid border-transparent als Base-Klasse für alle Appearances
2026-02-10WCAG 2.4.7 FixDefault-Variante: focus:outline-nonefocus:outline-dashed focus:outline-current
2026-02-10Keyboard A11y TestPlaywright-Test fokussiert alle Buttons und prüft outlineStyle !== 'none'
2026-02-10data-appearance AttributOsButton rendert data-appearance auf <button>; CSS-Selektoren nutzen [data-appearance="filled"] statt escaped Tailwind-Klassen
2026-02-10Code-Review FixesUnit-Tests: spezifischere Assertions (Compound-Variant-Logik), Trailing Spaces in Testnamen, ESLint restrict-template-expressions Fix
2026-02-10CSS-Linting@eslint/css + tailwind-csstree für Tailwind v4 Custom Syntax; excludeCSS() Helper verhindert JS-Regel-Konflikte; Regeln: no-empty-blocks, no-duplicate-imports, no-invalid-at-rules
2026-02-10CI-Workflow-Trigger9 UI-Workflows von on: push auf push+pull_request mit Branch-Filter (master) und Path-Filter (packages/ui/** + Workflow-Datei) umgestellt
2026-02-10custom-class entferntcustom-class Prop (entfernt aus OsButton) → class Attribut in notifications.vue, MapStylesButtons.vue, EmbedComponent.vue (4 Stellen); Snapshot aktualisiert
2026-02-10Vue 3 Template-Fixthis.$t()$t() in CommentCard.vue (this im Template in Vue 3 nicht verfügbar)
2026-02-11Icon-Slot implementiertBenannter #icon Slot für OsButton, slot-basiert statt Icon-Prop (icon-system-agnostisch)
2026-02-11Icon-Wrapper KlassenTailwind-Utility-Klassen direkt auf <span>: inline-flex items-center shrink-0 h-[1.2em] [&>svg]:h-full [&>svg]:w-auto [&>svg]:fill-current
2026-02-11VNode Text-ErkennunghasText prüft VNode-Children auf sichtbaren Inhalt; whitespace-only → icon-only Verhalten
2026-02-11Gap & Margin Logikgap-2 bei Icon+Text, -ml-1 bei Icon, -ml-1 -mr-1 bei Icon-Only (optischer Ausgleich)
2026-02-114 neue StoriesIcon, IconOnly, IconSizes, IconAppearances mit Inline-SVG Komponenten (CheckIcon, CloseIcon, PlusIcon)
2026-02-11Playground erweitertReaktiver Icon-Selektor (none/check/close/plus) + Label-Text-Control via computed()
2026-02-11Storybook: components OptionFunktionale Komponenten müssen in components registriert werden, nicht in setup() return
2026-02-11Storybook: CSS nicht in index.cssStorybook lädt eigene storybook.css, nicht src/styles/index.css → Utility-Klassen direkt verwenden
2026-02-11SVG-Targeting[&>svg] statt [&>*] für Icon-Sizing (BaseIcon rendert <span><svg>, Wrapper-Span darf nicht beeinflusst werden)
2026-02-11my-email-address migriertSave-Button: <os-button variant="primary"> mit <template #icon><base-icon name="check" /></template>
2026-02-11Code-OptimierungICON_CLASS Konstante extrahiert, iconMargin Variable, vereinfachte hasText-Logik (kein Symbol.for)
2026-02-11Größenabhängiger Gapgap-1 (4px) für xs/sm, gap-2 (8px) für md/lg/xl bei Icon+Text
2026-02-11Größenabhängiger MarginKein negativer Icon-Margin bei xs/sm (voller Padding-Abstand zur Button-Grenze)
2026-02-11DisableModal.vueConfirm-Button migriert: danger filled icon="exclamation-circle"variant="danger" + #icon Slot
2026-02-11DeleteUserModal.vueConfirm-Button migriert: identisches Pattern wie DisableModal
2026-02-11CtaUnblockAuthor.vueButton migriert: filled icon="arrow-right"variant="primary" + #icon Slot, OsButton importiert
2026-02-11LocationSelect.vueIcon-only Close-Button migriert: ghost size="small" icon="close"variant="primary" appearance="ghost" size="sm" + aria-label
2026-02-11CategoriesSelect.vuev-for Buttons migriert: dynamisches :icon#icon Slot, :filled:appearance, CSS .base-buttonbutton
2026-02-11profile/_id/_slug.vueChat-Button migriert: icon="chat-bubble"variant="primary" appearance="outline" full-width + #icon Slot
2026-02-11verify.vue korrigiertKein Button vorhanden (Eintrag aus Milestone-Liste entfernt)
2026-02-11PaginationButtons.vue2 circle icon-only Buttons migriert: outline primary circle + #icon Slot + aria-label
2026-02-11OsButton: circle Propcircle Prop: rounded-full p-0 + größenabhängige Breiten (CIRCLE_WIDTHS Map)
2026-02-11OsButton: loading PropAnimierter SVG-Spinner mit aria-busy="true", Button auto-disabled bei loading
2026-02-11Spinner-ArchitekturBeide Animationen (rotate + dash) auf <circle> Element; SVG ist statischer Container; Chrome-Compositing-Bug-Workaround
2026-02-11Spinner-ZentrierungIcon-Buttons: Spinner über Icon (translate-basiert, overflow:visible); Text-Buttons: Spinner im Button-Container (inset-0 m-auto)
2026-02-11animations.cssKeyframes os-spinner-dash + os-spinner-rotate in separate CSS-Datei ausgelagert
2026-02-11min-width pro Größemin-w-[26px]/min-w-[36px]/min-w-12/min-w-14 in button.variants.ts (verhindert zu kleine leere Buttons)
2026-02-11Code-OptimierungOsButton ~250→207 Zeilen: buttonData geteilt, SPINNER_PX vereinfacht, redundante cn() entfernt, getCurrentInstance nur Vue 2
2026-02-115 neue Unit-Testsdefault type, data-appearance, min-w, icon-only loading, circle gap-1; gesamt: 76 Tests
2026-02-11Milestone 4b abgeschlossenicon ✅, circle ✅, loading ✅ — alle OsButton-Props implementiert
2026-02-11Milestone 4c: 59 ButtonsChat (2), AddChatRoomByUserSearch (1), CommentCard (1), CommentForm (2), ComponentSlider (2), ContributionForm (1), DeleteData (1), EmbedComponent (1), FilterMenu (1), HeaderButton (2), CategoriesFilter (2), OrderByFilter (2), EventsByFilter (2), FollowingFilter (3), GroupButton (1), ConfirmModal (2), ReportModal (2), Password/Change (1), PasswordReset/Request (1), PasswordReset/ChangePassword (1), Registration/Signup (1), ReleaseModal (1), ImageUploader (2), CreateInvitation (1), Invitation (2), ProfileList (1), ReportRow (1), MySomethingList (3), ActionButton (1), pages/index (2), profile/add-post (1), post/blur-toggle (1), groups/slug (3), settings/index (1), admin/users (2), blocked-users (1), data-download (1), muted-users (1), groups/index (1), enter-nonce (1)
2026-02-11type="submit" PatternOsButton hat type="button" als Default; alle Form-Submit-Buttons brauchen explizit type="submit"
2026-02-11!!errors PatternDsForm errors ist ein Objekt, nicht Boolean; OsButton disabled Prop erwartet Boolean → !!errors nötig
2026-02-11CSS-Selector Pattern.base-button> button oder button; Position/Dimensions brauchen !important für Tailwind-Override
2026-02-11Disabled border-colorOutline disabled border von var(--color-disabled) auf var(--color-disabled-border,#e5e3e8) mit Fallback
2026-02-11Phase 3 abgeschlossen132 <os-button> Tags in 78 Dateien, 0 <base-button> in Templates verbleibend
2026-02-11Password/Change.vue Fix!!errors für disabled-Prop (DsForm errors ist Objekt)
2026-02-11CommentForm.vue Fixtype="submit" fehlte + !!errors für disabled-Prop
2026-02-11GroupForm.vue ds-buttonLetzter <ds-button> in Webapp → <os-button> mit #icon Slot migriert
2026-02-11OsButton.spec.ts TS-Fixsize aus Object.entries als Union Type gecastet (\`as 'sm'
2026-02-11Coverage 100%v8 ignore start/stop für Vue 2 Branch, v8 ignore next für defensive \`
2026-02-11Scope: 133 Buttons133 <os-button> Tags in 79 Dateien, 0 <base-button> + 0 <ds-button> verbleibend
2026-02-12data-variant AttributOsButton rendert data-variant auf <button> (konsistent mit data-appearance), ermöglicht CSS-Selektoren wie button[data-variant="danger"]
2026-02-12notifications.spec.jsTest-API korrigiert: wrapper.find() (Vue Test Utils) → screen.getByText() (Testing Library), button.disabled statt button.attributes('disabled')
2026-02-12FilterMenu Regressionsbugappearance="ghost" war hardcoded statt dynamisch; filterActive Computed Property existierte aber war nicht genutzt → :appearance="filterActive ? 'filled' : 'ghost'"
2026-02-12FilterMenu.spec.jsTest von CSS-Klasse --filled auf data-appearance="filled" Attribut-Selektor umgestellt
2026-02-12CtaUnblockAuthor.vueTypo require: truerequired: true (Vue ignorierte die Prop-Validierung)
2026-02-12LocationSelect.vue Fixesevent.target.valuethis.currentValue (Button hat kein value), @click.native@click (Vue 3), aria-label via i18n
2026-02-12i18n: actions.clearNeuer Key in allen 9 Sprachdateien: en=Clear, de=Zurücksetzen, fr=Effacer, es=Borrar, it=Cancella, nl=Wissen, pl=Wyczyść, pt=Limpar, ru=Очистить
2026-02-12OsButton JSDocSlot-Dokumentation (@slot default, @slot icon) für vue-component-meta/Storybook autodocs
2026-02-12OsButton xs entferntisSmall von ['xs', 'sm'].includes(size) auf size === 'sm' vereinfacht (xs ist kein gültiger Size-Wert)
2026-02-12Strikte Typisierungtype Size = NonNullable<ButtonVariants['size']>, Record<Size, ...> für CIRCLE_WIDTHS + SPINNER_PX; props.size!(props.size ?? 'md') as Size
2026-02-12animations.cssStylelint-konforme Formatierung: eine Deklaration pro Zeile, Leerzeilen zwischen Keyframe-Stufen
2026-02-12OsButton RefactoringvueAttrs() Helper für Vue 2/3 Attribut-Handling, Einmal-Variablen durch cn() ersetzt, children inline; 77 Tests, 100% Coverage
2026-02-12CSS @import Reihenfolge@import "./animations.css" vor @source-Direktiven verschoben (CSS-Spec: @import vor anderen At-Rules)
2026-02-12CustomButton CleanupisEmpty aus data() entfernt — reine Utility-Funktion braucht keine Vue-Reaktivität
2026-02-12notifications.spec.jsDoppelten beforeEach konsolidiert; wrapper von Modulebene in describe-Block verschoben
2026-02-12Style-ScopingMenuLegend.vue: <style scoped> hinzugefügt; ReportModal + DeleteUserModal: CSS-Selektoren mit Komponenten-Prefix
2026-02-12data-test SelektorenLocationSelect (clear-location-button) + HashtagsFilter (clear-search-button): spezifischere Test-Selektoren
2026-02-12Vue 3 Compat FixesFollowButton: .native entfernt; FilterMenu: slot/slot-scope<template #default>; HashtagsFilter: this.$t()$t()
2026-02-12A11y: aria-labelGroupContentMenu icon-only Button: $t('group.contentMenu.menuButton'); PaginationButtons: $t('pagination.previous/next')
2026-02-12i18n Keyspagination.previous/next + group.contentMenu.menuButton in allen 9 Sprachdateien angelegt
2026-02-12Modal KonsistenzDisableModal + DeleteUserModal: appearance="filled" + :loading="loading" auf Danger-Buttons
2026-02-12Loading Statemy-email-address/index.vue: loadingData hinzugefügt + finally Block für Reset
2026-02-12MapButton #icon SlotIcon von Default-Slot in <template #icon> verschoben (konsistent mit allen anderen Buttons)
2026-02-12Dead Code entferntMySomethingList.vue: .icon-button CSS-Klasse (nach Migration nicht mehr verwendet)
2026-02-12Button-Wrapper-Analyse15 OsButton-Wrapper klassifiziert: 4 Smart (Apollo/Vuex), 4 Presentational, 7 Borderline; GroupButton + MapButton als Inline-Kandidaten identifiziert
2026-02-12compat/ KonzeptSeparates Verzeichnis für temporäre Migrations-Wrapper (nicht von check-completeness.ts erfasst); BaseIcon als erster Kandidat (131 Nutzungen)
2026-02-13data-test Selektoren~10 Komponenten: data-test Attribute für robuste Test-Selektoren (unmute-btn, unblock-btn, follow-btn, join-leave-btn, login-btn, load-all-connections-btn, content-menu-button)
2026-02-13Cypress Selektoren4 Step-Definitions: .user-content-menu button / .content-menu button[data-test="content-menu-button"]
2026-02-13Spec-SelektorenFollowList, FollowButton, LoginButton, CtaJoinLeaveGroup, ReportRow, muted-users, blocked-users: generische button[data-test="..."]
2026-02-13A11y: aria-label~15 icon-only Buttons: aria-label hinzugefügt (admin/users, AddChatRoom, EmbedComponent, groups, profile, CustomButton, HeaderMenu, ImageUploader, ContentMenu, HeaderButton, InviteButton, LoginButton, blocked/muted-users)
2026-02-13Zustandsabhängiges aria-labelpost/_id/_slug: $t(blurred ? 'post.sensitiveContent.show' : 'post.sensitiveContent.hide')
2026-02-13ComponentSlider aria-labelInterpoliertes Label: $t('component-slider.step', { current: index + 1, total: ... })
2026-02-13i18n Keys (6 neue)actions.search, actions.close, actions.menu, site.navigation, post.sensitiveContent.show/hide, component-slider.step in allen 9 Sprachdateien
2026-02-13Loading-State FixesDisableModal + ReleaseModal: finally { this.loading = false } für Reset
2026-02-13BugfixesChangePassword: !!errors; Password/Change: disabled aus data() entfernt + 2 tote Tests; MenuBar: unbenutztes ref entfernt
2026-02-13Button-PropsGroupForm cancel: variant="default" appearance="filled"; donations/LoginForm/EnterNonce: appearance="filled" ergänzt
2026-02-13CSS-SelektorenLoginForm: .login-form button.login-form button[type='submit']; pages/index: redundante Klasse auf BaseIcon entfernt
2026-02-13JoinLeaveButton.native von @mouseenter/@mouseleave entfernt (Vue 3 Kompatibilität)
2026-02-13MySomethingList:title + :aria-label auf Edit/Delete-Buttons (Tooltip beibehalten neben Accessibility)
2026-02-13OsButton Klasseos-button CSS-Klasse auf Button-Element für Branding-Kompatibilität (#9211)
2026-02-14ESLint Config Updateeslint-config-it4c v0.11.2: Flat Config, path alias #src, CSS-Linting, security/detect-non-literal-fs-filename, n/no-sync, n/shebang (#9233)
2026-02-14check-completenessParallelisiertes File-Reading, breitere Regex für Keyboard-Tests, Playground-Tests ignoriert
2026-02-14Release v0.0.2@ocelot-social/ui v0.0.2 veröffentlicht
2026-02-14as PropPolymorphe OsButton-Komponente: as Prop für dynamischen Tag/Komponente (button, a, nuxt-link, router-link); moderner Standard (Headless UI, Radix Vue)
2026-02-14Naming: tag → astagas umbenannt nach Recherche moderner UI-Libraries (Headless UI, Radix Vue, Chakra UI, PrimeVue nutzen as)
2026-02-14Disabled nur für buttondisabled/type/loading nur bei as="button" (Links haben kein natives disabled); aria-disabled/tabindex Logik entfernt
2026-02-14Polymorphic StoryNeue Story Polymorphic mit Varianten, Icons, disabled-Vergleich; Playground mit as-Selektor (button/a)
2026-02-14nuxt-link Migration15 <nuxt-link>/<a>-Wrapper → as="nuxt-link"/as="a" in 15 Webapp-Dateien; invalides HTML (<button> in <a>) eliminiert
2026-02-14CustomButton konsolidiertv-if/v-else für <a>/<nuxt-link> Wrapper → einzelner <os-button :as="linkTag" v-bind="linkProps"> mit Computed Properties
2026-02-14NotificationMenu konsolidiert2 separate Buttons (kein Badge / mit Badge) zu einem zusammengeführt — counter-icon zeigt bei count=0 kein Badge
2026-02-14CSS-Selektor Fixpages/index.vue: button.post-add-button-top/bottom.post-add-button-top/bottom (nuxt-link rendert <a>, nicht <button>)
2026-02-14Profil-Spacingprofile/_id/_slug.vue: v-if auf ds-grid-item (kein leerer Abstand), symmetrisches Padding $space-x-small
2026-02-15OsIcon KomponenteNeue Komponente: name (System-Icon), icon (Custom Component), size (xs-2xl); Vue 2/3 via vue-demi h()
2026-02-15vite-svg-icon PluginCustom Vite Plugin: extrahiert viewBox + <path> aus SVG, transformiert zu Vue h()-Aufruf via ?icon Query
2026-02-15System-Icons3 SVG-Icons in Library: check, close, plus (viewBox 0 0 32 32, stroke-basiert); SYSTEM_ICONS Registry + SystemIconName Type
2026-02-15Icon-GrößenCVA-Varianten: xs(0.75em), sm(0.875em), md(1.2em default), lg(1.5em), xl(2em), 2xl(2.5em) — em-basiert für Kontext-Skalierung
2026-02-15Icon A11yDecorative: aria-hidden="true" (default); Semantic: role="img" + aria-label wenn Label-Prop vorhanden
2026-02-15OsIcon in OsButtonOsButton nutzt OsIcon statt inline SVG-Elemente für Icon-Slot-Rendering
2026-02-15Ocelot-IconsSeparates Entry-Point (ocelot.mjs): dynamisches Icon-Loading via import.meta.glob('**/*.svg', { query: '?icon' })
2026-02-15webapp → ocelotsrc/webapp/src/ocelot/ umbenannt; Stories, Tests, Exports angepasst; konsistentes Naming
2026-02-15OsIcon Tests211 Zeilen Unit-Tests (Rendering, Sizes, A11y, CSS, System-Icons); Visual Tests mit checkA11y(); Keyboard A11y; 100% Coverage
2026-02-15OsButton StoriesBereinigt: Inline-SVG-Komponenten durch OsIcon ersetzt; WithAriaLabel-Story entfernt; InheritColor-Story vereinfacht
2026-02-15check-completenessErweitert für ocelot/ Verzeichnis; unterstützt OsIcon-Patterns
2026-02-15svg-icon.d.tsTypeScript-Deklaration für ?icon Import-Query (Component-Typ)
2026-02-15BaseIcon → OsIcon Migration131 <base-icon> in 70+ Dateien → <os-icon :icon="icons.xxx">, 0 BaseIcon verbleibend
2026-02-1582 Ocelot-IconsVon 1 auf 82 Icons: Feature-Icons + 17 Kategorie-Icons aus Webapp kopiert
2026-02-15vite-svg-icon erweitertUnterstützt jetzt <rect>, <circle>, <polygon>, <polyline>, <ellipse>, <line> (war path-only)
2026-02-15SVG-MinifizierungAlle 21 neuen SVGs auf Single-Line minifiziert (Multiline brach JS-String-Literale im Plugin)
2026-02-15Kategorie-IconsDB-String → toCamelCase()ocelotIcons[key] Lookup in Category, CategoriesFilter, CategoriesSelect, admin/categories
2026-02-15MenuLegend.vue FixlegendItems von data()computed (data() läuft vor created(), this.icons undefined)
2026-02-15HeaderMenu.vue FixMap-Button Icon-Größe: size="xl" + negative Margin (OsIcon md=1.2em vs BaseIcon --large=2.2em)
2026-02-15ShowPassword.vue Fix:data-test="iconName" entfernt (Icon ist jetzt Render-Function statt String)
2026-02-15Test-Updates (8 Specs)Category, ProfileAvatar, CounterIcon, ReportRow, ActionButton, ComponentSlider, ShowPassword, LoginForm: BaseIcon → OsIcon + ocelotIcons
2026-02-158 Snapshots gelöschtStale Snapshot-Dateien entfernt nach BaseIcon → OsIcon Migration
2026-02-15CSS Migration.base-icon.os-icon in main.scss und Category/index.vue
2026-02-15Jest Mock ocelottest/__mocks__/@ocelot-social/ui/ocelot.js für ocelotIcons in Jest-Umgebung
2026-02-18OsSpinner KomponenteNeue Komponente: size (xs-2xl, em-basiert), currentColor, role="status", aria-label; Vue 2/3 via h() + isVue2
2026-02-18OsSpinner Decorativearia-hidden="true" unterdrückt role/aria-label; OsButton nutzt OsSpinner als Komponente (decorative)
2026-02-18ButtonSize TypeButtonSize (sm/md/lg/xl) exportiert aus button.variants.ts; types.d.ts Kommentar: Size ist Vokabular, nicht Pflicht
2026-02-18OsSpinner Webapp-Migration4 Stellen migriert: ImageUploader, profile, groups, admin; LoadingSpinner gelöscht
2026-02-18ds-space centered Bugfix<ds-space centered><div style="text-align:center;padding:48px 0"> in 3 Seiten (Styleguide-Bug)
2026-02-18Admin Spinner Fix<ApolloQuery>apollo-Option + $apollo.loading; SSR-Prefetch verhinderte Loading-State im Client
2026-02-18filterStatistics Fixdelete data.__typename → Destructuring { __typename, ...rest } (keine Mutation des Originalobjekts)
2026-02-18infinite-loading Spinner-SlotOsSpinner im spinner-Slot von vue-infinite-loading in 3 Seiten (index, profile, groups); einheitliches Spinner-Design
2026-02-19BaseCard → OsCard Migration~30 Webapp-Dateien: <base-card><os-card> mit lokalen Imports; CSS-Fixes für Tailwind p-6 Override, outline highlight, child→descendant selectors
2026-02-19#imageColumn/#topMenu inlineLoginForm, RegistrationSlider, password-reset: BaseCard-Slots → inline Layout mit .os-card.--columns CSS in main.scss
2026-02-19Tests & Stories migriert16 Spec-Dateien, 4 Story-Dateien, 12+2 Cypress E2E Step-Definitions: base-card → os-card Selektoren
2026-02-19BaseCard gelöschtBaseCard.vue Komponente + base-components.js Plugin entfernt; nuxt.config, maintenance config, testSetup bereinigt
2026-02-19CSS-FixesContributionForm Media-Query Selektoren, ProfileList Spezifität, InternalPage $space-small, OsCard highlight outline-1 Tests
2026-02-19Code-QualitySocialMedia Props typisiert, LoginForm querySelector, redundante client-only entfernt, NotificationsTable optional chaining, HashtagsFilter doppeltes Mounting
2026-02-19Review Fixes (Session 26)Cypress Kind-Kombinator .os-card > .title, OsCard.spec.ts Bitmask-Assertion fix, Maintenance-App Abhängigkeiten als pre-existing bewertet
2026-02-19Tier A Migration (Session 27)10 triviale ds-* Vue-Wrapper → Plain HTML + CSS-Klassen; _ds-compat.scss Utility-Klassen; ~90 Dateien geändert
2026-02-19ds-section/placeholder/tag/list19 Nutzungen in 13 Dateien → HTML-Elemente mit bestehenden CSS-Klassen aus system.css
2026-02-19ds-container14 Nutzungen in 12 Dateien → <div class="ds-container ds-container-{width}">
2026-02-19ds-heading31 Nutzungen in 25 Dateien → <h1-h4 class="ds-heading ds-heading-h{n}"> mit soft/no-margin/align
2026-02-19ds-text80 Nutzungen in 42 Dateien → <p/div class="ds-text ds-text-{color} ds-text-size-{size}">
2026-02-19ds-space139 Nutzungen in 55+ Dateien → <div class="ds-mb-{size}"> / <div class="ds-my-{size}">; neue Utility-Klassen in _ds-compat.scss
2026-02-19ds-flex/ds-flex-item103 Nutzungen in 29 Dateien → Plain HTML + CSS @media Queries; JS window.innerWidth → CSS Media Queries; gap statt negative-margin/padding
2026-02-19HTML-Validierung Bugfix<p> mit Block-Level-Kindern → <div> in DateTimeRange.vue und verify.vue
2026-02-19Test-FixEmpty.spec.js: attributes().marginclasses().toContain('ds-my-xxx-small')
2026-02-19Review Fixes (Session 28)~20 CodeRabbit Review-Kommentare für Tier A PR bearbeitet; Bugfixes, A11y, i18n, Scoping
2026-02-19Heading-SemantikComponentSlider h1→h3, SearchHeading h1→h5 (ds-heading size-Prop wurde falsch zu h1 migriert)
2026-02-19A11y FixesLabel-for Mismatch (RegistrationSlideEmail),   in Aside entfernt, link.id→link.url Key
2026-02-19i18nlogout.vue "Logging out..." → $t() mit 9 Sprachen; maintenance alt-Text → $t()
2026-02-19CSS Fixes.buttons Klasse ergänzt (GroupForm), display:flex auf .ds-space-centered, 33%→33.333%, inline-style→Utilities
2026-02-19ScopingSignup.vue, maintenance/index.vue, post/create/_type.vue, post/edit/_id.vue: unscoped → scoped Style-Blöcke
2026-02-19Migration-ArtefakteRedundante Wrapper-Divs, tote Attribute (margin="large"), Span→P Block-Level Regression
2026-02-20OsBadge Komponente (Session 29)Neue Komponente: CVA-Varianten (variant, size, shape), h() Render-Function, 16 Tests, 6 Stories
2026-02-20ds-chip → OsBadge20 Nutzungen in 5 Dateien: GroupTeaser, GroupMember, GroupForm, ContributionForm, groups/_slug
2026-02-20ds-tag → OsBadge3 Nutzungen in 3 Dateien: Category (shape="square"), Hashtag (shape="square"), PostTeaser (CSS)
2026-02-20OsBadge Featuresshape-Prop (pill/square), w-fit (Flex-Container-Fix), inline-flex items-center (Icon-Zentrierung)
2026-02-20CSS-Variable--color-default + --color-default-contrast für neutralen Badge-Hintergrund
2026-02-20Code-Review Fixes (Session 30)--color-default-contrast in requiredCssVariables, doppelte --color-default Deklaration entfernt
2026-02-20Type SafetyBadgeVariant Typ exportiert, PlaygroundArgs typisiert, redundante Ternäre entfernt
2026-02-20Layout-KonsistenzGroupForm float:right → Flexbox align-self:flex-end, Inline-Style → Tailwind in Stories
2026-02-20ARIA Live Regionsrole="status"/aria-live="polite" auf 11 Form-Badges (WCAG 4.1.3), live Prop → Standard-Attribute
2026-02-20ds-grid → CSS Grid10 Dateien migriert: ds-grid/ds-grid-item → native CSS Grid + Klassen
2026-02-20ds-table → Plain HTML (Session 31)7 Dateien: <ds-table> → native <table> + CSS-Klassen (.ds-table, .ds-table-col, etc.)
2026-02-20Table-CSS_ds-compat.scss erweitert: .ds-table-wrap, .ds-table, .ds-table-col, .ds-table-head-col, bordered, condensed, alignment
2026-02-20fields() entferntComputed Properties fields()/tableFields() aus 7 Dateien entfernt — Labels direkt in <th>
2026-02-20Scope-Objekte entferntscope.row Zugriffe → direkte Iteration-Variable (user, tag, member, report)
2026-02-20OsNumber Komponente (Session 32)Neue Komponente: h() Render-Function, requestAnimationFrame Animation (1500ms ease-out), count (required), label, animated Props
2026-02-20ds-number + CountTo → OsNumber5 Dateien: UserTeaserPopover, TabNavigation, admin/index, profile/_slug, groups/_slug
2026-02-20Animation-Stabilitättabular-nums + min-width: Nch für stabile Breite während Count-up Animation
2026-02-20CountTo.vue gelöschtvue-count-to Dependency entfernt, followedByCountStartValue/membersCountStartValue Pattern entfernt
2026-02-20CSS-Variable --color-text-softNeuer Contract-Eintrag in tailwind.preset.ts + ocelot-ui-variables.scss (Label-Farbe)
2026-02-20Admin-Label uppercase.admin-stats__item .os-number-label { text-transform: uppercase } per CSS statt neuem Prop

13. Komponenten-Katalog

`,316)),i("blockquote",null,[i("p",null,[i("strong",null,[s[1]||(s[1]=t("Detaillierte Katalogisierung in separater Datei: ")),d(n,{to:"/packages/ui/KATALOG.html"},{default:r(()=>s[0]||(s[0]=[t("KATALOG.md")])),_:1})])])]),s[3]||(s[3]=e(`

Zusammenfassung (aus KATALOG.md)

QuelleGesamtStatus
Webapp139✅ Katalogisiert
Styleguide38✅ Katalogisiert — 23 in Webapp genutzt

Styleguide-Migration:

StatusKomponenten
✅ UI-LibraryOsButton, OsIcon, OsSpinner, OsCard, OsBadge, OsNumber (6)
✅ → Plain HTMLSection, Placeholder, List, ListItem, Container, Heading, Text, Space, Flex, FlexItem, Grid, GridItem, Table (13) — Tier A/B
✅ → UI-LibraryChip, Tag → OsBadge (2), Number → OsNumber (1) — Tier B
⬜ → Plain HTMLRadio (1) — Tier B
⬜ → UI-LibraryModal, Input, Menu, MenuItem, Select (5) — Tier 2-3
⬜ Nicht genutztCode, CopyField, FormItem, InputError, InputLabel, Page, PageTitle, Logo, Avatar, TableCol, TableHeadCol (11)
⬜ OffenForm (18 Dateien — HTML <form> oder OsForm?)

Projekt:

Tracking:

Dokumentation:


15. Dokumentationsstrategie (Details)

Übersicht

┌─────────────────────────────────────────────────────────────┐
+│  GENERIERT (aus Code) - Single Source of Truth              │
+├─────────────────────────────────────────────────────────────┤
+│  • README.md Komponenten-Tabelle                            │
+│  • Props/Events/Slots Dokumentation                         │
+│  • TypeScript-Typen                                         │
+└─────────────────────────────────────────────────────────────┘
+                            +
+┌─────────────────────────────────────────────────────────────┐
+│  MANUELL                                                    │
+├─────────────────────────────────────────────────────────────┤
+│  • README.md Installation, Quick Start, Theming             │
+│  • Storybook Stories (interaktive Beispiele)                 │
+│  • ARCHITECTURE.md (Entscheidungen)                         │
+│  • Best Practices, Patterns                                 │
+└─────────────────────────────────────────────────────────────┘

README.md Struktur

# @ocelot-social/ui
+
+## Übersicht
+- Was ist die Library?
+- Link zu Storybook (Live-Dokumentation)
+
+## Installation
+- npm install
+- Peer Dependencies (vue, vue-demi)
+
+## Quick Start
+- Minimal-Beispiel (Import + Nutzung)
+- Mit Tailwind / Ohne Tailwind
+
+## Theming / Branding
+- CSS Custom Properties überschreiben
+- Beispiel-Branding
+
+## Icon-System
+- System-Icons (enthalten)
+- Eigene Icons registrieren
+
+## Vue 2 / Vue 3
+- vue-demi Erklärung
+- Kompatibilitätshinweise
+
+## Komponenten                    ← GENERIERT
+- Tabelle aller Komponenten
+- Link zu Storybook für Details
+
+## Contributing
+- Link zu CONTRIBUTING.md
+
+## License
+- Apache 2.0

Generierung mit vue-component-meta

Tool: vue-component-meta (offizielles Vue-Tool)

// scripts/generate-docs.ts
+import { createComponentMetaChecker } from 'vue-component-meta'
+
+// Extrahiert aus .vue Dateien:
+{
+  name: "OsButton",
+  description: "Primary button component for user actions",
+  props: [
+    {
+      name: "variant",
+      type: "'primary' | 'secondary' | 'danger'",
+      default: "'primary'",
+      required: false,
+      description: "Visual style variant"
+    }
+  ],
+  events: [{ name: "click", type: "(event: MouseEvent) => void" }],
+  slots: [{ name: "default", description: "Button content" }]
+}

Generierte Komponenten-Tabelle:

| Komponente | Beschreibung | Props | Events | Slots |
+|------------|--------------|-------|--------|-------|
+| OsButton | Primary button for actions | 8 | 1 | 2 |
+| OsCard | Container with header/footer | 5 | 0 | 3 |
+| ... | ... | ... | ... | ... |

CI-Workflow: docs-check

# .github/workflows/docs-check.yml
+name: Documentation Check
+
+on: [push, pull_request]
+
+jobs:
+  docs:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+
+      - name: Generate docs from components
+        run: npm run docs:generate
+
+      - name: Check for undocumented props
+        run: npm run docs:check-coverage
+        # Fails if props/events/slots missing JSDoc
+
+      - name: Verify README is up-to-date
+        run: npm run docs:verify
+        # Compares generated table with README
+        # Fails if differences found

Scripts in package.json:

{
+  "scripts": {
+    "docs:generate": "tsx scripts/generate-docs.ts",
+    "docs:check-coverage": "tsx scripts/check-doc-coverage.ts",
+    "docs:verify": "tsx scripts/verify-readme.ts",
+    "docs:update": "npm run docs:generate && npm run docs:inject-readme"
+  }
+}

ESLint-Regeln für Dokumentation

// eslint.config.js
+{
+  rules: {
+    // Erzwingt JSDoc für exportierte Funktionen/Komponenten
+    "jsdoc/require-jsdoc": ["error", {
+      require: {
+        FunctionDeclaration: true,
+        ClassDeclaration: true
+      }
+    }],
+    "jsdoc/require-description": "error",
+    "jsdoc/require-param-description": "error"
+  }
+}

Dokumentations-Phasen

PhaseDokumentationStatus
Phase 2README.md Grundgerüst (Installation, Setup)Manuell
Phase 2CONTRIBUTING.mdManuell
Phase 2docs:generate Script einrichtenAutomatisiert
Phase 2CI docs-check WorkflowAutomatisiert
Phase 4Storybook Stories pro KomponenteManuell
Phase 4JSDoc in KomponentenIm Code
Phase 4README Komponenten-TabelleGeneriert
Phase 4README FinalisierungManuell
Phase 5ARCHITECTURE.md (aus PROJEKT.md)Manuell

Nach der Migration: Datei-Transformation

Während Migration:
+├── PROJEKT.md          # Planungs- und Statusdokument
+├── KATALOG.md          # Komponenten-Tracking
+
+Nach Phase 5 (Migration abgeschlossen):
+├── README.md           # Nutzer-Dokumentation (teilweise generiert)
+├── CONTRIBUTING.md     # Beitragende
+├── CHANGELOG.md        # Automatisch via release-please
+├── ARCHITECTURE.md     # Entscheidungen aus PROJEKT.md §2, §4, §5, §11, §15, §16
+├── src/components/*/STATUS.md  # Komponenten-Status (colocated, werden beibehalten)
+└── docs/
+    └── archive/        # Historische Referenz (optional)
+        ├── PROJEKT.md
+        └── KATALOG.md

Was wird übernommen nach ARCHITECTURE.md:

Was wird archiviert/gelöscht:


ABGRENZUNGEN

16. Library vs. Webapp

Grundprinzip

┌─────────────────────────────────────────────────────────────┐
+│  @ocelot-social/ui (Library)                                │
+├─────────────────────────────────────────────────────────────┤
+│  • Rein präsentational                                      │
+│  • Keine Business-Logik                                     │
+│  • Keine API-Calls                                          │
+│  • Kein App-State                                           │
+│  • Wiederverwendbar in jedem Vue-Projekt                    │
+└─────────────────────────────────────────────────────────────┘
+
+                            │ nutzt
+┌─────────────────────────────────────────────────────────────┐
+│  Webapp (Ocelot)                                            │
+├─────────────────────────────────────────────────────────────┤
+│  • Business-Logik (GraphQL, Auth, etc.)                     │
+│  • App-State (Vuex/Pinia)                                   │
+│  • i18n Texte                                               │
+│  • Routing-Logik                                            │
+│  • Ocelot-spezifische Features                              │
+└─────────────────────────────────────────────────────────────┘

Entscheidungs-Checkliste

KriteriumLibrary ✅Webapp ✅
Business-LogikKeineHat GraphQL/API-Calls
App-StateKein Vuex/PiniaBraucht Store
i18nNur via PropsNutzt $t() direkt
RoutingNur via Props (to)Nutzt $router direkt
WiederverwendbarIn jedem Vue-ProjektNur in Ocelot
AbhängigkeitenNur Vue + vue-demiOcelot-spezifisch
StylingDesign-TokensApp-spezifische Styles
DatenErhält via PropsFetcht selbst

Entscheidungsbaum

Komponente X
+
+
+┌─────────────────────────────────────┐
+│ Hat sie Business-Logik?             │
+│ (API-Calls, Mutations, Auth-Check)  │
+└─────────────────────────────────────┘
+
+    ├── JA ──► WEBAPP
+
+    ▼ NEIN
+┌─────────────────────────────────────┐
+│ Braucht sie App-State?              │
+│ (Vuex, Pinia, globaler State)       │
+└─────────────────────────────────────┘
+
+    ├── JA ──► WEBAPP
+
+    ▼ NEIN
+┌─────────────────────────────────────┐
+│ Nutzt sie $t() oder $router direkt? │
+└─────────────────────────────────────┘
+
+    ├── JA ──► WEBAPP (oder refactoren)
+
+    ▼ NEIN
+┌─────────────────────────────────────┐
+│ Ist sie generisch wiederverwendbar? │
+│ (Könnte in anderem Projekt helfen)  │
+└─────────────────────────────────────┘
+
+    ├── NEIN ──► WEBAPP
+
+    ▼ JA
+
+    ══► LIBRARY

Quantitative Regel

Wenn ≥2 Kriterien auf "Webapp" zeigen → WebappWenn alle Kriterien auf "Library" zeigen → Library

Konkrete Beispiele

KomponenteEntscheidungBegründung
OsButtonLibraryRein präsentational, keine Logik
OsModalLibraryUI-Container, Logik via Events
OsInputLibraryGenerisches Form-Element
OsAvatarLibraryNur Bild + Fallback-Initialen
OsCardLibraryLayout-Container
OsDropdownLibraryPopover-Mechanik
FollowButtonWebappGraphQL Mutation, User-State
PostTeaserWebappOcelot-Datenstruktur, Links
CommentFormWebappAPI-Call, Auth-Check
ConfirmModalWebappNutzt OsModal + Callbacks
LoginFormWebappAuth-Logik, Routing, i18n
UserAvatarWebappNutzt OsAvatar + User-Daten
NotificationMenuWebappGraphQL, Store, i18n

Composition Pattern für Grenzfälle

Wenn eine Komponente UI- und Business-Anteile hat: Aufteilen

┌─────────────────────────────────────────────────────────────┐
+│  LIBRARY: OsModal                                           │
+│  - Overlay, Animation, Backdrop                             │
+│  - close/confirm Events                                     │
+│  - Slots für Content                                        │
+│  - Props: title, confirmLabel, cancelLabel                  │
+└─────────────────────────────────────────────────────────────┘
+
+                        │ nutzt
+┌─────────────────────────────────────────────────────────────┐
+│  WEBAPP: DeleteUserModal                                    │
+│  - Wraps OsModal                                            │
+│  - GraphQL Mutation                                         │
+│  - i18n Texte via $t()                                      │
+│  - Redirect nach Löschung                                   │
+└─────────────────────────────────────────────────────────────┘

Beispiel-Code:

<!-- Webapp: DeleteUserModal.vue -->
+<template>
+  <OsModal
+    :title="$t('user.delete.title')"
+    :confirm-label="$t('common.delete')"
+    confirm-variant="danger"
+    @confirm="handleDelete"
+    @cancel="$emit('close')"
+  >
+    <p>{{ $t('user.delete.warning', { name: user.name }) }}</p>
+  </OsModal>
+</template>
+
+<script setup>
+import { OsModal } from '@ocelot-social/ui'
+import { useDeleteUserMutation } from '~/graphql/mutations'
+import { useRouter } from 'vue-router'
+
+const props = defineProps(['user'])
+const emit = defineEmits(['close'])
+const router = useRouter()
+const { mutate: deleteUser } = useDeleteUserMutation()
+
+const handleDelete = async () => {
+  await deleteUser({ id: props.user.id })
+  emit('close')
+  router.push('/')
+}
+</script>

Checkliste bei neuer Komponente

Vor dem Erstellen einer Komponente diese Fragen beantworten:

[ ] Wo gehört die Komponente hin? (Entscheidungsbaum durchlaufen)
+[ ] Falls Library: Sind alle Texte via Props?
+[ ] Falls Library: Keine direkten Store/Router Imports?
+[ ] Falls Webapp: Welche Library-Komponenten werden genutzt?
+[ ] Falls Grenzfall: Kann sie aufgeteilt werden?

16a. Webapp ↔ Maintenance Code-Sharing

Problemstellung

Die Webapp und Maintenance-App sind aktuell verschachtelt und sollen getrennt werden. Einige Business-Komponenten werden in beiden Apps benötigt, gehören aber nicht in die UI-Library.

Das DX-Problem: "shared" hat kein logisches Kriterium außer "wird in beiden gebraucht".

Analysierte Optionen

OptionBeschreibungBewertung
A: Domain Packages@ocelot-social/auth, @ocelot-social/posts, etc.Gut bei vielen Komponenten, aber Overhead
B: Core + DuplikationComposables teilen, Komponenten duplizierenGut wenn UI unterschiedlich
C: Webapp als SourceMaintenance importiert aus WebappEinfachste Lösung

Empfehlung: Option C (Webapp als Source of Truth)

┌─────────────────────────────────────────────────────────────┐
+│  @ocelot-social/ui                                          │
+│  ─────────────────                                          │
+│  • OsButton, OsModal, OsCard, OsInput                       │
+│  • Rein präsentational, keine Abhängigkeiten                │
+├─────────────────────────────────────────────────────────────┤
+│  webapp/                                                    │
+│  ───────                                                    │
+│  • Alle Business-Komponenten (Source of Truth)              │
+│  • Composables in webapp/lib/composables/                   │
+│  • GraphQL in webapp/graphql/                               │
+│  • Ist die "Haupt-App"                                      │
+├─────────────────────────────────────────────────────────────┤
+│  maintenance/                                               │
+│  ────────────                                               │
+│  • Importiert aus @ocelot-social/ui                         │
+│  • Importiert aus webapp/ via Alias                         │
+│  • Nur maintenance-spezifische Komponenten lokal            │
+└─────────────────────────────────────────────────────────────┘

Umsetzung

maintenance/nuxt.config.js:

export default {
+  alias: {
+    '@webapp': '../webapp',
+    '@ocelot-social/ui': '../packages/ui/dist'
+  }
+}

Import in Maintenance:

// UI-Komponenten aus Library
+import { OsButton, OsModal } from '@ocelot-social/ui'
+
+// Business-Komponenten aus Webapp
+import FollowButton from '@webapp/components/FollowButton.vue'
+import PostTeaser from '@webapp/components/PostTeaser.vue'
+
+// Composables aus Webapp
+import { useAuth } from '@webapp/lib/composables/useAuth'
+import { useFollow } from '@webapp/lib/composables/useFollow'

Kriterien für Entwickler

FrageAntwort
Wo suche ich eine UI-Komponente?@ocelot-social/ui
Wo suche ich eine Business-Komponente?webapp/components/
Wo erstelle ich eine neue geteilte Komponente?webapp/components/
Wo erstelle ich maintenance-spezifische Komponenten?maintenance/components/

Vorteile

  1. Klare Regel: Alles Business-bezogene ist in Webapp
  2. Kein neues Package: Weniger Overhead
  3. Eine Source of Truth: Keine Sync-Probleme
  4. Einfache Migration: Später ggf. Domain-Packages extrahieren

Spätere Evolution (optional)

Wenn klare Patterns entstehen, können Domain-Packages extrahiert werden:

Phase 1 (jetzt):  Webapp ist Source of Truth
+Phase 2 (später): Patterns identifizieren
+Phase 3 (später): @ocelot-social/auth, @ocelot-social/posts, etc.

Entscheidung

#DatumEntscheidung
722026-02-09Webapp als Source of Truth für geteilte Business-Komponenten

16b. Daten-Entkopplung (ViewModel/Mapper Pattern)

Problemstellung

Komponenten sind oft direkt an API/GraphQL-Strukturen gekoppelt:

<!-- ❌ Tight Coupling -->
+<UserCard :user="graphqlResponse.User" />
+
+// Komponente kennt GraphQL-Struktur
+props.user.avatar.url
+props.user._followedByCurrentUserCount  // Underscore?!
+props.user.__typename                   // Leaked!

Probleme:

Lösung: ViewModel + Mapper Pattern

┌─────────────────────────────────────────────────────────────┐
+│  GraphQL / API Layer                                        │
+│  • Queries & Mutations                                      │
+│  • Generated Types (graphql-codegen)                        │
+└─────────────────────────────────────────────────────────────┘
+
+
+┌─────────────────────────────────────────────────────────────┐
+│  Mappers (einziger Ort der API-Struktur kennt)              │
+│  • toUserCardViewModel(graphqlUser) → UserCardViewModel     │
+│  • toPostTeaserViewModel(graphqlPost) → PostTeaserViewModel │
+└─────────────────────────────────────────────────────────────┘
+
+
+┌─────────────────────────────────────────────────────────────┐
+│  ViewModels (was die UI braucht)                            │
+│  • UserCardViewModel { displayName, avatarUrl, ... }        │
+│  • PostTeaserViewModel { title, excerpt, ... }              │
+└─────────────────────────────────────────────────────────────┘
+
+
+┌─────────────────────────────────────────────────────────────┐
+│  Presentational Components (kennen nur ViewModels)          │
+│  • <UserCard :user="UserCardViewModel" />                   │
+│  • <PostTeaser :post="PostTeaserViewModel" />               │
+└─────────────────────────────────────────────────────────────┘

Implementierung

1. ViewModels definieren:

// types/viewModels.ts
+export interface UserCardViewModel {
+  id: string
+  displayName: string
+  avatarUrl: string | null
+  followerCount: number
+  isFollowedByMe: boolean
+}
+
+export interface PostTeaserViewModel {
+  id: string
+  title: string
+  excerpt: string
+  authorName: string
+  authorAvatarUrl: string | null
+  createdAt: Date
+  commentCount: number
+  canEdit: boolean
+}

2. Mapper-Funktionen:

// mappers/userMapper.ts
+import type { UserCardViewModel } from '~/types/viewModels'
+import type { UserGraphQL } from '~/graphql/types'
+
+export function toUserCardViewModel(
+  user: UserGraphQL,
+  currentUserId?: string
+): UserCardViewModel {
+  return {
+    id: user.id,
+    displayName: user.name || user.slug || 'Anonymous',
+    avatarUrl: user.avatar?.url ?? null,
+    followerCount: user._followedByCurrentUserCount ?? 0,
+    isFollowedByMe: user.followedByCurrentUser ?? false,
+  }
+}

3. Komponenten nutzen nur ViewModels:

<!-- components/UserCard.vue -->
+<script setup lang="ts">
+import type { UserCardViewModel } from '~/types/viewModels'
+
+// Komponente kennt NUR das ViewModel, nicht GraphQL
+defineProps<{
+  user: UserCardViewModel
+}>()
+</script>

4. Composables kapseln Mapping:

// composables/useUser.ts
+import { computed } from 'vue'
+import { useQuery } from '@vue/apollo-composable'
+import { GET_USER } from '~/graphql/queries'
+import { toUserCardViewModel } from '~/mappers/userMapper'
+import type { UserCardViewModel } from '~/types/viewModels'
+
+export function useUser(userId: string) {
+  const { result, loading, error } = useQuery(GET_USER, { id: userId })
+
+  const user = computed<UserCardViewModel | null>(() => {
+    if (!result.value?.User) return null
+    return toUserCardViewModel(result.value.User)
+  })
+
+  return { user, loading, error }
+}

Ordnerstruktur

webapp/
+├── graphql/
+│   ├── queries/
+│   ├── mutations/
+│   └── types/              # Generated by graphql-codegen
+├── types/
+│   └── viewModels.ts       # UI-spezifische Interfaces
+├── mappers/
+│   ├── userMapper.ts
+│   ├── postMapper.ts
+│   └── index.ts
+├── lib/
+│   └── composables/
+│       ├── useAuth.ts
+│       ├── useUser.ts      # Gibt ViewModel zurück
+│       └── usePost.ts
+├── components/             # Presentational (nur ViewModels)
+│   ├── UserCard.vue
+│   └── PostTeaser.vue
+└── pages/                  # Nutzen Composables
+    └── users/[id].vue

Vorteile

AspektOhne MapperMit Mapper
API-ÄnderungAlle Komponenten anpassenNur Mapper anpassen
TestingMock GraphQL ResponseEinfaches ViewModel-Objekt
WiederverwendungKomponente an API gebundenKomponente API-agnostisch
TypeScriptKomplexe/generierte TypesKlare, einfache Interfaces
webapp ↔ maintenanceVerschiedene StrukturenGleiche ViewModels

Regeln

┌─────────────────────────────────────────────────────────────┐
+│  Regel 1: Komponenten definieren was sie BRAUCHEN           │
+│           (ViewModel), nicht was die API LIEFERT            │
+├─────────────────────────────────────────────────────────────┤
+│  Regel 2: Mapper sind der EINZIGE Ort der API kennt         │
+│           API-Änderung = nur Mapper ändern                  │
+├─────────────────────────────────────────────────────────────┤
+│  Regel 3: Composables kapseln Fetching + Mapping            │
+│           useUser() gibt UserCardViewModel zurück           │
+├─────────────────────────────────────────────────────────────┤
+│  Regel 4: Presentational Components sind API-agnostisch     │
+│           Einfach testbar, wiederverwendbar                 │
+└─────────────────────────────────────────────────────────────┘

Entscheidung

#DatumEntscheidung
732026-02-09ViewModel/Mapper Pattern für Daten-Entkopplung

17. Externe Abhängigkeiten

Übersicht

AbhängigkeitStatusBeschreibung
eslint-config-it4c⚠️ ESLint 10 ausstehendv0.8.0 eingebunden, ESLint 10 inkompatibel

eslint-config-it4c

Status: Funktional, ESLint 10 Update ausstehend

TODO: eslint-config-it4c muss für ESLint 10 aktualisiert werden (aktuell inkompatibel wegen @typescript-eslint/utils).

Lösung: Das Paket wurde in Version 0.8.0 modularisiert und unterstützt jetzt ESLint Flat Config.

Aktuelle Nutzung in @ocelot-social/ui:

// eslint.config.ts
+import config, { vue3, vitest } from 'eslint-config-it4c'
+
+export default [
+  ...config,    // Base + TypeScript + Prettier + weitere
+  ...vue3,      // Vue 3 Regeln
+  ...vitest,    // Vitest Test-Regeln
+  // Projekt-spezifische Overrides...
+]

Projekt-spezifische Anpassungen:


18. Kompatibilitätstests (Details)

Testmatrix

Die Library muss in 4 Kombinationen funktionieren:

                    │  Tailwind         │  CSS (vorkompiliert)
+────────────────────┼───────────────────┼──────────────────────
+Vue 3.4+            │  ✓ Muss testen    │  ✓ Muss testen
+Vue 2.7             │  ✓ Muss testen    │  ✓ Muss testen

Werkzeuge & Strategien

1. vue-demi (Code-Ebene)

Abstrahiert Vue 2/3 API-Unterschiede:

// Komponente importiert von vue-demi, nicht vue
+import { ref, computed, defineComponent } from 'vue-demi'

2. Unit Tests mit Vitest

Hauptpaket testet nur mit Vue 3 (Entwicklungsumgebung). Vue 2 Kompatibilität wird via vue-demi gewährleistet und in Example Apps getestet.

Begründung: Inline Vue 2/3 Matrix verursacht Peer-Dependency-Konflikte.

3. Example Apps (4 Kombinationen) - Hauptstrategie für Vue 2 Tests

packages/ui/
+├── examples/
+│   ├── vue3-tailwind/     # Vite + Vue 3 + Tailwind Preset
+│   │   ├── package.json
+│   │   ├── vite.config.ts
+│   │   ├── tailwind.config.js  # Nutzt @ocelot-social/ui/tailwind.preset
+│   │   └── src/App.vue         # Importiert alle Komponenten
+│   │
+│   ├── vue3-css/          # Vite + Vue 3 + style.css
+│   │   ├── package.json
+│   │   ├── vite.config.ts
+│   │   └── src/
+│   │       ├── main.ts         # import '@ocelot-social/ui/style.css'
+│   │       └── App.vue
+│   │
+│   ├── vue2-tailwind/     # Vue CLI / Nuxt 2 + Tailwind
+│   │   └── ...
+│   │
+│   └── vue2-css/          # Vue CLI / Nuxt 2 + style.css
+│       └── ...

Jede Example App:

4. Playwright E2E Tests

// e2e/compatibility.spec.ts
+import { test, expect } from '@playwright/test'
+
+const examples = [
+  { name: 'vue3-tailwind', port: 3001 },
+  { name: 'vue3-css', port: 3002 },
+  { name: 'vue2-tailwind', port: 3003 },
+  { name: 'vue2-css', port: 3004 },
+]
+
+for (const example of examples) {
+  test.describe(example.name, () => {
+    test('all components render', async ({ page }) => {
+      await page.goto(\`http://localhost:\${example.port}\`)
+
+      // Prüfe dass alle Komponenten sichtbar sind
+      await expect(page.locator('[data-testid="os-button"]')).toBeVisible()
+      await expect(page.locator('[data-testid="os-card"]')).toBeVisible()
+      await expect(page.locator('[data-testid="os-modal"]')).toBeVisible()
+    })
+
+    test('styles are applied correctly', async ({ page }) => {
+      await page.goto(\`http://localhost:\${example.port}\`)
+      const button = page.locator('[data-testid="os-button-primary"]')
+
+      // Prüfe dass CSS korrekt angewendet wird
+      await expect(button).toHaveCSS('background-color', /rgb/)
+    })
+
+    test('visual regression', async ({ page }) => {
+      await page.goto(\`http://localhost:\${example.port}\`)
+      await expect(page).toHaveScreenshot(\`\${example.name}.png\`)
+    })
+  })
+}

5. Package Validation

ToolZweck
publintPrüft package.json auf Export-Fehler
arethetypeswrongPrüft TypeScript-Typen für alle Entry Points
{
+  "scripts": {
+    "check:exports": "publint && attw --pack .",
+    "prepublishOnly": "npm run check:exports"
+  }
+}

6. package.json Exports (korrekte Struktur)

{
+  "name": "@ocelot-social/ui",
+  "type": "module",
+  "exports": {
+    ".": {
+      "import": "./dist/index.mjs",
+      "require": "./dist/index.cjs",
+      "types": "./dist/index.d.ts"
+    },
+    "./style.css": "./dist/style.css",
+    "./tailwind.preset": {
+      "import": "./dist/tailwind.preset.mjs",
+      "require": "./dist/tailwind.preset.cjs",
+      "types": "./dist/tailwind.preset.d.ts"
+    }
+  },
+  "peerDependencies": {
+    "vue": "^2.7.0 || ^3.0.0"
+  },
+  "peerDependenciesMeta": {
+    "tailwindcss": {
+      "optional": true
+    }
+  }
+}

CI Workflow: Compatibility Matrix

# .github/workflows/compatibility.yml
+name: Compatibility Tests
+
+on: [push, pull_request]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/setup-node@v4
+        with:
+          node-version: '20'
+      - run: npm ci
+      - run: npm run build
+      - uses: actions/upload-artifact@v4
+        with:
+          name: dist
+          path: packages/ui/dist
+
+  test-unit:
+    needs: build
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        vue-version: ['2.7', '3.4']
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/download-artifact@v4
+        with:
+          name: dist
+          path: packages/ui/dist
+      - run: npm ci
+      - run: npm test
+        env:
+          VUE_VERSION: \${{ matrix.vue-version }}
+
+  test-e2e:
+    needs: build
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        example: ['vue3-tailwind', 'vue3-css', 'vue2-tailwind', 'vue2-css']
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/download-artifact@v4
+        with:
+          name: dist
+          path: packages/ui/dist
+
+      - name: Setup example app
+        working-directory: packages/ui/examples/\${{ matrix.example }}
+        run: |
+          npm ci
+          npm run build
+
+      - name: Start preview server
+        working-directory: packages/ui/examples/\${{ matrix.example }}
+        run: npm run preview &
+
+      - name: Wait for server
+        run: npx wait-on http://localhost:4173 --timeout 30000
+
+      - name: Run Playwright tests
+        working-directory: packages/ui
+        run: npx playwright test --grep "\${{ matrix.example }}"
+
+      - uses: actions/upload-artifact@v4
+        if: failure()
+        with:
+          name: playwright-report-\${{ matrix.example }}
+          path: packages/ui/playwright-report/
+
+  validate-package:
+    needs: build
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: actions/download-artifact@v4
+        with:
+          name: dist
+          path: packages/ui/dist
+      - run: npm ci
+      - name: Validate exports
+        run: |
+          npx publint packages/ui
+          npx @arethetypeswrong/cli packages/ui

Werkzeug-Übersicht

WerkzeugZweckPhase
vue-demiVue 2/3 API-Kompatibilität im CodePhase 2
Vitest + MatrixUnit Tests für Vue 2.7 und Vue 3.4Phase 2
Example Apps (4x)Echte Projekte für jede KombinationPhase 2
PlaywrightE2E + Visual Regression für alle 4Phase 2
publintPackage.json Export-ValidierungPhase 2
arethetypeswrongTypeScript Entry Points CheckPhase 2
pkg-pr-newPreview-Releases in PRs (optional)Optional

Checkliste für neue Komponenten

[ ] Unit Tests laufen mit VUE_VERSION=2.7
+[ ] Unit Tests laufen mit VUE_VERSION=3.4
+[ ] Komponente in allen 4 Example Apps hinzugefügt
+[ ] E2E Tests für Komponente geschrieben
+[ ] Visual Regression Baseline erstellt
+[ ] Keine Vue 3-only APIs verwendet (oder via vue-demi abstrahiert)

19. Komplexitätsanalyse

Umfang nach Phasen

PhaseAufgabenKomplexitätAbhängigkeiten
Phase 0: Analyse6 Tasks✅ Erledigt-
Phase 1: Vue 2.76 Tasks✅ Erledigt-
Phase 2: Setup26 TasksMittel⚠️ eslint-config-it4c (extern)
Phase 3: Tokens6 TasksNiedrigKeine externen
Phase 4: Migration15 KomponentenHochPro Komponente: Spec→Dev→Test→Integrate
Phase 5: Finalisierung7 TasksNiedrigAlle vorherigen Phasen

Bekannte Risikofaktoren

RisikoBeschreibungAuswirkungMitigation
eslint-config-it4cExternes Projekt muss zuerst modularisiert werdenBlockiert Linting-Setup in Phase 2Temporäre lokale ESLint-Config als Workaround
vue-demi KompatibilitätUnbekannte Edge-Cases bei Vue 2/3 Dual-SupportUnerwartete Bugs bei IntegrationFrühzeitig in Example Apps testen
Visual Regression BaselinesKönnen bei Design-Änderungen viel Nacharbeit erfordernZusätzlicher Aufwand bei ÄnderungenBaselines erst nach Design-Freeze erstellen
Feature-ParityAlte Komponenten haben undokumentierte VerhaltensweisenRegressions bei MigrationGründliche Analyse vor Implementierung
Tailwind + CSS Dual-BuildKomplexe Build-KonfigurationBuild-Fehler, InkonsistenzenFrüh beide Varianten parallel testen

Parallelisierbarkeit

PhaseParallelisierbarDetails
Phase 2TeilweiseDie meisten Tasks sind sequentiell (Setup-Reihenfolge wichtig)
Phase 3NeinToken-Ebenen bauen aufeinander auf (Base → Semantic → Component)
Phase 4Ja (nach Tier 1)Tier 2/3 Komponenten können parallel entwickelt werden
Phase 5TeilweiseDokumentation kann parallel zur letzten Integration

Parallelisierbare Aufgaben in Phase 2:

Sequentielle Abhängigkeiten in Phase 2:

  1. Vite + Vue 3 Projekt → vue-demi → Tailwind → Build-Pipeline
  2. Vitest → Tests → Visual Regression
  3. Package-Struktur → release-please → npm Publish Workflow

Aufwandstreiber pro Komponente (Phase 4)

Jede Komponente durchläuft:

┌─────────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────┐
+│  ANALYSE    │ → │    SPEC     │ → │   DEVELOP   │ → │     QA      │ → │  INTEGRATE  │
+├─────────────┤   ├─────────────┤   ├─────────────┤   ├─────────────┤   ├─────────────┤
+│ Bestehende  │   │ Props       │   │ Vue 3 Code  │   │ Unit Tests  │   │ In Webapp   │
+│ Varianten   │   │ Events      │   │ TypeScript  │   │ Vue 2 Tests │   │ einbinden   │
+│ analysieren │   │ Slots       │   │ Tailwind    │   │ A11y Tests  │   │             │
+│             │   │ Tokens      │   │ Storybook    │   │ Visual Reg. │   │ Alte Komp.  │
+│             │   │ A11y        │   │ Stories     │   │ 4 Examples  │   │ entfernen   │
+└─────────────┘   └─────────────┘   └─────────────┘   └─────────────┘   └─────────────┘

Aufwand variiert stark nach Komponente:

KomponenteKomplexitätGrund
OsIconNiedrigEinfache Wrapper-Komponente
OsSpinnerNiedrigNur Animation + Größen
OsButtonHochViele Varianten, Link-Support, States
OsCardNiedrigEinfaches Layout
OsModalHochTeleport, Focus-Trap, Animations, A11y
OsDropdownHochPositioning, Click-Outside, Hover-States
OsInputMittelValidierung, States, Icons
OsAvatarNiedrigBild + Fallback
`,165))])}const m=a(h,[["render",k],["__file","PROJEKT.html.vue"]]),b=JSON.parse('{"path":"/packages/ui/PROJEKT.html","title":"@ocelot-social/ui - Projektdokumentation","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Inhaltsverzeichnis","slug":"inhaltsverzeichnis","link":"#inhaltsverzeichnis","children":[{"level":3,"title":"Schnellzugriff (Status)","slug":"schnellzugriff-status","link":"#schnellzugriff-status","children":[]},{"level":3,"title":"Nach Thema","slug":"nach-thema","link":"#nach-thema","children":[]},{"level":3,"title":"Wie dieses Dokument verwendet wird","slug":"wie-dieses-dokument-verwendet-wird","link":"#wie-dieses-dokument-verwendet-wird","children":[]}]},{"level":2,"title":"Fortschritt","slug":"fortschritt","link":"#fortschritt","children":[{"level":3,"title":"Gesamtprojekt","slug":"gesamtprojekt","link":"#gesamtprojekt","children":[]},{"level":3,"title":"Katalogisierung (Details in KATALOG.md)","slug":"katalogisierung-details-in-katalog-md","link":"#katalogisierung-details-in-katalog-md","children":[]},{"level":3,"title":"OsButton Migration (Phase 3) ✅","slug":"osbutton-migration-phase-3-✅","link":"#osbutton-migration-phase-3-✅","children":[]},{"level":3,"title":"OsIcon (Phase 4)","slug":"osicon-phase-4","link":"#osicon-phase-4","children":[]}]},{"level":2,"title":"Aktueller Stand","slug":"aktueller-stand","link":"#aktueller-stand","children":[]},{"level":2,"title":"Meilensteine","slug":"meilensteine","link":"#meilensteine","children":[{"level":3,"title":"Phase 0: Analyse & Katalogisierung ✅","slug":"phase-0-analyse-katalogisierung-✅","link":"#phase-0-analyse-katalogisierung-✅","children":[]},{"level":3,"title":"Phase 1: Vue 2.7 Upgrade ✅","slug":"phase-1-vue-2-7-upgrade-✅","link":"#phase-1-vue-2-7-upgrade-✅","children":[]},{"level":3,"title":"Phase 2: Projekt-Setup ✅","slug":"phase-2-projekt-setup-✅","link":"#phase-2-projekt-setup-✅","children":[]},{"level":3,"title":"Phase 3: Webapp-Integration (Validierung)","slug":"phase-3-webapp-integration-validierung","link":"#phase-3-webapp-integration-validierung","children":[]},{"level":3,"title":"Phase 4: Komponenten-Migration","slug":"phase-4-komponenten-migration","link":"#phase-4-komponenten-migration","children":[]},{"level":3,"title":"Phase 5: Finalisierung","slug":"phase-5-finalisierung","link":"#phase-5-finalisierung","children":[]}]},{"level":2,"title":"1. Projektziel & Vision","slug":"_1-projektziel-vision","link":"#_1-projektziel-vision","children":[]},{"level":2,"title":"2. Tech-Stack","slug":"_2-tech-stack","link":"#_2-tech-stack","children":[{"level":3,"title":"Konventionen","slug":"konventionen","link":"#konventionen","children":[]}]},{"level":2,"title":"3. Build & Distribution","slug":"_3-build-distribution","link":"#_3-build-distribution","children":[{"level":3,"title":"Dual-Build Strategie","slug":"dual-build-strategie","link":"#dual-build-strategie","children":[]},{"level":3,"title":"Nutzung MIT Tailwind","slug":"nutzung-mit-tailwind","link":"#nutzung-mit-tailwind","children":[]},{"level":3,"title":"Nutzung OHNE Tailwind","slug":"nutzung-ohne-tailwind","link":"#nutzung-ohne-tailwind","children":[]},{"level":3,"title":"Branding (funktioniert für beide)","slug":"branding-funktioniert-fur-beide","link":"#branding-funktioniert-fur-beide","children":[]},{"level":3,"title":"Webapp-Integration (Entwicklung)","slug":"webapp-integration-entwicklung","link":"#webapp-integration-entwicklung","children":[]},{"level":3,"title":"Webapp-Aufgaben (TODO für Ocelot-Webapp)","slug":"webapp-aufgaben-todo-fur-ocelot-webapp","link":"#webapp-aufgaben-todo-fur-ocelot-webapp","children":[]}]},{"level":2,"title":"4. Icon-Architektur","slug":"_4-icon-architektur","link":"#_4-icon-architektur","children":[{"level":3,"title":"Entscheidung: Hybrid-Ansatz","slug":"entscheidung-hybrid-ansatz","link":"#entscheidung-hybrid-ansatz","children":[]},{"level":3,"title":"Begründung","slug":"begrundung","link":"#begrundung","children":[]},{"level":3,"title":"System-Icons (in Library enthalten) ✅","slug":"system-icons-in-library-enthalten-✅","link":"#system-icons-in-library-enthalten-✅","children":[]},{"level":3,"title":"API-Design (implementiert)","slug":"api-design-implementiert","link":"#api-design-implementiert","children":[]},{"level":3,"title":"SVG-Loading (vite-svg-icon Plugin)","slug":"svg-loading-vite-svg-icon-plugin","link":"#svg-loading-vite-svg-icon-plugin","children":[]},{"level":3,"title":"Ocelot-Icons (separates Entry-Point)","slug":"ocelot-icons-separates-entry-point","link":"#ocelot-icons-separates-entry-point","children":[]},{"level":3,"title":"Aktuelle Icon-Statistik","slug":"aktuelle-icon-statistik","link":"#aktuelle-icon-statistik","children":[]}]},{"level":2,"title":"5. Design-Token & Branding","slug":"_5-design-token-branding","link":"#_5-design-token-branding","children":[{"level":3,"title":"3-Stufen Token-System","slug":"_3-stufen-token-system","link":"#_3-stufen-token-system","children":[]},{"level":3,"title":"Branding-Flexibilität","slug":"branding-flexibilitat","link":"#branding-flexibilitat","children":[]},{"level":3,"title":"Kompatibilität mit bestehendem System","slug":"kompatibilitat-mit-bestehendem-system","link":"#kompatibilitat-mit-bestehendem-system","children":[]},{"level":3,"title":"CVA + Tailwind + CSS-Variablen","slug":"cva-tailwind-css-variablen","link":"#cva-tailwind-css-variablen","children":[]}]},{"level":2,"title":"6. CI/CD & Release","slug":"_6-ci-cd-release","link":"#_6-ci-cd-release","children":[{"level":3,"title":"Release-Workflow (release-please)","slug":"release-workflow-release-please","link":"#release-workflow-release-please","children":[]},{"level":3,"title":"GitHub Workflows","slug":"github-workflows","link":"#github-workflows","children":[]},{"level":3,"title":"Qualitätssicherung bei PRs","slug":"qualitatssicherung-bei-prs","link":"#qualitatssicherung-bei-prs","children":[]},{"level":3,"title":"Automatische Deployments","slug":"automatische-deployments","link":"#automatische-deployments","children":[]},{"level":3,"title":"GitHub Workflows (vollständige Liste)","slug":"github-workflows-vollstandige-liste","link":"#github-workflows-vollstandige-liste","children":[]},{"level":3,"title":"Erweiterte Qualitätssicherung","slug":"erweiterte-qualitatssicherung","link":"#erweiterte-qualitatssicherung","children":[]},{"level":3,"title":"Migrations-Absicherung","slug":"migrations-absicherung","link":"#migrations-absicherung","children":[]}]},{"level":2,"title":"7. Dokumentation & DX","slug":"_7-dokumentation-dx","link":"#_7-dokumentation-dx","children":[{"level":3,"title":"Storybook als Komponenten-Dokumentation","slug":"storybook-als-komponenten-dokumentation","link":"#storybook-als-komponenten-dokumentation","children":[]}]},{"level":2,"title":"8. Migrationsstrategie","slug":"_8-migrationsstrategie","link":"#_8-migrationsstrategie","children":[{"level":3,"title":"Grundprinzipien","slug":"grundprinzipien","link":"#grundprinzipien","children":[]},{"level":3,"title":"Ablauf pro Komponente","slug":"ablauf-pro-komponente","link":"#ablauf-pro-komponente","children":[]},{"level":3,"title":"Komponenten-Protokoll","slug":"komponenten-protokoll","link":"#komponenten-protokoll","children":[]},{"level":3,"title":"Qualitätsanforderungen pro Komponente","slug":"qualitatsanforderungen-pro-komponente","link":"#qualitatsanforderungen-pro-komponente","children":[]},{"level":3,"title":"Konsolidierungsziele","slug":"konsolidierungsziele","link":"#konsolidierungsziele","children":[]}]},{"level":2,"title":"9. Dokumentationsstrategie","slug":"_9-dokumentationsstrategie","link":"#_9-dokumentationsstrategie","children":[]},{"level":2,"title":"10. Kompatibilitätstests","slug":"_10-kompatibilitatstests","link":"#_10-kompatibilitatstests","children":[]},{"level":2,"title":"11. Entscheidungen","slug":"_11-entscheidungen","link":"#_11-entscheidungen","children":[{"level":3,"title":"Vision & Ziele","slug":"vision-ziele","link":"#vision-ziele","children":[]},{"level":3,"title":"Tech-Stack","slug":"tech-stack","link":"#tech-stack","children":[]},{"level":3,"title":"Build & Distribution","slug":"build-distribution","link":"#build-distribution","children":[]},{"level":3,"title":"CI/CD & Release","slug":"ci-cd-release","link":"#ci-cd-release","children":[]},{"level":3,"title":"Testing & Qualität","slug":"testing-qualitat","link":"#testing-qualitat","children":[]},{"level":3,"title":"Design-System & Branding","slug":"design-system-branding","link":"#design-system-branding","children":[]},{"level":3,"title":"Komponenten-API & Konventionen","slug":"komponenten-api-konventionen","link":"#komponenten-api-konventionen","children":[]},{"level":3,"title":"Dokumentation","slug":"dokumentation","link":"#dokumentation","children":[]},{"level":3,"title":"Migration & Prozess","slug":"migration-prozess","link":"#migration-prozess","children":[]}]},{"level":2,"title":"12. Arbeitsprotokoll","slug":"_12-arbeitsprotokoll","link":"#_12-arbeitsprotokoll","children":[]},{"level":2,"title":"13. Komponenten-Katalog","slug":"_13-komponenten-katalog","link":"#_13-komponenten-katalog","children":[{"level":3,"title":"Zusammenfassung (aus KATALOG.md)","slug":"zusammenfassung-aus-katalog-md","link":"#zusammenfassung-aus-katalog-md","children":[]}]},{"level":2,"title":"14. Ressourcen & Links","slug":"_14-ressourcen-links","link":"#_14-ressourcen-links","children":[]},{"level":2,"title":"15. Dokumentationsstrategie (Details)","slug":"_15-dokumentationsstrategie-details","link":"#_15-dokumentationsstrategie-details","children":[{"level":3,"title":"Übersicht","slug":"ubersicht","link":"#ubersicht","children":[]},{"level":3,"title":"README.md Struktur","slug":"readme-md-struktur","link":"#readme-md-struktur","children":[]},{"level":3,"title":"Generierung mit vue-component-meta","slug":"generierung-mit-vue-component-meta","link":"#generierung-mit-vue-component-meta","children":[]},{"level":3,"title":"CI-Workflow: docs-check","slug":"ci-workflow-docs-check","link":"#ci-workflow-docs-check","children":[]},{"level":3,"title":"ESLint-Regeln für Dokumentation","slug":"eslint-regeln-fur-dokumentation","link":"#eslint-regeln-fur-dokumentation","children":[]},{"level":3,"title":"Dokumentations-Phasen","slug":"dokumentations-phasen","link":"#dokumentations-phasen","children":[]},{"level":3,"title":"Nach der Migration: Datei-Transformation","slug":"nach-der-migration-datei-transformation","link":"#nach-der-migration-datei-transformation","children":[]}]},{"level":2,"title":"16. Library vs. Webapp","slug":"_16-library-vs-webapp","link":"#_16-library-vs-webapp","children":[{"level":3,"title":"Grundprinzip","slug":"grundprinzip","link":"#grundprinzip","children":[]},{"level":3,"title":"Entscheidungs-Checkliste","slug":"entscheidungs-checkliste","link":"#entscheidungs-checkliste","children":[]},{"level":3,"title":"Entscheidungsbaum","slug":"entscheidungsbaum","link":"#entscheidungsbaum","children":[]},{"level":3,"title":"Quantitative Regel","slug":"quantitative-regel","link":"#quantitative-regel","children":[]},{"level":3,"title":"Konkrete Beispiele","slug":"konkrete-beispiele","link":"#konkrete-beispiele","children":[]},{"level":3,"title":"Composition Pattern für Grenzfälle","slug":"composition-pattern-fur-grenzfalle","link":"#composition-pattern-fur-grenzfalle","children":[]},{"level":3,"title":"Checkliste bei neuer Komponente","slug":"checkliste-bei-neuer-komponente","link":"#checkliste-bei-neuer-komponente","children":[]}]},{"level":2,"title":"16a. Webapp ↔ Maintenance Code-Sharing","slug":"_16a-webapp-↔-maintenance-code-sharing","link":"#_16a-webapp-↔-maintenance-code-sharing","children":[{"level":3,"title":"Problemstellung","slug":"problemstellung","link":"#problemstellung","children":[]},{"level":3,"title":"Analysierte Optionen","slug":"analysierte-optionen","link":"#analysierte-optionen","children":[]},{"level":3,"title":"Empfehlung: Option C (Webapp als Source of Truth)","slug":"empfehlung-option-c-webapp-als-source-of-truth","link":"#empfehlung-option-c-webapp-als-source-of-truth","children":[]},{"level":3,"title":"Umsetzung","slug":"umsetzung","link":"#umsetzung","children":[]},{"level":3,"title":"Kriterien für Entwickler","slug":"kriterien-fur-entwickler","link":"#kriterien-fur-entwickler","children":[]},{"level":3,"title":"Vorteile","slug":"vorteile","link":"#vorteile","children":[]},{"level":3,"title":"Spätere Evolution (optional)","slug":"spatere-evolution-optional","link":"#spatere-evolution-optional","children":[]},{"level":3,"title":"Entscheidung","slug":"entscheidung","link":"#entscheidung","children":[]}]},{"level":2,"title":"16b. Daten-Entkopplung (ViewModel/Mapper Pattern)","slug":"_16b-daten-entkopplung-viewmodel-mapper-pattern","link":"#_16b-daten-entkopplung-viewmodel-mapper-pattern","children":[{"level":3,"title":"Problemstellung","slug":"problemstellung-1","link":"#problemstellung-1","children":[]},{"level":3,"title":"Lösung: ViewModel + Mapper Pattern","slug":"losung-viewmodel-mapper-pattern","link":"#losung-viewmodel-mapper-pattern","children":[]},{"level":3,"title":"Implementierung","slug":"implementierung","link":"#implementierung","children":[]},{"level":3,"title":"Ordnerstruktur","slug":"ordnerstruktur","link":"#ordnerstruktur","children":[]},{"level":3,"title":"Vorteile","slug":"vorteile-1","link":"#vorteile-1","children":[]},{"level":3,"title":"Regeln","slug":"regeln","link":"#regeln","children":[]},{"level":3,"title":"Entscheidung","slug":"entscheidung-1","link":"#entscheidung-1","children":[]}]},{"level":2,"title":"17. Externe Abhängigkeiten","slug":"_17-externe-abhangigkeiten","link":"#_17-externe-abhangigkeiten","children":[{"level":3,"title":"Übersicht","slug":"ubersicht-1","link":"#ubersicht-1","children":[]},{"level":3,"title":"eslint-config-it4c","slug":"eslint-config-it4c","link":"#eslint-config-it4c","children":[]}]},{"level":2,"title":"18. Kompatibilitätstests (Details)","slug":"_18-kompatibilitatstests-details","link":"#_18-kompatibilitatstests-details","children":[{"level":3,"title":"Testmatrix","slug":"testmatrix","link":"#testmatrix","children":[]},{"level":3,"title":"Werkzeuge & Strategien","slug":"werkzeuge-strategien","link":"#werkzeuge-strategien","children":[]},{"level":3,"title":"CI Workflow: Compatibility Matrix","slug":"ci-workflow-compatibility-matrix","link":"#ci-workflow-compatibility-matrix","children":[]},{"level":3,"title":"Werkzeug-Übersicht","slug":"werkzeug-ubersicht","link":"#werkzeug-ubersicht","children":[]},{"level":3,"title":"Checkliste für neue Komponenten","slug":"checkliste-fur-neue-komponenten","link":"#checkliste-fur-neue-komponenten","children":[]}]},{"level":2,"title":"19. Komplexitätsanalyse","slug":"_19-komplexitatsanalyse","link":"#_19-komplexitatsanalyse","children":[{"level":3,"title":"Umfang nach Phasen","slug":"umfang-nach-phasen","link":"#umfang-nach-phasen","children":[]},{"level":3,"title":"Bekannte Risikofaktoren","slug":"bekannte-risikofaktoren","link":"#bekannte-risikofaktoren","children":[]},{"level":3,"title":"Parallelisierbarkeit","slug":"parallelisierbarkeit","link":"#parallelisierbarkeit","children":[]},{"level":3,"title":"Aufwandstreiber pro Komponente (Phase 4)","slug":"aufwandstreiber-pro-komponente-phase-4","link":"#aufwandstreiber-pro-komponente-phase-4","children":[]}]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":52.82,"words":15845},"filePathRelative":"packages/ui/PROJEKT.md","localizedDate":"March 1, 2026","excerpt":"\\n
\\n

Dieses Dokument dient als zentrale Planungs- und Statusübersicht für das UI-Library Subprojekt.\\nEs ermöglicht das Pausieren und Wiederaufnehmen der Arbeit zu jedem Zeitpunkt.

\\n
\\n
\\n

Inhaltsverzeichnis

\\n

Schnellzugriff (Status)

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AbschnittBeschreibung
FortschrittVisuelle Fortschrittsanzeige
Aktueller StandWas zuletzt erledigt wurde
MeilensteinePhasen 0-5 mit Checklisten
"}');export{m as comp,b as data}; diff --git a/assets/STATUS.html-BXjDgreh.js b/assets/STATUS.html-BXjDgreh.js new file mode 100644 index 000000000..e43ca18b1 --- /dev/null +++ b/assets/STATUS.html-BXjDgreh.js @@ -0,0 +1,50 @@ +import{_ as i}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as t,a as e,o as a}from"./app-C6w_Pklu.js";const n={};function l(r,s){return a(),t("div",null,s[0]||(s[0]=[e(`

OsButton Status

Status-Tracking der OsButton-Komponente


Übersicht

AspektStatus
ImplementierungBasis implementiert
CVA-IntegrationVollständig
Tests9 Tests vorhanden
StorybookAusstehend
A11yTeilweise

Implementierte Features

Props

PropTypDefaultStatusNotizen
variant'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info' | 'ghost' | 'outline''primary'Implementiert8 Varianten via CVA
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Implementiert5 Größen via CVA
fullWidthbooleanfalseImplementiert
type'button' | 'submit' | 'reset''button'Implementiert
disabledbooleanfalseImplementiert
classstring''ImplementiertVia cn() gemerged

Slots

SlotStatusNotizen
defaultImplementiertButton-Content

Events

EventStatusNotizen
Native EventsImplementiertclick, focus, etc. werden durchgereicht

Fehlende Features (aus KATALOG.md)

Hohe Priorität

FeatureBeschreibungAufwand
iconIcon-Name/Komponente einbindenMittel - erfordert OsIcon
iconPosition'left' | 'right'Klein - nach Icon-Support
loadingLadezustand mit SpinnerMittel - erfordert OsSpinner

Mittlere Priorität

FeatureBeschreibungAufwand
toVue Router Link-SupportMittel - erfordert router-link/NuxtLink
hrefExterner Link-SupportKlein - <a> statt <button>
circleRunder ButtonKlein - CVA-Variant hinzufügen

Niedrige Priorität

FeatureBeschreibungAufwand
filled vs ghostExplizite UnterscheidungDiskussion nötig - aktuell via variant

Nicht geplant

FeatureBegründung
bulletZu spezifisch, kann mit circle + custom size erreicht werden
hover propCSS :hover reicht
padding propSollte über size geregelt werden

Vergleich: Aktuell vs. Zielzustand

KATALOG.md Vorschlag (OsButtonProps)

interface OsButtonProps {
+  // Variante
+  variant?: 'default' | 'primary' | 'secondary' | 'danger'
+  filled?: boolean
+  ghost?: boolean
+
+  // Größe & Form
+  size?: 'tiny' | 'small' | 'base' | 'large'
+  circle?: boolean
+  fullWidth?: boolean
+
+  // Icon
+  icon?: string
+  iconPosition?: 'left' | 'right'
+
+  // Zustände
+  loading?: boolean
+  disabled?: boolean
+
+  // Link-Support
+  to?: string | RouteLocationRaw
+  href?: string
+
+  // Button-Typ
+  type?: 'button' | 'submit'
+}

Aktuelle Implementierung

interface OsButtonProps {
+  variant?: 'primary' | 'secondary' | 'danger' | 'warning' | 'success' | 'info' | 'ghost' | 'outline'
+  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
+  fullWidth?: boolean
+  type?: 'button' \\| 'submit' \\| 'reset'
+  disabled?: boolean
+  class?: string
+}

Unterschiede

AspektKATALOG.mdImplementiertKommentar
Varianten4 + filled/ghost Modifikatoren8 eigenständigeBesser: Mehr Varianten ohne Modifikatoren
Sizestiny, small, base, largexs, sm, md, lg, xlBesser: 5 statt 4, Standard-Naming
Icon-Supporticon, iconPosition-Fehlt: erfordert OsIcon
Loadingloading-Fehlt: erfordert OsSpinner
Link-Supportto, href-Fehlt: Router-Integration
Circlecircle-Fehlt: einfach hinzuzufügen

Test-Coverage

Datei: OsButton.spec.ts

TestBeschreibung
renders slot contentSlot-Inhalt wird gerendert
applies default variant classesPrimary-Variante als Default
applies size variant classesSize-Classes korrekt
applies variant classesVarianten-Classes korrekt
applies fullWidth classw-full wird gesetzt
merges custom classesCustom Classes werden via cn() gemerged
sets disabled attributedisabled-Attribut wird gesetzt
sets button typetype-Attribut wird gesetzt
emits click eventClick-Event wird emittiert

Fehlende Tests


Architektur

Datei-Struktur

src/components/OsButton/
+├── OsButton.vue          # Hauptkomponente
+├── OsButton.spec.ts      # Tests
+├── button.variants.ts    # CVA-Varianten-Definition
+├── index.ts              # Exports
+└── STATUS.md             # Diese Datei

CVA-Pattern

Die Komponente nutzt das CVA-Pattern (Class Variance Authority):

  1. button.variants.ts - Definiert alle Varianten als Type-Safe Funktion
  2. OsButton.vue - Nutzt buttonVariants() + cn() für finale Klassen
  3. Export - Varianten-Funktion + Typen werden exportiert für Composability

CSS-Variablen

Die Komponente nutzt CSS Custom Properties für Theming:

--color-primary
+--color-primary-contrast
+--color-primary-hover
+--color-secondary (etc.)
+--color-danger (etc.)
+--color-warning (etc.)
+--color-success (etc.)
+--color-info (etc.)

Nächste Schritte

Phase 1: Icon-Support (erfordert OsIcon)

  1. OsIcon-Komponente erstellen
  2. icon Prop hinzufügen (string für Icon-Name oder Komponente)
  3. iconPosition Prop hinzufügen ('left' | 'right')
  4. Layout für Icon + Text anpassen

Phase 2: Loading-State (erfordert OsSpinner)

  1. OsSpinner-Komponente erstellen
  2. loading Prop hinzufügen
  3. Bei loading: Spinner anzeigen, Button disabled
  1. to Prop für Vue Router Links
  2. href Prop für externe Links
  3. Dynamisches Element: <button> | <router-link> | <a>

Phase 4: Circle-Variant

  1. circle Prop hinzufügen
  2. CVA-Variant für runden Button

Abhängigkeiten

OsButton
+├── Benötigt: cn() utility  Vorhanden
+├── Benötigt: CVA           Vorhanden
+├── Für Icon: OsIcon        Ausstehend (Tier 1)
+├── Für Loading: OsSpinner  Ausstehend (Tier 1)
+└── Für Link: Vue Router    Optional (nur für SPA-Links)

Changelog

DatumÄnderung
2026-02-07Status-Datei erstellt
2026-02-07CVA-Integration abgeschlossen
2026-02-078 Varianten, 5 Sizes implementiert
2026-02-079 Tests vorhanden
`,63)]))}const p=i(n,[["render",l],["__file","STATUS.html.vue"]]),o=JSON.parse('{"path":"/packages/ui/src/components/OsButton/STATUS.html","title":"OsButton Status","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Übersicht","slug":"ubersicht","link":"#ubersicht","children":[]},{"level":2,"title":"Implementierte Features","slug":"implementierte-features","link":"#implementierte-features","children":[{"level":3,"title":"Props","slug":"props","link":"#props","children":[]},{"level":3,"title":"Slots","slug":"slots","link":"#slots","children":[]},{"level":3,"title":"Events","slug":"events","link":"#events","children":[]}]},{"level":2,"title":"Fehlende Features (aus KATALOG.md)","slug":"fehlende-features-aus-katalog-md","link":"#fehlende-features-aus-katalog-md","children":[{"level":3,"title":"Hohe Priorität","slug":"hohe-prioritat","link":"#hohe-prioritat","children":[]},{"level":3,"title":"Mittlere Priorität","slug":"mittlere-prioritat","link":"#mittlere-prioritat","children":[]},{"level":3,"title":"Niedrige Priorität","slug":"niedrige-prioritat","link":"#niedrige-prioritat","children":[]},{"level":3,"title":"Nicht geplant","slug":"nicht-geplant","link":"#nicht-geplant","children":[]}]},{"level":2,"title":"Vergleich: Aktuell vs. Zielzustand","slug":"vergleich-aktuell-vs-zielzustand","link":"#vergleich-aktuell-vs-zielzustand","children":[{"level":3,"title":"KATALOG.md Vorschlag (OsButtonProps)","slug":"katalog-md-vorschlag-osbuttonprops","link":"#katalog-md-vorschlag-osbuttonprops","children":[]},{"level":3,"title":"Aktuelle Implementierung","slug":"aktuelle-implementierung","link":"#aktuelle-implementierung","children":[]},{"level":3,"title":"Unterschiede","slug":"unterschiede","link":"#unterschiede","children":[]}]},{"level":2,"title":"Test-Coverage","slug":"test-coverage","link":"#test-coverage","children":[{"level":3,"title":"Fehlende Tests","slug":"fehlende-tests","link":"#fehlende-tests","children":[]}]},{"level":2,"title":"Architektur","slug":"architektur","link":"#architektur","children":[{"level":3,"title":"Datei-Struktur","slug":"datei-struktur","link":"#datei-struktur","children":[]},{"level":3,"title":"CVA-Pattern","slug":"cva-pattern","link":"#cva-pattern","children":[]},{"level":3,"title":"CSS-Variablen","slug":"css-variablen","link":"#css-variablen","children":[]}]},{"level":2,"title":"Nächste Schritte","slug":"nachste-schritte","link":"#nachste-schritte","children":[{"level":3,"title":"Phase 1: Icon-Support (erfordert OsIcon)","slug":"phase-1-icon-support-erfordert-osicon","link":"#phase-1-icon-support-erfordert-osicon","children":[]},{"level":3,"title":"Phase 2: Loading-State (erfordert OsSpinner)","slug":"phase-2-loading-state-erfordert-osspinner","link":"#phase-2-loading-state-erfordert-osspinner","children":[]},{"level":3,"title":"Phase 3: Link-Support","slug":"phase-3-link-support","link":"#phase-3-link-support","children":[]},{"level":3,"title":"Phase 4: Circle-Variant","slug":"phase-4-circle-variant","link":"#phase-4-circle-variant","children":[]}]},{"level":2,"title":"Abhängigkeiten","slug":"abhangigkeiten","link":"#abhangigkeiten","children":[]},{"level":2,"title":"Changelog","slug":"changelog","link":"#changelog","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":2.25,"words":676},"filePathRelative":"packages/ui/src/components/OsButton/STATUS.md","localizedDate":"March 1, 2026","excerpt":"\\n
\\n

Status-Tracking der OsButton-Komponente

\\n
\\n
\\n

Übersicht

\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
AspektStatus
ImplementierungBasis implementiert
CVA-IntegrationVollständig
Tests9 Tests vorhanden
StorybookAusstehend
A11yTeilweise
"}');export{p as comp,o as data}; diff --git a/assets/SUMMARY.html-DlsPW9yB.js b/assets/SUMMARY.html-DlsPW9yB.js new file mode 100644 index 000000000..be4bb0a70 --- /dev/null +++ b/assets/SUMMARY.html-DlsPW9yB.js @@ -0,0 +1 @@ +import{_ as o}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as r,b as t,e as n,f as a,r as u,o as s,d as i}from"./app-C6w_Pklu.js";const d={};function p(m,l){const e=u("RouteLink");return s(),r("div",null,[l[20]||(l[20]=t("h1",{id:"table-of-contents",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#table-of-contents"},[t("span",null,"Table of contents")])],-1)),t("ul",null,[t("li",null,[n(e,{to:"/"},{default:a(()=>l[0]||(l[0]=[i("Introduction")])),_:1})]),t("li",null,[n(e,{to:"/neo4j/"},{default:a(()=>l[1]||(l[1]=[i("Neo4J")])),_:1})]),t("li",null,[n(e,{to:"/backend/"},{default:a(()=>l[2]||(l[2]=[i("Backend")])),_:1}),t("ul",null,[t("li",null,[n(e,{to:"/backend/graphql.html"},{default:a(()=>l[3]||(l[3]=[i("GraphQL")])),_:1})]),t("li",null,[n(e,{to:"/backend/neo4j-graphql-js.html"},{default:a(()=>l[4]||(l[4]=[i("neo4j-graphql-js")])),_:1})])])]),t("li",null,[n(e,{to:"/webapp/"},{default:a(()=>l[5]||(l[5]=[i("Webapp (Frontend)")])),_:1}),t("ul",null,[t("li",null,[n(e,{to:"/webapp/components.html"},{default:a(()=>l[6]||(l[6]=[i("Components")])),_:1})]),t("li",null,[n(e,{to:"/webapp/html.html"},{default:a(()=>l[7]||(l[7]=[i("HTML")])),_:1})]),t("li",null,[n(e,{to:"/webapp/scss.html"},{default:a(()=>l[8]||(l[8]=[i("SCSS")])),_:1})]),t("li",null,[n(e,{to:"/webapp/vue.html"},{default:a(()=>l[9]||(l[9]=[i("Vue")])),_:1})])])]),t("li",null,[n(e,{to:"/testing.html"},{default:a(()=>l[10]||(l[10]=[i("Testing Guide")])),_:1}),t("ul",null,[t("li",null,[n(e,{to:"/cypress/"},{default:a(()=>l[11]||(l[11]=[i("End-to-end Tests")])),_:1})]),t("li",null,[n(e,{to:"/webapp/testing.html"},{default:a(()=>l[12]||(l[12]=[i("Webapp (Frontend) Tests")])),_:1})]),t("li",null,[n(e,{to:"/backend/testing.html"},{default:a(()=>l[13]||(l[13]=[i("Backend Tests")])),_:1})])])]),t("li",null,[n(e,{to:"/deployment/"},{default:a(()=>l[14]||(l[14]=[i("Deployment")])),_:1})]),t("li",null,[n(e,{to:"/CONTRIBUTING.html"},{default:a(()=>l[15]||(l[15]=[i("Contributing")])),_:1})]),t("li",null,[n(e,{to:"/cypress/features.html"},{default:a(()=>l[16]||(l[16]=[i("Feature Specification")])),_:1})]),t("li",null,[n(e,{to:"/CODE_OF_CONDUCT.html"},{default:a(()=>l[17]||(l[17]=[i("Code of Conduct")])),_:1})]),t("li",null,[n(e,{to:"/documentation.html"},{default:a(()=>l[18]||(l[18]=[i("Documentation")])),_:1})]),t("li",null,[n(e,{to:"/LICENSE.html"},{default:a(()=>l[19]||(l[19]=[i("License")])),_:1})])])])}const g=o(d,[["render",p],["__file","SUMMARY.html.vue"]]),k=JSON.parse('{"path":"/SUMMARY.html","title":"Table of contents","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.19,"words":58},"filePathRelative":"SUMMARY.md","localizedDate":"March 1, 2026","excerpt":"\\n"}');export{g as comp,k as data}; diff --git a/assets/SearchResult-CRxy2nzi.js b/assets/SearchResult-CRxy2nzi.js new file mode 100644 index 000000000..c1f0c8e10 --- /dev/null +++ b/assets/SearchResult-CRxy2nzi.js @@ -0,0 +1 @@ +import{u as B,g as se,h as te,i as M,j as le,P as ae,t as oe,k as ne,l as A,m as T,n as ue,w as _,p as t,q as ie,R as N,v as re,x as ce,y as ye,C as me,z as pe,A as de,B as ge,D as he,E as ve,F as be,G as ke,H as G,I as U,J as we,K as f,L as Ce}from"./app-C6w_Pklu.js";const He=["/CHANGELOG.html","/CODE_OF_CONDUCT.html","/CONTRIBUTING.html","/LICENSE.html","/","/SUMMARY.html","/documentation.html","/testing.html","/backend/","/backend/graphql.html","/backend/neo4j-graphql-js.html","/backend/testing.html","/cypress/","/cypress/features.html","/deployment/TODO-next-update.html","/deployment/deployment-values.html","/neo4j/","/styleguide/","/webapp/","/webapp/components.html","/webapp/html.html","/webapp/scss.html","/webapp/testing.html","/webapp/vue.html","/deployment/styleguide/","/packages/ui/CONTRIBUTING.html","/packages/ui/KATALOG.html","/packages/ui/PROJEKT.html","/packages/ui/","/webapp/maintenance/","/backend/src/graphql/GraphQL-Playground.html","/webapp/components/Category/","/webapp/components/DateTime/","/webapp/components/Logo/demo.html","/styleguide/src/styleguide/docs/DataDisplay.html","/styleguide/src/styleguide/docs/DesignTokens.html","/styleguide/src/styleguide/docs/Introduction.html","/styleguide/src/styleguide/docs/Layout.html","/styleguide/src/styleguide/docs/Navigation.html","/styleguide/src/styleguide/docs/Typography.html","/packages/ui/src/components/OsButton/STATUS.html","/webapp/static/img/mapbox/marker-icons/","/styleguide/src/system/components/data-display/Avatar/demo.html","/styleguide/src/system/components/data-display/CopyField/demo.html","/styleguide/src/system/components/data-display/List/demo.html","/styleguide/src/system/components/data-display/Number/demo.html","/styleguide/src/system/components/data-display/Table/demo.html","/styleguide/src/system/components/data-input/Form/demo.html","/styleguide/src/system/components/data-input/Input/demo.html","/styleguide/src/system/components/data-input/Radio/demo.html","/styleguide/src/system/components/data-input/Select/demo.html","/styleguide/src/system/components/layout/Card/demo.html","/styleguide/src/system/components/layout/Container/demo.html","/styleguide/src/system/components/layout/Flex/demo.html","/styleguide/src/system/components/layout/Grid/demo.html","/styleguide/src/system/components/layout/Modal/demo.html","/styleguide/src/system/components/layout/Page/demo.html","/styleguide/src/system/components/layout/PageTitle/demo.html","/styleguide/src/system/components/layout/Placeholder/demo.html","/styleguide/src/system/components/layout/Section/demo.html","/styleguide/src/system/components/layout/Space/demo.html","/styleguide/src/system/components/layout/Spinner/demo.html","/styleguide/src/system/components/navigation/Button/demo.html","/styleguide/src/system/components/navigation/Menu/demo.html","/styleguide/src/system/components/typography/Chip/demo.html","/styleguide/src/system/components/typography/Code/demo.html","/styleguide/src/system/components/typography/Heading/demo.html","/styleguide/src/system/components/typography/Icon/demo.html","/styleguide/src/system/components/typography/Logo/demo.html","/styleguide/src/system/components/typography/Tag/demo.html","/styleguide/src/system/components/typography/Text/demo.html","/404.html","/deployment/","/packages/","/backend/src/graphql/","/backend/src/","/webapp/components/","/webapp/components/Logo/","/styleguide/src/styleguide/docs/","/styleguide/src/styleguide/","/styleguide/src/","/packages/ui/src/components/OsButton/","/packages/ui/src/components/","/packages/ui/src/","/webapp/static/img/mapbox/","/webapp/static/img/","/webapp/static/","/styleguide/src/system/components/data-display/Avatar/","/styleguide/src/system/components/data-display/","/styleguide/src/system/components/","/styleguide/src/system/","/styleguide/src/system/components/data-display/CopyField/","/styleguide/src/system/components/data-display/List/","/styleguide/src/system/components/data-display/Number/","/styleguide/src/system/components/data-display/Table/","/styleguide/src/system/components/data-input/Form/","/styleguide/src/system/components/data-input/","/styleguide/src/system/components/data-input/Input/","/styleguide/src/system/components/data-input/Radio/","/styleguide/src/system/components/data-input/Select/","/styleguide/src/system/components/layout/Card/","/styleguide/src/system/components/layout/","/styleguide/src/system/components/layout/Container/","/styleguide/src/system/components/layout/Flex/","/styleguide/src/system/components/layout/Grid/","/styleguide/src/system/components/layout/Modal/","/styleguide/src/system/components/layout/Page/","/styleguide/src/system/components/layout/PageTitle/","/styleguide/src/system/components/layout/Placeholder/","/styleguide/src/system/components/layout/Section/","/styleguide/src/system/components/layout/Space/","/styleguide/src/system/components/layout/Spinner/","/styleguide/src/system/components/navigation/Button/","/styleguide/src/system/components/navigation/","/styleguide/src/system/components/navigation/Menu/","/styleguide/src/system/components/typography/Chip/","/styleguide/src/system/components/typography/","/styleguide/src/system/components/typography/Code/","/styleguide/src/system/components/typography/Heading/","/styleguide/src/system/components/typography/Icon/","/styleguide/src/system/components/typography/Logo/","/styleguide/src/system/components/typography/Tag/","/styleguide/src/system/components/typography/Text/"],Re="SEARCH_PRO_QUERY_HISTORY",v=B(Re,[]),Te=()=>{const{queryHistoryCount:l}=f,a=l>0;return{enabled:a,queryHistory:v,addQueryHistory:o=>{a&&(v.value=Array.from(new Set([o,...v.value.slice(0,l-1)])))},removeQueryHistory:o=>{v.value=[...v.value.slice(0,o),...v.value.slice(o+1)]}}},I=l=>He[l.id]+("anchor"in l?`#${l.anchor}`:""),fe="SEARCH_PRO_RESULT_HISTORY",{resultHistoryCount:j}=f,b=B(fe,[]),Se=()=>{const l=j>0;return{enabled:l,resultHistory:b,addResultHistory:a=>{if(l){const o={link:I(a),display:a.display};"header"in a&&(o.header=a.header),b.value=[o,...b.value.slice(0,j-1)]}},removeResultHistory:a=>{b.value=[...b.value.slice(0,a),...b.value.slice(a+1)]}}},xe=l=>{const a=me(),o=M(),S=pe(),u=A(0),C=T(()=>u.value>0),d=de([]);return ge(()=>{const{search:g,terminate:x}=he(),k=we(c=>{const w=c.join(" "),{searchFilter:L=p=>p,splitWord:q,suggestionsFilter:P,...h}=a.value;w?(u.value+=1,g(c.join(" "),o.value,h).then(p=>L(p,w,o.value,S.value)).then(p=>{u.value-=1,d.value=p}).catch(p=>{console.warn(p),u.value-=1,u.value||(d.value=[])})):d.value=[]},f.searchDelay-f.suggestDelay);_([l,o],([c])=>k(c),{immediate:!0}),ve(()=>{x()})}),{isSearching:C,results:d}};var qe=se({name:"SearchResult",props:{queries:{type:Array,required:!0},isFocusing:Boolean},emits:["close","updateQuery"],setup(l,{emit:a}){const o=te(),S=M(),u=le(ae),{enabled:C,addQueryHistory:d,queryHistory:g,removeQueryHistory:x}=Te(),{enabled:k,resultHistory:c,addResultHistory:w,removeResultHistory:L}=Se(),q=C||k,P=oe(l,"queries"),{results:h,isSearching:p}=xe(P),n=ne({isQuery:!0,index:0}),y=A(0),m=A(0),F=T(()=>q&&(g.value.length>0||c.value.length>0)),O=T(()=>h.value.length>0),Q=T(()=>h.value[y.value]||null),$=()=>{const{isQuery:e,index:s}=n;s===0?(n.isQuery=!e,n.index=e?c.value.length-1:g.value.length-1):n.index=s-1},Y=()=>{const{isQuery:e,index:s}=n;s===(e?g.value.length-1:c.value.length-1)?(n.isQuery=!e,n.index=0):n.index=s+1},K=()=>{y.value=y.value>0?y.value-1:h.value.length-1,m.value=Q.value.contents.length-1},J=()=>{y.value=y.value{m.value{m.value>0?m.value-=1:K()},D=e=>e.map(s=>Ce(s)?s:t(s[0],s[1])),W=e=>{if(e.type==="customField"){const s=be[e.index]||"$content",[i,R=""]=ke(s)?s[S.value].split("$content"):s.split("$content");return e.display.map(r=>t("div",D([i,...r,R])))}return e.display.map(s=>t("div",D(s)))},H=()=>{y.value=0,m.value=0,a("updateQuery",""),a("close")},X=()=>C?t("ul",{class:"search-pro-result-list"},t("li",{class:"search-pro-result-list-item"},[t("div",{class:"search-pro-result-title"},u.value.queryHistory),g.value.map((e,s)=>t("div",{class:["search-pro-result-item",{active:n.isQuery&&n.index===s}],onClick:()=>{a("updateQuery",e)}},[t(G,{class:"search-pro-result-type"}),t("div",{class:"search-pro-result-content"},e),t("button",{class:"search-pro-remove-icon",innerHTML:U,onClick:i=>{i.preventDefault(),i.stopPropagation(),x(s)}})]))])):null,Z=()=>k?t("ul",{class:"search-pro-result-list"},t("li",{class:"search-pro-result-list-item"},[t("div",{class:"search-pro-result-title"},u.value.resultHistory),c.value.map((e,s)=>t(N,{to:e.link,class:["search-pro-result-item",{active:!n.isQuery&&n.index===s}],onClick:()=>{H()}},()=>[t(G,{class:"search-pro-result-type"}),t("div",{class:"search-pro-result-content"},[e.header?t("div",{class:"content-header"},e.header):null,t("div",e.display.map(i=>D(i)).flat())]),t("button",{class:"search-pro-remove-icon",innerHTML:U,onClick:i=>{i.preventDefault(),i.stopPropagation(),L(s)}})]))])):null;return ue("keydown",e=>{if(l.isFocusing){if(O.value){if(e.key==="ArrowUp")V();else if(e.key==="ArrowDown")z();else if(e.key==="Enter"){const s=Q.value.contents[m.value];d(l.queries.join(" ")),w(s),o.push(I(s)),H()}}else if(k){if(e.key==="ArrowUp")$();else if(e.key==="ArrowDown")Y();else if(e.key==="Enter"){const{index:s}=n;n.isQuery?(a("updateQuery",g.value[s]),e.preventDefault()):(o.push(c.value[s].link),H())}}}}),_([y,m],()=>{var e;(e=document.querySelector(".search-pro-result-list-item.active .search-pro-result-item.active"))==null||e.scrollIntoView(!1)},{flush:"post"}),()=>t("div",{class:["search-pro-result-wrapper",{empty:l.queries.length?!O.value:!F.value}],id:"search-pro-results"},l.queries.length?p.value?t(ie,{hint:u.value.searching}):O.value?t("ul",{class:"search-pro-result-list"},h.value.map(({title:e,contents:s},i)=>{const R=y.value===i;return t("li",{class:["search-pro-result-list-item",{active:R}]},[t("div",{class:"search-pro-result-title"},e||u.value.defaultTitle),s.map((r,ee)=>{const E=R&&m.value===ee;return t(N,{to:I(r),class:["search-pro-result-item",{active:E,"aria-selected":E}],onClick:()=>{d(l.queries.join(" ")),w(r),H()}},()=>[r.type==="text"?null:t(r.type==="title"?re:r.type==="heading"?ce:ye,{class:"search-pro-result-type"}),t("div",{class:"search-pro-result-content"},[r.type==="text"&&r.header?t("div",{class:"content-header"},r.header):null,t("div",W(r))])])})])})):u.value.emptyResult:q?F.value?[X(),Z()]:u.value.emptyHistory:u.value.emptyResult)}});export{qe as default}; diff --git a/assets/TODO-next-update.html-Dbd1HQYH.js b/assets/TODO-next-update.html-Dbd1HQYH.js new file mode 100644 index 000000000..4696440b4 --- /dev/null +++ b/assets/TODO-next-update.html-Dbd1HQYH.js @@ -0,0 +1,12 @@ +import{_ as r}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as l,a as n,b as i,d as a,e as o,f as t,r as d,o as h}from"./app-C6w_Pklu.js";const c={};function p(k,e){const s=d("RouteLink");return h(),l("div",null,[e[19]||(e[19]=n('

Todo For Next Update

When you introduce a new version and branding and deploy it on your network, you need to consider the following changes and actions:

Version >= 3.2.0 with 'ocelotDockerVersionTag' 3.2.0-XXX

Backend and Kubernetes Config DBMS_DEFAULT_DATABASE

',4)),i("ul",null,[i("li",null,[e[1]||(e[1]=a("We have the new option to configure the default name of the Neo4j database to be used for operations and commands in environment variables (")),e[2]||(e[2]=i("code",null,".env",-1)),e[3]||(e[3]=a(", ")),e[4]||(e[4]=i("code",null,"docker-compose.yml",-1)),e[5]||(e[5]=a(" or ")),e[6]||(e[6]=i("code",null,"values.yaml",-1)),e[7]||(e[7]=a("). For more details see ")),o(s,{to:"/deployment/deployment-values.html"},{default:t(()=>e[0]||(e[0]=[a("deployment-values.md")])),_:1}),e[8]||(e[8]=a(":"))])]),e[20]||(e[20]=n('
DBMS_DEFAULT_DATABASE: "graph.db"

The default value is neo4j if it is not set.

Webapp Config dateTime

  • You can set RELATIVE_DATETIME and ABSOLUT_DATETIME_FORMAT in branding/constants/dateTime.js originally in main code file webapp/constants/dateTime.js to your preferred values.

Version >= 3.1.0 with 'ocelotDockerVersionTag' 3.1.0-555

',5)),i("ul",null,[i("li",null,[e[10]||(e[10]=a("We have the new option to configure DKIM for sent e-mails in environment variables (")),e[11]||(e[11]=i("code",null,".env",-1)),e[12]||(e[12]=a(", ")),e[13]||(e[13]=i("code",null,"docker-compose.yml",-1)),e[14]||(e[14]=a(" or ")),e[15]||(e[15]=i("code",null,"values.yaml",-1)),e[16]||(e[16]=a("), see ")),o(s,{to:"/deployment/deployment-values.html"},{default:t(()=>e[9]||(e[9]=[a("deployment-values.md")])),_:1}),e[17]||(e[17]=a(": ")),e[18]||(e[18]=i("ul",null,[i("li",null,[i("code",null,"SMTP_DKIM_DOMAINNAME=")]),i("li",null,[i("code",null,"SMTP_DKIM_KEYSELECTOR=")]),i("li",null,[i("code",null,"SMTP_DKIM_PRIVATEKEY=")])],-1))])]),e[21]||(e[21]=n(`

Version >= 2.7.0 with 'ocelotDockerVersionTag' 2.7.0-470

  • You have to rename all .js files to .ts in branding/constants

Version >= 2.4.0 with 'ocelotDockerVersionTag' 2.4.0-298

  • You have to set SHOW_CONTENT_FILTER_HEADER_MENU and SHOW_CONTENT_FILTER_MASONRY_GRID in branding/constants/filter.js originally in main code file webapp/constants/filter.js to your preferred values.

Main Code PR – feat(webapp): map #5843

  • Create your own Mapbox account at https://mapbox.com/ for your organization to get your own Mapbox token.
  • You have to add the MAPBOX_TOKEN from the deployment/kubernetes/values.template.yaml to your deployment/kubernetes/values.yaml and set it to your own Mapbox token.

Version >= 2.2.0 with 'ocelotDockerVersionTag' 2.2.0-267

  • You have to add property target to all array elements with value url to your preferred value in branding/constants/headerMenu.js originally in main code file webapp/constants/headerMenu.js.
  • You have to move value of all externalLink to new property externalLink.url and set new property externalLink.target to your preferred value in branding/constants/links.js originally in main code file webapp/constants/links.js.

Main Code PR – feat: 🍰 Make Donation Progress Bar Color Configurable #5593

  • You have to set PROGRESS_BAR_COLOR_TYPE in branding/constants/donation.js originally in main code file webapp/constants/donation.js to your preferred value.

Main Code PR – feat: 🍰 Header Logo Routing Update #5579

  • You have to move value of LOGO_HEADER_CLICK.externalLink to new property LOGO_HEADER_CLICK.externalLink.url and set new property LOGO_HEADER_CLICK.externalLink.target to your preferred value in branding/constants/logos.js originally in main code file webapp/constants/logos.js.

Version >= 2.0.0 with 'ocelotDockerVersionTag' 2.0.0-250

Main Code PR – feat: 🍰 Implement LOGO_HEADER_CLICK As Configuration #5525

  • You have to set LOGO_HEADER_CLICK in branding/constants/logos.js originally in main code file webapp/constants/logos.js to your preferred value.

Main Code Issue – 🌟 [EPIC] Release v2.0.0 – Beta Test → Final #5547

  • You have to set SHOW_GROUP_BUTTON_IN_HEADER in branding/constants/groups.js originally in main code file webapp/constants/groups.js to your preferred value.

Version >= 1.1.0 with 'ocelotDockerVersionTag' 1.1.0-205

Deployment/Rebranding PR – chore: 🍰 Release v1.1.0 - Implement Categories Again #63

  • You have to add the CATEGORIES_ACTIVE from the deployment/kubernetes/values.template.yaml to your deployment/kubernetes/values.yaml and set it to your preferred value.
  • Make sure the correct categories are in your Neo4j database on the server.

Version >= 1.0.9 with 'ocelotDockerVersionTag' 1.0.9-199

Deployment/Rebranding PR – chore: 🍰 Implement PRODUCTION_DB_CLEAN_ALLOW for Staging Production Environments #56

  • Copy PRODUCTION_DB_CLEAN_ALLOW from deployment/kubernetes/values.template.yaml to values.yaml and set it to false for production environments and only for several stage test servers to true.

Deployment/Rebranding PR – chore: [WIP] 🍰 Refine docs, first step #46

Upgrade the cert-manager, but install CRDs of the version 1.0.0-alpha to actually be able to upgrade ocelot. Then uninstall the legacy CRDs and install the correct ones.

# upgrade cert-manager to 1.9.1
+> helm upgrade --set installCRDs=true --version 1.9.1 --namespace cert-manager cert-manager jetstack/cert-manager
+# apply legacy CRDs
+> kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.0-alpha.1/cert-manager.crds.yaml
+# upgrade ocelot
+> helm upgrade ocelot ./
+# delete legacy CRDs
+> kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v1.0.0-alpha.1/cert-manager.crds.yaml
+# apply CRDs for cert-manager 1.9.1
+> kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml

Background: We had to upgrade cert-manager due to an external dependency - therefore we had to update cert-manager apiVersion cert-manager.io/v1alpha2 to cert-manager.io/v1.

The error occurring when not doing this is the following:

Error: UPGRADE FAILED: unable to build kubernetes objects from current release manifest: [resource mapping not found for name: "letsencrypt-production" namespace: "" from "": no matches for kind "ClusterIssuer" in version "cert-manager.io/v1alpha2"
+ensure CRDs are installed first, resource mapping not found for name: "letsencrypt-staging" namespace: "" from "": no matches for kind "ClusterIssuer" in version "cert-manager.io/v1alpha2"
+ensure CRDs are installed first]

Version >= 1.0.8 with 'ocelotDockerVersionTag' 1.0.8-182

  • You have to add the COOKIE_EXPIRE_TIME from the deployment/kubernetes/values.template.yaml to your deployment/kubernetes/values.yaml and set it to your preferred value.
  • Correct locale cookie exploration time in data privacy.

Version 1.0.7 with 'ocelotDockerVersionTag' 1.0.7-171

  • No information.
`,35))])}const m=r(c,[["render",p],["__file","TODO-next-update.html.vue"]]),v=JSON.parse(`{"path":"/deployment/TODO-next-update.html","title":"Todo For Next Update","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Version >= 3.2.0 with 'ocelotDockerVersionTag' 3.2.0-XXX","slug":"version-3-2-0-with-ocelotdockerversiontag-3-2-0-xxx","link":"#version-3-2-0-with-ocelotdockerversiontag-3-2-0-xxx","children":[{"level":3,"title":"Backend and Kubernetes Config DBMS_DEFAULT_DATABASE","slug":"backend-and-kubernetes-config-dbms-default-database","link":"#backend-and-kubernetes-config-dbms-default-database","children":[]},{"level":3,"title":"Webapp Config dateTime","slug":"webapp-config-datetime","link":"#webapp-config-datetime","children":[]}]},{"level":2,"title":"Version >= 3.1.0 with 'ocelotDockerVersionTag' 3.1.0-555","slug":"version-3-1-0-with-ocelotdockerversiontag-3-1-0-555","link":"#version-3-1-0-with-ocelotdockerversiontag-3-1-0-555","children":[]},{"level":2,"title":"Version >= 2.7.0 with 'ocelotDockerVersionTag' 2.7.0-470","slug":"version-2-7-0-with-ocelotdockerversiontag-2-7-0-470","link":"#version-2-7-0-with-ocelotdockerversiontag-2-7-0-470","children":[]},{"level":2,"title":"Version >= 2.4.0 with 'ocelotDockerVersionTag' 2.4.0-298","slug":"version-2-4-0-with-ocelotdockerversiontag-2-4-0-298","link":"#version-2-4-0-with-ocelotdockerversiontag-2-4-0-298","children":[{"level":3,"title":"Main Code PR – feat(webapp): map #5843","slug":"main-code-pr-–-feat-webapp-map-5843","link":"#main-code-pr-–-feat-webapp-map-5843","children":[]}]},{"level":2,"title":"Version >= 2.2.0 with 'ocelotDockerVersionTag' 2.2.0-267","slug":"version-2-2-0-with-ocelotdockerversiontag-2-2-0-267","link":"#version-2-2-0-with-ocelotdockerversiontag-2-2-0-267","children":[{"level":3,"title":"Main Code PR – feat: 🍰 Footer And Header Links Configurable To Have External Link Target #5590","slug":"main-code-pr-–-feat-🍰-footer-and-header-links-configurable-to-have-external-link-target-5590","link":"#main-code-pr-–-feat-🍰-footer-and-header-links-configurable-to-have-external-link-target-5590","children":[]},{"level":3,"title":"Main Code PR – feat: 🍰 Make Donation Progress Bar Color Configurable #5593","slug":"main-code-pr-–-feat-🍰-make-donation-progress-bar-color-configurable-5593","link":"#main-code-pr-–-feat-🍰-make-donation-progress-bar-color-configurable-5593","children":[]},{"level":3,"title":"Main Code PR – feat: 🍰 Header Logo Routing Update #5579","slug":"main-code-pr-–-feat-🍰-header-logo-routing-update-5579","link":"#main-code-pr-–-feat-🍰-header-logo-routing-update-5579","children":[]}]},{"level":2,"title":"Version >= 2.0.0 with 'ocelotDockerVersionTag' 2.0.0-250","slug":"version-2-0-0-with-ocelotdockerversiontag-2-0-0-250","link":"#version-2-0-0-with-ocelotdockerversiontag-2-0-0-250","children":[{"level":3,"title":"Main Code PR – feat: 🍰 Implement LOGO_HEADER_CLICK As Configuration #5525","slug":"main-code-pr-–-feat-🍰-implement-logo-header-click-as-configuration-5525","link":"#main-code-pr-–-feat-🍰-implement-logo-header-click-as-configuration-5525","children":[]},{"level":3,"title":"Main Code Issue – 🌟 [EPIC] Release v2.0.0 – Beta Test → Final #5547","slug":"main-code-issue-–-🌟-epic-release-v2-0-0-–-beta-test-→-final-5547","link":"#main-code-issue-–-🌟-epic-release-v2-0-0-–-beta-test-→-final-5547","children":[]}]},{"level":2,"title":"Version >= 1.1.0 with 'ocelotDockerVersionTag' 1.1.0-205","slug":"version-1-1-0-with-ocelotdockerversiontag-1-1-0-205","link":"#version-1-1-0-with-ocelotdockerversiontag-1-1-0-205","children":[{"level":3,"title":"Deployment/Rebranding PR – chore: 🍰 Release v1.1.0 - Implement Categories Again #63","slug":"deployment-rebranding-pr-–-chore-🍰-release-v1-1-0-implement-categories-again-63","link":"#deployment-rebranding-pr-–-chore-🍰-release-v1-1-0-implement-categories-again-63","children":[]}]},{"level":2,"title":"Version >= 1.0.9 with 'ocelotDockerVersionTag' 1.0.9-199","slug":"version-1-0-9-with-ocelotdockerversiontag-1-0-9-199","link":"#version-1-0-9-with-ocelotdockerversiontag-1-0-9-199","children":[{"level":3,"title":"Deployment/Rebranding PR – chore: 🍰 Implement PRODUCTION_DB_CLEAN_ALLOW for Staging Production Environments #56","slug":"deployment-rebranding-pr-–-chore-🍰-implement-production-db-clean-allow-for-staging-production-environments-56","link":"#deployment-rebranding-pr-–-chore-🍰-implement-production-db-clean-allow-for-staging-production-environments-56","children":[]},{"level":3,"title":"Deployment/Rebranding PR – chore: [WIP] 🍰 Refine docs, first step #46","slug":"deployment-rebranding-pr-–-chore-wip-🍰-refine-docs-first-step-46","link":"#deployment-rebranding-pr-–-chore-wip-🍰-refine-docs-first-step-46","children":[]}]},{"level":2,"title":"Version >= 1.0.8 with 'ocelotDockerVersionTag' 1.0.8-182","slug":"version-1-0-8-with-ocelotdockerversiontag-1-0-8-182","link":"#version-1-0-8-with-ocelotdockerversiontag-1-0-8-182","children":[{"level":3,"title":"PR – feat: 🍰 Configure Cookie Expire Time #43","slug":"pr-–-feat-🍰-configure-cookie-expire-time-43","link":"#pr-–-feat-🍰-configure-cookie-expire-time-43","children":[]}]},{"level":2,"title":"Version 1.0.7 with 'ocelotDockerVersionTag' 1.0.7-171","slug":"version-1-0-7-with-ocelotdockerversiontag-1-0-7-171","link":"#version-1-0-7-with-ocelotdockerversiontag-1-0-7-171","children":[]}],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":2.57,"words":770},"filePathRelative":"deployment/TODO-next-update.md","localizedDate":"March 1, 2026","excerpt":"\\n

When you introduce a new version and branding and deploy it on your network, you need to consider the following changes and actions:

\\n

Version >= 3.2.0 with 'ocelotDockerVersionTag' 3.2.0-XXX

\\n

Backend and Kubernetes Config DBMS_DEFAULT_DATABASE

\\n
    \\n
  • We have the new option to configure the default name of the Neo4j database to be used for operations and commands in environment variables (.env, docker-compose.yml or values.yaml).\\nFor more details see deployment-values.md:
  • \\n
"}`);export{m as comp,v as data}; diff --git a/assets/Typography.html-DOSESWuO.js b/assets/Typography.html-DOSESWuO.js new file mode 100644 index 000000000..15bc023cc --- /dev/null +++ b/assets/Typography.html-DOSESWuO.js @@ -0,0 +1 @@ +import{_ as t}from"./plugin-vue_export-helper-DlAUqK2U.js";import{c as a,b as r,o}from"./app-C6w_Pklu.js";const i={};function s(n,e){return o(),a("div",null,e[0]||(e[0]=[r("p",null,"Typographic components are used to give text a semantic meaning. They also create hierarchy and provide styling through size and color.",-1)]))}const l=t(i,[["render",s],["__file","Typography.html.vue"]]),p=JSON.parse('{"path":"/styleguide/src/styleguide/docs/Typography.html","title":"","lang":"en-US","frontmatter":{},"headers":[],"git":{"createdTime":1772365170000,"updatedTime":1772365170000,"contributors":[{"name":"Ulf Gebhardt","email":"ulf.gebhardt@webcraft-media.de","commits":1}]},"readingTime":{"minutes":0.07,"words":21},"filePathRelative":"styleguide/src/styleguide/docs/Typography.md","localizedDate":"March 1, 2026","excerpt":"

Typographic components are used to give text a semantic meaning. They also create hierarchy and provide styling through size and color.

\\n"}');export{l as comp,p as data}; diff --git a/assets/app-C6w_Pklu.js b/assets/app-C6w_Pklu.js new file mode 100644 index 000000000..df480e498 --- /dev/null +++ b/assets/app-C6w_Pklu.js @@ -0,0 +1,45 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CHANGELOG.html-Bnklulr8.js","assets/plugin-vue_export-helper-DlAUqK2U.js","assets/CODE_OF_CONDUCT.html-D7Z-kzHo.js","assets/CONTRIBUTING.html-DoGQ344g.js","assets/LICENSE.html-BkNHjkmj.js","assets/index.html-1dvphctW.js","assets/SUMMARY.html-DlsPW9yB.js","assets/documentation.html-B-SWCtsa.js","assets/testing.html-DIbeaaFd.js","assets/index.html-D1cGf28t.js","assets/graphql.html-hAUzkKsr.js","assets/graphql-playground (1)-C_SWrH2M.js","assets/neo4j-graphql-js.html-CoZVYA65.js","assets/testing.html-BI46pcUx.js","assets/index.html-vLTkaCiA.js","assets/features.html-jBF7v5Tb.js","assets/TODO-next-update.html-Dbd1HQYH.js","assets/deployment-values.html-BuK-P7uz.js","assets/index.html-DA6JIG7N.js","assets/index.html-DTeYXEMn.js","assets/index.html-BotCCvmf.js","assets/components.html-eb5EQ5pR.js","assets/html.html-D297kDdJ.js","assets/scss.html-B5_5w6uH.js","assets/testing.html-B-yKt6km.js","assets/vue.html-usvwTHmn.js","assets/index.html-e225B3G6.js","assets/CONTRIBUTING.html-vtvi86EK.js","assets/KATALOG.html-mRGwYwFN.js","assets/PROJEKT.html-BZRNQpP2.js","assets/index.html-CvqC5bIY.js","assets/index.html-CMfno-Jk.js","assets/GraphQL-Playground.html-KHcgqCNs.js","assets/index.html-Cei9bcC1.js","assets/index.html-kBh9kVNW.js","assets/demo.html-BiUsynyZ.js","assets/DataDisplay.html-Sq6mPmsX.js","assets/DesignTokens.html-BMTgeCjs.js","assets/Introduction.html-BLSaoncO.js","assets/Layout.html-47srRE8z.js","assets/Navigation.html-CYz7rQzP.js","assets/Typography.html-DOSESWuO.js","assets/STATUS.html-BXjDgreh.js","assets/index.html-Cww0Dhaz.js","assets/demo.html-B0pnlV6F.js","assets/demo.html-CW3cD-H7.js","assets/demo.html-6dfjrebI.js","assets/demo.html-C6Qxo9Yj.js","assets/demo.html-Cry2GElr.js","assets/demo.html-D5WfjYVc.js","assets/demo.html-DgTy1wh7.js","assets/demo.html-BJe7I_KV.js","assets/demo.html-4tqTFmIl.js","assets/demo.html-DYuC5F42.js","assets/demo.html-yVAERFv_.js","assets/demo.html-BvyZLl5C.js","assets/demo.html-BycQma2M.js","assets/demo.html-DtB7qtVV.js","assets/demo.html-DzDfUj7H.js","assets/demo.html-C19sXN7o.js","assets/demo.html-Kr4R8KpK.js","assets/demo.html-BF4J6jMP.js","assets/demo.html-BI-OLisc.js","assets/demo.html-B9TFHr4o.js","assets/demo.html-CWpO2OIy.js","assets/demo.html-pp2XB-6I.js","assets/demo.html-ESNHpVvJ.js","assets/demo.html-CREqiFsx.js","assets/demo.html-DiSwsATb.js","assets/demo.html-7n0yJEH_.js","assets/demo.html-B_2DIOaF.js","assets/demo.html-DWLc6gFO.js","assets/demo.html-DmAuEWx0.js","assets/404.html-CRHdR_pJ.js","assets/index.html-Buh1ncoF.js","assets/index.html-DGSGkBMu.js","assets/index.html-JQc0YsYs.js","assets/index.html-TA2-vxe5.js","assets/index.html-trrnbNUq.js","assets/index.html-cfpWt2jJ.js","assets/index.html-D6JUTu4R.js","assets/index.html-Bo7Ljf3a.js","assets/index.html-Ch-l52j_.js","assets/index.html-IpTOngCN.js","assets/index.html-LVrUA5Ul.js","assets/index.html-NfLl_DKG.js","assets/index.html-DVXBW6uR.js","assets/index.html-B9A0hIU3.js","assets/index.html-DzJKTok5.js","assets/index.html-Bnl9T6N5.js","assets/index.html-CT0wGi5f.js","assets/index.html-DwrHoA30.js","assets/index.html-BSwbVjcn.js","assets/index.html-BtnavBbg.js","assets/index.html-D3mIxgfr.js","assets/index.html-BrgOXTUr.js","assets/index.html-CKtpFMus.js","assets/index.html-BSOluCGA.js","assets/index.html-CrpjDBoX.js","assets/index.html-CZTXNS31.js","assets/index.html-Bm1PPhY4.js","assets/index.html-CI2ipqR1.js","assets/index.html-Bbb8AMlW.js","assets/index.html-CsIJCUeh.js","assets/index.html-B2TWVP9L.js","assets/index.html-Bwei2ul_.js","assets/index.html-BsZpCI8J.js","assets/index.html-BrAtRvv1.js","assets/index.html-CF1IpUUb.js","assets/index.html-DfhQXQ0d.js","assets/index.html-CMM88C29.js","assets/index.html-DXR7MLPg.js","assets/index.html-VtoA8tN6.js","assets/index.html-DnBsIglD.js","assets/index.html-Ca3OZ9Wf.js","assets/index.html-BEQOMUJ-.js","assets/index.html-2oMIHQ-B.js","assets/index.html-Bv1cv5QZ.js","assets/index.html-TZE5wDuj.js","assets/index.html-BOfzPdYe.js","assets/index.html-B7ltYIGI.js","assets/index.html-Cc8SuVO9.js","assets/index.html-TIaxxz0H.js","assets/index.html-DlRSH8xw.js","assets/index.html-BC6ChnxU.js"])))=>i.map(i=>d[i]); +const qp="modulepreload",Wp=function(e){return"/"+e},Cl={},C=function(t,n,r){let o=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),l=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));o=Promise.allSettled(n.map(i=>{if(i=Wp(i),i in Cl)return;Cl[i]=!0;const f=i.endsWith(".css"),c=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${i}"]${c}`))return;const u=document.createElement("link");if(u.rel=f?"stylesheet":qp,f||(u.as="script"),u.crossOrigin="",u.href=i,l&&u.setAttribute("nonce",l),document.head.appendChild(u),f)return new Promise((p,h)=>{u.addEventListener("load",p),u.addEventListener("error",()=>h(new Error(`Unable to preload CSS for ${i}`)))})}))}function s(a){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=a,window.dispatchEvent(l),!l.defaultPrevented)throw a}return o.then(a=>{for(const l of a||[])l.status==="rejected"&&s(l.reason);return t().catch(s)})};/** +* @vue/shared v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function lr(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Ee={},zn=[],Nt=()=>{},Gp=()=>!1,Yr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),wa=e=>e.startsWith("onUpdate:"),Ve=Object.assign,Ta=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Yp=Object.prototype.hasOwnProperty,me=(e,t)=>Yp.call(e,t),se=Array.isArray,Ar=e=>Ho(e)==="[object Map]",Qp=e=>Ho(e)==="[object Set]",oe=e=>typeof e=="function",ke=e=>typeof e=="string",ir=e=>typeof e=="symbol",Oe=e=>e!==null&&typeof e=="object",tc=e=>(Oe(e)||oe(e))&&oe(e.then)&&oe(e.catch),Xp=Object.prototype.toString,Ho=e=>Xp.call(e),Jp=e=>Ho(e).slice(8,-1),Zp=e=>Ho(e)==="[object Object]",Aa=e=>ke(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Kn=lr(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),jo=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},eh=/-(\w)/g,rt=jo(e=>e.replace(eh,(t,n)=>n?n.toUpperCase():"")),th=/\B([A-Z])/g,gn=jo(e=>e.replace(th,"-$1").toLowerCase()),Qr=jo(e=>e.charAt(0).toUpperCase()+e.slice(1)),is=jo(e=>e?`on${Qr(e)}`:""),dn=(e,t)=>!Object.is(e,t),us=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:r,value:n})},nh=e=>{const t=parseFloat(e);return isNaN(t)?e:t},rh=e=>{const t=ke(e)?Number(e):NaN;return isNaN(t)?e:t};let kl;const Uo=()=>kl||(kl=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function zo(e){if(se(e)){const t={};for(let n=0;n{if(n){const r=n.split(sh);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function ih(e){let t="";if(!e||ke(e))return t;for(const n in e){const r=e[n];if(ke(r)||typeof r=="number"){const o=n.startsWith("--")?n:gn(n);t+=`${o}:${r};`}}return t}function Ko(e){let t="";if(ke(e))t=e;else if(se(e))for(let n=0;n?@[\\\]^`{|}~]/g;function hh(e,t){return e.replace(ph,n=>`\\${n}`)}/** +* @vue/reactivity v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ye;class mh{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=Ye,!t&&Ye&&(this.index=(Ye.scopes||(Ye.scopes=[])).push(this)-1)}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t0)return;if(Cr){let t=Cr;for(Cr=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Sr;){let t=Sr;for(Sr=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(r){e||(e=r)}t=n}}if(e)throw e}function lc(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function ic(e){let t,n=e.depsTail,r=n;for(;r;){const o=r.prevDep;r.version===-1?(r===n&&(n=o),Oa(r),gh(r)):t=r,r.dep.activeLink=r.prevActiveLink,r.prevActiveLink=void 0,r=o}e.deps=t,e.depsTail=n}function Fs(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(uc(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function uc(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Vr))return;e.globalVersion=Vr;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!Fs(e)){e.flags&=-3;return}const n=ye,r=St;ye=e,St=!0;try{lc(e);const o=e.fn(e._value);(t.version===0||dn(o,e._value))&&(e._value=o,t.version++)}catch(o){throw t.version++,o}finally{ye=n,St=r,ic(e),e.flags&=-3}}function Oa(e,t=!1){const{dep:n,prevSub:r,nextSub:o}=e;if(r&&(r.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=r,e.nextSub=void 0),n.subs===e&&(n.subs=r,!r&&n.computed)){n.computed.flags&=-5;for(let s=n.computed.deps;s;s=s.nextDep)Oa(s,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function gh(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let St=!0;const cc=[];function Qt(){cc.push(St),St=!1}function Xt(){const e=cc.pop();St=e===void 0?!0:e}function xl(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ye;ye=void 0;try{t()}finally{ye=n}}}let Vr=0;class _h{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class qo{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!ye||!St||ye===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ye)n=this.activeLink=new _h(ye,this),ye.deps?(n.prevDep=ye.depsTail,ye.depsTail.nextDep=n,ye.depsTail=n):ye.deps=ye.depsTail=n,fc(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const r=n.nextDep;r.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=r),n.prevDep=ye.depsTail,n.nextDep=void 0,ye.depsTail.nextDep=n,ye.depsTail=n,ye.deps===n&&(ye.deps=r)}return n}trigger(t){this.version++,Vr++,this.notify(t)}notify(t){Ca();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{ka()}}}function fc(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let r=t.deps;r;r=r.nextDep)fc(r)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Oo=new WeakMap,xn=Symbol(""),Bs=Symbol(""),Nr=Symbol("");function Ke(e,t,n){if(St&&ye){let r=Oo.get(e);r||Oo.set(e,r=new Map);let o=r.get(n);o||(r.set(n,o=new qo),o.map=r,o.key=n),o.track()}}function Wt(e,t,n,r,o,s){const a=Oo.get(e);if(!a){Vr++;return}const l=i=>{i&&i.trigger()};if(Ca(),t==="clear")a.forEach(l);else{const i=se(e),f=i&&Aa(n);if(i&&n==="length"){const c=Number(r);a.forEach((u,p)=>{(p==="length"||p===Nr||!ir(p)&&p>=c)&&l(u)})}else switch((n!==void 0||a.has(void 0))&&l(a.get(n)),f&&l(a.get(Nr)),t){case"add":i?f&&l(a.get("length")):(l(a.get(xn)),Ar(e)&&l(a.get(Bs)));break;case"delete":i||(l(a.get(xn)),Ar(e)&&l(a.get(Bs)));break;case"set":Ar(e)&&l(a.get(xn));break}}ka()}function yh(e,t){const n=Oo.get(e);return n&&n.get(t)}function Fn(e){const t=ie(e);return t===e?t:(Ke(t,"iterate",Nr),Ct(e)?t:t.map(Qe))}function xa(e){return Ke(e=ie(e),"iterate",Nr),e}const Eh={__proto__:null,[Symbol.iterator](){return fs(this,Symbol.iterator,Qe)},concat(...e){return Fn(this).concat(...e.map(t=>se(t)?Fn(t):t))},entries(){return fs(this,"entries",e=>(e[1]=Qe(e[1]),e))},every(e,t){return Bt(this,"every",e,t,void 0,arguments)},filter(e,t){return Bt(this,"filter",e,t,n=>n.map(Qe),arguments)},find(e,t){return Bt(this,"find",e,t,Qe,arguments)},findIndex(e,t){return Bt(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Bt(this,"findLast",e,t,Qe,arguments)},findLastIndex(e,t){return Bt(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Bt(this,"forEach",e,t,void 0,arguments)},includes(...e){return ds(this,"includes",e)},indexOf(...e){return ds(this,"indexOf",e)},join(e){return Fn(this).join(e)},lastIndexOf(...e){return ds(this,"lastIndexOf",e)},map(e,t){return Bt(this,"map",e,t,void 0,arguments)},pop(){return hr(this,"pop")},push(...e){return hr(this,"push",e)},reduce(e,...t){return Rl(this,"reduce",e,t)},reduceRight(e,...t){return Rl(this,"reduceRight",e,t)},shift(){return hr(this,"shift")},some(e,t){return Bt(this,"some",e,t,void 0,arguments)},splice(...e){return hr(this,"splice",e)},toReversed(){return Fn(this).toReversed()},toSorted(e){return Fn(this).toSorted(e)},toSpliced(...e){return Fn(this).toSpliced(...e)},unshift(...e){return hr(this,"unshift",e)},values(){return fs(this,"values",Qe)}};function fs(e,t,n){const r=xa(e),o=r[t]();return r!==e&&!Ct(e)&&(o._next=o.next,o.next=()=>{const s=o._next();return s.value&&(s.value=n(s.value)),s}),o}const bh=Array.prototype;function Bt(e,t,n,r,o,s){const a=xa(e),l=a!==e&&!Ct(e),i=a[t];if(i!==bh[t]){const u=i.apply(e,s);return l?Qe(u):u}let f=n;a!==e&&(l?f=function(u,p){return n.call(this,Qe(u),p,e)}:n.length>2&&(f=function(u,p){return n.call(this,u,p,e)}));const c=i.call(a,f,r);return l&&o?o(c):c}function Rl(e,t,n,r){const o=xa(e);let s=n;return o!==e&&(Ct(e)?n.length>3&&(s=function(a,l,i){return n.call(this,a,l,i,e)}):s=function(a,l,i){return n.call(this,a,Qe(l),i,e)}),o[t](s,...r)}function ds(e,t,n){const r=ie(e);Ke(r,"iterate",Nr);const o=r[t](...n);return(o===-1||o===!1)&&Da(n[0])?(n[0]=ie(n[0]),r[t](...n)):o}function hr(e,t,n=[]){Qt(),Ca();const r=ie(e)[t].apply(e,n);return ka(),Xt(),r}const wh=lr("__proto__,__v_isRef,__isVue"),dc=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ir));function Th(e){ir(e)||(e=String(e));const t=ie(this);return Ke(t,"has",e),t.hasOwnProperty(e)}class pc{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,r){const o=this._isReadonly,s=this._isShallow;if(n==="__v_isReactive")return!o;if(n==="__v_isReadonly")return o;if(n==="__v_isShallow")return s;if(n==="__v_raw")return r===(o?s?Ph:gc:s?vc:mc).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(r)?t:void 0;const a=se(t);if(!o){let i;if(a&&(i=Eh[n]))return i;if(n==="hasOwnProperty")return Th}const l=Reflect.get(t,n,Pe(t)?t:r);return(ir(n)?dc.has(n):wh(n))||(o||Ke(t,"get",n),s)?l:Pe(l)?a&&Aa(n)?l:l.value:Oe(l)?o?Jr(l):Xr(l):l}}class hc extends pc{constructor(t=!1){super(!1,t)}set(t,n,r,o){let s=t[n];if(!this._isShallow){const i=Dn(s);if(!Ct(r)&&!Dn(r)&&(s=ie(s),r=ie(r)),!se(t)&&Pe(s)&&!Pe(r))return i?!1:(s.value=r,!0)}const a=se(t)&&Aa(n)?Number(n)e,fo=e=>Reflect.getPrototypeOf(e);function Oh(e,t,n){return function(...r){const o=this.__v_raw,s=ie(o),a=Ar(s),l=e==="entries"||e===Symbol.iterator&&a,i=e==="keys"&&a,f=o[e](...r),c=n?Hs:t?js:Qe;return!t&&Ke(s,"iterate",i?Bs:xn),{next(){const{value:u,done:p}=f.next();return p?{value:u,done:p}:{value:l?[c(u[0]),c(u[1])]:c(u),done:p}},[Symbol.iterator](){return this}}}}function po(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function xh(e,t){const n={get(o){const s=this.__v_raw,a=ie(s),l=ie(o);e||(dn(o,l)&&Ke(a,"get",o),Ke(a,"get",l));const{has:i}=fo(a),f=t?Hs:e?js:Qe;if(i.call(a,o))return f(s.get(o));if(i.call(a,l))return f(s.get(l));s!==a&&s.get(o)},get size(){const o=this.__v_raw;return!e&&Ke(ie(o),"iterate",xn),Reflect.get(o,"size",o)},has(o){const s=this.__v_raw,a=ie(s),l=ie(o);return e||(dn(o,l)&&Ke(a,"has",o),Ke(a,"has",l)),o===l?s.has(o):s.has(o)||s.has(l)},forEach(o,s){const a=this,l=a.__v_raw,i=ie(l),f=t?Hs:e?js:Qe;return!e&&Ke(i,"iterate",xn),l.forEach((c,u)=>o.call(s,f(c),f(u),a))}};return Ve(n,e?{add:po("add"),set:po("set"),delete:po("delete"),clear:po("clear")}:{add(o){!t&&!Ct(o)&&!Dn(o)&&(o=ie(o));const s=ie(this);return fo(s).has.call(s,o)||(s.add(o),Wt(s,"add",o,o)),this},set(o,s){!t&&!Ct(s)&&!Dn(s)&&(s=ie(s));const a=ie(this),{has:l,get:i}=fo(a);let f=l.call(a,o);f||(o=ie(o),f=l.call(a,o));const c=i.call(a,o);return a.set(o,s),f?dn(s,c)&&Wt(a,"set",o,s):Wt(a,"add",o,s),this},delete(o){const s=ie(this),{has:a,get:l}=fo(s);let i=a.call(s,o);i||(o=ie(o),i=a.call(s,o)),l&&l.call(s,o);const f=s.delete(o);return i&&Wt(s,"delete",o,void 0),f},clear(){const o=ie(this),s=o.size!==0,a=o.clear();return s&&Wt(o,"clear",void 0,void 0),a}}),["keys","values","entries",Symbol.iterator].forEach(o=>{n[o]=Oh(o,e,t)}),n}function Ra(e,t){const n=xh(e,t);return(r,o,s)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(me(n,o)&&o in r?n:r,o,s)}const Rh={get:Ra(!1,!1)},Ih={get:Ra(!1,!0)},Dh={get:Ra(!0,!1)};const mc=new WeakMap,vc=new WeakMap,gc=new WeakMap,Ph=new WeakMap;function Lh(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Vh(e){return e.__v_skip||!Object.isExtensible(e)?0:Lh(Jp(e))}function Xr(e){return Dn(e)?e:Ia(e,!1,Sh,Rh,mc)}function _c(e){return Ia(e,!1,kh,Ih,vc)}function Jr(e){return Ia(e,!0,Ch,Dh,gc)}function Ia(e,t,n,r,o){if(!Oe(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const s=o.get(e);if(s)return s;const a=Vh(e);if(a===0)return e;const l=new Proxy(e,a===2?r:n);return o.set(e,l),l}function kr(e){return Dn(e)?kr(e.__v_raw):!!(e&&e.__v_isReactive)}function Dn(e){return!!(e&&e.__v_isReadonly)}function Ct(e){return!!(e&&e.__v_isShallow)}function Da(e){return e?!!e.__v_raw:!1}function ie(e){const t=e&&e.__v_raw;return t?ie(t):e}function Nh(e){return!me(e,"__v_skip")&&Object.isExtensible(e)&&Zn(e,"__v_skip",!0),e}const Qe=e=>Oe(e)?Xr(e):e,js=e=>Oe(e)?Jr(e):e;function Pe(e){return e?e.__v_isRef===!0:!1}function te(e){return yc(e,!1)}function Fe(e){return yc(e,!0)}function yc(e,t){return Pe(e)?e:new Mh(e,t)}class Mh{constructor(t,n){this.dep=new qo,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:ie(t),this._value=n?t:Qe(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,r=this.__v_isShallow||Ct(t)||Dn(t);t=r?t:ie(t),dn(t,n)&&(this._rawValue=t,this._value=r?t:Qe(t),this.dep.trigger())}}function fn(e){return Pe(e)?e.value:e}const $h={get:(e,t,n)=>t==="__v_raw"?e:fn(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return Pe(o)&&!Pe(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function Ec(e){return kr(e)?e:new Proxy(e,$h)}class Fh{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new qo,{get:r,set:o}=t(n.track.bind(n),n.trigger.bind(n));this._get=r,this._set=o}get value(){return this._value=this._get()}set value(t){this._set(t)}}function bc(e){return new Fh(e)}class Bh{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0,this._value=void 0}get value(){const t=this._object[this._key];return this._value=t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return yh(ie(this._object),this._key)}}class Hh{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function Wo(e,t,n){return Pe(e)?e:oe(e)?new Hh(e):Oe(e)&&arguments.length>1?jh(e,t,n):te(e)}function jh(e,t,n){const r=e[t];return Pe(r)?r:new Bh(e,t,n)}class Uh{constructor(t,n,r){this.fn=t,this.setter=n,this._value=void 0,this.dep=new qo(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Vr-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=r}notify(){if(this.flags|=16,!(this.flags&8)&&ye!==this)return ac(this,!0),!0}get value(){const t=this.dep.track();return uc(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function zh(e,t,n=!1){let r,o;return oe(e)?r=e:(r=e.get,o=e.set),new Uh(r,o,n)}const ho={},xo=new WeakMap;let An;function Kh(e,t=!1,n=An){if(n){let r=xo.get(n);r||xo.set(n,r=[]),r.push(e)}}function qh(e,t,n=Ee){const{immediate:r,deep:o,once:s,scheduler:a,augmentJob:l,call:i}=n,f=T=>o?T:Ct(T)||o===!1||o===0?cn(T,1):cn(T);let c,u,p,h,m=!1,y=!1;if(Pe(e)?(u=()=>e.value,m=Ct(e)):kr(e)?(u=()=>f(e),m=!0):se(e)?(y=!0,m=e.some(T=>kr(T)||Ct(T)),u=()=>e.map(T=>{if(Pe(T))return T.value;if(kr(T))return f(T);if(oe(T))return i?i(T,2):T()})):oe(e)?t?u=i?()=>i(e,2):e:u=()=>{if(p){Qt();try{p()}finally{Xt()}}const T=An;An=c;try{return i?i(e,3,[h]):e(h)}finally{An=T}}:u=Nt,t&&o){const T=u,V=o===!0?1/0:o;u=()=>cn(T(),V)}const _=rc(),E=()=>{c.stop(),_&&Ta(_.effects,c)};if(s&&t){const T=t;t=(...V)=>{T(...V),E()}}let w=y?new Array(e.length).fill(ho):ho;const v=T=>{if(!(!(c.flags&1)||!c.dirty&&!T))if(t){const V=c.run();if(o||m||(y?V.some((H,$)=>dn(H,w[$])):dn(V,w))){p&&p();const H=An;An=c;try{const $=[V,w===ho?void 0:y&&w[0]===ho?[]:w,h];i?i(t,3,$):t(...$),w=V}finally{An=H}}}else c.run()};return l&&l(v),c=new oc(u),c.scheduler=a?()=>a(v,!1):v,h=T=>Kh(T,!1,c),p=c.onStop=()=>{const T=xo.get(c);if(T){if(i)i(T,4);else for(const V of T)V();xo.delete(c)}},t?r?v(!0):w=c.run():a?a(v.bind(null,!0),!0):c.run(),E.pause=c.pause.bind(c),E.resume=c.resume.bind(c),E.stop=E,E}function cn(e,t=1/0,n){if(t<=0||!Oe(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,Pe(e))cn(e.value,t,n);else if(se(e))for(let r=0;r{cn(r,t,n)});else if(Zp(e)){for(const r in e)cn(e[r],t,n);for(const r of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,r)&&cn(e[r],t,n)}return e}/** +* @vue/runtime-core v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const Or=[];let ps=!1;function rn(e,...t){if(ps)return;ps=!0,Qt();const n=Or.length?Or[Or.length-1].component:null,r=n&&n.appContext.config.warnHandler,o=Wh();if(r)ur(r,n,11,[e+t.map(s=>{var a,l;return(l=(a=s.toString)==null?void 0:a.call(s))!=null?l:JSON.stringify(s)}).join(""),n&&n.proxy,o.map(({vnode:s})=>`at <${ff(n,s.type)}>`).join(` +`),o]);else{const s=[`[Vue warn]: ${e}`,...t];o.length&&s.push(` +`,...Gh(o)),console.warn(...s)}Xt(),ps=!1}function Wh(){let e=Or[Or.length-1];if(!e)return[];const t=[];for(;e;){const n=t[0];n&&n.vnode===e?n.recurseCount++:t.push({vnode:e,recurseCount:0});const r=e.component&&e.component.parent;e=r&&r.vnode}return t}function Gh(e){const t=[];return e.forEach((n,r)=>{t.push(...r===0?[]:[` +`],...Yh(n))}),t}function Yh({vnode:e,recurseCount:t}){const n=t>0?`... (${t} recursive calls)`:"",r=e.component?e.component.parent==null:!1,o=` at <${ff(e.component,e.type,r)}`,s=">"+n;return e.props?[o,...Qh(e.props),s]:[o+s]}function Qh(e){const t=[],n=Object.keys(e);return n.slice(0,3).forEach(r=>{t.push(...wc(r,e[r]))}),n.length>3&&t.push(" ..."),t}function wc(e,t,n){return ke(t)?(t=JSON.stringify(t),n?t:[`${e}=${t}`]):typeof t=="number"||typeof t=="boolean"||t==null?n?t:[`${e}=${t}`]:Pe(t)?(t=wc(e,ie(t.value),!0),n?t:[`${e}=Ref<`,t,">"]):oe(t)?[`${e}=fn${t.name?`<${t.name}>`:""}`]:(t=ie(t),n?t:[`${e}=`,t])}function ur(e,t,n,r){try{return r?e(...r):e()}catch(o){Zr(o,t,n)}}function kt(e,t,n,r){if(oe(e)){const o=ur(e,t,n,r);return o&&tc(o)&&o.catch(s=>{Zr(s,t,n)}),o}if(se(e)){const o=[];for(let s=0;s>>1,o=Xe[r],s=Mr(o);s=Mr(n)?Xe.push(e):Xe.splice(Jh(t),0,e),e.flags|=1,Ac()}}function Ac(){Ro||(Ro=Tc.then(Sc))}function Zh(e){se(e)?qn.push(...e):sn&&e.id===-1?sn.splice(Hn+1,0,e):e.flags&1||(qn.push(e),e.flags|=1),Ac()}function Il(e,t,n=Dt+1){for(;nMr(n)-Mr(r));if(qn.length=0,sn){sn.push(...t);return}for(sn=t,Hn=0;Hne.id==null?e.flags&2?-1:1/0:e.id;function Sc(e){try{for(Dt=0;DtLt.emit(o,...s)),yr=[]):typeof window<"u"&&window.HTMLElement&&!((r=(n=window.navigator)==null?void 0:n.userAgent)!=null&&r.includes("jsdom"))?((t.__VUE_DEVTOOLS_HOOK_REPLAY__=t.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push(s=>{Cc(s,t)}),setTimeout(()=>{Lt||(t.__VUE_DEVTOOLS_HOOK_REPLAY__=null,Us=!0,yr=[])},3e3)):(Us=!0,yr=[])}function em(e,t){Go("app:init",e,t,{Fragment:Je,Text:pn,Comment:tt,Static:Yn})}function tm(e){Go("app:unmount",e)}const nm=La("component:added"),kc=La("component:updated"),rm=La("component:removed"),om=e=>{Lt&&typeof Lt.cleanupBuffer=="function"&&!Lt.cleanupBuffer(e)&&rm(e)};/*! #__NO_SIDE_EFFECTS__ */function La(e){return t=>{Go(e,t.appContext.app,t.uid,t.parent?t.parent.uid:void 0,t)}}function sm(e,t,n){Go("component:emit",e.appContext.app,e,t,n)}let yt=null,Oc=null;function Do(e){const t=yt;return yt=e,Oc=e&&e.type.__scopeId||null,t}function am(e,t=yt,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&Kl(-1);const s=Do(t);let a;try{a=e(...o)}finally{Do(s),r._d&&Kl(1)}return kc(t),a};return r._n=!0,r._c=!0,r._d=!0,r}function Pt(e,t,n,r){const o=e.dirs,s=t&&t.dirs;for(let a=0;ae.__isTeleport,an=Symbol("_leaveCb"),mo=Symbol("_enterCb");function Rc(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return Se(()=>{e.isMounted=!0}),Ma(()=>{e.isUnmounting=!0}),e}const ht=[Function,Array],Ic={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:ht,onEnter:ht,onAfterEnter:ht,onEnterCancelled:ht,onBeforeLeave:ht,onLeave:ht,onAfterLeave:ht,onLeaveCancelled:ht,onBeforeAppear:ht,onAppear:ht,onAfterAppear:ht,onAppearCancelled:ht},Dc=e=>{const t=e.subTree;return t.component?Dc(t.component):t},im={name:"BaseTransition",props:Ic,setup(e,{slots:t}){const n=Nn(),r=Rc();return()=>{const o=t.default&&Va(t.default(),!0);if(!o||!o.length)return;const s=Pc(o),a=ie(e),{mode:l}=a;if(r.isLeaving)return hs(s);const i=Dl(s);if(!i)return hs(s);let f=$r(i,a,r,n,p=>f=p);i.type!==tt&&Pn(i,f);const c=n.subTree,u=c&&Dl(c);if(u&&u.type!==tt&&!Cn(i,u)&&Dc(n).type!==tt){const p=$r(u,a,r,n);if(Pn(u,p),l==="out-in"&&i.type!==tt)return r.isLeaving=!0,p.afterLeave=()=>{r.isLeaving=!1,n.job.flags&8||n.update(),delete p.afterLeave},hs(s);l==="in-out"&&i.type!==tt&&(p.delayLeave=(h,m,y)=>{const _=Lc(r,u);_[String(u.key)]=u,h[an]=()=>{m(),h[an]=void 0,delete f.delayedLeave},f.delayedLeave=y})}return s}}};function Pc(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==tt){t=n;break}}return t}const um=im;function Lc(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function $r(e,t,n,r,o){const{appear:s,mode:a,persisted:l=!1,onBeforeEnter:i,onEnter:f,onAfterEnter:c,onEnterCancelled:u,onBeforeLeave:p,onLeave:h,onAfterLeave:m,onLeaveCancelled:y,onBeforeAppear:_,onAppear:E,onAfterAppear:w,onAppearCancelled:v}=t,T=String(e.key),V=Lc(n,e),H=(N,R)=>{N&&kt(N,r,9,R)},$=(N,R)=>{const j=R[1];H(N,R),se(N)?N.every(L=>L.length<=1)&&j():N.length<=1&&j()},J={mode:a,persisted:l,beforeEnter(N){let R=i;if(!n.isMounted)if(s)R=_||i;else return;N[an]&&N[an](!0);const j=V[T];j&&Cn(e,j)&&j.el[an]&&j.el[an](),H(R,[N])},enter(N){let R=f,j=c,L=u;if(!n.isMounted)if(s)R=E||f,j=w||c,L=v||u;else return;let Z=!1;const le=N[mo]=de=>{Z||(Z=!0,de?H(L,[N]):H(j,[N]),J.delayedLeave&&J.delayedLeave(),N[mo]=void 0)};R?$(R,[N,le]):le()},leave(N,R){const j=String(e.key);if(N[mo]&&N[mo](!0),n.isUnmounting)return R();H(p,[N]);let L=!1;const Z=N[an]=le=>{L||(L=!0,R(),le?H(y,[N]):H(m,[N]),N[an]=void 0,V[j]===e&&delete V[j])};V[j]=e,h?$(h,[N,Z]):Z()},clone(N){const R=$r(N,t,n,r,o);return o&&o(R),R}};return J}function hs(e){if(eo(e))return e=hn(e),e.children=null,e}function Dl(e){if(!eo(e))return xc(e.type)&&e.children?Pc(e.children):e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&oe(n.default))return n.default()}}function Pn(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Pn(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Va(e,t=!1,n){let r=[],o=0;for(let s=0;s1)for(let s=0;sPo(m,t&&(se(t)?t[y]:t),n,r,o));return}if(Wn(r)&&!o)return;const s=r.shapeFlag&4?Ua(r.component):r.el,a=o?null:s,{i:l,r:i}=e,f=t&&t.r,c=l.refs===Ee?l.refs={}:l.refs,u=l.setupState,p=ie(u),h=u===Ee?()=>!1:m=>me(p,m);if(f!=null&&f!==i&&(ke(f)?(c[f]=null,h(f)&&(u[f]=null)):Pe(f)&&(f.value=null)),oe(i))ur(i,l,12,[a,c]);else{const m=ke(i),y=Pe(i);if(m||y){const _=()=>{if(e.f){const E=m?h(i)?u[i]:c[i]:i.value;o?se(E)&&Ta(E,s):se(E)?E.includes(s)||E.push(s):m?(c[i]=[s],h(i)&&(u[i]=c[i])):(i.value=[s],e.k&&(c[e.k]=i.value))}else m?(c[i]=a,h(i)&&(u[i]=a)):y&&(i.value=a,e.k&&(c[e.k]=a))};a?(_.id=-1,lt(_,n)):_()}}}let Pl=!1;const En=()=>{Pl||(console.error("Hydration completed but contains mismatches."),Pl=!0)},cm=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",fm=e=>e.namespaceURI.includes("MathML"),vo=e=>{if(e.nodeType===1){if(cm(e))return"svg";if(fm(e))return"mathml"}},Sn=e=>e.nodeType===8;function dm(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:s,parentNode:a,remove:l,insert:i,createComment:f}}=e,c=(v,T)=>{if(!T.hasChildNodes()){rn("Attempting to hydrate existing markup but container is empty. Performing full mount instead."),n(null,v,T),Io(),T._vnode=v;return}u(T.firstChild,v,null,null,null),Io(),T._vnode=v},u=(v,T,V,H,$,J=!1)=>{J=J||!!T.dynamicChildren;const N=Sn(v)&&v.data==="[",R=()=>y(v,T,V,H,$,N),{type:j,ref:L,shapeFlag:Z,patchFlag:le}=T;let de=v.nodeType;T.el=v,Zn(v,"__vnode",T,!0),Zn(v,"__vueParentComponent",V,!0),le===-2&&(J=!1,T.dynamicChildren=null);let K=null;switch(j){case pn:de!==3?T.children===""?(i(T.el=o(""),a(v),v),K=v):K=R():(v.data!==T.children&&(rn("Hydration text mismatch in",v.parentNode,` + - rendered on server: ${JSON.stringify(v.data)} + - expected on client: ${JSON.stringify(T.children)}`),En(),v.data=T.children),K=s(v));break;case tt:w(v)?(K=s(v),E(T.el=v.content.firstChild,v,V)):de!==8||N?K=R():K=s(v);break;case Yn:if(N&&(v=s(v),de=v.nodeType),de===1||de===3){K=v;const F=!T.children.length;for(let Y=0;Y{J=J||!!T.dynamicChildren;const{type:N,props:R,patchFlag:j,shapeFlag:L,dirs:Z,transition:le}=T,de=N==="input"||N==="option";if(de||j!==-1){Z&&Pt(T,null,V,"created");let K=!1;if(w(v)){K=Xc(null,le)&&V&&V.vnode.props&&V.vnode.props.appear;const Y=v.content.firstChild;K&&le.beforeEnter(Y),E(Y,v,V),T.el=v=Y}if(L&16&&!(R&&(R.innerHTML||R.textContent))){let Y=h(v.firstChild,T,v,V,H,$,J),ae=!1;for(;Y;){Er(v,1)||(ae||(rn("Hydration children mismatch on",v,` +Server rendered element contains more child nodes than client vdom.`),ae=!0),En());const Ie=Y;Y=Y.nextSibling,l(Ie)}}else if(L&8){let Y=T.children;Y[0]===` +`&&(v.tagName==="PRE"||v.tagName==="TEXTAREA")&&(Y=Y.slice(1)),v.textContent!==Y&&(Er(v,0)||(rn("Hydration text content mismatch on",v,` + - rendered on server: ${v.textContent} + - expected on client: ${T.children}`),En()),v.textContent=T.children)}if(R){const Y=v.tagName.includes("-");for(const ae in R)!(Z&&Z.some(Ie=>Ie.dir.created))&&pm(v,ae,R[ae],T,V)&&En(),(de&&(ae.endsWith("value")||ae==="indeterminate")||Yr(ae)&&!Kn(ae)||ae[0]==="."||Y)&&r(v,ae,null,R[ae],void 0,V)}let F;(F=R&&R.onVnodeBeforeMount)&&mt(F,V,T),Z&&Pt(T,null,V,"beforeMount"),((F=R&&R.onVnodeMounted)||Z||K)&&rf(()=>{F&&mt(F,V,T),K&&le.enter(v),Z&&Pt(T,null,V,"mounted")},H)}return v.nextSibling},h=(v,T,V,H,$,J,N)=>{N=N||!!T.dynamicChildren;const R=T.children,j=R.length;let L=!1;for(let Z=0;Z{const{slotScopeIds:N}=T;N&&($=$?$.concat(N):N);const R=a(v),j=h(s(v),T,R,V,H,$,J);return j&&Sn(j)&&j.data==="]"?s(T.anchor=j):(En(),i(T.anchor=f("]"),R,j),j)},y=(v,T,V,H,$,J)=>{if(Er(v.parentElement,1)||(rn(`Hydration node mismatch: +- rendered on server:`,v,v.nodeType===3?"(text)":Sn(v)&&v.data==="["?"(start of fragment)":"",` +- expected on client:`,T.type),En()),T.el=null,J){const j=_(v);for(;;){const L=s(v);if(L&&L!==j)l(L);else break}}const N=s(v),R=a(v);return l(v),n(null,T,R,N,V,H,vo(R),$),N},_=(v,T="[",V="]")=>{let H=0;for(;v;)if(v=s(v),v&&Sn(v)&&(v.data===T&&H++,v.data===V)){if(H===0)return s(v);H--}return v},E=(v,T,V)=>{const H=T.parentNode;H&&H.replaceChild(v,T);let $=V;for(;$;)$.vnode.el===T&&($.vnode.el=$.subTree.el=v),$=$.parent},w=v=>v.nodeType===1&&v.tagName==="TEMPLATE";return[c,u]}function pm(e,t,n,r,o){let s,a,l,i;if(t==="class")l=e.getAttribute("class"),i=Ko(n),hm(Ll(l||""),Ll(i))||(s=2,a="class");else if(t==="style"){l=e.getAttribute("style")||"",i=ke(n)?n:ih(zo(n));const f=Vl(l),c=Vl(i);if(r.dirs)for(const{dir:u,value:p}of r.dirs)u.name==="show"&&!p&&c.set("display","none");o&&Vc(o,r,c),mm(f,c)||(s=3,a="style")}else(e instanceof SVGElement&&fh(t)||e instanceof HTMLElement&&(Ol(t)||ch(t)))&&(Ol(t)?(l=e.hasAttribute(t),i=Sa(n)):n==null?(l=e.hasAttribute(t),i=!1):(e.hasAttribute(t)?l=e.getAttribute(t):t==="value"&&e.tagName==="TEXTAREA"?l=e.value:l=!1,i=dh(n)?String(n):!1),l!==i&&(s=4,a=t));if(s!=null&&!Er(e,s)){const f=p=>p===!1?"(not rendered)":`${a}="${p}"`,c=`Hydration ${Nc[s]} mismatch on`,u=` + - rendered on server: ${f(l)} + - expected on client: ${f(i)} + Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead. + You should fix the source of the mismatch.`;return rn(c,e,u),!0}return!1}function Ll(e){return new Set(e.trim().split(/\s+/))}function hm(e,t){if(e.size!==t.size)return!1;for(const n of e)if(!t.has(n))return!1;return!0}function Vl(e){const t=new Map;for(const n of e.split(";")){let[r,o]=n.split(":");r=r.trim(),o=o&&o.trim(),r&&o&&t.set(r,o)}return t}function mm(e,t){if(e.size!==t.size)return!1;for(const[n,r]of e)if(r!==t.get(n))return!1;return!0}function Vc(e,t,n){const r=e.subTree;if(e.getCssVars&&(t===r||r&&r.type===Je&&r.children.includes(t))){const o=e.getCssVars();for(const s in o)n.set(`--${hh(s)}`,String(o[s]))}t===r&&e.parent&&Vc(e.parent,e.vnode,n)}const Nl="data-allow-mismatch",Nc={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function Er(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(Nl);)e=e.parentElement;const n=e&&e.getAttribute(Nl);if(n==null)return!1;if(n==="")return!0;{const r=n.split(",");return t===0&&r.includes("children")?!0:n.split(",").includes(Nc[t])}}Uo().requestIdleCallback;Uo().cancelIdleCallback;function vm(e,t){if(Sn(e)&&e.data==="["){let n=1,r=e.nextSibling;for(;r;){if(r.nodeType===1){if(t(r)===!1)break}else if(Sn(r))if(r.data==="]"){if(--n===0)break}else r.data==="["&&n++;r=r.nextSibling}}else t(e)}const Wn=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function Mc(e){oe(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,hydrate:s,timeout:a,suspensible:l=!0,onError:i}=e;let f=null,c,u=0;const p=()=>(u++,f=null,h()),h=()=>{let m;return f||(m=f=t().catch(y=>{if(y=y instanceof Error?y:new Error(String(y)),i)return new Promise((_,E)=>{i(y,()=>_(p()),()=>E(y),u+1)});throw y}).then(y=>m!==f&&f?f:(y&&(y.__esModule||y[Symbol.toStringTag]==="Module")&&(y=y.default),c=y,y)))};return X({name:"AsyncComponentWrapper",__asyncLoader:h,__asyncHydrate(m,y,_){const E=s?()=>{const w=s(_,v=>vm(m,v));w&&(y.bum||(y.bum=[])).push(w)}:_;c?E():h().then(()=>!y.isUnmounted&&E())},get __asyncResolved(){return c},setup(){const m=He;if(Na(m),c)return()=>ms(c,m);const y=v=>{f=null,Zr(v,m,13,!r)};if(l&&m.suspense||er)return h().then(v=>()=>ms(v,m)).catch(v=>(y(v),()=>r?$e(r,{error:v}):null));const _=te(!1),E=te(),w=te(!!o);return o&&setTimeout(()=>{w.value=!1},o),a!=null&&setTimeout(()=>{if(!_.value&&!E.value){const v=new Error(`Async component timed out after ${a}ms.`);y(v),E.value=v}},a),h().then(()=>{_.value=!0,m.parent&&eo(m.parent.vnode)&&m.parent.update()}).catch(v=>{y(v),E.value=v}),()=>{if(_.value&&c)return ms(c,m);if(E.value&&r)return $e(r,{error:E.value});if(n&&!w.value)return $e(n)}}})}function ms(e,t){const{ref:n,props:r,children:o,ce:s}=t.vnode,a=$e(e,r,o);return a.ref=n,a.ce=s,delete t.vnode.ce,a}const eo=e=>e.type.__isKeepAlive;function gm(e,t){$c(e,"a",t)}function _m(e,t){$c(e,"da",t)}function $c(e,t,n=He){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Yo(t,r,n),n){let o=n.parent;for(;o&&o.parent;)eo(o.parent.vnode)&&ym(r,t,n,o),o=o.parent}}function ym(e,t,n,r){const o=Yo(t,e,r,!0);Vn(()=>{Ta(r[t],o)},n)}function Yo(e,t,n=He,r=!1){if(n){const o=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...a)=>{Qt();const l=to(n),i=kt(t,n,e,a);return l(),Xt(),i});return r?o.unshift(s):o.push(s),s}}const Jt=e=>(t,n=He)=>{(!er||e==="sp")&&Yo(e,(...r)=>t(...r),n)},Em=Jt("bm"),Se=Jt("m"),bm=Jt("bu"),Fc=Jt("u"),Ma=Jt("bum"),Vn=Jt("um"),wm=Jt("sp"),Tm=Jt("rtg"),Am=Jt("rtc");function Sm(e,t=He){Yo("ec",e,t)}const Cm="components";function Mt(e,t){return Om(Cm,e,!0,t)||e}const km=Symbol.for("v-ndc");function Om(e,t,n=!0,r=!1){const o=yt||He;if(o){const s=o.type;{const l=cf(s,!1);if(l&&(l===t||l===rt(t)||l===Qr(rt(t))))return s}const a=Ml(o[e]||s[e],t)||Ml(o.appContext[e],t);return!a&&r?s:a}}function Ml(e,t){return e&&(e[t]||e[rt(t)]||e[Qr(rt(t))])}const zs=e=>e?lf(e)?Ua(e):zs(e.parent):null,xr=Ve(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>zs(e.parent),$root:e=>zs(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>$a(e),$forceUpdate:e=>e.f||(e.f=()=>{Pa(e.update)}),$nextTick:e=>e.n||(e.n=$t.bind(e.proxy)),$watch:e=>Gm.bind(e)}),vs=(e,t)=>e!==Ee&&!e.__isScriptSetup&&me(e,t),xm={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:r,data:o,props:s,accessCache:a,type:l,appContext:i}=e;let f;if(t[0]!=="$"){const h=a[t];if(h!==void 0)switch(h){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return s[t]}else{if(vs(r,t))return a[t]=1,r[t];if(o!==Ee&&me(o,t))return a[t]=2,o[t];if((f=e.propsOptions[0])&&me(f,t))return a[t]=3,s[t];if(n!==Ee&&me(n,t))return a[t]=4,n[t];Ks&&(a[t]=0)}}const c=xr[t];let u,p;if(c)return t==="$attrs"&&Ke(e.attrs,"get",""),c(e);if((u=l.__cssModules)&&(u=u[t]))return u;if(n!==Ee&&me(n,t))return a[t]=4,n[t];if(p=i.config.globalProperties,me(p,t))return p[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:s}=e;return vs(o,t)?(o[t]=n,!0):r!==Ee&&me(r,t)?(r[t]=n,!0):me(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(s[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:s}},a){let l;return!!n[a]||e!==Ee&&me(e,a)||vs(t,a)||(l=s[0])&&me(l,a)||me(r,a)||me(xr,a)||me(o.config.globalProperties,a)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:me(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function $l(e){return se(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Ks=!0;function Rm(e){const t=$a(e),n=e.proxy,r=e.ctx;Ks=!1,t.beforeCreate&&Fl(t.beforeCreate,e,"bc");const{data:o,computed:s,methods:a,watch:l,provide:i,inject:f,created:c,beforeMount:u,mounted:p,beforeUpdate:h,updated:m,activated:y,deactivated:_,beforeDestroy:E,beforeUnmount:w,destroyed:v,unmounted:T,render:V,renderTracked:H,renderTriggered:$,errorCaptured:J,serverPrefetch:N,expose:R,inheritAttrs:j,components:L,directives:Z,filters:le}=t;if(f&&Im(f,r,null),a)for(const F in a){const Y=a[F];oe(Y)&&(r[F]=Y.bind(n))}if(o){const F=o.call(n,n);Oe(F)&&(e.data=Xr(F))}if(Ks=!0,s)for(const F in s){const Y=s[F],ae=oe(Y)?Y.bind(n,n):oe(Y.get)?Y.get.bind(n,n):Nt,Ie=!oe(Y)&&oe(Y.set)?Y.set.bind(n):Nt,De=S({get:ae,set:Ie});Object.defineProperty(r,F,{enumerable:!0,configurable:!0,get:()=>De.value,set:pe=>De.value=pe})}if(l)for(const F in l)Bc(l[F],r,n,F);if(i){const F=oe(i)?i.call(n):i;Reflect.ownKeys(F).forEach(Y=>{Rn(Y,F[Y])})}c&&Fl(c,e,"c");function K(F,Y){se(Y)?Y.forEach(ae=>F(ae.bind(n))):Y&&F(Y.bind(n))}if(K(Em,u),K(Se,p),K(bm,h),K(Fc,m),K(gm,y),K(_m,_),K(Sm,J),K(Am,H),K(Tm,$),K(Ma,w),K(Vn,T),K(wm,N),se(R))if(R.length){const F=e.exposed||(e.exposed={});R.forEach(Y=>{Object.defineProperty(F,Y,{get:()=>n[Y],set:ae=>n[Y]=ae})})}else e.exposed||(e.exposed={});V&&e.render===Nt&&(e.render=V),j!=null&&(e.inheritAttrs=j),L&&(e.components=L),Z&&(e.directives=Z),N&&Na(e)}function Im(e,t,n=Nt){se(e)&&(e=qs(e));for(const r in e){const o=e[r];let s;Oe(o)?"default"in o?s=Ne(o.from||r,o.default,!0):s=Ne(o.from||r):s=Ne(o),Pe(s)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>s.value,set:a=>s.value=a}):t[r]=s}}function Fl(e,t,n){kt(se(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Bc(e,t,n,r){let o=r.includes(".")?ef(n,r):()=>n[r];if(ke(e)){const s=t[e];oe(s)&&ce(o,s)}else if(oe(e))ce(o,e.bind(n));else if(Oe(e))if(se(e))e.forEach(s=>Bc(s,t,n,r));else{const s=oe(e.handler)?e.handler.bind(n):t[e.handler];oe(s)&&ce(o,s,e)}}function $a(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:s,config:{optionMergeStrategies:a}}=e.appContext,l=s.get(t);let i;return l?i=l:!o.length&&!n&&!r?i=t:(i={},o.length&&o.forEach(f=>Lo(i,f,a,!0)),Lo(i,t,a)),Oe(t)&&s.set(t,i),i}function Lo(e,t,n,r=!1){const{mixins:o,extends:s}=t;s&&Lo(e,s,n,!0),o&&o.forEach(a=>Lo(e,a,n,!0));for(const a in t)if(!(r&&a==="expose")){const l=Dm[a]||n&&n[a];e[a]=l?l(e[a],t[a]):t[a]}return e}const Dm={data:Bl,props:Hl,emits:Hl,methods:br,computed:br,beforeCreate:Ge,created:Ge,beforeMount:Ge,mounted:Ge,beforeUpdate:Ge,updated:Ge,beforeDestroy:Ge,beforeUnmount:Ge,destroyed:Ge,unmounted:Ge,activated:Ge,deactivated:Ge,errorCaptured:Ge,serverPrefetch:Ge,components:br,directives:br,watch:Lm,provide:Bl,inject:Pm};function Bl(e,t){return t?e?function(){return Ve(oe(e)?e.call(this,this):e,oe(t)?t.call(this,this):t)}:t:e}function Pm(e,t){return br(qs(e),qs(t))}function qs(e){if(se(e)){const t={};for(let n=0;n1)return n&&oe(t)?t.call(r&&r.proxy):t}}const jc={},Uc=()=>Object.create(jc),zc=e=>Object.getPrototypeOf(e)===jc;function Mm(e,t,n,r=!1){const o={},s=Uc();e.propsDefaults=Object.create(null),Kc(e,t,o,s);for(const a in e.propsOptions[0])a in o||(o[a]=void 0);n?e.props=r?o:_c(o):e.type.props?e.props=o:e.props=s,e.attrs=s}function $m(e,t,n,r){const{props:o,attrs:s,vnode:{patchFlag:a}}=e,l=ie(o),[i]=e.propsOptions;let f=!1;if((r||a>0)&&!(a&16)){if(a&8){const c=e.vnode.dynamicProps;for(let u=0;u{i=!0;const[p,h]=qc(u,t,!0);Ve(a,p),h&&l.push(...h)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!s&&!i)return Oe(e)&&r.set(e,zn),zn;if(se(s))for(let c=0;ce[0]==="_"||e==="$stable",Fa=e=>se(e)?e.map(gt):[gt(e)],Bm=(e,t,n)=>{if(t._n)return t;const r=am((...o)=>Fa(t(...o)),n);return r._c=!1,r},Gc=(e,t,n)=>{const r=e._ctx;for(const o in e){if(Wc(o))continue;const s=e[o];if(oe(s))t[o]=Bm(o,s,r);else if(s!=null){const a=Fa(s);t[o]=()=>a}}},Yc=(e,t)=>{const n=Fa(t);e.slots.default=()=>n},Qc=(e,t,n)=>{for(const r in t)(n||r!=="_")&&(e[r]=t[r])},Hm=(e,t,n)=>{const r=e.slots=Uc();if(e.vnode.shapeFlag&32){const o=t._;o?(Qc(r,t,n),n&&Zn(r,"_",o,!0)):Gc(t,r)}else t&&Yc(e,t)},jm=(e,t,n)=>{const{vnode:r,slots:o}=e;let s=!0,a=Ee;if(r.shapeFlag&32){const l=t._;l?n&&l===1?s=!1:Qc(o,t,n):(s=!t.$stable,Gc(t,o)),a=t}else t&&(Yc(e,t),a={default:1});if(s)for(const l in o)!Wc(l)&&a[l]==null&&delete o[l]},lt=rf;function Um(e){return zm(e,dm)}function zm(e,t){const n=Uo();n.__VUE__=!0,Cc(n.__VUE_DEVTOOLS_GLOBAL_HOOK__,n);const{insert:r,remove:o,patchProp:s,createElement:a,createText:l,createComment:i,setText:f,setElementText:c,parentNode:u,nextSibling:p,setScopeId:h=Nt,insertStaticContent:m}=e,y=(g,b,A,I=null,O=null,D=null,z=void 0,B=null,M=!!b.dynamicChildren)=>{if(g===b)return;g&&!Cn(g,b)&&(I=k(g),pe(g,O,D,!0),g=null),b.patchFlag===-2&&(M=!1,b.dynamicChildren=null);const{type:P,ref:ne,shapeFlag:W}=b;switch(P){case pn:_(g,b,A,I);break;case tt:E(g,b,A,I);break;case Yn:g==null&&w(b,A,I,z);break;case Je:L(g,b,A,I,O,D,z,B,M);break;default:W&1?V(g,b,A,I,O,D,z,B,M):W&6?Z(g,b,A,I,O,D,z,B,M):(W&64||W&128)&&P.process(g,b,A,I,O,D,z,B,M,Q)}ne!=null&&O&&Po(ne,g&&g.ref,D,b||g,!b)},_=(g,b,A,I)=>{if(g==null)r(b.el=l(b.children),A,I);else{const O=b.el=g.el;b.children!==g.children&&f(O,b.children)}},E=(g,b,A,I)=>{g==null?r(b.el=i(b.children||""),A,I):b.el=g.el},w=(g,b,A,I)=>{[g.el,g.anchor]=m(g.children,b,A,I,g.el,g.anchor)},v=({el:g,anchor:b},A,I)=>{let O;for(;g&&g!==b;)O=p(g),r(g,A,I),g=O;r(b,A,I)},T=({el:g,anchor:b})=>{let A;for(;g&&g!==b;)A=p(g),o(g),g=A;o(b)},V=(g,b,A,I,O,D,z,B,M)=>{b.type==="svg"?z="svg":b.type==="math"&&(z="mathml"),g==null?H(b,A,I,O,D,z,B,M):N(g,b,O,D,z,B,M)},H=(g,b,A,I,O,D,z,B)=>{let M,P;const{props:ne,shapeFlag:W,transition:ee,dirs:re}=g;if(M=g.el=a(g.type,D,ne&&ne.is,ne),W&8?c(M,g.children):W&16&&J(g.children,M,null,I,O,gs(g,D),z,B),re&&Pt(g,null,I,"created"),$(M,g,g.scopeId,z,I),ne){for(const _e in ne)_e!=="value"&&!Kn(_e)&&s(M,_e,null,ne[_e],D,I);"value"in ne&&s(M,"value",null,ne.value,D),(P=ne.onVnodeBeforeMount)&&mt(P,I,g)}Zn(M,"__vnode",g,!0),Zn(M,"__vueParentComponent",I,!0),re&&Pt(g,null,I,"beforeMount");const ue=Xc(O,ee);ue&&ee.beforeEnter(M),r(M,b,A),((P=ne&&ne.onVnodeMounted)||ue||re)&<(()=>{P&&mt(P,I,g),ue&&ee.enter(M),re&&Pt(g,null,I,"mounted")},O)},$=(g,b,A,I,O)=>{if(A&&h(g,A),I)for(let D=0;D{for(let P=M;P{const B=b.el=g.el;B.__vnode=b;let{patchFlag:M,dynamicChildren:P,dirs:ne}=b;M|=g.patchFlag&16;const W=g.props||Ee,ee=b.props||Ee;let re;if(A&&bn(A,!1),(re=ee.onVnodeBeforeUpdate)&&mt(re,A,b,g),ne&&Pt(b,g,A,"beforeUpdate"),A&&bn(A,!0),(W.innerHTML&&ee.innerHTML==null||W.textContent&&ee.textContent==null)&&c(B,""),P?R(g.dynamicChildren,P,B,A,I,gs(b,O),D):z||Y(g,b,B,null,A,I,gs(b,O),D,!1),M>0){if(M&16)j(B,W,ee,A,O);else if(M&2&&W.class!==ee.class&&s(B,"class",null,ee.class,O),M&4&&s(B,"style",W.style,ee.style,O),M&8){const ue=b.dynamicProps;for(let _e=0;_e{re&&mt(re,A,b,g),ne&&Pt(b,g,A,"updated")},I)},R=(g,b,A,I,O,D,z)=>{for(let B=0;B{if(b!==A){if(b!==Ee)for(const D in b)!Kn(D)&&!(D in A)&&s(g,D,b[D],null,O,I);for(const D in A){if(Kn(D))continue;const z=A[D],B=b[D];z!==B&&D!=="value"&&s(g,D,B,z,O,I)}"value"in A&&s(g,"value",b.value,A.value,O)}},L=(g,b,A,I,O,D,z,B,M)=>{const P=b.el=g?g.el:l(""),ne=b.anchor=g?g.anchor:l("");let{patchFlag:W,dynamicChildren:ee,slotScopeIds:re}=b;re&&(B=B?B.concat(re):re),g==null?(r(P,A,I),r(ne,A,I),J(b.children||[],A,ne,O,D,z,B,M)):W>0&&W&64&&ee&&g.dynamicChildren?(R(g.dynamicChildren,ee,A,O,D,z,B),(b.key!=null||O&&b===O.subTree)&&Jc(g,b,!0)):Y(g,b,A,ne,O,D,z,B,M)},Z=(g,b,A,I,O,D,z,B,M)=>{b.slotScopeIds=B,g==null?b.shapeFlag&512?O.ctx.activate(b,A,I,z,M):le(b,A,I,O,D,z,M):de(g,b,M)},le=(g,b,A,I,O,D,z)=>{const B=g.component=i0(g,I,O);if(eo(g)&&(B.ctx.renderer=Q),u0(B,!1,z),B.asyncDep){if(O&&O.registerDep(B,K,z),!g.el){const M=B.subTree=$e(tt);E(null,M,b,A)}}else K(B,g,b,A,O,D,z)},de=(g,b,A)=>{const I=b.component=g.component;if(Zm(g,b,A))if(I.asyncDep&&!I.asyncResolved){F(I,b,A);return}else I.next=b,I.update();else b.el=g.el,I.vnode=b},K=(g,b,A,I,O,D,z)=>{const B=()=>{if(g.isMounted){let{next:W,bu:ee,u:re,parent:ue,vnode:_e}=g;{const st=Zc(g);if(st){W&&(W.el=_e.el,F(g,W,z)),st.asyncDep.then(()=>{g.isUnmounted||B()});return}}let ve=W,ot;bn(g,!1),W?(W.el=_e.el,F(g,W,z)):W=_e,ee&&us(ee),(ot=W.props&&W.props.onVnodeBeforeUpdate)&&mt(ot,ue,W,_e),bn(g,!0);const ze=_s(g),wt=g.subTree;g.subTree=ze,y(wt,ze,u(wt.el),k(wt),g,O,D),W.el=ze.el,ve===null&&e0(g,ze.el),re&<(re,O),(ot=W.props&&W.props.onVnodeUpdated)&<(()=>mt(ot,ue,W,_e),O),kc(g)}else{let W;const{el:ee,props:re}=b,{bm:ue,m:_e,parent:ve,root:ot,type:ze}=g,wt=Wn(b);if(bn(g,!1),ue&&us(ue),!wt&&(W=re&&re.onVnodeBeforeMount)&&mt(W,ve,b),bn(g,!0),ee&&ge){const st=()=>{g.subTree=_s(g),ge(ee,g.subTree,g,O,null)};wt&&ze.__asyncHydrate?ze.__asyncHydrate(ee,g,st):st()}else{ot.ce&&ot.ce._injectChildStyle(ze);const st=g.subTree=_s(g);y(null,st,A,I,g,O,D),b.el=st.el}if(_e&<(_e,O),!wt&&(W=re&&re.onVnodeMounted)){const st=b;lt(()=>mt(W,ve,st),O)}(b.shapeFlag&256||ve&&Wn(ve.vnode)&&ve.vnode.shapeFlag&256)&&g.a&<(g.a,O),g.isMounted=!0,nm(g),b=A=I=null}};g.scope.on();const M=g.effect=new oc(B);g.scope.off();const P=g.update=M.run.bind(M),ne=g.job=M.runIfDirty.bind(M);ne.i=g,ne.id=g.uid,M.scheduler=()=>Pa(ne),bn(g,!0),P()},F=(g,b,A)=>{b.component=g;const I=g.vnode.props;g.vnode=b,g.next=null,$m(g,b.props,I,A),jm(g,b.children,A),Qt(),Il(g),Xt()},Y=(g,b,A,I,O,D,z,B,M=!1)=>{const P=g&&g.children,ne=g?g.shapeFlag:0,W=b.children,{patchFlag:ee,shapeFlag:re}=b;if(ee>0){if(ee&128){Ie(P,W,A,I,O,D,z,B,M);return}else if(ee&256){ae(P,W,A,I,O,D,z,B,M);return}}re&8?(ne&16&&Ue(P,O,D),W!==P&&c(A,W)):ne&16?re&16?Ie(P,W,A,I,O,D,z,B,M):Ue(P,O,D,!0):(ne&8&&c(A,""),re&16&&J(W,A,I,O,D,z,B,M))},ae=(g,b,A,I,O,D,z,B,M)=>{g=g||zn,b=b||zn;const P=g.length,ne=b.length,W=Math.min(P,ne);let ee;for(ee=0;eene?Ue(g,O,D,!0,!1,W):J(b,A,I,O,D,z,B,M,W)},Ie=(g,b,A,I,O,D,z,B,M)=>{let P=0;const ne=b.length;let W=g.length-1,ee=ne-1;for(;P<=W&&P<=ee;){const re=g[P],ue=b[P]=M?ln(b[P]):gt(b[P]);if(Cn(re,ue))y(re,ue,A,null,O,D,z,B,M);else break;P++}for(;P<=W&&P<=ee;){const re=g[W],ue=b[ee]=M?ln(b[ee]):gt(b[ee]);if(Cn(re,ue))y(re,ue,A,null,O,D,z,B,M);else break;W--,ee--}if(P>W){if(P<=ee){const re=ee+1,ue=reee)for(;P<=W;)pe(g[P],O,D,!0),P++;else{const re=P,ue=P,_e=new Map;for(P=ue;P<=ee;P++){const at=b[P]=M?ln(b[P]):gt(b[P]);at.key!=null&&_e.set(at.key,P)}let ve,ot=0;const ze=ee-ue+1;let wt=!1,st=0;const pr=new Array(ze);for(P=0;P=ze){pe(at,O,D,!0);continue}let Rt;if(at.key!=null)Rt=_e.get(at.key);else for(ve=ue;ve<=ee;ve++)if(pr[ve-ue]===0&&Cn(at,b[ve])){Rt=ve;break}Rt===void 0?pe(at,O,D,!0):(pr[Rt-ue]=P+1,Rt>=st?st=Rt:wt=!0,y(at,b[Rt],A,null,O,D,z,B,M),ot++)}const Al=wt?Km(pr):zn;for(ve=Al.length-1,P=ze-1;P>=0;P--){const at=ue+P,Rt=b[at],Sl=at+1{const{el:D,type:z,transition:B,children:M,shapeFlag:P}=g;if(P&6){De(g.component.subTree,b,A,I);return}if(P&128){g.suspense.move(b,A,I);return}if(P&64){z.move(g,b,A,Q);return}if(z===Je){r(D,b,A);for(let W=0;WB.enter(D),O);else{const{leave:W,delayLeave:ee,afterLeave:re}=B,ue=()=>r(D,b,A),_e=()=>{W(D,()=>{ue(),re&&re()})};ee?ee(D,ue,_e):_e()}else r(D,b,A)},pe=(g,b,A,I=!1,O=!1)=>{const{type:D,props:z,ref:B,children:M,dynamicChildren:P,shapeFlag:ne,patchFlag:W,dirs:ee,cacheIndex:re}=g;if(W===-2&&(O=!1),B!=null&&Po(B,null,A,g,!0),re!=null&&(b.renderCache[re]=void 0),ne&256){b.ctx.deactivate(g);return}const ue=ne&1&&ee,_e=!Wn(g);let ve;if(_e&&(ve=z&&z.onVnodeBeforeUnmount)&&mt(ve,b,g),ne&6)Ze(g.component,A,I);else{if(ne&128){g.suspense.unmount(A,I);return}ue&&Pt(g,null,b,"beforeUnmount"),ne&64?g.type.remove(g,b,A,Q,I):P&&!P.hasOnce&&(D!==Je||W>0&&W&64)?Ue(P,b,A,!1,!0):(D===Je&&W&384||!O&&ne&16)&&Ue(M,b,A),I&&Me(g)}(_e&&(ve=z&&z.onVnodeUnmounted)||ue)&<(()=>{ve&&mt(ve,b,g),ue&&Pt(g,null,b,"unmounted")},A)},Me=g=>{const{type:b,el:A,anchor:I,transition:O}=g;if(b===Je){pt(A,I);return}if(b===Yn){T(g);return}const D=()=>{o(A),O&&!O.persisted&&O.afterLeave&&O.afterLeave()};if(g.shapeFlag&1&&O&&!O.persisted){const{leave:z,delayLeave:B}=O,M=()=>z(A,D);B?B(g.el,D,M):M()}else D()},pt=(g,b)=>{let A;for(;g!==b;)A=p(g),o(g),g=A;o(b)},Ze=(g,b,A)=>{const{bum:I,scope:O,job:D,subTree:z,um:B,m:M,a:P}=g;Ul(M),Ul(P),I&&us(I),O.stop(),D&&(D.flags|=8,pe(z,g,b,A)),B&<(B,b),lt(()=>{g.isUnmounted=!0},b),b&&b.pendingBranch&&!b.isUnmounted&&g.asyncDep&&!g.asyncResolved&&g.suspenseId===b.pendingId&&(b.deps--,b.deps===0&&b.resolve()),om(g)},Ue=(g,b,A,I=!1,O=!1,D=0)=>{for(let z=D;z{if(g.shapeFlag&6)return k(g.component.subTree);if(g.shapeFlag&128)return g.suspense.next();const b=p(g.anchor||g.el),A=b&&b[lm];return A?p(A):b};let q=!1;const U=(g,b,A)=>{g==null?b._vnode&&pe(b._vnode,null,null,!0):y(b._vnode||null,g,b,null,null,null,A),b._vnode=g,q||(q=!0,Il(),Io(),q=!1)},Q={p:y,um:pe,m:De,r:Me,mt:le,mc:J,pc:Y,pbc:R,n:k,o:e};let fe,ge;return t&&([fe,ge]=t(Q)),{render:U,hydrate:fe,createApp:Nm(U,fe)}}function gs({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function bn({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function Xc(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Jc(e,t,n=!1){const r=e.children,o=t.children;if(se(r)&&se(o))for(let s=0;s>1,e[n[l]]0&&(t[r]=n[s-1]),n[s]=r)}}for(s=n.length,a=n[s-1];s-- >0;)n[s]=a,a=t[a];return n}function Zc(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Zc(t)}function Ul(e){if(e)for(let t=0;tNe(qm);function Ba(e,t){return Ha(e,null,t)}function ce(e,t,n){return Ha(e,t,n)}function Ha(e,t,n=Ee){const{immediate:r,deep:o,flush:s,once:a}=n,l=Ve({},n),i=t&&r||!t&&s!=="post";let f;if(er){if(s==="sync"){const h=Wm();f=h.__watcherHandles||(h.__watcherHandles=[])}else if(!i){const h=()=>{};return h.stop=Nt,h.resume=Nt,h.pause=Nt,h}}const c=He;l.call=(h,m,y)=>kt(h,c,m,y);let u=!1;s==="post"?l.scheduler=h=>{lt(h,c&&c.suspense)}:s!=="sync"&&(u=!0,l.scheduler=(h,m)=>{m?h():Pa(h)}),l.augmentJob=h=>{t&&(h.flags|=4),u&&(h.flags|=2,c&&(h.id=c.uid,h.i=c))};const p=qh(e,t,l);return er&&(f?f.push(p):i&&p()),p}function Gm(e,t,n){const r=this.proxy,o=ke(e)?e.includes(".")?ef(r,e):()=>r[e]:e.bind(r,r);let s;oe(t)?s=t:(s=t.handler,n=t);const a=to(this),l=Ha(o,s.bind(r),n);return a(),l}function ef(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;ot==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${rt(t)}Modifiers`]||e[`${gn(t)}Modifiers`];function Qm(e,t,...n){if(e.isUnmounted)return;const r=e.vnode.props||Ee;let o=n;const s=t.startsWith("update:"),a=s&&Ym(r,t.slice(7));a&&(a.trim&&(o=n.map(c=>ke(c)?c.trim():c)),a.number&&(o=n.map(nh))),sm(e,t,o);let l,i=r[l=is(t)]||r[l=is(rt(t))];!i&&s&&(i=r[l=is(gn(t))]),i&&kt(i,e,6,o);const f=r[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,kt(f,e,6,o)}}function tf(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const s=e.emits;let a={},l=!1;if(!oe(e)){const i=f=>{const c=tf(f,t,!0);c&&(l=!0,Ve(a,c))};!n&&t.mixins.length&&t.mixins.forEach(i),e.extends&&i(e.extends),e.mixins&&e.mixins.forEach(i)}return!s&&!l?(Oe(e)&&r.set(e,null),null):(se(s)?s.forEach(i=>a[i]=null):Ve(a,s),Oe(e)&&r.set(e,a),a)}function Qo(e,t){return!e||!Yr(t)?!1:(t=t.slice(2).replace(/Once$/,""),me(e,t[0].toLowerCase()+t.slice(1))||me(e,gn(t))||me(e,t))}function _s(e){const{type:t,vnode:n,proxy:r,withProxy:o,propsOptions:[s],slots:a,attrs:l,emit:i,render:f,renderCache:c,props:u,data:p,setupState:h,ctx:m,inheritAttrs:y}=e,_=Do(e);let E,w;try{if(n.shapeFlag&4){const T=o||r,V=T;E=gt(f.call(V,T,c,u,h,p,m)),w=l}else{const T=t;E=gt(T.length>1?T(u,{attrs:l,slots:a,emit:i}):T(u,null)),w=t.props?l:Xm(l)}}catch(T){Rr.length=0,Zr(T,e,1),E=$e(tt)}let v=E;if(w&&y!==!1){const T=Object.keys(w),{shapeFlag:V}=v;T.length&&V&7&&(s&&T.some(wa)&&(w=Jm(w,s)),v=hn(v,w,!1,!0))}return n.dirs&&(v=hn(v,null,!1,!0),v.dirs=v.dirs?v.dirs.concat(n.dirs):n.dirs),n.transition&&Pn(v,n.transition),E=v,Do(_),E}const Xm=e=>{let t;for(const n in e)(n==="class"||n==="style"||Yr(n))&&((t||(t={}))[n]=e[n]);return t},Jm=(e,t)=>{const n={};for(const r in e)(!wa(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Zm(e,t,n){const{props:r,children:o,component:s}=e,{props:a,children:l,patchFlag:i}=t,f=s.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&i>=0){if(i&1024)return!0;if(i&16)return r?zl(r,a,f):!!a;if(i&8){const c=t.dynamicProps;for(let u=0;ue.__isSuspense;function rf(e,t){t&&t.pendingBranch?se(e)?t.effects.push(...e):t.effects.push(e):Zh(e)}const Je=Symbol.for("v-fgt"),pn=Symbol.for("v-txt"),tt=Symbol.for("v-cmt"),Yn=Symbol.for("v-stc"),Rr=[];let ct=null;function PE(e=!1){Rr.push(ct=e?null:[])}function t0(){Rr.pop(),ct=Rr[Rr.length-1]||null}let Fr=1;function Kl(e){Fr+=e,e<0&&ct&&(ct.hasOnce=!0)}function n0(e){return e.dynamicChildren=Fr>0?ct||zn:null,t0(),Fr>0&&ct&&ct.push(e),e}function LE(e,t,n,r,o,s){return n0(sf(e,t,n,r,o,s,!0))}function Vo(e){return e?e.__v_isVNode===!0:!1}function Cn(e,t){return e.type===t.type&&e.key===t.key}const of=({key:e})=>e??null,To=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ke(e)||Pe(e)||oe(e)?{i:yt,r:e,k:t,f:!!n}:e:null);function sf(e,t=null,n=null,r=0,o=null,s=e===Je?0:1,a=!1,l=!1){const i={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&of(t),ref:t&&To(t),scopeId:Oc,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:s,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:yt};return l?(ja(i,n),s&128&&e.normalize(i)):n&&(i.shapeFlag|=ke(n)?8:16),Fr>0&&!a&&ct&&(i.patchFlag>0||s&6)&&i.patchFlag!==32&&ct.push(i),i}const $e=r0;function r0(e,t=null,n=null,r=0,o=null,s=!1){if((!e||e===km)&&(e=tt),Vo(e)){const l=hn(e,t,!0);return n&&ja(l,n),Fr>0&&!s&&ct&&(l.shapeFlag&6?ct[ct.indexOf(e)]=l:ct.push(l)),l.patchFlag=-2,l}if(m0(e)&&(e=e.__vccOpts),t){t=o0(t);let{class:l,style:i}=t;l&&!ke(l)&&(t.class=Ko(l)),Oe(i)&&(Da(i)&&!se(i)&&(i=Ve({},i)),t.style=zo(i))}const a=ke(e)?1:nf(e)?128:xc(e)?64:Oe(e)?4:oe(e)?2:0;return sf(e,t,n,r,o,a,s,!0)}function o0(e){return e?Da(e)||zc(e)?Ve({},e):e:null}function hn(e,t,n=!1,r=!1){const{props:o,ref:s,patchFlag:a,children:l,transition:i}=e,f=t?s0(o||{},t):o,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&of(f),ref:t&&t.ref?n&&s?se(s)?s.concat(To(t)):[s,To(t)]:To(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Je?a===-1?16:a|16:a,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:i,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&hn(e.ssContent),ssFallback:e.ssFallback&&hn(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return i&&r&&Pn(c,i.clone(c)),c}function af(e=" ",t=0){return $e(pn,null,e,t)}function VE(e,t){const n=$e(Yn,null,e);return n.staticCount=t,n}function gt(e){return e==null||typeof e=="boolean"?$e(tt):se(e)?$e(Je,null,e.slice()):Vo(e)?ln(e):$e(pn,null,String(e))}function ln(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:hn(e)}function ja(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(se(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),ja(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!zc(t)?t._ctx=yt:o===3&&yt&&(yt.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else oe(t)?(t={default:t,_ctx:yt},n=32):(t=String(t),r&64?(n=16,t=[af(t)]):n=8);e.children=t,e.shapeFlag|=n}function s0(...e){const t={};for(let n=0;nHe||yt;let No,Gs;{const e=Uo(),t=(n,r)=>{let o;return(o=e[n])||(o=e[n]=[]),o.push(r),s=>{o.length>1?o.forEach(a=>a(s)):o[0](s)}};No=t("__VUE_INSTANCE_SETTERS__",n=>He=n),Gs=t("__VUE_SSR_SETTERS__",n=>er=n)}const to=e=>{const t=He;return No(e),e.scope.on(),()=>{e.scope.off(),No(t)}},ql=()=>{He&&He.scope.off(),No(null)};function lf(e){return e.vnode.shapeFlag&4}let er=!1;function u0(e,t=!1,n=!1){t&&Gs(t);const{props:r,children:o}=e.vnode,s=lf(e);Mm(e,r,s,t),Hm(e,o,n);const a=s?c0(e,t):void 0;return t&&Gs(!1),a}function c0(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,xm);const{setup:r}=n;if(r){Qt();const o=e.setupContext=r.length>1?d0(e):null,s=to(e),a=ur(r,e,0,[e.props,o]),l=tc(a);if(Xt(),s(),(l||e.sp)&&!Wn(e)&&Na(e),l){if(a.then(ql,ql),t)return a.then(i=>{Wl(e,i,t)}).catch(i=>{Zr(i,e,0)});e.asyncDep=a}else Wl(e,a,t)}else uf(e,t)}function Wl(e,t,n){oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Oe(t)&&(e.devtoolsRawSetupState=t,e.setupState=Ec(t)),uf(e,n)}let Gl;function uf(e,t,n){const r=e.type;if(!e.render){if(!t&&Gl&&!r.render){const o=r.template||$a(e).template;if(o){const{isCustomElement:s,compilerOptions:a}=e.appContext.config,{delimiters:l,compilerOptions:i}=r,f=Ve(Ve({isCustomElement:s,delimiters:l},a),i);r.render=Gl(o,f)}}e.render=r.render||Nt}{const o=to(e);Qt();try{Rm(e)}finally{Xt(),o()}}}const f0={get(e,t){return Ke(e,"get",""),e[t]}};function d0(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,f0),slots:e.slots,emit:e.emit,expose:t}}function Ua(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Ec(Nh(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in xr)return xr[n](e)},has(t,n){return n in t||n in xr}})):e.proxy}const p0=/(?:^|[-_])(\w)/g,h0=e=>e.replace(p0,t=>t.toUpperCase()).replace(/[-_]/g,"");function cf(e,t=!0){return oe(e)?e.displayName||e.name:e.name||t&&e.__name}function ff(e,t,n=!1){let r=cf(t);if(!r&&t.__file){const o=t.__file.match(/([^/\\]+)\.\w+$/);o&&(r=o[1])}if(!r&&e&&e.parent){const o=s=>{for(const a in s)if(s[a]===t)return a};r=o(e.components||e.parent.type.components)||o(e.appContext.components)}return r?h0(r):n?"App":"Anonymous"}function m0(e){return oe(e)&&"__vccOpts"in e}const S=(e,t)=>zh(e,t,er);function d(e,t,n){const r=arguments.length;return r===2?Oe(t)&&!se(t)?Vo(t)?$e(e,null,[t]):$e(e,t):$e(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Vo(n)&&(n=[n]),$e(e,t,n))}const Yl="3.5.12";/** +* @vue/runtime-dom v3.5.12 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ys;const Ql=typeof window<"u"&&window.trustedTypes;if(Ql)try{Ys=Ql.createPolicy("vue",{createHTML:e=>e})}catch{}const df=Ys?e=>Ys.createHTML(e):e=>e,v0="http://www.w3.org/2000/svg",g0="http://www.w3.org/1998/Math/MathML",Kt=typeof document<"u"?document:null,Xl=Kt&&Kt.createElement("template"),_0={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t==="svg"?Kt.createElementNS(v0,e):t==="mathml"?Kt.createElementNS(g0,e):n?Kt.createElement(e,{is:n}):Kt.createElement(e);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Kt.createTextNode(e),createComment:e=>Kt.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Kt.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,s){const a=n?n.previousSibling:t.lastChild;if(o&&(o===s||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===s||!(o=o.nextSibling)););else{Xl.innerHTML=df(r==="svg"?`${e}`:r==="mathml"?`${e}`:e);const l=Xl.content;if(r==="svg"||r==="mathml"){const i=l.firstChild;for(;i.firstChild;)l.appendChild(i.firstChild);l.removeChild(i)}t.insertBefore(l,n)}return[a?a.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},tn="transition",mr="animation",tr=Symbol("_vtc"),pf={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},hf=Ve({},Ic,pf),y0=e=>(e.displayName="Transition",e.props=hf,e),nr=y0((e,{slots:t})=>d(um,mf(e),t)),wn=(e,t=[])=>{se(e)?e.forEach(n=>n(...t)):e&&e(...t)},Jl=e=>e?se(e)?e.some(t=>t.length>1):e.length>1:!1;function mf(e){const t={};for(const L in e)L in pf||(t[L]=e[L]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:s=`${n}-enter-from`,enterActiveClass:a=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:i=s,appearActiveClass:f=a,appearToClass:c=l,leaveFromClass:u=`${n}-leave-from`,leaveActiveClass:p=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,m=E0(o),y=m&&m[0],_=m&&m[1],{onBeforeEnter:E,onEnter:w,onEnterCancelled:v,onLeave:T,onLeaveCancelled:V,onBeforeAppear:H=E,onAppear:$=w,onAppearCancelled:J=v}=t,N=(L,Z,le)=>{on(L,Z?c:l),on(L,Z?f:a),le&&le()},R=(L,Z)=>{L._isLeaving=!1,on(L,u),on(L,h),on(L,p),Z&&Z()},j=L=>(Z,le)=>{const de=L?$:w,K=()=>N(Z,L,le);wn(de,[Z,K]),Zl(()=>{on(Z,L?i:s),Ut(Z,L?c:l),Jl(de)||ei(Z,r,y,K)})};return Ve(t,{onBeforeEnter(L){wn(E,[L]),Ut(L,s),Ut(L,a)},onBeforeAppear(L){wn(H,[L]),Ut(L,i),Ut(L,f)},onEnter:j(!1),onAppear:j(!0),onLeave(L,Z){L._isLeaving=!0;const le=()=>R(L,Z);Ut(L,u),Ut(L,p),gf(),Zl(()=>{L._isLeaving&&(on(L,u),Ut(L,h),Jl(T)||ei(L,r,_,le))}),wn(T,[L,le])},onEnterCancelled(L){N(L,!1),wn(v,[L])},onAppearCancelled(L){N(L,!0),wn(J,[L])},onLeaveCancelled(L){R(L),wn(V,[L])}})}function E0(e){if(e==null)return null;if(Oe(e))return[ys(e.enter),ys(e.leave)];{const t=ys(e);return[t,t]}}function ys(e){return rh(e)}function Ut(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[tr]||(e[tr]=new Set)).add(t)}function on(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[tr];n&&(n.delete(t),n.size||(e[tr]=void 0))}function Zl(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let b0=0;function ei(e,t,n,r){const o=e._endId=++b0,s=()=>{o===e._endId&&r()};if(n!=null)return setTimeout(s,n);const{type:a,timeout:l,propCount:i}=vf(e,t);if(!a)return r();const f=a+"end";let c=0;const u=()=>{e.removeEventListener(f,p),s()},p=h=>{h.target===e&&++c>=i&&u()};setTimeout(()=>{c(n[m]||"").split(", "),o=r(`${tn}Delay`),s=r(`${tn}Duration`),a=ti(o,s),l=r(`${mr}Delay`),i=r(`${mr}Duration`),f=ti(l,i);let c=null,u=0,p=0;t===tn?a>0&&(c=tn,u=a,p=s.length):t===mr?f>0&&(c=mr,u=f,p=i.length):(u=Math.max(a,f),c=u>0?a>f?tn:mr:null,p=c?c===tn?s.length:i.length:0);const h=c===tn&&/\b(transform|all)(,|$)/.test(r(`${tn}Property`).toString());return{type:c,timeout:u,propCount:p,hasTransform:h}}function ti(e,t){for(;e.lengthni(n)+ni(e[r])))}function ni(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function gf(){return document.body.offsetHeight}function w0(e,t,n){const r=e[tr];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const ri=Symbol("_vod"),T0=Symbol("_vsh"),A0=Symbol(""),S0=/(^|;)\s*display\s*:/;function C0(e,t,n){const r=e.style,o=ke(n);let s=!1;if(n&&!o){if(t)if(ke(t))for(const a of t.split(";")){const l=a.slice(0,a.indexOf(":")).trim();n[l]==null&&Ao(r,l,"")}else for(const a in t)n[a]==null&&Ao(r,a,"");for(const a in n)a==="display"&&(s=!0),Ao(r,a,n[a])}else if(o){if(t!==n){const a=r[A0];a&&(n+=";"+a),r.cssText=n,s=S0.test(n)}}else t&&e.removeAttribute("style");ri in e&&(e[ri]=s?r.display:"",e[T0]&&(r.display="none"))}const oi=/\s*!important$/;function Ao(e,t,n){if(se(n))n.forEach(r=>Ao(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=k0(e,t);oi.test(n)?e.setProperty(gn(r),n.replace(oi,""),"important"):e[r]=n}}const si=["Webkit","Moz","ms"],Es={};function k0(e,t){const n=Es[t];if(n)return n;let r=rt(t);if(r!=="filter"&&r in e)return Es[t]=r;r=Qr(r);for(let o=0;obs||(D0.then(()=>bs=0),bs=Date.now());function L0(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;kt(V0(r,n.value),t,5,[r])};return n.value=e,n.attached=P0(),n}function V0(e,t){if(se(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const fi=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,N0=(e,t,n,r,o,s)=>{const a=o==="svg";t==="class"?w0(e,r,a):t==="style"?C0(e,n,r):Yr(t)?wa(t)||R0(e,t,n,r,s):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):M0(e,t,r,a))?(ii(e,t,r),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&li(e,t,r,a,s,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!ke(r))?ii(e,rt(t),r,s,t):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),li(e,t,r,a))};function M0(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&fi(t)&&oe(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return fi(t)&&ke(n)?!1:t in e}const _f=new WeakMap,yf=new WeakMap,Mo=Symbol("_moveCb"),di=Symbol("_enterCb"),$0=e=>(delete e.props.mode,e),F0=$0({name:"TransitionGroup",props:Ve({},hf,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=Nn(),r=Rc();let o,s;return Fc(()=>{if(!o.length)return;const a=e.moveClass||`${e.name||"v"}-move`;if(!U0(o[0].el,n.vnode.el,a))return;o.forEach(B0),o.forEach(H0);const l=o.filter(j0);gf(),l.forEach(i=>{const f=i.el,c=f.style;Ut(f,a),c.transform=c.webkitTransform=c.transitionDuration="";const u=f[Mo]=p=>{p&&p.target!==f||(!p||/transform$/.test(p.propertyName))&&(f.removeEventListener("transitionend",u),f[Mo]=null,on(f,a))};f.addEventListener("transitionend",u)})}),()=>{const a=ie(e),l=mf(a);let i=a.tag||Je;if(o=[],s)for(let f=0;f{l.split(/\s+/).forEach(i=>i&&r.classList.remove(i))}),n.split(/\s+/).forEach(l=>l&&r.classList.add(l)),r.style.display="none";const s=t.nodeType===1?t:t.parentNode;s.appendChild(r);const{hasTransform:a}=vf(r);return s.removeChild(r),a}const z0=Ve({patchProp:N0},_0);let ws,pi=!1;function K0(){return ws=pi?ws:Um(z0),pi=!0,ws}const q0=(...e)=>{const t=K0().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=G0(r);if(o)return n(o,!0,W0(o))},t};function W0(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function G0(e){return ke(e)?document.querySelector(e):e}var no=e=>/^[a-z][a-z0-9+.-]*:/.test(e)||e.startsWith("//"),Y0=/.md((\?|#).*)?$/,za=(e,t="/")=>no(e)||e.startsWith("/")&&!e.startsWith(t)&&!Y0.test(e),ro=e=>/^(https?:)?\/\//.test(e),hi=e=>{if(!e||e.endsWith("/"))return e;let t=e.replace(/(^|\/)README.md$/i,"$1index.html");return t.endsWith(".md")?t=`${t.substring(0,t.length-3)}.html`:t.endsWith(".html")||(t=`${t}.html`),t.endsWith("/index.html")&&(t=t.substring(0,t.length-10)),t},Q0="http://.",X0=(e,t)=>{if(!e.startsWith("/")&&t){const n=t.slice(0,t.lastIndexOf("/"));return hi(new URL(`${n}/${e}`,Q0).pathname)}return hi(e)},J0=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const s=o.split("/").length-r.split("/").length;return s!==0?s:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"},Z0=/(#|\?)/,bf=e=>{const[t,...n]=e.split(Z0);return{pathname:t,hashAndQueries:n.join("")}},e1=["link","meta","script","style","noscript","template"],t1=["title","base"],n1=([e,t,n])=>t1.includes(e)?e:e1.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([r,o])=>typeof o=="boolean"?o?[r,""]:null:[r,o]).filter(r=>r!=null).sort(([r],[o])=>r.localeCompare(o)),n]):null,r1=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=n1(r);o&&!t.has(o)&&(t.add(o),n.push(r))}),n},o1=e=>e.startsWith("/")?e:`/${e}`,wf=e=>e.endsWith("/")||e.endsWith(".html")?e:`${e}/`,Ka=e=>e.endsWith("/")?e.slice(0,-1):e,Tf=e=>e.startsWith("/")?e.slice(1):e,oo=e=>Object.prototype.toString.call(e)==="[object Object]",Le=e=>typeof e=="string";const s1=JSON.parse("{}"),a1=Object.fromEntries([["/CHANGELOG.html",{loader:()=>C(()=>import("./CHANGELOG.html-Bnklulr8.js"),__vite__mapDeps([0,1])),meta:{t:""}}],["/CODE_OF_CONDUCT.html",{loader:()=>C(()=>import("./CODE_OF_CONDUCT.html-D7Z-kzHo.js"),__vite__mapDeps([2,1])),meta:{t:"Contributor Covenant Code of Conduct"}}],["/CONTRIBUTING.html",{loader:()=>C(()=>import("./CONTRIBUTING.html-DoGQ344g.js"),__vite__mapDeps([3,1])),meta:{t:"CONTRIBUTING"}}],["/LICENSE.html",{loader:()=>C(()=>import("./LICENSE.html-BkNHjkmj.js"),__vite__mapDeps([4,1])),meta:{t:"LICENSE"}}],["/",{loader:()=>C(()=>import("./index.html-1dvphctW.js"),__vite__mapDeps([5,1])),meta:{t:"Ocelot.Social"}}],["/SUMMARY.html",{loader:()=>C(()=>import("./SUMMARY.html-DlsPW9yB.js"),__vite__mapDeps([6,1])),meta:{t:"Table of contents"}}],["/documentation.html",{loader:()=>C(()=>import("./documentation.html-B-SWCtsa.js"),__vite__mapDeps([7,1])),meta:{t:"Documentation"}}],["/testing.html",{loader:()=>C(()=>import("./testing.html-DIbeaaFd.js"),__vite__mapDeps([8,1])),meta:{t:"Testing Guide"}}],["/backend/",{loader:()=>C(()=>import("./index.html-D1cGf28t.js"),__vite__mapDeps([9,1])),meta:{t:"Backend"}}],["/backend/graphql.html",{loader:()=>C(()=>import("./graphql.html-hAUzkKsr.js"),__vite__mapDeps([10,11,1])),meta:{t:"GraphQL with Apollo"}}],["/backend/neo4j-graphql-js.html",{loader:()=>C(()=>import("./neo4j-graphql-js.html-CoZVYA65.js"),__vite__mapDeps([12,1])),meta:{t:"neo4j-graphql.js"}}],["/backend/testing.html",{loader:()=>C(()=>import("./testing.html-BI46pcUx.js"),__vite__mapDeps([13,1])),meta:{t:"Unit Testing"}}],["/cypress/",{loader:()=>C(()=>import("./index.html-vLTkaCiA.js"),__vite__mapDeps([14,1])),meta:{t:"End-to-End Testing"}}],["/cypress/features.html",{loader:()=>C(()=>import("./features.html-jBF7v5Tb.js"),__vite__mapDeps([15,1])),meta:{t:"Network Specification"}}],["/deployment/TODO-next-update.html",{loader:()=>C(()=>import("./TODO-next-update.html-Dbd1HQYH.js"),__vite__mapDeps([16,1])),meta:{t:"Todo For Next Update"}}],["/deployment/deployment-values.html",{loader:()=>C(()=>import("./deployment-values.html-BuK-P7uz.js"),__vite__mapDeps([17,1])),meta:{t:"Deployment Values"}}],["/neo4j/",{loader:()=>C(()=>import("./index.html-DA6JIG7N.js"),__vite__mapDeps([18,1])),meta:{t:"Neo4j 4.4"}}],["/styleguide/",{loader:()=>C(()=>import("./index.html-DTeYXEMn.js"),__vite__mapDeps([19,1])),meta:{t:"Human-Connection Styleguide"}}],["/webapp/",{loader:()=>C(()=>import("./index.html-BotCCvmf.js"),__vite__mapDeps([20,1])),meta:{t:"Webapp"}}],["/webapp/components.html",{loader:()=>C(()=>import("./components.html-eb5EQ5pR.js"),__vite__mapDeps([21,1])),meta:{t:"Components – Code Guidelines"}}],["/webapp/html.html",{loader:()=>C(()=>import("./html.html-D297kDdJ.js"),__vite__mapDeps([22,1])),meta:{t:"HTML – Code Guidelines"}}],["/webapp/scss.html",{loader:()=>C(()=>import("./scss.html-B5_5w6uH.js"),__vite__mapDeps([23,1])),meta:{t:"SCSS - Code Guidelines"}}],["/webapp/testing.html",{loader:()=>C(()=>import("./testing.html-B-yKt6km.js"),__vite__mapDeps([24,1])),meta:{t:"Component Testing"}}],["/webapp/vue.html",{loader:()=>C(()=>import("./vue.html-usvwTHmn.js"),__vite__mapDeps([25,1])),meta:{t:"Vue – Code Guidelines"}}],["/deployment/styleguide/",{loader:()=>C(()=>import("./index.html-e225B3G6.js"),__vite__mapDeps([26,1])),meta:{t:"Styleguide Deployment"}}],["/packages/ui/CONTRIBUTING.html",{loader:()=>C(()=>import("./CONTRIBUTING.html-vtvi86EK.js"),__vite__mapDeps([27,1])),meta:{t:"Contributing to @ocelot-social/ui"}}],["/packages/ui/KATALOG.html",{loader:()=>C(()=>import("./KATALOG.html-mRGwYwFN.js"),__vite__mapDeps([28,1])),meta:{t:"Komponenten-Katalog"}}],["/packages/ui/PROJEKT.html",{loader:()=>C(()=>import("./PROJEKT.html-BZRNQpP2.js"),__vite__mapDeps([29,1])),meta:{t:"@ocelot-social/ui - Projektdokumentation"}}],["/packages/ui/",{loader:()=>C(()=>import("./index.html-CvqC5bIY.js"),__vite__mapDeps([30,1])),meta:{t:"@ocelot-social/ui"}}],["/webapp/maintenance/",{loader:()=>C(()=>import("./index.html-CMfno-Jk.js"),__vite__mapDeps([31,1])),meta:{t:"Maintenance Mode"}}],["/backend/src/graphql/GraphQL-Playground.html",{loader:()=>C(()=>import("./GraphQL-Playground.html-KHcgqCNs.js"),__vite__mapDeps([32,11,1])),meta:{t:"GraphQL Playground"}}],["/webapp/components/Category/",{loader:()=>C(()=>import("./index.html-Cei9bcC1.js"),__vite__mapDeps([33,1])),meta:{t:""}}],["/webapp/components/DateTime/",{loader:()=>C(()=>import("./index.html-kBh9kVNW.js"),__vite__mapDeps([34,1])),meta:{t:""}}],["/webapp/components/Logo/demo.html",{loader:()=>C(()=>import("./demo.html-BiUsynyZ.js"),__vite__mapDeps([35,1])),meta:{t:"Basic usage"}}],["/styleguide/src/styleguide/docs/DataDisplay.html",{loader:()=>C(()=>import("./DataDisplay.html-Sq6mPmsX.js"),__vite__mapDeps([36,1])),meta:{t:""}}],["/styleguide/src/styleguide/docs/DesignTokens.html",{loader:()=>C(()=>import("./DesignTokens.html-BMTgeCjs.js"),__vite__mapDeps([37,1])),meta:{t:""}}],["/styleguide/src/styleguide/docs/Introduction.html",{loader:()=>C(()=>import("./Introduction.html-BLSaoncO.js"),__vite__mapDeps([38,1])),meta:{t:""}}],["/styleguide/src/styleguide/docs/Layout.html",{loader:()=>C(()=>import("./Layout.html-47srRE8z.js"),__vite__mapDeps([39,1])),meta:{t:""}}],["/styleguide/src/styleguide/docs/Navigation.html",{loader:()=>C(()=>import("./Navigation.html-CYz7rQzP.js"),__vite__mapDeps([40,1])),meta:{t:""}}],["/styleguide/src/styleguide/docs/Typography.html",{loader:()=>C(()=>import("./Typography.html-DOSESWuO.js"),__vite__mapDeps([41,1])),meta:{t:""}}],["/packages/ui/src/components/OsButton/STATUS.html",{loader:()=>C(()=>import("./STATUS.html-BXjDgreh.js"),__vite__mapDeps([42,1])),meta:{t:"OsButton Status"}}],["/webapp/static/img/mapbox/marker-icons/",{loader:()=>C(()=>import("./index.html-Cww0Dhaz.js"),__vite__mapDeps([43,1])),meta:{t:"Mabbox markers"}}],["/styleguide/src/system/components/data-display/Avatar/demo.html",{loader:()=>C(()=>import("./demo.html-B0pnlV6F.js"),__vite__mapDeps([44,1])),meta:{t:""}}],["/styleguide/src/system/components/data-display/CopyField/demo.html",{loader:()=>C(()=>import("./demo.html-CW3cD-H7.js"),__vite__mapDeps([45,1])),meta:{t:""}}],["/styleguide/src/system/components/data-display/List/demo.html",{loader:()=>C(()=>import("./demo.html-6dfjrebI.js"),__vite__mapDeps([46,1])),meta:{t:""}}],["/styleguide/src/system/components/data-display/Number/demo.html",{loader:()=>C(()=>import("./demo.html-C6Qxo9Yj.js"),__vite__mapDeps([47,1])),meta:{t:""}}],["/styleguide/src/system/components/data-display/Table/demo.html",{loader:()=>C(()=>import("./demo.html-Cry2GElr.js"),__vite__mapDeps([48,1])),meta:{t:""}}],["/styleguide/src/system/components/data-input/Form/demo.html",{loader:()=>C(()=>import("./demo.html-D5WfjYVc.js"),__vite__mapDeps([49,1])),meta:{t:""}}],["/styleguide/src/system/components/data-input/Input/demo.html",{loader:()=>C(()=>import("./demo.html-DgTy1wh7.js"),__vite__mapDeps([50,1])),meta:{t:""}}],["/styleguide/src/system/components/data-input/Radio/demo.html",{loader:()=>C(()=>import("./demo.html-BJe7I_KV.js"),__vite__mapDeps([51,1])),meta:{t:""}}],["/styleguide/src/system/components/data-input/Select/demo.html",{loader:()=>C(()=>import("./demo.html-4tqTFmIl.js"),__vite__mapDeps([52,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Card/demo.html",{loader:()=>C(()=>import("./demo.html-DYuC5F42.js"),__vite__mapDeps([53,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Container/demo.html",{loader:()=>C(()=>import("./demo.html-yVAERFv_.js"),__vite__mapDeps([54,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Flex/demo.html",{loader:()=>C(()=>import("./demo.html-BvyZLl5C.js"),__vite__mapDeps([55,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Grid/demo.html",{loader:()=>C(()=>import("./demo.html-BycQma2M.js"),__vite__mapDeps([56,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Modal/demo.html",{loader:()=>C(()=>import("./demo.html-DtB7qtVV.js"),__vite__mapDeps([57,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Page/demo.html",{loader:()=>C(()=>import("./demo.html-DzDfUj7H.js"),__vite__mapDeps([58,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/PageTitle/demo.html",{loader:()=>C(()=>import("./demo.html-C19sXN7o.js"),__vite__mapDeps([59,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Placeholder/demo.html",{loader:()=>C(()=>import("./demo.html-Kr4R8KpK.js"),__vite__mapDeps([60,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Section/demo.html",{loader:()=>C(()=>import("./demo.html-BF4J6jMP.js"),__vite__mapDeps([61,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Space/demo.html",{loader:()=>C(()=>import("./demo.html-BI-OLisc.js"),__vite__mapDeps([62,1])),meta:{t:""}}],["/styleguide/src/system/components/layout/Spinner/demo.html",{loader:()=>C(()=>import("./demo.html-B9TFHr4o.js"),__vite__mapDeps([63,1])),meta:{t:""}}],["/styleguide/src/system/components/navigation/Button/demo.html",{loader:()=>C(()=>import("./demo.html-CWpO2OIy.js"),__vite__mapDeps([64,1])),meta:{t:""}}],["/styleguide/src/system/components/navigation/Menu/demo.html",{loader:()=>C(()=>import("./demo.html-pp2XB-6I.js"),__vite__mapDeps([65,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Chip/demo.html",{loader:()=>C(()=>import("./demo.html-ESNHpVvJ.js"),__vite__mapDeps([66,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Code/demo.html",{loader:()=>C(()=>import("./demo.html-CREqiFsx.js"),__vite__mapDeps([67,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Heading/demo.html",{loader:()=>C(()=>import("./demo.html-DiSwsATb.js"),__vite__mapDeps([68,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Icon/demo.html",{loader:()=>C(()=>import("./demo.html-7n0yJEH_.js"),__vite__mapDeps([69,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Logo/demo.html",{loader:()=>C(()=>import("./demo.html-B_2DIOaF.js"),__vite__mapDeps([70,1])),meta:{t:"Basic usage"}}],["/styleguide/src/system/components/typography/Tag/demo.html",{loader:()=>C(()=>import("./demo.html-DWLc6gFO.js"),__vite__mapDeps([71,1])),meta:{t:""}}],["/styleguide/src/system/components/typography/Text/demo.html",{loader:()=>C(()=>import("./demo.html-DmAuEWx0.js"),__vite__mapDeps([72,1])),meta:{t:""}}],["/404.html",{loader:()=>C(()=>import("./404.html-CRHdR_pJ.js"),__vite__mapDeps([73,1])),meta:{t:""}}],["/deployment/",{loader:()=>C(()=>import("./index.html-Buh1ncoF.js"),__vite__mapDeps([74,1])),meta:{t:"Deployment"}}],["/packages/",{loader:()=>C(()=>import("./index.html-DGSGkBMu.js"),__vite__mapDeps([75,1])),meta:{t:"Packages"}}],["/backend/src/graphql/",{loader:()=>C(()=>import("./index.html-JQc0YsYs.js"),__vite__mapDeps([76,1])),meta:{t:"Graphql"}}],["/backend/src/",{loader:()=>C(()=>import("./index.html-TA2-vxe5.js"),__vite__mapDeps([77,1])),meta:{t:"Src"}}],["/webapp/components/",{loader:()=>C(()=>import("./index.html-trrnbNUq.js"),__vite__mapDeps([78,1])),meta:{t:"Components"}}],["/webapp/components/Logo/",{loader:()=>C(()=>import("./index.html-cfpWt2jJ.js"),__vite__mapDeps([79,1])),meta:{t:"Logo"}}],["/styleguide/src/styleguide/docs/",{loader:()=>C(()=>import("./index.html-D6JUTu4R.js"),__vite__mapDeps([80,1])),meta:{t:"Docs"}}],["/styleguide/src/styleguide/",{loader:()=>C(()=>import("./index.html-Bo7Ljf3a.js"),__vite__mapDeps([81,1])),meta:{t:"Styleguide"}}],["/styleguide/src/",{loader:()=>C(()=>import("./index.html-Ch-l52j_.js"),__vite__mapDeps([82,1])),meta:{t:"Src"}}],["/packages/ui/src/components/OsButton/",{loader:()=>C(()=>import("./index.html-IpTOngCN.js"),__vite__mapDeps([83,1])),meta:{t:"Os Button"}}],["/packages/ui/src/components/",{loader:()=>C(()=>import("./index.html-LVrUA5Ul.js"),__vite__mapDeps([84,1])),meta:{t:"Components"}}],["/packages/ui/src/",{loader:()=>C(()=>import("./index.html-NfLl_DKG.js"),__vite__mapDeps([85,1])),meta:{t:"Src"}}],["/webapp/static/img/mapbox/",{loader:()=>C(()=>import("./index.html-DVXBW6uR.js"),__vite__mapDeps([86,1])),meta:{t:"Mapbox"}}],["/webapp/static/img/",{loader:()=>C(()=>import("./index.html-B9A0hIU3.js"),__vite__mapDeps([87,1])),meta:{t:"Img"}}],["/webapp/static/",{loader:()=>C(()=>import("./index.html-DzJKTok5.js"),__vite__mapDeps([88,1])),meta:{t:"Static"}}],["/styleguide/src/system/components/data-display/Avatar/",{loader:()=>C(()=>import("./index.html-Bnl9T6N5.js"),__vite__mapDeps([89,1])),meta:{t:"Avatar"}}],["/styleguide/src/system/components/data-display/",{loader:()=>C(()=>import("./index.html-CT0wGi5f.js"),__vite__mapDeps([90,1])),meta:{t:"Data Display"}}],["/styleguide/src/system/components/",{loader:()=>C(()=>import("./index.html-DwrHoA30.js"),__vite__mapDeps([91,1])),meta:{t:"Components"}}],["/styleguide/src/system/",{loader:()=>C(()=>import("./index.html-BSwbVjcn.js"),__vite__mapDeps([92,1])),meta:{t:"System"}}],["/styleguide/src/system/components/data-display/CopyField/",{loader:()=>C(()=>import("./index.html-BtnavBbg.js"),__vite__mapDeps([93,1])),meta:{t:"Copy Field"}}],["/styleguide/src/system/components/data-display/List/",{loader:()=>C(()=>import("./index.html-D3mIxgfr.js"),__vite__mapDeps([94,1])),meta:{t:"List"}}],["/styleguide/src/system/components/data-display/Number/",{loader:()=>C(()=>import("./index.html-BrgOXTUr.js"),__vite__mapDeps([95,1])),meta:{t:"Number"}}],["/styleguide/src/system/components/data-display/Table/",{loader:()=>C(()=>import("./index.html-CKtpFMus.js"),__vite__mapDeps([96,1])),meta:{t:"Table"}}],["/styleguide/src/system/components/data-input/Form/",{loader:()=>C(()=>import("./index.html-BSOluCGA.js"),__vite__mapDeps([97,1])),meta:{t:"Form"}}],["/styleguide/src/system/components/data-input/",{loader:()=>C(()=>import("./index.html-CrpjDBoX.js"),__vite__mapDeps([98,1])),meta:{t:"Data Input"}}],["/styleguide/src/system/components/data-input/Input/",{loader:()=>C(()=>import("./index.html-CZTXNS31.js"),__vite__mapDeps([99,1])),meta:{t:"Input"}}],["/styleguide/src/system/components/data-input/Radio/",{loader:()=>C(()=>import("./index.html-Bm1PPhY4.js"),__vite__mapDeps([100,1])),meta:{t:"Radio"}}],["/styleguide/src/system/components/data-input/Select/",{loader:()=>C(()=>import("./index.html-CI2ipqR1.js"),__vite__mapDeps([101,1])),meta:{t:"Select"}}],["/styleguide/src/system/components/layout/Card/",{loader:()=>C(()=>import("./index.html-Bbb8AMlW.js"),__vite__mapDeps([102,1])),meta:{t:"Card"}}],["/styleguide/src/system/components/layout/",{loader:()=>C(()=>import("./index.html-CsIJCUeh.js"),__vite__mapDeps([103,1])),meta:{t:"Layout"}}],["/styleguide/src/system/components/layout/Container/",{loader:()=>C(()=>import("./index.html-B2TWVP9L.js"),__vite__mapDeps([104,1])),meta:{t:"Container"}}],["/styleguide/src/system/components/layout/Flex/",{loader:()=>C(()=>import("./index.html-Bwei2ul_.js"),__vite__mapDeps([105,1])),meta:{t:"Flex"}}],["/styleguide/src/system/components/layout/Grid/",{loader:()=>C(()=>import("./index.html-BsZpCI8J.js"),__vite__mapDeps([106,1])),meta:{t:"Grid"}}],["/styleguide/src/system/components/layout/Modal/",{loader:()=>C(()=>import("./index.html-BrAtRvv1.js"),__vite__mapDeps([107,1])),meta:{t:"Modal"}}],["/styleguide/src/system/components/layout/Page/",{loader:()=>C(()=>import("./index.html-CF1IpUUb.js"),__vite__mapDeps([108,1])),meta:{t:"Page"}}],["/styleguide/src/system/components/layout/PageTitle/",{loader:()=>C(()=>import("./index.html-DfhQXQ0d.js"),__vite__mapDeps([109,1])),meta:{t:"Page Title"}}],["/styleguide/src/system/components/layout/Placeholder/",{loader:()=>C(()=>import("./index.html-CMM88C29.js"),__vite__mapDeps([110,1])),meta:{t:"Placeholder"}}],["/styleguide/src/system/components/layout/Section/",{loader:()=>C(()=>import("./index.html-DXR7MLPg.js"),__vite__mapDeps([111,1])),meta:{t:"Section"}}],["/styleguide/src/system/components/layout/Space/",{loader:()=>C(()=>import("./index.html-VtoA8tN6.js"),__vite__mapDeps([112,1])),meta:{t:"Space"}}],["/styleguide/src/system/components/layout/Spinner/",{loader:()=>C(()=>import("./index.html-DnBsIglD.js"),__vite__mapDeps([113,1])),meta:{t:"Spinner"}}],["/styleguide/src/system/components/navigation/Button/",{loader:()=>C(()=>import("./index.html-Ca3OZ9Wf.js"),__vite__mapDeps([114,1])),meta:{t:"Button"}}],["/styleguide/src/system/components/navigation/",{loader:()=>C(()=>import("./index.html-BEQOMUJ-.js"),__vite__mapDeps([115,1])),meta:{t:"Navigation"}}],["/styleguide/src/system/components/navigation/Menu/",{loader:()=>C(()=>import("./index.html-2oMIHQ-B.js"),__vite__mapDeps([116,1])),meta:{t:"Menu"}}],["/styleguide/src/system/components/typography/Chip/",{loader:()=>C(()=>import("./index.html-Bv1cv5QZ.js"),__vite__mapDeps([117,1])),meta:{t:"Chip"}}],["/styleguide/src/system/components/typography/",{loader:()=>C(()=>import("./index.html-TZE5wDuj.js"),__vite__mapDeps([118,1])),meta:{t:"Typography"}}],["/styleguide/src/system/components/typography/Code/",{loader:()=>C(()=>import("./index.html-BOfzPdYe.js"),__vite__mapDeps([119,1])),meta:{t:"Code"}}],["/styleguide/src/system/components/typography/Heading/",{loader:()=>C(()=>import("./index.html-B7ltYIGI.js"),__vite__mapDeps([120,1])),meta:{t:"Heading"}}],["/styleguide/src/system/components/typography/Icon/",{loader:()=>C(()=>import("./index.html-Cc8SuVO9.js"),__vite__mapDeps([121,1])),meta:{t:"Icon"}}],["/styleguide/src/system/components/typography/Logo/",{loader:()=>C(()=>import("./index.html-TIaxxz0H.js"),__vite__mapDeps([122,1])),meta:{t:"Logo"}}],["/styleguide/src/system/components/typography/Tag/",{loader:()=>C(()=>import("./index.html-DlRSH8xw.js"),__vite__mapDeps([123,1])),meta:{t:"Tag"}}],["/styleguide/src/system/components/typography/Text/",{loader:()=>C(()=>import("./index.html-BC6ChnxU.js"),__vite__mapDeps([124,1])),meta:{t:"Text"}}]]);function l1(){return Af().__VUE_DEVTOOLS_GLOBAL_HOOK__}function Af(){return typeof navigator<"u"&&typeof window<"u"?window:typeof globalThis<"u"?globalThis:{}}const i1=typeof Proxy=="function",u1="devtools-plugin:setup",c1="plugin:settings:set";let Bn,Qs;function f1(){var e;return Bn!==void 0||(typeof window<"u"&&window.performance?(Bn=!0,Qs=window.performance):typeof globalThis<"u"&&(!((e=globalThis.perf_hooks)===null||e===void 0)&&e.performance)?(Bn=!0,Qs=globalThis.perf_hooks.performance):Bn=!1),Bn}function d1(){return f1()?Qs.now():Date.now()}class p1{constructor(t,n){this.target=null,this.targetQueue=[],this.onQueue=[],this.plugin=t,this.hook=n;const r={};if(t.settings)for(const a in t.settings){const l=t.settings[a];r[a]=l.defaultValue}const o=`__vue-devtools-plugin-settings__${t.id}`;let s=Object.assign({},r);try{const a=localStorage.getItem(o),l=JSON.parse(a);Object.assign(s,l)}catch{}this.fallbacks={getSettings(){return s},setSettings(a){try{localStorage.setItem(o,JSON.stringify(a))}catch{}s=a},now(){return d1()}},n&&n.on(c1,(a,l)=>{a===this.plugin.id&&this.fallbacks.setSettings(l)}),this.proxiedOn=new Proxy({},{get:(a,l)=>this.target?this.target.on[l]:(...i)=>{this.onQueue.push({method:l,args:i})}}),this.proxiedTarget=new Proxy({},{get:(a,l)=>this.target?this.target[l]:l==="on"?this.proxiedOn:Object.keys(this.fallbacks).includes(l)?(...i)=>(this.targetQueue.push({method:l,args:i,resolve:()=>{}}),this.fallbacks[l](...i)):(...i)=>new Promise(f=>{this.targetQueue.push({method:l,args:i,resolve:f})})})}async setRealTarget(t){this.target=t;for(const n of this.onQueue)this.target.on[n.method](...n.args);for(const n of this.targetQueue)n.resolve(await this.target[n.method](...n.args))}}function h1(e,t){const n=e,r=Af(),o=l1(),s=i1&&n.enableEarlyProxy;if(o&&(r.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__||!s))o.emit(u1,e,t);else{const a=s?new p1(n,o):null;(r.__VUE_DEVTOOLS_PLUGINS__=r.__VUE_DEVTOOLS_PLUGINS__||[]).push({pluginDescriptor:n,setupFn:t,proxy:a}),a&&t(a.proxiedTarget)}}/*! + * vue-router v4.4.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */const qt=typeof document<"u";function Sf(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function m1(e){return e.__esModule||e[Symbol.toStringTag]==="Module"||e.default&&Sf(e.default)}const he=Object.assign;function Ts(e,t){const n={};for(const r in t){const o=t[r];n[r]=dt(o)?o.map(e):e(o)}return n}const Ir=()=>{},dt=Array.isArray,Cf=/#/g,v1=/&/g,g1=/\//g,_1=/=/g,y1=/\?/g,kf=/\+/g,E1=/%5B/g,b1=/%5D/g,Of=/%5E/g,w1=/%60/g,xf=/%7B/g,T1=/%7C/g,Rf=/%7D/g,A1=/%20/g;function qa(e){return encodeURI(""+e).replace(T1,"|").replace(E1,"[").replace(b1,"]")}function S1(e){return qa(e).replace(xf,"{").replace(Rf,"}").replace(Of,"^")}function Xs(e){return qa(e).replace(kf,"%2B").replace(A1,"+").replace(Cf,"%23").replace(v1,"%26").replace(w1,"`").replace(xf,"{").replace(Rf,"}").replace(Of,"^")}function C1(e){return Xs(e).replace(_1,"%3D")}function k1(e){return qa(e).replace(Cf,"%23").replace(y1,"%3F")}function O1(e){return e==null?"":k1(e).replace(g1,"%2F")}function rr(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const x1=/\/$/,R1=e=>e.replace(x1,"");function As(e,t,n="/"){let r,o={},s="",a="";const l=t.indexOf("#");let i=t.indexOf("?");return l=0&&(i=-1),i>-1&&(r=t.slice(0,i),s=t.slice(i+1,l>-1?l:t.length),o=e(s)),l>-1&&(r=r||t.slice(0,l),a=t.slice(l,t.length)),r=L1(r??t,n),{fullPath:r+(s&&"?")+s+a,path:r,query:o,hash:rr(a)}}function I1(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function mi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function D1(e,t,n){const r=t.matched.length-1,o=n.matched.length-1;return r>-1&&r===o&&mn(t.matched[r],n.matched[o])&&If(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function mn(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function If(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!P1(e[n],t[n]))return!1;return!0}function P1(e,t){return dt(e)?vi(e,t):dt(t)?vi(t,e):e===t}function vi(e,t){return dt(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function L1(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),o=r[r.length-1];(o===".."||o===".")&&r.push("");let s=n.length-1,a,l;for(a=0;a1&&s--;else break;return n.slice(0,s).join("/")+"/"+r.slice(a).join("/")}const zt={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0};var Br;(function(e){e.pop="pop",e.push="push"})(Br||(Br={}));var Dr;(function(e){e.back="back",e.forward="forward",e.unknown=""})(Dr||(Dr={}));function V1(e){if(!e)if(qt){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),R1(e)}const N1=/^[^#]+#/;function M1(e,t){return e.replace(N1,"#")+t}function $1(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const Xo=()=>({left:window.scrollX,top:window.scrollY});function F1(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),o=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!o)return;t=$1(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function gi(e,t){return(history.state?history.state.position-t:-1)+e}const Js=new Map;function B1(e,t){Js.set(e,t)}function H1(e){const t=Js.get(e);return Js.delete(e),t}let j1=()=>location.protocol+"//"+location.host;function Df(e,t){const{pathname:n,search:r,hash:o}=t,s=e.indexOf("#");if(s>-1){let l=o.includes(e.slice(s))?e.slice(s).length:1,i=o.slice(l);return i[0]!=="/"&&(i="/"+i),mi(i,"")}return mi(n,e)+r+o}function U1(e,t,n,r){let o=[],s=[],a=null;const l=({state:p})=>{const h=Df(e,location),m=n.value,y=t.value;let _=0;if(p){if(n.value=h,t.value=p,a&&a===m){a=null;return}_=y?p.position-y.position:0}else r(h);o.forEach(E=>{E(n.value,m,{delta:_,type:Br.pop,direction:_?_>0?Dr.forward:Dr.back:Dr.unknown})})};function i(){a=n.value}function f(p){o.push(p);const h=()=>{const m=o.indexOf(p);m>-1&&o.splice(m,1)};return s.push(h),h}function c(){const{history:p}=window;p.state&&p.replaceState(he({},p.state,{scroll:Xo()}),"")}function u(){for(const p of s)p();s=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",c)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:i,listen:f,destroy:u}}function _i(e,t,n,r=!1,o=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:o?Xo():null}}function z1(e){const{history:t,location:n}=window,r={value:Df(e,n)},o={value:t.state};o.value||s(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function s(i,f,c){const u=e.indexOf("#"),p=u>-1?(n.host&&document.querySelector("base")?e:e.slice(u))+i:j1()+e+i;try{t[c?"replaceState":"pushState"](f,"",p),o.value=f}catch(h){console.error(h),n[c?"replace":"assign"](p)}}function a(i,f){const c=he({},t.state,_i(o.value.back,i,o.value.forward,!0),f,{position:o.value.position});s(i,c,!0),r.value=i}function l(i,f){const c=he({},o.value,t.state,{forward:i,scroll:Xo()});s(c.current,c,!0);const u=he({},_i(r.value,i,null),{position:c.position+1},f);s(i,u,!1),r.value=i}return{location:r,state:o,push:l,replace:a}}function K1(e){e=V1(e);const t=z1(e),n=U1(e,t.state,t.location,t.replace);function r(s,a=!0){a||n.pauseListeners(),history.go(s)}const o=he({location:"",base:e,go:r,createHref:M1.bind(null,e)},t,n);return Object.defineProperty(o,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(o,"state",{enumerable:!0,get:()=>t.state.value}),o}function Pf(e){return typeof e=="string"||e&&typeof e=="object"}function Lf(e){return typeof e=="string"||typeof e=="symbol"}const Vf=Symbol("");var yi;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(yi||(yi={}));function or(e,t){return he(new Error,{type:e,[Vf]:!0},t)}function Ht(e,t){return e instanceof Error&&Vf in e&&(t==null||!!(e.type&t))}const Ei="[^/]+?",q1={sensitive:!1,strict:!1,start:!0,end:!0},W1=/[.+*?^${}()[\]/\\]/g;function G1(e,t){const n=he({},q1,t),r=[];let o=n.start?"^":"";const s=[];for(const f of e){const c=f.length?[]:[90];n.strict&&!f.length&&(o+="/");for(let u=0;ut.length?t.length===1&&t[0]===80?1:-1:0}function Nf(e,t){let n=0;const r=e.score,o=t.score;for(;n0&&t[t.length-1]<0}const Q1={type:0,value:""},X1=/[a-zA-Z0-9_]/;function J1(e){if(!e)return[[]];if(e==="/")return[[Q1]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(h){throw new Error(`ERR (${n})/"${f}": ${h}`)}let n=0,r=n;const o=[];let s;function a(){s&&o.push(s),s=[]}let l=0,i,f="",c="";function u(){f&&(n===0?s.push({type:0,value:f}):n===1||n===2||n===3?(s.length>1&&(i==="*"||i==="+")&&t(`A repeatable param (${f}) must be alone in its segment. eg: '/:ids+.`),s.push({type:1,value:f,regexp:c,repeatable:i==="*"||i==="+",optional:i==="*"||i==="?"})):t("Invalid state to consume buffer"),f="")}function p(){f+=i}for(;l{a(v)}:Ir}function a(u){if(Lf(u)){const p=r.get(u);p&&(r.delete(u),n.splice(n.indexOf(p),1),p.children.forEach(a),p.alias.forEach(a))}else{const p=n.indexOf(u);p>-1&&(n.splice(p,1),u.record.name&&r.delete(u.record.name),u.children.forEach(a),u.alias.forEach(a))}}function l(){return n}function i(u){const p=rv(u,n);n.splice(p,0,u),u.record.name&&!Ai(u)&&r.set(u.record.name,u)}function f(u,p){let h,m={},y,_;if("name"in u&&u.name){if(h=r.get(u.name),!h)throw or(1,{location:u});_=h.record.name,m=he(wi(p.params,h.keys.filter(v=>!v.optional).concat(h.parent?h.parent.keys.filter(v=>v.optional):[]).map(v=>v.name)),u.params&&wi(u.params,h.keys.map(v=>v.name))),y=h.stringify(m)}else if(u.path!=null)y=u.path,h=n.find(v=>v.re.test(y)),h&&(m=h.parse(y),_=h.record.name);else{if(h=p.name?r.get(p.name):n.find(v=>v.re.test(p.path)),!h)throw or(1,{location:u,currentLocation:p});_=h.record.name,m=he({},p.params,u.params),y=h.stringify(m)}const E=[];let w=h;for(;w;)E.unshift(w.record),w=w.parent;return{name:_,path:y,params:m,matched:E,meta:nv(E)}}e.forEach(u=>s(u));function c(){n.length=0,r.clear()}return{addRoute:s,resolve:f,removeRoute:a,clearRoutes:c,getRoutes:l,getRecordMatcher:o}}function wi(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function Ti(e){const t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:tv(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function tv(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function Ai(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function nv(e){return e.reduce((t,n)=>he(t,n.meta),{})}function Si(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function rv(e,t){let n=0,r=t.length;for(;n!==r;){const s=n+r>>1;Nf(e,t[s])<0?r=s:n=s+1}const o=ov(e);return o&&(r=t.lastIndexOf(o,r-1)),r}function ov(e){let t=e;for(;t=t.parent;)if(Mf(t)&&Nf(e,t)===0)return t}function Mf({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function sv(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let o=0;os&&Xs(s)):[r&&Xs(r)]).forEach(s=>{s!==void 0&&(t+=(t.length?"&":"")+n,s!=null&&(t+="="+s))})}return t}function av(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=dt(r)?r.map(o=>o==null?null:""+o):r==null?r:""+r)}return t}const lv=Symbol(""),ki=Symbol(""),Jo=Symbol(""),Wa=Symbol(""),Zs=Symbol("");function vr(){let e=[];function t(r){return e.push(r),()=>{const o=e.indexOf(r);o>-1&&e.splice(o,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function un(e,t,n,r,o,s=a=>a()){const a=r&&(r.enterCallbacks[o]=r.enterCallbacks[o]||[]);return()=>new Promise((l,i)=>{const f=p=>{p===!1?i(or(4,{from:n,to:t})):p instanceof Error?i(p):Pf(p)?i(or(2,{from:t,to:p})):(a&&r.enterCallbacks[o]===a&&typeof p=="function"&&a.push(p),l())},c=s(()=>e.call(r&&r.instances[o],t,n,f));let u=Promise.resolve(c);e.length<3&&(u=u.then(f)),u.catch(p=>i(p))})}function Ss(e,t,n,r,o=s=>s()){const s=[];for(const a of e)for(const l in a.components){let i=a.components[l];if(!(t!=="beforeRouteEnter"&&!a.instances[l]))if(Sf(i)){const c=(i.__vccOpts||i)[t];c&&s.push(un(c,n,r,a,l,o))}else{let f=i();s.push(()=>f.then(c=>{if(!c)throw new Error(`Couldn't resolve component "${l}" at "${a.path}"`);const u=m1(c)?c.default:c;a.mods[l]=c,a.components[l]=u;const h=(u.__vccOpts||u)[t];return h&&un(h,n,r,a,l,o)()}))}}return s}function Oi(e){const t=Ne(Jo),n=Ne(Wa),r=S(()=>{const i=fn(e.to);return t.resolve(i)}),o=S(()=>{const{matched:i}=r.value,{length:f}=i,c=i[f-1],u=n.matched;if(!c||!u.length)return-1;const p=u.findIndex(mn.bind(null,c));if(p>-1)return p;const h=xi(i[f-2]);return f>1&&xi(c)===h&&u[u.length-1].path!==h?u.findIndex(mn.bind(null,i[f-2])):p}),s=S(()=>o.value>-1&&fv(n.params,r.value.params)),a=S(()=>o.value>-1&&o.value===n.matched.length-1&&If(n.params,r.value.params));function l(i={}){return cv(i)?t[fn(e.replace)?"replace":"push"](fn(e.to)).catch(Ir):Promise.resolve()}if(qt){const i=Nn();if(i){const f={route:r.value,isActive:s.value,isExactActive:a.value,error:null};i.__vrl_devtools=i.__vrl_devtools||[],i.__vrl_devtools.push(f),Ba(()=>{f.route=r.value,f.isActive=s.value,f.isExactActive=a.value,f.error=Pf(fn(e.to))?null:'Invalid "to" value'},{flush:"post"})}}return{route:r,href:S(()=>r.value.href),isActive:s,isExactActive:a,navigate:l}}const iv=X({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Oi,setup(e,{slots:t}){const n=Xr(Oi(e)),{options:r}=Ne(Jo),o=S(()=>({[Ri(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Ri(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const s=t.default&&t.default(n);return e.custom?s:d("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:o.value},s)}}}),uv=iv;function cv(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function fv(e,t){for(const n in t){const r=t[n],o=e[n];if(typeof r=="string"){if(r!==o)return!1}else if(!dt(o)||o.length!==r.length||r.some((s,a)=>s!==o[a]))return!1}return!0}function xi(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Ri=(e,t,n)=>e??t??n,dv=X({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=Ne(Zs),o=S(()=>e.route||r.value),s=Ne(ki,0),a=S(()=>{let f=fn(s);const{matched:c}=o.value;let u;for(;(u=c[f])&&!u.components;)f++;return f}),l=S(()=>o.value.matched[a.value]);Rn(ki,S(()=>a.value+1)),Rn(lv,l),Rn(Zs,o);const i=te();return ce(()=>[i.value,l.value,e.name],([f,c,u],[p,h,m])=>{c&&(c.instances[u]=f,h&&h!==c&&f&&f===p&&(c.leaveGuards.size||(c.leaveGuards=h.leaveGuards),c.updateGuards.size||(c.updateGuards=h.updateGuards))),f&&c&&(!h||!mn(c,h)||!p)&&(c.enterCallbacks[u]||[]).forEach(y=>y(f))},{flush:"post"}),()=>{const f=o.value,c=e.name,u=l.value,p=u&&u.components[c];if(!p)return Ii(n.default,{Component:p,route:f});const h=u.props[c],m=h?h===!0?f.params:typeof h=="function"?h(f):h:null,_=d(p,he({},m,t,{onVnodeUnmounted:E=>{E.component.isUnmounted&&(u.instances[c]=null)},ref:i}));if(qt&&_.ref){const E={depth:a.value,name:u.name,path:u.path,meta:u.meta};(dt(_.ref)?_.ref.map(v=>v.i):[_.ref.i]).forEach(v=>{v.__vrv_devtools=E})}return Ii(n.default,{Component:_,route:f})||_}}});function Ii(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const pv=dv;function gr(e,t){const n=he({},e,{matched:e.matched.map(r=>Av(r,["instances","children","aliasOf"]))});return{_custom:{type:null,readOnly:!0,display:e.fullPath,tooltip:t,value:n}}}function go(e){return{_custom:{display:e}}}let hv=0;function mv(e,t,n){if(t.__hasDevtools)return;t.__hasDevtools=!0;const r=hv++;h1({id:"org.vuejs.router"+(r?"."+r:""),label:"Vue Router",packageName:"vue-router",homepage:"https://router.vuejs.org",logo:"https://router.vuejs.org/logo.png",componentStateTypes:["Routing"],app:e},o=>{typeof o.now!="function"&&console.warn("[Vue Router]: You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html."),o.on.inspectComponent((c,u)=>{c.instanceData&&c.instanceData.state.push({type:"Routing",key:"$route",editable:!1,value:gr(t.currentRoute.value,"Current Route")})}),o.on.visitComponentTree(({treeNode:c,componentInstance:u})=>{if(u.__vrv_devtools){const p=u.__vrv_devtools;c.tags.push({label:(p.name?`${p.name.toString()}: `:"")+p.path,textColor:0,tooltip:"This component is rendered by <router-view>",backgroundColor:$f})}dt(u.__vrl_devtools)&&(u.__devtoolsApi=o,u.__vrl_devtools.forEach(p=>{let h=p.route.path,m=Hf,y="",_=0;p.error?(h=p.error,m=Ev,_=bv):p.isExactActive?(m=Bf,y="This is exactly active"):p.isActive&&(m=Ff,y="This link is active"),c.tags.push({label:h,textColor:_,tooltip:y,backgroundColor:m})}))}),ce(t.currentRoute,()=>{i(),o.notifyComponentUpdate(),o.sendInspectorTree(l),o.sendInspectorState(l)});const s="router:navigations:"+r;o.addTimelineLayer({id:s,label:`Router${r?" "+r:""} Navigations`,color:4237508}),t.onError((c,u)=>{o.addTimelineEvent({layerId:s,event:{title:"Error during Navigation",subtitle:u.fullPath,logType:"error",time:o.now(),data:{error:c},groupId:u.meta.__navigationId}})});let a=0;t.beforeEach((c,u)=>{const p={guard:go("beforeEach"),from:gr(u,"Current Location during this navigation"),to:gr(c,"Target location")};Object.defineProperty(c.meta,"__navigationId",{value:a++}),o.addTimelineEvent({layerId:s,event:{time:o.now(),title:"Start of navigation",subtitle:c.fullPath,data:p,groupId:c.meta.__navigationId}})}),t.afterEach((c,u,p)=>{const h={guard:go("afterEach")};p?(h.failure={_custom:{type:Error,readOnly:!0,display:p?p.message:"",tooltip:"Navigation Failure",value:p}},h.status=go("❌")):h.status=go("✅"),h.from=gr(u,"Current Location during this navigation"),h.to=gr(c,"Target location"),o.addTimelineEvent({layerId:s,event:{title:"End of navigation",subtitle:c.fullPath,time:o.now(),data:h,logType:p?"warning":"default",groupId:c.meta.__navigationId}})});const l="router-inspector:"+r;o.addInspector({id:l,label:"Routes"+(r?" "+r:""),icon:"book",treeFilterPlaceholder:"Search routes"});function i(){if(!f)return;const c=f;let u=n.getRoutes().filter(p=>!p.parent||!p.parent.record.components);u.forEach(zf),c.filter&&(u=u.filter(p=>ea(p,c.filter.toLowerCase()))),u.forEach(p=>Uf(p,t.currentRoute.value)),c.rootNodes=u.map(jf)}let f;o.on.getInspectorTree(c=>{f=c,c.app===e&&c.inspectorId===l&&i()}),o.on.getInspectorState(c=>{if(c.app===e&&c.inspectorId===l){const p=n.getRoutes().find(h=>h.record.__vd_id===c.nodeId);p&&(c.state={options:gv(p)})}}),o.sendInspectorTree(l),o.sendInspectorState(l)})}function vv(e){return e.optional?e.repeatable?"*":"?":e.repeatable?"+":""}function gv(e){const{record:t}=e,n=[{editable:!1,key:"path",value:t.path}];return t.name!=null&&n.push({editable:!1,key:"name",value:t.name}),n.push({editable:!1,key:"regexp",value:e.re}),e.keys.length&&n.push({editable:!1,key:"keys",value:{_custom:{type:null,readOnly:!0,display:e.keys.map(r=>`${r.name}${vv(r)}`).join(" "),tooltip:"Param keys",value:e.keys}}}),t.redirect!=null&&n.push({editable:!1,key:"redirect",value:t.redirect}),e.alias.length&&n.push({editable:!1,key:"aliases",value:e.alias.map(r=>r.record.path)}),Object.keys(e.record.meta).length&&n.push({editable:!1,key:"meta",value:e.record.meta}),n.push({key:"score",editable:!1,value:{_custom:{type:null,readOnly:!0,display:e.score.map(r=>r.join(", ")).join(" | "),tooltip:"Score used to sort routes",value:e.score}}}),n}const $f=15485081,Ff=2450411,Bf=8702998,_v=2282478,Hf=16486972,yv=6710886,Ev=16704226,bv=12131356;function jf(e){const t=[],{record:n}=e;n.name!=null&&t.push({label:String(n.name),textColor:0,backgroundColor:_v}),n.aliasOf&&t.push({label:"alias",textColor:0,backgroundColor:Hf}),e.__vd_match&&t.push({label:"matches",textColor:0,backgroundColor:$f}),e.__vd_exactActive&&t.push({label:"exact",textColor:0,backgroundColor:Bf}),e.__vd_active&&t.push({label:"active",textColor:0,backgroundColor:Ff}),n.redirect&&t.push({label:typeof n.redirect=="string"?`redirect: ${n.redirect}`:"redirects",textColor:16777215,backgroundColor:yv});let r=n.__vd_id;return r==null&&(r=String(wv++),n.__vd_id=r),{id:r,label:n.path,tags:t,children:e.children.map(jf)}}let wv=0;const Tv=/^\/(.*)\/([a-z]*)$/;function Uf(e,t){const n=t.matched.length&&mn(t.matched[t.matched.length-1],e.record);e.__vd_exactActive=e.__vd_active=n,n||(e.__vd_active=t.matched.some(r=>mn(r,e.record))),e.children.forEach(r=>Uf(r,t))}function zf(e){e.__vd_match=!1,e.children.forEach(zf)}function ea(e,t){const n=String(e.re).match(Tv);if(e.__vd_match=!1,!n||n.length<3)return!1;if(new RegExp(n[1].replace(/\$$/,""),n[2]).test(t))return e.children.forEach(a=>ea(a,t)),e.record.path!=="/"||t==="/"?(e.__vd_match=e.re.test(t),!0):!1;const o=e.record.path.toLowerCase(),s=rr(o);return!t.startsWith("/")&&(s.includes(t)||o.includes(t))||s.startsWith(t)||o.startsWith(t)||e.record.name&&String(e.record.name).includes(t)?!0:e.children.some(a=>ea(a,t))}function Av(e,t){const n={};for(const r in e)t.includes(r)||(n[r]=e[r]);return n}function Sv(e){const t=ev(e.routes,e),n=e.parseQuery||sv,r=e.stringifyQuery||Ci,o=e.history,s=vr(),a=vr(),l=vr(),i=Fe(zt);let f=zt;qt&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=Ts.bind(null,k=>""+k),u=Ts.bind(null,O1),p=Ts.bind(null,rr);function h(k,q){let U,Q;return Lf(k)?(U=t.getRecordMatcher(k),Q=q):Q=k,t.addRoute(Q,U)}function m(k){const q=t.getRecordMatcher(k);q&&t.removeRoute(q)}function y(){return t.getRoutes().map(k=>k.record)}function _(k){return!!t.getRecordMatcher(k)}function E(k,q){if(q=he({},q||i.value),typeof k=="string"){const b=As(n,k,q.path),A=t.resolve({path:b.path},q),I=o.createHref(b.fullPath);return he(b,A,{params:p(A.params),hash:rr(b.hash),redirectedFrom:void 0,href:I})}let U;if(k.path!=null)U=he({},k,{path:As(n,k.path,q.path).path});else{const b=he({},k.params);for(const A in b)b[A]==null&&delete b[A];U=he({},k,{params:u(b)}),q.params=u(q.params)}const Q=t.resolve(U,q),fe=k.hash||"";Q.params=c(p(Q.params));const ge=I1(r,he({},k,{hash:S1(fe),path:Q.path})),g=o.createHref(ge);return he({fullPath:ge,hash:fe,query:r===Ci?av(k.query):k.query||{}},Q,{redirectedFrom:void 0,href:g})}function w(k){return typeof k=="string"?As(n,k,i.value.path):he({},k)}function v(k,q){if(f!==k)return or(8,{from:q,to:k})}function T(k){return $(k)}function V(k){return T(he(w(k),{replace:!0}))}function H(k){const q=k.matched[k.matched.length-1];if(q&&q.redirect){const{redirect:U}=q;let Q=typeof U=="function"?U(k):U;return typeof Q=="string"&&(Q=Q.includes("?")||Q.includes("#")?Q=w(Q):{path:Q},Q.params={}),he({query:k.query,hash:k.hash,params:Q.path!=null?{}:k.params},Q)}}function $(k,q){const U=f=E(k),Q=i.value,fe=k.state,ge=k.force,g=k.replace===!0,b=H(U);if(b)return $(he(w(b),{state:typeof b=="object"?he({},fe,b.state):fe,force:ge,replace:g}),q||U);const A=U;A.redirectedFrom=q;let I;return!ge&&D1(r,Q,U)&&(I=or(16,{to:A,from:Q}),De(Q,Q,!0,!1)),(I?Promise.resolve(I):R(A,Q)).catch(O=>Ht(O)?Ht(O,2)?O:Ie(O):Y(O,A,Q)).then(O=>{if(O){if(Ht(O,2))return $(he({replace:g},w(O.to),{state:typeof O.to=="object"?he({},fe,O.to.state):fe,force:ge}),q||A)}else O=L(A,Q,!0,g,fe);return j(A,Q,O),O})}function J(k,q){const U=v(k,q);return U?Promise.reject(U):Promise.resolve()}function N(k){const q=pt.values().next().value;return q&&typeof q.runWithContext=="function"?q.runWithContext(k):k()}function R(k,q){let U;const[Q,fe,ge]=Cv(k,q);U=Ss(Q.reverse(),"beforeRouteLeave",k,q);for(const b of Q)b.leaveGuards.forEach(A=>{U.push(un(A,k,q))});const g=J.bind(null,k,q);return U.push(g),Ue(U).then(()=>{U=[];for(const b of s.list())U.push(un(b,k,q));return U.push(g),Ue(U)}).then(()=>{U=Ss(fe,"beforeRouteUpdate",k,q);for(const b of fe)b.updateGuards.forEach(A=>{U.push(un(A,k,q))});return U.push(g),Ue(U)}).then(()=>{U=[];for(const b of ge)if(b.beforeEnter)if(dt(b.beforeEnter))for(const A of b.beforeEnter)U.push(un(A,k,q));else U.push(un(b.beforeEnter,k,q));return U.push(g),Ue(U)}).then(()=>(k.matched.forEach(b=>b.enterCallbacks={}),U=Ss(ge,"beforeRouteEnter",k,q,N),U.push(g),Ue(U))).then(()=>{U=[];for(const b of a.list())U.push(un(b,k,q));return U.push(g),Ue(U)}).catch(b=>Ht(b,8)?b:Promise.reject(b))}function j(k,q,U){l.list().forEach(Q=>N(()=>Q(k,q,U)))}function L(k,q,U,Q,fe){const ge=v(k,q);if(ge)return ge;const g=q===zt,b=qt?history.state:{};U&&(Q||g?o.replace(k.fullPath,he({scroll:g&&b&&b.scroll},fe)):o.push(k.fullPath,fe)),i.value=k,De(k,q,U,g),Ie()}let Z;function le(){Z||(Z=o.listen((k,q,U)=>{if(!Ze.listening)return;const Q=E(k),fe=H(Q);if(fe){$(he(fe,{replace:!0}),Q).catch(Ir);return}f=Q;const ge=i.value;qt&&B1(gi(ge.fullPath,U.delta),Xo()),R(Q,ge).catch(g=>Ht(g,12)?g:Ht(g,2)?($(g.to,Q).then(b=>{Ht(b,20)&&!U.delta&&U.type===Br.pop&&o.go(-1,!1)}).catch(Ir),Promise.reject()):(U.delta&&o.go(-U.delta,!1),Y(g,Q,ge))).then(g=>{g=g||L(Q,ge,!1),g&&(U.delta&&!Ht(g,8)?o.go(-U.delta,!1):U.type===Br.pop&&Ht(g,20)&&o.go(-1,!1)),j(Q,ge,g)}).catch(Ir)}))}let de=vr(),K=vr(),F;function Y(k,q,U){Ie(k);const Q=K.list();return Q.length?Q.forEach(fe=>fe(k,q,U)):console.error(k),Promise.reject(k)}function ae(){return F&&i.value!==zt?Promise.resolve():new Promise((k,q)=>{de.add([k,q])})}function Ie(k){return F||(F=!k,le(),de.list().forEach(([q,U])=>k?U(k):q()),de.reset()),k}function De(k,q,U,Q){const{scrollBehavior:fe}=e;if(!qt||!fe)return Promise.resolve();const ge=!U&&H1(gi(k.fullPath,0))||(Q||!U)&&history.state&&history.state.scroll||null;return $t().then(()=>fe(k,q,ge)).then(g=>g&&F1(g)).catch(g=>Y(g,k,q))}const pe=k=>o.go(k);let Me;const pt=new Set,Ze={currentRoute:i,listening:!0,addRoute:h,removeRoute:m,clearRoutes:t.clearRoutes,hasRoute:_,getRoutes:y,resolve:E,options:e,push:T,replace:V,go:pe,back:()=>pe(-1),forward:()=>pe(1),beforeEach:s.add,beforeResolve:a.add,afterEach:l.add,onError:K.add,isReady:ae,install(k){const q=this;k.component("RouterLink",uv),k.component("RouterView",pv),k.config.globalProperties.$router=q,Object.defineProperty(k.config.globalProperties,"$route",{enumerable:!0,get:()=>fn(i)}),qt&&!Me&&i.value===zt&&(Me=!0,T(o.location).catch(fe=>{}));const U={};for(const fe in zt)Object.defineProperty(U,fe,{get:()=>i.value[fe],enumerable:!0});k.provide(Jo,q),k.provide(Wa,_c(U)),k.provide(Zs,i);const Q=k.unmount;pt.add(k),k.unmount=function(){pt.delete(k),pt.size<1&&(f=zt,Z&&Z(),Z=null,i.value=zt,Me=!1,F=!1),Q()},qt&&mv(k,q,t)}};function Ue(k){return k.reduce((q,U)=>q.then(()=>N(U)),Promise.resolve())}return Ze}function Cv(e,t){const n=[],r=[],o=[],s=Math.max(t.matched.length,e.matched.length);for(let a=0;amn(f,l))?r.push(l):n.push(l));const i=e.matched[a];i&&(t.matched.find(f=>mn(f,i))||o.push(i))}return[n,r,o]}function Mn(){return Ne(Jo)}function Zt(e){return Ne(Wa)}var Ga=Symbol(""),xt=()=>{const e=Ne(Ga);if(!e)throw new Error("useClientData() is called without provider.");return e},kv=()=>xt().pageComponent,Be=()=>xt().pageData,Re=()=>xt().pageFrontmatter,Ov=()=>xt().pageHead,Kf=()=>xt().pageLang,xv=()=>xt().pageLayout,en=()=>xt().routeLocale,qf=()=>xt().routePath,Rv=()=>xt().routes,Wf=()=>xt().siteData,Zo=()=>xt().siteLocaleData,Iv=Symbol(""),ta=Fe(s1),Qn=Fe(a1),Gf=(e,t)=>{const n=X0(e,t);if(Qn.value[n])return n;const r=encodeURI(n);if(Qn.value[r])return r;const o=ta.value[n]||ta.value[r];return o||n},Yt=(e,t)=>{const{pathname:n,hashAndQueries:r}=bf(e),o=Gf(n,t),s=o+r;return Qn.value[o]?{...Qn.value[o],path:s,notFound:!1}:{...Qn.value["/404.html"],path:s,notFound:!0}},Dv=(e,t)=>{const{pathname:n,hashAndQueries:r}=bf(e);return Gf(n,t)+r},Pv=e=>{if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget){const t=e.currentTarget.getAttribute("target");if(t!=null&&t.match(/\b_blank\b/i))return}return e.preventDefault(),!0}},At=X({name:"RouteLink",props:{to:{type:String,required:!0},active:Boolean,activeClass:{type:String,default:"route-link-active"}},slots:Object,setup(e,{slots:t}){const n=Mn(),r=Zt(),o=S(()=>e.to.startsWith("#")||e.to.startsWith("?")?e.to:`/${Dv(e.to,r.path).substring(1)}`);return()=>d("a",{class:["route-link",{[e.activeClass]:e.active}],href:o.value,onClick:(s={})=>{Pv(s)&&n.push(e.to).catch()}},t.default())}}),Lv=X({name:"AutoLink",props:{config:{type:Object,required:!0}},slots:Object,setup(e,{slots:t}){const n=Wo(e,"config"),r=Zt(),o=Wf(),s=S(()=>no(n.value.link)),a=S(()=>n.value.target||(s.value?"_blank":void 0)),l=S(()=>a.value==="_blank"),i=S(()=>!s.value&&!l.value),f=S(()=>n.value.rel||(l.value?"noopener noreferrer":null)),c=S(()=>n.value.ariaLabel??n.value.text),u=S(()=>{if(n.value.exact)return!1;const h=Object.keys(o.value.locales);return h.length?h.every(m=>m!==n.value.link):n.value.link!=="/"}),p=S(()=>i.value?n.value.activeMatch?(n.value.activeMatch instanceof RegExp?n.value.activeMatch:new RegExp(n.value.activeMatch,"u")).test(r.path):u.value?r.path.startsWith(n.value.link):r.path===n.value.link:!1);return()=>{const{before:h,after:m,default:y}=t,_=(y==null?void 0:y(n.value))??[h==null?void 0:h(n.value),n.value.text,m==null?void 0:m(n.value)];return i.value?d(At,{class:"auto-link",to:n.value.link,active:p.value,"aria-label":c.value},()=>_):d("a",{class:"auto-link external-link",href:n.value.link,"aria-label":c.value,rel:f.value,target:a.value},_)}}}),Yf=X({name:"ClientOnly",setup(e,t){const n=te(!1);return Se(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),Qf=X({name:"Content",props:{path:{type:String,required:!1,default:""}},setup(e){const t=kv(),n=S(()=>{if(!e.path)return t.value;const r=Yt(e.path);return Mc(async()=>r.loader().then(({comp:o})=>o))});return()=>d(n.value)}}),Vv="Layout",Nv="en-US",Tn=Xr({resolveLayouts:e=>e.reduce((t,n)=>({...t,...n.layouts}),{}),resolvePageHead:(e,t,n)=>{const r=Le(t.description)?t.description:n.description,o=[...Array.isArray(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return r1(o)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(n=>!!n).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||Nv,resolvePageLayout:(e,t)=>{const n=Le(e.frontmatter.layout)?e.frontmatter.layout:Vv;if(!t[n])throw new Error(`[vuepress] Cannot resolve layout: ${n}`);return t[n]},resolveRouteLocale:(e,t)=>J0(e,decodeURI(t)),resolveSiteLocaleData:({base:e,locales:t,...n},r)=>{var o;return{...n,...t[r],head:[...((o=t[r])==null?void 0:o.head)??[],...n.head]}}}),Ft=(e={})=>e,je=e=>ro(e)?e:`/${Tf(e)}`;const Mv=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),$v=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Xf=({size:e=48,stroke:t=4,wrapper:n=!0,height:r=2*e})=>{const o=d("svg",{xmlns:"http://www.w3.org/2000/svg",width:e,height:e,preserveAspectRatio:"xMidYMid",viewBox:"25 25 50 50"},[d("animateTransform",{attributeName:"transform",type:"rotate",dur:"2s",keyTimes:"0;1",repeatCount:"indefinite",values:"0;360"}),d("circle",{cx:"50",cy:"50",r:"20",fill:"none",stroke:"currentColor","stroke-width":t,"stroke-linecap":"round"},[d("animate",{attributeName:"stroke-dasharray",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"1,200;90,200;1,200"}),d("animate",{attributeName:"stroke-dashoffset",dur:"1.5s",keyTimes:"0;0.5;1",repeatCount:"indefinite",values:"0;-35px;-125px"})])]);return n?d("div",{class:"loading-icon-wrapper",style:`display:flex;align-items:center;justify-content:center;height:${r}px`},o):o};Xf.displayName="LoadingIcon";function cr(e){return rc()?(vh(e),!0):!1}function qe(e){return typeof e=="function"?e():fn(e)}const so=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Fv=Object.prototype.toString,Bv=e=>Fv.call(e)==="[object Object]",Gt=()=>{},na=Hv();function Hv(){var e,t;return so&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Ya(e,t){function n(...r){return new Promise((o,s)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(o).catch(s)})}return n}const Jf=e=>e();function jv(e,t={}){let n,r,o=Gt;const s=l=>{clearTimeout(l),o(),o=Gt};return l=>{const i=qe(e),f=qe(t.maxWait);return n&&s(n),i<=0||f!==void 0&&f<=0?(r&&(s(r),r=null),Promise.resolve(l())):new Promise((c,u)=>{o=t.rejectOnCancel?u:c,f&&!r&&(r=setTimeout(()=>{n&&s(n),r=null,c(l())},f)),n=setTimeout(()=>{r&&s(r),r=null,c(l())},i)})}}function Uv(...e){let t=0,n,r=!0,o=Gt,s,a,l,i,f;!Pe(e[0])&&typeof e[0]=="object"?{delay:a,trailing:l=!0,leading:i=!0,rejectOnCancel:f=!1}=e[0]:[a,l=!0,i=!0,f=!1]=e;const c=()=>{n&&(clearTimeout(n),n=void 0,o(),o=Gt)};return p=>{const h=qe(a),m=Date.now()-t,y=()=>s=p();return c(),h<=0?(t=Date.now(),y()):(m>h&&(i||!r)?(t=Date.now(),y()):l&&(s=new Promise((_,E)=>{o=f?E:_,n=setTimeout(()=>{t=Date.now(),r=!0,_(y()),c()},Math.max(0,h-m))})),!i&&!n&&(n=setTimeout(()=>r=!0,h)),r=!1,s)}}function zv(e=Jf){const t=te(!0);function n(){t.value=!1}function r(){t.value=!0}const o=(...s)=>{t.value&&e(...s)};return{isActive:Jr(t),pause:n,resume:r,eventFilter:o}}function Kv(e){let t;function n(){return t||(t=e()),t}return n.reset=async()=>{const r=t;t=void 0,r&&await r},n}function qv(e){return Nn()}function Wv(...e){if(e.length!==1)return Wo(...e);const t=e[0];return typeof t=="function"?Jr(bc(()=>({get:t,set:Gt}))):te(t)}function Zf(e,t=200,n={}){return Ya(jv(t,n),e)}function Gv(e,t=200,n=!1,r=!0,o=!1){return Ya(Uv(t,n,r,o),e)}function Yv(e,t,n={}){const{eventFilter:r=Jf,...o}=n;return ce(e,Ya(r,t),o)}function Qv(e,t,n={}){const{eventFilter:r,...o}=n,{eventFilter:s,pause:a,resume:l,isActive:i}=zv(r);return{stop:Yv(e,t,{...o,eventFilter:s}),pause:a,resume:l,isActive:i}}function Qa(e,t=!0,n){qv()?Se(e,n):t?e():$t(e)}function Xv(e,t,n={}){const{immediate:r=!0}=n,o=te(!1);let s=null;function a(){s&&(clearTimeout(s),s=null)}function l(){o.value=!1,a()}function i(...f){a(),o.value=!0,s=setTimeout(()=>{o.value=!1,s=null,e(...f)},qe(t))}return r&&(o.value=!0,so&&i()),cr(l),{isPending:Jr(o),start:i,stop:l}}function Hr(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,o=Pe(e),s=te(e);function a(l){if(arguments.length)return s.value=l,s.value;{const i=qe(n);return s.value=s.value===i?qe(r):i,s.value}}return o?a:[s,a]}const Et=so?window:void 0,Jv=so?window.document:void 0,ed=so?window.navigator:void 0;function ft(e){var t;const n=qe(e);return(t=n==null?void 0:n.$el)!=null?t:n}function Ae(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,o]=e,t=Et):[t,n,r,o]=e,!t)return Gt;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const s=[],a=()=>{s.forEach(c=>c()),s.length=0},l=(c,u,p,h)=>(c.addEventListener(u,p,h),()=>c.removeEventListener(u,p,h)),i=ce(()=>[ft(t),qe(o)],([c,u])=>{if(a(),!c)return;const p=Bv(u)?{...u}:u;s.push(...n.flatMap(h=>r.map(m=>l(c,h,m,p))))},{immediate:!0,flush:"post"}),f=()=>{i(),a()};return cr(f),f}let Di=!1;function Zv(e,t,n={}){const{window:r=Et,ignore:o=[],capture:s=!0,detectIframe:a=!1}=n;if(!r)return Gt;na&&!Di&&(Di=!0,Array.from(r.document.body.children).forEach(h=>h.addEventListener("click",Gt)),r.document.documentElement.addEventListener("click",Gt));let l=!0;const i=h=>qe(o).some(m=>{if(typeof m=="string")return Array.from(r.document.querySelectorAll(m)).some(y=>y===h.target||h.composedPath().includes(y));{const y=ft(m);return y&&(h.target===y||h.composedPath().includes(y))}}),f=h=>{const m=ft(e);if(!(!m||m===h.target||h.composedPath().includes(m))){if(h.detail===0&&(l=!i(h)),!l){l=!0;return}t(h)}};let c=!1;const u=[Ae(r,"click",h=>{c||(c=!0,setTimeout(()=>{c=!1},0),f(h))},{passive:!0,capture:s}),Ae(r,"pointerdown",h=>{const m=ft(e);l=!i(h)&&!!(m&&!h.composedPath().includes(m))},{passive:!0}),a&&Ae(r,"blur",h=>{setTimeout(()=>{var m;const y=ft(e);((m=r.document.activeElement)==null?void 0:m.tagName)==="IFRAME"&&!(y!=null&&y.contains(r.document.activeElement))&&t(h)},0)})].filter(Boolean);return()=>u.forEach(h=>h())}function eg(){const e=te(!1),t=Nn();return t&&Se(()=>{e.value=!0},t),e}function ao(e){const t=eg();return S(()=>(t.value,!!e()))}function Xa(e,t={}){const{window:n=Et}=t,r=ao(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let o;const s=te(!1),a=f=>{s.value=f.matches},l=()=>{o&&("removeEventListener"in o?o.removeEventListener("change",a):o.removeListener(a))},i=Ba(()=>{r.value&&(l(),o=n.matchMedia(qe(e)),"addEventListener"in o?o.addEventListener("change",a):o.addListener(a),s.value=o.matches)});return cr(()=>{i(),l(),o=void 0}),s}function Pi(e,t={}){const{controls:n=!1,navigator:r=ed}=t,o=ao(()=>r&&"permissions"in r),s=Fe(),a=typeof e=="string"?{name:e}:e,l=Fe(),i=()=>{var c,u;l.value=(u=(c=s.value)==null?void 0:c.state)!=null?u:"prompt"};Ae(s,"change",i);const f=Kv(async()=>{if(o.value){if(!s.value)try{s.value=await r.permissions.query(a)}catch{s.value=void 0}finally{i()}if(n)return ie(s.value)}});return f(),n?{state:l,isSupported:o,query:f}:l}function tg(e={}){const{navigator:t=ed,read:n=!1,source:r,copiedDuring:o=1500,legacy:s=!1}=e,a=ao(()=>t&&"clipboard"in t),l=Pi("clipboard-read"),i=Pi("clipboard-write"),f=S(()=>a.value||s),c=te(""),u=te(!1),p=Xv(()=>u.value=!1,o);function h(){a.value&&E(l.value)?t.clipboard.readText().then(w=>{c.value=w}):c.value=_()}f.value&&n&&Ae(["copy","cut"],h);async function m(w=qe(r)){f.value&&w!=null&&(a.value&&E(i.value)?await t.clipboard.writeText(w):y(w),c.value=w,u.value=!0,p.start())}function y(w){const v=document.createElement("textarea");v.value=w??"",v.style.position="absolute",v.style.opacity="0",document.body.appendChild(v),v.select(),document.execCommand("copy"),v.remove()}function _(){var w,v,T;return(T=(v=(w=document==null?void 0:document.getSelection)==null?void 0:w.call(document))==null?void 0:v.toString())!=null?T:""}function E(w){return w==="granted"||w==="prompt"}return{isSupported:f,text:c,copied:u,copy:m}}const _o=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},yo="__vueuse_ssr_handlers__",ng=rg();function rg(){return yo in _o||(_o[yo]=_o[yo]||{}),_o[yo]}function og(e,t){return ng[e]||t}function sg(e){return Xa("(prefers-color-scheme: dark)",e)}function ag(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const lg={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},Li="vueuse-storage";function Ja(e,t,n,r={}){var o;const{flush:s="pre",deep:a=!0,listenToStorageChanges:l=!0,writeDefaults:i=!0,mergeDefaults:f=!1,shallow:c,window:u=Et,eventFilter:p,onError:h=R=>{console.error(R)},initOnMounted:m}=r,y=(c?Fe:te)(typeof t=="function"?t():t);if(!n)try{n=og("getDefaultStorage",()=>{var R;return(R=Et)==null?void 0:R.localStorage})()}catch(R){h(R)}if(!n)return y;const _=qe(t),E=ag(_),w=(o=r.serializer)!=null?o:lg[E],{pause:v,resume:T}=Qv(y,()=>H(y.value),{flush:s,deep:a,eventFilter:p});u&&l&&Qa(()=>{n instanceof Storage?Ae(u,"storage",J):Ae(u,Li,N),m&&J()}),m||J();function V(R,j){if(u){const L={key:e,oldValue:R,newValue:j,storageArea:n};u.dispatchEvent(n instanceof Storage?new StorageEvent("storage",L):new CustomEvent(Li,{detail:L}))}}function H(R){try{const j=n.getItem(e);if(R==null)V(j,null),n.removeItem(e);else{const L=w.write(R);j!==L&&(n.setItem(e,L),V(j,L))}}catch(j){h(j)}}function $(R){const j=R?R.newValue:n.getItem(e);if(j==null)return i&&_!=null&&n.setItem(e,w.write(_)),_;if(!R&&f){const L=w.read(j);return typeof f=="function"?f(L,_):E==="object"&&!Array.isArray(L)?{..._,...L}:L}else return typeof j!="string"?j:w.read(j)}function J(R){if(!(R&&R.storageArea!==n)){if(R&&R.key==null){y.value=_;return}if(!(R&&R.key!==e)){v();try{(R==null?void 0:R.newValue)!==w.write(y.value)&&(y.value=$(R))}catch(j){h(j)}finally{R?$t(T):T()}}}}function N(R){J(R.detail)}return y}function ig(e,t,n={}){const{window:r=Et,...o}=n;let s;const a=ao(()=>r&&"ResizeObserver"in r),l=()=>{s&&(s.disconnect(),s=void 0)},i=S(()=>{const u=qe(e);return Array.isArray(u)?u.map(p=>ft(p)):[ft(u)]}),f=ce(i,u=>{if(l(),a.value&&r){s=new ResizeObserver(t);for(const p of u)p&&s.observe(p,o)}},{immediate:!0,flush:"post"}),c=()=>{l(),f()};return cr(c),{isSupported:a,stop:c}}function ug(e,t={width:0,height:0},n={}){const{window:r=Et,box:o="content-box"}=n,s=S(()=>{var u,p;return(p=(u=ft(e))==null?void 0:u.namespaceURI)==null?void 0:p.includes("svg")}),a=te(t.width),l=te(t.height),{stop:i}=ig(e,([u])=>{const p=o==="border-box"?u.borderBoxSize:o==="content-box"?u.contentBoxSize:u.devicePixelContentBoxSize;if(r&&s.value){const h=ft(e);if(h){const m=h.getBoundingClientRect();a.value=m.width,l.value=m.height}}else if(p){const h=Array.isArray(p)?p:[p];a.value=h.reduce((m,{inlineSize:y})=>m+y,0),l.value=h.reduce((m,{blockSize:y})=>m+y,0)}else a.value=u.contentRect.width,l.value=u.contentRect.height},n);Qa(()=>{const u=ft(e);u&&(a.value="offsetWidth"in u?u.offsetWidth:t.width,l.value="offsetHeight"in u?u.offsetHeight:t.height)});const f=ce(()=>ft(e),u=>{a.value=u?t.width:0,l.value=u?t.height:0});function c(){i(),f()}return{width:a,height:l,stop:c}}const Vi=["fullscreenchange","webkitfullscreenchange","webkitendfullscreen","mozfullscreenchange","MSFullscreenChange"];function es(e,t={}){const{document:n=Jv,autoExit:r=!1}=t,o=S(()=>{var E;return(E=ft(e))!=null?E:n==null?void 0:n.querySelector("html")}),s=te(!1),a=S(()=>["requestFullscreen","webkitRequestFullscreen","webkitEnterFullscreen","webkitEnterFullScreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen"].find(E=>n&&E in n||o.value&&E in o.value)),l=S(()=>["exitFullscreen","webkitExitFullscreen","webkitExitFullScreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen"].find(E=>n&&E in n||o.value&&E in o.value)),i=S(()=>["fullScreen","webkitIsFullScreen","webkitDisplayingFullscreen","mozFullScreen","msFullscreenElement"].find(E=>n&&E in n||o.value&&E in o.value)),f=["fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement"].find(E=>n&&E in n),c=ao(()=>o.value&&n&&a.value!==void 0&&l.value!==void 0&&i.value!==void 0),u=()=>f?(n==null?void 0:n[f])===o.value:!1,p=()=>{if(i.value){if(n&&n[i.value]!=null)return n[i.value];{const E=o.value;if((E==null?void 0:E[i.value])!=null)return!!E[i.value]}}return!1};async function h(){if(!(!c.value||!s.value)){if(l.value)if((n==null?void 0:n[l.value])!=null)await n[l.value]();else{const E=o.value;(E==null?void 0:E[l.value])!=null&&await E[l.value]()}s.value=!1}}async function m(){if(!c.value||s.value)return;p()&&await h();const E=o.value;a.value&&(E==null?void 0:E[a.value])!=null&&(await E[a.value](),s.value=!0)}async function y(){await(s.value?h():m())}const _=()=>{const E=p();(!E||E&&u())&&(s.value=E)};return Ae(n,Vi,_,!1),Ae(()=>ft(o),Vi,_,!1),r&&cr(h),{isSupported:c,isFullscreen:s,enter:m,exit:h,toggle:y}}function Cs(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function cg(e,t,n={}){const{window:r=Et}=n;return Ja(e,t,r==null?void 0:r.localStorage,n)}function fg(e={}){const{window:t=Et}=e;if(!t)return te(["en"]);const n=t.navigator,r=te(n.languages);return Ae(t,"languagechange",()=>{r.value=n.languages}),r}function td(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const ks=new WeakMap;function ts(e,t=!1){const n=te(t);let r=null,o="";ce(Wv(e),l=>{const i=Cs(qe(l));if(i){const f=i;if(ks.get(f)||ks.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(o=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const s=()=>{const l=Cs(qe(e));!l||n.value||(na&&(r=Ae(l,"touchmove",i=>{dg(i)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},a=()=>{const l=Cs(qe(e));!l||!n.value||(na&&(r==null||r()),l.style.overflow=o,ks.delete(l),n.value=!1)};return cr(a),S({get(){return n.value},set(l){l?s():a()}})}function pg(e,t,n={}){const{window:r=Et}=n;return Ja(e,t,r==null?void 0:r.sessionStorage,n)}function hg(e={}){const{window:t=Et,behavior:n="auto"}=e;if(!t)return{x:te(0),y:te(0)};const r=te(t.scrollX),o=te(t.scrollY),s=S({get(){return r.value},set(l){scrollTo({left:l,behavior:n})}}),a=S({get(){return o.value},set(l){scrollTo({top:l,behavior:n})}});return Ae(t,"scroll",()=>{r.value=t.scrollX,o.value=t.scrollY},{capture:!1,passive:!0}),{x:s,y:a}}function mg(e={}){const{window:t=Et,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:r=Number.POSITIVE_INFINITY,listenOrientation:o=!0,includeScrollbar:s=!0,type:a="inner"}=e,l=te(n),i=te(r),f=()=>{t&&(a==="outer"?(l.value=t.outerWidth,i.value=t.outerHeight):s?(l.value=t.innerWidth,i.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,i.value=t.document.documentElement.clientHeight))};if(f(),Qa(f),Ae("resize",f,{passive:!0}),o){const c=Xa("(orientation: portrait)");ce(c,()=>f())}return{width:l,height:i}}var ut=Uint8Array,jn=Uint16Array,vg=Int32Array,nd=new ut([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),rd=new ut([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),gg=new ut([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),od=function(e,t){for(var n=new jn(31),r=0;r<31;++r)n[r]=t+=1<>1|(Te&21845)<<1;nn=(nn&52428)>>2|(nn&13107)<<2,nn=(nn&61680)>>4|(nn&3855)<<4,ra[Te]=((nn&65280)>>8|(nn&255)<<8)>>1}var Pr=function(e,t,n){for(var r=e.length,o=0,s=new jn(t);o>i]=f}else for(l=new jn(r),o=0;o>15-e[o]);return l},lo=new ut(288);for(var Te=0;Te<144;++Te)lo[Te]=8;for(var Te=144;Te<256;++Te)lo[Te]=9;for(var Te=256;Te<280;++Te)lo[Te]=7;for(var Te=280;Te<288;++Te)lo[Te]=8;var ld=new ut(32);for(var Te=0;Te<32;++Te)ld[Te]=5;var bg=Pr(lo,9,1),wg=Pr(ld,5,1),Os=function(e){for(var t=e[0],n=1;nt&&(t=e[n]);return t},Tt=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},xs=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},Tg=function(e){return(e+7)/8|0},id=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new ut(e.subarray(t,n))},Ag=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],vt=function(e,t,n){var r=new Error(t||Ag[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,vt),!n)throw r;return r},Sg=function(e,t,n,r){var o=e.length,s=0;if(!o||t.f&&!t.l)return n||new ut(0);var a=!n,l=a||t.i!=2,i=t.i;a&&(n=new ut(o*3));var f=function(fe){var ge=n.length;if(fe>ge){var g=new ut(Math.max(ge*2,fe));g.set(n),n=g}},c=t.f||0,u=t.p||0,p=t.b||0,h=t.l,m=t.d,y=t.m,_=t.n,E=o*8;do{if(!h){c=Tt(e,u,1);var w=Tt(e,u+1,3);if(u+=3,w)if(w==1)h=bg,m=wg,y=9,_=5;else if(w==2){var H=Tt(e,u,31)+257,$=Tt(e,u+10,15)+4,J=H+Tt(e,u+5,31)+1;u+=14;for(var N=new ut(J),R=new ut(19),j=0;j<$;++j)R[gg[j]]=Tt(e,u+j*3,7);u+=$*3;for(var L=Os(R),Z=(1<>4;if(v<16)N[j++]=v;else{var K=0,F=0;for(v==16?(F=3+Tt(e,u,3),u+=2,K=N[j-1]):v==17?(F=3+Tt(e,u,7),u+=3):v==18&&(F=11+Tt(e,u,127),u+=7);F--;)N[j++]=K}}var Y=N.subarray(0,H),ae=N.subarray(H);y=Os(Y),_=Os(ae),h=Pr(Y,y,1),m=Pr(ae,_,1)}else vt(1);else{var v=Tg(u)+4,T=e[v-4]|e[v-3]<<8,V=v+T;if(V>o){i&&vt(0);break}l&&f(p+T),n.set(e.subarray(v,V),p),t.b=p+=T,t.p=u=V*8,t.f=c;continue}if(u>E){i&&vt(0);break}}l&&f(p+131072);for(var Ie=(1<>4;if(u+=K&15,u>E){i&&vt(0);break}if(K||vt(2),Me<256)n[p++]=Me;else if(Me==256){pe=u,h=null;break}else{var pt=Me-254;if(Me>264){var j=Me-257,Ze=nd[j];pt=Tt(e,u,(1<>4;Ue||vt(3),u+=Ue&15;var ae=Eg[k];if(k>3){var Ze=rd[k];ae+=xs(e,u)&(1<E){i&&vt(0);break}l&&f(p+131072);var q=p+pt;if(p>4>7||(e[0]<<8|e[1])%31)&&vt(6,"invalid zlib data"),(e[1]>>5&1)==+!t&&vt(6,"invalid zlib data: "+(e[1]&32?"need":"unexpected")+" dictionary"),(e[1]>>3&4)+2};function Og(e,t){return Sg(e.subarray(kg(e,t),-4),{i:2},t,t)}var oa=typeof TextDecoder<"u"&&new TextDecoder,xg=0;try{oa.decode(Cg,{stream:!0}),xg=1}catch{}var Rg=function(e){for(var t="",n=0;;){var r=e[n++],o=(r>127)+(r>223)+(r>239);if(n+o>e.length)return{s:t,r:id(e,n-1)};o?o==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):o&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function Ig(e,t){{for(var n=new ut(e.length),r=0;r{const t=atob(e);return Dg(Og(Ig(t)))},Ot=(e,t)=>{var r;const n=(r=(t==null?void 0:t._instance)??Nn())==null?void 0:r.appContext.components;return n?e in n||rt(e)in n||Qr(rt(e))in n:!1},Za=e=>new Promise(t=>{setTimeout(t,e)}),_n=e=>{const t=en();return S(()=>e[t.value]??{})},el=e=>typeof e<"u",Rs=e=>typeof e=="number",{isArray:sa}=Array,jr=(e,t)=>Le(e)&&e.startsWith(t),Pg=(e,t)=>Le(e)&&e.endsWith(t),{entries:ud}=Object,{keys:io}=Object,{values:Lg}=Object,Vg=e=>{if(e){if(typeof e=="number")return new Date(e);const t=Date.parse(e.toString());if(!Number.isNaN(t))return new Date(t)}return null},tl=e=>jr(e,"/"),cd=({type:e="info",text:t="",vertical:n,color:r,bgColor:o},{slots:s})=>{var a;return d("span",{class:["vp-badge",e,{diy:r||o}],style:{verticalAlign:n??!1,backgroundColor:o??!1,color:r??!1}},((a=s.default)==null?void 0:a.call(s))??t)};cd.displayName="Badge";var Ng=X({name:"FontIcon",props:{icon:{type:String,default:""},color:{type:String,default:""},size:{type:[String,Number],default:""}},setup(e){const t=S(()=>{const r=["font-icon icon"],o=`${e.icon}`;return r.push(o),r}),n=S(()=>{const r={};return e.color&&(r.color=e.color),e.size&&(r["font-size"]=Number.isNaN(Number(e.size))?e.size:`${e.size}px`),io(r).length?r:null});return()=>e.icon?d("span",{key:e.icon,class:t.value,style:n.value}):null}});const Mg={enhance:({app:e})=>{Ot("Badge")||e.component("Badge",cd),Ot("FontIcon")||e.component("FontIcon",Ng)},setup:()=>{},rootComponents:[]},$g=Object.freeze(Object.defineProperty({__proto__:null,default:Mg},Symbol.toStringTag,{value:"Module"})),Mi=async(e,t)=>{const{path:n,query:r}=e.currentRoute.value,{scrollBehavior:o}=e.options;e.options.scrollBehavior=void 0,await e.replace({path:n,query:r,hash:t}),e.options.scrollBehavior=o},Fg=({headerLinkSelector:e,headerAnchorSelector:t,delay:n,offset:r=5})=>{const o=Mn();Ae("scroll",Zf(()=>{var m,y;const a=Math.max(window.scrollY,document.documentElement.scrollTop,document.body.scrollTop);if(Math.abs(a-0)u.some(E=>E.hash===_.hash));for(let _=0;_=(((m=E.parentElement)==null?void 0:m.offsetTop)??0)-r,T=!w||a<(((y=w.parentElement)==null?void 0:y.offsetTop)??0)-r;if(!(v&&T))continue;const H=decodeURIComponent(o.currentRoute.value.hash),$=decodeURIComponent(E.hash);if(H===$)return;if(c){for(let J=_+1;JLe(e.title)?{title:e.title}:null;const dd=Symbol(""),qg=e=>{fd=e},Wg=()=>Ne(dd),Gg=e=>{e.provide(dd,fd)};var Yg={"/":{title:"Catalog",empty:"No catalog"}},Qg=X({name:"Catalog",props:{base:{type:String,default:""},level:{type:Number,default:3},index:Boolean,hideHeading:Boolean},setup(e){const t=Wg(),n=_n(Yg),r=Be(),o=Rv(),s=Wf(),a=Fe(ud(o.value).map(([i,{meta:f}])=>{const c=t(f);if(!c)return null;const u=i.split("/").length;return{level:Pg(i,"/")?u-2:u-1,base:i.replace(/\/[^/]+\/?$/,"/"),path:i,...c}}).filter(i=>oo(i)&&Le(i.title))),l=S(()=>{const i=e.base?o1(wf(e.base)):r.value.path.replace(/\/[^/]+$/,"/"),f=i.split("/").length-2,c=[];return a.value.filter(({level:u,path:p})=>{if(!jr(p,i)||p===i)return!1;if(i==="/"){const h=io(s.value.locales).filter(m=>m!=="/");if(p==="/404.html"||h.some(m=>jr(p,m)))return!1}return u-f<=e.level}).sort(({title:u,level:p,order:h},{title:m,level:y,order:_})=>p-y||(Rs(h)?Rs(_)?h>0?_>0?h-_:-1:_<0?h-_:1:h:Rs(_)?_:u.localeCompare(m))).forEach(u=>{var m;const{base:p,level:h}=u;switch(h-f){case 1:{c.push(u);break}case 2:{const y=c.find(_=>_.path===p);y&&(y.children??(y.children=[])).push(u);break}default:{const y=c.find(_=>_.path===p.replace(/\/[^/]+\/$/,"/"));if(y){const _=(m=y.children)==null?void 0:m.find(E=>E.path===p);_&&(_.children??(_.children=[])).push(u)}}}}),c});return()=>{const i=l.value.some(f=>f.children);return d("div",{class:["vp-catalog",{index:e.index}]},[e.hideHeading?null:d("h2",{class:"vp-catalog-main-title"},n.value.title),l.value.length?d(e.index?"ol":"ul",{class:["vp-catalog-list",{deep:i}]},l.value.map(({children:f=[],title:c,path:u,content:p})=>{const h=d(At,{class:"vp-catalog-title",to:u},()=>p?d(p):c);return d("li",{class:"vp-catalog-item"},i?[d("h3",{id:c,class:["vp-catalog-child-title",{"has-children":f.length}]},[d("a",{href:`#${c}`,class:"vp-catalog-header-anchor","aria-hidden":!0},"#"),h]),f.length?d(e.index?"ol":"ul",{class:"vp-child-catalogs"},f.map(({children:m=[],content:y,path:_,title:E})=>d("li",{class:"vp-child-catalog"},[d("div",{class:["vp-catalog-sub-title",{"has-children":m.length}]},[d("a",{href:`#${E}`,class:"vp-catalog-header-anchor"},"#"),d(At,{class:"vp-catalog-title",to:_},()=>y?d(y):E)]),m.length?d(e.index?"ol":"div",{class:e.index?"vp-sub-catalogs":"vp-sub-catalogs-wrapper"},m.map(({content:w,path:v,title:T})=>e.index?d("li",{class:"vp-sub-catalog"},d(At,{to:v},()=>w?d(w):T)):d(At,{class:"vp-sub-catalog-link",to:v},()=>w?d(w):T))):null]))):null]:d("div",{class:"vp-catalog-child-title"},h))})):d("p",{class:"vp-empty-catalog"},n.value.empty)])}}}),Xg=Ft({enhance:({app:e})=>{Gg(e),Ot("Catalog",e)||e.component("Catalog",Qg)}});const Jg=Object.freeze(Object.defineProperty({__proto__:null,default:Xg},Symbol.toStringTag,{value:"Module"}));var Zg={"/":{backToTop:"Back to top"}};const e_=X({name:"BackToTop",setup(){const e=Re(),t=_n(Zg),n=Fe(),{height:r}=ug(n),{height:o}=mg(),{y:s}=hg(),a=S(()=>e.value.backToTop!==!1&&s.value>100),l=S(()=>s.value/(r.value-o.value)*100);return Se(()=>{n.value=document.body}),()=>d(nr,{name:"back-to-top"},()=>a.value?d("button",{type:"button",class:"vp-back-to-top-button","aria-label":t.value.backToTop,onClick:()=>{window.scrollTo({top:0,behavior:"smooth"})}},[d("span",{class:"vp-scroll-progress",role:"progressbar","aria-labelledby":"loadinglabel","aria-valuenow":l.value},d("svg",d("circle",{cx:"26",cy:"26",r:"24",fill:"none",stroke:"currentColor","stroke-width":"4","stroke-dasharray":`${Math.PI*l.value*.48} ${Math.PI*(100-l.value)*.48}`}))),d("div",{class:"back-to-top-icon"})]):null)}}),t_=Ft({rootComponents:[e_]}),n_=Object.freeze(Object.defineProperty({__proto__:null,default:t_},Symbol.toStringTag,{value:"Module"}));/** + * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT + */const $i=(e,t)=>{e.classList.add(t)},Fi=(e,t)=>{e.classList.remove(t)},r_=e=>{var t;(t=e==null?void 0:e.parentNode)==null||t.removeChild(e)},Is=(e,t,n)=>en?n:e,Bi=e=>(-1+e)*100,o_=(()=>{const e=[],t=()=>{const n=e.shift();n&&n(t)};return n=>{e.push(n),e.length===1&&t()}})(),s_=e=>e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(t,n)=>n.toUpperCase()),Eo=(()=>{const e=["Webkit","O","Moz","ms"],t={},n=s=>{const{style:a}=document.body;if(s in a)return s;const l=s.charAt(0).toUpperCase()+s.slice(1);let i=e.length;for(;i--;){const f=`${e[i]}${l}`;if(f in a)return f}return s},r=s=>{const a=s_(s);return t[a]??(t[a]=n(a))},o=(s,a,l)=>{s.style[r(a)]=l};return(s,a)=>{for(const l in a){const i=a[l];Object.hasOwn(a,l)&&el(i)&&o(s,l,i)}}})(),jt={minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},xe={percent:null,isRendered:()=>!!document.getElementById("nprogress"),set:e=>{const{speed:t,easing:n}=jt,r=xe.isStarted(),o=Is(e,jt.minimum,1);xe.percent=o===1?null:o;const s=xe.render(!r),a=s.querySelector(jt.barSelector);return s.offsetWidth,o_(l=>{Eo(a,{transform:`translate3d(${Bi(o)}%,0,0)`,transition:`all ${t}ms ${n}`}),o===1?(Eo(s,{transition:"none",opacity:"1"}),s.offsetWidth,setTimeout(()=>{Eo(s,{transition:`all ${t}ms linear`,opacity:"0"}),setTimeout(()=>{xe.remove(),l()},t)},t)):setTimeout(()=>{l()},t)}),xe},isStarted:()=>typeof xe.percent=="number",start:()=>{xe.percent||xe.set(0);const e=()=>{setTimeout(()=>{xe.percent&&(xe.trickle(),e())},jt.trickleSpeed)};return e(),xe},done:e=>!e&&!xe.percent?xe:xe.increase(.3+.5*Math.random()).set(1),increase:e=>{let{percent:t}=xe;return t?(t=Is(t+(typeof e=="number"?e:(1-t)*Is(Math.random()*t,.1,.95)),0,.994),xe.set(t)):xe.start()},trickle:()=>xe.increase(Math.random()*jt.trickleRate),render:e=>{if(xe.isRendered())return document.getElementById("nprogress");$i(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=jt.template;const n=t.querySelector(jt.barSelector),r=document.querySelector(jt.parent),o=e?"-100":Bi(xe.percent??0);return Eo(n,{transition:"all 0 linear",transform:`translate3d(${o}%,0,0)`}),r&&(r!==document.body&&$i(r,"nprogress-custom-parent"),r.appendChild(t)),t},remove:()=>{Fi(document.documentElement,"nprogress-busy"),Fi(document.querySelector(jt.parent),"nprogress-custom-parent"),r_(document.getElementById("nprogress"))}},a_=()=>{Se(()=>{const e=Mn(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||xe.start()}),e.afterEach(n=>{t.add(n.path),xe.done()})})},l_=Ft({setup(){a_()}}),i_=Object.freeze(Object.defineProperty({__proto__:null,default:l_},Symbol.toStringTag,{value:"Module"}));var u_=Object.create,pd=Object.defineProperty,c_=Object.getOwnPropertyDescriptor,nl=Object.getOwnPropertyNames,f_=Object.getPrototypeOf,d_=Object.prototype.hasOwnProperty,p_=(e,t)=>function(){return e&&(t=(0,e[nl(e)[0]])(e=0)),t},h_=(e,t)=>function(){return t||(0,e[nl(e)[0]])((t={exports:{}}).exports,t),t.exports},m_=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of nl(t))!d_.call(e,o)&&o!==n&&pd(e,o,{get:()=>t[o],enumerable:!(r=c_(t,o))||r.enumerable});return e},v_=(e,t,n)=>(n=e!=null?u_(f_(e)):{},m_(pd(n,"default",{value:e,enumerable:!0}),e)),uo=p_({"../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.43.0_@types+node@20.16.14__@swc+core@1.5.29_jiti@2.0.0__utvtwgyeu6xd57udthcnogp47u/node_modules/tsup/assets/esm_shims.js"(){}}),g_=h_({"../../node_modules/.pnpm/rfdc@1.4.1/node_modules/rfdc/index.js"(e,t){uo(),t.exports=r;function n(s){return s instanceof Buffer?Buffer.from(s):new s.constructor(s.buffer.slice(),s.byteOffset,s.length)}function r(s){if(s=s||{},s.circles)return o(s);const a=new Map;if(a.set(Date,u=>new Date(u)),a.set(Map,(u,p)=>new Map(i(Array.from(u),p))),a.set(Set,(u,p)=>new Set(i(Array.from(u),p))),s.constructorHandlers)for(const u of s.constructorHandlers)a.set(u[0],u[1]);let l=null;return s.proto?c:f;function i(u,p){const h=Object.keys(u),m=new Array(h.length);for(let y=0;ynew Date(h)),i.set(Map,(h,m)=>new Map(c(Array.from(h),m))),i.set(Set,(h,m)=>new Set(c(Array.from(h),m))),s.constructorHandlers)for(const h of s.constructorHandlers)i.set(h[0],h[1]);let f=null;return s.proto?p:u;function c(h,m){const y=Object.keys(h),_=new Array(y.length);for(let E=0;E(a=A_(e,f,c),a.finally(()=>{if(a=null,n.trailing&&l&&!o){const u=i(f,l);return l=null,u}}),a);return function(...f){return a?(n.trailing&&(l=f),a):new Promise(c=>{const u=!o&&n.leading;clearTimeout(o),o=setTimeout(()=>{o=null;const p=n.leading?r:i(this,f);for(const h of s)h(p);s=[]},t),u?(r=i(this,f),c(r)):s.push(c)})}}async function A_(e,t,n){return await e.apply(t,n)}function aa(e,t={},n){for(const r in e){const o=e[r],s=n?`${n}:${r}`:r;typeof o=="object"&&o!==null?aa(o,t,s):typeof o=="function"&&(t[s]=o)}return t}const S_={run:e=>e()},C_=()=>S_,md=typeof console.createTask<"u"?console.createTask:C_;function k_(e,t){const n=t.shift(),r=md(n);return e.reduce((o,s)=>o.then(()=>r.run(()=>s(...t))),Promise.resolve())}function O_(e,t){const n=t.shift(),r=md(n);return Promise.all(e.map(o=>r.run(()=>o(...t))))}function Ds(e,t){for(const n of[...e])n(t)}class x_{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(t,n,r={}){if(!t||typeof n!="function")return()=>{};const o=t;let s;for(;this._deprecatedHooks[t];)s=this._deprecatedHooks[t],t=s.to;if(s&&!r.allowDeprecated){let a=s.message;a||(a=`${o} hook has been deprecated`+(s.to?`, please use ${s.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(a)||(console.warn(a),this._deprecatedMessages.add(a))}if(!n.name)try{Object.defineProperty(n,"name",{get:()=>"_"+t.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[t]=this._hooks[t]||[],this._hooks[t].push(n),()=>{n&&(this.removeHook(t,n),n=void 0)}}hookOnce(t,n){let r,o=(...s)=>(typeof r=="function"&&r(),r=void 0,o=void 0,n(...s));return r=this.hook(t,o),r}removeHook(t,n){if(this._hooks[t]){const r=this._hooks[t].indexOf(n);r!==-1&&this._hooks[t].splice(r,1),this._hooks[t].length===0&&delete this._hooks[t]}}deprecateHook(t,n){this._deprecatedHooks[t]=typeof n=="string"?{to:n}:n;const r=this._hooks[t]||[];delete this._hooks[t];for(const o of r)this.hook(t,o)}deprecateHooks(t){Object.assign(this._deprecatedHooks,t);for(const n in t)this.deprecateHook(n,t[n])}addHooks(t){const n=aa(t),r=Object.keys(n).map(o=>this.hook(o,n[o]));return()=>{for(const o of r.splice(0,r.length))o()}}removeHooks(t){const n=aa(t);for(const r in n)this.removeHook(r,n[r])}removeAllHooks(){for(const t in this._hooks)delete this._hooks[t]}callHook(t,...n){return n.unshift(t),this.callHookWith(k_,t,...n)}callHookParallel(t,...n){return n.unshift(t),this.callHookWith(O_,t,...n)}callHookWith(t,n,...r){const o=this._before||this._after?{name:n,args:r,context:{}}:void 0;this._before&&Ds(this._before,o);const s=t(n in this._hooks?[...this._hooks[n]]:[],r);return s instanceof Promise?s.finally(()=>{this._after&&o&&Ds(this._after,o)}):(this._after&&o&&Ds(this._after,o),s)}beforeEach(t){return this._before=this._before||[],this._before.push(t),()=>{if(this._before!==void 0){const n=this._before.indexOf(t);n!==-1&&this._before.splice(n,1)}}}afterEach(t){return this._after=this._after||[],this._after.push(t),()=>{if(this._after!==void 0){const n=this._after.indexOf(t);n!==-1&&this._after.splice(n,1)}}}}function vd(){return new x_}var R_=Object.create,gd=Object.defineProperty,I_=Object.getOwnPropertyDescriptor,rl=Object.getOwnPropertyNames,D_=Object.getPrototypeOf,P_=Object.prototype.hasOwnProperty,L_=(e,t)=>function(){return e&&(t=(0,e[rl(e)[0]])(e=0)),t},_d=(e,t)=>function(){return t||(0,e[rl(e)[0]])((t={exports:{}}).exports,t),t.exports},V_=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of rl(t))!P_.call(e,o)&&o!==n&&gd(e,o,{get:()=>t[o],enumerable:!(r=I_(t,o))||r.enumerable});return e},N_=(e,t,n)=>(n=e!=null?R_(D_(e)):{},V_(gd(n,"default",{value:e,enumerable:!0}),e)),x=L_({"../../node_modules/.pnpm/tsup@8.3.0_@microsoft+api-extractor@7.43.0_@types+node@20.16.14__@swc+core@1.5.29_jiti@2.0.0__utvtwgyeu6xd57udthcnogp47u/node_modules/tsup/assets/esm_shims.js"(){}}),M_=_d({"../../node_modules/.pnpm/speakingurl@14.0.1/node_modules/speakingurl/lib/speakingurl.js"(e,t){x(),function(n){var r={À:"A",Á:"A",Â:"A",Ã:"A",Ä:"Ae",Å:"A",Æ:"AE",Ç:"C",È:"E",É:"E",Ê:"E",Ë:"E",Ì:"I",Í:"I",Î:"I",Ï:"I",Ð:"D",Ñ:"N",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"Oe",Ő:"O",Ø:"O",Ù:"U",Ú:"U",Û:"U",Ü:"Ue",Ű:"U",Ý:"Y",Þ:"TH",ß:"ss",à:"a",á:"a",â:"a",ã:"a",ä:"ae",å:"a",æ:"ae",ç:"c",è:"e",é:"e",ê:"e",ë:"e",ì:"i",í:"i",î:"i",ï:"i",ð:"d",ñ:"n",ò:"o",ó:"o",ô:"o",õ:"o",ö:"oe",ő:"o",ø:"o",ù:"u",ú:"u",û:"u",ü:"ue",ű:"u",ý:"y",þ:"th",ÿ:"y","ẞ":"SS",ا:"a",أ:"a",إ:"i",آ:"aa",ؤ:"u",ئ:"e",ء:"a",ب:"b",ت:"t",ث:"th",ج:"j",ح:"h",خ:"kh",د:"d",ذ:"th",ر:"r",ز:"z",س:"s",ش:"sh",ص:"s",ض:"dh",ط:"t",ظ:"z",ع:"a",غ:"gh",ف:"f",ق:"q",ك:"k",ل:"l",م:"m",ن:"n",ه:"h",و:"w",ي:"y",ى:"a",ة:"h",ﻻ:"la",ﻷ:"laa",ﻹ:"lai",ﻵ:"laa",گ:"g",چ:"ch",پ:"p",ژ:"zh",ک:"k",ی:"y","َ":"a","ً":"an","ِ":"e","ٍ":"en","ُ":"u","ٌ":"on","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9",က:"k",ခ:"kh",ဂ:"g",ဃ:"ga",င:"ng",စ:"s",ဆ:"sa",ဇ:"z","စျ":"za",ည:"ny",ဋ:"t",ဌ:"ta",ဍ:"d",ဎ:"da",ဏ:"na",တ:"t",ထ:"ta",ဒ:"d",ဓ:"da",န:"n",ပ:"p",ဖ:"pa",ဗ:"b",ဘ:"ba",မ:"m",ယ:"y",ရ:"ya",လ:"l",ဝ:"w",သ:"th",ဟ:"h",ဠ:"la",အ:"a","ြ":"y","ျ":"ya","ွ":"w","ြွ":"yw","ျွ":"ywa","ှ":"h",ဧ:"e","၏":"-e",ဣ:"i",ဤ:"-i",ဉ:"u",ဦ:"-u",ဩ:"aw","သြော":"aw",ဪ:"aw","၀":"0","၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","္":"","့":"","း":"",č:"c",ď:"d",ě:"e",ň:"n",ř:"r",š:"s",ť:"t",ů:"u",ž:"z",Č:"C",Ď:"D",Ě:"E",Ň:"N",Ř:"R",Š:"S",Ť:"T",Ů:"U",Ž:"Z",ހ:"h",ށ:"sh",ނ:"n",ރ:"r",ބ:"b",ޅ:"lh",ކ:"k",އ:"a",ވ:"v",މ:"m",ފ:"f",ދ:"dh",ތ:"th",ލ:"l",ގ:"g",ޏ:"gn",ސ:"s",ޑ:"d",ޒ:"z",ޓ:"t",ޔ:"y",ޕ:"p",ޖ:"j",ޗ:"ch",ޘ:"tt",ޙ:"hh",ޚ:"kh",ޛ:"th",ޜ:"z",ޝ:"sh",ޞ:"s",ޟ:"d",ޠ:"t",ޡ:"z",ޢ:"a",ޣ:"gh",ޤ:"q",ޥ:"w","ަ":"a","ާ":"aa","ި":"i","ީ":"ee","ު":"u","ޫ":"oo","ެ":"e","ޭ":"ey","ޮ":"o","ޯ":"oa","ް":"",ა:"a",ბ:"b",გ:"g",დ:"d",ე:"e",ვ:"v",ზ:"z",თ:"t",ი:"i",კ:"k",ლ:"l",მ:"m",ნ:"n",ო:"o",პ:"p",ჟ:"zh",რ:"r",ს:"s",ტ:"t",უ:"u",ფ:"p",ქ:"k",ღ:"gh",ყ:"q",შ:"sh",ჩ:"ch",ც:"ts",ძ:"dz",წ:"ts",ჭ:"ch",ხ:"kh",ჯ:"j",ჰ:"h",α:"a",β:"v",γ:"g",δ:"d",ε:"e",ζ:"z",η:"i",θ:"th",ι:"i",κ:"k",λ:"l",μ:"m",ν:"n",ξ:"ks",ο:"o",π:"p",ρ:"r",σ:"s",τ:"t",υ:"y",φ:"f",χ:"x",ψ:"ps",ω:"o",ά:"a",έ:"e",ί:"i",ό:"o",ύ:"y",ή:"i",ώ:"o",ς:"s",ϊ:"i",ΰ:"y",ϋ:"y",ΐ:"i",Α:"A",Β:"B",Γ:"G",Δ:"D",Ε:"E",Ζ:"Z",Η:"I",Θ:"TH",Ι:"I",Κ:"K",Λ:"L",Μ:"M",Ν:"N",Ξ:"KS",Ο:"O",Π:"P",Ρ:"R",Σ:"S",Τ:"T",Υ:"Y",Φ:"F",Χ:"X",Ψ:"PS",Ω:"O",Ά:"A",Έ:"E",Ί:"I",Ό:"O",Ύ:"Y",Ή:"I",Ώ:"O",Ϊ:"I",Ϋ:"Y",ā:"a",ē:"e",ģ:"g",ī:"i",ķ:"k",ļ:"l",ņ:"n",ū:"u",Ā:"A",Ē:"E",Ģ:"G",Ī:"I",Ķ:"k",Ļ:"L",Ņ:"N",Ū:"U",Ќ:"Kj",ќ:"kj",Љ:"Lj",љ:"lj",Њ:"Nj",њ:"nj",Тс:"Ts",тс:"ts",ą:"a",ć:"c",ę:"e",ł:"l",ń:"n",ś:"s",ź:"z",ż:"z",Ą:"A",Ć:"C",Ę:"E",Ł:"L",Ń:"N",Ś:"S",Ź:"Z",Ż:"Z",Є:"Ye",І:"I",Ї:"Yi",Ґ:"G",є:"ye",і:"i",ї:"yi",ґ:"g",ă:"a",Ă:"A",ș:"s",Ș:"S",ț:"t",Ț:"T",ţ:"t",Ţ:"T",а:"a",б:"b",в:"v",г:"g",д:"d",е:"e",ё:"yo",ж:"zh",з:"z",и:"i",й:"i",к:"k",л:"l",м:"m",н:"n",о:"o",п:"p",р:"r",с:"s",т:"t",у:"u",ф:"f",х:"kh",ц:"c",ч:"ch",ш:"sh",щ:"sh",ъ:"",ы:"y",ь:"",э:"e",ю:"yu",я:"ya",А:"A",Б:"B",В:"V",Г:"G",Д:"D",Е:"E",Ё:"Yo",Ж:"Zh",З:"Z",И:"I",Й:"I",К:"K",Л:"L",М:"M",Н:"N",О:"O",П:"P",Р:"R",С:"S",Т:"T",У:"U",Ф:"F",Х:"Kh",Ц:"C",Ч:"Ch",Ш:"Sh",Щ:"Sh",Ъ:"",Ы:"Y",Ь:"",Э:"E",Ю:"Yu",Я:"Ya",ђ:"dj",ј:"j",ћ:"c",џ:"dz",Ђ:"Dj",Ј:"j",Ћ:"C",Џ:"Dz",ľ:"l",ĺ:"l",ŕ:"r",Ľ:"L",Ĺ:"L",Ŕ:"R",ş:"s",Ş:"S",ı:"i",İ:"I",ğ:"g",Ğ:"G",ả:"a",Ả:"A",ẳ:"a",Ẳ:"A",ẩ:"a",Ẩ:"A",đ:"d",Đ:"D",ẹ:"e",Ẹ:"E",ẽ:"e",Ẽ:"E",ẻ:"e",Ẻ:"E",ế:"e",Ế:"E",ề:"e",Ề:"E",ệ:"e",Ệ:"E",ễ:"e",Ễ:"E",ể:"e",Ể:"E",ỏ:"o",ọ:"o",Ọ:"o",ố:"o",Ố:"O",ồ:"o",Ồ:"O",ổ:"o",Ổ:"O",ộ:"o",Ộ:"O",ỗ:"o",Ỗ:"O",ơ:"o",Ơ:"O",ớ:"o",Ớ:"O",ờ:"o",Ờ:"O",ợ:"o",Ợ:"O",ỡ:"o",Ỡ:"O",Ở:"o",ở:"o",ị:"i",Ị:"I",ĩ:"i",Ĩ:"I",ỉ:"i",Ỉ:"i",ủ:"u",Ủ:"U",ụ:"u",Ụ:"U",ũ:"u",Ũ:"U",ư:"u",Ư:"U",ứ:"u",Ứ:"U",ừ:"u",Ừ:"U",ự:"u",Ự:"U",ữ:"u",Ữ:"U",ử:"u",Ử:"ư",ỷ:"y",Ỷ:"y",ỳ:"y",Ỳ:"Y",ỵ:"y",Ỵ:"Y",ỹ:"y",Ỹ:"Y",ạ:"a",Ạ:"A",ấ:"a",Ấ:"A",ầ:"a",Ầ:"A",ậ:"a",Ậ:"A",ẫ:"a",Ẫ:"A",ắ:"a",Ắ:"A",ằ:"a",Ằ:"A",ặ:"a",Ặ:"A",ẵ:"a",Ẵ:"A","⓪":"0","①":"1","②":"2","③":"3","④":"4","⑤":"5","⑥":"6","⑦":"7","⑧":"8","⑨":"9","⑩":"10","⑪":"11","⑫":"12","⑬":"13","⑭":"14","⑮":"15","⑯":"16","⑰":"17","⑱":"18","⑲":"18","⑳":"18","⓵":"1","⓶":"2","⓷":"3","⓸":"4","⓹":"5","⓺":"6","⓻":"7","⓼":"8","⓽":"9","⓾":"10","⓿":"0","⓫":"11","⓬":"12","⓭":"13","⓮":"14","⓯":"15","⓰":"16","⓱":"17","⓲":"18","⓳":"19","⓴":"20","Ⓐ":"A","Ⓑ":"B","Ⓒ":"C","Ⓓ":"D","Ⓔ":"E","Ⓕ":"F","Ⓖ":"G","Ⓗ":"H","Ⓘ":"I","Ⓙ":"J","Ⓚ":"K","Ⓛ":"L","Ⓜ":"M","Ⓝ":"N","Ⓞ":"O","Ⓟ":"P","Ⓠ":"Q","Ⓡ":"R","Ⓢ":"S","Ⓣ":"T","Ⓤ":"U","Ⓥ":"V","Ⓦ":"W","Ⓧ":"X","Ⓨ":"Y","Ⓩ":"Z","ⓐ":"a","ⓑ":"b","ⓒ":"c","ⓓ":"d","ⓔ":"e","ⓕ":"f","ⓖ":"g","ⓗ":"h","ⓘ":"i","ⓙ":"j","ⓚ":"k","ⓛ":"l","ⓜ":"m","ⓝ":"n","ⓞ":"o","ⓟ":"p","ⓠ":"q","ⓡ":"r","ⓢ":"s","ⓣ":"t","ⓤ":"u","ⓦ":"v","ⓥ":"w","ⓧ":"x","ⓨ":"y","ⓩ":"z","“":'"',"”":'"',"‘":"'","’":"'","∂":"d",ƒ:"f","™":"(TM)","©":"(C)",œ:"oe",Œ:"OE","®":"(R)","†":"+","℠":"(SM)","…":"...","˚":"o",º:"o",ª:"a","•":"*","၊":",","။":".",$:"USD","€":"EUR","₢":"BRN","₣":"FRF","£":"GBP","₤":"ITL","₦":"NGN","₧":"ESP","₩":"KRW","₪":"ILS","₫":"VND","₭":"LAK","₮":"MNT","₯":"GRD","₱":"ARS","₲":"PYG","₳":"ARA","₴":"UAH","₵":"GHS","¢":"cent","¥":"CNY",元:"CNY",円:"YEN","﷼":"IRR","₠":"EWE","฿":"THB","₨":"INR","₹":"INR","₰":"PF","₺":"TRY","؋":"AFN","₼":"AZN",лв:"BGN","៛":"KHR","₡":"CRC","₸":"KZT",ден:"MKD",zł:"PLN","₽":"RUB","₾":"GEL"},o=["်","ް"],s={"ာ":"a","ါ":"a","ေ":"e","ဲ":"e","ိ":"i","ီ":"i","ို":"o","ု":"u","ူ":"u","ေါင်":"aung","ော":"aw","ော်":"aw","ေါ":"aw","ေါ်":"aw","်":"်","က်":"et","ိုက်":"aik","ောက်":"auk","င်":"in","ိုင်":"aing","ောင်":"aung","စ်":"it","ည်":"i","တ်":"at","ိတ်":"eik","ုတ်":"ok","ွတ်":"ut","ေတ်":"it","ဒ်":"d","ိုဒ်":"ok","ုဒ်":"ait","န်":"an","ာန်":"an","ိန်":"ein","ုန်":"on","ွန်":"un","ပ်":"at","ိပ်":"eik","ုပ်":"ok","ွပ်":"ut","န်ုပ်":"nub","မ်":"an","ိမ်":"ein","ုမ်":"on","ွမ်":"un","ယ်":"e","ိုလ်":"ol","ဉ်":"in","ံ":"an","ိံ":"ein","ုံ":"on","ައް":"ah","ަށް":"ah"},a={en:{},az:{ç:"c",ə:"e",ğ:"g",ı:"i",ö:"o",ş:"s",ü:"u",Ç:"C",Ə:"E",Ğ:"G",İ:"I",Ö:"O",Ş:"S",Ü:"U"},cs:{č:"c",ď:"d",ě:"e",ň:"n",ř:"r",š:"s",ť:"t",ů:"u",ž:"z",Č:"C",Ď:"D",Ě:"E",Ň:"N",Ř:"R",Š:"S",Ť:"T",Ů:"U",Ž:"Z"},fi:{ä:"a",Ä:"A",ö:"o",Ö:"O"},hu:{ä:"a",Ä:"A",ö:"o",Ö:"O",ü:"u",Ü:"U",ű:"u",Ű:"U"},lt:{ą:"a",č:"c",ę:"e",ė:"e",į:"i",š:"s",ų:"u",ū:"u",ž:"z",Ą:"A",Č:"C",Ę:"E",Ė:"E",Į:"I",Š:"S",Ų:"U",Ū:"U"},lv:{ā:"a",č:"c",ē:"e",ģ:"g",ī:"i",ķ:"k",ļ:"l",ņ:"n",š:"s",ū:"u",ž:"z",Ā:"A",Č:"C",Ē:"E",Ģ:"G",Ī:"i",Ķ:"k",Ļ:"L",Ņ:"N",Š:"S",Ū:"u",Ž:"Z"},pl:{ą:"a",ć:"c",ę:"e",ł:"l",ń:"n",ó:"o",ś:"s",ź:"z",ż:"z",Ą:"A",Ć:"C",Ę:"e",Ł:"L",Ń:"N",Ó:"O",Ś:"S",Ź:"Z",Ż:"Z"},sv:{ä:"a",Ä:"A",ö:"o",Ö:"O"},sk:{ä:"a",Ä:"A"},sr:{љ:"lj",њ:"nj",Љ:"Lj",Њ:"Nj",đ:"dj",Đ:"Dj"},tr:{Ü:"U",Ö:"O",ü:"u",ö:"o"}},l={ar:{"∆":"delta","∞":"la-nihaya","♥":"hob","&":"wa","|":"aw","<":"aqal-men",">":"akbar-men","∑":"majmou","¤":"omla"},az:{},ca:{"∆":"delta","∞":"infinit","♥":"amor","&":"i","|":"o","<":"menys que",">":"mes que","∑":"suma dels","¤":"moneda"},cs:{"∆":"delta","∞":"nekonecno","♥":"laska","&":"a","|":"nebo","<":"mensi nez",">":"vetsi nez","∑":"soucet","¤":"mena"},de:{"∆":"delta","∞":"unendlich","♥":"Liebe","&":"und","|":"oder","<":"kleiner als",">":"groesser als","∑":"Summe von","¤":"Waehrung"},dv:{"∆":"delta","∞":"kolunulaa","♥":"loabi","&":"aai","|":"noonee","<":"ah vure kuda",">":"ah vure bodu","∑":"jumula","¤":"faisaa"},en:{"∆":"delta","∞":"infinity","♥":"love","&":"and","|":"or","<":"less than",">":"greater than","∑":"sum","¤":"currency"},es:{"∆":"delta","∞":"infinito","♥":"amor","&":"y","|":"u","<":"menos que",">":"mas que","∑":"suma de los","¤":"moneda"},fa:{"∆":"delta","∞":"bi-nahayat","♥":"eshgh","&":"va","|":"ya","<":"kamtar-az",">":"bishtar-az","∑":"majmooe","¤":"vahed"},fi:{"∆":"delta","∞":"aarettomyys","♥":"rakkaus","&":"ja","|":"tai","<":"pienempi kuin",">":"suurempi kuin","∑":"summa","¤":"valuutta"},fr:{"∆":"delta","∞":"infiniment","♥":"Amour","&":"et","|":"ou","<":"moins que",">":"superieure a","∑":"somme des","¤":"monnaie"},ge:{"∆":"delta","∞":"usasruloba","♥":"siqvaruli","&":"da","|":"an","<":"naklebi",">":"meti","∑":"jami","¤":"valuta"},gr:{},hu:{"∆":"delta","∞":"vegtelen","♥":"szerelem","&":"es","|":"vagy","<":"kisebb mint",">":"nagyobb mint","∑":"szumma","¤":"penznem"},it:{"∆":"delta","∞":"infinito","♥":"amore","&":"e","|":"o","<":"minore di",">":"maggiore di","∑":"somma","¤":"moneta"},lt:{"∆":"delta","∞":"begalybe","♥":"meile","&":"ir","|":"ar","<":"maziau nei",">":"daugiau nei","∑":"suma","¤":"valiuta"},lv:{"∆":"delta","∞":"bezgaliba","♥":"milestiba","&":"un","|":"vai","<":"mazak neka",">":"lielaks neka","∑":"summa","¤":"valuta"},my:{"∆":"kwahkhyaet","∞":"asaonasme","♥":"akhyait","&":"nhin","|":"tho","<":"ngethaw",">":"kyithaw","∑":"paungld","¤":"ngwekye"},mk:{},nl:{"∆":"delta","∞":"oneindig","♥":"liefde","&":"en","|":"of","<":"kleiner dan",">":"groter dan","∑":"som","¤":"valuta"},pl:{"∆":"delta","∞":"nieskonczonosc","♥":"milosc","&":"i","|":"lub","<":"mniejsze niz",">":"wieksze niz","∑":"suma","¤":"waluta"},pt:{"∆":"delta","∞":"infinito","♥":"amor","&":"e","|":"ou","<":"menor que",">":"maior que","∑":"soma","¤":"moeda"},ro:{"∆":"delta","∞":"infinit","♥":"dragoste","&":"si","|":"sau","<":"mai mic ca",">":"mai mare ca","∑":"suma","¤":"valuta"},ru:{"∆":"delta","∞":"beskonechno","♥":"lubov","&":"i","|":"ili","<":"menshe",">":"bolshe","∑":"summa","¤":"valjuta"},sk:{"∆":"delta","∞":"nekonecno","♥":"laska","&":"a","|":"alebo","<":"menej ako",">":"viac ako","∑":"sucet","¤":"mena"},sr:{},tr:{"∆":"delta","∞":"sonsuzluk","♥":"ask","&":"ve","|":"veya","<":"kucuktur",">":"buyuktur","∑":"toplam","¤":"para birimi"},uk:{"∆":"delta","∞":"bezkinechnist","♥":"lubov","&":"i","|":"abo","<":"menshe",">":"bilshe","∑":"suma","¤":"valjuta"},vn:{"∆":"delta","∞":"vo cuc","♥":"yeu","&":"va","|":"hoac","<":"nho hon",">":"lon hon","∑":"tong","¤":"tien te"}},i=[";","?",":","@","&","=","+","$",",","/"].join(""),f=[";","?",":","@","&","=","+","$",","].join(""),c=[".","!","~","*","'","(",")"].join(""),u=function(_,E){var w="-",v="",T="",V=!0,H={},$,J,N,R,j,L,Z,le,de,K,F,Y,ae,Ie,De="";if(typeof _!="string")return"";if(typeof E=="string"&&(w=E),Z=l.en,le=a.en,typeof E=="object"){$=E.maintainCase||!1,H=E.custom&&typeof E.custom=="object"?E.custom:H,N=+E.truncate>1&&E.truncate||!1,R=E.uric||!1,j=E.uricNoSlash||!1,L=E.mark||!1,V=!(E.symbols===!1||E.lang===!1),w=E.separator||w,R&&(De+=i),j&&(De+=f),L&&(De+=c),Z=E.lang&&l[E.lang]&&V?l[E.lang]:V?l.en:{},le=E.lang&&a[E.lang]?a[E.lang]:E.lang===!1||E.lang===!0?{}:a.en,E.titleCase&&typeof E.titleCase.length=="number"&&Array.prototype.toString.call(E.titleCase)?(E.titleCase.forEach(function(pe){H[pe+""]=pe+""}),J=!0):J=!!E.titleCase,E.custom&&typeof E.custom.length=="number"&&Array.prototype.toString.call(E.custom)&&E.custom.forEach(function(pe){H[pe+""]=pe+""}),Object.keys(H).forEach(function(pe){var Me;pe.length>1?Me=new RegExp("\\b"+h(pe)+"\\b","gi"):Me=new RegExp(h(pe),"gi"),_=_.replace(Me,H[pe])});for(F in H)De+=F}for(De+=w,De=h(De),_=_.replace(/(^\s+|\s+$)/g,""),ae=!1,Ie=!1,K=0,Y=_.length;K=0?(T+=F,F=""):Ie===!0?(F=s[T]+r[F],T=""):F=ae&&r[F].match(/[A-Za-z0-9]/)?" "+r[F]:r[F],ae=!1,Ie=!1):F in s?(T+=F,F="",K===Y-1&&(F=s[T]),Ie=!0):Z[F]&&!(R&&i.indexOf(F)!==-1)&&!(j&&f.indexOf(F)!==-1)?(F=ae||v.substr(-1).match(/[A-Za-z0-9]/)?w+Z[F]:Z[F],F+=_[K+1]!==void 0&&_[K+1].match(/[A-Za-z0-9]/)?w:"",ae=!0):(Ie===!0?(F=s[T]+F,T="",Ie=!1):ae&&(/[A-Za-z0-9]/.test(F)||v.substr(-1).match(/A-Za-z0-9]/))&&(F=" "+F),ae=!1),v+=F.replace(new RegExp("[^\\w\\s"+De+"_-]","g"),w);return J&&(v=v.replace(/(\w)(\S*)/g,function(pe,Me,pt){var Ze=Me.toUpperCase()+(pt!==null?pt:"");return Object.keys(H).indexOf(Ze.toLowerCase())<0?Ze:Ze.toLowerCase()})),v=v.replace(/\s+/g,w).replace(new RegExp("\\"+w+"+","g"),w).replace(new RegExp("(^\\"+w+"+|\\"+w+"+$)","g"),""),N&&v.length>N&&(de=v.charAt(N)===w,v=v.slice(0,N),de||(v=v.slice(0,v.lastIndexOf(w)))),!$&&!J&&(v=v.toLowerCase()),v},p=function(_){return function(w){return u(w,_)}},h=function(_){return _.replace(/[-\\^$*+?.()|[\]{}\/]/g,"\\$&")},m=function(y,_){for(var E in _)if(_[E]===y)return!0};if(typeof t<"u"&&t.exports)t.exports=u,t.exports.createSlug=p;else if(typeof define<"u"&&define.amd)define([],function(){return u});else try{if(n.getSlug||n.createSlug)throw"speakingurl: globals exists /(getSlug|createSlug)/";n.getSlug=u,n.createSlug=p}catch{}}(e)}}),$_=_d({"../../node_modules/.pnpm/speakingurl@14.0.1/node_modules/speakingurl/index.js"(e,t){x(),t.exports=M_()}});x();x();x();x();x();x();x();function F_(e){return!!(e&&e.__v_isReadonly)}function yd(e){return F_(e)?yd(e.__v_raw):!!(e&&e.__v_isReactive)}function Ps(e){return!!(e&&e.__v_isRef===!0)}function wr(e){const t=e&&e.__v_raw;return t?wr(t):e}var B_=Symbol.for("v-fgt");x();function H_(e){var t;const n=e.name||e._componentTag||e.__VUE_DEVTOOLS_COMPONENT_GUSSED_NAME__||e.__name;return n==="index"&&((t=e.__file)!=null&&t.endsWith("index.vue"))?"":n}function j_(e){const t=e.__file;if(t)return b_(w_(t,".vue"))}function Ui(e,t){return e.type.__VUE_DEVTOOLS_COMPONENT_GUSSED_NAME__=t,t}function ol(e){if(e.__VUE_DEVTOOLS_NEXT_APP_RECORD__)return e.__VUE_DEVTOOLS_NEXT_APP_RECORD__;if(e.root)return e.appContext.app.__VUE_DEVTOOLS_NEXT_APP_RECORD__}async function U_(e){const{app:t,uid:n,instance:r}=e;try{if(r.__VUE_DEVTOOLS_NEXT_UID__)return r.__VUE_DEVTOOLS_NEXT_UID__;const o=await ol(t);if(!o)return null;const s=o.rootInstance===r;return`${o.id}:${s?"root":n}`}catch{}}function Ed(e){var t;return((t=e.subTree)==null?void 0:t.type)===B_}function rs(e){var t,n,r;const o=H_((e==null?void 0:e.type)||{});if(o)return o;if((e==null?void 0:e.root)===e)return"Root";for(const a in(n=(t=e.parent)==null?void 0:t.type)==null?void 0:n.components)if(e.parent.type.components[a]===(e==null?void 0:e.type))return Ui(e,a);for(const a in(r=e.appContext)==null?void 0:r.components)if(e.appContext.components[a]===(e==null?void 0:e.type))return Ui(e,a);const s=j_((e==null?void 0:e.type)||{});return s||"Anonymous Component"}function la(e,t){return t=t||`${e.id}:root`,e.instanceMap.get(t)||e.instanceMap.get(":root")}var z_=class{constructor(){this.refEditor=new K_}set(e,t,n,r){const o=Array.isArray(t)?t:t.split(".");for(;o.length>1;){const l=o.shift();e instanceof Map&&(e=e.get(l)),e instanceof Set?e=Array.from(e.values())[l]:e=e[l],this.refEditor.isRef(e)&&(e=this.refEditor.get(e))}const s=o[0],a=this.refEditor.get(e)[s];r?r(e,s,n):this.refEditor.isRef(a)?this.refEditor.set(a,n):e[s]=n}get(e,t){const n=Array.isArray(t)?t:t.split(".");for(let r=0;r"u")return!1;const r=Array.isArray(t)?t.slice():t.split("."),o=n?2:1;for(;e&&r.length>o;){const s=r.shift();e=e[s],this.refEditor.isRef(e)&&(e=this.refEditor.get(e))}return e!=null&&Object.prototype.hasOwnProperty.call(e,r[0])}createDefaultSetCallback(e){return(t,n,r)=>{if((e.remove||e.newKey)&&(Array.isArray(t)?t.splice(n,1):wr(t)instanceof Map?t.delete(n):wr(t)instanceof Set?t.delete(Array.from(t.values())[n]):Reflect.deleteProperty(t,n)),!e.remove){const o=t[e.newKey||n];this.refEditor.isRef(o)?this.refEditor.set(o,r):wr(t)instanceof Map?t.set(e.newKey||n,r):wr(t)instanceof Set?t.add(r):t[e.newKey||n]=r}}}},K_=class{set(e,t){if(Ps(e))e.value=t;else{if(e instanceof Set&&Array.isArray(t)){e.clear(),t.forEach(o=>e.add(o));return}const n=Object.keys(t);if(e instanceof Map){const o=new Set(e.keys());n.forEach(s=>{e.set(s,Reflect.get(t,s)),o.delete(s)}),o.forEach(s=>e.delete(s));return}const r=new Set(Object.keys(e));n.forEach(o=>{Reflect.set(e,o,Reflect.get(t,o)),r.delete(o)}),r.forEach(o=>Reflect.deleteProperty(e,o))}}get(e){return Ps(e)?e.value:e}isRef(e){return Ps(e)||yd(e)}};x();function sl(e){return Ed(e)?q_(e.subTree):e.subTree?[e.subTree.el]:[]}function q_(e){if(!e.children)return[];const t=[];return e.children.forEach(n=>{n.component?t.push(...sl(n.component)):n!=null&&n.el&&t.push(n.el)}),t}x();x();function W_(){const e={top:0,bottom:0,left:0,right:0,get width(){return e.right-e.left},get height(){return e.bottom-e.top}};return e}var bo;function G_(e){return bo||(bo=document.createRange()),bo.selectNode(e),bo.getBoundingClientRect()}function Y_(e){const t=W_();if(!e.children)return t;for(let n=0,r=e.children.length;ne.bottom)&&(e.bottom=t.bottom),(!e.left||t.lefte.right)&&(e.right=t.right),e}var zi={top:0,left:0,right:0,bottom:0,width:0,height:0};function Ln(e){const t=e.subTree.el;return typeof window>"u"?zi:Ed(e)?Y_(e.subTree):(t==null?void 0:t.nodeType)===1?t==null?void 0:t.getBoundingClientRect():e.subTree.component?Ln(e.subTree.component):zi}var bd="__vue-devtools-component-inspector__",wd="__vue-devtools-component-inspector__card__",Td="__vue-devtools-component-inspector__name__",Ad="__vue-devtools-component-inspector__indicator__",Sd={display:"block",zIndex:2147483640,position:"fixed",backgroundColor:"#42b88325",border:"1px solid #42b88350",borderRadius:"5px",transition:"all 0.1s ease-in",pointerEvents:"none"},X_={fontFamily:"Arial, Helvetica, sans-serif",padding:"5px 8px",borderRadius:"4px",textAlign:"left",position:"absolute",left:0,color:"#e9e9e9",fontSize:"14px",fontWeight:600,lineHeight:"24px",backgroundColor:"#42b883",boxShadow:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)"},J_={display:"inline-block",fontWeight:400,fontStyle:"normal",fontSize:"12px",opacity:.7};function fr(){return document.getElementById(bd)}function Z_(){return document.getElementById(wd)}function e2(){return document.getElementById(Ad)}function t2(){return document.getElementById(Td)}function al(e){return{left:`${Math.round(e.left*100)/100}px`,top:`${Math.round(e.top*100)/100}px`,width:`${Math.round(e.width*100)/100}px`,height:`${Math.round(e.height*100)/100}px`}}function ll(e){var t;const n=document.createElement("div");n.id=(t=e.elementId)!=null?t:bd,Object.assign(n.style,{...Sd,...al(e.bounds),...e.style});const r=document.createElement("span");r.id=wd,Object.assign(r.style,{...X_,top:e.bounds.top<35?0:"-35px"});const o=document.createElement("span");o.id=Td,o.innerHTML=`<${e.name}>  `;const s=document.createElement("i");return s.id=Ad,s.innerHTML=`${Math.round(e.bounds.width*100)/100} x ${Math.round(e.bounds.height*100)/100}`,Object.assign(s.style,J_),r.appendChild(o),r.appendChild(s),n.appendChild(r),document.body.appendChild(n),n}function il(e){const t=fr(),n=Z_(),r=t2(),o=e2();t&&(Object.assign(t.style,{...Sd,...al(e.bounds)}),Object.assign(n.style,{top:e.bounds.top<35?0:"-35px"}),r.innerHTML=`<${e.name}>  `,o.innerHTML=`${Math.round(e.bounds.width*100)/100} x ${Math.round(e.bounds.height*100)/100}`)}function n2(e){const t=Ln(e),n=rs(e);fr()?il({bounds:t,name:n}):ll({bounds:t,name:n})}function Cd(){const e=fr();e&&(e.style.display="none")}var ia=null;function ua(e){const t=e.target;if(t){const n=t.__vueParentComponent;if(n&&(ia=n,n.vnode.el)){const o=Ln(n),s=rs(n);fr()?il({bounds:o,name:s}):ll({bounds:o,name:s})}}}function r2(e,t){var n;if(e.preventDefault(),e.stopPropagation(),ia){const r=(n=et.value)==null?void 0:n.app;U_({app:r,uid:r.uid,instance:ia}).then(o=>{t(o)})}}var $o=null;function o2(){Cd(),window.removeEventListener("mouseover",ua),window.removeEventListener("click",$o,!0),$o=null}function s2(){return window.addEventListener("mouseover",ua),new Promise(e=>{function t(n){n.preventDefault(),n.stopPropagation(),r2(n,r=>{window.removeEventListener("click",t,!0),$o=null,window.removeEventListener("mouseover",ua);const o=fr();o&&(o.style.display="none"),e(JSON.stringify({id:r}))})}$o=t,window.addEventListener("click",t,!0)})}function a2(e){const t=la(et.value,e.id);if(t){const[n]=sl(t);if(typeof n.scrollIntoView=="function")n.scrollIntoView({behavior:"smooth"});else{const r=Ln(t),o=document.createElement("div"),s={...al(r),position:"absolute"};Object.assign(o.style,s),document.body.appendChild(o),o.scrollIntoView({behavior:"smooth"}),setTimeout(()=>{document.body.removeChild(o)},2e3)}setTimeout(()=>{const r=Ln(t);if(r.width||r.height){const o=rs(t),s=fr();s?il({...e,name:o,bounds:r}):ll({...e,name:o,bounds:r}),setTimeout(()=>{s&&(s.style.display="none")},1500)}},1200)}}x();var Ki,qi;(qi=(Ki=G).__VUE_DEVTOOLS_COMPONENT_INSPECTOR_ENABLED__)!=null||(Ki.__VUE_DEVTOOLS_COMPONENT_INSPECTOR_ENABLED__=!0);function l2(e){let t=0;const n=setInterval(()=>{G.__VUE_INSPECTOR__&&(clearInterval(n),t+=30,e()),t>=5e3&&clearInterval(n)},30)}function i2(){const e=G.__VUE_INSPECTOR__,t=e.openInEditor;e.openInEditor=async(...n)=>{e.disable(),t(...n)}}function u2(){return new Promise(e=>{function t(){i2(),e(G.__VUE_INSPECTOR__)}G.__VUE_INSPECTOR__?t():l2(()=>{t()})})}x();x();x();var c2="__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS_STATE__";function f2(){if(!hd||typeof localStorage>"u"||localStorage===null)return{recordingState:!1,mouseEventEnabled:!1,keyboardEventEnabled:!1,componentEventEnabled:!1,performanceEventEnabled:!1,selected:""};const e=localStorage.getItem(c2);return e?JSON.parse(e):{recordingState:!1,mouseEventEnabled:!1,keyboardEventEnabled:!1,componentEventEnabled:!1,performanceEventEnabled:!1,selected:""}}x();x();x();var Wi,Gi;(Gi=(Wi=G).__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS)!=null||(Wi.__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS=[]);var d2=new Proxy(G.__VUE_DEVTOOLS_KIT_TIMELINE_LAYERS,{get(e,t,n){return Reflect.get(e,t,n)}});function p2(e,t){d2.push({...e,descriptorId:t.id,appRecord:ol(t.app)})}var Yi,Qi;(Qi=(Yi=G).__VUE_DEVTOOLS_KIT_INSPECTOR__)!=null||(Yi.__VUE_DEVTOOLS_KIT_INSPECTOR__=[]);var ul=new Proxy(G.__VUE_DEVTOOLS_KIT_INSPECTOR__,{get(e,t,n){return Reflect.get(e,t,n)}}),kd=ns(()=>{dr.hooks.callHook("sendInspectorToClient",Od())});function h2(e,t){ul.push({options:e,descriptor:t,treeFilter:"",selectedNodeId:"",appRecord:ol(t.app)}),kd()}function Od(){return ul.filter(e=>e.descriptor.app===et.value.app).filter(e=>e.descriptor.id!=="components").map(e=>{var t;const n=e.descriptor,r=e.options;return{id:r.id,label:r.label,logo:n.logo,icon:`custom-ic-baseline-${(t=r==null?void 0:r.icon)==null?void 0:t.replace(/_/g,"-")}`,packageName:n.packageName,homepage:n.homepage,pluginId:n.id}})}function So(e,t){return ul.find(n=>n.options.id===e&&(t?n.descriptor.app===t:!0))}function m2(){const e=vd();return e.hook("addInspector",({inspector:t,plugin:n})=>{h2(t,n.descriptor)}),e.hook("sendInspectorTree",async({inspectorId:t,plugin:n})=>{var r;if(!t||!((r=n==null?void 0:n.descriptor)!=null&&r.app))return;const o=So(t,n.descriptor.app),s={app:n.descriptor.app,inspectorId:t,filter:(o==null?void 0:o.treeFilter)||"",rootNodes:[]};await new Promise(a=>{e.callHookWith(async l=>{await Promise.all(l.map(i=>i(s))),a()},"getInspectorTree")}),e.callHookWith(async a=>{await Promise.all(a.map(l=>l({inspectorId:t,rootNodes:s.rootNodes})))},"sendInspectorTreeToClient")}),e.hook("sendInspectorState",async({inspectorId:t,plugin:n})=>{var r;if(!t||!((r=n==null?void 0:n.descriptor)!=null&&r.app))return;const o=So(t,n.descriptor.app),s={app:n.descriptor.app,inspectorId:t,nodeId:(o==null?void 0:o.selectedNodeId)||"",state:null},a={currentTab:`custom-inspector:${t}`};s.nodeId&&await new Promise(l=>{e.callHookWith(async i=>{await Promise.all(i.map(f=>f(s,a))),l()},"getInspectorState")}),e.callHookWith(async l=>{await Promise.all(l.map(i=>i({inspectorId:t,nodeId:s.nodeId,state:s.state})))},"sendInspectorStateToClient")}),e.hook("customInspectorSelectNode",({inspectorId:t,nodeId:n,plugin:r})=>{const o=So(t,r.descriptor.app);o&&(o.selectedNodeId=n)}),e.hook("timelineLayerAdded",({options:t,plugin:n})=>{p2(t,n.descriptor)}),e.hook("timelineEventAdded",({options:t,plugin:n})=>{e.callHookWith(async r=>{await Promise.all(r.map(o=>o(t)))},"sendTimelineEventToClient")}),e.hook("getComponentInstances",async({app:t})=>{const n=t.__VUE_DEVTOOLS_NEXT_APP_RECORD__;if(!n)return null;const r=n.id.toString();return[...n.instanceMap].filter(([s])=>s.split(":")[0]===r).map(([,s])=>s)}),e.hook("getComponentBounds",async({instance:t})=>Ln(t)),e.hook("getComponentName",({instance:t})=>rs(t)),e.hook("componentHighlight",({uid:t})=>{const n=et.value.instanceMap.get(t);n&&n2(n)}),e.hook("componentUnhighlight",()=>{Cd()}),e}var Xi,Ji;(Ji=(Xi=G).__VUE_DEVTOOLS_KIT_APP_RECORDS__)!=null||(Xi.__VUE_DEVTOOLS_KIT_APP_RECORDS__=[]);var Zi,eu;(eu=(Zi=G).__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__)!=null||(Zi.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__={});var tu,nu;(nu=(tu=G).__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__)!=null||(tu.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__="");var ru,ou;(ou=(ru=G).__VUE_DEVTOOLS_KIT_CUSTOM_TABS__)!=null||(ru.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__=[]);var su,au;(au=(su=G).__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__)!=null||(su.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__=[]);var kn="__VUE_DEVTOOLS_KIT_GLOBAL_STATE__";function v2(){return{connected:!1,clientConnected:!1,vitePluginDetected:!0,appRecords:[],activeAppRecordId:"",tabs:[],commands:[],highPerfModeEnabled:!0,devtoolsClientDetected:{},perfUniqueGroupId:0,timelineLayersState:f2()}}var lu,iu;(iu=(lu=G)[kn])!=null||(lu[kn]=v2());var g2=ns(e=>{dr.hooks.callHook("devtoolsStateUpdated",{state:e})});ns((e,t)=>{dr.hooks.callHook("devtoolsConnectedUpdated",{state:e,oldState:t})});var os=new Proxy(G.__VUE_DEVTOOLS_KIT_APP_RECORDS__,{get(e,t,n){return t==="value"?G.__VUE_DEVTOOLS_KIT_APP_RECORDS__:G.__VUE_DEVTOOLS_KIT_APP_RECORDS__[t]}}),et=new Proxy(G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__,{get(e,t,n){return t==="value"?G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__:t==="id"?G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__:G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__[t]}});function xd(){g2({...G[kn],appRecords:os.value,activeAppRecordId:et.id,tabs:G.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__,commands:G.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__})}function _2(e){G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD__=e,xd()}function y2(e){G.__VUE_DEVTOOLS_KIT_ACTIVE_APP_RECORD_ID__=e,xd()}var In=new Proxy(G[kn],{get(e,t){return t==="appRecords"?os:t==="activeAppRecordId"?et.id:t==="tabs"?G.__VUE_DEVTOOLS_KIT_CUSTOM_TABS__:t==="commands"?G.__VUE_DEVTOOLS_KIT_CUSTOM_COMMANDS__:G[kn][t]},deleteProperty(e,t){return delete e[t],!0},set(e,t,n){return{...G[kn]},e[t]=n,G[kn][t]=n,!0}});function E2(e={}){var t,n,r;const{file:o,host:s,baseUrl:a=window.location.origin,line:l=0,column:i=0}=e;if(o){if(s==="chrome-extension"){const f=o.replace(/\\/g,"\\\\"),c=(n=(t=window.VUE_DEVTOOLS_CONFIG)==null?void 0:t.openInEditorHost)!=null?n:"/";fetch(`${c}__open-in-editor?file=${encodeURI(o)}`).then(u=>{if(!u.ok){const p=`Opening component ${f} failed`;console.log(`%c${p}`,"color:red")}})}else if(In.vitePluginDetected){const f=(r=G.__VUE_DEVTOOLS_OPEN_IN_EDITOR_BASE_URL__)!=null?r:a;G.__VUE_INSPECTOR__.openInEditor(f,o,l,i)}}}x();x();x();x();x();var uu,cu;(cu=(uu=G).__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__)!=null||(uu.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__=[]);var cl=new Proxy(G.__VUE_DEVTOOLS_KIT_PLUGIN_BUFFER__,{get(e,t,n){return Reflect.get(e,t,n)}});function ca(e){const t={};return Object.keys(e).forEach(n=>{t[n]=e[n].defaultValue}),t}function fl(e){return`__VUE_DEVTOOLS_NEXT_PLUGIN_SETTINGS__${e}__`}function b2(e){var t,n,r;const o=(n=(t=cl.find(s=>{var a;return s[0].id===e&&!!((a=s[0])!=null&&a.settings)}))==null?void 0:t[0])!=null?n:null;return(r=o==null?void 0:o.settings)!=null?r:null}function Rd(e,t){var n,r,o;const s=fl(e);if(s){const a=localStorage.getItem(s);if(a)return JSON.parse(a)}if(e){const a=(r=(n=cl.find(l=>l[0].id===e))==null?void 0:n[0])!=null?r:null;return ca((o=a==null?void 0:a.settings)!=null?o:{})}return ca(t)}function w2(e,t){const n=fl(e);localStorage.getItem(n)||localStorage.setItem(n,JSON.stringify(ca(t)))}function T2(e,t,n){const r=fl(e),o=localStorage.getItem(r),s=JSON.parse(o||"{}"),a={...s,[t]:n};localStorage.setItem(r,JSON.stringify(a)),dr.hooks.callHookWith(l=>{l.forEach(i=>i({pluginId:e,key:t,oldValue:s[t],newValue:n,settings:a}))},"setPluginSettings")}x();x();x();x();x();x();x();x();x();x();x();var fu,du,it=(du=(fu=G).__VUE_DEVTOOLS_HOOK)!=null?du:fu.__VUE_DEVTOOLS_HOOK=vd(),A2={vueAppInit(e){it.hook("app:init",e)},vueAppUnmount(e){it.hook("app:unmount",e)},vueAppConnected(e){it.hook("app:connected",e)},componentAdded(e){return it.hook("component:added",e)},componentEmit(e){return it.hook("component:emit",e)},componentUpdated(e){return it.hook("component:updated",e)},componentRemoved(e){return it.hook("component:removed",e)},setupDevtoolsPlugin(e){it.hook("devtools-plugin:setup",e)},perfStart(e){return it.hook("perf:start",e)},perfEnd(e){return it.hook("perf:end",e)}},Id={on:A2,setupDevToolsPlugin(e,t){return it.callHook("devtools-plugin:setup",e,t)}},S2=class{constructor({plugin:e,ctx:t}){this.hooks=t.hooks,this.plugin=e}get on(){return{visitComponentTree:e=>{this.hooks.hook("visitComponentTree",e)},inspectComponent:e=>{this.hooks.hook("inspectComponent",e)},editComponentState:e=>{this.hooks.hook("editComponentState",e)},getInspectorTree:e=>{this.hooks.hook("getInspectorTree",e)},getInspectorState:e=>{this.hooks.hook("getInspectorState",e)},editInspectorState:e=>{this.hooks.hook("editInspectorState",e)},inspectTimelineEvent:e=>{this.hooks.hook("inspectTimelineEvent",e)},timelineCleared:e=>{this.hooks.hook("timelineCleared",e)},setPluginSettings:e=>{this.hooks.hook("setPluginSettings",e)}}}notifyComponentUpdate(e){var t;const n=Od().find(r=>r.packageName===this.plugin.descriptor.packageName);if(n!=null&&n.id){if(e){const r=[e.appContext.app,e.uid,(t=e.parent)==null?void 0:t.uid,e];it.callHook("component:updated",...r)}else it.callHook("component:updated");this.hooks.callHook("sendInspectorState",{inspectorId:n.id,plugin:this.plugin})}}addInspector(e){this.hooks.callHook("addInspector",{inspector:e,plugin:this.plugin}),this.plugin.descriptor.settings&&w2(e.id,this.plugin.descriptor.settings)}sendInspectorTree(e){this.hooks.callHook("sendInspectorTree",{inspectorId:e,plugin:this.plugin})}sendInspectorState(e){this.hooks.callHook("sendInspectorState",{inspectorId:e,plugin:this.plugin})}selectInspectorNode(e,t){this.hooks.callHook("customInspectorSelectNode",{inspectorId:e,nodeId:t,plugin:this.plugin})}now(){return Date.now()}addTimelineLayer(e){this.hooks.callHook("timelineLayerAdded",{options:e,plugin:this.plugin})}addTimelineEvent(e){this.hooks.callHook("timelineEventAdded",{options:e,plugin:this.plugin})}getSettings(e){return Rd(e??this.plugin.descriptor.id,this.plugin.descriptor.settings)}getComponentInstances(e){return this.hooks.callHook("getComponentInstances",{app:e})}getComponentBounds(e){return this.hooks.callHook("getComponentBounds",{instance:e})}getComponentName(e){return this.hooks.callHook("getComponentName",{instance:e})}highlightElement(e){const t=e.__VUE_DEVTOOLS_NEXT_UID__;return this.hooks.callHook("componentHighlight",{uid:t})}unhighlightElement(){return this.hooks.callHook("componentUnhighlight")}},C2=S2;x();x();x();x();var k2="__vue_devtool_undefined__",O2="__vue_devtool_infinity__",x2="__vue_devtool_negative_infinity__",R2="__vue_devtool_nan__";x();x();var I2={[k2]:"undefined",[R2]:"NaN",[O2]:"Infinity",[x2]:"-Infinity"};Object.entries(I2).reduce((e,[t,n])=>(e[n]=t,e),{});x();x();x();x();x();var pu,hu;(hu=(pu=G).__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__)!=null||(pu.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__=new Set);function D2(e,t){return Id.setupDevToolsPlugin(e,t)}function P2(e,t){const[n,r]=e;if(n.app!==t)return;const o=new C2({plugin:{setupFn:r,descriptor:n},ctx:dr});n.packageName==="vuex"&&o.on.editInspectorState(s=>{o.sendInspectorState(s.inspectorId)}),r(o)}function L2(e){G.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.has(e)||(G.__VUE_DEVTOOLS_KIT__REGISTERED_PLUGIN_APPS__.add(e),cl.forEach(t=>{P2(t,e)}))}x();x();var Ur="__VUE_DEVTOOLS_ROUTER__",sr="__VUE_DEVTOOLS_ROUTER_INFO__",mu,vu;(vu=(mu=G)[sr])!=null||(mu[sr]={currentRoute:null,routes:[]});var gu,_u;(_u=(gu=G)[Ur])!=null||(gu[Ur]={});new Proxy(G[sr],{get(e,t){return G[sr][t]}});new Proxy(G[Ur],{get(e,t){if(t==="value")return G[Ur]}});function V2(e){const t=new Map;return((e==null?void 0:e.getRoutes())||[]).filter(n=>!t.has(n.path)&&t.set(n.path,1))}function dl(e){return e.map(t=>{let{path:n,name:r,children:o,meta:s}=t;return o!=null&&o.length&&(o=dl(o)),{path:n,name:r,children:o,meta:s}})}function N2(e){if(e){const{fullPath:t,hash:n,href:r,path:o,name:s,matched:a,params:l,query:i}=e;return{fullPath:t,hash:n,href:r,path:o,name:s,params:l,query:i,matched:dl(a)}}return e}function M2(e,t){function n(){var r;const o=(r=e.app)==null?void 0:r.config.globalProperties.$router,s=N2(o==null?void 0:o.currentRoute.value),a=dl(V2(o)),l=console.warn;console.warn=()=>{},G[sr]={currentRoute:s?ji(s):{},routes:ji(a)},G[Ur]=o,console.warn=l}n(),Id.on.componentUpdated(ns(()=>{var r;((r=t.value)==null?void 0:r.app)===e.app&&(n(),dr.hooks.callHook("routerInfoUpdated",{state:G[sr]}))},200))}function $2(e){return{async getInspectorTree(t){const n={...t,app:et.value.app,rootNodes:[]};return await new Promise(r=>{e.callHookWith(async o=>{await Promise.all(o.map(s=>s(n))),r()},"getInspectorTree")}),n.rootNodes},async getInspectorState(t){const n={...t,app:et.value.app,state:null},r={currentTab:`custom-inspector:${t.inspectorId}`};return await new Promise(o=>{e.callHookWith(async s=>{await Promise.all(s.map(a=>a(n,r))),o()},"getInspectorState")}),n.state},editInspectorState(t){const n=new z_,r={...t,app:et.value.app,set:(o,s=t.path,a=t.state.value,l)=>{n.set(o,s,a,l||n.createDefaultSetCallback(t.state))}};e.callHookWith(o=>{o.forEach(s=>s(r))},"editInspectorState")},sendInspectorState(t){const n=So(t);e.callHook("sendInspectorState",{inspectorId:t,plugin:{descriptor:n.descriptor,setupFn:()=>({})}})},inspectComponentInspector(){return s2()},cancelInspectComponentInspector(){return o2()},getComponentRenderCode(t){const n=la(et.value,t);if(n)return(n==null?void 0:n.type)instanceof Function?n.type.toString():n.render.toString()},scrollToComponent(t){return a2({id:t})},openInEditor:E2,getVueInspector:u2,toggleApp(t){const n=os.value.find(r=>r.id===t);n&&(y2(t),_2(n),M2(n,et),kd(),L2(n.app))},inspectDOM(t){const n=la(et.value,t);if(n){const[r]=sl(n);r&&(G.__VUE_DEVTOOLS_INSPECT_DOM_TARGET__=r)}},updatePluginSettings(t,n,r){T2(t,n,r)},getPluginSettings(t){return{options:b2(t),values:Rd(t)}}}}x();var yu,Eu;(Eu=(yu=G).__VUE_DEVTOOLS_ENV__)!=null||(yu.__VUE_DEVTOOLS_ENV__={vitePluginDetected:!1});var bu=m2(),wu,Tu;(Tu=(wu=G).__VUE_DEVTOOLS_KIT_CONTEXT__)!=null||(wu.__VUE_DEVTOOLS_KIT_CONTEXT__={hooks:bu,get state(){return{...In,activeAppRecordId:et.id,activeAppRecord:et.value,appRecords:os.value}},api:$2(bu)});var dr=G.__VUE_DEVTOOLS_KIT_CONTEXT__;x();N_($_());var Au,Su;(Su=(Au=G).__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__)!=null||(Au.__VUE_DEVTOOLS_NEXT_APP_RECORD_INFO__={id:0,appIds:new Set});x();function F2(e){In.highPerfModeEnabled=e??!In.highPerfModeEnabled}x();x();x();function B2(e){In.devtoolsClientDetected={...In.devtoolsClientDetected,...e};const t=Object.values(In.devtoolsClientDetected).some(Boolean);F2(!t)}var Cu,ku;(ku=(Cu=G).__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__)!=null||(Cu.__VUE_DEVTOOLS_UPDATE_CLIENT_DETECTED__=B2);x();x();x();x();x();x();x();var H2=class{constructor(){this.keyToValue=new Map,this.valueToKey=new Map}set(e,t){this.keyToValue.set(e,t),this.valueToKey.set(t,e)}getByKey(e){return this.keyToValue.get(e)}getByValue(e){return this.valueToKey.get(e)}clear(){this.keyToValue.clear(),this.valueToKey.clear()}},Dd=class{constructor(e){this.generateIdentifier=e,this.kv=new H2}register(e,t){this.kv.getByValue(e)||(t||(t=this.generateIdentifier(e)),this.kv.set(t,e))}clear(){this.kv.clear()}getIdentifier(e){return this.kv.getByValue(e)}getValue(e){return this.kv.getByKey(e)}},j2=class extends Dd{constructor(){super(e=>e.name),this.classToAllowedProps=new Map}register(e,t){typeof t=="object"?(t.allowProps&&this.classToAllowedProps.set(e,t.allowProps),super.register(e,t.identifier)):super.register(e,t)}getAllowedProps(e){return this.classToAllowedProps.get(e)}};x();x();function U2(e){if("values"in Object)return Object.values(e);const t=[];for(const n in e)e.hasOwnProperty(n)&&t.push(e[n]);return t}function z2(e,t){const n=U2(e);if("find"in n)return n.find(t);const r=n;for(let o=0;ot(r,n))}function Co(e,t){return e.indexOf(t)!==-1}function Ou(e,t){for(let n=0;nt.isApplicable(e))}findByName(e){return this.transfomers[e]}};x();x();var q2=e=>Object.prototype.toString.call(e).slice(8,-1),Pd=e=>typeof e>"u",W2=e=>e===null,zr=e=>typeof e!="object"||e===null||e===Object.prototype?!1:Object.getPrototypeOf(e)===null?!0:Object.getPrototypeOf(e)===Object.prototype,fa=e=>zr(e)&&Object.keys(e).length===0,vn=e=>Array.isArray(e),G2=e=>typeof e=="string",Y2=e=>typeof e=="number"&&!isNaN(e),Q2=e=>typeof e=="boolean",X2=e=>e instanceof RegExp,Kr=e=>e instanceof Map,qr=e=>e instanceof Set,Ld=e=>q2(e)==="Symbol",J2=e=>e instanceof Date&&!isNaN(e.valueOf()),Z2=e=>e instanceof Error,xu=e=>typeof e=="number"&&isNaN(e),e4=e=>Q2(e)||W2(e)||Pd(e)||Y2(e)||G2(e)||Ld(e),t4=e=>typeof e=="bigint",n4=e=>e===1/0||e===-1/0,r4=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),o4=e=>e instanceof URL;x();var Vd=e=>e.replace(/\./g,"\\."),Ls=e=>e.map(String).map(Vd).join("."),Lr=e=>{const t=[];let n="";for(let o=0;onull,()=>{}),It(t4,"bigint",e=>e.toString(),e=>typeof BigInt<"u"?BigInt(e):(console.error("Please add a BigInt polyfill."),e)),It(J2,"Date",e=>e.toISOString(),e=>new Date(e)),It(Z2,"Error",(e,t)=>{const n={name:e.name,message:e.message};return t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n},(e,t)=>{const n=new Error(e.message);return n.name=e.name,n.stack=e.stack,t.allowedErrorProps.forEach(r=>{n[r]=e[r]}),n}),It(X2,"regexp",e=>""+e,e=>{const t=e.slice(1,e.lastIndexOf("/")),n=e.slice(e.lastIndexOf("/")+1);return new RegExp(t,n)}),It(qr,"set",e=>[...e.values()],e=>new Set(e)),It(Kr,"map",e=>[...e.entries()],e=>new Map(e)),It(e=>xu(e)||n4(e),"number",e=>xu(e)?"NaN":e>0?"Infinity":"-Infinity",Number),It(e=>e===0&&1/e===-1/0,"number",()=>"-0",Number),It(o4,"URL",e=>e.toString(),e=>new URL(e))];function ss(e,t,n,r){return{isApplicable:e,annotation:t,transform:n,untransform:r}}var Md=ss((e,t)=>Ld(e)?!!t.symbolRegistry.getIdentifier(e):!1,(e,t)=>["symbol",t.symbolRegistry.getIdentifier(e)],e=>e.description,(e,t,n)=>{const r=n.symbolRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown symbol");return r}),s4=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array,Uint8ClampedArray].reduce((e,t)=>(e[t.name]=t,e),{}),$d=ss(r4,e=>["typed-array",e.constructor.name],e=>[...e],(e,t)=>{const n=s4[t[1]];if(!n)throw new Error("Trying to deserialize unknown typed array");return new n(e)});function Fd(e,t){return e!=null&&e.constructor?!!t.classRegistry.getIdentifier(e.constructor):!1}var Bd=ss(Fd,(e,t)=>["class",t.classRegistry.getIdentifier(e.constructor)],(e,t)=>{const n=t.classRegistry.getAllowedProps(e.constructor);if(!n)return{...e};const r={};return n.forEach(o=>{r[o]=e[o]}),r},(e,t,n)=>{const r=n.classRegistry.getValue(t[1]);if(!r)throw new Error("Trying to deserialize unknown class - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564");return Object.assign(Object.create(r.prototype),e)}),Hd=ss((e,t)=>!!t.customTransformerRegistry.findApplicable(e),(e,t)=>["custom",t.customTransformerRegistry.findApplicable(e).name],(e,t)=>t.customTransformerRegistry.findApplicable(e).serialize(e),(e,t,n)=>{const r=n.customTransformerRegistry.findByName(t[1]);if(!r)throw new Error("Trying to deserialize unknown custom value");return r.deserialize(e)}),a4=[Bd,Md,Hd,$d],Ru=(e,t)=>{const n=Ou(a4,o=>o.isApplicable(e,t));if(n)return{value:n.transform(e,t),type:n.annotation(e,t)};const r=Ou(Nd,o=>o.isApplicable(e,t));if(r)return{value:r.transform(e,t),type:r.annotation}},jd={};Nd.forEach(e=>{jd[e.annotation]=e});var l4=(e,t,n)=>{if(vn(t))switch(t[0]){case"symbol":return Md.untransform(e,t,n);case"class":return Bd.untransform(e,t,n);case"custom":return Hd.untransform(e,t,n);case"typed-array":return $d.untransform(e,t,n);default:throw new Error("Unknown transformation: "+t)}else{const r=jd[t];if(!r)throw new Error("Unknown transformation: "+t);return r.untransform(e,n)}};x();var Un=(e,t)=>{const n=e.keys();for(;t>0;)n.next(),t--;return n.next().value};function Ud(e){if(Co(e,"__proto__"))throw new Error("__proto__ is not allowed as a property");if(Co(e,"prototype"))throw new Error("prototype is not allowed as a property");if(Co(e,"constructor"))throw new Error("constructor is not allowed as a property")}var i4=(e,t)=>{Ud(t);for(let n=0;n{if(Ud(t),t.length===0)return n(e);let r=e;for(let s=0;spa(s,t,[...n,...Lr(a)]));return}const[r,o]=e;o&&ar(o,(s,a)=>{pa(s,t,[...n,...Lr(a)])}),t(r,n)}function u4(e,t,n){return pa(t,(r,o)=>{e=da(e,o,s=>l4(s,r,n))}),e}function c4(e,t){function n(r,o){const s=i4(e,Lr(o));r.map(Lr).forEach(a=>{e=da(e,a,()=>s)})}if(vn(t)){const[r,o]=t;r.forEach(s=>{e=da(e,Lr(s),()=>e)}),o&&ar(o,n)}else ar(t,n);return e}var f4=(e,t)=>zr(e)||vn(e)||Kr(e)||qr(e)||Fd(e,t);function d4(e,t,n){const r=n.get(e);r?r.push(t):n.set(e,[t])}function p4(e,t){const n={};let r;return e.forEach(o=>{if(o.length<=1)return;t||(o=o.map(l=>l.map(String)).sort((l,i)=>l.length-i.length));const[s,...a]=o;s.length===0?r=a.map(Ls):n[Ls(s)]=a.map(Ls)}),r?fa(n)?[r]:[r,n]:fa(n)?void 0:n}var zd=(e,t,n,r,o=[],s=[],a=new Map)=>{var l;const i=e4(e);if(!i){d4(e,o,t);const m=a.get(e);if(m)return r?{transformedValue:null}:m}if(!f4(e,n)){const m=Ru(e,n),y=m?{transformedValue:m.value,annotations:[m.type]}:{transformedValue:e};return i||a.set(e,y),y}if(Co(s,e))return{transformedValue:null};const f=Ru(e,n),c=(l=f==null?void 0:f.value)!=null?l:e,u=vn(c)?[]:{},p={};ar(c,(m,y)=>{if(y==="__proto__"||y==="constructor"||y==="prototype")throw new Error(`Detected property ${y}. This is a prototype pollution risk, please remove it from your object.`);const _=zd(m,t,n,r,[...o,y],[...s,e],a);u[y]=_.transformedValue,vn(_.annotations)?p[y]=_.annotations:zr(_.annotations)&&ar(_.annotations,(E,w)=>{p[Vd(y)+"."+w]=E})});const h=fa(p)?{transformedValue:u,annotations:f?[f.type]:void 0}:{transformedValue:u,annotations:f?[f.type,p]:p};return i||a.set(e,h),h};x();x();function Kd(e){return Object.prototype.toString.call(e).slice(8,-1)}function Iu(e){return Kd(e)==="Array"}function h4(e){if(Kd(e)!=="Object")return!1;const t=Object.getPrototypeOf(e);return!!t&&t.constructor===Object&&t===Object.prototype}function m4(e,t,n,r,o){const s={}.propertyIsEnumerable.call(r,t)?"enumerable":"nonenumerable";s==="enumerable"&&(e[t]=n),o&&s==="nonenumerable"&&Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0,configurable:!0})}function ha(e,t={}){if(Iu(e))return e.map(o=>ha(o,t));if(!h4(e))return e;const n=Object.getOwnPropertyNames(e),r=Object.getOwnPropertySymbols(e);return[...n,...r].reduce((o,s)=>{if(Iu(t.props)&&!t.props.includes(s))return o;const a=e[s],l=ha(a,t);return m4(o,s,l,e,t.nonenumerable),o},{})}var be=class{constructor({dedupe:e=!1}={}){this.classRegistry=new j2,this.symbolRegistry=new Dd(t=>{var n;return(n=t.description)!=null?n:""}),this.customTransformerRegistry=new K2,this.allowedErrorProps=[],this.dedupe=e}serialize(e){const t=new Map,n=zd(e,t,this,this.dedupe),r={json:n.transformedValue};n.annotations&&(r.meta={...r.meta,values:n.annotations});const o=p4(t,this.dedupe);return o&&(r.meta={...r.meta,referentialEqualities:o}),r}deserialize(e){const{json:t,meta:n}=e;let r=ha(t);return n!=null&&n.values&&(r=u4(r,n.values,this)),n!=null&&n.referentialEqualities&&(r=c4(r,n.referentialEqualities)),r}stringify(e){return JSON.stringify(this.serialize(e))}parse(e){return this.deserialize(JSON.parse(e))}registerClass(e,t){this.classRegistry.register(e,t)}registerSymbol(e,t){this.symbolRegistry.register(e,t)}registerCustom(e,t){this.customTransformerRegistry.register({name:t,...e})}allowErrorProps(...e){this.allowedErrorProps.push(...e)}};be.defaultInstance=new be;be.serialize=be.defaultInstance.serialize.bind(be.defaultInstance);be.deserialize=be.defaultInstance.deserialize.bind(be.defaultInstance);be.stringify=be.defaultInstance.stringify.bind(be.defaultInstance);be.parse=be.defaultInstance.parse.bind(be.defaultInstance);be.registerClass=be.defaultInstance.registerClass.bind(be.defaultInstance);be.registerSymbol=be.defaultInstance.registerSymbol.bind(be.defaultInstance);be.registerCustom=be.defaultInstance.registerCustom.bind(be.defaultInstance);be.allowErrorProps=be.defaultInstance.allowErrorProps.bind(be.defaultInstance);x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();x();var Du,Pu;(Pu=(Du=G).__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__)!=null||(Du.__VUE_DEVTOOLS_KIT_MESSAGE_CHANNELS__=[]);var Lu,Vu;(Vu=(Lu=G).__VUE_DEVTOOLS_KIT_RPC_CLIENT__)!=null||(Lu.__VUE_DEVTOOLS_KIT_RPC_CLIENT__=null);var Nu,Mu;(Mu=(Nu=G).__VUE_DEVTOOLS_KIT_RPC_SERVER__)!=null||(Nu.__VUE_DEVTOOLS_KIT_RPC_SERVER__=null);var $u,Fu;(Fu=($u=G).__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__)!=null||($u.__VUE_DEVTOOLS_KIT_VITE_RPC_CLIENT__=null);var Bu,Hu;(Hu=(Bu=G).__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__)!=null||(Bu.__VUE_DEVTOOLS_KIT_VITE_RPC_SERVER__=null);var ju,Uu;(Uu=(ju=G).__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__)!=null||(ju.__VUE_DEVTOOLS_KIT_BROADCAST_RPC_SERVER__=null);x();x();x();x();x();x();x();const v4=JSON.parse(`{"encrypt":{},"logo":"/logo.svg","docsRepo":"https://github.com/Ocelot-Social-Community/Ocelot-Social","docsBranch":"master","docsDir":".","editLink":true,"lastUpdated":false,"contributors":false,"print":false,"pure":true,"navbarLayout":{"start":["Brand"],"center":["Links"],"end":["Repo","Outlook","Search"]},"repo":"Ocelot-Social-Community/Ocelot-Social","repoLabel":"GitHub","repoDisplay":true,"displayFooter":true,"copyright":"© by busFaktor() e.V. & Authors | Imprint","footer":"Released under the MIT License.","locales":{"/":{"lang":"en-US","navbarLocales":{"langName":"English","selectLangAriaLabel":"Select language"},"metaLocales":{"author":"Author","date":"Writing Date","origin":"Original","views":"Page views","category":"Category","tag":"Tag","readingTime":"Reading Time","words":"Words","toc":"On This Page","prev":"Prev","next":"Next","lastUpdated":"Last update","contributors":"Contributors","editLink":"Edit this page","print":"Print"},"outlookLocales":{"themeColor":"Theme Color","darkmode":"Theme Mode","fullscreen":"Full Screen"},"routeLocales":{"skipToContent":"Skip to main content","notFoundTitle":"Page not found","notFoundMsg":["There’s nothing here.","How did we get here?","That’s a Four-Oh-Four.","Looks like we've got some broken links."],"back":"Go back","home":"Take me home"},"sidebar":[{"text":"Introduction","link":"/README.md"},{"text":"Neo4J","link":"/neo4j/README.md"},{"text":"Backend","link":"/backend/README.md","children":[{"text":"GraphQL","link":"/backend/graphql.md"},{"text":"neo4j-graphql-js","link":"/backend/neo4j-graphql-js.md"}]},{"text":"Webapp (Frontend)","link":"/webapp/README.md","children":[{"text":"Components","link":"/webapp/components.md"},{"text":"HTML","link":"/webapp/html.md"},{"text":"SCSS","link":"/webapp/scss.md"},{"text":"Vue","link":"/webapp/vue.md"}]},{"text":"Testing Guide","link":"/testing.md","children":[{"text":"End-to-end Tests","link":"/cypress/README.md"},{"text":"Webapp (Frontend) Tests","link":"/webapp/testing.md"},{"text":"Backend Tests","link":"/backend/testing.md"}]},{"text":"Deployment","link":"/deployment/README.md"},{"text":"Contributing","link":"/CONTRIBUTING.md"},{"text":"Feature Specification","link":"/cypress/features.md"},{"text":"Code of Conduct","link":"/CODE_OF_CONDUCT.md"},{"text":"Documentation","link":"/documentation.md"},{"text":"License","link":"/LICENSE.md"}],"navbar":[{"text":"Demo","link":"https://stage.ocelot.social/","target":"_self"}]}}}`),g4=te(v4),qd=()=>g4,Wd=Symbol(""),_4=()=>{const e=Ne(Wd);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},y4=(e,t)=>{const{locales:n,...r}=e;return{...r,...n==null?void 0:n[t]}},E4=Ft({enhance({app:e}){const t=qd(),n=e._context.provides[Ga],r=S(()=>y4(t.value,n.routeLocale.value));e.provide(Wd,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}}),D2({app:e,id:"org.vuejs.vuepress.plugin-theme-data",label:"VuePress Theme Data Plugin",packageName:"@vuepress/plugin-theme-data",homepage:"https://v2.vuepress.vuejs.org",logo:"https://v2.vuepress.vuejs.org/images/hero.png",componentStateTypes:["VuePress"]},o=>{o.on.inspectComponent(s=>{s.instanceData.state.push({type:"VuePress",key:"themeData",editable:!1,value:t.value},{type:"VuePress",key:"themeLocaleData",editable:!1,value:r.value})})})}}),b4=Object.freeze(Object.defineProperty({__proto__:null,default:E4},Symbol.toStringTag,{value:"Module"})),w4=/language-(shellscript|shell|bash|sh|zsh)/,T4=({delay:e=500,duration:t=2e3,locales:n,selector:r,showInMobile:o,ignoreSelector:s=[],transform:a})=>{const l=Xa("(max-width: 419px)"),i=S(()=>!l.value||o),f=_n(n),c=Be(),u=_=>{var w;if(_.hasAttribute("copy-code"))return;const E=document.createElement("button");E.type="button",E.classList.add("vp-copy-code-button"),E.setAttribute("aria-label",f.value.copy),E.setAttribute("data-copied",f.value.copied),(w=_.parentElement)==null||w.insertBefore(E,_),_.setAttribute("copy-code","")};ce(()=>[c.value.path,i.value],async()=>{document.body.classList.toggle("no-copy-code",!i.value),i.value&&(await $t(),await Za(e),document.querySelectorAll(r.join(",")).forEach(u))},{immediate:!0});const{copy:h}=tg({legacy:!0}),m=new WeakMap,y=async(_,E,w)=>{const v=E.cloneNode(!0);s.length&&v.querySelectorAll(s.join(",")).forEach(H=>{H.remove()}),a&&a(v);let T=v.textContent||"";if(w4.test(_.className)&&(T=T.replace(/^ *(\$|>) /gm,"")),await h(T),t<=0)return;w.classList.add("copied"),clearTimeout(m.get(w));const V=setTimeout(()=>{w.classList.remove("copied"),w.blur(),m.delete(w)},t);m.set(w,V)};Ae("click",_=>{const E=_.target;if(i.value&&E.matches('div[class*="language-"] > button.vp-copy-code-button')){const w=E.parentElement,v=E.nextElementSibling;if(!w||!v)return;y(w,v,E)}})};var A4=[],S4={"/":{copy:"Copy code",copied:"Copied"}},C4=['[vp-content] div[class*="language-"] pre'];const k4=Ft({setup:()=>{T4({selector:C4,ignoreSelector:A4,locales:S4,duration:2e3,delay:500,showInMobile:!1})}}),O4=Object.freeze(Object.defineProperty({__proto__:null,default:k4},Symbol.toStringTag,{value:"Module"})),x4=Ft({setup(){Ae("beforeprint",()=>{document.querySelectorAll("details").forEach(e=>{e.open=!0})})}}),R4=Object.freeze(Object.defineProperty({__proto__:null,default:x4},Symbol.toStringTag,{value:"Module"})),I4=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),D4='',P4='';var L4={useBabel:!1,jsLib:[],cssLib:[],codepenLayout:"left",codepenEditors:"101",babel:"https://unpkg.com/@babel/standalone/babel.min.js",vue:"https://unpkg.com/vue/dist/vue.global.prod.js",react:"https://unpkg.com/react/umd/react.production.min.js",reactDOM:"https://unpkg.com/react-dom/umd/react-dom.production.min.js"};const Vs=L4,zu={html:{types:["html","slim","haml","md","markdown","vue"],map:{html:"none",vue:"none",md:"markdown"}},js:{types:["js","javascript","coffee","coffeescript","ts","typescript","ls","livescript"],map:{js:"none",javascript:"none",coffee:"coffeescript",ls:"livescript",ts:"typescript"}},css:{types:["css","less","sass","scss","stylus","styl"],map:{css:"none",styl:"stylus"}}},V4=(e,t,n)=>{const r=document.createElement(e);return oo(t)&&io(t).forEach(o=>{if(o.indexOf("data"))r[o]=t[o];else{const s=o.replace("data","");r.dataset[s]=t[o]}}),r},pl=e=>({...Vs,...e,jsLib:Array.from(new Set([Vs.jsLib??[],e.jsLib??[]].flat())),cssLib:Array.from(new Set([Vs.cssLib??[],e.cssLib??[]].flat()))}),Xn=(e,t)=>{if(el(e[t]))return e[t];const n=new Promise(r=>{var s;const o=document.createElement("script");o.src=t,(s=document.querySelector("body"))==null||s.appendChild(o),o.onload=()=>{r()}});return e[t]=n,n},N4=(e,t)=>{if(t.css&&Array.from(e.childNodes).every(n=>n.nodeName!=="STYLE")){const n=V4("style",{innerHTML:t.css});e.appendChild(n)}},M4=(e,t,n)=>{const r=n.getScript();if(r&&Array.from(t.childNodes).every(o=>o.nodeName!=="SCRIPT")){const o=document.createElement("script");o.appendChild(document.createTextNode(`{const document=window.document.querySelector('#${e} .vp-code-demo-display').shadowRoot; +${r}}`)),t.appendChild(o)}},$4=["html","js","css"],F4=e=>{const t=io(e),n={html:[],js:[],css:[],isLegal:!1};return $4.forEach(r=>{const o=t.filter(s=>zu[r].types.includes(s));if(o.length){const s=o[0];n[r]=[e[s].replace(/^\n|\n$/g,""),zu[r].map[s]??s]}}),n.isLegal=(!n.html.length||n.html[1]==="none")&&(!n.js.length||n.js[1]==="none")&&(!n.css.length||n.css[1]==="none"),n},Gd=e=>e.replace(/
/g,"
").replace(/<((\S+)[^<]*?)\s+\/>/g,"<$1>"),Yd=e=>`
+${Gd(e)} +
`,B4=e=>`${e.replace("export default ","const $reactApp = ").replace(/App\.__style__(\s*)=(\s*)`([\s\S]*)?`/,"")}; +ReactDOM.createRoot(document.getElementById("app")).render(React.createElement($reactApp))`,H4=e=>e.replace(/export\s+default\s*\{(\n*[\s\S]*)\n*\}\s*;?$/u,"Vue.createApp({$1}).mount('#app')").replace(/export\s+default\s*define(Async)?Component\s*\(\s*\{(\n*[\s\S]*)\n*\}\s*\)\s*;?$/u,"Vue.createApp({$1}).mount('#app')").trim(),Qd=e=>`(function(exports){var module={};module.exports=exports;${e};return module.exports.__esModule?exports.default:module.exports;})({})`,j4=(e,t)=>{const n=pl(t),r=e.js[0]??"";return{...n,html:Gd(e.html[0]??""),js:r,css:e.css[0]??"",isLegal:e.isLegal,getScript:()=>{var o;return n.useBabel?((o=window.Babel.transform(r,{presets:["es2015"]}))==null?void 0:o.code)??"":r}}},U4=/