From 4c44044c0cf7ab1177beea03dd869627c37d1872 Mon Sep 17 00:00:00 2001 From: Gani Georgiev Date: Sat, 18 Apr 2026 16:29:34 +0300 Subject: [PATCH] merge newui branch --- CHANGELOG.md | 5 + CONTRIBUTING.md | 27 +- README.md | 11 +- apis/base.go | 6 +- apis/collection.go | 87 + apis/collection_test.go | 196 +- apis/extensions.go | 94 + apis/extensions_test.go | 177 + apis/health.go | 1 + apis/installer.go | 8 +- apis/middlewares_body_limit.go | 2 +- apis/record_auth_methods.go | 11 +- apis/record_auth_methods_test.go | 2 + apis/record_auth_with_oauth2_redirect.go | 44 +- apis/serve.go | 40 +- apis/settings.go | 12 +- core/app.go | 9 + core/collection_model_test.go | 54 +- core/collection_model_view_options_test.go | 18 + core/collection_validate.go | 14 +- core/events.go | 19 + core/field.go | 20 + core/field_autodate.go | 4 +- core/field_bool.go | 7 +- core/field_bool_test.go | 1 + core/field_date.go | 7 +- core/field_date_test.go | 1 + core/field_editor.go | 7 +- core/field_editor_test.go | 1 + core/field_email.go | 7 +- core/field_email_test.go | 1 + core/field_file.go | 7 +- core/field_file_test.go | 1 + core/field_geo_point.go | 7 +- core/field_geo_point_test.go | 1 + core/field_json.go | 7 +- core/field_json_test.go | 1 + core/field_number.go | 7 +- core/field_number_test.go | 1 + core/field_password.go | 9 +- core/field_password_test.go | 1 + core/field_relation.go | 7 +- core/field_relation_test.go | 1 + core/field_select.go | 7 +- core/field_select_test.go | 1 + core/field_test.go | 63 +- core/field_text.go | 7 +- core/field_text_test.go | 1 + core/field_url.go | 7 +- core/field_url_test.go | 1 + core/fields_list_test.go | 12 +- core/settings_model.go | 7 + core/settings_model_test.go | 35 +- core/view.go | 123 +- core/view_test.go | 126 + plugins/jsvm/binds.go | 55 +- plugins/jsvm/binds_test.go | 176 +- .../jsvm/internal/types/generated/types.d.ts | 10616 ++++++++-------- plugins/jsvm/jsvm.go | 41 +- plugins/migratecmd/migratecmd_test.go | 32 + tools/auth/apple.go | 2 + tools/auth/auth.go | 21 +- tools/auth/base_provider.go | 16 +- tools/auth/base_provider_test.go | 60 +- tools/auth/bitbucket.go | 2 + tools/auth/box.go | 2 + tools/auth/discord.go | 2 + tools/auth/facebook.go | 2 + tools/auth/gitea.go | 2 + tools/auth/gitee.go | 2 + tools/auth/github.go | 2 + tools/auth/gitlab.go | 2 + tools/auth/google.go | 2 + tools/auth/instagram.go | 2 + tools/auth/kakao.go | 2 + tools/auth/lark.go | 2 + tools/auth/linear.go | 2 + tools/auth/livechat.go | 2 + tools/auth/mailcow.go | 2 + tools/auth/microsoft.go | 2 + tools/auth/monday.go | 2 + tools/auth/notion.go | 2 + tools/auth/oidc.go | 2 + tools/auth/patreon.go | 2 + tools/auth/planningcenter.go | 2 + tools/auth/spotify.go | 2 + tools/auth/strava.go | 2 + tools/auth/trakt.go | 2 + tools/auth/twitch.go | 2 + tools/auth/twitter.go | 2 + tools/auth/vk.go | 4 + tools/auth/wakatime.go | 2 + tools/auth/yandex.go | 2 + ui/.env | 6 +- ui/.gitignore | 27 +- ui/README.md | 13 +- ui/dist/assets/AuthMethodsDocs-CoFGCgbc.js | 39 - ui/dist/assets/AuthRefreshDocs-CQwCsEss.js | 79 - ui/dist/assets/AuthWithOAuth2Docs-dZYwc-te.js | 117 - ui/dist/assets/AuthWithOtpDocs-DwGQ2_6Y.js | 136 - .../assets/AuthWithPasswordDocs-Dgg678dt.js | 96 - ui/dist/assets/BatchApiDocs-CaJSx-jz.js | 158 - ui/dist/assets/CodeEditor-BjqGK3BY.js | 14 - ui/dist/assets/CreateApiDocs-Cg4p-Cu8.js | 90 - ui/dist/assets/DeleteApiDocs-CVqJaHXL.js | 53 - ui/dist/assets/EmailChangeDocs-ALKkvYws.js | 120 - ui/dist/assets/FieldsQueryParam-B36GF025.js | 7 - .../FilterAutocompleteInput-UU1zPsgx.js | 1 - ui/dist/assets/Leaflet-DCQr6yJv.css | 1 - ui/dist/assets/Leaflet-P16gNgV3.js | 4 - ui/dist/assets/ListApiDocs-ByASLUZu.css | 1 - ui/dist/assets/ListApiDocs-DGceQHQZ.js | 137 - ui/dist/assets/PageInstaller-DktNc-jf.js | 3 - .../PageOAuth2RedirectFailure-CguUZswk.js | 1 - .../PageOAuth2RedirectSuccess-CcK3psIw.js | 1 - .../PageRecordConfirmEmailChange-CylRwYOU.js | 2 - ...PageRecordConfirmPasswordReset-Dcwt0hvf.js | 2 - .../PageRecordConfirmVerification-gDDwBfsB.js | 1 - ...eSuperuserConfirmPasswordReset-DrNd_wUS.js | 2 - ...eSuperuserRequestPasswordReset-D7jINQSc.js | 1 - ui/dist/assets/PasswordResetDocs-bUVxSWLH.js | 100 - ui/dist/assets/RealtimeApiDocs-kmoD_vEm.js | 110 - ui/dist/assets/UpdateApiDocs-Bmron_nJ.js | 90 - ui/dist/assets/VerificationDocs-BfIVQ1pO.js | 79 - ui/dist/assets/ViewApiDocs-DKZ-e-0R.js | 59 - .../assets/autocomplete.worker-Bb6Toth-.js | 4 - ui/dist/assets/docsAuthRefresh-UjveHHwo.js | 49 + ui/dist/assets/docsAuthWithOAuth2-DUIE4EoY.js | 67 + ui/dist/assets/docsAuthWithOTP-B7z2VJzp.js | 95 + .../assets/docsAuthWithPassword-DEWj8Jyn.js | 55 + ui/dist/assets/docsBatch-DNJl1NTn.js | 92 + ui/dist/assets/docsCreate-Be3S3y5K.js | 52 + ui/dist/assets/docsDelete-CybOn5jy.js | 39 + ui/dist/assets/docsEmailChange-B---6FKV.js | 94 + ui/dist/assets/docsList-BHALa0P4.js | 64 + .../assets/docsListAuthMethods-9feSopQX.js | 25 + ui/dist/assets/docsPasswordReset-vLO_ZWrq.js | 73 + ui/dist/assets/docsRealtime-PMESvmJN.js | 81 + ui/dist/assets/docsUpdate-LtD8DbWI.js | 56 + ui/dist/assets/docsVerification-B_Nb90xU.js | 63 + ui/dist/assets/docsView-Be6Uhvcf.js | 37 + ui/dist/assets/expandInfo-DGS0CLSa.js | 1 + ui/dist/assets/fieldsInfo-Bz62125-.js | 3 + ui/dist/assets/filterSyntax-UQrUrYb5.js | 1 + ui/dist/assets/index-Bk1sdyO7.js | 80 + ui/dist/assets/index-CCCeZnET.css | 1 + ui/dist/assets/index-Cs_DmB1i.js | 14 - ui/dist/assets/index-DMlPjiFP.js | 231 - ui/dist/assets/index-wnKjfGML.css | 1 - .../assets/pageConfirmEmailChange-DErDx8nk.js | 1 + .../pageConfirmPasswordReset-9XIqssFn.js | 1 + .../pageConfirmVerification-BSn_UexA.js | 1 + ui/dist/assets/pageInstaller-DeCAFNnQ.js | 1 + .../pageOAuth2RedirectFailure-CDpbQFyk.js | 1 + .../pageOAuth2RedirectSuccess-D2cNvtvq.js | 1 + ...eRequestSuperuserPasswordReset-BAGI7oww.js | 1 + ui/dist/assets/pocketbase.es-B_4DUNUU.js | 1 + .../ibm-plex-mono-v20-latin-600.woff2 | Bin 0 -> 15620 bytes .../ibm-plex-mono-v20-latin-regular.woff2 | Bin 0 -> 14708 bytes ...ans-v23-cyrillic_latin_latin-ext-600.woff2 | Bin 0 -> 76564 bytes ...3-cyrillic_latin_latin-ext-600italic.woff2 | Bin 0 -> 83508 bytes ...-v23-cyrillic_latin_latin-ext-italic.woff2 | Bin 0 -> 76204 bytes ...v23-cyrillic_latin_latin-ext-regular.woff2 | Bin 0 -> 69868 bytes ui/dist/fonts/remixicon/remixicon.woff2 | Bin 165440 -> 176812 bytes ...s-3-v18-cyrillic_latin_latin-ext-600.woff2 | Bin 74708 -> 0 bytes ...8-cyrillic_latin_latin-ext-600italic.woff2 | Bin 72640 -> 0 bytes ...s-3-v18-cyrillic_latin_latin-ext-700.woff2 | Bin 74736 -> 0 bytes ...8-cyrillic_latin_latin-ext-700italic.woff2 | Bin 73064 -> 0 bytes ...-v18-cyrillic_latin_latin-ext-italic.woff2 | Bin 73180 -> 0 bytes ...v18-cyrillic_latin_latin-ext-regular.woff2 | Bin 75084 -> 0 bytes ...ono-v17-cyrillic_latin_latin-ext-700.woff2 | Bin 77156 -> 0 bytes ...v17-cyrillic_latin_latin-ext-regular.woff2 | Bin 79680 -> 0 bytes ui/dist/images/{favicon => }/favicon.png | Bin ui/dist/images/favicon/apple-touch-icon.png | Bin 1874 -> 0 bytes ui/dist/images/favicon/safari-pinned-tab.svg | 41 - ui/dist/images/{favicon => }/favicon_prod.png | Bin ui/dist/images/logo.svg | 10 +- ui/dist/images/logo_white.svg | 1 + ui/dist/images/oauth2/apple.svg | 7 +- ui/dist/images/oauth2/bitbucket.svg | 2 +- ui/dist/images/oauth2/box.svg | 2 +- ui/dist/images/oauth2/discord.svg | 7 +- ui/dist/images/oauth2/facebook.svg | 9 +- ui/dist/images/oauth2/gitea.svg | 13 +- ui/dist/images/oauth2/gitee.svg | 2 +- ui/dist/images/oauth2/github.svg | 7 +- ui/dist/images/oauth2/gitlab.svg | 7 +- ui/dist/images/oauth2/google.svg | 10 +- ui/dist/images/oauth2/instagram.svg | 2 +- ui/dist/images/oauth2/kakao.svg | 2 +- ui/dist/images/oauth2/lark.svg | 2 +- ui/dist/images/oauth2/linear.svg | 4 +- ui/dist/images/oauth2/livechat.svg | 15 +- ui/dist/images/oauth2/mailcow.svg | 4 +- ui/dist/images/oauth2/microsoft.svg | 11 +- ui/dist/images/oauth2/monday.svg | 6 +- ui/dist/images/oauth2/notion.svg | 4 +- ui/dist/images/oauth2/oidc.svg | 5 +- ui/dist/images/oauth2/patreon.svg | 4 +- ui/dist/images/oauth2/planningcenter.svg | 22 +- ui/dist/images/oauth2/spotify.svg | 8 +- ui/dist/images/oauth2/trakt.svg | 35 +- ui/dist/images/oauth2/twitch.svg | 7 +- ui/dist/images/oauth2/twitter.svg | 5 +- ui/dist/images/oauth2/vk.svg | 5 +- ui/dist/images/oauth2/wakatime.svg | 5 +- ui/dist/images/oauth2/yandex.svg | 5 +- ui/dist/index.html | 44 +- ui/dist/libs/prism/{prism.min.js => prism.js} | 13 +- ui/dist/libs/prism/prism.min.css | 2 - ui/dist/libs/shablon/shablon.iife.js | 3 + ui/dist/libs/tinymce/license.txt | 21 - ui/dist/libs/tinymce/models/dom/model.min.js | 3 - .../libs/tinymce/plugins/anchor/plugin.min.js | 4 - .../tinymce/plugins/autolink/plugin.min.js | 3 +- .../tinymce/plugins/autoresize/plugin.min.js | 3 +- .../tinymce/plugins/autosave/plugin.min.js | 4 - .../libs/tinymce/plugins/code/plugin.min.js | 3 +- .../tinymce/plugins/codesample/plugin.min.js | 11 +- .../plugins/directionality/plugin.min.js | 3 +- .../tinymce/plugins/fullscreen/plugin.min.js | 4 - .../libs/tinymce/plugins/image/plugin.min.js | 3 +- .../tinymce/plugins/importcss/plugin.min.js | 4 - .../plugins/insertdatetime/plugin.min.js | 4 - .../libs/tinymce/plugins/link/plugin.min.js | 3 +- .../libs/tinymce/plugins/lists/plugin.min.js | 3 +- .../libs/tinymce/plugins/media/plugin.min.js | 3 +- .../tinymce/plugins/nonbreaking/plugin.min.js | 4 - .../tinymce/plugins/pagebreak/plugin.min.js | 4 - .../tinymce/plugins/preview/plugin.min.js | 4 - .../tinymce/plugins/quickbars/plugin.min.js | 4 - .../libs/tinymce/plugins/save/plugin.min.js | 4 - .../plugins/searchreplace/plugin.min.js | 4 - .../libs/tinymce/plugins/table/plugin.min.js | 3 +- .../tinymce/plugins/template/plugin.min.js | 4 - .../plugins/visualblocks/plugin.min.js | 4 - .../tinymce/plugins/visualchars/plugin.min.js | 4 - .../tinymce/plugins/wordcount/plugin.min.js | 3 +- .../tinymce/skins/content/default/content.js | 14 +- .../skins/content/default/content.min.css | 2 +- .../skins/content/pocketbase/content.css | 43 - .../skins/content/pocketbase/content.min.css | 1 - .../skins/ui/oxide/content.inline.min.css | 14 + .../tinymce/skins/ui/oxide/content.min.css | 1 + .../libs/tinymce/skins/ui/oxide/skin.min.css | 1 + .../skins/ui/oxide/skin.shadowdom.min.css | 1 + .../tinymce/skins/ui/pocketbase/content.css | 705 - .../skins/ui/pocketbase/content.inline.css | 699 - .../ui/pocketbase/content.inline.min.css | 1 - .../skins/ui/pocketbase/content.min.css | 1 - .../skins/ui/pocketbase/content.mobile.css | 23 - .../ui/pocketbase/content.mobile.min.css | 1 - .../ui/pocketbase/fonts/tinymce-mobile.woff | Bin 4624 -> 0 bytes .../libs/tinymce/skins/ui/pocketbase/skin.css | 3039 ----- .../tinymce/skins/ui/pocketbase/skin.min.css | 1 - .../skins/ui/pocketbase/skin.mobile.css | 671 - .../skins/ui/pocketbase/skin.mobile.min.css | 1 - .../libs/tinymce/themes/silver/theme.min.js | 5 +- ui/dist/libs/tinymce/tinymce.min.js | 13 +- ui/dist/libs/uplot/uplot.css | 1 + ui/dist/libs/uplot/uplot.iife.js | 2 + ui/dprint-typescript-0.95.15.wasm | Bin 0 -> 4171851 bytes ui/dprint.json | 13 + ui/embed.go | 2 + ui/embed_no_ui.go | 8 + ui/index.html | 41 +- ui/package-lock.json | 3211 ++--- ui/package.json | 54 +- .../ibm-plex-mono-v20-latin-600.woff2 | Bin 0 -> 15620 bytes .../ibm-plex-mono-v20-latin-regular.woff2 | Bin 0 -> 14708 bytes ...ans-v23-cyrillic_latin_latin-ext-600.woff2 | Bin 0 -> 76564 bytes ...3-cyrillic_latin_latin-ext-600italic.woff2 | Bin 0 -> 83508 bytes ...-v23-cyrillic_latin_latin-ext-italic.woff2 | Bin 0 -> 76204 bytes ...v23-cyrillic_latin_latin-ext-regular.woff2 | Bin 0 -> 69868 bytes ui/public/fonts/remixicon/remixicon.woff2 | Bin 165440 -> 176812 bytes ...s-3-v18-cyrillic_latin_latin-ext-600.woff2 | Bin 74708 -> 0 bytes ...8-cyrillic_latin_latin-ext-600italic.woff2 | Bin 72640 -> 0 bytes ...s-3-v18-cyrillic_latin_latin-ext-700.woff2 | Bin 74736 -> 0 bytes ...8-cyrillic_latin_latin-ext-700italic.woff2 | Bin 73064 -> 0 bytes ...-v18-cyrillic_latin_latin-ext-italic.woff2 | Bin 73180 -> 0 bytes ...v18-cyrillic_latin_latin-ext-regular.woff2 | Bin 75084 -> 0 bytes ...ono-v17-cyrillic_latin_latin-ext-700.woff2 | Bin 77156 -> 0 bytes ...v17-cyrillic_latin_latin-ext-regular.woff2 | Bin 79680 -> 0 bytes ui/public/images/{favicon => }/favicon.png | Bin ui/public/images/favicon/apple-touch-icon.png | Bin 1874 -> 0 bytes .../images/favicon/safari-pinned-tab.svg | 41 - .../images/{favicon => }/favicon_prod.png | Bin ui/public/images/logo.svg | 10 +- ui/public/images/logo_white.svg | 1 + ui/public/images/oauth2/apple.svg | 7 +- ui/public/images/oauth2/bitbucket.svg | 2 +- ui/public/images/oauth2/box.svg | 2 +- ui/public/images/oauth2/discord.svg | 7 +- ui/public/images/oauth2/facebook.svg | 9 +- ui/public/images/oauth2/gitea.svg | 13 +- ui/public/images/oauth2/gitee.svg | 2 +- ui/public/images/oauth2/github.svg | 7 +- ui/public/images/oauth2/gitlab.svg | 7 +- ui/public/images/oauth2/google.svg | 10 +- ui/public/images/oauth2/instagram.svg | 2 +- ui/public/images/oauth2/kakao.svg | 2 +- ui/public/images/oauth2/lark.svg | 2 +- ui/public/images/oauth2/linear.svg | 4 +- ui/public/images/oauth2/livechat.svg | 15 +- ui/public/images/oauth2/mailcow.svg | 4 +- ui/public/images/oauth2/microsoft.svg | 11 +- ui/public/images/oauth2/monday.svg | 6 +- ui/public/images/oauth2/notion.svg | 4 +- ui/public/images/oauth2/oidc.svg | 5 +- ui/public/images/oauth2/patreon.svg | 4 +- ui/public/images/oauth2/planningcenter.svg | 22 +- ui/public/images/oauth2/spotify.svg | 8 +- ui/public/images/oauth2/trakt.svg | 35 +- ui/public/images/oauth2/twitch.svg | 7 +- ui/public/images/oauth2/twitter.svg | 5 +- ui/public/images/oauth2/vk.svg | 5 +- ui/public/images/oauth2/wakatime.svg | 5 +- ui/public/images/oauth2/yandex.svg | 5 +- .../libs/prism/{prism.min.js => prism.js} | 13 +- ui/public/libs/prism/prism.min.css | 2 - ui/public/libs/shablon/shablon.iife.js | 3 + ui/public/libs/tinymce/license.txt | 21 - .../libs/tinymce/models/dom/model.min.js | 3 - .../libs/tinymce/plugins/anchor/plugin.min.js | 4 - .../tinymce/plugins/autolink/plugin.min.js | 3 +- .../tinymce/plugins/autoresize/plugin.min.js | 3 +- .../tinymce/plugins/autosave/plugin.min.js | 4 - .../libs/tinymce/plugins/code/plugin.min.js | 3 +- .../tinymce/plugins/codesample/plugin.min.js | 11 +- .../plugins/directionality/plugin.min.js | 3 +- .../tinymce/plugins/fullscreen/plugin.min.js | 4 - .../libs/tinymce/plugins/image/plugin.min.js | 3 +- .../tinymce/plugins/importcss/plugin.min.js | 4 - .../plugins/insertdatetime/plugin.min.js | 4 - .../libs/tinymce/plugins/link/plugin.min.js | 3 +- .../libs/tinymce/plugins/lists/plugin.min.js | 3 +- .../libs/tinymce/plugins/media/plugin.min.js | 3 +- .../tinymce/plugins/nonbreaking/plugin.min.js | 4 - .../tinymce/plugins/pagebreak/plugin.min.js | 4 - .../tinymce/plugins/preview/plugin.min.js | 4 - .../tinymce/plugins/quickbars/plugin.min.js | 4 - .../libs/tinymce/plugins/save/plugin.min.js | 4 - .../plugins/searchreplace/plugin.min.js | 4 - .../libs/tinymce/plugins/table/plugin.min.js | 3 +- .../tinymce/plugins/template/plugin.min.js | 4 - .../plugins/visualblocks/plugin.min.js | 4 - .../tinymce/plugins/visualchars/plugin.min.js | 4 - .../tinymce/plugins/wordcount/plugin.min.js | 3 +- .../tinymce/skins/content/default/content.js | 14 +- .../skins/content/default/content.min.css | 2 +- .../skins/content/pocketbase/content.css | 43 - .../skins/content/pocketbase/content.min.css | 1 - .../skins/ui/oxide/content.inline.min.css | 14 + .../tinymce/skins/ui/oxide/content.min.css | 1 + .../libs/tinymce/skins/ui/oxide/skin.min.css | 1 + .../skins/ui/oxide/skin.shadowdom.min.css | 1 + .../tinymce/skins/ui/pocketbase/content.css | 705 - .../skins/ui/pocketbase/content.inline.css | 699 - .../ui/pocketbase/content.inline.min.css | 1 - .../skins/ui/pocketbase/content.min.css | 1 - .../skins/ui/pocketbase/content.mobile.css | 23 - .../ui/pocketbase/content.mobile.min.css | 1 - .../ui/pocketbase/fonts/tinymce-mobile.woff | Bin 4624 -> 0 bytes .../libs/tinymce/skins/ui/pocketbase/skin.css | 3039 ----- .../tinymce/skins/ui/pocketbase/skin.min.css | 1 - .../skins/ui/pocketbase/skin.mobile.css | 671 - .../skins/ui/pocketbase/skin.mobile.min.css | 1 - .../libs/tinymce/themes/silver/theme.min.js | 5 +- ui/public/libs/tinymce/tinymce.min.js | 13 +- ui/public/libs/uplot/uplot.css | 1 + ui/public/libs/uplot/uplot.iife.js | 2 + ui/src/App.svelte | 185 - ui/src/actions/scrollend.js | 64 - ui/src/actions/tooltip.js | 187 - ui/src/apiPreview/apiPreviewModal.js | 228 + ui/src/apiPreview/docsAuthRefresh.js | 179 + ui/src/apiPreview/docsAuthWithOAuth2.js | 261 + ui/src/apiPreview/docsAuthWithOTP.js | 324 + ui/src/apiPreview/docsAuthWithPassword.js | 225 + ui/src/apiPreview/docsBatch.js | 263 + ui/src/apiPreview/docsCreate.js | 404 + ui/src/apiPreview/docsDelete.js | 147 + ui/src/apiPreview/docsEmailChange.js | 284 + ui/src/apiPreview/docsList.js | 277 + ui/src/apiPreview/docsListAuthMethods.js | 144 + ui/src/apiPreview/docsPasswordReset.js | 260 + ui/src/apiPreview/docsRealtime.js | 190 + ui/src/apiPreview/docsUpdate.js | 242 + ui/src/apiPreview/docsVerification.js | 234 + ui/src/apiPreview/docsView.js | 180 + ui/src/apiPreview/expandInfo.js | 25 + ui/src/apiPreview/fieldsInfo.js | 25 + ui/src/apiPreview/filterSyntax.js | 165 + ui/src/auth/pageConfirmEmailChange.js | 129 + ui/src/auth/pageConfirmPasswordReset.js | 167 + ui/src/auth/pageConfirmVerification.js | 112 + ui/src/auth/pageInstaller.js | 266 + ui/src/auth/pageOAuth2RedirectFailure.js | 20 + ui/src/auth/pageOAuth2RedirectSuccess.js | 17 + .../auth/pageRequestSuperuserPasswordReset.js | 92 + ui/src/auth/pageSuperuserLogin.js | 420 + ui/src/autocomplete.worker.js | 39 - ui/src/base/appHeader.js | 148 + ui/src/base/autoAccordionOpenOnError.js | 14 + ui/src/base/codeBlock.js | 78 + ui/src/base/codeBlockTabs.js | 96 + ui/src/base/codeEditor.js | 507 + ui/src/base/colorPicker.js | 142 + ui/src/base/confirm.js | 157 + ui/src/base/copyButton.js | 60 + ui/src/base/credits.js | 36 + ui/src/base/dragline.js | 123 + ui/src/base/dropdownKeyboardNav.js | 98 + ui/src/base/erd.js | 467 + ui/src/base/fieldSettings.js | 439 + ui/src/base/filePreviewModal.js | 119 + ui/src/base/formattedDate.js | 54 + ui/src/base/leaflet.js | 313 + ui/src/base/modal.js | 261 + ui/src/base/pageSidebar.js | 170 + ui/src/base/refreshButton.js | 71 + ui/src/base/ruleField.js | 165 + ui/src/base/s3ConfigFields.js | 216 + ui/src/base/s3Test.js | 125 + ui/src/base/searchHistoryButton.js | 153 + ui/src/base/searchbar.js | 128 + ui/src/base/select.js | 331 + ui/src/base/slide.js | 38 + ui/src/base/sortable.js | 188 + ui/src/base/tinymce.js | 542 + ui/src/base/toast.js | 158 + ui/src/base/tooltip.js | 153 + ui/src/base/uploadedFileThumb.js | 83 + .../collections/addCollectionFieldButton.js | 104 + ui/src/collections/autocomplete.utils.js | 246 + .../collections/collectionAuthOptionsTab.js | 89 + .../collectionChangesConfirmationModal.js | 347 + ui/src/collections/collectionFieldsTab.js | 82 + ui/src/collections/collectionRulesTab.js | 274 + ui/src/collections/collectionUpsertModal.js | 913 ++ ui/src/collections/collectionViewQueryTab.js | 192 + .../collections/collectionsOverviewModal.js | 282 + ui/src/collections/collectionsSidebar.js | 258 + ui/src/collections/emailTemplateAccordion.js | 112 + ui/src/collections/indexUpsertModal.js | 273 + ui/src/collections/mfaAccordion.js | 131 + ui/src/collections/oauth2/appleOptions.js | 236 + ui/src/collections/oauth2/larkOptions.js | 73 + ui/src/collections/oauth2/microsoftOptions.js | 53 + ui/src/collections/oauth2/oidcOptions.js | 234 + ui/src/collections/oauth2/selfhostOptions.js | 115 + ui/src/collections/oauth2Accordion.js | 314 + ui/src/collections/otpAccordion.js | 105 + ui/src/collections/pageCollections.js | 331 + ui/src/collections/passwordAuthAccordion.js | 112 + ui/src/collections/providerPickerModal.js | 175 + ui/src/collections/providerSettingsModal.js | 200 + ui/src/collections/tokenOptionsAccordion.js | 78 + ui/src/components/PageIndex.svelte | 14 - ui/src/components/base/Accordion.svelte | 114 - .../components/base/AutoExpandTextarea.svelte | 55 - .../components/base/AutocompleteInput.svelte | 24 - .../components/base/BaseSelectOption.svelte | 10 - ui/src/components/base/CodeBlock.svelte | 49 - ui/src/components/base/CodeEditor.svelte | 284 - ui/src/components/base/Confirmation.svelte | 66 - ui/src/components/base/CopyIcon.svelte | 45 - ui/src/components/base/Draggable.svelte | 110 - ui/src/components/base/Dragline.svelte | 107 - .../base/DynamicOptionsSelect.svelte | 151 - ui/src/components/base/Field.svelte | 70 - .../base/FilterAutocompleteInput.svelte | 438 - ui/src/components/base/FormattedDate.svelte | 40 - ui/src/components/base/FullPage.svelte | 32 - ui/src/components/base/InitialsAvatar.svelte | 29 - ui/src/components/base/Leaflet.svelte | 233 - .../base/MimeTypeSelectOption.svelte | 6 - .../components/base/MultipleValueInput.svelte | 21 - ui/src/components/base/ObjectSelect.svelte | 73 - ui/src/components/base/OverlayPanel.svelte | 274 - ui/src/components/base/PageInstaller.svelte | 221 - ui/src/components/base/PageSidebar.svelte | 34 - ui/src/components/base/PageWrapper.svelte | 29 - ui/src/components/base/PreviewPopup.svelte | 84 - .../base/RedactedPasswordInput.svelte | 33 - ui/src/components/base/RefreshButton.svelte | 54 - ui/src/components/base/Scroller.svelte | 151 - ui/src/components/base/SdkTabs.svelte | 67 - ui/src/components/base/Searchbar.svelte | 109 - .../base/SecretGeneratorButton.svelte | 70 - ui/src/components/base/Select.svelte | 318 - ui/src/components/base/SortHeader.svelte | 39 - ui/src/components/base/TinyMCE.svelte | 244 - ui/src/components/base/Toasts.svelte | 38 - ui/src/components/base/Toggler.svelte | 216 - .../base/UploadedFilePreview.svelte | 33 - .../CollectionAuthOptionsTab.svelte | 127 - .../collections/CollectionDocsPanel.svelte | 162 - .../collections/CollectionFieldsTab.svelte | 264 - .../collections/CollectionQueryTab.svelte | 114 - .../collections/CollectionRulesTab.svelte | 182 - .../collections/CollectionSidebarItem.svelte | 74 - .../CollectionUpdateConfirm.svelte | 284 - .../collections/CollectionUpsertPanel.svelte | 654 - .../collections/CollectionsDiffTable.svelte | 268 - .../collections/CollectionsSidebar.svelte | 161 - .../collections/EmailTemplateAccordion.svelte | 132 - .../collections/IndexUpsertPanel.svelte | 164 - .../components/collections/IndexesList.svelte | 99 - .../collections/MFAAccordion.svelte | 85 - .../collections/OAuth2Accordion.svelte | 254 - .../collections/OAuth2ProviderPanel.svelte | 115 - .../OAuth2ProvidersListPanel.svelte | 107 - .../collections/OTPAccordion.svelte | 99 - .../collections/PasswordAuthAccordion.svelte | 108 - .../components/collections/RuleField.svelte | 210 - .../components/collections/TokenField.svelte | 32 - .../collections/TokenOptionsAccordion.svelte | 76 - .../collections/docs/AuthMethodsDocs.svelte | 117 - .../collections/docs/AuthRefreshDocs.svelte | 163 - .../docs/AuthWithOAuth2Docs.svelte | 263 - .../docs/AuthWithOtpApiAuthDocs.svelte | 136 - .../docs/AuthWithOtpApiRequestDocs.svelte | 103 - .../collections/docs/AuthWithOtpDocs.svelte | 100 - .../docs/AuthWithPasswordDocs.svelte | 203 - .../collections/docs/BatchApiDocs.svelte | 267 - .../collections/docs/CreateApiDocs.svelte | 323 - .../collections/docs/DeleteApiDocs.svelte | 140 - .../docs/EmailChangeApiConfirmDocs.svelte | 98 - .../docs/EmailChangeApiRequestDocs.svelte | 107 - .../collections/docs/EmailChangeDocs.svelte | 92 - .../collections/docs/FieldsQueryParam.svelte | 33 - .../collections/docs/FilterSyntax.svelte | 142 - .../collections/docs/ListApiDocs.svelte | 256 - .../docs/PasswordResetApiConfirmDocs.svelte | 110 - .../docs/PasswordResetApiRequestDocs.svelte | 86 - .../collections/docs/PasswordResetDocs.svelte | 88 - .../collections/docs/RealtimeApiDocs.svelte | 116 - .../collections/docs/UpdateApiDocs.svelte | 368 - .../docs/VerificationApiConfirmDocs.svelte | 86 - .../docs/VerificationApiRequestDocs.svelte | 86 - .../collections/docs/VerificationDocs.svelte | 74 - .../collections/docs/ViewApiDocs.svelte | 161 - .../collections/providers/AppleOptions.svelte | 24 - .../providers/AppleSecretPopup.svelte | 152 - .../collections/providers/LarkOptions.svelte | 49 - .../providers/MicrosoftOptions.svelte | 22 - .../collections/providers/OIDCOptions.svelte | 126 - .../providers/SelfHostedOptions.svelte | 24 - .../collections/schema/NewField.svelte | 122 - .../collections/schema/SchemaField.svelte | 346 - .../schema/SchemaFieldAutodate.svelte | 78 - .../collections/schema/SchemaFieldBool.svelte | 8 - .../collections/schema/SchemaFieldDate.svelte | 59 - .../schema/SchemaFieldEditor.svelte | 39 - .../schema/SchemaFieldEmail.svelte | 58 - .../collections/schema/SchemaFieldFile.svelte | 305 - .../schema/SchemaFieldGeoPoint.svelte | 8 - .../collections/schema/SchemaFieldJson.svelte | 70 - .../schema/SchemaFieldNumber.svelte | 43 - .../schema/SchemaFieldPassword.svelte | 76 - .../schema/SchemaFieldRelation.svelte | 172 - .../schema/SchemaFieldSelect.svelte | 90 - .../collections/schema/SchemaFieldText.svelte | 92 - .../collections/schema/SchemaFieldUrl.svelte | 9 - ui/src/components/logs/LogDate.svelte | 18 - ui/src/components/logs/LogLevel.svelte | 40 - ui/src/components/logs/LogViewPanel.svelte | 244 - ui/src/components/logs/LogsChart.svelte | 247 - ui/src/components/logs/LogsLevelsInfo.svelte | 15 - ui/src/components/logs/LogsList.svelte | 404 - .../components/logs/LogsSettingsPanel.svelte | 142 - ui/src/components/logs/PageLogs.svelte | 123 - ui/src/components/records/AutodateIcon.svelte | 44 - .../records/ExternalAuthsList.svelte | 102 - .../records/ImpersonatePopup.svelte | 161 - .../records/PageOAuth2RedirectFailure.svelte | 15 - .../records/PageOAuth2RedirectSuccess.svelte | 15 - .../PageRecordConfirmEmailChange.svelte | 78 - .../PageRecordConfirmPasswordReset.svelte | 86 - .../PageRecordConfirmVerification.svelte | 117 - ui/src/components/records/PageRecords.svelte | 304 - .../records/RecordFieldValue.svelte | 142 - .../records/RecordFilePicker.svelte | 365 - .../components/records/RecordFileThumb.svelte | 87 - ui/src/components/records/RecordInfo.svelte | 43 - .../records/RecordInfoContent.svelte | 76 - .../records/RecordPreviewPanel.svelte | 90 - .../records/RecordUpsertPanel.svelte | 799 -- ui/src/components/records/RecordsCount.svelte | 53 - ui/src/components/records/RecordsList.svelte | 501 - .../components/records/RecordsPicker.svelte | 424 - .../records/fields/AuthFields.svelte | 147 - .../records/fields/BoolField.svelte | 12 - .../records/fields/DateField.svelte | 60 - .../records/fields/EditorField.svelte | 78 - .../records/fields/EmailField.svelte | 13 - .../records/fields/FieldLabel.svelte | 25 - .../records/fields/FileField.svelte | 242 - .../records/fields/GeoPointField.svelte | 143 - .../records/fields/GeoPointValue.svelte | 5 - .../records/fields/JsonField.svelte | 83 - .../records/fields/NumberField.svelte | 21 - .../records/fields/PasswordField.svelte | 13 - .../records/fields/RelationField.svelte | 235 - .../records/fields/SelectField.svelte | 40 - .../records/fields/TextField.svelte | 25 - .../components/records/fields/UrlField.svelte | 13 - .../settings/BackupCreatePanel.svelte | 138 - .../settings/BackupRestorePanel.svelte | 144 - .../settings/BackupUploadButton.svelte | 94 - ui/src/components/settings/BackupsList.svelte | 222 - .../components/settings/BatchAccordion.svelte | 100 - .../components/settings/EmailTestPopup.svelte | 186 - ui/src/components/settings/ImportPopup.svelte | 152 - .../settings/PageApplication.svelte | 260 - ui/src/components/settings/PageBackups.svelte | 302 - ui/src/components/settings/PageCrons.svelte | 133 - .../settings/PageExportCollections.svelte | 192 - .../settings/PageImportCollections.svelte | 456 - ui/src/components/settings/PageMail.svelte | 301 - ui/src/components/settings/PageStorage.svelte | 200 - .../settings/RateLimitAccordion.svelte | 336 - ui/src/components/settings/S3Fields.svelte | 154 - .../settings/SettingsSidebar.svelte | 76 - .../settings/TrustedProxyAccordion.svelte | 172 - .../PageSuperuserConfirmPasswordReset.svelte | 70 - .../superusers/PageSuperuserLogin.svelte | 285 - .../PageSuperuserRequestPasswordReset.svelte | 65 - ui/src/css/_main.css | 37 + ui/src/css/accordion.css | 163 + ui/src/css/animations.css | 50 + ui/src/css/apiPreviewModal.css | 128 + ui/src/css/base.css | 1283 ++ ui/src/css/bulkbar.css | 74 + ui/src/css/collectionModal.css | 95 + ui/src/css/collectionsOverview.css | 70 + ui/src/css/colorPicker.css | 97 + ui/src/css/dropdown.css | 163 + ui/src/css/erd.css | 183 + ui/src/css/export.css | 156 + ui/src/css/fonts.css | 57 + ui/src/css/form.css | 1122 ++ ui/src/css/grid.css | 184 + ui/src/css/hideControls.css | 7 + ui/src/css/layout.css | 616 + ui/src/css/list.css | 136 + ui/src/css/logs.css | 248 + ui/src/css/map.css | 41 + ui/src/css/modal.css | 302 + ui/src/css/prism.css | 74 + ui/src/css/providers.css | 98 + ui/src/css/ratelimit.css | 91 + ui/src/css/recordFields.css | 325 + ui/src/css/recordFilePicker.css | 56 + ui/src/css/recordSummary.css | 71 + ui/src/css/recordsPicker.css | 38 + ui/src/css/remixicon.css | 9185 +++++++++++++ ui/src/css/ruleField.css | 133 + ui/src/css/table.css | 505 + ui/src/css/tabs.css | 58 + ui/src/css/tinymce.css | 0 ui/src/css/toast.css | 114 + ui/src/css/tooltip.css | 30 + ui/src/css/vars.css | 246 + ui/src/fields/autodate/init.js | 20 + ui/src/fields/autodate/onrecordduplicate.js | 8 + ui/src/fields/autodate/settings.js | 74 + ui/src/fields/autodate/view.js | 14 + ui/src/fields/bool/init.js | 16 + ui/src/fields/bool/input.js | 31 + ui/src/fields/bool/settings.js | 53 + ui/src/fields/bool/view.js | 14 + ui/src/fields/date/init.js | 16 + ui/src/fields/date/input.js | 37 + ui/src/fields/date/settings.js | 87 + ui/src/fields/date/view.js | 14 + ui/src/fields/editor/init.js | 19 + ui/src/fields/editor/input.js | 47 + ui/src/fields/editor/settings.js | 101 + ui/src/fields/editor/view.js | 29 + ui/src/fields/email/init.js | 19 + ui/src/fields/email/input.js | 36 + ui/src/fields/email/settings.js | 105 + ui/src/fields/email/view.js | 26 + ui/src/fields/file/init.js | 51 + ui/src/fields/file/input.js | 256 + ui/src/fields/file/onrecordduplicate.js | 9 + ui/src/fields/file/onrecordsave.js | 23 + ui/src/fields/file/settings.js | 357 + ui/src/fields/file/view.js | 34 + ui/src/fields/geoPoint/init.js | 19 + ui/src/fields/geoPoint/input.js | 105 + ui/src/fields/geoPoint/settings.js | 53 + ui/src/fields/geoPoint/view.js | 14 + ui/src/fields/json/init.js | 18 + ui/src/fields/json/input.js | 122 + ui/src/fields/json/onrecordsave.js | 30 + ui/src/fields/json/settings.js | 131 + ui/src/fields/json/view.js | 21 + ui/src/fields/number/init.js | 16 + ui/src/fields/number/input.js | 37 + ui/src/fields/number/settings.js | 101 + ui/src/fields/number/view.js | 11 + ui/src/fields/password/init.js | 9 + ui/src/fields/password/settings.js | 166 + ui/src/fields/relation/init.js | 19 + ui/src/fields/relation/input.js | 197 + ui/src/fields/relation/settings.js | 204 + ui/src/fields/relation/view.js | 214 + ui/src/fields/select/init.js | 22 + ui/src/fields/select/input.js | 47 + ui/src/fields/select/settings.js | 189 + ui/src/fields/select/view.js | 25 + ui/src/fields/text/init.js | 19 + ui/src/fields/text/input.js | 78 + ui/src/fields/text/settings.js | 161 + ui/src/fields/text/view.js | 42 + ui/src/fields/url/init.js | 16 + ui/src/fields/url/input.js | 35 + ui/src/fields/url/settings.js | 105 + ui/src/fields/url/view.js | 29 + ui/src/logs/defaultLogLevels.js | 13 + ui/src/logs/logLevel.js | 8 + ui/src/logs/logPreviewModal.js | 276 + ui/src/logs/logsChart.js | 482 + ui/src/logs/logsList.js | 468 + ui/src/logs/logsSettingsModal.js | 233 + ui/src/logs/pageLogs.js | 179 + ui/src/main.js | 151 +- ui/src/mimeTypes.js | 197 + ui/src/mimes.js | 183 - ui/src/pb.js | 246 + ui/src/providers.js | 193 - ui/src/records/recordFilePickerModal.js | 440 + ui/src/records/recordFileThumb.js | 149 + ui/src/records/recordImpersonateModal.js | 203 + ui/src/records/recordPreviewModal.js | 246 + ui/src/records/recordSummary.js | 219 + ui/src/records/recordUpsertModal.js | 1440 +++ ui/src/records/recordsList.js | 735 ++ ui/src/records/recordsPickerModal.js | 484 + ui/src/records/recordsSearchbar.js | 62 + ui/src/router.js | 172 + ui/src/routes.js | 148 - ui/src/scss/_accordion.scss | 152 - ui/src/scss/_alert.scss | 128 - ui/src/scss/_animations.scss | 98 - ui/src/scss/_base.scss | 1148 -- ui/src/scss/_bulkbar.scss | 19 - ui/src/scss/_collections_export.scss | 66 - ui/src/scss/_docs_panel.scss | 104 - ui/src/scss/_dropdown.scss | 139 - ui/src/scss/_file_picker.scss | 91 - ui/src/scss/_flatpickr.scss | 738 -- ui/src/scss/_fonts.scss | 71 - ui/src/scss/_form.scss | 1396 -- ui/src/scss/_grid.scss | 79 - ui/src/scss/_icons.scss | 2917 ----- ui/src/scss/_layout.scss | 371 - ui/src/scss/_mixins.scss | 66 - ui/src/scss/_overlay_panel.scss | 326 - ui/src/scss/_rate_limit.scss | 78 - ui/src/scss/_reset.scss | 50 - ui/src/scss/_schema_field.scss | 198 - ui/src/scss/_searchbar.scss | 66 - ui/src/scss/_table.scss | 329 - ui/src/scss/_tabs.scss | 148 - ui/src/scss/_tooltip.scss | 44 - ui/src/scss/_vars.scss | 103 - ui/src/scss/main.scss | 49 - ui/src/scss/prism_light.scss | 3 - ui/src/settings/application/batchAccordion.js | 121 + .../application/pageApplicationSettings.js | 287 + .../application/rateLimitAccordion.js | 415 + .../application/rateLimitInfoModal.js | 152 + .../application/trustedProxyAccordion.js | 240 + ui/src/settings/backups/backupCreateModal.js | 151 + ui/src/settings/backups/backupRestoreModal.js | 181 + ui/src/settings/backups/backupUploadButton.js | 89 + ui/src/settings/backups/backupsForm.js | 287 + ui/src/settings/backups/backupsList.js | 225 + .../settings/backups/pageBackupsSettings.js | 62 + ui/src/settings/crons/cronsList.js | 113 + ui/src/settings/crons/pageCronsSettings.js | 63 + ui/src/settings/mail/mailTestModal.js | 203 + ui/src/settings/mail/pageMailSettings.js | 385 + ui/src/settings/settingsSidebar.js | 54 + .../settings/storage/pageStorageSettings.js | 187 + ui/src/settings/sync/collectionsDiffTable.js | 319 + .../sync/importCollectionsReviewModal.js | 180 + ui/src/settings/sync/pageExportCollections.js | 191 + ui/src/settings/sync/pageImportCollections.js | 536 + ui/src/store.js | 452 + ui/src/stores/app.js | 7 - ui/src/stores/collections.js | 122 - ui/src/stores/confirmation.js | 26 - ui/src/stores/errors.js | 32 - ui/src/stores/superuser.js | 8 - ui/src/stores/toasts.js | 76 - ui/src/utils.js | 1787 +++ ui/src/utils/ApiClient.js | 149 - ui/src/utils/CommonHelper.js | 2296 ---- ui/vite.config.js | 28 +- 804 files changed, 58660 insertions(+), 56663 deletions(-) create mode 100644 apis/extensions.go create mode 100644 apis/extensions_test.go delete mode 100644 ui/dist/assets/AuthMethodsDocs-CoFGCgbc.js delete mode 100644 ui/dist/assets/AuthRefreshDocs-CQwCsEss.js delete mode 100644 ui/dist/assets/AuthWithOAuth2Docs-dZYwc-te.js delete mode 100644 ui/dist/assets/AuthWithOtpDocs-DwGQ2_6Y.js delete mode 100644 ui/dist/assets/AuthWithPasswordDocs-Dgg678dt.js delete mode 100644 ui/dist/assets/BatchApiDocs-CaJSx-jz.js delete mode 100644 ui/dist/assets/CodeEditor-BjqGK3BY.js delete mode 100644 ui/dist/assets/CreateApiDocs-Cg4p-Cu8.js delete mode 100644 ui/dist/assets/DeleteApiDocs-CVqJaHXL.js delete mode 100644 ui/dist/assets/EmailChangeDocs-ALKkvYws.js delete mode 100644 ui/dist/assets/FieldsQueryParam-B36GF025.js delete mode 100644 ui/dist/assets/FilterAutocompleteInput-UU1zPsgx.js delete mode 100644 ui/dist/assets/Leaflet-DCQr6yJv.css delete mode 100644 ui/dist/assets/Leaflet-P16gNgV3.js delete mode 100644 ui/dist/assets/ListApiDocs-ByASLUZu.css delete mode 100644 ui/dist/assets/ListApiDocs-DGceQHQZ.js delete mode 100644 ui/dist/assets/PageInstaller-DktNc-jf.js delete mode 100644 ui/dist/assets/PageOAuth2RedirectFailure-CguUZswk.js delete mode 100644 ui/dist/assets/PageOAuth2RedirectSuccess-CcK3psIw.js delete mode 100644 ui/dist/assets/PageRecordConfirmEmailChange-CylRwYOU.js delete mode 100644 ui/dist/assets/PageRecordConfirmPasswordReset-Dcwt0hvf.js delete mode 100644 ui/dist/assets/PageRecordConfirmVerification-gDDwBfsB.js delete mode 100644 ui/dist/assets/PageSuperuserConfirmPasswordReset-DrNd_wUS.js delete mode 100644 ui/dist/assets/PageSuperuserRequestPasswordReset-D7jINQSc.js delete mode 100644 ui/dist/assets/PasswordResetDocs-bUVxSWLH.js delete mode 100644 ui/dist/assets/RealtimeApiDocs-kmoD_vEm.js delete mode 100644 ui/dist/assets/UpdateApiDocs-Bmron_nJ.js delete mode 100644 ui/dist/assets/VerificationDocs-BfIVQ1pO.js delete mode 100644 ui/dist/assets/ViewApiDocs-DKZ-e-0R.js delete mode 100644 ui/dist/assets/autocomplete.worker-Bb6Toth-.js create mode 100644 ui/dist/assets/docsAuthRefresh-UjveHHwo.js create mode 100644 ui/dist/assets/docsAuthWithOAuth2-DUIE4EoY.js create mode 100644 ui/dist/assets/docsAuthWithOTP-B7z2VJzp.js create mode 100644 ui/dist/assets/docsAuthWithPassword-DEWj8Jyn.js create mode 100644 ui/dist/assets/docsBatch-DNJl1NTn.js create mode 100644 ui/dist/assets/docsCreate-Be3S3y5K.js create mode 100644 ui/dist/assets/docsDelete-CybOn5jy.js create mode 100644 ui/dist/assets/docsEmailChange-B---6FKV.js create mode 100644 ui/dist/assets/docsList-BHALa0P4.js create mode 100644 ui/dist/assets/docsListAuthMethods-9feSopQX.js create mode 100644 ui/dist/assets/docsPasswordReset-vLO_ZWrq.js create mode 100644 ui/dist/assets/docsRealtime-PMESvmJN.js create mode 100644 ui/dist/assets/docsUpdate-LtD8DbWI.js create mode 100644 ui/dist/assets/docsVerification-B_Nb90xU.js create mode 100644 ui/dist/assets/docsView-Be6Uhvcf.js create mode 100644 ui/dist/assets/expandInfo-DGS0CLSa.js create mode 100644 ui/dist/assets/fieldsInfo-Bz62125-.js create mode 100644 ui/dist/assets/filterSyntax-UQrUrYb5.js create mode 100644 ui/dist/assets/index-Bk1sdyO7.js create mode 100644 ui/dist/assets/index-CCCeZnET.css delete mode 100644 ui/dist/assets/index-Cs_DmB1i.js delete mode 100644 ui/dist/assets/index-DMlPjiFP.js delete mode 100644 ui/dist/assets/index-wnKjfGML.css create mode 100644 ui/dist/assets/pageConfirmEmailChange-DErDx8nk.js create mode 100644 ui/dist/assets/pageConfirmPasswordReset-9XIqssFn.js create mode 100644 ui/dist/assets/pageConfirmVerification-BSn_UexA.js create mode 100644 ui/dist/assets/pageInstaller-DeCAFNnQ.js create mode 100644 ui/dist/assets/pageOAuth2RedirectFailure-CDpbQFyk.js create mode 100644 ui/dist/assets/pageOAuth2RedirectSuccess-D2cNvtvq.js create mode 100644 ui/dist/assets/pageRequestSuperuserPasswordReset-BAGI7oww.js create mode 100644 ui/dist/assets/pocketbase.es-B_4DUNUU.js create mode 100644 ui/dist/fonts/ibm-plex-mono/ibm-plex-mono-v20-latin-600.woff2 create mode 100644 ui/dist/fonts/ibm-plex-mono/ibm-plex-mono-v20-latin-regular.woff2 create mode 100644 ui/dist/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-600.woff2 create mode 100644 ui/dist/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-600italic.woff2 create mode 100644 ui/dist/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-italic.woff2 create mode 100644 ui/dist/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-regular.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-600.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-600italic.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-700.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-700italic.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-italic.woff2 delete mode 100644 ui/dist/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-regular.woff2 delete mode 100644 ui/dist/fonts/ubuntu-mono/ubuntu-mono-v17-cyrillic_latin_latin-ext-700.woff2 delete mode 100644 ui/dist/fonts/ubuntu-mono/ubuntu-mono-v17-cyrillic_latin_latin-ext-regular.woff2 rename ui/dist/images/{favicon => }/favicon.png (100%) delete mode 100644 ui/dist/images/favicon/apple-touch-icon.png delete mode 100644 ui/dist/images/favicon/safari-pinned-tab.svg rename ui/dist/images/{favicon => }/favicon_prod.png (100%) create mode 100644 ui/dist/images/logo_white.svg rename ui/dist/libs/prism/{prism.min.js => prism.js} (66%) delete mode 100644 ui/dist/libs/prism/prism.min.css create mode 100644 ui/dist/libs/shablon/shablon.iife.js delete mode 100644 ui/dist/libs/tinymce/license.txt delete mode 100644 ui/dist/libs/tinymce/plugins/anchor/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/autosave/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/fullscreen/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/importcss/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/insertdatetime/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/nonbreaking/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/pagebreak/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/preview/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/quickbars/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/save/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/searchreplace/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/template/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/visualblocks/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/plugins/visualchars/plugin.min.js delete mode 100644 ui/dist/libs/tinymce/skins/content/pocketbase/content.css delete mode 100644 ui/dist/libs/tinymce/skins/content/pocketbase/content.min.css create mode 100644 ui/dist/libs/tinymce/skins/ui/oxide/content.inline.min.css create mode 100644 ui/dist/libs/tinymce/skins/ui/oxide/content.min.css create mode 100644 ui/dist/libs/tinymce/skins/ui/oxide/skin.min.css create mode 100644 ui/dist/libs/tinymce/skins/ui/oxide/skin.shadowdom.min.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.inline.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.inline.min.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.min.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.mobile.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/content.mobile.min.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/fonts/tinymce-mobile.woff delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/skin.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/skin.min.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/skin.mobile.css delete mode 100644 ui/dist/libs/tinymce/skins/ui/pocketbase/skin.mobile.min.css create mode 100644 ui/dist/libs/uplot/uplot.css create mode 100644 ui/dist/libs/uplot/uplot.iife.js create mode 100644 ui/dprint-typescript-0.95.15.wasm create mode 100644 ui/dprint.json create mode 100644 ui/embed_no_ui.go create mode 100644 ui/public/fonts/ibm-plex-mono/ibm-plex-mono-v20-latin-600.woff2 create mode 100644 ui/public/fonts/ibm-plex-mono/ibm-plex-mono-v20-latin-regular.woff2 create mode 100644 ui/public/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-600.woff2 create mode 100644 ui/public/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-600italic.woff2 create mode 100644 ui/public/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-italic.woff2 create mode 100644 ui/public/fonts/ibm-plex-sans/ibm-plex-sans-v23-cyrillic_latin_latin-ext-regular.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-600.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-600italic.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-700.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-700italic.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-italic.woff2 delete mode 100644 ui/public/fonts/source-sans-3/source-sans-3-v18-cyrillic_latin_latin-ext-regular.woff2 delete mode 100644 ui/public/fonts/ubuntu-mono/ubuntu-mono-v17-cyrillic_latin_latin-ext-700.woff2 delete mode 100644 ui/public/fonts/ubuntu-mono/ubuntu-mono-v17-cyrillic_latin_latin-ext-regular.woff2 rename ui/public/images/{favicon => }/favicon.png (100%) delete mode 100644 ui/public/images/favicon/apple-touch-icon.png delete mode 100644 ui/public/images/favicon/safari-pinned-tab.svg rename ui/public/images/{favicon => }/favicon_prod.png (100%) create mode 100644 ui/public/images/logo_white.svg rename ui/public/libs/prism/{prism.min.js => prism.js} (66%) delete mode 100644 ui/public/libs/prism/prism.min.css create mode 100644 ui/public/libs/shablon/shablon.iife.js delete mode 100644 ui/public/libs/tinymce/license.txt delete mode 100644 ui/public/libs/tinymce/plugins/anchor/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/autosave/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/fullscreen/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/importcss/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/insertdatetime/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/nonbreaking/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/pagebreak/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/preview/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/quickbars/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/save/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/searchreplace/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/template/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/visualblocks/plugin.min.js delete mode 100644 ui/public/libs/tinymce/plugins/visualchars/plugin.min.js delete mode 100644 ui/public/libs/tinymce/skins/content/pocketbase/content.css delete mode 100644 ui/public/libs/tinymce/skins/content/pocketbase/content.min.css create mode 100644 ui/public/libs/tinymce/skins/ui/oxide/content.inline.min.css create mode 100644 ui/public/libs/tinymce/skins/ui/oxide/content.min.css create mode 100644 ui/public/libs/tinymce/skins/ui/oxide/skin.min.css create mode 100644 ui/public/libs/tinymce/skins/ui/oxide/skin.shadowdom.min.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.inline.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.inline.min.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.min.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.mobile.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/content.mobile.min.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/fonts/tinymce-mobile.woff delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/skin.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/skin.min.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/skin.mobile.css delete mode 100644 ui/public/libs/tinymce/skins/ui/pocketbase/skin.mobile.min.css create mode 100644 ui/public/libs/uplot/uplot.css create mode 100644 ui/public/libs/uplot/uplot.iife.js delete mode 100644 ui/src/App.svelte delete mode 100644 ui/src/actions/scrollend.js delete mode 100644 ui/src/actions/tooltip.js create mode 100644 ui/src/apiPreview/apiPreviewModal.js create mode 100644 ui/src/apiPreview/docsAuthRefresh.js create mode 100644 ui/src/apiPreview/docsAuthWithOAuth2.js create mode 100644 ui/src/apiPreview/docsAuthWithOTP.js create mode 100644 ui/src/apiPreview/docsAuthWithPassword.js create mode 100644 ui/src/apiPreview/docsBatch.js create mode 100644 ui/src/apiPreview/docsCreate.js create mode 100644 ui/src/apiPreview/docsDelete.js create mode 100644 ui/src/apiPreview/docsEmailChange.js create mode 100644 ui/src/apiPreview/docsList.js create mode 100644 ui/src/apiPreview/docsListAuthMethods.js create mode 100644 ui/src/apiPreview/docsPasswordReset.js create mode 100644 ui/src/apiPreview/docsRealtime.js create mode 100644 ui/src/apiPreview/docsUpdate.js create mode 100644 ui/src/apiPreview/docsVerification.js create mode 100644 ui/src/apiPreview/docsView.js create mode 100644 ui/src/apiPreview/expandInfo.js create mode 100644 ui/src/apiPreview/fieldsInfo.js create mode 100644 ui/src/apiPreview/filterSyntax.js create mode 100644 ui/src/auth/pageConfirmEmailChange.js create mode 100644 ui/src/auth/pageConfirmPasswordReset.js create mode 100644 ui/src/auth/pageConfirmVerification.js create mode 100644 ui/src/auth/pageInstaller.js create mode 100644 ui/src/auth/pageOAuth2RedirectFailure.js create mode 100644 ui/src/auth/pageOAuth2RedirectSuccess.js create mode 100644 ui/src/auth/pageRequestSuperuserPasswordReset.js create mode 100644 ui/src/auth/pageSuperuserLogin.js delete mode 100644 ui/src/autocomplete.worker.js create mode 100644 ui/src/base/appHeader.js create mode 100644 ui/src/base/autoAccordionOpenOnError.js create mode 100644 ui/src/base/codeBlock.js create mode 100644 ui/src/base/codeBlockTabs.js create mode 100644 ui/src/base/codeEditor.js create mode 100644 ui/src/base/colorPicker.js create mode 100644 ui/src/base/confirm.js create mode 100644 ui/src/base/copyButton.js create mode 100644 ui/src/base/credits.js create mode 100644 ui/src/base/dragline.js create mode 100644 ui/src/base/dropdownKeyboardNav.js create mode 100644 ui/src/base/erd.js create mode 100644 ui/src/base/fieldSettings.js create mode 100644 ui/src/base/filePreviewModal.js create mode 100644 ui/src/base/formattedDate.js create mode 100644 ui/src/base/leaflet.js create mode 100644 ui/src/base/modal.js create mode 100644 ui/src/base/pageSidebar.js create mode 100644 ui/src/base/refreshButton.js create mode 100644 ui/src/base/ruleField.js create mode 100644 ui/src/base/s3ConfigFields.js create mode 100644 ui/src/base/s3Test.js create mode 100644 ui/src/base/searchHistoryButton.js create mode 100644 ui/src/base/searchbar.js create mode 100644 ui/src/base/select.js create mode 100644 ui/src/base/slide.js create mode 100644 ui/src/base/sortable.js create mode 100644 ui/src/base/tinymce.js create mode 100644 ui/src/base/toast.js create mode 100644 ui/src/base/tooltip.js create mode 100644 ui/src/base/uploadedFileThumb.js create mode 100644 ui/src/collections/addCollectionFieldButton.js create mode 100644 ui/src/collections/autocomplete.utils.js create mode 100644 ui/src/collections/collectionAuthOptionsTab.js create mode 100644 ui/src/collections/collectionChangesConfirmationModal.js create mode 100644 ui/src/collections/collectionFieldsTab.js create mode 100644 ui/src/collections/collectionRulesTab.js create mode 100644 ui/src/collections/collectionUpsertModal.js create mode 100644 ui/src/collections/collectionViewQueryTab.js create mode 100644 ui/src/collections/collectionsOverviewModal.js create mode 100644 ui/src/collections/collectionsSidebar.js create mode 100644 ui/src/collections/emailTemplateAccordion.js create mode 100644 ui/src/collections/indexUpsertModal.js create mode 100644 ui/src/collections/mfaAccordion.js create mode 100644 ui/src/collections/oauth2/appleOptions.js create mode 100644 ui/src/collections/oauth2/larkOptions.js create mode 100644 ui/src/collections/oauth2/microsoftOptions.js create mode 100644 ui/src/collections/oauth2/oidcOptions.js create mode 100644 ui/src/collections/oauth2/selfhostOptions.js create mode 100644 ui/src/collections/oauth2Accordion.js create mode 100644 ui/src/collections/otpAccordion.js create mode 100644 ui/src/collections/pageCollections.js create mode 100644 ui/src/collections/passwordAuthAccordion.js create mode 100644 ui/src/collections/providerPickerModal.js create mode 100644 ui/src/collections/providerSettingsModal.js create mode 100644 ui/src/collections/tokenOptionsAccordion.js delete mode 100644 ui/src/components/PageIndex.svelte delete mode 100644 ui/src/components/base/Accordion.svelte delete mode 100644 ui/src/components/base/AutoExpandTextarea.svelte delete mode 100644 ui/src/components/base/AutocompleteInput.svelte delete mode 100644 ui/src/components/base/BaseSelectOption.svelte delete mode 100644 ui/src/components/base/CodeBlock.svelte delete mode 100644 ui/src/components/base/CodeEditor.svelte delete mode 100644 ui/src/components/base/Confirmation.svelte delete mode 100644 ui/src/components/base/CopyIcon.svelte delete mode 100644 ui/src/components/base/Draggable.svelte delete mode 100644 ui/src/components/base/Dragline.svelte delete mode 100644 ui/src/components/base/DynamicOptionsSelect.svelte delete mode 100644 ui/src/components/base/Field.svelte delete mode 100644 ui/src/components/base/FilterAutocompleteInput.svelte delete mode 100644 ui/src/components/base/FormattedDate.svelte delete mode 100644 ui/src/components/base/FullPage.svelte delete mode 100644 ui/src/components/base/InitialsAvatar.svelte delete mode 100644 ui/src/components/base/Leaflet.svelte delete mode 100644 ui/src/components/base/MimeTypeSelectOption.svelte delete mode 100644 ui/src/components/base/MultipleValueInput.svelte delete mode 100644 ui/src/components/base/ObjectSelect.svelte delete mode 100644 ui/src/components/base/OverlayPanel.svelte delete mode 100644 ui/src/components/base/PageInstaller.svelte delete mode 100644 ui/src/components/base/PageSidebar.svelte delete mode 100644 ui/src/components/base/PageWrapper.svelte delete mode 100644 ui/src/components/base/PreviewPopup.svelte delete mode 100644 ui/src/components/base/RedactedPasswordInput.svelte delete mode 100644 ui/src/components/base/RefreshButton.svelte delete mode 100644 ui/src/components/base/Scroller.svelte delete mode 100644 ui/src/components/base/SdkTabs.svelte delete mode 100644 ui/src/components/base/Searchbar.svelte delete mode 100644 ui/src/components/base/SecretGeneratorButton.svelte delete mode 100644 ui/src/components/base/Select.svelte delete mode 100644 ui/src/components/base/SortHeader.svelte delete mode 100644 ui/src/components/base/TinyMCE.svelte delete mode 100644 ui/src/components/base/Toasts.svelte delete mode 100644 ui/src/components/base/Toggler.svelte delete mode 100644 ui/src/components/base/UploadedFilePreview.svelte delete mode 100644 ui/src/components/collections/CollectionAuthOptionsTab.svelte delete mode 100644 ui/src/components/collections/CollectionDocsPanel.svelte delete mode 100644 ui/src/components/collections/CollectionFieldsTab.svelte delete mode 100644 ui/src/components/collections/CollectionQueryTab.svelte delete mode 100644 ui/src/components/collections/CollectionRulesTab.svelte delete mode 100644 ui/src/components/collections/CollectionSidebarItem.svelte delete mode 100644 ui/src/components/collections/CollectionUpdateConfirm.svelte delete mode 100644 ui/src/components/collections/CollectionUpsertPanel.svelte delete mode 100644 ui/src/components/collections/CollectionsDiffTable.svelte delete mode 100644 ui/src/components/collections/CollectionsSidebar.svelte delete mode 100644 ui/src/components/collections/EmailTemplateAccordion.svelte delete mode 100644 ui/src/components/collections/IndexUpsertPanel.svelte delete mode 100644 ui/src/components/collections/IndexesList.svelte delete mode 100644 ui/src/components/collections/MFAAccordion.svelte delete mode 100644 ui/src/components/collections/OAuth2Accordion.svelte delete mode 100644 ui/src/components/collections/OAuth2ProviderPanel.svelte delete mode 100644 ui/src/components/collections/OAuth2ProvidersListPanel.svelte delete mode 100644 ui/src/components/collections/OTPAccordion.svelte delete mode 100644 ui/src/components/collections/PasswordAuthAccordion.svelte delete mode 100644 ui/src/components/collections/RuleField.svelte delete mode 100644 ui/src/components/collections/TokenField.svelte delete mode 100644 ui/src/components/collections/TokenOptionsAccordion.svelte delete mode 100644 ui/src/components/collections/docs/AuthMethodsDocs.svelte delete mode 100644 ui/src/components/collections/docs/AuthRefreshDocs.svelte delete mode 100644 ui/src/components/collections/docs/AuthWithOAuth2Docs.svelte delete mode 100644 ui/src/components/collections/docs/AuthWithOtpApiAuthDocs.svelte delete mode 100644 ui/src/components/collections/docs/AuthWithOtpApiRequestDocs.svelte delete mode 100644 ui/src/components/collections/docs/AuthWithOtpDocs.svelte delete mode 100644 ui/src/components/collections/docs/AuthWithPasswordDocs.svelte delete mode 100644 ui/src/components/collections/docs/BatchApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/CreateApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/DeleteApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/EmailChangeApiConfirmDocs.svelte delete mode 100644 ui/src/components/collections/docs/EmailChangeApiRequestDocs.svelte delete mode 100644 ui/src/components/collections/docs/EmailChangeDocs.svelte delete mode 100644 ui/src/components/collections/docs/FieldsQueryParam.svelte delete mode 100644 ui/src/components/collections/docs/FilterSyntax.svelte delete mode 100644 ui/src/components/collections/docs/ListApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/PasswordResetApiConfirmDocs.svelte delete mode 100644 ui/src/components/collections/docs/PasswordResetApiRequestDocs.svelte delete mode 100644 ui/src/components/collections/docs/PasswordResetDocs.svelte delete mode 100644 ui/src/components/collections/docs/RealtimeApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/UpdateApiDocs.svelte delete mode 100644 ui/src/components/collections/docs/VerificationApiConfirmDocs.svelte delete mode 100644 ui/src/components/collections/docs/VerificationApiRequestDocs.svelte delete mode 100644 ui/src/components/collections/docs/VerificationDocs.svelte delete mode 100644 ui/src/components/collections/docs/ViewApiDocs.svelte delete mode 100644 ui/src/components/collections/providers/AppleOptions.svelte delete mode 100644 ui/src/components/collections/providers/AppleSecretPopup.svelte delete mode 100644 ui/src/components/collections/providers/LarkOptions.svelte delete mode 100644 ui/src/components/collections/providers/MicrosoftOptions.svelte delete mode 100644 ui/src/components/collections/providers/OIDCOptions.svelte delete mode 100644 ui/src/components/collections/providers/SelfHostedOptions.svelte delete mode 100644 ui/src/components/collections/schema/NewField.svelte delete mode 100644 ui/src/components/collections/schema/SchemaField.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldAutodate.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldBool.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldDate.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldEditor.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldEmail.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldFile.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldGeoPoint.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldJson.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldNumber.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldPassword.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldRelation.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldSelect.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldText.svelte delete mode 100644 ui/src/components/collections/schema/SchemaFieldUrl.svelte delete mode 100644 ui/src/components/logs/LogDate.svelte delete mode 100644 ui/src/components/logs/LogLevel.svelte delete mode 100644 ui/src/components/logs/LogViewPanel.svelte delete mode 100644 ui/src/components/logs/LogsChart.svelte delete mode 100644 ui/src/components/logs/LogsLevelsInfo.svelte delete mode 100644 ui/src/components/logs/LogsList.svelte delete mode 100644 ui/src/components/logs/LogsSettingsPanel.svelte delete mode 100644 ui/src/components/logs/PageLogs.svelte delete mode 100644 ui/src/components/records/AutodateIcon.svelte delete mode 100644 ui/src/components/records/ExternalAuthsList.svelte delete mode 100644 ui/src/components/records/ImpersonatePopup.svelte delete mode 100644 ui/src/components/records/PageOAuth2RedirectFailure.svelte delete mode 100644 ui/src/components/records/PageOAuth2RedirectSuccess.svelte delete mode 100644 ui/src/components/records/PageRecordConfirmEmailChange.svelte delete mode 100644 ui/src/components/records/PageRecordConfirmPasswordReset.svelte delete mode 100644 ui/src/components/records/PageRecordConfirmVerification.svelte delete mode 100644 ui/src/components/records/PageRecords.svelte delete mode 100644 ui/src/components/records/RecordFieldValue.svelte delete mode 100644 ui/src/components/records/RecordFilePicker.svelte delete mode 100644 ui/src/components/records/RecordFileThumb.svelte delete mode 100644 ui/src/components/records/RecordInfo.svelte delete mode 100644 ui/src/components/records/RecordInfoContent.svelte delete mode 100644 ui/src/components/records/RecordPreviewPanel.svelte delete mode 100644 ui/src/components/records/RecordUpsertPanel.svelte delete mode 100644 ui/src/components/records/RecordsCount.svelte delete mode 100644 ui/src/components/records/RecordsList.svelte delete mode 100644 ui/src/components/records/RecordsPicker.svelte delete mode 100644 ui/src/components/records/fields/AuthFields.svelte delete mode 100644 ui/src/components/records/fields/BoolField.svelte delete mode 100644 ui/src/components/records/fields/DateField.svelte delete mode 100644 ui/src/components/records/fields/EditorField.svelte delete mode 100644 ui/src/components/records/fields/EmailField.svelte delete mode 100644 ui/src/components/records/fields/FieldLabel.svelte delete mode 100644 ui/src/components/records/fields/FileField.svelte delete mode 100644 ui/src/components/records/fields/GeoPointField.svelte delete mode 100644 ui/src/components/records/fields/GeoPointValue.svelte delete mode 100644 ui/src/components/records/fields/JsonField.svelte delete mode 100644 ui/src/components/records/fields/NumberField.svelte delete mode 100644 ui/src/components/records/fields/PasswordField.svelte delete mode 100644 ui/src/components/records/fields/RelationField.svelte delete mode 100644 ui/src/components/records/fields/SelectField.svelte delete mode 100644 ui/src/components/records/fields/TextField.svelte delete mode 100644 ui/src/components/records/fields/UrlField.svelte delete mode 100644 ui/src/components/settings/BackupCreatePanel.svelte delete mode 100644 ui/src/components/settings/BackupRestorePanel.svelte delete mode 100644 ui/src/components/settings/BackupUploadButton.svelte delete mode 100644 ui/src/components/settings/BackupsList.svelte delete mode 100644 ui/src/components/settings/BatchAccordion.svelte delete mode 100644 ui/src/components/settings/EmailTestPopup.svelte delete mode 100644 ui/src/components/settings/ImportPopup.svelte delete mode 100644 ui/src/components/settings/PageApplication.svelte delete mode 100644 ui/src/components/settings/PageBackups.svelte delete mode 100644 ui/src/components/settings/PageCrons.svelte delete mode 100644 ui/src/components/settings/PageExportCollections.svelte delete mode 100644 ui/src/components/settings/PageImportCollections.svelte delete mode 100644 ui/src/components/settings/PageMail.svelte delete mode 100644 ui/src/components/settings/PageStorage.svelte delete mode 100644 ui/src/components/settings/RateLimitAccordion.svelte delete mode 100644 ui/src/components/settings/S3Fields.svelte delete mode 100644 ui/src/components/settings/SettingsSidebar.svelte delete mode 100644 ui/src/components/settings/TrustedProxyAccordion.svelte delete mode 100644 ui/src/components/superusers/PageSuperuserConfirmPasswordReset.svelte delete mode 100644 ui/src/components/superusers/PageSuperuserLogin.svelte delete mode 100644 ui/src/components/superusers/PageSuperuserRequestPasswordReset.svelte create mode 100644 ui/src/css/_main.css create mode 100644 ui/src/css/accordion.css create mode 100644 ui/src/css/animations.css create mode 100644 ui/src/css/apiPreviewModal.css create mode 100644 ui/src/css/base.css create mode 100644 ui/src/css/bulkbar.css create mode 100644 ui/src/css/collectionModal.css create mode 100644 ui/src/css/collectionsOverview.css create mode 100644 ui/src/css/colorPicker.css create mode 100644 ui/src/css/dropdown.css create mode 100644 ui/src/css/erd.css create mode 100644 ui/src/css/export.css create mode 100644 ui/src/css/fonts.css create mode 100644 ui/src/css/form.css create mode 100644 ui/src/css/grid.css create mode 100644 ui/src/css/hideControls.css create mode 100644 ui/src/css/layout.css create mode 100644 ui/src/css/list.css create mode 100644 ui/src/css/logs.css create mode 100644 ui/src/css/map.css create mode 100644 ui/src/css/modal.css create mode 100644 ui/src/css/prism.css create mode 100644 ui/src/css/providers.css create mode 100644 ui/src/css/ratelimit.css create mode 100644 ui/src/css/recordFields.css create mode 100644 ui/src/css/recordFilePicker.css create mode 100644 ui/src/css/recordSummary.css create mode 100644 ui/src/css/recordsPicker.css create mode 100644 ui/src/css/remixicon.css create mode 100644 ui/src/css/ruleField.css create mode 100644 ui/src/css/table.css create mode 100644 ui/src/css/tabs.css create mode 100644 ui/src/css/tinymce.css create mode 100644 ui/src/css/toast.css create mode 100644 ui/src/css/tooltip.css create mode 100644 ui/src/css/vars.css create mode 100644 ui/src/fields/autodate/init.js create mode 100644 ui/src/fields/autodate/onrecordduplicate.js create mode 100644 ui/src/fields/autodate/settings.js create mode 100644 ui/src/fields/autodate/view.js create mode 100644 ui/src/fields/bool/init.js create mode 100644 ui/src/fields/bool/input.js create mode 100644 ui/src/fields/bool/settings.js create mode 100644 ui/src/fields/bool/view.js create mode 100644 ui/src/fields/date/init.js create mode 100644 ui/src/fields/date/input.js create mode 100644 ui/src/fields/date/settings.js create mode 100644 ui/src/fields/date/view.js create mode 100644 ui/src/fields/editor/init.js create mode 100644 ui/src/fields/editor/input.js create mode 100644 ui/src/fields/editor/settings.js create mode 100644 ui/src/fields/editor/view.js create mode 100644 ui/src/fields/email/init.js create mode 100644 ui/src/fields/email/input.js create mode 100644 ui/src/fields/email/settings.js create mode 100644 ui/src/fields/email/view.js create mode 100644 ui/src/fields/file/init.js create mode 100644 ui/src/fields/file/input.js create mode 100644 ui/src/fields/file/onrecordduplicate.js create mode 100644 ui/src/fields/file/onrecordsave.js create mode 100644 ui/src/fields/file/settings.js create mode 100644 ui/src/fields/file/view.js create mode 100644 ui/src/fields/geoPoint/init.js create mode 100644 ui/src/fields/geoPoint/input.js create mode 100644 ui/src/fields/geoPoint/settings.js create mode 100644 ui/src/fields/geoPoint/view.js create mode 100644 ui/src/fields/json/init.js create mode 100644 ui/src/fields/json/input.js create mode 100644 ui/src/fields/json/onrecordsave.js create mode 100644 ui/src/fields/json/settings.js create mode 100644 ui/src/fields/json/view.js create mode 100644 ui/src/fields/number/init.js create mode 100644 ui/src/fields/number/input.js create mode 100644 ui/src/fields/number/settings.js create mode 100644 ui/src/fields/number/view.js create mode 100644 ui/src/fields/password/init.js create mode 100644 ui/src/fields/password/settings.js create mode 100644 ui/src/fields/relation/init.js create mode 100644 ui/src/fields/relation/input.js create mode 100644 ui/src/fields/relation/settings.js create mode 100644 ui/src/fields/relation/view.js create mode 100644 ui/src/fields/select/init.js create mode 100644 ui/src/fields/select/input.js create mode 100644 ui/src/fields/select/settings.js create mode 100644 ui/src/fields/select/view.js create mode 100644 ui/src/fields/text/init.js create mode 100644 ui/src/fields/text/input.js create mode 100644 ui/src/fields/text/settings.js create mode 100644 ui/src/fields/text/view.js create mode 100644 ui/src/fields/url/init.js create mode 100644 ui/src/fields/url/input.js create mode 100644 ui/src/fields/url/settings.js create mode 100644 ui/src/fields/url/view.js create mode 100644 ui/src/logs/defaultLogLevels.js create mode 100644 ui/src/logs/logLevel.js create mode 100644 ui/src/logs/logPreviewModal.js create mode 100644 ui/src/logs/logsChart.js create mode 100644 ui/src/logs/logsList.js create mode 100644 ui/src/logs/logsSettingsModal.js create mode 100644 ui/src/logs/pageLogs.js create mode 100644 ui/src/mimeTypes.js delete mode 100644 ui/src/mimes.js create mode 100644 ui/src/pb.js delete mode 100644 ui/src/providers.js create mode 100644 ui/src/records/recordFilePickerModal.js create mode 100644 ui/src/records/recordFileThumb.js create mode 100644 ui/src/records/recordImpersonateModal.js create mode 100644 ui/src/records/recordPreviewModal.js create mode 100644 ui/src/records/recordSummary.js create mode 100644 ui/src/records/recordUpsertModal.js create mode 100644 ui/src/records/recordsList.js create mode 100644 ui/src/records/recordsPickerModal.js create mode 100644 ui/src/records/recordsSearchbar.js create mode 100644 ui/src/router.js delete mode 100644 ui/src/routes.js delete mode 100644 ui/src/scss/_accordion.scss delete mode 100644 ui/src/scss/_alert.scss delete mode 100644 ui/src/scss/_animations.scss delete mode 100644 ui/src/scss/_base.scss delete mode 100644 ui/src/scss/_bulkbar.scss delete mode 100644 ui/src/scss/_collections_export.scss delete mode 100644 ui/src/scss/_docs_panel.scss delete mode 100644 ui/src/scss/_dropdown.scss delete mode 100644 ui/src/scss/_file_picker.scss delete mode 100644 ui/src/scss/_flatpickr.scss delete mode 100644 ui/src/scss/_fonts.scss delete mode 100644 ui/src/scss/_form.scss delete mode 100644 ui/src/scss/_grid.scss delete mode 100644 ui/src/scss/_icons.scss delete mode 100644 ui/src/scss/_layout.scss delete mode 100644 ui/src/scss/_mixins.scss delete mode 100644 ui/src/scss/_overlay_panel.scss delete mode 100644 ui/src/scss/_rate_limit.scss delete mode 100644 ui/src/scss/_reset.scss delete mode 100644 ui/src/scss/_schema_field.scss delete mode 100644 ui/src/scss/_searchbar.scss delete mode 100644 ui/src/scss/_table.scss delete mode 100644 ui/src/scss/_tabs.scss delete mode 100644 ui/src/scss/_tooltip.scss delete mode 100644 ui/src/scss/_vars.scss delete mode 100644 ui/src/scss/main.scss delete mode 100644 ui/src/scss/prism_light.scss create mode 100644 ui/src/settings/application/batchAccordion.js create mode 100644 ui/src/settings/application/pageApplicationSettings.js create mode 100644 ui/src/settings/application/rateLimitAccordion.js create mode 100644 ui/src/settings/application/rateLimitInfoModal.js create mode 100644 ui/src/settings/application/trustedProxyAccordion.js create mode 100644 ui/src/settings/backups/backupCreateModal.js create mode 100644 ui/src/settings/backups/backupRestoreModal.js create mode 100644 ui/src/settings/backups/backupUploadButton.js create mode 100644 ui/src/settings/backups/backupsForm.js create mode 100644 ui/src/settings/backups/backupsList.js create mode 100644 ui/src/settings/backups/pageBackupsSettings.js create mode 100644 ui/src/settings/crons/cronsList.js create mode 100644 ui/src/settings/crons/pageCronsSettings.js create mode 100644 ui/src/settings/mail/mailTestModal.js create mode 100644 ui/src/settings/mail/pageMailSettings.js create mode 100644 ui/src/settings/settingsSidebar.js create mode 100644 ui/src/settings/storage/pageStorageSettings.js create mode 100644 ui/src/settings/sync/collectionsDiffTable.js create mode 100644 ui/src/settings/sync/importCollectionsReviewModal.js create mode 100644 ui/src/settings/sync/pageExportCollections.js create mode 100644 ui/src/settings/sync/pageImportCollections.js create mode 100644 ui/src/store.js delete mode 100644 ui/src/stores/app.js delete mode 100644 ui/src/stores/collections.js delete mode 100644 ui/src/stores/confirmation.js delete mode 100644 ui/src/stores/errors.js delete mode 100644 ui/src/stores/superuser.js delete mode 100644 ui/src/stores/toasts.js create mode 100644 ui/src/utils.js delete mode 100644 ui/src/utils/ApiClient.js delete mode 100644 ui/src/utils/CommonHelper.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 06fe9287..8a79452a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## v0.37.0 (WIP) + +- @todo + + ## v0.36.9 - Updated the Discord `AuthUser.Name` field to use `global_name` ([#7603](https://github.com/pocketbase/pocketbase/pull/7603); thanks @HansHans135). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a0db7aaa..e5cae793 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,17 +1,20 @@ # Contributing to PocketBase -Thanks for taking the time to improve PocketBase! +> [!IMPORTANT] +> Due to recent LLM spam, PRs are temporary disabled and only existing collaborators can open a PR. +> If you stumble on an problem that you want to fix, please consider instead opening an issue or discussion with link to your fork _(if not obvious - LLM contributions are not welcome)_. +> This status may change in the future in case GitHub finally decide to do something about the constant spam, or when I find time to move the project somewhere else. This document describes how to prepare a PR for a change in the main repository. - [Prerequisites](#prerequisites) - [Making changes in the Go code](#making-changes-in-the-go-code) -- [Making changes in the Admin UI](#making-changes-in-the-admin-ui) +- [Making changes in the Superuser UI](#making-changes-in-the-admin-ui) ## Prerequisites - Go 1.25+ (for making changes in the Go code) -- Node 18+ (for making changes in the Admin UI) +- Node 24+ (for making changes in the Superuser UI) If you haven't already, you can fork the main repository and clone your fork so that you can work locally: @@ -34,7 +37,7 @@ So, let's assume that you already done some changes in the PocketBase Go code an 1. Navigate to `examples/base` 2. Run `go run main.go serve` -This will start a web server on `http://localhost:8090` with the embedded prebuilt Admin UI from `ui/dist`. And that's it! +This will start a web server on `http://localhost:8090` with the embedded prebuilt Superuser UI from `ui/dist`. And that's it! **Before making a PR to the main repository, it is a good idea to:** @@ -57,11 +60,11 @@ This will start a web server on `http://localhost:8090` with the embedded prebui make lint ``` -## Making changes in the Admin UI +## Making changes in the Superuser UI -PocketBase Admin UI is a single-page application (SPA) built with Svelte and Vite. +PocketBase Superuser UI is a single-page application (SPA) built with Svelte and Vite. -To start the Admin UI: +To start the Superuser UI: 1. Navigate to the `ui` project directory 2. Run `npm install` to install the node dependencies @@ -70,13 +73,13 @@ To start the Admin UI: npm run dev ``` -You could open the browser and access the running Admin UI at `http://localhost:3000`. +You could open the browser and access the running Superuser UI at `http://localhost:5173`. -Since the Admin UI is just a client-side application, you need to have the PocketBase backend server also running in the background (either manually running the `examples/base/main.go` or download a prebuilt executable). +Since the Superuser UI is just a client-side application, you need to have the PocketBase backend server also running in the background (either manually running the `examples/base/main.go` or download a prebuilt executable). > [!NOTE] -> By default, the Admin UI is expecting the backend server to be started at `http://localhost:8090`, but you could change that by creating a new `ui/.env.development.local` file with `PB_BACKEND_URL = YOUR_ADDRESS` variable inside it. +> By default, the Superuser UI is expecting the backend server to be started at `http://localhost:8090`, but you could change that by creating a new `ui/.env.development.local` file with `PB_BACKEND_URL = YOUR_ADDRESS` variable inside it. -Every change you make in the Admin UI should be automatically reflected in the browser at `http://localhost:3000` without reloading the page. +Every change you make in the Superuser UI should be automatically reflected in the browser at `http://localhost:5173` without reloading the page. -Once you are done with your changes, you have to build the Admin UI with `npm run build`, so that it can be embedded in the go package. And that's it - you can make your PR to the main PocketBase repository. +Once you are done with your changes, you have to build the Superuser UI with `npm run build`, so that it can be embedded in the go package. And that's it - you can make your PR to the main PocketBase repository. diff --git a/README.md b/README.md index 913dfcb3..b274c625 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- PocketBase - open source backend in 1 file + PocketBase - open source backend in 1 file

@@ -146,10 +146,13 @@ You could help continuing its development by: - [Contribute to the source code](CONTRIBUTING.md) - [Suggest new features and report issues](https://github.com/pocketbase/pocketbase/issues) -PRs for new OAuth2 providers, bug fixes, code optimizations and documentation improvements are more than welcome. - -But please refrain creating PRs for _new features_ without previously discussing the implementation details. +Please refrain creating PRs for _new features_ without previously discussing the implementation details. PocketBase has a [roadmap](https://github.com/orgs/pocketbase/projects/2) and I try to work on issues in specific order and such PRs often come in out of nowhere and skew all initial planning with tedious back-and-forth communication. Don't get upset if I close your PR, even if it is well executed and tested. This doesn't mean that it will never be merged. Later we can always refer to it and/or take pieces of your implementation when the time comes to work on the issue (don't worry you'll be credited in the release notes). + +> [!IMPORTANT] +> Due to recent LLM spam, PRs are temporary disabled and only existing collaborators can open a PR. +> If you stumble on an problem that you want to fix, please consider instead opening an issue or discussion with link to your fork _(if not obvious - LLM contributions are not welcome)_. +> This status may change in the future in case GitHub finally decide to do something about the constant spam, or when I find time to move the project somewhere else. diff --git a/apis/base.go b/apis/base.go index 750b4d0b..c57075d4 100644 --- a/apis/base.go +++ b/apis/base.go @@ -15,7 +15,7 @@ import ( // StaticWildcardParam is the name of Static handler wildcard parameter. const StaticWildcardParam = "path" -// NewRouter returns a new router instance loaded with the default app middlewares and api routes. +// NewRouter returns a new router instance loaded with the default app middlewares and routes. func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) { pbRouter := router.NewRouter(func(w http.ResponseWriter, r *http.Request) (*core.RequestEvent, router.EventCleanupFunc) { event := new(core.RequestEvent) @@ -34,6 +34,7 @@ func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) { pbRouter.Bind(securityHeaders()) pbRouter.Bind(BodyLimit(DefaultMaxBodySize)) + // API routes apiGroup := pbRouter.Group("/api") bindSettingsApi(app, apiGroup) bindCollectionApi(app, apiGroup) @@ -47,6 +48,9 @@ func NewRouter(app core.App) (*router.Router[*core.RequestEvent], error) { bindRealtimeApi(app, apiGroup) bindHealthApi(app, apiGroup) + // UI routes + bindUIExtensions(app) + return pbRouter, nil } diff --git a/apis/collection.go b/apis/collection.go index baa24fe7..cfea38ff 100644 --- a/apis/collection.go +++ b/apis/collection.go @@ -3,10 +3,12 @@ package apis import ( "errors" "net/http" + "slices" "strings" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/auth" "github.com/pocketbase/pocketbase/tools/router" "github.com/pocketbase/pocketbase/tools/search" "github.com/pocketbase/pocketbase/tools/security" @@ -23,6 +25,10 @@ func bindCollectionApi(app core.App, rg *router.RouterGroup[*core.RequestEvent]) subGroup.DELETE("/{collection}/truncate", collectionTruncate) subGroup.PUT("/import", collectionsImport) subGroup.GET("/meta/scaffolds", collectionScaffolds) + + // @todo experimental + subGroup.GET("/meta/oauth2-providers", collectionListOAuth2Providers) + subGroup.POST("/meta/dry-run-view", collectionDryRunView) } func collectionsList(e *core.RequestEvent) error { @@ -207,3 +213,84 @@ func collectionScaffolds(e *core.RequestEvent) error { return e.JSON(http.StatusOK, collections) } + +type providerListItem struct { + order int + + Name string `json:"name"` + DisplayName string `json:"displayName"` + Logo string `json:"logo"` +} + +func collectionListOAuth2Providers(e *core.RequestEvent) error { + providers := make([]*providerListItem, 0, len(auth.Providers)) + + for name, factory := range auth.Providers { + p := factory() + + providers = append(providers, &providerListItem{ + order: p.Order(), + Name: name, + DisplayName: p.DisplayName(), + Logo: p.Logo(), + }) + } + + slices.SortStableFunc(providers, func(a, b *providerListItem) int { + // sort by order + if a.order < b.order { + return -1 + } + if a.order > b.order { + return 1 + } + + // fallback sort by name + if a.Name < b.Name { + return -1 + } + if a.Name > b.Name { + return 1 + } + + return 0 + }) + + return e.JSON(http.StatusOK, providers) +} + +func collectionDryRunView(e *core.RequestEvent) error { + // extra precaution in case reused in custom route group + if !e.HasSuperuserAuth() { + return e.ForbiddenError("", nil) + } + + form := dryRunViewForm{} + + err := e.BindBody(&form) + if err != nil { + return firstApiError(err, e.BadRequestError("An error occurred while loading the submitted data.", err)) + } + + err = form.validate() + if err != nil { + return firstApiError(err, e.BadRequestError("An error occurred while validating the submitted data.", err)) + } + + result, err := e.App.DryRunView(form.Query, 10) + if err != nil { + return firstApiError(err, e.BadRequestError("Invalid view query. Raw error: \n"+err.Error(), nil)) + } + + return e.JSON(http.StatusOK, result) +} + +type dryRunViewForm struct { + Query string `form:"query" json:"query"` +} + +func (form *dryRunViewForm) validate() error { + return validation.ValidateStruct(form, + validation.Field(&form.Query, validation.Required, validation.Length(0, 5000)), + ) +} diff --git a/apis/collection_test.go b/apis/collection_test.go index 8d74f750..27051826 100644 --- a/apis/collection_test.go +++ b/apis/collection_test.go @@ -536,7 +536,7 @@ func TestCollectionCreate(t *testing.T) { `"type":"base"`, `"system":false`, // ensures that id field was prepended - `"fields":[{"autogeneratePattern":"[a-z0-9]{15}","hidden":false,"id":"text3208210256","max":15,"min":15,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"},{"autogeneratePattern":"","hidden":false,"id":"12345789","max":0,"min":0,"name":"test","pattern":"","presentable":false,"primaryKey":false,"required":false,"system":false,"type":"text"}]`, + `"fields":[{"autogeneratePattern":"[a-z0-9]{15}","help":"","hidden":false,"id":"text3208210256","max":15,"min":15,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"},{"autogeneratePattern":"","help":"","hidden":false,"id":"12345789","max":0,"min":0,"name":"test","pattern":"","presentable":false,"primaryKey":false,"required":false,"system":false,"type":"text"}]`, }, ExpectedEvents: map[string]int{ "*": 0, @@ -585,7 +585,7 @@ func TestCollectionCreate(t *testing.T) { `"name":"verified"`, `"duration":123`, // should overwrite the user required option but keep the min value - `{"autogeneratePattern":"","hidden":true,"id":"text2504183744","max":0,"min":10,"name":"tokenKey","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":true,"type":"text"}`, + `{"autogeneratePattern":"","help":"","hidden":true,"id":"text2504183744","max":0,"min":10,"name":"tokenKey","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":true,"type":"text"}`, }, NotExpectedContent: []string{ `"secret":"`, @@ -751,7 +751,7 @@ func TestCollectionCreate(t *testing.T) { "name":"new", "type":"view", "fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}], - "viewQuery":"invalid" + "viewQuery":"select '123' as abc" }`), Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", @@ -780,7 +780,7 @@ func TestCollectionCreate(t *testing.T) { "name":"new", "type":"view", "fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}], - "viewQuery": "select 1 as id from ` + core.CollectionNameSuperusers + `" + "viewQuery": "select 1 as id from ` + core.CollectionNameSuperusers + ` limit 1" }`), Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", @@ -789,7 +789,7 @@ func TestCollectionCreate(t *testing.T) { ExpectedContent: []string{ `"name":"new"`, `"type":"view"`, - `"fields":[{"autogeneratePattern":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`, + `"fields":[{"autogeneratePattern":"","help":"","hidden":false,"id":"text3208210256","max":0,"min":0,"name":"id","pattern":"^[a-z0-9]+$","presentable":false,"primaryKey":true,"required":true,"system":true,"type":"text"}]`, }, ExpectedEvents: map[string]int{ "*": 0, @@ -1262,7 +1262,7 @@ func TestCollectionUpdate(t *testing.T) { Body: strings.NewReader(`{ "name":"view2_update", "fields":[{"type":"text","id":"12345789","name":"ignored!@#$"}], - "viewQuery": "select 2 as id, created, updated, email from ` + core.CollectionNameSuperusers + `" + "viewQuery": "select 2 as id, created, updated, email from ` + core.CollectionNameSuperusers + ` limit 1" }`), Headers: map[string]string{ "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", @@ -1584,3 +1584,187 @@ func TestCollectionTruncate(t *testing.T) { scenario.Test(t) } } + +func TestCollectionOAuth2Providers(t *testing.T) { + t.Parallel() + + scenarios := []tests.ApiScenario{ + { + Name: "unauthorized", + Method: http.MethodGet, + URL: "/api/collections/meta/oauth2-providers", + ExpectedStatus: 401, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "authorized as regular user", + Method: http.MethodGet, + URL: "/api/collections/meta/oauth2-providers", + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo", + }, + ExpectedStatus: 403, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "authorized as superuser", + Method: http.MethodGet, + URL: "/api/collections/meta/oauth2-providers", + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 200, + ExpectedContent: []string{ + `{"name":"oidc3","displayName":"OIDC","logo":"\u003csvg`, + }, + NotExpectedContent: []string{ + `"order":`, + `"pkce":`, + `"scopes":`, + `"authURL":`, + `"tokenURL":`, + `"userInfoURL":`, + }, + }, + } + + for _, scenario := range scenarios { + scenario.Test(t) + } +} + +func TestCollectionTestView(t *testing.T) { + t.Parallel() + + scenarios := []tests.ApiScenario{ + { + Name: "unauthorized", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"select 1 as id"}`), + ExpectedStatus: 401, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "authorized as regular user", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"select 1 as id"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjRxMXhsY2xtZmxva3UzMyIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoiX3BiX3VzZXJzX2F1dGhfIiwiZXhwIjoyNTI0NjA0NDYxLCJyZWZyZXNoYWJsZSI6dHJ1ZX0.ZT3F0Z3iM-xbGgSG3LEKiEzHrPHr8t8IuHLZGGNuxLo", + }, + ExpectedStatus: 403, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "authorized as superuser", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"select 1 as id"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 200, + ExpectedContent: []string{ + `"fields":[{`, + `"name":"id"`, + `"type":"text"`, + `"sample":[{`, + `"id":"1"`, + }, + }, + { + Name: "empty query", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":""}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 400, + ExpectedContent: []string{ + `"data":{"query":`, + }, + }, + { + Name: "query length beyond validator limit", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"` + strings.Repeat("a", 5001) + `"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 400, + ExpectedContent: []string{ + `"data":{"query":`, + }, + }, + { + Name: "query with length equal to the validator limit", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"select 1 as id` + strings.Repeat(" ", 4986) + `"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 200, + ExpectedContent: []string{ + `"fields":[{`, + `"name":"id"`, + `"type":"text"`, + `"sample":[`, + `"id":"1"`, + }, + }, + { + Name: "missing ids sample", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"(select 1 as id union select '' as id)"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 400, + ExpectedContent: []string{ + `"data":{}`, + `Raw error:`, + }, + }, + { + Name: "duplicated ids sample", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"(select 1 as id union all select 1 as id)"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 400, + ExpectedContent: []string{ + `"data":{}`, + `Raw error:`, + }, + }, + { + Name: "write query", + Method: http.MethodPost, + URL: "/api/collections/meta/dry-run-view", + Body: strings.NewReader(`{"query":"CREATE TABLE t1(x INT)"}`), + Headers: map[string]string{ + "Authorization": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6InN5d2JoZWNuaDQ2cmhtMCIsInR5cGUiOiJhdXRoIiwiY29sbGVjdGlvbklkIjoicGJjXzMxNDI2MzU4MjMiLCJleHAiOjI1MjQ2MDQ0NjEsInJlZnJlc2hhYmxlIjp0cnVlfQ.UXgO3j-0BumcugrFjbd7j0M4MQvbrLggLlcu_YNGjoY", + }, + ExpectedStatus: 400, + ExpectedContent: []string{ + `"data":{}`, + `Raw error:`, + }, + }, + } + + for _, scenario := range scenarios { + scenario.Test(t) + } +} diff --git a/apis/extensions.go b/apis/extensions.go new file mode 100644 index 00000000..b230bce7 --- /dev/null +++ b/apis/extensions.go @@ -0,0 +1,94 @@ +package apis + +import ( + "bytes" + "errors" + "fmt" + "io" + "log/slog" + "os" + + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tools/hook" + "github.com/pocketbase/pocketbase/ui" +) + +// bindUIExtensions binds the superuser UI extensions routes to the ServeEvent.Router. +// +// This method does nothing if the superuser UI is not bundled (aka. build with "no_ui" tag), +func bindUIExtensions(app core.App) { + if ui.DistDirFS == nil { + return + } + + app.OnServe().Bind(&hook.Handler[*core.ServeEvent]{ + Priority: 9999, // execute as latest as possible + Func: func(se *core.ServeEvent) error { + uiGroup := se.Router.Group("/_"). + BindFunc(func(e *core.RequestEvent) error { + if !e.App.IsDev() && e.Response.Header().Get("Cache-Control") == "" { + e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400") + } + + if e.Response.Header().Get("Content-Security-Policy") == "" { + e.Response.Header().Set("Content-Security-Policy", defaultCSP) + } + + return e.Next() + }). + Bind(Gzip()) + + // register static extension routes + for _, ext := range se.UIExtensions { + if ext.Name == "" || ext.FS == nil { + se.App.Logger().Debug("Invalid UI extension configuration", slog.Any("extension", ext)) + continue + } + + uiGroup.GET("/extensions/"+ext.Name+"/{path...}", Static(ext.FS, false)) + } + + // combine all extensions main.js in one file + // + // note: don't cache in memory to allow previewing changes without restart + uiGroup.GET("/extensions.js", func(re *core.RequestEvent) error { + buf := new(bytes.Buffer) + + for _, ext := range se.UIExtensions { + err := copyExtensionMainjs(buf, ext) + if err != nil { + return re.InternalServerError("An error occurred while generating the main.js extension file", err) + } + } + + return re.Stream(200, "text/javascript", buf) + }).Bind(SkipSuccessActivityLog()) + + return se.Next() + }, + }) +} + +func copyExtensionMainjs(buf *bytes.Buffer, ext core.UIExtension) error { + f, err := ext.FS.Open("main.js") + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil // nothing to copy + } + + return fmt.Errorf("[UI extension %q] main.js open error: %w", ext.Name, err) + } + defer f.Close() + + // wrap in a self-executing function to avoid scope and concatenation issues + _, _ = buf.WriteString("(function(){") + + _, err = io.Copy(buf, f) + if err != nil { + return fmt.Errorf("[UI extension %q] main.js copy error: %w", ext.Name, err) + } + + _, _ = buf.WriteString("})();") + + return nil +} diff --git a/apis/extensions_test.go b/apis/extensions_test.go new file mode 100644 index 00000000..b292a2d3 --- /dev/null +++ b/apis/extensions_test.go @@ -0,0 +1,177 @@ +package apis_test + +import ( + "net/http" + "testing" + "testing/fstest" + + "github.com/pocketbase/pocketbase/core" + "github.com/pocketbase/pocketbase/tests" + "github.com/pocketbase/pocketbase/ui" +) + +// note: don't run in parallel to avoid conflicts with the ui.DistDirFS nil test +func TestUIExtensions_Mainjs(t *testing.T) { + successAfterTestFunc := func(t testing.TB, app *tests.TestApp, res *http.Response) { + expected := "text/javascript" + if ct := res.Header.Get("content-type"); ct != expected { + t.Fatalf("Expected response Content-Type %q, got %q", expected, ct) + } + } + + oldDistDirFS := ui.DistDirFS + + scenarios := []tests.ApiScenario{ + { + Name: "disabled UI", + Method: http.MethodGet, + URL: "/_/extensions.js", + TestAppFactory: func(t testing.TB) *tests.TestApp { + app, err := tests.NewTestApp() + if err != nil { + t.Fatal(err) + } + + // simulate no_ui tag (needs to be cleared before the router is initialized) + ui.DistDirFS = nil + + return app + }, + AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) { + ui.DistDirFS = oldDistDirFS + }, + ExpectedStatus: 404, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "no extensions", + Method: http.MethodGet, + URL: "/_/extensions.js", + AfterTestFunc: successAfterTestFunc, + ExpectedStatus: 200, + ExpectedContent: []string{}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "with extensions", + Method: http.MethodGet, + URL: "/_/extensions.js", + TestAppFactory: func(t testing.TB) *tests.TestApp { + app, err := tests.NewTestApp() + if err != nil { + t.Fatal(err) + } + + app.OnServe().BindFunc(func(e *core.ServeEvent) error { + e.UIExtensions = createTestExtensions() + return e.Next() + }) + + return app + }, + AfterTestFunc: successAfterTestFunc, + ExpectedStatus: 200, + ExpectedContent: []string{"(function(){ext1_main})();(function(){ext3_main})();"}, + ExpectedEvents: map[string]int{"*": 0}, + }, + } + + for _, scenario := range scenarios { + scenario.Test(t) + } +} + +// note: don't run in parallel to avoid conflicts with the ui.DistDirFS nil test +func TestUIExtensions_Files(t *testing.T) { + testAppFactory := func(t testing.TB) *tests.TestApp { + app, err := tests.NewTestApp() + if err != nil { + t.Fatal(err) + } + + app.OnServe().BindFunc(func(e *core.ServeEvent) error { + e.UIExtensions = createTestExtensions() + return e.Next() + }) + + return app + } + + scenarios := []tests.ApiScenario{ + { + Name: "no extensions", + Method: http.MethodGet, + URL: "/_/extensions/ext1/test.txt", + ExpectedStatus: 404, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "with missing extension file", + Method: http.MethodGet, + URL: "/_/extensions/ext1/missing", + TestAppFactory: testAppFactory, + ExpectedStatus: 404, + ExpectedContent: []string{`"data":{}`}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "with existing extension file (ext1)", + Method: http.MethodGet, + URL: "/_/extensions/ext1/test.txt", + TestAppFactory: testAppFactory, + ExpectedStatus: 200, + ExpectedContent: []string{"ext1_txt"}, + ExpectedEvents: map[string]int{"*": 0}, + }, + { + Name: "with existing extension file (extension name escape)", + Method: http.MethodGet, + URL: "/_/extensions/ext3%20with%20spaces/test.txt", + TestAppFactory: testAppFactory, + ExpectedStatus: 200, + ExpectedContent: []string{"ext3_txt"}, + ExpectedEvents: map[string]int{"*": 0}, + }, + } + + for _, scenario := range scenarios { + scenario.Test(t) + } +} + +func createTestExtensions() []core.UIExtension { + return []core.UIExtension{ + { + Name: "ext1", + FS: fstest.MapFS{ + "main.js": &fstest.MapFile{ + Data: []byte("ext1_main"), + }, + "test.txt": &fstest.MapFile{ + Data: []byte("ext1_txt"), + }, + }, + }, + { + Name: "ext2", + FS: fstest.MapFS{ + "test.txt": &fstest.MapFile{ + Data: []byte("ext2_txt"), + }, + }, + }, + { + Name: "ext3 with spaces", + FS: fstest.MapFS{ + "main.js": &fstest.MapFile{ + Data: []byte("ext3_main"), + }, + "test.txt": &fstest.MapFile{ + Data: []byte("ext3_txt"), + }, + }, + }, + } +} diff --git a/apis/health.go b/apis/health.go index 5b13b429..aa438070 100644 --- a/apis/health.go +++ b/apis/health.go @@ -25,6 +25,7 @@ func healthCheck(e *core.RequestEvent) error { Message: "API is healthy.", } + // @todo evaluate whether it is worth removing the extra info from the health endpoint if e.HasSuperuserAuth() { resp.Data = make(map[string]any, 3) resp.Data["canBackup"] = !e.App.Store().Has(core.StoreKeyActiveBackup) diff --git a/apis/installer.go b/apis/installer.go index 72405808..7085525f 100644 --- a/apis/installer.go +++ b/apis/installer.go @@ -12,6 +12,7 @@ import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/osutils" + "github.com/pocketbase/pocketbase/ui" ) // DefaultInstallerFunc is the default PocketBase installer function. @@ -22,13 +23,18 @@ import ( // // See https://github.com/pocketbase/pocketbase/discussions/5814. func DefaultInstallerFunc(app core.App, systemSuperuser *core.Record, baseURL string) error { + if ui.DistDirFS == nil { + color.Magenta("You can create your first superuser by running: %s superuser upsert EMAIL PASS", executablePath()) + return nil + } + token, err := systemSuperuser.NewStaticAuthToken(30 * time.Minute) if err != nil { return err } // launch url (ignore errors and always print a help text as fallback) - url := fmt.Sprintf("%s/_/#/pbinstal/%s", strings.TrimRight(baseURL, "/"), token) + url := fmt.Sprintf("%s/_/#/pbinstall/%s", strings.TrimRight(baseURL, "/"), token) _ = osutils.LaunchURL(url) color.Magenta("\n(!) Launch the URL below in the browser if it hasn't been open already to create your first superuser account:") color.New(color.Bold).Add(color.FgCyan).Println(url) diff --git a/apis/middlewares_body_limit.go b/apis/middlewares_body_limit.go index d2a16e0b..b02f0f65 100644 --- a/apis/middlewares_body_limit.go +++ b/apis/middlewares_body_limit.go @@ -11,7 +11,7 @@ import ( var ErrRequestEntityTooLarge = router.NewApiError(http.StatusRequestEntityTooLarge, "Request entity too large", nil) -const DefaultMaxBodySize int64 = 32 << 20 +const DefaultMaxBodySize int64 = 32 << 20 // @todo consider replacing with router.DefaultMaxMemory const ( DefaultBodyLimitMiddlewareId = "pbBodyLimit" diff --git a/apis/record_auth_methods.go b/apis/record_auth_methods.go index df39d662..1cb59cfd 100644 --- a/apis/record_auth_methods.go +++ b/apis/record_auth_methods.go @@ -34,6 +34,7 @@ type oauth2Response struct { type providerInfo struct { Name string `json:"name"` DisplayName string `json:"displayName"` + Logo string `json:"logo"` State string `json:"state"` AuthURL string `json:"authURL"` @@ -68,7 +69,14 @@ func (amr *authMethodsResponse) fillLegacyFields() { amr.UsernamePassword = amr.Password.Enabled && slices.Contains(amr.Password.IdentityFields, "username") if amr.OAuth2.Enabled { - amr.AuthProviders = amr.OAuth2.Providers + // clone without the logo + legacyProviders := make([]providerInfo, len(amr.OAuth2.Providers)) + for i, p := range amr.OAuth2.Providers { + legacyProviders[i] = p + legacyProviders[i].Logo = "" + } + + amr.AuthProviders = legacyProviders } } @@ -128,6 +136,7 @@ func recordAuthMethods(e *core.RequestEvent) error { info := providerInfo{ Name: config.Name, DisplayName: provider.DisplayName(), + Logo: provider.Logo(), State: security.RandomString(30), } diff --git a/apis/record_auth_methods_test.go b/apis/record_auth_methods_test.go index ec624681..0ea1bd67 100644 --- a/apis/record_auth_methods_test.go +++ b/apis/record_auth_methods_test.go @@ -54,6 +54,8 @@ func TestRecordAuthMethodsList(t *testing.T) { `"providers":[{`, `"name":"google"`, `"name":"gitlab"`, + `"logo":"\u003csvg`, + `"logo":""`, // for the legacy fields `"state":`, `"displayName":`, `"codeVerifier":`, diff --git a/apis/record_auth_with_oauth2_redirect.go b/apis/record_auth_with_oauth2_redirect.go index c4ac4583..c2c73c7d 100644 --- a/apis/record_auth_with_oauth2_redirect.go +++ b/apis/record_auth_with_oauth2_redirect.go @@ -9,6 +9,7 @@ import ( "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/subscriptions" + "github.com/pocketbase/pocketbase/ui" ) const ( @@ -28,17 +29,12 @@ type oauth2RedirectData struct { } func oauth2SubscriptionRedirect(e *core.RequestEvent) error { - redirectStatusCode := http.StatusTemporaryRedirect - if e.Request.Method != http.MethodGet { - redirectStatusCode = http.StatusSeeOther - } - data := oauth2RedirectData{} if e.Request.Method == http.MethodPost { if err := e.BindBody(&data); err != nil { e.App.Logger().Debug("Failed to read OAuth2 redirect data", "error", err) - return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath) + return failureRedirect(e) } } else { query := e.Request.URL.Query() @@ -49,13 +45,13 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error { if data.State == "" { e.App.Logger().Debug("Missing OAuth2 state parameter") - return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath) + return failureRedirect(e) } client, err := e.App.SubscriptionsBroker().ClientById(data.State) if err != nil || client.IsDiscarded() || !client.HasSubscription(oauth2SubscriptionTopic) { e.App.Logger().Debug("Missing or invalid OAuth2 subscription client", "error", err, "clientId", data.State) - return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath) + return failureRedirect(e) } defer client.Unsubscribe(oauth2SubscriptionTopic) @@ -76,7 +72,7 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error { encodedData, err := json.Marshal(data) if err != nil { e.App.Logger().Debug("Failed to marshalize OAuth2 redirect data", "error", err) - return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath) + return failureRedirect(e) } msg := subscriptions.Message{ @@ -88,10 +84,36 @@ func oauth2SubscriptionRedirect(e *core.RequestEvent) error { if data.Error != "" || data.Code == "" { e.App.Logger().Debug("Failed OAuth2 redirect due to an error or missing code parameter", "error", data.Error, "clientId", data.State) - return e.Redirect(redirectStatusCode, oauth2RedirectFailurePath) + return failureRedirect(e) } - return e.Redirect(redirectStatusCode, oauth2RedirectSuccessPath) + return successRedirect(e) +} + +func redirectStatusCode(e *core.RequestEvent) int { + if e.Request.Method != http.MethodGet { + return http.StatusSeeOther + } + + return http.StatusTemporaryRedirect +} + +func failureRedirect(e *core.RequestEvent) error { + // fallback if UI is not bundled + if ui.DistDirFS == nil { + return e.String(http.StatusOK, "Failed to authenticate. You can close this window and go back to the app to try again.") + } + + return e.Redirect(redirectStatusCode(e), oauth2RedirectFailurePath) +} + +func successRedirect(e *core.RequestEvent) error { + // fallback if UI is not bundled + if ui.DistDirFS == nil { + return e.HTML(http.StatusOK, "Auth completed. You can close this window and go back to the app.") + } + + return e.Redirect(redirectStatusCode(e), oauth2RedirectSuccessPath) } // parseAndStoreAppleRedirectName extracts the first and last name diff --git a/apis/serve.go b/apis/serve.go index d2af0c76..193d103c 100644 --- a/apis/serve.go +++ b/apis/serve.go @@ -22,6 +22,8 @@ import ( "golang.org/x/crypto/acme/autocert" ) +const defaultCSP = "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' http://127.0.0.1:* https://tile.openstreetmap.org data: blob:; connect-src 'self' http://127.0.0.1:* https://nominatim.openstreetmap.org; script-src 'self' http://127.0.0.1:*; frame-src 'none'" + // ServeConfig defines a configuration struct for apis.Serve(). type ServeConfig struct { // ShowStartBanner indicates whether to show or hide the server start console message. @@ -77,21 +79,25 @@ func Serve(app core.App, config ServeConfig) error { AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete}, })) - pbRouter.GET("/_/{path...}", Static(ui.DistDirFS, false)). - BindFunc(func(e *core.RequestEvent) error { - // ignore root path - if e.Request.PathValue(StaticWildcardParam) != "" { - e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400") - } + // @todo consider moving in base + if ui.DistDirFS != nil { + pbRouter.GET("/_/{path...}", Static(ui.DistDirFS, false)). + BindFunc(func(e *core.RequestEvent) error { + if !e.App.IsDev() && + // exclude root path + e.Request.PathValue(StaticWildcardParam) != "" && + e.Response.Header().Get("Cache-Control") == "" { + e.Response.Header().Set("Cache-Control", "max-age=1209600, stale-while-revalidate=86400") + } - // add a default CSP - if e.Response.Header().Get("Content-Security-Policy") == "" { - e.Response.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' http://127.0.0.1:* https://tile.openstreetmap.org data: blob:; connect-src 'self' http://127.0.0.1:* https://nominatim.openstreetmap.org; script-src 'self' 'sha256-GRUzBA7PzKYug7pqxv5rJaec5bwDCw1Vo6/IXwvD3Tc='") - } + if e.Response.Header().Get("Content-Security-Policy") == "" { + e.Response.Header().Set("Content-Security-Policy", defaultCSP) + } - return e.Next() - }). - Bind(Gzip()) + return e.Next() + }). + Bind(Gzip()) + } // start http server // --- @@ -279,8 +285,12 @@ func Serve(app core.App, config ServeConfig) error { ) regular := color.New() - regular.Printf("├─ REST API: %s\n", color.CyanString("%s/api/", baseURL)) - regular.Printf("└─ Dashboard: %s\n", color.CyanString("%s/_/", baseURL)) + if ui.DistDirFS == nil { + regular.Printf("└─ REST API: %s\n", color.CyanString("%s/api/", baseURL)) + } else { + regular.Printf("├─ REST API: %s\n", color.CyanString("%s/api/", baseURL)) + regular.Printf("└─ Dashboard: %s\n", color.CyanString("%s/_/", baseURL)) + } } var serveErr error diff --git a/apis/settings.go b/apis/settings.go index d6d609cd..c0522d0b 100644 --- a/apis/settings.go +++ b/apis/settings.go @@ -16,6 +16,8 @@ func bindSettingsApi(app core.App, rg *router.RouterGroup[*core.RequestEvent]) { subGroup.PATCH("", settingsSet) subGroup.POST("/test/s3", settingsTestS3) subGroup.POST("/test/email", settingsTestEmail) + + // @todo move to collections subGroup.POST("/apple/generate-client-secret", settingsGenerateAppleClientSecret) } @@ -62,12 +64,12 @@ func settingsSet(e *core.RequestEvent) error { return e.BadRequestError("An error occurred while saving the new settings.", err) } - appSettings, err := e.App.Settings().Clone() - if err != nil { - return e.InternalServerError("Failed to clone app settings.", err) - } - return execAfterSuccessTx(true, e.App, func() error { + appSettings, err := e.App.Settings().Clone() + if err != nil { + return e.InternalServerError("Failed to clone app settings.", err) + } + return e.JSON(http.StatusOK, appSettings) }) }) diff --git a/core/app.go b/core/app.go index 57875d0e..729f1175 100644 --- a/core/app.go +++ b/core/app.go @@ -267,6 +267,15 @@ type App interface { // "dangerousSelectQuery" argument must come only from trusted input! CreateViewFields(dangerousSelectQuery string) (FieldsList, error) + // DryRunView executes the provided query by creating a temporary view + // collection and returning a sample of the resulting query records (if valid). + // + // The same caveats from CreateViewFields apply here too. + // + // NB! Be aware that this method is vulnerable to SQL injection and the + // "dangerousSelectQuery" argument must come only from trusted input! + DryRunView(dangerousSelectQuery string, sampleSize int) (*DryRunViewResult, error) + // FindRecordByViewFile returns the original Record of the provided view collection file. FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) diff --git a/core/collection_model_test.go b/core/collection_model_test.go index f8fca426..c328118e 100644 --- a/core/collection_model_test.go +++ b/core/collection_model_test.go @@ -817,19 +817,19 @@ func TestCollectionDBExport(t *testing.T) { }{ { "unknown", - `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"unknown","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, + `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"unknown","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, }, { core.CollectionTypeBase, - `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"base","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, + `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":"{}","system":true,"type":"base","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, }, { core.CollectionTypeView, - `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"viewQuery":"select 1"},"system":true,"type":"view","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, + `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"viewQuery":"select 1"},"system":true,"type":"view","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, }, { core.CollectionTypeAuth, - `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":null,"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":null},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, + `{"createRule":"1=3","created":"2024-07-01 01:02:03.456Z","deleteRule":"1=5","fields":[{"help":"","hidden":false,"id":"f1_id","name":"f1","presentable":false,"required":false,"system":true,"type":"bool"},{"help":"","hidden":false,"id":"f2_id","name":"f2","presentable":false,"required":true,"system":false,"type":"bool"}],"id":"test_id","indexes":["CREATE INDEX idx1 on test_name(id)","CREATE INDEX idx2 on test_name(id)"],"listRule":"1=1","name":"test_name","options":{"authRule":null,"manageRule":"1=6","authAlert":{"enabled":false,"emailTemplate":{"subject":"","body":""}},"oauth2":{"providers":null,"mappedFields":{"id":"","name":"","username":"","avatarURL":""},"enabled":false},"passwordAuth":{"enabled":false,"identityFields":null},"mfa":{"enabled":false,"duration":0,"rule":""},"otp":{"enabled":false,"duration":0,"length":0,"emailTemplate":{"subject":"","body":""}},"authToken":{"duration":0},"passwordResetToken":{"duration":0},"emailChangeToken":{"duration":0},"verificationToken":{"duration":0},"fileToken":{"duration":0},"verificationTemplate":{"subject":"","body":""},"resetPasswordTemplate":{"subject":"","body":""},"confirmEmailChangeTemplate":{"subject":"","body":""}},"system":true,"type":"auth","updateRule":"1=4","updated":"2024-07-01 01:02:03.456Z","viewRule":"1=7"}`, }, } @@ -1576,60 +1576,62 @@ func TestCollectionSaveViewWrapping(t *testing.T) { viewName := "test_wrapping" + // note: some of the queries use "limit 0" because the tested field value could be empty + // which will trigger the extra sample records validation that are not important for this test scenarios := []struct { name string query string expected string }{ { - "no wrapping - text field", - "select text as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1)", + "no wrapping - id field", + "select id, bool from demo1", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select id, bool from demo1)", }, { - "no wrapping - id field", - "select text as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1)", + "no wrapping - text field", + "select text as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select text as id, bool from demo1 limit 0)", }, { "no wrapping - relation field", - "select rel_one as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select rel_one as id, bool from demo1)", + "select rel_one as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select rel_one as id, bool from demo1 limit 0)", }, { "no wrapping - select field", - "select select_many as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select select_many as id, bool from demo1)", + "select select_many as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select select_many as id, bool from demo1 limit 0)", }, { "no wrapping - email field", - "select email as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select email as id, bool from demo1)", + "select email as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select email as id, bool from demo1 limit 0)", }, { "no wrapping - datetime field", - "select datetime as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select datetime as id, bool from demo1)", + "select datetime as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select datetime as id, bool from demo1 limit 0)", }, { "no wrapping - url field", - "select url as id, bool from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (select url as id, bool from demo1)", + "select url as id, bool from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (select url as id, bool from demo1 limit 0)", }, { "wrapping - bool field", - "select bool as id, text as txt, url from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`txt`,`url` FROM (select bool as id, text as txt, url from demo1))", + "select bool as id, text as txt, url from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`txt`,`url` FROM (select bool as id, text as txt, url from demo1 limit 0))", }, { "wrapping - bool field (different order)", - "select text as txt, url, bool as id from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT `txt`,`url`,CAST(`id` as TEXT) `id` FROM (select text as txt, url, bool as id from demo1))", + "select text as txt, url, bool as id from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT `txt`,`url`,CAST(`id` as TEXT) `id` FROM (select text as txt, url, bool as id from demo1 limit 0))", }, { "wrapping - json field", - "select json as id, text, url from demo1", - "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`text`,`url` FROM (select json as id, text, url from demo1))", + "select json as id, text, url from demo1 limit 0", + "CREATE VIEW `test_wrapping` AS SELECT * FROM (SELECT CAST(`id` as TEXT) `id`,`text`,`url` FROM (select json as id, text, url from demo1 limit 0))", }, { "wrapping - numeric id", diff --git a/core/collection_model_view_options_test.go b/core/collection_model_view_options_test.go index c7da1eff..cb50bbb5 100644 --- a/core/collection_model_view_options_test.go +++ b/core/collection_model_view_options_test.go @@ -41,6 +41,24 @@ func TestCollectionViewOptionsValidate(t *testing.T) { }, expectedErrors: []string{"fields", "viewQuery"}, }, + { + name: "view with valid query but empty sample id", + collection: func(app core.App) (*core.Collection, error) { + c := core.NewViewCollection("new_auth") + c.ViewQuery = "select '' as id" + return c, nil + }, + expectedErrors: []string{"viewQuery"}, + }, + { + name: "view with valid query but duplicated sample id", + collection: func(app core.App) (*core.Collection, error) { + c := core.NewViewCollection("new_auth") + c.ViewQuery = "(select 'a' as id union all select 'a' as id union all select 'c' as id)" + return c, nil + }, + expectedErrors: []string{"viewQuery"}, + }, { name: "view with valid query", collection: func(app core.App) (*core.Collection, error) { diff --git a/core/collection_validate.go b/core/collection_validate.go index ca4c654a..5b83bb8d 100644 --- a/core/collection_validate.go +++ b/core/collection_validate.go @@ -314,11 +314,15 @@ func (cv *collectionValidator) checkViewQuery(value any) error { return nil // nothing to check } - if _, err := cv.app.CreateViewFields(v); err != nil { - return validation.NewError( - "validation_invalid_view_query", - fmt.Sprintf("Invalid query - %s", err.Error()), - ) + _, err := cv.app.DryRunView(v, 10) + if err != nil { + rawErr := err.Error() + if len(rawErr) > 500 { + // restrict just as an extra precaution + rawErr = rawErr[:500] + } + + return validation.NewError("validation_invalid_view_query", "Invalid query - "+rawErr) } return nil diff --git a/core/events.go b/core/events.go index 4a03af62..f0da6ea2 100644 --- a/core/events.go +++ b/core/events.go @@ -2,6 +2,7 @@ package core import ( "context" + "io/fs" "net" "net/http" "time" @@ -57,6 +58,9 @@ type baseCollectionEventData struct { Collection *Collection } +// @todo consider storing the original collection name and use that as a tag +// to avoid the ambiguity when the collection is being modified (#7613); +// for new collection also maybe return empty tags? func (e *baseCollectionEventData) Tags() []string { if e.Collection == nil { return nil @@ -125,6 +129,21 @@ type ServeEvent struct { // // Set it to nil if you want to skip the installer. InstallerFunc func(app App, systemSuperuser *Record, baseURL string) error + + // @todo experimental + // + // UIExtensions is a list with the superuser UI extensions. + UIExtensions []UIExtension +} + +type UIExtension struct { + // Name is the name of the extension. + // It is also used as path segment for the registered public extension endpoint + // (e.g. /_/extensions/{name}/*) + Name string + + // FS is the extension file system. + FS fs.FS } // ------------------------------------------------------------------- diff --git a/core/field.go b/core/field.go index 8ee4d502..0ccf78ba 100644 --- a/core/field.go +++ b/core/field.go @@ -184,6 +184,26 @@ type RecordInterceptor interface { ) error } +// DefaultFieldHelpValidationRule performs base validation on a field's "help" value. +func DefaultFieldHelpValidationRule(value any) error { + v, ok := value.(string) + if !ok { + return validators.ErrUnsupportedValueType + } + + rules := []validation.Rule{ + validation.Length(1, 300), + } + + for _, r := range rules { + if err := r.Validate(v); err != nil { + return err + } + } + + return nil +} + // DefaultFieldIdValidationRule performs base validation on a field id value. func DefaultFieldIdValidationRule(value any) error { v, ok := value.(string) diff --git a/core/field_autodate.go b/core/field_autodate.go index ca29bed2..8239d090 100644 --- a/core/field_autodate.go +++ b/core/field_autodate.go @@ -46,12 +46,12 @@ type AutodateField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- - // OnCreate auto sets the current datetime as field value on record create. OnCreate bool `form:"onCreate" json:"onCreate"` diff --git a/core/field_bool.go b/core/field_bool.go index 7be98c2a..f737c834 100644 --- a/core/field_bool.go +++ b/core/field_bool.go @@ -36,11 +36,15 @@ type BoolField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Required will require the field value to be always "true". Required bool `form:"required" json:"required"` @@ -120,5 +124,6 @@ func (f *BoolField) ValidateSettings(ctx context.Context, app App, collection *C return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), ) } diff --git a/core/field_bool_test.go b/core/field_bool_test.go index 6706099b..1c45428f 100644 --- a/core/field_bool_test.go +++ b/core/field_bool_test.go @@ -147,4 +147,5 @@ func TestBoolFieldValidateValue(t *testing.T) { func TestBoolFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeBool) testDefaultFieldNameValidation(t, core.FieldTypeBool) + testDefaultFieldHelpValidation[core.BoolField](t) } diff --git a/core/field_date.go b/core/field_date.go index 67ee1ebf..81f2e9d8 100644 --- a/core/field_date.go +++ b/core/field_date.go @@ -36,11 +36,15 @@ type DateField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Min specifies the min allowed field value. // @@ -148,6 +152,7 @@ func (f *DateField) ValidateSettings(ctx context.Context, app App, collection *C return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.Max, validation.By(f.checkRange(f.Min, f.Max))), ) } diff --git a/core/field_date_test.go b/core/field_date_test.go index ea95b191..27cacf4d 100644 --- a/core/field_date_test.go +++ b/core/field_date_test.go @@ -133,6 +133,7 @@ func TestDateFieldValidateValue(t *testing.T) { func TestDateFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeDate) testDefaultFieldNameValidation(t, core.FieldTypeDate) + testDefaultFieldHelpValidation[core.DateField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_editor.go b/core/field_editor.go index e3f17489..629d6be8 100644 --- a/core/field_editor.go +++ b/core/field_editor.go @@ -41,11 +41,15 @@ type EditorField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). // @@ -148,6 +152,7 @@ func (f *EditorField) ValidateSettings(ctx context.Context, app App, collection return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)), ) } diff --git a/core/field_editor_test.go b/core/field_editor_test.go index 8bcebcd7..2b29ffd5 100644 --- a/core/field_editor_test.go +++ b/core/field_editor_test.go @@ -163,6 +163,7 @@ func TestEditorFieldValidateValue(t *testing.T) { func TestEditorFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeEditor) testDefaultFieldNameValidation(t, core.FieldTypeEditor) + testDefaultFieldHelpValidation[core.EditorField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_email.go b/core/field_email.go index 9d82ac1d..a68b0298 100644 --- a/core/field_email.go +++ b/core/field_email.go @@ -39,11 +39,15 @@ type EmailField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // ExceptDomains will require the email domain to NOT be included in the listed ones. // @@ -155,6 +159,7 @@ func (f *EmailField) ValidateSettings(ctx context.Context, app App, collection * return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field( &f.ExceptDomains, validation.When(len(f.OnlyDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)), diff --git a/core/field_email_test.go b/core/field_email_test.go index 600f2c2c..0cff54dd 100644 --- a/core/field_email_test.go +++ b/core/field_email_test.go @@ -182,6 +182,7 @@ func TestEmailFieldValidateValue(t *testing.T) { func TestEmailFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeEmail) testDefaultFieldNameValidation(t, core.FieldTypeEmail) + testDefaultFieldHelpValidation[core.EmailField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_file.go b/core/field_file.go index ad53a3e8..0e773277 100644 --- a/core/field_file.go +++ b/core/field_file.go @@ -88,11 +88,15 @@ type FileField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // MaxSize specifies the maximum size of a single uploaded file (in bytes and up to 2^53-1). // @@ -223,6 +227,7 @@ func (f *FileField) ValidateSettings(ctx context.Context, app App, collection *C return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.MaxSelect, validation.Min(0), validation.Max(maxSafeJSONInt)), validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)), validation.Field(&f.Thumbs, validation.Each( diff --git a/core/field_file_test.go b/core/field_file_test.go index 82ad3694..0e210050 100644 --- a/core/field_file_test.go +++ b/core/field_file_test.go @@ -443,6 +443,7 @@ func TestFileFieldValidateValue(t *testing.T) { func TestFileFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeFile) testDefaultFieldNameValidation(t, core.FieldTypeFile) + testDefaultFieldHelpValidation[core.FileField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_geo_point.go b/core/field_geo_point.go index eecc4186..542abe85 100644 --- a/core/field_geo_point.go +++ b/core/field_geo_point.go @@ -46,11 +46,15 @@ type GeoPointField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Required will require the field coordinates to be non-zero (aka. not "Null Island"). Required bool `form:"required" json:"required"` @@ -144,5 +148,6 @@ func (f *GeoPointField) ValidateSettings(ctx context.Context, app App, collectio return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), ) } diff --git a/core/field_geo_point_test.go b/core/field_geo_point_test.go index dfee422f..2800a4f2 100644 --- a/core/field_geo_point_test.go +++ b/core/field_geo_point_test.go @@ -199,4 +199,5 @@ func TestGeoPointFieldValidateValue(t *testing.T) { func TestGeoPointFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeGeoPoint) testDefaultFieldNameValidation(t, core.FieldTypeGeoPoint) + testDefaultFieldHelpValidation[core.GeoPointField](t) } diff --git a/core/field_json.go b/core/field_json.go index 4a30edfc..aa4954d7 100644 --- a/core/field_json.go +++ b/core/field_json.go @@ -45,11 +45,15 @@ type JSONField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). // @@ -181,6 +185,7 @@ func (f *JSONField) ValidateSettings(ctx context.Context, app App, collection *C return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.MaxSize, validation.Min(0), validation.Max(maxSafeJSONInt)), ) } diff --git a/core/field_json_test.go b/core/field_json_test.go index 75263a99..13eb1f21 100644 --- a/core/field_json_test.go +++ b/core/field_json_test.go @@ -188,6 +188,7 @@ func TestJSONFieldValidateValue(t *testing.T) { func TestJSONFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeJSON) testDefaultFieldNameValidation(t, core.FieldTypeJSON) + testDefaultFieldHelpValidation[core.JSONField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_number.go b/core/field_number.go index d11e1750..7f4855cb 100644 --- a/core/field_number.go +++ b/core/field_number.go @@ -48,11 +48,15 @@ type NumberField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Min specifies the min allowed field value. // @@ -173,6 +177,7 @@ func (f *NumberField) ValidateSettings(ctx context.Context, app App, collection return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.Min, validation.By(f.checkOnlyInt)), validation.Field(&f.Max, maxRules...), ) diff --git a/core/field_number_test.go b/core/field_number_test.go index a9117d6b..eae6fb4d 100644 --- a/core/field_number_test.go +++ b/core/field_number_test.go @@ -214,6 +214,7 @@ func TestNumberFieldValidateValue(t *testing.T) { func TestNumberFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeNumber) testDefaultFieldNameValidation(t, core.FieldTypeNumber) + testDefaultFieldHelpValidation[core.NumberField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_password.go b/core/field_password.go index 794846f7..ed1b1d5d 100644 --- a/core/field_password.go +++ b/core/field_password.go @@ -61,11 +61,17 @@ type PasswordField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + + // @todo remove + // // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Pattern specifies an optional regex pattern to match against the field value. // @@ -209,6 +215,7 @@ func (f *PasswordField) ValidateSettings(ctx context.Context, app App, collectio return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.Min, validation.Min(1), validation.Max(71)), validation.Field(&f.Max, validation.Min(f.Min), validation.Max(71)), validation.Field(&f.Cost, validation.Min(bcrypt.MinCost), validation.Max(bcrypt.MaxCost)), diff --git a/core/field_password_test.go b/core/field_password_test.go index 31a1113d..39733e62 100644 --- a/core/field_password_test.go +++ b/core/field_password_test.go @@ -287,6 +287,7 @@ func TestPasswordFieldValidateValue(t *testing.T) { func TestPasswordFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypePassword) testDefaultFieldNameValidation(t, core.FieldTypePassword) + testDefaultFieldHelpValidation[core.PasswordField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_relation.go b/core/field_relation.go index 77956457..bf75674a 100644 --- a/core/field_relation.go +++ b/core/field_relation.go @@ -66,11 +66,15 @@ type RelationField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // CollectionId is the id of the related collection. CollectionId string `form:"collectionId" json:"collectionId"` @@ -237,6 +241,7 @@ func (f *RelationField) ValidateSettings(ctx context.Context, app App, collectio return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.CollectionId, validation.Required, validation.By(f.checkCollectionId(app, collection))), validation.Field(&f.MinSelect, validation.Min(0)), validation.Field(&f.MaxSelect, validation.When(f.MinSelect > 0, validation.Required), validation.Min(f.MinSelect)), diff --git a/core/field_relation_test.go b/core/field_relation_test.go index 598e361b..501530fe 100644 --- a/core/field_relation_test.go +++ b/core/field_relation_test.go @@ -348,6 +348,7 @@ func TestRelationFieldValidateValue(t *testing.T) { func TestRelationFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeRelation) testDefaultFieldNameValidation(t, core.FieldTypeRelation) + testDefaultFieldHelpValidation[core.RelationField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_select.go b/core/field_select.go index e77eb38c..8b1c5c9d 100644 --- a/core/field_select.go +++ b/core/field_select.go @@ -66,11 +66,15 @@ type SelectField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Values specifies the list of accepted values. Values []string `form:"values" json:"values"` @@ -216,6 +220,7 @@ func (f *SelectField) ValidateSettings(ctx context.Context, app App, collection return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.Values, validation.Required), validation.Field(&f.MaxSelect, validation.Min(0), validation.Max(max)), ) diff --git a/core/field_select_test.go b/core/field_select_test.go index 808c1096..093c7011 100644 --- a/core/field_select_test.go +++ b/core/field_select_test.go @@ -337,6 +337,7 @@ func TestSelectFieldValidateValue(t *testing.T) { func TestSelectFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeSelect) testDefaultFieldNameValidation(t, core.FieldTypeSelect) + testDefaultFieldHelpValidation[core.SelectField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_test.go b/core/field_test.go index fba7089a..158dde2e 100644 --- a/core/field_test.go +++ b/core/field_test.go @@ -2,6 +2,8 @@ package core_test import ( "context" + "encoding/json" + "reflect" "strings" "testing" @@ -113,7 +115,7 @@ func testDefaultFieldIdValidation(t *testing.T, fieldType string) { hasErr := errs["id"] != nil if hasErr != s.expectError { - t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr) + t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs) } }) } @@ -254,7 +256,64 @@ func testDefaultFieldNameValidation(t *testing.T, fieldType string) { hasErr := errs["name"] != nil if hasErr != s.expectError { - t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr) + t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs) + } + }) + } +} + +func testDefaultFieldHelpValidation[T any](t *testing.T) { + app, _ := tests.NewTestApp() + defer app.Cleanup() + + collection := core.NewBaseCollection("test_collection") + + scenarios := []struct { + name string + json string + expectError bool + }{ + { + "empty value", + `{}`, + false, + }, + { + "< max limit", + `{"help":"abc"}`, + false, + }, + { + "= max limit", + `{"help":"` + strings.Repeat("a", 300) + `"}`, + false, + }, + { + "> max limit", + `{"help":"` + strings.Repeat("a", 301) + `"}`, + true, + }, + } + + for _, s := range scenarios { + t.Run("[help] "+s.name, func(t *testing.T) { + var zeroField T + + field, ok := reflect.New(reflect.TypeOf(zeroField)).Interface().(core.Field) + if !ok { + t.Fatalf("Expected core.Field instance, got %T", zeroField) + } + + err := json.Unmarshal([]byte(s.json), &field) + if err != nil { + t.Fatal(err) + } + + errs, _ := field.ValidateSettings(context.Background(), app, collection).(validation.Errors) + + hasErr := errs["help"] != nil + if hasErr != s.expectError { + t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, errs) } }) } diff --git a/core/field_text.go b/core/field_text.go index 75439fad..2a2af532 100644 --- a/core/field_text.go +++ b/core/field_text.go @@ -72,11 +72,15 @@ type TextField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // Min specifies the minimum required string characters. // @@ -283,6 +287,7 @@ func (f *TextField) ValidateSettings(ctx context.Context, app App, collection *C validation.By(DefaultFieldNameValidationRule), validation.When(f.PrimaryKey, validation.In(idColumn).Error(`The primary key must be named "id".`)), ), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field(&f.PrimaryKey, validation.By(f.checkOtherFieldsForPK(collection))), validation.Field(&f.Min, validation.Min(0), validation.Max(maxSafeJSONInt)), validation.Field(&f.Max, validation.Min(f.Min), validation.Max(maxSafeJSONInt)), diff --git a/core/field_text_test.go b/core/field_text_test.go index 94357d18..671a6575 100644 --- a/core/field_text_test.go +++ b/core/field_text_test.go @@ -381,6 +381,7 @@ func TestTextFieldValidateValue(t *testing.T) { func TestTextFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeText) testDefaultFieldNameValidation(t, core.FieldTypeText) + testDefaultFieldHelpValidation[core.TextField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/field_url.go b/core/field_url.go index 79a61dc3..06d6d856 100644 --- a/core/field_url.go +++ b/core/field_url.go @@ -39,11 +39,15 @@ type URLField struct { // Hidden hides the field from the API response. Hidden bool `form:"hidden" json:"hidden"` + // --- + // Presentable hints the Dashboard UI to use the underlying // field record value in the relation preview label. Presentable bool `form:"presentable" json:"presentable"` - // --- + // Help is an extra text explaining what the field is about. + // It is usually shown in Dashboard UI under the field input. + Help string `form:"help" json:"help"` // ExceptDomains will require the URL domain to NOT be included in the listed ones. // @@ -156,6 +160,7 @@ func (f *URLField) ValidateSettings(ctx context.Context, app App, collection *Co return validation.ValidateStruct(f, validation.Field(&f.Id, validation.By(DefaultFieldIdValidationRule)), validation.Field(&f.Name, validation.By(DefaultFieldNameValidationRule)), + validation.Field(&f.Help, validation.By(DefaultFieldHelpValidationRule)), validation.Field( &f.ExceptDomains, validation.When(len(f.OnlyDomains) > 0, validation.Empty).Else(validation.Each(is.Domain)), diff --git a/core/field_url_test.go b/core/field_url_test.go index 0b2db39d..7f59e069 100644 --- a/core/field_url_test.go +++ b/core/field_url_test.go @@ -182,6 +182,7 @@ func TestURLFieldValidateValue(t *testing.T) { func TestURLFieldValidateSettings(t *testing.T) { testDefaultFieldIdValidation(t, core.FieldTypeURL) testDefaultFieldNameValidation(t, core.FieldTypeURL) + testDefaultFieldHelpValidation[core.URLField](t) app, _ := tests.NewTestApp() defer app.Cleanup() diff --git a/core/fields_list_test.go b/core/fields_list_test.go index e667e769..13457e39 100644 --- a/core/fields_list_test.go +++ b/core/fields_list_test.go @@ -473,13 +473,13 @@ func TestFieldsListScan(t *testing.T) { "only the minimum field options", `[{"id":"123","name":"test1","type":"text","required":true},{"id":"456","name":"test2","type":"bool"}]`, false, - `[{"autogeneratePattern":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`, }, { "all field options", - `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, false, - `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, }, } @@ -523,13 +523,13 @@ func TestFieldsListJSON(t *testing.T) { "only the minimum field options", `[{"id":"123","name":"test1","type":"text","required":true},{"id":"456","name":"test2","type":"bool"}]`, false, - `[{"autogeneratePattern":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"","hidden":false,"id":"123","max":0,"min":0,"name":"test1","pattern":"","presentable":false,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":false,"type":"bool"}]`, }, { "all field options", - `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, false, - `[{"autogeneratePattern":"","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, + `[{"autogeneratePattern":"","help":"abc","hidden":true,"id":"123","max":12,"min":0,"name":"test1","pattern":"","presentable":true,"primaryKey":false,"required":true,"system":false,"type":"text"},{"help":"def","hidden":false,"id":"456","name":"test2","presentable":false,"required":false,"system":true,"type":"bool"}]`, }, } diff --git a/core/settings_model.go b/core/settings_model.go index a1100001..1adead7b 100644 --- a/core/settings_model.go +++ b/core/settings_model.go @@ -143,6 +143,7 @@ func newDefaultSettings() *Settings { isNew: true, settings: settings{ Meta: MetaConfig{ + AccentColor: "#1055c9", AppName: "Acme", AppURL: "http://localhost:8090", HideControls: false, @@ -513,6 +514,11 @@ func checkCronExpression(value any) error { // ------------------------------------------------------------------- type MetaConfig struct { + // @todo experimental + // + // AccentColor specify the UI "accent" color (HEX). + AccentColor string `form:"accentColor" json:"accentColor"` + AppName string `form:"appName" json:"appName"` AppURL string `form:"appURL" json:"appURL"` SenderName string `form:"senderName" json:"senderName"` @@ -523,6 +529,7 @@ type MetaConfig struct { // Validate makes MetaConfig validatable by implementing [validation.Validatable] interface. func (c MetaConfig) Validate() error { return validation.ValidateStruct(&c, + validation.Field(&c.AccentColor, validation.Length(7, 7), is.HexColor), validation.Field(&c.AppName, validation.Required, validation.Length(1, 255)), validation.Field(&c.AppURL, validation.Required, is.URL), validation.Field(&c.SenderName, validation.Required, validation.Length(1, 255)), diff --git a/core/settings_model_test.go b/core/settings_model_test.go index b0ea8983..5f577f8d 100644 --- a/core/settings_model_test.go +++ b/core/settings_model_test.go @@ -84,7 +84,7 @@ func TestSettings_DBExport(t *testing.T) { valueStr = string(export["value"].([]byte)) } - expected := `{"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}` + expected := `{"smtp":{"enabled":false,"port":0,"host":"smtp_host","username":"smtp_username","password":"","authMethod":"","tls":false,"localName":""},"backups":{"cron":"* * * * *","cronMaxKeep":0,"s3":{"enabled":true,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"s3_endpoint","accessKey":"","secret":"s3_secret","forcePathStyle":false},"meta":{"accentColor":"","appName":"test_app_name","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":true},"trustedProxy":{"headers":[],"useLeftmostIP":true},"batch":{"enabled":false,"maxRequests":0,"timeout":15,"maxBodySize":0},"logs":{"maxDays":123,"minLevel":0,"logIP":false,"logAuthId":false}}` if valueStr != expected { t.Fatalf("Expected exported settings\n%s\ngot\n%s", expected, valueStr) } @@ -93,6 +93,8 @@ func TestSettings_DBExport(t *testing.T) { } func TestSettingsMerge(t *testing.T) { + t.Parallel() + s1 := &core.Settings{} s1.Meta.AppURL = "app_url" // should be unset @@ -126,6 +128,8 @@ func TestSettingsMerge(t *testing.T) { } func TestSettingsClone(t *testing.T) { + t.Parallel() + s1 := &core.Settings{} s1.Meta.AppName = "test_name" @@ -156,6 +160,8 @@ func TestSettingsClone(t *testing.T) { } func TestSettingsMarshalJSON(t *testing.T) { + t.Parallel() + settings := &core.Settings{} // control fields @@ -174,7 +180,7 @@ func TestSettingsMarshalJSON(t *testing.T) { } rawStr := string(raw) - expected := `{"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}` + expected := `{"smtp":{"enabled":false,"port":0,"host":"","username":"abc","authMethod":"","tls":false,"localName":""},"backups":{"cron":"","cronMaxKeep":0,"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false}},"s3":{"enabled":false,"bucket":"","region":"","endpoint":"","accessKey":"","forcePathStyle":false},"meta":{"accentColor":"","appName":"test123","appURL":"","senderName":"","senderAddress":"","hideControls":false},"rateLimits":{"rules":[],"enabled":false},"trustedProxy":{"headers":[],"useLeftmostIP":false},"batch":{"enabled":false,"maxRequests":0,"timeout":0,"maxBodySize":0},"logs":{"maxDays":0,"minLevel":0,"logIP":false,"logAuthId":false}}` if rawStr != expected { t.Fatalf("Expected\n%v\ngot\n%v", expected, rawStr) @@ -230,6 +236,8 @@ func TestSettingsValidate(t *testing.T) { } func TestMetaConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.MetaConfig @@ -248,12 +256,14 @@ func TestMetaConfigValidate(t *testing.T) { { "invalid data", core.MetaConfig{ + AccentColor: "#fff", AppName: strings.Repeat("a", 300), AppURL: "test", SenderName: strings.Repeat("a", 300), SenderAddress: "invalid_email", }, []string{ + "accentColor", "appName", "appURL", "senderName", @@ -263,6 +273,7 @@ func TestMetaConfigValidate(t *testing.T) { { "valid data", core.MetaConfig{ + AccentColor: "#ffffff", AppName: "test", AppURL: "https://example.com", SenderName: "test", @@ -282,6 +293,8 @@ func TestMetaConfigValidate(t *testing.T) { } func TestLogsConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.LogsConfig @@ -314,6 +327,8 @@ func TestLogsConfigValidate(t *testing.T) { } func TestSMTPConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.SMTPConfig @@ -373,6 +388,8 @@ func TestSMTPConfigValidate(t *testing.T) { } func TestS3ConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.S3Config @@ -444,6 +461,8 @@ func TestS3ConfigValidate(t *testing.T) { } func TestBackupsConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.BackupsConfig @@ -499,6 +518,8 @@ func TestBackupsConfigValidate(t *testing.T) { } func TestBatchConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.BatchConfig @@ -554,6 +575,8 @@ func TestBatchConfigValidate(t *testing.T) { } func TestRateLimitsConfigValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string config core.RateLimitsConfig @@ -699,6 +722,8 @@ func TestRateLimitsConfigValidate(t *testing.T) { } func TestRateLimitsFindRateLimitRule(t *testing.T) { + t.Parallel() + limits := core.RateLimitsConfig{ Rules: []core.RateLimitRule{ {Label: "abc"}, @@ -753,6 +778,8 @@ func TestRateLimitsFindRateLimitRule(t *testing.T) { } func TestRateLimitRuleValidate(t *testing.T) { + t.Parallel() + scenarios := []struct { name string rule core.RateLimitRule @@ -860,6 +887,8 @@ func TestRateLimitRuleValidate(t *testing.T) { } func TestRateLimitRuleDurationTime(t *testing.T) { + t.Parallel() + scenarios := []struct { rule core.RateLimitRule expected time.Duration @@ -880,6 +909,8 @@ func TestRateLimitRuleDurationTime(t *testing.T) { } func TestRateLimitRuleString(t *testing.T) { + t.Parallel() + scenarios := []struct { name string rule core.RateLimitRule diff --git a/core/view.go b/core/view.go index fdfefdf2..5b44e8bc 100644 --- a/core/view.go +++ b/core/view.go @@ -1,6 +1,7 @@ package core import ( + "context" "errors" "fmt" "io" @@ -36,17 +37,14 @@ func (app *BaseApp) DeleteView(dangerousViewName string) error { func (app *BaseApp) SaveView(dangerousViewName string, dangerousSelectQuery string) error { return app.RunInTransaction(func(txApp App) error { // delete old view (if exists) - if err := txApp.DeleteView(dangerousViewName); err != nil { + err := txApp.DeleteView(dangerousViewName) + if err != nil { return err } - dangerousSelectQuery = strings.Trim(strings.TrimSpace(dangerousSelectQuery), ";") - - // try to loosely detect multiple inline statements - tk := tokenizer.NewFromString(dangerousSelectQuery) - tk.Separators(';') - if queryParts, _ := tk.ScanAll(); len(queryParts) > 1 { - return errors.New("multiple statements are not supported") + dangerousSelectQuery, err = normalizeViewSelectQuery(dangerousSelectQuery) + if err != nil { + return err } // (re)create the view @@ -54,7 +52,8 @@ func (app *BaseApp) SaveView(dangerousViewName string, dangerousSelectQuery stri // note: the query is wrapped in a secondary SELECT as a rudimentary // measure to discourage multiple inline sql statements execution viewQuery := fmt.Sprintf("CREATE VIEW {{%s}} AS SELECT * FROM (%s)", dangerousViewName, dangerousSelectQuery) - if _, err := txApp.DB().NewQuery(viewQuery).Execute(); err != nil { + _, err = txApp.DB().NewQuery(viewQuery).Execute() + if err != nil { return err } @@ -124,6 +123,76 @@ func (app *BaseApp) CreateViewFields(dangerousSelectQuery string) (FieldsList, e return result, txErr } +type DryRunViewResult struct { + Fields FieldsList `json:"fields"` + Sample []*Record `json:"sample"` +} + +// DryRunView executes the provided query by creating a temporary view +// collection and returning a sample of the resulting query records (if valid). +// +// The same caveats from CreateViewFields apply here too. +// +// NB! Be aware that this method is vulnerable to SQL injection and the +// "dangerousSelectQuery" argument must come only from trusted input! +func (app *BaseApp) DryRunView(dangerousSelectQuery string, sampleSize int) (*DryRunViewResult, error) { + dangerousSelectQuery, err := normalizeViewSelectQuery(dangerousSelectQuery) + if err != nil { + return nil, err + } + + fields, err := app.CreateViewFields(dangerousSelectQuery) + if err != nil { + return nil, err + } + + tempName := "temp_view_" + security.RandomString(5) + tempCollection := NewViewCollection(tempName) + tempCollection.Fields = fields + + // validate generated view fields + ctx := context.Background() + for i, f := range fields { + err = f.ValidateSettings(ctx, app, tempCollection) + if err != nil { + return nil, fmt.Errorf("invalid field %q (%d): %w", f.GetName(), i, err) + } + } + + records := []*Record{} + + err = app.RecordQuery(tempCollection). + // note: the query is wrapped in a secondary SELECT as a rudimentary + // measure to discourage multiple inline sql statements execution + From("(SELECT * FROM (" + dangerousSelectQuery + ")) as " + tempName). + Limit(int64(sampleSize)). + All(&records) + if err != nil { + return nil, fmt.Errorf("failed to retrieve query records: %w", err) + } + + // warn for possible empty or duplicated record ids found in the sample + // (it is not intended for security and it is here to quickly provide a + // helpful error message without doing multiple query executions) + ids := make(map[string]struct{}, len(records)) + for _, r := range records { + if r.Id == "" { + return nil, errors.New("the query could return records with empty or invalid ids") + } + + if _, ok := ids[r.Id]; ok { + return nil, errors.New("the query could return records with non-unique ids") + } + + ids[r.Id] = struct{}{} + } + + return &DryRunViewResult{ + Fields: fields, + Sample: records, + }, nil +} + // FindRecordByViewFile returns the original Record of the provided view collection file. func (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fileFieldName string, filename string) (*Record, error) { view, err := getCollectionByModelOrIdentifier(app, viewCollectionModelOrIdentifier) @@ -198,6 +267,20 @@ func (app *BaseApp) FindRecordByViewFile(viewCollectionModelOrIdentifier any, fi // Raw query to schema helpers // ------------------------------------------------------------------- +// loosely normalizes the specified view query and warn against multiple inline statements +// (the check is not perfect and it is NOT intended as a security measure; it is done primarily to provide a helpful error message) +func normalizeViewSelectQuery(dangerousSelectQuery string) (string, error) { + dangerousSelectQuery = strings.Trim(strings.TrimSpace(dangerousSelectQuery), ";") + + tk := tokenizer.NewFromString(dangerousSelectQuery) + tk.Separators(';') + if queryParts, _ := tk.ScanAll(); len(queryParts) > 1 { + return "", errors.New("multiple statements are not supported") + } + + return dangerousSelectQuery, nil +} + type queryField struct { // field is the final resolved field. field Field @@ -212,12 +295,26 @@ type queryField struct { } func defaultViewField(name string) Field { + if name == FieldNameId { + return defaultViewIdField() + } + return &JSONField{ Name: name, MaxSize: 1, // unused for views } } +func defaultViewIdField() Field { + return &TextField{ + Name: FieldNameId, + System: true, + Required: true, + PrimaryKey: true, + Pattern: `^[a-z0-9]+$`, + } +} + var castRegex = regexp.MustCompile(`(?is)^cast\s*\(.*\s+as\s+(\w+)\s*\)$`) func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, error) { @@ -245,13 +342,7 @@ func parseQueryToFields(app App, selectQuery string) (map[string]*queryField, er // pk (always assume text field for now) if col.alias == FieldNameId { result[col.alias] = &queryField{ - field: &TextField{ - Name: col.alias, - System: true, - Required: true, - PrimaryKey: true, - Pattern: `^[a-z0-9]+$`, - }, + field: defaultViewIdField(), } continue } diff --git a/core/view_test.go b/core/view_test.go index 2f717598..384f3e23 100644 --- a/core/view_test.go +++ b/core/view_test.go @@ -732,3 +732,129 @@ func TestFindRecordByViewFile(t *testing.T) { }) } } + +func TestDryRunView(t *testing.T) { + t.Parallel() + + app, _ := tests.NewTestApp() + defer app.Cleanup() + + scenarios := []struct { + name string + query string + sampleSize int + expectError bool + expectFields map[string]string // name-type pairs + expectSampleIds []string // record ids of the resulting sample + }{ + { + "empty query", + "", + 10, + true, + nil, + nil, + }, + { + "non-select query", + "CREATE TABLE t1(x INT)", + 10, + true, + nil, + nil, + }, + { + "multiple inline select statements", + "select 'a' as id; select 'b' as id", + 10, + true, + nil, + nil, + }, + { + "select with invalid formatted field name", + "select 'a' as id, count(*)", // missing field alias + 10, + true, + nil, + nil, + }, + { + "select resolving to records with missing id", + "(select 'a' as id UNION ALL select null as id UNION ALL select 'c' as id)", + 10, + true, + nil, + nil, + }, + { + "select resolving to records with duplicated ids", + "(select 'a' as id UNION ALL select 'a' as id UNION ALL select 'c' as id)", + 10, + true, + nil, + nil, + }, + { + "no sample size and valid select query but with invalid records result", + "(select 'a' as id UNION ALL select 'a' as id UNION ALL select 'c' as id)", + 0, + false, // still "valid" because there is no sample to check + map[string]string{"id": "text"}, + nil, + }, + { + "sample size < total select records", + "(select 'a' as id UNION ALL select 'b' as id UNION ALL select 'c' as id UNION ALL select 'd' as id)", + 3, + false, + map[string]string{"id": "text"}, + []string{"a", "b", "c"}, + }, + } + + for _, s := range scenarios { + t.Run(s.name, func(t *testing.T) { + result, err := app.DryRunView(s.query, s.sampleSize) + + hasErr := err != nil + if hasErr != s.expectError { + t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, err) + } + + if hasErr { + return + } + + // check fields + // --- + if len(s.expectFields) != len(result.Fields) { + serialized, _ := json.Marshal(result.Fields) + t.Fatalf("Expected %d fields, got %d: \n%s", len(s.expectFields), len(result.Fields), serialized) + } + for name, typ := range s.expectFields { + field := result.Fields.GetByName(name) + if field == nil { + t.Fatalf("Expected to find field %s, got nil", name) + } + + if field.Type() != typ { + t.Fatalf("Expected field %s to be %q, got %q", name, typ, field.Type()) + } + } + + // check sample ids + // --- + if len(s.expectSampleIds) != len(result.Sample) { + t.Fatalf("Expected %d sample records, got %d", len(s.expectSampleIds), len(result.Sample)) + } + for i, r := range result.Sample { + if s.expectSampleIds[i] != r.Id { + t.Fatalf("Expected sample record id %q, got %q at %d", s.expectSampleIds[i], r.Id, i) + } + } + }) + } + + ensureNoTempViews(app, t) +} diff --git a/plugins/jsvm/binds.go b/plugins/jsvm/binds.go index 6ec4b9ff..c76fc749 100644 --- a/plugins/jsvm/binds.go +++ b/plugins/jsvm/binds.go @@ -289,9 +289,13 @@ func wrapMiddlewares(executors *vmsPool, rawMiddlewares ...goja.Value) ([]*hook. return wrappedMiddlewares, nil } +// ------------------------------------------------------------------- + var cachedArrayOfTypes = store.New[reflect.Type, reflect.Type](nil) -func baseBinds(vm *goja.Runtime) { +// BindCore registers common core objects and functions such as sleep, +// toString, DynamicModel, etc. into the provided runtime. +func BindCore(vm *goja.Runtime) { vm.SetFieldNameMapper(FieldMapper{}) // deprecated: use toString @@ -659,7 +663,10 @@ func baseBinds(vm *goja.Runtime) { }) } -func dbxBinds(vm *goja.Runtime) { +// BindDbx registers $dbx.* namespaced object with dbx database builder related methods. +// +// See https://pocketbase.io/jsvm/modules/_dbx.html. +func BindDbx(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$dbx", obj) @@ -682,7 +689,10 @@ func dbxBinds(vm *goja.Runtime) { obj.Set("notBetween", dbx.NotBetween) } -func mailsBinds(vm *goja.Runtime) { +// BindMails registers $mail.* namespaced object with common mail related helpers. +// +// See https://pocketbase.io/jsvm/modules/_mails.html. +func BindMails(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$mails", obj) @@ -693,7 +703,10 @@ func mailsBinds(vm *goja.Runtime) { obj.Set("sendRecordAuthAlert", mails.SendRecordAuthAlert) } -func securityBinds(vm *goja.Runtime) { +// BindSecurity registers $security.* namespaced object with common security related helpers. +// +// See https://pocketbase.io/jsvm/modules/_security.html. +func BindSecurity(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$security", obj) @@ -736,7 +749,11 @@ func securityBinds(vm *goja.Runtime) { }) } -func filesystemBinds(vm *goja.Runtime) { +// BindFilesystem registers $filesystem.* namespaced object with +// common filesystem package related helpers. +// +// See https://pocketbase.io/jsvm/modules/_filesystem.html. +func BindFilesystem(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$filesystem", obj) @@ -757,7 +774,11 @@ func filesystemBinds(vm *goja.Runtime) { }) } -func filepathBinds(vm *goja.Runtime) { +// BindFilesystem registers $filepath.* namespaced object with +// common std Go filepath package related exports. +// +// See https://pocketbase.io/jsvm/modules/_filepath.html. +func BindFilepath(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$filepath", obj) @@ -778,7 +799,11 @@ func filepathBinds(vm *goja.Runtime) { obj.Set("walkDir", filepath.WalkDir) } -func osBinds(vm *goja.Runtime) { +// BindFilesystem registers $os.* namespaced object with +// common std Go os package related exports. +// +// See https://pocketbase.io/jsvm/modules/_os.html. +func BindOs(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$os", obj) @@ -804,14 +829,20 @@ func osBinds(vm *goja.Runtime) { obj.Set("openInRoot", os.OpenInRoot) } -func formsBinds(vm *goja.Runtime) { +// BindForms registers various application form constructors. +// These bindings are mostly used internally and/or preserved for backward compatibility with earlier versions. +func BindForms(vm *goja.Runtime) { registerFactoryAsConstructor(vm, "AppleClientSecretCreateForm", forms.NewAppleClientSecretCreate) registerFactoryAsConstructor(vm, "RecordUpsertForm", forms.NewRecordUpsert) registerFactoryAsConstructor(vm, "TestEmailSendForm", forms.NewTestEmailSend) registerFactoryAsConstructor(vm, "TestS3FilesystemForm", forms.NewTestS3Filesystem) } -func apisBinds(vm *goja.Runtime) { +// BindApis registers $apis.* namespaced object with reusable Web API +// handlers, middlewares and other related helpers. +// +// See https://pocketbase.io/jsvm/modules/_apis.html. +func BindApis(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$apis", obj) @@ -850,7 +881,11 @@ func apisBinds(vm *goja.Runtime) { registerFactoryAsConstructor(vm, "InternalServerError", router.NewInternalServerError) } -func httpClientBinds(vm *goja.Runtime) { +// BindHttpClient registers $http.* namespaced object with common utils +// for sending HTTP requests. +// +// See https://pocketbase.io/jsvm/modules/_http.html. +func BindHttpClient(vm *goja.Runtime) { obj := vm.NewObject() vm.Set("$http", obj) diff --git a/plugins/jsvm/binds_test.go b/plugins/jsvm/binds_test.go index 7e4c5121..4accf892 100644 --- a/plugins/jsvm/binds_test.go +++ b/plugins/jsvm/binds_test.go @@ -43,16 +43,16 @@ func testBindsCount(vm *goja.Runtime, namespace string, count int, t *testing.T) // note: this test is useful as a reminder to update the tests in case // a new base binding is added. -func TestBaseBindsCount(t *testing.T) { +func TestBindCoreCount(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) testBindsCount(vm, "this", 41, t) } -func TestBaseBindsSleep(t *testing.T) { +func TestBindCoreSleep(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("reader", strings.NewReader("test")) start := time.Now() @@ -69,9 +69,9 @@ func TestBaseBindsSleep(t *testing.T) { } } -func TestBaseBindsReaderToString(t *testing.T) { +func TestBindCoreReaderToString(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("reader", strings.NewReader("test")) _, err := vm.RunString(` @@ -86,9 +86,9 @@ func TestBaseBindsReaderToString(t *testing.T) { } } -func TestBaseBindsToString(t *testing.T) { +func TestBindCoreToString(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("scenarios", []struct { Name string Value any @@ -120,9 +120,9 @@ func TestBaseBindsToString(t *testing.T) { } } -func TestBaseBindsToBytes(t *testing.T) { +func TestBindCoreToBytes(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("bytesEqual", bytes.Equal) vm.Set("scenarios", []struct { Name string @@ -160,9 +160,9 @@ func TestBaseBindsToBytes(t *testing.T) { } } -func TestBaseBindsUnmarshal(t *testing.T) { +func TestBindCoreUnmarshal(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("data", &map[string]any{"a": 123}) _, err := vm.RunString(` @@ -181,9 +181,9 @@ func TestBaseBindsUnmarshal(t *testing.T) { } } -func TestBaseBindsContext(t *testing.T) { +func TestBindCoreContext(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const base = new Context(null, "a", 123); @@ -205,9 +205,9 @@ func TestBaseBindsContext(t *testing.T) { } } -func TestBaseBindsCookie(t *testing.T) { +func TestBindCoreCookie(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const cookie = new Cookie({ @@ -234,9 +234,9 @@ func TestBaseBindsCookie(t *testing.T) { } } -func TestBaseBindsSubscriptionMessage(t *testing.T) { +func TestBindCoreSubscriptionMessage(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("bytesToString", func(b []byte) string { return string(b) }) @@ -262,7 +262,7 @@ func TestBaseBindsSubscriptionMessage(t *testing.T) { } } -func TestBaseBindsRecord(t *testing.T) { +func TestBindCoreRecord(t *testing.T) { app, _ := tests.NewTestApp() defer app.Cleanup() @@ -272,7 +272,7 @@ func TestBaseBindsRecord(t *testing.T) { } vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("collection", collection) // without record data @@ -308,9 +308,9 @@ func TestBaseBindsRecord(t *testing.T) { } } -func TestBaseBindsCollection(t *testing.T) { +func TestBindCoreCollection(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) v, err := vm.RunString(`new Collection({ name: "test", createRule: "@request.auth.id != ''", fields: [{name: "title", "type": "text"}] })`) if err != nil { @@ -336,9 +336,9 @@ func TestBaseBindsCollection(t *testing.T) { } } -func TestBaseBindsFieldsList(t *testing.T) { +func TestBindCoreFieldsList(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) v, err := vm.RunString(`new FieldsList([{name: "title", "type": "text"}])`) if err != nil { @@ -355,9 +355,9 @@ func TestBaseBindsFieldsList(t *testing.T) { } } -func TestBaseBindsField(t *testing.T) { +func TestBindCoreField(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) v, err := vm.RunString(`new Field({name: "test", "type": "bool"})`) if err != nil { @@ -379,11 +379,11 @@ func isType[T any](v any) bool { return ok } -func TestBaseBindsNamedFields(t *testing.T) { +func TestBindCoreNamedFields(t *testing.T) { t.Parallel() vm := goja.New() - baseBinds(vm) + BindCore(vm) scenarios := []struct { js string @@ -470,9 +470,9 @@ func TestBaseBindsNamedFields(t *testing.T) { } } -func TestBaseBindsMailerMessage(t *testing.T) { +func TestBindCoreMailerMessage(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) v, err := vm.RunString(`new MailerMessage({ from: {name: "test_from", address: "test_from@example.com"}, @@ -517,9 +517,9 @@ func TestBaseBindsMailerMessage(t *testing.T) { } } -func TestBaseBindsCommand(t *testing.T) { +func TestBindCoreCommand(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` let runCalls = 0; @@ -546,9 +546,9 @@ func TestBaseBindsCommand(t *testing.T) { } } -func TestBaseBindsRequestInfo(t *testing.T) { +func TestBindCoreRequestInfo(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const info = new RequestInfo({ @@ -564,9 +564,9 @@ func TestBaseBindsRequestInfo(t *testing.T) { } } -func TestBaseBindsMiddleware(t *testing.T) { +func TestBindCoreMiddleware(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const m = new Middleware( @@ -584,9 +584,9 @@ func TestBaseBindsMiddleware(t *testing.T) { } } -func TestBaseBindsTimezone(t *testing.T) { +func TestBindCoreTimezone(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const v0 = (new Timezone()).string(); @@ -609,9 +609,9 @@ func TestBaseBindsTimezone(t *testing.T) { } } -func TestBaseBindsDateTime(t *testing.T) { +func TestBindCoreDateTime(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) _, err := vm.RunString(` const now = new DateTime(); @@ -650,9 +650,9 @@ func TestBaseBindsDateTime(t *testing.T) { } } -func TestBaseBindsValidationError(t *testing.T) { +func TestBindCoreValidationError(t *testing.T) { vm := goja.New() - baseBinds(vm) + BindCore(vm) scenarios := []struct { js string @@ -697,14 +697,14 @@ func TestBaseBindsValidationError(t *testing.T) { } } -func TestDbxBinds(t *testing.T) { +func TestBindDbx(t *testing.T) { app, _ := tests.NewTestApp() defer app.Cleanup() vm := goja.New() vm.Set("db", app.DB()) - baseBinds(vm) - dbxBinds(vm) + BindCore(vm) + BindDbx(vm) testBindsCount(vm, "$dbx", 15, t) @@ -792,14 +792,14 @@ func TestDbxBinds(t *testing.T) { } } -func TestMailsBindsCount(t *testing.T) { +func TestBindMailsCount(t *testing.T) { vm := goja.New() - mailsBinds(vm) + BindMails(vm) testBindsCount(vm, "$mails", 5, t) } -func TestMailsBinds(t *testing.T) { +func TestBindMails(t *testing.T) { app, _ := tests.NewTestApp() defer app.Cleanup() @@ -809,8 +809,8 @@ func TestMailsBinds(t *testing.T) { } vm := goja.New() - baseBinds(vm) - mailsBinds(vm) + BindCore(vm) + BindMails(vm) vm.Set("$app", app) vm.Set("record", record) @@ -845,17 +845,17 @@ func TestMailsBinds(t *testing.T) { } } -func TestSecurityBindsCount(t *testing.T) { +func TestBindSecurityCount(t *testing.T) { vm := goja.New() - securityBinds(vm) + BindSecurity(vm) testBindsCount(vm, "$security", 16, t) } func TestSecurityCryptoBinds(t *testing.T) { vm := goja.New() - baseBinds(vm) - securityBinds(vm) + BindCore(vm) + BindSecurity(vm) sceneraios := []struct { js string @@ -888,8 +888,8 @@ func TestSecurityCryptoBinds(t *testing.T) { func TestSecurityRandomStringBinds(t *testing.T) { vm := goja.New() - baseBinds(vm) - securityBinds(vm) + BindCore(vm) + BindSecurity(vm) sceneraios := []struct { js string @@ -964,8 +964,8 @@ func TestSecurityJWTBinds(t *testing.T) { for _, s := range sceneraios { t.Run(s.name, func(t *testing.T) { vm := goja.New() - baseBinds(vm) - securityBinds(vm) + BindCore(vm) + BindSecurity(vm) _, err := vm.RunString(s.js) if err != nil { @@ -977,8 +977,8 @@ func TestSecurityJWTBinds(t *testing.T) { func TestSecurityEncryptAndDecryptBinds(t *testing.T) { vm := goja.New() - baseBinds(vm) - securityBinds(vm) + BindCore(vm) + BindSecurity(vm) _, err := vm.RunString(` const key = "abcdabcdabcdabcdabcdabcdabcdabcd" @@ -996,7 +996,7 @@ func TestSecurityEncryptAndDecryptBinds(t *testing.T) { } } -func TestFilesystemBinds(t *testing.T) { +func TestBindFilesystem(t *testing.T) { app, _ := tests.NewTestApp() defer app.Cleanup() @@ -1020,8 +1020,8 @@ func TestFilesystemBinds(t *testing.T) { vm.Set("tmpDir", tmpDir) vm.Set("testFile", filepath.Join(app.DataDir(), "data.db")) vm.Set("baseURL", srv.URL) - baseBinds(vm) - filesystemBinds(vm) + BindCore(vm) + BindFilesystem(vm) testBindsCount(vm, "$filesystem", 6, t) @@ -1116,24 +1116,24 @@ func TestFilesystemBinds(t *testing.T) { } } -func TestFormsBinds(t *testing.T) { +func TestBindForms(t *testing.T) { vm := goja.New() - formsBinds(vm) + BindForms(vm) testBindsCount(vm, "this", 4, t) } -func TestApisBindsCount(t *testing.T) { +func TestBindApisCount(t *testing.T) { vm := goja.New() - apisBinds(vm) + BindApis(vm) testBindsCount(vm, "this", 8, t) testBindsCount(vm, "$apis", 11, t) } -func TestApisBindsApiError(t *testing.T) { +func TestBindApisErrors(t *testing.T) { vm := goja.New() - apisBinds(vm) + BindApis(vm) scenarios := []struct { js string @@ -1190,8 +1190,8 @@ func TestLoadingDynamicModel(t *testing.T) { defer app.Cleanup() vm := goja.New() - baseBinds(vm) - dbxBinds(vm) + BindCore(vm) + BindDbx(vm) vm.Set("$app", app) _, err := vm.RunString(` @@ -1291,8 +1291,8 @@ func TestDynamicModelMapFieldCaching(t *testing.T) { defer app.Cleanup() vm := goja.New() - baseBinds(vm) - dbxBinds(vm) + BindCore(vm) + BindDbx(vm) vm.Set("$app", app) _, err := vm.RunString(` @@ -1350,8 +1350,8 @@ func TestLoadingArrayOf(t *testing.T) { defer app.Cleanup() vm := goja.New() - baseBinds(vm) - dbxBinds(vm) + BindCore(vm) + BindDbx(vm) vm.Set("$app", app) _, err := vm.RunString(` @@ -1391,18 +1391,18 @@ func TestLoadingArrayOf(t *testing.T) { } } -func TestHttpClientBindsCount(t *testing.T) { +func TestBindHttpClientCount(t *testing.T) { app, _ := tests.NewTestApp() defer app.Cleanup() vm := goja.New() - httpClientBinds(vm) + BindHttpClient(vm) testBindsCount(vm, "this", 2, t) // + FormData testBindsCount(vm, "$http", 1, t) } -func TestHttpClientBindsSend(t *testing.T) { +func TestBindHttpClientSend(t *testing.T) { t.Parallel() // start a test server @@ -1447,8 +1447,8 @@ func TestHttpClientBindsSend(t *testing.T) { defer server.Close() vm := goja.New() - baseBinds(vm) - httpClientBinds(vm) + BindCore(vm) + BindHttpClient(vm) vm.Set("testURL", server.URL) _, err := vm.RunString(` @@ -1626,7 +1626,7 @@ func TestHooksBinds(t *testing.T) { vmFactory := func() *goja.Runtime { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("$app", app) vm.Set("result", result) return vm @@ -1712,7 +1712,7 @@ func TestHooksExceptionUnwrapping(t *testing.T) { vmFactory := func() *goja.Runtime { vm := goja.New() - baseBinds(vm) + BindCore(vm) vm.Set("$app", app) vm.Set("goErr", goErr) return vm @@ -1766,8 +1766,8 @@ func TestRouterBinds(t *testing.T) { vmFactory := func() *goja.Runtime { vm := goja.New() - baseBinds(vm) - apisBinds(vm) + BindCore(vm) + BindApis(vm) vm.Set("$app", app) vm.Set("result", result) return vm @@ -1855,16 +1855,16 @@ func TestRouterBinds(t *testing.T) { } } -func TestFilepathBindsCount(t *testing.T) { +func TestBindFilepathCount(t *testing.T) { vm := goja.New() - filepathBinds(vm) + BindFilepath(vm) testBindsCount(vm, "$filepath", 15, t) } -func TestOsBindsCount(t *testing.T) { +func TestBindOsCount(t *testing.T) { vm := goja.New() - osBinds(vm) + BindOs(vm) testBindsCount(vm, "$os", 20, t) } diff --git a/plugins/jsvm/internal/types/generated/types.d.ts b/plugins/jsvm/internal/types/generated/types.d.ts index 52898b79..fff98a65 100644 --- a/plugins/jsvm/internal/types/generated/types.d.ts +++ b/plugins/jsvm/internal/types/generated/types.d.ts @@ -1,4 +1,4 @@ -// 1775386251 +// 1776520206 // GENERATED CODE - DO NOT MODIFY BY HAND // ------------------------------------------------------------------- @@ -1948,8 +1948,8 @@ namespace os { * than ReadFrom. This is used to permit ReadFrom to call io.Copy * without leading to a recursive call to ReadFrom. */ - type _sqpeBfS = noReadFrom&File - interface fileWithoutReadFrom extends _sqpeBfS { + type _suctCDC = noReadFrom&File + interface fileWithoutReadFrom extends _suctCDC { } interface File { /** @@ -1993,8 +1993,8 @@ namespace os { * than WriteTo. This is used to permit WriteTo to call io.Copy * without leading to a recursive call to WriteTo. */ - type _sEowvrW = noWriteTo&File - interface fileWithoutWriteTo extends _sEowvrW { + type _stDWZwf = noWriteTo&File + interface fileWithoutWriteTo extends _stDWZwf { } interface File { /** @@ -2940,8 +2940,8 @@ namespace os { * * The methods of File are safe for concurrent use. */ - type _sUQXiYX = file - interface File extends _sUQXiYX { + type _svIqMNy = file + interface File extends _svIqMNy { } /** * A FileInfo describes a file and is returned by [Stat] and [Lstat]. @@ -2991,6 +2991,366 @@ namespace os { } } +/** + * Package filepath implements utility routines for manipulating filename paths + * in a way compatible with the target operating system-defined file paths. + * + * The filepath package uses either forward slashes or backslashes, + * depending on the operating system. To process paths such as URLs + * that always use forward slashes regardless of the operating + * system, see the [path] package. + */ +namespace filepath { + interface match { + /** + * Match reports whether name matches the shell file name pattern. + * The pattern syntax is: + * + * ``` + * pattern: + * { term } + * term: + * '*' matches any sequence of non-Separator characters + * '?' matches any single non-Separator character + * '[' [ '^' ] { character-range } ']' + * character class (must be non-empty) + * c matches character c (c != '*', '?', '\\', '[') + * '\\' c matches character c + * + * character-range: + * c matches character c (c != '\\', '-', ']') + * '\\' c matches character c + * lo '-' hi matches character c for lo <= c <= hi + * ``` + * + * Match requires pattern to match all of name, not just a substring. + * The only possible returned error is [ErrBadPattern], when pattern + * is malformed. + * + * On Windows, escaping is disabled. Instead, '\\' is treated as + * path separator. + */ + (pattern: string, name: string): boolean + } + interface glob { + /** + * Glob returns the names of all files matching pattern or nil + * if there is no matching file. The syntax of patterns is the same + * as in [Match]. The pattern may describe hierarchical names such as + * /usr/*\/bin/ed (assuming the [Separator] is '/'). + * + * Glob ignores file system errors such as I/O errors reading directories. + * The only possible returned error is [ErrBadPattern], when pattern + * is malformed. + */ + (pattern: string): Array + } + interface clean { + /** + * Clean returns the shortest path name equivalent to path + * by purely lexical processing. It applies the following rules + * iteratively until no further processing can be done: + * + * 1. Replace multiple [Separator] elements with a single one. + * 2. Eliminate each . path name element (the current directory). + * 3. Eliminate each inner .. path name element (the parent directory) + * ``` + * along with the non-.. element that precedes it. + * ``` + * 4. Eliminate .. elements that begin a rooted path: + * ``` + * that is, replace "/.." by "/" at the beginning of a path, + * assuming Separator is '/'. + * ``` + * + * The returned path ends in a slash only if it represents a root directory, + * such as "/" on Unix or `C:\` on Windows. + * + * Finally, any occurrences of slash are replaced by Separator. + * + * If the result of this process is an empty string, Clean + * returns the string ".". + * + * On Windows, Clean does not modify the volume name other than to replace + * occurrences of "/" with `\`. + * For example, Clean("//host/share/../x") returns `\\host\share\x`. + * + * See also Rob Pike, “Lexical File Names in Plan 9 or + * Getting Dot-Dot Right,” + * https://9p.io/sys/doc/lexnames.html + */ + (path: string): string + } + interface isLocal { + /** + * IsLocal reports whether path, using lexical analysis only, has all of these properties: + * + * ``` + * - is within the subtree rooted at the directory in which path is evaluated + * - is not an absolute path + * - is not empty + * - on Windows, is not a reserved name such as "NUL" + * ``` + * + * If IsLocal(path) returns true, then + * Join(base, path) will always produce a path contained within base and + * Clean(path) will always produce an unrooted path with no ".." path elements. + * + * IsLocal is a purely lexical operation. + * In particular, it does not account for the effect of any symbolic links + * that may exist in the filesystem. + */ + (path: string): boolean + } + interface localize { + /** + * Localize converts a slash-separated path into an operating system path. + * The input path must be a valid path as reported by [io/fs.ValidPath]. + * + * Localize returns an error if the path cannot be represented by the operating system. + * For example, the path a\b is rejected on Windows, on which \ is a separator + * character and cannot be part of a filename. + * + * The path returned by Localize will always be local, as reported by IsLocal. + */ + (path: string): string + } + interface toSlash { + /** + * ToSlash returns the result of replacing each separator character + * in path with a slash ('/') character. Multiple separators are + * replaced by multiple slashes. + */ + (path: string): string + } + interface fromSlash { + /** + * FromSlash returns the result of replacing each slash ('/') character + * in path with a separator character. Multiple slashes are replaced + * by multiple separators. + * + * See also the Localize function, which converts a slash-separated path + * as used by the io/fs package to an operating system path. + */ + (path: string): string + } + interface splitList { + /** + * SplitList splits a list of paths joined by the OS-specific [ListSeparator], + * usually found in PATH or GOPATH environment variables. + * Unlike strings.Split, SplitList returns an empty slice when passed an empty + * string. + */ + (path: string): Array + } + interface split { + /** + * Split splits path immediately following the final [Separator], + * separating it into a directory and file name component. + * If there is no Separator in path, Split returns an empty dir + * and file set to path. + * The returned values have the property that path = dir+file. + */ + (path: string): [string, string] + } + interface join { + /** + * Join joins any number of path elements into a single path, + * separating them with an OS specific [Separator]. Empty elements + * are ignored. The result is Cleaned. However, if the argument + * list is empty or all its elements are empty, Join returns + * an empty string. + * On Windows, the result will only be a UNC path if the first + * non-empty element is a UNC path. + */ + (...elem: string[]): string + } + interface ext { + /** + * Ext returns the file name extension used by path. + * The extension is the suffix beginning at the final dot + * in the final element of path; it is empty if there is + * no dot. + */ + (path: string): string + } + interface evalSymlinks { + /** + * EvalSymlinks returns the path name after the evaluation of any symbolic + * links. + * If path is relative the result will be relative to the current directory, + * unless one of the components is an absolute symbolic link. + * EvalSymlinks calls [Clean] on the result. + */ + (path: string): string + } + interface isAbs { + /** + * IsAbs reports whether the path is absolute. + */ + (path: string): boolean + } + interface abs { + /** + * Abs returns an absolute representation of path. + * If the path is not absolute it will be joined with the current + * working directory to turn it into an absolute path. The absolute + * path name for a given file is not guaranteed to be unique. + * Abs calls [Clean] on the result. + */ + (path: string): string + } + interface rel { + /** + * Rel returns a relative path that is lexically equivalent to targpath when + * joined to basepath with an intervening separator. That is, + * [Join](basepath, Rel(basepath, targpath)) is equivalent to targpath itself. + * On success, the returned path will always be relative to basepath, + * even if basepath and targpath share no elements. + * An error is returned if targpath can't be made relative to basepath or if + * knowing the current working directory would be necessary to compute it. + * Rel calls [Clean] on the result. + */ + (basepath: string, targpath: string): string + } + /** + * WalkFunc is the type of the function called by [Walk] to visit each + * file or directory. + * + * The path argument contains the argument to Walk as a prefix. + * That is, if Walk is called with root argument "dir" and finds a file + * named "a" in that directory, the walk function will be called with + * argument "dir/a". + * + * The directory and file are joined with Join, which may clean the + * directory name: if Walk is called with the root argument "x/../dir" + * and finds a file named "a" in that directory, the walk function will + * be called with argument "dir/a", not "x/../dir/a". + * + * The info argument is the fs.FileInfo for the named path. + * + * The error result returned by the function controls how Walk continues. + * If the function returns the special value [SkipDir], Walk skips the + * current directory (path if info.IsDir() is true, otherwise path's + * parent directory). If the function returns the special value [SkipAll], + * Walk skips all remaining files and directories. Otherwise, if the function + * returns a non-nil error, Walk stops entirely and returns that error. + * + * The err argument reports an error related to path, signaling that Walk + * will not walk into that directory. The function can decide how to + * handle that error; as described earlier, returning the error will + * cause Walk to stop walking the entire tree. + * + * Walk calls the function with a non-nil err argument in two cases. + * + * First, if an [os.Lstat] on the root directory or any directory or file + * in the tree fails, Walk calls the function with path set to that + * directory or file's path, info set to nil, and err set to the error + * from os.Lstat. + * + * Second, if a directory's Readdirnames method fails, Walk calls the + * function with path set to the directory's path, info, set to an + * [fs.FileInfo] describing the directory, and err set to the error from + * Readdirnames. + */ + interface WalkFunc {(path: string, info: fs.FileInfo, err: Error): void } + interface walkDir { + /** + * WalkDir walks the file tree rooted at root, calling fn for each file or + * directory in the tree, including root. + * + * All errors that arise visiting files and directories are filtered by fn: + * see the [fs.WalkDirFunc] documentation for details. + * + * The files are walked in lexical order, which makes the output deterministic + * but requires WalkDir to read an entire directory into memory before proceeding + * to walk that directory. + * + * WalkDir does not follow symbolic links. + * + * WalkDir calls fn with paths that use the separator character appropriate + * for the operating system. This is unlike [io/fs.WalkDir], which always + * uses slash separated paths. + */ + (root: string, fn: fs.WalkDirFunc): void + } + interface walk { + /** + * Walk walks the file tree rooted at root, calling fn for each file or + * directory in the tree, including root. + * + * All errors that arise visiting files and directories are filtered by fn: + * see the [WalkFunc] documentation for details. + * + * The files are walked in lexical order, which makes the output deterministic + * but requires Walk to read an entire directory into memory before proceeding + * to walk that directory. + * + * Walk does not follow symbolic links. + * + * Walk is less efficient than [WalkDir], introduced in Go 1.16, + * which avoids calling os.Lstat on every visited file or directory. + */ + (root: string, fn: WalkFunc): void + } + interface base { + /** + * Base returns the last element of path. + * Trailing path separators are removed before extracting the last element. + * If the path is empty, Base returns ".". + * If the path consists entirely of separators, Base returns a single separator. + */ + (path: string): string + } + interface dir { + /** + * Dir returns all but the last element of path, typically the path's directory. + * After dropping the final element, Dir calls [Clean] on the path and trailing + * slashes are removed. + * If the path is empty, Dir returns ".". + * If the path consists entirely of separators, Dir returns a single separator. + * The returned path does not end in a separator unless it is the root directory. + */ + (path: string): string + } + interface volumeName { + /** + * VolumeName returns leading volume name. + * Given "C:\foo\bar" it returns "C:" on Windows. + * Given "\\host\share\foo" it returns "\\host\share". + * On other platforms it returns "". + */ + (path: string): string + } + interface hasPrefix { + /** + * HasPrefix exists for historical compatibility and should not be used. + * + * Deprecated: HasPrefix does not respect path boundaries and + * does not ignore case when required. + */ + (p: string, prefix: string): boolean + } +} + +/** + * Package validation provides configurable and extensible rules for validating data of various types. + */ +namespace ozzo_validation { + /** + * Error interface represents an validation error + */ + interface Error { + [key:string]: any; + error(): string + code(): string + message(): string + setMessage(_arg0: string): Error + params(): _TygojaDict + setParams(_arg0: _TygojaDict): Error + } +} + /** * Package dbx provides a set of DB-agnostic and easy-to-use query building methods for relational databases. */ @@ -3327,14 +3687,14 @@ namespace dbx { /** * MssqlBuilder is the builder for SQL Server databases. */ - type _sCHEhNd = BaseBuilder - interface MssqlBuilder extends _sCHEhNd { + type _sHLDdri = BaseBuilder + interface MssqlBuilder extends _sHLDdri { } /** * MssqlQueryBuilder is the query builder for SQL Server databases. */ - type _sUjmedL = BaseQueryBuilder - interface MssqlQueryBuilder extends _sUjmedL { + type _sWCeSkQ = BaseQueryBuilder + interface MssqlQueryBuilder extends _sWCeSkQ { } interface newMssqlBuilder { /** @@ -3405,8 +3765,8 @@ namespace dbx { /** * MysqlBuilder is the builder for MySQL databases. */ - type _sSFtjLm = BaseBuilder - interface MysqlBuilder extends _sSFtjLm { + type _sJqClKK = BaseBuilder + interface MysqlBuilder extends _sJqClKK { } interface newMysqlBuilder { /** @@ -3481,14 +3841,14 @@ namespace dbx { /** * OciBuilder is the builder for Oracle databases. */ - type _sCYaXFI = BaseBuilder - interface OciBuilder extends _sCYaXFI { + type _stzmBoy = BaseBuilder + interface OciBuilder extends _stzmBoy { } /** * OciQueryBuilder is the query builder for Oracle databases. */ - type _sLcNFEh = BaseQueryBuilder - interface OciQueryBuilder extends _sLcNFEh { + type _sjGRsll = BaseQueryBuilder + interface OciQueryBuilder extends _sjGRsll { } interface newOciBuilder { /** @@ -3551,8 +3911,8 @@ namespace dbx { /** * PgsqlBuilder is the builder for PostgreSQL databases. */ - type _suaFvTr = BaseBuilder - interface PgsqlBuilder extends _suaFvTr { + type _sePvgMC = BaseBuilder + interface PgsqlBuilder extends _sePvgMC { } interface newPgsqlBuilder { /** @@ -3619,8 +3979,8 @@ namespace dbx { /** * SqliteQueryBuilder is the query builder for SQLite databases. */ - type _spXNsOQ = BaseQueryBuilder - interface SqliteQueryBuilder extends _spXNsOQ { + type _sDukgXi = BaseQueryBuilder + interface SqliteQueryBuilder extends _sDukgXi { } interface SqliteQueryBuilder { /** @@ -3641,8 +4001,8 @@ namespace dbx { /** * SqliteBuilder is the builder for SQLite databases. */ - type _sibotlw = BaseBuilder - interface SqliteBuilder extends _sibotlw { + type _sbnzcXy = BaseBuilder + interface SqliteBuilder extends _sbnzcXy { } interface newSqliteBuilder { /** @@ -3741,8 +4101,8 @@ namespace dbx { /** * StandardBuilder is the builder that is used by DB for an unknown driver. */ - type _syRszNu = BaseBuilder - interface StandardBuilder extends _syRszNu { + type _sgnvzTj = BaseBuilder + interface StandardBuilder extends _sgnvzTj { } interface newStandardBuilder { /** @@ -3808,8 +4168,8 @@ namespace dbx { * DB enhances sql.DB by providing a set of DB-agnostic query building methods. * DB allows easier query building and population of data into Go variables. */ - type _sNsFARL = Builder - interface DB extends _sNsFARL { + type _ssRtHfn = Builder + interface DB extends _ssRtHfn { /** * FieldMapper maps struct fields to DB columns. Defaults to DefaultFieldMapFunc. */ @@ -4639,8 +4999,8 @@ namespace dbx { * Rows enhances sql.Rows by providing additional data query methods. * Rows can be obtained by calling Query.Rows(). It is mainly used to populate data row by row. */ - type _sDlLhRs = sql.Rows - interface Rows extends _sDlLhRs { + type _sWZmqAq = sql.Rows + interface Rows extends _sWZmqAq { } interface Rows { /** @@ -5015,8 +5375,8 @@ namespace dbx { }): string } interface structInfo { } - type _sMdGugf = structInfo - interface structValue extends _sMdGugf { + type _siCTHGT = structInfo + interface structValue extends _siCTHGT { } interface fieldInfo { } @@ -5055,8 +5415,8 @@ namespace dbx { /** * Tx enhances sql.Tx with additional querying methods. */ - type _sliGPQb = Builder - interface Tx extends _sliGPQb { + type _siOcSEO = Builder + interface Tx extends _siOcSEO { } interface Tx { /** @@ -5072,348 +5432,6 @@ namespace dbx { } } -/** - * Package filepath implements utility routines for manipulating filename paths - * in a way compatible with the target operating system-defined file paths. - * - * The filepath package uses either forward slashes or backslashes, - * depending on the operating system. To process paths such as URLs - * that always use forward slashes regardless of the operating - * system, see the [path] package. - */ -namespace filepath { - interface match { - /** - * Match reports whether name matches the shell file name pattern. - * The pattern syntax is: - * - * ``` - * pattern: - * { term } - * term: - * '*' matches any sequence of non-Separator characters - * '?' matches any single non-Separator character - * '[' [ '^' ] { character-range } ']' - * character class (must be non-empty) - * c matches character c (c != '*', '?', '\\', '[') - * '\\' c matches character c - * - * character-range: - * c matches character c (c != '\\', '-', ']') - * '\\' c matches character c - * lo '-' hi matches character c for lo <= c <= hi - * ``` - * - * Match requires pattern to match all of name, not just a substring. - * The only possible returned error is [ErrBadPattern], when pattern - * is malformed. - * - * On Windows, escaping is disabled. Instead, '\\' is treated as - * path separator. - */ - (pattern: string, name: string): boolean - } - interface glob { - /** - * Glob returns the names of all files matching pattern or nil - * if there is no matching file. The syntax of patterns is the same - * as in [Match]. The pattern may describe hierarchical names such as - * /usr/*\/bin/ed (assuming the [Separator] is '/'). - * - * Glob ignores file system errors such as I/O errors reading directories. - * The only possible returned error is [ErrBadPattern], when pattern - * is malformed. - */ - (pattern: string): Array - } - interface clean { - /** - * Clean returns the shortest path name equivalent to path - * by purely lexical processing. It applies the following rules - * iteratively until no further processing can be done: - * - * 1. Replace multiple [Separator] elements with a single one. - * 2. Eliminate each . path name element (the current directory). - * 3. Eliminate each inner .. path name element (the parent directory) - * ``` - * along with the non-.. element that precedes it. - * ``` - * 4. Eliminate .. elements that begin a rooted path: - * ``` - * that is, replace "/.." by "/" at the beginning of a path, - * assuming Separator is '/'. - * ``` - * - * The returned path ends in a slash only if it represents a root directory, - * such as "/" on Unix or `C:\` on Windows. - * - * Finally, any occurrences of slash are replaced by Separator. - * - * If the result of this process is an empty string, Clean - * returns the string ".". - * - * On Windows, Clean does not modify the volume name other than to replace - * occurrences of "/" with `\`. - * For example, Clean("//host/share/../x") returns `\\host\share\x`. - * - * See also Rob Pike, “Lexical File Names in Plan 9 or - * Getting Dot-Dot Right,” - * https://9p.io/sys/doc/lexnames.html - */ - (path: string): string - } - interface isLocal { - /** - * IsLocal reports whether path, using lexical analysis only, has all of these properties: - * - * ``` - * - is within the subtree rooted at the directory in which path is evaluated - * - is not an absolute path - * - is not empty - * - on Windows, is not a reserved name such as "NUL" - * ``` - * - * If IsLocal(path) returns true, then - * Join(base, path) will always produce a path contained within base and - * Clean(path) will always produce an unrooted path with no ".." path elements. - * - * IsLocal is a purely lexical operation. - * In particular, it does not account for the effect of any symbolic links - * that may exist in the filesystem. - */ - (path: string): boolean - } - interface localize { - /** - * Localize converts a slash-separated path into an operating system path. - * The input path must be a valid path as reported by [io/fs.ValidPath]. - * - * Localize returns an error if the path cannot be represented by the operating system. - * For example, the path a\b is rejected on Windows, on which \ is a separator - * character and cannot be part of a filename. - * - * The path returned by Localize will always be local, as reported by IsLocal. - */ - (path: string): string - } - interface toSlash { - /** - * ToSlash returns the result of replacing each separator character - * in path with a slash ('/') character. Multiple separators are - * replaced by multiple slashes. - */ - (path: string): string - } - interface fromSlash { - /** - * FromSlash returns the result of replacing each slash ('/') character - * in path with a separator character. Multiple slashes are replaced - * by multiple separators. - * - * See also the Localize function, which converts a slash-separated path - * as used by the io/fs package to an operating system path. - */ - (path: string): string - } - interface splitList { - /** - * SplitList splits a list of paths joined by the OS-specific [ListSeparator], - * usually found in PATH or GOPATH environment variables. - * Unlike strings.Split, SplitList returns an empty slice when passed an empty - * string. - */ - (path: string): Array - } - interface split { - /** - * Split splits path immediately following the final [Separator], - * separating it into a directory and file name component. - * If there is no Separator in path, Split returns an empty dir - * and file set to path. - * The returned values have the property that path = dir+file. - */ - (path: string): [string, string] - } - interface join { - /** - * Join joins any number of path elements into a single path, - * separating them with an OS specific [Separator]. Empty elements - * are ignored. The result is Cleaned. However, if the argument - * list is empty or all its elements are empty, Join returns - * an empty string. - * On Windows, the result will only be a UNC path if the first - * non-empty element is a UNC path. - */ - (...elem: string[]): string - } - interface ext { - /** - * Ext returns the file name extension used by path. - * The extension is the suffix beginning at the final dot - * in the final element of path; it is empty if there is - * no dot. - */ - (path: string): string - } - interface evalSymlinks { - /** - * EvalSymlinks returns the path name after the evaluation of any symbolic - * links. - * If path is relative the result will be relative to the current directory, - * unless one of the components is an absolute symbolic link. - * EvalSymlinks calls [Clean] on the result. - */ - (path: string): string - } - interface isAbs { - /** - * IsAbs reports whether the path is absolute. - */ - (path: string): boolean - } - interface abs { - /** - * Abs returns an absolute representation of path. - * If the path is not absolute it will be joined with the current - * working directory to turn it into an absolute path. The absolute - * path name for a given file is not guaranteed to be unique. - * Abs calls [Clean] on the result. - */ - (path: string): string - } - interface rel { - /** - * Rel returns a relative path that is lexically equivalent to targpath when - * joined to basepath with an intervening separator. That is, - * [Join](basepath, Rel(basepath, targpath)) is equivalent to targpath itself. - * On success, the returned path will always be relative to basepath, - * even if basepath and targpath share no elements. - * An error is returned if targpath can't be made relative to basepath or if - * knowing the current working directory would be necessary to compute it. - * Rel calls [Clean] on the result. - */ - (basepath: string, targpath: string): string - } - /** - * WalkFunc is the type of the function called by [Walk] to visit each - * file or directory. - * - * The path argument contains the argument to Walk as a prefix. - * That is, if Walk is called with root argument "dir" and finds a file - * named "a" in that directory, the walk function will be called with - * argument "dir/a". - * - * The directory and file are joined with Join, which may clean the - * directory name: if Walk is called with the root argument "x/../dir" - * and finds a file named "a" in that directory, the walk function will - * be called with argument "dir/a", not "x/../dir/a". - * - * The info argument is the fs.FileInfo for the named path. - * - * The error result returned by the function controls how Walk continues. - * If the function returns the special value [SkipDir], Walk skips the - * current directory (path if info.IsDir() is true, otherwise path's - * parent directory). If the function returns the special value [SkipAll], - * Walk skips all remaining files and directories. Otherwise, if the function - * returns a non-nil error, Walk stops entirely and returns that error. - * - * The err argument reports an error related to path, signaling that Walk - * will not walk into that directory. The function can decide how to - * handle that error; as described earlier, returning the error will - * cause Walk to stop walking the entire tree. - * - * Walk calls the function with a non-nil err argument in two cases. - * - * First, if an [os.Lstat] on the root directory or any directory or file - * in the tree fails, Walk calls the function with path set to that - * directory or file's path, info set to nil, and err set to the error - * from os.Lstat. - * - * Second, if a directory's Readdirnames method fails, Walk calls the - * function with path set to the directory's path, info, set to an - * [fs.FileInfo] describing the directory, and err set to the error from - * Readdirnames. - */ - interface WalkFunc {(path: string, info: fs.FileInfo, err: Error): void } - interface walkDir { - /** - * WalkDir walks the file tree rooted at root, calling fn for each file or - * directory in the tree, including root. - * - * All errors that arise visiting files and directories are filtered by fn: - * see the [fs.WalkDirFunc] documentation for details. - * - * The files are walked in lexical order, which makes the output deterministic - * but requires WalkDir to read an entire directory into memory before proceeding - * to walk that directory. - * - * WalkDir does not follow symbolic links. - * - * WalkDir calls fn with paths that use the separator character appropriate - * for the operating system. This is unlike [io/fs.WalkDir], which always - * uses slash separated paths. - */ - (root: string, fn: fs.WalkDirFunc): void - } - interface walk { - /** - * Walk walks the file tree rooted at root, calling fn for each file or - * directory in the tree, including root. - * - * All errors that arise visiting files and directories are filtered by fn: - * see the [WalkFunc] documentation for details. - * - * The files are walked in lexical order, which makes the output deterministic - * but requires Walk to read an entire directory into memory before proceeding - * to walk that directory. - * - * Walk does not follow symbolic links. - * - * Walk is less efficient than [WalkDir], introduced in Go 1.16, - * which avoids calling os.Lstat on every visited file or directory. - */ - (root: string, fn: WalkFunc): void - } - interface base { - /** - * Base returns the last element of path. - * Trailing path separators are removed before extracting the last element. - * If the path is empty, Base returns ".". - * If the path consists entirely of separators, Base returns a single separator. - */ - (path: string): string - } - interface dir { - /** - * Dir returns all but the last element of path, typically the path's directory. - * After dropping the final element, Dir calls [Clean] on the path and trailing - * slashes are removed. - * If the path is empty, Dir returns ".". - * If the path consists entirely of separators, Dir returns a single separator. - * The returned path does not end in a separator unless it is the root directory. - */ - (path: string): string - } - interface volumeName { - /** - * VolumeName returns leading volume name. - * Given "C:\foo\bar" it returns "C:" on Windows. - * Given "\\host\share\foo" it returns "\\host\share". - * On other platforms it returns "". - */ - (path: string): string - } - interface hasPrefix { - /** - * HasPrefix exists for historical compatibility and should not be used. - * - * Deprecated: HasPrefix does not respect path boundaries and - * does not ignore case when required. - */ - (p: string, prefix: string): boolean - } -} - namespace security { interface s256Challenge { /** @@ -5557,129 +5575,6 @@ namespace security { } } -/** - * Package template is a thin wrapper around the standard html/template - * and text/template packages that implements a convenient registry to - * load and cache templates on the fly concurrently. - * - * It was created to assist the JSVM plugin HTML rendering, but could be used in other Go code. - * - * Example: - * - * ``` - * registry := template.NewRegistry() - * - * html1, err := registry.LoadFiles( - * // the files set wil be parsed only once and then cached - * "layout.html", - * "content.html", - * ).Render(map[string]any{"name": "John"}) - * - * html2, err := registry.LoadFiles( - * // reuse the already parsed and cached files set - * "layout.html", - * "content.html", - * ).Render(map[string]any{"name": "Jane"}) - * ``` - */ -namespace template { - interface newRegistry { - /** - * NewRegistry creates and initializes a new templates registry with - * some defaults (eg. global "raw" template function for unescaped HTML). - * - * Use the Registry.Load* methods to load templates into the registry. - */ - (): (Registry) - } - /** - * Registry defines a templates registry that is safe to be used by multiple goroutines. - * - * Use the Registry.Load* methods to load templates into the registry. - */ - interface Registry { - } - interface Registry { - /** - * AddFuncs registers new global template functions. - * - * The key of each map entry is the function name that will be used in the templates. - * If a function with the map entry name already exists it will be replaced with the new one. - * - * The value of each map entry is a function that must have either a - * single return value, or two return values of which the second has type error. - * - * Example: - * - * ``` - * r.AddFuncs(map[string]any{ - * "toUpper": func(str string) string { - * return strings.ToUppser(str) - * }, - * ... - * }) - * ``` - */ - addFuncs(funcs: _TygojaDict): (Registry) - } - interface Registry { - /** - * LoadFiles caches (if not already) the specified filenames set as a - * single template and returns a ready to use Renderer instance. - * - * There must be at least 1 filename specified. - */ - loadFiles(...filenames: string[]): (Renderer) - } - interface Registry { - /** - * LoadString caches (if not already) the specified inline string as a - * single template and returns a ready to use Renderer instance. - */ - loadString(text: string): (Renderer) - } - interface Registry { - /** - * LoadFS caches (if not already) the specified fs and globPatterns - * pair as single template and returns a ready to use Renderer instance. - * - * There must be at least 1 file matching the provided globPattern(s) - * (note that most file names serves as glob patterns matching themselves). - */ - loadFS(fsys: fs.FS, ...globPatterns: string[]): (Renderer) - } - /** - * Renderer defines a single parsed template. - */ - interface Renderer { - } - interface Renderer { - /** - * Render executes the template with the specified data as the dot object - * and returns the result as plain string. - */ - render(data: any): string - } -} - -/** - * Package validation provides configurable and extensible rules for validating data of various types. - */ -namespace ozzo_validation { - /** - * Error interface represents an validation error - */ - interface Error { - [key:string]: any; - error(): string - code(): string - message(): string - setMessage(_arg0: string): Error - params(): _TygojaDict - setParams(_arg0: _TygojaDict): Error - } -} - namespace filesystem { /** * FileReader defines an interface for a file resource reader. @@ -5776,8 +5671,8 @@ namespace filesystem { */ open(): io.ReadSeekCloser } - type _sXCJRsA = bytes.Reader - interface bytesReadSeekCloser extends _sXCJRsA { + type _sUikSqo = bytes.Reader + interface bytesReadSeekCloser extends _sUikSqo { } interface bytesReadSeekCloser { /** @@ -5961,6 +5856,111 @@ namespace filesystem { } } +/** + * Package template is a thin wrapper around the standard html/template + * and text/template packages that implements a convenient registry to + * load and cache templates on the fly concurrently. + * + * It was created to assist the JSVM plugin HTML rendering, but could be used in other Go code. + * + * Example: + * + * ``` + * registry := template.NewRegistry() + * + * html1, err := registry.LoadFiles( + * // the files set wil be parsed only once and then cached + * "layout.html", + * "content.html", + * ).Render(map[string]any{"name": "John"}) + * + * html2, err := registry.LoadFiles( + * // reuse the already parsed and cached files set + * "layout.html", + * "content.html", + * ).Render(map[string]any{"name": "Jane"}) + * ``` + */ +namespace template { + interface newRegistry { + /** + * NewRegistry creates and initializes a new templates registry with + * some defaults (eg. global "raw" template function for unescaped HTML). + * + * Use the Registry.Load* methods to load templates into the registry. + */ + (): (Registry) + } + /** + * Registry defines a templates registry that is safe to be used by multiple goroutines. + * + * Use the Registry.Load* methods to load templates into the registry. + */ + interface Registry { + } + interface Registry { + /** + * AddFuncs registers new global template functions. + * + * The key of each map entry is the function name that will be used in the templates. + * If a function with the map entry name already exists it will be replaced with the new one. + * + * The value of each map entry is a function that must have either a + * single return value, or two return values of which the second has type error. + * + * Example: + * + * ``` + * r.AddFuncs(map[string]any{ + * "toUpper": func(str string) string { + * return strings.ToUppser(str) + * }, + * ... + * }) + * ``` + */ + addFuncs(funcs: _TygojaDict): (Registry) + } + interface Registry { + /** + * LoadFiles caches (if not already) the specified filenames set as a + * single template and returns a ready to use Renderer instance. + * + * There must be at least 1 filename specified. + */ + loadFiles(...filenames: string[]): (Renderer) + } + interface Registry { + /** + * LoadString caches (if not already) the specified inline string as a + * single template and returns a ready to use Renderer instance. + */ + loadString(text: string): (Renderer) + } + interface Registry { + /** + * LoadFS caches (if not already) the specified fs and globPatterns + * pair as single template and returns a ready to use Renderer instance. + * + * There must be at least 1 file matching the provided globPattern(s) + * (note that most file names serves as glob patterns matching themselves). + */ + loadFS(fsys: fs.FS, ...globPatterns: string[]): (Renderer) + } + /** + * Renderer defines a single parsed template. + */ + interface Renderer { + } + interface Renderer { + /** + * Render executes the template with the specified data as the dot object + * and returns the result as plain string. + */ + render(data: any): string + } +} + /** * Package exec runs external commands. It wraps os.StartProcess to make it * easier to remap stdin and stdout, connect I/O with pipes, and do other @@ -6381,6 +6381,16 @@ namespace core { * "dangerousSelectQuery" argument must come only from trusted input! */ createViewFields(dangerousSelectQuery: string): FieldsList + /** + * DryRunView executes the provided query by creating a temporary view + * collection and returning a sample of the resulting query records (if valid). + * + * The same caveats from CreateViewFields apply here too. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "dangerousSelectQuery" argument must come only from trusted input! + */ + dryRunView(dangerousSelectQuery: string, sampleSize: number): (DryRunViewResult) /** * FindRecordByViewFile returns the original Record of the provided view collection file. */ @@ -7745,8 +7755,8 @@ namespace core { /** * AuthOrigin defines a Record proxy for working with the authOrigins collection. */ - type _sHgvaxY = Record - interface AuthOrigin extends _sHgvaxY { + type _scTBnOT = Record + interface AuthOrigin extends _scTBnOT { } interface newAuthOrigin { /** @@ -8491,8 +8501,8 @@ namespace core { /** * @todo experiment eventually replacing the rules *string with a struct? */ - type _sGzXAzW = BaseModel - interface baseCollection extends _sGzXAzW { + type _sDHXMrV = BaseModel + interface baseCollection extends _sDHXMrV { listRule?: string viewRule?: string createRule?: string @@ -8519,8 +8529,8 @@ namespace core { /** * Collection defines the table, fields and various options related to a set of records. */ - type _sRMHUSX = baseCollection&collectionAuthOptions&collectionViewOptions - interface Collection extends _sRMHUSX { + type _sSFIpTf = baseCollection&collectionAuthOptions&collectionViewOptions + interface Collection extends _sSFIpTf { } interface newCollection { /** @@ -9530,8 +9540,8 @@ namespace core { /** * RequestEvent defines the PocketBase router handler event. */ - type _seycyrn = router.Event - interface RequestEvent extends _seycyrn { + type _sFNHWWc = router.Event + interface RequestEvent extends _sFNHWWc { app: App auth?: Record } @@ -9591,8 +9601,8 @@ namespace core { */ clone(): (RequestInfo) } - type _sOHvNTa = hook.Event&RequestEvent - interface BatchRequestEvent extends _sOHvNTa { + type _smofDkV = hook.Event&RequestEvent + interface BatchRequestEvent extends _smofDkV { batch: Array<(InternalRequest | undefined)> } interface InternalRequest { @@ -9627,26 +9637,31 @@ namespace core { collection?: Collection } interface baseCollectionEventData { + /** + * @todo consider storing the original collection name and use that as a tag + * to avoid the ambiguity when the collection is being modified (#7613); + * for new collection also maybe return empty tags? + */ tags(): Array } - type _sBLZMfk = hook.Event - interface BootstrapEvent extends _sBLZMfk { + type _sAkfpmx = hook.Event + interface BootstrapEvent extends _sAkfpmx { app: App } - type _sKvnHjI = hook.Event - interface TerminateEvent extends _sKvnHjI { + type _smyBnni = hook.Event + interface TerminateEvent extends _smyBnni { app: App isRestart: boolean } - type _syHyPDy = hook.Event - interface BackupEvent extends _syHyPDy { + type _ssgtYuq = hook.Event + interface BackupEvent extends _ssgtYuq { app: App context: context.Context name: string // the name of the backup to create/restore. exclude: Array // list of dir entries to exclude from the backup create/restore. } - type _scSvdOO = hook.Event - interface ServeEvent extends _scSvdOO { + type _siNDrxi = hook.Event + interface ServeEvent extends _siNDrxi { app: App router?: router.Router server?: http.Server @@ -9674,32 +9689,50 @@ namespace core { * Set it to nil if you want to skip the installer. */ installerFunc: (app: App, systemSuperuser: Record, baseURL: string) => void + /** + * @todo experimental + * + * UIExtensions is a list with the superuser UI extensions. + */ + uiExtensions: Array } - type _suSufTZ = hook.Event&RequestEvent - interface SettingsListRequestEvent extends _suSufTZ { + interface UIExtension { + /** + * Name is the name of the extension. + * It is also used as path segment for the registered public extension endpoint + * (e.g. /_/extensions/{name}/*) + */ + name: string + /** + * FS is the extension file system. + */ + fs: fs.FS + } + type _sGUGxGZ = hook.Event&RequestEvent + interface SettingsListRequestEvent extends _sGUGxGZ { settings?: Settings } - type _sxqhtjV = hook.Event&RequestEvent - interface SettingsUpdateRequestEvent extends _sxqhtjV { + type _sEjvJpz = hook.Event&RequestEvent + interface SettingsUpdateRequestEvent extends _sEjvJpz { oldSettings?: Settings newSettings?: Settings } - type _sQkYwSD = hook.Event - interface SettingsReloadEvent extends _sQkYwSD { + type _sspkPjA = hook.Event + interface SettingsReloadEvent extends _sspkPjA { app: App } - type _szuLVQN = hook.Event - interface MailerEvent extends _szuLVQN { + type _sNOucYl = hook.Event + interface MailerEvent extends _sNOucYl { app: App mailer: mailer.Mailer message?: mailer.Message } - type _sHLpKGI = MailerEvent&baseRecordEventData - interface MailerRecordEvent extends _sHLpKGI { + type _sHgQkKL = MailerEvent&baseRecordEventData + interface MailerRecordEvent extends _sHgQkKL { meta: _TygojaDict } - type _sHLjwEy = hook.Event&baseModelEventData - interface ModelEvent extends _sHLjwEy { + type _sLWDXqg = hook.Event&baseModelEventData + interface ModelEvent extends _sLWDXqg { app: App context: context.Context /** @@ -9711,12 +9744,12 @@ namespace core { */ type: string } - type _sTPjoLw = ModelEvent - interface ModelErrorEvent extends _sTPjoLw { + type _srZFIWq = ModelEvent + interface ModelErrorEvent extends _srZFIWq { error: Error } - type _sREDOmz = hook.Event&baseRecordEventData - interface RecordEvent extends _sREDOmz { + type _sLufonV = hook.Event&baseRecordEventData + interface RecordEvent extends _sLufonV { app: App context: context.Context /** @@ -9728,12 +9761,12 @@ namespace core { */ type: string } - type _sGIIrIs = RecordEvent - interface RecordErrorEvent extends _sGIIrIs { + type _sBSuaAd = RecordEvent + interface RecordErrorEvent extends _sBSuaAd { error: Error } - type _sTJeDts = hook.Event&baseCollectionEventData - interface CollectionEvent extends _sTJeDts { + type _sHQGeaJ = hook.Event&baseCollectionEventData + interface CollectionEvent extends _sHQGeaJ { app: App context: context.Context /** @@ -9745,16 +9778,16 @@ namespace core { */ type: string } - type _sDAdXzH = CollectionEvent - interface CollectionErrorEvent extends _sDAdXzH { + type _sQePZIo = CollectionEvent + interface CollectionErrorEvent extends _sQePZIo { error: Error } - type _sSsDuFH = hook.Event&RequestEvent&baseRecordEventData - interface FileTokenRequestEvent extends _sSsDuFH { + type _sTXaTCY = hook.Event&RequestEvent&baseRecordEventData + interface FileTokenRequestEvent extends _sTXaTCY { token: string } - type _sRFPXHX = hook.Event&RequestEvent&baseCollectionEventData - interface FileDownloadRequestEvent extends _sRFPXHX { + type _sSSLPbT = hook.Event&RequestEvent&baseCollectionEventData + interface FileDownloadRequestEvent extends _sSSLPbT { record?: Record fileField?: FileField servedPath: string @@ -9768,80 +9801,80 @@ namespace core { */ thumbError: Error } - type _sZPkKFr = hook.Event&RequestEvent - interface CollectionsListRequestEvent extends _sZPkKFr { + type _sBHjQYN = hook.Event&RequestEvent + interface CollectionsListRequestEvent extends _sBHjQYN { collections: Array<(Collection | undefined)> result?: search.Result } - type _sFIxzEG = hook.Event&RequestEvent - interface CollectionsImportRequestEvent extends _sFIxzEG { + type _suRMEQi = hook.Event&RequestEvent + interface CollectionsImportRequestEvent extends _suRMEQi { collectionsData: Array<_TygojaDict> deleteMissing: boolean } - type _sKUvElw = hook.Event&RequestEvent&baseCollectionEventData - interface CollectionRequestEvent extends _sKUvElw { + type _srHvMtM = hook.Event&RequestEvent&baseCollectionEventData + interface CollectionRequestEvent extends _srHvMtM { } - type _sZQgaiI = hook.Event&RequestEvent - interface RealtimeConnectRequestEvent extends _sZQgaiI { + type _slFrNrp = hook.Event&RequestEvent + interface RealtimeConnectRequestEvent extends _slFrNrp { client: subscriptions.Client /** * note: modifying it after the connect has no effect */ idleTimeout: time.Duration } - type _sSuIMSv = hook.Event&RequestEvent - interface RealtimeMessageEvent extends _sSuIMSv { + type _sLJjGky = hook.Event&RequestEvent + interface RealtimeMessageEvent extends _sLJjGky { client: subscriptions.Client message?: subscriptions.Message } - type _shvJVSq = hook.Event&RequestEvent - interface RealtimeSubscribeRequestEvent extends _shvJVSq { + type _suxTJjg = hook.Event&RequestEvent + interface RealtimeSubscribeRequestEvent extends _suxTJjg { client: subscriptions.Client subscriptions: Array } - type _sjLThjH = hook.Event&RequestEvent&baseCollectionEventData - interface RecordsListRequestEvent extends _sjLThjH { + type _sFhPrdO = hook.Event&RequestEvent&baseCollectionEventData + interface RecordsListRequestEvent extends _sFhPrdO { /** * @todo consider removing and maybe add as generic to the search.Result? */ records: Array<(Record | undefined)> result?: search.Result } - type _sXtSbvi = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestEvent extends _sXtSbvi { + type _saHanQJ = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEvent extends _saHanQJ { record?: Record } - type _sojhWQK = hook.Event&baseRecordEventData - interface RecordEnrichEvent extends _sojhWQK { + type _szajIdi = hook.Event&baseRecordEventData + interface RecordEnrichEvent extends _szajIdi { app: App requestInfo?: RequestInfo } - type _sPnFMal = hook.Event&RequestEvent&baseCollectionEventData - interface RecordCreateOTPRequestEvent extends _sPnFMal { + type _sBnNigu = hook.Event&RequestEvent&baseCollectionEventData + interface RecordCreateOTPRequestEvent extends _sBnNigu { record?: Record password: string } - type _sSOdGzw = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithOTPRequestEvent extends _sSOdGzw { + type _sHURedw = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOTPRequestEvent extends _sHURedw { record?: Record otp?: OTP } - type _sAFesTl = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthRequestEvent extends _sAFesTl { + type _sQWgoSv = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRequestEvent extends _sQWgoSv { record?: Record token: string meta: any authMethod: string } - type _sGNOizY = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithPasswordRequestEvent extends _sGNOizY { + type _stdldOq = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithPasswordRequestEvent extends _stdldOq { record?: Record identity: string identityField: string password: string } - type _sIuWdXu = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthWithOAuth2RequestEvent extends _sIuWdXu { + type _swoBYye = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthWithOAuth2RequestEvent extends _swoBYye { providerName: string providerClient: auth.Provider record?: Record @@ -9849,41 +9882,41 @@ namespace core { createData: _TygojaDict isNewRecord: boolean } - type _skoYlCa = hook.Event&RequestEvent&baseCollectionEventData - interface RecordAuthRefreshRequestEvent extends _skoYlCa { + type _szCfvnQ = hook.Event&RequestEvent&baseCollectionEventData + interface RecordAuthRefreshRequestEvent extends _szCfvnQ { record?: Record } - type _sWpLPsE = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestPasswordResetRequestEvent extends _sWpLPsE { + type _sLPbndB = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestPasswordResetRequestEvent extends _sLPbndB { record?: Record } - type _sJkJUZt = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmPasswordResetRequestEvent extends _sJkJUZt { + type _sVcqkmu = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmPasswordResetRequestEvent extends _sVcqkmu { record?: Record } - type _spiojOR = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestVerificationRequestEvent extends _spiojOR { + type _sMYvUAc = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestVerificationRequestEvent extends _sMYvUAc { record?: Record } - type _sMxoFyV = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmVerificationRequestEvent extends _sMxoFyV { + type _soRosYm = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmVerificationRequestEvent extends _soRosYm { record?: Record } - type _sGCkdUA = hook.Event&RequestEvent&baseCollectionEventData - interface RecordRequestEmailChangeRequestEvent extends _sGCkdUA { + type _svBLQPR = hook.Event&RequestEvent&baseCollectionEventData + interface RecordRequestEmailChangeRequestEvent extends _svBLQPR { record?: Record newEmail: string } - type _soNtnzd = hook.Event&RequestEvent&baseCollectionEventData - interface RecordConfirmEmailChangeRequestEvent extends _soNtnzd { + type _sagnnlS = hook.Event&RequestEvent&baseCollectionEventData + interface RecordConfirmEmailChangeRequestEvent extends _sagnnlS { record?: Record newEmail: string } /** * ExternalAuth defines a Record proxy for working with the externalAuths collection. */ - type _sFhoiYT = Record - interface ExternalAuth extends _sFhoiYT { + type _suGHpDy = Record + interface ExternalAuth extends _suGHpDy { } interface newExternalAuth { /** @@ -10150,6 +10183,12 @@ namespace core { */ intercept(ctx: context.Context, app: App, record: Record, actionName: string, actionFunc: () => void): void } + interface defaultFieldHelpValidationRule { + /** + * DefaultFieldHelpValidationRule performs base validation on a field's "help" value. + */ + (value: any): void + } interface defaultFieldIdValidationRule { /** * DefaultFieldIdValidationRule performs base validation on a field id value. @@ -10322,6 +10361,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Required will require the field value to be always "true". */ @@ -10434,6 +10478,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Min specifies the min allowed field value. * @@ -10558,6 +10607,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). * @@ -10690,6 +10744,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * ExceptDomains will require the email domain to NOT be included in the listed ones. * @@ -10842,6 +10901,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * MaxSize specifies the maximum size of a single uploaded file (in bytes and up to 2^53-1). * @@ -11046,6 +11110,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Required will require the field coordinates to be non-zero (aka. not "Null Island"). */ @@ -11158,6 +11227,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * MaxSize specifies the maximum size of the allowed field value (in bytes and up to 2^53-1). * @@ -11292,6 +11366,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Min specifies the min allowed field value. * @@ -11440,10 +11519,17 @@ namespace core { */ hidden: boolean /** + * @todo remove + * * Presentable hints the Dashboard UI to use the underlying * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Pattern specifies an optional regex pattern to match against the field value. * @@ -11637,6 +11723,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * CollectionId is the id of the related collection. */ @@ -11818,6 +11909,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Values specifies the list of accepted values. */ @@ -11968,6 +12064,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * Min specifies the minimum required string characters. * @@ -12130,6 +12231,11 @@ namespace core { * field record value in the relation preview label. */ presentable: boolean + /** + * Help is an extra text explaining what the field is about. + * It is usually shown in Dashboard UI under the field input. + */ + help: string /** * ExceptDomains will require the URL domain to NOT be included in the listed ones. * @@ -12345,8 +12451,8 @@ namespace core { interface onlyFieldType { type: string } - type _sLstiqt = Field - interface fieldWithType extends _sLstiqt { + type _sGHfhOm = Field + interface fieldWithType extends _sGHfhOm { type: string } interface fieldWithType { @@ -12378,8 +12484,8 @@ namespace core { */ scan(value: any): void } - type _sZRVcVD = BaseModel - interface Log extends _sZRVcVD { + type _sCwhdkm = BaseModel + interface Log extends _sCwhdkm { created: types.DateTime data: types.JSONMap message: string @@ -12425,8 +12531,8 @@ namespace core { /** * MFA defines a Record proxy for working with the mfas collection. */ - type _shxPFuR = Record - interface MFA extends _shxPFuR { + type _seabzoM = Record + interface MFA extends _seabzoM { } interface newMFA { /** @@ -12648,8 +12754,8 @@ namespace core { /** * OTP defines a Record proxy for working with the otps collection. */ - type _sBeLRsQ = Record - interface OTP extends _sBeLRsQ { + type _sApkWyq = Record + interface OTP extends _sApkWyq { } interface newOTP { /** @@ -12885,8 +12991,8 @@ namespace core { } interface runner { } - type _saOTAnI = BaseModel - interface Record extends _saOTAnI { + type _sixuDWf = BaseModel + interface Record extends _sixuDWf { } interface newRecord { /** @@ -13361,8 +13467,8 @@ namespace core { * BaseRecordProxy implements the [RecordProxy] interface and it is intended * to be used as embed to custom user provided Record proxy structs. */ - type _swwiIEU = Record - interface BaseRecordProxy extends _swwiIEU { + type _sAAfrDL = Record + interface BaseRecordProxy extends _sAAfrDL { } interface BaseRecordProxy { /** @@ -13611,8 +13717,8 @@ namespace core { /** * Settings defines the PocketBase app settings. */ - type _sBWpWss = settings - interface Settings extends _sBWpWss { + type _sGBqfIb = settings + interface Settings extends _sGBqfIb { } interface Settings { /** @@ -13796,6 +13902,12 @@ namespace core { validate(): void } interface MetaConfig { + /** + * @todo experimental + * + * AccentColor specify the UI "accent" color (HEX). + */ + accentColor: string appName: string appURL: string senderName: string @@ -13925,8 +14037,8 @@ namespace core { */ string(): string } - type _swJezTI = BaseModel - interface Param extends _swJezTI { + type _swmWBcn = BaseModel + interface Param extends _swmWBcn { created: types.DateTime updated: types.DateTime value: types.JSONRaw @@ -13975,6 +14087,22 @@ namespace core { */ createViewFields(dangerousSelectQuery: string): FieldsList } + interface DryRunViewResult { + fields: FieldsList + sample: Array<(Record | undefined)> + } + interface BaseApp { + /** + * DryRunView executes the provided query by creating a temporary view + * collection and returning a sample of the resulting query records (if valid). + * + * The same caveats from CreateViewFields apply here too. + * + * NB! Be aware that this method is vulnerable to SQL injection and the + * "dangerousSelectQuery" argument must come only from trusted input! + */ + dryRunView(dangerousSelectQuery: string, sampleSize: number): (DryRunViewResult) + } interface BaseApp { /** * FindRecordByViewFile returns the original Record of the provided view collection file. @@ -14279,7 +14407,7 @@ namespace apis { } interface newRouter { /** - * NewRouter returns a new router instance loaded with the default app middlewares and api routes. + * NewRouter returns a new router instance loaded with the default app middlewares and routes. */ (app: CoreApp): (router.Router) } @@ -14356,6 +14484,14 @@ namespace apis { interface BatchResponseError { marshalJSON(): string|Array } + interface providerListItem { + name: string + displayName: string + logo: string + } + interface dryRunViewForm { + query: string + } interface collectionsImportForm { collections: Array<_TygojaDict> deleteMissing: boolean @@ -14443,8 +14579,8 @@ namespace apis { */ (limitBytes: number): (hook.Handler) } - type _sFRBhMZ = io.ReadCloser - interface limitedReader extends _sFRBhMZ { + type _sIyHjaB = io.ReadCloser + interface limitedReader extends _sIyHjaB { } interface limitedReader { read(b: string|Array): number @@ -14598,8 +14734,8 @@ namespace apis { */ (config: GzipConfig): (hook.Handler) } - type _seNzbcU = http.ResponseWriter&io.Writer - interface gzipResponseWriter extends _seNzbcU { + type _sMXRnmN = http.ResponseWriter&io.Writer + interface gzipResponseWriter extends _sMXRnmN { } interface gzipResponseWriter { writeHeader(code: number): void @@ -14619,16 +14755,16 @@ namespace apis { interface gzipResponseWriter { unwrap(): http.ResponseWriter } - type _sLfCowm = sync.RWMutex - interface rateLimiter extends _sLfCowm { + type _slRgPdG = sync.RWMutex + interface rateLimiter extends _slRgPdG { } /** * @todo evaluate swiching to sliding window with approximation counter similar to Cloudflare. * * rateClient implements fixed window rate limit strategy. */ - type _seqmKwd = sync.Mutex - interface rateClient extends _seqmKwd { + type _sZvOeZC = sync.Mutex + interface rateClient extends _sZvOeZC { } interface realtimeSubscribeForm { clientId: string @@ -14673,6 +14809,7 @@ namespace apis { interface providerInfo { name: string displayName: string + logo: string state: string authURL: string /** @@ -14873,8 +15010,8 @@ namespace pocketbase { * It implements [CoreApp] via embedding and all of the app interface methods * could be accessed directly through the instance (eg. PocketBase.DataDir()). */ - type _sxZqaJI = CoreApp - interface PocketBase extends _sxZqaJI { + type _syPxemM = CoreApp + interface PocketBase extends _syPxemM { /** * RootCmd is the main console command */ @@ -15188,91 +15325,6 @@ namespace io { } } -/** - * Package bytes implements functions for the manipulation of byte slices. - * It is analogous to the facilities of the [strings] package. - */ -namespace bytes { - /** - * A Reader implements the [io.Reader], [io.ReaderAt], [io.WriterTo], [io.Seeker], - * [io.ByteScanner], and [io.RuneScanner] interfaces by reading from - * a byte slice. - * Unlike a [Buffer], a Reader is read-only and supports seeking. - * The zero value for Reader operates like a Reader of an empty slice. - */ - interface Reader { - } - interface Reader { - /** - * Len returns the number of bytes of the unread portion of the - * slice. - */ - len(): number - } - interface Reader { - /** - * Size returns the original length of the underlying byte slice. - * Size is the number of bytes available for reading via [Reader.ReadAt]. - * The result is unaffected by any method calls except [Reader.Reset]. - */ - size(): number - } - interface Reader { - /** - * Read implements the [io.Reader] interface. - */ - read(b: string|Array): number - } - interface Reader { - /** - * ReadAt implements the [io.ReaderAt] interface. - */ - readAt(b: string|Array, off: number): number - } - interface Reader { - /** - * ReadByte implements the [io.ByteReader] interface. - */ - readByte(): number - } - interface Reader { - /** - * UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface. - */ - unreadByte(): void - } - interface Reader { - /** - * ReadRune implements the [io.RuneReader] interface. - */ - readRune(): [number, number] - } - interface Reader { - /** - * UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface. - */ - unreadRune(): void - } - interface Reader { - /** - * Seek implements the [io.Seeker] interface. - */ - seek(offset: number, whence: number): number - } - interface Reader { - /** - * WriteTo implements the [io.WriterTo] interface. - */ - writeTo(w: io.Writer): number - } - interface Reader { - /** - * Reset resets the [Reader] to be reading from b. - */ - reset(b: string|Array): void - } -} - /** * Package syscall contains an interface to the low-level operating system * primitives. The details vary depending on the underlying system, and @@ -16024,172 +16076,6 @@ namespace time { } } -/** - * Package context defines the Context type, which carries deadlines, - * cancellation signals, and other request-scoped values across API boundaries - * and between processes. - * - * Incoming requests to a server should create a [Context], and outgoing - * calls to servers should accept a Context. The chain of function - * calls between them must propagate the Context, optionally replacing - * it with a derived Context created using [WithCancel], [WithDeadline], - * [WithTimeout], or [WithValue]. - * - * A Context may be canceled to indicate that work done on its behalf should stop. - * A Context with a deadline is canceled after the deadline passes. - * When a Context is canceled, all Contexts derived from it are also canceled. - * - * The [WithCancel], [WithDeadline], and [WithTimeout] functions take a - * Context (the parent) and return a derived Context (the child) and a - * [CancelFunc]. Calling the CancelFunc directly cancels the child and its - * children, removes the parent's reference to the child, and stops - * any associated timers. Failing to call the CancelFunc leaks the - * child and its children until the parent is canceled. The go vet tool - * checks that CancelFuncs are used on all control-flow paths. - * - * The [WithCancelCause], [WithDeadlineCause], and [WithTimeoutCause] functions - * return a [CancelCauseFunc], which takes an error and records it as - * the cancellation cause. Calling [Cause] on the canceled context - * or any of its children retrieves the cause. If no cause is specified, - * Cause(ctx) returns the same value as ctx.Err(). - * - * Programs that use Contexts should follow these rules to keep interfaces - * consistent across packages and enable static analysis tools to check context - * propagation: - * - * Do not store Contexts inside a struct type; instead, pass a Context - * explicitly to each function that needs it. This is discussed further in - * https://go.dev/blog/context-and-structs. The Context should be the first - * parameter, typically named ctx: - * - * ``` - * func DoSomething(ctx context.Context, arg Arg) error { - * // ... use ctx ... - * } - * ``` - * - * Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] - * if you are unsure about which Context to use. - * - * Use context Values only for request-scoped data that transits processes and - * APIs, not for passing optional parameters to functions. - * - * The same Context may be passed to functions running in different goroutines; - * Contexts are safe for simultaneous use by multiple goroutines. - * - * See https://go.dev/blog/context for example code for a server that uses - * Contexts. - */ -namespace context { - /** - * A Context carries a deadline, a cancellation signal, and other values across - * API boundaries. - * - * Context's methods may be called by multiple goroutines simultaneously. - */ - interface Context { - [key:string]: any; - /** - * Deadline returns the time when work done on behalf of this context - * should be canceled. Deadline returns ok==false when no deadline is - * set. Successive calls to Deadline return the same results. - */ - deadline(): [time.Time, boolean] - /** - * Done returns a channel that's closed when work done on behalf of this - * context should be canceled. Done may return nil if this context can - * never be canceled. Successive calls to Done return the same value. - * The close of the Done channel may happen asynchronously, - * after the cancel function returns. - * - * WithCancel arranges for Done to be closed when cancel is called; - * WithDeadline arranges for Done to be closed when the deadline - * expires; WithTimeout arranges for Done to be closed when the timeout - * elapses. - * - * Done is provided for use in select statements: - * - * // Stream generates values with DoSomething and sends them to out - * // until DoSomething returns an error or ctx.Done is closed. - * func Stream(ctx context.Context, out chan<- Value) error { - * for { - * v, err := DoSomething(ctx) - * if err != nil { - * return err - * } - * select { - * case <-ctx.Done(): - * return ctx.Err() - * case out <- v: - * } - * } - * } - * - * See https://blog.golang.org/pipelines for more examples of how to use - * a Done channel for cancellation. - */ - done(): undefined - /** - * If Done is not yet closed, Err returns nil. - * If Done is closed, Err returns a non-nil error explaining why: - * DeadlineExceeded if the context's deadline passed, - * or Canceled if the context was canceled for some other reason. - * After Err returns a non-nil error, successive calls to Err return the same error. - */ - err(): void - /** - * Value returns the value associated with this context for key, or nil - * if no value is associated with key. Successive calls to Value with - * the same key returns the same result. - * - * Use context values only for request-scoped data that transits - * processes and API boundaries, not for passing optional parameters to - * functions. - * - * A key identifies a specific value in a Context. Functions that wish - * to store values in Context typically allocate a key in a global - * variable then use that key as the argument to context.WithValue and - * Context.Value. A key can be any type that supports equality; - * packages should define keys as an unexported type to avoid - * collisions. - * - * Packages that define a Context key should provide type-safe accessors - * for the values stored using that key: - * - * ``` - * // Package user defines a User type that's stored in Contexts. - * package user - * - * import "context" - * - * // User is the type of value stored in the Contexts. - * type User struct {...} - * - * // key is an unexported type for keys defined in this package. - * // This prevents collisions with keys defined in other packages. - * type key int - * - * // userKey is the key for user.User values in Contexts. It is - * // unexported; clients use user.NewContext and user.FromContext - * // instead of using this key directly. - * var userKey key - * - * // NewContext returns a new Context that carries value u. - * func NewContext(ctx context.Context, u *User) context.Context { - * return context.WithValue(ctx, userKey, u) - * } - * - * // FromContext returns the User value stored in ctx, if any. - * func FromContext(ctx context.Context) (*User, bool) { - * u, ok := ctx.Value(userKey).(*User) - * return u, ok - * } - * ``` - */ - value(key: any): any - } -} - /** * Package fs defines basic interfaces to a file system. * A file system can be provided by the host operating system @@ -16392,17 +16278,350 @@ namespace fs { } /** - * Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer - * object, creating another object (Reader or Writer) that also implements - * the interface but provides buffering and some help for textual I/O. + * Package bytes implements functions for the manipulation of byte slices. + * It is analogous to the facilities of the [strings] package. */ -namespace bufio { +namespace bytes { /** - * ReadWriter stores pointers to a [Reader] and a [Writer]. - * It implements [io.ReadWriter]. + * A Reader implements the [io.Reader], [io.ReaderAt], [io.WriterTo], [io.Seeker], + * [io.ByteScanner], and [io.RuneScanner] interfaces by reading from + * a byte slice. + * Unlike a [Buffer], a Reader is read-only and supports seeking. + * The zero value for Reader operates like a Reader of an empty slice. */ - type _sUQolAm = Reader&Writer - interface ReadWriter extends _sUQolAm { + interface Reader { + } + interface Reader { + /** + * Len returns the number of bytes of the unread portion of the + * slice. + */ + len(): number + } + interface Reader { + /** + * Size returns the original length of the underlying byte slice. + * Size is the number of bytes available for reading via [Reader.ReadAt]. + * The result is unaffected by any method calls except [Reader.Reset]. + */ + size(): number + } + interface Reader { + /** + * Read implements the [io.Reader] interface. + */ + read(b: string|Array): number + } + interface Reader { + /** + * ReadAt implements the [io.ReaderAt] interface. + */ + readAt(b: string|Array, off: number): number + } + interface Reader { + /** + * ReadByte implements the [io.ByteReader] interface. + */ + readByte(): number + } + interface Reader { + /** + * UnreadByte complements [Reader.ReadByte] in implementing the [io.ByteScanner] interface. + */ + unreadByte(): void + } + interface Reader { + /** + * ReadRune implements the [io.RuneReader] interface. + */ + readRune(): [number, number] + } + interface Reader { + /** + * UnreadRune complements [Reader.ReadRune] in implementing the [io.RuneScanner] interface. + */ + unreadRune(): void + } + interface Reader { + /** + * Seek implements the [io.Seeker] interface. + */ + seek(offset: number, whence: number): number + } + interface Reader { + /** + * WriteTo implements the [io.WriterTo] interface. + */ + writeTo(w: io.Writer): number + } + interface Reader { + /** + * Reset resets the [Reader] to be reading from b. + */ + reset(b: string|Array): void + } +} + +/** + * Package cron implements a crontab-like service to execute and schedule + * repeative tasks/jobs. + * + * Example: + * + * ``` + * c := cron.New() + * c.MustAdd("dailyReport", "0 0 * * *", func() { ... }) + * c.Start() + * ``` + */ +namespace cron { + /** + * Cron is a crontab-like struct for tasks/jobs scheduling. + */ + interface Cron { + } + interface Cron { + /** + * SetInterval changes the current cron tick interval + * (it usually should be >= 1 minute). + */ + setInterval(d: time.Duration): void + } + interface Cron { + /** + * SetTimezone changes the current cron tick timezone. + */ + setTimezone(l: time.Location): void + } + interface Cron { + /** + * MustAdd is similar to Add() but panic on failure. + */ + mustAdd(jobId: string, cronExpr: string, run: () => void): void + } + interface Cron { + /** + * Add registers a single cron job. + * + * If there is already a job with the provided id, then the old job + * will be replaced with the new one. + * + * cronExpr is a regular cron expression, eg. "0 *\/3 * * *" (aka. at minute 0 past every 3rd hour). + * Check cron.NewSchedule() for the supported tokens. + */ + add(jobId: string, cronExpr: string, fn: () => void): void + } + interface Cron { + /** + * Remove removes a single cron job by its id. + */ + remove(jobId: string): void + } + interface Cron { + /** + * RemoveAll removes all registered cron jobs. + */ + removeAll(): void + } + interface Cron { + /** + * Total returns the current total number of registered cron jobs. + */ + total(): number + } + interface Cron { + /** + * Jobs returns a shallow copy of the currently registered cron jobs. + */ + jobs(): Array<(Job | undefined)> + } + interface Cron { + /** + * Stop stops the current cron ticker (if not already). + * + * You can resume the ticker by calling Start(). + */ + stop(): void + } + interface Cron { + /** + * Start starts the cron ticker. + * + * Calling Start() on already started cron will restart the ticker. + */ + start(): void + } + interface Cron { + /** + * HasStarted checks whether the current Cron ticker has been started. + */ + hasStarted(): boolean + } +} + +/** + * Package context defines the Context type, which carries deadlines, + * cancellation signals, and other request-scoped values across API boundaries + * and between processes. + * + * Incoming requests to a server should create a [Context], and outgoing + * calls to servers should accept a Context. The chain of function + * calls between them must propagate the Context, optionally replacing + * it with a derived Context created using [WithCancel], [WithDeadline], + * [WithTimeout], or [WithValue]. + * + * A Context may be canceled to indicate that work done on its behalf should stop. + * A Context with a deadline is canceled after the deadline passes. + * When a Context is canceled, all Contexts derived from it are also canceled. + * + * The [WithCancel], [WithDeadline], and [WithTimeout] functions take a + * Context (the parent) and return a derived Context (the child) and a + * [CancelFunc]. Calling the CancelFunc directly cancels the child and its + * children, removes the parent's reference to the child, and stops + * any associated timers. Failing to call the CancelFunc leaks the + * child and its children until the parent is canceled. The go vet tool + * checks that CancelFuncs are used on all control-flow paths. + * + * The [WithCancelCause], [WithDeadlineCause], and [WithTimeoutCause] functions + * return a [CancelCauseFunc], which takes an error and records it as + * the cancellation cause. Calling [Cause] on the canceled context + * or any of its children retrieves the cause. If no cause is specified, + * Cause(ctx) returns the same value as ctx.Err(). + * + * Programs that use Contexts should follow these rules to keep interfaces + * consistent across packages and enable static analysis tools to check context + * propagation: + * + * Do not store Contexts inside a struct type; instead, pass a Context + * explicitly to each function that needs it. This is discussed further in + * https://go.dev/blog/context-and-structs. The Context should be the first + * parameter, typically named ctx: + * + * ``` + * func DoSomething(ctx context.Context, arg Arg) error { + * // ... use ctx ... + * } + * ``` + * + * Do not pass a nil [Context], even if a function permits it. Pass [context.TODO] + * if you are unsure about which Context to use. + * + * Use context Values only for request-scoped data that transits processes and + * APIs, not for passing optional parameters to functions. + * + * The same Context may be passed to functions running in different goroutines; + * Contexts are safe for simultaneous use by multiple goroutines. + * + * See https://go.dev/blog/context for example code for a server that uses + * Contexts. + */ +namespace context { + /** + * A Context carries a deadline, a cancellation signal, and other values across + * API boundaries. + * + * Context's methods may be called by multiple goroutines simultaneously. + */ + interface Context { + [key:string]: any; + /** + * Deadline returns the time when work done on behalf of this context + * should be canceled. Deadline returns ok==false when no deadline is + * set. Successive calls to Deadline return the same results. + */ + deadline(): [time.Time, boolean] + /** + * Done returns a channel that's closed when work done on behalf of this + * context should be canceled. Done may return nil if this context can + * never be canceled. Successive calls to Done return the same value. + * The close of the Done channel may happen asynchronously, + * after the cancel function returns. + * + * WithCancel arranges for Done to be closed when cancel is called; + * WithDeadline arranges for Done to be closed when the deadline + * expires; WithTimeout arranges for Done to be closed when the timeout + * elapses. + * + * Done is provided for use in select statements: + * + * // Stream generates values with DoSomething and sends them to out + * // until DoSomething returns an error or ctx.Done is closed. + * func Stream(ctx context.Context, out chan<- Value) error { + * for { + * v, err := DoSomething(ctx) + * if err != nil { + * return err + * } + * select { + * case <-ctx.Done(): + * return ctx.Err() + * case out <- v: + * } + * } + * } + * + * See https://blog.golang.org/pipelines for more examples of how to use + * a Done channel for cancellation. + */ + done(): undefined + /** + * If Done is not yet closed, Err returns nil. + * If Done is closed, Err returns a non-nil error explaining why: + * DeadlineExceeded if the context's deadline passed, + * or Canceled if the context was canceled for some other reason. + * After Err returns a non-nil error, successive calls to Err return the same error. + */ + err(): void + /** + * Value returns the value associated with this context for key, or nil + * if no value is associated with key. Successive calls to Value with + * the same key returns the same result. + * + * Use context values only for request-scoped data that transits + * processes and API boundaries, not for passing optional parameters to + * functions. + * + * A key identifies a specific value in a Context. Functions that wish + * to store values in Context typically allocate a key in a global + * variable then use that key as the argument to context.WithValue and + * Context.Value. A key can be any type that supports equality; + * packages should define keys as an unexported type to avoid + * collisions. + * + * Packages that define a Context key should provide type-safe accessors + * for the values stored using that key: + * + * ``` + * // Package user defines a User type that's stored in Contexts. + * package user + * + * import "context" + * + * // User is the type of value stored in the Contexts. + * type User struct {...} + * + * // key is an unexported type for keys defined in this package. + * // This prevents collisions with keys defined in other packages. + * type key int + * + * // userKey is the key for user.User values in Contexts. It is + * // unexported; clients use user.NewContext and user.FromContext + * // instead of using this key directly. + * var userKey key + * + * // NewContext returns a new Context that carries value u. + * func NewContext(ctx context.Context, u *User) context.Context { + * return context.WithValue(ctx, userKey, u) + * } + * + * // FromContext returns the User value stored in ctx, if any. + * func FromContext(ctx context.Context) (*User, bool) { + * u, ok := ctx.Value(userKey).(*User) + * return u, ok + * } + * ``` + */ + value(key: any): any } } @@ -16766,6 +16985,3333 @@ namespace syntax { interface Flags extends Number{} } +/** + * Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html + * + * See README.md for more info. + */ +namespace jwt { + /** + * MapClaims is a claims type that uses the map[string]any for JSON + * decoding. This is the default claims type if you don't supply one + */ + interface MapClaims extends _TygojaDict{} + interface MapClaims { + /** + * GetExpirationTime implements the Claims interface. + */ + getExpirationTime(): (NumericDate) + } + interface MapClaims { + /** + * GetNotBefore implements the Claims interface. + */ + getNotBefore(): (NumericDate) + } + interface MapClaims { + /** + * GetIssuedAt implements the Claims interface. + */ + getIssuedAt(): (NumericDate) + } + interface MapClaims { + /** + * GetAudience implements the Claims interface. + */ + getAudience(): ClaimStrings + } + interface MapClaims { + /** + * GetIssuer implements the Claims interface. + */ + getIssuer(): string + } + interface MapClaims { + /** + * GetSubject implements the Claims interface. + */ + getSubject(): string + } +} + +/** + * Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer + * object, creating another object (Reader or Writer) that also implements + * the interface but provides buffering and some help for textual I/O. + */ +namespace bufio { + /** + * ReadWriter stores pointers to a [Reader] and a [Writer]. + * It implements [io.ReadWriter]. + */ + type _srSsGWn = Reader&Writer + interface ReadWriter extends _srSsGWn { + } +} + +/** + * Package multipart implements MIME multipart parsing, as defined in RFC + * 2046. + * + * The implementation is sufficient for HTTP (RFC 2388) and the multipart + * bodies generated by popular browsers. + * + * # Limits + * + * To protect against malicious inputs, this package sets limits on the size + * of the MIME data it processes. + * + * [Reader.NextPart] and [Reader.NextRawPart] limit the number of headers in a + * part to 10000 and [Reader.ReadForm] limits the total number of headers in all + * FileHeaders to 10000. + * These limits may be adjusted with the GODEBUG=multipartmaxheaders= + * setting. + * + * Reader.ReadForm further limits the number of parts in a form to 1000. + * This limit may be adjusted with the GODEBUG=multipartmaxparts= + * setting. + */ +namespace multipart { + /** + * A FileHeader describes a file part of a multipart request. + */ + interface FileHeader { + filename: string + header: textproto.MIMEHeader + size: number + } + interface FileHeader { + /** + * Open opens and returns the [FileHeader]'s associated File. + */ + open(): File + } +} + +/** + * Package http provides HTTP client and server implementations. + * + * [Get], [Head], [Post], and [PostForm] make HTTP (or HTTPS) requests: + * + * ``` + * resp, err := http.Get("http://example.com/") + * ... + * resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) + * ... + * resp, err := http.PostForm("http://example.com/form", + * url.Values{"key": {"Value"}, "id": {"123"}}) + * ``` + * + * The caller must close the response body when finished with it: + * + * ``` + * resp, err := http.Get("http://example.com/") + * if err != nil { + * // handle error + * } + * defer resp.Body.Close() + * body, err := io.ReadAll(resp.Body) + * // ... + * ``` + * + * # Clients and Transports + * + * For control over HTTP client headers, redirect policy, and other + * settings, create a [Client]: + * + * ``` + * client := &http.Client{ + * CheckRedirect: redirectPolicyFunc, + * } + * + * resp, err := client.Get("http://example.com") + * // ... + * + * req, err := http.NewRequest("GET", "http://example.com", nil) + * // ... + * req.Header.Add("If-None-Match", `W/"wyzzy"`) + * resp, err := client.Do(req) + * // ... + * ``` + * + * For control over proxies, TLS configuration, keep-alives, + * compression, and other settings, create a [Transport]: + * + * ``` + * tr := &http.Transport{ + * MaxIdleConns: 10, + * IdleConnTimeout: 30 * time.Second, + * DisableCompression: true, + * } + * client := &http.Client{Transport: tr} + * resp, err := client.Get("https://example.com") + * ``` + * + * Clients and Transports are safe for concurrent use by multiple + * goroutines and for efficiency should only be created once and re-used. + * + * # Servers + * + * ListenAndServe starts an HTTP server with a given address and handler. + * The handler is usually nil, which means to use [DefaultServeMux]. + * [Handle] and [HandleFunc] add handlers to [DefaultServeMux]: + * + * ``` + * http.Handle("/foo", fooHandler) + * + * http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { + * fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) + * }) + * + * log.Fatal(http.ListenAndServe(":8080", nil)) + * ``` + * + * More control over the server's behavior is available by creating a + * custom Server: + * + * ``` + * s := &http.Server{ + * Addr: ":8080", + * Handler: myHandler, + * ReadTimeout: 10 * time.Second, + * WriteTimeout: 10 * time.Second, + * MaxHeaderBytes: 1 << 20, + * } + * log.Fatal(s.ListenAndServe()) + * ``` + * + * # HTTP/2 + * + * Starting with Go 1.6, the http package has transparent support for the + * HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2 + * can do so by setting [Transport.TLSNextProto] (for clients) or + * [Server.TLSNextProto] (for servers) to a non-nil, empty + * map. Alternatively, the following GODEBUG settings are + * currently supported: + * + * ``` + * GODEBUG=http2client=0 # disable HTTP/2 client support + * GODEBUG=http2server=0 # disable HTTP/2 server support + * GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs + * GODEBUG=http2debug=2 # ... even more verbose, with frame dumps + * ``` + * + * Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug + * + * The http package's [Transport] and [Server] both automatically enable + * HTTP/2 support for simple configurations. To enable HTTP/2 for more + * complex configurations, to use lower-level HTTP/2 features, or to use + * a newer version of Go's http2 package, import "golang.org/x/net/http2" + * directly and use its ConfigureTransport and/or ConfigureServer + * functions. Manually configuring HTTP/2 via the golang.org/x/net/http2 + * package takes precedence over the net/http package's built-in HTTP/2 + * support. + */ +namespace http { + // @ts-ignore + import mathrand = rand + /** + * PushOptions describes options for [Pusher.Push]. + */ + interface PushOptions { + /** + * Method specifies the HTTP method for the promised request. + * If set, it must be "GET" or "HEAD". Empty means "GET". + */ + method: string + /** + * Header specifies additional promised request headers. This cannot + * include HTTP/2 pseudo header fields like ":path" and ":scheme", + * which will be added automatically. + */ + header: Header + } + // @ts-ignore + import urlpkg = url + /** + * A Request represents an HTTP request received by a server + * or to be sent by a client. + * + * The field semantics differ slightly between client and server + * usage. In addition to the notes on the fields below, see the + * documentation for [Request.Write] and [RoundTripper]. + */ + interface Request { + /** + * Method specifies the HTTP method (GET, POST, PUT, etc.). + * For client requests, an empty string means GET. + */ + method: string + /** + * URL specifies either the URI being requested (for server + * requests) or the URL to access (for client requests). + * + * For server requests, the URL is parsed from the URI + * supplied on the Request-Line as stored in RequestURI. For + * most requests, fields other than Path and RawQuery will be + * empty. (See RFC 7230, Section 5.3) + * + * For client requests, the URL's Host specifies the server to + * connect to, while the Request's Host field optionally + * specifies the Host header value to send in the HTTP + * request. + */ + url?: url.URL + /** + * The protocol version for incoming server requests. + * + * For client requests, these fields are ignored. The HTTP + * client code always uses either HTTP/1.1 or HTTP/2. + * See the docs on Transport for details. + */ + proto: string // "HTTP/1.0" + protoMajor: number // 1 + protoMinor: number // 0 + /** + * Header contains the request header fields either received + * by the server or to be sent by the client. + * + * If a server received a request with header lines, + * + * ``` + * Host: example.com + * accept-encoding: gzip, deflate + * Accept-Language: en-us + * fOO: Bar + * foo: two + * ``` + * + * then + * + * ``` + * Header = map[string][]string{ + * "Accept-Encoding": {"gzip, deflate"}, + * "Accept-Language": {"en-us"}, + * "Foo": {"Bar", "two"}, + * } + * ``` + * + * For incoming requests, the Host header is promoted to the + * Request.Host field and removed from the Header map. + * + * HTTP defines that header names are case-insensitive. The + * request parser implements this by using CanonicalHeaderKey, + * making the first character and any characters following a + * hyphen uppercase and the rest lowercase. + * + * For client requests, certain headers such as Content-Length + * and Connection are automatically written when needed and + * values in Header may be ignored. See the documentation + * for the Request.Write method. + */ + header: Header + /** + * Body is the request's body. + * + * For client requests, a nil body means the request has no + * body, such as a GET request. The HTTP Client's Transport + * is responsible for calling the Close method. + * + * For server requests, the Request Body is always non-nil + * but will return EOF immediately when no body is present. + * The Server will close the request body. The ServeHTTP + * Handler does not need to. + * + * Body must allow Read to be called concurrently with Close. + * In particular, calling Close should unblock a Read waiting + * for input. + */ + body: io.ReadCloser + /** + * GetBody defines an optional func to return a new copy of + * Body. It is used for client requests when a redirect requires + * reading the body more than once. Use of GetBody still + * requires setting Body. + * + * For server requests, it is unused. + */ + getBody: () => io.ReadCloser + /** + * ContentLength records the length of the associated content. + * The value -1 indicates that the length is unknown. + * Values >= 0 indicate that the given number of bytes may + * be read from Body. + * + * For client requests, a value of 0 with a non-nil Body is + * also treated as unknown. + */ + contentLength: number + /** + * TransferEncoding lists the transfer encodings from outermost to + * innermost. An empty list denotes the "identity" encoding. + * TransferEncoding can usually be ignored; chunked encoding is + * automatically added and removed as necessary when sending and + * receiving requests. + */ + transferEncoding: Array + /** + * Close indicates whether to close the connection after + * replying to this request (for servers) or after sending this + * request and reading its response (for clients). + * + * For server requests, the HTTP server handles this automatically + * and this field is not needed by Handlers. + * + * For client requests, setting this field prevents re-use of + * TCP connections between requests to the same hosts, as if + * Transport.DisableKeepAlives were set. + */ + close: boolean + /** + * For server requests, Host specifies the host on which the + * URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this + * is either the value of the "Host" header or the host name + * given in the URL itself. For HTTP/2, it is the value of the + * ":authority" pseudo-header field. + * It may be of the form "host:port". For international domain + * names, Host may be in Punycode or Unicode form. Use + * golang.org/x/net/idna to convert it to either format if + * needed. + * To prevent DNS rebinding attacks, server Handlers should + * validate that the Host header has a value for which the + * Handler considers itself authoritative. The included + * ServeMux supports patterns registered to particular host + * names and thus protects its registered Handlers. + * + * For client requests, Host optionally overrides the Host + * header to send. If empty, the Request.Write method uses + * the value of URL.Host. Host may contain an international + * domain name. + */ + host: string + /** + * Form contains the parsed form data, including both the URL + * field's query parameters and the PATCH, POST, or PUT form data. + * This field is only available after ParseForm is called. + * The HTTP client ignores Form and uses Body instead. + */ + form: url.Values + /** + * PostForm contains the parsed form data from PATCH, POST + * or PUT body parameters. + * + * This field is only available after ParseForm is called. + * The HTTP client ignores PostForm and uses Body instead. + */ + postForm: url.Values + /** + * MultipartForm is the parsed multipart form, including file uploads. + * This field is only available after ParseMultipartForm is called. + * The HTTP client ignores MultipartForm and uses Body instead. + */ + multipartForm?: multipart.Form + /** + * Trailer specifies additional headers that are sent after the request + * body. + * + * For server requests, the Trailer map initially contains only the + * trailer keys, with nil values. (The client declares which trailers it + * will later send.) While the handler is reading from Body, it must + * not reference Trailer. After reading from Body returns EOF, Trailer + * can be read again and will contain non-nil values, if they were sent + * by the client. + * + * For client requests, Trailer must be initialized to a map containing + * the trailer keys to later send. The values may be nil or their final + * values. The ContentLength must be 0 or -1, to send a chunked request. + * After the HTTP request is sent the map values can be updated while + * the request body is read. Once the body returns EOF, the caller must + * not mutate Trailer. + * + * Few HTTP clients, servers, or proxies support HTTP trailers. + */ + trailer: Header + /** + * RemoteAddr allows HTTP servers and other software to record + * the network address that sent the request, usually for + * logging. This field is not filled in by ReadRequest and + * has no defined format. The HTTP server in this package + * sets RemoteAddr to an "IP:port" address before invoking a + * handler. + * This field is ignored by the HTTP client. + */ + remoteAddr: string + /** + * RequestURI is the unmodified request-target of the + * Request-Line (RFC 7230, Section 3.1.1) as sent by the client + * to a server. Usually the URL field should be used instead. + * It is an error to set this field in an HTTP client request. + */ + requestURI: string + /** + * TLS allows HTTP servers and other software to record + * information about the TLS connection on which the request + * was received. This field is not filled in by ReadRequest. + * The HTTP server in this package sets the field for + * TLS-enabled connections before invoking a handler; + * otherwise it leaves the field nil. + * This field is ignored by the HTTP client. + */ + tls?: any + /** + * Cancel is an optional channel whose closure indicates that the client + * request should be regarded as canceled. Not all implementations of + * RoundTripper may support Cancel. + * + * For server requests, this field is not applicable. + * + * Deprecated: Set the Request's context with NewRequestWithContext + * instead. If a Request's Cancel field and context are both + * set, it is undefined whether Cancel is respected. + */ + cancel: undefined + /** + * Response is the redirect response which caused this request + * to be created. This field is only populated during client + * redirects. + */ + response?: Response + /** + * Pattern is the [ServeMux] pattern that matched the request. + * It is empty if the request was not matched against a pattern. + */ + pattern: string + } + interface Request { + /** + * Context returns the request's context. To change the context, use + * [Request.Clone] or [Request.WithContext]. + * + * The returned context is always non-nil; it defaults to the + * background context. + * + * For outgoing client requests, the context controls cancellation. + * + * For incoming server requests, the context is canceled when the + * client's connection closes, the request is canceled (with HTTP/2), + * or when the ServeHTTP method returns. + */ + context(): context.Context + } + interface Request { + /** + * WithContext returns a shallow copy of r with its context changed + * to ctx. The provided ctx must be non-nil. + * + * For outgoing client request, the context controls the entire + * lifetime of a request and its response: obtaining a connection, + * sending the request, and reading the response headers and body. + * + * To create a new request with a context, use [NewRequestWithContext]. + * To make a deep copy of a request with a new context, use [Request.Clone]. + */ + withContext(ctx: context.Context): (Request) + } + interface Request { + /** + * Clone returns a deep copy of r with its context changed to ctx. + * The provided ctx must be non-nil. + * + * Clone only makes a shallow copy of the Body field. + * + * For an outgoing client request, the context controls the entire + * lifetime of a request and its response: obtaining a connection, + * sending the request, and reading the response headers and body. + */ + clone(ctx: context.Context): (Request) + } + interface Request { + /** + * ProtoAtLeast reports whether the HTTP protocol used + * in the request is at least major.minor. + */ + protoAtLeast(major: number, minor: number): boolean + } + interface Request { + /** + * UserAgent returns the client's User-Agent, if sent in the request. + */ + userAgent(): string + } + interface Request { + /** + * Cookies parses and returns the HTTP cookies sent with the request. + */ + cookies(): Array<(Cookie | undefined)> + } + interface Request { + /** + * CookiesNamed parses and returns the named HTTP cookies sent with the request + * or an empty slice if none matched. + */ + cookiesNamed(name: string): Array<(Cookie | undefined)> + } + interface Request { + /** + * Cookie returns the named cookie provided in the request or + * [ErrNoCookie] if not found. + * If multiple cookies match the given name, only one cookie will + * be returned. + */ + cookie(name: string): (Cookie) + } + interface Request { + /** + * AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, + * AddCookie does not attach more than one [Cookie] header field. That + * means all cookies, if any, are written into the same line, + * separated by semicolon. + * AddCookie only sanitizes c's name and value, and does not sanitize + * a Cookie header already present in the request. + */ + addCookie(c: Cookie): void + } + interface Request { + /** + * Referer returns the referring URL, if sent in the request. + * + * Referer is misspelled as in the request itself, a mistake from the + * earliest days of HTTP. This value can also be fetched from the + * [Header] map as Header["Referer"]; the benefit of making it available + * as a method is that the compiler can diagnose programs that use the + * alternate (correct English) spelling req.Referrer() but cannot + * diagnose programs that use Header["Referrer"]. + */ + referer(): string + } + interface Request { + /** + * MultipartReader returns a MIME multipart reader if this is a + * multipart/form-data or a multipart/mixed POST request, else returns nil and an error. + * Use this function instead of [Request.ParseMultipartForm] to + * process the request body as a stream. + */ + multipartReader(): (multipart.Reader) + } + interface Request { + /** + * Write writes an HTTP/1.1 request, which is the header and body, in wire format. + * This method consults the following fields of the request: + * + * ``` + * Host + * URL + * Method (defaults to "GET") + * Header + * ContentLength + * TransferEncoding + * Body + * ``` + * + * If Body is present, Content-Length is <= 0 and [Request.TransferEncoding] + * hasn't been set to "identity", Write adds "Transfer-Encoding: + * chunked" to the header. Body is closed after it is sent. + */ + write(w: io.Writer): void + } + interface Request { + /** + * WriteProxy is like [Request.Write] but writes the request in the form + * expected by an HTTP proxy. In particular, [Request.WriteProxy] writes the + * initial Request-URI line of the request with an absolute URI, per + * section 5.3 of RFC 7230, including the scheme and host. + * In either case, WriteProxy also writes a Host header, using + * either r.Host or r.URL.Host. + */ + writeProxy(w: io.Writer): void + } + interface Request { + /** + * BasicAuth returns the username and password provided in the request's + * Authorization header, if the request uses HTTP Basic Authentication. + * See RFC 2617, Section 2. + */ + basicAuth(): [string, string, boolean] + } + interface Request { + /** + * SetBasicAuth sets the request's Authorization header to use HTTP + * Basic Authentication with the provided username and password. + * + * With HTTP Basic Authentication the provided username and password + * are not encrypted. It should generally only be used in an HTTPS + * request. + * + * The username may not contain a colon. Some protocols may impose + * additional requirements on pre-escaping the username and + * password. For instance, when used with OAuth2, both arguments must + * be URL encoded first with [url.QueryEscape]. + */ + setBasicAuth(username: string, password: string): void + } + interface Request { + /** + * ParseForm populates r.Form and r.PostForm. + * + * For all requests, ParseForm parses the raw query from the URL and updates + * r.Form. + * + * For POST, PUT, and PATCH requests, it also reads the request body, parses it + * as a form and puts the results into both r.PostForm and r.Form. Request body + * parameters take precedence over URL query string values in r.Form. + * + * If the request Body's size has not already been limited by [MaxBytesReader], + * the size is capped at 10MB. + * + * For other HTTP methods, or when the Content-Type is not + * application/x-www-form-urlencoded, the request Body is not read, and + * r.PostForm is initialized to a non-nil, empty value. + * + * [Request.ParseMultipartForm] calls ParseForm automatically. + * ParseForm is idempotent. + */ + parseForm(): void + } + interface Request { + /** + * ParseMultipartForm parses a request body as multipart/form-data. + * The whole request body is parsed and up to a total of maxMemory bytes of + * its file parts are stored in memory, with the remainder stored on + * disk in temporary files. + * ParseMultipartForm calls [Request.ParseForm] if necessary. + * If ParseForm returns an error, ParseMultipartForm returns it but also + * continues parsing the request body. + * After one call to ParseMultipartForm, subsequent calls have no effect. + */ + parseMultipartForm(maxMemory: number): void + } + interface Request { + /** + * FormValue returns the first value for the named component of the query. + * The precedence order: + * 1. application/x-www-form-urlencoded form body (POST, PUT, PATCH only) + * 2. query parameters (always) + * 3. multipart/form-data form body (always) + * + * FormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] + * if necessary and ignores any errors returned by these functions. + * If key is not present, FormValue returns the empty string. + * To access multiple values of the same key, call ParseForm and + * then inspect [Request.Form] directly. + */ + formValue(key: string): string + } + interface Request { + /** + * PostFormValue returns the first value for the named component of the POST, + * PUT, or PATCH request body. URL query parameters are ignored. + * PostFormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary and ignores + * any errors returned by these functions. + * If key is not present, PostFormValue returns the empty string. + */ + postFormValue(key: string): string + } + interface Request { + /** + * FormFile returns the first file for the provided form key. + * FormFile calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary. + */ + formFile(key: string): [multipart.File, (multipart.FileHeader)] + } + interface Request { + /** + * PathValue returns the value for the named path wildcard in the [ServeMux] pattern + * that matched the request. + * It returns the empty string if the request was not matched against a pattern + * or there is no such wildcard in the pattern. + */ + pathValue(name: string): string + } + interface Request { + /** + * SetPathValue sets name to value, so that subsequent calls to r.PathValue(name) + * return value. + */ + setPathValue(name: string, value: string): void + } + /** + * A Handler responds to an HTTP request. + * + * [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter] + * and then return. Returning signals that the request is finished; it + * is not valid to use the [ResponseWriter] or read from the + * [Request.Body] after or concurrently with the completion of the + * ServeHTTP call. + * + * Depending on the HTTP client software, HTTP protocol version, and + * any intermediaries between the client and the Go server, it may not + * be possible to read from the [Request.Body] after writing to the + * [ResponseWriter]. Cautious handlers should read the [Request.Body] + * first, and then reply. + * + * Except for reading the body, handlers should not modify the + * provided Request. + * + * If ServeHTTP panics, the server (the caller of ServeHTTP) assumes + * that the effect of the panic was isolated to the active request. + * It recovers the panic, logs a stack trace to the server error log, + * and either closes the network connection or sends an HTTP/2 + * RST_STREAM, depending on the HTTP protocol. To abort a handler so + * the client sees an interrupted response but the server doesn't log + * an error, panic with the value [ErrAbortHandler]. + */ + interface Handler { + [key:string]: any; + serveHTTP(_arg0: ResponseWriter, _arg1: Request): void + } + /** + * A ResponseWriter interface is used by an HTTP handler to + * construct an HTTP response. + * + * A ResponseWriter may not be used after [Handler.ServeHTTP] has returned. + */ + interface ResponseWriter { + [key:string]: any; + /** + * Header returns the header map that will be sent by + * [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which + * [Handler] implementations can set HTTP trailers. + * + * Changing the header map after a call to [ResponseWriter.WriteHeader] (or + * [ResponseWriter.Write]) has no effect unless the HTTP status code was of the + * 1xx class or the modified headers are trailers. + * + * There are two ways to set Trailers. The preferred way is to + * predeclare in the headers which trailers you will later + * send by setting the "Trailer" header to the names of the + * trailer keys which will come later. In this case, those + * keys of the Header map are treated as if they were + * trailers. See the example. The second way, for trailer + * keys not known to the [Handler] until after the first [ResponseWriter.Write], + * is to prefix the [Header] map keys with the [TrailerPrefix] + * constant value. + * + * To suppress automatic response headers (such as "Date"), set + * their value to nil. + */ + header(): Header + /** + * Write writes the data to the connection as part of an HTTP reply. + * + * If [ResponseWriter.WriteHeader] has not yet been called, Write calls + * WriteHeader(http.StatusOK) before writing the data. If the Header + * does not contain a Content-Type line, Write adds a Content-Type set + * to the result of passing the initial 512 bytes of written data to + * [DetectContentType]. Additionally, if the total size of all written + * data is under a few KB and there are no Flush calls, the + * Content-Length header is added automatically. + * + * Depending on the HTTP protocol version and the client, calling + * Write or WriteHeader may prevent future reads on the + * Request.Body. For HTTP/1.x requests, handlers should read any + * needed request body data before writing the response. Once the + * headers have been flushed (due to either an explicit Flusher.Flush + * call or writing enough data to trigger a flush), the request body + * may be unavailable. For HTTP/2 requests, the Go HTTP server permits + * handlers to continue to read the request body while concurrently + * writing the response. However, such behavior may not be supported + * by all HTTP/2 clients. Handlers should read before writing if + * possible to maximize compatibility. + */ + write(_arg0: string|Array): number + /** + * WriteHeader sends an HTTP response header with the provided + * status code. + * + * If WriteHeader is not called explicitly, the first call to Write + * will trigger an implicit WriteHeader(http.StatusOK). + * Thus explicit calls to WriteHeader are mainly used to + * send error codes or 1xx informational responses. + * + * The provided code must be a valid HTTP 1xx-5xx status code. + * Any number of 1xx headers may be written, followed by at most + * one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx + * headers may be buffered. Use the Flusher interface to send + * buffered data. The header map is cleared when 2xx-5xx headers are + * sent, but not with 1xx headers. + * + * The server will automatically send a 100 (Continue) header + * on the first read from the request body if the request has + * an "Expect: 100-continue" header. + */ + writeHeader(statusCode: number): void + } + /** + * A Server defines parameters for running an HTTP server. + * The zero value for Server is a valid configuration. + */ + interface Server { + /** + * Addr optionally specifies the TCP address for the server to listen on, + * in the form "host:port". If empty, ":http" (port 80) is used. + * The service names are defined in RFC 6335 and assigned by IANA. + * See net.Dial for details of the address format. + */ + addr: string + handler: Handler // handler to invoke, http.DefaultServeMux if nil + /** + * DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler, + * otherwise responds with 200 OK and Content-Length: 0. + */ + disableGeneralOptionsHandler: boolean + /** + * TLSConfig optionally provides a TLS configuration for use + * by ServeTLS and ListenAndServeTLS. Note that this value is + * cloned by ServeTLS and ListenAndServeTLS, so it's not + * possible to modify the configuration with methods like + * tls.Config.SetSessionTicketKeys. To use + * SetSessionTicketKeys, use Server.Serve with a TLS Listener + * instead. + */ + tlsConfig?: any + /** + * ReadTimeout is the maximum duration for reading the entire + * request, including the body. A zero or negative value means + * there will be no timeout. + * + * Because ReadTimeout does not let Handlers make per-request + * decisions on each request body's acceptable deadline or + * upload rate, most users will prefer to use + * ReadHeaderTimeout. It is valid to use them both. + */ + readTimeout: time.Duration + /** + * ReadHeaderTimeout is the amount of time allowed to read + * request headers. The connection's read deadline is reset + * after reading the headers and the Handler can decide what + * is considered too slow for the body. If zero, the value of + * ReadTimeout is used. If negative, or if zero and ReadTimeout + * is zero or negative, there is no timeout. + */ + readHeaderTimeout: time.Duration + /** + * WriteTimeout is the maximum duration before timing out + * writes of the response. It is reset whenever a new + * request's header is read. Like ReadTimeout, it does not + * let Handlers make decisions on a per-request basis. + * A zero or negative value means there will be no timeout. + */ + writeTimeout: time.Duration + /** + * IdleTimeout is the maximum amount of time to wait for the + * next request when keep-alives are enabled. If zero, the value + * of ReadTimeout is used. If negative, or if zero and ReadTimeout + * is zero or negative, there is no timeout. + */ + idleTimeout: time.Duration + /** + * MaxHeaderBytes controls the maximum number of bytes the + * server will read parsing the request header's keys and + * values, including the request line. It does not limit the + * size of the request body. + * If zero, DefaultMaxHeaderBytes is used. + */ + maxHeaderBytes: number + /** + * TLSNextProto optionally specifies a function to take over + * ownership of the provided TLS connection when an ALPN + * protocol upgrade has occurred. The map key is the protocol + * name negotiated. The Handler argument should be used to + * handle HTTP requests and will initialize the Request's TLS + * and RemoteAddr if not already set. The connection is + * automatically closed when the function returns. + * If TLSNextProto is not nil, HTTP/2 support is not enabled + * automatically. + */ + tlsNextProto: _TygojaDict + /** + * ConnState specifies an optional callback function that is + * called when a client connection changes state. See the + * ConnState type and associated constants for details. + */ + connState: (_arg0: net.Conn, _arg1: ConnState) => void + /** + * ErrorLog specifies an optional logger for errors accepting + * connections, unexpected behavior from handlers, and + * underlying FileSystem errors. + * If nil, logging is done via the log package's standard logger. + */ + errorLog?: any + /** + * BaseContext optionally specifies a function that returns + * the base context for incoming requests on this server. + * The provided Listener is the specific Listener that's + * about to start accepting requests. + * If BaseContext is nil, the default is context.Background(). + * If non-nil, it must return a non-nil context. + */ + baseContext: (_arg0: net.Listener) => context.Context + /** + * ConnContext optionally specifies a function that modifies + * the context used for a new connection c. The provided ctx + * is derived from the base context and has a ServerContextKey + * value. + */ + connContext: (ctx: context.Context, c: net.Conn) => context.Context + /** + * HTTP2 configures HTTP/2 connections. + * + * This field does not yet have any effect. + * See https://go.dev/issue/67813. + */ + http2?: HTTP2Config + /** + * Protocols is the set of protocols accepted by the server. + * + * If Protocols includes UnencryptedHTTP2, the server will accept + * unencrypted HTTP/2 connections. The server can serve both + * HTTP/1 and unencrypted HTTP/2 on the same address and port. + * + * If Protocols is nil, the default is usually HTTP/1 and HTTP/2. + * If TLSNextProto is non-nil and does not contain an "h2" entry, + * the default is HTTP/1 only. + */ + protocols?: Protocols + } + interface Server { + /** + * Close immediately closes all active net.Listeners and any + * connections in state [StateNew], [StateActive], or [StateIdle]. For a + * graceful shutdown, use [Server.Shutdown]. + * + * Close does not attempt to close (and does not even know about) + * any hijacked connections, such as WebSockets. + * + * Close returns any error returned from closing the [Server]'s + * underlying Listener(s). + */ + close(): void + } + interface Server { + /** + * Shutdown gracefully shuts down the server without interrupting any + * active connections. Shutdown works by first closing all open + * listeners, then closing all idle connections, and then waiting + * indefinitely for connections to return to idle and then shut down. + * If the provided context expires before the shutdown is complete, + * Shutdown returns the context's error, otherwise it returns any + * error returned from closing the [Server]'s underlying Listener(s). + * + * When Shutdown is called, [Serve], [ServeTLS], [ListenAndServe], and + * [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the + * program doesn't exit and waits instead for Shutdown to return. + * + * Shutdown does not attempt to close nor wait for hijacked + * connections such as WebSockets. The caller of Shutdown should + * separately notify such long-lived connections of shutdown and wait + * for them to close, if desired. See [Server.RegisterOnShutdown] for a way to + * register shutdown notification functions. + * + * Once Shutdown has been called on a server, it may not be reused; + * future calls to methods such as Serve will return ErrServerClosed. + */ + shutdown(ctx: context.Context): void + } + interface Server { + /** + * RegisterOnShutdown registers a function to call on [Server.Shutdown]. + * This can be used to gracefully shutdown connections that have + * undergone ALPN protocol upgrade or that have been hijacked. + * This function should start protocol-specific graceful shutdown, + * but should not wait for shutdown to complete. + */ + registerOnShutdown(f: () => void): void + } + interface Server { + /** + * ListenAndServe listens on the TCP network address s.Addr and then + * calls [Serve] to handle requests on incoming connections. + * Accepted connections are configured to enable TCP keep-alives. + * + * If s.Addr is blank, ":http" is used. + * + * ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close], + * the returned error is [ErrServerClosed]. + */ + listenAndServe(): void + } + interface Server { + /** + * Serve accepts incoming connections on the Listener l, creating a + * new service goroutine for each. The service goroutines read requests and + * then call s.Handler to reply to them. + * + * HTTP/2 support is only enabled if the Listener returns [*tls.Conn] + * connections and they were configured with "h2" in the TLS + * Config.NextProtos. + * + * Serve always returns a non-nil error and closes l. + * After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed]. + */ + serve(l: net.Listener): void + } + interface Server { + /** + * ServeTLS accepts incoming connections on the Listener l, creating a + * new service goroutine for each. The service goroutines perform TLS + * setup and then read requests, calling s.Handler to reply to them. + * + * Files containing a certificate and matching private key for the + * server must be provided if neither the [Server]'s + * TLSConfig.Certificates, TLSConfig.GetCertificate nor + * config.GetConfigForClient are populated. + * If the certificate is signed by a certificate authority, the + * certFile should be the concatenation of the server's certificate, + * any intermediates, and the CA's certificate. + * + * ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the + * returned error is [ErrServerClosed]. + */ + serveTLS(l: net.Listener, certFile: string, keyFile: string): void + } + interface Server { + /** + * SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. + * By default, keep-alives are always enabled. Only very + * resource-constrained environments or servers in the process of + * shutting down should disable them. + */ + setKeepAlivesEnabled(v: boolean): void + } + interface Server { + /** + * ListenAndServeTLS listens on the TCP network address s.Addr and + * then calls [ServeTLS] to handle requests on incoming TLS connections. + * Accepted connections are configured to enable TCP keep-alives. + * + * Filenames containing a certificate and matching private key for the + * server must be provided if neither the [Server]'s TLSConfig.Certificates + * nor TLSConfig.GetCertificate are populated. If the certificate is + * signed by a certificate authority, the certFile should be the + * concatenation of the server's certificate, any intermediates, and + * the CA's certificate. + * + * If s.Addr is blank, ":https" is used. + * + * ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or + * [Server.Close], the returned error is [ErrServerClosed]. + */ + listenAndServeTLS(certFile: string, keyFile: string): void + } +} + +/** + * Package types implements some commonly used db serializable types + * like datetime, json, etc. + */ +namespace types { + /** + * DateTime represents a [time.Time] instance in UTC that is wrapped + * and serialized using the app default date layout. + */ + interface DateTime { + } + interface DateTime { + /** + * Time returns the internal [time.Time] instance. + */ + time(): time.Time + } + interface DateTime { + /** + * Add returns a new DateTime based on the current DateTime + the specified duration. + */ + add(duration: time.Duration): DateTime + } + interface DateTime { + /** + * Sub returns a [time.Duration] by subtracting the specified DateTime from the current one. + * + * If the result exceeds the maximum (or minimum) value that can be stored in a [time.Duration], + * the maximum (or minimum) duration will be returned. + */ + sub(u: DateTime): time.Duration + } + interface DateTime { + /** + * AddDate returns a new DateTime based on the current one + duration. + * + * It follows the same rules as [time.AddDate]. + */ + addDate(years: number, months: number, days: number): DateTime + } + interface DateTime { + /** + * After reports whether the current DateTime instance is after u. + */ + after(u: DateTime): boolean + } + interface DateTime { + /** + * Before reports whether the current DateTime instance is before u. + */ + before(u: DateTime): boolean + } + interface DateTime { + /** + * Compare compares the current DateTime instance with u. + * If the current instance is before u, it returns -1. + * If the current instance is after u, it returns +1. + * If they're the same, it returns 0. + */ + compare(u: DateTime): number + } + interface DateTime { + /** + * Equal reports whether the current DateTime and u represent the same time instant. + * Two DateTime can be equal even if they are in different locations. + * For example, 6:00 +0200 and 4:00 UTC are Equal. + */ + equal(u: DateTime): boolean + } + interface DateTime { + /** + * Unix returns the current DateTime as a Unix time, aka. + * the number of seconds elapsed since January 1, 1970 UTC. + */ + unix(): number + } + interface DateTime { + /** + * IsZero checks whether the current DateTime instance has zero time value. + */ + isZero(): boolean + } + interface DateTime { + /** + * String serializes the current DateTime instance into a formatted + * UTC date string. + * + * The zero value is serialized to an empty string. + */ + string(): string + } + interface DateTime { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface DateTime { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface DateTime { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface DateTime { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current DateTime instance. + */ + scan(value: any): void + } + /** + * GeoPoint defines a struct for storing geo coordinates as serialized json object + * (e.g. {lon:0,lat:0}). + * + * Note: using object notation and not a plain array to avoid the confusion + * as there doesn't seem to be a fixed standard for the coordinates order. + */ + interface GeoPoint { + lon: number + lat: number + } + interface GeoPoint { + /** + * String returns the string representation of the current GeoPoint instance. + */ + string(): string + } + interface GeoPoint { + /** + * AsMap implements [core.mapExtractor] and returns a value suitable + * to be used in an API rule expression. + */ + asMap(): _TygojaDict + } + interface GeoPoint { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface GeoPoint { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current GeoPoint instance. + * + * The value argument could be nil (no-op), another GeoPoint instance, + * map or serialized json object with lat-lon props. + */ + scan(value: any): void + } + /** + * JSONArray defines a slice that is safe for json and db read/write. + */ + interface JSONArray extends Array{} + interface JSONArray { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONArray { + /** + * String returns the string representation of the current json array. + */ + string(): string + } + interface JSONArray { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONArray { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONArray[T] instance. + */ + scan(value: any): void + } + /** + * JSONMap defines a map that is safe for json and db read/write. + */ + interface JSONMap extends _TygojaDict{} + interface JSONMap { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONMap { + /** + * String returns the string representation of the current json map. + */ + string(): string + } + interface JSONMap { + /** + * Get retrieves a single value from the current JSONMap[T]. + * + * This helper was added primarily to assist the goja integration since custom map types + * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). + */ + get(key: string): T + } + interface JSONMap { + /** + * Set sets a single value in the current JSONMap[T]. + * + * This helper was added primarily to assist the goja integration since custom map types + * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). + */ + set(key: string, value: T): void + } + interface JSONMap { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONMap { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONMap[T] instance. + */ + scan(value: any): void + } + /** + * JSONRaw defines a json value type that is safe for db read/write. + */ + interface JSONRaw extends Array{} + interface JSONRaw { + /** + * String returns the current JSONRaw instance as a json encoded string. + */ + string(): string + } + interface JSONRaw { + /** + * MarshalJSON implements the [json.Marshaler] interface. + */ + marshalJSON(): string|Array + } + interface JSONRaw { + /** + * UnmarshalJSON implements the [json.Unmarshaler] interface. + */ + unmarshalJSON(b: string|Array): void + } + interface JSONRaw { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + interface JSONRaw { + /** + * Scan implements [sql.Scanner] interface to scan the provided value + * into the current JSONRaw instance. + */ + scan(value: any): void + } +} + +namespace auth { + /** + * @todo refactor and consider replace with a plain struct + * + * Provider defines a common interface for an OAuth2 client. + */ + interface Provider { + [key:string]: any; + /** + * @todo temp backport + * + * Order returns the sorting order of the provider usually used in the auth methods list response. + */ + logo(): string + /** + * @todo temp backport + * + * Order returns the sorting order of the provider usually used in the auth methods list response. + */ + order(): number + /** + * Context returns the context associated with the provider (if any). + */ + context(): context.Context + /** + * SetContext assigns the specified context to the current provider. + */ + setContext(ctx: context.Context): void + /** + * PKCE indicates whether the provider can use the PKCE flow. + */ + pkce(): boolean + /** + * SetPKCE toggles the state whether the provider can use the PKCE flow or not. + */ + setPKCE(enable: boolean): void + /** + * DisplayName usually returns provider name as it is officially written + * and it could be used directly in the UI. + */ + displayName(): string + /** + * SetDisplayName sets the provider's display name. + */ + setDisplayName(displayName: string): void + /** + * Scopes returns the provider access permissions that will be requested. + */ + scopes(): Array + /** + * SetScopes sets the provider access permissions that will be requested later. + */ + setScopes(scopes: Array): void + /** + * ClientId returns the provider client's app ID. + */ + clientId(): string + /** + * SetClientId sets the provider client's ID. + */ + setClientId(clientId: string): void + /** + * ClientSecret returns the provider client's app secret. + */ + clientSecret(): string + /** + * SetClientSecret sets the provider client's app secret. + */ + setClientSecret(secret: string): void + /** + * RedirectURL returns the end address to redirect the user + * going through the OAuth flow. + */ + redirectURL(): string + /** + * SetRedirectURL sets the provider's RedirectURL. + */ + setRedirectURL(url: string): void + /** + * AuthURL returns the provider's authorization service url. + */ + authURL(): string + /** + * SetAuthURL sets the provider's AuthURL. + */ + setAuthURL(url: string): void + /** + * TokenURL returns the provider's token exchange service url. + */ + tokenURL(): string + /** + * SetTokenURL sets the provider's TokenURL. + */ + setTokenURL(url: string): void + /** + * UserInfoURL returns the provider's user info api url. + */ + userInfoURL(): string + /** + * SetUserInfoURL sets the provider's UserInfoURL. + */ + setUserInfoURL(url: string): void + /** + * Extra returns a shallow copy of any custom config data + * that the provider may need. + */ + extra(): _TygojaDict + /** + * SetExtra updates the provider's custom config data. + */ + setExtra(data: _TygojaDict): void + /** + * Client returns an http client using the provided token. + */ + client(token: oauth2.Token): (any) + /** + * BuildAuthURL returns a URL to the provider's consent page + * that asks for permissions for the required scopes explicitly. + */ + buildAuthURL(state: string, ...opts: oauth2.AuthCodeOption[]): string + /** + * FetchToken converts an authorization code to token. + */ + fetchToken(code: string, ...opts: oauth2.AuthCodeOption[]): (oauth2.Token) + /** + * FetchRawUserInfo requests and marshalizes into `result` the + * the OAuth user api response. + */ + fetchRawUserInfo(token: oauth2.Token): string|Array + /** + * FetchAuthUser is similar to FetchRawUserInfo, but normalizes and + * marshalizes the user api response into a standardized AuthUser struct. + */ + fetchAuthUser(token: oauth2.Token): (AuthUser) + } + /** + * AuthUser defines a standardized OAuth2 user data structure. + */ + interface AuthUser { + expiry: types.DateTime + rawUser: _TygojaDict + id: string + name: string + username: string + avatarURL: string + accessToken: string + refreshToken: string + /** + * The VERIFIED OAuth2 account email. + * + * It must be empty if the provider is not able to verify the email ownership. + */ + email: string + /** + * @todo + * deprecated: use AvatarURL instead + * AvatarUrl will be removed after dropping v0.22 support + */ + avatarUrl: string + } + interface AuthUser { + /** + * MarshalJSON implements the [json.Marshaler] interface. + * + * @todo remove after dropping v0.22 support + */ + marshalJSON(): string|Array + } +} + +namespace store { + /** + * Store defines a concurrent safe in memory key-value data store. + */ + interface Store { + } + interface Store { + /** + * Reset clears the store and replaces the store data with a + * shallow copy of the provided newData. + */ + reset(newData: _TygojaDict): void + } + interface Store { + /** + * Length returns the current number of elements in the store. + */ + length(): number + } + interface Store { + /** + * RemoveAll removes all the existing store entries. + */ + removeAll(): void + } + interface Store { + /** + * Remove removes a single entry from the store. + * + * Remove does nothing if key doesn't exist in the store. + */ + remove(key: K): void + } + interface Store { + /** + * Has checks if element with the specified key exist or not. + */ + has(key: K): boolean + } + interface Store { + /** + * Get returns a single element value from the store. + * + * If key is not set, the zero T value is returned. + */ + get(key: K): T + } + interface Store { + /** + * GetOk is similar to Get but returns also a boolean indicating whether the key exists or not. + */ + getOk(key: K): [T, boolean] + } + interface Store { + /** + * GetAll returns a shallow copy of the current store data. + */ + getAll(): _TygojaDict + } + interface Store { + /** + * Values returns a slice with all of the current store values. + */ + values(): Array + } + interface Store { + /** + * Set sets (or overwrite if already exists) a new value for key. + */ + set(key: K, value: T): void + } + interface Store { + /** + * SetFunc sets (or overwrite if already exists) a new value resolved + * from the function callback for the provided key. + * + * The function callback receives as argument the old store element value (if exists). + * If there is no old store element, the argument will be the T zero value. + * + * Example: + * + * ``` + * s := store.New[string, int](nil) + * s.SetFunc("count", func(old int) int { + * return old + 1 + * }) + * ``` + */ + setFunc(key: K, fn: (old: T) => T): void + } + interface Store { + /** + * GetOrSet retrieves a single existing value for the provided key + * or stores a new one if it doesn't exist. + */ + getOrSet(key: K, setFunc: () => T): T + } + interface Store { + /** + * SetIfLessThanLimit sets (or overwrite if already exist) a new value for key. + * + * This method is similar to Set() but **it will skip adding new elements** + * to the store if the store length has reached the specified limit. + * false is returned if maxAllowedElements limit is reached. + */ + setIfLessThanLimit(key: K, value: T, maxAllowedElements: number): boolean + } + interface Store { + /** + * UnmarshalJSON implements [json.Unmarshaler] and imports the + * provided JSON data into the store. + * + * The store entries that match with the ones from the data will be overwritten with the new value. + */ + unmarshalJSON(data: string|Array): void + } + interface Store { + /** + * MarshalJSON implements [json.Marshaler] and export the current + * store data into valid JSON. + */ + marshalJSON(): string|Array + } +} + +namespace hook { + /** + * Event implements [Resolver] and it is intended to be used as a base + * Hook event that you can embed in your custom typed event structs. + * + * Example: + * + * ``` + * type CustomEvent struct { + * hook.Event + * + * SomeField int + * } + * ``` + */ + interface Event { + } + interface Event { + /** + * Next calls the next hook handler. + */ + next(): void + } + /** + * Handler defines a single Hook handler. + * Multiple handlers can share the same id. + * If Id is not explicitly set it will be autogenerated by Hook.Add and Hook.AddHandler. + */ + interface Handler { + /** + * Func defines the handler function to execute. + * + * Note that users need to call e.Next() in order to proceed with + * the execution of the hook chain. + */ + func: (_arg0: T) => void + /** + * Id is the unique identifier of the handler. + * + * It could be used later to remove the handler from a hook via [Hook.Remove]. + * + * If missing, an autogenerated value will be assigned when adding + * the handler to a hook. + */ + id: string + /** + * Priority allows changing the default exec priority of the handler within a hook. + * + * If 0, the handler will be executed in the same order it was registered. + */ + priority: number + } + /** + * Hook defines a generic concurrent safe structure for managing event hooks. + * + * When using custom event it must embed the base [hook.Event]. + * + * Example: + * + * ``` + * type CustomEvent struct { + * hook.Event + * SomeField int + * } + * + * h := Hook[*CustomEvent]{} + * + * h.BindFunc(func(e *CustomEvent) error { + * println(e.SomeField) + * + * return e.Next() + * }) + * + * h.Trigger(&CustomEvent{ SomeField: 123 }) + * ``` + */ + interface Hook { + } + interface Hook { + /** + * Bind registers the provided handler to the current hooks queue. + * + * If handler.Id is empty it is updated with autogenerated value. + * + * If a handler from the current hook list has Id matching handler.Id + * then the old handler is replaced with the new one. + */ + bind(handler: Handler): string + } + interface Hook { + /** + * BindFunc is similar to Bind but registers a new handler from just the provided function. + * + * The registered handler is added with a default 0 priority and the id will be autogenerated. + * + * If you want to register a handler with custom priority or id use the [Hook.Bind] method. + */ + bindFunc(fn: (e: T) => void): string + } + interface Hook { + /** + * Unbind removes one or many hook handler by their id. + */ + unbind(...idsToRemove: string[]): void + } + interface Hook { + /** + * UnbindAll removes all registered handlers. + */ + unbindAll(): void + } + interface Hook { + /** + * Length returns to total number of registered hook handlers. + */ + length(): number + } + interface Hook { + /** + * Trigger executes all registered hook handlers one by one + * with the specified event as an argument. + * + * Optionally, this method allows also to register additional one off + * handler funcs that will be temporary appended to the handlers queue. + * + * NB! Each hook handler must call event.Next() in order the hook chain to proceed. + */ + trigger(event: T, ...oneOffHandlerFuncs: ((_arg0: T) => void)[]): void + } + /** + * TaggedHook defines a proxy hook which register handlers that are triggered only + * if the TaggedHook.tags are empty or includes at least one of the event data tag(s). + */ + type _syyYiyB = mainHook + interface TaggedHook extends _syyYiyB { + } + interface TaggedHook { + /** + * CanTriggerOn checks if the current TaggedHook can be triggered with + * the provided event data tags. + * + * It returns always true if the hook doesn't have any tags. + */ + canTriggerOn(tagsToCheck: Array): boolean + } + interface TaggedHook { + /** + * Bind registers the provided handler to the current hooks queue. + * + * It is similar to [Hook.Bind] with the difference that the handler + * function is invoked only if the event data tags satisfy h.CanTriggerOn. + */ + bind(handler: Handler): string + } + interface TaggedHook { + /** + * BindFunc registers a new handler with the specified function. + * + * It is similar to [Hook.Bind] with the difference that the handler + * function is invoked only if the event data tags satisfy h.CanTriggerOn. + */ + bindFunc(fn: (e: T) => void): string + } +} + +/** + * Package sql provides a generic interface around SQL (or SQL-like) + * databases. + * + * The sql package must be used in conjunction with a database driver. + * See https://golang.org/s/sqldrivers for a list of drivers. + * + * Drivers that do not support context cancellation will not return until + * after the query is completed. + * + * For usage examples, see the wiki page at + * https://golang.org/s/sqlwiki. + */ +namespace sql { + /** + * TxOptions holds the transaction options to be used in [DB.BeginTx]. + */ + interface TxOptions { + /** + * Isolation is the transaction isolation level. + * If zero, the driver or database's default level is used. + */ + isolation: IsolationLevel + readOnly: boolean + } + /** + * NullString represents a string that may be null. + * NullString implements the [Scanner] interface so + * it can be used as a scan destination: + * + * ``` + * var s NullString + * err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) + * ... + * if s.Valid { + * // use s.String + * } else { + * // NULL value + * } + * ``` + */ + interface NullString { + string: string + valid: boolean // Valid is true if String is not NULL + } + interface NullString { + /** + * Scan implements the [Scanner] interface. + */ + scan(value: any): void + } + interface NullString { + /** + * Value implements the [driver.Valuer] interface. + */ + value(): any + } + /** + * DB is a database handle representing a pool of zero or more + * underlying connections. It's safe for concurrent use by multiple + * goroutines. + * + * The sql package creates and frees connections automatically; it + * also maintains a free pool of idle connections. If the database has + * a concept of per-connection state, such state can be reliably observed + * within a transaction ([Tx]) or connection ([Conn]). Once [DB.Begin] is called, the + * returned [Tx] is bound to a single connection. Once [Tx.Commit] or + * [Tx.Rollback] is called on the transaction, that transaction's + * connection is returned to [DB]'s idle connection pool. The pool size + * can be controlled with [DB.SetMaxIdleConns]. + */ + interface DB { + } + interface DB { + /** + * PingContext verifies a connection to the database is still alive, + * establishing a connection if necessary. + */ + pingContext(ctx: context.Context): void + } + interface DB { + /** + * Ping verifies a connection to the database is still alive, + * establishing a connection if necessary. + * + * Ping uses [context.Background] internally; to specify the context, use + * [DB.PingContext]. + */ + ping(): void + } + interface DB { + /** + * Close closes the database and prevents new queries from starting. + * Close then waits for all queries that have started processing on the server + * to finish. + * + * It is rare to Close a [DB], as the [DB] handle is meant to be + * long-lived and shared between many goroutines. + */ + close(): void + } + interface DB { + /** + * SetMaxIdleConns sets the maximum number of connections in the idle + * connection pool. + * + * If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, + * then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. + * + * If n <= 0, no idle connections are retained. + * + * The default max idle connections is currently 2. This may change in + * a future release. + */ + setMaxIdleConns(n: number): void + } + interface DB { + /** + * SetMaxOpenConns sets the maximum number of open connections to the database. + * + * If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than + * MaxIdleConns, then MaxIdleConns will be reduced to match the new + * MaxOpenConns limit. + * + * If n <= 0, then there is no limit on the number of open connections. + * The default is 0 (unlimited). + */ + setMaxOpenConns(n: number): void + } + interface DB { + /** + * SetConnMaxLifetime sets the maximum amount of time a connection may be reused. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's age. + */ + setConnMaxLifetime(d: time.Duration): void + } + interface DB { + /** + * SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. + * + * Expired connections may be closed lazily before reuse. + * + * If d <= 0, connections are not closed due to a connection's idle time. + */ + setConnMaxIdleTime(d: time.Duration): void + } + interface DB { + /** + * Stats returns database statistics. + */ + stats(): DBStats + } + interface DB { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface DB { + /** + * Prepare creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [DB.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface DB { + /** + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface DB { + /** + * Exec executes a query without returning any rows. + * The args are for any placeholder parameters in the query. + * + * Exec uses [context.Background] internally; to specify the context, use + * [DB.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface DB { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * Query executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. + * + * Query uses [context.Background] internally; to specify the context, use + * [DB.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface DB { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface DB { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [DB.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + interface DB { + /** + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. + */ + beginTx(ctx: context.Context, opts: TxOptions): (Tx) + } + interface DB { + /** + * Begin starts a transaction. The default isolation level is dependent on + * the driver. + * + * Begin uses [context.Background] internally; to specify the context, use + * [DB.BeginTx]. + */ + begin(): (Tx) + } + interface DB { + /** + * Driver returns the database's underlying driver. + */ + driver(): any + } + interface DB { + /** + * Conn returns a single connection by either opening a new connection + * or returning an existing connection from the connection pool. Conn will + * block until either a connection is returned or ctx is canceled. + * Queries run on the same Conn will be run in the same database session. + * + * Every Conn must be returned to the database pool after use by + * calling [Conn.Close]. + */ + conn(ctx: context.Context): (Conn) + } + /** + * Tx is an in-progress database transaction. + * + * A transaction must end with a call to [Tx.Commit] or [Tx.Rollback]. + * + * After a call to [Tx.Commit] or [Tx.Rollback], all operations on the + * transaction fail with [ErrTxDone]. + * + * The statements prepared for a transaction by calling + * the transaction's [Tx.Prepare] or [Tx.Stmt] methods are closed + * by the call to [Tx.Commit] or [Tx.Rollback]. + */ + interface Tx { + } + interface Tx { + /** + * Commit commits the transaction. + */ + commit(): void + } + interface Tx { + /** + * Rollback aborts the transaction. + */ + rollback(): void + } + interface Tx { + /** + * PrepareContext creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * The provided context will be used for the preparation of the context, not + * for the execution of the returned statement. The returned statement + * will run in the transaction context. + */ + prepareContext(ctx: context.Context, query: string): (Stmt) + } + interface Tx { + /** + * Prepare creates a prepared statement for use within a transaction. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * To use an existing prepared statement on this transaction, see [Tx.Stmt]. + * + * Prepare uses [context.Background] internally; to specify the context, use + * [Tx.PrepareContext]. + */ + prepare(query: string): (Stmt) + } + interface Tx { + /** + * StmtContext returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) + * ``` + * + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + */ + stmtContext(ctx: context.Context, stmt: Stmt): (Stmt) + } + interface Tx { + /** + * Stmt returns a transaction-specific prepared statement from + * an existing statement. + * + * Example: + * + * ``` + * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") + * ... + * tx, err := db.Begin() + * ... + * res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) + * ``` + * + * The returned statement operates within the transaction and will be closed + * when the transaction has been committed or rolled back. + * + * Stmt uses [context.Background] internally; to specify the context, use + * [Tx.StmtContext]. + */ + stmt(stmt: Stmt): (Stmt) + } + interface Tx { + /** + * ExecContext executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + */ + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Tx { + /** + * Exec executes a query that doesn't return rows. + * For example: an INSERT and UPDATE. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Tx.ExecContext]. + */ + exec(query: string, ...args: any[]): Result + } + interface Tx { + /** + * QueryContext executes a query that returns rows, typically a SELECT. + */ + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * Query executes a query that returns rows, typically a SELECT. + * + * Query uses [context.Background] internally; to specify the context, use + * [Tx.QueryContext]. + */ + query(query: string, ...args: any[]): (Rows) + } + interface Tx { + /** + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Tx { + /** + * QueryRow executes a query that is expected to return at most one row. + * QueryRow always returns a non-nil value. Errors are deferred until + * [Row]'s Scan method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Tx.QueryRowContext]. + */ + queryRow(query: string, ...args: any[]): (Row) + } + /** + * Stmt is a prepared statement. + * A Stmt is safe for concurrent use by multiple goroutines. + * + * If a Stmt is prepared on a [Tx] or [Conn], it will be bound to a single + * underlying connection forever. If the [Tx] or [Conn] closes, the Stmt will + * become unusable and all operations will return an error. + * If a Stmt is prepared on a [DB], it will remain usable for the lifetime of the + * [DB]. When the Stmt needs to execute on a new underlying connection, it will + * prepare itself on the new connection automatically. + */ + interface Stmt { + } + interface Stmt { + /** + * ExecContext executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + */ + execContext(ctx: context.Context, ...args: any[]): Result + } + interface Stmt { + /** + * Exec executes a prepared statement with the given arguments and + * returns a [Result] summarizing the effect of the statement. + * + * Exec uses [context.Background] internally; to specify the context, use + * [Stmt.ExecContext]. + */ + exec(...args: any[]): Result + } + interface Stmt { + /** + * QueryContext executes a prepared query statement with the given arguments + * and returns the query results as a [*Rows]. + */ + queryContext(ctx: context.Context, ...args: any[]): (Rows) + } + interface Stmt { + /** + * Query executes a prepared query statement with the given arguments + * and returns the query results as a *Rows. + * + * Query uses [context.Background] internally; to specify the context, use + * [Stmt.QueryContext]. + */ + query(...args: any[]): (Rows) + } + interface Stmt { + /** + * QueryRowContext executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, ...args: any[]): (Row) + } + interface Stmt { + /** + * QueryRow executes a prepared query statement with the given arguments. + * If an error occurs during the execution of the statement, that error will + * be returned by a call to Scan on the returned [*Row], which is always non-nil. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + * + * Example usage: + * + * ``` + * var name string + * err := nameByUseridStmt.QueryRow(id).Scan(&name) + * ``` + * + * QueryRow uses [context.Background] internally; to specify the context, use + * [Stmt.QueryRowContext]. + */ + queryRow(...args: any[]): (Row) + } + interface Stmt { + /** + * Close closes the statement. + */ + close(): void + } + /** + * Rows is the result of a query. Its cursor starts before the first row + * of the result set. Use [Rows.Next] to advance from row to row. + */ + interface Rows { + } + interface Rows { + /** + * Next prepares the next result row for reading with the [Rows.Scan] method. It + * returns true on success, or false if there is no next result row or an error + * happened while preparing it. [Rows.Err] should be consulted to distinguish between + * the two cases. + * + * Every call to [Rows.Scan], even the first one, must be preceded by a call to [Rows.Next]. + */ + next(): boolean + } + interface Rows { + /** + * NextResultSet prepares the next result set for reading. It reports whether + * there is further result sets, or false if there is no further result set + * or if there is an error advancing to it. The [Rows.Err] method should be consulted + * to distinguish between the two cases. + * + * After calling NextResultSet, the [Rows.Next] method should always be called before + * scanning. If there are further result sets they may not have rows in the result + * set. + */ + nextResultSet(): boolean + } + interface Rows { + /** + * Err returns the error, if any, that was encountered during iteration. + * Err may be called after an explicit or implicit [Rows.Close]. + */ + err(): void + } + interface Rows { + /** + * Columns returns the column names. + * Columns returns an error if the rows are closed. + */ + columns(): Array + } + interface Rows { + /** + * ColumnTypes returns column information such as column type, length, + * and nullable. Some information may not be available from some drivers. + */ + columnTypes(): Array<(ColumnType | undefined)> + } + interface Rows { + /** + * Scan copies the columns in the current row into the values pointed + * at by dest. The number of values in dest must be the same as the + * number of columns in [Rows]. + * + * Scan converts columns read from the database into the following + * common Go types and special types provided by the sql package: + * + * ``` + * *string + * *[]byte + * *int, *int8, *int16, *int32, *int64 + * *uint, *uint8, *uint16, *uint32, *uint64 + * *bool + * *float32, *float64 + * *interface{} + * *RawBytes + * *Rows (cursor value) + * any type implementing Scanner (see Scanner docs) + * ``` + * + * In the most simple case, if the type of the value from the source + * column is an integer, bool or string type T and dest is of type *T, + * Scan simply assigns the value through the pointer. + * + * Scan also converts between string and numeric types, as long as no + * information would be lost. While Scan stringifies all numbers + * scanned from numeric database columns into *string, scans into + * numeric types are checked for overflow. For example, a float64 with + * value 300 or a string with value "300" can scan into a uint16, but + * not into a uint8, though float64(255) or "255" can scan into a + * uint8. One exception is that scans of some float64 numbers to + * strings may lose information when stringifying. In general, scan + * floating point columns into *float64. + * + * If a dest argument has type *[]byte, Scan saves in that argument a + * copy of the corresponding data. The copy is owned by the caller and + * can be modified and held indefinitely. The copy can be avoided by + * using an argument of type [*RawBytes] instead; see the documentation + * for [RawBytes] for restrictions on its use. + * + * If an argument has type *interface{}, Scan copies the value + * provided by the underlying driver without conversion. When scanning + * from a source value of type []byte to *interface{}, a copy of the + * slice is made and the caller owns the result. + * + * Source values of type [time.Time] may be scanned into values of type + * *time.Time, *interface{}, *string, or *[]byte. When converting to + * the latter two, [time.RFC3339Nano] is used. + * + * Source values of type bool may be scanned into types *bool, + * *interface{}, *string, *[]byte, or [*RawBytes]. + * + * For scanning into *bool, the source may be true, false, 1, 0, or + * string inputs parseable by [strconv.ParseBool]. + * + * Scan can also convert a cursor returned from a query, such as + * "select cursor(select * from my_table) from dual", into a + * [*Rows] value that can itself be scanned from. The parent + * select query will close any cursor [*Rows] if the parent [*Rows] is closed. + * + * If any of the first arguments implementing [Scanner] returns an error, + * that error will be wrapped in the returned error. + */ + scan(...dest: any[]): void + } + interface Rows { + /** + * Close closes the [Rows], preventing further enumeration. If [Rows.Next] is called + * and returns false and there are no further result sets, + * the [Rows] are closed automatically and it will suffice to check the + * result of [Rows.Err]. Close is idempotent and does not affect the result of [Rows.Err]. + */ + close(): void + } + /** + * A Result summarizes an executed SQL command. + */ + interface Result { + [key:string]: any; + /** + * LastInsertId returns the integer generated by the database + * in response to a command. Typically this will be from an + * "auto increment" column when inserting a new row. Not all + * databases support this feature, and the syntax of such + * statements varies. + */ + lastInsertId(): number + /** + * RowsAffected returns the number of rows affected by an + * update, insert, or delete. Not every database or database + * driver may support this. + */ + rowsAffected(): number + } +} + +/** + * Package blob defines a lightweight abstration for interacting with + * various storage services (local filesystem, S3, etc.). + * + * NB! + * For compatibility with earlier PocketBase versions and to prevent + * unnecessary breaking changes, this package is based and implemented + * as a minimal, stripped down version of the previously used gocloud.dev/blob. + * While there is no promise that it won't diverge in the future to accommodate + * better some PocketBase specific use cases, currently it copies and + * tries to follow as close as possible the same implementations, + * conventions and rules for the key escaping/unescaping, blob read/write + * interfaces and struct options as gocloud.dev/blob, therefore the + * credits goes to the original Go Cloud Development Kit Authors. + */ +namespace blob { + /** + * ListObject represents a single blob returned from List. + */ + interface ListObject { + /** + * Key is the key for this blob. + */ + key: string + /** + * ModTime is the time the blob was last modified. + */ + modTime: time.Time + /** + * Size is the size of the blob's content in bytes. + */ + size: number + /** + * MD5 is an MD5 hash of the blob contents or nil if not available. + */ + md5: string|Array + /** + * IsDir indicates that this result represents a "directory" in the + * hierarchical namespace, ending in ListOptions.Delimiter. Key can be + * passed as ListOptions.Prefix to list items in the "directory". + * Fields other than Key and IsDir will not be set if IsDir is true. + */ + isDir: boolean + } + /** + * Attributes contains attributes about a blob. + */ + interface Attributes { + /** + * CacheControl specifies caching attributes that services may use + * when serving the blob. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control + */ + cacheControl: string + /** + * ContentDisposition specifies whether the blob content is expected to be + * displayed inline or as an attachment. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + */ + contentDisposition: string + /** + * ContentEncoding specifies the encoding used for the blob's content, if any. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + */ + contentEncoding: string + /** + * ContentLanguage specifies the language used in the blob's content, if any. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language + */ + contentLanguage: string + /** + * ContentType is the MIME type of the blob. It will not be empty. + * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type + */ + contentType: string + /** + * Metadata holds key/value pairs associated with the blob. + * Keys are guaranteed to be in lowercase, even if the backend service + * has case-sensitive keys (although note that Metadata written via + * this package will always be lowercased). If there are duplicate + * case-insensitive keys (e.g., "foo" and "FOO"), only one value + * will be kept, and it is undefined which one. + */ + metadata: _TygojaDict + /** + * CreateTime is the time the blob was created, if available. If not available, + * CreateTime will be the zero time. + */ + createTime: time.Time + /** + * ModTime is the time the blob was last modified. + */ + modTime: time.Time + /** + * Size is the size of the blob's content in bytes. + */ + size: number + /** + * MD5 is an MD5 hash of the blob contents or nil if not available. + */ + md5: string|Array + /** + * ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag. + */ + eTag: string + } + /** + * Reader reads bytes from a blob. + * It implements io.ReadSeekCloser, and must be closed after reads are finished. + */ + interface Reader { + } + interface Reader { + /** + * Read implements io.Reader (https://golang.org/pkg/io/#Reader). + */ + read(p: string|Array): number + } + interface Reader { + /** + * Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker). + */ + seek(offset: number, whence: number): number + } + interface Reader { + /** + * Close implements io.Closer (https://golang.org/pkg/io/#Closer). + */ + close(): void + } + interface Reader { + /** + * ContentType returns the MIME type of the blob. + */ + contentType(): string + } + interface Reader { + /** + * ModTime returns the time the blob was last modified. + */ + modTime(): time.Time + } + interface Reader { + /** + * Size returns the size of the blob content in bytes. + */ + size(): number + } + interface Reader { + /** + * WriteTo reads from r and writes to w until there's no more data or + * an error occurs. + * The return value is the number of bytes written to w. + * + * It implements the io.WriterTo interface. + */ + writeTo(w: io.Writer): number + } +} + +namespace search { + /** + * Result defines the returned search result structure. + */ + interface Result { + items: any + page: number + perPage: number + totalItems: number + totalPages: number + } + /** + * ResolverResult defines a single FieldResolver.Resolve() successfully parsed result. + */ + interface ResolverResult { + /** + * Identifier is the plain SQL identifier/column that will be used + * in the final db expression as left or right operand. + */ + identifier: string + /** + * NullFallback specify the preference for how NULL or empty values + * should be resolved (default to "auto"). + * + * Set to NullFallbackDisabled to prevent any COALESCE or NULL fallbacks. + * Set to NullFallbackEnforced to prefer COALESCE or NULL fallbacks when needed. + */ + nullFallback: NullFallbackPreference + /** + * Params is a map with db placeholder->value pairs that will be added + * to the query when building both resolved operands/sides in a single expression. + */ + params: dbx.Params + /** + * MultiMatchSubQuery is an optional sub query expression that will be added + * in addition to the combined ResolverResult expression during build. + */ + multiMatchSubQuery?: MultiMatchSubquery + /** + * AfterBuild is an optional function that will be called after building + * and combining the result of both resolved operands/sides in a single expression. + */ + afterBuild: (expr: dbx.Expression) => dbx.Expression + } +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation + /** + * ApiError defines the struct for a basic api error response. + */ + interface ApiError { + data: _TygojaDict + message: string + status: number + } + interface ApiError { + /** + * Error makes it compatible with the `error` interface. + */ + error(): string + } + interface ApiError { + /** + * RawData returns the unformatted error data (could be an internal error, text, etc.) + */ + rawData(): any + } + interface ApiError { + /** + * Is reports whether the current ApiError wraps the target. + */ + is(target: Error): boolean + } + /** + * Event specifies based Route handler event that is usually intended + * to be embedded as part of a custom event struct. + * + * NB! It is expected that the Response and Request fields are always set. + */ + type _sZCZnSo = hook.Event + interface Event extends _sZCZnSo { + response: http.ResponseWriter + request?: http.Request + } + interface Event { + /** + * Written reports whether the current response has already been written. + * + * This method always returns false if e.ResponseWritter doesn't implement the WriteTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + written(): boolean + } + interface Event { + /** + * Status reports the status code of the current response. + * + * This method always returns 0 if e.Response doesn't implement the StatusTracker interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + status(): number + } + interface Event { + /** + * Flush flushes buffered data to the current response. + * + * Returns [http.ErrNotSupported] if e.Response doesn't implement the [http.Flusher] interface + * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). + */ + flush(): void + } + interface Event { + /** + * IsTLS reports whether the connection on which the request was received is TLS. + */ + isTLS(): boolean + } + interface Event { + /** + * SetCookie is an alias for [http.SetCookie]. + * + * SetCookie adds a Set-Cookie header to the current response's headers. + * The provided cookie must have a valid Name. + * Invalid cookies may be silently dropped. + */ + setCookie(cookie: http.Cookie): void + } + interface Event { + /** + * RemoteIP returns the IP address of the client that sent the request. + * + * IPv6 addresses are returned expanded. + * For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001". + * + * Note that if you are behind reverse proxy(ies), this method returns + * the IP of the last connecting proxy. + */ + remoteIP(): string + } + interface Event { + /** + * FindUploadedFiles extracts all form files of "key" from a http request + * and returns a slice with filesystem.File instances (if any). + */ + findUploadedFiles(key: string): Array<(filesystem.File | undefined)> + } + interface Event { + /** + * Get retrieves single value from the current event data store. + */ + get(key: string): any + } + interface Event { + /** + * GetAll returns a copy of the current event data store. + */ + getAll(): _TygojaDict + } + interface Event { + /** + * Set saves single value into the current event data store. + */ + set(key: string, value: any): void + } + interface Event { + /** + * SetAll saves all items from m into the current event data store. + */ + setAll(m: _TygojaDict): void + } + interface Event { + /** + * String writes a plain string response. + */ + string(status: number, data: string): void + } + interface Event { + /** + * HTML writes an HTML response. + */ + html(status: number, data: string): void + } + interface Event { + /** + * JSON writes a JSON response. + * + * It also provides a generic response data fields picker if the "fields" query parameter is set. + * For example, if you are requesting `?fields=a,b` for `e.JSON(200, map[string]int{ "a":1, "b":2, "c":3 })`, + * it should result in a JSON response like: `{"a":1, "b": 2}`. + */ + json(status: number, data: any): void + } + interface Event { + /** + * XML writes an XML response. + * It automatically prepends the generic [xml.Header] string to the response. + */ + xml(status: number, data: any): void + } + interface Event { + /** + * Stream streams the specified reader into the response. + */ + stream(status: number, contentType: string, reader: io.Reader): void + } + interface Event { + /** + * Blob writes a blob (bytes slice) response. + */ + blob(status: number, contentType: string, b: string|Array): void + } + interface Event { + /** + * FileFS serves the specified filename from fsys. + * + * It is similar to [echo.FileFS] for consistency with earlier versions. + */ + fileFS(fsys: fs.FS, filename: string): void + } + interface Event { + /** + * NoContent writes a response with no body (ex. 204). + */ + noContent(status: number): void + } + interface Event { + /** + * Redirect writes a redirect response to the specified url. + * The status code must be in between 300 – 399 range. + */ + redirect(status: number, url: string): void + } + interface Event { + error(status: number, message: string, errData: any): (ApiError) + } + interface Event { + badRequestError(message: string, errData: any): (ApiError) + } + interface Event { + notFoundError(message: string, errData: any): (ApiError) + } + interface Event { + forbiddenError(message: string, errData: any): (ApiError) + } + interface Event { + unauthorizedError(message: string, errData: any): (ApiError) + } + interface Event { + tooManyRequestsError(message: string, errData: any): (ApiError) + } + interface Event { + internalServerError(message: string, errData: any): (ApiError) + } + interface Event { + /** + * BindBody unmarshal the request body into the provided dst. + * + * dst must be either a struct pointer or map[string]any. + * + * The rules how the body will be scanned depends on the request Content-Type. + * + * Currently the following Content-Types are supported: + * ``` + * - application/json + * - text/xml, application/xml + * - multipart/form-data, application/x-www-form-urlencoded + * ``` + * + * Respectively the following struct tags are supported (again, which one will be used depends on the Content-Type): + * ``` + * - "json" (json body)- uses the builtin Go json package for unmarshaling. + * - "xml" (xml body) - uses the builtin Go xml package for unmarshaling. + * - "form" (form data) - utilizes the custom [router.UnmarshalRequestData] method. + * ``` + * + * NB! When dst is a struct make sure that it doesn't have public fields + * that shouldn't be bindable and it is advisible such fields to be unexported + * or have a separate struct just for the binding. For example: + * + * ``` + * data := struct{ + * somethingPrivate string + * + * Title string `json:"title" form:"title"` + * Total int `json:"total" form:"total"` + * } + * err := e.BindBody(&data) + * ``` + */ + bindBody(dst: any): void + } + /** + * Router defines a thin wrapper around the standard Go [http.ServeMux] by + * adding support for routing sub-groups, middlewares and other common utils. + * + * Example: + * + * ``` + * r := NewRouter[*MyEvent](eventFactory) + * + * // middlewares + * r.BindFunc(m1, m2) + * + * // routes + * r.GET("/test", handler1) + * + * // sub-routers/groups + * api := r.Group("/api") + * api.GET("/admins", handler2) + * + * // generate a http.ServeMux instance based on the router configurations + * mux, _ := r.BuildMux() + * + * http.ListenAndServe("localhost:8090", mux) + * ``` + */ + type _sdyWRKt = RouterGroup + interface Router extends _sdyWRKt { + } + interface Router { + /** + * BuildMux constructs a new mux [http.Handler] instance from the current router configurations. + */ + buildMux(): http.Handler + } +} + +namespace exec { + /** + * Cmd represents an external command being prepared or run. + * + * A Cmd cannot be reused after calling its [Cmd.Run], [Cmd.Output] or [Cmd.CombinedOutput] + * methods. + */ + interface Cmd { + /** + * Path is the path of the command to run. + * + * This is the only field that must be set to a non-zero + * value. If Path is relative, it is evaluated relative + * to Dir. + */ + path: string + /** + * Args holds command line arguments, including the command as Args[0]. + * If the Args field is empty or nil, Run uses {Path}. + * + * In typical use, both Path and Args are set by calling Command. + */ + args: Array + /** + * Env specifies the environment of the process. + * Each entry is of the form "key=value". + * If Env is nil, the new process uses the current process's + * environment. + * If Env contains duplicate environment keys, only the last + * value in the slice for each duplicate key is used. + * As a special case on Windows, SYSTEMROOT is always added if + * missing and not explicitly set to the empty string. + * + * See also the Dir field, which may set PWD in the environment. + */ + env: Array + /** + * Dir specifies the working directory of the command. + * If Dir is the empty string, Run runs the command in the + * calling process's current directory. + * + * On Unix systems, the value of Dir also determines the + * child process's PWD environment variable if not otherwise + * specified. A Unix process represents its working directory + * not by name but as an implicit reference to a node in the + * file tree. So, if the child process obtains its working + * directory by calling a function such as C's getcwd, which + * computes the canonical name by walking up the file tree, it + * will not recover the original value of Dir if that value + * was an alias involving symbolic links. However, if the + * child process calls Go's [os.Getwd] or GNU C's + * get_current_dir_name, and the value of PWD is an alias for + * the current directory, those functions will return the + * value of PWD, which matches the value of Dir. + */ + dir: string + /** + * Stdin specifies the process's standard input. + * + * If Stdin is nil, the process reads from the null device (os.DevNull). + * + * If Stdin is an *os.File, the process's standard input is connected + * directly to that file. + * + * Otherwise, during the execution of the command a separate + * goroutine reads from Stdin and delivers that data to the command + * over a pipe. In this case, Wait does not complete until the goroutine + * stops copying, either because it has reached the end of Stdin + * (EOF or a read error), or because writing to the pipe returned an error, + * or because a nonzero WaitDelay was set and expired. + */ + stdin: io.Reader + /** + * Stdout and Stderr specify the process's standard output and error. + * + * If either is nil, Run connects the corresponding file descriptor + * to the null device (os.DevNull). + * + * If either is an *os.File, the corresponding output from the process + * is connected directly to that file. + * + * Otherwise, during the execution of the command a separate goroutine + * reads from the process over a pipe and delivers that data to the + * corresponding Writer. In this case, Wait does not complete until the + * goroutine reaches EOF or encounters an error or a nonzero WaitDelay + * expires. + * + * If Stdout and Stderr are the same writer, and have a type that can + * be compared with ==, at most one goroutine at a time will call Write. + */ + stdout: io.Writer + stderr: io.Writer + /** + * ExtraFiles specifies additional open files to be inherited by the + * new process. It does not include standard input, standard output, or + * standard error. If non-nil, entry i becomes file descriptor 3+i. + * + * ExtraFiles is not supported on Windows. + */ + extraFiles: Array<(os.File | undefined)> + /** + * SysProcAttr holds optional, operating system-specific attributes. + * Run passes it to os.StartProcess as the os.ProcAttr's Sys field. + */ + sysProcAttr?: syscall.SysProcAttr + /** + * Process is the underlying process, once started. + */ + process?: os.Process + /** + * ProcessState contains information about an exited process. + * If the process was started successfully, Wait or Run will + * populate its ProcessState when the command completes. + */ + processState?: os.ProcessState + err: Error // LookPath error, if any. + /** + * If Cancel is non-nil, the command must have been created with + * CommandContext and Cancel will be called when the command's + * Context is done. By default, CommandContext sets Cancel to + * call the Kill method on the command's Process. + * + * Typically a custom Cancel will send a signal to the command's + * Process, but it may instead take other actions to initiate cancellation, + * such as closing a stdin or stdout pipe or sending a shutdown request on a + * network socket. + * + * If the command exits with a success status after Cancel is + * called, and Cancel does not return an error equivalent to + * os.ErrProcessDone, then Wait and similar methods will return a non-nil + * error: either an error wrapping the one returned by Cancel, + * or the error from the Context. + * (If the command exits with a non-success status, or Cancel + * returns an error that wraps os.ErrProcessDone, Wait and similar methods + * continue to return the command's usual exit status.) + * + * If Cancel is set to nil, nothing will happen immediately when the command's + * Context is done, but a nonzero WaitDelay will still take effect. That may + * be useful, for example, to work around deadlocks in commands that do not + * support shutdown signals but are expected to always finish quickly. + * + * Cancel will not be called if Start returns a non-nil error. + */ + cancel: () => void + /** + * If WaitDelay is non-zero, it bounds the time spent waiting on two sources + * of unexpected delay in Wait: a child process that fails to exit after the + * associated Context is canceled, and a child process that exits but leaves + * its I/O pipes unclosed. + * + * The WaitDelay timer starts when either the associated Context is done or a + * call to Wait observes that the child process has exited, whichever occurs + * first. When the delay has elapsed, the command shuts down the child process + * and/or its I/O pipes. + * + * If the child process has failed to exit — perhaps because it ignored or + * failed to receive a shutdown signal from a Cancel function, or because no + * Cancel function was set — then it will be terminated using os.Process.Kill. + * + * Then, if the I/O pipes communicating with the child process are still open, + * those pipes are closed in order to unblock any goroutines currently blocked + * on Read or Write calls. + * + * If pipes are closed due to WaitDelay, no Cancel call has occurred, + * and the command has otherwise exited with a successful status, Wait and + * similar methods will return ErrWaitDelay instead of nil. + * + * If WaitDelay is zero (the default), I/O pipes will be read until EOF, + * which might not occur until orphaned subprocesses of the command have + * also closed their descriptors for the pipes. + */ + waitDelay: time.Duration + } + interface Cmd { + /** + * String returns a human-readable description of c. + * It is intended only for debugging. + * In particular, it is not suitable for use as input to a shell. + * The output of String may vary across Go releases. + */ + string(): string + } + interface Cmd { + /** + * Run starts the specified command and waits for it to complete. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command starts but does not complete successfully, the error is of + * type [*ExitError]. Other error types may be returned for other situations. + * + * If the calling goroutine has locked the operating system thread + * with [runtime.LockOSThread] and modified any inheritable OS-level + * thread state (for example, Linux or Plan 9 name spaces), the new + * process will inherit the caller's thread state. + */ + run(): void + } + interface Cmd { + /** + * Start starts the specified command but does not wait for it to complete. + * + * If Start returns successfully, the c.Process field will be set. + * + * After a successful call to Start the [Cmd.Wait] method must be called in + * order to release associated system resources. + */ + start(): void + } + interface Cmd { + /** + * Wait waits for the command to exit and waits for any copying to + * stdin or copying from stdout or stderr to complete. + * + * The command must have been started by [Cmd.Start]. + * + * The returned error is nil if the command runs, has no problems + * copying stdin, stdout, and stderr, and exits with a zero exit + * status. + * + * If the command fails to run or doesn't complete successfully, the + * error is of type [*ExitError]. Other error types may be + * returned for I/O problems. + * + * If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits + * for the respective I/O loop copying to or from the process to complete. + * + * Wait releases any resources associated with the [Cmd]. + */ + wait(): void + } + interface Cmd { + /** + * Output runs the command and returns its standard output. + * Any returned error will usually be of type [*ExitError]. + * If c.Stderr was nil and the returned error is of type + * [*ExitError], Output populates the Stderr field of the + * returned error. + */ + output(): string|Array + } + interface Cmd { + /** + * CombinedOutput runs the command and returns its combined standard + * output and standard error. + */ + combinedOutput(): string|Array + } + interface Cmd { + /** + * StdinPipe returns a pipe that will be connected to the command's + * standard input when the command starts. + * The pipe will be closed automatically after [Cmd.Wait] sees the command exit. + * A caller need only call Close to force the pipe to close sooner. + * For example, if the command being run will not exit until standard input + * is closed, the caller must close the pipe. + */ + stdinPipe(): io.WriteCloser + } + interface Cmd { + /** + * StdoutPipe returns a pipe that will be connected to the command's + * standard output when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe. + * See the example for idiomatic usage. + */ + stdoutPipe(): io.ReadCloser + } + interface Cmd { + /** + * StderrPipe returns a pipe that will be connected to the command's + * standard error when the command starts. + * + * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers + * need not close the pipe themselves. It is thus incorrect to call Wait + * before all reads from the pipe have completed. + * For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe. + * See the StdoutPipe example for idiomatic usage. + */ + stderrPipe(): io.ReadCloser + } + interface Cmd { + /** + * Environ returns a copy of the environment in which the command would be run + * as it is currently configured. + */ + environ(): Array + } +} + +namespace mailer { + /** + * Message defines a generic email message struct. + */ + interface Message { + from: { address: string; name?: string; } + to: Array<{ address: string; name?: string; }> + bcc: Array<{ address: string; name?: string; }> + cc: Array<{ address: string; name?: string; }> + subject: string + html: string + text: string + headers: _TygojaDict + attachments: _TygojaDict + inlineAttachments: _TygojaDict + } + /** + * Mailer defines a base mail client interface. + */ + interface Mailer { + [key:string]: any; + /** + * Send sends an email with the provided Message. + */ + send(message: Message): void + } +} + /** * Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. * In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. @@ -17848,3387 +21394,6 @@ namespace cobra { } } -/** - * Package sql provides a generic interface around SQL (or SQL-like) - * databases. - * - * The sql package must be used in conjunction with a database driver. - * See https://golang.org/s/sqldrivers for a list of drivers. - * - * Drivers that do not support context cancellation will not return until - * after the query is completed. - * - * For usage examples, see the wiki page at - * https://golang.org/s/sqlwiki. - */ -namespace sql { - /** - * TxOptions holds the transaction options to be used in [DB.BeginTx]. - */ - interface TxOptions { - /** - * Isolation is the transaction isolation level. - * If zero, the driver or database's default level is used. - */ - isolation: IsolationLevel - readOnly: boolean - } - /** - * NullString represents a string that may be null. - * NullString implements the [Scanner] interface so - * it can be used as a scan destination: - * - * ``` - * var s NullString - * err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) - * ... - * if s.Valid { - * // use s.String - * } else { - * // NULL value - * } - * ``` - */ - interface NullString { - string: string - valid: boolean // Valid is true if String is not NULL - } - interface NullString { - /** - * Scan implements the [Scanner] interface. - */ - scan(value: any): void - } - interface NullString { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - /** - * DB is a database handle representing a pool of zero or more - * underlying connections. It's safe for concurrent use by multiple - * goroutines. - * - * The sql package creates and frees connections automatically; it - * also maintains a free pool of idle connections. If the database has - * a concept of per-connection state, such state can be reliably observed - * within a transaction ([Tx]) or connection ([Conn]). Once [DB.Begin] is called, the - * returned [Tx] is bound to a single connection. Once [Tx.Commit] or - * [Tx.Rollback] is called on the transaction, that transaction's - * connection is returned to [DB]'s idle connection pool. The pool size - * can be controlled with [DB.SetMaxIdleConns]. - */ - interface DB { - } - interface DB { - /** - * PingContext verifies a connection to the database is still alive, - * establishing a connection if necessary. - */ - pingContext(ctx: context.Context): void - } - interface DB { - /** - * Ping verifies a connection to the database is still alive, - * establishing a connection if necessary. - * - * Ping uses [context.Background] internally; to specify the context, use - * [DB.PingContext]. - */ - ping(): void - } - interface DB { - /** - * Close closes the database and prevents new queries from starting. - * Close then waits for all queries that have started processing on the server - * to finish. - * - * It is rare to Close a [DB], as the [DB] handle is meant to be - * long-lived and shared between many goroutines. - */ - close(): void - } - interface DB { - /** - * SetMaxIdleConns sets the maximum number of connections in the idle - * connection pool. - * - * If MaxOpenConns is greater than 0 but less than the new MaxIdleConns, - * then the new MaxIdleConns will be reduced to match the MaxOpenConns limit. - * - * If n <= 0, no idle connections are retained. - * - * The default max idle connections is currently 2. This may change in - * a future release. - */ - setMaxIdleConns(n: number): void - } - interface DB { - /** - * SetMaxOpenConns sets the maximum number of open connections to the database. - * - * If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than - * MaxIdleConns, then MaxIdleConns will be reduced to match the new - * MaxOpenConns limit. - * - * If n <= 0, then there is no limit on the number of open connections. - * The default is 0 (unlimited). - */ - setMaxOpenConns(n: number): void - } - interface DB { - /** - * SetConnMaxLifetime sets the maximum amount of time a connection may be reused. - * - * Expired connections may be closed lazily before reuse. - * - * If d <= 0, connections are not closed due to a connection's age. - */ - setConnMaxLifetime(d: time.Duration): void - } - interface DB { - /** - * SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. - * - * Expired connections may be closed lazily before reuse. - * - * If d <= 0, connections are not closed due to a connection's idle time. - */ - setConnMaxIdleTime(d: time.Duration): void - } - interface DB { - /** - * Stats returns database statistics. - */ - stats(): DBStats - } - interface DB { - /** - * PrepareContext creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface DB { - /** - * Prepare creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * Prepare uses [context.Background] internally; to specify the context, use - * [DB.PrepareContext]. - */ - prepare(query: string): (Stmt) - } - interface DB { - /** - * ExecContext executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface DB { - /** - * Exec executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - * - * Exec uses [context.Background] internally; to specify the context, use - * [DB.ExecContext]. - */ - exec(query: string, ...args: any[]): Result - } - interface DB { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface DB { - /** - * Query executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - * - * Query uses [context.Background] internally; to specify the context, use - * [DB.QueryContext]. - */ - query(query: string, ...args: any[]): (Rows) - } - interface DB { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface DB { - /** - * QueryRow executes a query that is expected to return at most one row. - * QueryRow always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, [*Row.Scan] scans the first selected row and discards - * the rest. - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [DB.QueryRowContext]. - */ - queryRow(query: string, ...args: any[]): (Row) - } - interface DB { - /** - * BeginTx starts a transaction. - * - * The provided context is used until the transaction is committed or rolled back. - * If the context is canceled, the sql package will roll back - * the transaction. [Tx.Commit] will return an error if the context provided to - * BeginTx is canceled. - * - * The provided [TxOptions] is optional and may be nil if defaults should be used. - * If a non-default isolation level is used that the driver doesn't support, - * an error will be returned. - */ - beginTx(ctx: context.Context, opts: TxOptions): (Tx) - } - interface DB { - /** - * Begin starts a transaction. The default isolation level is dependent on - * the driver. - * - * Begin uses [context.Background] internally; to specify the context, use - * [DB.BeginTx]. - */ - begin(): (Tx) - } - interface DB { - /** - * Driver returns the database's underlying driver. - */ - driver(): any - } - interface DB { - /** - * Conn returns a single connection by either opening a new connection - * or returning an existing connection from the connection pool. Conn will - * block until either a connection is returned or ctx is canceled. - * Queries run on the same Conn will be run in the same database session. - * - * Every Conn must be returned to the database pool after use by - * calling [Conn.Close]. - */ - conn(ctx: context.Context): (Conn) - } - /** - * Tx is an in-progress database transaction. - * - * A transaction must end with a call to [Tx.Commit] or [Tx.Rollback]. - * - * After a call to [Tx.Commit] or [Tx.Rollback], all operations on the - * transaction fail with [ErrTxDone]. - * - * The statements prepared for a transaction by calling - * the transaction's [Tx.Prepare] or [Tx.Stmt] methods are closed - * by the call to [Tx.Commit] or [Tx.Rollback]. - */ - interface Tx { - } - interface Tx { - /** - * Commit commits the transaction. - */ - commit(): void - } - interface Tx { - /** - * Rollback aborts the transaction. - */ - rollback(): void - } - interface Tx { - /** - * PrepareContext creates a prepared statement for use within a transaction. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * To use an existing prepared statement on this transaction, see [Tx.Stmt]. - * - * The provided context will be used for the preparation of the context, not - * for the execution of the returned statement. The returned statement - * will run in the transaction context. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface Tx { - /** - * Prepare creates a prepared statement for use within a transaction. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * To use an existing prepared statement on this transaction, see [Tx.Stmt]. - * - * Prepare uses [context.Background] internally; to specify the context, use - * [Tx.PrepareContext]. - */ - prepare(query: string): (Stmt) - } - interface Tx { - /** - * StmtContext returns a transaction-specific prepared statement from - * an existing statement. - * - * Example: - * - * ``` - * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") - * ... - * tx, err := db.Begin() - * ... - * res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) - * ``` - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - */ - stmtContext(ctx: context.Context, stmt: Stmt): (Stmt) - } - interface Tx { - /** - * Stmt returns a transaction-specific prepared statement from - * an existing statement. - * - * Example: - * - * ``` - * updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") - * ... - * tx, err := db.Begin() - * ... - * res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) - * ``` - * - * The returned statement operates within the transaction and will be closed - * when the transaction has been committed or rolled back. - * - * Stmt uses [context.Background] internally; to specify the context, use - * [Tx.StmtContext]. - */ - stmt(stmt: Stmt): (Stmt) - } - interface Tx { - /** - * ExecContext executes a query that doesn't return rows. - * For example: an INSERT and UPDATE. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface Tx { - /** - * Exec executes a query that doesn't return rows. - * For example: an INSERT and UPDATE. - * - * Exec uses [context.Background] internally; to specify the context, use - * [Tx.ExecContext]. - */ - exec(query: string, ...args: any[]): Result - } - interface Tx { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface Tx { - /** - * Query executes a query that returns rows, typically a SELECT. - * - * Query uses [context.Background] internally; to specify the context, use - * [Tx.QueryContext]. - */ - query(query: string, ...args: any[]): (Rows) - } - interface Tx { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface Tx { - /** - * QueryRow executes a query that is expected to return at most one row. - * QueryRow always returns a non-nil value. Errors are deferred until - * [Row]'s Scan method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [Tx.QueryRowContext]. - */ - queryRow(query: string, ...args: any[]): (Row) - } - /** - * Stmt is a prepared statement. - * A Stmt is safe for concurrent use by multiple goroutines. - * - * If a Stmt is prepared on a [Tx] or [Conn], it will be bound to a single - * underlying connection forever. If the [Tx] or [Conn] closes, the Stmt will - * become unusable and all operations will return an error. - * If a Stmt is prepared on a [DB], it will remain usable for the lifetime of the - * [DB]. When the Stmt needs to execute on a new underlying connection, it will - * prepare itself on the new connection automatically. - */ - interface Stmt { - } - interface Stmt { - /** - * ExecContext executes a prepared statement with the given arguments and - * returns a [Result] summarizing the effect of the statement. - */ - execContext(ctx: context.Context, ...args: any[]): Result - } - interface Stmt { - /** - * Exec executes a prepared statement with the given arguments and - * returns a [Result] summarizing the effect of the statement. - * - * Exec uses [context.Background] internally; to specify the context, use - * [Stmt.ExecContext]. - */ - exec(...args: any[]): Result - } - interface Stmt { - /** - * QueryContext executes a prepared query statement with the given arguments - * and returns the query results as a [*Rows]. - */ - queryContext(ctx: context.Context, ...args: any[]): (Rows) - } - interface Stmt { - /** - * Query executes a prepared query statement with the given arguments - * and returns the query results as a *Rows. - * - * Query uses [context.Background] internally; to specify the context, use - * [Stmt.QueryContext]. - */ - query(...args: any[]): (Rows) - } - interface Stmt { - /** - * QueryRowContext executes a prepared query statement with the given arguments. - * If an error occurs during the execution of the statement, that error will - * be returned by a call to Scan on the returned [*Row], which is always non-nil. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, ...args: any[]): (Row) - } - interface Stmt { - /** - * QueryRow executes a prepared query statement with the given arguments. - * If an error occurs during the execution of the statement, that error will - * be returned by a call to Scan on the returned [*Row], which is always non-nil. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - * - * Example usage: - * - * ``` - * var name string - * err := nameByUseridStmt.QueryRow(id).Scan(&name) - * ``` - * - * QueryRow uses [context.Background] internally; to specify the context, use - * [Stmt.QueryRowContext]. - */ - queryRow(...args: any[]): (Row) - } - interface Stmt { - /** - * Close closes the statement. - */ - close(): void - } - /** - * Rows is the result of a query. Its cursor starts before the first row - * of the result set. Use [Rows.Next] to advance from row to row. - */ - interface Rows { - } - interface Rows { - /** - * Next prepares the next result row for reading with the [Rows.Scan] method. It - * returns true on success, or false if there is no next result row or an error - * happened while preparing it. [Rows.Err] should be consulted to distinguish between - * the two cases. - * - * Every call to [Rows.Scan], even the first one, must be preceded by a call to [Rows.Next]. - */ - next(): boolean - } - interface Rows { - /** - * NextResultSet prepares the next result set for reading. It reports whether - * there is further result sets, or false if there is no further result set - * or if there is an error advancing to it. The [Rows.Err] method should be consulted - * to distinguish between the two cases. - * - * After calling NextResultSet, the [Rows.Next] method should always be called before - * scanning. If there are further result sets they may not have rows in the result - * set. - */ - nextResultSet(): boolean - } - interface Rows { - /** - * Err returns the error, if any, that was encountered during iteration. - * Err may be called after an explicit or implicit [Rows.Close]. - */ - err(): void - } - interface Rows { - /** - * Columns returns the column names. - * Columns returns an error if the rows are closed. - */ - columns(): Array - } - interface Rows { - /** - * ColumnTypes returns column information such as column type, length, - * and nullable. Some information may not be available from some drivers. - */ - columnTypes(): Array<(ColumnType | undefined)> - } - interface Rows { - /** - * Scan copies the columns in the current row into the values pointed - * at by dest. The number of values in dest must be the same as the - * number of columns in [Rows]. - * - * Scan converts columns read from the database into the following - * common Go types and special types provided by the sql package: - * - * ``` - * *string - * *[]byte - * *int, *int8, *int16, *int32, *int64 - * *uint, *uint8, *uint16, *uint32, *uint64 - * *bool - * *float32, *float64 - * *interface{} - * *RawBytes - * *Rows (cursor value) - * any type implementing Scanner (see Scanner docs) - * ``` - * - * In the most simple case, if the type of the value from the source - * column is an integer, bool or string type T and dest is of type *T, - * Scan simply assigns the value through the pointer. - * - * Scan also converts between string and numeric types, as long as no - * information would be lost. While Scan stringifies all numbers - * scanned from numeric database columns into *string, scans into - * numeric types are checked for overflow. For example, a float64 with - * value 300 or a string with value "300" can scan into a uint16, but - * not into a uint8, though float64(255) or "255" can scan into a - * uint8. One exception is that scans of some float64 numbers to - * strings may lose information when stringifying. In general, scan - * floating point columns into *float64. - * - * If a dest argument has type *[]byte, Scan saves in that argument a - * copy of the corresponding data. The copy is owned by the caller and - * can be modified and held indefinitely. The copy can be avoided by - * using an argument of type [*RawBytes] instead; see the documentation - * for [RawBytes] for restrictions on its use. - * - * If an argument has type *interface{}, Scan copies the value - * provided by the underlying driver without conversion. When scanning - * from a source value of type []byte to *interface{}, a copy of the - * slice is made and the caller owns the result. - * - * Source values of type [time.Time] may be scanned into values of type - * *time.Time, *interface{}, *string, or *[]byte. When converting to - * the latter two, [time.RFC3339Nano] is used. - * - * Source values of type bool may be scanned into types *bool, - * *interface{}, *string, *[]byte, or [*RawBytes]. - * - * For scanning into *bool, the source may be true, false, 1, 0, or - * string inputs parseable by [strconv.ParseBool]. - * - * Scan can also convert a cursor returned from a query, such as - * "select cursor(select * from my_table) from dual", into a - * [*Rows] value that can itself be scanned from. The parent - * select query will close any cursor [*Rows] if the parent [*Rows] is closed. - * - * If any of the first arguments implementing [Scanner] returns an error, - * that error will be wrapped in the returned error. - */ - scan(...dest: any[]): void - } - interface Rows { - /** - * Close closes the [Rows], preventing further enumeration. If [Rows.Next] is called - * and returns false and there are no further result sets, - * the [Rows] are closed automatically and it will suffice to check the - * result of [Rows.Err]. Close is idempotent and does not affect the result of [Rows.Err]. - */ - close(): void - } - /** - * A Result summarizes an executed SQL command. - */ - interface Result { - [key:string]: any; - /** - * LastInsertId returns the integer generated by the database - * in response to a command. Typically this will be from an - * "auto increment" column when inserting a new row. Not all - * databases support this feature, and the syntax of such - * statements varies. - */ - lastInsertId(): number - /** - * RowsAffected returns the number of rows affected by an - * update, insert, or delete. Not every database or database - * driver may support this. - */ - rowsAffected(): number - } -} - -/** - * Package multipart implements MIME multipart parsing, as defined in RFC - * 2046. - * - * The implementation is sufficient for HTTP (RFC 2388) and the multipart - * bodies generated by popular browsers. - * - * # Limits - * - * To protect against malicious inputs, this package sets limits on the size - * of the MIME data it processes. - * - * [Reader.NextPart] and [Reader.NextRawPart] limit the number of headers in a - * part to 10000 and [Reader.ReadForm] limits the total number of headers in all - * FileHeaders to 10000. - * These limits may be adjusted with the GODEBUG=multipartmaxheaders= - * setting. - * - * Reader.ReadForm further limits the number of parts in a form to 1000. - * This limit may be adjusted with the GODEBUG=multipartmaxparts= - * setting. - */ -namespace multipart { - /** - * A FileHeader describes a file part of a multipart request. - */ - interface FileHeader { - filename: string - header: textproto.MIMEHeader - size: number - } - interface FileHeader { - /** - * Open opens and returns the [FileHeader]'s associated File. - */ - open(): File - } -} - -/** - * Package http provides HTTP client and server implementations. - * - * [Get], [Head], [Post], and [PostForm] make HTTP (or HTTPS) requests: - * - * ``` - * resp, err := http.Get("http://example.com/") - * ... - * resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) - * ... - * resp, err := http.PostForm("http://example.com/form", - * url.Values{"key": {"Value"}, "id": {"123"}}) - * ``` - * - * The caller must close the response body when finished with it: - * - * ``` - * resp, err := http.Get("http://example.com/") - * if err != nil { - * // handle error - * } - * defer resp.Body.Close() - * body, err := io.ReadAll(resp.Body) - * // ... - * ``` - * - * # Clients and Transports - * - * For control over HTTP client headers, redirect policy, and other - * settings, create a [Client]: - * - * ``` - * client := &http.Client{ - * CheckRedirect: redirectPolicyFunc, - * } - * - * resp, err := client.Get("http://example.com") - * // ... - * - * req, err := http.NewRequest("GET", "http://example.com", nil) - * // ... - * req.Header.Add("If-None-Match", `W/"wyzzy"`) - * resp, err := client.Do(req) - * // ... - * ``` - * - * For control over proxies, TLS configuration, keep-alives, - * compression, and other settings, create a [Transport]: - * - * ``` - * tr := &http.Transport{ - * MaxIdleConns: 10, - * IdleConnTimeout: 30 * time.Second, - * DisableCompression: true, - * } - * client := &http.Client{Transport: tr} - * resp, err := client.Get("https://example.com") - * ``` - * - * Clients and Transports are safe for concurrent use by multiple - * goroutines and for efficiency should only be created once and re-used. - * - * # Servers - * - * ListenAndServe starts an HTTP server with a given address and handler. - * The handler is usually nil, which means to use [DefaultServeMux]. - * [Handle] and [HandleFunc] add handlers to [DefaultServeMux]: - * - * ``` - * http.Handle("/foo", fooHandler) - * - * http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { - * fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) - * }) - * - * log.Fatal(http.ListenAndServe(":8080", nil)) - * ``` - * - * More control over the server's behavior is available by creating a - * custom Server: - * - * ``` - * s := &http.Server{ - * Addr: ":8080", - * Handler: myHandler, - * ReadTimeout: 10 * time.Second, - * WriteTimeout: 10 * time.Second, - * MaxHeaderBytes: 1 << 20, - * } - * log.Fatal(s.ListenAndServe()) - * ``` - * - * # HTTP/2 - * - * Starting with Go 1.6, the http package has transparent support for the - * HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2 - * can do so by setting [Transport.TLSNextProto] (for clients) or - * [Server.TLSNextProto] (for servers) to a non-nil, empty - * map. Alternatively, the following GODEBUG settings are - * currently supported: - * - * ``` - * GODEBUG=http2client=0 # disable HTTP/2 client support - * GODEBUG=http2server=0 # disable HTTP/2 server support - * GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs - * GODEBUG=http2debug=2 # ... even more verbose, with frame dumps - * ``` - * - * Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug - * - * The http package's [Transport] and [Server] both automatically enable - * HTTP/2 support for simple configurations. To enable HTTP/2 for more - * complex configurations, to use lower-level HTTP/2 features, or to use - * a newer version of Go's http2 package, import "golang.org/x/net/http2" - * directly and use its ConfigureTransport and/or ConfigureServer - * functions. Manually configuring HTTP/2 via the golang.org/x/net/http2 - * package takes precedence over the net/http package's built-in HTTP/2 - * support. - */ -namespace http { - // @ts-ignore - import mathrand = rand - /** - * PushOptions describes options for [Pusher.Push]. - */ - interface PushOptions { - /** - * Method specifies the HTTP method for the promised request. - * If set, it must be "GET" or "HEAD". Empty means "GET". - */ - method: string - /** - * Header specifies additional promised request headers. This cannot - * include HTTP/2 pseudo header fields like ":path" and ":scheme", - * which will be added automatically. - */ - header: Header - } - // @ts-ignore - import urlpkg = url - /** - * A Request represents an HTTP request received by a server - * or to be sent by a client. - * - * The field semantics differ slightly between client and server - * usage. In addition to the notes on the fields below, see the - * documentation for [Request.Write] and [RoundTripper]. - */ - interface Request { - /** - * Method specifies the HTTP method (GET, POST, PUT, etc.). - * For client requests, an empty string means GET. - */ - method: string - /** - * URL specifies either the URI being requested (for server - * requests) or the URL to access (for client requests). - * - * For server requests, the URL is parsed from the URI - * supplied on the Request-Line as stored in RequestURI. For - * most requests, fields other than Path and RawQuery will be - * empty. (See RFC 7230, Section 5.3) - * - * For client requests, the URL's Host specifies the server to - * connect to, while the Request's Host field optionally - * specifies the Host header value to send in the HTTP - * request. - */ - url?: url.URL - /** - * The protocol version for incoming server requests. - * - * For client requests, these fields are ignored. The HTTP - * client code always uses either HTTP/1.1 or HTTP/2. - * See the docs on Transport for details. - */ - proto: string // "HTTP/1.0" - protoMajor: number // 1 - protoMinor: number // 0 - /** - * Header contains the request header fields either received - * by the server or to be sent by the client. - * - * If a server received a request with header lines, - * - * ``` - * Host: example.com - * accept-encoding: gzip, deflate - * Accept-Language: en-us - * fOO: Bar - * foo: two - * ``` - * - * then - * - * ``` - * Header = map[string][]string{ - * "Accept-Encoding": {"gzip, deflate"}, - * "Accept-Language": {"en-us"}, - * "Foo": {"Bar", "two"}, - * } - * ``` - * - * For incoming requests, the Host header is promoted to the - * Request.Host field and removed from the Header map. - * - * HTTP defines that header names are case-insensitive. The - * request parser implements this by using CanonicalHeaderKey, - * making the first character and any characters following a - * hyphen uppercase and the rest lowercase. - * - * For client requests, certain headers such as Content-Length - * and Connection are automatically written when needed and - * values in Header may be ignored. See the documentation - * for the Request.Write method. - */ - header: Header - /** - * Body is the request's body. - * - * For client requests, a nil body means the request has no - * body, such as a GET request. The HTTP Client's Transport - * is responsible for calling the Close method. - * - * For server requests, the Request Body is always non-nil - * but will return EOF immediately when no body is present. - * The Server will close the request body. The ServeHTTP - * Handler does not need to. - * - * Body must allow Read to be called concurrently with Close. - * In particular, calling Close should unblock a Read waiting - * for input. - */ - body: io.ReadCloser - /** - * GetBody defines an optional func to return a new copy of - * Body. It is used for client requests when a redirect requires - * reading the body more than once. Use of GetBody still - * requires setting Body. - * - * For server requests, it is unused. - */ - getBody: () => io.ReadCloser - /** - * ContentLength records the length of the associated content. - * The value -1 indicates that the length is unknown. - * Values >= 0 indicate that the given number of bytes may - * be read from Body. - * - * For client requests, a value of 0 with a non-nil Body is - * also treated as unknown. - */ - contentLength: number - /** - * TransferEncoding lists the transfer encodings from outermost to - * innermost. An empty list denotes the "identity" encoding. - * TransferEncoding can usually be ignored; chunked encoding is - * automatically added and removed as necessary when sending and - * receiving requests. - */ - transferEncoding: Array - /** - * Close indicates whether to close the connection after - * replying to this request (for servers) or after sending this - * request and reading its response (for clients). - * - * For server requests, the HTTP server handles this automatically - * and this field is not needed by Handlers. - * - * For client requests, setting this field prevents re-use of - * TCP connections between requests to the same hosts, as if - * Transport.DisableKeepAlives were set. - */ - close: boolean - /** - * For server requests, Host specifies the host on which the - * URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this - * is either the value of the "Host" header or the host name - * given in the URL itself. For HTTP/2, it is the value of the - * ":authority" pseudo-header field. - * It may be of the form "host:port". For international domain - * names, Host may be in Punycode or Unicode form. Use - * golang.org/x/net/idna to convert it to either format if - * needed. - * To prevent DNS rebinding attacks, server Handlers should - * validate that the Host header has a value for which the - * Handler considers itself authoritative. The included - * ServeMux supports patterns registered to particular host - * names and thus protects its registered Handlers. - * - * For client requests, Host optionally overrides the Host - * header to send. If empty, the Request.Write method uses - * the value of URL.Host. Host may contain an international - * domain name. - */ - host: string - /** - * Form contains the parsed form data, including both the URL - * field's query parameters and the PATCH, POST, or PUT form data. - * This field is only available after ParseForm is called. - * The HTTP client ignores Form and uses Body instead. - */ - form: url.Values - /** - * PostForm contains the parsed form data from PATCH, POST - * or PUT body parameters. - * - * This field is only available after ParseForm is called. - * The HTTP client ignores PostForm and uses Body instead. - */ - postForm: url.Values - /** - * MultipartForm is the parsed multipart form, including file uploads. - * This field is only available after ParseMultipartForm is called. - * The HTTP client ignores MultipartForm and uses Body instead. - */ - multipartForm?: multipart.Form - /** - * Trailer specifies additional headers that are sent after the request - * body. - * - * For server requests, the Trailer map initially contains only the - * trailer keys, with nil values. (The client declares which trailers it - * will later send.) While the handler is reading from Body, it must - * not reference Trailer. After reading from Body returns EOF, Trailer - * can be read again and will contain non-nil values, if they were sent - * by the client. - * - * For client requests, Trailer must be initialized to a map containing - * the trailer keys to later send. The values may be nil or their final - * values. The ContentLength must be 0 or -1, to send a chunked request. - * After the HTTP request is sent the map values can be updated while - * the request body is read. Once the body returns EOF, the caller must - * not mutate Trailer. - * - * Few HTTP clients, servers, or proxies support HTTP trailers. - */ - trailer: Header - /** - * RemoteAddr allows HTTP servers and other software to record - * the network address that sent the request, usually for - * logging. This field is not filled in by ReadRequest and - * has no defined format. The HTTP server in this package - * sets RemoteAddr to an "IP:port" address before invoking a - * handler. - * This field is ignored by the HTTP client. - */ - remoteAddr: string - /** - * RequestURI is the unmodified request-target of the - * Request-Line (RFC 7230, Section 3.1.1) as sent by the client - * to a server. Usually the URL field should be used instead. - * It is an error to set this field in an HTTP client request. - */ - requestURI: string - /** - * TLS allows HTTP servers and other software to record - * information about the TLS connection on which the request - * was received. This field is not filled in by ReadRequest. - * The HTTP server in this package sets the field for - * TLS-enabled connections before invoking a handler; - * otherwise it leaves the field nil. - * This field is ignored by the HTTP client. - */ - tls?: any - /** - * Cancel is an optional channel whose closure indicates that the client - * request should be regarded as canceled. Not all implementations of - * RoundTripper may support Cancel. - * - * For server requests, this field is not applicable. - * - * Deprecated: Set the Request's context with NewRequestWithContext - * instead. If a Request's Cancel field and context are both - * set, it is undefined whether Cancel is respected. - */ - cancel: undefined - /** - * Response is the redirect response which caused this request - * to be created. This field is only populated during client - * redirects. - */ - response?: Response - /** - * Pattern is the [ServeMux] pattern that matched the request. - * It is empty if the request was not matched against a pattern. - */ - pattern: string - } - interface Request { - /** - * Context returns the request's context. To change the context, use - * [Request.Clone] or [Request.WithContext]. - * - * The returned context is always non-nil; it defaults to the - * background context. - * - * For outgoing client requests, the context controls cancellation. - * - * For incoming server requests, the context is canceled when the - * client's connection closes, the request is canceled (with HTTP/2), - * or when the ServeHTTP method returns. - */ - context(): context.Context - } - interface Request { - /** - * WithContext returns a shallow copy of r with its context changed - * to ctx. The provided ctx must be non-nil. - * - * For outgoing client request, the context controls the entire - * lifetime of a request and its response: obtaining a connection, - * sending the request, and reading the response headers and body. - * - * To create a new request with a context, use [NewRequestWithContext]. - * To make a deep copy of a request with a new context, use [Request.Clone]. - */ - withContext(ctx: context.Context): (Request) - } - interface Request { - /** - * Clone returns a deep copy of r with its context changed to ctx. - * The provided ctx must be non-nil. - * - * Clone only makes a shallow copy of the Body field. - * - * For an outgoing client request, the context controls the entire - * lifetime of a request and its response: obtaining a connection, - * sending the request, and reading the response headers and body. - */ - clone(ctx: context.Context): (Request) - } - interface Request { - /** - * ProtoAtLeast reports whether the HTTP protocol used - * in the request is at least major.minor. - */ - protoAtLeast(major: number, minor: number): boolean - } - interface Request { - /** - * UserAgent returns the client's User-Agent, if sent in the request. - */ - userAgent(): string - } - interface Request { - /** - * Cookies parses and returns the HTTP cookies sent with the request. - */ - cookies(): Array<(Cookie | undefined)> - } - interface Request { - /** - * CookiesNamed parses and returns the named HTTP cookies sent with the request - * or an empty slice if none matched. - */ - cookiesNamed(name: string): Array<(Cookie | undefined)> - } - interface Request { - /** - * Cookie returns the named cookie provided in the request or - * [ErrNoCookie] if not found. - * If multiple cookies match the given name, only one cookie will - * be returned. - */ - cookie(name: string): (Cookie) - } - interface Request { - /** - * AddCookie adds a cookie to the request. Per RFC 6265 section 5.4, - * AddCookie does not attach more than one [Cookie] header field. That - * means all cookies, if any, are written into the same line, - * separated by semicolon. - * AddCookie only sanitizes c's name and value, and does not sanitize - * a Cookie header already present in the request. - */ - addCookie(c: Cookie): void - } - interface Request { - /** - * Referer returns the referring URL, if sent in the request. - * - * Referer is misspelled as in the request itself, a mistake from the - * earliest days of HTTP. This value can also be fetched from the - * [Header] map as Header["Referer"]; the benefit of making it available - * as a method is that the compiler can diagnose programs that use the - * alternate (correct English) spelling req.Referrer() but cannot - * diagnose programs that use Header["Referrer"]. - */ - referer(): string - } - interface Request { - /** - * MultipartReader returns a MIME multipart reader if this is a - * multipart/form-data or a multipart/mixed POST request, else returns nil and an error. - * Use this function instead of [Request.ParseMultipartForm] to - * process the request body as a stream. - */ - multipartReader(): (multipart.Reader) - } - interface Request { - /** - * Write writes an HTTP/1.1 request, which is the header and body, in wire format. - * This method consults the following fields of the request: - * - * ``` - * Host - * URL - * Method (defaults to "GET") - * Header - * ContentLength - * TransferEncoding - * Body - * ``` - * - * If Body is present, Content-Length is <= 0 and [Request.TransferEncoding] - * hasn't been set to "identity", Write adds "Transfer-Encoding: - * chunked" to the header. Body is closed after it is sent. - */ - write(w: io.Writer): void - } - interface Request { - /** - * WriteProxy is like [Request.Write] but writes the request in the form - * expected by an HTTP proxy. In particular, [Request.WriteProxy] writes the - * initial Request-URI line of the request with an absolute URI, per - * section 5.3 of RFC 7230, including the scheme and host. - * In either case, WriteProxy also writes a Host header, using - * either r.Host or r.URL.Host. - */ - writeProxy(w: io.Writer): void - } - interface Request { - /** - * BasicAuth returns the username and password provided in the request's - * Authorization header, if the request uses HTTP Basic Authentication. - * See RFC 2617, Section 2. - */ - basicAuth(): [string, string, boolean] - } - interface Request { - /** - * SetBasicAuth sets the request's Authorization header to use HTTP - * Basic Authentication with the provided username and password. - * - * With HTTP Basic Authentication the provided username and password - * are not encrypted. It should generally only be used in an HTTPS - * request. - * - * The username may not contain a colon. Some protocols may impose - * additional requirements on pre-escaping the username and - * password. For instance, when used with OAuth2, both arguments must - * be URL encoded first with [url.QueryEscape]. - */ - setBasicAuth(username: string, password: string): void - } - interface Request { - /** - * ParseForm populates r.Form and r.PostForm. - * - * For all requests, ParseForm parses the raw query from the URL and updates - * r.Form. - * - * For POST, PUT, and PATCH requests, it also reads the request body, parses it - * as a form and puts the results into both r.PostForm and r.Form. Request body - * parameters take precedence over URL query string values in r.Form. - * - * If the request Body's size has not already been limited by [MaxBytesReader], - * the size is capped at 10MB. - * - * For other HTTP methods, or when the Content-Type is not - * application/x-www-form-urlencoded, the request Body is not read, and - * r.PostForm is initialized to a non-nil, empty value. - * - * [Request.ParseMultipartForm] calls ParseForm automatically. - * ParseForm is idempotent. - */ - parseForm(): void - } - interface Request { - /** - * ParseMultipartForm parses a request body as multipart/form-data. - * The whole request body is parsed and up to a total of maxMemory bytes of - * its file parts are stored in memory, with the remainder stored on - * disk in temporary files. - * ParseMultipartForm calls [Request.ParseForm] if necessary. - * If ParseForm returns an error, ParseMultipartForm returns it but also - * continues parsing the request body. - * After one call to ParseMultipartForm, subsequent calls have no effect. - */ - parseMultipartForm(maxMemory: number): void - } - interface Request { - /** - * FormValue returns the first value for the named component of the query. - * The precedence order: - * 1. application/x-www-form-urlencoded form body (POST, PUT, PATCH only) - * 2. query parameters (always) - * 3. multipart/form-data form body (always) - * - * FormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] - * if necessary and ignores any errors returned by these functions. - * If key is not present, FormValue returns the empty string. - * To access multiple values of the same key, call ParseForm and - * then inspect [Request.Form] directly. - */ - formValue(key: string): string - } - interface Request { - /** - * PostFormValue returns the first value for the named component of the POST, - * PUT, or PATCH request body. URL query parameters are ignored. - * PostFormValue calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary and ignores - * any errors returned by these functions. - * If key is not present, PostFormValue returns the empty string. - */ - postFormValue(key: string): string - } - interface Request { - /** - * FormFile returns the first file for the provided form key. - * FormFile calls [Request.ParseMultipartForm] and [Request.ParseForm] if necessary. - */ - formFile(key: string): [multipart.File, (multipart.FileHeader)] - } - interface Request { - /** - * PathValue returns the value for the named path wildcard in the [ServeMux] pattern - * that matched the request. - * It returns the empty string if the request was not matched against a pattern - * or there is no such wildcard in the pattern. - */ - pathValue(name: string): string - } - interface Request { - /** - * SetPathValue sets name to value, so that subsequent calls to r.PathValue(name) - * return value. - */ - setPathValue(name: string, value: string): void - } - /** - * A Handler responds to an HTTP request. - * - * [Handler.ServeHTTP] should write reply headers and data to the [ResponseWriter] - * and then return. Returning signals that the request is finished; it - * is not valid to use the [ResponseWriter] or read from the - * [Request.Body] after or concurrently with the completion of the - * ServeHTTP call. - * - * Depending on the HTTP client software, HTTP protocol version, and - * any intermediaries between the client and the Go server, it may not - * be possible to read from the [Request.Body] after writing to the - * [ResponseWriter]. Cautious handlers should read the [Request.Body] - * first, and then reply. - * - * Except for reading the body, handlers should not modify the - * provided Request. - * - * If ServeHTTP panics, the server (the caller of ServeHTTP) assumes - * that the effect of the panic was isolated to the active request. - * It recovers the panic, logs a stack trace to the server error log, - * and either closes the network connection or sends an HTTP/2 - * RST_STREAM, depending on the HTTP protocol. To abort a handler so - * the client sees an interrupted response but the server doesn't log - * an error, panic with the value [ErrAbortHandler]. - */ - interface Handler { - [key:string]: any; - serveHTTP(_arg0: ResponseWriter, _arg1: Request): void - } - /** - * A ResponseWriter interface is used by an HTTP handler to - * construct an HTTP response. - * - * A ResponseWriter may not be used after [Handler.ServeHTTP] has returned. - */ - interface ResponseWriter { - [key:string]: any; - /** - * Header returns the header map that will be sent by - * [ResponseWriter.WriteHeader]. The [Header] map also is the mechanism with which - * [Handler] implementations can set HTTP trailers. - * - * Changing the header map after a call to [ResponseWriter.WriteHeader] (or - * [ResponseWriter.Write]) has no effect unless the HTTP status code was of the - * 1xx class or the modified headers are trailers. - * - * There are two ways to set Trailers. The preferred way is to - * predeclare in the headers which trailers you will later - * send by setting the "Trailer" header to the names of the - * trailer keys which will come later. In this case, those - * keys of the Header map are treated as if they were - * trailers. See the example. The second way, for trailer - * keys not known to the [Handler] until after the first [ResponseWriter.Write], - * is to prefix the [Header] map keys with the [TrailerPrefix] - * constant value. - * - * To suppress automatic response headers (such as "Date"), set - * their value to nil. - */ - header(): Header - /** - * Write writes the data to the connection as part of an HTTP reply. - * - * If [ResponseWriter.WriteHeader] has not yet been called, Write calls - * WriteHeader(http.StatusOK) before writing the data. If the Header - * does not contain a Content-Type line, Write adds a Content-Type set - * to the result of passing the initial 512 bytes of written data to - * [DetectContentType]. Additionally, if the total size of all written - * data is under a few KB and there are no Flush calls, the - * Content-Length header is added automatically. - * - * Depending on the HTTP protocol version and the client, calling - * Write or WriteHeader may prevent future reads on the - * Request.Body. For HTTP/1.x requests, handlers should read any - * needed request body data before writing the response. Once the - * headers have been flushed (due to either an explicit Flusher.Flush - * call or writing enough data to trigger a flush), the request body - * may be unavailable. For HTTP/2 requests, the Go HTTP server permits - * handlers to continue to read the request body while concurrently - * writing the response. However, such behavior may not be supported - * by all HTTP/2 clients. Handlers should read before writing if - * possible to maximize compatibility. - */ - write(_arg0: string|Array): number - /** - * WriteHeader sends an HTTP response header with the provided - * status code. - * - * If WriteHeader is not called explicitly, the first call to Write - * will trigger an implicit WriteHeader(http.StatusOK). - * Thus explicit calls to WriteHeader are mainly used to - * send error codes or 1xx informational responses. - * - * The provided code must be a valid HTTP 1xx-5xx status code. - * Any number of 1xx headers may be written, followed by at most - * one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx - * headers may be buffered. Use the Flusher interface to send - * buffered data. The header map is cleared when 2xx-5xx headers are - * sent, but not with 1xx headers. - * - * The server will automatically send a 100 (Continue) header - * on the first read from the request body if the request has - * an "Expect: 100-continue" header. - */ - writeHeader(statusCode: number): void - } - /** - * A Server defines parameters for running an HTTP server. - * The zero value for Server is a valid configuration. - */ - interface Server { - /** - * Addr optionally specifies the TCP address for the server to listen on, - * in the form "host:port". If empty, ":http" (port 80) is used. - * The service names are defined in RFC 6335 and assigned by IANA. - * See net.Dial for details of the address format. - */ - addr: string - handler: Handler // handler to invoke, http.DefaultServeMux if nil - /** - * DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler, - * otherwise responds with 200 OK and Content-Length: 0. - */ - disableGeneralOptionsHandler: boolean - /** - * TLSConfig optionally provides a TLS configuration for use - * by ServeTLS and ListenAndServeTLS. Note that this value is - * cloned by ServeTLS and ListenAndServeTLS, so it's not - * possible to modify the configuration with methods like - * tls.Config.SetSessionTicketKeys. To use - * SetSessionTicketKeys, use Server.Serve with a TLS Listener - * instead. - */ - tlsConfig?: any - /** - * ReadTimeout is the maximum duration for reading the entire - * request, including the body. A zero or negative value means - * there will be no timeout. - * - * Because ReadTimeout does not let Handlers make per-request - * decisions on each request body's acceptable deadline or - * upload rate, most users will prefer to use - * ReadHeaderTimeout. It is valid to use them both. - */ - readTimeout: time.Duration - /** - * ReadHeaderTimeout is the amount of time allowed to read - * request headers. The connection's read deadline is reset - * after reading the headers and the Handler can decide what - * is considered too slow for the body. If zero, the value of - * ReadTimeout is used. If negative, or if zero and ReadTimeout - * is zero or negative, there is no timeout. - */ - readHeaderTimeout: time.Duration - /** - * WriteTimeout is the maximum duration before timing out - * writes of the response. It is reset whenever a new - * request's header is read. Like ReadTimeout, it does not - * let Handlers make decisions on a per-request basis. - * A zero or negative value means there will be no timeout. - */ - writeTimeout: time.Duration - /** - * IdleTimeout is the maximum amount of time to wait for the - * next request when keep-alives are enabled. If zero, the value - * of ReadTimeout is used. If negative, or if zero and ReadTimeout - * is zero or negative, there is no timeout. - */ - idleTimeout: time.Duration - /** - * MaxHeaderBytes controls the maximum number of bytes the - * server will read parsing the request header's keys and - * values, including the request line. It does not limit the - * size of the request body. - * If zero, DefaultMaxHeaderBytes is used. - */ - maxHeaderBytes: number - /** - * TLSNextProto optionally specifies a function to take over - * ownership of the provided TLS connection when an ALPN - * protocol upgrade has occurred. The map key is the protocol - * name negotiated. The Handler argument should be used to - * handle HTTP requests and will initialize the Request's TLS - * and RemoteAddr if not already set. The connection is - * automatically closed when the function returns. - * If TLSNextProto is not nil, HTTP/2 support is not enabled - * automatically. - */ - tlsNextProto: _TygojaDict - /** - * ConnState specifies an optional callback function that is - * called when a client connection changes state. See the - * ConnState type and associated constants for details. - */ - connState: (_arg0: net.Conn, _arg1: ConnState) => void - /** - * ErrorLog specifies an optional logger for errors accepting - * connections, unexpected behavior from handlers, and - * underlying FileSystem errors. - * If nil, logging is done via the log package's standard logger. - */ - errorLog?: any - /** - * BaseContext optionally specifies a function that returns - * the base context for incoming requests on this server. - * The provided Listener is the specific Listener that's - * about to start accepting requests. - * If BaseContext is nil, the default is context.Background(). - * If non-nil, it must return a non-nil context. - */ - baseContext: (_arg0: net.Listener) => context.Context - /** - * ConnContext optionally specifies a function that modifies - * the context used for a new connection c. The provided ctx - * is derived from the base context and has a ServerContextKey - * value. - */ - connContext: (ctx: context.Context, c: net.Conn) => context.Context - /** - * HTTP2 configures HTTP/2 connections. - * - * This field does not yet have any effect. - * See https://go.dev/issue/67813. - */ - http2?: HTTP2Config - /** - * Protocols is the set of protocols accepted by the server. - * - * If Protocols includes UnencryptedHTTP2, the server will accept - * unencrypted HTTP/2 connections. The server can serve both - * HTTP/1 and unencrypted HTTP/2 on the same address and port. - * - * If Protocols is nil, the default is usually HTTP/1 and HTTP/2. - * If TLSNextProto is non-nil and does not contain an "h2" entry, - * the default is HTTP/1 only. - */ - protocols?: Protocols - } - interface Server { - /** - * Close immediately closes all active net.Listeners and any - * connections in state [StateNew], [StateActive], or [StateIdle]. For a - * graceful shutdown, use [Server.Shutdown]. - * - * Close does not attempt to close (and does not even know about) - * any hijacked connections, such as WebSockets. - * - * Close returns any error returned from closing the [Server]'s - * underlying Listener(s). - */ - close(): void - } - interface Server { - /** - * Shutdown gracefully shuts down the server without interrupting any - * active connections. Shutdown works by first closing all open - * listeners, then closing all idle connections, and then waiting - * indefinitely for connections to return to idle and then shut down. - * If the provided context expires before the shutdown is complete, - * Shutdown returns the context's error, otherwise it returns any - * error returned from closing the [Server]'s underlying Listener(s). - * - * When Shutdown is called, [Serve], [ServeTLS], [ListenAndServe], and - * [ListenAndServeTLS] immediately return [ErrServerClosed]. Make sure the - * program doesn't exit and waits instead for Shutdown to return. - * - * Shutdown does not attempt to close nor wait for hijacked - * connections such as WebSockets. The caller of Shutdown should - * separately notify such long-lived connections of shutdown and wait - * for them to close, if desired. See [Server.RegisterOnShutdown] for a way to - * register shutdown notification functions. - * - * Once Shutdown has been called on a server, it may not be reused; - * future calls to methods such as Serve will return ErrServerClosed. - */ - shutdown(ctx: context.Context): void - } - interface Server { - /** - * RegisterOnShutdown registers a function to call on [Server.Shutdown]. - * This can be used to gracefully shutdown connections that have - * undergone ALPN protocol upgrade or that have been hijacked. - * This function should start protocol-specific graceful shutdown, - * but should not wait for shutdown to complete. - */ - registerOnShutdown(f: () => void): void - } - interface Server { - /** - * ListenAndServe listens on the TCP network address s.Addr and then - * calls [Serve] to handle requests on incoming connections. - * Accepted connections are configured to enable TCP keep-alives. - * - * If s.Addr is blank, ":http" is used. - * - * ListenAndServe always returns a non-nil error. After [Server.Shutdown] or [Server.Close], - * the returned error is [ErrServerClosed]. - */ - listenAndServe(): void - } - interface Server { - /** - * Serve accepts incoming connections on the Listener l, creating a - * new service goroutine for each. The service goroutines read requests and - * then call s.Handler to reply to them. - * - * HTTP/2 support is only enabled if the Listener returns [*tls.Conn] - * connections and they were configured with "h2" in the TLS - * Config.NextProtos. - * - * Serve always returns a non-nil error and closes l. - * After [Server.Shutdown] or [Server.Close], the returned error is [ErrServerClosed]. - */ - serve(l: net.Listener): void - } - interface Server { - /** - * ServeTLS accepts incoming connections on the Listener l, creating a - * new service goroutine for each. The service goroutines perform TLS - * setup and then read requests, calling s.Handler to reply to them. - * - * Files containing a certificate and matching private key for the - * server must be provided if neither the [Server]'s - * TLSConfig.Certificates, TLSConfig.GetCertificate nor - * config.GetConfigForClient are populated. - * If the certificate is signed by a certificate authority, the - * certFile should be the concatenation of the server's certificate, - * any intermediates, and the CA's certificate. - * - * ServeTLS always returns a non-nil error. After [Server.Shutdown] or [Server.Close], the - * returned error is [ErrServerClosed]. - */ - serveTLS(l: net.Listener, certFile: string, keyFile: string): void - } - interface Server { - /** - * SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. - * By default, keep-alives are always enabled. Only very - * resource-constrained environments or servers in the process of - * shutting down should disable them. - */ - setKeepAlivesEnabled(v: boolean): void - } - interface Server { - /** - * ListenAndServeTLS listens on the TCP network address s.Addr and - * then calls [ServeTLS] to handle requests on incoming TLS connections. - * Accepted connections are configured to enable TCP keep-alives. - * - * Filenames containing a certificate and matching private key for the - * server must be provided if neither the [Server]'s TLSConfig.Certificates - * nor TLSConfig.GetCertificate are populated. If the certificate is - * signed by a certificate authority, the certFile should be the - * concatenation of the server's certificate, any intermediates, and - * the CA's certificate. - * - * If s.Addr is blank, ":https" is used. - * - * ListenAndServeTLS always returns a non-nil error. After [Server.Shutdown] or - * [Server.Close], the returned error is [ErrServerClosed]. - */ - listenAndServeTLS(certFile: string, keyFile: string): void - } -} - -/** - * Package blob defines a lightweight abstration for interacting with - * various storage services (local filesystem, S3, etc.). - * - * NB! - * For compatibility with earlier PocketBase versions and to prevent - * unnecessary breaking changes, this package is based and implemented - * as a minimal, stripped down version of the previously used gocloud.dev/blob. - * While there is no promise that it won't diverge in the future to accommodate - * better some PocketBase specific use cases, currently it copies and - * tries to follow as close as possible the same implementations, - * conventions and rules for the key escaping/unescaping, blob read/write - * interfaces and struct options as gocloud.dev/blob, therefore the - * credits goes to the original Go Cloud Development Kit Authors. - */ -namespace blob { - /** - * ListObject represents a single blob returned from List. - */ - interface ListObject { - /** - * Key is the key for this blob. - */ - key: string - /** - * ModTime is the time the blob was last modified. - */ - modTime: time.Time - /** - * Size is the size of the blob's content in bytes. - */ - size: number - /** - * MD5 is an MD5 hash of the blob contents or nil if not available. - */ - md5: string|Array - /** - * IsDir indicates that this result represents a "directory" in the - * hierarchical namespace, ending in ListOptions.Delimiter. Key can be - * passed as ListOptions.Prefix to list items in the "directory". - * Fields other than Key and IsDir will not be set if IsDir is true. - */ - isDir: boolean - } - /** - * Attributes contains attributes about a blob. - */ - interface Attributes { - /** - * CacheControl specifies caching attributes that services may use - * when serving the blob. - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control - */ - cacheControl: string - /** - * ContentDisposition specifies whether the blob content is expected to be - * displayed inline or as an attachment. - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition - */ - contentDisposition: string - /** - * ContentEncoding specifies the encoding used for the blob's content, if any. - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding - */ - contentEncoding: string - /** - * ContentLanguage specifies the language used in the blob's content, if any. - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language - */ - contentLanguage: string - /** - * ContentType is the MIME type of the blob. It will not be empty. - * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type - */ - contentType: string - /** - * Metadata holds key/value pairs associated with the blob. - * Keys are guaranteed to be in lowercase, even if the backend service - * has case-sensitive keys (although note that Metadata written via - * this package will always be lowercased). If there are duplicate - * case-insensitive keys (e.g., "foo" and "FOO"), only one value - * will be kept, and it is undefined which one. - */ - metadata: _TygojaDict - /** - * CreateTime is the time the blob was created, if available. If not available, - * CreateTime will be the zero time. - */ - createTime: time.Time - /** - * ModTime is the time the blob was last modified. - */ - modTime: time.Time - /** - * Size is the size of the blob's content in bytes. - */ - size: number - /** - * MD5 is an MD5 hash of the blob contents or nil if not available. - */ - md5: string|Array - /** - * ETag for the blob; see https://en.wikipedia.org/wiki/HTTP_ETag. - */ - eTag: string - } - /** - * Reader reads bytes from a blob. - * It implements io.ReadSeekCloser, and must be closed after reads are finished. - */ - interface Reader { - } - interface Reader { - /** - * Read implements io.Reader (https://golang.org/pkg/io/#Reader). - */ - read(p: string|Array): number - } - interface Reader { - /** - * Seek implements io.Seeker (https://golang.org/pkg/io/#Seeker). - */ - seek(offset: number, whence: number): number - } - interface Reader { - /** - * Close implements io.Closer (https://golang.org/pkg/io/#Closer). - */ - close(): void - } - interface Reader { - /** - * ContentType returns the MIME type of the blob. - */ - contentType(): string - } - interface Reader { - /** - * ModTime returns the time the blob was last modified. - */ - modTime(): time.Time - } - interface Reader { - /** - * Size returns the size of the blob content in bytes. - */ - size(): number - } - interface Reader { - /** - * WriteTo reads from r and writes to w until there's no more data or - * an error occurs. - * The return value is the number of bytes written to w. - * - * It implements the io.WriterTo interface. - */ - writeTo(w: io.Writer): number - } -} - -namespace store { - /** - * Store defines a concurrent safe in memory key-value data store. - */ - interface Store { - } - interface Store { - /** - * Reset clears the store and replaces the store data with a - * shallow copy of the provided newData. - */ - reset(newData: _TygojaDict): void - } - interface Store { - /** - * Length returns the current number of elements in the store. - */ - length(): number - } - interface Store { - /** - * RemoveAll removes all the existing store entries. - */ - removeAll(): void - } - interface Store { - /** - * Remove removes a single entry from the store. - * - * Remove does nothing if key doesn't exist in the store. - */ - remove(key: K): void - } - interface Store { - /** - * Has checks if element with the specified key exist or not. - */ - has(key: K): boolean - } - interface Store { - /** - * Get returns a single element value from the store. - * - * If key is not set, the zero T value is returned. - */ - get(key: K): T - } - interface Store { - /** - * GetOk is similar to Get but returns also a boolean indicating whether the key exists or not. - */ - getOk(key: K): [T, boolean] - } - interface Store { - /** - * GetAll returns a shallow copy of the current store data. - */ - getAll(): _TygojaDict - } - interface Store { - /** - * Values returns a slice with all of the current store values. - */ - values(): Array - } - interface Store { - /** - * Set sets (or overwrite if already exists) a new value for key. - */ - set(key: K, value: T): void - } - interface Store { - /** - * SetFunc sets (or overwrite if already exists) a new value resolved - * from the function callback for the provided key. - * - * The function callback receives as argument the old store element value (if exists). - * If there is no old store element, the argument will be the T zero value. - * - * Example: - * - * ``` - * s := store.New[string, int](nil) - * s.SetFunc("count", func(old int) int { - * return old + 1 - * }) - * ``` - */ - setFunc(key: K, fn: (old: T) => T): void - } - interface Store { - /** - * GetOrSet retrieves a single existing value for the provided key - * or stores a new one if it doesn't exist. - */ - getOrSet(key: K, setFunc: () => T): T - } - interface Store { - /** - * SetIfLessThanLimit sets (or overwrite if already exist) a new value for key. - * - * This method is similar to Set() but **it will skip adding new elements** - * to the store if the store length has reached the specified limit. - * false is returned if maxAllowedElements limit is reached. - */ - setIfLessThanLimit(key: K, value: T, maxAllowedElements: number): boolean - } - interface Store { - /** - * UnmarshalJSON implements [json.Unmarshaler] and imports the - * provided JSON data into the store. - * - * The store entries that match with the ones from the data will be overwritten with the new value. - */ - unmarshalJSON(data: string|Array): void - } - interface Store { - /** - * MarshalJSON implements [json.Marshaler] and export the current - * store data into valid JSON. - */ - marshalJSON(): string|Array - } -} - -/** - * Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html - * - * See README.md for more info. - */ -namespace jwt { - /** - * MapClaims is a claims type that uses the map[string]any for JSON - * decoding. This is the default claims type if you don't supply one - */ - interface MapClaims extends _TygojaDict{} - interface MapClaims { - /** - * GetExpirationTime implements the Claims interface. - */ - getExpirationTime(): (NumericDate) - } - interface MapClaims { - /** - * GetNotBefore implements the Claims interface. - */ - getNotBefore(): (NumericDate) - } - interface MapClaims { - /** - * GetIssuedAt implements the Claims interface. - */ - getIssuedAt(): (NumericDate) - } - interface MapClaims { - /** - * GetAudience implements the Claims interface. - */ - getAudience(): ClaimStrings - } - interface MapClaims { - /** - * GetIssuer implements the Claims interface. - */ - getIssuer(): string - } - interface MapClaims { - /** - * GetSubject implements the Claims interface. - */ - getSubject(): string - } -} - -namespace hook { - /** - * Event implements [Resolver] and it is intended to be used as a base - * Hook event that you can embed in your custom typed event structs. - * - * Example: - * - * ``` - * type CustomEvent struct { - * hook.Event - * - * SomeField int - * } - * ``` - */ - interface Event { - } - interface Event { - /** - * Next calls the next hook handler. - */ - next(): void - } - /** - * Handler defines a single Hook handler. - * Multiple handlers can share the same id. - * If Id is not explicitly set it will be autogenerated by Hook.Add and Hook.AddHandler. - */ - interface Handler { - /** - * Func defines the handler function to execute. - * - * Note that users need to call e.Next() in order to proceed with - * the execution of the hook chain. - */ - func: (_arg0: T) => void - /** - * Id is the unique identifier of the handler. - * - * It could be used later to remove the handler from a hook via [Hook.Remove]. - * - * If missing, an autogenerated value will be assigned when adding - * the handler to a hook. - */ - id: string - /** - * Priority allows changing the default exec priority of the handler within a hook. - * - * If 0, the handler will be executed in the same order it was registered. - */ - priority: number - } - /** - * Hook defines a generic concurrent safe structure for managing event hooks. - * - * When using custom event it must embed the base [hook.Event]. - * - * Example: - * - * ``` - * type CustomEvent struct { - * hook.Event - * SomeField int - * } - * - * h := Hook[*CustomEvent]{} - * - * h.BindFunc(func(e *CustomEvent) error { - * println(e.SomeField) - * - * return e.Next() - * }) - * - * h.Trigger(&CustomEvent{ SomeField: 123 }) - * ``` - */ - interface Hook { - } - interface Hook { - /** - * Bind registers the provided handler to the current hooks queue. - * - * If handler.Id is empty it is updated with autogenerated value. - * - * If a handler from the current hook list has Id matching handler.Id - * then the old handler is replaced with the new one. - */ - bind(handler: Handler): string - } - interface Hook { - /** - * BindFunc is similar to Bind but registers a new handler from just the provided function. - * - * The registered handler is added with a default 0 priority and the id will be autogenerated. - * - * If you want to register a handler with custom priority or id use the [Hook.Bind] method. - */ - bindFunc(fn: (e: T) => void): string - } - interface Hook { - /** - * Unbind removes one or many hook handler by their id. - */ - unbind(...idsToRemove: string[]): void - } - interface Hook { - /** - * UnbindAll removes all registered handlers. - */ - unbindAll(): void - } - interface Hook { - /** - * Length returns to total number of registered hook handlers. - */ - length(): number - } - interface Hook { - /** - * Trigger executes all registered hook handlers one by one - * with the specified event as an argument. - * - * Optionally, this method allows also to register additional one off - * handler funcs that will be temporary appended to the handlers queue. - * - * NB! Each hook handler must call event.Next() in order the hook chain to proceed. - */ - trigger(event: T, ...oneOffHandlerFuncs: ((_arg0: T) => void)[]): void - } - /** - * TaggedHook defines a proxy hook which register handlers that are triggered only - * if the TaggedHook.tags are empty or includes at least one of the event data tag(s). - */ - type _sboxsdB = mainHook - interface TaggedHook extends _sboxsdB { - } - interface TaggedHook { - /** - * CanTriggerOn checks if the current TaggedHook can be triggered with - * the provided event data tags. - * - * It returns always true if the hook doesn't have any tags. - */ - canTriggerOn(tagsToCheck: Array): boolean - } - interface TaggedHook { - /** - * Bind registers the provided handler to the current hooks queue. - * - * It is similar to [Hook.Bind] with the difference that the handler - * function is invoked only if the event data tags satisfy h.CanTriggerOn. - */ - bind(handler: Handler): string - } - interface TaggedHook { - /** - * BindFunc registers a new handler with the specified function. - * - * It is similar to [Hook.Bind] with the difference that the handler - * function is invoked only if the event data tags satisfy h.CanTriggerOn. - */ - bindFunc(fn: (e: T) => void): string - } -} - -/** - * Package types implements some commonly used db serializable types - * like datetime, json, etc. - */ -namespace types { - /** - * DateTime represents a [time.Time] instance in UTC that is wrapped - * and serialized using the app default date layout. - */ - interface DateTime { - } - interface DateTime { - /** - * Time returns the internal [time.Time] instance. - */ - time(): time.Time - } - interface DateTime { - /** - * Add returns a new DateTime based on the current DateTime + the specified duration. - */ - add(duration: time.Duration): DateTime - } - interface DateTime { - /** - * Sub returns a [time.Duration] by subtracting the specified DateTime from the current one. - * - * If the result exceeds the maximum (or minimum) value that can be stored in a [time.Duration], - * the maximum (or minimum) duration will be returned. - */ - sub(u: DateTime): time.Duration - } - interface DateTime { - /** - * AddDate returns a new DateTime based on the current one + duration. - * - * It follows the same rules as [time.AddDate]. - */ - addDate(years: number, months: number, days: number): DateTime - } - interface DateTime { - /** - * After reports whether the current DateTime instance is after u. - */ - after(u: DateTime): boolean - } - interface DateTime { - /** - * Before reports whether the current DateTime instance is before u. - */ - before(u: DateTime): boolean - } - interface DateTime { - /** - * Compare compares the current DateTime instance with u. - * If the current instance is before u, it returns -1. - * If the current instance is after u, it returns +1. - * If they're the same, it returns 0. - */ - compare(u: DateTime): number - } - interface DateTime { - /** - * Equal reports whether the current DateTime and u represent the same time instant. - * Two DateTime can be equal even if they are in different locations. - * For example, 6:00 +0200 and 4:00 UTC are Equal. - */ - equal(u: DateTime): boolean - } - interface DateTime { - /** - * Unix returns the current DateTime as a Unix time, aka. - * the number of seconds elapsed since January 1, 1970 UTC. - */ - unix(): number - } - interface DateTime { - /** - * IsZero checks whether the current DateTime instance has zero time value. - */ - isZero(): boolean - } - interface DateTime { - /** - * String serializes the current DateTime instance into a formatted - * UTC date string. - * - * The zero value is serialized to an empty string. - */ - string(): string - } - interface DateTime { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface DateTime { - /** - * UnmarshalJSON implements the [json.Unmarshaler] interface. - */ - unmarshalJSON(b: string|Array): void - } - interface DateTime { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface DateTime { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current DateTime instance. - */ - scan(value: any): void - } - /** - * GeoPoint defines a struct for storing geo coordinates as serialized json object - * (e.g. {lon:0,lat:0}). - * - * Note: using object notation and not a plain array to avoid the confusion - * as there doesn't seem to be a fixed standard for the coordinates order. - */ - interface GeoPoint { - lon: number - lat: number - } - interface GeoPoint { - /** - * String returns the string representation of the current GeoPoint instance. - */ - string(): string - } - interface GeoPoint { - /** - * AsMap implements [core.mapExtractor] and returns a value suitable - * to be used in an API rule expression. - */ - asMap(): _TygojaDict - } - interface GeoPoint { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface GeoPoint { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current GeoPoint instance. - * - * The value argument could be nil (no-op), another GeoPoint instance, - * map or serialized json object with lat-lon props. - */ - scan(value: any): void - } - /** - * JSONArray defines a slice that is safe for json and db read/write. - */ - interface JSONArray extends Array{} - interface JSONArray { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface JSONArray { - /** - * String returns the string representation of the current json array. - */ - string(): string - } - interface JSONArray { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface JSONArray { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current JSONArray[T] instance. - */ - scan(value: any): void - } - /** - * JSONMap defines a map that is safe for json and db read/write. - */ - interface JSONMap extends _TygojaDict{} - interface JSONMap { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface JSONMap { - /** - * String returns the string representation of the current json map. - */ - string(): string - } - interface JSONMap { - /** - * Get retrieves a single value from the current JSONMap[T]. - * - * This helper was added primarily to assist the goja integration since custom map types - * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). - */ - get(key: string): T - } - interface JSONMap { - /** - * Set sets a single value in the current JSONMap[T]. - * - * This helper was added primarily to assist the goja integration since custom map types - * don't have direct access to the map keys (https://pkg.go.dev/github.com/dop251/goja#hdr-Maps_with_methods). - */ - set(key: string, value: T): void - } - interface JSONMap { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface JSONMap { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current JSONMap[T] instance. - */ - scan(value: any): void - } - /** - * JSONRaw defines a json value type that is safe for db read/write. - */ - interface JSONRaw extends Array{} - interface JSONRaw { - /** - * String returns the current JSONRaw instance as a json encoded string. - */ - string(): string - } - interface JSONRaw { - /** - * MarshalJSON implements the [json.Marshaler] interface. - */ - marshalJSON(): string|Array - } - interface JSONRaw { - /** - * UnmarshalJSON implements the [json.Unmarshaler] interface. - */ - unmarshalJSON(b: string|Array): void - } - interface JSONRaw { - /** - * Value implements the [driver.Valuer] interface. - */ - value(): any - } - interface JSONRaw { - /** - * Scan implements [sql.Scanner] interface to scan the provided value - * into the current JSONRaw instance. - */ - scan(value: any): void - } -} - -namespace search { - /** - * Result defines the returned search result structure. - */ - interface Result { - items: any - page: number - perPage: number - totalItems: number - totalPages: number - } - /** - * ResolverResult defines a single FieldResolver.Resolve() successfully parsed result. - */ - interface ResolverResult { - /** - * Identifier is the plain SQL identifier/column that will be used - * in the final db expression as left or right operand. - */ - identifier: string - /** - * NullFallback specify the preference for how NULL or empty values - * should be resolved (default to "auto"). - * - * Set to NullFallbackDisabled to prevent any COALESCE or NULL fallbacks. - * Set to NullFallbackEnforced to prefer COALESCE or NULL fallbacks when needed. - */ - nullFallback: NullFallbackPreference - /** - * Params is a map with db placeholder->value pairs that will be added - * to the query when building both resolved operands/sides in a single expression. - */ - params: dbx.Params - /** - * MultiMatchSubQuery is an optional sub query expression that will be added - * in addition to the combined ResolverResult expression during build. - */ - multiMatchSubQuery?: MultiMatchSubquery - /** - * AfterBuild is an optional function that will be called after building - * and combining the result of both resolved operands/sides in a single expression. - */ - afterBuild: (expr: dbx.Expression) => dbx.Expression - } -} - -namespace router { - // @ts-ignore - import validation = ozzo_validation - /** - * ApiError defines the struct for a basic api error response. - */ - interface ApiError { - data: _TygojaDict - message: string - status: number - } - interface ApiError { - /** - * Error makes it compatible with the `error` interface. - */ - error(): string - } - interface ApiError { - /** - * RawData returns the unformatted error data (could be an internal error, text, etc.) - */ - rawData(): any - } - interface ApiError { - /** - * Is reports whether the current ApiError wraps the target. - */ - is(target: Error): boolean - } - /** - * Event specifies based Route handler event that is usually intended - * to be embedded as part of a custom event struct. - * - * NB! It is expected that the Response and Request fields are always set. - */ - type _sbkZyQr = hook.Event - interface Event extends _sbkZyQr { - response: http.ResponseWriter - request?: http.Request - } - interface Event { - /** - * Written reports whether the current response has already been written. - * - * This method always returns false if e.ResponseWritter doesn't implement the WriteTracker interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - written(): boolean - } - interface Event { - /** - * Status reports the status code of the current response. - * - * This method always returns 0 if e.Response doesn't implement the StatusTracker interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - status(): number - } - interface Event { - /** - * Flush flushes buffered data to the current response. - * - * Returns [http.ErrNotSupported] if e.Response doesn't implement the [http.Flusher] interface - * (all router package handlers receives a ResponseWritter that implements it unless explicitly replaced with a custom one). - */ - flush(): void - } - interface Event { - /** - * IsTLS reports whether the connection on which the request was received is TLS. - */ - isTLS(): boolean - } - interface Event { - /** - * SetCookie is an alias for [http.SetCookie]. - * - * SetCookie adds a Set-Cookie header to the current response's headers. - * The provided cookie must have a valid Name. - * Invalid cookies may be silently dropped. - */ - setCookie(cookie: http.Cookie): void - } - interface Event { - /** - * RemoteIP returns the IP address of the client that sent the request. - * - * IPv6 addresses are returned expanded. - * For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001". - * - * Note that if you are behind reverse proxy(ies), this method returns - * the IP of the last connecting proxy. - */ - remoteIP(): string - } - interface Event { - /** - * FindUploadedFiles extracts all form files of "key" from a http request - * and returns a slice with filesystem.File instances (if any). - */ - findUploadedFiles(key: string): Array<(filesystem.File | undefined)> - } - interface Event { - /** - * Get retrieves single value from the current event data store. - */ - get(key: string): any - } - interface Event { - /** - * GetAll returns a copy of the current event data store. - */ - getAll(): _TygojaDict - } - interface Event { - /** - * Set saves single value into the current event data store. - */ - set(key: string, value: any): void - } - interface Event { - /** - * SetAll saves all items from m into the current event data store. - */ - setAll(m: _TygojaDict): void - } - interface Event { - /** - * String writes a plain string response. - */ - string(status: number, data: string): void - } - interface Event { - /** - * HTML writes an HTML response. - */ - html(status: number, data: string): void - } - interface Event { - /** - * JSON writes a JSON response. - * - * It also provides a generic response data fields picker if the "fields" query parameter is set. - * For example, if you are requesting `?fields=a,b` for `e.JSON(200, map[string]int{ "a":1, "b":2, "c":3 })`, - * it should result in a JSON response like: `{"a":1, "b": 2}`. - */ - json(status: number, data: any): void - } - interface Event { - /** - * XML writes an XML response. - * It automatically prepends the generic [xml.Header] string to the response. - */ - xml(status: number, data: any): void - } - interface Event { - /** - * Stream streams the specified reader into the response. - */ - stream(status: number, contentType: string, reader: io.Reader): void - } - interface Event { - /** - * Blob writes a blob (bytes slice) response. - */ - blob(status: number, contentType: string, b: string|Array): void - } - interface Event { - /** - * FileFS serves the specified filename from fsys. - * - * It is similar to [echo.FileFS] for consistency with earlier versions. - */ - fileFS(fsys: fs.FS, filename: string): void - } - interface Event { - /** - * NoContent writes a response with no body (ex. 204). - */ - noContent(status: number): void - } - interface Event { - /** - * Redirect writes a redirect response to the specified url. - * The status code must be in between 300 – 399 range. - */ - redirect(status: number, url: string): void - } - interface Event { - error(status: number, message: string, errData: any): (ApiError) - } - interface Event { - badRequestError(message: string, errData: any): (ApiError) - } - interface Event { - notFoundError(message: string, errData: any): (ApiError) - } - interface Event { - forbiddenError(message: string, errData: any): (ApiError) - } - interface Event { - unauthorizedError(message: string, errData: any): (ApiError) - } - interface Event { - tooManyRequestsError(message: string, errData: any): (ApiError) - } - interface Event { - internalServerError(message: string, errData: any): (ApiError) - } - interface Event { - /** - * BindBody unmarshal the request body into the provided dst. - * - * dst must be either a struct pointer or map[string]any. - * - * The rules how the body will be scanned depends on the request Content-Type. - * - * Currently the following Content-Types are supported: - * ``` - * - application/json - * - text/xml, application/xml - * - multipart/form-data, application/x-www-form-urlencoded - * ``` - * - * Respectively the following struct tags are supported (again, which one will be used depends on the Content-Type): - * ``` - * - "json" (json body)- uses the builtin Go json package for unmarshaling. - * - "xml" (xml body) - uses the builtin Go xml package for unmarshaling. - * - "form" (form data) - utilizes the custom [router.UnmarshalRequestData] method. - * ``` - * - * NB! When dst is a struct make sure that it doesn't have public fields - * that shouldn't be bindable and it is advisible such fields to be unexported - * or have a separate struct just for the binding. For example: - * - * ``` - * data := struct{ - * somethingPrivate string - * - * Title string `json:"title" form:"title"` - * Total int `json:"total" form:"total"` - * } - * err := e.BindBody(&data) - * ``` - */ - bindBody(dst: any): void - } - /** - * Router defines a thin wrapper around the standard Go [http.ServeMux] by - * adding support for routing sub-groups, middlewares and other common utils. - * - * Example: - * - * ``` - * r := NewRouter[*MyEvent](eventFactory) - * - * // middlewares - * r.BindFunc(m1, m2) - * - * // routes - * r.GET("/test", handler1) - * - * // sub-routers/groups - * api := r.Group("/api") - * api.GET("/admins", handler2) - * - * // generate a http.ServeMux instance based on the router configurations - * mux, _ := r.BuildMux() - * - * http.ListenAndServe("localhost:8090", mux) - * ``` - */ - type _sDUkutP = RouterGroup - interface Router extends _sDUkutP { - } - interface Router { - /** - * BuildMux constructs a new mux [http.Handler] instance from the current router configurations. - */ - buildMux(): http.Handler - } -} - -/** - * Package cron implements a crontab-like service to execute and schedule - * repeative tasks/jobs. - * - * Example: - * - * ``` - * c := cron.New() - * c.MustAdd("dailyReport", "0 0 * * *", func() { ... }) - * c.Start() - * ``` - */ -namespace cron { - /** - * Cron is a crontab-like struct for tasks/jobs scheduling. - */ - interface Cron { - } - interface Cron { - /** - * SetInterval changes the current cron tick interval - * (it usually should be >= 1 minute). - */ - setInterval(d: time.Duration): void - } - interface Cron { - /** - * SetTimezone changes the current cron tick timezone. - */ - setTimezone(l: time.Location): void - } - interface Cron { - /** - * MustAdd is similar to Add() but panic on failure. - */ - mustAdd(jobId: string, cronExpr: string, run: () => void): void - } - interface Cron { - /** - * Add registers a single cron job. - * - * If there is already a job with the provided id, then the old job - * will be replaced with the new one. - * - * cronExpr is a regular cron expression, eg. "0 *\/3 * * *" (aka. at minute 0 past every 3rd hour). - * Check cron.NewSchedule() for the supported tokens. - */ - add(jobId: string, cronExpr: string, fn: () => void): void - } - interface Cron { - /** - * Remove removes a single cron job by its id. - */ - remove(jobId: string): void - } - interface Cron { - /** - * RemoveAll removes all registered cron jobs. - */ - removeAll(): void - } - interface Cron { - /** - * Total returns the current total number of registered cron jobs. - */ - total(): number - } - interface Cron { - /** - * Jobs returns a shallow copy of the currently registered cron jobs. - */ - jobs(): Array<(Job | undefined)> - } - interface Cron { - /** - * Stop stops the current cron ticker (if not already). - * - * You can resume the ticker by calling Start(). - */ - stop(): void - } - interface Cron { - /** - * Start starts the cron ticker. - * - * Calling Start() on already started cron will restart the ticker. - */ - start(): void - } - interface Cron { - /** - * HasStarted checks whether the current Cron ticker has been started. - */ - hasStarted(): boolean - } -} - -namespace exec { - /** - * Cmd represents an external command being prepared or run. - * - * A Cmd cannot be reused after calling its [Cmd.Run], [Cmd.Output] or [Cmd.CombinedOutput] - * methods. - */ - interface Cmd { - /** - * Path is the path of the command to run. - * - * This is the only field that must be set to a non-zero - * value. If Path is relative, it is evaluated relative - * to Dir. - */ - path: string - /** - * Args holds command line arguments, including the command as Args[0]. - * If the Args field is empty or nil, Run uses {Path}. - * - * In typical use, both Path and Args are set by calling Command. - */ - args: Array - /** - * Env specifies the environment of the process. - * Each entry is of the form "key=value". - * If Env is nil, the new process uses the current process's - * environment. - * If Env contains duplicate environment keys, only the last - * value in the slice for each duplicate key is used. - * As a special case on Windows, SYSTEMROOT is always added if - * missing and not explicitly set to the empty string. - * - * See also the Dir field, which may set PWD in the environment. - */ - env: Array - /** - * Dir specifies the working directory of the command. - * If Dir is the empty string, Run runs the command in the - * calling process's current directory. - * - * On Unix systems, the value of Dir also determines the - * child process's PWD environment variable if not otherwise - * specified. A Unix process represents its working directory - * not by name but as an implicit reference to a node in the - * file tree. So, if the child process obtains its working - * directory by calling a function such as C's getcwd, which - * computes the canonical name by walking up the file tree, it - * will not recover the original value of Dir if that value - * was an alias involving symbolic links. However, if the - * child process calls Go's [os.Getwd] or GNU C's - * get_current_dir_name, and the value of PWD is an alias for - * the current directory, those functions will return the - * value of PWD, which matches the value of Dir. - */ - dir: string - /** - * Stdin specifies the process's standard input. - * - * If Stdin is nil, the process reads from the null device (os.DevNull). - * - * If Stdin is an *os.File, the process's standard input is connected - * directly to that file. - * - * Otherwise, during the execution of the command a separate - * goroutine reads from Stdin and delivers that data to the command - * over a pipe. In this case, Wait does not complete until the goroutine - * stops copying, either because it has reached the end of Stdin - * (EOF or a read error), or because writing to the pipe returned an error, - * or because a nonzero WaitDelay was set and expired. - */ - stdin: io.Reader - /** - * Stdout and Stderr specify the process's standard output and error. - * - * If either is nil, Run connects the corresponding file descriptor - * to the null device (os.DevNull). - * - * If either is an *os.File, the corresponding output from the process - * is connected directly to that file. - * - * Otherwise, during the execution of the command a separate goroutine - * reads from the process over a pipe and delivers that data to the - * corresponding Writer. In this case, Wait does not complete until the - * goroutine reaches EOF or encounters an error or a nonzero WaitDelay - * expires. - * - * If Stdout and Stderr are the same writer, and have a type that can - * be compared with ==, at most one goroutine at a time will call Write. - */ - stdout: io.Writer - stderr: io.Writer - /** - * ExtraFiles specifies additional open files to be inherited by the - * new process. It does not include standard input, standard output, or - * standard error. If non-nil, entry i becomes file descriptor 3+i. - * - * ExtraFiles is not supported on Windows. - */ - extraFiles: Array<(os.File | undefined)> - /** - * SysProcAttr holds optional, operating system-specific attributes. - * Run passes it to os.StartProcess as the os.ProcAttr's Sys field. - */ - sysProcAttr?: syscall.SysProcAttr - /** - * Process is the underlying process, once started. - */ - process?: os.Process - /** - * ProcessState contains information about an exited process. - * If the process was started successfully, Wait or Run will - * populate its ProcessState when the command completes. - */ - processState?: os.ProcessState - err: Error // LookPath error, if any. - /** - * If Cancel is non-nil, the command must have been created with - * CommandContext and Cancel will be called when the command's - * Context is done. By default, CommandContext sets Cancel to - * call the Kill method on the command's Process. - * - * Typically a custom Cancel will send a signal to the command's - * Process, but it may instead take other actions to initiate cancellation, - * such as closing a stdin or stdout pipe or sending a shutdown request on a - * network socket. - * - * If the command exits with a success status after Cancel is - * called, and Cancel does not return an error equivalent to - * os.ErrProcessDone, then Wait and similar methods will return a non-nil - * error: either an error wrapping the one returned by Cancel, - * or the error from the Context. - * (If the command exits with a non-success status, or Cancel - * returns an error that wraps os.ErrProcessDone, Wait and similar methods - * continue to return the command's usual exit status.) - * - * If Cancel is set to nil, nothing will happen immediately when the command's - * Context is done, but a nonzero WaitDelay will still take effect. That may - * be useful, for example, to work around deadlocks in commands that do not - * support shutdown signals but are expected to always finish quickly. - * - * Cancel will not be called if Start returns a non-nil error. - */ - cancel: () => void - /** - * If WaitDelay is non-zero, it bounds the time spent waiting on two sources - * of unexpected delay in Wait: a child process that fails to exit after the - * associated Context is canceled, and a child process that exits but leaves - * its I/O pipes unclosed. - * - * The WaitDelay timer starts when either the associated Context is done or a - * call to Wait observes that the child process has exited, whichever occurs - * first. When the delay has elapsed, the command shuts down the child process - * and/or its I/O pipes. - * - * If the child process has failed to exit — perhaps because it ignored or - * failed to receive a shutdown signal from a Cancel function, or because no - * Cancel function was set — then it will be terminated using os.Process.Kill. - * - * Then, if the I/O pipes communicating with the child process are still open, - * those pipes are closed in order to unblock any goroutines currently blocked - * on Read or Write calls. - * - * If pipes are closed due to WaitDelay, no Cancel call has occurred, - * and the command has otherwise exited with a successful status, Wait and - * similar methods will return ErrWaitDelay instead of nil. - * - * If WaitDelay is zero (the default), I/O pipes will be read until EOF, - * which might not occur until orphaned subprocesses of the command have - * also closed their descriptors for the pipes. - */ - waitDelay: time.Duration - } - interface Cmd { - /** - * String returns a human-readable description of c. - * It is intended only for debugging. - * In particular, it is not suitable for use as input to a shell. - * The output of String may vary across Go releases. - */ - string(): string - } - interface Cmd { - /** - * Run starts the specified command and waits for it to complete. - * - * The returned error is nil if the command runs, has no problems - * copying stdin, stdout, and stderr, and exits with a zero exit - * status. - * - * If the command starts but does not complete successfully, the error is of - * type [*ExitError]. Other error types may be returned for other situations. - * - * If the calling goroutine has locked the operating system thread - * with [runtime.LockOSThread] and modified any inheritable OS-level - * thread state (for example, Linux or Plan 9 name spaces), the new - * process will inherit the caller's thread state. - */ - run(): void - } - interface Cmd { - /** - * Start starts the specified command but does not wait for it to complete. - * - * If Start returns successfully, the c.Process field will be set. - * - * After a successful call to Start the [Cmd.Wait] method must be called in - * order to release associated system resources. - */ - start(): void - } - interface Cmd { - /** - * Wait waits for the command to exit and waits for any copying to - * stdin or copying from stdout or stderr to complete. - * - * The command must have been started by [Cmd.Start]. - * - * The returned error is nil if the command runs, has no problems - * copying stdin, stdout, and stderr, and exits with a zero exit - * status. - * - * If the command fails to run or doesn't complete successfully, the - * error is of type [*ExitError]. Other error types may be - * returned for I/O problems. - * - * If any of c.Stdin, c.Stdout or c.Stderr are not an [*os.File], Wait also waits - * for the respective I/O loop copying to or from the process to complete. - * - * Wait releases any resources associated with the [Cmd]. - */ - wait(): void - } - interface Cmd { - /** - * Output runs the command and returns its standard output. - * Any returned error will usually be of type [*ExitError]. - * If c.Stderr was nil and the returned error is of type - * [*ExitError], Output populates the Stderr field of the - * returned error. - */ - output(): string|Array - } - interface Cmd { - /** - * CombinedOutput runs the command and returns its combined standard - * output and standard error. - */ - combinedOutput(): string|Array - } - interface Cmd { - /** - * StdinPipe returns a pipe that will be connected to the command's - * standard input when the command starts. - * The pipe will be closed automatically after [Cmd.Wait] sees the command exit. - * A caller need only call Close to force the pipe to close sooner. - * For example, if the command being run will not exit until standard input - * is closed, the caller must close the pipe. - */ - stdinPipe(): io.WriteCloser - } - interface Cmd { - /** - * StdoutPipe returns a pipe that will be connected to the command's - * standard output when the command starts. - * - * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers - * need not close the pipe themselves. It is thus incorrect to call Wait - * before all reads from the pipe have completed. - * For the same reason, it is incorrect to call [Cmd.Run] when using StdoutPipe. - * See the example for idiomatic usage. - */ - stdoutPipe(): io.ReadCloser - } - interface Cmd { - /** - * StderrPipe returns a pipe that will be connected to the command's - * standard error when the command starts. - * - * [Cmd.Wait] will close the pipe after seeing the command exit, so most callers - * need not close the pipe themselves. It is thus incorrect to call Wait - * before all reads from the pipe have completed. - * For the same reason, it is incorrect to use [Cmd.Run] when using StderrPipe. - * See the StdoutPipe example for idiomatic usage. - */ - stderrPipe(): io.ReadCloser - } - interface Cmd { - /** - * Environ returns a copy of the environment in which the command would be run - * as it is currently configured. - */ - environ(): Array - } -} - -namespace mailer { - /** - * Message defines a generic email message struct. - */ - interface Message { - from: { address: string; name?: string; } - to: Array<{ address: string; name?: string; }> - bcc: Array<{ address: string; name?: string; }> - cc: Array<{ address: string; name?: string; }> - subject: string - html: string - text: string - headers: _TygojaDict - attachments: _TygojaDict - inlineAttachments: _TygojaDict - } - /** - * Mailer defines a base mail client interface. - */ - interface Mailer { - [key:string]: any; - /** - * Send sends an email with the provided Message. - */ - send(message: Message): void - } -} - -namespace subscriptions { - /** - * Broker defines a struct for managing subscriptions clients. - */ - interface Broker { - } - interface Broker { - /** - * Clients returns a shallow copy of all registered clients indexed - * with their connection id. - */ - clients(): _TygojaDict - } - interface Broker { - /** - * ChunkedClients splits the current clients into a chunked slice. - */ - chunkedClients(chunkSize: number): Array> - } - interface Broker { - /** - * TotalClients returns the total number of registered clients. - */ - totalClients(): number - } - interface Broker { - /** - * ClientById finds a registered client by its id. - * - * Returns non-nil error when client with clientId is not registered. - */ - clientById(clientId: string): Client - } - interface Broker { - /** - * Register adds a new client to the broker instance. - */ - register(client: Client): void - } - interface Broker { - /** - * Unregister removes a single client by its id and marks it as discarded. - * - * If client with clientId doesn't exist, this method does nothing. - */ - unregister(clientId: string): void - } - /** - * Client is an interface for a generic subscription client. - */ - interface Client { - [key:string]: any; - /** - * Id Returns the unique id of the client. - */ - id(): string - /** - * Channel returns the client's communication channel. - * - * NB! The channel shouldn't be used after calling Discard(). - */ - channel(): undefined - /** - * Subscriptions returns a shallow copy of the client subscriptions matching the prefixes. - * If no prefix is specified, returns all subscriptions. - */ - subscriptions(...prefixes: string[]): _TygojaDict - /** - * Subscribe subscribes the client to the provided subscriptions list. - * - * Each subscription can also have "options" (json serialized SubscriptionOptions) as query parameter. - * - * Example: - * - * ``` - * Subscribe( - * "subscriptionA", - * `subscriptionB?options={"query":{"a":1},"headers":{"x_token":"abc"}}`, - * ) - * ``` - */ - subscribe(...subs: string[]): void - /** - * Unsubscribe unsubscribes the client from the provided subscriptions list. - */ - unsubscribe(...subs: string[]): void - /** - * HasSubscription checks if the client is subscribed to `sub`. - */ - hasSubscription(sub: string): boolean - /** - * Set stores any value to the client's context. - */ - set(key: string, value: any): void - /** - * Unset removes a single value from the client's context. - */ - unset(key: string): void - /** - * Get retrieves the key value from the client's context. - */ - get(key: string): any - /** - * Discard marks the client as "discarded" (and closes its channel), - * meaning that it shouldn't be used anymore for sending new messages. - * - * It is safe to call Discard() multiple times. - */ - discard(): void - /** - * IsDiscarded indicates whether the client has been "discarded" - * and should no longer be used. - */ - isDiscarded(): boolean - /** - * Send sends the specified message to the client's channel (if not discarded). - */ - send(m: Message): void - } - /** - * Message defines a client's channel data. - */ - interface Message { - name: string - data: string|Array - } - interface Message { - /** - * WriteSSE writes the current message in a SSE format into the provided writer. - * - * For example, writing to a router.Event: - * - * ``` - * m := Message{Name: "users/create", Data: []byte{...}} - * m.WriteSSE(e.Response, "yourEventId") - * e.Flush() - * ``` - */ - writeSSE(w: io.Writer, eventId: string): void - } -} - /** * Package slog provides structured logging, * in which log records include a message, @@ -21719,154 +21884,145 @@ namespace slog { } } -namespace auth { +namespace subscriptions { /** - * Provider defines a common interface for an OAuth2 client. + * Broker defines a struct for managing subscriptions clients. */ - interface Provider { + interface Broker { + } + interface Broker { + /** + * Clients returns a shallow copy of all registered clients indexed + * with their connection id. + */ + clients(): _TygojaDict + } + interface Broker { + /** + * ChunkedClients splits the current clients into a chunked slice. + */ + chunkedClients(chunkSize: number): Array> + } + interface Broker { + /** + * TotalClients returns the total number of registered clients. + */ + totalClients(): number + } + interface Broker { + /** + * ClientById finds a registered client by its id. + * + * Returns non-nil error when client with clientId is not registered. + */ + clientById(clientId: string): Client + } + interface Broker { + /** + * Register adds a new client to the broker instance. + */ + register(client: Client): void + } + interface Broker { + /** + * Unregister removes a single client by its id and marks it as discarded. + * + * If client with clientId doesn't exist, this method does nothing. + */ + unregister(clientId: string): void + } + /** + * Client is an interface for a generic subscription client. + */ + interface Client { [key:string]: any; /** - * Context returns the context associated with the provider (if any). + * Id Returns the unique id of the client. */ - context(): context.Context + id(): string /** - * SetContext assigns the specified context to the current provider. + * Channel returns the client's communication channel. + * + * NB! The channel shouldn't be used after calling Discard(). */ - setContext(ctx: context.Context): void + channel(): undefined /** - * PKCE indicates whether the provider can use the PKCE flow. + * Subscriptions returns a shallow copy of the client subscriptions matching the prefixes. + * If no prefix is specified, returns all subscriptions. */ - pkce(): boolean + subscriptions(...prefixes: string[]): _TygojaDict /** - * SetPKCE toggles the state whether the provider can use the PKCE flow or not. + * Subscribe subscribes the client to the provided subscriptions list. + * + * Each subscription can also have "options" (json serialized SubscriptionOptions) as query parameter. + * + * Example: + * + * ``` + * Subscribe( + * "subscriptionA", + * `subscriptionB?options={"query":{"a":1},"headers":{"x_token":"abc"}}`, + * ) + * ``` */ - setPKCE(enable: boolean): void + subscribe(...subs: string[]): void /** - * DisplayName usually returns provider name as it is officially written - * and it could be used directly in the UI. + * Unsubscribe unsubscribes the client from the provided subscriptions list. */ - displayName(): string + unsubscribe(...subs: string[]): void /** - * SetDisplayName sets the provider's display name. + * HasSubscription checks if the client is subscribed to `sub`. */ - setDisplayName(displayName: string): void + hasSubscription(sub: string): boolean /** - * Scopes returns the provider access permissions that will be requested. + * Set stores any value to the client's context. */ - scopes(): Array + set(key: string, value: any): void /** - * SetScopes sets the provider access permissions that will be requested later. + * Unset removes a single value from the client's context. */ - setScopes(scopes: Array): void + unset(key: string): void /** - * ClientId returns the provider client's app ID. + * Get retrieves the key value from the client's context. */ - clientId(): string + get(key: string): any /** - * SetClientId sets the provider client's ID. + * Discard marks the client as "discarded" (and closes its channel), + * meaning that it shouldn't be used anymore for sending new messages. + * + * It is safe to call Discard() multiple times. */ - setClientId(clientId: string): void + discard(): void /** - * ClientSecret returns the provider client's app secret. + * IsDiscarded indicates whether the client has been "discarded" + * and should no longer be used. */ - clientSecret(): string + isDiscarded(): boolean /** - * SetClientSecret sets the provider client's app secret. + * Send sends the specified message to the client's channel (if not discarded). */ - setClientSecret(secret: string): void - /** - * RedirectURL returns the end address to redirect the user - * going through the OAuth flow. - */ - redirectURL(): string - /** - * SetRedirectURL sets the provider's RedirectURL. - */ - setRedirectURL(url: string): void - /** - * AuthURL returns the provider's authorization service url. - */ - authURL(): string - /** - * SetAuthURL sets the provider's AuthURL. - */ - setAuthURL(url: string): void - /** - * TokenURL returns the provider's token exchange service url. - */ - tokenURL(): string - /** - * SetTokenURL sets the provider's TokenURL. - */ - setTokenURL(url: string): void - /** - * UserInfoURL returns the provider's user info api url. - */ - userInfoURL(): string - /** - * SetUserInfoURL sets the provider's UserInfoURL. - */ - setUserInfoURL(url: string): void - /** - * Extra returns a shallow copy of any custom config data - * that the provider may need. - */ - extra(): _TygojaDict - /** - * SetExtra updates the provider's custom config data. - */ - setExtra(data: _TygojaDict): void - /** - * Client returns an http client using the provided token. - */ - client(token: oauth2.Token): (any) - /** - * BuildAuthURL returns a URL to the provider's consent page - * that asks for permissions for the required scopes explicitly. - */ - buildAuthURL(state: string, ...opts: oauth2.AuthCodeOption[]): string - /** - * FetchToken converts an authorization code to token. - */ - fetchToken(code: string, ...opts: oauth2.AuthCodeOption[]): (oauth2.Token) - /** - * FetchRawUserInfo requests and marshalizes into `result` the - * the OAuth user api response. - */ - fetchRawUserInfo(token: oauth2.Token): string|Array - /** - * FetchAuthUser is similar to FetchRawUserInfo, but normalizes and - * marshalizes the user api response into a standardized AuthUser struct. - */ - fetchAuthUser(token: oauth2.Token): (AuthUser) + send(m: Message): void } /** - * AuthUser defines a standardized OAuth2 user data structure. + * Message defines a client's channel data. */ - interface AuthUser { - expiry: types.DateTime - rawUser: _TygojaDict - id: string + interface Message { name: string - username: string - email: string - avatarURL: string - accessToken: string - refreshToken: string - /** - * @todo - * deprecated: use AvatarURL instead - * AvatarUrl will be removed after dropping v0.22 support - */ - avatarUrl: string + data: string|Array } - interface AuthUser { + interface Message { /** - * MarshalJSON implements the [json.Marshaler] interface. + * WriteSSE writes the current message in a SSE format into the provided writer. * - * @todo remove after dropping v0.22 support + * For example, writing to a router.Event: + * + * ``` + * m := Message{Name: "users/create", Data: []byte{...}} + * m.WriteSSE(e.Response, "yourEventId") + * e.Flush() + * ``` */ - marshalJSON(): string|Array + writeSSE(w: io.Writer, eventId: string): void } } @@ -21892,612 +22048,6 @@ namespace io { } } -namespace syscall { - // @ts-ignore - import errpkg = errors - /** - * SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux. - * See user_namespaces(7). - * - * Note that User Namespaces are not available on a number of popular Linux - * versions (due to security issues), or are available but subject to AppArmor - * restrictions like in Ubuntu 24.04. - */ - interface SysProcIDMap { - containerID: number // Container ID. - hostID: number // Host ID. - size: number // Size. - } - // @ts-ignore - import errorspkg = errors - /** - * Credential holds user and group identities to be assumed - * by a child process started by [StartProcess]. - */ - interface Credential { - uid: number // User ID. - gid: number // Group ID. - groups: Array // Supplementary group IDs. - noSetGroups: boolean // If true, don't set supplementary groups - } - // @ts-ignore - import runtimesyscall = syscall - /** - * A Signal is a number describing a process signal. - * It implements the [os.Signal] interface. - */ - interface Signal extends Number{} - interface Signal { - signal(): void - } - interface Signal { - string(): string - } -} - -namespace time { - /** - * A Month specifies a month of the year (January = 1, ...). - */ - interface Month extends Number{} - interface Month { - /** - * String returns the English name of the month ("January", "February", ...). - */ - string(): string - } - /** - * A Weekday specifies a day of the week (Sunday = 0, ...). - */ - interface Weekday extends Number{} - interface Weekday { - /** - * String returns the English name of the day ("Sunday", "Monday", ...). - */ - string(): string - } - /** - * A Location maps time instants to the zone in use at that time. - * Typically, the Location represents the collection of time offsets - * in use in a geographical area. For many Locations the time offset varies - * depending on whether daylight savings time is in use at the time instant. - * - * Location is used to provide a time zone in a printed Time value and for - * calculations involving intervals that may cross daylight savings time - * boundaries. - */ - interface Location { - } - interface Location { - /** - * String returns a descriptive name for the time zone information, - * corresponding to the name argument to [LoadLocation] or [FixedZone]. - */ - string(): string - } -} - -namespace fs { -} - -namespace store { -} - -/** - * Package url parses URLs and implements query escaping. - * - * See RFC 3986. This package generally follows RFC 3986, except where - * it deviates for compatibility reasons. - * RFC 6874 followed for IPv6 zone literals. - */ -namespace url { - /** - * A URL represents a parsed URL (technically, a URI reference). - * - * The general form represented is: - * - * ``` - * [scheme:][//[userinfo@]host][/]path[?query][#fragment] - * ``` - * - * URLs that do not start with a slash after the scheme are interpreted as: - * - * ``` - * scheme:opaque[?query][#fragment] - * ``` - * - * The Host field contains the host and port subcomponents of the URL. - * When the port is present, it is separated from the host with a colon. - * When the host is an IPv6 address, it must be enclosed in square brackets: - * "[fe80::1]:80". The [net.JoinHostPort] function combines a host and port - * into a string suitable for the Host field, adding square brackets to - * the host when necessary. - * - * Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. - * A consequence is that it is impossible to tell which slashes in the Path were - * slashes in the raw URL and which were %2f. This distinction is rarely important, - * but when it is, the code should use the [URL.EscapedPath] method, which preserves - * the original encoding of Path. - * - * The RawPath field is an optional field which is only set when the default - * encoding of Path is different from the escaped path. See the EscapedPath method - * for more details. - * - * URL's String method uses the EscapedPath method to obtain the path. - */ - interface URL { - scheme: string - opaque: string // encoded opaque data - user?: Userinfo // username and password information - host: string // host or host:port (see Hostname and Port methods) - path: string // path (relative paths may omit leading slash) - rawPath: string // encoded path hint (see EscapedPath method) - omitHost: boolean // do not emit empty host (authority) - forceQuery: boolean // append a query ('?') even if RawQuery is empty - rawQuery: string // encoded query values, without '?' - fragment: string // fragment for references, without '#' - rawFragment: string // encoded fragment hint (see EscapedFragment method) - } - interface URL { - /** - * EscapedPath returns the escaped form of u.Path. - * In general there are multiple possible escaped forms of any path. - * EscapedPath returns u.RawPath when it is a valid escaping of u.Path. - * Otherwise EscapedPath ignores u.RawPath and computes an escaped - * form on its own. - * The [URL.String] and [URL.RequestURI] methods use EscapedPath to construct - * their results. - * In general, code should call EscapedPath instead of - * reading u.RawPath directly. - */ - escapedPath(): string - } - interface URL { - /** - * EscapedFragment returns the escaped form of u.Fragment. - * In general there are multiple possible escaped forms of any fragment. - * EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. - * Otherwise EscapedFragment ignores u.RawFragment and computes an escaped - * form on its own. - * The [URL.String] method uses EscapedFragment to construct its result. - * In general, code should call EscapedFragment instead of - * reading u.RawFragment directly. - */ - escapedFragment(): string - } - interface URL { - /** - * String reassembles the [URL] into a valid URL string. - * The general form of the result is one of: - * - * ``` - * scheme:opaque?query#fragment - * scheme://userinfo@host/path?query#fragment - * ``` - * - * If u.Opaque is non-empty, String uses the first form; - * otherwise it uses the second form. - * Any non-ASCII characters in host are escaped. - * To obtain the path, String uses u.EscapedPath(). - * - * In the second form, the following rules apply: - * ``` - * - if u.Scheme is empty, scheme: is omitted. - * - if u.User is nil, userinfo@ is omitted. - * - if u.Host is empty, host/ is omitted. - * - if u.Scheme and u.Host are empty and u.User is nil, - * the entire scheme://userinfo@host/ is omitted. - * - if u.Host is non-empty and u.Path begins with a /, - * the form host/path does not add its own /. - * - if u.RawQuery is empty, ?query is omitted. - * - if u.Fragment is empty, #fragment is omitted. - * ``` - */ - string(): string - } - interface URL { - /** - * Redacted is like [URL.String] but replaces any password with "xxxxx". - * Only the password in u.User is redacted. - */ - redacted(): string - } - /** - * Values maps a string key to a list of values. - * It is typically used for query parameters and form values. - * Unlike in the http.Header map, the keys in a Values map - * are case-sensitive. - */ - interface Values extends _TygojaDict{} - interface Values { - /** - * Get gets the first value associated with the given key. - * If there are no values associated with the key, Get returns - * the empty string. To access multiple values, use the map - * directly. - */ - get(key: string): string - } - interface Values { - /** - * Set sets the key to value. It replaces any existing - * values. - */ - set(key: string, value: string): void - } - interface Values { - /** - * Add adds the value to key. It appends to any existing - * values associated with key. - */ - add(key: string, value: string): void - } - interface Values { - /** - * Del deletes the values associated with key. - */ - del(key: string): void - } - interface Values { - /** - * Has checks whether a given key is set. - */ - has(key: string): boolean - } - interface Values { - /** - * Encode encodes the values into “URL encoded” form - * ("bar=baz&foo=quux") sorted by key. - */ - encode(): string - } - interface URL { - /** - * IsAbs reports whether the [URL] is absolute. - * Absolute means that it has a non-empty scheme. - */ - isAbs(): boolean - } - interface URL { - /** - * Parse parses a [URL] in the context of the receiver. The provided URL - * may be relative or absolute. Parse returns nil, err on parse - * failure, otherwise its return value is the same as [URL.ResolveReference]. - */ - parse(ref: string): (URL) - } - interface URL { - /** - * ResolveReference resolves a URI reference to an absolute URI from - * an absolute base URI u, per RFC 3986 Section 5.2. The URI reference - * may be relative or absolute. ResolveReference always returns a new - * [URL] instance, even if the returned URL is identical to either the - * base or reference. If ref is an absolute URL, then ResolveReference - * ignores base and returns a copy of ref. - */ - resolveReference(ref: URL): (URL) - } - interface URL { - /** - * Query parses RawQuery and returns the corresponding values. - * It silently discards malformed value pairs. - * To check errors use [ParseQuery]. - */ - query(): Values - } - interface URL { - /** - * RequestURI returns the encoded path?query or opaque?query - * string that would be used in an HTTP request for u. - */ - requestURI(): string - } - interface URL { - /** - * Hostname returns u.Host, stripping any valid port number if present. - * - * If the result is enclosed in square brackets, as literal IPv6 addresses are, - * the square brackets are removed from the result. - */ - hostname(): string - } - interface URL { - /** - * Port returns the port part of u.Host, without the leading colon. - * - * If u.Host doesn't contain a valid numeric port, Port returns an empty string. - */ - port(): string - } - interface URL { - marshalBinary(): string|Array - } - interface URL { - appendBinary(b: string|Array): string|Array - } - interface URL { - unmarshalBinary(text: string|Array): void - } - interface URL { - /** - * JoinPath returns a new [URL] with the provided path elements joined to - * any existing path and the resulting path cleaned of any ./ or ../ elements. - * Any sequences of multiple / characters will be reduced to a single /. - */ - joinPath(...elem: string[]): (URL) - } -} - -namespace context { -} - -namespace net { - /** - * Addr represents a network end point address. - * - * The two methods [Addr.Network] and [Addr.String] conventionally return strings - * that can be passed as the arguments to [Dial], but the exact form - * and meaning of the strings is up to the implementation. - */ - interface Addr { - [key:string]: any; - network(): string // name of the network (for example, "tcp", "udp") - string(): string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") - } - // @ts-ignore - import _cgopackage = cgo -} - -namespace jwt { - /** - * NumericDate represents a JSON numeric date value, as referenced at - * https://datatracker.ietf.org/doc/html/rfc7519#section-2. - */ - type _sIVkVHa = time.Time - interface NumericDate extends _sIVkVHa { - } - interface NumericDate { - /** - * MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch - * represented in NumericDate to a byte array, using the precision specified in TimePrecision. - */ - marshalJSON(): string|Array - } - interface NumericDate { - /** - * UnmarshalJSON is an implementation of the json.RawMessage interface and - * deserializes a [NumericDate] from a JSON representation, i.e. a - * [json.Number]. This number represents an UNIX epoch with either integer or - * non-integer seconds. - */ - unmarshalJSON(b: string|Array): void - } - /** - * ClaimStrings is basically just a slice of strings, but it can be either - * serialized from a string array or just a string. This type is necessary, - * since the "aud" claim can either be a single string or an array. - */ - interface ClaimStrings extends Array{} - interface ClaimStrings { - unmarshalJSON(data: string|Array): void - } - interface ClaimStrings { - marshalJSON(): string|Array - } -} - -namespace hook { - /** - * wrapped local Hook embedded struct to limit the public API surface. - */ - type _sVWAIPu = Hook - interface mainHook extends _sVWAIPu { - } -} - -namespace sql { - /** - * IsolationLevel is the transaction isolation level used in [TxOptions]. - */ - interface IsolationLevel extends Number{} - interface IsolationLevel { - /** - * String returns the name of the transaction isolation level. - */ - string(): string - } - /** - * DBStats contains database statistics. - */ - interface DBStats { - maxOpenConnections: number // Maximum number of open connections to the database. - /** - * Pool Status - */ - openConnections: number // The number of established connections both in use and idle. - inUse: number // The number of connections currently in use. - idle: number // The number of idle connections. - /** - * Counters - */ - waitCount: number // The total number of connections waited for. - waitDuration: time.Duration // The total time blocked waiting for a new connection. - maxIdleClosed: number // The total number of connections closed due to SetMaxIdleConns. - maxIdleTimeClosed: number // The total number of connections closed due to SetConnMaxIdleTime. - maxLifetimeClosed: number // The total number of connections closed due to SetConnMaxLifetime. - } - /** - * Conn represents a single database connection rather than a pool of database - * connections. Prefer running queries from [DB] unless there is a specific - * need for a continuous single database connection. - * - * A Conn must call [Conn.Close] to return the connection to the database pool - * and may do so concurrently with a running query. - * - * After a call to [Conn.Close], all operations on the - * connection fail with [ErrConnDone]. - */ - interface Conn { - } - interface Conn { - /** - * PingContext verifies the connection to the database is still alive. - */ - pingContext(ctx: context.Context): void - } - interface Conn { - /** - * ExecContext executes a query without returning any rows. - * The args are for any placeholder parameters in the query. - */ - execContext(ctx: context.Context, query: string, ...args: any[]): Result - } - interface Conn { - /** - * QueryContext executes a query that returns rows, typically a SELECT. - * The args are for any placeholder parameters in the query. - */ - queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) - } - interface Conn { - /** - * QueryRowContext executes a query that is expected to return at most one row. - * QueryRowContext always returns a non-nil value. Errors are deferred until - * the [*Row.Scan] method is called. - * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. - * Otherwise, the [*Row.Scan] scans the first selected row and discards - * the rest. - */ - queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) - } - interface Conn { - /** - * PrepareContext creates a prepared statement for later queries or executions. - * Multiple queries or executions may be run concurrently from the - * returned statement. - * The caller must call the statement's [*Stmt.Close] method - * when the statement is no longer needed. - * - * The provided context is used for the preparation of the statement, not for the - * execution of the statement. - */ - prepareContext(ctx: context.Context, query: string): (Stmt) - } - interface Conn { - /** - * Raw executes f exposing the underlying driver connection for the - * duration of f. The driverConn must not be used outside of f. - * - * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable - * until [Conn.Close] is called. - */ - raw(f: (driverConn: any) => void): void - } - interface Conn { - /** - * BeginTx starts a transaction. - * - * The provided context is used until the transaction is committed or rolled back. - * If the context is canceled, the sql package will roll back - * the transaction. [Tx.Commit] will return an error if the context provided to - * BeginTx is canceled. - * - * The provided [TxOptions] is optional and may be nil if defaults should be used. - * If a non-default isolation level is used that the driver doesn't support, - * an error will be returned. - */ - beginTx(ctx: context.Context, opts: TxOptions): (Tx) - } - interface Conn { - /** - * Close returns the connection to the connection pool. - * All operations after a Close will return with [ErrConnDone]. - * Close is safe to call concurrently with other operations and will - * block until all other operations finish. It may be useful to first - * cancel any used context and then call close directly after. - */ - close(): void - } - /** - * ColumnType contains the name and type of a column. - */ - interface ColumnType { - } - interface ColumnType { - /** - * Name returns the name or alias of the column. - */ - name(): string - } - interface ColumnType { - /** - * Length returns the column type length for variable length column types such - * as text and binary field types. If the type length is unbounded the value will - * be [math.MaxInt64] (any database limits will still apply). - * If the column type is not variable length, such as an int, or if not supported - * by the driver ok is false. - */ - length(): [number, boolean] - } - interface ColumnType { - /** - * DecimalSize returns the scale and precision of a decimal type. - * If not applicable or if not supported ok is false. - */ - decimalSize(): [number, number, boolean] - } - interface ColumnType { - /** - * ScanType returns a Go type suitable for scanning into using [Rows.Scan]. - * If a driver does not support this property ScanType will return - * the type of an empty interface. - */ - scanType(): any - } - interface ColumnType { - /** - * Nullable reports whether the column may be null. - * If a driver does not support this property ok will be false. - */ - nullable(): [boolean, boolean] - } - interface ColumnType { - /** - * DatabaseTypeName returns the database system name of the column type. If an empty - * string is returned, then the driver type name is not supported. - * Consult your driver documentation for a list of driver data types. [ColumnType.Length] specifiers - * are not included. - * Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", - * "INT", and "BIGINT". - */ - databaseTypeName(): string - } - /** - * Row is the result of calling [DB.QueryRow] to select a single row. - */ - interface Row { - } - interface Row { - /** - * Scan copies the columns from the matched row into the values - * pointed at by dest. See the documentation on [Rows.Scan] for details. - * If more than one row matches the query, - * Scan uses the first row and discards the rest. If no row matches - * the query, Scan returns [ErrNoRows]. - */ - scan(...dest: any[]): void - } - interface Row { - /** - * Err provides a way for wrapping packages to check for - * query errors without calling [Row.Scan]. - * Err returns the error, if any, that was encountered while running the query. - * If this error is not nil, this error will also be returned from [Row.Scan]. - */ - err(): void - } -} - namespace bufio { /** * Reader implements buffering for an io.Reader object. @@ -22762,30 +22312,112 @@ namespace bufio { } } -namespace types { +namespace syscall { + // @ts-ignore + import errpkg = errors + /** + * SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux. + * See user_namespaces(7). + * + * Note that User Namespaces are not available on a number of popular Linux + * versions (due to security issues), or are available but subject to AppArmor + * restrictions like in Ubuntu 24.04. + */ + interface SysProcIDMap { + containerID: number // Container ID. + hostID: number // Host ID. + size: number // Size. + } + // @ts-ignore + import errorspkg = errors + /** + * Credential holds user and group identities to be assumed + * by a child process started by [StartProcess]. + */ + interface Credential { + uid: number // User ID. + gid: number // Group ID. + groups: Array // Supplementary group IDs. + noSetGroups: boolean // If true, don't set supplementary groups + } + // @ts-ignore + import runtimesyscall = syscall + /** + * A Signal is a number describing a process signal. + * It implements the [os.Signal] interface. + */ + interface Signal extends Number{} + interface Signal { + signal(): void + } + interface Signal { + string(): string + } } -namespace search { +namespace time { /** - * MultiMatchSubquery defines a multi-match record subquery expression. + * A Month specifies a month of the year (January = 1, ...). */ - interface MultiMatchSubquery { - targetTableAlias: string - fromTableName: string - fromTableAlias: string - valueIdentifier: string - joins: Array<(Join | undefined)> - params: dbx.Params - } - interface MultiMatchSubquery { + interface Month extends Number{} + interface Month { /** - * Build converts the expression into a SQL fragment. - * - * Implements [dbx.Expression] interface. + * String returns the English name of the month ("January", "February", ...). */ - build(db: dbx.DB, params: dbx.Params): string + string(): string } - interface NullFallbackPreference extends Number{} + /** + * A Weekday specifies a day of the week (Sunday = 0, ...). + */ + interface Weekday extends Number{} + interface Weekday { + /** + * String returns the English name of the day ("Sunday", "Monday", ...). + */ + string(): string + } + /** + * A Location maps time instants to the zone in use at that time. + * Typically, the Location represents the collection of time offsets + * in use in a geographical area. For many Locations the time offset varies + * depending on whether daylight savings time is in use at the time instant. + * + * Location is used to provide a time zone in a printed Time value and for + * calculations involving intervals that may cross daylight savings time + * boundaries. + */ + interface Location { + } + interface Location { + /** + * String returns a descriptive name for the time zone information, + * corresponding to the name argument to [LoadLocation] or [FixedZone]. + */ + string(): string + } +} + +namespace fs { +} + +namespace context { +} + +namespace net { + /** + * Addr represents a network end point address. + * + * The two methods [Addr.Network] and [Addr.String] conventionally return strings + * that can be passed as the arguments to [Dial], but the exact form + * and meaning of the strings is up to the implementation. + */ + interface Addr { + [key:string]: any; + network(): string // name of the network (for example, "tcp", "udp") + string(): string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") + } + // @ts-ignore + import _cgopackage = cgo } /** @@ -22930,6 +22562,251 @@ namespace multipart { } } +/** + * Package url parses URLs and implements query escaping. + * + * See RFC 3986. This package generally follows RFC 3986, except where + * it deviates for compatibility reasons. + * RFC 6874 followed for IPv6 zone literals. + */ +namespace url { + /** + * A URL represents a parsed URL (technically, a URI reference). + * + * The general form represented is: + * + * ``` + * [scheme:][//[userinfo@]host][/]path[?query][#fragment] + * ``` + * + * URLs that do not start with a slash after the scheme are interpreted as: + * + * ``` + * scheme:opaque[?query][#fragment] + * ``` + * + * The Host field contains the host and port subcomponents of the URL. + * When the port is present, it is separated from the host with a colon. + * When the host is an IPv6 address, it must be enclosed in square brackets: + * "[fe80::1]:80". The [net.JoinHostPort] function combines a host and port + * into a string suitable for the Host field, adding square brackets to + * the host when necessary. + * + * Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. + * A consequence is that it is impossible to tell which slashes in the Path were + * slashes in the raw URL and which were %2f. This distinction is rarely important, + * but when it is, the code should use the [URL.EscapedPath] method, which preserves + * the original encoding of Path. + * + * The RawPath field is an optional field which is only set when the default + * encoding of Path is different from the escaped path. See the EscapedPath method + * for more details. + * + * URL's String method uses the EscapedPath method to obtain the path. + */ + interface URL { + scheme: string + opaque: string // encoded opaque data + user?: Userinfo // username and password information + host: string // host or host:port (see Hostname and Port methods) + path: string // path (relative paths may omit leading slash) + rawPath: string // encoded path hint (see EscapedPath method) + omitHost: boolean // do not emit empty host (authority) + forceQuery: boolean // append a query ('?') even if RawQuery is empty + rawQuery: string // encoded query values, without '?' + fragment: string // fragment for references, without '#' + rawFragment: string // encoded fragment hint (see EscapedFragment method) + } + interface URL { + /** + * EscapedPath returns the escaped form of u.Path. + * In general there are multiple possible escaped forms of any path. + * EscapedPath returns u.RawPath when it is a valid escaping of u.Path. + * Otherwise EscapedPath ignores u.RawPath and computes an escaped + * form on its own. + * The [URL.String] and [URL.RequestURI] methods use EscapedPath to construct + * their results. + * In general, code should call EscapedPath instead of + * reading u.RawPath directly. + */ + escapedPath(): string + } + interface URL { + /** + * EscapedFragment returns the escaped form of u.Fragment. + * In general there are multiple possible escaped forms of any fragment. + * EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment. + * Otherwise EscapedFragment ignores u.RawFragment and computes an escaped + * form on its own. + * The [URL.String] method uses EscapedFragment to construct its result. + * In general, code should call EscapedFragment instead of + * reading u.RawFragment directly. + */ + escapedFragment(): string + } + interface URL { + /** + * String reassembles the [URL] into a valid URL string. + * The general form of the result is one of: + * + * ``` + * scheme:opaque?query#fragment + * scheme://userinfo@host/path?query#fragment + * ``` + * + * If u.Opaque is non-empty, String uses the first form; + * otherwise it uses the second form. + * Any non-ASCII characters in host are escaped. + * To obtain the path, String uses u.EscapedPath(). + * + * In the second form, the following rules apply: + * ``` + * - if u.Scheme is empty, scheme: is omitted. + * - if u.User is nil, userinfo@ is omitted. + * - if u.Host is empty, host/ is omitted. + * - if u.Scheme and u.Host are empty and u.User is nil, + * the entire scheme://userinfo@host/ is omitted. + * - if u.Host is non-empty and u.Path begins with a /, + * the form host/path does not add its own /. + * - if u.RawQuery is empty, ?query is omitted. + * - if u.Fragment is empty, #fragment is omitted. + * ``` + */ + string(): string + } + interface URL { + /** + * Redacted is like [URL.String] but replaces any password with "xxxxx". + * Only the password in u.User is redacted. + */ + redacted(): string + } + /** + * Values maps a string key to a list of values. + * It is typically used for query parameters and form values. + * Unlike in the http.Header map, the keys in a Values map + * are case-sensitive. + */ + interface Values extends _TygojaDict{} + interface Values { + /** + * Get gets the first value associated with the given key. + * If there are no values associated with the key, Get returns + * the empty string. To access multiple values, use the map + * directly. + */ + get(key: string): string + } + interface Values { + /** + * Set sets the key to value. It replaces any existing + * values. + */ + set(key: string, value: string): void + } + interface Values { + /** + * Add adds the value to key. It appends to any existing + * values associated with key. + */ + add(key: string, value: string): void + } + interface Values { + /** + * Del deletes the values associated with key. + */ + del(key: string): void + } + interface Values { + /** + * Has checks whether a given key is set. + */ + has(key: string): boolean + } + interface Values { + /** + * Encode encodes the values into “URL encoded” form + * ("bar=baz&foo=quux") sorted by key. + */ + encode(): string + } + interface URL { + /** + * IsAbs reports whether the [URL] is absolute. + * Absolute means that it has a non-empty scheme. + */ + isAbs(): boolean + } + interface URL { + /** + * Parse parses a [URL] in the context of the receiver. The provided URL + * may be relative or absolute. Parse returns nil, err on parse + * failure, otherwise its return value is the same as [URL.ResolveReference]. + */ + parse(ref: string): (URL) + } + interface URL { + /** + * ResolveReference resolves a URI reference to an absolute URI from + * an absolute base URI u, per RFC 3986 Section 5.2. The URI reference + * may be relative or absolute. ResolveReference always returns a new + * [URL] instance, even if the returned URL is identical to either the + * base or reference. If ref is an absolute URL, then ResolveReference + * ignores base and returns a copy of ref. + */ + resolveReference(ref: URL): (URL) + } + interface URL { + /** + * Query parses RawQuery and returns the corresponding values. + * It silently discards malformed value pairs. + * To check errors use [ParseQuery]. + */ + query(): Values + } + interface URL { + /** + * RequestURI returns the encoded path?query or opaque?query + * string that would be used in an HTTP request for u. + */ + requestURI(): string + } + interface URL { + /** + * Hostname returns u.Host, stripping any valid port number if present. + * + * If the result is enclosed in square brackets, as literal IPv6 addresses are, + * the square brackets are removed from the result. + */ + hostname(): string + } + interface URL { + /** + * Port returns the port part of u.Host, without the leading colon. + * + * If u.Host doesn't contain a valid numeric port, Port returns an empty string. + */ + port(): string + } + interface URL { + marshalBinary(): string|Array + } + interface URL { + appendBinary(b: string|Array): string|Array + } + interface URL { + unmarshalBinary(text: string|Array): void + } + interface URL { + /** + * JoinPath returns a new [URL] with the provided path elements joined to + * any existing path and the resulting path cleaned of any ./ or ../ elements. + * Any sequences of multiple / characters will be reduced to a single /. + */ + joinPath(...elem: string[]): (URL) + } +} + namespace http { /** * A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an @@ -23345,99 +23222,416 @@ namespace http { } } -/** - * Package oauth2 provides support for making - * OAuth2 authorized and authenticated HTTP requests, - * as specified in RFC 6749. - * It can additionally grant authorization with Bearer JWT. - */ -namespace oauth2 { +namespace store { +} + +namespace types { +} + +namespace sql { /** - * An AuthCodeOption is passed to Config.AuthCodeURL. + * IsolationLevel is the transaction isolation level used in [TxOptions]. */ - interface AuthCodeOption { - [key:string]: any; + interface IsolationLevel extends Number{} + interface IsolationLevel { + /** + * String returns the name of the transaction isolation level. + */ + string(): string } /** - * Token represents the credentials used to authorize - * the requests to access protected resources on the OAuth 2.0 - * provider's backend. + * DBStats contains database statistics. + */ + interface DBStats { + maxOpenConnections: number // Maximum number of open connections to the database. + /** + * Pool Status + */ + openConnections: number // The number of established connections both in use and idle. + inUse: number // The number of connections currently in use. + idle: number // The number of idle connections. + /** + * Counters + */ + waitCount: number // The total number of connections waited for. + waitDuration: time.Duration // The total time blocked waiting for a new connection. + maxIdleClosed: number // The total number of connections closed due to SetMaxIdleConns. + maxIdleTimeClosed: number // The total number of connections closed due to SetConnMaxIdleTime. + maxLifetimeClosed: number // The total number of connections closed due to SetConnMaxLifetime. + } + /** + * Conn represents a single database connection rather than a pool of database + * connections. Prefer running queries from [DB] unless there is a specific + * need for a continuous single database connection. * - * Most users of this package should not access fields of Token - * directly. They're exported mostly for use by related packages - * implementing derivative OAuth2 flows. + * A Conn must call [Conn.Close] to return the connection to the database pool + * and may do so concurrently with a running query. + * + * After a call to [Conn.Close], all operations on the + * connection fail with [ErrConnDone]. */ - interface Token { + interface Conn { + } + interface Conn { /** - * AccessToken is the token that authorizes and authenticates - * the requests. + * PingContext verifies the connection to the database is still alive. */ - accessToken: string + pingContext(ctx: context.Context): void + } + interface Conn { /** - * TokenType is the type of token. - * The Type method returns either this or "Bearer", the default. + * ExecContext executes a query without returning any rows. + * The args are for any placeholder parameters in the query. */ - tokenType: string + execContext(ctx: context.Context, query: string, ...args: any[]): Result + } + interface Conn { /** - * RefreshToken is a token that's used by the application - * (as opposed to the user) to refresh the access token - * if it expires. + * QueryContext executes a query that returns rows, typically a SELECT. + * The args are for any placeholder parameters in the query. */ - refreshToken: string + queryContext(ctx: context.Context, query: string, ...args: any[]): (Rows) + } + interface Conn { /** - * Expiry is the optional expiration time of the access token. + * QueryRowContext executes a query that is expected to return at most one row. + * QueryRowContext always returns a non-nil value. Errors are deferred until + * the [*Row.Scan] method is called. + * If the query selects no rows, the [*Row.Scan] will return [ErrNoRows]. + * Otherwise, the [*Row.Scan] scans the first selected row and discards + * the rest. + */ + queryRowContext(ctx: context.Context, query: string, ...args: any[]): (Row) + } + interface Conn { + /** + * PrepareContext creates a prepared statement for later queries or executions. + * Multiple queries or executions may be run concurrently from the + * returned statement. + * The caller must call the statement's [*Stmt.Close] method + * when the statement is no longer needed. * - * If zero, [TokenSource] implementations will reuse the same - * token forever and RefreshToken or equivalent - * mechanisms for that TokenSource will not be used. + * The provided context is used for the preparation of the statement, not for the + * execution of the statement. */ - expiry: time.Time - /** - * ExpiresIn is the OAuth2 wire format "expires_in" field, - * which specifies how many seconds later the token expires, - * relative to an unknown time base approximately around "now". - * It is the application's responsibility to populate - * `Expiry` from `ExpiresIn` when required. - */ - expiresIn: number + prepareContext(ctx: context.Context, query: string): (Stmt) } - interface Token { + interface Conn { /** - * Type returns t.TokenType if non-empty, else "Bearer". - */ - type(): string - } - interface Token { - /** - * SetAuthHeader sets the Authorization header to r using the access - * token in t. + * Raw executes f exposing the underlying driver connection for the + * duration of f. The driverConn must not be used outside of f. * - * This method is unnecessary when using [Transport] or an HTTP Client - * returned by this package. + * Once f returns and err is not [driver.ErrBadConn], the [Conn] will continue to be usable + * until [Conn.Close] is called. */ - setAuthHeader(r: http.Request): void + raw(f: (driverConn: any) => void): void } - interface Token { + interface Conn { /** - * WithExtra returns a new [Token] that's a clone of t, but using the - * provided raw extra map. This is only intended for use by packages - * implementing derivative OAuth2 flows. + * BeginTx starts a transaction. + * + * The provided context is used until the transaction is committed or rolled back. + * If the context is canceled, the sql package will roll back + * the transaction. [Tx.Commit] will return an error if the context provided to + * BeginTx is canceled. + * + * The provided [TxOptions] is optional and may be nil if defaults should be used. + * If a non-default isolation level is used that the driver doesn't support, + * an error will be returned. */ - withExtra(extra: any): (Token) + beginTx(ctx: context.Context, opts: TxOptions): (Tx) } - interface Token { + interface Conn { /** - * Extra returns an extra field. - * Extra fields are key-value pairs returned by the server as - * part of the token retrieval response. + * Close returns the connection to the connection pool. + * All operations after a Close will return with [ErrConnDone]. + * Close is safe to call concurrently with other operations and will + * block until all other operations finish. It may be useful to first + * cancel any used context and then call close directly after. */ - extra(key: string): any + close(): void } - interface Token { + /** + * ColumnType contains the name and type of a column. + */ + interface ColumnType { + } + interface ColumnType { /** - * Valid reports whether t is non-nil, has an AccessToken, and is not expired. + * Name returns the name or alias of the column. */ - valid(): boolean + name(): string + } + interface ColumnType { + /** + * Length returns the column type length for variable length column types such + * as text and binary field types. If the type length is unbounded the value will + * be [math.MaxInt64] (any database limits will still apply). + * If the column type is not variable length, such as an int, or if not supported + * by the driver ok is false. + */ + length(): [number, boolean] + } + interface ColumnType { + /** + * DecimalSize returns the scale and precision of a decimal type. + * If not applicable or if not supported ok is false. + */ + decimalSize(): [number, number, boolean] + } + interface ColumnType { + /** + * ScanType returns a Go type suitable for scanning into using [Rows.Scan]. + * If a driver does not support this property ScanType will return + * the type of an empty interface. + */ + scanType(): any + } + interface ColumnType { + /** + * Nullable reports whether the column may be null. + * If a driver does not support this property ok will be false. + */ + nullable(): [boolean, boolean] + } + interface ColumnType { + /** + * DatabaseTypeName returns the database system name of the column type. If an empty + * string is returned, then the driver type name is not supported. + * Consult your driver documentation for a list of driver data types. [ColumnType.Length] specifiers + * are not included. + * Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", + * "INT", and "BIGINT". + */ + databaseTypeName(): string + } + /** + * Row is the result of calling [DB.QueryRow] to select a single row. + */ + interface Row { + } + interface Row { + /** + * Scan copies the columns from the matched row into the values + * pointed at by dest. See the documentation on [Rows.Scan] for details. + * If more than one row matches the query, + * Scan uses the first row and discards the rest. If no row matches + * the query, Scan returns [ErrNoRows]. + */ + scan(...dest: any[]): void + } + interface Row { + /** + * Err provides a way for wrapping packages to check for + * query errors without calling [Row.Scan]. + * Err returns the error, if any, that was encountered while running the query. + * If this error is not nil, this error will also be returned from [Row.Scan]. + */ + err(): void + } +} + +namespace jwt { + /** + * NumericDate represents a JSON numeric date value, as referenced at + * https://datatracker.ietf.org/doc/html/rfc7519#section-2. + */ + type _sRxQbal = time.Time + interface NumericDate extends _sRxQbal { + } + interface NumericDate { + /** + * MarshalJSON is an implementation of the json.RawMessage interface and serializes the UNIX epoch + * represented in NumericDate to a byte array, using the precision specified in TimePrecision. + */ + marshalJSON(): string|Array + } + interface NumericDate { + /** + * UnmarshalJSON is an implementation of the json.RawMessage interface and + * deserializes a [NumericDate] from a JSON representation, i.e. a + * [json.Number]. This number represents an UNIX epoch with either integer or + * non-integer seconds. + */ + unmarshalJSON(b: string|Array): void + } + /** + * ClaimStrings is basically just a slice of strings, but it can be either + * serialized from a string array or just a string. This type is necessary, + * since the "aud" claim can either be a single string or an array. + */ + interface ClaimStrings extends Array{} + interface ClaimStrings { + unmarshalJSON(data: string|Array): void + } + interface ClaimStrings { + marshalJSON(): string|Array + } +} + +namespace hook { + /** + * wrapped local Hook embedded struct to limit the public API surface. + */ + type _sIvilbe = Hook + interface mainHook extends _sIvilbe { + } +} + +namespace search { + /** + * MultiMatchSubquery defines a multi-match record subquery expression. + */ + interface MultiMatchSubquery { + targetTableAlias: string + fromTableName: string + fromTableAlias: string + valueIdentifier: string + joins: Array<(Join | undefined)> + params: dbx.Params + } + interface MultiMatchSubquery { + /** + * Build converts the expression into a SQL fragment. + * + * Implements [dbx.Expression] interface. + */ + build(db: dbx.DB, params: dbx.Params): string + } + interface NullFallbackPreference extends Number{} +} + +namespace router { + // @ts-ignore + import validation = ozzo_validation + /** + * RouterGroup represents a collection of routes and other sub groups + * that share common pattern prefix and middlewares. + */ + interface RouterGroup { + prefix: string + middlewares: Array<(hook.Handler | undefined)> + } + interface RouterGroup { + /** + * Group creates and register a new child Group into the current one + * with the specified prefix. + * + * The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]") + * and will be concatenated recursively into the final route path, meaning that + * only the root level group could have HOST as part of the prefix. + * + * Returns the newly created group to allow chaining and registering + * sub-routes and group specific middlewares. + */ + group(prefix: string): (RouterGroup) + } + interface RouterGroup { + /** + * BindFunc registers one or multiple middleware functions to the current group. + * + * The registered middleware functions are "anonymous" and with default priority, + * aka. executes in the order they were registered. + * + * If you need to specify a named middleware (ex. so that it can be removed) + * or middleware with custom exec prirority, use [RouterGroup.Bind] method. + */ + bindFunc(...middlewareFuncs: ((e: T) => void)[]): (RouterGroup) + } + interface RouterGroup { + /** + * Bind registers one or multiple middleware handlers to the current group. + */ + bind(...middlewares: (hook.Handler | undefined)[]): (RouterGroup) + } + interface RouterGroup { + /** + * Unbind removes one or more middlewares with the specified id(s) + * from the current group and its children (if any). + * + * Anonymous middlewares are not removable, aka. this method does nothing + * if the middleware id is an empty string. + */ + unbind(...middlewareIds: string[]): (RouterGroup) + } + interface RouterGroup { + /** + * Route registers a single route into the current group. + * + * Note that the final route path will be the concatenation of all parent groups prefixes + the route path. + * The path follows the standard Go net/http ServeMux format ("[HOST]/[PATH]"), + * meaning that only a top level group route could have HOST as part of the prefix. + * + * Returns the newly created route to allow attaching route-only middlewares. + */ + route(method: string, path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * Any is a shorthand for [RouterGroup.AddRoute] with "" as route method (aka. matches any method). + */ + any(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * GET is a shorthand for [RouterGroup.AddRoute] with GET as route method. + */ + get(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * SEARCH is a shorthand for [RouterGroup.AddRoute] with SEARCH as route method. + */ + search(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * POST is a shorthand for [RouterGroup.AddRoute] with POST as route method. + */ + post(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * DELETE is a shorthand for [RouterGroup.AddRoute] with DELETE as route method. + */ + delete(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * PATCH is a shorthand for [RouterGroup.AddRoute] with PATCH as route method. + */ + patch(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * PUT is a shorthand for [RouterGroup.AddRoute] with PUT as route method. + */ + put(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * HEAD is a shorthand for [RouterGroup.AddRoute] with HEAD as route method. + */ + head(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * OPTIONS is a shorthand for [RouterGroup.AddRoute] with OPTIONS as route method. + */ + options(path: string, action: (e: T) => void): (Route) + } + interface RouterGroup { + /** + * HasRoute checks whether the specified route pattern (method + path) + * is registered in the current group or its children. + * + * This could be useful to conditionally register and checks for routes + * in order prevent panic on duplicated routes. + * + * Note that routes with anonymous and named wildcard placeholder are treated as equal, + * aka. "GET /abc/" is considered the same as "GET /abc/{something...}". + */ + hasRoute(method: string, path: string): boolean } } @@ -23721,137 +23915,99 @@ namespace cron { } } -namespace router { - // @ts-ignore - import validation = ozzo_validation +/** + * Package oauth2 provides support for making + * OAuth2 authorized and authenticated HTTP requests, + * as specified in RFC 6749. + * It can additionally grant authorization with Bearer JWT. + */ +namespace oauth2 { /** - * RouterGroup represents a collection of routes and other sub groups - * that share common pattern prefix and middlewares. + * An AuthCodeOption is passed to Config.AuthCodeURL. */ - interface RouterGroup { - prefix: string - middlewares: Array<(hook.Handler | undefined)> + interface AuthCodeOption { + [key:string]: any; } - interface RouterGroup { + /** + * Token represents the credentials used to authorize + * the requests to access protected resources on the OAuth 2.0 + * provider's backend. + * + * Most users of this package should not access fields of Token + * directly. They're exported mostly for use by related packages + * implementing derivative OAuth2 flows. + */ + interface Token { /** - * Group creates and register a new child Group into the current one - * with the specified prefix. + * AccessToken is the token that authorizes and authenticates + * the requests. + */ + accessToken: string + /** + * TokenType is the type of token. + * The Type method returns either this or "Bearer", the default. + */ + tokenType: string + /** + * RefreshToken is a token that's used by the application + * (as opposed to the user) to refresh the access token + * if it expires. + */ + refreshToken: string + /** + * Expiry is the optional expiration time of the access token. * - * The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]") - * and will be concatenated recursively into the final route path, meaning that - * only the root level group could have HOST as part of the prefix. + * If zero, [TokenSource] implementations will reuse the same + * token forever and RefreshToken or equivalent + * mechanisms for that TokenSource will not be used. + */ + expiry: time.Time + /** + * ExpiresIn is the OAuth2 wire format "expires_in" field, + * which specifies how many seconds later the token expires, + * relative to an unknown time base approximately around "now". + * It is the application's responsibility to populate + * `Expiry` from `ExpiresIn` when required. + */ + expiresIn: number + } + interface Token { + /** + * Type returns t.TokenType if non-empty, else "Bearer". + */ + type(): string + } + interface Token { + /** + * SetAuthHeader sets the Authorization header to r using the access + * token in t. * - * Returns the newly created group to allow chaining and registering - * sub-routes and group specific middlewares. + * This method is unnecessary when using [Transport] or an HTTP Client + * returned by this package. */ - group(prefix: string): (RouterGroup) + setAuthHeader(r: http.Request): void } - interface RouterGroup { + interface Token { /** - * BindFunc registers one or multiple middleware functions to the current group. - * - * The registered middleware functions are "anonymous" and with default priority, - * aka. executes in the order they were registered. - * - * If you need to specify a named middleware (ex. so that it can be removed) - * or middleware with custom exec prirority, use [RouterGroup.Bind] method. + * WithExtra returns a new [Token] that's a clone of t, but using the + * provided raw extra map. This is only intended for use by packages + * implementing derivative OAuth2 flows. */ - bindFunc(...middlewareFuncs: ((e: T) => void)[]): (RouterGroup) + withExtra(extra: any): (Token) } - interface RouterGroup { + interface Token { /** - * Bind registers one or multiple middleware handlers to the current group. + * Extra returns an extra field. + * Extra fields are key-value pairs returned by the server as + * part of the token retrieval response. */ - bind(...middlewares: (hook.Handler | undefined)[]): (RouterGroup) + extra(key: string): any } - interface RouterGroup { + interface Token { /** - * Unbind removes one or more middlewares with the specified id(s) - * from the current group and its children (if any). - * - * Anonymous middlewares are not removable, aka. this method does nothing - * if the middleware id is an empty string. + * Valid reports whether t is non-nil, has an AccessToken, and is not expired. */ - unbind(...middlewareIds: string[]): (RouterGroup) - } - interface RouterGroup { - /** - * Route registers a single route into the current group. - * - * Note that the final route path will be the concatenation of all parent groups prefixes + the route path. - * The path follows the standard Go net/http ServeMux format ("[HOST]/[PATH]"), - * meaning that only a top level group route could have HOST as part of the prefix. - * - * Returns the newly created route to allow attaching route-only middlewares. - */ - route(method: string, path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * Any is a shorthand for [RouterGroup.AddRoute] with "" as route method (aka. matches any method). - */ - any(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * GET is a shorthand for [RouterGroup.AddRoute] with GET as route method. - */ - get(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * SEARCH is a shorthand for [RouterGroup.AddRoute] with SEARCH as route method. - */ - search(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * POST is a shorthand for [RouterGroup.AddRoute] with POST as route method. - */ - post(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * DELETE is a shorthand for [RouterGroup.AddRoute] with DELETE as route method. - */ - delete(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * PATCH is a shorthand for [RouterGroup.AddRoute] with PATCH as route method. - */ - patch(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * PUT is a shorthand for [RouterGroup.AddRoute] with PUT as route method. - */ - put(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * HEAD is a shorthand for [RouterGroup.AddRoute] with HEAD as route method. - */ - head(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * OPTIONS is a shorthand for [RouterGroup.AddRoute] with OPTIONS as route method. - */ - options(path: string, action: (e: T) => void): (Route) - } - interface RouterGroup { - /** - * HasRoute checks whether the specified route pattern (method + path) - * is registered in the current group or its children. - * - * This could be useful to conditionally register and checks for routes - * in order prevent panic on duplicated routes. - * - * Note that routes with anonymous and named wildcard placeholder are treated as equal, - * aka. "GET /abc/" is considered the same as "GET /abc/{something...}". - */ - hasRoute(method: string, path: string): boolean + valid(): boolean } } @@ -23885,6 +24041,17 @@ namespace url { } } +namespace search { + /** + * Join defines common fields required for a single SQL JOIN clause. + */ + interface Join { + tableName: string + tableAlias: string + on: dbx.Expression + } +} + namespace multipart { /** * A Part represents a single part in a multipart body. @@ -23940,18 +24107,58 @@ namespace http { import urlpkg = url } -namespace oauth2 { +namespace router { + // @ts-ignore + import validation = ozzo_validation + interface Route { + action: (e: T) => void + method: string + path: string + middlewares: Array<(hook.Handler | undefined)> + } + interface Route { + /** + * BindFunc registers one or multiple middleware functions to the current route. + * + * The registered middleware functions are "anonymous" and with default priority, + * aka. executes in the order they were registered. + * + * If you need to specify a named middleware (ex. so that it can be removed) + * or middleware with custom exec prirority, use the [Route.Bind] method. + */ + bindFunc(...middlewareFuncs: ((e: T) => void)[]): (Route) + } + interface Route { + /** + * Bind registers one or multiple middleware handlers to the current route. + */ + bind(...middlewares: (hook.Handler | undefined)[]): (Route) + } + interface Route { + /** + * Unbind removes one or more middlewares with the specified id(s) from the current route. + * + * It also adds the removed middleware ids to an exclude list so that they could be skipped from + * the execution chain in case the middleware is registered in a parent group. + * + * Anonymous middlewares are considered non-removable, aka. this method + * does nothing if the middleware id is an empty string. + */ + unbind(...middlewareIds: string[]): (Route) + } } -namespace search { +namespace cobra { + // @ts-ignore + import flag = pflag /** - * Join defines common fields required for a single SQL JOIN clause. + * ShellCompDirective is a bit map representing the different behaviors the shell + * can be instructed to have once completions have been provided. */ - interface Join { - tableName: string - tableAlias: string - on: dbx.Expression - } + interface ShellCompDirective extends Number{} +} + +namespace oauth2 { } namespace slog { @@ -24134,57 +24341,6 @@ namespace slog { } } -namespace cobra { - // @ts-ignore - import flag = pflag - /** - * ShellCompDirective is a bit map representing the different behaviors the shell - * can be instructed to have once completions have been provided. - */ - interface ShellCompDirective extends Number{} -} - -namespace router { - // @ts-ignore - import validation = ozzo_validation - interface Route { - action: (e: T) => void - method: string - path: string - middlewares: Array<(hook.Handler | undefined)> - } - interface Route { - /** - * BindFunc registers one or multiple middleware functions to the current route. - * - * The registered middleware functions are "anonymous" and with default priority, - * aka. executes in the order they were registered. - * - * If you need to specify a named middleware (ex. so that it can be removed) - * or middleware with custom exec prirority, use the [Route.Bind] method. - */ - bindFunc(...middlewareFuncs: ((e: T) => void)[]): (Route) - } - interface Route { - /** - * Bind registers one or multiple middleware handlers to the current route. - */ - bind(...middlewares: (hook.Handler | undefined)[]): (Route) - } - interface Route { - /** - * Unbind removes one or more middlewares with the specified id(s) from the current route. - * - * It also adds the removed middleware ids to an exclude list so that they could be skipped from - * the execution chain in case the middleware is registered in a parent group. - * - * Anonymous middlewares are considered non-removable, aka. this method - * does nothing if the middleware id is an empty string. - */ - unbind(...middlewareIds: string[]): (Route) - } -} - namespace slog { // @ts-ignore import loginternal = internal diff --git a/plugins/jsvm/jsvm.go b/plugins/jsvm/jsvm.go index bf194537..37da3583 100644 --- a/plugins/jsvm/jsvm.go +++ b/plugins/jsvm/jsvm.go @@ -1,6 +1,9 @@ // Package jsvm implements pluggable utilities for binding a JS goja runtime // to the PocketBase instance (loading migrations, attaching to app hooks, etc.). // +// The package also exports several reusable bindings so that users +// can utilize them as part of their own custom goja runtime setup. +// // Example: // // jsvm.MustRegister(app, jsvm.Config{ @@ -200,15 +203,15 @@ func (p *plugin) registerMigrations() error { process.Enable(vm) buffer.Enable(vm) - baseBinds(vm) - dbxBinds(vm) - securityBinds(vm) - osBinds(vm) - filepathBinds(vm) - httpClientBinds(vm) - filesystemBinds(vm) - formsBinds(vm) - mailsBinds(vm) + BindCore(vm) + BindDbx(vm) + BindSecurity(vm) + BindOs(vm) + BindFilepath(vm) + BindHttpClient(vm) + BindFilesystem(vm) + BindForms(vm) + BindMails(vm) vm.Set("$template", templateRegistry) vm.Set("__hooks", absHooksDir) @@ -288,16 +291,16 @@ func (p *plugin) registerHooks() error { process.Enable(vm) buffer.Enable(vm) - baseBinds(vm) - dbxBinds(vm) - filesystemBinds(vm) - securityBinds(vm) - osBinds(vm) - filepathBinds(vm) - httpClientBinds(vm) - formsBinds(vm) - apisBinds(vm) - mailsBinds(vm) + BindCore(vm) + BindDbx(vm) + BindSecurity(vm) + BindOs(vm) + BindFilepath(vm) + BindHttpClient(vm) + BindFilesystem(vm) + BindForms(vm) + BindMails(vm) + BindApis(vm) vm.Set("$app", p.app) vm.Set("$template", templateRegistry) diff --git a/plugins/migratecmd/migratecmd_test.go b/plugins/migratecmd/migratecmd_test.go index b405e061..310147cc 100644 --- a/plugins/migratecmd/migratecmd_test.go +++ b/plugins/migratecmd/migratecmd_test.go @@ -50,6 +50,7 @@ migrate((app) => { "fields": [ { "autogeneratePattern": "[a-z0-9]{15}", + "help": "", "hidden": false, "id": "text@TEST_RANDOM", "max": 15, @@ -64,6 +65,7 @@ migrate((app) => { }, { "cost": 0, + "help": "", "hidden": true, "id": "password@TEST_RANDOM", "max": 0, @@ -77,6 +79,7 @@ migrate((app) => { }, { "autogeneratePattern": "[a-zA-Z0-9]{50}", + "help": "", "hidden": true, "id": "text@TEST_RANDOM", "max": 60, @@ -91,6 +94,7 @@ migrate((app) => { }, { "exceptDomains": null, + "help": "", "hidden": false, "id": "email@TEST_RANDOM", "name": "email", @@ -101,6 +105,7 @@ migrate((app) => { "type": "email" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "emailVisibility", @@ -110,6 +115,7 @@ migrate((app) => { "type": "bool" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "verified", @@ -226,6 +232,7 @@ func init() { "fields": [ { "autogeneratePattern": "[a-z0-9]{15}", + "help": "", "hidden": false, "id": "text@TEST_RANDOM", "max": 15, @@ -240,6 +247,7 @@ func init() { }, { "cost": 0, + "help": "", "hidden": true, "id": "password@TEST_RANDOM", "max": 0, @@ -253,6 +261,7 @@ func init() { }, { "autogeneratePattern": "[a-zA-Z0-9]{50}", + "help": "", "hidden": true, "id": "text@TEST_RANDOM", "max": 60, @@ -267,6 +276,7 @@ func init() { }, { "exceptDomains": null, + "help": "", "hidden": false, "id": "email@TEST_RANDOM", "name": "email", @@ -277,6 +287,7 @@ func init() { "type": "email" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "emailVisibility", @@ -286,6 +297,7 @@ func init() { "type": "bool" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "verified", @@ -491,6 +503,7 @@ migrate((app) => { "fields": [ { "autogeneratePattern": "[a-z0-9]{15}", + "help": "", "hidden": false, "id": "text@TEST_RANDOM", "max": 15, @@ -505,6 +518,7 @@ migrate((app) => { }, { "cost": 0, + "help": "", "hidden": true, "id": "password@TEST_RANDOM", "max": 0, @@ -518,6 +532,7 @@ migrate((app) => { }, { "autogeneratePattern": "[a-zA-Z0-9]{50}", + "help": "", "hidden": true, "id": "text@TEST_RANDOM", "max": 60, @@ -532,6 +547,7 @@ migrate((app) => { }, { "exceptDomains": null, + "help": "", "hidden": false, "id": "email3885137012", "name": "email", @@ -542,6 +558,7 @@ migrate((app) => { "type": "email" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "emailVisibility", @@ -551,6 +568,7 @@ migrate((app) => { "type": "bool" }, { + "help": "", "hidden": false, "id": "bool256245529", "name": "verified", @@ -670,6 +688,7 @@ func init() { "fields": [ { "autogeneratePattern": "[a-z0-9]{15}", + "help": "", "hidden": false, "id": "text@TEST_RANDOM", "max": 15, @@ -684,6 +703,7 @@ func init() { }, { "cost": 0, + "help": "", "hidden": true, "id": "password@TEST_RANDOM", "max": 0, @@ -697,6 +717,7 @@ func init() { }, { "autogeneratePattern": "[a-zA-Z0-9]{50}", + "help": "", "hidden": true, "id": "text@TEST_RANDOM", "max": 60, @@ -711,6 +732,7 @@ func init() { }, { "exceptDomains": null, + "help": "", "hidden": false, "id": "email3885137012", "name": "email", @@ -721,6 +743,7 @@ func init() { "type": "email" }, { + "help": "", "hidden": false, "id": "bool@TEST_RANDOM", "name": "emailVisibility", @@ -730,6 +753,7 @@ func init() { "type": "bool" }, { + "help": "", "hidden": false, "id": "bool256245529", "name": "verified", @@ -923,6 +947,7 @@ migrate((app) => { // add field collection.fields.addAt(8, new Field({ "autogeneratePattern": "", + "help": "", "hidden": false, "id": "f4_id", "max": 0, @@ -938,6 +963,7 @@ migrate((app) => { // update field collection.fields.addAt(7, new Field({ + "help": "", "hidden": false, "id": "f2_id", "max": null, @@ -976,6 +1002,7 @@ migrate((app) => { // add field collection.fields.addAt(8, new Field({ + "help": "", "hidden": false, "id": "f3_id", "name": "f3_name", @@ -990,6 +1017,7 @@ migrate((app) => { // update field collection.fields.addAt(7, new Field({ + "help": "", "hidden": false, "id": "f2_id", "max": null, @@ -1054,6 +1082,7 @@ func init() { // add field if err := collection.Fields.AddMarshaledJSONAt(8, []byte(` + "`" + `{ "autogeneratePattern": "", + "help": "", "hidden": false, "id": "f4_id", "max": 0, @@ -1071,6 +1100,7 @@ func init() { // update field if err := collection.Fields.AddMarshaledJSONAt(7, []byte(` + "`" + `{ + "help": "", "hidden": false, "id": "f2_id", "max": null, @@ -1116,6 +1146,7 @@ func init() { // add field if err := collection.Fields.AddMarshaledJSONAt(8, []byte(` + "`" + `{ + "help": "", "hidden": false, "id": "f3_id", "name": "f3_name", @@ -1132,6 +1163,7 @@ func init() { // update field if err := collection.Fields.AddMarshaledJSONAt(7, []byte(` + "`" + `{ + "help": "", "hidden": false, "id": "f2_id", "max": null, diff --git a/tools/auth/apple.go b/tools/auth/apple.go index 8ee92763..2a7da930 100644 --- a/tools/auth/apple.go +++ b/tools/auth/apple.go @@ -36,6 +36,8 @@ func NewAppleProvider() *Apple { return &Apple{ BaseProvider: BaseProvider{ ctx: context.Background(), + order: 1, + logo: ``, displayName: "Apple", pkce: true, scopes: []string{"name", "email"}, diff --git a/tools/auth/auth.go b/tools/auth/auth.go index 5a1b13c5..d0a9fbe8 100644 --- a/tools/auth/auth.go +++ b/tools/auth/auth.go @@ -28,8 +28,20 @@ func NewProviderByName(name string) (Provider, error) { return factory(), nil } +// @todo refactor and consider replace with a plain struct +// // Provider defines a common interface for an OAuth2 client. type Provider interface { + // @todo temp backport + // + // Order returns the sorting order of the provider usually used in the auth methods list response. + Logo() string + + // @todo temp backport + // + // Order returns the sorting order of the provider usually used in the auth methods list response. + Order() int + // Context returns the context associated with the provider (if any). Context() context.Context @@ -133,11 +145,18 @@ type AuthUser struct { Id string `json:"id"` Name string `json:"name"` Username string `json:"username"` - Email string `json:"email"` AvatarURL string `json:"avatarURL"` AccessToken string `json:"accessToken"` RefreshToken string `json:"refreshToken"` + // @todo consider assigning the non-verified email and combining + // with an extra Verified bool flag. + + // The VERIFIED OAuth2 account email. + // + // It must be empty if the provider is not able to verify the email ownership. + Email string `json:"email"` + // @todo // deprecated: use AvatarURL instead // AvatarUrl will be removed after dropping v0.22 support diff --git a/tools/auth/base_provider.go b/tools/auth/base_provider.go index a99edbc0..715c2270 100644 --- a/tools/auth/base_provider.go +++ b/tools/auth/base_provider.go @@ -13,16 +13,28 @@ import ( // BaseProvider defines common fields and methods used by OAuth2 client providers. type BaseProvider struct { ctx context.Context + extra map[string]any + redirectURL string clientId string clientSecret string displayName string - redirectURL string + logo string authURL string tokenURL string userInfoURL string scopes []string + order int pkce bool - extra map[string]any +} + +// Order implements Provider.Order() interface method. +func (p *BaseProvider) Order() int { + return p.order +} + +// Logo implements Provider.Logo() interface method. +func (p *BaseProvider) Logo() string { + return p.logo } // Context implements Provider.Context() interface method. diff --git a/tools/auth/base_provider_test.go b/tools/auth/base_provider_test.go index 047abc3e..1ec37012 100644 --- a/tools/auth/base_provider_test.go +++ b/tools/auth/base_provider_test.go @@ -30,14 +30,46 @@ func TestDisplayName(t *testing.T) { before := b.DisplayName() if before != "" { - t.Fatalf("Expected displayName to be empty, got %v", before) + t.Fatalf("Expected displayName to be empty, got %q", before) } b.SetDisplayName("test") after := b.DisplayName() if after != "test" { - t.Fatalf("Expected displayName to be 'test', got %v", after) + t.Fatalf("Expected displayName to be %q, got %q", "test", after) + } +} + +func TestOrder(t *testing.T) { + b := BaseProvider{} + + before := b.Order() + if before != 0 { + t.Fatalf("Expected order to be empty, got %d", before) + } + + b.order = 123 + + after := b.Order() + if after != 123 { + t.Fatalf("Expected order to be %d, got %d", 123, after) + } +} + +func TestLogo(t *testing.T) { + b := BaseProvider{} + + before := b.Logo() + if before != "" { + t.Fatalf("Expected logo to be empty, got %q", before) + } + + b.logo = "test" + + after := b.Logo() + if after != "test" { + t.Fatalf("Expected logo to be %q, got %q", "test", after) } } @@ -78,14 +110,14 @@ func TestClientId(t *testing.T) { before := b.ClientId() if before != "" { - t.Fatalf("Expected clientId to be empty, got %v", before) + t.Fatalf("Expected clientId to be empty, got %q", before) } b.SetClientId("test") after := b.ClientId() if after != "test" { - t.Fatalf("Expected clientId to be 'test', got %v", after) + t.Fatalf("Expected clientId to be %q, got %q", "test", after) } } @@ -94,14 +126,14 @@ func TestClientSecret(t *testing.T) { before := b.ClientSecret() if before != "" { - t.Fatalf("Expected clientSecret to be empty, got %v", before) + t.Fatalf("Expected clientSecret to be empty, got %q", before) } b.SetClientSecret("test") after := b.ClientSecret() if after != "test" { - t.Fatalf("Expected clientSecret to be 'test', got %v", after) + t.Fatalf("Expected clientSecret to be %q, got %q", "test", after) } } @@ -110,14 +142,14 @@ func TestRedirectURL(t *testing.T) { before := b.RedirectURL() if before != "" { - t.Fatalf("Expected RedirectURL to be empty, got %v", before) + t.Fatalf("Expected RedirectURL to be empty, got %q", before) } b.SetRedirectURL("test") after := b.RedirectURL() if after != "test" { - t.Fatalf("Expected RedirectURL to be 'test', got %v", after) + t.Fatalf("Expected RedirectURL to be %q, got %q", "test", after) } } @@ -126,14 +158,14 @@ func TestAuthURL(t *testing.T) { before := b.AuthURL() if before != "" { - t.Fatalf("Expected authURL to be empty, got %v", before) + t.Fatalf("Expected authURL to be empty, got %q", before) } b.SetAuthURL("test") after := b.AuthURL() if after != "test" { - t.Fatalf("Expected authURL to be 'test', got %v", after) + t.Fatalf("Expected authURL to be %q, got %q", "test", after) } } @@ -142,14 +174,14 @@ func TestTokenURL(t *testing.T) { before := b.TokenURL() if before != "" { - t.Fatalf("Expected tokenURL to be empty, got %v", before) + t.Fatalf("Expected tokenURL to be empty, got %q", before) } b.SetTokenURL("test") after := b.TokenURL() if after != "test" { - t.Fatalf("Expected tokenURL to be 'test', got %v", after) + t.Fatalf("Expected tokenURL to be %q, got %q", "test", after) } } @@ -158,14 +190,14 @@ func TestUserInfoURL(t *testing.T) { before := b.UserInfoURL() if before != "" { - t.Fatalf("Expected userInfoURL to be empty, got %v", before) + t.Fatalf("Expected userInfoURL to be empty, got %q", before) } b.SetUserInfoURL("test") after := b.UserInfoURL() if after != "test" { - t.Fatalf("Expected userInfoURL to be 'test', got %v", after) + t.Fatalf("Expected userInfoURL to be %q, got %q", "test", after) } } diff --git a/tools/auth/bitbucket.go b/tools/auth/bitbucket.go index ca5d8776..e0b0a5b0 100644 --- a/tools/auth/bitbucket.go +++ b/tools/auth/bitbucket.go @@ -28,6 +28,8 @@ type Bitbucket struct { func NewBitbucketProvider() *Bitbucket { return &Bitbucket{BaseProvider{ ctx: context.Background(), + order: 9, + logo: ``, displayName: "Bitbucket", pkce: false, scopes: []string{"account"}, diff --git a/tools/auth/box.go b/tools/auth/box.go index 47b54f37..b93394c5 100644 --- a/tools/auth/box.go +++ b/tools/auth/box.go @@ -27,6 +27,8 @@ type Box struct { func NewBoxProvider() *Box { return &Box{BaseProvider{ ctx: context.Background(), + order: 20, + logo: ``, displayName: "Box", pkce: true, scopes: []string{"root_readonly"}, diff --git a/tools/auth/discord.go b/tools/auth/discord.go index 355ae758..b3588719 100644 --- a/tools/auth/discord.go +++ b/tools/auth/discord.go @@ -29,6 +29,8 @@ func NewDiscordProvider() *Discord { // https://discord.com/developers/docs/resources/user#get-current-user return &Discord{BaseProvider{ ctx: context.Background(), + order: 12, + logo: ``, displayName: "Discord", pkce: true, scopes: []string{"identify", "email"}, diff --git a/tools/auth/facebook.go b/tools/auth/facebook.go index b3f08c06..07f61988 100644 --- a/tools/auth/facebook.go +++ b/tools/auth/facebook.go @@ -27,6 +27,8 @@ type Facebook struct { func NewFacebookProvider() *Facebook { return &Facebook{BaseProvider{ ctx: context.Background(), + order: 5, + logo: ``, displayName: "Facebook", pkce: true, scopes: []string{"email"}, diff --git a/tools/auth/gitea.go b/tools/auth/gitea.go index 721efaf8..5f8f4b81 100644 --- a/tools/auth/gitea.go +++ b/tools/auth/gitea.go @@ -27,6 +27,8 @@ type Gitea struct { func NewGiteaProvider() *Gitea { return &Gitea{BaseProvider{ ctx: context.Background(), + order: 11, + logo: ``, displayName: "Gitea", pkce: true, scopes: []string{"read:user", "user:email"}, diff --git a/tools/auth/gitee.go b/tools/auth/gitee.go index ae0b07b7..a31e279b 100644 --- a/tools/auth/gitee.go +++ b/tools/auth/gitee.go @@ -29,6 +29,8 @@ type Gitee struct { func NewGiteeProvider() *Gitee { return &Gitee{BaseProvider{ ctx: context.Background(), + order: 10, + logo: ``, displayName: "Gitee", pkce: true, scopes: []string{"user_info", "emails"}, diff --git a/tools/auth/github.go b/tools/auth/github.go index f4aa72fa..b3b80837 100644 --- a/tools/auth/github.go +++ b/tools/auth/github.go @@ -29,6 +29,8 @@ type Github struct { func NewGithubProvider() *Github { return &Github{BaseProvider{ ctx: context.Background(), + order: 7, + logo: ``, displayName: "GitHub", pkce: true, // technically is not supported yet but it is safe as the PKCE params are just ignored scopes: []string{"read:user", "user:email"}, diff --git a/tools/auth/gitlab.go b/tools/auth/gitlab.go index 837197bb..0fb83b7c 100644 --- a/tools/auth/gitlab.go +++ b/tools/auth/gitlab.go @@ -27,6 +27,8 @@ type Gitlab struct { func NewGitlabProvider() *Gitlab { return &Gitlab{BaseProvider{ ctx: context.Background(), + order: 8, + logo: ``, displayName: "GitLab", pkce: true, scopes: []string{"read_user"}, diff --git a/tools/auth/google.go b/tools/auth/google.go index 086cc97e..4c6fe142 100644 --- a/tools/auth/google.go +++ b/tools/auth/google.go @@ -26,6 +26,8 @@ type Google struct { func NewGoogleProvider() *Google { return &Google{BaseProvider{ ctx: context.Background(), + order: 2, + logo: ``, displayName: "Google", pkce: true, scopes: []string{ diff --git a/tools/auth/instagram.go b/tools/auth/instagram.go index 9de0f602..580149b7 100644 --- a/tools/auth/instagram.go +++ b/tools/auth/instagram.go @@ -26,6 +26,8 @@ type Instagram struct { func NewInstagramProvider() *Instagram { return &Instagram{BaseProvider{ ctx: context.Background(), + order: 6, + logo: ``, displayName: "Instagram", pkce: true, scopes: []string{"instagram_business_basic"}, diff --git a/tools/auth/kakao.go b/tools/auth/kakao.go index 849718a2..68fd5f54 100644 --- a/tools/auth/kakao.go +++ b/tools/auth/kakao.go @@ -28,6 +28,8 @@ type Kakao struct { func NewKakaoProvider() *Kakao { return &Kakao{BaseProvider{ ctx: context.Background(), + order: 14, + logo: ``, displayName: "Kakao", pkce: true, scopes: []string{"account_email", "profile_nickname", "profile_image"}, diff --git a/tools/auth/lark.go b/tools/auth/lark.go index 7466f86f..d4d93ef9 100644 --- a/tools/auth/lark.go +++ b/tools/auth/lark.go @@ -26,6 +26,8 @@ type Lark struct { func NewLarkProvider() *Lark { return &Lark{BaseProvider{ ctx: context.Background(), + order: 19, + logo: ``, displayName: "Lark", pkce: true, // Lark has two domains with the same API: feishu.cn and larksuite.com. diff --git a/tools/auth/linear.go b/tools/auth/linear.go index d5bab3c8..bf256b1a 100644 --- a/tools/auth/linear.go +++ b/tools/auth/linear.go @@ -31,6 +31,8 @@ type Linear struct { func NewLinearProvider() *Linear { return &Linear{BaseProvider{ ctx: context.Background(), + order: 16, + logo: ``, displayName: "Linear", pkce: false, // Linear doesn't support PKCE at the moment and returns an error if enabled scopes: []string{"read"}, diff --git a/tools/auth/livechat.go b/tools/auth/livechat.go index 2272091b..0d5d480c 100644 --- a/tools/auth/livechat.go +++ b/tools/auth/livechat.go @@ -26,6 +26,8 @@ type Livechat struct { func NewLivechatProvider() *Livechat { return &Livechat{BaseProvider{ ctx: context.Background(), + order: 27, + logo: ``, displayName: "LiveChat", pkce: true, scopes: []string{}, // default scopes are specified from the provider dashboard diff --git a/tools/auth/mailcow.go b/tools/auth/mailcow.go index 7e802be7..b7c37b9b 100644 --- a/tools/auth/mailcow.go +++ b/tools/auth/mailcow.go @@ -28,6 +28,8 @@ type Mailcow struct { func NewMailcowProvider() *Mailcow { return &Mailcow{BaseProvider{ ctx: context.Background(), + order: 28, + logo: ``, displayName: "mailcow", pkce: true, scopes: []string{"profile"}, diff --git a/tools/auth/microsoft.go b/tools/auth/microsoft.go index 98732583..47789e9e 100644 --- a/tools/auth/microsoft.go +++ b/tools/auth/microsoft.go @@ -28,6 +28,8 @@ func NewMicrosoftProvider() *Microsoft { endpoints := microsoft.AzureADEndpoint("") return &Microsoft{BaseProvider{ ctx: context.Background(), + order: 3, + logo: ``, displayName: "Microsoft", pkce: true, scopes: []string{"User.Read"}, diff --git a/tools/auth/monday.go b/tools/auth/monday.go index 3076c49a..416f1822 100644 --- a/tools/auth/monday.go +++ b/tools/auth/monday.go @@ -29,6 +29,8 @@ type Monday struct { func NewMondayProvider() *Monday { return &Monday{BaseProvider{ ctx: context.Background(), + order: 18, + logo: ``, displayName: "monday.com", pkce: true, scopes: []string{"me:read"}, diff --git a/tools/auth/notion.go b/tools/auth/notion.go index 5138e216..2a0d09dd 100644 --- a/tools/auth/notion.go +++ b/tools/auth/notion.go @@ -27,6 +27,8 @@ type Notion struct { func NewNotionProvider() *Notion { return &Notion{BaseProvider{ ctx: context.Background(), + order: 17, + logo: ``, displayName: "Notion", pkce: true, authURL: "https://api.notion.com/v1/oauth/authorize", diff --git a/tools/auth/oidc.go b/tools/auth/oidc.go index 1bc6ff69..9390eb93 100644 --- a/tools/auth/oidc.go +++ b/tools/auth/oidc.go @@ -57,6 +57,8 @@ type OIDC struct { func NewOIDCProvider() *OIDC { return &OIDC{BaseProvider{ ctx: context.Background(), + order: 99, + logo: ``, displayName: "OIDC", pkce: true, scopes: []string{ diff --git a/tools/auth/patreon.go b/tools/auth/patreon.go index ccccc795..3a85fc64 100644 --- a/tools/auth/patreon.go +++ b/tools/auth/patreon.go @@ -27,6 +27,8 @@ type Patreon struct { func NewPatreonProvider() *Patreon { return &Patreon{BaseProvider{ ctx: context.Background(), + order: 24, + logo: ``, displayName: "Patreon", pkce: true, scopes: []string{"identity", "identity[email]"}, diff --git a/tools/auth/planningcenter.go b/tools/auth/planningcenter.go index 2d834dcc..1658f234 100644 --- a/tools/auth/planningcenter.go +++ b/tools/auth/planningcenter.go @@ -27,6 +27,8 @@ type Planningcenter struct { func NewPlanningcenterProvider() *Planningcenter { return &Planningcenter{BaseProvider{ ctx: context.Background(), + order: 29, + logo: ``, displayName: "Planning Center", pkce: true, scopes: []string{"people"}, diff --git a/tools/auth/spotify.go b/tools/auth/spotify.go index 7e6b970e..5f4d44c5 100644 --- a/tools/auth/spotify.go +++ b/tools/auth/spotify.go @@ -27,6 +27,8 @@ type Spotify struct { func NewSpotifyProvider() *Spotify { return &Spotify{BaseProvider{ ctx: context.Background(), + order: 21, + logo: ``, displayName: "Spotify", pkce: true, scopes: []string{ diff --git a/tools/auth/strava.go b/tools/auth/strava.go index 836af0f2..510fb03d 100644 --- a/tools/auth/strava.go +++ b/tools/auth/strava.go @@ -27,6 +27,8 @@ type Strava struct { func NewStravaProvider() *Strava { return &Strava{BaseProvider{ ctx: context.Background(), + order: 25, + logo: ``, displayName: "Strava", pkce: true, scopes: []string{ diff --git a/tools/auth/trakt.go b/tools/auth/trakt.go index b6bfdcda..740f31bd 100644 --- a/tools/auth/trakt.go +++ b/tools/auth/trakt.go @@ -27,6 +27,8 @@ type Trakt struct { func NewTraktProvider() *Trakt { return &Trakt{BaseProvider{ ctx: context.Background(), + order: 22, + logo: ``, displayName: "Trakt", pkce: true, authURL: "https://trakt.tv/oauth/authorize", diff --git a/tools/auth/twitch.go b/tools/auth/twitch.go index 17db99e4..2b336820 100644 --- a/tools/auth/twitch.go +++ b/tools/auth/twitch.go @@ -29,6 +29,8 @@ type Twitch struct { func NewTwitchProvider() *Twitch { return &Twitch{BaseProvider{ ctx: context.Background(), + order: 23, + logo: ``, displayName: "Twitch", pkce: true, scopes: []string{"user:read:email"}, diff --git a/tools/auth/twitter.go b/tools/auth/twitter.go index 9272e5f3..b57125c7 100644 --- a/tools/auth/twitter.go +++ b/tools/auth/twitter.go @@ -26,6 +26,8 @@ type Twitter struct { func NewTwitterProvider() *Twitter { return &Twitter{BaseProvider{ ctx: context.Background(), + order: 13, + logo: ``, displayName: "X/Twitter", pkce: true, scopes: []string{ diff --git a/tools/auth/vk.go b/tools/auth/vk.go index acba3f58..fc75d200 100644 --- a/tools/auth/vk.go +++ b/tools/auth/vk.go @@ -22,6 +22,8 @@ var _ Provider = (*VK)(nil) // NameVK is the unique name of the VK provider. const NameVK string = "vk" +// @todo mark as deprecated +// // VK allows authentication via VK OAuth2. type VK struct { BaseProvider @@ -33,6 +35,8 @@ type VK struct { func NewVKProvider() *VK { return &VK{BaseProvider{ ctx: context.Background(), + order: 15, + logo: ``, displayName: "ВКонтакте", pkce: false, // VK currently doesn't support PKCE and throws an error if PKCE params are send scopes: []string{"email"}, diff --git a/tools/auth/wakatime.go b/tools/auth/wakatime.go index a69ead92..d2fede3b 100644 --- a/tools/auth/wakatime.go +++ b/tools/auth/wakatime.go @@ -26,6 +26,8 @@ type Wakatime struct { func NewWakatimeProvider() *Wakatime { return &Wakatime{BaseProvider{ ctx: context.Background(), + order: 26, + logo: ``, displayName: "WakaTime", pkce: true, scopes: []string{"email"}, diff --git a/tools/auth/yandex.go b/tools/auth/yandex.go index d4af1fa0..024b890d 100644 --- a/tools/auth/yandex.go +++ b/tools/auth/yandex.go @@ -29,6 +29,8 @@ type Yandex struct { func NewYandexProvider() *Yandex { return &Yandex{BaseProvider{ ctx: context.Background(), + order: 4, + logo: ``, displayName: "Yandex", pkce: true, scopes: []string{"login:email", "login:avatar", "login:info"}, diff --git a/ui/.env b/ui/.env index af8a586d..a611cac5 100644 --- a/ui/.env +++ b/ui/.env @@ -1,12 +1,14 @@ # all environments should start with 'PB_' prefix PB_BACKEND_URL = "../" PB_MFA_DOCS = "https://pocketbase.io/docs/authentication#multi-factor-authentication" -PB_OAUTH2_EXAMPLE = "https://pocketbase.io/docs/authentication#authenticate-with-oauth2" +PB_OAUTH2_DOCS = "https://pocketbase.io/docs/authentication#authenticate-with-oauth2" PB_RULES_SYNTAX_DOCS = "https://pocketbase.io/docs/api-rules-and-filters" PB_FILE_UPLOAD_DOCS = "https://pocketbase.io/docs/files-handling" PB_PROTECTED_FILE_DOCS = "https://pocketbase.io/docs/files-handling#protected-files" +PB_REALTIME_DOCS = "https://pocketbase.io/docs/api-realtime/" +PB_FIELDS_DOCS = "https://pocketbase.io/docs/collections/#fields" PB_DOCS_URL = "https://pocketbase.io/docs" PB_JS_SDK_URL = "https://github.com/pocketbase/js-sdk" PB_DART_SDK_URL = "https://github.com/pocketbase/dart-sdk" PB_RELEASES = "https://github.com/pocketbase/pocketbase/releases" -PB_VERSION = "v0.36.9" +PB_VERSION = "v0.37.0" diff --git a/ui/.gitignore b/ui/.gitignore index 631b5f86..e6814f9a 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -1,7 +1,22 @@ -/node_modules/ -/.vscode/ -.DS_Store +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* -# exclude local env files -.env.local -.env.*.local +node_modules +*.local +*.todo + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/ui/README.md b/ui/README.md index 854eea88..21155ed0 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,20 +1,23 @@ PocketBase Superuser dashboard UI ====================================================================== -This is the PocketBase Superuser dashboard UI (built with Svelte and Vite). +This is the PocketBase Superuser dashboard UI (built with Shablon and Vite). -Although it could be used independently, it is mainly intended to be embedded -as part of a PocketBase app executable (hence the `embed.go` file). +Although it could be used independently, it is intended to be embedded and extended +as part of the PocketBase app executable (hence the `dist` directory and `embed.go` file). + +> [!WARNING] +> The UI kit and extension APIs remains deliberately undocumented for the time being until a stable PocketBase release is published ([#7612](https://github.com/pocketbase/pocketbase/discussions/7612)). ## Development -Download the repo and run the appropriate console commands: +Download the repository and run the appropriate console commands: ```sh # install dependencies npm install -# start a dev server with hot reload at localhost:3000 +# start a dev server with hot reload at localhost:5173 npm run dev # or generate production ready bundle in dist/ directory diff --git a/ui/dist/assets/AuthMethodsDocs-CoFGCgbc.js b/ui/dist/assets/AuthMethodsDocs-CoFGCgbc.js deleted file mode 100644 index 6a59d7ff..00000000 --- a/ui/dist/assets/AuthMethodsDocs-CoFGCgbc.js +++ /dev/null @@ -1,39 +0,0 @@ -import{S as Ce,i as Be,s as Te,V as Le,X as J,h as u,d as ae,t as Q,a as G,I as N,Z as we,_ as Se,C as De,$ as Re,D as Ue,l as d,n as a,m as ne,u as c,A as y,v as k,c as ie,w as h,p as oe,J as je,k as O,o as qe,W as Ee}from"./index-DMlPjiFP.js";import{F as Fe}from"./FieldsQueryParam-B36GF025.js";function ye(n,s,l){const o=n.slice();return o[8]=s[l],o}function Me(n,s,l){const o=n.slice();return o[8]=s[l],o}function Ae(n,s){let l,o=s[8].code+"",p,b,i,f;function m(){return s[6](s[8])}return{key:n,first:null,c(){l=c("button"),p=y(o),b=k(),h(l,"class","tab-item"),O(l,"active",s[1]===s[8].code),this.first=l},m(v,$){d(v,l,$),a(l,p),a(l,b),i||(f=qe(l,"click",m),i=!0)},p(v,$){s=v,$&4&&o!==(o=s[8].code+"")&&N(p,o),$&6&&O(l,"active",s[1]===s[8].code)},d(v){v&&u(l),i=!1,f()}}}function Pe(n,s){let l,o,p,b;return o=new Ee({props:{content:s[8].body}}),{key:n,first:null,c(){l=c("div"),ie(o.$$.fragment),p=k(),h(l,"class","tab-item"),O(l,"active",s[1]===s[8].code),this.first=l},m(i,f){d(i,l,f),ne(o,l,null),a(l,p),b=!0},p(i,f){s=i;const m={};f&4&&(m.content=s[8].body),o.$set(m),(!b||f&6)&&O(l,"active",s[1]===s[8].code)},i(i){b||(G(o.$$.fragment,i),b=!0)},o(i){Q(o.$$.fragment,i),b=!1},d(i){i&&u(l),ae(o)}}}function He(n){var ke,ge;let s,l,o=n[0].name+"",p,b,i,f,m,v,$,g=n[0].name+"",V,ce,W,M,X,L,Z,A,E,re,F,S,ue,z,H=n[0].name+"",K,de,Y,D,x,P,ee,fe,te,T,le,R,se,C,U,w=[],me=new Map,pe,j,_=[],be=new Map,B;M=new Le({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${n[3]}'); - - ... - - const result = await pb.collection('${(ke=n[0])==null?void 0:ke.name}').listAuthMethods(); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${n[3]}'); - - ... - - final result = await pb.collection('${(ge=n[0])==null?void 0:ge.name}').listAuthMethods(); - `}}),T=new Fe({});let I=J(n[2]);const he=e=>e[8].code;for(let e=0;ee[8].code;for(let e=0;eParam Type Description',fe=k(),te=c("tbody"),ie(T.$$.fragment),le=k(),R=c("div"),R.textContent="Responses",se=k(),C=c("div"),U=c("div");for(let e=0;el(1,b=g.code);return n.$$set=g=>{"collection"in g&&l(0,p=g.collection)},n.$$.update=()=>{n.$$.dirty&48&&l(2,i=[{code:200,body:m?"...":JSON.stringify(f,null,2)},{code:404,body:` - { - "status": 404, - "message": "Missing collection context.", - "data": {} - } - `}])},l(3,o=je.getApiExampleUrl(oe.baseURL)),[p,b,i,o,f,m,$]}class Ge extends Ce{constructor(s){super(),Be(this,s,Ie,He,Te,{collection:0})}}export{Ge as default}; diff --git a/ui/dist/assets/AuthRefreshDocs-CQwCsEss.js b/ui/dist/assets/AuthRefreshDocs-CQwCsEss.js deleted file mode 100644 index 15018b48..00000000 --- a/ui/dist/assets/AuthRefreshDocs-CQwCsEss.js +++ /dev/null @@ -1,79 +0,0 @@ -import{S as je,i as xe,s as Ie,V as Ke,W as Ue,X as I,h as d,d as K,t as E,a as z,I as de,Z as Oe,_ as Qe,C as We,$ as Xe,D as Ze,l as u,n as o,m as Q,u as s,A as k,v as p,c as W,w as b,J as Ve,p as Ge,k as X,o as Ye}from"./index-DMlPjiFP.js";import{F as et}from"./FieldsQueryParam-B36GF025.js";function Ee(r,a,l){const n=r.slice();return n[5]=a[l],n}function ze(r,a,l){const n=r.slice();return n[5]=a[l],n}function Je(r,a){let l,n=a[5].code+"",m,_,i,h;function g(){return a[4](a[5])}return{key:r,first:null,c(){l=s("button"),m=k(n),_=p(),b(l,"class","tab-item"),X(l,"active",a[1]===a[5].code),this.first=l},m(v,w){u(v,l,w),o(l,m),o(l,_),i||(h=Ye(l,"click",g),i=!0)},p(v,w){a=v,w&4&&n!==(n=a[5].code+"")&&de(m,n),w&6&&X(l,"active",a[1]===a[5].code)},d(v){v&&d(l),i=!1,h()}}}function Ne(r,a){let l,n,m,_;return n=new Ue({props:{content:a[5].body}}),{key:r,first:null,c(){l=s("div"),W(n.$$.fragment),m=p(),b(l,"class","tab-item"),X(l,"active",a[1]===a[5].code),this.first=l},m(i,h){u(i,l,h),Q(n,l,null),o(l,m),_=!0},p(i,h){a=i;const g={};h&4&&(g.content=a[5].body),n.$set(g),(!_||h&6)&&X(l,"active",a[1]===a[5].code)},i(i){_||(z(n.$$.fragment,i),_=!0)},o(i){E(n.$$.fragment,i),_=!1},d(i){i&&d(l),K(n)}}}function tt(r){var qe,Fe;let a,l,n=r[0].name+"",m,_,i,h,g,v,w,D,Z,S,J,ue,N,M,pe,G,U=r[0].name+"",Y,he,fe,j,ee,q,te,T,oe,be,F,C,ae,me,le,_e,f,ke,P,ge,ve,$e,se,ye,ne,Se,we,Te,re,Ce,Re,A,ie,H,ce,R,L,y=[],Pe=new Map,Ae,O,$=[],Be=new Map,B;v=new Ke({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${r[3]}'); - - ... - - const authData = await pb.collection('${(qe=r[0])==null?void 0:qe.name}').authRefresh(); - - // after the above you can also access the refreshed auth data from the authStore - console.log(pb.authStore.isValid); - console.log(pb.authStore.token); - console.log(pb.authStore.record.id); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${r[3]}'); - - ... - - final authData = await pb.collection('${(Fe=r[0])==null?void 0:Fe.name}').authRefresh(); - - // after the above you can also access the refreshed auth data from the authStore - print(pb.authStore.isValid); - print(pb.authStore.token); - print(pb.authStore.record.id); - `}}),P=new Ue({props:{content:"?expand=relField1,relField2.subRelField"}}),A=new et({props:{prefix:"record."}});let x=I(r[2]);const De=e=>e[5].code;for(let e=0;ee[5].code;for(let e=0;eReturns a new auth response (token and record data) for an - already authenticated record.

This method is usually called by users on page/screen reload to ensure that the previously stored data - in pb.authStore is still valid and up-to-date.

`,g=p(),W(v.$$.fragment),w=p(),D=s("h6"),D.textContent="API details",Z=p(),S=s("div"),J=s("strong"),J.textContent="POST",ue=p(),N=s("div"),M=s("p"),pe=k("/api/collections/"),G=s("strong"),Y=k(U),he=k("/auth-refresh"),fe=p(),j=s("p"),j.innerHTML="Requires Authorization:TOKEN header",ee=p(),q=s("div"),q.textContent="Query parameters",te=p(),T=s("table"),oe=s("thead"),oe.innerHTML='Param Type Description',be=p(),F=s("tbody"),C=s("tr"),ae=s("td"),ae.textContent="expand",me=p(),le=s("td"),le.innerHTML='String',_e=p(),f=s("td"),ke=k(`Auto expand record relations. Ex.: - `),W(P.$$.fragment),ge=k(` - Supports up to 6-levels depth nested relations expansion. `),ve=s("br"),$e=k(` - The expanded relations will be appended to the record under the - `),se=s("code"),se.textContent="expand",ye=k(" property (eg. "),ne=s("code"),ne.textContent='"expand": {"relField1": {...}, ...}',Se=k(`). - `),we=s("br"),Te=k(` - Only the relations to which the request user has permissions to `),re=s("strong"),re.textContent="view",Ce=k(" will be expanded."),Re=p(),W(A.$$.fragment),ie=p(),H=s("div"),H.textContent="Responses",ce=p(),R=s("div"),L=s("div");for(let e=0;el(1,_=g.code);return r.$$set=g=>{"collection"in g&&l(0,m=g.collection)},r.$$.update=()=>{r.$$.dirty&1&&l(2,i=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:Ve.dummyCollectionRecord(m)},null,2)},{code:401,body:` - { - "status": 401, - "message": "The request requires valid record authorization token to be set.", - "data": {} - } - `},{code:403,body:` - { - "status": 403, - "message": "The authorized record model is not allowed to perform this action.", - "data": {} - } - `},{code:404,body:` - { - "status": 404, - "message": "Missing auth record context.", - "data": {} - } - `}])},l(3,n=Ve.getApiExampleUrl(Ge.baseURL)),[m,_,i,n,h]}class st extends je{constructor(a){super(),xe(this,a,ot,tt,Ie,{collection:0})}}export{st as default}; diff --git a/ui/dist/assets/AuthWithOAuth2Docs-dZYwc-te.js b/ui/dist/assets/AuthWithOAuth2Docs-dZYwc-te.js deleted file mode 100644 index 46806517..00000000 --- a/ui/dist/assets/AuthWithOAuth2Docs-dZYwc-te.js +++ /dev/null @@ -1,117 +0,0 @@ -import{S as Je,i as xe,s as Ee,V as Ne,W as je,X as Q,h as r,d as Z,t as j,a as J,I as pe,Z as Ue,_ as Ie,C as Qe,$ as Ze,D as ze,l as c,n as a,m as z,u as o,A as _,v as h,c as K,w as p,J as Be,p as Ke,k as X,o as Xe}from"./index-DMlPjiFP.js";import{F as Ge}from"./FieldsQueryParam-B36GF025.js";function Fe(s,l,n){const i=s.slice();return i[5]=l[n],i}function Le(s,l,n){const i=s.slice();return i[5]=l[n],i}function He(s,l){let n,i=l[5].code+"",f,g,d,b;function k(){return l[4](l[5])}return{key:s,first:null,c(){n=o("button"),f=_(i),g=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(v,O){c(v,n,O),a(n,f),a(n,g),d||(b=Xe(n,"click",k),d=!0)},p(v,O){l=v,O&4&&i!==(i=l[5].code+"")&&pe(f,i),O&6&&X(n,"active",l[1]===l[5].code)},d(v){v&&r(n),d=!1,b()}}}function Ve(s,l){let n,i,f,g;return i=new je({props:{content:l[5].body}}),{key:s,first:null,c(){n=o("div"),K(i.$$.fragment),f=h(),p(n,"class","tab-item"),X(n,"active",l[1]===l[5].code),this.first=n},m(d,b){c(d,n,b),z(i,n,null),a(n,f),g=!0},p(d,b){l=d;const k={};b&4&&(k.content=l[5].body),i.$set(k),(!g||b&6)&&X(n,"active",l[1]===l[5].code)},i(d){g||(J(i.$$.fragment,d),g=!0)},o(d){j(i.$$.fragment,d),g=!1},d(d){d&&r(n),Z(i)}}}function Ye(s){let l,n,i=s[0].name+"",f,g,d,b,k,v,O,R,G,A,x,be,E,P,me,Y,N=s[0].name+"",ee,fe,te,M,ae,W,le,U,ne,y,oe,ge,B,S,se,_e,ie,ke,m,ve,C,we,$e,Oe,re,Ae,ce,ye,Se,Te,de,Ce,qe,q,ue,F,he,T,L,$=[],De=new Map,Re,H,w=[],Pe=new Map,D;v=new Ne({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${s[3]}'); - - ... - - // OAuth2 authentication with a single realtime call. - // - // Make sure to register ${s[3]}/api/oauth2-redirect as redirect url. - const authData = await pb.collection('${s[0].name}').authWithOAuth2({ provider: 'google' }); - - // OR authenticate with manual OAuth2 code exchange - // const authData = await pb.collection('${s[0].name}').authWithOAuth2Code(...); - - // after the above you can also access the auth data from the authStore - console.log(pb.authStore.isValid); - console.log(pb.authStore.token); - console.log(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - import 'package:url_launcher/url_launcher.dart'; - - final pb = PocketBase('${s[3]}'); - - ... - - // OAuth2 authentication with a single realtime call. - // - // Make sure to register ${s[3]}/api/oauth2-redirect as redirect url. - final authData = await pb.collection('${s[0].name}').authWithOAuth2('google', (url) async { - await launchUrl(url); - }); - - // OR authenticate with manual OAuth2 code exchange - // final authData = await pb.collection('${s[0].name}').authWithOAuth2Code(...); - - // after the above you can also access the auth data from the authStore - print(pb.authStore.isValid); - print(pb.authStore.token); - print(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `}}),C=new je({props:{content:"?expand=relField1,relField2.subRelField"}}),q=new Ge({props:{prefix:"record."}});let I=Q(s[2]);const Me=e=>e[5].code;for(let e=0;ee[5].code;for(let e=0;eAuthenticate with an OAuth2 provider and returns a new auth token and record data.

For more details please check the - OAuth2 integration documentation - .

`,k=h(),K(v.$$.fragment),O=h(),R=o("h6"),R.textContent="API details",G=h(),A=o("div"),x=o("strong"),x.textContent="POST",be=h(),E=o("div"),P=o("p"),me=_("/api/collections/"),Y=o("strong"),ee=_(N),fe=_("/auth-with-oauth2"),te=h(),M=o("div"),M.textContent="Body Parameters",ae=h(),W=o("table"),W.innerHTML=`Param Type Description
Required provider
String The name of the OAuth2 client provider (eg. "google").
Required code
String The authorization code returned from the initial request.
Required codeVerifier
String The code verifier sent with the initial request as part of the code_challenge.
Required redirectURL
String The redirect url sent with the initial request.
Optional createData
Object

Optional data that will be used when creating the auth record on OAuth2 sign-up.

The created auth record must comply with the same requirements and validations in the - regular create action. -
The data can only be in json, aka. multipart/form-data and files - upload currently are not supported during OAuth2 sign-ups.

`,le=h(),U=o("div"),U.textContent="Query parameters",ne=h(),y=o("table"),oe=o("thead"),oe.innerHTML='Param Type Description',ge=h(),B=o("tbody"),S=o("tr"),se=o("td"),se.textContent="expand",_e=h(),ie=o("td"),ie.innerHTML='String',ke=h(),m=o("td"),ve=_(`Auto expand record relations. Ex.: - `),K(C.$$.fragment),we=_(` - Supports up to 6-levels depth nested relations expansion. `),$e=o("br"),Oe=_(` - The expanded relations will be appended to the record under the - `),re=o("code"),re.textContent="expand",Ae=_(" property (eg. "),ce=o("code"),ce.textContent='"expand": {"relField1": {...}, ...}',ye=_(`). - `),Se=o("br"),Te=_(` - Only the relations to which the request user has permissions to `),de=o("strong"),de.textContent="view",Ce=_(" will be expanded."),qe=h(),K(q.$$.fragment),ue=h(),F=o("div"),F.textContent="Responses",he=h(),T=o("div"),L=o("div");for(let e=0;e<$.length;e+=1)$[e].c();Re=h(),H=o("div");for(let e=0;en(1,g=k.code);return s.$$set=k=>{"collection"in k&&n(0,f=k.collection)},s.$$.update=()=>{s.$$.dirty&1&&n(2,d=[{code:200,body:JSON.stringify({token:"JWT_AUTH_TOKEN",record:Be.dummyCollectionRecord(f),meta:{id:"abc123",name:"John Doe",username:"john.doe",email:"test@example.com",avatarURL:"https://example.com/avatar.png",accessToken:"...",refreshToken:"...",expiry:"2022-01-01 10:00:00.123Z",isNew:!1,rawUser:{}}},null,2)},{code:400,body:` - { - "status": 400, - "message": "An error occurred while submitting the form.", - "data": { - "provider": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}])},n(3,i=Be.getApiExampleUrl(Ke.baseURL)),[f,g,d,i,b]}class lt extends Je{constructor(l){super(),xe(this,l,et,Ye,Ee,{collection:0})}}export{lt as default}; diff --git a/ui/dist/assets/AuthWithOtpDocs-DwGQ2_6Y.js b/ui/dist/assets/AuthWithOtpDocs-DwGQ2_6Y.js deleted file mode 100644 index 24a8c966..00000000 --- a/ui/dist/assets/AuthWithOtpDocs-DwGQ2_6Y.js +++ /dev/null @@ -1,136 +0,0 @@ -import{S as be,i as _e,s as ve,W as ge,X as V,h as b,d as x,t as j,a as J,I as ce,Z as de,_ as je,C as ue,$ as Qe,D as he,l as _,n as s,m as ee,u as d,v as T,A as R,c as te,w as g,J as ke,k as N,o as $e,V as Ke,Y as De,p as Xe,a0 as Me}from"./index-DMlPjiFP.js";import{F as Ze}from"./FieldsQueryParam-B36GF025.js";function Be(a,t,e){const l=a.slice();return l[4]=t[e],l}function Ie(a,t,e){const l=a.slice();return l[4]=t[e],l}function We(a,t){let e,l=t[4].code+"",h,i,c,n;function m(){return t[3](t[4])}return{key:a,first:null,c(){e=d("button"),h=R(l),i=T(),g(e,"class","tab-item"),N(e,"active",t[1]===t[4].code),this.first=e},m(v,C){_(v,e,C),s(e,h),s(e,i),c||(n=$e(e,"click",m),c=!0)},p(v,C){t=v,C&4&&l!==(l=t[4].code+"")&&ce(h,l),C&6&&N(e,"active",t[1]===t[4].code)},d(v){v&&b(e),c=!1,n()}}}function Fe(a,t){let e,l,h,i;return l=new ge({props:{content:t[4].body}}),{key:a,first:null,c(){e=d("div"),te(l.$$.fragment),h=T(),g(e,"class","tab-item"),N(e,"active",t[1]===t[4].code),this.first=e},m(c,n){_(c,e,n),ee(l,e,null),s(e,h),i=!0},p(c,n){t=c;const m={};n&4&&(m.content=t[4].body),l.$set(m),(!i||n&6)&&N(e,"active",t[1]===t[4].code)},i(c){i||(J(l.$$.fragment,c),i=!0)},o(c){j(l.$$.fragment,c),i=!1},d(c){c&&b(e),x(l)}}}function ze(a){let t,e,l,h,i,c,n,m=a[0].name+"",v,C,F,B,I,D,Q,M,U,y,O,q,k,L,Y,A,X,E,o,$,P,z,u,p,S,w,Z,we,Te,Pe,pe,Oe,ye,le,fe,oe,me,G,ae,K=[],Se=new Map,qe,ne,H=[],Ce=new Map,se;P=new ge({props:{content:"?expand=relField1,relField2.subRelField"}}),le=new Ze({props:{prefix:"record."}});let re=V(a[2]);const Ae=r=>r[4].code;for(let r=0;rr[4].code;for(let r=0;rParam Type Description
Required otpId
String The id of the OTP request.
Required password
String The one-time password.',Q=T(),M=d("div"),M.textContent="Query parameters",U=T(),y=d("table"),O=d("thead"),O.innerHTML='Param Type Description',q=T(),k=d("tbody"),L=d("tr"),Y=d("td"),Y.textContent="expand",A=T(),X=d("td"),X.innerHTML='String',E=T(),o=d("td"),$=R(`Auto expand record relations. Ex.: - `),te(P.$$.fragment),z=R(` - Supports up to 6-levels depth nested relations expansion. `),u=d("br"),p=R(` - The expanded relations will be appended to the record under the - `),S=d("code"),S.textContent="expand",w=R(" property (eg. "),Z=d("code"),Z.textContent='"expand": {"relField1": {...}, ...}',we=R(`). - `),Te=d("br"),Pe=R(` - Only the relations to which the request user has permissions to `),pe=d("strong"),pe.textContent="view",Oe=R(" will be expanded."),ye=T(),te(le.$$.fragment),fe=T(),oe=d("div"),oe.textContent="Responses",me=T(),G=d("div"),ae=d("div");for(let r=0;re(1,h=n.code);return a.$$set=n=>{"collection"in n&&e(0,l=n.collection)},a.$$.update=()=>{a.$$.dirty&1&&e(2,i=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:ke.dummyCollectionRecord(l)},null,2)},{code:400,body:` - { - "status": 400, - "message": "Failed to authenticate.", - "data": { - "otpId": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}])},[l,h,i,c]}class xe extends be{constructor(t){super(),_e(this,t,Ge,ze,ve,{collection:0})}}function Ue(a,t,e){const l=a.slice();return l[4]=t[e],l}function He(a,t,e){const l=a.slice();return l[4]=t[e],l}function Le(a,t){let e,l=t[4].code+"",h,i,c,n;function m(){return t[3](t[4])}return{key:a,first:null,c(){e=d("button"),h=R(l),i=T(),g(e,"class","tab-item"),N(e,"active",t[1]===t[4].code),this.first=e},m(v,C){_(v,e,C),s(e,h),s(e,i),c||(n=$e(e,"click",m),c=!0)},p(v,C){t=v,C&4&&l!==(l=t[4].code+"")&&ce(h,l),C&6&&N(e,"active",t[1]===t[4].code)},d(v){v&&b(e),c=!1,n()}}}function Ye(a,t){let e,l,h,i;return l=new ge({props:{content:t[4].body}}),{key:a,first:null,c(){e=d("div"),te(l.$$.fragment),h=T(),g(e,"class","tab-item"),N(e,"active",t[1]===t[4].code),this.first=e},m(c,n){_(c,e,n),ee(l,e,null),s(e,h),i=!0},p(c,n){t=c;const m={};n&4&&(m.content=t[4].body),l.$set(m),(!i||n&6)&&N(e,"active",t[1]===t[4].code)},i(c){i||(J(l.$$.fragment,c),i=!0)},o(c){j(l.$$.fragment,c),i=!1},d(c){c&&b(e),x(l)}}}function et(a){let t,e,l,h,i,c,n,m=a[0].name+"",v,C,F,B,I,D,Q,M,U,y,O,q=[],k=new Map,L,Y,A=[],X=new Map,E,o=V(a[2]);const $=u=>u[4].code;for(let u=0;uu[4].code;for(let u=0;uParam Type Description
Required email
String The auth record email address to send the OTP request (if exists).',Q=T(),M=d("div"),M.textContent="Responses",U=T(),y=d("div"),O=d("div");for(let u=0;ue(1,h=n.code);return a.$$set=n=>{"collection"in n&&e(0,l=n.collection)},e(2,i=[{code:200,body:JSON.stringify({otpId:ke.randomString(15)},null,2)},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "email": { - "code": "validation_is_email", - "message": "Must be a valid email address." - } - } - } - `},{code:429,body:` - { - "status": 429, - "message": "You've send too many OTP requests, please try again later.", - "data": {} - } - `}]),[l,h,i,c]}class lt extends be{constructor(t){super(),_e(this,t,tt,et,ve,{collection:0})}}function Ve(a,t,e){const l=a.slice();return l[5]=t[e],l[7]=e,l}function Je(a,t,e){const l=a.slice();return l[5]=t[e],l[7]=e,l}function Ne(a){let t,e,l,h,i;function c(){return a[4](a[7])}return{c(){t=d("button"),e=d("div"),e.textContent=`${a[5].title}`,l=T(),g(e,"class","txt"),g(t,"class","tab-item"),N(t,"active",a[1]==a[7])},m(n,m){_(n,t,m),s(t,e),s(t,l),h||(i=$e(t,"click",c),h=!0)},p(n,m){a=n,m&2&&N(t,"active",a[1]==a[7])},d(n){n&&b(t),h=!1,i()}}}function Ee(a){let t,e,l,h;var i=a[5].component;function c(n,m){return{props:{collection:n[0]}}}return i&&(e=Me(i,c(a))),{c(){t=d("div"),e&&te(e.$$.fragment),l=T(),g(t,"class","tab-item"),N(t,"active",a[1]==a[7])},m(n,m){_(n,t,m),e&&ee(e,t,null),s(t,l),h=!0},p(n,m){if(i!==(i=n[5].component)){if(e){ue();const v=e;j(v.$$.fragment,1,0,()=>{x(v,1)}),he()}i?(e=Me(i,c(n)),te(e.$$.fragment),J(e.$$.fragment,1),ee(e,t,l)):e=null}else if(i){const v={};m&1&&(v.collection=n[0]),e.$set(v)}(!h||m&2)&&N(t,"active",n[1]==n[7])},i(n){h||(e&&J(e.$$.fragment,n),h=!0)},o(n){e&&j(e.$$.fragment,n),h=!1},d(n){n&&b(t),e&&x(e)}}}function ot(a){var Y,A,X,E;let t,e,l=a[0].name+"",h,i,c,n,m,v,C,F,B,I,D,Q,M,U;v=new Ke({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${a[2]}'); - - ... - - // send OTP email to the provided auth record - const req = await pb.collection('${(Y=a[0])==null?void 0:Y.name}').requestOTP('test@example.com'); - - // ... show a screen/popup to enter the password from the email ... - - // authenticate with the requested OTP id and the email password - const authData = await pb.collection('${(A=a[0])==null?void 0:A.name}').authWithOTP( - req.otpId, - "YOUR_OTP", - ); - - // after the above you can also access the auth data from the authStore - console.log(pb.authStore.isValid); - console.log(pb.authStore.token); - console.log(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${a[2]}'); - - ... - - // send OTP email to the provided auth record - final req = await pb.collection('${(X=a[0])==null?void 0:X.name}').requestOTP('test@example.com'); - - // ... show a screen/popup to enter the password from the email ... - - // authenticate with the requested OTP id and the email password - final authData = await pb.collection('${(E=a[0])==null?void 0:E.name}').authWithOTP( - req.otpId, - "YOUR_OTP", - ); - - // after the above you can also access the auth data from the authStore - print(pb.authStore.isValid); - print(pb.authStore.token); - print(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `}});let y=V(a[3]),O=[];for(let o=0;oj(k[o],1,1,()=>{k[o]=null});return{c(){t=d("h3"),e=R("Auth with OTP ("),h=R(l),i=R(")"),c=T(),n=d("div"),n.innerHTML=`

Authenticate with an one-time password (OTP).

Note that when requesting an OTP we return an otpId even if a user with the provided email - doesn't exist as a very basic enumeration protection.

`,m=T(),te(v.$$.fragment),C=T(),F=d("h6"),F.textContent="API details",B=T(),I=d("div"),D=d("div");for(let o=0;oe(1,c=m);return a.$$set=m=>{"collection"in m&&e(0,h=m.collection)},e(2,l=ke.getApiExampleUrl(Xe.baseURL)),[h,c,l,i,n]}class it extends be{constructor(t){super(),_e(this,t,at,ot,ve,{collection:0})}}export{it as default}; diff --git a/ui/dist/assets/AuthWithPasswordDocs-Dgg678dt.js b/ui/dist/assets/AuthWithPasswordDocs-Dgg678dt.js deleted file mode 100644 index 81db8c89..00000000 --- a/ui/dist/assets/AuthWithPasswordDocs-Dgg678dt.js +++ /dev/null @@ -1,96 +0,0 @@ -import{S as kt,i as gt,s as vt,V as St,X as L,W as _t,h as c,d as ae,Y as wt,t as X,a as Z,I as z,Z as ct,_ as yt,C as $t,$ as Pt,D as Ct,l as d,n as t,m as oe,u as s,A as f,v as u,c as se,w as k,J as dt,p as Rt,k as ne,o as Ot}from"./index-DMlPjiFP.js";import{F as Tt}from"./FieldsQueryParam-B36GF025.js";function pt(i,o,a){const n=i.slice();return n[7]=o[a],n}function ut(i,o,a){const n=i.slice();return n[7]=o[a],n}function ht(i,o,a){const n=i.slice();return n[12]=o[a],n[14]=a,n}function At(i){let o;return{c(){o=f("or")},m(a,n){d(a,o,n)},d(a){a&&c(o)}}}function bt(i){let o,a,n=i[12]+"",m,b=i[14]>0&&At();return{c(){b&&b.c(),o=u(),a=s("strong"),m=f(n)},m(r,h){b&&b.m(r,h),d(r,o,h),d(r,a,h),t(a,m)},p(r,h){h&2&&n!==(n=r[12]+"")&&z(m,n)},d(r){r&&(c(o),c(a)),b&&b.d(r)}}}function ft(i,o){let a,n=o[7].code+"",m,b,r,h;function g(){return o[6](o[7])}return{key:i,first:null,c(){a=s("button"),m=f(n),b=u(),k(a,"class","tab-item"),ne(a,"active",o[2]===o[7].code),this.first=a},m($,_){d($,a,_),t(a,m),t(a,b),r||(h=Ot(a,"click",g),r=!0)},p($,_){o=$,_&8&&n!==(n=o[7].code+"")&&z(m,n),_&12&&ne(a,"active",o[2]===o[7].code)},d($){$&&c(a),r=!1,h()}}}function mt(i,o){let a,n,m,b;return n=new _t({props:{content:o[7].body}}),{key:i,first:null,c(){a=s("div"),se(n.$$.fragment),m=u(),k(a,"class","tab-item"),ne(a,"active",o[2]===o[7].code),this.first=a},m(r,h){d(r,a,h),oe(n,a,null),t(a,m),b=!0},p(r,h){o=r;const g={};h&8&&(g.content=o[7].body),n.$set(g),(!b||h&12)&&ne(a,"active",o[2]===o[7].code)},i(r){b||(Z(n.$$.fragment,r),b=!0)},o(r){X(n.$$.fragment,r),b=!1},d(r){r&&c(a),ae(n)}}}function Dt(i){var ot,st;let o,a,n=i[0].name+"",m,b,r,h,g,$,_,G=i[1].join("/")+"",ie,De,re,We,ce,C,de,q,pe,R,x,Fe,ee,H,Me,ue,te=i[0].name+"",he,Ue,be,Y,fe,O,me,Be,j,T,_e,Le,ke,qe,V,ge,He,ve,Se,E,we,A,ye,Ye,N,D,$e,je,Pe,Ve,v,Ee,M,Ne,Ie,Je,Ce,Qe,Re,Ke,Xe,Ze,Oe,ze,Ge,U,Te,I,Ae,W,J,P=[],xe=new Map,et,Q,w=[],tt=new Map,F;C=new St({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${i[5]}'); - - ... - - const authData = await pb.collection('${(ot=i[0])==null?void 0:ot.name}').authWithPassword( - '${i[4]}', - 'YOUR_PASSWORD', - ); - - // after the above you can also access the auth data from the authStore - console.log(pb.authStore.isValid); - console.log(pb.authStore.token); - console.log(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${i[5]}'); - - ... - - final authData = await pb.collection('${(st=i[0])==null?void 0:st.name}').authWithPassword( - '${i[4]}', - 'YOUR_PASSWORD', - ); - - // after the above you can also access the auth data from the authStore - print(pb.authStore.isValid); - print(pb.authStore.token); - print(pb.authStore.record.id); - - // "logout" - pb.authStore.clear(); - `}});let B=L(i[1]),S=[];for(let e=0;ee[7].code;for(let e=0;ee[7].code;for(let e=0;eParam Type Description',Be=u(),j=s("tbody"),T=s("tr"),_e=s("td"),_e.innerHTML='
Required identity
',Le=u(),ke=s("td"),ke.innerHTML='String',qe=u(),V=s("td");for(let e=0;e
Required password
String The auth record password.',Se=u(),E=s("div"),E.textContent="Query parameters",we=u(),A=s("table"),ye=s("thead"),ye.innerHTML='Param Type Description',Ye=u(),N=s("tbody"),D=s("tr"),$e=s("td"),$e.textContent="expand",je=u(),Pe=s("td"),Pe.innerHTML='String',Ve=u(),v=s("td"),Ee=f(`Auto expand record relations. Ex.: - `),se(M.$$.fragment),Ne=f(` - Supports up to 6-levels depth nested relations expansion. `),Ie=s("br"),Je=f(` - The expanded relations will be appended to the record under the - `),Ce=s("code"),Ce.textContent="expand",Qe=f(" property (eg. "),Re=s("code"),Re.textContent='"expand": {"relField1": {...}, ...}',Ke=f(`). - `),Xe=s("br"),Ze=f(` - Only the relations to which the request user has permissions to `),Oe=s("strong"),Oe.textContent="view",ze=f(" will be expanded."),Ge=u(),se(U.$$.fragment),Te=u(),I=s("div"),I.textContent="Responses",Ae=u(),W=s("div"),J=s("div");for(let e=0;ea(2,h=_.code);return i.$$set=_=>{"collection"in _&&a(0,r=_.collection)},i.$$.update=()=>{var _;i.$$.dirty&1&&a(1,m=((_=r==null?void 0:r.passwordAuth)==null?void 0:_.identityFields)||[]),i.$$.dirty&2&&a(4,b=m.length==0?"NONE":"YOUR_"+m.join("_OR_").toUpperCase()),i.$$.dirty&1&&a(3,g=[{code:200,body:JSON.stringify({token:"JWT_TOKEN",record:dt.dummyCollectionRecord(r)},null,2)},{code:400,body:` - { - "status": 400, - "message": "Failed to authenticate.", - "data": { - "identity": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}])},a(5,n=dt.getApiExampleUrl(Rt.baseURL)),[r,m,h,g,b,n,$]}class Ut extends kt{constructor(o){super(),gt(this,o,Wt,Dt,vt,{collection:0})}}export{Ut as default}; diff --git a/ui/dist/assets/BatchApiDocs-CaJSx-jz.js b/ui/dist/assets/BatchApiDocs-CaJSx-jz.js deleted file mode 100644 index 479f0fef..00000000 --- a/ui/dist/assets/BatchApiDocs-CaJSx-jz.js +++ /dev/null @@ -1,158 +0,0 @@ -import{S as St,i as At,s as Lt,V as Mt,W as Ht,X as Q,h as d,d as Re,t as Y,a as x,I as jt,Z as Pt,_ as Nt,C as Ut,$ as Jt,D as zt,l as u,n as t,m as Te,E as Wt,G as Gt,u as o,A as _,v as i,c as Pe,w as b,J as Ft,p as Kt,k as ee,o as Vt}from"./index-DMlPjiFP.js";function Bt(a,s,n){const c=a.slice();return c[6]=s[n],c}function Et(a,s,n){const c=a.slice();return c[6]=s[n],c}function Ot(a,s){let n,c,y;function f(){return s[5](s[6])}return{key:a,first:null,c(){n=o("button"),n.textContent=`${s[6].code} `,b(n,"class","tab-item"),ee(n,"active",s[1]===s[6].code),this.first=n},m(r,h){u(r,n,h),c||(y=Vt(n,"click",f),c=!0)},p(r,h){s=r,h&10&&ee(n,"active",s[1]===s[6].code)},d(r){r&&d(n),c=!1,y()}}}function It(a,s){let n,c,y,f;return c=new Ht({props:{content:s[6].body}}),{key:a,first:null,c(){n=o("div"),Pe(c.$$.fragment),y=i(),b(n,"class","tab-item"),ee(n,"active",s[1]===s[6].code),this.first=n},m(r,h){u(r,n,h),Te(c,n,null),t(n,y),f=!0},p(r,h){s=r,(!f||h&10)&&ee(n,"active",s[1]===s[6].code)},i(r){f||(x(c.$$.fragment,r),f=!0)},o(r){Y(c.$$.fragment,r),f=!1},d(r){r&&d(n),Re(c)}}}function Xt(a){var pt,mt,bt,ht,ft,_t,yt,kt;let s,n,c=a[0].name+"",y,f,r,h,F,g,U,Fe,P,B,Be,E,Ee,Oe,te,le,w,oe,O,ae,I,se,H,ne,J,ie,q,ce,Ie,re,S,z,He,k,W,Se,de,Ae,D,G,Le,ue,Me,K,je,pe,Ne,C,Ue,me,Je,ze,We,V,Ge,X,Ke,be,Ve,he,Xe,fe,Ze,p,_e,Qe,ye,Ye,ke,xe,$e,et,ge,tt,ve,lt,ot,at,De,st,R,Ce,A,we,T,L,v=[],nt=new Map,it,M,$=[],ct=new Map,j,qe,rt;w=new Mt({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${a[2]}'); - - ... - - const batch = pb.createBatch(); - - batch.collection('${(pt=a[0])==null?void 0:pt.name}').create({ ... }); - batch.collection('${(mt=a[0])==null?void 0:mt.name}').update('RECORD_ID', { ... }); - batch.collection('${(bt=a[0])==null?void 0:bt.name}').delete('RECORD_ID'); - batch.collection('${(ht=a[0])==null?void 0:ht.name}').upsert({ ... }); - - const result = await batch.send(); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${a[2]}'); - - ... - - final batch = pb.createBatch(); - - batch.collection('${(ft=a[0])==null?void 0:ft.name}').create(body: { ... }); - batch.collection('${(_t=a[0])==null?void 0:_t.name}').update('RECORD_ID', body: { ... }); - batch.collection('${(yt=a[0])==null?void 0:yt.name}').delete('RECORD_ID'); - batch.collection('${(kt=a[0])==null?void 0:kt.name}').upsert(body: { ... }); - - final result = await batch.send(); - `}}),R=new Ht({props:{language:"javascript",content:` - const formData = new FormData(); - - formData.append("@jsonPayload", JSON.stringify({ - requests: [ - { - method: "POST", - url: "/api/collections/${a[0].name}/records?fields=id", - body: { someField: "test1" } - }, - { - method: "PATCH", - url: "/api/collections/${a[0].name}/records/RECORD_ID", - body: { someField: "test2" } - } - ] - })) - - // file for the first request - formData.append("requests.0.someFileField", new File(...)) - - // file for the second request - formData.append("requests.1.someFileField", new File(...)) - `}});let Z=Q(a[3]);const dt=e=>e[6].code;for(let e=0;ee[6].code;for(let e=0;eBatch and transactional create/update/upsert/delete of multiple records in a single request.

",F=i(),g=o("div"),U=o("div"),U.innerHTML='',Fe=i(),P=o("div"),B=o("p"),Be=_(`The batch Web API need to be explicitly enabled and configured from the - `),E=o("a"),E.textContent="Dashboard settings",Ee=_("."),Oe=i(),te=o("p"),te.innerHTML=`Because this endpoint process the requests in a single DB transaction it could degrade the - performance of your application if not used with proper care and configuration - (prefer smaller max processing and body size limits, avoid large file uploads over slow S3 - networks and custom hooks that communicate with slow external APIs).`,le=i(),Pe(w.$$.fragment),oe=i(),O=o("h6"),O.textContent="API details",ae=i(),I=o("div"),I.innerHTML='POST
/api/batch
',se=i(),H=o("div"),H.textContent="Body Parameters",ne=i(),J=o("p"),J.innerHTML=`Body parameters could be sent as application/json or multipart/form-data. -
- File upload is supported only via multipart/form-data (see below for more details).`,ie=i(),q=o("table"),ce=o("thead"),ce.innerHTML='Param Description',Ie=i(),re=o("tbody"),S=o("tr"),z=o("td"),z.innerHTML='
Required requests
',He=i(),k=o("td"),W=o("span"),W.textContent="Array",Se=_(` - List of the requests to process. - - `),de=o("p"),de.textContent="The supported batch request actions are:",Ae=i(),D=o("ul"),G=o("li"),Le=_("record create - "),ue=o("code"),ue.textContent="POST /api/collections/{collection}/records",Me=i(),K=o("li"),je=_(`record update - - `),pe=o("code"),pe.textContent="PATCH /api/collections/{collection}/records/{id}",Ne=i(),C=o("li"),Ue=_("record upsert - "),me=o("code"),me.textContent="PUT /api/collections/{collection}/records",Je=i(),ze=o("br"),We=i(),V=o("small"),V.innerHTML='(the body must have id field)',Ge=i(),X=o("li"),Ke=_(`record delete - - `),be=o("code"),be.textContent="DELETE /api/collections/{collection}/records/{id}",Ve=i(),he=o("p"),he.textContent="Each batch Request element have the following properties:",Xe=i(),fe=o("ul"),fe.innerHTML=`
  • url path (could include query parameters)
  • method (GET, POST, PUT, PATCH, DELETE)
  • headers
    (custom per-request Authorization header is not supported at the moment, - aka. all batch requests have the same auth state)
  • body
  • `,Ze=i(),p=o("p"),_e=o("strong"),_e.textContent="NB!",Qe=_(` When the batch request is send as - `),ye=o("code"),ye.textContent="multipart/form-data",Ye=_(`, the regular batch action fields are expected to be - submitted as serialized json under the `),ke=o("code"),ke.textContent="@jsonPayload",xe=_(` field and file keys need - to follow the pattern `),$e=o("code"),$e.textContent="requests.N.fileField",et=_(` or - `),ge=o("code"),ge.textContent="requests[N].fileField",tt=i(),ve=o("em"),ve.textContent=`(this is usually handled transparently by the SDKs when their specific object notation - is used) - `,lt=_(`. - `),ot=o("br"),at=_(` - If you don't use the SDKs or prefer manually to construct the `),De=o("code"),De.textContent="FormData",st=_(` - body, then it could look something like: - `),Pe(R.$$.fragment),Ce=i(),A=o("div"),A.textContent="Responses",we=i(),T=o("div"),L=o("div");for(let e=0;en(1,r=g.code);return a.$$set=g=>{"collection"in g&&n(0,f=g.collection)},a.$$.update=()=>{a.$$.dirty&1&&n(4,y=Ft.dummyCollectionRecord(f)),a.$$.dirty&17&&f!=null&&f.id&&(h.push({code:200,body:JSON.stringify([{status:200,body:y},{status:200,body:Object.assign({},y,{id:y.id+"2"})}],null,2)}),h.push({code:400,body:` - { - "status": 400, - "message": "Batch transaction failed.", - "data": { - "requests": { - "1": { - "code": "batch_request_failed", - "message": "Batch request failed.", - "response": { - "status": 400, - "message": "Failed to create record.", - "data": { - "id": { - "code": "validation_min_text_constraint", - "message": "Must be at least 3 character(s).", - "params": { "min": 3 } - } - } - } - } - } - } - } - `}),h.push({code:403,body:` - { - "status": 403, - "message": "Batch requests are not allowed.", - "data": {} - } - `}))},n(2,c=Ft.getApiExampleUrl(Kt.baseURL)),[f,r,c,h,y,F]}class Yt extends St{constructor(s){super(),At(this,s,Zt,Xt,Lt,{collection:0})}}export{Yt as default}; diff --git a/ui/dist/assets/CodeEditor-BjqGK3BY.js b/ui/dist/assets/CodeEditor-BjqGK3BY.js deleted file mode 100644 index 049b6408..00000000 --- a/ui/dist/assets/CodeEditor-BjqGK3BY.js +++ /dev/null @@ -1,14 +0,0 @@ -import{S as vt,i as jt,s as _t,H as BO,h as Yt,a1 as H,l as Rt,u as zt,w as qt,O as Vt,T as Wt,U as Gt,Q as Ct,J as Ut,y as At}from"./index-DMlPjiFP.js";import{P as Et,N as Mt,w as Lt,D as It,x as YO,T as eO,I as RO,y as Nt,z as D,A as o,L as B,B as K,F as z,G as J,H as zO,J as F,v as U,K as Re,M as ze,O as qe,Q as Ve,R as Dt,U as Bt,V as X,E as R,W as We,X as Kt,Y as Jt,b as A,e as Ft,f as Ht,g as Oa,i as ea,j as ta,k as aa,u as ra,l as ia,m as sa,r as la,n as na,o as oa,c as ca,d as Qa,h as ua,a as pa,s as da,p as ha,C as OO,q as KO}from"./index-Cs_DmB1i.js";var JO={};class iO{constructor(O,a,t,r,s,i,l,n,Q,p=0,c){this.p=O,this.stack=a,this.state=t,this.reducePos=r,this.pos=s,this.score=i,this.buffer=l,this.bufferBase=n,this.curContext=Q,this.lookAhead=p,this.parent=c}toString(){return`[${this.stack.filter((O,a)=>a%3==0).concat(this.state)}]@${this.pos}${this.score?"!"+this.score:""}`}static start(O,a,t=0){let r=O.parser.context;return new iO(O,[],a,t,t,0,[],0,r?new FO(r,r.start):null,0,null)}get context(){return this.curContext?this.curContext.context:null}pushState(O,a){this.stack.push(this.state,a,this.bufferBase+this.buffer.length),this.state=O}reduce(O){var a;let t=O>>19,r=O&65535,{parser:s}=this.p,i=this.reducePos=2e3&&!(!((a=this.p.parser.nodeSet.types[r])===null||a===void 0)&&a.isAnonymous)&&(Q==this.p.lastBigReductionStart?(this.p.bigReductionCount++,this.p.lastBigReductionSize=p):this.p.lastBigReductionSizen;)this.stack.pop();this.reduceContext(r,Q)}storeNode(O,a,t,r=4,s=!1){if(O==0&&(!this.stack.length||this.stack[this.stack.length-1]0&&i.buffer[l-4]==0&&i.buffer[l-1]>-1){if(a==t)return;if(i.buffer[l-2]>=a){i.buffer[l-2]=t;return}}}if(!s||this.pos==t)this.buffer.push(O,a,t,r);else{let i=this.buffer.length;if(i>0&&(this.buffer[i-4]!=0||this.buffer[i-1]<0)){let l=!1;for(let n=i;n>0&&this.buffer[n-2]>t;n-=4)if(this.buffer[n-1]>=0){l=!0;break}if(l)for(;i>0&&this.buffer[i-2]>t;)this.buffer[i]=this.buffer[i-4],this.buffer[i+1]=this.buffer[i-3],this.buffer[i+2]=this.buffer[i-2],this.buffer[i+3]=this.buffer[i-1],i-=4,r>4&&(r-=4)}this.buffer[i]=O,this.buffer[i+1]=a,this.buffer[i+2]=t,this.buffer[i+3]=r}}shift(O,a,t,r){if(O&131072)this.pushState(O&65535,this.pos);else if(O&262144)this.pos=r,this.shiftContext(a,t),a<=this.p.parser.maxNode&&this.buffer.push(a,t,r,4);else{let s=O,{parser:i}=this.p;this.pos=r;let l=i.stateFlag(s,1);!l&&(r>t||a<=i.maxNode)&&(this.reducePos=r),this.pushState(s,l?t:Math.min(t,this.reducePos)),this.shiftContext(a,t),a<=i.maxNode&&this.buffer.push(a,t,r,4)}}apply(O,a,t,r){O&65536?this.reduce(O):this.shift(O,a,t,r)}useNode(O,a){let t=this.p.reused.length-1;(t<0||this.p.reused[t]!=O)&&(this.p.reused.push(O),t++);let r=this.pos;this.reducePos=this.pos=r+O.length,this.pushState(a,r),this.buffer.push(t,r,this.reducePos,-1),this.curContext&&this.updateContext(this.curContext.tracker.reuse(this.curContext.context,O,this,this.p.stream.reset(this.pos-O.length)))}split(){let O=this,a=O.buffer.length;for(;a>0&&O.buffer[a-2]>O.reducePos;)a-=4;let t=O.buffer.slice(a),r=O.bufferBase+a;for(;O&&r==O.bufferBase;)O=O.parent;return new iO(this.p,this.stack.slice(),this.state,this.reducePos,this.pos,this.score,t,r,this.curContext,this.lookAhead,O)}recoverByDelete(O,a){let t=O<=this.p.parser.maxNode;t&&this.storeNode(O,this.pos,a,4),this.storeNode(0,this.pos,a,t?8:4),this.pos=this.reducePos=a,this.score-=190}canShift(O){for(let a=new $a(this);;){let t=this.p.parser.stateSlot(a.state,4)||this.p.parser.hasAction(a.state,O);if(t==0)return!1;if(!(t&65536))return!0;a.reduce(t)}}recoverByInsert(O){if(this.stack.length>=300)return[];let a=this.p.parser.nextStates(this.state);if(a.length>8||this.stack.length>=120){let r=[];for(let s=0,i;sn&1&&l==i)||r.push(a[s],i)}a=r}let t=[];for(let r=0;r>19,r=a&65535,s=this.stack.length-t*3;if(s<0||O.getGoto(this.stack[s],r,!1)<0){let i=this.findForcedReduction();if(i==null)return!1;a=i}this.storeNode(0,this.pos,this.pos,4,!0),this.score-=100}return this.reducePos=this.pos,this.reduce(a),!0}findForcedReduction(){let{parser:O}=this.p,a=[],t=(r,s)=>{if(!a.includes(r))return a.push(r),O.allActions(r,i=>{if(!(i&393216))if(i&65536){let l=(i>>19)-s;if(l>1){let n=i&65535,Q=this.stack.length-l*3;if(Q>=0&&O.getGoto(this.stack[Q],n,!1)>=0)return l<<19|65536|n}}else{let l=t(i,s+1);if(l!=null)return l}})};return t(this.state,0)}forceAll(){for(;!this.p.parser.stateFlag(this.state,2);)if(!this.forceReduce()){this.storeNode(0,this.pos,this.pos,4,!0);break}return this}get deadEnd(){if(this.stack.length!=3)return!1;let{parser:O}=this.p;return O.data[O.stateSlot(this.state,1)]==65535&&!O.stateSlot(this.state,4)}restart(){this.storeNode(0,this.pos,this.pos,4,!0),this.state=this.stack[0],this.stack.length=0}sameState(O){if(this.state!=O.state||this.stack.length!=O.stack.length)return!1;for(let a=0;a0&&this.emitLookAhead()}}class FO{constructor(O,a){this.tracker=O,this.context=a,this.hash=O.strict?O.hash(a):0}}class $a{constructor(O){this.start=O,this.state=O.state,this.stack=O.stack,this.base=this.stack.length}reduce(O){let a=O&65535,t=O>>19;t==0?(this.stack==this.start.stack&&(this.stack=this.stack.slice()),this.stack.push(this.state,0,0),this.base+=3):this.base-=(t-1)*3;let r=this.start.p.parser.getGoto(this.stack[this.base-3],a,!0);this.state=r}}class sO{constructor(O,a,t){this.stack=O,this.pos=a,this.index=t,this.buffer=O.buffer,this.index==0&&this.maybeNext()}static create(O,a=O.bufferBase+O.buffer.length){return new sO(O,a,a-O.bufferBase)}maybeNext(){let O=this.stack.parent;O!=null&&(this.index=this.stack.bufferBase-O.bufferBase,this.stack=O,this.buffer=O.buffer)}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}next(){this.index-=4,this.pos-=4,this.index==0&&this.maybeNext()}fork(){return new sO(this.stack,this.pos,this.index)}}function L(e,O=Uint16Array){if(typeof e!="string")return e;let a=null;for(let t=0,r=0;t=92&&i--,i>=34&&i--;let n=i-32;if(n>=46&&(n-=46,l=!0),s+=n,l)break;s*=46}a?a[r++]=s:a=new O(s)}return a}class tO{constructor(){this.start=-1,this.value=-1,this.end=-1,this.extended=-1,this.lookAhead=0,this.mask=0,this.context=0}}const HO=new tO;class fa{constructor(O,a){this.input=O,this.ranges=a,this.chunk="",this.chunkOff=0,this.chunk2="",this.chunk2Pos=0,this.next=-1,this.token=HO,this.rangeIndex=0,this.pos=this.chunkPos=a[0].from,this.range=a[0],this.end=a[a.length-1].to,this.readNext()}resolveOffset(O,a){let t=this.range,r=this.rangeIndex,s=this.pos+O;for(;st.to:s>=t.to;){if(r==this.ranges.length-1)return null;let i=this.ranges[++r];s+=i.from-t.to,t=i}return s}clipPos(O){if(O>=this.range.from&&OO)return Math.max(O,a.from);return this.end}peek(O){let a=this.chunkOff+O,t,r;if(a>=0&&a=this.chunk2Pos&&tl.to&&(this.chunk2=this.chunk2.slice(0,l.to-t)),r=this.chunk2.charCodeAt(0)}}return t>=this.token.lookAhead&&(this.token.lookAhead=t+1),r}acceptToken(O,a=0){let t=a?this.resolveOffset(a,-1):this.pos;if(t==null||t=this.chunk2Pos&&this.posthis.range.to?O.slice(0,this.range.to-this.pos):O,this.chunkPos=this.pos,this.chunkOff=0}}readNext(){return this.chunkOff>=this.chunk.length&&(this.getChunk(),this.chunkOff==this.chunk.length)?this.next=-1:this.next=this.chunk.charCodeAt(this.chunkOff)}advance(O=1){for(this.chunkOff+=O;this.pos+O>=this.range.to;){if(this.rangeIndex==this.ranges.length-1)return this.setDone();O-=this.range.to-this.pos,this.range=this.ranges[++this.rangeIndex],this.pos=this.range.from}return this.pos+=O,this.pos>=this.token.lookAhead&&(this.token.lookAhead=this.pos+1),this.readNext()}setDone(){return this.pos=this.chunkPos=this.end,this.range=this.ranges[this.rangeIndex=this.ranges.length-1],this.chunk="",this.next=-1}reset(O,a){if(a?(this.token=a,a.start=O,a.lookAhead=O+1,a.value=a.extended=-1):this.token=HO,this.pos!=O){if(this.pos=O,O==this.end)return this.setDone(),this;for(;O=this.range.to;)this.range=this.ranges[++this.rangeIndex];O>=this.chunkPos&&O=this.chunkPos&&a<=this.chunkPos+this.chunk.length)return this.chunk.slice(O-this.chunkPos,a-this.chunkPos);if(O>=this.chunk2Pos&&a<=this.chunk2Pos+this.chunk2.length)return this.chunk2.slice(O-this.chunk2Pos,a-this.chunk2Pos);if(O>=this.range.from&&a<=this.range.to)return this.input.read(O,a);let t="";for(let r of this.ranges){if(r.from>=a)break;r.to>O&&(t+=this.input.read(Math.max(r.from,O),Math.min(r.to,a)))}return t}}class V{constructor(O,a){this.data=O,this.id=a}token(O,a){let{parser:t}=a.p;Ge(this.data,O,a,this.id,t.data,t.tokenPrecTable)}}V.prototype.contextual=V.prototype.fallback=V.prototype.extend=!1;class lO{constructor(O,a,t){this.precTable=a,this.elseToken=t,this.data=typeof O=="string"?L(O):O}token(O,a){let t=O.pos,r=0;for(;;){let s=O.next<0,i=O.resolveOffset(1,1);if(Ge(this.data,O,a,0,this.data,this.precTable),O.token.value>-1)break;if(this.elseToken==null)return;if(s||r++,i==null)break;O.reset(i,O.token)}r&&(O.reset(t,O.token),O.acceptToken(this.elseToken,r))}}lO.prototype.contextual=V.prototype.fallback=V.prototype.extend=!1;class b{constructor(O,a={}){this.token=O,this.contextual=!!a.contextual,this.fallback=!!a.fallback,this.extend=!!a.extend}}function Ge(e,O,a,t,r,s){let i=0,l=1<0){let h=e[u];if(n.allows(h)&&(O.token.value==-1||O.token.value==h||ma(h,O.token.value,r,s))){O.acceptToken(h);break}}let p=O.next,c=0,$=e[i+2];if(O.next<0&&$>c&&e[Q+$*3-3]==65535){i=e[Q+$*3-1];continue O}for(;c<$;){let u=c+$>>1,h=Q+u+(u<<1),m=e[h],g=e[h+1]||65536;if(p=g)c=u+1;else{i=e[h+2],O.advance();continue O}}break}}function Oe(e,O,a){for(let t=O,r;(r=e[t])!=65535;t++)if(r==a)return t-O;return-1}function ma(e,O,a,t){let r=Oe(a,t,O);return r<0||Oe(a,t,e)O)&&!t.type.isError)return a<0?Math.max(0,Math.min(t.to-1,O-25)):Math.min(e.length,Math.max(t.from+1,O+25));if(a<0?t.prevSibling():t.nextSibling())break;if(!t.parent())return a<0?0:e.length}}class ga{constructor(O,a){this.fragments=O,this.nodeSet=a,this.i=0,this.fragment=null,this.safeFrom=-1,this.safeTo=-1,this.trees=[],this.start=[],this.index=[],this.nextFragment()}nextFragment(){let O=this.fragment=this.i==this.fragments.length?null:this.fragments[this.i++];if(O){for(this.safeFrom=O.openStart?ee(O.tree,O.from+O.offset,1)-O.offset:O.from,this.safeTo=O.openEnd?ee(O.tree,O.to+O.offset,-1)-O.offset:O.to;this.trees.length;)this.trees.pop(),this.start.pop(),this.index.pop();this.trees.push(O.tree),this.start.push(-O.offset),this.index.push(0),this.nextStart=this.safeFrom}else this.nextStart=1e9}nodeAt(O){if(OO)return this.nextStart=i,null;if(s instanceof eO){if(i==O){if(i=Math.max(this.safeFrom,O)&&(this.trees.push(s),this.start.push(i),this.index.push(0))}else this.index[a]++,this.nextStart=i+s.length}}}class Pa{constructor(O,a){this.stream=a,this.tokens=[],this.mainToken=null,this.actions=[],this.tokens=O.tokenizers.map(t=>new tO)}getActions(O){let a=0,t=null,{parser:r}=O.p,{tokenizers:s}=r,i=r.stateSlot(O.state,3),l=O.curContext?O.curContext.hash:0,n=0;for(let Q=0;Qc.end+25&&(n=Math.max(c.lookAhead,n)),c.value!=0)){let $=a;if(c.extended>-1&&(a=this.addActions(O,c.extended,c.end,a)),a=this.addActions(O,c.value,c.end,a),!p.extend&&(t=c,a>$))break}}for(;this.actions.length>a;)this.actions.pop();return n&&O.setLookAhead(n),!t&&O.pos==this.stream.end&&(t=new tO,t.value=O.p.parser.eofTerm,t.start=t.end=O.pos,a=this.addActions(O,t.value,t.end,a)),this.mainToken=t,this.actions}getMainToken(O){if(this.mainToken)return this.mainToken;let a=new tO,{pos:t,p:r}=O;return a.start=t,a.end=Math.min(t+1,r.stream.end),a.value=t==r.stream.end?r.parser.eofTerm:0,a}updateCachedToken(O,a,t){let r=this.stream.clipPos(t.pos);if(a.token(this.stream.reset(r,O),t),O.value>-1){let{parser:s}=t.p;for(let i=0;i=0&&t.p.parser.dialect.allows(l>>1)){l&1?O.extended=l>>1:O.value=l>>1;break}}}else O.value=0,O.end=this.stream.clipPos(r+1)}putAction(O,a,t,r){for(let s=0;sO.bufferLength*4?new ga(t,O.nodeSet):null}get parsedPos(){return this.minStackPos}advance(){let O=this.stacks,a=this.minStackPos,t=this.stacks=[],r,s;if(this.bigReductionCount>300&&O.length==1){let[i]=O;for(;i.forceReduce()&&i.stack.length&&i.stack[i.stack.length-2]>=this.lastBigReductionStart;);this.bigReductionCount=this.lastBigReductionSize=0}for(let i=0;ia)t.push(l);else{if(this.advanceStack(l,t,O))continue;{r||(r=[],s=[]),r.push(l);let n=this.tokens.getMainToken(l);s.push(n.value,n.end)}}break}}if(!t.length){let i=r&&Xa(r);if(i)return k&&console.log("Finish with "+this.stackID(i)),this.stackToTree(i);if(this.parser.strict)throw k&&r&&console.log("Stuck with token "+(this.tokens.mainToken?this.parser.getName(this.tokens.mainToken.value):"none")),new SyntaxError("No parse at "+a);this.recovering||(this.recovering=5)}if(this.recovering&&r){let i=this.stoppedAt!=null&&r[0].pos>this.stoppedAt?r[0]:this.runRecovery(r,s,t);if(i)return k&&console.log("Force-finish "+this.stackID(i)),this.stackToTree(i.forceAll())}if(this.recovering){let i=this.recovering==1?1:this.recovering*3;if(t.length>i)for(t.sort((l,n)=>n.score-l.score);t.length>i;)t.pop();t.some(l=>l.reducePos>a)&&this.recovering--}else if(t.length>1){O:for(let i=0;i500&&Q.buffer.length>500)if((l.score-Q.score||l.buffer.length-Q.buffer.length)>0)t.splice(n--,1);else{t.splice(i--,1);continue O}}}t.length>12&&(t.sort((i,l)=>l.score-i.score),t.splice(12,t.length-12))}this.minStackPos=t[0].pos;for(let i=1;i ":"";if(this.stoppedAt!=null&&r>this.stoppedAt)return O.forceReduce()?O:null;if(this.fragments){let Q=O.curContext&&O.curContext.tracker.strict,p=Q?O.curContext.hash:0;for(let c=this.fragments.nodeAt(r);c;){let $=this.parser.nodeSet.types[c.type.id]==c.type?s.getGoto(O.state,c.type.id):-1;if($>-1&&c.length&&(!Q||(c.prop(YO.contextHash)||0)==p))return O.useNode(c,$),k&&console.log(i+this.stackID(O)+` (via reuse of ${s.getName(c.type.id)})`),!0;if(!(c instanceof eO)||c.children.length==0||c.positions[0]>0)break;let u=c.children[0];if(u instanceof eO&&c.positions[0]==0)c=u;else break}}let l=s.stateSlot(O.state,4);if(l>0)return O.reduce(l),k&&console.log(i+this.stackID(O)+` (via always-reduce ${s.getName(l&65535)})`),!0;if(O.stack.length>=8400)for(;O.stack.length>6e3&&O.forceReduce(););let n=this.tokens.getActions(O);for(let Q=0;Qr?a.push(h):t.push(h)}return!1}advanceFully(O,a){let t=O.pos;for(;;){if(!this.advanceStack(O,null,null))return!1;if(O.pos>t)return te(O,a),!0}}runRecovery(O,a,t){let r=null,s=!1;for(let i=0;i ":"";if(l.deadEnd&&(s||(s=!0,l.restart(),k&&console.log(p+this.stackID(l)+" (restarted)"),this.advanceFully(l,t))))continue;let c=l.split(),$=p;for(let u=0;u<10&&c.forceReduce()&&(k&&console.log($+this.stackID(c)+" (via force-reduce)"),!this.advanceFully(c,t));u++)k&&($=this.stackID(c)+" -> ");for(let u of l.recoverByInsert(n))k&&console.log(p+this.stackID(u)+" (via recover-insert)"),this.advanceFully(u,t);this.stream.end>l.pos?(Q==l.pos&&(Q++,n=0),l.recoverByDelete(n,Q),k&&console.log(p+this.stackID(l)+` (via recover-delete ${this.parser.getName(n)})`),te(l,t)):(!r||r.scoree;class Ce{constructor(O){this.start=O.start,this.shift=O.shift||dO,this.reduce=O.reduce||dO,this.reuse=O.reuse||dO,this.hash=O.hash||(()=>0),this.strict=O.strict!==!1}}class j extends Et{constructor(O){if(super(),this.wrappers=[],O.version!=14)throw new RangeError(`Parser version (${O.version}) doesn't match runtime version (14)`);let a=O.nodeNames.split(" ");this.minRepeatTerm=a.length;for(let l=0;lO.topRules[l][1]),r=[];for(let l=0;l=0)s(p,n,l[Q++]);else{let c=l[Q+-p];for(let $=-p;$>0;$--)s(l[Q++],n,c);Q++}}}this.nodeSet=new Mt(a.map((l,n)=>Lt.define({name:n>=this.minRepeatTerm?void 0:l,id:n,props:r[n],top:t.indexOf(n)>-1,error:n==0,skipped:O.skippedNodes&&O.skippedNodes.indexOf(n)>-1}))),O.propSources&&(this.nodeSet=this.nodeSet.extend(...O.propSources)),this.strict=!1,this.bufferLength=It;let i=L(O.tokenData);this.context=O.context,this.specializerSpecs=O.specialized||[],this.specialized=new Uint16Array(this.specializerSpecs.length);for(let l=0;ltypeof l=="number"?new V(i,l):l),this.topRules=O.topRules,this.dialects=O.dialects||{},this.dynamicPrecedences=O.dynamicPrecedences||null,this.tokenPrecTable=O.tokenPrec,this.termNames=O.termNames||null,this.maxNode=this.nodeSet.types.length-1,this.dialect=this.parseDialect(),this.top=this.topRules[Object.keys(this.topRules)[0]]}createParse(O,a,t){let r=new Sa(this,O,a,t);for(let s of this.wrappers)r=s(r,O,a,t);return r}getGoto(O,a,t=!1){let r=this.goto;if(a>=r[0])return-1;for(let s=r[a+1];;){let i=r[s++],l=i&1,n=r[s++];if(l&&t)return n;for(let Q=s+(i>>1);s0}validAction(O,a){return!!this.allActions(O,t=>t==a?!0:null)}allActions(O,a){let t=this.stateSlot(O,4),r=t?a(t):void 0;for(let s=this.stateSlot(O,1);r==null;s+=3){if(this.data[s]==65535)if(this.data[s+1]==1)s=v(this.data,s+2);else break;r=a(v(this.data,s+1))}return r}nextStates(O){let a=[];for(let t=this.stateSlot(O,1);;t+=3){if(this.data[t]==65535)if(this.data[t+1]==1)t=v(this.data,t+2);else break;if(!(this.data[t+2]&1)){let r=this.data[t+1];a.some((s,i)=>i&1&&s==r)||a.push(this.data[t],r)}}return a}configure(O){let a=Object.assign(Object.create(j.prototype),this);if(O.props&&(a.nodeSet=this.nodeSet.extend(...O.props)),O.top){let t=this.topRules[O.top];if(!t)throw new RangeError(`Invalid top rule name ${O.top}`);a.top=t}return O.tokenizers&&(a.tokenizers=this.tokenizers.map(t=>{let r=O.tokenizers.find(s=>s.from==t);return r?r.to:t})),O.specializers&&(a.specializers=this.specializers.slice(),a.specializerSpecs=this.specializerSpecs.map((t,r)=>{let s=O.specializers.find(l=>l.from==t.external);if(!s)return t;let i=Object.assign(Object.assign({},t),{external:s.to});return a.specializers[r]=ae(i),i})),O.contextTracker&&(a.context=O.contextTracker),O.dialect&&(a.dialect=this.parseDialect(O.dialect)),O.strict!=null&&(a.strict=O.strict),O.wrap&&(a.wrappers=a.wrappers.concat(O.wrap)),O.bufferLength!=null&&(a.bufferLength=O.bufferLength),a}hasWrappers(){return this.wrappers.length>0}getName(O){return this.termNames?this.termNames[O]:String(O<=this.maxNode&&this.nodeSet.types[O].name||O)}get eofTerm(){return this.maxNode+1}get topNode(){return this.nodeSet.types[this.top[1]]}dynamicPrecedence(O){let a=this.dynamicPrecedences;return a==null?0:a[O]||0}parseDialect(O){let a=Object.keys(this.dialects),t=a.map(()=>!1);if(O)for(let s of O.split(" ")){let i=a.indexOf(s);i>=0&&(t[i]=!0)}let r=null;for(let s=0;st)&&a.p.parser.stateFlag(a.state,2)&&(!O||O.scoree.external(a,t)<<1|O}return e.get}const ba=55,ka=1,xa=56,ya=2,Ta=57,wa=3,re=4,va=5,qO=6,Ue=7,Ae=8,Ee=9,Me=10,ja=11,_a=12,Ya=13,hO=58,Ra=14,za=15,ie=59,Le=21,qa=23,Ie=24,Va=25,kO=27,Ne=28,Wa=29,Ga=32,Ca=35,Ua=37,Aa=38,Ea=0,Ma=1,La={area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},Ia={dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},se={dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}};function Na(e){return e==45||e==46||e==58||e>=65&&e<=90||e==95||e>=97&&e<=122||e>=161}let le=null,ne=null,oe=0;function xO(e,O){let a=e.pos+O;if(oe==a&&ne==e)return le;let t=e.peek(O),r="";for(;Na(t);)r+=String.fromCharCode(t),t=e.peek(++O);return ne=e,oe=a,le=r?r.toLowerCase():t==Da||t==Ba?void 0:null}const De=60,nO=62,VO=47,Da=63,Ba=33,Ka=45;function ce(e,O){this.name=e,this.parent=O}const Ja=[qO,Me,Ue,Ae,Ee],Fa=new Ce({start:null,shift(e,O,a,t){return Ja.indexOf(O)>-1?new ce(xO(t,1)||"",e):e},reduce(e,O){return O==Le&&e?e.parent:e},reuse(e,O,a,t){let r=O.type.id;return r==qO||r==Ua?new ce(xO(t,1)||"",e):e},strict:!1}),Ha=new b((e,O)=>{if(e.next!=De){e.next<0&&O.context&&e.acceptToken(hO);return}e.advance();let a=e.next==VO;a&&e.advance();let t=xO(e,0);if(t===void 0)return;if(!t)return e.acceptToken(a?za:Ra);let r=O.context?O.context.name:null;if(a){if(t==r)return e.acceptToken(ja);if(r&&Ia[r])return e.acceptToken(hO,-2);if(O.dialectEnabled(Ea))return e.acceptToken(_a);for(let s=O.context;s;s=s.parent)if(s.name==t)return;e.acceptToken(Ya)}else{if(t=="script")return e.acceptToken(Ue);if(t=="style")return e.acceptToken(Ae);if(t=="textarea")return e.acceptToken(Ee);if(La.hasOwnProperty(t))return e.acceptToken(Me);r&&se[r]&&se[r][t]?e.acceptToken(hO,-1):e.acceptToken(qO)}},{contextual:!0}),Or=new b(e=>{for(let O=0,a=0;;a++){if(e.next<0){a&&e.acceptToken(ie);break}if(e.next==Ka)O++;else if(e.next==nO&&O>=2){a>=3&&e.acceptToken(ie,-2);break}else O=0;e.advance()}});function er(e){for(;e;e=e.parent)if(e.name=="svg"||e.name=="math")return!0;return!1}const tr=new b((e,O)=>{if(e.next==VO&&e.peek(1)==nO){let a=O.dialectEnabled(Ma)||er(O.context);e.acceptToken(a?va:re,2)}else e.next==nO&&e.acceptToken(re,1)});function WO(e,O,a){let t=2+e.length;return new b(r=>{for(let s=0,i=0,l=0;;l++){if(r.next<0){l&&r.acceptToken(O);break}if(s==0&&r.next==De||s==1&&r.next==VO||s>=2&&si?r.acceptToken(O,-i):r.acceptToken(a,-(i-2));break}else if((r.next==10||r.next==13)&&l){r.acceptToken(O,1);break}else s=i=0;r.advance()}})}const ar=WO("script",ba,ka),rr=WO("style",xa,ya),ir=WO("textarea",Ta,wa),sr=D({"Text RawText IncompleteTag IncompleteCloseTag":o.content,"StartTag StartCloseTag SelfClosingEndTag EndTag":o.angleBracket,TagName:o.tagName,"MismatchedCloseTag/TagName":[o.tagName,o.invalid],AttributeName:o.attributeName,"AttributeValue UnquotedAttributeValue":o.attributeValue,Is:o.definitionOperator,"EntityReference CharacterReference":o.character,Comment:o.blockComment,ProcessingInst:o.processingInstruction,DoctypeDecl:o.documentMeta}),lr=j.deserialize({version:14,states:",xOVO!rOOO!ZQ#tO'#CrO!`Q#tO'#C{O!eQ#tO'#DOO!jQ#tO'#DRO!oQ#tO'#DTO!tOaO'#CqO#PObO'#CqO#[OdO'#CqO$kO!rO'#CqOOO`'#Cq'#CqO$rO$fO'#DUO$zQ#tO'#DWO%PQ#tO'#DXOOO`'#Dl'#DlOOO`'#DZ'#DZQVO!rOOO%UQ&rO,59^O%aQ&rO,59gO%lQ&rO,59jO%wQ&rO,59mO&SQ&rO,59oOOOa'#D_'#D_O&_OaO'#CyO&jOaO,59]OOOb'#D`'#D`O&rObO'#C|O&}ObO,59]OOOd'#Da'#DaO'VOdO'#DPO'bOdO,59]OOO`'#Db'#DbO'jO!rO,59]O'qQ#tO'#DSOOO`,59],59]OOOp'#Dc'#DcO'vO$fO,59pOOO`,59p,59pO(OQ#|O,59rO(TQ#|O,59sOOO`-E7X-E7XO(YQ&rO'#CtOOQW'#D['#D[O(hQ&rO1G.xOOOa1G.x1G.xOOO`1G/Z1G/ZO(sQ&rO1G/ROOOb1G/R1G/RO)OQ&rO1G/UOOOd1G/U1G/UO)ZQ&rO1G/XOOO`1G/X1G/XO)fQ&rO1G/ZOOOa-E7]-E7]O)qQ#tO'#CzOOO`1G.w1G.wOOOb-E7^-E7^O)vQ#tO'#C}OOOd-E7_-E7_O){Q#tO'#DQOOO`-E7`-E7`O*QQ#|O,59nOOOp-E7a-E7aOOO`1G/[1G/[OOO`1G/^1G/^OOO`1G/_1G/_O*VQ,UO,59`OOQW-E7Y-E7YOOOa7+$d7+$dOOO`7+$u7+$uOOOb7+$m7+$mOOOd7+$p7+$pOOO`7+$s7+$sO*bQ#|O,59fO*gQ#|O,59iO*lQ#|O,59lOOO`1G/Y1G/YO*qO7[O'#CwO+SOMhO'#CwOOQW1G.z1G.zOOO`1G/Q1G/QOOO`1G/T1G/TOOO`1G/W1G/WOOOO'#D]'#D]O+eO7[O,59cOOQW,59c,59cOOOO'#D^'#D^O+vOMhO,59cOOOO-E7Z-E7ZOOQW1G.}1G.}OOOO-E7[-E7[",stateData:",c~O!_OS~OUSOVPOWQOXROYTO[]O][O^^O_^Oa^Ob^Oc^Od^Oy^O|_O!eZO~OgaO~OgbO~OgcO~OgdO~OgeO~O!XfOPmP![mP~O!YiOQpP![pP~O!ZlORsP![sP~OUSOVPOWQOXROYTOZqO[]O][O^^O_^Oa^Ob^Oc^Od^Oy^O!eZO~O![rO~P#gO!]sO!fuO~OgvO~OgwO~OS|OT}OiyO~OS!POT}OiyO~OS!ROT}OiyO~OS!TOT}OiyO~OS}OT}OiyO~O!XfOPmX![mX~OP!WO![!XO~O!YiOQpX![pX~OQ!ZO![!XO~O!ZlORsX![sX~OR!]O![!XO~O![!XO~P#gOg!_O~O!]sO!f!aO~OS!bO~OS!cO~Oj!dOShXThXihX~OS!fOT!gOiyO~OS!hOT!gOiyO~OS!iOT!gOiyO~OS!jOT!gOiyO~OS!gOT!gOiyO~Og!kO~Og!lO~Og!mO~OS!nO~Ol!qO!a!oO!c!pO~OS!rO~OS!sO~OS!tO~Ob!uOc!uOd!uO!a!wO!b!uO~Ob!xOc!xOd!xO!c!wO!d!xO~Ob!uOc!uOd!uO!a!{O!b!uO~Ob!xOc!xOd!xO!c!{O!d!xO~OT~cbd!ey|!e~",goto:"%q!aPPPPPPPPPPPPPPPPPPPPP!b!hP!nPP!zP!}#Q#T#Z#^#a#g#j#m#s#y!bP!b!bP$P$V$m$s$y%P%V%]%cPPPPPPPP%iX^OX`pXUOX`pezabcde{!O!Q!S!UR!q!dRhUR!XhXVOX`pRkVR!XkXWOX`pRnWR!XnXXOX`pQrXR!XpXYOX`pQ`ORx`Q{aQ!ObQ!QcQ!SdQ!UeZ!e{!O!Q!S!UQ!v!oR!z!vQ!y!pR!|!yQgUR!VgQjVR!YjQmWR![mQpXR!^pQtZR!`tS_O`ToXp",nodeNames:"⚠ StartCloseTag StartCloseTag StartCloseTag EndTag SelfClosingEndTag StartTag StartTag StartTag StartTag StartTag StartCloseTag StartCloseTag StartCloseTag IncompleteTag IncompleteCloseTag Document Text EntityReference CharacterReference InvalidEntity Element OpenTag TagName Attribute AttributeName Is AttributeValue UnquotedAttributeValue ScriptText CloseTag OpenTag StyleText CloseTag OpenTag TextareaText CloseTag OpenTag CloseTag SelfClosingTag Comment ProcessingInst MismatchedCloseTag CloseTag DoctypeDecl",maxTerm:68,context:Fa,nodeProps:[["closedBy",-10,1,2,3,7,8,9,10,11,12,13,"EndTag",6,"EndTag SelfClosingEndTag",-4,22,31,34,37,"CloseTag"],["openedBy",4,"StartTag StartCloseTag",5,"StartTag",-4,30,33,36,38,"OpenTag"],["group",-10,14,15,18,19,20,21,40,41,42,43,"Entity",17,"Entity TextContent",-3,29,32,35,"TextContent Entity"],["isolate",-11,22,30,31,33,34,36,37,38,39,42,43,"ltr",-3,27,28,40,""]],propSources:[sr],skippedNodes:[0],repeatNodeCount:9,tokenData:"!]tw8twx7Sx!P8t!P!Q5u!Q!]8t!]!^/^!^!a7S!a#S8t#S#T;{#T#s8t#s$f5u$f;'S8t;'S;=`>V<%l?Ah8t?Ah?BY5u?BY?Mn8t?MnO5u!Z5zblWOX5uXZ7SZ[5u[^7S^p5uqr5urs7Sst+Ptw5uwx7Sx!]5u!]!^7w!^!a7S!a#S5u#S#T7S#T;'S5u;'S;=`8n<%lO5u!R7VVOp7Sqs7St!]7S!]!^7l!^;'S7S;'S;=`7q<%lO7S!R7qOb!R!R7tP;=`<%l7S!Z8OYlWb!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!Z8qP;=`<%l5u!_8{iiSlWOX5uXZ7SZ[5u[^7S^p5uqr8trs7Sst/^tw8twx7Sx!P8t!P!Q5u!Q!]8t!]!^:j!^!a7S!a#S8t#S#T;{#T#s8t#s$f5u$f;'S8t;'S;=`>V<%l?Ah8t?Ah?BY5u?BY?Mn8t?MnO5u!_:sbiSlWb!ROX+PZ[+P^p+Pqr/^sw/^x!P/^!P!Q+P!Q!^/^!a#S/^#S#T0m#T#s/^#s$f+P$f;'S/^;'S;=`1e<%l?Ah/^?Ah?BY+P?BY?Mn/^?MnO+P!VP<%l?Ah;{?Ah?BY7S?BY?Mn;{?MnO7S!V=dXiSb!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!V>SP;=`<%l;{!_>YP;=`<%l8t!_>dhiSlWOX@OXZAYZ[@O[^AY^p@OqrBwrsAYswBwwxAYx!PBw!P!Q@O!Q!]Bw!]!^/^!^!aAY!a#SBw#S#TE{#T#sBw#s$f@O$f;'SBw;'S;=`HS<%l?AhBw?Ah?BY@O?BY?MnBw?MnO@O!Z@TalWOX@OXZAYZ[@O[^AY^p@Oqr@OrsAYsw@OwxAYx!]@O!]!^Az!^!aAY!a#S@O#S#TAY#T;'S@O;'S;=`Bq<%lO@O!RA]UOpAYq!]AY!]!^Ao!^;'SAY;'S;=`At<%lOAY!RAtOc!R!RAwP;=`<%lAY!ZBRYlWc!ROX+PZ[+P^p+Pqr+Psw+Px!^+P!a#S+P#T;'S+P;'S;=`+t<%lO+P!ZBtP;=`<%l@O!_COhiSlWOX@OXZAYZ[@O[^AY^p@OqrBwrsAYswBwwxAYx!PBw!P!Q@O!Q!]Bw!]!^Dj!^!aAY!a#SBw#S#TE{#T#sBw#s$f@O$f;'SBw;'S;=`HS<%l?AhBw?Ah?BY@O?BY?MnBw?MnO@O!_DsbiSlWc!ROX+PZ[+P^p+Pqr/^sw/^x!P/^!P!Q+P!Q!^/^!a#S/^#S#T0m#T#s/^#s$f+P$f;'S/^;'S;=`1e<%l?Ah/^?Ah?BY+P?BY?Mn/^?MnO+P!VFQbiSOpAYqrE{rsAYswE{wxAYx!PE{!P!QAY!Q!]E{!]!^GY!^!aAY!a#sE{#s$fAY$f;'SE{;'S;=`G|<%l?AhE{?Ah?BYAY?BY?MnE{?MnOAY!VGaXiSc!Rqr0msw0mx!P0m!Q!^0m!a#s0m$f;'S0m;'S;=`1_<%l?Ah0m?BY?Mn0m!VHPP;=`<%lE{!_HVP;=`<%lBw!ZHcW!cxaP!b`Or(trs'ksv(tw!^(t!^!_)e!_;'S(t;'S;=`*P<%lO(t!aIYliSaPlW!b`!dpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx}-_}!OKQ!O!P-_!P!Q$q!Q!^-_!^!_*V!_!a&X!a#S-_#S#T1k#T#s-_#s$f$q$f;'S-_;'S;=`3X<%l?Ah-_?Ah?BY$q?BY?Mn-_?MnO$q!aK_kiSaPlW!b`!dpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx!P-_!P!Q$q!Q!^-_!^!_*V!_!`&X!`!aMS!a#S-_#S#T1k#T#s-_#s$f$q$f;'S-_;'S;=`3X<%l?Ah-_?Ah?BY$q?BY?Mn-_?MnO$q!TM_XaP!b`!dp!fQOr&Xrs&}sv&Xwx(tx!^&X!^!_*V!_;'S&X;'S;=`*y<%lO&X!aNZ!ZiSgQaPlW!b`!dpOX$qXZ&XZ[$q[^&X^p$qpq&Xqr-_rs&}sv-_vw/^wx(tx}-_}!OMz!O!PMz!P!Q$q!Q![Mz![!]Mz!]!^-_!^!_*V!_!a&X!a!c-_!c!}Mz!}#R-_#R#SMz#S#T1k#T#oMz#o#s-_#s$f$q$f$}-_$}%OMz%O%W-_%W%oMz%o%p-_%p&aMz&a&b-_&b1pMz1p4UMz4U4dMz4d4e-_4e$ISMz$IS$I`-_$I`$IbMz$Ib$Je-_$Je$JgMz$Jg$Kh-_$Kh%#tMz%#t&/x-_&/x&EtMz&Et&FV-_&FV;'SMz;'S;:j!#|;:j;=`3X<%l?&r-_?&r?AhMz?Ah?BY$q?BY?MnMz?MnO$q!a!$PP;=`<%lMz!R!$ZY!b`!dpOq*Vqr!$yrs(Vsv*Vwx)ex!a*V!a!b!4t!b;'S*V;'S;=`*s<%lO*V!R!%Q]!b`!dpOr*Vrs(Vsv*Vwx)ex}*V}!O!%y!O!f*V!f!g!']!g#W*V#W#X!0`#X;'S*V;'S;=`*s<%lO*V!R!&QX!b`!dpOr*Vrs(Vsv*Vwx)ex}*V}!O!&m!O;'S*V;'S;=`*s<%lO*V!R!&vV!b`!dp!ePOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!'dX!b`!dpOr*Vrs(Vsv*Vwx)ex!q*V!q!r!(P!r;'S*V;'S;=`*s<%lO*V!R!(WX!b`!dpOr*Vrs(Vsv*Vwx)ex!e*V!e!f!(s!f;'S*V;'S;=`*s<%lO*V!R!(zX!b`!dpOr*Vrs(Vsv*Vwx)ex!v*V!v!w!)g!w;'S*V;'S;=`*s<%lO*V!R!)nX!b`!dpOr*Vrs(Vsv*Vwx)ex!{*V!{!|!*Z!|;'S*V;'S;=`*s<%lO*V!R!*bX!b`!dpOr*Vrs(Vsv*Vwx)ex!r*V!r!s!*}!s;'S*V;'S;=`*s<%lO*V!R!+UX!b`!dpOr*Vrs(Vsv*Vwx)ex!g*V!g!h!+q!h;'S*V;'S;=`*s<%lO*V!R!+xY!b`!dpOr!+qrs!,hsv!+qvw!-Swx!.[x!`!+q!`!a!/j!a;'S!+q;'S;=`!0Y<%lO!+qq!,mV!dpOv!,hvx!-Sx!`!,h!`!a!-q!a;'S!,h;'S;=`!.U<%lO!,hP!-VTO!`!-S!`!a!-f!a;'S!-S;'S;=`!-k<%lO!-SP!-kO|PP!-nP;=`<%l!-Sq!-xS!dp|POv(Vx;'S(V;'S;=`(h<%lO(Vq!.XP;=`<%l!,ha!.aX!b`Or!.[rs!-Ssv!.[vw!-Sw!`!.[!`!a!.|!a;'S!.[;'S;=`!/d<%lO!.[a!/TT!b`|POr)esv)ew;'S)e;'S;=`)y<%lO)ea!/gP;=`<%l!.[!R!/sV!b`!dp|POr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!0]P;=`<%l!+q!R!0gX!b`!dpOr*Vrs(Vsv*Vwx)ex#c*V#c#d!1S#d;'S*V;'S;=`*s<%lO*V!R!1ZX!b`!dpOr*Vrs(Vsv*Vwx)ex#V*V#V#W!1v#W;'S*V;'S;=`*s<%lO*V!R!1}X!b`!dpOr*Vrs(Vsv*Vwx)ex#h*V#h#i!2j#i;'S*V;'S;=`*s<%lO*V!R!2qX!b`!dpOr*Vrs(Vsv*Vwx)ex#m*V#m#n!3^#n;'S*V;'S;=`*s<%lO*V!R!3eX!b`!dpOr*Vrs(Vsv*Vwx)ex#d*V#d#e!4Q#e;'S*V;'S;=`*s<%lO*V!R!4XX!b`!dpOr*Vrs(Vsv*Vwx)ex#X*V#X#Y!+q#Y;'S*V;'S;=`*s<%lO*V!R!4{Y!b`!dpOr!4trs!5ksv!4tvw!6Vwx!8]x!a!4t!a!b!:]!b;'S!4t;'S;=`!;r<%lO!4tq!5pV!dpOv!5kvx!6Vx!a!5k!a!b!7W!b;'S!5k;'S;=`!8V<%lO!5kP!6YTO!a!6V!a!b!6i!b;'S!6V;'S;=`!7Q<%lO!6VP!6lTO!`!6V!`!a!6{!a;'S!6V;'S;=`!7Q<%lO!6VP!7QOyPP!7TP;=`<%l!6Vq!7]V!dpOv!5kvx!6Vx!`!5k!`!a!7r!a;'S!5k;'S;=`!8V<%lO!5kq!7yS!dpyPOv(Vx;'S(V;'S;=`(h<%lO(Vq!8YP;=`<%l!5ka!8bX!b`Or!8]rs!6Vsv!8]vw!6Vw!a!8]!a!b!8}!b;'S!8];'S;=`!:V<%lO!8]a!9SX!b`Or!8]rs!6Vsv!8]vw!6Vw!`!8]!`!a!9o!a;'S!8];'S;=`!:V<%lO!8]a!9vT!b`yPOr)esv)ew;'S)e;'S;=`)y<%lO)ea!:YP;=`<%l!8]!R!:dY!b`!dpOr!4trs!5ksv!4tvw!6Vwx!8]x!`!4t!`!a!;S!a;'S!4t;'S;=`!;r<%lO!4t!R!;]V!b`!dpyPOr*Vrs(Vsv*Vwx)ex;'S*V;'S;=`*s<%lO*V!R!;uP;=`<%l!4t!V!{let Q=l.type.id;if(Q==Wa)return $O(l,n,a);if(Q==Ga)return $O(l,n,t);if(Q==Ca)return $O(l,n,r);if(Q==Le&&s.length){let p=l.node,c=p.firstChild,$=c&&Qe(c,n),u;if($){for(let h of s)if(h.tag==$&&(!h.attrs||h.attrs(u||(u=Be(c,n))))){let m=p.lastChild,g=m.type.id==Aa?m.from:p.to;if(g>c.to)return{parser:h.parser,overlay:[{from:c.to,to:g}]}}}}if(i&&Q==Ie){let p=l.node,c;if(c=p.firstChild){let $=i[n.read(c.from,c.to)];if($)for(let u of $){if(u.tagName&&u.tagName!=Qe(p.parent,n))continue;let h=p.lastChild;if(h.type.id==kO){let m=h.from+1,g=h.lastChild,Z=h.to-(g&&g.isError?0:1);if(Z>m)return{parser:u.parser,overlay:[{from:m,to:Z}],bracketed:!0}}else if(h.type.id==Ne)return{parser:u.parser,overlay:[{from:h.from,to:h.to}]}}}}return null})}const nr=135,ue=1,or=136,cr=137,Je=2,Qr=138,ur=3,pr=4,Fe=[9,10,11,12,13,32,133,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288],dr=58,hr=40,He=95,$r=91,aO=45,fr=46,mr=35,gr=37,Pr=38,Sr=92,Zr=10,Xr=42;function I(e){return e>=65&&e<=90||e>=97&&e<=122||e>=161}function GO(e){return e>=48&&e<=57}function pe(e){return GO(e)||e>=97&&e<=102||e>=65&&e<=70}const Ot=(e,O,a)=>(t,r)=>{for(let s=!1,i=0,l=0;;l++){let{next:n}=t;if(I(n)||n==aO||n==He||s&&GO(n))!s&&(n!=aO||l>0)&&(s=!0),i===l&&n==aO&&i++,t.advance();else if(n==Sr&&t.peek(1)!=Zr){if(t.advance(),pe(t.next)){do t.advance();while(pe(t.next));t.next==32&&t.advance()}else t.next>-1&&t.advance();s=!0}else{s&&t.acceptToken(i==2&&r.canShift(Je)?O:n==hr?a:e);break}}},br=new b(Ot(or,Je,cr),{contextual:!0}),kr=new b(Ot(Qr,ur,pr),{contextual:!0}),xr=new b(e=>{if(Fe.includes(e.peek(-1))){let{next:O}=e;(I(O)||O==He||O==mr||O==fr||O==Xr||O==$r||O==dr&&I(e.peek(1))||O==aO||O==Pr)&&e.acceptToken(nr)}}),yr=new b(e=>{if(!Fe.includes(e.peek(-1))){let{next:O}=e;if(O==gr&&(e.advance(),e.acceptToken(ue)),I(O)){do e.advance();while(I(e.next)||GO(e.next));e.acceptToken(ue)}}}),Tr=D({"AtKeyword import charset namespace keyframes media supports font-feature-values":o.definitionKeyword,"from to selector scope MatchFlag":o.keyword,NamespaceName:o.namespace,KeyframeName:o.labelName,KeyframeRangeName:o.operatorKeyword,TagName:o.tagName,ClassName:o.className,PseudoClassName:o.constant(o.className),IdName:o.labelName,"FeatureName PropertyName":o.propertyName,AttributeName:o.attributeName,NumberLiteral:o.number,KeywordQuery:o.keyword,UnaryQueryOp:o.operatorKeyword,"CallTag ValueName FontName":o.atom,VariableName:o.variableName,Callee:o.operatorKeyword,Unit:o.unit,"UniversalSelector NestingSelector":o.definitionOperator,"MatchOp CompareOp":o.compareOperator,"ChildOp SiblingOp, LogicOp":o.logicOperator,BinOp:o.arithmeticOperator,Important:o.modifier,Comment:o.blockComment,ColorLiteral:o.color,"ParenthesizedContent StringLiteral":o.string,":":o.punctuation,"PseudoOp #":o.derefOperator,"; , |":o.separator,"( )":o.paren,"[ ]":o.squareBracket,"{ }":o.brace}),wr={__proto__:null,lang:44,"nth-child":44,"nth-last-child":44,"nth-of-type":44,"nth-last-of-type":44,dir:44,"host-context":44,if:90,url:132,"url-prefix":132,domain:132,regexp:132},vr={__proto__:null,or:104,and:104,not:112,only:112,layer:186},jr={__proto__:null,selector:118,layer:182},_r={__proto__:null,"@import":178,"@media":190,"@charset":194,"@namespace":198,"@keyframes":204,"@supports":216,"@scope":220,"@font-feature-values":226},Yr={__proto__:null,to:223},Rr=j.deserialize({version:14,states:"IpQYQdOOO#}QdOOP$UO`OOO%OQaO'#CfOOQP'#Ce'#CeO%VQdO'#CgO%[Q`O'#CgO%aQaO'#FdO&XQdO'#CkO&xQaO'#CcO'SQdO'#CnO'_QdO'#DtO'dQdO'#DvO'oQdO'#D}O'oQdO'#EQOOQP'#Fd'#FdO)OQhO'#EsOOQS'#Fc'#FcOOQS'#Ev'#EvQYQdOOO)VQdO'#EWO*cQhO'#E^O)VQdO'#E`O*jQdO'#EbO*uQdO'#EeO)zQhO'#EkO*}QdO'#EmO+YQdO'#EpO+_QaO'#CfO+fQ`O'#ETO+kQ`O'#FnO+vQdO'#FnQOQ`OOP,QO&jO'#CaPOOO)CAR)CAROOQP'#Ci'#CiOOQP,59R,59RO%VQdO,59ROOQP'#Cm'#CmOOQP,59V,59VO&XQdO,59VO,]QdO,59YO'_QdO,5:`O'dQdO,5:bO'oQdO,5:iO'oQdO,5:kO'oQdO,5:lO'oQdO'#E}O,hQ`O,58}O,pQdO'#ESOOQS,58},58}OOQP'#Cq'#CqOOQO'#Dr'#DrOOQP,59Y,59YO,wQ`O,59YO,|Q`O,59YOOQP'#Du'#DuOOQP,5:`,5:`O-RQpO'#DwO-^QdO'#DxO-cQ`O'#DxO-hQpO,5:bO.RQaO,5:iO.iQaO,5:lOOQW'#D^'#D^O/eQhO'#DgO/xQhO,5;_O)zQhO'#DeO0VQ`O'#DkO0[QhO'#DnOOQW'#Fj'#FjOOQS,5;_,5;_O0aQ`O'#DhOOQS-E8t-E8tOOQ['#Cv'#CvO0fQdO'#CwO0|QdO'#C}O1dQdO'#DQO1zQ!pO'#DSO4TQ!jO,5:rOOQO'#DX'#DXO,|Q`O'#DWO4eQ!nO'#FgO6hQ`O'#DYO6mQ`O'#DoOOQ['#Fg'#FgO6rQhO'#FqO7QQ`O,5:xO7VQ!bO,5:zOOQS'#Ed'#EdO7_Q`O,5:|O7dQdO,5:|OOQO'#Eg'#EgO7lQ`O,5;PO7qQhO,5;VO'oQdO'#DjOOQS,5;X,5;XO0aQ`O,5;XO7yQdO,5;XOOQS'#FU'#FUO8RQdO'#ErO7QQ`O,5;[O8ZQdO,5:oO8kQdO'#FPO8xQ`O,5QQhO'#DlOOQW,5:V,5:VOOQW,5:Y,5:YOOQW,5:S,5:SO>[Q!fO'#FhOOQS'#Fh'#FhOOQS'#Ex'#ExO?lQdO,59cOOQ[,59c,59cO@SQdO,59iOOQ[,59i,59iO@jQdO,59lOOQ[,59l,59lOOQ[,59n,59nO)VQdO,59pOAQQhO'#EYOOQW'#EY'#EYOAlQ`O1G0^O4^QhO1G0^OOQ[,59r,59rO)zQhO'#D[OOQ[,59t,59tOAqQ#tO,5:ZOA|QhO'#FROBZQ`O,5<]OOQS1G0d1G0dOOQS1G0f1G0fOOQS1G0h1G0hOBfQ`O1G0hOBkQdO'#EhOOQS1G0k1G0kOOQS1G0q1G0qOBvQaO,5:UO7QQ`O1G0sOOQS1G0s1G0sO0aQ`O1G0sOOQS-E9S-E9SOOQS1G0v1G0vOB}Q!fO1G0ZOCeQ`O'#EVOOQO1G0Z1G0ZOOQO,5;k,5;kOCjQdO,5;kOOQO-E8}-E8}OCwQ`O1G1tPOOO-E8s-E8sPOOO1G.g1G.gOOQP7+$`7+$`OOQP7+%h7+%hO)VQdO7+%hOOQS1G0Y1G0YODSQaO'#FmOD^Q`O,5:_ODcQ!fO'#EwOEaQdO'#FfOEkQ`O,59aOOQO1G0O1G0OOEpQ!bO7+%hO)VQdO1G/eOE{QhO1G/iOOQW1G/m1G/mOOQW1G/g1G/gOF^QhO,5;qOOQW-E9T-E9TOOQS7+&e7+&eOGRQhO'#D^OGaQhO'#FlOGlQ`O'#FlOGqQ`O,5:WOOQS-E8v-E8vOOQ[1G.}1G.}OOQ[1G/T1G/TOOQ[1G/W1G/WOOQ[1G/[1G/[OGvQdO,5:tOOQS7+%x7+%xOG{Q`O7+%xOHQQhO'#D]OHYQ`O,59vO)zQhO,59vOOQ[1G/u1G/uOHbQ`O1G/uOHgQhO,5;mOOQO-E9P-E9POOQS7+&S7+&SOHuQbO'#DSOOQO'#Ej'#EjOITQ`O'#EiOOQO'#Ei'#EiOI`Q`O'#FSOIhQdO,5;SOOQS,5;S,5;SOOQ[1G/p1G/pOOQS7+&_7+&_O7QQ`O7+&_OIsQ!fO'#FOO)VQdO'#FOOJzQdO7+%uOOQO7+%u7+%uOOQO,5:q,5:qOOQO1G1V1G1VOK_Q!bO<nAN>nO! bQ`OAN>nO! gQaO,5;hOOQO-E8z-E8zO! qQdO,5;gOOQO-E8y-E8yOOQW<ZO)VQdO1G1QO!#nQ`O7+'^OOQO,5;l,5;lOOQO-E9O-E9OOOQW<Q!]!^>|!^!_?_!_!`@Z!`!a@n!a!b%Z!b!cAo!c!k%Z!k!lC|!l!u%Z!u!vC|!v!}%Z!}#OD_#O#P%Z#P#QDp#Q#R2X#R#]%Z#]#^ER#^#g%Z#g#hC|#h#o%Z#o#pIf#p#qIw#q#rJ`#r#sJq#s#y%Z#y#z&R#z$f%Z$f$g&R$g#BY%Z#BY#BZ&R#BZ$IS%Z$IS$I_&R$I_$I|%Z$I|$JO&R$JO$JT%Z$JT$JU&R$JU$KV%Z$KV$KW&R$KW&FU%Z&FU&FV&R&FV;'S%Z;'S;=`KY<%lO%Z`%^SOy%jz;'S%j;'S;=`%{<%lO%j`%oS!e`Oy%jz;'S%j;'S;=`%{<%lO%j`&OP;=`<%l%j~&Wh$Q~OX%jX^'r^p%jpq'rqy%jz#y%j#y#z'r#z$f%j$f$g'r$g#BY%j#BY#BZ'r#BZ$IS%j$IS$I_'r$I_$I|%j$I|$JO'r$JO$JT%j$JT$JU'r$JU$KV%j$KV$KW'r$KW&FU%j&FU&FV'r&FV;'S%j;'S;=`%{<%lO%j~'yh$Q~!e`OX%jX^'r^p%jpq'rqy%jz#y%j#y#z'r#z$f%j$f$g'r$g#BY%j#BY#BZ'r#BZ$IS%j$IS$I_'r$I_$I|%j$I|$JO'r$JO$JT%j$JT$JU'r$JU$KV%j$KV$KW'r$KW&FU%j&FU&FV'r&FV;'S%j;'S;=`%{<%lO%jj)jS$dYOy%jz;'S%j;'S;=`%{<%lO%j~)yWOY)vZr)vrs*cs#O)v#O#P*h#P;'S)v;'S;=`+d<%lO)v~*hOw~~*kRO;'S)v;'S;=`*t;=`O)v~*wXOY)vZr)vrs*cs#O)v#O#P*h#P;'S)v;'S;=`+d;=`<%l)v<%lO)v~+gP;=`<%l)vj+oYmYOy%jz!Q%j!Q![,_![!c%j!c!i,_!i#T%j#T#Z,_#Z;'S%j;'S;=`%{<%lO%jj,dY!e`Oy%jz!Q%j!Q![-S![!c%j!c!i-S!i#T%j#T#Z-S#Z;'S%j;'S;=`%{<%lO%jj-XY!e`Oy%jz!Q%j!Q![-w![!c%j!c!i-w!i#T%j#T#Z-w#Z;'S%j;'S;=`%{<%lO%jj.OYuY!e`Oy%jz!Q%j!Q![.n![!c%j!c!i.n!i#T%j#T#Z.n#Z;'S%j;'S;=`%{<%lO%jj.uYuY!e`Oy%jz!Q%j!Q![/e![!c%j!c!i/e!i#T%j#T#Z/e#Z;'S%j;'S;=`%{<%lO%jj/jY!e`Oy%jz!Q%j!Q![0Y![!c%j!c!i0Y!i#T%j#T#Z0Y#Z;'S%j;'S;=`%{<%lO%jj0aYuY!e`Oy%jz!Q%j!Q![1P![!c%j!c!i1P!i#T%j#T#Z1P#Z;'S%j;'S;=`%{<%lO%jj1UY!e`Oy%jz!Q%j!Q![1t![!c%j!c!i1t!i#T%j#T#Z1t#Z;'S%j;'S;=`%{<%lO%jj1{SuY!e`Oy%jz;'S%j;'S;=`%{<%lO%jd2[UOy%jz!_%j!_!`2n!`;'S%j;'S;=`%{<%lO%jd2uS!oS!e`Oy%jz;'S%j;'S;=`%{<%lO%jb3WS^QOy%jz;'S%j;'S;=`%{<%lO%j~3gWOY3dZw3dwx*cx#O3d#O#P4P#P;'S3d;'S;=`4{<%lO3d~4SRO;'S3d;'S;=`4];=`O3d~4`XOY3dZw3dwx*cx#O3d#O#P4P#P;'S3d;'S;=`4{;=`<%l3d<%lO3d~5OP;=`<%l3dj5WShYOy%jz;'S%j;'S;=`%{<%lO%j~5iOg~n5pUWQyWOy%jz!_%j!_!`2n!`;'S%j;'S;=`%{<%lO%jj6ZWyW!uQOy%jz!O%j!O!P6s!P!Q%j!Q![9x![;'S%j;'S;=`%{<%lO%jj6xU!e`Oy%jz!Q%j!Q![7[![;'S%j;'S;=`%{<%lO%jj7cY!e`$]YOy%jz!Q%j!Q![7[![!g%j!g!h8R!h#X%j#X#Y8R#Y;'S%j;'S;=`%{<%lO%jj8WY!e`Oy%jz{%j{|8v|}%j}!O8v!O!Q%j!Q![9_![;'S%j;'S;=`%{<%lO%jj8{U!e`Oy%jz!Q%j!Q![9_![;'S%j;'S;=`%{<%lO%jj9fU!e`$]YOy%jz!Q%j!Q![9_![;'S%j;'S;=`%{<%lO%jj:P[!e`$]YOy%jz!O%j!O!P7[!P!Q%j!Q![9x![!g%j!g!h8R!h#X%j#X#Y8R#Y;'S%j;'S;=`%{<%lO%jj:zS!aYOy%jz;'S%j;'S;=`%{<%lO%jj;]WyWOy%jz!O%j!O!P6s!P!Q%j!Q![9x![;'S%j;'S;=`%{<%lO%jj;zU`YOy%jz!Q%j!Q![7[![;'S%j;'S;=`%{<%lO%j~VUcYOy%jz![%j![!]>i!];'S%j;'S;=`%{<%lO%jj>pSdY!e`Oy%jz;'S%j;'S;=`%{<%lO%jj?RSnYOy%jz;'S%j;'S;=`%{<%lO%jh?dU!WWOy%jz!_%j!_!`?v!`;'S%j;'S;=`%{<%lO%jh?}S!WW!e`Oy%jz;'S%j;'S;=`%{<%lO%jl@bS!WW!oSOy%jz;'S%j;'S;=`%{<%lO%jj@uV!rQ!WWOy%jz!_%j!_!`?v!`!aA[!a;'S%j;'S;=`%{<%lO%jbAcS!rQ!e`Oy%jz;'S%j;'S;=`%{<%lO%jjArYOy%jz}%j}!OBb!O!c%j!c!}CP!}#T%j#T#oCP#o;'S%j;'S;=`%{<%lO%jjBgW!e`Oy%jz!c%j!c!}CP!}#T%j#T#oCP#o;'S%j;'S;=`%{<%lO%jjCW[lY!e`Oy%jz}%j}!OCP!O!Q%j!Q![CP![!c%j!c!}CP!}#T%j#T#oCP#o;'S%j;'S;=`%{<%lO%jhDRS!pWOy%jz;'S%j;'S;=`%{<%lO%jjDdSpYOy%jz;'S%j;'S;=`%{<%lO%jnDuSo^Oy%jz;'S%j;'S;=`%{<%lO%jjEWU!pWOy%jz#a%j#a#bEj#b;'S%j;'S;=`%{<%lO%jbEoU!e`Oy%jz#d%j#d#eFR#e;'S%j;'S;=`%{<%lO%jbFWU!e`Oy%jz#c%j#c#dFj#d;'S%j;'S;=`%{<%lO%jbFoU!e`Oy%jz#f%j#f#gGR#g;'S%j;'S;=`%{<%lO%jbGWU!e`Oy%jz#h%j#h#iGj#i;'S%j;'S;=`%{<%lO%jbGoU!e`Oy%jz#T%j#T#UHR#U;'S%j;'S;=`%{<%lO%jbHWU!e`Oy%jz#b%j#b#cHj#c;'S%j;'S;=`%{<%lO%jbHoU!e`Oy%jz#h%j#h#iIR#i;'S%j;'S;=`%{<%lO%jbIYS$cQ!e`Oy%jz;'S%j;'S;=`%{<%lO%jjIkSsYOy%jz;'S%j;'S;=`%{<%lO%jfI|U$XUOy%jz!_%j!_!`2n!`;'S%j;'S;=`%{<%lO%jjJeSrYOy%jz;'S%j;'S;=`%{<%lO%jfJvU!uQOy%jz!_%j!_!`2n!`;'S%j;'S;=`%{<%lO%j`K]P;=`<%l%Z",tokenizers:[xr,yr,br,kr,1,2,3,4,new lO("m~RRYZ[z{a~~g~aO$T~~dP!P!Qg~lO$U~~",28,142)],topRules:{StyleSheet:[0,6],Styles:[1,116]},dynamicPrecedences:{84:1},specialized:[{term:137,get:e=>wr[e]||-1},{term:138,get:e=>vr[e]||-1},{term:4,get:e=>jr[e]||-1},{term:28,get:e=>_r[e]||-1},{term:136,get:e=>Yr[e]||-1}],tokenPrec:2256});let fO=null;function mO(){if(!fO&&typeof document=="object"&&document.body){let{style:e}=document.body,O=[],a=new Set;for(let t in e)t!="cssText"&&t!="cssFloat"&&typeof e[t]=="string"&&(/[A-Z]/.test(t)&&(t=t.replace(/[A-Z]/g,r=>"-"+r.toLowerCase())),a.has(t)||(O.push(t),a.add(t)));fO=O.sort().map(t=>({type:"property",label:t,apply:t+": "}))}return fO||[]}const de=["active","after","any-link","autofill","backdrop","before","checked","cue","default","defined","disabled","empty","enabled","file-selector-button","first","first-child","first-letter","first-line","first-of-type","focus","focus-visible","focus-within","fullscreen","has","host","host-context","hover","in-range","indeterminate","invalid","is","lang","last-child","last-of-type","left","link","marker","modal","not","nth-child","nth-last-child","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","part","placeholder","placeholder-shown","read-only","read-write","required","right","root","scope","selection","slotted","target","target-text","valid","visited","where"].map(e=>({type:"class",label:e})),he=["above","absolute","activeborder","additive","activecaption","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","antialiased","appworkspace","asterisks","attr","auto","auto-flow","avoid","avoid-column","avoid-page","avoid-region","axis-pan","background","backwards","baseline","below","bidi-override","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","clear","clip","close-quote","col-resize","collapse","color","color-burn","color-dodge","column","column-reverse","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","darken","dashed","decimal","decimal-leading-zero","default","default-button","dense","destination-atop","destination-in","destination-out","destination-over","difference","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic-abegede-gez","ethiopic-halehame-aa-er","ethiopic-halehame-gez","ew-resize","exclusion","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fill-box","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","graytext","grid","groove","hand","hard-light","help","hidden","hide","higher","highlight","highlighttext","horizontal","hsl","hsla","hue","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-grid","inline-table","inset","inside","intrinsic","invert","italic","justify","keep-all","landscape","large","larger","left","level","lighter","lighten","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-hexadecimal","lower-latin","lower-norwegian","lowercase","ltr","luminosity","manipulation","match","matrix","matrix3d","medium","menu","menutext","message-box","middle","min-intrinsic","mix","monospace","move","multiple","multiple_mask_images","multiply","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","opacity","open-quote","optimizeLegibility","optimizeSpeed","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","perspective","pinch-zoom","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","saturation","scale","scale3d","scaleX","scaleY","scaleZ","screen","scroll","scrollbar","scroll-position","se-resize","self-start","self-end","semi-condensed","semi-expanded","separate","serif","show","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","soft-light","solid","source-atop","source-in","source-out","source-over","space","space-around","space-between","space-evenly","spell-out","square","start","static","status-bar","stretch","stroke","stroke-box","sub","subpixel-antialiased","svg_masks","super","sw-resize","symbolic","symbols","system-ui","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","text","text-bottom","text-top","textarea","textfield","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","to","top","transform","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","unidirectional-pan","unset","up","upper-latin","uppercase","url","var","vertical","vertical-text","view-box","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"].map(e=>({type:"keyword",label:e})).concat(["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"].map(e=>({type:"constant",label:e}))),zr=["a","abbr","address","article","aside","b","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","dd","del","details","dfn","dialog","div","dl","dt","em","figcaption","figure","footer","form","header","hgroup","h1","h2","h3","h4","h5","h6","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","main","meter","nav","ol","output","p","pre","ruby","section","select","small","source","span","strong","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","tr","u","ul"].map(e=>({type:"type",label:e})),qr=["@charset","@color-profile","@container","@counter-style","@font-face","@font-feature-values","@font-palette-values","@import","@keyframes","@layer","@media","@namespace","@page","@position-try","@property","@scope","@starting-style","@supports","@view-transition"].map(e=>({type:"keyword",label:e})),w=/^(\w[\w-]*|-\w[\w-]*|)$/,Vr=/^-(-[\w-]*)?$/;function Wr(e,O){var a;if((e.name=="("||e.type.isError)&&(e=e.parent||e),e.name!="ArgList")return!1;let t=(a=e.parent)===null||a===void 0?void 0:a.firstChild;return(t==null?void 0:t.name)!="Callee"?!1:O.sliceString(t.from,t.to)=="var"}const $e=new Re,Gr=["Declaration"];function Cr(e){for(let O=e;;){if(O.type.isTop)return O;if(!(O=O.parent))return e}}function et(e,O,a){if(O.to-O.from>4096){let t=$e.get(O);if(t)return t;let r=[],s=new Set,i=O.cursor(RO.IncludeAnonymous);if(i.firstChild())do for(let l of et(e,i.node,a))s.has(l.label)||(s.add(l.label),r.push(l));while(i.nextSibling());return $e.set(O,r),r}else{let t=[],r=new Set;return O.cursor().iterate(s=>{var i;if(a(s)&&s.matchContext(Gr)&&((i=s.node.nextSibling)===null||i===void 0?void 0:i.name)==":"){let l=e.sliceString(s.from,s.to);r.has(l)||(r.add(l),t.push({label:l,type:"variable"}))}}),t}}const Ur=e=>O=>{let{state:a,pos:t}=O,r=U(a).resolveInner(t,-1),s=r.type.isError&&r.from==r.to-1&&a.doc.sliceString(r.from,r.to)=="-";if(r.name=="PropertyName"||(s||r.name=="TagName")&&/^(Block|Styles)$/.test(r.resolve(r.to).name))return{from:r.from,options:mO(),validFor:w};if(r.name=="ValueName")return{from:r.from,options:he,validFor:w};if(r.name=="PseudoClassName")return{from:r.from,options:de,validFor:w};if(e(r)||(O.explicit||s)&&Wr(r,a.doc))return{from:e(r)||s?r.from:t,options:et(a.doc,Cr(r),e),validFor:Vr};if(r.name=="TagName"){for(let{parent:n}=r;n;n=n.parent)if(n.name=="Block")return{from:r.from,options:mO(),validFor:w};return{from:r.from,options:zr,validFor:w}}if(r.name=="AtKeyword")return{from:r.from,options:qr,validFor:w};if(!O.explicit)return null;let i=r.resolve(t),l=i.childBefore(t);return l&&l.name==":"&&i.name=="PseudoClassSelector"?{from:t,options:de,validFor:w}:l&&l.name==":"&&i.name=="Declaration"||i.name=="ArgList"?{from:t,options:he,validFor:w}:i.name=="Block"||i.name=="Styles"?{from:t,options:mO(),validFor:w}:null},Ar=Ur(e=>e.name=="VariableName"),oO=B.define({name:"css",parser:Rr.configure({props:[K.add({Declaration:z()}),J.add({"Block KeyframeList":zO})]}),languageData:{commentTokens:{block:{open:"/*",close:"*/"}},indentOnInput:/^\s*\}$/,wordChars:"-"}});function Er(){return new F(oO,oO.data.of({autocomplete:Ar}))}const Mr=316,Lr=317,fe=1,Ir=2,Nr=3,Dr=4,Br=318,Kr=320,Jr=321,Fr=5,Hr=6,Oi=0,yO=[9,10,11,12,13,32,133,160,5760,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8232,8233,8239,8287,12288],tt=125,ei=59,TO=47,ti=42,ai=43,ri=45,ii=60,si=44,li=63,ni=46,oi=91,ci=new Ce({start:!1,shift(e,O){return O==Fr||O==Hr||O==Kr?e:O==Jr},strict:!1}),Qi=new b((e,O)=>{let{next:a}=e;(a==tt||a==-1||O.context)&&e.acceptToken(Br)},{contextual:!0,fallback:!0}),ui=new b((e,O)=>{let{next:a}=e,t;yO.indexOf(a)>-1||a==TO&&((t=e.peek(1))==TO||t==ti)||a!=tt&&a!=ei&&a!=-1&&!O.context&&e.acceptToken(Mr)},{contextual:!0}),pi=new b((e,O)=>{e.next==oi&&!O.context&&e.acceptToken(Lr)},{contextual:!0}),di=new b((e,O)=>{let{next:a}=e;if(a==ai||a==ri){if(e.advance(),a==e.next){e.advance();let t=!O.context&&O.canShift(fe);e.acceptToken(t?fe:Ir)}}else a==li&&e.peek(1)==ni&&(e.advance(),e.advance(),(e.next<48||e.next>57)&&e.acceptToken(Nr))},{contextual:!0});function gO(e,O){return e>=65&&e<=90||e>=97&&e<=122||e==95||e>=192||!O&&e>=48&&e<=57}const hi=new b((e,O)=>{if(e.next!=ii||!O.dialectEnabled(Oi)||(e.advance(),e.next==TO))return;let a=0;for(;yO.indexOf(e.next)>-1;)e.advance(),a++;if(gO(e.next,!0)){for(e.advance(),a++;gO(e.next,!1);)e.advance(),a++;for(;yO.indexOf(e.next)>-1;)e.advance(),a++;if(e.next==si)return;for(let t=0;;t++){if(t==7){if(!gO(e.next,!0))return;break}if(e.next!="extends".charCodeAt(t))break;e.advance(),a++}}e.acceptToken(Dr,-a)}),$i=D({"get set async static":o.modifier,"for while do if else switch try catch finally return throw break continue default case defer":o.controlKeyword,"in of await yield void typeof delete instanceof as satisfies":o.operatorKeyword,"let var const using function class extends":o.definitionKeyword,"import export from":o.moduleKeyword,"with debugger new":o.keyword,TemplateString:o.special(o.string),super:o.atom,BooleanLiteral:o.bool,this:o.self,null:o.null,Star:o.modifier,VariableName:o.variableName,"CallExpression/VariableName TaggedTemplateExpression/VariableName":o.function(o.variableName),VariableDefinition:o.definition(o.variableName),Label:o.labelName,PropertyName:o.propertyName,PrivatePropertyName:o.special(o.propertyName),"CallExpression/MemberExpression/PropertyName":o.function(o.propertyName),"FunctionDeclaration/VariableDefinition":o.function(o.definition(o.variableName)),"ClassDeclaration/VariableDefinition":o.definition(o.className),"NewExpression/VariableName":o.className,PropertyDefinition:o.definition(o.propertyName),PrivatePropertyDefinition:o.definition(o.special(o.propertyName)),UpdateOp:o.updateOperator,"LineComment Hashbang":o.lineComment,BlockComment:o.blockComment,Number:o.number,String:o.string,Escape:o.escape,ArithOp:o.arithmeticOperator,LogicOp:o.logicOperator,BitOp:o.bitwiseOperator,CompareOp:o.compareOperator,RegExp:o.regexp,Equals:o.definitionOperator,Arrow:o.function(o.punctuation),": Spread":o.punctuation,"( )":o.paren,"[ ]":o.squareBracket,"{ }":o.brace,"InterpolationStart InterpolationEnd":o.special(o.brace),".":o.derefOperator,", ;":o.separator,"@":o.meta,TypeName:o.typeName,TypeDefinition:o.definition(o.typeName),"type enum interface implements namespace module declare":o.definitionKeyword,"abstract global Privacy readonly override":o.modifier,"is keyof unique infer asserts":o.operatorKeyword,JSXAttributeValue:o.attributeValue,JSXText:o.content,"JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag":o.angleBracket,"JSXIdentifier JSXNameSpacedName":o.tagName,"JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName":o.attributeName,"JSXBuiltin/JSXIdentifier":o.standard(o.tagName)}),fi={__proto__:null,export:20,as:25,from:33,default:36,async:41,function:42,in:52,out:55,const:56,extends:60,this:64,true:72,false:72,null:84,void:88,typeof:92,super:108,new:142,delete:154,yield:163,await:167,class:172,public:235,private:235,protected:235,readonly:237,instanceof:256,satisfies:259,import:292,keyof:349,unique:353,infer:359,asserts:395,is:397,abstract:417,implements:419,type:421,let:424,var:426,using:429,interface:435,enum:439,namespace:445,module:447,declare:451,global:455,defer:471,for:476,of:485,while:488,with:492,do:496,if:500,else:502,switch:506,case:512,try:518,catch:522,finally:526,return:530,throw:534,break:538,continue:542,debugger:546},mi={__proto__:null,async:129,get:131,set:133,declare:195,public:197,private:197,protected:197,static:199,abstract:201,override:203,readonly:209,accessor:211,new:401},gi={__proto__:null,"<":193},Pi=j.deserialize({version:14,states:"$F|Q%TQlOOO%[QlOOO'_QpOOP(lO`OOO*zQ!0MxO'#CiO+RO#tO'#CjO+aO&jO'#CjO+oO#@ItO'#DaO.QQlO'#DgO.bQlO'#DrO%[QlO'#DzO0fQlO'#ESOOQ!0Lf'#E['#E[O1PQ`O'#EXOOQO'#Ep'#EpOOQO'#Il'#IlO1XQ`O'#GsO1dQ`O'#EoO1iQ`O'#EoO3hQ!0MxO'#JrO6[Q!0MxO'#JsO6uQ`O'#F]O6zQ,UO'#FtOOQ!0Lf'#Ff'#FfO7VO7dO'#FfO9XQMhO'#F|O9`Q`O'#F{OOQ!0Lf'#Js'#JsOOQ!0Lb'#Jr'#JrO9eQ`O'#GwOOQ['#K_'#K_O9pQ`O'#IYO9uQ!0LrO'#IZOOQ['#J`'#J`OOQ['#I_'#I_Q`QlOOQ`QlOOO9}Q!L^O'#DvO:UQlO'#EOO:]QlO'#EQO9kQ`O'#GsO:dQMhO'#CoO:rQ`O'#EnO:}Q`O'#EyO;hQMhO'#FeO;xQ`O'#GsOOQO'#K`'#K`O;}Q`O'#K`O<]Q`O'#G{O<]Q`O'#G|O<]Q`O'#HOO9kQ`O'#HRO=SQ`O'#HUO>kQ`O'#CeO>{Q`O'#HcO?TQ`O'#HiO?TQ`O'#HkO`QlO'#HmO?TQ`O'#HoO?TQ`O'#HrO?YQ`O'#HxO?_Q!0LsO'#IOO%[QlO'#IQO?jQ!0LsO'#ISO?uQ!0LsO'#IUO9uQ!0LrO'#IWO@QQ!0MxO'#CiOASQpO'#DlQOQ`OOO%[QlO'#EQOAjQ`O'#ETO:dQMhO'#EnOAuQ`O'#EnOBQQ!bO'#FeOOQ['#Cg'#CgOOQ!0Lb'#Dq'#DqOOQ!0Lb'#Jv'#JvO%[QlO'#JvOOQO'#Jy'#JyOOQO'#Ih'#IhOCQQpO'#EgOOQ!0Lb'#Ef'#EfOOQ!0Lb'#J}'#J}OC|Q!0MSO'#EgODWQpO'#EWOOQO'#Jx'#JxODlQpO'#JyOEyQpO'#EWODWQpO'#EgPFWO&2DjO'#CbPOOO)CD})CD}OOOO'#I`'#I`OFcO#tO,59UOOQ!0Lh,59U,59UOOOO'#Ia'#IaOFqO&jO,59UOGPQ!L^O'#DcOOOO'#Ic'#IcOGWO#@ItO,59{OOQ!0Lf,59{,59{OGfQlO'#IdOGyQ`O'#JtOIxQ!fO'#JtO+}QlO'#JtOJPQ`O,5:ROJgQ`O'#EpOJtQ`O'#KTOKPQ`O'#KSOKPQ`O'#KSOKXQ`O,5;^OK^Q`O'#KROOQ!0Ln,5:^,5:^OKeQlO,5:^OMcQ!0MxO,5:fONSQ`O,5:nONmQ!0LrO'#KQONtQ`O'#KPO9eQ`O'#KPO! YQ`O'#KPO! bQ`O,5;]O! gQ`O'#KPO!#lQ!fO'#JsOOQ!0Lh'#Ci'#CiO%[QlO'#ESO!$[Q!fO,5:sOOQS'#Jz'#JzOOQO-EtOOQ['#Jh'#JhOOQ[,5>u,5>uOOQ[-E<]-E<]O!TO`QlO,5>VO!LOQ`O,5>XO`QlO,5>ZO!LTQ`O,5>^O!LYQlO,5>dOOQ[,5>j,5>jO%[QlO,5>jO9uQ!0LrO,5>lOOQ[,5>n,5>nO#!dQ`O,5>nOOQ[,5>p,5>pO#!dQ`O,5>pOOQ[,5>r,5>rO##QQpO'#D_O%[QlO'#JvO##sQpO'#JvO##}QpO'#DmO#$`QpO'#DmO#&qQlO'#DmO#&xQ`O'#JuO#'QQ`O,5:WO#'VQ`O'#EtO#'eQ`O'#KUO#'mQ`O,5;_O#'rQpO'#DmO#(PQpO'#EVOOQ!0Lf,5:o,5:oO%[QlO,5:oO#(WQ`O,5:oO?YQ`O,5;YO!CUQpO,5;YO!C^QMhO,5;YO:dQMhO,5;YO#(`Q`O,5@bO#(eQ07dO,5:sOOQO-EPO$6^Q`O,5>POOQ[1G3i1G3iO`QlO1G3iOOQ[1G3o1G3oOOQ[1G3q1G3qO?TQ`O1G3sO$6cQlO1G3uO$:gQlO'#HtOOQ[1G3x1G3xO$:tQ`O'#HzO?YQ`O'#H|OOQ[1G4O1G4OO$:|QlO1G4OO9uQ!0LrO1G4UOOQ[1G4W1G4WOOQ!0Lb'#G_'#G_O9uQ!0LrO1G4YO9uQ!0LrO1G4[O$?TQ`O,5@bO!)[QlO,5;`O9eQ`O,5;`O?YQ`O,5:XO!)[QlO,5:XO!CUQpO,5:XO$?YQ?MtO,5:XOOQO,5;`,5;`O$?dQpO'#IeO$?zQ`O,5@aOOQ!0Lf1G/r1G/rO$@SQpO'#IkO$@^Q`O,5@pOOQ!0Lb1G0y1G0yO#$`QpO,5:XOOQO'#Ig'#IgO$@fQpO,5:qOOQ!0Ln,5:q,5:qO#(ZQ`O1G0ZOOQ!0Lf1G0Z1G0ZO%[QlO1G0ZOOQ!0Lf1G0t1G0tO?YQ`O1G0tO!CUQpO1G0tO!C^QMhO1G0tOOQ!0Lb1G5|1G5|O!ByQ!0LrO1G0^OOQO1G0m1G0mO%[QlO1G0mO$@mQ!0LrO1G0mO$@xQ!0LrO1G0mO!CUQpO1G0^ODWQpO1G0^O$AWQ!0LrO1G0mOOQO1G0^1G0^O$AlQ!0MxO1G0mPOOO-E<[-E<[POOO1G.h1G.hOOOO1G/i1G/iO$AvQ!bO,5QQpO,5@}OOQ!0Lb1G3c1G3cOOQ[7+$V7+$VO@zQ`O7+$VO9uQ!0LrO7+$VO%>]Q`O7+$VO%[QlO1G6lO%[QlO1G6mO%>bQ!0LrO1G6lO%>lQlO1G3kO%>sQ`O1G3kO%>xQlO1G3kOOQ[7+)T7+)TO9uQ!0LrO7+)_O`QlO7+)aOOQ['#Kh'#KhOOQ['#JS'#JSO%?PQlO,5>`OOQ[,5>`,5>`O%[QlO'#HuO%?^Q`O'#HwOOQ[,5>f,5>fO9eQ`O,5>fOOQ[,5>h,5>hOOQ[7+)j7+)jOOQ[7+)p7+)pOOQ[7+)t7+)tOOQ[7+)v7+)vO%?cQpO1G5|O%?}Q?MtO1G0zO%@XQ`O1G0zOOQO1G/s1G/sO%@dQ?MtO1G/sO?YQ`O1G/sO!)[QlO'#DmOOQO,5?P,5?POOQO-ERQ`O7+,WO&>WQ`O7+,XO%[QlO7+,WO%[QlO7+,XOOQ[7+)V7+)VO&>]Q`O7+)VO&>bQlO7+)VO&>iQ`O7+)VOOQ[<nQ`O,5>aOOQ[,5>c,5>cO&>sQ`O1G4QO9eQ`O7+&fO!)[QlO7+&fOOQO7+%_7+%_O&>xQ?MtO1G6ZO?YQ`O7+%_OOQ!0Lf<yQ?MvO,5?aO'@|Q?MvO,5?cO'CPQ?MvO7+'|O'DuQMjOG27TOOQO<VO!l$xO#jROe!iOpkOrPO(T)]O(VTO(YUO(aVO(o[O~O!]$_Oa$qa'z$qa'w$qa!k$qa!Y$qa!_$qa%i$qa!g$qa~Ol)dO~P!&zOh%VOp%WOr%XOs$tOt$tOz%YO|%ZO!O%]O!S${O!_$|O!i%bO!l$xO#j%cO$W%`O$t%^O$v%_O$y%aO(T(vO(VTO(YUO(a$uO(y$}O(z%PO~Og(pP~P!,TO!Q)iO!g)hO!_$^X$Z$^X$]$^X$_$^X$f$^X~O!g)hO!_({X$Z({X$]({X$_({X$f({X~O!Q)iO~P!.^O!Q)iO!_({X$Z({X$]({X$_({X$f({X~O!_)kO$Z)oO$])jO$_)jO$f)pO~O![)sO~P!)[O$]$hO$_$gO$f)wO~On$zX!Q$zX#S$zX'y$zX(y$zX(z$zX~OgmXg$zXnmX!]mX#`mX~P!0SOx)yO(b)zO(c)|O~On*VO!Q*OO'y*PO(y$}O(z%PO~Og)}O~P!1WOg*WO~Oh%VOr%XOs$tOt$tOz%YO|%ZO!OVO!l$xO#jVO!l$xO#jROe!iOpkOrPO(VTO(YUO(aVO(o[O~O(T=QO~P#$qO!]-]O!^(iX~O!^-_O~O!g-VO#`-UO!]#hX!^#hX~O!]-`O!^(xX~O!^-bO~O!c-cO!d-cO(U!lO~P#$`O!^-fO~P'_On-iO!_'`O~O!Y-nO~Os!{a!b!{a!c!{a!d!{a#T!{a#U!{a#V!{a#W!{a#X!{a#[!{a#]!{a(U!{a(V!{a(Y!{a(e!{a(o!{a~P!#vO!p-sO#`-qO~PChO!c-uO!d-uO(U!lO~PDWOa%nO#`-qO'z%nO~Oa%nO!g#vO#`-qO'z%nO~Oa%nO!g#vO!p-sO#`-qO'z%nO(r'pO~O(P'xO(Q'xO(R-zO~Ov-{O~O!Y'Wa!]'Wa~P!:tO![.PO!Y'WX!]'WX~P%[O!](VO!Y(ha~O!Y(ha~PHRO!](^O!Y(va~O!S%hO![.TO!_%iO(T%gO!Y'^X!]'^X~O#`.VO!](ta!k(taa(ta'z(ta~O!g#vO~P#,wO!](jO!k(sa~O!S%hO!_%iO#j.ZO(T%gO~Op.`O!S%hO![.]O!_%iO!|]O#i._O#j.]O(T%gO!]'aX!k'aX~OR.dO!l#xO~Oh%VOn.gO!_'`O%i.fO~Oa#ci!]#ci'z#ci'w#ci!Y#ci!k#civ#ci!_#ci%i#ci!g#ci~P!:tOn>]O!Q*OO'y*PO(y$}O(z%PO~O#k#_aa#_a#`#_a'z#_a!]#_a!k#_a!_#_a!Y#_a~P#/sO#k(`XP(`XR(`X[(`Xa(`Xj(`Xr(`X!S(`X!l(`X!p(`X#R(`X#n(`X#o(`X#p(`X#q(`X#r(`X#s(`X#t(`X#u(`X#v(`X#x(`X#z(`X#{(`X'z(`X(a(`X(r(`X!k(`X!Y(`X'w(`Xv(`X!_(`X%i(`X!g(`X~P!6kO!].tO!k(kX~P!:tO!k.wO~O!Y.yO~OP$[OR#zO!Q#yO!S#{O!l#xO!p$[O(aVO[#mia#mij#mir#mi!]#mi#R#mi#o#mi#p#mi#q#mi#r#mi#s#mi#t#mi#u#mi#v#mi#x#mi#z#mi#{#mi'z#mi(r#mi(y#mi(z#mi'w#mi!Y#mi!k#miv#mi!_#mi%i#mi!g#mi~O#n#mi~P#3cO#n$OO~P#3cOP$[OR#zOr$aO!Q#yO!S#{O!l#xO!p$[O#n$OO#o$PO#p$PO#q$PO(aVO[#mia#mij#mi!]#mi#R#mi#s#mi#t#mi#u#mi#v#mi#x#mi#z#mi#{#mi'z#mi(r#mi(y#mi(z#mi'w#mi!Y#mi!k#miv#mi!_#mi%i#mi!g#mi~O#r#mi~P#6QO#r$QO~P#6QOP$[OR#zO[$cOj$ROr$aO!Q#yO!S#{O!l#xO!p$[O#R$RO#n$OO#o$PO#p$PO#q$PO#r$QO#s$RO#t$RO#u$bO(aVOa#mi!]#mi#x#mi#z#mi#{#mi'z#mi(r#mi(y#mi(z#mi'w#mi!Y#mi!k#miv#mi!_#mi%i#mi!g#mi~O#v#mi~P#8oOP$[OR#zO[$cOj$ROr$aO!Q#yO!S#{O!l#xO!p$[O#R$RO#n$OO#o$PO#p$PO#q$PO#r$QO#s$RO#t$RO#u$bO#v$SO(aVO(z#}Oa#mi!]#mi#z#mi#{#mi'z#mi(r#mi(y#mi'w#mi!Y#mi!k#miv#mi!_#mi%i#mi!g#mi~O#x$UO~P#;VO#x#mi~P#;VO#v$SO~P#8oOP$[OR#zO[$cOj$ROr$aO!Q#yO!S#{O!l#xO!p$[O#R$RO#n$OO#o$PO#p$PO#q$PO#r$QO#s$RO#t$RO#u$bO#v$SO#x$UO(aVO(y#|O(z#}Oa#mi!]#mi#{#mi'z#mi(r#mi'w#mi!Y#mi!k#miv#mi!_#mi%i#mi!g#mi~O#z#mi~P#={O#z$WO~P#={OP]XR]X[]Xj]Xr]X!Q]X!S]X!l]X!p]X#R]X#S]X#`]X#kfX#n]X#o]X#p]X#q]X#r]X#s]X#t]X#u]X#v]X#x]X#z]X#{]X$Q]X(a]X(r]X(y]X(z]X!]]X!^]X~O$O]X~P#@jOP$[OR#zO[]O!Q*OO'y*PO(y$}O(z%POP#miR#mi!S#mi!l#mi!p#mi#n#mi#o#mi#p#mi#q#mi(a#mi~P#EyO!]/POg(pX~P!1WOg/RO~Oa$Pi!]$Pi'z$Pi'w$Pi!Y$Pi!k$Piv$Pi!_$Pi%i$Pi!g$Pi~P!:tO$]/SO$_/SO~O$]/TO$_/TO~O!g)hO#`/UO!_$cX$Z$cX$]$cX$_$cX$f$cX~O![/VO~O!_)kO$Z/XO$])jO$_)jO$f/YO~O!]VO!l$xO#j^O!Q*OO'y*PO(y$}O(z%POP#miR#mi!S#mi!l#mi!p#mi#n#mi#o#mi#p#mi#q#mi(a#mi~P&,QO#S$dOP(`XR(`X[(`Xj(`Xn(`Xr(`X!Q(`X!S(`X!l(`X!p(`X#R(`X#n(`X#o(`X#p(`X#q(`X#r(`X#s(`X#t(`X#u(`X#v(`X#x(`X#z(`X#{(`X$O(`X'y(`X(a(`X(r(`X(y(`X(z(`X!](`X!^(`X~O$O$Pi!]$Pi!^$Pi~P#BwO$O!ri!^!ri~P$+oOg']a!]']a~P!1WO!^7nO~O!]'da!^'da~P#BwO!Y7oO~P#/sO!g#vO(r'pO!]'ea!k'ea~O!]/pO!k)Oi~O!]/pO!g#vO!k)Oi~Og$|q!]$|q#`$|q$O$|q~P!1WO!Y'ga!]'ga~P#/sO!g7vO~O!]/yO!Y)Pi~P#/sO!]/yO!Y)Pi~O!Y7yO~Oh%VOr8OO!l%eO(r'pO~Oj8QO!g#vO~Or8TO!g#vO(r'pO~O!Q*OO'y*PO(z%POn'ja(y'ja!]'ja#`'ja~Og'ja$O'ja~P&5RO!Q*OO'y*POn'la(y'la(z'la!]'la#`'la~Og'la$O'la~P&5tOg(_q!](_q~P!1WO#`8VOg(_q!](_q~P!1WO!Y8WO~Og%Oq!]%Oq#`%Oq$O%Oq~P!1WOa$oy!]$oy'z$oy'w$oy!Y$oy!k$oyv$oy!_$oy%i$oy!g$oy~P!:tO!g6rO~O!]5[O!_)Qa~O!_'`OP$TaR$Ta[$Taj$Tar$Ta!Q$Ta!S$Ta!]$Ta!l$Ta!p$Ta#R$Ta#n$Ta#o$Ta#p$Ta#q$Ta#r$Ta#s$Ta#t$Ta#u$Ta#v$Ta#x$Ta#z$Ta#{$Ta(a$Ta(r$Ta(y$Ta(z$Ta~O%i7WO~P&8fO%^8[Oa%[i!_%[i'z%[i!]%[i~Oa#cy!]#cy'z#cy'w#cy!Y#cy!k#cyv#cy!_#cy%i#cy!g#cy~P!:tO[8^O~Ob8`O(T+qO(VTO(YUO~O!]1TO!^)Xi~O`8dO~O(e(|O!]'pX!^'pX~O!]5uO!^)Ua~O!^8nO~P%;eO(o!sO~P$&YO#[8oO~O!_1oO~O!_1oO%i8qO~On8tO!_1oO%i8qO~O[8yO!]'sa!^'sa~O!]1zO!^)Vi~O!k8}O~O!k9OO~O!k9RO~O!k9RO~P%[Oa9TO~O!g9UO~O!k9VO~O!](wi!^(wi~P#BwOa%nO#`9_O'z%nO~O!](ty!k(tya(ty'z(ty~P!:tO!](jO!k(sy~O%i9bO~P&8fO!_'`O%i9bO~O#k$|qP$|qR$|q[$|qa$|qj$|qr$|q!S$|q!]$|q!l$|q!p$|q#R$|q#n$|q#o$|q#p$|q#q$|q#r$|q#s$|q#t$|q#u$|q#v$|q#x$|q#z$|q#{$|q'z$|q(a$|q(r$|q!k$|q!Y$|q'w$|q#`$|qv$|q!_$|q%i$|q!g$|q~P#/sO#k'jaP'jaR'ja['jaa'jaj'jar'ja!S'ja!l'ja!p'ja#R'ja#n'ja#o'ja#p'ja#q'ja#r'ja#s'ja#t'ja#u'ja#v'ja#x'ja#z'ja#{'ja'z'ja(a'ja(r'ja!k'ja!Y'ja'w'jav'ja!_'ja%i'ja!g'ja~P&5RO#k'laP'laR'la['laa'laj'lar'la!S'la!l'la!p'la#R'la#n'la#o'la#p'la#q'la#r'la#s'la#t'la#u'la#v'la#x'la#z'la#{'la'z'la(a'la(r'la!k'la!Y'la'w'lav'la!_'la%i'la!g'la~P&5tO#k%OqP%OqR%Oq[%Oqa%Oqj%Oqr%Oq!S%Oq!]%Oq!l%Oq!p%Oq#R%Oq#n%Oq#o%Oq#p%Oq#q%Oq#r%Oq#s%Oq#t%Oq#u%Oq#v%Oq#x%Oq#z%Oq#{%Oq'z%Oq(a%Oq(r%Oq!k%Oq!Y%Oq'w%Oq#`%Oqv%Oq!_%Oq%i%Oq!g%Oq~P#/sO!]'Yi!k'Yi~P!:tO$O#cq!]#cq!^#cq~P#BwO(y$}OP%aaR%aa[%aaj%aar%aa!S%aa!l%aa!p%aa#R%aa#n%aa#o%aa#p%aa#q%aa#r%aa#s%aa#t%aa#u%aa#v%aa#x%aa#z%aa#{%aa$O%aa(a%aa(r%aa!]%aa!^%aa~On%aa!Q%aa'y%aa(z%aa~P&IyO(z%POP%caR%ca[%caj%car%ca!S%ca!l%ca!p%ca#R%ca#n%ca#o%ca#p%ca#q%ca#r%ca#s%ca#t%ca#u%ca#v%ca#x%ca#z%ca#{%ca$O%ca(a%ca(r%ca!]%ca!^%ca~On%ca!Q%ca'y%ca(y%ca~P&LQOn>^O!Q*OO'y*PO(z%PO~P&IyOn>^O!Q*OO'y*PO(y$}O~P&LQOR0kO!Q0kO!S0lO#S$dOP}a[}aj}an}ar}a!l}a!p}a#R}a#n}a#o}a#p}a#q}a#r}a#s}a#t}a#u}a#v}a#x}a#z}a#{}a$O}a'y}a(a}a(r}a(y}a(z}a!]}a!^}a~O!Q*OO'y*POP$saR$sa[$saj$san$sar$sa!S$sa!l$sa!p$sa#R$sa#n$sa#o$sa#p$sa#q$sa#r$sa#s$sa#t$sa#u$sa#v$sa#x$sa#z$sa#{$sa$O$sa(a$sa(r$sa(y$sa(z$sa!]$sa!^$sa~O!Q*OO'y*POP$uaR$ua[$uaj$uan$uar$ua!S$ua!l$ua!p$ua#R$ua#n$ua#o$ua#p$ua#q$ua#r$ua#s$ua#t$ua#u$ua#v$ua#x$ua#z$ua#{$ua$O$ua(a$ua(r$ua(y$ua(z$ua!]$ua!^$ua~On>^O!Q*OO'y*PO(y$}O(z%PO~OP%TaR%Ta[%Taj%Tar%Ta!S%Ta!l%Ta!p%Ta#R%Ta#n%Ta#o%Ta#p%Ta#q%Ta#r%Ta#s%Ta#t%Ta#u%Ta#v%Ta#x%Ta#z%Ta#{%Ta$O%Ta(a%Ta(r%Ta!]%Ta!^%Ta~P''VO$O$mq!]$mq!^$mq~P#BwO$O$oq!]$oq!^$oq~P#BwO!^9oO~O$O9pO~P!1WO!g#vO!]'ei!k'ei~O!g#vO(r'pO!]'ei!k'ei~O!]/pO!k)Oq~O!Y'gi!]'gi~P#/sO!]/yO!Y)Pq~Or9wO!g#vO(r'pO~O[9yO!Y9xO~P#/sO!Y9xO~Oj:PO!g#vO~Og(_y!](_y~P!1WO!]'na!_'na~P#/sOa%[q!_%[q'z%[q!]%[q~P#/sO[:UO~O!]1TO!^)Xq~O`:YO~O#`:ZO!]'pa!^'pa~O!]5uO!^)Ui~P#BwO!S:]O~O!_1oO%i:`O~O(VTO(YUO(e:eO~O!]1zO!^)Vq~O!k:hO~O!k:iO~O!k:jO~O!k:jO~P%[O#`:mO!]#hy!^#hy~O!]#hy!^#hy~P#BwO%i:rO~P&8fO!_'`O%i:rO~O$O#|y!]#|y!^#|y~P#BwOP$|iR$|i[$|ij$|ir$|i!S$|i!l$|i!p$|i#R$|i#n$|i#o$|i#p$|i#q$|i#r$|i#s$|i#t$|i#u$|i#v$|i#x$|i#z$|i#{$|i$O$|i(a$|i(r$|i!]$|i!^$|i~P''VO!Q*OO'y*PO(z%POP'iaR'ia['iaj'ian'iar'ia!S'ia!l'ia!p'ia#R'ia#n'ia#o'ia#p'ia#q'ia#r'ia#s'ia#t'ia#u'ia#v'ia#x'ia#z'ia#{'ia$O'ia(a'ia(r'ia(y'ia!]'ia!^'ia~O!Q*OO'y*POP'kaR'ka['kaj'kan'kar'ka!S'ka!l'ka!p'ka#R'ka#n'ka#o'ka#p'ka#q'ka#r'ka#s'ka#t'ka#u'ka#v'ka#x'ka#z'ka#{'ka$O'ka(a'ka(r'ka(y'ka(z'ka!]'ka!^'ka~O(y$}OP%aiR%ai[%aij%ain%air%ai!Q%ai!S%ai!l%ai!p%ai#R%ai#n%ai#o%ai#p%ai#q%ai#r%ai#s%ai#t%ai#u%ai#v%ai#x%ai#z%ai#{%ai$O%ai'y%ai(a%ai(r%ai(z%ai!]%ai!^%ai~O(z%POP%ciR%ci[%cij%cin%cir%ci!Q%ci!S%ci!l%ci!p%ci#R%ci#n%ci#o%ci#p%ci#q%ci#r%ci#s%ci#t%ci#u%ci#v%ci#x%ci#z%ci#{%ci$O%ci'y%ci(a%ci(r%ci(y%ci!]%ci!^%ci~O$O$oy!]$oy!^$oy~P#BwO$O#cy!]#cy!^#cy~P#BwO!g#vO!]'eq!k'eq~O!]/pO!k)Oy~O!Y'gq!]'gq~P#/sOr:|O!g#vO(r'pO~O[;QO!Y;PO~P#/sO!Y;PO~Og(_!R!](_!R~P!1WOa%[y!_%[y'z%[y!]%[y~P#/sO!]1TO!^)Xy~O!]5uO!^)Uq~O(T;XO~O!_1oO%i;[O~O!k;_O~O%i;dO~P&8fOP$|qR$|q[$|qj$|qr$|q!S$|q!l$|q!p$|q#R$|q#n$|q#o$|q#p$|q#q$|q#r$|q#s$|q#t$|q#u$|q#v$|q#x$|q#z$|q#{$|q$O$|q(a$|q(r$|q!]$|q!^$|q~P''VO!Q*OO'y*PO(z%POP'jaR'ja['jaj'jan'jar'ja!S'ja!l'ja!p'ja#R'ja#n'ja#o'ja#p'ja#q'ja#r'ja#s'ja#t'ja#u'ja#v'ja#x'ja#z'ja#{'ja$O'ja(a'ja(r'ja(y'ja!]'ja!^'ja~O!Q*OO'y*POP'laR'la['laj'lan'lar'la!S'la!l'la!p'la#R'la#n'la#o'la#p'la#q'la#r'la#s'la#t'la#u'la#v'la#x'la#z'la#{'la$O'la(a'la(r'la(y'la(z'la!]'la!^'la~OP%OqR%Oq[%Oqj%Oqr%Oq!S%Oq!l%Oq!p%Oq#R%Oq#n%Oq#o%Oq#p%Oq#q%Oq#r%Oq#s%Oq#t%Oq#u%Oq#v%Oq#x%Oq#z%Oq#{%Oq$O%Oq(a%Oq(r%Oq!]%Oq!^%Oq~P''VOg%e!Z!]%e!Z#`%e!Z$O%e!Z~P!1WO!Y;hO~P#/sOr;iO!g#vO(r'pO~O[;kO!Y;hO~P#/sO!]'pq!^'pq~P#BwO!]#h!Z!^#h!Z~P#BwO#k%e!ZP%e!ZR%e!Z[%e!Za%e!Zj%e!Zr%e!Z!S%e!Z!]%e!Z!l%e!Z!p%e!Z#R%e!Z#n%e!Z#o%e!Z#p%e!Z#q%e!Z#r%e!Z#s%e!Z#t%e!Z#u%e!Z#v%e!Z#x%e!Z#z%e!Z#{%e!Z'z%e!Z(a%e!Z(r%e!Z!k%e!Z!Y%e!Z'w%e!Z#`%e!Zv%e!Z!_%e!Z%i%e!Z!g%e!Z~P#/sOr;tO!g#vO(r'pO~O!Y;uO~P#/sOr;|O!g#vO(r'pO~O!Y;}O~P#/sOP%e!ZR%e!Z[%e!Zj%e!Zr%e!Z!S%e!Z!l%e!Z!p%e!Z#R%e!Z#n%e!Z#o%e!Z#p%e!Z#q%e!Z#r%e!Z#s%e!Z#t%e!Z#u%e!Z#v%e!Z#x%e!Z#z%e!Z#{%e!Z$O%e!Z(a%e!Z(r%e!Z!]%e!Z!^%e!Z~P''VOrROe!iOpkOrPO(T)]O(VTO(YUO(aVO(o[O~O!]WO!l$xO#jgPPP!>oI[PPPPPPPPP!BOP!C]PPI[!DnPI[PI[I[I[I[I[PI[!FQP!I[P!LbP!Lf!Lp!Lt!LtP!IXP!Lx!LxP#!OP#!SI[PI[#!Y#%_CjA^PA^PA^A^P#&lA^A^#)OA^#+vA^#.SA^A^#.r#1W#1W#1]#1f#1W#1qPP#1WPA^#2ZA^#6YA^A^6mPPP#:_PPP#:x#:xP#:xP#;`#:xPP#;fP#;]P#;]#;y#;]#P#>V#>]#>k#>q#>{#?R#?]#?c#?s#?y#@k#@}#AT#AZ#Ai#BO#Cs#DR#DY#Et#FS#Gt#HS#HY#H`#Hf#Hp#Hv#H|#IW#Ij#IpPPPPPPPPPPP#IvPPPPPPP#Jk#Mx$ b$ i$ qPPP$']P$'f$*_$0x$0{$1O$1}$2Q$2X$2aP$2g$2jP$3W$3[$4S$5b$5g$5}PP$6S$6Y$6^$6a$6e$6i$7e$7|$8e$8i$8l$8o$8y$8|$9Q$9UR!|RoqOXst!Z#d%m&r&t&u&w,s,x2[2_Y!vQ'`-e1o5{Q%tvQ%|yQ&T|Q&j!VS'W!e-]Q'f!iS'l!r!yU*k$|*Z*oQ+o%}S+|&V&WQ,d&dQ-c'_Q-m'gQ-u'mQ0[*qQ1b,OQ1y,eR<{SU+P%]S!S!nQ!r!v!y!z$|'W'_'`'l'm'n*k*o*q*r-]-c-e-u0[0_1o5{5}%[$ti#v$b$c$d$x${%O%Q%^%_%c)y*R*T*V*Y*a*g*w*x+f+i,S,V.f/P/d/m/x/y/{0`0b0i0j0o1f1i1q3c4^4_4j4o5Q5[5_6S7W7v8Q8V8[8q9b9p9y:P:`:r;Q;[;d;kP>X>Y>]>^Q&X|Q'U!eS'[%i-`Q+t&PQ,P&WQ,f&gQ0n+SQ1Y+uQ1_+{Q2Q,jQ2R,kQ5f1TQ5o1aQ6[1zQ6_1|Q6`2PQ8`5gQ8c5lQ8|6bQ:X8dQ:f8yQ;V:YR<}*ZrnOXst!V!Z#d%m&i&r&t&u&w,s,x2[2_R,h&k&z^OPXYstuvwz!Z!`!g!j!o#S#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$Z$_$a$e$n%m%t&R&k&n&o&r&t&u&w&{'T'b'r(V(](d(x(z)O)s)}*i+X+]+g,p,s,x-U-X-i-q.P.V.g.t.{/V/n0]0l0r1S1r2S2T2V2X2[2_2a2p3Q3W3d3l4T4z5w6T6e6f6i6s6|7[8t9T9_:Z:mR>S[#]WZ#W#Z'X(T!b%jm#h#i#l$x%e%h(^(h(i(j*Y*^*b+Z+[+^,o-V.T.Z.[.]._/m/p2d3[3]4a6r7TQ%wxQ%{yW&Q|&V&W,OQ&_!TQ'c!hQ'e!iQ(q#sS+n%|%}Q+r&PQ,_&bQ,c&dS-l'f'gQ.i(rQ1R+oQ1X+uQ1Z+vQ1^+zQ1t,`S1x,d,eQ2|-mQ5e1TQ5i1WQ5n1`Q6Z1yQ8_5gQ8b5kQ8f5pQ:T8^R;T:U!U$zi$d%O%Q%^%_%c*R*T*a*w*x/P/x0`0b0i0j0o4_5Q8V9p>P>X>Y!^%yy!i!u%{%|%}'V'e'f'g'k'u*j+n+o-Y-l-m-t0R0U1R2u2|3T4r4s4v7}9{Q+h%wQ,T&[Q,W&]Q,b&dQ.h(qQ1s,_U1w,c,d,eQ3e.iQ6U1tS6Y1x1yQ8x6Z#f>T#v$b$c$x${)y*V*Y*g+f+i,S,V.f/d/m/y/{1f1i1q3c4^4j4o5[5_6S7W7v8Q8[8q9b9y:P:`:r;Q;[;d;k]>^o>UPS&[!Q&iQ&]!RQ&^!SU*}%[%d=sR,R&Y%]%Si#v$b$c$d$x${%O%Q%^%_%c)y*R*T*V*Y*a*g*w*x+f+i,S,V.f/P/d/m/x/y/{0`0b0i0j0o1f1i1q3c4^4_4j4o5Q5[5_6S7W7v8Q8V8[8q9b9p9y:P:`:r;Q;[;d;kP>X>Y>]>^T)z$u){V+P%]S$i$^c#Y#e%q%s%u(S(Y(t(y)R)S)T)U)V)W)X)Y)Z)[)^)`)b)g)q+d+x-Z-x-}.S.U.s.v.z.|.}/O/b0p2k2n3O3V3k3p3q3r3s3t3u3v3w3x3y3z3{3|4P4Q4X5X5c6u6{7Q7a7b7k7l8k9X9]9g9m9n:o;W;`SQ'Y!eR2q-]!W!nQ!e!r!v!y!z$|'W'_'`'l'm'n*Z*k*o*q*r-]-c-e-u0[0_1o5{5}R1l,ZnqOXst!Z#d%m&r&t&u&w,s,x2[2_Q&y!^Q'v!xS(s#u<^Q+l%zQ,]&_Q,^&aQ-j'dQ-w'oS.r(x=PS0q+X=ZQ1P+mQ1n,[Q2c,zQ2e,{Q2m-WQ2z-kQ2}-oS5Y0r=eQ5a1QS5d1S=fQ6t2oQ6x2{Q6}3SQ8]5bQ9Y6vQ9Z6yQ9^7OR:l9V$d$]c#Y#e%s%u(S(Y(t(y)R)S)T)U)V)W)X)Y)Z)[)^)`)b)g)q+d+x-Z-x-}.S.U.s.v.z.}/O/b0p2k2n3O3V3k3p3q3r3s3t3u3v3w3x3y3z3{3|4P4Q4X5X5c6u6{7Q7a7b7k7l8k9X9]9g9m9n:o;W;`SS#q]SU$fd)_,mS(p#p'iU*v%R(w4OU0m+O.n7gQ5^0xQ7V3`Q9d7YR:s9em!tQ!r!v!y!z'`'l'm'n-e-u1o5{5}Q't!uS(f#g2US-s'k'wQ/s*]Q0R*jQ3U-vQ4f/tQ4r0TQ4s0UQ4x0^Q7r4`S7}4t4vS8R4y4{Q9r7sQ9v7yQ9{8OQ:Q8TS:{9w9xS;g:|;PS;s;h;iS;{;t;uSSR=o>R%^bOPWXYZstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$_$a$e%m%t&R&k&n&o&r&t&u&w&{'T'b'r(T(V(](d(x(z)O)}*i+X+]+g,p,s,x-i-q.P.V.g.t.{/n0]0l0r1S1r2S2T2V2X2[2_2a3Q3W3d3l4z6T6e6f6i6|7[8t9T9_Q%fj!^%xy!i!u%{%|%}'V'e'f'g'k'u*j+n+o-Y-l-m-t0R0U1R2u2|3T4r4s4v7}9{S&Oz!jQ+k%yQ,a&dW1v,b,c,d,eU6X1w1x1yS8w6Y6ZQ:d8x!r=j$Z$n'X)s-U-X/V2p4T5w6s:Z:mSQ=t>QR=u>R%QeOPXYstuvw!Z!`!g!o#S#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$_$a$e%m%t&R&k&n&r&t&u&w&{'T'b'r(V(](d(x(z)O)}*i+X+]+g,p,s,x-i-q.P.V.g.t.{/n0]0l0r1S1r2S2T2V2X2[2_2a3Q3W3d3l4z6T6e6f6i6|7[8t9T9_Y#bWZ#W#Z(T!b%jm#h#i#l$x%e%h(^(h(i(j*Y*^*b+Z+[+^,o-V.T.Z.[.]._/m/p2d3[3]4a6r7TQ,n&o!p=k$Z$n)s-U-X/V2p4T5w6s:Z:mSR=n'XU']!e%i*ZR2s-`%SdOPWXYZstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$_$a$e%m%t&R&k&n&r&t&u&w&{'T'b'r(T(V(](d(x(z)O)}*i+X+],p,s,x-i-q.P.V.t.{/n0]0l0r1S1r2S2T2V2X2[2_2a3Q3W3l4z6T6e6f6i6|8t9T9_!r)_$Z$n'X)s-U-X/V2p4T5w6s:Z:mSQ,m&oQ0x+gQ3`.gQ7Y3dR9e7[!b$Tc#Y%q(S(Y(t(y)Z)[)`)g+x-x-}.S.U.s.v/b0p3O3V3k3{5X5c6{7Q7a9]:oS)^)q-Z.|2k2n3p4P4X6u7b7k7l8k9X9g9m9n;W;`=vQ>X>ZR>Y>['QkOPWXYZstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$Z$_$a$e$n%m%t&R&k&n&o&r&t&u&w&{'T'X'b'r(T(V(](d(x(z)O)s)}*i+X+]+g,p,s,x-U-X-i-q.P.V.g.t.{/V/n0]0l0r1S1r2S2T2V2X2[2_2a2p3Q3W3d3l4T4z5w6T6e6f6i6s6|7[8t9T9_:Z:mSS$oh$pR4U/U'XgOPWXYZhstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$Z$_$a$e$n$p%m%t&R&k&n&o&r&t&u&w&{'T'X'b'r(T(V(](d(x(z)O)s)}*i+X+]+g,p,s,x-U-X-i-q.P.V.g.t.{/U/V/n0]0l0r1S1r2S2T2V2X2[2_2a2p3Q3W3d3l4T4z5w6T6e6f6i6s6|7[8t9T9_:Z:mST$kf$qQ$ifS)j$l)nR)v$qT$jf$qT)l$l)n'XhOPWXYZhstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$Z$_$a$e$n$p%m%t&R&k&n&o&r&t&u&w&{'T'X'b'r(T(V(](d(x(z)O)s)}*i+X+]+g,p,s,x-U-X-i-q.P.V.g.t.{/U/V/n0]0l0r1S1r2S2T2V2X2[2_2a2p3Q3W3d3l4T4z5w6T6e6f6i6s6|7[8t9T9_:Z:mST$oh$pQ$rhR)u$p%^jOPWXYZstuvw!Z!`!g!o#S#W#Z#d#o#u#x#{$O$P$Q$R$S$T$U$V$W$X$_$a$e%m%t&R&k&n&o&r&t&u&w&{'T'b'r(T(V(](d(x(z)O)}*i+X+]+g,p,s,x-i-q.P.V.g.t.{/n0]0l0r1S1r2S2T2V2X2[2_2a3Q3W3d3l4z6T6e6f6i6|7[8t9T9_!s>Q$Z$n'X)s-U-X/V2p4T5w6s:Z:mS#glOPXZst!Z!`!o#S#d#o#{$n%m&k&n&o&r&t&u&w&{'T'b)O)s*i+]+g,p,s,x-i.g/V/n0]0l1r2S2T2V2X2[2_2a3d4T4z6T6e6f6i7[8t9T!U%Ri$d%O%Q%^%_%c*R*T*a*w*x/P/x0`0b0i0j0o4_5Q8V9p>P>X>Y#f(w#v$b$c$x${)y*V*Y*g+f+i,S,V.f/d/m/y/{1f1i1q3c4^4j4o5[5_6S7W7v8Q8[8q9b9y:P:`:r;Q;[;d;k]>^Q+T%aQ/c*Oo4OP>X>YQ*c$zU*l$|*Z*oQ+U%bQ0W*m#f=q#v$b$c$x${)y*V*Y*g+f+i,S,V.f/d/m/y/{1f1i1q3c4^4j4o5[5_6S7W7v8Q8[8q9b9y:P:`:r;Q;[;d;k]>^n=rTQ=x>UQ=y>VR=z>W!U%Ri$d%O%Q%^%_%c*R*T*a*w*x/P/x0`0b0i0j0o4_5Q8V9p>P>X>Y#f(w#v$b$c$x${)y*V*Y*g+f+i,S,V.f/d/m/y/{1f1i1q3c4^4j4o5[5_6S7W7v8Q8[8q9b9y:P:`:r;Q;[;d;k]>^o4OP>X>Y>]>^Q,U&]Q1h,WQ5s1gR8h5tV*n$|*Z*oU*n$|*Z*oT5z1o5{S0P*i/nQ4w0]T8S4z:]Q+j%xQ0V*lQ1O+kQ1u,aQ6W1vQ8v6XQ:c8wR;^:d!U%Oi$d%O%Q%^%_%c*R*T*a*w*x/P/x0`0b0i0j0o4_5Q8V9p>P>X>Yx*R$v)e*S*u+V/v0d0e4R4g5R5S5W7p8U:R:x=p=}>OS0`*t0a#f]>^nZ>[`=T3}7c7f7j9h:t:w;yS=_.l3iT=`7e9k!U%Qi$d%O%Q%^%_%c*R*T*a*w*x/P/x0`0b0i0j0o4_5Q8V9p>P>X>Y|*T$v)e*U*t+V/g/v0d0e4R4g4|5R5S5W7p8U:R:x=p=}>OS0b*u0c#f]>^nZ>[d=V3}7d7e7j9h9i:t:u:w;yS=a.m3jT=b7f9lrnOXst!V!Z#d%m&i&r&t&u&w,s,x2[2_Q&f!UR,p&ornOXst!V!Z#d%m&i&r&t&u&w,s,x2[2_R&f!UQ,Y&^R1d,RsnOXst!V!Z#d%m&i&r&t&u&w,s,x2[2_Q1p,_S6R1s1tU8p6P6Q6US:_8r8sS;Y:^:aQ;m;ZR;w;nQ&m!VR,i&iR6_1|R:f8yW&Q|&V&W,OR1Z+vQ&r!WR,s&sR,y&xT2],x2_R,}&yQ,|&yR2f,}Q'y!{R-y'ySsOtQ#dXT%ps#dQ#OTR'{#OQ#RUR'}#RQ){$uR/`){Q#UVR(Q#UQ#XWU(W#X(X.QQ(X#YR.Q(YQ-^'YR2r-^Q.u(yS3m.u3nR3n.vQ-e'`R2v-eY!rQ'`-e1o5{R'j!rQ/Q)eR4S/QU#_W%h*YU(_#_(`.RQ(`#`R.R(ZQ-a']R2t-at`OXst!V!Z#d%m&i&k&r&t&u&w,s,x2[2_S#hZ%eU#r`#h.[R.[(jQ(k#jQ.X(gW.a(k.X3X7RQ3X.YR7R3YQ)n$lR/W)nQ$phR)t$pQ$`cU)a$`-|O>Z>[Q/z*eU4k/z4m7xQ4m/|R7x4lS*o$|*ZR0Y*ox*S$v)e*t*u+V/v0d0e4R4g5R5S5W7p8U:R:x=p=}>O!d.j(u)c*[*e.l.m.q/_/k/|0v1e3h4[4h4l5r7]7`7w7z8X8Z9t9|:S:};R;e;j;v>Z>[U/h*S.j7ca7c3}7e7f7j9h:t:w;yQ0a*tQ3i.lU4}0a3i9kR9k7e|*U$v)e*t*u+V/g/v0d0e4R4g4|5R5S5W7p8U:R:x=p=}>O!h.k(u)c*[*e.l.m.q/_/k/|0v1e3f3h4[4h4l5r7]7^7`7w7z8X8Z9t9|:S:};R;e;j;v>Z>[U/j*U.k7de7d3}7e7f7j9h9i:t:u:w;yQ0c*uQ3j.mU5P0c3j9lR9l7fQ*z%UR0g*zQ5]0vR8Y5]Q+_%kR0u+_Q5v1jS8j5v:[R:[8kQ,[&_R1m,[Q5{1oR8m5{Q1{,fS6]1{8zR8z6_Q1U+rW5h1U5j8a:VQ5j1XQ8a5iR:V8bQ+w&QR1[+wQ2_,xR6m2_YrOXst#dQ&v!ZQ+a%mQ,r&rQ,t&tQ,u&uQ,w&wQ2Y,sS2],x2_R6l2[Q%opQ&z!_Q&}!aQ'P!bQ'R!cQ'q!uQ+`%lQ+l%zQ,Q&XQ,h&mQ-P&|W-p'k's't'wQ-w'oQ0X*nQ1P+mQ1c,PS2O,i,lQ2g-OQ2h-RQ2i-SQ2}-oW3P-r-s-v-xQ5a1QQ5m1_Q5q1eQ6V1uQ6a2QQ6k2ZU6z3O3R3UQ6}3SQ8]5bQ8e5oQ8g5rQ8l5zQ8u6WQ8{6`S9[6{7PQ9^7OQ:W8cQ:b8vQ:g8|Q:n9]Q;U:XQ;]:cQ;a:oQ;l;VR;o;^Q%zyQ'd!iQ'o!uU+m%{%|%}Q-W'VU-k'e'f'gS-o'k'uQ0Q*jS1Q+n+oQ2o-YS2{-l-mQ3S-tS4p0R0UQ5b1RQ6v2uQ6y2|Q7O3TU7{4r4s4vQ9z7}R;O9{S$wi>PR*{%VU%Ui%V>PR0f*yQ$viS(u#v+iS)c$b$cQ)e$dQ*[$xS*e${*YQ*t%OQ*u%QQ+Q%^Q+R%_Q+V%cQ.lPQ=}>XQ>O>YQ>Z>]R>[>^Q+O%]Q.nSR#[WR'Z!el!tQ!r!v!y!z'`'l'm'n-e-u1o5{5}S'V!e-]U*j$|*Z*oS-Y'W'_S0U*k*qQ0^*rQ2u-cQ4v0[R4{0_R({#xQ!fQT-d'`-e]!qQ!r'`-e1o5{Q#p]R'i < TypeParamList in out const TypeDefinition extends ThisType this LiteralType ArithOp Number BooleanLiteral TemplateType InterpolationEnd Interpolation InterpolationStart NullType null VoidType void TypeofType typeof MemberExpression . PropertyName [ TemplateString Escape Interpolation super RegExp ] ArrayExpression Spread , } { ObjectExpression Property async get set PropertyDefinition Block : NewTarget new NewExpression ) ( ArgList UnaryExpression delete LogicOp BitOp YieldExpression yield AwaitExpression await ParenthesizedExpression ClassExpression class ClassBody MethodDeclaration Decorator @ MemberExpression PrivatePropertyName CallExpression TypeArgList CompareOp < declare Privacy static abstract override PrivatePropertyDefinition PropertyDeclaration readonly accessor Optional TypeAnnotation Equals StaticBlock FunctionExpression ArrowFunction ParamList ParamList ArrayPattern ObjectPattern PatternProperty Privacy readonly Arrow MemberExpression BinaryExpression ArithOp ArithOp ArithOp ArithOp BitOp CompareOp instanceof satisfies CompareOp BitOp BitOp BitOp LogicOp LogicOp ConditionalExpression LogicOp LogicOp AssignmentExpression UpdateOp PostfixExpression CallExpression InstantiationExpression TaggedTemplateExpression DynamicImport import ImportMeta JSXElement JSXSelfCloseEndTag JSXSelfClosingTag JSXIdentifier JSXBuiltin JSXIdentifier JSXNamespacedName JSXMemberExpression JSXSpreadAttribute JSXAttribute JSXAttributeValue JSXEscape JSXEndTag JSXOpenTag JSXFragmentTag JSXText JSXEscape JSXStartCloseTag JSXCloseTag PrefixCast < ArrowFunction TypeParamList SequenceExpression InstantiationExpression KeyofType keyof UniqueType unique ImportType InferredType infer TypeName ParenthesizedType FunctionSignature ParamList NewSignature IndexedType TupleType Label ArrayType ReadonlyType ObjectType MethodType PropertyType IndexSignature PropertyDefinition CallSignature TypePredicate asserts is NewSignature new UnionType LogicOp IntersectionType LogicOp ConditionalType ParameterizedType ClassDeclaration abstract implements type VariableDeclaration let var using TypeAliasDeclaration InterfaceDeclaration interface EnumDeclaration enum EnumBody NamespaceDeclaration namespace module AmbientDeclaration declare GlobalDeclaration global ClassDeclaration ClassBody AmbientFunctionDeclaration ExportGroup VariableName VariableName ImportDeclaration defer ImportGroup ForStatement for ForSpec ForInSpec ForOfSpec of WhileStatement while WithStatement with DoStatement do IfStatement if else SwitchStatement switch SwitchBody CaseLabel case DefaultLabel TryStatement try CatchClause catch FinallyClause finally ReturnStatement return ThrowStatement throw BreakStatement break ContinueStatement continue DebuggerStatement debugger LabeledStatement ExpressionStatement SingleExpression SingleClassItem",maxTerm:380,context:ci,nodeProps:[["isolate",-8,5,6,14,37,39,51,53,55,""],["group",-26,9,17,19,68,207,211,215,216,218,221,224,234,237,243,245,247,249,252,258,264,266,268,270,272,274,275,"Statement",-34,13,14,32,35,36,42,51,54,55,57,62,70,72,76,80,82,84,85,110,111,120,121,136,139,141,142,143,144,145,147,148,167,169,171,"Expression",-23,31,33,37,41,43,45,173,175,177,178,180,181,182,184,185,186,188,189,190,201,203,205,206,"Type",-3,88,103,109,"ClassItem"],["openedBy",23,"<",38,"InterpolationStart",56,"[",60,"{",73,"(",160,"JSXStartCloseTag"],["closedBy",-2,24,168,">",40,"InterpolationEnd",50,"]",61,"}",74,")",165,"JSXEndTag"]],propSources:[$i],skippedNodes:[0,5,6,278],repeatNodeCount:37,tokenData:"$Fq07[R!bOX%ZXY+gYZ-yZ[+g[]%Z]^.c^p%Zpq+gqr/mrs3cst:_tuEruvJSvwLkwx! Yxy!'iyz!(sz{!)}{|!,q|}!.O}!O!,q!O!P!/Y!P!Q!9j!Q!R#:O!R![#<_![!]#I_!]!^#Jk!^!_#Ku!_!`$![!`!a$$v!a!b$*T!b!c$,r!c!}Er!}#O$-|#O#P$/W#P#Q$4o#Q#R$5y#R#SEr#S#T$7W#T#o$8b#o#p$x#r#s$@U#s$f%Z$f$g+g$g#BYEr#BY#BZ$A`#BZ$ISEr$IS$I_$A`$I_$I|Er$I|$I}$Dk$I}$JO$Dk$JO$JTEr$JT$JU$A`$JU$KVEr$KV$KW$A`$KW&FUEr&FU&FV$A`&FV;'SEr;'S;=`I|<%l?HTEr?HT?HU$A`?HUOEr(n%d_$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z&j&hT$i&jO!^&c!_#o&c#p;'S&c;'S;=`&w<%lO&c&j&zP;=`<%l&c'|'U]$i&j(Z!bOY&}YZ&cZw&}wx&cx!^&}!^!_'}!_#O&}#O#P&c#P#o&}#o#p'}#p;'S&};'S;=`(l<%lO&}!b(SU(Z!bOY'}Zw'}x#O'}#P;'S'};'S;=`(f<%lO'}!b(iP;=`<%l'}'|(oP;=`<%l&}'[(y]$i&j(WpOY(rYZ&cZr(rrs&cs!^(r!^!_)r!_#O(r#O#P&c#P#o(r#o#p)r#p;'S(r;'S;=`*a<%lO(rp)wU(WpOY)rZr)rs#O)r#P;'S)r;'S;=`*Z<%lO)rp*^P;=`<%l)r'[*dP;=`<%l(r#S*nX(Wp(Z!bOY*gZr*grs'}sw*gwx)rx#O*g#P;'S*g;'S;=`+Z<%lO*g#S+^P;=`<%l*g(n+dP;=`<%l%Z07[+rq$i&j(Wp(Z!b'|0/lOX%ZXY+gYZ&cZ[+g[p%Zpq+gqr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p$f%Z$f$g+g$g#BY%Z#BY#BZ+g#BZ$IS%Z$IS$I_+g$I_$JT%Z$JT$JU+g$JU$KV%Z$KV$KW+g$KW&FU%Z&FU&FV+g&FV;'S%Z;'S;=`+a<%l?HT%Z?HT?HU+g?HUO%Z07[.ST(X#S$i&j'}0/lO!^&c!_#o&c#p;'S&c;'S;=`&w<%lO&c07[.n_$i&j(Wp(Z!b'}0/lOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z)3p/x`$i&j!p),Q(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_!`0z!`#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z(KW1V`#v(Ch$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_!`2X!`#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z(KW2d_#v(Ch$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'At3l_(V':f$i&j(Z!bOY4kYZ5qZr4krs7nsw4kwx5qx!^4k!^!_8p!_#O4k#O#P5q#P#o4k#o#p8p#p;'S4k;'S;=`:X<%lO4k(^4r_$i&j(Z!bOY4kYZ5qZr4krs7nsw4kwx5qx!^4k!^!_8p!_#O4k#O#P5q#P#o4k#o#p8p#p;'S4k;'S;=`:X<%lO4k&z5vX$i&jOr5qrs6cs!^5q!^!_6y!_#o5q#o#p6y#p;'S5q;'S;=`7h<%lO5q&z6jT$d`$i&jO!^&c!_#o&c#p;'S&c;'S;=`&w<%lO&c`6|TOr6yrs7]s;'S6y;'S;=`7b<%lO6y`7bO$d``7eP;=`<%l6y&z7kP;=`<%l5q(^7w]$d`$i&j(Z!bOY&}YZ&cZw&}wx&cx!^&}!^!_'}!_#O&}#O#P&c#P#o&}#o#p'}#p;'S&};'S;=`(l<%lO&}!r8uZ(Z!bOY8pYZ6yZr8prs9hsw8pwx6yx#O8p#O#P6y#P;'S8p;'S;=`:R<%lO8p!r9oU$d`(Z!bOY'}Zw'}x#O'}#P;'S'};'S;=`(f<%lO'}!r:UP;=`<%l8p(^:[P;=`<%l4k%9[:hh$i&j(Wp(Z!bOY%ZYZ&cZq%Zqr`#P#o`x!^=^!^!_?q!_#O=^#O#P>`#P#o=^#o#p?q#p;'S=^;'S;=`@h<%lO=^&n>gXWS$i&jOY>`YZ&cZ!^>`!^!_?S!_#o>`#o#p?S#p;'S>`;'S;=`?k<%lO>`S?XSWSOY?SZ;'S?S;'S;=`?e<%lO?SS?hP;=`<%l?S&n?nP;=`<%l>`!f?xWWS(Z!bOY?qZw?qwx?Sx#O?q#O#P?S#P;'S?q;'S;=`@b<%lO?q!f@eP;=`<%l?q(Q@kP;=`<%l=^'`@w]WS$i&j(WpOY@nYZ&cZr@nrs>`s!^@n!^!_Ap!_#O@n#O#P>`#P#o@n#o#pAp#p;'S@n;'S;=`Bg<%lO@ntAwWWS(WpOYApZrAprs?Ss#OAp#O#P?S#P;'SAp;'S;=`Ba<%lOAptBdP;=`<%lAp'`BjP;=`<%l@n#WBvYWS(Wp(Z!bOYBmZrBmrs?qswBmwxApx#OBm#O#P?S#P;'SBm;'S;=`Cf<%lOBm#WCiP;=`<%lBm(rCoP;=`<%l^!Q^$i&j!X7`OY!=yYZ&cZ!P!=y!P!Q!>|!Q!^!=y!^!_!@c!_!}!=y!}#O!CW#O#P!Dy#P#o!=y#o#p!@c#p;'S!=y;'S;=`!Ek<%lO!=y|#X#Z&c#Z#[!>|#[#]&c#]#^!>|#^#a&c#a#b!>|#b#g&c#g#h!>|#h#i&c#i#j!>|#j#k!>|#k#m&c#m#n!>|#n#o&c#p;'S&c;'S;=`&w<%lO&c7`!@hX!X7`OY!@cZ!P!@c!P!Q!AT!Q!}!@c!}#O!Ar#O#P!Bq#P;'S!@c;'S;=`!CQ<%lO!@c7`!AYW!X7`#W#X!AT#Z#[!AT#]#^!AT#a#b!AT#g#h!AT#i#j!AT#j#k!AT#m#n!AT7`!AuVOY!ArZ#O!Ar#O#P!B[#P#Q!@c#Q;'S!Ar;'S;=`!Bk<%lO!Ar7`!B_SOY!ArZ;'S!Ar;'S;=`!Bk<%lO!Ar7`!BnP;=`<%l!Ar7`!BtSOY!@cZ;'S!@c;'S;=`!CQ<%lO!@c7`!CTP;=`<%l!@c^!Ezl$i&j(Z!b!X7`OY&}YZ&cZw&}wx&cx!^&}!^!_'}!_#O&}#O#P&c#P#W&}#W#X!Eq#X#Z&}#Z#[!Eq#[#]&}#]#^!Eq#^#a&}#a#b!Eq#b#g&}#g#h!Eq#h#i&}#i#j!Eq#j#k!Eq#k#m&}#m#n!Eq#n#o&}#o#p'}#p;'S&};'S;=`(l<%lO&}8r!GyZ(Z!b!X7`OY!GrZw!Grwx!@cx!P!Gr!P!Q!Hl!Q!}!Gr!}#O!JU#O#P!Bq#P;'S!Gr;'S;=`!J|<%lO!Gr8r!Hse(Z!b!X7`OY'}Zw'}x#O'}#P#W'}#W#X!Hl#X#Z'}#Z#[!Hl#[#]'}#]#^!Hl#^#a'}#a#b!Hl#b#g'}#g#h!Hl#h#i'}#i#j!Hl#j#k!Hl#k#m'}#m#n!Hl#n;'S'};'S;=`(f<%lO'}8r!JZX(Z!bOY!JUZw!JUwx!Arx#O!JU#O#P!B[#P#Q!Gr#Q;'S!JU;'S;=`!Jv<%lO!JU8r!JyP;=`<%l!JU8r!KPP;=`<%l!Gr>^!KZ^$i&j(Z!bOY!KSYZ&cZw!KSwx!CWx!^!KS!^!_!JU!_#O!KS#O#P!DR#P#Q!^!LYP;=`<%l!KS>^!L`P;=`<%l!_#c#d#Bq#d#l%Z#l#m#Es#m#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#_#c#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#>j_$i&j(Wp(Z!bs'9tOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#?rd$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q!R#AQ!R!S#AQ!S!^%Z!^!_*g!_#O%Z#O#P&c#P#R%Z#R#S#AQ#S#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#A]f$i&j(Wp(Z!bs'9tOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q!R#AQ!R!S#AQ!S!^%Z!^!_*g!_#O%Z#O#P&c#P#R%Z#R#S#AQ#S#b%Z#b#c#>_#c#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#Bzc$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q!Y#DV!Y!^%Z!^!_*g!_#O%Z#O#P&c#P#R%Z#R#S#DV#S#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#Dbe$i&j(Wp(Z!bs'9tOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q!Y#DV!Y!^%Z!^!_*g!_#O%Z#O#P&c#P#R%Z#R#S#DV#S#b%Z#b#c#>_#c#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#E|g$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q![#Ge![!^%Z!^!_*g!_!c%Z!c!i#Ge!i#O%Z#O#P&c#P#R%Z#R#S#Ge#S#T%Z#T#Z#Ge#Z#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z'Ad#Gpi$i&j(Wp(Z!bs'9tOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!Q%Z!Q![#Ge![!^%Z!^!_*g!_!c%Z!c!i#Ge!i#O%Z#O#P&c#P#R%Z#R#S#Ge#S#T%Z#T#Z#Ge#Z#b%Z#b#c#>_#c#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z*)x#Il_!g$b$i&j$O)Lv(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z)[#Jv_al$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z04f#LS^h#)`#R-v$?V_!^(CdvBr$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z?O$@a_!q7`$i&j(Wp(Z!bOY%ZYZ&cZr%Zrs&}sw%Zwx(rx!^%Z!^!_*g!_#O%Z#O#P&c#P#o%Z#o#p*g#p;'S%Z;'S;=`+a<%lO%Z07[$Aq|$i&j(Wp(Z!b'|0/l$]#t(T,2j(e$I[OX%ZXY+gYZ&cZ[+g[p%Zpq+gqr%Zrs&}st%ZtuEruw%Zwx(rx}%Z}!OGv!O!Q%Z!Q![Er![!^%Z!^!_*g!_!c%Z!c!}Er!}#O%Z#O#P&c#P#R%Z#R#SEr#S#T%Z#T#oEr#o#p*g#p$f%Z$f$g+g$g#BYEr#BY#BZ$A`#BZ$ISEr$IS$I_$A`$I_$JTEr$JT$JU$A`$JU$KVEr$KV$KW$A`$KW&FUEr&FU&FV$A`&FV;'SEr;'S;=`I|<%l?HTEr?HT?HU$A`?HUOEr07[$D|k$i&j(Wp(Z!b'}0/l$]#t(T,2j(e$I[OY%ZYZ&cZr%Zrs&}st%ZtuEruw%Zwx(rx}%Z}!OGv!O!Q%Z!Q![Er![!^%Z!^!_*g!_!c%Z!c!}Er!}#O%Z#O#P&c#P#R%Z#R#SEr#S#T%Z#T#oEr#o#p*g#p$g%Z$g;'SEr;'S;=`I|<%lOEr",tokenizers:[ui,pi,di,hi,2,3,4,5,6,7,8,9,10,11,12,13,14,Qi,new lO("$S~RRtu[#O#Pg#S#T#|~_P#o#pb~gOx~~jVO#i!P#i#j!U#j#l!P#l#m!q#m;'S!P;'S;=`#v<%lO!P~!UO!U~~!XS!Q![!e!c!i!e#T#Z!e#o#p#Z~!hR!Q![!q!c!i!q#T#Z!q~!tR!Q![!}!c!i!}#T#Z!}~#QR!Q![!P!c!i!P#T#Z!P~#^R!Q![#g!c!i#g#T#Z#g~#jS!Q![#g!c!i#g#T#Z#g#q#r!P~#yP;=`<%l!P~$RO(c~~",141,340),new lO("j~RQYZXz{^~^O(Q~~aP!P!Qd~iO(R~~",25,323)],topRules:{Script:[0,7],SingleExpression:[1,276],SingleClassItem:[2,277]},dialects:{jsx:0,ts:15175},dynamicPrecedences:{80:1,82:1,94:1,169:1,199:1},specialized:[{term:327,get:e=>fi[e]||-1},{term:343,get:e=>mi[e]||-1},{term:95,get:e=>gi[e]||-1}],tokenPrec:15201}),at=[X("function ${name}(${params}) {\n ${}\n}",{label:"function",detail:"definition",type:"keyword"}),X("for (let ${index} = 0; ${index} < ${bound}; ${index}++) {\n ${}\n}",{label:"for",detail:"loop",type:"keyword"}),X("for (let ${name} of ${collection}) {\n ${}\n}",{label:"for",detail:"of loop",type:"keyword"}),X("do {\n ${}\n} while (${})",{label:"do",detail:"loop",type:"keyword"}),X("while (${}) {\n ${}\n}",{label:"while",detail:"loop",type:"keyword"}),X(`try { - \${} -} catch (\${error}) { - \${} -}`,{label:"try",detail:"/ catch block",type:"keyword"}),X("if (${}) {\n ${}\n}",{label:"if",detail:"block",type:"keyword"}),X(`if (\${}) { - \${} -} else { - \${} -}`,{label:"if",detail:"/ else block",type:"keyword"}),X(`class \${name} { - constructor(\${params}) { - \${} - } -}`,{label:"class",detail:"definition",type:"keyword"}),X('import {${names}} from "${module}"\n${}',{label:"import",detail:"named",type:"keyword"}),X('import ${name} from "${module}"\n${}',{label:"import",detail:"default",type:"keyword"})],Si=at.concat([X("interface ${name} {\n ${}\n}",{label:"interface",detail:"definition",type:"keyword"}),X("type ${name} = ${type}",{label:"type",detail:"definition",type:"keyword"}),X("enum ${name} {\n ${}\n}",{label:"enum",detail:"definition",type:"keyword"})]),me=new Re,rt=new Set(["Script","Block","FunctionExpression","FunctionDeclaration","ArrowFunction","MethodDeclaration","ForStatement"]);function E(e){return(O,a)=>{let t=O.node.getChild("VariableDefinition");return t&&a(t,e),!0}}const Zi=["FunctionDeclaration"],Xi={FunctionDeclaration:E("function"),ClassDeclaration:E("class"),ClassExpression:()=>!0,EnumDeclaration:E("constant"),TypeAliasDeclaration:E("type"),NamespaceDeclaration:E("namespace"),VariableDefinition(e,O){e.matchContext(Zi)||O(e,"variable")},TypeDefinition(e,O){O(e,"type")},__proto__:null};function it(e,O){let a=me.get(O);if(a)return a;let t=[],r=!0;function s(i,l){let n=e.sliceString(i.from,i.to);t.push({label:n,type:l})}return O.cursor(RO.IncludeAnonymous).iterate(i=>{if(r)r=!1;else if(i.name){let l=Xi[i.name];if(l&&l(i,s)||rt.has(i.name))return!1}else if(i.to-i.from>8192){for(let l of it(e,i.node))t.push(l);return!1}}),me.set(O,t),t}const ge=/^[\w$\xa1-\uffff][\w$\d\xa1-\uffff]*$/,st=["TemplateString","String","RegExp","LineComment","BlockComment","VariableDefinition","TypeDefinition","Label","PropertyDefinition","PropertyName","PrivatePropertyDefinition","PrivatePropertyName","JSXText","JSXAttributeValue","JSXOpenTag","JSXCloseTag","JSXSelfClosingTag",".","?."];function bi(e){let O=U(e.state).resolveInner(e.pos,-1);if(st.indexOf(O.name)>-1)return null;let a=O.name=="VariableName"||O.to-O.from<20&&ge.test(e.state.sliceDoc(O.from,O.to));if(!a&&!e.explicit)return null;let t=[];for(let r=O;r;r=r.parent)rt.has(r.name)&&(t=t.concat(it(e.state.doc,r)));return{options:t,from:a?O.from:e.pos,validFor:ge}}const y=B.define({name:"javascript",parser:Pi.configure({props:[K.add({IfStatement:z({except:/^\s*({|else\b)/}),TryStatement:z({except:/^\s*({|catch\b|finally\b)/}),LabeledStatement:Dt,SwitchBody:e=>{let O=e.textAfter,a=/^\s*\}/.test(O),t=/^\s*(case|default)\b/.test(O);return e.baseIndent+(a?0:t?1:2)*e.unit},Block:Bt({closing:"}"}),ArrowFunction:e=>e.baseIndent+e.unit,"TemplateString BlockComment":()=>null,"Statement Property":z({except:/^\s*{/}),JSXElement(e){let O=/^\s*<\//.test(e.textAfter);return e.lineIndent(e.node.from)+(O?0:e.unit)},JSXEscape(e){let O=/\s*\}/.test(e.textAfter);return e.lineIndent(e.node.from)+(O?0:e.unit)},"JSXOpenTag JSXSelfClosingTag"(e){return e.column(e.node.from)+e.unit}}),J.add({"Block ClassBody SwitchBody EnumBody ObjectExpression ArrayExpression ObjectType":zO,BlockComment(e){return{from:e.from+2,to:e.to-2}},JSXElement(e){let O=e.firstChild;if(!O||O.name=="JSXSelfClosingTag")return null;let a=e.lastChild;return{from:O.to,to:a.type.isError?e.to:a.from}},"JSXSelfClosingTag JSXOpenTag"(e){var O;let a=(O=e.firstChild)===null||O===void 0?void 0:O.nextSibling,t=e.lastChild;return!a||a.type.isError?null:{from:a.to,to:t.type.isError?e.to:t.from}}})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"`"]},commentTokens:{line:"//",block:{open:"/*",close:"*/"}},indentOnInput:/^\s*(?:case |default:|\{|\}|<\/)$/,wordChars:"$"}}),lt={test:e=>/^JSX/.test(e.name),facet:Kt({commentTokens:{block:{open:"{/*",close:"*/}"}}})},nt=y.configure({dialect:"ts"},"typescript"),ot=y.configure({dialect:"jsx",props:[Ve.add(e=>e.isTop?[lt]:void 0)]}),ct=y.configure({dialect:"jsx ts",props:[Ve.add(e=>e.isTop?[lt]:void 0)]},"typescript");let Qt=e=>({label:e,type:"keyword"});const ut="break case const continue default delete export extends false finally in instanceof let new return static super switch this throw true typeof var yield".split(" ").map(Qt),ki=ut.concat(["declare","implements","private","protected","public"].map(Qt));function pt(e={}){let O=e.jsx?e.typescript?ct:ot:e.typescript?nt:y,a=e.typescript?Si.concat(ki):at.concat(ut);return new F(O,[y.data.of({autocomplete:ze(st,qe(a))}),y.data.of({autocomplete:bi}),e.jsx?Ti:[]])}function xi(e){for(;;){if(e.name=="JSXOpenTag"||e.name=="JSXSelfClosingTag"||e.name=="JSXFragmentTag")return e;if(e.name=="JSXEscape"||!e.parent)return null;e=e.parent}}function Pe(e,O,a=e.length){for(let t=O==null?void 0:O.firstChild;t;t=t.nextSibling)if(t.name=="JSXIdentifier"||t.name=="JSXBuiltin"||t.name=="JSXNamespacedName"||t.name=="JSXMemberExpression")return e.sliceString(t.from,Math.min(t.to,a));return""}const yi=typeof navigator=="object"&&/Android\b/.test(navigator.userAgent),Ti=R.inputHandler.of((e,O,a,t,r)=>{if((yi?e.composing:e.compositionStarted)||e.state.readOnly||O!=a||t!=">"&&t!="/"||!y.isActiveAt(e.state,O,-1))return!1;let s=r(),{state:i}=s,l=i.changeByRange(n=>{var Q;let{head:p}=n,c=U(i).resolveInner(p-1,-1),$;if(c.name=="JSXStartTag"&&(c=c.parent),!(i.doc.sliceString(p-1,p)!=t||c.name=="JSXAttributeValue"&&c.to>p)){if(t==">"&&c.name=="JSXFragmentTag")return{range:n,changes:{from:p,insert:""}};if(t=="/"&&c.name=="JSXStartCloseTag"){let u=c.parent,h=u.parent;if(h&&u.from==p-2&&(($=Pe(i.doc,h.firstChild,p))||((Q=h.firstChild)===null||Q===void 0?void 0:Q.name)=="JSXFragmentTag")){let m=`${$}>`;return{range:We.cursor(p+m.length,-1),changes:{from:p,insert:m}}}}else if(t==">"){let u=xi(c);if(u&&u.name=="JSXOpenTag"&&!/^\/?>|^<\//.test(i.doc.sliceString(p,p+2))&&($=Pe(i.doc,u,p)))return{range:n,changes:{from:p,insert:``}}}}return{range:n}});return l.changes.empty?!1:(e.dispatch([s,i.update(l,{userEvent:"input.complete",scrollIntoView:!0})]),!0)}),M=["_blank","_self","_top","_parent"],PO=["ascii","utf-8","utf-16","latin1","latin1"],SO=["get","post","put","delete"],ZO=["application/x-www-form-urlencoded","multipart/form-data","text/plain"],x=["true","false"],d={},wi={a:{attrs:{href:null,ping:null,type:null,media:null,target:M,hreflang:null}},abbr:d,address:d,area:{attrs:{alt:null,coords:null,href:null,target:null,ping:null,media:null,hreflang:null,type:null,shape:["default","rect","circle","poly"]}},article:d,aside:d,audio:{attrs:{src:null,mediagroup:null,crossorigin:["anonymous","use-credentials"],preload:["none","metadata","auto"],autoplay:["autoplay"],loop:["loop"],controls:["controls"]}},b:d,base:{attrs:{href:null,target:M}},bdi:d,bdo:d,blockquote:{attrs:{cite:null}},body:d,br:d,button:{attrs:{form:null,formaction:null,name:null,value:null,autofocus:["autofocus"],disabled:["autofocus"],formenctype:ZO,formmethod:SO,formnovalidate:["novalidate"],formtarget:M,type:["submit","reset","button"]}},canvas:{attrs:{width:null,height:null}},caption:d,center:d,cite:d,code:d,col:{attrs:{span:null}},colgroup:{attrs:{span:null}},command:{attrs:{type:["command","checkbox","radio"],label:null,icon:null,radiogroup:null,command:null,title:null,disabled:["disabled"],checked:["checked"]}},data:{attrs:{value:null}},datagrid:{attrs:{disabled:["disabled"],multiple:["multiple"]}},datalist:{attrs:{data:null}},dd:d,del:{attrs:{cite:null,datetime:null}},details:{attrs:{open:["open"]}},dfn:d,div:d,dl:d,dt:d,em:d,embed:{attrs:{src:null,type:null,width:null,height:null}},eventsource:{attrs:{src:null}},fieldset:{attrs:{disabled:["disabled"],form:null,name:null}},figcaption:d,figure:d,footer:d,form:{attrs:{action:null,name:null,"accept-charset":PO,autocomplete:["on","off"],enctype:ZO,method:SO,novalidate:["novalidate"],target:M}},h1:d,h2:d,h3:d,h4:d,h5:d,h6:d,head:{children:["title","base","link","style","meta","script","noscript","command"]},header:d,hgroup:d,hr:d,html:{attrs:{manifest:null}},i:d,iframe:{attrs:{src:null,srcdoc:null,name:null,width:null,height:null,sandbox:["allow-top-navigation","allow-same-origin","allow-forms","allow-scripts"],seamless:["seamless"]}},img:{attrs:{alt:null,src:null,ismap:null,usemap:null,width:null,height:null,crossorigin:["anonymous","use-credentials"]}},input:{attrs:{alt:null,dirname:null,form:null,formaction:null,height:null,list:null,max:null,maxlength:null,min:null,name:null,pattern:null,placeholder:null,size:null,src:null,step:null,value:null,width:null,accept:["audio/*","video/*","image/*"],autocomplete:["on","off"],autofocus:["autofocus"],checked:["checked"],disabled:["disabled"],formenctype:ZO,formmethod:SO,formnovalidate:["novalidate"],formtarget:M,multiple:["multiple"],readonly:["readonly"],required:["required"],type:["hidden","text","search","tel","url","email","password","datetime","date","month","week","time","datetime-local","number","range","color","checkbox","radio","file","submit","image","reset","button"]}},ins:{attrs:{cite:null,datetime:null}},kbd:d,keygen:{attrs:{challenge:null,form:null,name:null,autofocus:["autofocus"],disabled:["disabled"],keytype:["RSA"]}},label:{attrs:{for:null,form:null}},legend:d,li:{attrs:{value:null}},link:{attrs:{href:null,type:null,hreflang:null,media:null,sizes:["all","16x16","16x16 32x32","16x16 32x32 64x64"]}},map:{attrs:{name:null}},mark:d,menu:{attrs:{label:null,type:["list","context","toolbar"]}},meta:{attrs:{content:null,charset:PO,name:["viewport","application-name","author","description","generator","keywords"],"http-equiv":["content-language","content-type","default-style","refresh"]}},meter:{attrs:{value:null,min:null,low:null,high:null,max:null,optimum:null}},nav:d,noscript:d,object:{attrs:{data:null,type:null,name:null,usemap:null,form:null,width:null,height:null,typemustmatch:["typemustmatch"]}},ol:{attrs:{reversed:["reversed"],start:null,type:["1","a","A","i","I"]},children:["li","script","template","ul","ol"]},optgroup:{attrs:{disabled:["disabled"],label:null}},option:{attrs:{disabled:["disabled"],label:null,selected:["selected"],value:null}},output:{attrs:{for:null,form:null,name:null}},p:d,param:{attrs:{name:null,value:null}},pre:d,progress:{attrs:{value:null,max:null}},q:{attrs:{cite:null}},rp:d,rt:d,ruby:d,samp:d,script:{attrs:{type:["text/javascript"],src:null,async:["async"],defer:["defer"],charset:PO}},section:d,select:{attrs:{form:null,name:null,size:null,autofocus:["autofocus"],disabled:["disabled"],multiple:["multiple"]}},slot:{attrs:{name:null}},small:d,source:{attrs:{src:null,type:null,media:null}},span:d,strong:d,style:{attrs:{type:["text/css"],media:null,scoped:null}},sub:d,summary:d,sup:d,table:d,tbody:d,td:{attrs:{colspan:null,rowspan:null,headers:null}},template:d,textarea:{attrs:{dirname:null,form:null,maxlength:null,name:null,placeholder:null,rows:null,cols:null,autofocus:["autofocus"],disabled:["disabled"],readonly:["readonly"],required:["required"],wrap:["soft","hard"]}},tfoot:d,th:{attrs:{colspan:null,rowspan:null,headers:null,scope:["row","col","rowgroup","colgroup"]}},thead:d,time:{attrs:{datetime:null}},title:d,tr:d,track:{attrs:{src:null,label:null,default:null,kind:["subtitles","captions","descriptions","chapters","metadata"],srclang:null}},ul:{children:["li","script","template","ul","ol"]},var:d,video:{attrs:{src:null,poster:null,width:null,height:null,crossorigin:["anonymous","use-credentials"],preload:["auto","metadata","none"],autoplay:["autoplay"],mediagroup:["movie"],muted:["muted"],controls:["controls"]}},wbr:d},dt={accesskey:null,class:null,contenteditable:x,contextmenu:null,dir:["ltr","rtl","auto"],draggable:["true","false","auto"],dropzone:["copy","move","link","string:","file:"],hidden:["hidden"],id:null,inert:["inert"],itemid:null,itemprop:null,itemref:null,itemscope:["itemscope"],itemtype:null,lang:["ar","bn","de","en-GB","en-US","es","fr","hi","id","ja","pa","pt","ru","tr","zh"],spellcheck:x,autocorrect:x,autocapitalize:x,style:null,tabindex:null,title:null,translate:["yes","no"],rel:["stylesheet","alternate","author","bookmark","help","license","next","nofollow","noreferrer","prefetch","prev","search","tag"],role:"alert application article banner button cell checkbox complementary contentinfo dialog document feed figure form grid gridcell heading img list listbox listitem main navigation region row rowgroup search switch tab table tabpanel textbox timer".split(" "),"aria-activedescendant":null,"aria-atomic":x,"aria-autocomplete":["inline","list","both","none"],"aria-busy":x,"aria-checked":["true","false","mixed","undefined"],"aria-controls":null,"aria-describedby":null,"aria-disabled":x,"aria-dropeffect":null,"aria-expanded":["true","false","undefined"],"aria-flowto":null,"aria-grabbed":["true","false","undefined"],"aria-haspopup":x,"aria-hidden":x,"aria-invalid":["true","false","grammar","spelling"],"aria-label":null,"aria-labelledby":null,"aria-level":null,"aria-live":["off","polite","assertive"],"aria-multiline":x,"aria-multiselectable":x,"aria-owns":null,"aria-posinset":null,"aria-pressed":["true","false","mixed","undefined"],"aria-readonly":x,"aria-relevant":null,"aria-required":x,"aria-selected":["true","false","undefined"],"aria-setsize":null,"aria-sort":["ascending","descending","none","other"],"aria-valuemax":null,"aria-valuemin":null,"aria-valuenow":null,"aria-valuetext":null},ht="beforeunload copy cut dragstart dragover dragleave dragenter dragend drag paste focus blur change click load mousedown mouseenter mouseleave mouseup keydown keyup resize scroll unload".split(" ").map(e=>"on"+e);for(let e of ht)dt[e]=null;class cO{constructor(O,a){this.tags={...wi,...O},this.globalAttrs={...dt,...a},this.allTags=Object.keys(this.tags),this.globalAttrNames=Object.keys(this.globalAttrs)}}cO.default=new cO;function W(e,O,a=e.length){if(!O)return"";let t=O.firstChild,r=t&&t.getChild("TagName");return r?e.sliceString(r.from,Math.min(r.to,a)):""}function G(e,O=!1){for(;e;e=e.parent)if(e.name=="Element")if(O)O=!1;else return e;return null}function $t(e,O,a){let t=a.tags[W(e,G(O))];return(t==null?void 0:t.children)||a.allTags}function CO(e,O){let a=[];for(let t=G(O);t&&!t.type.isTop;t=G(t.parent)){let r=W(e,t);if(r&&t.lastChild.name=="CloseTag")break;r&&a.indexOf(r)<0&&(O.name=="EndTag"||O.from>=t.firstChild.to)&&a.push(r)}return a}const ft=/^[:\-\.\w\u00b7-\uffff]*$/;function Se(e,O,a,t,r){let s=/\s*>/.test(e.sliceDoc(r,r+5))?"":">",i=G(a,a.name=="StartTag"||a.name=="TagName");return{from:t,to:r,options:$t(e.doc,i,O).map(l=>({label:l,type:"type"})).concat(CO(e.doc,a).map((l,n)=>({label:"/"+l,apply:"/"+l+s,type:"type",boost:99-n}))),validFor:/^\/?[:\-\.\w\u00b7-\uffff]*$/}}function Ze(e,O,a,t){let r=/\s*>/.test(e.sliceDoc(t,t+5))?"":">";return{from:a,to:t,options:CO(e.doc,O).map((s,i)=>({label:s,apply:s+r,type:"type",boost:99-i})),validFor:ft}}function vi(e,O,a,t){let r=[],s=0;for(let i of $t(e.doc,a,O))r.push({label:"<"+i,type:"type"});for(let i of CO(e.doc,a))r.push({label:"",type:"type",boost:99-s++});return{from:t,to:t,options:r,validFor:/^<\/?[:\-\.\w\u00b7-\uffff]*$/}}function ji(e,O,a,t,r){let s=G(a),i=s?O.tags[W(e.doc,s)]:null,l=i&&i.attrs?Object.keys(i.attrs):[],n=i&&i.globalAttrs===!1?l:l.length?l.concat(O.globalAttrNames):O.globalAttrNames;return{from:t,to:r,options:n.map(Q=>({label:Q,type:"property"})),validFor:ft}}function _i(e,O,a,t,r){var s;let i=(s=a.parent)===null||s===void 0?void 0:s.getChild("AttributeName"),l=[],n;if(i){let Q=e.sliceDoc(i.from,i.to),p=O.globalAttrs[Q];if(!p){let c=G(a),$=c?O.tags[W(e.doc,c)]:null;p=($==null?void 0:$.attrs)&&$.attrs[Q]}if(p){let c=e.sliceDoc(t,r).toLowerCase(),$='"',u='"';/^['"]/.test(c)?(n=c[0]=='"'?/^[^"]*$/:/^[^']*$/,$="",u=e.sliceDoc(r,r+1)==c[0]?"":c[0],c=c.slice(1),t++):n=/^[^\s<>='"]*$/;for(let h of p)l.push({label:h,apply:$+h+u,type:"constant"})}}return{from:t,to:r,options:l,validFor:n}}function Yi(e,O){let{state:a,pos:t}=O,r=U(a).resolveInner(t,-1),s=r.resolve(t);for(let i=t,l;s==r&&(l=r.childBefore(i));){let n=l.lastChild;if(!n||!n.type.isError||n.fromYi(t,r)}const zi=y.parser.configure({top:"SingleExpression"}),mt=[{tag:"script",attrs:e=>e.type=="text/typescript"||e.lang=="ts",parser:nt.parser},{tag:"script",attrs:e=>e.type=="text/babel"||e.type=="text/jsx",parser:ot.parser},{tag:"script",attrs:e=>e.type=="text/typescript-jsx",parser:ct.parser},{tag:"script",attrs(e){return/^(importmap|speculationrules|application\/(.+\+)?json)$/i.test(e.type)},parser:zi},{tag:"script",attrs(e){return!e.type||/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(e.type)},parser:y.parser},{tag:"style",attrs(e){return(!e.lang||e.lang=="css")&&(!e.type||/^(text\/)?(x-)?(stylesheet|css)$/i.test(e.type))},parser:oO.parser}],gt=[{name:"style",parser:oO.parser.configure({top:"Styles"})}].concat(ht.map(e=>({name:e,parser:y.parser}))),Pt=B.define({name:"html",parser:lr.configure({props:[K.add({Element(e){let O=/^(\s*)(<\/)?/.exec(e.textAfter);return e.node.to<=e.pos+O[0].length?e.continue():e.lineIndent(e.node.from)+(O[2]?0:e.unit)},"OpenTag CloseTag SelfClosingTag"(e){return e.column(e.node.from)+e.unit},Document(e){if(e.pos+/\s*/.exec(e.textAfter)[0].lengthe.getChild("TagName")})]}),languageData:{commentTokens:{block:{open:""}},indentOnInput:/^\s*<\/\w+\W$/,wordChars:"-_"}}),rO=Pt.configure({wrap:Ke(mt,gt)});function qi(e={}){let O="",a;e.matchClosingTags===!1&&(O="noMatch"),e.selfClosingTags===!0&&(O=(O?O+" ":"")+"selfClosing"),(e.nestedLanguages&&e.nestedLanguages.length||e.nestedAttributes&&e.nestedAttributes.length)&&(a=Ke((e.nestedLanguages||[]).concat(mt),(e.nestedAttributes||[]).concat(gt)));let t=a?Pt.configure({wrap:a,dialect:O}):O?rO.configure({dialect:O}):rO;return new F(t,[rO.data.of({autocomplete:Ri(e)}),e.autoCloseTags!==!1?Vi:[],pt().support,Er().support])}const Xe=new Set("area base br col command embed frame hr img input keygen link meta param source track wbr menuitem".split(" ")),Vi=R.inputHandler.of((e,O,a,t,r)=>{if(e.composing||e.state.readOnly||O!=a||t!=">"&&t!="/"||!rO.isActiveAt(e.state,O,-1))return!1;let s=r(),{state:i}=s,l=i.changeByRange(n=>{var Q,p,c;let $=i.doc.sliceString(n.from-1,n.to)==t,{head:u}=n,h=U(i).resolveInner(u,-1),m;if($&&t==">"&&h.name=="EndTag"){let g=h.parent;if(((p=(Q=g.parent)===null||Q===void 0?void 0:Q.lastChild)===null||p===void 0?void 0:p.name)!="CloseTag"&&(m=W(i.doc,g.parent,u))&&!Xe.has(m)){let Z=u+(i.doc.sliceString(u,u+1)===">"?1:0),S=``;return{range:n,changes:{from:u,to:Z,insert:S}}}}else if($&&t=="/"&&h.name=="IncompleteCloseTag"){let g=h.parent;if(h.from==u-2&&((c=g.lastChild)===null||c===void 0?void 0:c.name)!="CloseTag"&&(m=W(i.doc,g,u))&&!Xe.has(m)){let Z=u+(i.doc.sliceString(u,u+1)===">"?1:0),S=`${m}>`;return{range:We.cursor(u+S.length,-1),changes:{from:u,to:Z,insert:S}}}}return{range:n}});return l.changes.empty?!1:(e.dispatch([s,i.update(l,{userEvent:"input.complete",scrollIntoView:!0})]),!0)}),Wi=D({String:o.string,Number:o.number,"True False":o.bool,PropertyName:o.propertyName,Null:o.null,", :":o.separator,"[ ]":o.squareBracket,"{ }":o.brace}),Gi=j.deserialize({version:14,states:"$bOVQPOOOOQO'#Cb'#CbOnQPO'#CeOvQPO'#ClOOQO'#Cr'#CrQOQPOOOOQO'#Cg'#CgO}QPO'#CfO!SQPO'#CtOOQO,59P,59PO![QPO,59PO!aQPO'#CuOOQO,59W,59WO!iQPO,59WOVQPO,59QOqQPO'#CmO!nQPO,59`OOQO1G.k1G.kOVQPO'#CnO!vQPO,59aOOQO1G.r1G.rOOQO1G.l1G.lOOQO,59X,59XOOQO-E6k-E6kOOQO,59Y,59YOOQO-E6l-E6l",stateData:"#O~OeOS~OQSORSOSSOTSOWQO_ROgPO~OVXOgUO~O^[O~PVO[^O~O]_OVhX~OVaO~O]bO^iX~O^dO~O]_OVha~O]bO^ia~O",goto:"!kjPPPPPPkPPkqwPPPPk{!RPPP!XP!e!hXSOR^bQWQRf_TVQ_Q`WRg`QcZRicQTOQZRQe^RhbRYQR]R",nodeNames:"⚠ JsonText True False Null Number String } { Object Property PropertyName : , ] [ Array",maxTerm:25,nodeProps:[["isolate",-2,6,11,""],["openedBy",7,"{",14,"["],["closedBy",8,"}",15,"]"]],propSources:[Wi],skippedNodes:[0],repeatNodeCount:2,tokenData:"(|~RaXY!WYZ!W]^!Wpq!Wrs!]|}$u}!O$z!Q!R%T!R![&c![!]&t!}#O&y#P#Q'O#Y#Z'T#b#c'r#h#i(Z#o#p(r#q#r(w~!]Oe~~!`Wpq!]qr!]rs!xs#O!]#O#P!}#P;'S!];'S;=`$o<%lO!]~!}Og~~#QXrs!]!P!Q!]#O#P!]#U#V!]#Y#Z!]#b#c!]#f#g!]#h#i!]#i#j#m~#pR!Q![#y!c!i#y#T#Z#y~#|R!Q![$V!c!i$V#T#Z$V~$YR!Q![$c!c!i$c#T#Z$c~$fR!Q![!]!c!i!]#T#Z!]~$rP;=`<%l!]~$zO]~~$}Q!Q!R%T!R![&c~%YRT~!O!P%c!g!h%w#X#Y%w~%fP!Q![%i~%nRT~!Q![%i!g!h%w#X#Y%w~%zR{|&T}!O&T!Q![&Z~&WP!Q![&Z~&`PT~!Q![&Z~&hST~!O!P%c!Q![&c!g!h%w#X#Y%w~&yO[~~'OO_~~'TO^~~'WP#T#U'Z~'^P#`#a'a~'dP#g#h'g~'jP#X#Y'm~'rOR~~'uP#i#j'x~'{P#`#a(O~(RP#`#a(U~(ZOS~~(^P#f#g(a~(dP#i#j(g~(jP#X#Y(m~(rOQ~~(wOW~~(|OV~",tokenizers:[0],topRules:{JsonText:[0,1]},tokenPrec:0}),Ci=B.define({name:"json",parser:Gi.configure({props:[K.add({Object:z({except:/^\s*\}/}),Array:z({except:/^\s*\]/})}),J.add({"Object Array":zO})]}),languageData:{closeBrackets:{brackets:["[","{",'"']},indentOnInput:/^\s*[\}\]]$/}});function Ui(){return new F(Ci)}const Ai=36,be=1,Ei=2,q=3,XO=4,Mi=5,Li=6,Ii=7,Ni=8,Di=9,Bi=10,Ki=11,Ji=12,Fi=13,Hi=14,Os=15,es=16,ts=17,ke=18,as=19,St=20,Zt=21,xe=22,rs=23,is=24;function wO(e){return e>=65&&e<=90||e>=97&&e<=122||e>=48&&e<=57}function ss(e){return e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70}function Y(e,O,a){for(let t=!1;;){if(e.next<0)return;if(e.next==O&&!t){e.advance();return}t=a&&!t&&e.next==92,e.advance()}}function ls(e,O){O:for(;;){if(e.next<0)return;if(e.next==36){e.advance();for(let a=0;a)".charCodeAt(a);for(;;){if(e.next<0)return;if(e.next==t&&e.peek(1)==39){e.advance(2);return}e.advance()}}function vO(e,O){for(;!(e.next!=95&&!wO(e.next));)O!=null&&(O+=String.fromCharCode(e.next)),e.advance();return O}function os(e){if(e.next==39||e.next==34||e.next==96){let O=e.next;e.advance(),Y(e,O,!1)}else vO(e)}function ye(e,O){for(;e.next==48||e.next==49;)e.advance();O&&e.next==O&&e.advance()}function Te(e,O){for(;;){if(e.next==46){if(O)break;O=!0}else if(e.next<48||e.next>57)break;e.advance()}if(e.next==69||e.next==101)for(e.advance(),(e.next==43||e.next==45)&&e.advance();e.next>=48&&e.next<=57;)e.advance()}function we(e){for(;!(e.next<0||e.next==10);)e.advance()}function _(e,O){for(let a=0;a!=&|~^/",specialVar:"?",identifierQuotes:'"',caseInsensitiveIdentifiers:!1,words:Xt(Qs,cs)};function us(e,O,a,t){let r={};for(let s in jO)r[s]=(e.hasOwnProperty(s)?e:jO)[s];return O&&(r.words=Xt(O,a||"",t)),r}function bt(e){return new b(O=>{var a;let{next:t}=O;if(O.advance(),_(t,bO)){for(;_(O.next,bO);)O.advance();O.acceptToken(Ai)}else if(t==36&&e.doubleDollarQuotedStrings){let r=vO(O,"");O.next==36&&(O.advance(),ls(O,r),O.acceptToken(q))}else if(t==39||t==34&&e.doubleQuotedStrings)Y(O,t,e.backslashEscapes),O.acceptToken(q);else if(t==35&&e.hashComments||t==47&&O.next==47&&e.slashComments)we(O),O.acceptToken(be);else if(t==45&&O.next==45&&(!e.spaceAfterDashes||O.peek(1)==32))we(O),O.acceptToken(be);else if(t==47&&O.next==42){O.advance();for(let r=1;;){let s=O.next;if(O.next<0)break;if(O.advance(),s==42&&O.next==47){if(r--,O.advance(),!r)break}else s==47&&O.next==42&&(r++,O.advance())}O.acceptToken(Ei)}else if((t==101||t==69)&&O.next==39)O.advance(),Y(O,39,!0),O.acceptToken(q);else if((t==110||t==78)&&O.next==39&&e.charSetCasts)O.advance(),Y(O,39,e.backslashEscapes),O.acceptToken(q);else if(t==95&&e.charSetCasts)for(let r=0;;r++){if(O.next==39&&r>1){O.advance(),Y(O,39,e.backslashEscapes),O.acceptToken(q);break}if(!wO(O.next))break;O.advance()}else if(e.plsqlQuotingMechanism&&(t==113||t==81)&&O.next==39&&O.peek(1)>0&&!_(O.peek(1),bO)){let r=O.peek(1);O.advance(2),ns(O,r),O.acceptToken(q)}else if(_(t,e.identifierQuotes)){const r=t==91?93:t;Y(O,r,!1),O.acceptToken(as)}else if(t==40)O.acceptToken(Ii);else if(t==41)O.acceptToken(Ni);else if(t==123)O.acceptToken(Di);else if(t==125)O.acceptToken(Bi);else if(t==91)O.acceptToken(Ki);else if(t==93)O.acceptToken(Ji);else if(t==59)O.acceptToken(Fi);else if(e.unquotedBitLiterals&&t==48&&O.next==98)O.advance(),ye(O),O.acceptToken(xe);else if((t==98||t==66)&&(O.next==39||O.next==34)){const r=O.next;O.advance(),e.treatBitsAsBytes?(Y(O,r,e.backslashEscapes),O.acceptToken(rs)):(ye(O,r),O.acceptToken(xe))}else if(t==48&&(O.next==120||O.next==88)||(t==120||t==88)&&O.next==39){let r=O.next==39;for(O.advance();ss(O.next);)O.advance();r&&O.next==39&&O.advance(),O.acceptToken(XO)}else if(t==46&&O.next>=48&&O.next<=57)Te(O,!0),O.acceptToken(XO);else if(t==46)O.acceptToken(Hi);else if(t>=48&&t<=57)Te(O,!1),O.acceptToken(XO);else if(_(t,e.operatorChars)){for(;_(O.next,e.operatorChars);)O.advance();O.acceptToken(Os)}else if(_(t,e.specialVar))O.next==t&&O.advance(),os(O),O.acceptToken(ts);else if(t==58||t==44)O.acceptToken(es);else if(wO(t)){let r=vO(O,String.fromCharCode(t));O.acceptToken(O.next==46||O.peek(-r.length-1)==46?ke:(a=e.words[r.toLowerCase()])!==null&&a!==void 0?a:ke)}})}const kt=bt(jO),ps=j.deserialize({version:14,states:"%vQ]QQOOO#wQRO'#DSO$OQQO'#CwO%eQQO'#CxO%lQQO'#CyO%sQQO'#CzOOQQ'#DS'#DSOOQQ'#C}'#C}O'UQRO'#C{OOQQ'#Cv'#CvOOQQ'#C|'#C|Q]QQOOQOQQOOO'`QQO'#DOO(xQRO,59cO)PQQO,59cO)UQQO'#DSOOQQ,59d,59dO)cQQO,59dOOQQ,59e,59eO)jQQO,59eOOQQ,59f,59fO)qQQO,59fOOQQ-E6{-E6{OOQQ,59b,59bOOQQ-E6z-E6zOOQQ,59j,59jOOQQ-E6|-E6|O+VQRO1G.}O+^QQO,59cOOQQ1G/O1G/OOOQQ1G/P1G/POOQQ1G/Q1G/QP+kQQO'#C}O+rQQO1G.}O)PQQO,59cO,PQQO'#Cw",stateData:",[~OtOSPOSQOS~ORUOSUOTUOUUOVROXSOZTO]XO^QO_UO`UOaPObPOcPOdUOeUOfUOgUOhUO~O^]ORvXSvXTvXUvXVvXXvXZvX]vX_vX`vXavXbvXcvXdvXevXfvXgvXhvX~OsvX~P!jOa_Ob_Oc_O~ORUOSUOTUOUUOVROXSOZTO^tO_UO`UOa`Ob`Oc`OdUOeUOfUOgUOhUO~OWaO~P$ZOYcO~P$ZO[eO~P$ZORUOSUOTUOUUOVROXSOZTO^QO_UO`UOaPObPOcPOdUOeUOfUOgUOhUO~O]hOsoX~P%zOajObjOcjO~O^]ORkaSkaTkaUkaVkaXkaZka]ka_ka`kaakabkackadkaekafkagkahka~Oska~P'kO^]O~OWvXYvX[vX~P!jOWnO~P$ZOYoO~P$ZO[pO~P$ZO^]ORkiSkiTkiUkiVkiXkiZki]ki_ki`kiakibkickidkiekifkigkihki~Oski~P)xOWkaYka[ka~P'kO]hO~P$ZOWkiYki[ki~P)xOasObsOcsO~O",goto:"#hwPPPPPPPPPPPPPPPPPPPPPPPPPPx||||!Y!^!d!xPPP#[TYOZeUORSTWZbdfqT[OZQZORiZSWOZQbRQdSQfTZgWbdfqQ^PWk^lmrQl_Qm`RrseVORSTWZbdfq",nodeNames:"⚠ LineComment BlockComment String Number Bool Null ( ) { } [ ] ; . Operator Punctuation SpecialVar Identifier QuotedIdentifier Keyword Type Bits Bytes Builtin Script Statement CompositeIdentifier Parens Braces Brackets Statement",maxTerm:38,nodeProps:[["isolate",-4,1,2,3,19,""]],skippedNodes:[0,1,2],repeatNodeCount:3,tokenData:"RORO",tokenizers:[0,kt],topRules:{Script:[0,25]},tokenPrec:0});function _O(e){let O=e.cursor().moveTo(e.from,-1);for(;/Comment/.test(O.name);)O.moveTo(O.from,-1);return O.node}function N(e,O){let a=e.sliceString(O.from,O.to),t=/^([`'"\[])(.*)([`'"\]])$/.exec(a);return t?t[2]:a}function QO(e){return e&&(e.name=="Identifier"||e.name=="QuotedIdentifier")}function ds(e,O){if(O.name=="CompositeIdentifier"){let a=[];for(let t=O.firstChild;t;t=t.nextSibling)QO(t)&&a.push(N(e,t));return a}return[N(e,O)]}function ve(e,O){for(let a=[];;){if(!O||O.name!=".")return a;let t=_O(O);if(!QO(t))return a;a.unshift(N(e,t)),O=_O(t)}}function hs(e,O){let a=U(e).resolveInner(O,-1),t=fs(e.doc,a);return a.name=="Identifier"||a.name=="QuotedIdentifier"||a.name=="Keyword"?{from:a.from,quoted:a.name=="QuotedIdentifier"?e.doc.sliceString(a.from,a.from+1):null,parents:ve(e.doc,_O(a)),aliases:t}:a.name=="."?{from:O,quoted:null,parents:ve(e.doc,a),aliases:t}:{from:O,quoted:null,parents:[],empty:!0,aliases:t}}const $s=new Set("where group having order union intersect except all distinct limit offset fetch for".split(" "));function fs(e,O){let a;for(let r=O;!a;r=r.parent){if(!r)return null;r.name=="Statement"&&(a=r)}let t=null;for(let r=a.firstChild,s=!1,i=null;r;r=r.nextSibling){let l=r.name=="Keyword"?e.sliceString(r.from,r.to).toLowerCase():null,n=null;if(!s)s=l=="from";else if(l=="as"&&i&&QO(r.nextSibling))n=N(e,r.nextSibling);else{if(l&&$s.has(l))break;i&&QO(r)&&(n=N(e,r))}n&&(t||(t=Object.create(null)),t[n]=ds(e,i)),i=/Identifier$/.test(r.name)?r:null}return t}function ms(e,O,a){return a.map(t=>({...t,label:t.label[0]==e?t.label:e+t.label+O,apply:void 0}))}const gs=/^\w*$/,Ps=/^[`'"\[]?\w*[`'"\]]?$/;function je(e){return e.self&&typeof e.self.label=="string"}class UO{constructor(O,a){this.idQuote=O,this.idCaseInsensitive=a,this.list=[],this.children=void 0}child(O){let a=this.children||(this.children=Object.create(null)),t=a[O];return t||(O&&!this.list.some(r=>r.label==O)&&this.list.push(_e(O,"type",this.idQuote,this.idCaseInsensitive)),a[O]=new UO(this.idQuote,this.idCaseInsensitive))}maybeChild(O){return this.children?this.children[O]:null}addCompletion(O){let a=this.list.findIndex(t=>t.label==O.label);a>-1?this.list[a]=O:this.list.push(O)}addCompletions(O){for(let a of O)this.addCompletion(typeof a=="string"?_e(a,"property",this.idQuote,this.idCaseInsensitive):a)}addNamespace(O){Array.isArray(O)?this.addCompletions(O):je(O)?this.addNamespace(O.children):this.addNamespaceObject(O)}addNamespaceObject(O){for(let a of Object.keys(O)){let t=O[a],r=null,s=a.replace(/\\?\./g,l=>l=="."?"\0":l).split("\0"),i=this;je(t)&&(r=t.self,t=t.children);for(let l=0;l{let{parents:c,from:$,quoted:u,empty:h,aliases:m}=hs(p.state,p.pos);if(h&&!p.explicit)return null;m&&c.length==1&&(c=m[c[0]]||c);let g=n;for(let S of c){for(;!g.children||!g.children[S];)if(g==n&&Q)g=Q;else if(g==Q&&t)g=g.child(t);else return null;let T=g.maybeChild(S);if(!T)return null;g=T}let Z=g.list;if(g==n&&m&&(Z=Z.concat(Object.keys(m).map(S=>({label:S,type:"constant"})))),u){let S=u[0],T=xt(S),uO=p.state.sliceDoc(p.pos,p.pos+1)==T;return{from:$,to:uO?p.pos+1:void 0,options:ms(S,T,Z),validFor:Ps}}else return{from:$,options:Z,validFor:gs}}}function Zs(e){return e==Zt?"type":e==St?"keyword":"variable"}function Xs(e,O,a){let t=Object.keys(e).map(r=>a(O?r.toUpperCase():r,Zs(e[r])));return ze(["QuotedIdentifier","String","LineComment","BlockComment","."],qe(t))}let bs=ps.configure({props:[K.add({Statement:z()}),J.add({Statement(e,O){return{from:Math.min(e.from+100,O.doc.lineAt(e.from).to),to:e.to}},BlockComment(e){return{from:e.from+2,to:e.to-2}}}),D({Keyword:o.keyword,Type:o.typeName,Builtin:o.standard(o.name),Bits:o.number,Bytes:o.string,Bool:o.bool,Null:o.null,Number:o.number,String:o.string,Identifier:o.name,QuotedIdentifier:o.special(o.string),SpecialVar:o.special(o.name),LineComment:o.lineComment,BlockComment:o.blockComment,Operator:o.operator,"Semi Punctuation":o.punctuation,"( )":o.paren,"{ }":o.brace,"[ ]":o.squareBracket})]});class C{constructor(O,a,t){this.dialect=O,this.language=a,this.spec=t}get extension(){return this.language.extension}configureLanguage(O,a){return new C(this.dialect,this.language.configure(O,a),this.spec)}static define(O){let a=us(O,O.keywords,O.types,O.builtin),t=B.define({name:"sql",parser:bs.configure({tokenizers:[{from:kt,to:bt(a)}]}),languageData:{commentTokens:{line:"--",block:{open:"/*",close:"*/"}},closeBrackets:{brackets:["(","[","{","'",'"',"`"]}}});return new C(a,t,O)}}function ks(e,O){return{label:e,type:O,boost:-1}}function xs(e,O=!1,a){return Xs(e.dialect.words,O,a||ks)}function ys(e){return e.schema?Ss(e.schema,e.tables,e.schemas,e.defaultTable,e.defaultSchema,e.dialect||AO):()=>null}function Ts(e){return e.schema?(e.dialect||AO).language.data.of({autocomplete:ys(e)}):[]}function Ye(e={}){let O=e.dialect||AO;return new F(O.language,[Ts(e),O.language.data.of({autocomplete:xs(O,e.upperCaseKeywords,e.keywordCompletion)})])}const AO=C.define({});function ws(e){let O;return{c(){O=zt("div"),qt(O,"class","code-editor"),H(O,"min-height",e[0]?e[0]+"px":null),H(O,"max-height",e[1]?e[1]+"px":"auto")},m(a,t){Rt(a,O,t),e[11](O)},p(a,[t]){t&1&&H(O,"min-height",a[0]?a[0]+"px":null),t&2&&H(O,"max-height",a[1]?a[1]+"px":"auto")},i:BO,o:BO,d(a){a&&Yt(O),e[11](null)}}}function vs(e,O,a){let t;Vt(e,Wt,f=>a(12,t=f));const r=Gt();let{id:s=""}=O,{value:i=""}=O,{minHeight:l=null}=O,{maxHeight:n=null}=O,{disabled:Q=!1}=O,{placeholder:p=""}=O,{language:c="javascript"}=O,{singleLine:$=!1}=O,u,h,m=new OO,g=new OO,Z=new OO,S=new OO;function T(){u==null||u.focus()}function uO(){h==null||h.dispatchEvent(new CustomEvent("change",{detail:{value:i},bubbles:!0})),r("change",i)}function EO(){if(!s)return;const f=document.querySelectorAll('[for="'+s+'"]');for(let P of f)P.removeEventListener("click",T)}function MO(){if(!s)return;EO();const f=document.querySelectorAll('[for="'+s+'"]');for(let P of f)P.addEventListener("click",T)}function LO(){switch(c){case"html":return qi();case"json":return Ui();case"sql-create-index":return Ye({dialect:C.define({keywords:"create unique index if not exists on collate asc desc where like isnull notnull date time datetime unixepoch strftime lower upper substr case when then iif if else json_extract json_each json_tree json_array_length json_valid ",operatorChars:"*+-%<>!=&|/~",identifierQuotes:'`"',specialVar:"@:?$"}),upperCaseKeywords:!0});case"sql-select":let f={};for(let P of t)f[P.name]=Ut.getAllCollectionIdentifiers(P);return Ye({dialect:C.define({keywords:"select distinct from where having group by order limit offset join left right inner with like not in match asc desc regexp isnull notnull glob count avg sum min max current random cast as int real text bool date time datetime unixepoch strftime coalesce lower upper substr case when then iif if else json_extract json_each json_tree json_array_length json_valid ",operatorChars:"*+-%<>!=&|/~",identifierQuotes:'`"',specialVar:"@:?$"}),schema:f,upperCaseKeywords:!0});default:return pt()}}Ct(()=>{const f={key:"Enter",run:P=>{$&&r("submit",i)}};return MO(),a(10,u=new R({parent:h,state:A.create({doc:i,extensions:[Ft(),Ht(),Oa(),ea(),ta(),A.allowMultipleSelections.of(!0),aa(ra,{fallback:!0}),ia(),sa(),la(),na(),oa.of([f,...ca,...Qa,da.find(P=>P.key==="Mod-d"),...ua,...pa]),R.lineWrapping,ha({icons:!1}),m.of(LO()),S.of(KO(p)),g.of(R.editable.of(!0)),Z.of(A.readOnly.of(!1)),A.transactionFilter.of(P=>{var IO,NO,DO;if($&&P.newDoc.lines>1){if(!((DO=(NO=(IO=P.changes)==null?void 0:IO.inserted)==null?void 0:NO.filter(Tt=>!!Tt.text.find(wt=>wt)))!=null&&DO.length))return[];P.newDoc.text=[P.newDoc.text.join(" ")]}return P}),R.updateListener.of(P=>{!P.docChanged||Q||(a(3,i=P.state.doc.toString()),uO())})]})})),()=>{EO(),u==null||u.destroy()}});function yt(f){At[f?"unshift":"push"](()=>{h=f,a(2,h)})}return e.$$set=f=>{"id"in f&&a(4,s=f.id),"value"in f&&a(3,i=f.value),"minHeight"in f&&a(0,l=f.minHeight),"maxHeight"in f&&a(1,n=f.maxHeight),"disabled"in f&&a(5,Q=f.disabled),"placeholder"in f&&a(6,p=f.placeholder),"language"in f&&a(7,c=f.language),"singleLine"in f&&a(8,$=f.singleLine)},e.$$.update=()=>{e.$$.dirty&16&&s&&MO(),e.$$.dirty&1152&&u&&c&&u.dispatch({effects:[m.reconfigure(LO())]}),e.$$.dirty&1056&&u&&typeof Q<"u"&&u.dispatch({effects:[g.reconfigure(R.editable.of(!Q)),Z.reconfigure(A.readOnly.of(Q))]}),e.$$.dirty&1032&&u&&i!=u.state.doc.toString()&&u.dispatch({changes:{from:0,to:u.state.doc.length,insert:i}}),e.$$.dirty&1088&&u&&typeof p<"u"&&u.dispatch({effects:[S.reconfigure(KO(p))]})},[l,n,h,i,s,Q,p,c,$,T,u,yt]}class Ys extends vt{constructor(O){super(),jt(this,O,vs,ws,_t,{id:4,value:3,minHeight:0,maxHeight:1,disabled:5,placeholder:6,language:7,singleLine:8,focus:9})}get focus(){return this.$$.ctx[9]}}export{Ys as default}; diff --git a/ui/dist/assets/CreateApiDocs-Cg4p-Cu8.js b/ui/dist/assets/CreateApiDocs-Cg4p-Cu8.js deleted file mode 100644 index a76862f5..00000000 --- a/ui/dist/assets/CreateApiDocs-Cg4p-Cu8.js +++ /dev/null @@ -1,90 +0,0 @@ -import{S as $t,i as qt,s as Tt,V as St,X as ce,W as Ct,h as o,d as $e,t as he,a as ve,I as ae,Z as Ne,_ as pt,C as Mt,$ as Pt,D as Lt,l as r,n as i,m as qe,u as a,A as b,v as p,c as Te,w,J as we,p as Ft,k as Se,o as Ht,L as Ot,H as fe}from"./index-DMlPjiFP.js";import{F as Rt}from"./FieldsQueryParam-B36GF025.js";function mt(s,e,t){const l=s.slice();return l[10]=e[t],l}function bt(s,e,t){const l=s.slice();return l[10]=e[t],l}function _t(s,e,t){const l=s.slice();return l[15]=e[t],l}function kt(s){let e;return{c(){e=a("p"),e.innerHTML="Requires superuser Authorization:TOKEN header",w(e,"class","txt-hint txt-sm txt-right")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function yt(s){let e,t,l,c,f,u,_,m,q,y,g,B,S,$,R,P,I,D,M,W,L,T,k,F,ee,z,U,oe,K,X,Y;function ue(h,C){var N,x,O;return C&1&&(u=null),u==null&&(u=!!((O=(x=(N=h[0])==null?void 0:N.fields)==null?void 0:x.find(Yt))!=null&&O.required)),u?Bt:At}let te=ue(s,-1),E=te(s);function Z(h,C){var N,x,O;return C&1&&(I=null),I==null&&(I=!!((O=(x=(N=h[0])==null?void 0:N.fields)==null?void 0:x.find(Xt))!=null&&O.required)),I?Nt:Vt}let G=Z(s,-1),H=G(s);return{c(){e=a("tr"),e.innerHTML='Auth specific fields',t=p(),l=a("tr"),c=a("td"),f=a("div"),E.c(),_=p(),m=a("span"),m.textContent="email",q=p(),y=a("td"),y.innerHTML='String',g=p(),B=a("td"),B.textContent="Auth record email address.",S=p(),$=a("tr"),R=a("td"),P=a("div"),H.c(),D=p(),M=a("span"),M.textContent="emailVisibility",W=p(),L=a("td"),L.innerHTML='Boolean',T=p(),k=a("td"),k.textContent="Whether to show/hide the auth record email when fetching the record data.",F=p(),ee=a("tr"),ee.innerHTML='
    Required password
    String Auth record password.',z=p(),U=a("tr"),U.innerHTML='
    Required passwordConfirm
    String Auth record password confirmation.',oe=p(),K=a("tr"),K.innerHTML=`
    Optional verified
    Boolean Indicates whether the auth record is verified or not. -
    - This field can be set only by superusers or auth records with "Manage" access.`,X=p(),Y=a("tr"),Y.innerHTML='Other fields',w(f,"class","inline-flex"),w(P,"class","inline-flex")},m(h,C){r(h,e,C),r(h,t,C),r(h,l,C),i(l,c),i(c,f),E.m(f,null),i(f,_),i(f,m),i(l,q),i(l,y),i(l,g),i(l,B),r(h,S,C),r(h,$,C),i($,R),i(R,P),H.m(P,null),i(P,D),i(P,M),i($,W),i($,L),i($,T),i($,k),r(h,F,C),r(h,ee,C),r(h,z,C),r(h,U,C),r(h,oe,C),r(h,K,C),r(h,X,C),r(h,Y,C)},p(h,C){te!==(te=ue(h,C))&&(E.d(1),E=te(h),E&&(E.c(),E.m(f,_))),G!==(G=Z(h,C))&&(H.d(1),H=G(h),H&&(H.c(),H.m(P,D)))},d(h){h&&(o(e),o(t),o(l),o(S),o($),o(F),o(ee),o(z),o(U),o(oe),o(K),o(X),o(Y)),E.d(),H.d()}}}function At(s){let e;return{c(){e=a("span"),e.textContent="Optional",w(e,"class","label label-warning")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function Bt(s){let e;return{c(){e=a("span"),e.textContent="Required",w(e,"class","label label-success")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function Vt(s){let e;return{c(){e=a("span"),e.textContent="Optional",w(e,"class","label label-warning")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function Nt(s){let e;return{c(){e=a("span"),e.textContent="Required",w(e,"class","label label-success")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function jt(s){let e;return{c(){e=a("span"),e.textContent="Required",w(e,"class","label label-success")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function Jt(s){let e;return{c(){e=a("span"),e.textContent="Optional",w(e,"class","label label-warning")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function Dt(s){let e,t=s[15].maxSelect===1?"id":"ids",l,c;return{c(){e=b("Relation record "),l=b(t),c=b(".")},m(f,u){r(f,e,u),r(f,l,u),r(f,c,u)},p(f,u){u&32&&t!==(t=f[15].maxSelect===1?"id":"ids")&&ae(l,t)},d(f){f&&(o(e),o(l),o(c))}}}function Et(s){let e,t,l,c,f,u,_,m,q;return{c(){e=b("File object."),t=a("br"),l=b(` - Set to empty value (`),c=a("code"),c.textContent="null",f=b(", "),u=a("code"),u.textContent='""',_=b(" or "),m=a("code"),m.textContent="[]",q=b(`) to delete - already uploaded file(s).`)},m(y,g){r(y,e,g),r(y,t,g),r(y,l,g),r(y,c,g),r(y,f,g),r(y,u,g),r(y,_,g),r(y,m,g),r(y,q,g)},p:fe,d(y){y&&(o(e),o(t),o(l),o(c),o(f),o(u),o(_),o(m),o(q))}}}function It(s){let e,t;return{c(){e=a("code"),e.textContent='{"lon":x,"lat":y}',t=b(" object.")},m(l,c){r(l,e,c),r(l,t,c)},p:fe,d(l){l&&(o(e),o(t))}}}function Ut(s){let e;return{c(){e=b("URL address.")},m(t,l){r(t,e,l)},p:fe,d(t){t&&o(e)}}}function Qt(s){let e;return{c(){e=b("Email address.")},m(t,l){r(t,e,l)},p:fe,d(t){t&&o(e)}}}function Wt(s){let e;return{c(){e=b("JSON array or object.")},m(t,l){r(t,e,l)},p:fe,d(t){t&&o(e)}}}function xt(s){let e;return{c(){e=b("Number value.")},m(t,l){r(t,e,l)},p:fe,d(t){t&&o(e)}}}function zt(s){let e,t,l=s[15].autogeneratePattern&&ht();return{c(){e=b(`Plain text value. - `),l&&l.c(),t=Ot()},m(c,f){r(c,e,f),l&&l.m(c,f),r(c,t,f)},p(c,f){c[15].autogeneratePattern?l||(l=ht(),l.c(),l.m(t.parentNode,t)):l&&(l.d(1),l=null)},d(c){c&&(o(e),o(t)),l&&l.d(c)}}}function ht(s){let e;return{c(){e=b("It is autogenerated if not set.")},m(t,l){r(t,e,l)},d(t){t&&o(e)}}}function vt(s,e){let t,l,c,f,u,_=e[15].name+"",m,q,y,g,B=we.getFieldValueType(e[15])+"",S,$,R,P;function I(k,F){return!k[15].required||k[15].type=="text"&&k[15].autogeneratePattern?Jt:jt}let D=I(e),M=D(e);function W(k,F){if(k[15].type==="text")return zt;if(k[15].type==="number")return xt;if(k[15].type==="json")return Wt;if(k[15].type==="email")return Qt;if(k[15].type==="url")return Ut;if(k[15].type==="geoPoint")return It;if(k[15].type==="file")return Et;if(k[15].type==="relation")return Dt}let L=W(e),T=L&&L(e);return{key:s,first:null,c(){t=a("tr"),l=a("td"),c=a("div"),M.c(),f=p(),u=a("span"),m=b(_),q=p(),y=a("td"),g=a("span"),S=b(B),$=p(),R=a("td"),T&&T.c(),P=p(),w(c,"class","inline-flex"),w(g,"class","label"),this.first=t},m(k,F){r(k,t,F),i(t,l),i(l,c),M.m(c,null),i(c,f),i(c,u),i(u,m),i(t,q),i(t,y),i(y,g),i(g,S),i(t,$),i(t,R),T&&T.m(R,null),i(t,P)},p(k,F){e=k,D!==(D=I(e))&&(M.d(1),M=D(e),M&&(M.c(),M.m(c,f))),F&32&&_!==(_=e[15].name+"")&&ae(m,_),F&32&&B!==(B=we.getFieldValueType(e[15])+"")&&ae(S,B),L===(L=W(e))&&T?T.p(e,F):(T&&T.d(1),T=L&&L(e),T&&(T.c(),T.m(R,null)))},d(k){k&&o(t),M.d(),T&&T.d()}}}function wt(s,e){let t,l=e[10].code+"",c,f,u,_;function m(){return e[9](e[10])}return{key:s,first:null,c(){t=a("button"),c=b(l),f=p(),w(t,"class","tab-item"),Se(t,"active",e[2]===e[10].code),this.first=t},m(q,y){r(q,t,y),i(t,c),i(t,f),u||(_=Ht(t,"click",m),u=!0)},p(q,y){e=q,y&8&&l!==(l=e[10].code+"")&&ae(c,l),y&12&&Se(t,"active",e[2]===e[10].code)},d(q){q&&o(t),u=!1,_()}}}function gt(s,e){let t,l,c,f;return l=new Ct({props:{content:e[10].body}}),{key:s,first:null,c(){t=a("div"),Te(l.$$.fragment),c=p(),w(t,"class","tab-item"),Se(t,"active",e[2]===e[10].code),this.first=t},m(u,_){r(u,t,_),qe(l,t,null),i(t,c),f=!0},p(u,_){e=u;const m={};_&8&&(m.content=e[10].body),l.$set(m),(!f||_&12)&&Se(t,"active",e[2]===e[10].code)},i(u){f||(ve(l.$$.fragment,u),f=!0)},o(u){he(l.$$.fragment,u),f=!1},d(u){u&&o(t),$e(l)}}}function Kt(s){var st,at,ot,rt;let e,t,l=s[0].name+"",c,f,u,_,m,q,y,g=s[0].name+"",B,S,$,R,P,I,D,M,W,L,T,k,F,ee,z,U,oe,K,X=s[0].name+"",Y,ue,te,E,Z,G,H,h,C,N,x,O=[],je=new Map,Me,pe,Pe,le,Le,Je,me,ne,Fe,De,He,Ee,A,Ie,re,Ue,Qe,We,Oe,xe,Re,ze,Ke,Xe,Ae,Ye,Ze,de,Be,be,Ve,ie,_e,Q=[],Ge=new Map,et,ke,j=[],tt=new Map,se;M=new St({props:{js:` -import PocketBase from 'pocketbase'; - -const pb = new PocketBase('${s[4]}'); - -... - -// example create data -const data = ${JSON.stringify(s[7](s[0]),null,4)}; - -const record = await pb.collection('${(st=s[0])==null?void 0:st.name}').create(data); -`+(s[1]?` -// (optional) send an email verification request -await pb.collection('${(at=s[0])==null?void 0:at.name}').requestVerification('test@example.com'); -`:""),dart:` -import 'package:pocketbase/pocketbase.dart'; - -final pb = PocketBase('${s[4]}'); - -... - -// example create body -final body = ${JSON.stringify(s[7](s[0]),null,2)}; - -final record = await pb.collection('${(ot=s[0])==null?void 0:ot.name}').create(body: body); -`+(s[1]?` -// (optional) send an email verification request -await pb.collection('${(rt=s[0])==null?void 0:rt.name}').requestVerification('test@example.com'); -`:"")}});let J=s[6]&&kt(),V=s[1]&&yt(s),ge=ce(s[5]);const lt=n=>n[15].name;for(let n=0;nn[10].code;for(let n=0;nn[10].code;for(let n=0;napplication/json or - multipart/form-data.`,P=p(),I=a("p"),I.innerHTML=`File upload is supported only via multipart/form-data. -
    - For more info and examples you could check the detailed - Files upload and handling docs - .`,D=p(),Te(M.$$.fragment),W=p(),L=a("h6"),L.textContent="API details",T=p(),k=a("div"),F=a("strong"),F.textContent="POST",ee=p(),z=a("div"),U=a("p"),oe=b("/api/collections/"),K=a("strong"),Y=b(X),ue=b("/records"),te=p(),J&&J.c(),E=p(),Z=a("div"),Z.textContent="Body Parameters",G=p(),H=a("table"),h=a("thead"),h.innerHTML='Param Type Description',C=p(),N=a("tbody"),V&&V.c(),x=p();for(let n=0;nParam Type Description',Je=p(),me=a("tbody"),ne=a("tr"),Fe=a("td"),Fe.textContent="expand",De=p(),He=a("td"),He.innerHTML='String',Ee=p(),A=a("td"),Ie=b(`Auto expand relations when returning the created record. Ex.: - `),Te(re.$$.fragment),Ue=b(` - Supports up to 6-levels depth nested relations expansion. `),Qe=a("br"),We=b(` - The expanded relations will be appended to the record under the - `),Oe=a("code"),Oe.textContent="expand",xe=b(" property (eg. "),Re=a("code"),Re.textContent='"expand": {"relField1": {...}, ...}',ze=b(`). - `),Ke=a("br"),Xe=b(` - Only the relations to which the request user has permissions to `),Ae=a("strong"),Ae.textContent="view",Ye=b(" will be expanded."),Ze=p(),Te(de.$$.fragment),Be=p(),be=a("div"),be.textContent="Responses",Ve=p(),ie=a("div"),_e=a("div");for(let n=0;n${JSON.stringify(n[7](n[0]),null,2)}; - -final record = await pb.collection('${(ft=n[0])==null?void 0:ft.name}').create(body: body); -`+(n[1]?` -// (optional) send an email verification request -await pb.collection('${(ut=n[0])==null?void 0:ut.name}').requestVerification('test@example.com'); -`:"")),M.$set(v),(!se||d&1)&&X!==(X=n[0].name+"")&&ae(Y,X),n[6]?J||(J=kt(),J.c(),J.m(k,null)):J&&(J.d(1),J=null),n[1]?V?V.p(n,d):(V=yt(n),V.c(),V.m(N,x)):V&&(V.d(1),V=null),d&32&&(ge=ce(n[5]),O=Ne(O,d,lt,1,n,ge,je,N,pt,vt,null,_t)),d&12&&(Ce=ce(n[3]),Q=Ne(Q,d,nt,1,n,Ce,Ge,_e,pt,wt,null,bt)),d&12&&(ye=ce(n[3]),Mt(),j=Ne(j,d,it,1,n,ye,tt,ke,Pt,gt,null,mt),Lt())},i(n){if(!se){ve(M.$$.fragment,n),ve(re.$$.fragment,n),ve(de.$$.fragment,n);for(let d=0;ds.name=="emailVisibility",Yt=s=>s.name=="email";function Zt(s,e,t){let l,c,f,u,_,{collection:m}=e,q=200,y=[];function g(S){let $=we.dummyCollectionSchemaData(S,!0);return l&&($.password="12345678",$.passwordConfirm="12345678",delete $.verified),$}const B=S=>t(2,q=S.code);return s.$$set=S=>{"collection"in S&&t(0,m=S.collection)},s.$$.update=()=>{var S,$,R;s.$$.dirty&1&&t(1,l=m.type==="auth"),s.$$.dirty&1&&t(6,c=(m==null?void 0:m.createRule)===null),s.$$.dirty&2&&t(8,f=l?["password","verified","email","emailVisibility"]:[]),s.$$.dirty&257&&t(5,u=((S=m==null?void 0:m.fields)==null?void 0:S.filter(P=>!P.hidden&&P.type!="autodate"&&!f.includes(P.name)))||[]),s.$$.dirty&1&&t(3,y=[{code:200,body:JSON.stringify(we.dummyCollectionRecord(m),null,2)},{code:400,body:` - { - "status": 400, - "message": "Failed to create record.", - "data": { - "${(R=($=m==null?void 0:m.fields)==null?void 0:$[0])==null?void 0:R.name}": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `},{code:403,body:` - { - "status": 403, - "message": "You are not allowed to perform this request.", - "data": {} - } - `}])},t(4,_=we.getApiExampleUrl(Ft.baseURL)),[m,l,q,y,_,u,c,g,f,B]}class tl extends $t{constructor(e){super(),qt(this,e,Zt,Kt,Tt,{collection:0})}}export{tl as default}; diff --git a/ui/dist/assets/DeleteApiDocs-CVqJaHXL.js b/ui/dist/assets/DeleteApiDocs-CVqJaHXL.js deleted file mode 100644 index eb1f7982..00000000 --- a/ui/dist/assets/DeleteApiDocs-CVqJaHXL.js +++ /dev/null @@ -1,53 +0,0 @@ -import{S as Re,i as Ee,s as Pe,V as Te,X as j,h as p,d as De,t as te,a as le,I as ee,Z as he,_ as Be,C as Ie,$ as Oe,D as Ae,l as f,n as i,m as Ce,u as c,A as $,v as k,c as we,w as m,J as Me,p as qe,k as z,o as Le,W as Se}from"./index-DMlPjiFP.js";function ke(a,l,s){const n=a.slice();return n[6]=l[s],n}function ge(a,l,s){const n=a.slice();return n[6]=l[s],n}function ve(a){let l;return{c(){l=c("p"),l.innerHTML="Requires superuser Authorization:TOKEN header",m(l,"class","txt-hint txt-sm txt-right")},m(s,n){f(s,l,n)},d(s){s&&p(l)}}}function $e(a,l){let s,n,h;function r(){return l[5](l[6])}return{key:a,first:null,c(){s=c("button"),s.textContent=`${l[6].code} `,m(s,"class","tab-item"),z(s,"active",l[2]===l[6].code),this.first=s},m(o,d){f(o,s,d),n||(h=Le(s,"click",r),n=!0)},p(o,d){l=o,d&20&&z(s,"active",l[2]===l[6].code)},d(o){o&&p(s),n=!1,h()}}}function ye(a,l){let s,n,h,r;return n=new Se({props:{content:l[6].body}}),{key:a,first:null,c(){s=c("div"),we(n.$$.fragment),h=k(),m(s,"class","tab-item"),z(s,"active",l[2]===l[6].code),this.first=s},m(o,d){f(o,s,d),Ce(n,s,null),i(s,h),r=!0},p(o,d){l=o,(!r||d&20)&&z(s,"active",l[2]===l[6].code)},i(o){r||(le(n.$$.fragment,o),r=!0)},o(o){te(n.$$.fragment,o),r=!1},d(o){o&&p(s),De(n)}}}function He(a){var fe,me;let l,s,n=a[0].name+"",h,r,o,d,y,D,F,q=a[0].name+"",J,se,K,C,N,P,V,g,L,ae,S,E,ne,W,H=a[0].name+"",X,oe,Z,ie,G,T,Q,B,Y,I,x,w,O,v=[],ce=new Map,re,A,b=[],de=new Map,R;C=new Te({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${a[3]}'); - - ... - - await pb.collection('${(fe=a[0])==null?void 0:fe.name}').delete('RECORD_ID'); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${a[3]}'); - - ... - - await pb.collection('${(me=a[0])==null?void 0:me.name}').delete('RECORD_ID'); - `}});let _=a[1]&&ve(),U=j(a[4]);const ue=e=>e[6].code;for(let e=0;ee[6].code;for(let e=0;eParam Type Description id String ID of the record to delete.',Y=k(),I=c("div"),I.textContent="Responses",x=k(),w=c("div"),O=c("div");for(let e=0;es(2,o=D.code);return a.$$set=D=>{"collection"in D&&s(0,r=D.collection)},a.$$.update=()=>{a.$$.dirty&1&&s(1,n=(r==null?void 0:r.deleteRule)===null),a.$$.dirty&3&&r!=null&&r.id&&(d.push({code:204,body:` - null - `}),d.push({code:400,body:` - { - "status": 400, - "message": "Failed to delete record. Make sure that the record is not part of a required relation reference.", - "data": {} - } - `}),n&&d.push({code:403,body:` - { - "status": 403, - "message": "Only superusers can access this action.", - "data": {} - } - `}),d.push({code:404,body:` - { - "status": 404, - "message": "The requested resource wasn't found.", - "data": {} - } - `}))},s(3,h=Me.getApiExampleUrl(qe.baseURL)),[r,n,o,h,d,y]}class ze extends Re{constructor(l){super(),Ee(this,l,Ue,He,Pe,{collection:0})}}export{ze as default}; diff --git a/ui/dist/assets/EmailChangeDocs-ALKkvYws.js b/ui/dist/assets/EmailChangeDocs-ALKkvYws.js deleted file mode 100644 index 08f789c7..00000000 --- a/ui/dist/assets/EmailChangeDocs-ALKkvYws.js +++ /dev/null @@ -1,120 +0,0 @@ -import{S as se,i as oe,s as ie,X as K,h as g,t as X,a as V,I as F,Z as le,_ as Re,C as ne,$ as Se,D as ae,l as v,n as u,u as p,v as y,A as U,w as b,k as Y,o as ce,W as Oe,d as x,m as ee,c as te,V as Me,Y as _e,J as Be,p as De,a0 as be}from"./index-DMlPjiFP.js";function ge(n,e,t){const l=n.slice();return l[4]=e[t],l}function ve(n,e,t){const l=n.slice();return l[4]=e[t],l}function ke(n,e){let t,l=e[4].code+"",d,i,r,a;function m(){return e[3](e[4])}return{key:n,first:null,c(){t=p("button"),d=U(l),i=y(),b(t,"class","tab-item"),Y(t,"active",e[1]===e[4].code),this.first=t},m(k,q){v(k,t,q),u(t,d),u(t,i),r||(a=ce(t,"click",m),r=!0)},p(k,q){e=k,q&4&&l!==(l=e[4].code+"")&&F(d,l),q&6&&Y(t,"active",e[1]===e[4].code)},d(k){k&&g(t),r=!1,a()}}}function $e(n,e){let t,l,d,i;return l=new Oe({props:{content:e[4].body}}),{key:n,first:null,c(){t=p("div"),te(l.$$.fragment),d=y(),b(t,"class","tab-item"),Y(t,"active",e[1]===e[4].code),this.first=t},m(r,a){v(r,t,a),ee(l,t,null),u(t,d),i=!0},p(r,a){e=r;const m={};a&4&&(m.content=e[4].body),l.$set(m),(!i||a&6)&&Y(t,"active",e[1]===e[4].code)},i(r){i||(V(l.$$.fragment,r),i=!0)},o(r){X(l.$$.fragment,r),i=!1},d(r){r&&g(t),x(l)}}}function Ne(n){let e,t,l,d,i,r,a,m=n[0].name+"",k,q,G,H,J,L,z,B,D,S,N,A=[],O=new Map,P,j,T=[],W=new Map,w,E=K(n[2]);const M=c=>c[4].code;for(let c=0;cc[4].code;for(let c=0;c<_.length;c+=1){let f=ge(n,_,c),s=Z(f);W.set(s,T[c]=$e(s,f))}return{c(){e=p("div"),t=p("strong"),t.textContent="POST",l=y(),d=p("div"),i=p("p"),r=U("/api/collections/"),a=p("strong"),k=U(m),q=U("/confirm-email-change"),G=y(),H=p("div"),H.textContent="Body Parameters",J=y(),L=p("table"),L.innerHTML='Param Type Description
    Required token
    String The token from the change email request email.
    Required password
    String The account password to confirm the email change.',z=y(),B=p("div"),B.textContent="Responses",D=y(),S=p("div"),N=p("div");for(let c=0;ct(1,d=a.code);return n.$$set=a=>{"collection"in a&&t(0,l=a.collection)},t(2,i=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "token": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}]),[l,d,i,r]}class He extends se{constructor(e){super(),oe(this,e,We,Ne,ie,{collection:0})}}function we(n,e,t){const l=n.slice();return l[4]=e[t],l}function Ce(n,e,t){const l=n.slice();return l[4]=e[t],l}function ye(n,e){let t,l=e[4].code+"",d,i,r,a;function m(){return e[3](e[4])}return{key:n,first:null,c(){t=p("button"),d=U(l),i=y(),b(t,"class","tab-item"),Y(t,"active",e[1]===e[4].code),this.first=t},m(k,q){v(k,t,q),u(t,d),u(t,i),r||(a=ce(t,"click",m),r=!0)},p(k,q){e=k,q&4&&l!==(l=e[4].code+"")&&F(d,l),q&6&&Y(t,"active",e[1]===e[4].code)},d(k){k&&g(t),r=!1,a()}}}function Ee(n,e){let t,l,d,i;return l=new Oe({props:{content:e[4].body}}),{key:n,first:null,c(){t=p("div"),te(l.$$.fragment),d=y(),b(t,"class","tab-item"),Y(t,"active",e[1]===e[4].code),this.first=t},m(r,a){v(r,t,a),ee(l,t,null),u(t,d),i=!0},p(r,a){e=r;const m={};a&4&&(m.content=e[4].body),l.$set(m),(!i||a&6)&&Y(t,"active",e[1]===e[4].code)},i(r){i||(V(l.$$.fragment,r),i=!0)},o(r){X(l.$$.fragment,r),i=!1},d(r){r&&g(t),x(l)}}}function Le(n){let e,t,l,d,i,r,a,m=n[0].name+"",k,q,G,H,J,L,z,B,D,S,N,A,O,P=[],j=new Map,T,W,w=[],E=new Map,M,_=K(n[2]);const Z=s=>s[4].code;for(let s=0;s<_.length;s+=1){let h=Ce(n,_,s),R=Z(h);j.set(R,P[s]=ye(R,h))}let c=K(n[2]);const f=s=>s[4].code;for(let s=0;sAuthorization:TOKEN",J=y(),L=p("div"),L.textContent="Body Parameters",z=y(),B=p("table"),B.innerHTML='Param Type Description
    Required newEmail
    String The new email address to send the change email request.',D=y(),S=p("div"),S.textContent="Responses",N=y(),A=p("div"),O=p("div");for(let s=0;st(1,d=a.code);return n.$$set=a=>{"collection"in a&&t(0,l=a.collection)},t(2,i=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "newEmail": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `},{code:401,body:` - { - "status": 401, - "message": "The request requires valid record authorization token to be set.", - "data": {} - } - `},{code:403,body:` - { - "status": 403, - "message": "The authorized record model is not allowed to perform this action.", - "data": {} - } - `}]),[l,d,i,r]}class Ie extends se{constructor(e){super(),oe(this,e,Ue,Le,ie,{collection:0})}}function Ae(n,e,t){const l=n.slice();return l[5]=e[t],l[7]=t,l}function Te(n,e,t){const l=n.slice();return l[5]=e[t],l[7]=t,l}function qe(n){let e,t,l,d,i;function r(){return n[4](n[7])}return{c(){e=p("button"),t=p("div"),t.textContent=`${n[5].title}`,l=y(),b(t,"class","txt"),b(e,"class","tab-item"),Y(e,"active",n[1]==n[7])},m(a,m){v(a,e,m),u(e,t),u(e,l),d||(i=ce(e,"click",r),d=!0)},p(a,m){n=a,m&2&&Y(e,"active",n[1]==n[7])},d(a){a&&g(e),d=!1,i()}}}function Pe(n){let e,t,l,d;var i=n[5].component;function r(a,m){return{props:{collection:a[0]}}}return i&&(t=be(i,r(n))),{c(){e=p("div"),t&&te(t.$$.fragment),l=y(),b(e,"class","tab-item"),Y(e,"active",n[1]==n[7])},m(a,m){v(a,e,m),t&&ee(t,e,null),u(e,l),d=!0},p(a,m){if(i!==(i=a[5].component)){if(t){ne();const k=t;X(k.$$.fragment,1,0,()=>{x(k,1)}),ae()}i?(t=be(i,r(a)),te(t.$$.fragment),V(t.$$.fragment,1),ee(t,e,l)):t=null}else if(i){const k={};m&1&&(k.collection=a[0]),t.$set(k)}(!d||m&2)&&Y(e,"active",a[1]==a[7])},i(a){d||(t&&V(t.$$.fragment,a),d=!0)},o(a){t&&X(t.$$.fragment,a),d=!1},d(a){a&&g(e),t&&x(t)}}}function Ke(n){var c,f,s,h,R,re;let e,t,l=n[0].name+"",d,i,r,a,m,k,q,G=n[0].name+"",H,J,L,z,B,D,S,N,A,O,P,j,T,W;D=new Me({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${n[2]}'); - - ... - - await pb.collection('${(c=n[0])==null?void 0:c.name}').authWithPassword('test@example.com', '1234567890'); - - await pb.collection('${(f=n[0])==null?void 0:f.name}').requestEmailChange('new@example.com'); - - // --- - // (optional) in your custom confirmation page: - // --- - - // note: after this call all previously issued auth tokens are invalidated - await pb.collection('${(s=n[0])==null?void 0:s.name}').confirmEmailChange( - 'EMAIL_CHANGE_TOKEN', - 'YOUR_PASSWORD', - ); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${n[2]}'); - - ... - - await pb.collection('${(h=n[0])==null?void 0:h.name}').authWithPassword('test@example.com', '1234567890'); - - await pb.collection('${(R=n[0])==null?void 0:R.name}').requestEmailChange('new@example.com'); - - ... - - // --- - // (optional) in your custom confirmation page: - // --- - - // note: after this call all previously issued auth tokens are invalidated - await pb.collection('${(re=n[0])==null?void 0:re.name}').confirmEmailChange( - 'EMAIL_CHANGE_TOKEN', - 'YOUR_PASSWORD', - ); - `}});let w=K(n[3]),E=[];for(let o=0;oX(_[o],1,1,()=>{_[o]=null});return{c(){e=p("h3"),t=U("Email change ("),d=U(l),i=U(")"),r=y(),a=p("div"),m=p("p"),k=U("Sends "),q=p("strong"),H=U(G),J=U(" email change request."),L=y(),z=p("p"),z.textContent=`On successful email change all previously issued auth tokens for the specific record will be - automatically invalidated.`,B=y(),te(D.$$.fragment),S=y(),N=p("h6"),N.textContent="API details",A=y(),O=p("div"),P=p("div");for(let o=0;ot(1,r=m);return n.$$set=m=>{"collection"in m&&t(0,d=m.collection)},t(2,l=Be.getApiExampleUrl(De.baseURL)),[d,r,l,i,a]}class ze extends se{constructor(e){super(),oe(this,e,Ye,Ke,ie,{collection:0})}}export{ze as default}; diff --git a/ui/dist/assets/FieldsQueryParam-B36GF025.js b/ui/dist/assets/FieldsQueryParam-B36GF025.js deleted file mode 100644 index 7123a573..00000000 --- a/ui/dist/assets/FieldsQueryParam-B36GF025.js +++ /dev/null @@ -1,7 +0,0 @@ -import{S as J,i as N,s as O,W as P,h as Q,d as R,t as W,a as j,I as z,l as D,n as e,m as G,u as t,v as c,A as i,c as K,w as U}from"./index-DMlPjiFP.js";function V(f){let n,o,u,d,k,s,p,w,g,y,r,F,_,S,b,E,C,a,$,L,q,H,I,M,m,T,v,A,x;return r=new P({props:{content:"?fields=*,"+f[0]+"expand.relField.name"}}),{c(){n=t("tr"),o=t("td"),o.textContent="fields",u=c(),d=t("td"),d.innerHTML='String',k=c(),s=t("td"),p=t("p"),w=i(`Comma separated string of the fields to return in the JSON response - `),g=t("em"),g.textContent="(by default returns all fields)",y=i(`. Ex.: - `),K(r.$$.fragment),F=c(),_=t("p"),_.innerHTML="* targets all keys from the specific depth level.",S=c(),b=t("p"),b.textContent="In addition, the following field modifiers are also supported:",E=c(),C=t("ul"),a=t("li"),$=t("code"),$.textContent=":excerpt(maxLength, withEllipsis?)",L=c(),q=t("br"),H=i(` - Returns a short plain text version of the field string value. - `),I=t("br"),M=i(` - Ex.: - `),m=t("code"),T=i("?fields=*,"),v=i(f[0]),A=i("description:excerpt(200,true)"),U(o,"id","query-page")},m(l,h){D(l,n,h),e(n,o),e(n,u),e(n,d),e(n,k),e(n,s),e(s,p),e(p,w),e(p,g),e(p,y),G(r,p,null),e(s,F),e(s,_),e(s,S),e(s,b),e(s,E),e(s,C),e(C,a),e(a,$),e(a,L),e(a,q),e(a,H),e(a,I),e(a,M),e(a,m),e(m,T),e(m,v),e(m,A),x=!0},p(l,[h]){const B={};h&1&&(B.content="?fields=*,"+l[0]+"expand.relField.name"),r.$set(B),(!x||h&1)&&z(v,l[0])},i(l){x||(j(r.$$.fragment,l),x=!0)},o(l){W(r.$$.fragment,l),x=!1},d(l){l&&Q(n),R(r)}}}function X(f,n,o){let{prefix:u=""}=n;return f.$$set=d=>{"prefix"in d&&o(0,u=d.prefix)},[u]}class Z extends J{constructor(n){super(),N(this,n,X,V,O,{prefix:0})}}export{Z as F}; diff --git a/ui/dist/assets/FilterAutocompleteInput-UU1zPsgx.js b/ui/dist/assets/FilterAutocompleteInput-UU1zPsgx.js deleted file mode 100644 index 2072cf5d..00000000 --- a/ui/dist/assets/FilterAutocompleteInput-UU1zPsgx.js +++ /dev/null @@ -1 +0,0 @@ -import{S as $,i as ee,s as te,H as v,h as ne,l as re,u as ie,w as ae,O as oe,T as le,U as se,Q as de,J as u,y as ce}from"./index-DMlPjiFP.js";import{c as fe,d as ue,h as ge,a as he,s as ye,E,b as S,e as pe,f as ke,g as me,i as xe,j as be,k as we,l as Ee,m as Se,r as Ke,n as Ce,o as Re,p as Le,C as R,q as G,t as qe,S as Oe,u as Te,v as We}from"./index-Cs_DmB1i.js";function _e(e){return new Worker(""+new URL("autocomplete.worker-Bb6Toth-.js",import.meta.url).href,{name:e==null?void 0:e.name})}function ve(e){Q(e,"start");var r={},t=e.languageData||{},g=!1;for(var h in e)if(h!=t&&e.hasOwnProperty(h))for(var f=r[h]=[],a=e[h],i=0;i2&&a.token&&typeof a.token!="string"){t.pending=[];for(var s=2;s-1)return null;var h=t.indent.length-1,f=e[t.state];e:for(;;){for(var a=0;at(21,g=n));const h=se();let{id:f=""}=r,{value:a=""}=r,{disabled:i=!1}=r,{placeholder:o=""}=r,{baseCollection:s=null}=r,{singleLine:y=!1}=r,{extraAutocompleteKeys:L=[]}=r,{disableRequestKeys:b=!1}=r,{disableCollectionJoinKeys:m=!1}=r,d,p,q=i,D=new R,J=new R,A=new R,B=new R,O=new _e,H=[],I=[],M=[],K="",T="";function W(){d==null||d.focus()}let _=null;O.onmessage=n=>{M=n.data.baseKeys||[],H=n.data.requestKeys||[],I=n.data.collectionJoinKeys||[]};function V(){clearTimeout(_),_=setTimeout(()=>{O.postMessage({baseCollection:s,collections:j(g),disableRequestKeys:b,disableCollectionJoinKeys:m})},250)}function j(n){let c=n.slice();return s&&u.pushOrReplaceByKey(c,s,"id"),c}function U(){p==null||p.dispatchEvent(new CustomEvent("change",{detail:{value:a},bubbles:!0}))}function F(){if(!f)return;const n=document.querySelectorAll('[for="'+f+'"]');for(let c of n)c.removeEventListener("click",W)}function N(){if(!f)return;F();const n=document.querySelectorAll('[for="'+f+'"]');for(let c of n)c.addEventListener("click",W)}function z(n=!0,c=!0){let l=[].concat(L);return l=l.concat(M||[]),n&&(l=l.concat(H||[])),c&&(l=l.concat(I||[])),l}function X(n){var w;let c=n.matchBefore(/[\'\"\@\w\.\:]*/);if(c&&c.from==c.to&&!n.explicit)return null;let l=We(n.state).resolveInner(n.pos,-1);if(((w=l==null?void 0:l.type)==null?void 0:w.name)=="comment")return null;let x=[{label:"false"},{label:"true"},{label:"@now"},{label:"@second"},{label:"@minute"},{label:"@hour"},{label:"@year"},{label:"@day"},{label:"@month"},{label:"@weekday"},{label:"@yesterday"},{label:"@tomorrow"},{label:"@todayStart"},{label:"@todayEnd"},{label:"@monthStart"},{label:"@monthEnd"},{label:"@yearStart"},{label:"@yearEnd"}];m||x.push({label:"@collection.*",apply:"@collection."});let C=z(!b&&c.text.startsWith("@r"),!m&&c.text.startsWith("@c"));for(const k of C)x.push({label:k.endsWith(".")?k+"*":k,apply:k,boost:k.indexOf("_via_")>0?-1:0});return{from:c.from,options:x}}function P(){return Oe.define(ve({start:[{regex:/true|false|null/,token:"atom"},{regex:/\/\/.*/,token:"comment"},{regex:/"(?:[^\\]|\\.)*?(?:"|$)/,token:"string"},{regex:/'(?:[^\\]|\\.)*?(?:'|$)/,token:"string"},{regex:/0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i,token:"number"},{regex:/\&\&|\|\||\=|\!\=|\~|\!\~|\>|\<|\>\=|\<\=/,token:"operator"},{regex:/[\{\[\(]/,indent:!0},{regex:/[\}\]\)]/,dedent:!0},{regex:/\w+[\w\.]*\w+/,token:"keyword"},{regex:u.escapeRegExp("@now"),token:"keyword"},{regex:u.escapeRegExp("@second"),token:"keyword"},{regex:u.escapeRegExp("@minute"),token:"keyword"},{regex:u.escapeRegExp("@hour"),token:"keyword"},{regex:u.escapeRegExp("@year"),token:"keyword"},{regex:u.escapeRegExp("@day"),token:"keyword"},{regex:u.escapeRegExp("@month"),token:"keyword"},{regex:u.escapeRegExp("@weekday"),token:"keyword"},{regex:u.escapeRegExp("@todayStart"),token:"keyword"},{regex:u.escapeRegExp("@todayEnd"),token:"keyword"},{regex:u.escapeRegExp("@monthStart"),token:"keyword"},{regex:u.escapeRegExp("@monthEnd"),token:"keyword"},{regex:u.escapeRegExp("@yearStart"),token:"keyword"},{regex:u.escapeRegExp("@yearEnd"),token:"keyword"},{regex:u.escapeRegExp("@request.method"),token:"keyword"}],meta:{lineComment:"//"}}))}de(()=>{const n={key:"Enter",run:l=>{y&&h("submit",a)}};N();let c=[n,...fe,...ue,ye.find(l=>l.key==="Mod-d"),...ge,...he];return y||c.push(qe),t(11,d=new E({parent:p,state:S.create({doc:a,extensions:[pe(),ke(),me(),xe(),be(),S.allowMultipleSelections.of(!0),we(Te,{fallback:!0}),Ee(),Se(),Ke(),Ce(),Re.of(c),E.lineWrapping,Le({override:[X],icons:!1}),B.of(G(o)),J.of(E.editable.of(!i)),A.of(S.readOnly.of(i)),D.of(P()),S.transactionFilter.of(l=>{var x,C,w;if(y&&l.newDoc.lines>1){if(!((w=(C=(x=l.changes)==null?void 0:x.inserted)==null?void 0:C.filter(k=>!!k.text.find(Z=>Z)))!=null&&w.length))return[];l.newDoc.text=[l.newDoc.text.join(" ")]}return l}),E.updateListener.of(l=>{!l.docChanged||i||(t(1,a=l.state.doc.toString()),U())})]})})),()=>{clearTimeout(_),F(),d==null||d.destroy(),O.terminate()}});function Y(n){ce[n?"unshift":"push"](()=>{p=n,t(0,p)})}return e.$$set=n=>{"id"in n&&t(2,f=n.id),"value"in n&&t(1,a=n.value),"disabled"in n&&t(3,i=n.disabled),"placeholder"in n&&t(4,o=n.placeholder),"baseCollection"in n&&t(5,s=n.baseCollection),"singleLine"in n&&t(6,y=n.singleLine),"extraAutocompleteKeys"in n&&t(7,L=n.extraAutocompleteKeys),"disableRequestKeys"in n&&t(8,b=n.disableRequestKeys),"disableCollectionJoinKeys"in n&&t(9,m=n.disableCollectionJoinKeys)},e.$$.update=()=>{e.$$.dirty[0]&32&&t(13,K=Me(s)),e.$$.dirty[0]&25352&&!i&&(T!=K||b!==-1||m!==-1)&&(t(14,T=K),V()),e.$$.dirty[0]&4&&f&&N(),e.$$.dirty[0]&2080&&d&&s!=null&&s.fields&&d.dispatch({effects:[D.reconfigure(P())]}),e.$$.dirty[0]&6152&&d&&q!=i&&(d.dispatch({effects:[J.reconfigure(E.editable.of(!i)),A.reconfigure(S.readOnly.of(i))]}),t(12,q=i),U()),e.$$.dirty[0]&2050&&d&&a!=d.state.doc.toString()&&d.dispatch({changes:{from:0,to:d.state.doc.length,insert:a}}),e.$$.dirty[0]&2064&&d&&typeof o<"u"&&d.dispatch({effects:[B.reconfigure(G(o))]})},[p,a,f,i,o,s,y,L,b,m,W,d,q,K,T,Y]}class Pe extends ${constructor(r){super(),ee(this,r,Ue,Ie,te,{id:2,value:1,disabled:3,placeholder:4,baseCollection:5,singleLine:6,extraAutocompleteKeys:7,disableRequestKeys:8,disableCollectionJoinKeys:9,focus:10},null,[-1,-1])}get focus(){return this.$$.ctx[10]}}export{Pe as default}; diff --git a/ui/dist/assets/Leaflet-DCQr6yJv.css b/ui/dist/assets/Leaflet-DCQr6yJv.css deleted file mode 100644 index c4d83305..00000000 --- a/ui/dist/assets/Leaflet-DCQr6yJv.css +++ /dev/null @@ -1 +0,0 @@ -.leaflet-pane,.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-tile-container,.leaflet-pane>svg,.leaflet-pane>canvas,.leaflet-zoom-box,.leaflet-image-layer,.leaflet-layer{position:absolute;left:0;top:0}.leaflet-container{overflow:hidden}.leaflet-tile,.leaflet-marker-icon,.leaflet-marker-shadow{-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.leaflet-tile::selection{background:transparent}.leaflet-safari .leaflet-tile{image-rendering:-webkit-optimize-contrast}.leaflet-safari .leaflet-tile-container{width:1600px;height:1600px;-webkit-transform-origin:0 0}.leaflet-marker-icon,.leaflet-marker-shadow{display:block}.leaflet-container .leaflet-overlay-pane svg{max-width:none!important;max-height:none!important}.leaflet-container .leaflet-marker-pane img,.leaflet-container .leaflet-shadow-pane img,.leaflet-container .leaflet-tile-pane img,.leaflet-container img.leaflet-image-layer,.leaflet-container .leaflet-tile{max-width:none!important;max-height:none!important;width:auto;padding:0}.leaflet-container img.leaflet-tile{mix-blend-mode:plus-lighter}.leaflet-container.leaflet-touch-zoom{-ms-touch-action:pan-x pan-y;touch-action:pan-x pan-y}.leaflet-container.leaflet-touch-drag{-ms-touch-action:pinch-zoom;touch-action:none;touch-action:pinch-zoom}.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom{-ms-touch-action:none;touch-action:none}.leaflet-container{-webkit-tap-highlight-color:transparent}.leaflet-container a{-webkit-tap-highlight-color:rgba(51,181,229,.4)}.leaflet-tile{filter:inherit;visibility:hidden}.leaflet-tile-loaded{visibility:inherit}.leaflet-zoom-box{width:0;height:0;-moz-box-sizing:border-box;box-sizing:border-box;z-index:800}.leaflet-overlay-pane svg{-moz-user-select:none}.leaflet-pane{z-index:400}.leaflet-tile-pane{z-index:200}.leaflet-overlay-pane{z-index:400}.leaflet-shadow-pane{z-index:500}.leaflet-marker-pane{z-index:600}.leaflet-tooltip-pane{z-index:650}.leaflet-popup-pane{z-index:700}.leaflet-map-pane canvas{z-index:100}.leaflet-map-pane svg{z-index:200}.leaflet-vml-shape{width:1px;height:1px}.lvml{behavior:url(#default#VML);display:inline-block;position:absolute}.leaflet-control{position:relative;z-index:800;pointer-events:visiblePainted;pointer-events:auto}.leaflet-top,.leaflet-bottom{position:absolute;z-index:1000;pointer-events:none}.leaflet-top{top:0}.leaflet-right{right:0}.leaflet-bottom{bottom:0}.leaflet-left{left:0}.leaflet-control{float:left;clear:both}.leaflet-right .leaflet-control{float:right}.leaflet-top .leaflet-control{margin-top:10px}.leaflet-bottom .leaflet-control{margin-bottom:10px}.leaflet-left .leaflet-control{margin-left:10px}.leaflet-right .leaflet-control{margin-right:10px}.leaflet-fade-anim .leaflet-popup{opacity:0;-webkit-transition:opacity .2s linear;-moz-transition:opacity .2s linear;transition:opacity .2s linear}.leaflet-fade-anim .leaflet-map-pane .leaflet-popup{opacity:1}.leaflet-zoom-animated{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0}svg.leaflet-zoom-animated{will-change:transform}.leaflet-zoom-anim .leaflet-zoom-animated{-webkit-transition:-webkit-transform .25s cubic-bezier(0,0,.25,1);-moz-transition:-moz-transform .25s cubic-bezier(0,0,.25,1);transition:transform .25s cubic-bezier(0,0,.25,1)}.leaflet-zoom-anim .leaflet-tile,.leaflet-pan-anim .leaflet-tile{-webkit-transition:none;-moz-transition:none;transition:none}.leaflet-zoom-anim .leaflet-zoom-hide{visibility:hidden}.leaflet-interactive{cursor:pointer}.leaflet-grab{cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.leaflet-crosshair,.leaflet-crosshair .leaflet-interactive{cursor:crosshair}.leaflet-popup-pane,.leaflet-control{cursor:auto}.leaflet-dragging .leaflet-grab,.leaflet-dragging .leaflet-grab .leaflet-interactive,.leaflet-dragging .leaflet-marker-draggable{cursor:move;cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.leaflet-marker-icon,.leaflet-marker-shadow,.leaflet-image-layer,.leaflet-pane>svg path,.leaflet-tile-container{pointer-events:none}.leaflet-marker-icon.leaflet-interactive,.leaflet-image-layer.leaflet-interactive,.leaflet-pane>svg path.leaflet-interactive,svg.leaflet-image-layer.leaflet-interactive path{pointer-events:visiblePainted;pointer-events:auto}.leaflet-container{background:#ddd;outline-offset:1px}.leaflet-container a{color:#0078a8}.leaflet-zoom-box{border:2px dotted #38f;background:#ffffff80}.leaflet-container{font-family:Helvetica Neue,Arial,Helvetica,sans-serif;font-size:12px;font-size:.75rem;line-height:1.5}.leaflet-bar{box-shadow:0 1px 5px #000000a6;border-radius:4px}.leaflet-bar a{background-color:#fff;border-bottom:1px solid #ccc;width:26px;height:26px;line-height:26px;display:block;text-align:center;text-decoration:none;color:#000}.leaflet-bar a,.leaflet-control-layers-toggle{background-position:50% 50%;background-repeat:no-repeat;display:block}.leaflet-bar a:hover,.leaflet-bar a:focus{background-color:#f4f4f4}.leaflet-bar a:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.leaflet-bar a:last-child{border-bottom-left-radius:4px;border-bottom-right-radius:4px;border-bottom:none}.leaflet-bar a.leaflet-disabled{cursor:default;background-color:#f4f4f4;color:#bbb}.leaflet-touch .leaflet-bar a{width:30px;height:30px;line-height:30px}.leaflet-touch .leaflet-bar a:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.leaflet-touch .leaflet-bar a:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.leaflet-control-zoom-in,.leaflet-control-zoom-out{font:700 18px Lucida Console,Monaco,monospace;text-indent:1px}.leaflet-touch .leaflet-control-zoom-in,.leaflet-touch .leaflet-control-zoom-out{font-size:22px}.leaflet-control-layers{box-shadow:0 1px 5px #0006;background:#fff;border-radius:5px}.leaflet-control-layers-toggle{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAQAAAADQ4RFAAACf0lEQVR4AY1UM3gkARTePdvdoTxXKc+qTl3aU5U6b2Kbkz3Gtq3Zw6ziLGNPzrYx7946Tr6/ee/XeCQ4D3ykPtL5tHno4n0d/h3+xfuWHGLX81cn7r0iTNzjr7LrlxCqPtkbTQEHeqOrTy4Yyt3VCi/IOB0v7rVC7q45Q3Gr5K6jt+3Gl5nCoDD4MtO+j96Wu8atmhGqcNGHObuf8OM/x3AMx38+4Z2sPqzCxRFK2aF2e5Jol56XTLyggAMTL56XOMoS1W4pOyjUcGGQdZxU6qRh7B9Zp+PfpOFlqt0zyDZckPi1ttmIp03jX8gyJ8a/PG2yutpS/Vol7peZIbZcKBAEEheEIAgFbDkz5H6Zrkm2hVWGiXKiF4Ycw0RWKdtC16Q7qe3X4iOMxruonzegJzWaXFrU9utOSsLUmrc0YjeWYjCW4PDMADElpJSSQ0vQvA1Tm6/JlKnqFs1EGyZiFCqnRZTEJJJiKRYzVYzJck2Rm6P4iH+cmSY0YzimYa8l0EtTODFWhcMIMVqdsI2uiTvKmTisIDHJ3od5GILVhBCarCfVRmo4uTjkhrhzkiBV7SsaqS+TzrzM1qpGGUFt28pIySQHR6h7F6KSwGWm97ay+Z+ZqMcEjEWebE7wxCSQwpkhJqoZA5ivCdZDjJepuJ9IQjGGUmuXJdBFUygxVqVsxFsLMbDe8ZbDYVCGKxs+W080max1hFCarCfV+C1KATwcnvE9gRRuMP2prdbWGowm1KB1y+zwMMENkM755cJ2yPDtqhTI6ED1M/82yIDtC/4j4BijjeObflpO9I9MwXTCsSX8jWAFeHr05WoLTJ5G8IQVS/7vwR6ohirYM7f6HzYpogfS3R2OAAAAAElFTkSuQmCC);width:36px;height:36px}.leaflet-retina .leaflet-control-layers-toggle{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAQAAABvcdNgAAAEsklEQVR4AWL4TydIhpZK1kpWOlg0w3ZXP6D2soBtG42jeI6ZmQTHzAxiTbSJsYLjO9HhP+WOmcuhciVnmHVQcJnp7DFvScowZorad/+V/fVzMdMT2g9Cv9guXGv/7pYOrXh2U+RRR3dSd9JRx6bIFc/ekqHI29JC6pJ5ZEh1yWkhkbcFeSjxgx3L2m1cb1C7bceyxA+CNjT/Ifff+/kDk2u/w/33/IeCMOSaWZ4glosqT3DNnNZQ7Cs58/3Ce5HL78iZH/vKVIaYlqzfdLu8Vi7dnvUbEza5Idt36tquZFldl6N5Z/POLof0XLK61mZCmJSWjVF9tEjUluu74IUXvgttuVIHE7YxSkaYhJZam7yiM9Pv82JYfl9nptxZaxMJE4YSPty+vF0+Y2up9d3wwijfjZbabqm/3bZ9ecKHsiGmRflnn1MW4pjHf9oLufyn2z3y1D6n8g8TZhxyzipLNPnAUpsOiuWimg52psrTZYnOWYNDTMuWBWa0tJb4rgq1UvmutpaYEbZlwU3CLJm/ayYjHW5/h7xWLn9Hh1vepDkyf7dE7MtT5LR4e7yYpHrkhOUpEfssBLq2pPhAqoSWKUkk7EDqkmK6RrCEzqDjhNDWNE+XSMvkJRDWlZTmCW0l0PHQGRZY5t1L83kT0Y3l2SItk5JAWHl2dCOBm+fPu3fo5/3v61RMCO9Jx2EEYYhb0rmNQMX/vm7gqOEJLcXTGw3CAuRNeyaPWwjR8PRqKQ1PDA/dpv+on9Shox52WFnx0KY8onHayrJzm87i5h9xGw/tfkev0jGsQizqezUKjk12hBMKJ4kbCqGPVNXudyyrShovGw5CgxsRICxF6aRmSjlBnHRzg7Gx8fKqEubI2rahQYdR1YgDIRQO7JvQyD52hoIQx0mxa0ODtW2Iozn1le2iIRdzwWewedyZzewidueOGqlsn1MvcnQpuVwLGG3/IR1hIKxCjelIDZ8ldqWz25jWAsnldEnK0Zxro19TGVb2ffIZEsIO89EIEDvKMPrzmBOQcKQ+rroye6NgRRxqR4U8EAkz0CL6uSGOm6KQCdWjvjRiSP1BPalCRS5iQYiEIvxuBMJEWgzSoHADcVMuN7IuqqTeyUPq22qFimFtxDyBBJEwNyt6TM88blFHao/6tWWhuuOM4SAK4EI4QmFHA+SEyWlp4EQoJ13cYGzMu7yszEIBOm2rVmHUNqwAIQabISNMRstmdhNWcFLsSm+0tjJH1MdRxO5Nx0WDMhCtgD6OKgZeljJqJKc9po8juskR9XN0Y1lZ3mWjLR9JCO1jRDMd0fpYC2VnvjBSEFg7wBENc0R9HFlb0xvF1+TBEpF68d+DHR6IOWVv2BECtxo46hOFUBd/APU57WIoEwJhIi2CdpyZX0m93BZicktMj1AS9dClteUFAUNUIEygRZCtik5zSxI9MubTBH1GOiHsiLJ3OCoSZkILa9PxiN0EbvhsAo8tdAf9Seepd36lGWHmtNANTv5Jd0z4QYyeo/UEJqxKRpg5LZx6btLPsOaEmdMyxYdlc8LMaJnikDlhclqmPiQnTEpLUIZEwkRagjYkEibQErwhkTAKCLQEbUgkzJQWc/0PstHHcfEdQ+UAAAAASUVORK5CYII=);background-size:26px 26px}.leaflet-touch .leaflet-control-layers-toggle{width:44px;height:44px}.leaflet-control-layers .leaflet-control-layers-list,.leaflet-control-layers-expanded .leaflet-control-layers-toggle{display:none}.leaflet-control-layers-expanded .leaflet-control-layers-list{display:block;position:relative}.leaflet-control-layers-expanded{padding:6px 10px 6px 6px;color:#333;background:#fff}.leaflet-control-layers-scrollbar{overflow-y:scroll;overflow-x:hidden;padding-right:5px}.leaflet-control-layers-selector{margin-top:2px;position:relative;top:1px}.leaflet-control-layers label{display:block;font-size:13px;font-size:1.08333em}.leaflet-control-layers-separator{height:0;border-top:1px solid #ddd;margin:5px -10px 5px -6px}.leaflet-default-icon-path{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=)}.leaflet-container .leaflet-control-attribution{background:#fff;background:#fffc;margin:0}.leaflet-control-attribution,.leaflet-control-scale-line{padding:0 5px;color:#333;line-height:1.4}.leaflet-control-attribution a{text-decoration:none}.leaflet-control-attribution a:hover,.leaflet-control-attribution a:focus{text-decoration:underline}.leaflet-attribution-flag{display:inline!important;vertical-align:baseline!important;width:1em;height:.6669em}.leaflet-left .leaflet-control-scale{margin-left:5px}.leaflet-bottom .leaflet-control-scale{margin-bottom:5px}.leaflet-control-scale-line{border:2px solid #777;border-top:none;line-height:1.1;padding:2px 5px 1px;white-space:nowrap;-moz-box-sizing:border-box;box-sizing:border-box;background:#fffc;text-shadow:1px 1px #fff}.leaflet-control-scale-line:not(:first-child){border-top:2px solid #777;border-bottom:none;margin-top:-2px}.leaflet-control-scale-line:not(:first-child):not(:last-child){border-bottom:2px solid #777}.leaflet-touch .leaflet-control-attribution,.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{box-shadow:none}.leaflet-touch .leaflet-control-layers,.leaflet-touch .leaflet-bar{border:2px solid rgba(0,0,0,.2);background-clip:padding-box}.leaflet-popup{position:absolute;text-align:center;margin-bottom:20px}.leaflet-popup-content-wrapper{padding:1px;text-align:left;border-radius:12px}.leaflet-popup-content{margin:13px 24px 13px 20px;line-height:1.3;font-size:13px;font-size:1.08333em;min-height:1px}.leaflet-popup-content p{margin:1.3em 0}.leaflet-popup-tip-container{width:40px;height:20px;position:absolute;left:50%;margin-top:-1px;margin-left:-20px;overflow:hidden;pointer-events:none}.leaflet-popup-tip{width:17px;height:17px;padding:1px;margin:-10px auto 0;pointer-events:auto;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);transform:rotate(45deg)}.leaflet-popup-content-wrapper,.leaflet-popup-tip{background:#fff;color:#333;box-shadow:0 3px 14px #0006}.leaflet-container a.leaflet-popup-close-button{position:absolute;top:0;right:0;border:none;text-align:center;width:24px;height:24px;font:16px/24px Tahoma,Verdana,sans-serif;color:#757575;text-decoration:none;background:transparent}.leaflet-container a.leaflet-popup-close-button:hover,.leaflet-container a.leaflet-popup-close-button:focus{color:#585858}.leaflet-popup-scrolled{overflow:auto}.leaflet-oldie .leaflet-popup-content-wrapper{-ms-zoom:1}.leaflet-oldie .leaflet-popup-tip{width:24px;margin:0 auto;-ms-filter:"progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";filter:progid:DXImageTransform.Microsoft.Matrix(M11=.70710678,M12=.70710678,M21=-.70710678,M22=.70710678)}.leaflet-oldie .leaflet-control-zoom,.leaflet-oldie .leaflet-control-layers,.leaflet-oldie .leaflet-popup-content-wrapper,.leaflet-oldie .leaflet-popup-tip{border:1px solid #999}.leaflet-div-icon{background:#fff;border:1px solid #666}.leaflet-tooltip{position:absolute;padding:6px;background-color:#fff;border:1px solid #fff;border-radius:3px;color:#222;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;box-shadow:0 1px 3px #0006}.leaflet-tooltip.leaflet-interactive{cursor:pointer;pointer-events:auto}.leaflet-tooltip-top:before,.leaflet-tooltip-bottom:before,.leaflet-tooltip-left:before,.leaflet-tooltip-right:before{position:absolute;pointer-events:none;border:6px solid transparent;background:transparent;content:""}.leaflet-tooltip-bottom{margin-top:6px}.leaflet-tooltip-top{margin-top:-6px}.leaflet-tooltip-bottom:before,.leaflet-tooltip-top:before{left:50%;margin-left:-6px}.leaflet-tooltip-top:before{bottom:0;margin-bottom:-12px;border-top-color:#fff}.leaflet-tooltip-bottom:before{top:0;margin-top:-12px;margin-left:-6px;border-bottom-color:#fff}.leaflet-tooltip-left{margin-left:-6px}.leaflet-tooltip-right{margin-left:6px}.leaflet-tooltip-left:before,.leaflet-tooltip-right:before{top:50%;margin-top:-6px}.leaflet-tooltip-left:before{right:0;margin-right:-12px;border-left-color:#fff}.leaflet-tooltip-right:before{left:0;margin-left:-12px;border-right-color:#fff}@media print{.leaflet-control{-webkit-print-color-adjust:exact;print-color-adjust:exact}}.map-wrapper.svelte-14gvave.svelte-14gvave{position:relative;display:block;height:100%;width:100%}.map-box.svelte-14gvave.svelte-14gvave{z-index:1;height:100%;width:100%}.map-search.svelte-14gvave.svelte-14gvave{position:absolute;z-index:2;top:10px;width:70%;max-width:400px;margin-left:15%;height:auto}.map-search.svelte-14gvave input.svelte-14gvave{opacity:.7;background:var(--baseColor);border:0;box-shadow:0 0 3px 0 var(--shadowColor);transition:opacity var(--baseAnimationSpeed)}.map-search.svelte-14gvave .dropdown.svelte-14gvave{max-height:150px;border:0;box-shadow:0 0 3px 0 var(--shadowColor)}.map-search.svelte-14gvave:focus-within input.svelte-14gvave{opacity:1} diff --git a/ui/dist/assets/Leaflet-P16gNgV3.js b/ui/dist/assets/Leaflet-P16gNgV3.js deleted file mode 100644 index 94072361..00000000 --- a/ui/dist/assets/Leaflet-P16gNgV3.js +++ /dev/null @@ -1,4 +0,0 @@ -import{a2 as ss,a3 as rs,S as as,i as hs,s as us,H as Ee,h as ae,z as Cn,w as Y,l as he,n as gt,o as _i,u as vt,v as Ae,Q as ls,X as kn,Y as cs,y as fs,j as ds,I as _s,E as ms,a4 as ps,A as gs}from"./index-DMlPjiFP.js";var di={exports:{}};/* @preserve - * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com - * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade - */(function(C,g){(function(u,v){v(g)})(rs,function(u){var v="1.9.4";function c(t){var e,i,n,o;for(i=1,n=arguments.length;i"u"||!L||!L.Mixin)){t=J(t)?t:[t];for(var e=0;e0?Math.floor(t):Math.ceil(t)};w.prototype={clone:function(){return new w(this.x,this.y)},add:function(t){return this.clone()._add(y(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(y(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new w(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new w(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=mi(this.x),this.y=mi(this.y),this},distanceTo:function(t){t=y(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=y(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=y(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+H(this.x)+", "+H(this.y)+")"}};function y(t,e,i){return t instanceof w?t:J(t)?new w(t[0],t[1]):t==null?t:typeof t=="object"&&"x"in t&&"y"in t?new w(t.x,t.y):new w(t,e,i)}function R(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;n=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=tt(t);var e=this.min,i=this.max,n=t.min,o=t.max,s=o.x>=e.x&&n.x<=i.x,r=o.y>=e.y&&n.y<=i.y;return s&&r},overlaps:function(t){t=tt(t);var e=this.min,i=this.max,n=t.min,o=t.max,s=o.x>e.x&&n.xe.y&&n.y=e.lat&&o.lat<=i.lat&&n.lng>=e.lng&&o.lng<=i.lng},intersects:function(t){t=W(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=e.lat&&n.lat<=i.lat,r=o.lng>=e.lng&&n.lng<=i.lng;return s&&r},overlaps:function(t){t=W(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>e.lat&&n.late.lng&&n.lng1,Kn=function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("testPassiveEventSupport",A,e),window.removeEventListener("testPassiveEventSupport",A,e)}catch{}return t}(),jn=function(){return!!document.createElement("canvas").getContext}(),He=!!(document.createElementNS&&gi("svg").createSVGRect),Jn=!!He&&function(){var t=document.createElement("div");return t.innerHTML="",(t.firstChild&&t.firstChild.namespaceURI)==="http://www.w3.org/2000/svg"}(),Yn=!He&&function(){try{var t=document.createElement("div");t.innerHTML='';var e=t.firstChild;return e.style.behavior="url(#default#VML)",e&&typeof e.adj=="object"}catch{return!1}}(),Xn=navigator.platform.indexOf("Mac")===0,Qn=navigator.platform.indexOf("Linux")===0;function dt(t){return navigator.userAgent.toLowerCase().indexOf(t)>=0}var d={ie:ce,ielt9:Bn,edge:yi,webkit:Ne,android:wi,android23:xi,androidStock:Nn,opera:Re,chrome:Pi,gecko:Li,safari:Rn,phantom:bi,opera12:Ti,win:Dn,ie3d:Mi,webkit3d:De,gecko3d:Ci,any3d:Hn,mobile:jt,mobileWebkit:Fn,mobileWebkit3d:Wn,msPointer:ki,pointer:Si,touch:Un,touchNative:zi,mobileOpera:Vn,mobileGecko:qn,retina:Gn,passiveEvents:Kn,canvas:jn,svg:He,vml:Yn,inlineSvg:Jn,mac:Xn,linux:Qn},Ai=d.msPointer?"MSPointerDown":"pointerdown",Ei=d.msPointer?"MSPointerMove":"pointermove",Oi=d.msPointer?"MSPointerUp":"pointerup",Zi=d.msPointer?"MSPointerCancel":"pointercancel",Fe={touchstart:Ai,touchmove:Ei,touchend:Oi,touchcancel:Zi},Bi={touchstart:oo,touchmove:fe,touchend:fe,touchcancel:fe},Bt={},Ii=!1;function $n(t,e,i){return e==="touchstart"&&no(),Bi[e]?(i=Bi[e].bind(this,i),t.addEventListener(Fe[e],i,!1),i):(console.warn("wrong event specified:",e),A)}function to(t,e,i){if(!Fe[e]){console.warn("wrong event specified:",e);return}t.removeEventListener(Fe[e],i,!1)}function eo(t){Bt[t.pointerId]=t}function io(t){Bt[t.pointerId]&&(Bt[t.pointerId]=t)}function Ni(t){delete Bt[t.pointerId]}function no(){Ii||(document.addEventListener(Ai,eo,!0),document.addEventListener(Ei,io,!0),document.addEventListener(Oi,Ni,!0),document.addEventListener(Zi,Ni,!0),Ii=!0)}function fe(t,e){if(e.pointerType!==(e.MSPOINTER_TYPE_MOUSE||"mouse")){e.touches=[];for(var i in Bt)e.touches.push(Bt[i]);e.changedTouches=[e],t(e)}}function oo(t,e){e.MSPOINTER_TYPE_TOUCH&&e.pointerType===e.MSPOINTER_TYPE_TOUCH&&j(e),fe(t,e)}function so(t){var e={},i,n;for(n in t)i=t[n],e[n]=i&&i.bind?i.bind(t):i;return t=e,e.type="dblclick",e.detail=2,e.isTrusted=!1,e._simulated=!0,e}var ro=200;function ao(t,e){t.addEventListener("dblclick",e);var i=0,n;function o(s){if(s.detail!==1){n=s.detail;return}if(!(s.pointerType==="mouse"||s.sourceCapabilities&&!s.sourceCapabilities.firesTouchEvents)){var r=Wi(s);if(!(r.some(function(h){return h instanceof HTMLLabelElement&&h.attributes.for})&&!r.some(function(h){return h instanceof HTMLInputElement||h instanceof HTMLSelectElement}))){var a=Date.now();a-i<=ro?(n++,n===2&&e(so(s))):n=1,i=a}}}return t.addEventListener("click",o),{dblclick:e,simDblclick:o}}function ho(t,e){t.removeEventListener("dblclick",e.dblclick),t.removeEventListener("click",e.simDblclick)}var We=me(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),Jt=me(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),Ri=Jt==="webkitTransition"||Jt==="OTransition"?Jt+"End":"transitionend";function Di(t){return typeof t=="string"?document.getElementById(t):t}function Yt(t,e){var i=t.style[e]||t.currentStyle&&t.currentStyle[e];if((!i||i==="auto")&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);i=n?n[e]:null}return i==="auto"?null:i}function z(t,e,i){var n=document.createElement(t);return n.className=e||"",i&&i.appendChild(n),n}function D(t){var e=t.parentNode;e&&e.removeChild(t)}function de(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function It(t){var e=t.parentNode;e&&e.lastChild!==t&&e.appendChild(t)}function Nt(t){var e=t.parentNode;e&&e.firstChild!==t&&e.insertBefore(t,e.firstChild)}function Ue(t,e){if(t.classList!==void 0)return t.classList.contains(e);var i=_e(t);return i.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(i)}function T(t,e){if(t.classList!==void 0)for(var i=Z(e),n=0,o=i.length;n0?2*window.devicePixelRatio:1;function Vi(t){return d.edge?t.wheelDeltaY/2:t.deltaY&&t.deltaMode===0?-t.deltaY/co:t.deltaY&&t.deltaMode===1?-t.deltaY*20:t.deltaY&&t.deltaMode===2?-t.deltaY*60:t.deltaX||t.deltaZ?0:t.wheelDelta?(t.wheelDeltaY||t.wheelDelta)/2:t.detail&&Math.abs(t.detail)<32765?-t.detail*20:t.detail?t.detail/-32765*60:0}function ei(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch{return!1}return i!==t}var fo={__proto__:null,on:x,off:O,stopPropagation:zt,disableScrollPropagation:ti,disableClickPropagation:te,preventDefault:j,stop:At,getPropagationPath:Wi,getMousePosition:Ui,getWheelDelta:Vi,isExternalTarget:ei,addListener:x,removeListener:O},qi=Gt.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=St(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=q(this._animate,this),this._step()},_step:function(t){var e=+new Date-this._startTime,i=this._duration*1e3;ethis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),n=this._limitCenter(i,this._zoom,W(t));return i.equals(n)||this.panTo(n,e),this._enforcingBounds=!1,this},panInside:function(t,e){e=e||{};var i=y(e.paddingTopLeft||e.padding||[0,0]),n=y(e.paddingBottomRight||e.padding||[0,0]),o=this.project(this.getCenter()),s=this.project(t),r=this.getPixelBounds(),a=tt([r.min.add(i),r.max.subtract(n)]),h=a.getSize();if(!a.contains(s)){this._enforcingBounds=!0;var l=s.subtract(a.getCenter()),f=a.extend(s).getSize().subtract(h);o.x+=l.x<0?-f.x:f.x,o.y+=l.y<0?-f.y:f.y,this.panTo(this.unproject(o),e),this._enforcingBounds=!1}return this},invalidateSize:function(t){if(!this._loaded)return this;t=c({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),o=i.divideBy(2).round(),s=n.subtract(o);return!s.x&&!s.y?this:(t.animate&&t.pan?this.panBy(s):(t.pan&&this._rawPanBy(s),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(_(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i}))},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=c({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=_(this._handleGeolocationResponse,this),i=_(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){if(this._container._leaflet_id){var e=t.code,i=t.message||(e===1?"permission denied":e===2?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})}},_handleGeolocationResponse:function(t){if(this._container._leaflet_id){var e=t.coords.latitude,i=t.coords.longitude,n=new E(e,i),o=n.toBounds(t.coords.accuracy*2),s=this._locateOptions;if(s.setView){var r=this.getBoundsZoom(o);this.setView(n,s.maxZoom?Math.min(r,s.maxZoom):r)}var a={latlng:n,bounds:o,timestamp:t.timestamp};for(var h in t.coords)typeof t.coords[h]=="number"&&(a[h]=t.coords[h]);this.fire("locationfound",a)}},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){if(this._initEvents(!0),this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch{this._container._leaflet_id=void 0,this._containerId=void 0}this._locationWatchId!==void 0&&this.stopLocate(),this._stop(),D(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(at(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)D(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,e){var i="leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),n=z("div",i,e||this._mapPane);return t&&(this._panes[t]=n),n},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter.clone():this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new et(e,i)},getMinZoom:function(){return this.options.minZoom===void 0?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===void 0?this._layersMaxZoom===void 0?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=W(t),i=y(i||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(i),l=tt(this.project(a,n),this.project(r,n)).getSize(),f=d.any3d?this.options.zoomSnap:1,p=h.x/l.x,M=h.y/l.y,Q=e?Math.max(p,M):Math.min(p,M);return n=this.getScaleZoom(Q,n),f&&(n=Math.round(n/(f/100))*(f/100),n=e?Math.ceil(n/f)*f:Math.floor(n/f)*f),Math.max(o,Math.min(s,n))},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new w(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){var i=this._getTopLeftPoint(t,e);return new R(i,i.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(t===void 0?this.getZoom():t)},getPane:function(t){return typeof t=="string"?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var i=this.options.crs;return e=e===void 0?this._zoom:e,i.scale(t)/i.scale(e)},getScaleZoom:function(t,e){var i=this.options.crs;e=e===void 0?this._zoom:e;var n=i.zoom(t*i.scale(e));return isNaN(n)?1/0:n},project:function(t,e){return e=e===void 0?this._zoom:e,this.options.crs.latLngToPoint(k(t),e)},unproject:function(t,e){return e=e===void 0?this._zoom:e,this.options.crs.pointToLatLng(y(t),e)},layerPointToLatLng:function(t){var e=y(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(k(t))._round();return e._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(k(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(W(t))},distance:function(t,e){return this.options.crs.distance(k(t),k(e))},containerPointToLayerPoint:function(t){return y(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return y(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(y(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(k(t)))},mouseEventToContainerPoint:function(t){return Ui(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=Di(t);if(e){if(e._leaflet_id)throw new Error("Map container is already initialized.")}else throw new Error("Map container not found.");x(e,"scroll",this._onScroll,this),this._containerId=m(e)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&d.any3d,T(t,"leaflet-container"+(d.touch?" leaflet-touch":"")+(d.retina?" leaflet-retina":"")+(d.ielt9?" leaflet-oldie":"")+(d.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var e=Yt(t,"position");e!=="absolute"&&e!=="relative"&&e!=="fixed"&&e!=="sticky"&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),U(this._mapPane,new w(0,0)),this.createPane("tilePane"),this.createPane("overlayPane"),this.createPane("shadowPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(T(t.markerPane,"leaflet-zoom-hide"),T(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e,i){U(this._mapPane,new w(0,0));var n=!this._loaded;this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset");var o=this._zoom!==e;this._moveStart(o,i)._move(t,e)._moveEnd(o),this.fire("viewreset"),n&&this.fire("load")},_moveStart:function(t,e){return t&&this.fire("zoomstart"),e||this.fire("movestart"),this},_move:function(t,e,i,n){e===void 0&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),n?i&&i.pinch&&this.fire("zoom",i):((o||i&&i.pinch)&&this.fire("zoom",i),this.fire("move",i)),this},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return at(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){U(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[m(this._container)]=this;var e=t?O:x;e(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup",this._handleDOMEvent,this),this.options.trackResize&&e(window,"resize",this._onResize,this),d.any3d&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){at(this._resizeRequest),this._resizeRequest=q(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i=[],n,o=e==="mouseout"||e==="mouseover",s=t.target||t.srcElement,r=!1;s;){if(n=this._targets[m(s)],n&&(e==="click"||e==="preclick")&&this._draggableMoved(n)){r=!0;break}if(n&&n.listens(e,!0)&&(o&&!ei(s,t)||(i.push(n),o))||s===this._container)break;s=s.parentNode}return!i.length&&!r&&!o&&this.listens(e,!0)&&(i=[this]),i},_isClickDisabled:function(t){for(;t&&t!==this._container;){if(t._leaflet_disable_click)return!0;t=t.parentNode}},_handleDOMEvent:function(t){var e=t.target||t.srcElement;if(!(!this._loaded||e._leaflet_disable_events||t.type==="click"&&this._isClickDisabled(e))){var i=t.type;i==="mousedown"&&Je(e),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,i){if(t.type==="click"){var n=c({},t);n.type="preclick",this._fireDOMEvent(n,n.type,i)}var o=this._findEventTargets(t,e);if(i){for(var s=[],r=0;r0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom(),n=d.any3d?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(e,Math.min(i,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){F(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._trunc();return(e&&e.animate)!==!0&&!this.getSize().contains(i)?!1:(this.panBy(i,e),!0)},_createAnimProxy:function(){var t=this._proxy=z("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(e){var i=We,n=this._proxy.style[i];kt(this._proxy,this.project(e.center,e.zoom),this.getZoomScale(e.zoom,1)),n===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",this._animMoveEnd,this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){D(this._proxy),this.off("load moveend",this._animMoveEnd,this),delete this._proxy},_animMoveEnd:function(){var t=this.getCenter(),e=this.getZoom();kt(this._proxy,this.project(t,e),this.getZoomScale(e,1))},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),o=this._getCenterOffset(t)._divideBy(1-1/n);return i.animate!==!0&&!this.getSize().contains(o)?!1:(q(function(){this._moveStart(!0,i.noMoveStart||!1)._animateZoom(t,e,!0)},this),!0)},_animateZoom:function(t,e,i,n){this._mapPane&&(i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,T(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),this._tempFireZoomEvent||(this._tempFireZoomEvent=this._zoom!==this._animateToZoom),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),setTimeout(_(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&F(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._tempFireZoomEvent&&this.fire("zoom"),delete this._tempFireZoomEvent,this.fire("move"),this._moveEnd(!0))}});function _o(t,e){return new S(t,e)}var ct=yt.extend({options:{position:"topright"},initialize:function(t){b(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return T(e,"leaflet-control"),i.indexOf("bottom")!==-1?n.insertBefore(e,n.firstChild):n.appendChild(e),this._map.on("unload",this.remove,this),this},remove:function(){return this._map?(D(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),ee=function(t){return new ct(t)};S.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){var t=this._controlCorners={},e="leaflet-",i=this._controlContainer=z("div",e+"control-container",this._container);function n(o,s){var r=e+o+" "+e+s;t[o+s]=z("div",r,i)}n("top","left"),n("top","right"),n("bottom","left"),n("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)D(this._controlCorners[t]);D(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Gi=ct.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,e,i,n){return i1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=e&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var e=this._getLayer(m(t.target)),i=e.overlay?t.type==="add"?"overlayadd":"overlayremove":t.type==="add"?"baselayerchange":null;i&&this._map.fire(i,e)},_createRadioElement:function(t,e){var i='",n=document.createElement("div");return n.innerHTML=i,n.firstChild},_addItem:function(t){var e=document.createElement("label"),i=this._map.hasLayer(t.layer),n;t.overlay?(n=document.createElement("input"),n.type="checkbox",n.className="leaflet-control-layers-selector",n.defaultChecked=i):n=this._createRadioElement("leaflet-base-layers_"+m(this),i),this._layerControlInputs.push(n),n.layerId=m(t.layer),x(n,"click",this._onInputClick,this);var o=document.createElement("span");o.innerHTML=" "+t.name;var s=document.createElement("span");e.appendChild(s),s.appendChild(n),s.appendChild(o);var r=t.overlay?this._overlaysList:this._baseLayersList;return r.appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){if(!this._preventClick){var t=this._layerControlInputs,e,i,n=[],o=[];this._handlingClick=!0;for(var s=t.length-1;s>=0;s--)e=t[s],i=this._getLayer(e.layerId).layer,e.checked?n.push(i):e.checked||o.push(i);for(s=0;s=0;o--)e=t[o],i=this._getLayer(e.layerId).layer,e.disabled=i.options.minZoom!==void 0&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expandSafely:function(){var t=this._section;this._preventClick=!0,x(t,"click",j),this.expand();var e=this;setTimeout(function(){O(t,"click",j),e._preventClick=!1})}}),mo=function(t,e,i){return new Gi(t,e,i)},ii=ct.extend({options:{position:"topleft",zoomInText:'',zoomInTitle:"Zoom in",zoomOutText:'',zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=z("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,o){var s=z("a",i,n);return s.innerHTML=t,s.href="#",s.title=e,s.setAttribute("role","button"),s.setAttribute("aria-label",e),te(s),x(s,"click",At),x(s,"click",o,this),x(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";F(this._zoomInButton,e),F(this._zoomOutButton,e),this._zoomInButton.setAttribute("aria-disabled","false"),this._zoomOutButton.setAttribute("aria-disabled","false"),(this._disabled||t._zoom===t.getMinZoom())&&(T(this._zoomOutButton,e),this._zoomOutButton.setAttribute("aria-disabled","true")),(this._disabled||t._zoom===t.getMaxZoom())&&(T(this._zoomInButton,e),this._zoomInButton.setAttribute("aria-disabled","true"))}});S.mergeOptions({zoomControl:!0}),S.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ii,this.addControl(this.zoomControl))});var po=function(t){return new ii(t)},Ki=ct.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=z("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=z("div",e,i)),t.imperial&&(this._iScale=z("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,i=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(i)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t),i=e<1e3?e+" m":e/1e3+" km";this._updateScale(this._mScale,i,e/t)},_updateImperial:function(t){var e=t*3.2808399,i,n,o;e>5280?(i=e/5280,n=this._getRoundNum(i),this._updateScale(this._iScale,n+" mi",n/i)):(o=this._getRoundNum(e),this._updateScale(this._iScale,o+" ft",o/e))},_updateScale:function(t,e,i){t.style.width=Math.round(this.options.maxWidth*i)+"px",t.innerHTML=e},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),go=function(t){return new Ki(t)},vo='',ni=ct.extend({options:{position:"bottomright",prefix:''+(d.inlineSvg?vo+" ":"")+"Leaflet"},initialize:function(t){b(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=z("div","leaflet-control-attribution"),te(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),t.on("layeradd",this._addAttribution,this),this._container},onRemove:function(t){t.off("layeradd",this._addAttribution,this)},_addAttribution:function(t){t.layer.getAttribution&&(this.addAttribution(t.layer.getAttribution()),t.layer.once("remove",function(){this.removeAttribution(t.layer.getAttribution())},this))},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(' ')}}});S.mergeOptions({attributionControl:!0}),S.addInitHook(function(){this.options.attributionControl&&new ni().addTo(this)});var yo=function(t){return new ni(t)};ct.Layers=Gi,ct.Zoom=ii,ct.Scale=Ki,ct.Attribution=ni,ee.layers=mo,ee.zoom=po,ee.scale=go,ee.attribution=yo;var mt=yt.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});mt.addTo=function(t,e){return t.addHandler(e,this),this};var wo={Events:rt},ji=d.touch?"touchstart mousedown":"mousedown",Mt=Gt.extend({options:{clickTolerance:3},initialize:function(t,e,i,n){b(this,n),this._element=t,this._dragStartTarget=e||t,this._preventOutline=i},enable:function(){this._enabled||(x(this._dragStartTarget,ji,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Mt._dragging===this&&this.finishDrag(!0),O(this._dragStartTarget,ji,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(this._enabled&&(this._moved=!1,!Ue(this._element,"leaflet-zoom-anim"))){if(t.touches&&t.touches.length!==1){Mt._dragging===this&&this.finishDrag();return}if(!(Mt._dragging||t.shiftKey||t.which!==1&&t.button!==1&&!t.touches)&&(Mt._dragging=this,this._preventOutline&&Je(this._element),Ge(),Xt(),!this._moving)){this.fire("down");var e=t.touches?t.touches[0]:t,i=Hi(this._element);this._startPoint=new w(e.clientX,e.clientY),this._startPos=St(this._element),this._parentScale=Ye(i);var n=t.type==="mousedown";x(document,n?"mousemove":"touchmove",this._onMove,this),x(document,n?"mouseup":"touchend touchcancel",this._onUp,this)}}},_onMove:function(t){if(this._enabled){if(t.touches&&t.touches.length>1){this._moved=!0;return}var e=t.touches&&t.touches.length===1?t.touches[0]:t,i=new w(e.clientX,e.clientY)._subtract(this._startPoint);!i.x&&!i.y||Math.abs(i.x)+Math.abs(i.y)s&&(r=a,s=h);s>i&&(e[r]=1,si(t,e,i,n,r),si(t,e,i,r,o))}function bo(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;ne&&(i.push(t[n]),o=n);return oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i}function To(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n}function ie(t,e,i,n){var o=e.x,s=e.y,r=i.x-o,a=i.y-s,h=r*r+a*a,l;return h>0&&(l=((t.x-o)*r+(t.y-s)*a)/h,l>1?(o=i.x,s=i.y):l>0&&(o+=r*l,s+=a*l)),r=t.x-o,a=t.y-s,n?r*r+a*a:new w(o,s)}function ut(t){return!J(t[0])||typeof t[0][0]!="object"&&typeof t[0][0]<"u"}function en(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),ut(t)}function nn(t,e){var i,n,o,s,r,a,h,l;if(!t||t.length===0)throw new Error("latlngs not passed");ut(t)||(console.warn("latlngs are not flat! Only the first ring will be used"),t=t[0]);var f=k([0,0]),p=W(t),M=p.getNorthWest().distanceTo(p.getSouthWest())*p.getNorthEast().distanceTo(p.getNorthWest());M<1700&&(f=oi(t));var Q=t.length,G=[];for(i=0;in){h=(s-n)/o,l=[a.x-h*(a.x-r.x),a.y-h*(a.y-r.y)];break}var it=e.unproject(y(l));return k([it.lat+f.lat,it.lng+f.lng])}var Mo={__proto__:null,simplify:Xi,pointToSegmentDistance:Qi,closestPointOnSegment:Po,clipSegment:tn,_getEdgeIntersection:ve,_getBitCode:Et,_sqClosestPointOnSegment:ie,isFlat:ut,_flat:en,polylineCenter:nn},ri={project:function(t){return new w(t.lng,t.lat)},unproject:function(t){return new E(t.y,t.x)},bounds:new R([-180,-90],[180,90])},ai={R:6378137,R_MINOR:6356752314245179e-9,bounds:new R([-2003750834279e-5,-1549657073972e-5],[2003750834279e-5,1876465623138e-5]),project:function(t){var e=Math.PI/180,i=this.R,n=t.lat*e,o=this.R_MINOR/i,s=Math.sqrt(1-o*o),r=s*Math.sin(n),a=Math.tan(Math.PI/4-n/2)/Math.pow((1-r)/(1+r),s/2);return n=-i*Math.log(Math.max(a,1e-10)),new w(t.lng*e*i,n)},unproject:function(t){for(var e=180/Math.PI,i=this.R,n=this.R_MINOR/i,o=Math.sqrt(1-n*n),s=Math.exp(-t.y/i),r=Math.PI/2-2*Math.atan(s),a=0,h=.1,l;a<15&&Math.abs(h)>1e-7;a++)l=o*Math.sin(r),l=Math.pow((1-l)/(1+l),o/2),h=Math.PI/2-2*Math.atan(s*l)-r,r+=h;return new E(r*e,t.x*e/i)}},Co={__proto__:null,LonLat:ri,Mercator:ai,SphericalMercator:Oe},ko=c({},Tt,{code:"EPSG:3395",projection:ai,transformation:function(){var t=.5/(Math.PI*ai.R);return Kt(t,.5,-t,.5)}()}),on=c({},Tt,{code:"EPSG:4326",projection:ri,transformation:Kt(1/180,1,-1/180,.5)}),So=c({},wt,{projection:ri,transformation:Kt(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,e){var i=e.lng-t.lng,n=e.lat-t.lat;return Math.sqrt(i*i+n*n)},infinite:!0});wt.Earth=Tt,wt.EPSG3395=ko,wt.EPSG3857=Be,wt.EPSG900913=Zn,wt.EPSG4326=on,wt.Simple=So;var ft=Gt.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[m(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[m(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var e=t.target;if(e.hasLayer(this)){if(this._map=e,this._zoomAnimated=e._zoomAnimated,this.getEvents){var i=this.getEvents();e.on(i,this),this.once("remove",function(){e.off(i,this)},this)}this.onAdd(e),this.fire("add"),e.fire("layeradd",{layer:this})}}});S.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var e=m(t);return this._layers[e]?this:(this._layers[e]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var e=m(t);return this._layers[e]?(this._loaded&&t.onRemove(this),delete this._layers[e],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return m(t)in this._layers},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},_addLayers:function(t){t=t?J(t)?t:[t]:[];for(var e=0,i=t.length;ethis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),this.options.minZoom===void 0&&this._layersMinZoom&&this.getZoom()=2&&e[0]instanceof E&&e[0].equals(e[i-1])&&e.pop(),e},_setLatLngs:function(t){Pt.prototype._setLatLngs.call(this,t),ut(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return ut(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,e=this.options.weight,i=new w(e,e);if(t=new R(t.min.subtract(i),t.max.add(i)),this._parts=[],!(!this._pxBounds||!this._pxBounds.intersects(t))){if(this.options.noClip){this._parts=this._rings;return}for(var n=0,o=this._rings.length,s;nt.y!=o.y>t.y&&t.x<(o.x-n.x)*(t.y-n.y)/(o.y-n.y)+n.x&&(e=!e);return e||Pt.prototype._containsPoint.call(this,t,!0)}});function No(t,e){return new Ht(t,e)}var Lt=xt.extend({initialize:function(t,e){b(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e=J(t)?t:t.features,i,n,o;if(e){for(i=0,n=e.length;i0&&o.push(o[0].slice()),o}function Ft(t,e){return t.feature?c({},t.feature,{geometry:e}):be(e)}function be(t){return t.type==="Feature"||t.type==="FeatureCollection"?t:{type:"Feature",properties:{},geometry:t}}var ci={toGeoJSON:function(t){return Ft(this,{type:"Point",coordinates:li(this.getLatLng(),t)})}};ye.include(ci),hi.include(ci),we.include(ci),Pt.include({toGeoJSON:function(t){var e=!ut(this._latlngs),i=Le(this._latlngs,e?1:0,!1,t);return Ft(this,{type:(e?"Multi":"")+"LineString",coordinates:i})}}),Ht.include({toGeoJSON:function(t){var e=!ut(this._latlngs),i=e&&!ut(this._latlngs[0]),n=Le(this._latlngs,i?2:e?1:0,!0,t);return e||(n=[n]),Ft(this,{type:(i?"Multi":"")+"Polygon",coordinates:n})}}),Rt.include({toMultiPoint:function(t){var e=[];return this.eachLayer(function(i){e.push(i.toGeoJSON(t).geometry.coordinates)}),Ft(this,{type:"MultiPoint",coordinates:e})},toGeoJSON:function(t){var e=this.feature&&this.feature.geometry&&this.feature.geometry.type;if(e==="MultiPoint")return this.toMultiPoint(t);var i=e==="GeometryCollection",n=[];return this.eachLayer(function(o){if(o.toGeoJSON){var s=o.toGeoJSON(t);if(i)n.push(s.geometry);else{var r=be(s);r.type==="FeatureCollection"?n.push.apply(n,r.features):n.push(r)}}}),i?Ft(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}});function an(t,e){return new Lt(t,e)}var Ro=an,Te=ft.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1,errorOverlayUrl:"",zIndex:1,className:""},initialize:function(t,e,i){this._url=t,this._bounds=W(e),b(this,i)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(T(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){D(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&It(this._image),this},bringToBack:function(){return this._map&&Nt(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=W(t),this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t=this._url.tagName==="IMG",e=this._image=t?this._url:z("img");if(T(e,"leaflet-image-layer"),this._zoomAnimated&&T(e,"leaflet-zoom-animated"),this.options.className&&T(e,this.options.className),e.onselectstart=A,e.onmousemove=A,e.onload=_(this.fire,this,"load"),e.onerror=_(this._overlayOnError,this,"error"),(this.options.crossOrigin||this.options.crossOrigin==="")&&(e.crossOrigin=this.options.crossOrigin===!0?"":this.options.crossOrigin),this.options.zIndex&&this._updateZIndex(),t){this._url=e.src;return}e.src=this._url,e.alt=this.options.alt},_animateZoom:function(t){var e=this._map.getZoomScale(t.zoom),i=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min;kt(this._image,i,e)},_reset:function(){var t=this._image,e=new R(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),i=e.getSize();U(t,e.min),t.style.width=i.x+"px",t.style.height=i.y+"px"},_updateOpacity:function(){ht(this._image,this.options.opacity)},_updateZIndex:function(){this._image&&this.options.zIndex!==void 0&&this.options.zIndex!==null&&(this._image.style.zIndex=this.options.zIndex)},_overlayOnError:function(){this.fire("error");var t=this.options.errorOverlayUrl;t&&this._url!==t&&(this._url=t,this._image.src=t)},getCenter:function(){return this._bounds.getCenter()}}),Do=function(t,e,i){return new Te(t,e,i)},hn=Te.extend({options:{autoplay:!0,loop:!0,keepAspectRatio:!0,muted:!1,playsInline:!0},_initImage:function(){var t=this._url.tagName==="VIDEO",e=this._image=t?this._url:z("video");if(T(e,"leaflet-image-layer"),this._zoomAnimated&&T(e,"leaflet-zoom-animated"),this.options.className&&T(e,this.options.className),e.onselectstart=A,e.onmousemove=A,e.onloadeddata=_(this.fire,this,"load"),t){for(var i=e.getElementsByTagName("source"),n=[],o=0;o0?n:[e.src];return}J(this._url)||(this._url=[this._url]),!this.options.keepAspectRatio&&Object.prototype.hasOwnProperty.call(e.style,"objectFit")&&(e.style.objectFit="fill"),e.autoplay=!!this.options.autoplay,e.loop=!!this.options.loop,e.muted=!!this.options.muted,e.playsInline=!!this.options.playsInline;for(var s=0;so?(e.height=o+"px",T(t,s)):F(t,s),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),i=this._getAnchor();U(this._container,e.add(i))},_adjustPan:function(){if(this.options.autoPan){if(this._map._panAnim&&this._map._panAnim.stop(),this._autopanning){this._autopanning=!1;return}var t=this._map,e=parseInt(Yt(this._container,"marginBottom"),10)||0,i=this._container.offsetHeight+e,n=this._containerWidth,o=new w(this._containerLeft,-i-this._containerBottom);o._add(St(this._container));var s=t.layerPointToContainerPoint(o),r=y(this.options.autoPanPadding),a=y(this.options.autoPanPaddingTopLeft||r),h=y(this.options.autoPanPaddingBottomRight||r),l=t.getSize(),f=0,p=0;s.x+n+h.x>l.x&&(f=s.x+n-l.x+h.x),s.x-f-a.x<0&&(f=s.x-a.x),s.y+i+h.y>l.y&&(p=s.y+i-l.y+h.y),s.y-p-a.y<0&&(p=s.y-a.y),(f||p)&&(this.options.keepInView&&(this._autopanning=!0),t.fire("autopanstart").panBy([f,p]))}},_getAnchor:function(){return y(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}}),Wo=function(t,e){return new Me(t,e)};S.mergeOptions({closePopupOnClick:!0}),S.include({openPopup:function(t,e,i){return this._initOverlay(Me,t,e,i).openOn(this),this},closePopup:function(t){return t=arguments.length?t:this._popup,t&&t.close(),this}}),ft.include({bindPopup:function(t,e){return this._popup=this._initOverlay(Me,this._popup,t,e),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t){return this._popup&&(this instanceof xt||(this._popup._source=this),this._popup._prepareOpen(t||this._latlng)&&this._popup.openOn(this._map)),this},closePopup:function(){return this._popup&&this._popup.close(),this},togglePopup:function(){return this._popup&&this._popup.toggle(this),this},isPopupOpen:function(){return this._popup?this._popup.isOpen():!1},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){if(!(!this._popup||!this._map)){At(t);var e=t.layer||t.target;if(this._popup._source===e&&!(e instanceof Ct)){this._map.hasLayer(this._popup)?this.closePopup():this.openPopup(t.latlng);return}this._popup._source=e,this.openPopup(t.latlng)}},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){t.originalEvent.keyCode===13&&this._openPopup(t)}});var Ce=pt.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,opacity:.9},onAdd:function(t){pt.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&(this.addEventParent(this._source),this._source.fire("tooltipopen",{tooltip:this},!0))},onRemove:function(t){pt.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&(this.removeEventParent(this._source),this._source.fire("tooltipclose",{tooltip:this},!0))},getEvents:function(){var t=pt.prototype.getEvents.call(this);return this.options.permanent||(t.preclick=this.close),t},_initLayout:function(){var t="leaflet-tooltip",e=t+" "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=z("div",e),this._container.setAttribute("role","tooltip"),this._container.setAttribute("id","leaflet-tooltip-"+m(this))},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e,i,n=this._map,o=this._container,s=n.latLngToContainerPoint(n.getCenter()),r=n.layerPointToContainerPoint(t),a=this.options.direction,h=o.offsetWidth,l=o.offsetHeight,f=y(this.options.offset),p=this._getAnchor();a==="top"?(e=h/2,i=l):a==="bottom"?(e=h/2,i=0):a==="center"?(e=h/2,i=l/2):a==="right"?(e=0,i=l/2):a==="left"?(e=h,i=l/2):r.xthis.options.maxZoom||in?this._retainParent(o,s,r,n):!1)},_retainChildren:function(t,e,i,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*e;s<2*e+2;s++){var r=new w(o,s);r.z=i+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];if(h&&h.active){h.retain=!0;continue}else h&&h.loaded&&(h.retain=!0);i+1this.options.maxZoom||this.options.minZoom!==void 0&&o1){this._setView(t,i);return}for(var p=o.min.y;p<=o.max.y;p++)for(var M=o.min.x;M<=o.max.x;M++){var Q=new w(M,p);if(Q.z=this._tileZoom,!!this._isValidTile(Q)){var G=this._tiles[this._tileCoordsToKey(Q)];G?G.current=!0:r.push(Q)}}if(r.sort(function(it,Ut){return it.distanceTo(s)-Ut.distanceTo(s)}),r.length!==0){this._loading||(this._loading=!0,this.fire("loading"));var lt=document.createDocumentFragment();for(M=0;Mi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return W(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),o=n.add(i),s=e.unproject(n,t.z),r=e.unproject(o,t.z);return[s,r]},_tileCoordsToBounds:function(t){var e=this._tileCoordsToNwSe(t),i=new et(e[0],e[1]);return this.options.noWrap||(i=this._map.wrapLatLngBounds(i)),i},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var e=t.split(":"),i=new w(+e[0],+e[1]);return i.z=+e[2],i},_removeTile:function(t){var e=this._tiles[t];e&&(D(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){T(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=A,t.onmousemove=A,d.ielt9&&this.options.opacity<1&&ht(t,this.options.opacity)},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),_(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&q(_(this._tileReady,this,t,null,o)),U(o,i),this._tiles[n]={el:o,coords:t,current:!0},e.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,e,i){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);i=this._tiles[n],i&&(i.loaded=+new Date,this._map._fadeAnimated?(ht(i.el,0),at(this._fadeFrame),this._fadeFrame=q(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(T(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),d.ielt9||!this._map._fadeAnimated?q(this._pruneTiles,this):setTimeout(_(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new w(this._wrapX?X(t.x,this._wrapX):t.x,this._wrapY?X(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new R(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});function qo(t){return new oe(t)}var Wt=oe.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1,referrerPolicy:!1},initialize:function(t,e){this._url=t,e=b(this,e),e.detectRetina&&d.retina&&e.maxZoom>0?(e.tileSize=Math.floor(e.tileSize/2),e.zoomReverse?(e.zoomOffset--,e.minZoom=Math.min(e.maxZoom,e.minZoom+1)):(e.zoomOffset++,e.maxZoom=Math.max(e.minZoom,e.maxZoom-1)),e.minZoom=Math.max(0,e.minZoom)):e.zoomReverse?e.minZoom=Math.min(e.maxZoom,e.minZoom):e.maxZoom=Math.max(e.minZoom,e.maxZoom),typeof e.subdomains=="string"&&(e.subdomains=e.subdomains.split("")),this.on("tileunload",this._onTileRemove)},setUrl:function(t,e){return this._url===t&&e===void 0&&(e=!0),this._url=t,e||this.redraw(),this},createTile:function(t,e){var i=document.createElement("img");return x(i,"load",_(this._tileOnLoad,this,e,i)),x(i,"error",_(this._tileOnError,this,e,i)),(this.options.crossOrigin||this.options.crossOrigin==="")&&(i.crossOrigin=this.options.crossOrigin===!0?"":this.options.crossOrigin),typeof this.options.referrerPolicy=="string"&&(i.referrerPolicy=this.options.referrerPolicy),i.alt="",i.src=this.getTileUrl(t),i},getTileUrl:function(t){var e={r:d.retina?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var i=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=i),e["-y"]=i}return ue(this._url,c(e,this.options))},_tileOnLoad:function(t,e){d.ielt9?setTimeout(_(t,this,null,e),0):t(null,e)},_tileOnError:function(t,e,i){var n=this.options.errorTileUrl;n&&e.getAttribute("src")!==n&&(e.src=n),t(i,e)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,e=this.options.maxZoom,i=this.options.zoomReverse,n=this.options.zoomOffset;return i&&(t=e-t),t+n},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_abortLoading:function(){var t,e;for(t in this._tiles)if(this._tiles[t].coords.z!==this._tileZoom&&(e=this._tiles[t].el,e.onload=A,e.onerror=A,!e.complete)){e.src=Zt;var i=this._tiles[t].coords;D(e),delete this._tiles[t],this.fire("tileabort",{tile:e,coords:i})}},_removeTile:function(t){var e=this._tiles[t];if(e)return e.el.setAttribute("src",Zt),oe.prototype._removeTile.call(this,t)},_tileReady:function(t,e,i){if(!(!this._map||i&&i.getAttribute("src")===Zt))return oe.prototype._tileReady.call(this,t,e,i)}});function cn(t,e){return new Wt(t,e)}var fn=Wt.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var i=c({},this.defaultWmsParams);for(var n in e)n in this.options||(i[n]=e[n]);e=b(this,e);var o=e.detectRetina&&d.retina?2:1,s=this.getTileSize();i.width=s.x*o,i.height=s.y*o,this.wmsParams=i},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,Wt.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._tileCoordsToNwSe(t),i=this._crs,n=tt(i.project(e[0]),i.project(e[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===on?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=Wt.prototype.getTileUrl.call(this,t);return a+I(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return c(this.wmsParams,t),e||this.redraw(),this}});function Go(t,e){return new fn(t,e)}Wt.WMS=fn,cn.wms=Go;var bt=ft.extend({options:{padding:.1},initialize:function(t){b(this,t),m(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),T(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,e){var i=this._map.getZoomScale(e,this._zoom),n=this._map.getSize().multiplyBy(.5+this.options.padding),o=this._map.project(this._center,e),s=n.multiplyBy(-i).add(o).subtract(this._map._getNewPixelOrigin(t,e));d.any3d?kt(this._container,s,i):U(this._container,s)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,e=this._map.getSize(),i=this._map.containerPointToLayerPoint(e.multiplyBy(-t)).round();this._bounds=new R(i,i.add(e.multiplyBy(1+t*2)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),dn=bt.extend({options:{tolerance:0},getEvents:function(){var t=bt.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){bt.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");x(t,"mousemove",this._onMouseMove,this),x(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),x(t,"mouseout",this._handleMouseOut,this),t._leaflet_disable_events=!0,this._ctx=t.getContext("2d")},_destroyContainer:function(){at(this._redrawRequest),delete this._ctx,D(this._container),O(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){var t;this._redrawBounds=null;for(var e in this._layers)t=this._layers[e],t._update();this._redraw()}},_update:function(){if(!(this._map._animatingZoom&&this._bounds)){bt.prototype._update.call(this);var t=this._bounds,e=this._container,i=t.getSize(),n=d.retina?2:1;U(e,t.min),e.width=n*i.x,e.height=n*i.y,e.style.width=i.x+"px",e.style.height=i.y+"px",d.retina&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){bt.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[m(t)]=t;var e=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=e),this._drawLast=e,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var e=t._order,i=e.next,n=e.prev;i?i.prev=n:this._drawLast=n,n?n.next=i:this._drawFirst=i,delete t._order,delete this._layers[m(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(typeof t.options.dashArray=="string"){var e=t.options.dashArray.split(/[, ]+/),i=[],n,o;for(o=0;o')}}catch{}return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}(),Ko={_initContainer:function(){this._container=z("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(bt.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=se("shape");T(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=se("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[m(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;D(e),t.removeInteractiveTarget(e),delete this._layers[m(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(e||(e=t._stroke=se("stroke")),o.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=J(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(o.removeChild(e),t._stroke=null),n.fill?(i||(i=t._fill=se("fill")),o.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(o.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,"+65535*360)},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){It(t._container)},_bringToBack:function(t){Nt(t._container)}},ke=d.vml?se:gi,re=bt.extend({_initContainer:function(){this._container=ke("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=ke("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){D(this._container),O(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_update:function(){if(!(this._map._animatingZoom&&this._bounds)){bt.prototype._update.call(this);var t=this._bounds,e=t.getSize(),i=this._container;(!this._svgSize||!this._svgSize.equals(e))&&(this._svgSize=e,i.setAttribute("width",e.x),i.setAttribute("height",e.y)),U(i,t.min),i.setAttribute("viewBox",[t.min.x,t.min.y,e.x,e.y].join(" ")),this.fire("update")}},_initPath:function(t){var e=t._path=ke("path");t.options.className&&T(e,t.options.className),t.options.interactive&&T(e,"leaflet-interactive"),this._updateStyle(t),this._layers[m(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){D(t._path),t.removeInteractiveTarget(t._path),delete this._layers[m(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var e=t._path,i=t.options;e&&(i.stroke?(e.setAttribute("stroke",i.color),e.setAttribute("stroke-opacity",i.opacity),e.setAttribute("stroke-width",i.weight),e.setAttribute("stroke-linecap",i.lineCap),e.setAttribute("stroke-linejoin",i.lineJoin),i.dashArray?e.setAttribute("stroke-dasharray",i.dashArray):e.removeAttribute("stroke-dasharray"),i.dashOffset?e.setAttribute("stroke-dashoffset",i.dashOffset):e.removeAttribute("stroke-dashoffset")):e.setAttribute("stroke","none"),i.fill?(e.setAttribute("fill",i.fillColor||i.color),e.setAttribute("fill-opacity",i.fillOpacity),e.setAttribute("fill-rule",i.fillRule||"evenodd")):e.setAttribute("fill","none"))},_updatePoly:function(t,e){this._setPath(t,vi(t._parts,e))},_updateCircle:function(t){var e=t._point,i=Math.max(Math.round(t._radius),1),n=Math.max(Math.round(t._radiusY),1)||i,o="a"+i+","+n+" 0 1,0 ",s=t._empty()?"M0 0":"M"+(e.x-i)+","+e.y+o+i*2+",0 "+o+-i*2+",0 ";this._setPath(t,s)},_setPath:function(t,e){t._path.setAttribute("d",e)},_bringToFront:function(t){It(t._path)},_bringToBack:function(t){Nt(t._path)}});d.vml&&re.include(Ko);function mn(t){return d.svg||d.vml?new re(t):null}S.include({getRenderer:function(t){var e=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return e||(e=this._renderer=this._createRenderer()),this.hasLayer(e)||this.addLayer(e),e},_getPaneRenderer:function(t){if(t==="overlayPane"||t===void 0)return!1;var e=this._paneRenderers[t];return e===void 0&&(e=this._createRenderer({pane:t}),this._paneRenderers[t]=e),e},_createRenderer:function(t){return this.options.preferCanvas&&_n(t)||mn(t)}});var pn=Ht.extend({initialize:function(t,e){Ht.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=W(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});function jo(t,e){return new pn(t,e)}re.create=ke,re.pointsToPath=vi,Lt.geometryToLayer=xe,Lt.coordsToLatLng=ui,Lt.coordsToLatLngs=Pe,Lt.latLngToCoords=li,Lt.latLngsToCoords=Le,Lt.getFeature=Ft,Lt.asFeature=be,S.mergeOptions({boxZoom:!0});var gn=mt.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){x(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){O(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){D(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){this._resetStateTimeout!==0&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||t.which!==1&&t.button!==1)return!1;this._clearDeferredResetState(),this._resetState(),Xt(),Ge(),this._startPoint=this._map.mouseEventToContainerPoint(t),x(document,{contextmenu:At,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=z("div","leaflet-zoom-box",this._container),T(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var e=new R(this._point,this._startPoint),i=e.getSize();U(this._box,e.min),this._box.style.width=i.x+"px",this._box.style.height=i.y+"px"},_finish:function(){this._moved&&(D(this._box),F(this._container,"leaflet-crosshair")),Qt(),Ke(),O(document,{contextmenu:At,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if(!(t.which!==1&&t.button!==1)&&(this._finish(),!!this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(_(this._resetState,this),0);var e=new et(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(e).fire("boxzoomend",{boxZoomBounds:e})}},_onKeyDown:function(t){t.keyCode===27&&(this._finish(),this._clearDeferredResetState(),this._resetState())}});S.addInitHook("addHandler","boxZoom",gn),S.mergeOptions({doubleClickZoom:!0});var vn=mt.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom(),n=e.options.zoomDelta,o=t.originalEvent.shiftKey?i-n:i+n;e.options.doubleClickZoom==="center"?e.setZoom(o):e.setZoomAround(t.containerPoint,o)}});S.addInitHook("addHandler","doubleClickZoom",vn),S.mergeOptions({dragging:!0,inertia:!0,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var yn=mt.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Mt(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}T(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){F(this._map._container,"leaflet-grab"),F(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var e=W(this._map.options.maxBounds);this._offsetLimit=tt(this._map.latLngToContainerPoint(e.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(e.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var e=this._lastTime=+new Date,i=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(i),this._times.push(e),this._prunePositions(e)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,e){return t-(t-e)*this._viscosity},_onPreDragLimit:function(){if(!(!this._viscosity||!this._offsetLimit)){var t=this._draggable._newPos.subtract(this._draggable._startPos),e=this._offsetLimit;t.xe.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,r=Math.abs(o+i)0?s:-s))-e;this._delta=0,this._startTime=null,r&&(t.options.scrollWheelZoom==="center"?t.setZoom(e+r):t.setZoomAround(this._lastMousePos,e+r))}});S.addInitHook("addHandler","scrollWheelZoom",xn);var Jo=600;S.mergeOptions({tapHold:d.touchNative&&d.safari&&d.mobile,tapTolerance:15});var Pn=mt.extend({addHooks:function(){x(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){O(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(clearTimeout(this._holdTimeout),t.touches.length===1){var e=t.touches[0];this._startPos=this._newPos=new w(e.clientX,e.clientY),this._holdTimeout=setTimeout(_(function(){this._cancel(),this._isTapValid()&&(x(document,"touchend",j),x(document,"touchend touchcancel",this._cancelClickPrevent),this._simulateEvent("contextmenu",e))},this),Jo),x(document,"touchend touchcancel contextmenu",this._cancel,this),x(document,"touchmove",this._onMove,this)}},_cancelClickPrevent:function t(){O(document,"touchend",j),O(document,"touchend touchcancel",t)},_cancel:function(){clearTimeout(this._holdTimeout),O(document,"touchend touchcancel contextmenu",this._cancel,this),O(document,"touchmove",this._onMove,this)},_onMove:function(t){var e=t.touches[0];this._newPos=new w(e.clientX,e.clientY)},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_simulateEvent:function(t,e){var i=new MouseEvent(t,{bubbles:!0,cancelable:!0,view:window,screenX:e.screenX,screenY:e.screenY,clientX:e.clientX,clientY:e.clientY});i._simulated=!0,e.target.dispatchEvent(i)}});S.addInitHook("addHandler","tapHold",Pn),S.mergeOptions({touchZoom:d.touch,bounceAtZoomLimits:!0});var Ln=mt.extend({addHooks:function(){T(this._map._container,"leaflet-touch-zoom"),x(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){F(this._map._container,"leaflet-touch-zoom"),O(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var e=this._map;if(!(!t.touches||t.touches.length!==2||e._animatingZoom||this._zooming)){var i=e.mouseEventToContainerPoint(t.touches[0]),n=e.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=e.getSize()._divideBy(2),this._startLatLng=e.containerPointToLatLng(this._centerPoint),e.options.touchZoom!=="center"&&(this._pinchStartLatLng=e.containerPointToLatLng(i.add(n)._divideBy(2))),this._startDist=i.distanceTo(n),this._startZoom=e.getZoom(),this._moved=!1,this._zooming=!0,e._stop(),x(document,"touchmove",this._onTouchMove,this),x(document,"touchend touchcancel",this._onTouchEnd,this),j(t)}},_onTouchMove:function(t){if(!(!t.touches||t.touches.length!==2||!this._zooming)){var e=this._map,i=e.mouseEventToContainerPoint(t.touches[0]),n=e.mouseEventToContainerPoint(t.touches[1]),o=i.distanceTo(n)/this._startDist;if(this._zoom=e.getScaleZoom(o,this._startZoom),!e.options.bounceAtZoomLimits&&(this._zoome.getMaxZoom()&&o>1)&&(this._zoom=e._limitZoom(this._zoom)),e.options.touchZoom==="center"){if(this._center=this._startLatLng,o===1)return}else{var s=i._add(n)._divideBy(2)._subtract(this._centerPoint);if(o===1&&s.x===0&&s.y===0)return;this._center=e.unproject(e.project(this._pinchStartLatLng,this._zoom).subtract(s),this._zoom)}this._moved||(e._moveStart(!0,!1),this._moved=!0),at(this._animRequest);var r=_(e._move,e,this._center,this._zoom,{pinch:!0,round:!1},void 0);this._animRequest=q(r,this,!0),j(t)}},_onTouchEnd:function(){if(!this._moved||!this._zooming){this._zooming=!1;return}this._zooming=!1,at(this._animRequest),O(document,"touchmove",this._onTouchMove,this),O(document,"touchend touchcancel",this._onTouchEnd,this),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))}});S.addInitHook("addHandler","touchZoom",Ln),S.BoxZoom=gn,S.DoubleClickZoom=vn,S.Drag=yn,S.Keyboard=wn,S.ScrollWheelZoom=xn,S.TapHold=Pn,S.TouchZoom=Ln,u.Bounds=R,u.Browser=d,u.CRS=wt,u.Canvas=dn,u.Circle=hi,u.CircleMarker=we,u.Class=yt,u.Control=ct,u.DivIcon=ln,u.DivOverlay=pt,u.DomEvent=fo,u.DomUtil=lo,u.Draggable=Mt,u.Evented=Gt,u.FeatureGroup=xt,u.GeoJSON=Lt,u.GridLayer=oe,u.Handler=mt,u.Icon=Dt,u.ImageOverlay=Te,u.LatLng=E,u.LatLngBounds=et,u.Layer=ft,u.LayerGroup=Rt,u.LineUtil=Mo,u.Map=S,u.Marker=ye,u.Mixin=wo,u.Path=Ct,u.Point=w,u.PolyUtil=xo,u.Polygon=Ht,u.Polyline=Pt,u.Popup=Me,u.PosAnimation=qi,u.Projection=Co,u.Rectangle=pn,u.Renderer=bt,u.SVG=re,u.SVGOverlay=un,u.TileLayer=Wt,u.Tooltip=Ce,u.Transformation=Ze,u.Util=En,u.VideoOverlay=hn,u.bind=_,u.bounds=tt,u.canvas=_n,u.circle=Bo,u.circleMarker=Zo,u.control=ee,u.divIcon=Vo,u.extend=c,u.featureGroup=Ao,u.geoJSON=an,u.geoJson=Ro,u.gridLayer=qo,u.icon=Eo,u.imageOverlay=Do,u.latLng=k,u.latLngBounds=W,u.layerGroup=zo,u.map=_o,u.marker=Oo,u.point=y,u.polygon=No,u.polyline=Io,u.popup=Wo,u.rectangle=jo,u.setOptions=b,u.stamp=m,u.svg=mn,u.svgOverlay=Fo,u.tileLayer=cn,u.tooltip=Uo,u.transformation=Kt,u.version=v,u.videoOverlay=Ho;var Yo=window.L;u.noConflict=function(){return window.L=Yo,this},window.L=u})})(di,di.exports);var vs=di.exports;const Ot=ss(vs),ys="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=",ws="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAABSCAMAAAAhFXfZAAAC91BMVEVMaXEzeak2f7I4g7g3g7cua5gzeKg8hJo3grY4g7c3grU0gLI2frE0daAubJc2gbQwd6QzeKk2gLMtd5sxdKIua5g1frA2f7IydaM0e6w2fq41fK01eqo3grgubJgta5cxdKI1f7AydaQydaMxc6EubJgvbJkwcZ4ubZkwcJwubZgubJcydqUydKIxapgubJctbJcubZcubJcvbJYubJcvbZkubJctbJctbZcubJg2f7AubJcrbZcubJcubJcua5g3grY0fq8ubJcubJdEkdEwhsw6i88vhswuhcsuhMtBjMgthMsrg8srgss6is8qgcs8i9A9iMYtg8spgcoogMo7hcMngMonf8olfso4gr8kfck5iM8jfMk4iM8he8k1fro7itAgesk2hs8eecgzfLcofssdeMg0hc4cd8g2hcsxeLQbdsgZdcgxeLImfcszhM0vda4xgckzhM4xg84wf8Yxgs4udKsvfcQucqhUndROmdM1fK0wcZ8vb5w0eqpQm9MzeKhXoNVcpdYydKNWn9VZotVKltJFjsIwcJ1Rms9OlslLmtH///8+kc9epdYzd6dbo9VHkMM2f7FHmNBClM8ydqVcpNY9hro3gLM9hLczealQmcw3fa46f7A8gLMxc6I3eagyc6FIldJMl9JSnNRSntNNl9JPnNJFi75UnM9ZodVKksg8kM45jc09e6ZHltFBk883gbRBh7pDk9EwcaBzn784g7dKkcY2i81Om9M7j85Llc81is09g7Q4grY/j9A0eqxKmdFFltBEjcXf6fFImdBCiLxJl9FGlNFBi78yiMxVndEvbpo6js74+vx+psPP3+o/ks5HkcpGmNCjwdZCkNDM3ehYoNJEls+lxNkxh8xHks0+jdC1zd5Lg6r+/v/H2ufz9/o3jM3t8/edvdM/k89Th61OiLBSjbZklbaTt9BfptdjmL1AicBHj8hGk9FAgK1dkLNTjLRekrdClc/k7fM0icy0y9tgp9c4jc2NtM9Dlc8zicxeXZn3AAAAQ3RSTlMAHDdTb4yPA+LtnEQmC4L2EmHqB7XA0d0sr478x4/Yd5i1zOfyPkf1sLVq4Nh3FvjxopQ2/STNuFzUwFIwxKaejILpIBEV9wAABhVJREFUeF6s1NdyFEcYBeBeoQIhRAkLlRDGrhIgY3BJL8CVeKzuyXFzzjkn5ZxzzuScg3PO8cKzu70JkO0LfxdTU//pM9vTu7Xgf6KqOVTb9X7toRrVEfBf1HTVjZccrT/2by1VV928Yty9ZbVuucdz90frG8DBjl9pVApbOstvmMuvVgaNXSfAAd6pGxpy6yxf5ph43pS/4f3uoaGm2rdu72S9xzOvMymkZFq/ptDrk90mhW7e4zl7HLzhxGWPR20xmSxJ/VqldG5m9XhaVOA1DadsNh3Pu5L2N6QtPO/32JpqQBVVk20oy/Pi2s23WEvyfHbe1thadVQttvm7Llf65gGmXK67XtupyoM7HQhmXdLS8oGWJNeOJ3C5fG5XCEJnkez3/oFdsvgJ4l2ANZwhrJKk/7OSXa+3Vw2WJMlKnGkobouYk6T0TyX30klOUnTD9HJ5qpckL3EW/w4XF3Xd0FGywXUrstrclVsqz5Pd/sXFYyDnPdrLcQODmGOK47IZb4CmibmMn+MYRzFZ5jg33ZL/EJrWcszHmANy3ARBK/IXtciJy8VsitPSdE3uuHxzougojcUdr8/32atnz/ev3f/K5wtpxUTpcaI45zusVDpYtZi+jg0oU9b3x74h7+n9ABvYEZeKaVq0sh0AtLKsFtqNBdeT0MrSzwwlq9+x6xAO4tgOtSzbCjrNQQiNvQUbUEubvzBUeGw26yDCsRHCoLkTHDa7IdOLIThs/gHvChszh2CimE8peRs47cxANI0lYNB5y1DljpOF0IhzBDPOZnDOqYYbeGKECbPzWnXludPphw5c2YBq5zlwXphIbO4VDCZ0gnPfUO1TwZoYwAs2ExPCedAu9DAjfQUjzITQb3jNj0KG2Sgt6BHaQUdYzWz+XmBktOHwanXjaSTcwwziBcuMOtwBmqPrTOxFQR/DRKKPqyur0aiW6cULYsx6tBm0jXpR/AUWR6HRq9WVW6MRhIq5jLyjbaCTDCijyYJNpCajdyobP/eTw0iexBAKkJ3gA5KcQb2zBXsIBckn+xVv8jkZSaEFHE+jFEleAEfayRU0MouNoBmB/L50Ai/HSLIHxcrpCvnhSQAuakKp2C/YbCylJjXRVy/z3+Kv/RrNcCo+WUzlVEhzKffnTQnxeN9fWF88fiNCUdSTsaufaChKWInHeysygfpIqagoakW+vV20J8uyl6TyNKEZWV4oRSPyCkWpgOLSbkCObT8o2r6tlG58HQquf6O0v50tB7JM7F4EORd2dx/K0w/KHsVkLPaoYrwgP/y7krr3SSMA4zj+OBgmjYkxcdIJQyQRKgg2viX9Hddi9UBb29LrKR7CVVEEEXWojUkXNyfTNDE14W9gbHJNuhjDettN3ZvbOvdOqCD3Jp/9l+/wJE+9PkYGjx/fqkys3S2rMozM/o2106rfMUINo6hVqz+eu/hd1c4xTg0TAfy5kV+4UG6+IthHTU9woWmxuKNbTfuCSfovBCxq7EtHqvYL4Sm6F8GVxsSXHMQ07TOi1DKtZxjWaaIyi4CXWjxPccUw8WVbMYY5wxC1mzEyXMJWkllpRloi+Kkoq69sxBTlElF6aAxYUbjXNlhlDZilDnM4U5SlN5biRsRHnbx3mbeWjEh4mEyiuJDl5XcWVmX5GvNkFgLWZM5qwsop4/AWfLhU1cR7k1VVvcYCWRkOI6Xy5gmnphCYIkvzuNYzHzosq2oNk2RtSs8khfUOfHIDgR6ysYBaMpl4uEgk2U/oJTs9AaTSwma7dT69geAE2ZpEjUsn2ieJNHeKfrI3EcAGJ2ZaNgVuC8EBctCLc57P5u5led6IOBkIYkuQMrmmjChs4VkfOerHqSBkPzZlhe06RslZ3zMjk2sscqKwY0RcjKK+LWbzd7KiHhkncs/siFJ+V5eXxD34B8nVuJEpGJNmxN2gH3vSvp7J70tF+D1Ej8qUJD1TkErAND2GZwTFg/LubvmgiBG3SOvdlsqFQrkEzJCL1rstlnVFROixZoDDSuXQFHESwVGlcuQcMb/b42NgjLowh5MTDFE3vNB5qStRIErdCQEh6pLPR92anSUb/wAIhldAaDMpGgAAAABJRU5ErkJggg==",xs="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAQAAAACach9AAACMUlEQVR4Ae3ShY7jQBAE0Aoz/f9/HTMzhg1zrdKUrJbdx+Kd2nD8VNudfsL/Th///dyQN2TH6f3y/BGpC379rV+S+qqetBOxImNQXL8JCAr2V4iMQXHGNJxeCfZXhSRBcQMfvkOWUdtfzlLgAENmZDcmo2TVmt8OSM2eXxBp3DjHSMFutqS7SbmemzBiR+xpKCNUIRkdkkYxhAkyGoBvyQFEJEefwSmmvBfJuJ6aKqKWnAkvGZOaZXTUgFqYULWNSHUckZuR1HIIimUExutRxwzOLROIG4vKmCKQt364mIlhSyzAf1m9lHZHJZrlAOMMztRRiKimp/rpdJDc9Awry5xTZCte7FHtuS8wJgeYGrex28xNTd086Dik7vUMscQOa8y4DoGtCCSkAKlNwpgNtphjrC6MIHUkR6YWxxs6Sc5xqn222mmCRFzIt8lEdKx+ikCtg91qS2WpwVfBelJCiQJwvzixfI9cxZQWgiSJelKnwBElKYtDOb2MFbhmUigbReQBV0Cg4+qMXSxXSyGUn4UbF8l+7qdSGnTC0XLCmahIgUHLhLOhpVCtw4CzYXvLQWQbJNmxoCsOKAxSgBJno75avolkRw8iIAFcsdc02e9iyCd8tHwmeSSoKTowIgvscSGZUOA7PuCN5b2BX9mQM7S0wYhMNU74zgsPBj3HU7wguAfnxxjFQGBE6pwN+GjME9zHY7zGp8wVxMShYX9NXvEWD3HbwJf4giO4CFIQxXScH1/TM+04kkBiAAAAAElFTkSuQmCC";function Sn(C,g,u){const v=C.slice();return v[21]=g[u],v[23]=u,v}function Ps(C){let g,u,v,c;return{c(){g=vt("div"),u=vt("button"),u.innerHTML='',Y(u,"type","button"),Y(u,"class","btn btn-circle btn-xs btn-transparent"),Y(g,"class","form-field-addon")},m(P,_){he(P,g,_),gt(g,u),v||(c=_i(u,"click",C[5]),v=!0)},p:Ee,d(P){P&&ae(g),v=!1,c()}}}function Ls(C){let g;return{c(){g=vt("div"),g.innerHTML='',Y(g,"class","form-field-addon")},m(u,v){he(u,g,v)},p:Ee,d(u){u&&ae(g)}}}function zn(C){let g,u=kn(C[4]),v=[];for(let c=0;c{B==null||B.setLatLng([c.lat,c.lon]),P==null||P.panInside([c.lat,c.lon],{padding:[20,40]})},N)}function b(){const N=[ze(c.lat),ze(c.lon)];P=Ot.map(_,{zoomControl:!1}).setView(N,Ts),Ot.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png",{attribution:'© OpenStreetMap'}).addTo(P),Ot.Icon.Default.prototype.options.iconUrl=ys,Ot.Icon.Default.prototype.options.iconRetinaUrl=ws,Ot.Icon.Default.prototype.options.shadowUrl=xs,Ot.Icon.Default.imagePath="",B=Ot.marker(N,{draggable:!0,autoPan:!0}).addTo(P),B.bindTooltip("drag or right click anywhere on the map to move"),B.on("moveend",st=>{var $;($=st.sourceTarget)!=null&&$._latlng&&J(st.sourceTarget._latlng.lat,st.sourceTarget._latlng.lng,!1)}),P.on("contextmenu",st=>{J(st.latlng.lat,st.latlng.lng,!1)})}function I(){ot(),B==null||B.remove(),P==null||P.remove()}function ot(){H==null||H.abort(),clearTimeout(A),u(3,m=!1),u(4,X=[]),u(1,K="")}function ue(N,st=1100){if(u(3,m=!0),u(4,X=[]),clearTimeout(A),H==null||H.abort(),!N){u(3,m=!1);return}A=setTimeout(async()=>{H=new AbortController;try{const $=await fetch("https://nominatim.openstreetmap.org/search.php?format=jsonv2&q="+encodeURIComponent(N),{signal:H.signal});if($.status!=200)throw new Error("OpenStreetMap API error "+$.status);const le=await $.json();for(const q of le)X.push({lat:q.lat,lon:q.lon,name:q.display_name})}catch($){console.warn("[address search failed]",$)}u(4,X),u(3,m=!1)},st)}function J(N,st,$=!0){u(7,c.lat=ze(N),c),u(7,c.lon=ze(st),c),$&&(B==null||B.setLatLng([c.lat,c.lon]),P==null||P.panTo([c.lat,c.lon],{animate:!1})),ot()}ls(()=>(b(),()=>{I()}));function Vt(){K=this.value,u(1,K)}const Zt=N=>J(N.lat,N.lon);function qt(N){fs[N?"unshift":"push"](()=>{_=N,u(2,_)})}return C.$$set=N=>{"height"in N&&u(0,v=N.height),"point"in N&&u(7,c=N.point)},C.$$.update=()=>{C.$$.dirty&2&&ue(K),C.$$.dirty&128&&c.lat&&c.lon&&Z()},[v,K,_,m,X,ot,J,c,Vt,Zt,qt]}class ks extends as{constructor(g){super(),hs(this,g,Ms,bs,us,{height:0,point:7})}}export{ks as default}; diff --git a/ui/dist/assets/ListApiDocs-ByASLUZu.css b/ui/dist/assets/ListApiDocs-ByASLUZu.css deleted file mode 100644 index b4b41974..00000000 --- a/ui/dist/assets/ListApiDocs-ByASLUZu.css +++ /dev/null @@ -1 +0,0 @@ -.filter-op.svelte-1w7s5nw{display:inline-block;vertical-align:top;margin-right:5px;width:30px;text-align:center;padding-left:0;padding-right:0} diff --git a/ui/dist/assets/ListApiDocs-DGceQHQZ.js b/ui/dist/assets/ListApiDocs-DGceQHQZ.js deleted file mode 100644 index 907ffce4..00000000 --- a/ui/dist/assets/ListApiDocs-DGceQHQZ.js +++ /dev/null @@ -1,137 +0,0 @@ -import{S as el,i as ll,s as sl,H as ze,h as m,l as h,o as nl,u as e,v as s,L as ol,w as a,n as t,A as g,V as al,W as Le,X as ae,d as Kt,Y as il,t as Ct,a as kt,I as ve,Z as Je,_ as rl,C as cl,$ as dl,D as pl,m as Qt,c as Vt,J as Te,p as fl,k as Ae}from"./index-DMlPjiFP.js";import{F as ul}from"./FieldsQueryParam-B36GF025.js";function ml(r){let n,o,i;return{c(){n=e("span"),n.textContent="Show details",o=s(),i=e("i"),a(n,"class","txt"),a(i,"class","ri-arrow-down-s-line")},m(f,b){h(f,n,b),h(f,o,b),h(f,i,b)},d(f){f&&(m(n),m(o),m(i))}}}function hl(r){let n,o,i;return{c(){n=e("span"),n.textContent="Hide details",o=s(),i=e("i"),a(n,"class","txt"),a(i,"class","ri-arrow-up-s-line")},m(f,b){h(f,n,b),h(f,o,b),h(f,i,b)},d(f){f&&(m(n),m(o),m(i))}}}function Ke(r){let n,o,i,f,b,p,u,C,_,x,d,Y,yt,Wt,E,Xt,D,it,P,Z,ie,j,U,re,rt,vt,tt,Ft,ce,ct,dt,et,N,Yt,Lt,k,lt,At,Zt,Tt,z,st,Pt,te,Rt,v,pt,Ot,de,ft,pe,H,St,nt,Et,F,ut,fe,J,Nt,ee,qt,le,Dt,ue,L,mt,me,ht,he,M,be,T,Ht,ot,Mt,K,bt,ge,I,It,y,Bt,at,Gt,_e,Q,gt,we,_t,xe,jt,$e,B,Ut,Ce,G,ke,wt,se,R,xt,V,W,O,zt,ne,X;return{c(){n=e("p"),n.innerHTML=`The syntax basically follows the format - OPERAND OPERATOR OPERAND, where:`,o=s(),i=e("ul"),f=e("li"),f.innerHTML=`OPERAND - could be any of the above field literal, string (single - or double quoted), number, null, true, false`,b=s(),p=e("li"),u=e("code"),u.textContent="OPERATOR",C=g(` - is one of: - `),_=e("br"),x=s(),d=e("ul"),Y=e("li"),yt=e("code"),yt.textContent="=",Wt=s(),E=e("span"),E.textContent="Equal",Xt=s(),D=e("li"),it=e("code"),it.textContent="!=",P=s(),Z=e("span"),Z.textContent="NOT equal",ie=s(),j=e("li"),U=e("code"),U.textContent=">",re=s(),rt=e("span"),rt.textContent="Greater than",vt=s(),tt=e("li"),Ft=e("code"),Ft.textContent=">=",ce=s(),ct=e("span"),ct.textContent="Greater than or equal",dt=s(),et=e("li"),N=e("code"),N.textContent="<",Yt=s(),Lt=e("span"),Lt.textContent="Less than",k=s(),lt=e("li"),At=e("code"),At.textContent="<=",Zt=s(),Tt=e("span"),Tt.textContent="Less than or equal",z=s(),st=e("li"),Pt=e("code"),Pt.textContent="~",te=s(),Rt=e("span"),Rt.textContent=`Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for - wildcard match)`,v=s(),pt=e("li"),Ot=e("code"),Ot.textContent="!~",de=s(),ft=e("span"),ft.textContent=`NOT Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for - wildcard match)`,pe=s(),H=e("li"),St=e("code"),St.textContent="?=",nt=s(),Et=e("em"),Et.textContent="Any/At least one of",F=s(),ut=e("span"),ut.textContent="Equal",fe=s(),J=e("li"),Nt=e("code"),Nt.textContent="?!=",ee=s(),qt=e("em"),qt.textContent="Any/At least one of",le=s(),Dt=e("span"),Dt.textContent="NOT equal",ue=s(),L=e("li"),mt=e("code"),mt.textContent="?>",me=s(),ht=e("em"),ht.textContent="Any/At least one of",he=s(),M=e("span"),M.textContent="Greater than",be=s(),T=e("li"),Ht=e("code"),Ht.textContent="?>=",ot=s(),Mt=e("em"),Mt.textContent="Any/At least one of",K=s(),bt=e("span"),bt.textContent="Greater than or equal",ge=s(),I=e("li"),It=e("code"),It.textContent="?<",y=s(),Bt=e("em"),Bt.textContent="Any/At least one of",at=s(),Gt=e("span"),Gt.textContent="Less than",_e=s(),Q=e("li"),gt=e("code"),gt.textContent="?<=",we=s(),_t=e("em"),_t.textContent="Any/At least one of",xe=s(),jt=e("span"),jt.textContent="Less than or equal",$e=s(),B=e("li"),Ut=e("code"),Ut.textContent="?~",Ce=s(),G=e("em"),G.textContent="Any/At least one of",ke=s(),wt=e("span"),wt.textContent=`Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for - wildcard match)`,se=s(),R=e("li"),xt=e("code"),xt.textContent="?!~",V=s(),W=e("em"),W.textContent="Any/At least one of",O=s(),zt=e("span"),zt.textContent=`NOT Like/Contains (if not specified auto wraps the right string OPERAND in a "%" for - wildcard match)`,ne=s(),X=e("p"),X.innerHTML=`To group and combine several expressions you could use brackets - (...), && (AND) and || (OR) tokens.`,a(u,"class","txt-danger"),a(yt,"class","filter-op svelte-1w7s5nw"),a(E,"class","txt"),a(it,"class","filter-op svelte-1w7s5nw"),a(Z,"class","txt"),a(U,"class","filter-op svelte-1w7s5nw"),a(rt,"class","txt"),a(Ft,"class","filter-op svelte-1w7s5nw"),a(ct,"class","txt"),a(N,"class","filter-op svelte-1w7s5nw"),a(Lt,"class","txt"),a(At,"class","filter-op svelte-1w7s5nw"),a(Tt,"class","txt"),a(Pt,"class","filter-op svelte-1w7s5nw"),a(Rt,"class","txt"),a(Ot,"class","filter-op svelte-1w7s5nw"),a(ft,"class","txt"),a(St,"class","filter-op svelte-1w7s5nw"),a(Et,"class","txt-hint"),a(ut,"class","txt"),a(Nt,"class","filter-op svelte-1w7s5nw"),a(qt,"class","txt-hint"),a(Dt,"class","txt"),a(mt,"class","filter-op svelte-1w7s5nw"),a(ht,"class","txt-hint"),a(M,"class","txt"),a(Ht,"class","filter-op svelte-1w7s5nw"),a(Mt,"class","txt-hint"),a(bt,"class","txt"),a(It,"class","filter-op svelte-1w7s5nw"),a(Bt,"class","txt-hint"),a(Gt,"class","txt"),a(gt,"class","filter-op svelte-1w7s5nw"),a(_t,"class","txt-hint"),a(jt,"class","txt"),a(Ut,"class","filter-op svelte-1w7s5nw"),a(G,"class","txt-hint"),a(wt,"class","txt"),a(xt,"class","filter-op svelte-1w7s5nw"),a(W,"class","txt-hint"),a(zt,"class","txt")},m($,$t){h($,n,$t),h($,o,$t),h($,i,$t),t(i,f),t(i,b),t(i,p),t(p,u),t(p,C),t(p,_),t(p,x),t(p,d),t(d,Y),t(Y,yt),t(Y,Wt),t(Y,E),t(d,Xt),t(d,D),t(D,it),t(D,P),t(D,Z),t(d,ie),t(d,j),t(j,U),t(j,re),t(j,rt),t(d,vt),t(d,tt),t(tt,Ft),t(tt,ce),t(tt,ct),t(d,dt),t(d,et),t(et,N),t(et,Yt),t(et,Lt),t(d,k),t(d,lt),t(lt,At),t(lt,Zt),t(lt,Tt),t(d,z),t(d,st),t(st,Pt),t(st,te),t(st,Rt),t(d,v),t(d,pt),t(pt,Ot),t(pt,de),t(pt,ft),t(d,pe),t(d,H),t(H,St),t(H,nt),t(H,Et),t(H,F),t(H,ut),t(d,fe),t(d,J),t(J,Nt),t(J,ee),t(J,qt),t(J,le),t(J,Dt),t(d,ue),t(d,L),t(L,mt),t(L,me),t(L,ht),t(L,he),t(L,M),t(d,be),t(d,T),t(T,Ht),t(T,ot),t(T,Mt),t(T,K),t(T,bt),t(d,ge),t(d,I),t(I,It),t(I,y),t(I,Bt),t(I,at),t(I,Gt),t(d,_e),t(d,Q),t(Q,gt),t(Q,we),t(Q,_t),t(Q,xe),t(Q,jt),t(d,$e),t(d,B),t(B,Ut),t(B,Ce),t(B,G),t(B,ke),t(B,wt),t(d,se),t(d,R),t(R,xt),t(R,V),t(R,W),t(R,O),t(R,zt),h($,ne,$t),h($,X,$t)},d($){$&&(m(n),m(o),m(i),m(ne),m(X))}}}function bl(r){let n,o,i,f,b;function p(x,d){return x[0]?hl:ml}let u=p(r),C=u(r),_=r[0]&&Ke();return{c(){n=e("button"),C.c(),o=s(),_&&_.c(),i=ol(),a(n,"class","btn btn-sm btn-secondary m-t-10")},m(x,d){h(x,n,d),C.m(n,null),h(x,o,d),_&&_.m(x,d),h(x,i,d),f||(b=nl(n,"click",r[1]),f=!0)},p(x,[d]){u!==(u=p(x))&&(C.d(1),C=u(x),C&&(C.c(),C.m(n,null))),x[0]?_||(_=Ke(),_.c(),_.m(i.parentNode,i)):_&&(_.d(1),_=null)},i:ze,o:ze,d(x){x&&(m(n),m(o),m(i)),C.d(),_&&_.d(x),f=!1,b()}}}function gl(r,n,o){let i=!1;function f(){o(0,i=!i)}return[i,f]}class _l extends el{constructor(n){super(),ll(this,n,gl,bl,sl,{})}}function Qe(r,n,o){const i=r.slice();return i[8]=n[o],i}function Ve(r,n,o){const i=r.slice();return i[8]=n[o],i}function We(r,n,o){const i=r.slice();return i[13]=n[o],i[15]=o,i}function Xe(r){let n;return{c(){n=e("p"),n.innerHTML="Requires superuser Authorization:TOKEN header",a(n,"class","txt-hint txt-sm txt-right")},m(o,i){h(o,n,i)},d(o){o&&m(n)}}}function Ye(r){let n,o=r[13]+"",i,f=r[15]'2022-01-01') - `}}),ot=new _l({}),at=new Le({props:{content:"?expand=relField1,relField2.subRelField"}}),G=new ul({});let Fe=ae(r[5]);const Pe=l=>l[8].code;for(let l=0;ll[8].code;for(let l=0;lParam Type Description',Lt=s(),k=e("tbody"),lt=e("tr"),lt.innerHTML='page Number The page (aka. offset) of the paginated list (default to 1).',At=s(),Zt=e("tr"),Zt.innerHTML='perPage Number Specify the max returned records per page (default to 30).',Tt=s(),z=e("tr"),st=e("td"),st.textContent="sort",Pt=s(),te=e("td"),te.innerHTML='String',Rt=s(),v=e("td"),pt=g("Specify the records order attribute(s). "),Ot=e("br"),de=g(` - Add `),ft=e("code"),ft.textContent="-",pe=g(" / "),H=e("code"),H.textContent="+",St=g(` (default) in front of the attribute for DESC / ASC order. - Ex.: - `),Vt(nt.$$.fragment),Et=s(),F=e("p"),ut=e("strong"),ut.textContent="Supported record sort fields:",fe=s(),J=e("br"),Nt=s(),ee=e("code"),ee.textContent="@random",qt=g(`, - `),le=e("code"),le.textContent="@rowid",Dt=g(`, - `);for(let l=0;lString',he=s(),M=e("td"),be=g(`Filter the returned records. Ex.: - `),Vt(T.$$.fragment),Ht=s(),Vt(ot.$$.fragment),Mt=s(),K=e("tr"),bt=e("td"),bt.textContent="expand",ge=s(),I=e("td"),I.innerHTML='String',It=s(),y=e("td"),Bt=g(`Auto expand record relations. Ex.: - `),Vt(at.$$.fragment),Gt=g(` - Supports up to 6-levels depth nested relations expansion. `),_e=e("br"),Q=g(` - The expanded relations will be appended to each individual record under the - `),gt=e("code"),gt.textContent="expand",we=g(" property (eg. "),_t=e("code"),_t.textContent='"expand": {"relField1": {...}, ...}',xe=g(`). - `),jt=e("br"),$e=g(` - Only the relations to which the request user has permissions to `),B=e("strong"),B.textContent="view",Ut=g(" will be expanded."),Ce=s(),Vt(G.$$.fragment),ke=s(),wt=e("tr"),wt.innerHTML=`skipTotal Boolean If it is set the total counts query will be skipped and the response fields - totalItems and totalPages will have -1 value. -
    - This could drastically speed up the search queries when the total counters are not needed or cursor - based pagination is used. -
    - For optimization purposes, it is set by default for the - getFirstListItem() - and - getFullList() SDKs methods.`,se=s(),R=e("div"),R.textContent="Responses",xt=s(),V=e("div"),W=e("div");for(let l=0;lo(2,C=d.code);return r.$$set=d=>{"collection"in d&&o(0,u=d.collection)},r.$$.update=()=>{r.$$.dirty&1&&o(4,i=Te.getAllCollectionIdentifiers(u)),r.$$.dirty&1&&o(1,f=(u==null?void 0:u.listRule)===null),r.$$.dirty&1&&o(6,p=Te.dummyCollectionRecord(u)),r.$$.dirty&67&&u!=null&&u.id&&(_.push({code:200,body:JSON.stringify({page:1,perPage:30,totalPages:1,totalItems:2,items:[p,Object.assign({},p,{id:p.id+"2"})]},null,2)}),_.push({code:400,body:` - { - "status": 400, - "message": "Something went wrong while processing your request. Invalid filter.", - "data": {} - } - `}),f&&_.push({code:403,body:` - { - "status": 403, - "message": "Only superusers can access this action.", - "data": {} - } - `}))},o(3,b=Te.getApiExampleUrl(fl.baseURL)),[u,f,C,b,i,_,p,x]}class kl extends el{constructor(n){super(),ll(this,n,xl,wl,sl,{collection:0})}}export{kl as default}; diff --git a/ui/dist/assets/PageInstaller-DktNc-jf.js b/ui/dist/assets/PageInstaller-DktNc-jf.js deleted file mode 100644 index 568b691d..00000000 --- a/ui/dist/assets/PageInstaller-DktNc-jf.js +++ /dev/null @@ -1,3 +0,0 @@ -import{S as W,i as G,s as J,F as Q,d as S,t as E,a as O,m as j,c as D,r as M,g as V,p as C,b as X,e as Y,f as K,h as m,j as Z,k as z,l as h,n as T,o as I,q as x,u as k,v as q,w as r,x as ee,y as U,z as A,A as N,B as te}from"./index-DMlPjiFP.js";function ne(s){let t,o,u,n,e,p,_,d;return{c(){t=k("label"),o=N("Email"),n=q(),e=k("input"),r(t,"for",u=s[20]),r(e,"type","email"),r(e,"autocomplete","off"),r(e,"id",p=s[20]),e.disabled=s[7],e.required=!0},m(a,i){h(a,t,i),T(t,o),h(a,n,i),h(a,e,i),s[11](e),A(e,s[2]),_||(d=I(e,"input",s[12]),_=!0)},p(a,i){i&1048576&&u!==(u=a[20])&&r(t,"for",u),i&1048576&&p!==(p=a[20])&&r(e,"id",p),i&128&&(e.disabled=a[7]),i&4&&e.value!==a[2]&&A(e,a[2])},d(a){a&&(m(t),m(n),m(e)),s[11](null),_=!1,d()}}}function le(s){let t,o,u,n,e,p,_,d,a,i;return{c(){t=k("label"),o=N("Password"),n=q(),e=k("input"),_=q(),d=k("div"),d.textContent="Recommended at least 10 characters.",r(t,"for",u=s[20]),r(e,"type","password"),r(e,"autocomplete","new-password"),r(e,"minlength","10"),r(e,"id",p=s[20]),e.disabled=s[7],e.required=!0,r(d,"class","help-block")},m(c,g){h(c,t,g),T(t,o),h(c,n,g),h(c,e,g),A(e,s[3]),h(c,_,g),h(c,d,g),a||(i=I(e,"input",s[13]),a=!0)},p(c,g){g&1048576&&u!==(u=c[20])&&r(t,"for",u),g&1048576&&p!==(p=c[20])&&r(e,"id",p),g&128&&(e.disabled=c[7]),g&8&&e.value!==c[3]&&A(e,c[3])},d(c){c&&(m(t),m(n),m(e),m(_),m(d)),a=!1,i()}}}function se(s){let t,o,u,n,e,p,_,d;return{c(){t=k("label"),o=N("Password confirm"),n=q(),e=k("input"),r(t,"for",u=s[20]),r(e,"type","password"),r(e,"minlength","10"),r(e,"id",p=s[20]),e.disabled=s[7],e.required=!0},m(a,i){h(a,t,i),T(t,o),h(a,n,i),h(a,e,i),A(e,s[4]),_||(d=I(e,"input",s[14]),_=!0)},p(a,i){i&1048576&&u!==(u=a[20])&&r(t,"for",u),i&1048576&&p!==(p=a[20])&&r(e,"id",p),i&128&&(e.disabled=a[7]),i&16&&e.value!==a[4]&&A(e,a[4])},d(a){a&&(m(t),m(n),m(e)),_=!1,d()}}}function ie(s){let t,o,u,n,e,p,_,d,a,i,c,g,B,w,F,$,v,y,L;return n=new K({props:{class:"form-field required",name:"email",$$slots:{default:[ne,({uniqueId:l})=>({20:l}),({uniqueId:l})=>l?1048576:0]},$$scope:{ctx:s}}}),p=new K({props:{class:"form-field required",name:"password",$$slots:{default:[le,({uniqueId:l})=>({20:l}),({uniqueId:l})=>l?1048576:0]},$$scope:{ctx:s}}}),d=new K({props:{class:"form-field required",name:"passwordConfirm",$$slots:{default:[se,({uniqueId:l})=>({20:l}),({uniqueId:l})=>l?1048576:0]},$$scope:{ctx:s}}}),{c(){t=k("form"),o=k("div"),o.innerHTML="

    Create your first superuser account in order to continue

    ",u=q(),D(n.$$.fragment),e=q(),D(p.$$.fragment),_=q(),D(d.$$.fragment),a=q(),i=k("button"),i.innerHTML='Create superuser and login ',c=q(),g=k("hr"),B=q(),w=k("label"),w.innerHTML=' Or initialize from backup',F=q(),$=k("input"),r(o,"class","content txt-center m-b-base"),r(i,"type","submit"),r(i,"class","btn btn-lg btn-block btn-next"),z(i,"btn-disabled",s[7]),z(i,"btn-loading",s[0]),r(t,"class","block"),r(t,"autocomplete","off"),r(w,"for","backupFileInput"),r(w,"class","btn btn-lg btn-hint btn-transparent btn-block"),z(w,"btn-disabled",s[7]),z(w,"btn-loading",s[1]),r($,"id","backupFileInput"),r($,"type","file"),r($,"class","hidden"),r($,"accept",".zip")},m(l,b){h(l,t,b),T(t,o),T(t,u),j(n,t,null),T(t,e),j(p,t,null),T(t,_),j(d,t,null),T(t,a),T(t,i),h(l,c,b),h(l,g,b),h(l,B,b),h(l,w,b),h(l,F,b),h(l,$,b),s[15]($),v=!0,y||(L=[I(t,"submit",x(s[8])),I($,"change",s[16])],y=!0)},p(l,b){const H={};b&3145892&&(H.$$scope={dirty:b,ctx:l}),n.$set(H);const f={};b&3145864&&(f.$$scope={dirty:b,ctx:l}),p.$set(f);const P={};b&3145872&&(P.$$scope={dirty:b,ctx:l}),d.$set(P),(!v||b&128)&&z(i,"btn-disabled",l[7]),(!v||b&1)&&z(i,"btn-loading",l[0]),(!v||b&128)&&z(w,"btn-disabled",l[7]),(!v||b&2)&&z(w,"btn-loading",l[1])},i(l){v||(O(n.$$.fragment,l),O(p.$$.fragment,l),O(d.$$.fragment,l),v=!0)},o(l){E(n.$$.fragment,l),E(p.$$.fragment,l),E(d.$$.fragment,l),v=!1},d(l){l&&(m(t),m(c),m(g),m(B),m(w),m(F),m($)),S(n),S(p),S(d),s[15](null),y=!1,Z(L)}}}function ae(s){let t,o;return t=new Q({props:{$$slots:{default:[ie]},$$scope:{ctx:s}}}),{c(){D(t.$$.fragment)},m(u,n){j(t,u,n),o=!0},p(u,[n]){const e={};n&2097407&&(e.$$scope={dirty:n,ctx:u}),t.$set(e)},i(u){o||(O(t.$$.fragment,u),o=!0)},o(u){E(t.$$.fragment,u),o=!1},d(u){S(t,u)}}}function oe(s,t,o){let u,{params:n}=t,e="",p="",_="",d=!1,a=!1,i,c;g();async function g(){if(!(n!=null&&n.token))return M("/");o(0,d=!0);try{const f=V(n==null?void 0:n.token);await C.collection("_superusers").getOne(f.id,{requestKey:"installer_token_check",headers:{Authorization:n==null?void 0:n.token}})}catch(f){f!=null&&f.isAbort||(X("The installer token is invalid or has expired."),M("/"))}o(0,d=!1),await Y(),i==null||i.focus()}async function B(){if(!u){o(0,d=!0);try{await C.collection("_superusers").create({email:e,password:p,passwordConfirm:_},{headers:{Authorization:n==null?void 0:n.token}}),await C.collection("_superusers").authWithPassword(e,p),M("/")}catch(f){C.error(f)}o(0,d=!1)}}function w(){c&&o(6,c.value="",c)}function F(f){f&&ee(`Note that we don't perform validations for the uploaded backup files. Proceed with caution and only if you trust the file source. - -Do you really want to upload and initialize "${f.name}"?`,()=>{$(f)},()=>{w()})}async function $(f){if(!(!f||u)){o(1,a=!0);try{await C.backups.upload({file:f},{headers:{Authorization:n==null?void 0:n.token}}),await C.backups.restore(f.name,{headers:{Authorization:n==null?void 0:n.token}}),te("Please wait while extracting the uploaded archive!"),await new Promise(P=>setTimeout(P,2e3)),M("/")}catch(P){C.error(P)}w(),o(1,a=!1)}}function v(f){U[f?"unshift":"push"](()=>{i=f,o(5,i)})}function y(){e=this.value,o(2,e)}function L(){p=this.value,o(3,p)}function l(){_=this.value,o(4,_)}function b(f){U[f?"unshift":"push"](()=>{c=f,o(6,c)})}const H=f=>{var P,R;F((R=(P=f.target)==null?void 0:P.files)==null?void 0:R[0])};return s.$$set=f=>{"params"in f&&o(10,n=f.params)},s.$$.update=()=>{s.$$.dirty&3&&o(7,u=d||a)},[d,a,e,p,_,i,c,u,B,F,n,v,y,L,l,b,H]}class re extends W{constructor(t){super(),G(this,t,oe,ae,J,{params:10})}}export{re as default}; diff --git a/ui/dist/assets/PageOAuth2RedirectFailure-CguUZswk.js b/ui/dist/assets/PageOAuth2RedirectFailure-CguUZswk.js deleted file mode 100644 index c67aad5d..00000000 --- a/ui/dist/assets/PageOAuth2RedirectFailure-CguUZswk.js +++ /dev/null @@ -1 +0,0 @@ -import{S as r,i as c,s as l,H as n,h as u,l as h,u as p,w as d,O as f,P as m,Q as g,R as o}from"./index-DMlPjiFP.js";function _(s){let t;return{c(){t=p("div"),t.innerHTML='

    Auth failed.

    You can close this window and go back to the app to try again.
    ',d(t,"class","content txt-hint txt-center p-base")},m(e,a){h(e,t,a)},p:n,i:n,o:n,d(e){e&&u(t)}}}function b(s,t,e){let a;return f(s,o,i=>e(0,a=i)),m(o,a="OAuth2 auth failed",a),g(()=>{window.close()}),[]}class x extends r{constructor(t){super(),c(this,t,b,_,l,{})}}export{x as default}; diff --git a/ui/dist/assets/PageOAuth2RedirectSuccess-CcK3psIw.js b/ui/dist/assets/PageOAuth2RedirectSuccess-CcK3psIw.js deleted file mode 100644 index 342fece4..00000000 --- a/ui/dist/assets/PageOAuth2RedirectSuccess-CcK3psIw.js +++ /dev/null @@ -1 +0,0 @@ -import{S as i,i as r,s as u,H as n,h as l,l as p,u as h,w as d,O as m,P as f,Q as _,R as o}from"./index-DMlPjiFP.js";function b(a){let t;return{c(){t=h("div"),t.innerHTML='

    Auth completed.

    You can close this window and go back to the app.
    ',d(t,"class","content txt-hint txt-center p-base")},m(e,s){p(e,t,s)},p:n,i:n,o:n,d(e){e&&l(t)}}}function g(a,t,e){let s;return m(a,o,c=>e(0,s=c)),f(o,s="OAuth2 auth completed",s),_(()=>{window.close()}),[]}class x extends i{constructor(t){super(),r(this,t,g,b,u,{})}}export{x as default}; diff --git a/ui/dist/assets/PageRecordConfirmEmailChange-CylRwYOU.js b/ui/dist/assets/PageRecordConfirmEmailChange-CylRwYOU.js deleted file mode 100644 index 19808c00..00000000 --- a/ui/dist/assets/PageRecordConfirmEmailChange-CylRwYOU.js +++ /dev/null @@ -1,2 +0,0 @@ -import{S as J,i as M,s as z,F as A,d as L,t as h,a as v,m as S,c as I,J as D,h as _,D as N,l as b,L as R,M as W,g as Y,p as j,H as P,o as q,u as m,v as y,w as p,f as B,k as T,n as g,q as G,A as C,I as K,z as F,C as O}from"./index-DMlPjiFP.js";function Q(i){let e,t,n,l,s,o,f,a,r,u,k,$,d=i[3]&&H(i);return o=new B({props:{class:"form-field required",name:"password",$$slots:{default:[V,({uniqueId:c})=>({8:c}),({uniqueId:c})=>c?256:0]},$$scope:{ctx:i}}}),{c(){e=m("form"),t=m("div"),n=m("h5"),l=C(`Type your password to confirm changing your email address - `),d&&d.c(),s=y(),I(o.$$.fragment),f=y(),a=m("button"),r=m("span"),r.textContent="Confirm new email",p(t,"class","content txt-center m-b-base"),p(r,"class","txt"),p(a,"type","submit"),p(a,"class","btn btn-lg btn-block"),a.disabled=i[1],T(a,"btn-loading",i[1])},m(c,w){b(c,e,w),g(e,t),g(t,n),g(n,l),d&&d.m(n,null),g(e,s),S(o,e,null),g(e,f),g(e,a),g(a,r),u=!0,k||($=q(e,"submit",G(i[4])),k=!0)},p(c,w){c[3]?d?d.p(c,w):(d=H(c),d.c(),d.m(n,null)):d&&(d.d(1),d=null);const E={};w&769&&(E.$$scope={dirty:w,ctx:c}),o.$set(E),(!u||w&2)&&(a.disabled=c[1]),(!u||w&2)&&T(a,"btn-loading",c[1])},i(c){u||(v(o.$$.fragment,c),u=!0)},o(c){h(o.$$.fragment,c),u=!1},d(c){c&&_(e),d&&d.d(),L(o),k=!1,$()}}}function U(i){let e,t,n,l,s;return{c(){e=m("div"),e.innerHTML='

    Successfully changed the user email address.

    You can now sign in with your new email address.

    ',t=y(),n=m("button"),n.textContent="Close",p(e,"class","alert alert-success"),p(n,"type","button"),p(n,"class","btn btn-transparent btn-block")},m(o,f){b(o,e,f),b(o,t,f),b(o,n,f),l||(s=q(n,"click",i[6]),l=!0)},p:P,i:P,o:P,d(o){o&&(_(e),_(t),_(n)),l=!1,s()}}}function H(i){let e,t,n;return{c(){e=C("to "),t=m("strong"),n=C(i[3]),p(t,"class","txt-nowrap")},m(l,s){b(l,e,s),b(l,t,s),g(t,n)},p(l,s){s&8&&K(n,l[3])},d(l){l&&(_(e),_(t))}}}function V(i){let e,t,n,l,s,o,f,a;return{c(){e=m("label"),t=C("Password"),l=y(),s=m("input"),p(e,"for",n=i[8]),p(s,"type","password"),p(s,"id",o=i[8]),s.required=!0,s.autofocus=!0},m(r,u){b(r,e,u),g(e,t),b(r,l,u),b(r,s,u),F(s,i[0]),s.focus(),f||(a=q(s,"input",i[7]),f=!0)},p(r,u){u&256&&n!==(n=r[8])&&p(e,"for",n),u&256&&o!==(o=r[8])&&p(s,"id",o),u&1&&s.value!==r[0]&&F(s,r[0])},d(r){r&&(_(e),_(l),_(s)),f=!1,a()}}}function X(i){let e,t,n,l;const s=[U,Q],o=[];function f(a,r){return a[2]?0:1}return e=f(i),t=o[e]=s[e](i),{c(){t.c(),n=R()},m(a,r){o[e].m(a,r),b(a,n,r),l=!0},p(a,r){let u=e;e=f(a),e===u?o[e].p(a,r):(O(),h(o[u],1,1,()=>{o[u]=null}),N(),t=o[e],t?t.p(a,r):(t=o[e]=s[e](a),t.c()),v(t,1),t.m(n.parentNode,n))},i(a){l||(v(t),l=!0)},o(a){h(t),l=!1},d(a){a&&_(n),o[e].d(a)}}}function Z(i){let e,t;return e=new A({props:{nobranding:!0,$$slots:{default:[X]},$$scope:{ctx:i}}}),{c(){I(e.$$.fragment)},m(n,l){S(e,n,l),t=!0},p(n,[l]){const s={};l&527&&(s.$$scope={dirty:l,ctx:n}),e.$set(s)},i(n){t||(v(e.$$.fragment,n),t=!0)},o(n){h(e.$$.fragment,n),t=!1},d(n){L(e,n)}}}function x(i,e,t){let n,{params:l}=e,s="",o=!1,f=!1;async function a(){if(o)return;t(1,o=!0);const k=new W("../");try{const $=Y(l==null?void 0:l.token);await k.collection($.collectionId).confirmEmailChange(l==null?void 0:l.token,s),t(2,f=!0)}catch($){j.error($)}t(1,o=!1)}const r=()=>window.close();function u(){s=this.value,t(0,s)}return i.$$set=k=>{"params"in k&&t(5,l=k.params)},i.$$.update=()=>{i.$$.dirty&32&&t(3,n=D.getJWTPayload(l==null?void 0:l.token).newEmail||"")},[s,o,f,n,a,l,r,u]}class te extends J{constructor(e){super(),M(this,e,x,Z,z,{params:5})}}export{te as default}; diff --git a/ui/dist/assets/PageRecordConfirmPasswordReset-Dcwt0hvf.js b/ui/dist/assets/PageRecordConfirmPasswordReset-Dcwt0hvf.js deleted file mode 100644 index 18a4e381..00000000 --- a/ui/dist/assets/PageRecordConfirmPasswordReset-Dcwt0hvf.js +++ /dev/null @@ -1,2 +0,0 @@ -import{S as A,i as D,s as W,F as Y,d as H,t as P,a as q,m as L,c as N,J as j,h as _,C as B,D as E,l as m,L as G,M as K,g as O,p as Q,H as F,o as S,u as b,v as C,w as p,f as J,k as M,n as w,q as U,A as y,I as V,z as R}from"./index-DMlPjiFP.js";function X(a){let e,l,s,n,t,o,c,r,i,u,v,g,k,h,d=a[4]&&z(a);return o=new J({props:{class:"form-field required",name:"password",$$slots:{default:[x,({uniqueId:f})=>({10:f}),({uniqueId:f})=>f?1024:0]},$$scope:{ctx:a}}}),r=new J({props:{class:"form-field required",name:"passwordConfirm",$$slots:{default:[ee,({uniqueId:f})=>({10:f}),({uniqueId:f})=>f?1024:0]},$$scope:{ctx:a}}}),{c(){e=b("form"),l=b("div"),s=b("h5"),n=y(`Reset your user password - `),d&&d.c(),t=C(),N(o.$$.fragment),c=C(),N(r.$$.fragment),i=C(),u=b("button"),v=b("span"),v.textContent="Set new password",p(l,"class","content txt-center m-b-base"),p(v,"class","txt"),p(u,"type","submit"),p(u,"class","btn btn-lg btn-block"),u.disabled=a[2],M(u,"btn-loading",a[2])},m(f,$){m(f,e,$),w(e,l),w(l,s),w(s,n),d&&d.m(s,null),w(e,t),L(o,e,null),w(e,c),L(r,e,null),w(e,i),w(e,u),w(u,v),g=!0,k||(h=S(e,"submit",U(a[5])),k=!0)},p(f,$){f[4]?d?d.p(f,$):(d=z(f),d.c(),d.m(s,null)):d&&(d.d(1),d=null);const T={};$&3073&&(T.$$scope={dirty:$,ctx:f}),o.$set(T);const I={};$&3074&&(I.$$scope={dirty:$,ctx:f}),r.$set(I),(!g||$&4)&&(u.disabled=f[2]),(!g||$&4)&&M(u,"btn-loading",f[2])},i(f){g||(q(o.$$.fragment,f),q(r.$$.fragment,f),g=!0)},o(f){P(o.$$.fragment,f),P(r.$$.fragment,f),g=!1},d(f){f&&_(e),d&&d.d(),H(o),H(r),k=!1,h()}}}function Z(a){let e,l,s,n,t;return{c(){e=b("div"),e.innerHTML='

    Successfully changed the user password.

    You can now sign in with your new password.

    ',l=C(),s=b("button"),s.textContent="Close",p(e,"class","alert alert-success"),p(s,"type","button"),p(s,"class","btn btn-transparent btn-block")},m(o,c){m(o,e,c),m(o,l,c),m(o,s,c),n||(t=S(s,"click",a[7]),n=!0)},p:F,i:F,o:F,d(o){o&&(_(e),_(l),_(s)),n=!1,t()}}}function z(a){let e,l,s;return{c(){e=y("for "),l=b("strong"),s=y(a[4])},m(n,t){m(n,e,t),m(n,l,t),w(l,s)},p(n,t){t&16&&V(s,n[4])},d(n){n&&(_(e),_(l))}}}function x(a){let e,l,s,n,t,o,c,r;return{c(){e=b("label"),l=y("New password"),n=C(),t=b("input"),p(e,"for",s=a[10]),p(t,"type","password"),p(t,"id",o=a[10]),t.required=!0,t.autofocus=!0},m(i,u){m(i,e,u),w(e,l),m(i,n,u),m(i,t,u),R(t,a[0]),t.focus(),c||(r=S(t,"input",a[8]),c=!0)},p(i,u){u&1024&&s!==(s=i[10])&&p(e,"for",s),u&1024&&o!==(o=i[10])&&p(t,"id",o),u&1&&t.value!==i[0]&&R(t,i[0])},d(i){i&&(_(e),_(n),_(t)),c=!1,r()}}}function ee(a){let e,l,s,n,t,o,c,r;return{c(){e=b("label"),l=y("New password confirm"),n=C(),t=b("input"),p(e,"for",s=a[10]),p(t,"type","password"),p(t,"id",o=a[10]),t.required=!0},m(i,u){m(i,e,u),w(e,l),m(i,n,u),m(i,t,u),R(t,a[1]),c||(r=S(t,"input",a[9]),c=!0)},p(i,u){u&1024&&s!==(s=i[10])&&p(e,"for",s),u&1024&&o!==(o=i[10])&&p(t,"id",o),u&2&&t.value!==i[1]&&R(t,i[1])},d(i){i&&(_(e),_(n),_(t)),c=!1,r()}}}function te(a){let e,l,s,n;const t=[Z,X],o=[];function c(r,i){return r[3]?0:1}return e=c(a),l=o[e]=t[e](a),{c(){l.c(),s=G()},m(r,i){o[e].m(r,i),m(r,s,i),n=!0},p(r,i){let u=e;e=c(r),e===u?o[e].p(r,i):(B(),P(o[u],1,1,()=>{o[u]=null}),E(),l=o[e],l?l.p(r,i):(l=o[e]=t[e](r),l.c()),q(l,1),l.m(s.parentNode,s))},i(r){n||(q(l),n=!0)},o(r){P(l),n=!1},d(r){r&&_(s),o[e].d(r)}}}function se(a){let e,l;return e=new Y({props:{nobranding:!0,$$slots:{default:[te]},$$scope:{ctx:a}}}),{c(){N(e.$$.fragment)},m(s,n){L(e,s,n),l=!0},p(s,[n]){const t={};n&2079&&(t.$$scope={dirty:n,ctx:s}),e.$set(t)},i(s){l||(q(e.$$.fragment,s),l=!0)},o(s){P(e.$$.fragment,s),l=!1},d(s){H(e,s)}}}function le(a,e,l){let s,{params:n}=e,t="",o="",c=!1,r=!1;async function i(){if(c)return;l(2,c=!0);const k=new K("../");try{const h=O(n==null?void 0:n.token);await k.collection(h.collectionId).confirmPasswordReset(n==null?void 0:n.token,t,o),l(3,r=!0)}catch(h){Q.error(h)}l(2,c=!1)}const u=()=>window.close();function v(){t=this.value,l(0,t)}function g(){o=this.value,l(1,o)}return a.$$set=k=>{"params"in k&&l(6,n=k.params)},a.$$.update=()=>{a.$$.dirty&64&&l(4,s=j.getJWTPayload(n==null?void 0:n.token).email||"")},[t,o,c,r,s,i,n,u,v,g]}class oe extends A{constructor(e){super(),D(this,e,le,se,W,{params:6})}}export{oe as default}; diff --git a/ui/dist/assets/PageRecordConfirmVerification-gDDwBfsB.js b/ui/dist/assets/PageRecordConfirmVerification-gDDwBfsB.js deleted file mode 100644 index 4157f711..00000000 --- a/ui/dist/assets/PageRecordConfirmVerification-gDDwBfsB.js +++ /dev/null @@ -1 +0,0 @@ -import{S as M,i as P,s as R,F as I,d as N,t as S,a as V,m as q,c as F,M as w,g as y,N as E,h as r,l as a,L as g,p as j,H as k,u,w as d,o as m,v,k as C,n as z}from"./index-DMlPjiFP.js";function A(o){let e,l,n;function t(i,f){return i[4]?K:J}let s=t(o),c=s(o);return{c(){e=u("div"),e.innerHTML='

    Invalid or expired verification token.

    ',l=v(),c.c(),n=g(),d(e,"class","alert alert-danger")},m(i,f){a(i,e,f),a(i,l,f),c.m(i,f),a(i,n,f)},p(i,f){s===(s=t(i))&&c?c.p(i,f):(c.d(1),c=s(i),c&&(c.c(),c.m(n.parentNode,n)))},d(i){i&&(r(e),r(l),r(n)),c.d(i)}}}function B(o){let e,l,n,t,s;return{c(){e=u("div"),e.innerHTML='

    Please check your email for the new verification link.

    ',l=v(),n=u("button"),n.textContent="Close",d(e,"class","alert alert-success"),d(n,"type","button"),d(n,"class","btn btn-transparent btn-block")},m(c,i){a(c,e,i),a(c,l,i),a(c,n,i),t||(s=m(n,"click",o[8]),t=!0)},p:k,d(c){c&&(r(e),r(l),r(n)),t=!1,s()}}}function D(o){let e,l,n,t,s;return{c(){e=u("div"),e.innerHTML='

    Successfully verified email address.

    ',l=v(),n=u("button"),n.textContent="Close",d(e,"class","alert alert-success"),d(n,"type","button"),d(n,"class","btn btn-transparent btn-block")},m(c,i){a(c,e,i),a(c,l,i),a(c,n,i),t||(s=m(n,"click",o[7]),t=!0)},p:k,d(c){c&&(r(e),r(l),r(n)),t=!1,s()}}}function G(o){let e;return{c(){e=u("div"),e.innerHTML='
    Please wait...
    ',d(e,"class","txt-center")},m(l,n){a(l,e,n)},p:k,d(l){l&&r(e)}}}function J(o){let e,l,n;return{c(){e=u("button"),e.textContent="Close",d(e,"type","button"),d(e,"class","btn btn-transparent btn-block")},m(t,s){a(t,e,s),l||(n=m(e,"click",o[9]),l=!0)},p:k,d(t){t&&r(e),l=!1,n()}}}function K(o){let e,l,n,t;return{c(){e=u("button"),l=u("span"),l.textContent="Resend",d(l,"class","txt"),d(e,"type","button"),d(e,"class","btn btn-transparent btn-block"),e.disabled=o[3],C(e,"btn-loading",o[3])},m(s,c){a(s,e,c),z(e,l),n||(t=m(e,"click",o[5]),n=!0)},p(s,c){c&8&&(e.disabled=s[3]),c&8&&C(e,"btn-loading",s[3])},d(s){s&&r(e),n=!1,t()}}}function O(o){let e;function l(s,c){return s[1]?G:s[0]?D:s[2]?B:A}let n=l(o),t=n(o);return{c(){t.c(),e=g()},m(s,c){t.m(s,c),a(s,e,c)},p(s,c){n===(n=l(s))&&t?t.p(s,c):(t.d(1),t=n(s),t&&(t.c(),t.m(e.parentNode,e)))},d(s){s&&r(e),t.d(s)}}}function Q(o){let e,l;return e=new I({props:{nobranding:!0,$$slots:{default:[O]},$$scope:{ctx:o}}}),{c(){F(e.$$.fragment)},m(n,t){q(e,n,t),l=!0},p(n,[t]){const s={};t&2079&&(s.$$scope={dirty:t,ctx:n}),e.$set(s)},i(n){l||(V(e.$$.fragment,n),l=!0)},o(n){S(e.$$.fragment,n),l=!1},d(n){N(e,n)}}}function U(o,e,l){let n,{params:t}=e,s=!1,c=!1,i=!1,f=!1;x();async function x(){if(c)return;l(1,c=!0);const p=new w("../");try{const b=y(t==null?void 0:t.token);await p.collection(b.collectionId).confirmVerification(t==null?void 0:t.token),l(0,s=!0)}catch{l(0,s=!1)}l(1,c=!1)}async function T(){const p=y(t==null?void 0:t.token);if(f||!p.collectionId||!p.email)return;l(3,f=!0);const b=new w("../");try{const _=y(t==null?void 0:t.token);await b.collection(_.collectionId).requestVerification(_.email),l(2,i=!0)}catch(_){j.error(_),l(2,i=!1)}l(3,f=!1)}const h=()=>window.close(),H=()=>window.close(),L=()=>window.close();return o.$$set=p=>{"params"in p&&l(6,t=p.params)},o.$$.update=()=>{o.$$.dirty&64&&l(4,n=(t==null?void 0:t.token)&&E(t.token))},[s,c,i,f,n,T,t,h,H,L]}class X extends M{constructor(e){super(),P(this,e,U,Q,R,{params:6})}}export{X as default}; diff --git a/ui/dist/assets/PageSuperuserConfirmPasswordReset-DrNd_wUS.js b/ui/dist/assets/PageSuperuserConfirmPasswordReset-DrNd_wUS.js deleted file mode 100644 index 93d9558d..00000000 --- a/ui/dist/assets/PageSuperuserConfirmPasswordReset-DrNd_wUS.js +++ /dev/null @@ -1,2 +0,0 @@ -import{S as L,i as W,s as y,F as D,d as R,t as J,a as N,m as T,c as j,J as M,f as G,h as b,j as O,k as H,l as w,n as c,o as z,q as Q,E as U,G as V,u as _,A as P,v as h,w as f,p as I,K as X,r as Y,I as Z,z as q}from"./index-DMlPjiFP.js";function K(r){let e,n,s;return{c(){e=P("for "),n=_("strong"),s=P(r[3]),f(n,"class","txt-nowrap")},m(l,t){w(l,e,t),w(l,n,t),c(n,s)},p(l,t){t&8&&Z(s,l[3])},d(l){l&&(b(e),b(n))}}}function x(r){let e,n,s,l,t,i,p,d;return{c(){e=_("label"),n=P("New password"),l=h(),t=_("input"),f(e,"for",s=r[8]),f(t,"type","password"),f(t,"id",i=r[8]),t.required=!0,t.autofocus=!0},m(u,a){w(u,e,a),c(e,n),w(u,l,a),w(u,t,a),q(t,r[0]),t.focus(),p||(d=z(t,"input",r[6]),p=!0)},p(u,a){a&256&&s!==(s=u[8])&&f(e,"for",s),a&256&&i!==(i=u[8])&&f(t,"id",i),a&1&&t.value!==u[0]&&q(t,u[0])},d(u){u&&(b(e),b(l),b(t)),p=!1,d()}}}function ee(r){let e,n,s,l,t,i,p,d;return{c(){e=_("label"),n=P("New password confirm"),l=h(),t=_("input"),f(e,"for",s=r[8]),f(t,"type","password"),f(t,"id",i=r[8]),t.required=!0},m(u,a){w(u,e,a),c(e,n),w(u,l,a),w(u,t,a),q(t,r[1]),p||(d=z(t,"input",r[7]),p=!0)},p(u,a){a&256&&s!==(s=u[8])&&f(e,"for",s),a&256&&i!==(i=u[8])&&f(t,"id",i),a&2&&t.value!==u[1]&&q(t,u[1])},d(u){u&&(b(e),b(l),b(t)),p=!1,d()}}}function te(r){let e,n,s,l,t,i,p,d,u,a,g,S,C,v,k,F,A,m=r[3]&&K(r);return i=new G({props:{class:"form-field required",name:"password",$$slots:{default:[x,({uniqueId:o})=>({8:o}),({uniqueId:o})=>o?256:0]},$$scope:{ctx:r}}}),d=new G({props:{class:"form-field required",name:"passwordConfirm",$$slots:{default:[ee,({uniqueId:o})=>({8:o}),({uniqueId:o})=>o?256:0]},$$scope:{ctx:r}}}),{c(){e=_("form"),n=_("div"),s=_("h4"),l=P(`Reset your superuser password - `),m&&m.c(),t=h(),j(i.$$.fragment),p=h(),j(d.$$.fragment),u=h(),a=_("button"),g=_("span"),g.textContent="Set new password",S=h(),C=_("div"),v=_("a"),v.textContent="Back to login",f(s,"class","m-b-xs"),f(n,"class","content txt-center m-b-sm"),f(g,"class","txt"),f(a,"type","submit"),f(a,"class","btn btn-lg btn-block"),a.disabled=r[2],H(a,"btn-loading",r[2]),f(e,"class","m-b-base"),f(v,"href","/login"),f(v,"class","link-hint"),f(C,"class","content txt-center")},m(o,$){w(o,e,$),c(e,n),c(n,s),c(s,l),m&&m.m(s,null),c(e,t),T(i,e,null),c(e,p),T(d,e,null),c(e,u),c(e,a),c(a,g),w(o,S,$),w(o,C,$),c(C,v),k=!0,F||(A=[z(e,"submit",Q(r[4])),U(V.call(null,v))],F=!0)},p(o,$){o[3]?m?m.p(o,$):(m=K(o),m.c(),m.m(s,null)):m&&(m.d(1),m=null);const B={};$&769&&(B.$$scope={dirty:$,ctx:o}),i.$set(B);const E={};$&770&&(E.$$scope={dirty:$,ctx:o}),d.$set(E),(!k||$&4)&&(a.disabled=o[2]),(!k||$&4)&&H(a,"btn-loading",o[2])},i(o){k||(N(i.$$.fragment,o),N(d.$$.fragment,o),k=!0)},o(o){J(i.$$.fragment,o),J(d.$$.fragment,o),k=!1},d(o){o&&(b(e),b(S),b(C)),m&&m.d(),R(i),R(d),F=!1,O(A)}}}function se(r){let e,n;return e=new D({props:{$$slots:{default:[te]},$$scope:{ctx:r}}}),{c(){j(e.$$.fragment)},m(s,l){T(e,s,l),n=!0},p(s,[l]){const t={};l&527&&(t.$$scope={dirty:l,ctx:s}),e.$set(t)},i(s){n||(N(e.$$.fragment,s),n=!0)},o(s){J(e.$$.fragment,s),n=!1},d(s){R(e,s)}}}function le(r,e,n){let s,{params:l}=e,t="",i="",p=!1;async function d(){if(!p){n(2,p=!0);try{await I.collection("_superusers").confirmPasswordReset(l==null?void 0:l.token,t,i),X("Successfully set a new superuser password."),Y("/")}catch(g){I.error(g)}n(2,p=!1)}}function u(){t=this.value,n(0,t)}function a(){i=this.value,n(1,i)}return r.$$set=g=>{"params"in g&&n(5,l=g.params)},r.$$.update=()=>{r.$$.dirty&32&&n(3,s=M.getJWTPayload(l==null?void 0:l.token).email||"")},[t,i,p,s,d,l,u,a]}class ae extends L{constructor(e){super(),W(this,e,le,se,y,{params:5})}}export{ae as default}; diff --git a/ui/dist/assets/PageSuperuserRequestPasswordReset-D7jINQSc.js b/ui/dist/assets/PageSuperuserRequestPasswordReset-D7jINQSc.js deleted file mode 100644 index be7fc05d..00000000 --- a/ui/dist/assets/PageSuperuserRequestPasswordReset-D7jINQSc.js +++ /dev/null @@ -1 +0,0 @@ -import{S as M,i as T,s as z,F as A,d as E,t as w,a as y,m as H,c as L,h as g,C as B,D,l as k,n as d,E as G,G as I,v,u as m,w as p,p as C,H as F,I as N,A as h,f as j,k as P,o as R,q as J,z as S}from"./index-DMlPjiFP.js";function K(u){let e,s,n,l,t,r,c,_,i,a,b,f;return l=new j({props:{class:"form-field required",name:"email",$$slots:{default:[Q,({uniqueId:o})=>({5:o}),({uniqueId:o})=>o?32:0]},$$scope:{ctx:u}}}),{c(){e=m("form"),s=m("div"),s.innerHTML='

    Forgotten superuser password

    Enter the email associated with your account and we’ll send you a recovery link:

    ',n=v(),L(l.$$.fragment),t=v(),r=m("button"),c=m("i"),_=v(),i=m("span"),i.textContent="Send recovery link",p(s,"class","content txt-center m-b-sm"),p(c,"class","ri-mail-send-line"),p(i,"class","txt"),p(r,"type","submit"),p(r,"class","btn btn-lg btn-block"),r.disabled=u[1],P(r,"btn-loading",u[1]),p(e,"class","m-b-base")},m(o,$){k(o,e,$),d(e,s),d(e,n),H(l,e,null),d(e,t),d(e,r),d(r,c),d(r,_),d(r,i),a=!0,b||(f=R(e,"submit",J(u[3])),b=!0)},p(o,$){const q={};$&97&&(q.$$scope={dirty:$,ctx:o}),l.$set(q),(!a||$&2)&&(r.disabled=o[1]),(!a||$&2)&&P(r,"btn-loading",o[1])},i(o){a||(y(l.$$.fragment,o),a=!0)},o(o){w(l.$$.fragment,o),a=!1},d(o){o&&g(e),E(l),b=!1,f()}}}function O(u){let e,s,n,l,t,r,c,_,i;return{c(){e=m("div"),s=m("div"),s.innerHTML='',n=v(),l=m("div"),t=m("p"),r=h("Check "),c=m("strong"),_=h(u[0]),i=h(" for the recovery link."),p(s,"class","icon"),p(c,"class","txt-nowrap"),p(l,"class","content"),p(e,"class","alert alert-success")},m(a,b){k(a,e,b),d(e,s),d(e,n),d(e,l),d(l,t),d(t,r),d(t,c),d(c,_),d(t,i)},p(a,b){b&1&&N(_,a[0])},i:F,o:F,d(a){a&&g(e)}}}function Q(u){let e,s,n,l,t,r,c,_;return{c(){e=m("label"),s=h("Email"),l=v(),t=m("input"),p(e,"for",n=u[5]),p(t,"type","email"),p(t,"id",r=u[5]),t.required=!0,t.autofocus=!0},m(i,a){k(i,e,a),d(e,s),k(i,l,a),k(i,t,a),S(t,u[0]),t.focus(),c||(_=R(t,"input",u[4]),c=!0)},p(i,a){a&32&&n!==(n=i[5])&&p(e,"for",n),a&32&&r!==(r=i[5])&&p(t,"id",r),a&1&&t.value!==i[0]&&S(t,i[0])},d(i){i&&(g(e),g(l),g(t)),c=!1,_()}}}function U(u){let e,s,n,l,t,r,c,_;const i=[O,K],a=[];function b(f,o){return f[2]?0:1}return e=b(u),s=a[e]=i[e](u),{c(){s.c(),n=v(),l=m("div"),t=m("a"),t.textContent="Back to login",p(t,"href","/login"),p(t,"class","link-hint"),p(l,"class","content txt-center")},m(f,o){a[e].m(f,o),k(f,n,o),k(f,l,o),d(l,t),r=!0,c||(_=G(I.call(null,t)),c=!0)},p(f,o){let $=e;e=b(f),e===$?a[e].p(f,o):(B(),w(a[$],1,1,()=>{a[$]=null}),D(),s=a[e],s?s.p(f,o):(s=a[e]=i[e](f),s.c()),y(s,1),s.m(n.parentNode,n))},i(f){r||(y(s),r=!0)},o(f){w(s),r=!1},d(f){f&&(g(n),g(l)),a[e].d(f),c=!1,_()}}}function V(u){let e,s;return e=new A({props:{$$slots:{default:[U]},$$scope:{ctx:u}}}),{c(){L(e.$$.fragment)},m(n,l){H(e,n,l),s=!0},p(n,[l]){const t={};l&71&&(t.$$scope={dirty:l,ctx:n}),e.$set(t)},i(n){s||(y(e.$$.fragment,n),s=!0)},o(n){w(e.$$.fragment,n),s=!1},d(n){E(e,n)}}}function W(u,e,s){let n="",l=!1,t=!1;async function r(){if(!l){s(1,l=!0);try{await C.collection("_superusers").requestPasswordReset(n),s(2,t=!0)}catch(_){C.error(_)}s(1,l=!1)}}function c(){n=this.value,s(0,n)}return[n,l,t,r,c]}class Y extends M{constructor(e){super(),T(this,e,W,V,z,{})}}export{Y as default}; diff --git a/ui/dist/assets/PasswordResetDocs-bUVxSWLH.js b/ui/dist/assets/PasswordResetDocs-bUVxSWLH.js deleted file mode 100644 index 816b9599..00000000 --- a/ui/dist/assets/PasswordResetDocs-bUVxSWLH.js +++ /dev/null @@ -1,100 +0,0 @@ -import{S as se,i as ne,s as oe,X as H,h as b,t as X,a as V,I as Z,Z as ee,_ as ye,C as te,$ as Te,D as le,l as v,n as u,u as p,v as S,A as D,w as k,k as L,o as ae,W as Ee,d as G,m as Q,c as x,V as Ce,Y as fe,J as qe,p as Oe,a0 as pe}from"./index-DMlPjiFP.js";function me(o,t,e){const n=o.slice();return n[4]=t[e],n}function _e(o,t,e){const n=o.slice();return n[4]=t[e],n}function he(o,t){let e,n=t[4].code+"",d,c,r,a;function f(){return t[3](t[4])}return{key:o,first:null,c(){e=p("button"),d=D(n),c=S(),k(e,"class","tab-item"),L(e,"active",t[1]===t[4].code),this.first=e},m(g,y){v(g,e,y),u(e,d),u(e,c),r||(a=ae(e,"click",f),r=!0)},p(g,y){t=g,y&4&&n!==(n=t[4].code+"")&&Z(d,n),y&6&&L(e,"active",t[1]===t[4].code)},d(g){g&&b(e),r=!1,a()}}}function be(o,t){let e,n,d,c;return n=new Ee({props:{content:t[4].body}}),{key:o,first:null,c(){e=p("div"),x(n.$$.fragment),d=S(),k(e,"class","tab-item"),L(e,"active",t[1]===t[4].code),this.first=e},m(r,a){v(r,e,a),Q(n,e,null),u(e,d),c=!0},p(r,a){t=r;const f={};a&4&&(f.content=t[4].body),n.$set(f),(!c||a&6)&&L(e,"active",t[1]===t[4].code)},i(r){c||(V(n.$$.fragment,r),c=!0)},o(r){X(n.$$.fragment,r),c=!1},d(r){r&&b(e),G(n)}}}function Ae(o){let t,e,n,d,c,r,a,f=o[0].name+"",g,y,F,q,J,W,U,O,A,T,C,R=[],M=new Map,j,N,h=[],K=new Map,E,P=H(o[2]);const B=l=>l[4].code;for(let l=0;ll[4].code;for(let l=0;lParam Type Description
    Required token
    String The token from the password reset request email.
    Required password
    String The new password to set.
    Required passwordConfirm
    String The new password confirmation.',U=S(),O=p("div"),O.textContent="Responses",A=S(),T=p("div"),C=p("div");for(let l=0;le(1,d=a.code);return o.$$set=a=>{"collection"in a&&e(0,n=a.collection)},e(2,c=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "token": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}]),[n,d,c,r]}class Ne extends se{constructor(t){super(),ne(this,t,We,Ae,oe,{collection:0})}}function ve(o,t,e){const n=o.slice();return n[4]=t[e],n}function ke(o,t,e){const n=o.slice();return n[4]=t[e],n}function ge(o,t){let e,n=t[4].code+"",d,c,r,a;function f(){return t[3](t[4])}return{key:o,first:null,c(){e=p("button"),d=D(n),c=S(),k(e,"class","tab-item"),L(e,"active",t[1]===t[4].code),this.first=e},m(g,y){v(g,e,y),u(e,d),u(e,c),r||(a=ae(e,"click",f),r=!0)},p(g,y){t=g,y&4&&n!==(n=t[4].code+"")&&Z(d,n),y&6&&L(e,"active",t[1]===t[4].code)},d(g){g&&b(e),r=!1,a()}}}function we(o,t){let e,n,d,c;return n=new Ee({props:{content:t[4].body}}),{key:o,first:null,c(){e=p("div"),x(n.$$.fragment),d=S(),k(e,"class","tab-item"),L(e,"active",t[1]===t[4].code),this.first=e},m(r,a){v(r,e,a),Q(n,e,null),u(e,d),c=!0},p(r,a){t=r;const f={};a&4&&(f.content=t[4].body),n.$set(f),(!c||a&6)&&L(e,"active",t[1]===t[4].code)},i(r){c||(V(n.$$.fragment,r),c=!0)},o(r){X(n.$$.fragment,r),c=!1},d(r){r&&b(e),G(n)}}}function De(o){let t,e,n,d,c,r,a,f=o[0].name+"",g,y,F,q,J,W,U,O,A,T,C,R=[],M=new Map,j,N,h=[],K=new Map,E,P=H(o[2]);const B=l=>l[4].code;for(let l=0;ll[4].code;for(let l=0;lParam Type Description
    Required email
    String The auth record email address to send the password reset request (if exists).',U=S(),O=p("div"),O.textContent="Responses",A=S(),T=p("div"),C=p("div");for(let l=0;le(1,d=a.code);return o.$$set=a=>{"collection"in a&&e(0,n=a.collection)},e(2,c=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "email": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}]),[n,d,c,r]}class Be extends se{constructor(t){super(),ne(this,t,Me,De,oe,{collection:0})}}function $e(o,t,e){const n=o.slice();return n[5]=t[e],n[7]=e,n}function Re(o,t,e){const n=o.slice();return n[5]=t[e],n[7]=e,n}function Pe(o){let t,e,n,d,c;function r(){return o[4](o[7])}return{c(){t=p("button"),e=p("div"),e.textContent=`${o[5].title}`,n=S(),k(e,"class","txt"),k(t,"class","tab-item"),L(t,"active",o[1]==o[7])},m(a,f){v(a,t,f),u(t,e),u(t,n),d||(c=ae(t,"click",r),d=!0)},p(a,f){o=a,f&2&&L(t,"active",o[1]==o[7])},d(a){a&&b(t),d=!1,c()}}}function Se(o){let t,e,n,d;var c=o[5].component;function r(a,f){return{props:{collection:a[0]}}}return c&&(e=pe(c,r(o))),{c(){t=p("div"),e&&x(e.$$.fragment),n=S(),k(t,"class","tab-item"),L(t,"active",o[1]==o[7])},m(a,f){v(a,t,f),e&&Q(e,t,null),u(t,n),d=!0},p(a,f){if(c!==(c=a[5].component)){if(e){te();const g=e;X(g.$$.fragment,1,0,()=>{G(g,1)}),le()}c?(e=pe(c,r(a)),x(e.$$.fragment),V(e.$$.fragment,1),Q(e,t,n)):e=null}else if(c){const g={};f&1&&(g.collection=a[0]),e.$set(g)}(!d||f&2)&&L(t,"active",a[1]==a[7])},i(a){d||(e&&V(e.$$.fragment,a),d=!0)},o(a){e&&X(e.$$.fragment,a),d=!1},d(a){a&&b(t),e&&G(e)}}}function Ie(o){var l,s,_,ie;let t,e,n=o[0].name+"",d,c,r,a,f,g,y,F=o[0].name+"",q,J,W,U,O,A,T,C,R,M,j,N,h,K;A=new Ce({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${o[2]}'); - - ... - - await pb.collection('${(l=o[0])==null?void 0:l.name}').requestPasswordReset('test@example.com'); - - // --- - // (optional) in your custom confirmation page: - // --- - - // note: after this call all previously issued auth tokens are invalidated - await pb.collection('${(s=o[0])==null?void 0:s.name}').confirmPasswordReset( - 'RESET_TOKEN', - 'NEW_PASSWORD', - 'NEW_PASSWORD_CONFIRM', - ); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${o[2]}'); - - ... - - await pb.collection('${(_=o[0])==null?void 0:_.name}').requestPasswordReset('test@example.com'); - - // --- - // (optional) in your custom confirmation page: - // --- - - // note: after this call all previously issued auth tokens are invalidated - await pb.collection('${(ie=o[0])==null?void 0:ie.name}').confirmPasswordReset( - 'RESET_TOKEN', - 'NEW_PASSWORD', - 'NEW_PASSWORD_CONFIRM', - ); - `}});let E=H(o[3]),P=[];for(let i=0;iX(m[i],1,1,()=>{m[i]=null});return{c(){t=p("h3"),e=D("Password reset ("),d=D(n),c=D(")"),r=S(),a=p("div"),f=p("p"),g=D("Sends "),y=p("strong"),q=D(F),J=D(" password reset email request."),W=S(),U=p("p"),U.textContent=`On successful password reset all previously issued auth tokens for the specific record will be - automatically invalidated.`,O=S(),x(A.$$.fragment),T=S(),C=p("h6"),C.textContent="API details",R=S(),M=p("div"),j=p("div");for(let i=0;ie(1,r=f);return o.$$set=f=>{"collection"in f&&e(0,d=f.collection)},e(2,n=qe.getApiExampleUrl(Oe.baseURL)),[d,r,n,c,a]}class He extends se{constructor(t){super(),ne(this,t,Fe,Ie,oe,{collection:0})}}export{He as default}; diff --git a/ui/dist/assets/RealtimeApiDocs-kmoD_vEm.js b/ui/dist/assets/RealtimeApiDocs-kmoD_vEm.js deleted file mode 100644 index 66d6cd2b..00000000 --- a/ui/dist/assets/RealtimeApiDocs-kmoD_vEm.js +++ /dev/null @@ -1,110 +0,0 @@ -import{S as re,i as ae,s as be,V as pe,W as ue,J as P,h as s,d as se,t as ne,a as ie,I as me,l as n,n as y,m as ce,u as p,A as I,v as a,c as le,w as u,p as de}from"./index-DMlPjiFP.js";function he(o){var B,U,W,A,L,H,T,q,J,M,j,N;let i,m,c=o[0].name+"",b,d,k,h,D,f,_,l,S,$,w,g,C,v,E,r,R;return l=new pe({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${o[1]}'); - - ... - - // (Optionally) authenticate - await pb.collection('users').authWithPassword('test@example.com', '123456'); - - // Subscribe to changes in any ${(B=o[0])==null?void 0:B.name} record - pb.collection('${(U=o[0])==null?void 0:U.name}').subscribe('*', function (e) { - console.log(e.action); - console.log(e.record); - }, { /* other options like: filter, expand, custom headers, etc. */ }); - - // Subscribe to changes only in the specified record - pb.collection('${(W=o[0])==null?void 0:W.name}').subscribe('RECORD_ID', function (e) { - console.log(e.action); - console.log(e.record); - }, { /* other options like: filter, expand, custom headers, etc. */ }); - - // Unsubscribe - pb.collection('${(A=o[0])==null?void 0:A.name}').unsubscribe('RECORD_ID'); // remove all 'RECORD_ID' subscriptions - pb.collection('${(L=o[0])==null?void 0:L.name}').unsubscribe('*'); // remove all '*' topic subscriptions - pb.collection('${(H=o[0])==null?void 0:H.name}').unsubscribe(); // remove all subscriptions in the collection - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${o[1]}'); - - ... - - // (Optionally) authenticate - await pb.collection('users').authWithPassword('test@example.com', '123456'); - - // Subscribe to changes in any ${(T=o[0])==null?void 0:T.name} record - pb.collection('${(q=o[0])==null?void 0:q.name}').subscribe('*', (e) { - print(e.action); - print(e.record); - }, /* other options like: filter, expand, custom headers, etc. */); - - // Subscribe to changes only in the specified record - pb.collection('${(J=o[0])==null?void 0:J.name}').subscribe('RECORD_ID', (e) { - print(e.action); - print(e.record); - }, /* other options like: filter, expand, custom headers, etc. */); - - // Unsubscribe - pb.collection('${(M=o[0])==null?void 0:M.name}').unsubscribe('RECORD_ID'); // remove all 'RECORD_ID' subscriptions - pb.collection('${(j=o[0])==null?void 0:j.name}').unsubscribe('*'); // remove all '*' topic subscriptions - pb.collection('${(N=o[0])==null?void 0:N.name}').unsubscribe(); // remove all subscriptions in the collection - `}}),r=new ue({props:{content:JSON.stringify({action:"create",record:P.dummyCollectionRecord(o[0])},null,2).replace('"action": "create"','"action": "create" // create, update or delete')}}),{c(){i=p("h3"),m=I("Realtime ("),b=I(c),d=I(")"),k=a(),h=p("div"),h.innerHTML=`

    Subscribe to realtime changes via Server-Sent Events (SSE).

    Events are sent for create, update - and delete record operations (see "Event data format" section below).

    `,D=a(),f=p("div"),f.innerHTML=`

    You could subscribe to a single record or to an entire collection.

    When you subscribe to a single record, the collection's - ViewRule will be used to determine whether the subscriber has access to receive the - event message.

    When you subscribe to an entire collection, the collection's - ListRule will be used to determine whether the subscriber has access to receive the - event message.

    `,_=a(),le(l.$$.fragment),S=a(),$=p("h6"),$.textContent="API details",w=a(),g=p("div"),g.innerHTML='SSE

    /api/realtime

    ',C=a(),v=p("div"),v.textContent="Event data format",E=a(),le(r.$$.fragment),u(i,"class","m-b-sm"),u(h,"class","content txt-lg m-b-sm"),u(f,"class","alert alert-info m-t-10 m-b-sm"),u($,"class","m-b-xs"),u(g,"class","alert"),u(v,"class","section-title")},m(e,t){n(e,i,t),y(i,m),y(i,b),y(i,d),n(e,k,t),n(e,h,t),n(e,D,t),n(e,f,t),n(e,_,t),ce(l,e,t),n(e,S,t),n(e,$,t),n(e,w,t),n(e,g,t),n(e,C,t),n(e,v,t),n(e,E,t),ce(r,e,t),R=!0},p(e,[t]){var Y,z,F,G,K,Q,X,Z,x,ee,te,oe;(!R||t&1)&&c!==(c=e[0].name+"")&&me(b,c);const O={};t&3&&(O.js=` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${e[1]}'); - - ... - - // (Optionally) authenticate - await pb.collection('users').authWithPassword('test@example.com', '123456'); - - // Subscribe to changes in any ${(Y=e[0])==null?void 0:Y.name} record - pb.collection('${(z=e[0])==null?void 0:z.name}').subscribe('*', function (e) { - console.log(e.action); - console.log(e.record); - }, { /* other options like: filter, expand, custom headers, etc. */ }); - - // Subscribe to changes only in the specified record - pb.collection('${(F=e[0])==null?void 0:F.name}').subscribe('RECORD_ID', function (e) { - console.log(e.action); - console.log(e.record); - }, { /* other options like: filter, expand, custom headers, etc. */ }); - - // Unsubscribe - pb.collection('${(G=e[0])==null?void 0:G.name}').unsubscribe('RECORD_ID'); // remove all 'RECORD_ID' subscriptions - pb.collection('${(K=e[0])==null?void 0:K.name}').unsubscribe('*'); // remove all '*' topic subscriptions - pb.collection('${(Q=e[0])==null?void 0:Q.name}').unsubscribe(); // remove all subscriptions in the collection - `),t&3&&(O.dart=` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${e[1]}'); - - ... - - // (Optionally) authenticate - await pb.collection('users').authWithPassword('test@example.com', '123456'); - - // Subscribe to changes in any ${(X=e[0])==null?void 0:X.name} record - pb.collection('${(Z=e[0])==null?void 0:Z.name}').subscribe('*', (e) { - print(e.action); - print(e.record); - }, /* other options like: filter, expand, custom headers, etc. */); - - // Subscribe to changes only in the specified record - pb.collection('${(x=e[0])==null?void 0:x.name}').subscribe('RECORD_ID', (e) { - print(e.action); - print(e.record); - }, /* other options like: filter, expand, custom headers, etc. */); - - // Unsubscribe - pb.collection('${(ee=e[0])==null?void 0:ee.name}').unsubscribe('RECORD_ID'); // remove all 'RECORD_ID' subscriptions - pb.collection('${(te=e[0])==null?void 0:te.name}').unsubscribe('*'); // remove all '*' topic subscriptions - pb.collection('${(oe=e[0])==null?void 0:oe.name}').unsubscribe(); // remove all subscriptions in the collection - `),l.$set(O);const V={};t&1&&(V.content=JSON.stringify({action:"create",record:P.dummyCollectionRecord(e[0])},null,2).replace('"action": "create"','"action": "create" // create, update or delete')),r.$set(V)},i(e){R||(ie(l.$$.fragment,e),ie(r.$$.fragment,e),R=!0)},o(e){ne(l.$$.fragment,e),ne(r.$$.fragment,e),R=!1},d(e){e&&(s(i),s(k),s(h),s(D),s(f),s(_),s(S),s($),s(w),s(g),s(C),s(v),s(E)),se(l,e),se(r,e)}}}function fe(o,i,m){let c,{collection:b}=i;return o.$$set=d=>{"collection"in d&&m(0,b=d.collection)},m(1,c=P.getApiExampleUrl(de.baseURL)),[b,c]}class ge extends re{constructor(i){super(),ae(this,i,fe,he,be,{collection:0})}}export{ge as default}; diff --git a/ui/dist/assets/UpdateApiDocs-Bmron_nJ.js b/ui/dist/assets/UpdateApiDocs-Bmron_nJ.js deleted file mode 100644 index 78c37007..00000000 --- a/ui/dist/assets/UpdateApiDocs-Bmron_nJ.js +++ /dev/null @@ -1,90 +0,0 @@ -import{S as $t,i as Mt,s as St,V as Ot,X as se,W as Tt,h as d,d as ge,t as _e,a as he,I as ee,Z as Je,_ as bt,C as qt,$ as Rt,D as Ht,l as o,n as a,m as we,u as s,A as _,v as f,c as Ce,w as k,J as ye,p as Pt,k as Te,o as Lt,H as te}from"./index-DMlPjiFP.js";import{F as Dt}from"./FieldsQueryParam-B36GF025.js";function mt(r,e,t){const n=r.slice();return n[10]=e[t],n}function _t(r,e,t){const n=r.slice();return n[10]=e[t],n}function ht(r,e,t){const n=r.slice();return n[15]=e[t],n}function yt(r){let e;return{c(){e=s("p"),e.innerHTML=`Note that in case of a password change all previously issued tokens for the current record - will be automatically invalidated and if you want your user to remain signed in you need to - reauthenticate manually after the update call.`},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function kt(r){let e;return{c(){e=s("p"),e.innerHTML="Requires superuser Authorization:TOKEN header",k(e,"class","txt-hint txt-sm txt-right")},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function vt(r){let e,t,n,b,p,c,u,m,S,T,H,P,$,M,q,L,J,j,O,R,D,v,g,w;function x(h,C){var le,W,ne;return C&1&&(m=null),m==null&&(m=!!((ne=(W=(le=h[0])==null?void 0:le.fields)==null?void 0:W.find(zt))!=null&&ne.required)),m?Bt:Ft}let Q=x(r,-1),B=Q(r);return{c(){e=s("tr"),e.innerHTML='Auth specific fields',t=f(),n=s("tr"),n.innerHTML=`
    Optional email
    String The auth record email address. -
    - This field can be updated only by superusers or auth records with "Manage" access. -
    - Regular accounts can update their email by calling "Request email change".`,b=f(),p=s("tr"),c=s("td"),u=s("div"),B.c(),S=f(),T=s("span"),T.textContent="emailVisibility",H=f(),P=s("td"),P.innerHTML='Boolean',$=f(),M=s("td"),M.textContent="Whether to show/hide the auth record email when fetching the record data.",q=f(),L=s("tr"),L.innerHTML=`
    Optional oldPassword
    String Old auth record password. -
    - This field is required only when changing the record password. Superusers and auth records - with "Manage" access can skip this field.`,J=f(),j=s("tr"),j.innerHTML='
    Optional password
    String New auth record password.',O=f(),R=s("tr"),R.innerHTML='
    Optional passwordConfirm
    String New auth record password confirmation.',D=f(),v=s("tr"),v.innerHTML=`
    Optional verified
    Boolean Indicates whether the auth record is verified or not. -
    - This field can be set only by superusers or auth records with "Manage" access.`,g=f(),w=s("tr"),w.innerHTML='Other fields',k(u,"class","inline-flex")},m(h,C){o(h,e,C),o(h,t,C),o(h,n,C),o(h,b,C),o(h,p,C),a(p,c),a(c,u),B.m(u,null),a(u,S),a(u,T),a(p,H),a(p,P),a(p,$),a(p,M),o(h,q,C),o(h,L,C),o(h,J,C),o(h,j,C),o(h,O,C),o(h,R,C),o(h,D,C),o(h,v,C),o(h,g,C),o(h,w,C)},p(h,C){Q!==(Q=x(h,C))&&(B.d(1),B=Q(h),B&&(B.c(),B.m(u,S)))},d(h){h&&(d(e),d(t),d(n),d(b),d(p),d(q),d(L),d(J),d(j),d(O),d(R),d(D),d(v),d(g),d(w)),B.d()}}}function Ft(r){let e;return{c(){e=s("span"),e.textContent="Optional",k(e,"class","label label-warning")},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function Bt(r){let e;return{c(){e=s("span"),e.textContent="Required",k(e,"class","label label-success")},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function Nt(r){let e;return{c(){e=s("span"),e.textContent="Optional",k(e,"class","label label-warning")},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function At(r){let e;return{c(){e=s("span"),e.textContent="Required",k(e,"class","label label-success")},m(t,n){o(t,e,n)},d(t){t&&d(e)}}}function Et(r){let e,t=r[15].maxSelect==1?"id":"ids",n,b;return{c(){e=_("Relation record "),n=_(t),b=_(".")},m(p,c){o(p,e,c),o(p,n,c),o(p,b,c)},p(p,c){c&32&&t!==(t=p[15].maxSelect==1?"id":"ids")&&ee(n,t)},d(p){p&&(d(e),d(n),d(b))}}}function It(r){let e,t,n,b,p;return{c(){e=_("File object."),t=s("br"),n=_(` - Set to `),b=s("code"),b.textContent="null",p=_(" to delete already uploaded file(s).")},m(c,u){o(c,e,u),o(c,t,u),o(c,n,u),o(c,b,u),o(c,p,u)},p:te,d(c){c&&(d(e),d(t),d(n),d(b),d(p))}}}function jt(r){let e,t;return{c(){e=s("code"),e.textContent='{"lon":x,"lat":y}',t=_(" object.")},m(n,b){o(n,e,b),o(n,t,b)},p:te,d(n){n&&(d(e),d(t))}}}function Jt(r){let e;return{c(){e=_("URL address.")},m(t,n){o(t,e,n)},p:te,d(t){t&&d(e)}}}function Ut(r){let e;return{c(){e=_("Email address.")},m(t,n){o(t,e,n)},p:te,d(t){t&&d(e)}}}function Vt(r){let e;return{c(){e=_("JSON array or object.")},m(t,n){o(t,e,n)},p:te,d(t){t&&d(e)}}}function xt(r){let e;return{c(){e=_("Number value.")},m(t,n){o(t,e,n)},p:te,d(t){t&&d(e)}}}function Qt(r){let e;return{c(){e=_("Plain text value.")},m(t,n){o(t,e,n)},p:te,d(t){t&&d(e)}}}function gt(r,e){let t,n,b,p,c,u=e[15].name+"",m,S,T,H,P=ye.getFieldValueType(e[15])+"",$,M,q,L;function J(g,w){return g[15].required?At:Nt}let j=J(e),O=j(e);function R(g,w){if(g[15].type==="text")return Qt;if(g[15].type==="number")return xt;if(g[15].type==="json")return Vt;if(g[15].type==="email")return Ut;if(g[15].type==="url")return Jt;if(g[15].type==="geoPoint")return jt;if(g[15].type==="file")return It;if(g[15].type==="relation")return Et}let D=R(e),v=D&&D(e);return{key:r,first:null,c(){t=s("tr"),n=s("td"),b=s("div"),O.c(),p=f(),c=s("span"),m=_(u),S=f(),T=s("td"),H=s("span"),$=_(P),M=f(),q=s("td"),v&&v.c(),L=f(),k(b,"class","inline-flex"),k(H,"class","label"),this.first=t},m(g,w){o(g,t,w),a(t,n),a(n,b),O.m(b,null),a(b,p),a(b,c),a(c,m),a(t,S),a(t,T),a(T,H),a(H,$),a(t,M),a(t,q),v&&v.m(q,null),a(t,L)},p(g,w){e=g,j!==(j=J(e))&&(O.d(1),O=j(e),O&&(O.c(),O.m(b,p))),w&32&&u!==(u=e[15].name+"")&&ee(m,u),w&32&&P!==(P=ye.getFieldValueType(e[15])+"")&&ee($,P),D===(D=R(e))&&v?v.p(e,w):(v&&v.d(1),v=D&&D(e),v&&(v.c(),v.m(q,null)))},d(g){g&&d(t),O.d(),v&&v.d()}}}function wt(r,e){let t,n=e[10].code+"",b,p,c,u;function m(){return e[9](e[10])}return{key:r,first:null,c(){t=s("button"),b=_(n),p=f(),k(t,"class","tab-item"),Te(t,"active",e[2]===e[10].code),this.first=t},m(S,T){o(S,t,T),a(t,b),a(t,p),c||(u=Lt(t,"click",m),c=!0)},p(S,T){e=S,T&8&&n!==(n=e[10].code+"")&&ee(b,n),T&12&&Te(t,"active",e[2]===e[10].code)},d(S){S&&d(t),c=!1,u()}}}function Ct(r,e){let t,n,b,p;return n=new Tt({props:{content:e[10].body}}),{key:r,first:null,c(){t=s("div"),Ce(n.$$.fragment),b=f(),k(t,"class","tab-item"),Te(t,"active",e[2]===e[10].code),this.first=t},m(c,u){o(c,t,u),we(n,t,null),a(t,b),p=!0},p(c,u){e=c;const m={};u&8&&(m.content=e[10].body),n.$set(m),(!p||u&12)&&Te(t,"active",e[2]===e[10].code)},i(c){p||(he(n.$$.fragment,c),p=!0)},o(c){_e(n.$$.fragment,c),p=!1},d(c){c&&d(t),ge(n)}}}function Wt(r){var ct,ut;let e,t,n=r[0].name+"",b,p,c,u,m,S,T,H=r[0].name+"",P,$,M,q,L,J,j,O,R,D,v,g,w,x,Q,B,h,C,le,W=r[0].name+"",ne,Ue,$e,Ve,Me,de,Se,oe,Oe,re,qe,z,Re,xe,K,He,U=[],Qe=new Map,Pe,ce,Le,X,De,We,ue,Y,Fe,ze,Be,Ke,N,Xe,ae,Ye,Ze,Ge,Ne,et,Ae,tt,Ee,lt,nt,ie,Ie,pe,je,Z,fe,V=[],at=new Map,it,be,A=[],st=new Map,G,E=r[1]&&yt();R=new Ot({props:{js:` -import PocketBase from 'pocketbase'; - -const pb = new PocketBase('${r[4]}'); - -... - -// example update data -const data = ${JSON.stringify(r[7](r[0]),null,4)}; - -const record = await pb.collection('${(ct=r[0])==null?void 0:ct.name}').update('RECORD_ID', data); - `,dart:` -import 'package:pocketbase/pocketbase.dart'; - -final pb = PocketBase('${r[4]}'); - -... - -// example update body -final body = ${JSON.stringify(r[7](r[0]),null,2)}; - -final record = await pb.collection('${(ut=r[0])==null?void 0:ut.name}').update('RECORD_ID', body: body); - `}});let I=r[6]&&kt(),F=r[1]&&vt(r),ke=se(r[5]);const dt=l=>l[15].name;for(let l=0;ll[10].code;for(let l=0;ll[10].code;for(let l=0;lapplication/json or - multipart/form-data.`,L=f(),J=s("p"),J.innerHTML=`File upload is supported only via multipart/form-data. -
    - For more info and examples you could check the detailed - Files upload and handling docs - .`,j=f(),E&&E.c(),O=f(),Ce(R.$$.fragment),D=f(),v=s("h6"),v.textContent="API details",g=f(),w=s("div"),x=s("strong"),x.textContent="PATCH",Q=f(),B=s("div"),h=s("p"),C=_("/api/collections/"),le=s("strong"),ne=_(W),Ue=_("/records/"),$e=s("strong"),$e.textContent=":id",Ve=f(),I&&I.c(),Me=f(),de=s("div"),de.textContent="Path parameters",Se=f(),oe=s("table"),oe.innerHTML='Param Type Description id String ID of the record to update.',Oe=f(),re=s("div"),re.textContent="Body Parameters",qe=f(),z=s("table"),Re=s("thead"),Re.innerHTML='Param Type Description',xe=f(),K=s("tbody"),F&&F.c(),He=f();for(let l=0;lParam Type Description',We=f(),ue=s("tbody"),Y=s("tr"),Fe=s("td"),Fe.textContent="expand",ze=f(),Be=s("td"),Be.innerHTML='String',Ke=f(),N=s("td"),Xe=_(`Auto expand relations when returning the updated record. Ex.: - `),Ce(ae.$$.fragment),Ye=_(` - Supports up to 6-levels depth nested relations expansion. `),Ze=s("br"),Ge=_(` - The expanded relations will be appended to the record under the - `),Ne=s("code"),Ne.textContent="expand",et=_(" property (eg. "),Ae=s("code"),Ae.textContent='"expand": {"relField1": {...}, ...}',tt=_(`). Only - the relations that the user has permissions to `),Ee=s("strong"),Ee.textContent="view",lt=_(" will be expanded."),nt=f(),Ce(ie.$$.fragment),Ie=f(),pe=s("div"),pe.textContent="Responses",je=f(),Z=s("div"),fe=s("div");for(let l=0;l${JSON.stringify(l[7](l[0]),null,2)}; - -final record = await pb.collection('${(ft=l[0])==null?void 0:ft.name}').update('RECORD_ID', body: body); - `),R.$set(y),(!G||i&1)&&W!==(W=l[0].name+"")&&ee(ne,W),l[6]?I||(I=kt(),I.c(),I.m(w,null)):I&&(I.d(1),I=null),l[1]?F?F.p(l,i):(F=vt(l),F.c(),F.m(K,He)):F&&(F.d(1),F=null),i&32&&(ke=se(l[5]),U=Je(U,i,dt,1,l,ke,Qe,K,bt,gt,null,ht)),i&12&&(ve=se(l[3]),V=Je(V,i,ot,1,l,ve,at,fe,bt,wt,null,_t)),i&12&&(me=se(l[3]),qt(),A=Je(A,i,rt,1,l,me,st,be,Rt,Ct,null,mt),Ht())},i(l){if(!G){he(R.$$.fragment,l),he(ae.$$.fragment,l),he(ie.$$.fragment,l);for(let i=0;ir.name=="emailVisibility";function Kt(r,e,t){let n,b,p,c,u,{collection:m}=e,S=200,T=[];function H($){let M=ye.dummyCollectionSchemaData($,!0);return n&&(M.oldPassword="12345678",M.password="87654321",M.passwordConfirm="87654321",delete M.verified,delete M.email),M}const P=$=>t(2,S=$.code);return r.$$set=$=>{"collection"in $&&t(0,m=$.collection)},r.$$.update=()=>{var $,M,q;r.$$.dirty&1&&t(1,n=(m==null?void 0:m.type)==="auth"),r.$$.dirty&1&&t(6,b=(m==null?void 0:m.updateRule)===null),r.$$.dirty&2&&t(8,p=n?["id","password","verified","email","emailVisibility"]:["id"]),r.$$.dirty&257&&t(5,c=(($=m==null?void 0:m.fields)==null?void 0:$.filter(L=>!L.hidden&&L.type!="autodate"&&!p.includes(L.name)))||[]),r.$$.dirty&1&&t(3,T=[{code:200,body:JSON.stringify(ye.dummyCollectionRecord(m),null,2)},{code:400,body:` - { - "status": 400, - "message": "Failed to update record.", - "data": { - "${(q=(M=m==null?void 0:m.fields)==null?void 0:M[0])==null?void 0:q.name}": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `},{code:403,body:` - { - "status": 403, - "message": "You are not allowed to perform this request.", - "data": {} - } - `},{code:404,body:` - { - "status": 404, - "message": "The requested resource wasn't found.", - "data": {} - } - `}])},t(4,u=ye.getApiExampleUrl(Pt.baseURL)),[m,n,S,T,u,c,b,H,p,P]}class Zt extends $t{constructor(e){super(),Mt(this,e,Kt,Wt,St,{collection:0})}}export{Zt as default}; diff --git a/ui/dist/assets/VerificationDocs-BfIVQ1pO.js b/ui/dist/assets/VerificationDocs-BfIVQ1pO.js deleted file mode 100644 index e706bb7b..00000000 --- a/ui/dist/assets/VerificationDocs-BfIVQ1pO.js +++ /dev/null @@ -1,79 +0,0 @@ -import{S as le,i as ne,s as ie,X as F,h as b,t as j,a as U,I as Y,Z as x,_ as Te,C as ee,$ as Ce,D as te,l as h,n as u,u as m,v as y,A as M,w as v,k as K,o as oe,W as qe,d as z,m as G,c as Q,V as Ve,Y as fe,J as Ae,p as Ie,a0 as ue}from"./index-DMlPjiFP.js";function de(s,t,e){const o=s.slice();return o[4]=t[e],o}function me(s,t,e){const o=s.slice();return o[4]=t[e],o}function pe(s,t){let e,o=t[4].code+"",f,c,r,a;function d(){return t[3](t[4])}return{key:s,first:null,c(){e=m("button"),f=M(o),c=y(),v(e,"class","tab-item"),K(e,"active",t[1]===t[4].code),this.first=e},m(g,C){h(g,e,C),u(e,f),u(e,c),r||(a=oe(e,"click",d),r=!0)},p(g,C){t=g,C&4&&o!==(o=t[4].code+"")&&Y(f,o),C&6&&K(e,"active",t[1]===t[4].code)},d(g){g&&b(e),r=!1,a()}}}function _e(s,t){let e,o,f,c;return o=new qe({props:{content:t[4].body}}),{key:s,first:null,c(){e=m("div"),Q(o.$$.fragment),f=y(),v(e,"class","tab-item"),K(e,"active",t[1]===t[4].code),this.first=e},m(r,a){h(r,e,a),G(o,e,null),u(e,f),c=!0},p(r,a){t=r;const d={};a&4&&(d.content=t[4].body),o.$set(d),(!c||a&6)&&K(e,"active",t[1]===t[4].code)},i(r){c||(U(o.$$.fragment,r),c=!0)},o(r){j(o.$$.fragment,r),c=!1},d(r){r&&b(e),z(o)}}}function Pe(s){let t,e,o,f,c,r,a,d=s[0].name+"",g,C,D,P,L,R,B,O,N,q,V,$=[],J=new Map,H,I,p=[],T=new Map,A,_=F(s[2]);const X=l=>l[4].code;for(let l=0;l<_.length;l+=1){let i=me(s,_,l),n=X(i);J.set(n,$[l]=pe(n,i))}let E=F(s[2]);const W=l=>l[4].code;for(let l=0;lParam Type Description
    Required token
    String The token from the verification request email.',B=y(),O=m("div"),O.textContent="Responses",N=y(),q=m("div"),V=m("div");for(let l=0;l<$.length;l+=1)$[l].c();H=y(),I=m("div");for(let l=0;le(1,f=a.code);return s.$$set=a=>{"collection"in a&&e(0,o=a.collection)},e(2,c=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "token": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}]),[o,f,c,r]}class Be extends le{constructor(t){super(),ne(this,t,Re,Pe,ie,{collection:0})}}function be(s,t,e){const o=s.slice();return o[4]=t[e],o}function he(s,t,e){const o=s.slice();return o[4]=t[e],o}function ve(s,t){let e,o=t[4].code+"",f,c,r,a;function d(){return t[3](t[4])}return{key:s,first:null,c(){e=m("button"),f=M(o),c=y(),v(e,"class","tab-item"),K(e,"active",t[1]===t[4].code),this.first=e},m(g,C){h(g,e,C),u(e,f),u(e,c),r||(a=oe(e,"click",d),r=!0)},p(g,C){t=g,C&4&&o!==(o=t[4].code+"")&&Y(f,o),C&6&&K(e,"active",t[1]===t[4].code)},d(g){g&&b(e),r=!1,a()}}}function ge(s,t){let e,o,f,c;return o=new qe({props:{content:t[4].body}}),{key:s,first:null,c(){e=m("div"),Q(o.$$.fragment),f=y(),v(e,"class","tab-item"),K(e,"active",t[1]===t[4].code),this.first=e},m(r,a){h(r,e,a),G(o,e,null),u(e,f),c=!0},p(r,a){t=r;const d={};a&4&&(d.content=t[4].body),o.$set(d),(!c||a&6)&&K(e,"active",t[1]===t[4].code)},i(r){c||(U(o.$$.fragment,r),c=!0)},o(r){j(o.$$.fragment,r),c=!1},d(r){r&&b(e),z(o)}}}function Oe(s){let t,e,o,f,c,r,a,d=s[0].name+"",g,C,D,P,L,R,B,O,N,q,V,$=[],J=new Map,H,I,p=[],T=new Map,A,_=F(s[2]);const X=l=>l[4].code;for(let l=0;l<_.length;l+=1){let i=he(s,_,l),n=X(i);J.set(n,$[l]=ve(n,i))}let E=F(s[2]);const W=l=>l[4].code;for(let l=0;lParam Type Description
    Required email
    String The auth record email address to send the verification request (if exists).',B=y(),O=m("div"),O.textContent="Responses",N=y(),q=m("div"),V=m("div");for(let l=0;l<$.length;l+=1)$[l].c();H=y(),I=m("div");for(let l=0;le(1,f=a.code);return s.$$set=a=>{"collection"in a&&e(0,o=a.collection)},e(2,c=[{code:204,body:"null"},{code:400,body:` - { - "status": 400, - "message": "An error occurred while validating the submitted data.", - "data": { - "email": { - "code": "validation_required", - "message": "Missing required value." - } - } - } - `}]),[o,f,c,r]}class Me extends le{constructor(t){super(),ne(this,t,Ee,Oe,ie,{collection:0})}}function ke(s,t,e){const o=s.slice();return o[5]=t[e],o[7]=e,o}function $e(s,t,e){const o=s.slice();return o[5]=t[e],o[7]=e,o}function we(s){let t,e,o,f,c;function r(){return s[4](s[7])}return{c(){t=m("button"),e=m("div"),e.textContent=`${s[5].title}`,o=y(),v(e,"class","txt"),v(t,"class","tab-item"),K(t,"active",s[1]==s[7])},m(a,d){h(a,t,d),u(t,e),u(t,o),f||(c=oe(t,"click",r),f=!0)},p(a,d){s=a,d&2&&K(t,"active",s[1]==s[7])},d(a){a&&b(t),f=!1,c()}}}function ye(s){let t,e,o,f;var c=s[5].component;function r(a,d){return{props:{collection:a[0]}}}return c&&(e=ue(c,r(s))),{c(){t=m("div"),e&&Q(e.$$.fragment),o=y(),v(t,"class","tab-item"),K(t,"active",s[1]==s[7])},m(a,d){h(a,t,d),e&&G(e,t,null),u(t,o),f=!0},p(a,d){if(c!==(c=a[5].component)){if(e){ee();const g=e;j(g.$$.fragment,1,0,()=>{z(g,1)}),te()}c?(e=ue(c,r(a)),Q(e.$$.fragment),U(e.$$.fragment,1),G(e,t,o)):e=null}else if(c){const g={};d&1&&(g.collection=a[0]),e.$set(g)}(!f||d&2)&&K(t,"active",a[1]==a[7])},i(a){f||(e&&U(e.$$.fragment,a),f=!0)},o(a){e&&j(e.$$.fragment,a),f=!1},d(a){a&&b(t),e&&z(e)}}}function Ne(s){var E,W,l,i;let t,e,o=s[0].name+"",f,c,r,a,d,g,C,D=s[0].name+"",P,L,R,B,O,N,q,V,$,J,H,I;B=new Ve({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${s[2]}'); - - ... - - await pb.collection('${(E=s[0])==null?void 0:E.name}').requestVerification('test@example.com'); - - // --- - // (optional) in your custom confirmation page: - // --- - - await pb.collection('${(W=s[0])==null?void 0:W.name}').confirmVerification('VERIFICATION_TOKEN'); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${s[2]}'); - - ... - - await pb.collection('${(l=s[0])==null?void 0:l.name}').requestVerification('test@example.com'); - - // --- - // (optional) in your custom confirmation page: - // --- - - await pb.collection('${(i=s[0])==null?void 0:i.name}').confirmVerification('VERIFICATION_TOKEN'); - `}});let p=F(s[3]),T=[];for(let n=0;nj(_[n],1,1,()=>{_[n]=null});return{c(){t=m("h3"),e=M("Account verification ("),f=M(o),c=M(")"),r=y(),a=m("div"),d=m("p"),g=M("Sends "),C=m("strong"),P=M(D),L=M(" account verification request."),R=y(),Q(B.$$.fragment),O=y(),N=m("h6"),N.textContent="API details",q=y(),V=m("div"),$=m("div");for(let n=0;ne(1,r=d);return s.$$set=d=>{"collection"in d&&e(0,f=d.collection)},e(2,o=Ae.getApiExampleUrl(Ie.baseURL)),[f,r,o,c,a]}class Fe extends le{constructor(t){super(),ne(this,t,Se,Ne,ie,{collection:0})}}export{Fe as default}; diff --git a/ui/dist/assets/ViewApiDocs-DKZ-e-0R.js b/ui/dist/assets/ViewApiDocs-DKZ-e-0R.js deleted file mode 100644 index 8e8fbd81..00000000 --- a/ui/dist/assets/ViewApiDocs-DKZ-e-0R.js +++ /dev/null @@ -1,59 +0,0 @@ -import{S as lt,i as st,s as nt,V as at,W as tt,X as K,h as r,d as W,t as V,a as j,I as ve,Z as Ge,_ as ot,C as it,$ as rt,D as dt,l as d,n as l,m as X,u as a,A as _,v as b,c as Z,w as m,J as Ke,p as ct,k as Y,o as pt}from"./index-DMlPjiFP.js";import{F as ut}from"./FieldsQueryParam-B36GF025.js";function We(o,s,n){const i=o.slice();return i[6]=s[n],i}function Xe(o,s,n){const i=o.slice();return i[6]=s[n],i}function Ze(o){let s;return{c(){s=a("p"),s.innerHTML="Requires superuser Authorization:TOKEN header",m(s,"class","txt-hint txt-sm txt-right")},m(n,i){d(n,s,i)},d(n){n&&r(s)}}}function Ye(o,s){let n,i,v;function p(){return s[5](s[6])}return{key:o,first:null,c(){n=a("button"),n.textContent=`${s[6].code} `,m(n,"class","tab-item"),Y(n,"active",s[2]===s[6].code),this.first=n},m(c,f){d(c,n,f),i||(v=pt(n,"click",p),i=!0)},p(c,f){s=c,f&20&&Y(n,"active",s[2]===s[6].code)},d(c){c&&r(n),i=!1,v()}}}function et(o,s){let n,i,v,p;return i=new tt({props:{content:s[6].body}}),{key:o,first:null,c(){n=a("div"),Z(i.$$.fragment),v=b(),m(n,"class","tab-item"),Y(n,"active",s[2]===s[6].code),this.first=n},m(c,f){d(c,n,f),X(i,n,null),l(n,v),p=!0},p(c,f){s=c,(!p||f&20)&&Y(n,"active",s[2]===s[6].code)},i(c){p||(j(i.$$.fragment,c),p=!0)},o(c){V(i.$$.fragment,c),p=!1},d(c){c&&r(n),W(i)}}}function ft(o){var Je,Ne;let s,n,i=o[0].name+"",v,p,c,f,w,C,ee,J=o[0].name+"",te,$e,le,F,se,B,ne,$,N,ye,Q,T,we,ae,z=o[0].name+"",oe,Ce,ie,Fe,re,I,de,S,ce,x,pe,R,ue,Re,M,D,fe,De,be,Oe,h,Pe,E,Te,Ee,Ae,me,Be,_e,Ie,Se,xe,he,Me,qe,A,ke,q,ge,O,H,y=[],He=new Map,Le,L,k=[],Ue=new Map,P;F=new at({props:{js:` - import PocketBase from 'pocketbase'; - - const pb = new PocketBase('${o[3]}'); - - ... - - const record = await pb.collection('${(Je=o[0])==null?void 0:Je.name}').getOne('RECORD_ID', { - expand: 'relField1,relField2.subRelField', - }); - `,dart:` - import 'package:pocketbase/pocketbase.dart'; - - final pb = PocketBase('${o[3]}'); - - ... - - final record = await pb.collection('${(Ne=o[0])==null?void 0:Ne.name}').getOne('RECORD_ID', - expand: 'relField1,relField2.subRelField', - ); - `}});let g=o[1]&&Ze();E=new tt({props:{content:"?expand=relField1,relField2.subRelField"}}),A=new ut({});let G=K(o[4]);const Ve=e=>e[6].code;for(let e=0;ee[6].code;for(let e=0;eParam Type Description id String ID of the record to view.',ce=b(),x=a("div"),x.textContent="Query parameters",pe=b(),R=a("table"),ue=a("thead"),ue.innerHTML='Param Type Description',Re=b(),M=a("tbody"),D=a("tr"),fe=a("td"),fe.textContent="expand",De=b(),be=a("td"),be.innerHTML='String',Oe=b(),h=a("td"),Pe=_(`Auto expand record relations. Ex.: - `),Z(E.$$.fragment),Te=_(` - Supports up to 6-levels depth nested relations expansion. `),Ee=a("br"),Ae=_(` - The expanded relations will be appended to the record under the - `),me=a("code"),me.textContent="expand",Be=_(" property (eg. "),_e=a("code"),_e.textContent='"expand": {"relField1": {...}, ...}',Ie=_(`). - `),Se=a("br"),xe=_(` - Only the relations to which the request user has permissions to `),he=a("strong"),he.textContent="view",Me=_(" will be expanded."),qe=b(),Z(A.$$.fragment),ke=b(),q=a("div"),q.textContent="Responses",ge=b(),O=a("div"),H=a("div");for(let e=0;en(2,c=C.code);return o.$$set=C=>{"collection"in C&&n(0,p=C.collection)},o.$$.update=()=>{o.$$.dirty&1&&n(1,i=(p==null?void 0:p.viewRule)===null),o.$$.dirty&3&&p!=null&&p.id&&(f.push({code:200,body:JSON.stringify(Ke.dummyCollectionRecord(p),null,2)}),i&&f.push({code:403,body:` - { - "status": 403, - "message": "Only superusers can access this action.", - "data": {} - } - `}),f.push({code:404,body:` - { - "status": 404, - "message": "The requested resource wasn't found.", - "data": {} - } - `}))},n(3,v=Ke.getApiExampleUrl(ct.baseURL)),[p,i,c,v,f,w]}class ht extends lt{constructor(s){super(),st(this,s,bt,ft,nt,{collection:0})}}export{ht as default}; diff --git a/ui/dist/assets/autocomplete.worker-Bb6Toth-.js b/ui/dist/assets/autocomplete.worker-Bb6Toth-.js deleted file mode 100644 index 0eec484b..00000000 --- a/ui/dist/assets/autocomplete.worker-Bb6Toth-.js +++ /dev/null @@ -1,4 +0,0 @@ -(function(){"use strict";class Y extends Error{}class jn extends Y{constructor(e){super(`Invalid DateTime: ${e.toMessage()}`)}}class Gn extends Y{constructor(e){super(`Invalid Interval: ${e.toMessage()}`)}}class Kn extends Y{constructor(e){super(`Invalid Duration: ${e.toMessage()}`)}}class G extends Y{}class ht extends Y{constructor(e){super(`Invalid unit ${e}`)}}class b extends Y{}class Z extends Y{constructor(){super("Zone is an abstract class")}}const c="numeric",C="short",I="long",Se={year:c,month:c,day:c},mt={year:c,month:C,day:c},Hn={year:c,month:C,day:c,weekday:C},yt={year:c,month:I,day:c},gt={year:c,month:I,day:c,weekday:I},pt={hour:c,minute:c},wt={hour:c,minute:c,second:c},St={hour:c,minute:c,second:c,timeZoneName:C},kt={hour:c,minute:c,second:c,timeZoneName:I},Tt={hour:c,minute:c,hourCycle:"h23"},Ot={hour:c,minute:c,second:c,hourCycle:"h23"},xt={hour:c,minute:c,second:c,hourCycle:"h23",timeZoneName:C},Et={hour:c,minute:c,second:c,hourCycle:"h23",timeZoneName:I},Nt={year:c,month:c,day:c,hour:c,minute:c},bt={year:c,month:c,day:c,hour:c,minute:c,second:c},vt={year:c,month:C,day:c,hour:c,minute:c},Mt={year:c,month:C,day:c,hour:c,minute:c,second:c},Qn={year:c,month:C,day:c,weekday:C,hour:c,minute:c},It={year:c,month:I,day:c,hour:c,minute:c,timeZoneName:C},Dt={year:c,month:I,day:c,hour:c,minute:c,second:c,timeZoneName:C},Ft={year:c,month:I,day:c,weekday:I,hour:c,minute:c,timeZoneName:I},Vt={year:c,month:I,day:c,weekday:I,hour:c,minute:c,second:c,timeZoneName:I};class ae{get type(){throw new Z}get name(){throw new Z}get ianaName(){return this.name}get isUniversal(){throw new Z}offsetName(e,t){throw new Z}formatOffset(e,t){throw new Z}offset(e){throw new Z}equals(e){throw new Z}get isValid(){throw new Z}}let Le=null;class ke extends ae{static get instance(){return Le===null&&(Le=new ke),Le}get type(){return"system"}get name(){return new Intl.DateTimeFormat().resolvedOptions().timeZone}get isUniversal(){return!1}offsetName(e,{format:t,locale:n}){return rn(e,t,n)}formatOffset(e,t){return ce(this.offset(e),t)}offset(e){return-new Date(e).getTimezoneOffset()}equals(e){return e.type==="system"}get isValid(){return!0}}const Re=new Map;function _n(s){let e=Re.get(s);return e===void 0&&(e=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:s,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",era:"short"}),Re.set(s,e)),e}const Xn={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6};function es(s,e){const t=s.format(e).replace(/\u200E/g,""),n=/(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(t),[,r,i,a,o,u,l,f]=n;return[a,r,i,o,u,l,f]}function ts(s,e){const t=s.formatToParts(e),n=[];for(let r=0;r=0?T:1e3+T,(w-m)/(60*1e3)}equals(e){return e.type==="iana"&&e.name===this.name}get isValid(){return this.valid}}let At={};function ns(s,e={}){const t=JSON.stringify([s,e]);let n=At[t];return n||(n=new Intl.ListFormat(s,e),At[t]=n),n}const Ue=new Map;function Ze(s,e={}){const t=JSON.stringify([s,e]);let n=Ue.get(t);return n===void 0&&(n=new Intl.DateTimeFormat(s,e),Ue.set(t,n)),n}const qe=new Map;function ss(s,e={}){const t=JSON.stringify([s,e]);let n=qe.get(t);return n===void 0&&(n=new Intl.NumberFormat(s,e),qe.set(t,n)),n}const ze=new Map;function rs(s,e={}){const{base:t,...n}=e,r=JSON.stringify([s,n]);let i=ze.get(r);return i===void 0&&(i=new Intl.RelativeTimeFormat(s,e),ze.set(r,i)),i}let oe=null;function is(){return oe||(oe=new Intl.DateTimeFormat().resolvedOptions().locale,oe)}const Pe=new Map;function Ct(s){let e=Pe.get(s);return e===void 0&&(e=new Intl.DateTimeFormat(s).resolvedOptions(),Pe.set(s,e)),e}const Ye=new Map;function as(s){let e=Ye.get(s);if(!e){const t=new Intl.Locale(s);e="getWeekInfo"in t?t.getWeekInfo():t.weekInfo,"minimalDays"in e||(e={...Wt,...e}),Ye.set(s,e)}return e}function os(s){const e=s.indexOf("-x-");e!==-1&&(s=s.substring(0,e));const t=s.indexOf("-u-");if(t===-1)return[s];{let n,r;try{n=Ze(s).resolvedOptions(),r=s}catch{const u=s.substring(0,t);n=Ze(u).resolvedOptions(),r=u}const{numberingSystem:i,calendar:a}=n;return[r,i,a]}}function us(s,e,t){return(t||e)&&(s.includes("-u-")||(s+="-u"),t&&(s+=`-ca-${t}`),e&&(s+=`-nu-${e}`)),s}function ls(s){const e=[];for(let t=1;t<=12;t++){const n=y.utc(2009,t,1);e.push(s(n))}return e}function cs(s){const e=[];for(let t=1;t<=7;t++){const n=y.utc(2016,11,13+t);e.push(s(n))}return e}function Te(s,e,t,n){const r=s.listingMode();return r==="error"?null:r==="en"?t(e):n(e)}function fs(s){return s.numberingSystem&&s.numberingSystem!=="latn"?!1:s.numberingSystem==="latn"||!s.locale||s.locale.startsWith("en")||Ct(s.locale).numberingSystem==="latn"}class ds{constructor(e,t,n){this.padTo=n.padTo||0,this.floor=n.floor||!1;const{padTo:r,floor:i,...a}=n;if(!t||Object.keys(a).length>0){const o={useGrouping:!1,...n};n.padTo>0&&(o.minimumIntegerDigits=n.padTo),this.inf=ss(e,o)}}format(e){if(this.inf){const t=this.floor?Math.floor(e):e;return this.inf.format(t)}else{const t=this.floor?Math.floor(e):Xe(e,3);return E(t,this.padTo)}}}class hs{constructor(e,t,n){this.opts=n,this.originalZone=void 0;let r;if(this.opts.timeZone)this.dt=e;else if(e.zone.type==="fixed"){const a=-1*(e.offset/60),o=a>=0?`Etc/GMT+${a}`:`Etc/GMT${a}`;e.offset!==0&&$.create(o).valid?(r=o,this.dt=e):(r="UTC",this.dt=e.offset===0?e:e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone)}else e.zone.type==="system"?this.dt=e:e.zone.type==="iana"?(this.dt=e,r=e.zone.name):(r="UTC",this.dt=e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone);const i={...this.opts};i.timeZone=i.timeZone||r,this.dtf=Ze(t,i)}format(){return this.originalZone?this.formatToParts().map(({value:e})=>e).join(""):this.dtf.format(this.dt.toJSDate())}formatToParts(){const e=this.dtf.formatToParts(this.dt.toJSDate());return this.originalZone?e.map(t=>{if(t.type==="timeZoneName"){const n=this.originalZone.offsetName(this.dt.ts,{locale:this.dt.locale,format:this.opts.timeZoneName});return{...t,value:n}}else return t}):e}resolvedOptions(){return this.dtf.resolvedOptions()}}class ms{constructor(e,t,n){this.opts={style:"long",...n},!t&&en()&&(this.rtf=rs(e,n))}format(e,t){return this.rtf?this.rtf.format(e,t):Ls(t,e,this.opts.numeric,this.opts.style!=="long")}formatToParts(e,t){return this.rtf?this.rtf.formatToParts(e,t):[]}}const Wt={firstDay:1,minimalDays:4,weekend:[6,7]};class k{static fromOpts(e){return k.create(e.locale,e.numberingSystem,e.outputCalendar,e.weekSettings,e.defaultToEN)}static create(e,t,n,r,i=!1){const a=e||O.defaultLocale,o=a||(i?"en-US":is()),u=t||O.defaultNumberingSystem,l=n||O.defaultOutputCalendar,f=Qe(r)||O.defaultWeekSettings;return new k(o,u,l,f,a)}static resetCache(){oe=null,Ue.clear(),qe.clear(),ze.clear(),Pe.clear(),Ye.clear()}static fromObject({locale:e,numberingSystem:t,outputCalendar:n,weekSettings:r}={}){return k.create(e,t,n,r)}constructor(e,t,n,r,i){const[a,o,u]=os(e);this.locale=a,this.numberingSystem=t||o||null,this.outputCalendar=n||u||null,this.weekSettings=r,this.intl=us(this.locale,this.numberingSystem,this.outputCalendar),this.weekdaysCache={format:{},standalone:{}},this.monthsCache={format:{},standalone:{}},this.meridiemCache=null,this.eraCache={},this.specifiedLocale=i,this.fastNumbersCached=null}get fastNumbers(){return this.fastNumbersCached==null&&(this.fastNumbersCached=fs(this)),this.fastNumbersCached}listingMode(){const e=this.isEnglish(),t=(this.numberingSystem===null||this.numberingSystem==="latn")&&(this.outputCalendar===null||this.outputCalendar==="gregory");return e&&t?"en":"intl"}clone(e){return!e||Object.getOwnPropertyNames(e).length===0?this:k.create(e.locale||this.specifiedLocale,e.numberingSystem||this.numberingSystem,e.outputCalendar||this.outputCalendar,Qe(e.weekSettings)||this.weekSettings,e.defaultToEN||!1)}redefaultToEN(e={}){return this.clone({...e,defaultToEN:!0})}redefaultToSystem(e={}){return this.clone({...e,defaultToEN:!1})}months(e,t=!1){return Te(this,e,un,()=>{const n=this.intl==="ja"||this.intl.startsWith("ja-");t&=!n;const r=t?{month:e,day:"numeric"}:{month:e},i=t?"format":"standalone";if(!this.monthsCache[i][e]){const a=n?o=>this.dtFormatter(o,r).format():o=>this.extract(o,r,"month");this.monthsCache[i][e]=ls(a)}return this.monthsCache[i][e]})}weekdays(e,t=!1){return Te(this,e,fn,()=>{const n=t?{weekday:e,year:"numeric",month:"long",day:"numeric"}:{weekday:e},r=t?"format":"standalone";return this.weekdaysCache[r][e]||(this.weekdaysCache[r][e]=cs(i=>this.extract(i,n,"weekday"))),this.weekdaysCache[r][e]})}meridiems(){return Te(this,void 0,()=>dn,()=>{if(!this.meridiemCache){const e={hour:"numeric",hourCycle:"h12"};this.meridiemCache=[y.utc(2016,11,13,9),y.utc(2016,11,13,19)].map(t=>this.extract(t,e,"dayperiod"))}return this.meridiemCache})}eras(e){return Te(this,e,hn,()=>{const t={era:e};return this.eraCache[e]||(this.eraCache[e]=[y.utc(-40,1,1),y.utc(2017,1,1)].map(n=>this.extract(n,t,"era"))),this.eraCache[e]})}extract(e,t,n){const r=this.dtFormatter(e,t),i=r.formatToParts(),a=i.find(o=>o.type.toLowerCase()===n);return a?a.value:null}numberFormatter(e={}){return new ds(this.intl,e.forceSimple||this.fastNumbers,e)}dtFormatter(e,t={}){return new hs(e,this.intl,t)}relFormatter(e={}){return new ms(this.intl,this.isEnglish(),e)}listFormatter(e={}){return ns(this.intl,e)}isEnglish(){return this.locale==="en"||this.locale.toLowerCase()==="en-us"||Ct(this.intl).locale.startsWith("en-us")}getWeekSettings(){return this.weekSettings?this.weekSettings:tn()?as(this.locale):Wt}getStartOfWeek(){return this.getWeekSettings().firstDay}getMinDaysInFirstWeek(){return this.getWeekSettings().minimalDays}getWeekendDays(){return this.getWeekSettings().weekend}equals(e){return this.locale===e.locale&&this.numberingSystem===e.numberingSystem&&this.outputCalendar===e.outputCalendar}toString(){return`Locale(${this.locale}, ${this.numberingSystem}, ${this.outputCalendar})`}}let Je=null;class M extends ae{static get utcInstance(){return Je===null&&(Je=new M(0)),Je}static instance(e){return e===0?M.utcInstance:new M(e)}static parseSpecifier(e){if(e){const t=e.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);if(t)return new M(be(t[1],t[2]))}return null}constructor(e){super(),this.fixed=e}get type(){return"fixed"}get name(){return this.fixed===0?"UTC":`UTC${ce(this.fixed,"narrow")}`}get ianaName(){return this.fixed===0?"Etc/UTC":`Etc/GMT${ce(-this.fixed,"narrow")}`}offsetName(){return this.name}formatOffset(e,t){return ce(this.fixed,t)}get isUniversal(){return!0}offset(){return this.fixed}equals(e){return e.type==="fixed"&&e.fixed===this.fixed}get isValid(){return!0}}class ys extends ae{constructor(e){super(),this.zoneName=e}get type(){return"invalid"}get name(){return this.zoneName}get isUniversal(){return!1}offsetName(){return null}formatOffset(){return""}offset(){return NaN}equals(){return!1}get isValid(){return!1}}function q(s,e){if(g(s)||s===null)return e;if(s instanceof ae)return s;if(Ts(s)){const t=s.toLowerCase();return t==="default"?e:t==="local"||t==="system"?ke.instance:t==="utc"||t==="gmt"?M.utcInstance:M.parseSpecifier(t)||$.create(s)}else return z(s)?M.instance(s):typeof s=="object"&&"offset"in s&&typeof s.offset=="function"?s:new ys(s)}const Be={arab:"[٠-٩]",arabext:"[۰-۹]",bali:"[᭐-᭙]",beng:"[০-৯]",deva:"[०-९]",fullwide:"[0-9]",gujr:"[૦-૯]",hanidec:"[〇|一|二|三|四|五|六|七|八|九]",khmr:"[០-៩]",knda:"[೦-೯]",laoo:"[໐-໙]",limb:"[᥆-᥏]",mlym:"[൦-൯]",mong:"[᠐-᠙]",mymr:"[၀-၉]",orya:"[୦-୯]",tamldec:"[௦-௯]",telu:"[౦-౯]",thai:"[๐-๙]",tibt:"[༠-༩]",latn:"\\d"},Lt={arab:[1632,1641],arabext:[1776,1785],bali:[6992,7001],beng:[2534,2543],deva:[2406,2415],fullwide:[65296,65303],gujr:[2790,2799],khmr:[6112,6121],knda:[3302,3311],laoo:[3792,3801],limb:[6470,6479],mlym:[3430,3439],mong:[6160,6169],mymr:[4160,4169],orya:[2918,2927],tamldec:[3046,3055],telu:[3174,3183],thai:[3664,3673],tibt:[3872,3881]},gs=Be.hanidec.replace(/[\[|\]]/g,"").split("");function ps(s){let e=parseInt(s,10);if(isNaN(e)){e="";for(let t=0;t=i&&n<=a&&(e+=n-i)}}return parseInt(e,10)}else return e}const je=new Map;function ws(){je.clear()}function W({numberingSystem:s},e=""){const t=s||"latn";let n=je.get(t);n===void 0&&(n=new Map,je.set(t,n));let r=n.get(e);return r===void 0&&(r=new RegExp(`${Be[t]}${e}`),n.set(e,r)),r}let Rt=()=>Date.now(),$t="system",Ut=null,Zt=null,qt=null,zt=60,Pt,Yt=null;class O{static get now(){return Rt}static set now(e){Rt=e}static set defaultZone(e){$t=e}static get defaultZone(){return q($t,ke.instance)}static get defaultLocale(){return Ut}static set defaultLocale(e){Ut=e}static get defaultNumberingSystem(){return Zt}static set defaultNumberingSystem(e){Zt=e}static get defaultOutputCalendar(){return qt}static set defaultOutputCalendar(e){qt=e}static get defaultWeekSettings(){return Yt}static set defaultWeekSettings(e){Yt=Qe(e)}static get twoDigitCutoffYear(){return zt}static set twoDigitCutoffYear(e){zt=e%100}static get throwOnInvalid(){return Pt}static set throwOnInvalid(e){Pt=e}static resetCaches(){k.resetCache(),$.resetCache(),y.resetCache(),ws()}}class L{constructor(e,t){this.reason=e,this.explanation=t}toMessage(){return this.explanation?`${this.reason}: ${this.explanation}`:this.reason}}const Jt=[0,31,59,90,120,151,181,212,243,273,304,334],Bt=[0,31,60,91,121,152,182,213,244,274,305,335];function F(s,e){return new L("unit out of range",`you specified ${e} (of type ${typeof e}) as a ${s}, which is invalid`)}function Ge(s,e,t){const n=new Date(Date.UTC(s,e-1,t));s<100&&s>=0&&n.setUTCFullYear(n.getUTCFullYear()-1900);const r=n.getUTCDay();return r===0?7:r}function jt(s,e,t){return t+(ue(s)?Bt:Jt)[e-1]}function Gt(s,e){const t=ue(s)?Bt:Jt,n=t.findIndex(i=>ile(n,e,t)?(l=n+1,u=1):l=n,{weekYear:l,weekNumber:u,weekday:o,...Me(s)}}function Kt(s,e=4,t=1){const{weekYear:n,weekNumber:r,weekday:i}=s,a=Ke(Ge(n,1,e),t),o=H(n);let u=r*7+i-a-7+e,l;u<1?(l=n-1,u+=H(l)):u>o?(l=n+1,u-=H(n)):l=n;const{month:f,day:h}=Gt(l,u);return{year:l,month:f,day:h,...Me(s)}}function He(s){const{year:e,month:t,day:n}=s,r=jt(e,t,n);return{year:e,ordinal:r,...Me(s)}}function Ht(s){const{year:e,ordinal:t}=s,{month:n,day:r}=Gt(e,t);return{year:e,month:n,day:r,...Me(s)}}function Qt(s,e){if(!g(s.localWeekday)||!g(s.localWeekNumber)||!g(s.localWeekYear)){if(!g(s.weekday)||!g(s.weekNumber)||!g(s.weekYear))throw new G("Cannot mix locale-based week fields with ISO-based week fields");return g(s.localWeekday)||(s.weekday=s.localWeekday),g(s.localWeekNumber)||(s.weekNumber=s.localWeekNumber),g(s.localWeekYear)||(s.weekYear=s.localWeekYear),delete s.localWeekday,delete s.localWeekNumber,delete s.localWeekYear,{minDaysInFirstWeek:e.getMinDaysInFirstWeek(),startOfWeek:e.getStartOfWeek()}}else return{minDaysInFirstWeek:4,startOfWeek:1}}function Ss(s,e=4,t=1){const n=xe(s.weekYear),r=V(s.weekNumber,1,le(s.weekYear,e,t)),i=V(s.weekday,1,7);return n?r?i?!1:F("weekday",s.weekday):F("week",s.weekNumber):F("weekYear",s.weekYear)}function ks(s){const e=xe(s.year),t=V(s.ordinal,1,H(s.year));return e?t?!1:F("ordinal",s.ordinal):F("year",s.year)}function _t(s){const e=xe(s.year),t=V(s.month,1,12),n=V(s.day,1,Ee(s.year,s.month));return e?t?n?!1:F("day",s.day):F("month",s.month):F("year",s.year)}function Xt(s){const{hour:e,minute:t,second:n,millisecond:r}=s,i=V(e,0,23)||e===24&&t===0&&n===0&&r===0,a=V(t,0,59),o=V(n,0,59),u=V(r,0,999);return i?a?o?u?!1:F("millisecond",r):F("second",n):F("minute",t):F("hour",e)}function g(s){return typeof s>"u"}function z(s){return typeof s=="number"}function xe(s){return typeof s=="number"&&s%1===0}function Ts(s){return typeof s=="string"}function Os(s){return Object.prototype.toString.call(s)==="[object Date]"}function en(){try{return typeof Intl<"u"&&!!Intl.RelativeTimeFormat}catch{return!1}}function tn(){try{return typeof Intl<"u"&&!!Intl.Locale&&("weekInfo"in Intl.Locale.prototype||"getWeekInfo"in Intl.Locale.prototype)}catch{return!1}}function xs(s){return Array.isArray(s)?s:[s]}function nn(s,e,t){if(s.length!==0)return s.reduce((n,r)=>{const i=[e(r),r];return n&&t(n[0],i[0])===n[0]?n:i},null)[1]}function Es(s,e){return e.reduce((t,n)=>(t[n]=s[n],t),{})}function K(s,e){return Object.prototype.hasOwnProperty.call(s,e)}function Qe(s){if(s==null)return null;if(typeof s!="object")throw new b("Week settings must be an object");if(!V(s.firstDay,1,7)||!V(s.minimalDays,1,7)||!Array.isArray(s.weekend)||s.weekend.some(e=>!V(e,1,7)))throw new b("Invalid week settings");return{firstDay:s.firstDay,minimalDays:s.minimalDays,weekend:Array.from(s.weekend)}}function V(s,e,t){return xe(s)&&s>=e&&s<=t}function Ns(s,e){return s-e*Math.floor(s/e)}function E(s,e=2){const t=s<0;let n;return t?n="-"+(""+-s).padStart(e,"0"):n=(""+s).padStart(e,"0"),n}function P(s){if(!(g(s)||s===null||s===""))return parseInt(s,10)}function J(s){if(!(g(s)||s===null||s===""))return parseFloat(s)}function _e(s){if(!(g(s)||s===null||s==="")){const e=parseFloat("0."+s)*1e3;return Math.floor(e)}}function Xe(s,e,t="round"){const n=10**e;switch(t){case"expand":return s>0?Math.ceil(s*n)/n:Math.floor(s*n)/n;case"trunc":return Math.trunc(s*n)/n;case"round":return Math.round(s*n)/n;case"floor":return Math.floor(s*n)/n;case"ceil":return Math.ceil(s*n)/n;default:throw new RangeError(`Value rounding ${t} is out of range`)}}function ue(s){return s%4===0&&(s%100!==0||s%400===0)}function H(s){return ue(s)?366:365}function Ee(s,e){const t=Ns(e-1,12)+1,n=s+(e-t)/12;return t===2?ue(n)?29:28:[31,null,31,30,31,30,31,31,30,31,30,31][t-1]}function Ne(s){let e=Date.UTC(s.year,s.month-1,s.day,s.hour,s.minute,s.second,s.millisecond);return s.year<100&&s.year>=0&&(e=new Date(e),e.setUTCFullYear(s.year,s.month-1,s.day)),+e}function sn(s,e,t){return-Ke(Ge(s,1,e),t)+e-1}function le(s,e=4,t=1){const n=sn(s,e,t),r=sn(s+1,e,t);return(H(s)-n+r)/7}function et(s){return s>99?s:s>O.twoDigitCutoffYear?1900+s:2e3+s}function rn(s,e,t,n=null){const r=new Date(s),i={hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"};n&&(i.timeZone=n);const a={timeZoneName:e,...i},o=new Intl.DateTimeFormat(t,a).formatToParts(r).find(u=>u.type.toLowerCase()==="timezonename");return o?o.value:null}function be(s,e){let t=parseInt(s,10);Number.isNaN(t)&&(t=0);const n=parseInt(e,10)||0,r=t<0||Object.is(t,-0)?-n:n;return t*60+r}function an(s){const e=Number(s);if(typeof s=="boolean"||s===""||!Number.isFinite(e))throw new b(`Invalid unit value ${s}`);return e}function ve(s,e){const t={};for(const n in s)if(K(s,n)){const r=s[n];if(r==null)continue;t[e(n)]=an(r)}return t}function ce(s,e){const t=Math.trunc(Math.abs(s/60)),n=Math.trunc(Math.abs(s%60)),r=s>=0?"+":"-";switch(e){case"short":return`${r}${E(t,2)}:${E(n,2)}`;case"narrow":return`${r}${t}${n>0?`:${n}`:""}`;case"techie":return`${r}${E(t,2)}${E(n,2)}`;default:throw new RangeError(`Value format ${e} is out of range for property format`)}}function Me(s){return Es(s,["hour","minute","second","millisecond"])}const bs=["January","February","March","April","May","June","July","August","September","October","November","December"],on=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],vs=["J","F","M","A","M","J","J","A","S","O","N","D"];function un(s){switch(s){case"narrow":return[...vs];case"short":return[...on];case"long":return[...bs];case"numeric":return["1","2","3","4","5","6","7","8","9","10","11","12"];case"2-digit":return["01","02","03","04","05","06","07","08","09","10","11","12"];default:return null}}const ln=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],cn=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],Ms=["M","T","W","T","F","S","S"];function fn(s){switch(s){case"narrow":return[...Ms];case"short":return[...cn];case"long":return[...ln];case"numeric":return["1","2","3","4","5","6","7"];default:return null}}const dn=["AM","PM"],Is=["Before Christ","Anno Domini"],Ds=["BC","AD"],Fs=["B","A"];function hn(s){switch(s){case"narrow":return[...Fs];case"short":return[...Ds];case"long":return[...Is];default:return null}}function Vs(s){return dn[s.hour<12?0:1]}function As(s,e){return fn(e)[s.weekday-1]}function Cs(s,e){return un(e)[s.month-1]}function Ws(s,e){return hn(e)[s.year<0?0:1]}function Ls(s,e,t="always",n=!1){const r={years:["year","yr."],quarters:["quarter","qtr."],months:["month","mo."],weeks:["week","wk."],days:["day","day","days"],hours:["hour","hr."],minutes:["minute","min."],seconds:["second","sec."]},i=["hours","minutes","seconds"].indexOf(s)===-1;if(t==="auto"&&i){const h=s==="days";switch(e){case 1:return h?"tomorrow":`next ${r[s][0]}`;case-1:return h?"yesterday":`last ${r[s][0]}`;case 0:return h?"today":`this ${r[s][0]}`}}const a=Object.is(e,-0)||e<0,o=Math.abs(e),u=o===1,l=r[s],f=n?u?l[1]:l[2]||l[1]:u?r[s][0]:s;return a?`${o} ${f} ago`:`in ${o} ${f}`}function mn(s,e){let t="";for(const n of s)n.literal?t+=n.val:t+=e(n.val);return t}const Rs={D:Se,DD:mt,DDD:yt,DDDD:gt,t:pt,tt:wt,ttt:St,tttt:kt,T:Tt,TT:Ot,TTT:xt,TTTT:Et,f:Nt,ff:vt,fff:It,ffff:Ft,F:bt,FF:Mt,FFF:Dt,FFFF:Vt};class v{static create(e,t={}){return new v(e,t)}static parseFormat(e){let t=null,n="",r=!1;const i=[];for(let a=0;a0||r)&&i.push({literal:r||/^\s+$/.test(n),val:n===""?"'":n}),t=null,n="",r=!r):r||o===t?n+=o:(n.length>0&&i.push({literal:/^\s+$/.test(n),val:n}),n=o,t=o)}return n.length>0&&i.push({literal:r||/^\s+$/.test(n),val:n}),i}static macroTokenToFormatOpts(e){return Rs[e]}constructor(e,t){this.opts=t,this.loc=e,this.systemLoc=null}formatWithSystemDefault(e,t){return this.systemLoc===null&&(this.systemLoc=this.loc.redefaultToSystem()),this.systemLoc.dtFormatter(e,{...this.opts,...t}).format()}dtFormatter(e,t={}){return this.loc.dtFormatter(e,{...this.opts,...t})}formatDateTime(e,t){return this.dtFormatter(e,t).format()}formatDateTimeParts(e,t){return this.dtFormatter(e,t).formatToParts()}formatInterval(e,t){return this.dtFormatter(e.start,t).dtf.formatRange(e.start.toJSDate(),e.end.toJSDate())}resolvedOptions(e,t){return this.dtFormatter(e,t).resolvedOptions()}num(e,t=0,n=void 0){if(this.opts.forceSimple)return E(e,t);const r={...this.opts};return t>0&&(r.padTo=t),n&&(r.signDisplay=n),this.loc.numberFormatter(r).format(e)}formatDateTimeFromString(e,t){const n=this.loc.listingMode()==="en",r=this.loc.outputCalendar&&this.loc.outputCalendar!=="gregory",i=(m,T)=>this.loc.extract(e,m,T),a=m=>e.isOffsetFixed&&e.offset===0&&m.allowZ?"Z":e.isValid?e.zone.formatOffset(e.ts,m.format):"",o=()=>n?Vs(e):i({hour:"numeric",hourCycle:"h12"},"dayperiod"),u=(m,T)=>n?Cs(e,m):i(T?{month:m}:{month:m,day:"numeric"},"month"),l=(m,T)=>n?As(e,m):i(T?{weekday:m}:{weekday:m,month:"long",day:"numeric"},"weekday"),f=m=>{const T=v.macroTokenToFormatOpts(m);return T?this.formatWithSystemDefault(e,T):m},h=m=>n?Ws(e,m):i({era:m},"era"),w=m=>{switch(m){case"S":return this.num(e.millisecond);case"u":case"SSS":return this.num(e.millisecond,3);case"s":return this.num(e.second);case"ss":return this.num(e.second,2);case"uu":return this.num(Math.floor(e.millisecond/10),2);case"uuu":return this.num(Math.floor(e.millisecond/100));case"m":return this.num(e.minute);case"mm":return this.num(e.minute,2);case"h":return this.num(e.hour%12===0?12:e.hour%12);case"hh":return this.num(e.hour%12===0?12:e.hour%12,2);case"H":return this.num(e.hour);case"HH":return this.num(e.hour,2);case"Z":return a({format:"narrow",allowZ:this.opts.allowZ});case"ZZ":return a({format:"short",allowZ:this.opts.allowZ});case"ZZZ":return a({format:"techie",allowZ:this.opts.allowZ});case"ZZZZ":return e.zone.offsetName(e.ts,{format:"short",locale:this.loc.locale});case"ZZZZZ":return e.zone.offsetName(e.ts,{format:"long",locale:this.loc.locale});case"z":return e.zoneName;case"a":return o();case"d":return r?i({day:"numeric"},"day"):this.num(e.day);case"dd":return r?i({day:"2-digit"},"day"):this.num(e.day,2);case"c":return this.num(e.weekday);case"ccc":return l("short",!0);case"cccc":return l("long",!0);case"ccccc":return l("narrow",!0);case"E":return this.num(e.weekday);case"EEE":return l("short",!1);case"EEEE":return l("long",!1);case"EEEEE":return l("narrow",!1);case"L":return r?i({month:"numeric",day:"numeric"},"month"):this.num(e.month);case"LL":return r?i({month:"2-digit",day:"numeric"},"month"):this.num(e.month,2);case"LLL":return u("short",!0);case"LLLL":return u("long",!0);case"LLLLL":return u("narrow",!0);case"M":return r?i({month:"numeric"},"month"):this.num(e.month);case"MM":return r?i({month:"2-digit"},"month"):this.num(e.month,2);case"MMM":return u("short",!1);case"MMMM":return u("long",!1);case"MMMMM":return u("narrow",!1);case"y":return r?i({year:"numeric"},"year"):this.num(e.year);case"yy":return r?i({year:"2-digit"},"year"):this.num(e.year.toString().slice(-2),2);case"yyyy":return r?i({year:"numeric"},"year"):this.num(e.year,4);case"yyyyyy":return r?i({year:"numeric"},"year"):this.num(e.year,6);case"G":return h("short");case"GG":return h("long");case"GGGGG":return h("narrow");case"kk":return this.num(e.weekYear.toString().slice(-2),2);case"kkkk":return this.num(e.weekYear,4);case"W":return this.num(e.weekNumber);case"WW":return this.num(e.weekNumber,2);case"n":return this.num(e.localWeekNumber);case"nn":return this.num(e.localWeekNumber,2);case"ii":return this.num(e.localWeekYear.toString().slice(-2),2);case"iiii":return this.num(e.localWeekYear,4);case"o":return this.num(e.ordinal);case"ooo":return this.num(e.ordinal,3);case"q":return this.num(e.quarter);case"qq":return this.num(e.quarter,2);case"X":return this.num(Math.floor(e.ts/1e3));case"x":return this.num(e.ts);default:return f(m)}};return mn(v.parseFormat(t),w)}formatDurationFromString(e,t){const n=this.opts.signMode==="negativeLargestOnly"?-1:1,r=f=>{switch(f[0]){case"S":return"milliseconds";case"s":return"seconds";case"m":return"minutes";case"h":return"hours";case"d":return"days";case"w":return"weeks";case"M":return"months";case"y":return"years";default:return null}},i=(f,h)=>w=>{const m=r(w);if(m){const T=h.isNegativeDuration&&m!==h.largestUnit?n:1;let N;return this.opts.signMode==="negativeLargestOnly"&&m!==h.largestUnit?N="never":this.opts.signMode==="all"?N="always":N="auto",this.num(f.get(m)*T,w.length,N)}else return w},a=v.parseFormat(t),o=a.reduce((f,{literal:h,val:w})=>h?f:f.concat(w),[]),u=e.shiftTo(...o.map(r).filter(f=>f)),l={isNegativeDuration:u<0,largestUnit:Object.keys(u.values)[0]};return mn(a,i(u,l))}}const yn=/[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;function Q(...s){const e=s.reduce((t,n)=>t+n.source,"");return RegExp(`^${e}$`)}function _(...s){return e=>s.reduce(([t,n,r],i)=>{const[a,o,u]=i(e,r);return[{...t,...a},o||n,u]},[{},null,1]).slice(0,2)}function X(s,...e){if(s==null)return[null,null];for(const[t,n]of e){const r=t.exec(s);if(r)return n(r)}return[null,null]}function gn(...s){return(e,t)=>{const n={};let r;for(r=0;rm!==void 0&&(T||m&&f)?-m:m;return[{years:w(J(t)),months:w(J(n)),weeks:w(J(r)),days:w(J(i)),hours:w(J(a)),minutes:w(J(o)),seconds:w(J(u),u==="-0"),milliseconds:w(_e(l),h)}]}const Hs={GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function st(s,e,t,n,r,i,a){const o={year:e.length===2?et(P(e)):P(e),month:on.indexOf(t)+1,day:P(n),hour:P(r),minute:P(i)};return a&&(o.second=P(a)),s&&(o.weekday=s.length>3?ln.indexOf(s)+1:cn.indexOf(s)+1),o}const Qs=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;function _s(s){const[,e,t,n,r,i,a,o,u,l,f,h]=s,w=st(e,r,n,t,i,a,o);let m;return u?m=Hs[u]:l?m=0:m=be(f,h),[w,new M(m)]}function Xs(s){return s.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim()}const er=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,tr=/^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,nr=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;function kn(s){const[,e,t,n,r,i,a,o]=s;return[st(e,r,n,t,i,a,o),M.utcInstance]}function sr(s){const[,e,t,n,r,i,a,o]=s;return[st(e,o,t,n,r,i,a),M.utcInstance]}const rr=Q(Us,nt),ir=Q(Zs,nt),ar=Q(qs,nt),or=Q(wn),Tn=_(Bs,te,fe,de),ur=_(zs,te,fe,de),lr=_(Ps,te,fe,de),cr=_(te,fe,de);function fr(s){return X(s,[rr,Tn],[ir,ur],[ar,lr],[or,cr])}function dr(s){return X(Xs(s),[Qs,_s])}function hr(s){return X(s,[er,kn],[tr,kn],[nr,sr])}function mr(s){return X(s,[Gs,Ks])}const yr=_(te);function gr(s){return X(s,[js,yr])}const pr=Q(Ys,Js),wr=Q(Sn),Sr=_(te,fe,de);function kr(s){return X(s,[pr,Tn],[wr,Sr])}const On="Invalid Duration",xn={weeks:{days:7,hours:7*24,minutes:7*24*60,seconds:7*24*60*60,milliseconds:7*24*60*60*1e3},days:{hours:24,minutes:24*60,seconds:24*60*60,milliseconds:24*60*60*1e3},hours:{minutes:60,seconds:60*60,milliseconds:60*60*1e3},minutes:{seconds:60,milliseconds:60*1e3},seconds:{milliseconds:1e3}},Tr={years:{quarters:4,months:12,weeks:52,days:365,hours:365*24,minutes:365*24*60,seconds:365*24*60*60,milliseconds:365*24*60*60*1e3},quarters:{months:3,weeks:13,days:91,hours:91*24,minutes:91*24*60,seconds:91*24*60*60,milliseconds:91*24*60*60*1e3},months:{weeks:4,days:30,hours:30*24,minutes:30*24*60,seconds:30*24*60*60,milliseconds:30*24*60*60*1e3},...xn},A=146097/400,ne=146097/4800,Or={years:{quarters:4,months:12,weeks:A/7,days:A,hours:A*24,minutes:A*24*60,seconds:A*24*60*60,milliseconds:A*24*60*60*1e3},quarters:{months:3,weeks:A/28,days:A/4,hours:A*24/4,minutes:A*24*60/4,seconds:A*24*60*60/4,milliseconds:A*24*60*60*1e3/4},months:{weeks:ne/7,days:ne,hours:ne*24,minutes:ne*24*60,seconds:ne*24*60*60,milliseconds:ne*24*60*60*1e3},...xn},B=["years","quarters","months","weeks","days","hours","minutes","seconds","milliseconds"],xr=B.slice(0).reverse();function U(s,e,t=!1){const n={values:t?e.values:{...s.values,...e.values||{}},loc:s.loc.clone(e.loc),conversionAccuracy:e.conversionAccuracy||s.conversionAccuracy,matrix:e.matrix||s.matrix};return new p(n)}function En(s,e){let t=e.milliseconds??0;for(const n of xr.slice(1))e[n]&&(t+=e[n]*s[n].milliseconds);return t}function Nn(s,e){const t=En(s,e)<0?-1:1;B.reduceRight((n,r)=>{if(g(e[r]))return n;if(n){const i=e[n]*t,a=s[r][n],o=Math.floor(i/a);e[r]+=o*t,e[n]-=o*a*t}return r},null),B.reduce((n,r)=>{if(g(e[r]))return n;if(n){const i=e[n]%1;e[n]-=i,e[r]+=i*s[n][r]}return r},null)}function bn(s){const e={};for(const[t,n]of Object.entries(s))n!==0&&(e[t]=n);return e}class p{constructor(e){const t=e.conversionAccuracy==="longterm"||!1;let n=t?Or:Tr;e.matrix&&(n=e.matrix),this.values=e.values,this.loc=e.loc||k.create(),this.conversionAccuracy=t?"longterm":"casual",this.invalid=e.invalid||null,this.matrix=n,this.isLuxonDuration=!0}static fromMillis(e,t){return p.fromObject({milliseconds:e},t)}static fromObject(e,t={}){if(e==null||typeof e!="object")throw new b(`Duration.fromObject: argument expected to be an object, got ${e===null?"null":typeof e}`);return new p({values:ve(e,p.normalizeUnit),loc:k.fromObject(t),conversionAccuracy:t.conversionAccuracy,matrix:t.matrix})}static fromDurationLike(e){if(z(e))return p.fromMillis(e);if(p.isDuration(e))return e;if(typeof e=="object")return p.fromObject(e);throw new b(`Unknown duration argument ${e} of type ${typeof e}`)}static fromISO(e,t){const[n]=mr(e);return n?p.fromObject(n,t):p.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static fromISOTime(e,t){const[n]=gr(e);return n?p.fromObject(n,t):p.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static invalid(e,t=null){if(!e)throw new b("need to specify a reason the Duration is invalid");const n=e instanceof L?e:new L(e,t);if(O.throwOnInvalid)throw new Kn(n);return new p({invalid:n})}static normalizeUnit(e){const t={year:"years",years:"years",quarter:"quarters",quarters:"quarters",month:"months",months:"months",week:"weeks",weeks:"weeks",day:"days",days:"days",hour:"hours",hours:"hours",minute:"minutes",minutes:"minutes",second:"seconds",seconds:"seconds",millisecond:"milliseconds",milliseconds:"milliseconds"}[e&&e.toLowerCase()];if(!t)throw new ht(e);return t}static isDuration(e){return e&&e.isLuxonDuration||!1}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}toFormat(e,t={}){const n={...t,floor:t.round!==!1&&t.floor!==!1};return this.isValid?v.create(this.loc,n).formatDurationFromString(this,e):On}toHuman(e={}){if(!this.isValid)return On;const t=e.showZeros!==!1,n=B.map(r=>{const i=this.values[r];return g(i)||i===0&&!t?null:this.loc.numberFormatter({style:"unit",unitDisplay:"long",...e,unit:r.slice(0,-1)}).format(i)}).filter(r=>r);return this.loc.listFormatter({type:"conjunction",style:e.listStyle||"narrow",...e}).format(n)}toObject(){return this.isValid?{...this.values}:{}}toISO(){if(!this.isValid)return null;let e="P";return this.years!==0&&(e+=this.years+"Y"),(this.months!==0||this.quarters!==0)&&(e+=this.months+this.quarters*3+"M"),this.weeks!==0&&(e+=this.weeks+"W"),this.days!==0&&(e+=this.days+"D"),(this.hours!==0||this.minutes!==0||this.seconds!==0||this.milliseconds!==0)&&(e+="T"),this.hours!==0&&(e+=this.hours+"H"),this.minutes!==0&&(e+=this.minutes+"M"),(this.seconds!==0||this.milliseconds!==0)&&(e+=Xe(this.seconds+this.milliseconds/1e3,3)+"S"),e==="P"&&(e+="T0S"),e}toISOTime(e={}){if(!this.isValid)return null;const t=this.toMillis();return t<0||t>=864e5?null:(e={suppressMilliseconds:!1,suppressSeconds:!1,includePrefix:!1,format:"extended",...e,includeOffset:!1},y.fromMillis(t,{zone:"UTC"}).toISOTime(e))}toJSON(){return this.toISO()}toString(){return this.toISO()}[Symbol.for("nodejs.util.inspect.custom")](){return this.isValid?`Duration { values: ${JSON.stringify(this.values)} }`:`Duration { Invalid, reason: ${this.invalidReason} }`}toMillis(){return this.isValid?En(this.matrix,this.values):NaN}valueOf(){return this.toMillis()}plus(e){if(!this.isValid)return this;const t=p.fromDurationLike(e),n={};for(const r of B)(K(t.values,r)||K(this.values,r))&&(n[r]=t.get(r)+this.get(r));return U(this,{values:n},!0)}minus(e){if(!this.isValid)return this;const t=p.fromDurationLike(e);return this.plus(t.negate())}mapUnits(e){if(!this.isValid)return this;const t={};for(const n of Object.keys(this.values))t[n]=an(e(this.values[n],n));return U(this,{values:t},!0)}get(e){return this[p.normalizeUnit(e)]}set(e){if(!this.isValid)return this;const t={...this.values,...ve(e,p.normalizeUnit)};return U(this,{values:t})}reconfigure({locale:e,numberingSystem:t,conversionAccuracy:n,matrix:r}={}){const a={loc:this.loc.clone({locale:e,numberingSystem:t}),matrix:r,conversionAccuracy:n};return U(this,a)}as(e){return this.isValid?this.shiftTo(e).get(e):NaN}normalize(){if(!this.isValid)return this;const e=this.toObject();return Nn(this.matrix,e),U(this,{values:e},!0)}rescale(){if(!this.isValid)return this;const e=bn(this.normalize().shiftToAll().toObject());return U(this,{values:e},!0)}shiftTo(...e){if(!this.isValid)return this;if(e.length===0)return this;e=e.map(a=>p.normalizeUnit(a));const t={},n={},r=this.toObject();let i;for(const a of B)if(e.indexOf(a)>=0){i=a;let o=0;for(const l in n)o+=this.matrix[l][a]*n[l],n[l]=0;z(r[a])&&(o+=r[a]);const u=Math.trunc(o);t[a]=u,n[a]=(o*1e3-u*1e3)/1e3}else z(r[a])&&(n[a]=r[a]);for(const a in n)n[a]!==0&&(t[i]+=a===i?n[a]:n[a]/this.matrix[i][a]);return Nn(this.matrix,t),U(this,{values:t},!0)}shiftToAll(){return this.isValid?this.shiftTo("years","months","weeks","days","hours","minutes","seconds","milliseconds"):this}negate(){if(!this.isValid)return this;const e={};for(const t of Object.keys(this.values))e[t]=this.values[t]===0?0:-this.values[t];return U(this,{values:e},!0)}removeZeros(){if(!this.isValid)return this;const e=bn(this.values);return U(this,{values:e},!0)}get years(){return this.isValid?this.values.years||0:NaN}get quarters(){return this.isValid?this.values.quarters||0:NaN}get months(){return this.isValid?this.values.months||0:NaN}get weeks(){return this.isValid?this.values.weeks||0:NaN}get days(){return this.isValid?this.values.days||0:NaN}get hours(){return this.isValid?this.values.hours||0:NaN}get minutes(){return this.isValid?this.values.minutes||0:NaN}get seconds(){return this.isValid?this.values.seconds||0:NaN}get milliseconds(){return this.isValid?this.values.milliseconds||0:NaN}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}equals(e){if(!this.isValid||!e.isValid||!this.loc.equals(e.loc))return!1;function t(n,r){return n===void 0||n===0?r===void 0||r===0:n===r}for(const n of B)if(!t(this.values[n],e.values[n]))return!1;return!0}}const se="Invalid Interval";function Er(s,e){return!s||!s.isValid?x.invalid("missing or invalid start"):!e||!e.isValid?x.invalid("missing or invalid end"):ee:!1}isBefore(e){return this.isValid?this.e<=e:!1}contains(e){return this.isValid?this.s<=e&&this.e>e:!1}set({start:e,end:t}={}){return this.isValid?x.fromDateTimes(e||this.s,t||this.e):this}splitAt(...e){if(!this.isValid)return[];const t=e.map(ye).filter(a=>this.contains(a)).sort((a,o)=>a.toMillis()-o.toMillis()),n=[];let{s:r}=this,i=0;for(;r+this.e?this.e:a;n.push(x.fromDateTimes(r,o)),r=o,i+=1}return n}splitBy(e){const t=p.fromDurationLike(e);if(!this.isValid||!t.isValid||t.as("milliseconds")===0)return[];let{s:n}=this,r=1,i;const a=[];for(;nu*r));i=+o>+this.e?this.e:o,a.push(x.fromDateTimes(n,i)),n=i,r+=1}return a}divideEqually(e){return this.isValid?this.splitBy(this.length()/e).slice(0,e):[]}overlaps(e){return this.e>e.s&&this.s=e.e:!1}equals(e){return!this.isValid||!e.isValid?!1:this.s.equals(e.s)&&this.e.equals(e.e)}intersection(e){if(!this.isValid)return this;const t=this.s>e.s?this.s:e.s,n=this.e=n?null:x.fromDateTimes(t,n)}union(e){if(!this.isValid)return this;const t=this.se.e?this.e:e.e;return x.fromDateTimes(t,n)}static merge(e){const[t,n]=e.sort((r,i)=>r.s-i.s).reduce(([r,i],a)=>i?i.overlaps(a)||i.abutsStart(a)?[r,i.union(a)]:[r.concat([i]),a]:[r,a],[[],null]);return n&&t.push(n),t}static xor(e){let t=null,n=0;const r=[],i=e.map(u=>[{time:u.s,type:"s"},{time:u.e,type:"e"}]),a=Array.prototype.concat(...i),o=a.sort((u,l)=>u.time-l.time);for(const u of o)n+=u.type==="s"?1:-1,n===1?t=u.time:(t&&+t!=+u.time&&r.push(x.fromDateTimes(t,u.time)),t=null);return x.merge(r)}difference(...e){return x.xor([this].concat(e)).map(t=>this.intersection(t)).filter(t=>t&&!t.isEmpty())}toString(){return this.isValid?`[${this.s.toISO()} – ${this.e.toISO()})`:se}[Symbol.for("nodejs.util.inspect.custom")](){return this.isValid?`Interval { start: ${this.s.toISO()}, end: ${this.e.toISO()} }`:`Interval { Invalid, reason: ${this.invalidReason} }`}toLocaleString(e=Se,t={}){return this.isValid?v.create(this.s.loc.clone(t),e).formatInterval(this):se}toISO(e){return this.isValid?`${this.s.toISO(e)}/${this.e.toISO(e)}`:se}toISODate(){return this.isValid?`${this.s.toISODate()}/${this.e.toISODate()}`:se}toISOTime(e){return this.isValid?`${this.s.toISOTime(e)}/${this.e.toISOTime(e)}`:se}toFormat(e,{separator:t=" – "}={}){return this.isValid?`${this.s.toFormat(e)}${t}${this.e.toFormat(e)}`:se}toDuration(e,t){return this.isValid?this.e.diff(this.s,e,t):p.invalid(this.invalidReason)}mapEndpoints(e){return x.fromDateTimes(e(this.s),e(this.e))}}class Ie{static hasDST(e=O.defaultZone){const t=y.now().setZone(e).set({month:12});return!e.isUniversal&&t.offset!==t.set({month:6}).offset}static isValidIANAZone(e){return $.isValidZone(e)}static normalizeZone(e){return q(e,O.defaultZone)}static getStartOfWeek({locale:e=null,locObj:t=null}={}){return(t||k.create(e)).getStartOfWeek()}static getMinimumDaysInFirstWeek({locale:e=null,locObj:t=null}={}){return(t||k.create(e)).getMinDaysInFirstWeek()}static getWeekendWeekdays({locale:e=null,locObj:t=null}={}){return(t||k.create(e)).getWeekendDays().slice()}static months(e="long",{locale:t=null,numberingSystem:n=null,locObj:r=null,outputCalendar:i="gregory"}={}){return(r||k.create(t,n,i)).months(e)}static monthsFormat(e="long",{locale:t=null,numberingSystem:n=null,locObj:r=null,outputCalendar:i="gregory"}={}){return(r||k.create(t,n,i)).months(e,!0)}static weekdays(e="long",{locale:t=null,numberingSystem:n=null,locObj:r=null}={}){return(r||k.create(t,n,null)).weekdays(e)}static weekdaysFormat(e="long",{locale:t=null,numberingSystem:n=null,locObj:r=null}={}){return(r||k.create(t,n,null)).weekdays(e,!0)}static meridiems({locale:e=null}={}){return k.create(e).meridiems()}static eras(e="short",{locale:t=null}={}){return k.create(t,null,"gregory").eras(e)}static features(){return{relative:en(),localeWeek:tn()}}}function vn(s,e){const t=r=>r.toUTC(0,{keepLocalTime:!0}).startOf("day").valueOf(),n=t(e)-t(s);return Math.floor(p.fromMillis(n).as("days"))}function Nr(s,e,t){const n=[["years",(u,l)=>l.year-u.year],["quarters",(u,l)=>l.quarter-u.quarter+(l.year-u.year)*4],["months",(u,l)=>l.month-u.month+(l.year-u.year)*12],["weeks",(u,l)=>{const f=vn(u,l);return(f-f%7)/7}],["days",vn]],r={},i=s;let a,o;for(const[u,l]of n)t.indexOf(u)>=0&&(a=u,r[u]=l(s,e),o=i.plus(r),o>e?(r[u]--,s=i.plus(r),s>e&&(o=s,r[u]--,s=i.plus(r))):s=o);return[s,r,o,a]}function br(s,e,t,n){let[r,i,a,o]=Nr(s,e,t);const u=e-r,l=t.filter(h=>["hours","minutes","seconds","milliseconds"].indexOf(h)>=0);l.length===0&&(a0?p.fromMillis(u,n).shiftTo(...l).plus(f):f}const vr="missing Intl.DateTimeFormat.formatToParts support";function S(s,e=t=>t){return{regex:s,deser:([t])=>e(ps(t))}}const Mn="[  ]",In=new RegExp(Mn,"g");function Mr(s){return s.replace(/\./g,"\\.?").replace(In,Mn)}function Dn(s){return s.replace(/\./g,"").replace(In," ").toLowerCase()}function R(s,e){return s===null?null:{regex:RegExp(s.map(Mr).join("|")),deser:([t])=>s.findIndex(n=>Dn(t)===Dn(n))+e}}function Fn(s,e){return{regex:s,deser:([,t,n])=>be(t,n),groups:e}}function De(s){return{regex:s,deser:([e])=>e}}function Ir(s){return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function Dr(s,e){const t=W(e),n=W(e,"{2}"),r=W(e,"{3}"),i=W(e,"{4}"),a=W(e,"{6}"),o=W(e,"{1,2}"),u=W(e,"{1,3}"),l=W(e,"{1,6}"),f=W(e,"{1,9}"),h=W(e,"{2,4}"),w=W(e,"{4,6}"),m=D=>({regex:RegExp(Ir(D.val)),deser:([ie])=>ie,literal:!0}),N=(D=>{if(s.literal)return m(D);switch(D.val){case"G":return R(e.eras("short"),0);case"GG":return R(e.eras("long"),0);case"y":return S(l);case"yy":return S(h,et);case"yyyy":return S(i);case"yyyyy":return S(w);case"yyyyyy":return S(a);case"M":return S(o);case"MM":return S(n);case"MMM":return R(e.months("short",!0),1);case"MMMM":return R(e.months("long",!0),1);case"L":return S(o);case"LL":return S(n);case"LLL":return R(e.months("short",!1),1);case"LLLL":return R(e.months("long",!1),1);case"d":return S(o);case"dd":return S(n);case"o":return S(u);case"ooo":return S(r);case"HH":return S(n);case"H":return S(o);case"hh":return S(n);case"h":return S(o);case"mm":return S(n);case"m":return S(o);case"q":return S(o);case"qq":return S(n);case"s":return S(o);case"ss":return S(n);case"S":return S(u);case"SSS":return S(r);case"u":return De(f);case"uu":return De(o);case"uuu":return S(t);case"a":return R(e.meridiems(),0);case"kkkk":return S(i);case"kk":return S(h,et);case"W":return S(o);case"WW":return S(n);case"E":case"c":return S(t);case"EEE":return R(e.weekdays("short",!1),1);case"EEEE":return R(e.weekdays("long",!1),1);case"ccc":return R(e.weekdays("short",!0),1);case"cccc":return R(e.weekdays("long",!0),1);case"Z":case"ZZ":return Fn(new RegExp(`([+-]${o.source})(?::(${n.source}))?`),2);case"ZZZ":return Fn(new RegExp(`([+-]${o.source})(${n.source})?`),2);case"z":return De(/[a-z_+-/]{1,256}?/i);case" ":return De(/[^\S\n\r]/);default:return m(D)}})(s)||{invalidReason:vr};return N.token=s,N}const Fr={year:{"2-digit":"yy",numeric:"yyyyy"},month:{numeric:"M","2-digit":"MM",short:"MMM",long:"MMMM"},day:{numeric:"d","2-digit":"dd"},weekday:{short:"EEE",long:"EEEE"},dayperiod:"a",dayPeriod:"a",hour12:{numeric:"h","2-digit":"hh"},hour24:{numeric:"H","2-digit":"HH"},minute:{numeric:"m","2-digit":"mm"},second:{numeric:"s","2-digit":"ss"},timeZoneName:{long:"ZZZZZ",short:"ZZZ"}};function Vr(s,e,t){const{type:n,value:r}=s;if(n==="literal"){const u=/^\s+$/.test(r);return{literal:!u,val:u?" ":r}}const i=e[n];let a=n;n==="hour"&&(e.hour12!=null?a=e.hour12?"hour12":"hour24":e.hourCycle!=null?e.hourCycle==="h11"||e.hourCycle==="h12"?a="hour12":a="hour24":a=t.hour12?"hour12":"hour24");let o=Fr[a];if(typeof o=="object"&&(o=o[i]),o)return{literal:!1,val:o}}function Ar(s){return[`^${s.map(t=>t.regex).reduce((t,n)=>`${t}(${n.source})`,"")}$`,s]}function Cr(s,e,t){const n=s.match(e);if(n){const r={};let i=1;for(const a in t)if(K(t,a)){const o=t[a],u=o.groups?o.groups+1:1;!o.literal&&o.token&&(r[o.token.val[0]]=o.deser(n.slice(i,i+u))),i+=u}return[n,r]}else return[n,{}]}function Wr(s){const e=i=>{switch(i){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":case"H":return"hour";case"d":return"day";case"o":return"ordinal";case"L":case"M":return"month";case"y":return"year";case"E":case"c":return"weekday";case"W":return"weekNumber";case"k":return"weekYear";case"q":return"quarter";default:return null}};let t=null,n;return g(s.z)||(t=$.create(s.z)),g(s.Z)||(t||(t=new M(s.Z)),n=s.Z),g(s.q)||(s.M=(s.q-1)*3+1),g(s.h)||(s.h<12&&s.a===1?s.h+=12:s.h===12&&s.a===0&&(s.h=0)),s.G===0&&s.y&&(s.y=-s.y),g(s.u)||(s.S=_e(s.u)),[Object.keys(s).reduce((i,a)=>{const o=e(a);return o&&(i[o]=s[a]),i},{}),t,n]}let rt=null;function Lr(){return rt||(rt=y.fromMillis(1555555555555)),rt}function Rr(s,e){if(s.literal)return s;const t=v.macroTokenToFormatOpts(s.val),n=Wn(t,e);return n==null||n.includes(void 0)?s:n}function Vn(s,e){return Array.prototype.concat(...s.map(t=>Rr(t,e)))}class An{constructor(e,t){if(this.locale=e,this.format=t,this.tokens=Vn(v.parseFormat(t),e),this.units=this.tokens.map(n=>Dr(n,e)),this.disqualifyingUnit=this.units.find(n=>n.invalidReason),!this.disqualifyingUnit){const[n,r]=Ar(this.units);this.regex=RegExp(n,"i"),this.handlers=r}}explainFromTokens(e){if(this.isValid){const[t,n]=Cr(e,this.regex,this.handlers),[r,i,a]=n?Wr(n):[null,null,void 0];if(K(n,"a")&&K(n,"H"))throw new G("Can't include meridiem when specifying 24-hour format");return{input:e,tokens:this.tokens,regex:this.regex,rawMatches:t,matches:n,result:r,zone:i,specificOffset:a}}else return{input:e,tokens:this.tokens,invalidReason:this.invalidReason}}get isValid(){return!this.disqualifyingUnit}get invalidReason(){return this.disqualifyingUnit?this.disqualifyingUnit.invalidReason:null}}function Cn(s,e,t){return new An(s,t).explainFromTokens(e)}function $r(s,e,t){const{result:n,zone:r,specificOffset:i,invalidReason:a}=Cn(s,e,t);return[n,r,i,a]}function Wn(s,e){if(!s)return null;const n=v.create(e,s).dtFormatter(Lr()),r=n.formatToParts(),i=n.resolvedOptions();return r.map(a=>Vr(a,s,i))}const it="Invalid DateTime",Ln=864e13;function he(s){return new L("unsupported zone",`the zone "${s.name}" is not supported`)}function at(s){return s.weekData===null&&(s.weekData=Oe(s.c)),s.weekData}function ot(s){return s.localWeekData===null&&(s.localWeekData=Oe(s.c,s.loc.getMinDaysInFirstWeek(),s.loc.getStartOfWeek())),s.localWeekData}function j(s,e){const t={ts:s.ts,zone:s.zone,c:s.c,o:s.o,loc:s.loc,invalid:s.invalid};return new y({...t,...e,old:t})}function Rn(s,e,t){let n=s-e*60*1e3;const r=t.offset(n);if(e===r)return[n,e];n-=(r-e)*60*1e3;const i=t.offset(n);return r===i?[n,r]:[s-Math.min(r,i)*60*1e3,Math.max(r,i)]}function Fe(s,e){s+=e*60*1e3;const t=new Date(s);return{year:t.getUTCFullYear(),month:t.getUTCMonth()+1,day:t.getUTCDate(),hour:t.getUTCHours(),minute:t.getUTCMinutes(),second:t.getUTCSeconds(),millisecond:t.getUTCMilliseconds()}}function Ve(s,e,t){return Rn(Ne(s),e,t)}function $n(s,e){const t=s.o,n=s.c.year+Math.trunc(e.years),r=s.c.month+Math.trunc(e.months)+Math.trunc(e.quarters)*3,i={...s.c,year:n,month:r,day:Math.min(s.c.day,Ee(n,r))+Math.trunc(e.days)+Math.trunc(e.weeks)*7},a=p.fromObject({years:e.years-Math.trunc(e.years),quarters:e.quarters-Math.trunc(e.quarters),months:e.months-Math.trunc(e.months),weeks:e.weeks-Math.trunc(e.weeks),days:e.days-Math.trunc(e.days),hours:e.hours,minutes:e.minutes,seconds:e.seconds,milliseconds:e.milliseconds}).as("milliseconds"),o=Ne(i);let[u,l]=Rn(o,t,s.zone);return a!==0&&(u+=a,l=s.zone.offset(u)),{ts:u,o:l}}function re(s,e,t,n,r,i){const{setZone:a,zone:o}=t;if(s&&Object.keys(s).length!==0||e){const u=e||o,l=y.fromObject(s,{...t,zone:u,specificOffset:i});return a?l:l.setZone(o)}else return y.invalid(new L("unparsable",`the input "${r}" can't be parsed as ${n}`))}function Ae(s,e,t=!0){return s.isValid?v.create(k.create("en-US"),{allowZ:t,forceSimple:!0}).formatDateTimeFromString(s,e):null}function ut(s,e,t){const n=s.c.year>9999||s.c.year<0;let r="";if(n&&s.c.year>=0&&(r+="+"),r+=E(s.c.year,n?6:4),t==="year")return r;if(e){if(r+="-",r+=E(s.c.month),t==="month")return r;r+="-"}else if(r+=E(s.c.month),t==="month")return r;return r+=E(s.c.day),r}function Un(s,e,t,n,r,i,a){let o=!t||s.c.millisecond!==0||s.c.second!==0,u="";switch(a){case"day":case"month":case"year":break;default:if(u+=E(s.c.hour),a==="hour")break;if(e){if(u+=":",u+=E(s.c.minute),a==="minute")break;o&&(u+=":",u+=E(s.c.second))}else{if(u+=E(s.c.minute),a==="minute")break;o&&(u+=E(s.c.second))}if(a==="second")break;o&&(!n||s.c.millisecond!==0)&&(u+=".",u+=E(s.c.millisecond,3))}return r&&(s.isOffsetFixed&&s.offset===0&&!i?u+="Z":s.o<0?(u+="-",u+=E(Math.trunc(-s.o/60)),u+=":",u+=E(Math.trunc(-s.o%60))):(u+="+",u+=E(Math.trunc(s.o/60)),u+=":",u+=E(Math.trunc(s.o%60)))),i&&(u+="["+s.zone.ianaName+"]"),u}const Zn={month:1,day:1,hour:0,minute:0,second:0,millisecond:0},Ur={weekNumber:1,weekday:1,hour:0,minute:0,second:0,millisecond:0},Zr={ordinal:1,hour:0,minute:0,second:0,millisecond:0},Ce=["year","month","day","hour","minute","second","millisecond"],qr=["weekYear","weekNumber","weekday","hour","minute","second","millisecond"],zr=["year","ordinal","hour","minute","second","millisecond"];function We(s){const e={year:"year",years:"year",month:"month",months:"month",day:"day",days:"day",hour:"hour",hours:"hour",minute:"minute",minutes:"minute",quarter:"quarter",quarters:"quarter",second:"second",seconds:"second",millisecond:"millisecond",milliseconds:"millisecond",weekday:"weekday",weekdays:"weekday",weeknumber:"weekNumber",weeksnumber:"weekNumber",weeknumbers:"weekNumber",weekyear:"weekYear",weekyears:"weekYear",ordinal:"ordinal"}[s.toLowerCase()];if(!e)throw new ht(s);return e}function qn(s){switch(s.toLowerCase()){case"localweekday":case"localweekdays":return"localWeekday";case"localweeknumber":case"localweeknumbers":return"localWeekNumber";case"localweekyear":case"localweekyears":return"localWeekYear";default:return We(s)}}function Pr(s){if(me===void 0&&(me=O.now()),s.type!=="iana")return s.offset(me);const e=s.name;let t=lt.get(e);return t===void 0&&(t=s.offset(me),lt.set(e,t)),t}function zn(s,e){const t=q(e.zone,O.defaultZone);if(!t.isValid)return y.invalid(he(t));const n=k.fromObject(e);let r,i;if(g(s.year))r=O.now();else{for(const u of Ce)g(s[u])&&(s[u]=Zn[u]);const a=_t(s)||Xt(s);if(a)return y.invalid(a);const o=Pr(t);[r,i]=Ve(s,o,t)}return new y({ts:r,zone:t,loc:n,o:i})}function Pn(s,e,t){const n=g(t.round)?!0:t.round,r=g(t.rounding)?"trunc":t.rounding,i=(o,u)=>(o=Xe(o,n||t.calendary?0:2,t.calendary?"round":r),e.loc.clone(t).relFormatter(t).format(o,u)),a=o=>t.calendary?e.hasSame(s,o)?0:e.startOf(o).diff(s.startOf(o),o).get(o):e.diff(s,o).get(o);if(t.unit)return i(a(t.unit),t.unit);for(const o of t.units){const u=a(o);if(Math.abs(u)>=1)return i(u,o)}return i(s>e?-0:0,t.units[t.units.length-1])}function Yn(s){let e={},t;return s.length>0&&typeof s[s.length-1]=="object"?(e=s[s.length-1],t=Array.from(s).slice(0,s.length-1)):t=Array.from(s),[e,t]}let me;const lt=new Map;class y{constructor(e){const t=e.zone||O.defaultZone;let n=e.invalid||(Number.isNaN(e.ts)?new L("invalid input"):null)||(t.isValid?null:he(t));this.ts=g(e.ts)?O.now():e.ts;let r=null,i=null;if(!n)if(e.old&&e.old.ts===this.ts&&e.old.zone.equals(t))[r,i]=[e.old.c,e.old.o];else{const o=z(e.o)&&!e.old?e.o:t.offset(this.ts);r=Fe(this.ts,o),n=Number.isNaN(r.year)?new L("invalid input"):null,r=n?null:r,i=n?null:o}this._zone=t,this.loc=e.loc||k.create(),this.invalid=n,this.weekData=null,this.localWeekData=null,this.c=r,this.o=i,this.isLuxonDateTime=!0}static now(){return new y({})}static local(){const[e,t]=Yn(arguments),[n,r,i,a,o,u,l]=t;return zn({year:n,month:r,day:i,hour:a,minute:o,second:u,millisecond:l},e)}static utc(){const[e,t]=Yn(arguments),[n,r,i,a,o,u,l]=t;return e.zone=M.utcInstance,zn({year:n,month:r,day:i,hour:a,minute:o,second:u,millisecond:l},e)}static fromJSDate(e,t={}){const n=Os(e)?e.valueOf():NaN;if(Number.isNaN(n))return y.invalid("invalid input");const r=q(t.zone,O.defaultZone);return r.isValid?new y({ts:n,zone:r,loc:k.fromObject(t)}):y.invalid(he(r))}static fromMillis(e,t={}){if(z(e))return e<-Ln||e>Ln?y.invalid("Timestamp out of range"):new y({ts:e,zone:q(t.zone,O.defaultZone),loc:k.fromObject(t)});throw new b(`fromMillis requires a numerical input, but received a ${typeof e} with value ${e}`)}static fromSeconds(e,t={}){if(z(e))return new y({ts:e*1e3,zone:q(t.zone,O.defaultZone),loc:k.fromObject(t)});throw new b("fromSeconds requires a numerical input")}static fromObject(e,t={}){e=e||{};const n=q(t.zone,O.defaultZone);if(!n.isValid)return y.invalid(he(n));const r=k.fromObject(t),i=ve(e,qn),{minDaysInFirstWeek:a,startOfWeek:o}=Qt(i,r),u=O.now(),l=g(t.specificOffset)?n.offset(u):t.specificOffset,f=!g(i.ordinal),h=!g(i.year),w=!g(i.month)||!g(i.day),m=h||w,T=i.weekYear||i.weekNumber;if((m||f)&&T)throw new G("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(w&&f)throw new G("Can't mix ordinal dates with month/day");const N=T||i.weekday&&!m;let D,ie,ge=Fe(u,l);N?(D=qr,ie=Ur,ge=Oe(ge,a,o)):f?(D=zr,ie=Zr,ge=He(ge)):(D=Ce,ie=Zn);let Jn=!1;for(const we of D){const ei=i[we];g(ei)?Jn?i[we]=ie[we]:i[we]=ge[we]:Jn=!0}const Hr=N?Ss(i,a,o):f?ks(i):_t(i),Bn=Hr||Xt(i);if(Bn)return y.invalid(Bn);const Qr=N?Kt(i,a,o):f?Ht(i):i,[_r,Xr]=Ve(Qr,l,n),pe=new y({ts:_r,zone:n,o:Xr,loc:r});return i.weekday&&m&&e.weekday!==pe.weekday?y.invalid("mismatched weekday",`you can't specify both a weekday of ${i.weekday} and a date of ${pe.toISO()}`):pe.isValid?pe:y.invalid(pe.invalid)}static fromISO(e,t={}){const[n,r]=fr(e);return re(n,r,t,"ISO 8601",e)}static fromRFC2822(e,t={}){const[n,r]=dr(e);return re(n,r,t,"RFC 2822",e)}static fromHTTP(e,t={}){const[n,r]=hr(e);return re(n,r,t,"HTTP",t)}static fromFormat(e,t,n={}){if(g(e)||g(t))throw new b("fromFormat requires an input string and a format");const{locale:r=null,numberingSystem:i=null}=n,a=k.fromOpts({locale:r,numberingSystem:i,defaultToEN:!0}),[o,u,l,f]=$r(a,e,t);return f?y.invalid(f):re(o,u,n,`format ${t}`,e,l)}static fromString(e,t,n={}){return y.fromFormat(e,t,n)}static fromSQL(e,t={}){const[n,r]=kr(e);return re(n,r,t,"SQL",e)}static invalid(e,t=null){if(!e)throw new b("need to specify a reason the DateTime is invalid");const n=e instanceof L?e:new L(e,t);if(O.throwOnInvalid)throw new jn(n);return new y({invalid:n})}static isDateTime(e){return e&&e.isLuxonDateTime||!1}static parseFormatForOpts(e,t={}){const n=Wn(e,k.fromObject(t));return n?n.map(r=>r?r.val:null).join(""):null}static expandFormat(e,t={}){return Vn(v.parseFormat(e),k.fromObject(t)).map(r=>r.val).join("")}static resetCache(){me=void 0,lt.clear()}get(e){return this[e]}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}get outputCalendar(){return this.isValid?this.loc.outputCalendar:null}get zone(){return this._zone}get zoneName(){return this.isValid?this.zone.name:null}get year(){return this.isValid?this.c.year:NaN}get quarter(){return this.isValid?Math.ceil(this.c.month/3):NaN}get month(){return this.isValid?this.c.month:NaN}get day(){return this.isValid?this.c.day:NaN}get hour(){return this.isValid?this.c.hour:NaN}get minute(){return this.isValid?this.c.minute:NaN}get second(){return this.isValid?this.c.second:NaN}get millisecond(){return this.isValid?this.c.millisecond:NaN}get weekYear(){return this.isValid?at(this).weekYear:NaN}get weekNumber(){return this.isValid?at(this).weekNumber:NaN}get weekday(){return this.isValid?at(this).weekday:NaN}get isWeekend(){return this.isValid&&this.loc.getWeekendDays().includes(this.weekday)}get localWeekday(){return this.isValid?ot(this).weekday:NaN}get localWeekNumber(){return this.isValid?ot(this).weekNumber:NaN}get localWeekYear(){return this.isValid?ot(this).weekYear:NaN}get ordinal(){return this.isValid?He(this.c).ordinal:NaN}get monthShort(){return this.isValid?Ie.months("short",{locObj:this.loc})[this.month-1]:null}get monthLong(){return this.isValid?Ie.months("long",{locObj:this.loc})[this.month-1]:null}get weekdayShort(){return this.isValid?Ie.weekdays("short",{locObj:this.loc})[this.weekday-1]:null}get weekdayLong(){return this.isValid?Ie.weekdays("long",{locObj:this.loc})[this.weekday-1]:null}get offset(){return this.isValid?+this.o:NaN}get offsetNameShort(){return this.isValid?this.zone.offsetName(this.ts,{format:"short",locale:this.locale}):null}get offsetNameLong(){return this.isValid?this.zone.offsetName(this.ts,{format:"long",locale:this.locale}):null}get isOffsetFixed(){return this.isValid?this.zone.isUniversal:null}get isInDST(){return this.isOffsetFixed?!1:this.offset>this.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset}getPossibleOffsets(){if(!this.isValid||this.isOffsetFixed)return[this];const e=864e5,t=6e4,n=Ne(this.c),r=this.zone.offset(n-e),i=this.zone.offset(n+e),a=this.zone.offset(n-r*t),o=this.zone.offset(n-i*t);if(a===o)return[this];const u=n-a*t,l=n-o*t,f=Fe(u,a),h=Fe(l,o);return f.hour===h.hour&&f.minute===h.minute&&f.second===h.second&&f.millisecond===h.millisecond?[j(this,{ts:u}),j(this,{ts:l})]:[this]}get isInLeapYear(){return ue(this.year)}get daysInMonth(){return Ee(this.year,this.month)}get daysInYear(){return this.isValid?H(this.year):NaN}get weeksInWeekYear(){return this.isValid?le(this.weekYear):NaN}get weeksInLocalWeekYear(){return this.isValid?le(this.localWeekYear,this.loc.getMinDaysInFirstWeek(),this.loc.getStartOfWeek()):NaN}resolvedLocaleOptions(e={}){const{locale:t,numberingSystem:n,calendar:r}=v.create(this.loc.clone(e),e).resolvedOptions(this);return{locale:t,numberingSystem:n,outputCalendar:r}}toUTC(e=0,t={}){return this.setZone(M.instance(e),t)}toLocal(){return this.setZone(O.defaultZone)}setZone(e,{keepLocalTime:t=!1,keepCalendarTime:n=!1}={}){if(e=q(e,O.defaultZone),e.equals(this.zone))return this;if(e.isValid){let r=this.ts;if(t||n){const i=e.offset(this.ts),a=this.toObject();[r]=Ve(a,i,e)}return j(this,{ts:r,zone:e})}else return y.invalid(he(e))}reconfigure({locale:e,numberingSystem:t,outputCalendar:n}={}){const r=this.loc.clone({locale:e,numberingSystem:t,outputCalendar:n});return j(this,{loc:r})}setLocale(e){return this.reconfigure({locale:e})}set(e){if(!this.isValid)return this;const t=ve(e,qn),{minDaysInFirstWeek:n,startOfWeek:r}=Qt(t,this.loc),i=!g(t.weekYear)||!g(t.weekNumber)||!g(t.weekday),a=!g(t.ordinal),o=!g(t.year),u=!g(t.month)||!g(t.day),l=o||u,f=t.weekYear||t.weekNumber;if((l||a)&&f)throw new G("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(u&&a)throw new G("Can't mix ordinal dates with month/day");let h;i?h=Kt({...Oe(this.c,n,r),...t},n,r):g(t.ordinal)?(h={...this.toObject(),...t},g(t.day)&&(h.day=Math.min(Ee(h.year,h.month),h.day))):h=Ht({...He(this.c),...t});const[w,m]=Ve(h,this.o,this.zone);return j(this,{ts:w,o:m})}plus(e){if(!this.isValid)return this;const t=p.fromDurationLike(e);return j(this,$n(this,t))}minus(e){if(!this.isValid)return this;const t=p.fromDurationLike(e).negate();return j(this,$n(this,t))}startOf(e,{useLocaleWeeks:t=!1}={}){if(!this.isValid)return this;const n={},r=p.normalizeUnit(e);switch(r){case"years":n.month=1;case"quarters":case"months":n.day=1;case"weeks":case"days":n.hour=0;case"hours":n.minute=0;case"minutes":n.second=0;case"seconds":n.millisecond=0;break}if(r==="weeks")if(t){const i=this.loc.getStartOfWeek(),{weekday:a}=this;a=3&&(u+="T"),u+=Un(this,o,t,n,r,i,a),u}toISODate({format:e="extended",precision:t="day"}={}){return this.isValid?ut(this,e==="extended",We(t)):null}toISOWeekDate(){return Ae(this,"kkkk-'W'WW-c")}toISOTime({suppressMilliseconds:e=!1,suppressSeconds:t=!1,includeOffset:n=!0,includePrefix:r=!1,extendedZone:i=!1,format:a="extended",precision:o="milliseconds"}={}){return this.isValid?(o=We(o),(r&&Ce.indexOf(o)>=3?"T":"")+Un(this,a==="extended",t,e,n,i,o)):null}toRFC2822(){return Ae(this,"EEE, dd LLL yyyy HH:mm:ss ZZZ",!1)}toHTTP(){return Ae(this.toUTC(),"EEE, dd LLL yyyy HH:mm:ss 'GMT'")}toSQLDate(){return this.isValid?ut(this,!0):null}toSQLTime({includeOffset:e=!0,includeZone:t=!1,includeOffsetSpace:n=!0}={}){let r="HH:mm:ss.SSS";return(t||e)&&(n&&(r+=" "),t?r+="z":e&&(r+="ZZ")),Ae(this,r,!0)}toSQL(e={}){return this.isValid?`${this.toSQLDate()} ${this.toSQLTime(e)}`:null}toString(){return this.isValid?this.toISO():it}[Symbol.for("nodejs.util.inspect.custom")](){return this.isValid?`DateTime { ts: ${this.toISO()}, zone: ${this.zone.name}, locale: ${this.locale} }`:`DateTime { Invalid, reason: ${this.invalidReason} }`}valueOf(){return this.toMillis()}toMillis(){return this.isValid?this.ts:NaN}toSeconds(){return this.isValid?this.ts/1e3:NaN}toUnixInteger(){return this.isValid?Math.floor(this.ts/1e3):NaN}toJSON(){return this.toISO()}toBSON(){return this.toJSDate()}toObject(e={}){if(!this.isValid)return{};const t={...this.c};return e.includeConfig&&(t.outputCalendar=this.outputCalendar,t.numberingSystem=this.loc.numberingSystem,t.locale=this.loc.locale),t}toJSDate(){return new Date(this.isValid?this.ts:NaN)}diff(e,t="milliseconds",n={}){if(!this.isValid||!e.isValid)return p.invalid("created by diffing an invalid DateTime");const r={locale:this.locale,numberingSystem:this.numberingSystem,...n},i=xs(t).map(p.normalizeUnit),a=e.valueOf()>this.valueOf(),o=a?this:e,u=a?e:this,l=br(o,u,i,r);return a?l.negate():l}diffNow(e="milliseconds",t={}){return this.diff(y.now(),e,t)}until(e){return this.isValid?x.fromDateTimes(this,e):this}hasSame(e,t,n){if(!this.isValid)return!1;const r=e.valueOf(),i=this.setZone(e.zone,{keepLocalTime:!0});return i.startOf(t,n)<=r&&r<=i.endOf(t,n)}equals(e){return this.isValid&&e.isValid&&this.valueOf()===e.valueOf()&&this.zone.equals(e.zone)&&this.loc.equals(e.loc)}toRelative(e={}){if(!this.isValid)return null;const t=e.base||y.fromObject({},{zone:this.zone}),n=e.padding?thist.valueOf(),Math.min)}static max(...e){if(!e.every(y.isDateTime))throw new b("max requires all arguments be DateTimes");return nn(e,t=>t.valueOf(),Math.max)}static fromFormatExplain(e,t,n={}){const{locale:r=null,numberingSystem:i=null}=n,a=k.fromOpts({locale:r,numberingSystem:i,defaultToEN:!0});return Cn(a,e,t)}static fromStringExplain(e,t,n={}){return y.fromFormatExplain(e,t,n)}static buildFormatParser(e,t={}){const{locale:n=null,numberingSystem:r=null}=t,i=k.fromOpts({locale:n,numberingSystem:r,defaultToEN:!0});return new An(i,e)}static fromFormatParser(e,t,n={}){if(g(e)||g(t))throw new b("fromFormatParser requires an input string and a format parser");const{locale:r=null,numberingSystem:i=null}=n,a=k.fromOpts({locale:r,numberingSystem:i,defaultToEN:!0});if(!a.equals(t.locale))throw new b(`fromFormatParser called with a locale of ${a}, but the format parser was created for ${t.locale}`);const{result:o,zone:u,specificOffset:l,invalidReason:f}=t.explainFromTokens(e);return f?y.invalid(f):re(o,u,n,`format ${t.format}`,e,l)}static get DATE_SHORT(){return Se}static get DATE_MED(){return mt}static get DATE_MED_WITH_WEEKDAY(){return Hn}static get DATE_FULL(){return yt}static get DATE_HUGE(){return gt}static get TIME_SIMPLE(){return pt}static get TIME_WITH_SECONDS(){return wt}static get TIME_WITH_SHORT_OFFSET(){return St}static get TIME_WITH_LONG_OFFSET(){return kt}static get TIME_24_SIMPLE(){return Tt}static get TIME_24_WITH_SECONDS(){return Ot}static get TIME_24_WITH_SHORT_OFFSET(){return xt}static get TIME_24_WITH_LONG_OFFSET(){return Et}static get DATETIME_SHORT(){return Nt}static get DATETIME_SHORT_WITH_SECONDS(){return bt}static get DATETIME_MED(){return vt}static get DATETIME_MED_WITH_SECONDS(){return Mt}static get DATETIME_MED_WITH_WEEKDAY(){return Qn}static get DATETIME_FULL(){return It}static get DATETIME_FULL_WITH_SECONDS(){return Dt}static get DATETIME_HUGE(){return Ft}static get DATETIME_HUGE_WITH_SECONDS(){return Vt}}function ye(s){if(y.isDateTime(s))return s;if(s&&s.valueOf&&z(s.valueOf()))return y.fromJSDate(s);if(s&&typeof s=="object")return y.fromObject(s);throw new b(`Unknown datetime argument: ${s}, of type ${typeof s}`)}const Yr=[".jpg",".jpeg",".png",".svg",".gif",".jfif",".webp",".avif"],Jr=[".mp4",".avi",".mov",".3gp",".wmv"],Br=[".aa",".aac",".m4v",".mp3",".ogg",".oga",".mogg",".amr"],jr=[".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".odp",".odt",".ods",".txt"],Gr=["relation","file","select"],Kr=["text","email","url","editor"];class d{static isObject(e){return e!==null&&typeof e=="object"&&e.constructor===Object}static clone(e){return typeof structuredClone<"u"?structuredClone(e):JSON.parse(JSON.stringify(e))}static zeroValue(e){switch(typeof e){case"string":return"";case"number":return 0;case"boolean":return!1;case"object":return e===null?null:Array.isArray(e)?[]:{};case"undefined":return;default:return null}}static isEmpty(e){return e===""||e===null||typeof e>"u"||Array.isArray(e)&&e.length===0||d.isObject(e)&&Object.keys(e).length===0}static isInput(e){let t=e&&e.tagName?e.tagName.toLowerCase():"";return t==="input"||t==="select"||t==="textarea"||(e==null?void 0:e.isContentEditable)}static isFocusable(e){let t=e&&e.tagName?e.tagName.toLowerCase():"";return d.isInput(e)||t==="button"||t==="a"||t==="details"||(e==null?void 0:e.tabIndex)>=0}static hasNonEmptyProps(e){for(let t in e)if(!d.isEmpty(e[t]))return!0;return!1}static toArray(e,t=!1){return Array.isArray(e)?e.slice():(t||!d.isEmpty(e))&&typeof e<"u"?[e]:[]}static inArray(e,t){e=Array.isArray(e)?e:[];for(let n=e.length-1;n>=0;n--)if(e[n]==t)return!0;return!1}static removeByValue(e,t){e=Array.isArray(e)?e:[];for(let n=e.length-1;n>=0;n--)if(e[n]==t){e.splice(n,1);break}}static pushUnique(e,t){d.inArray(e,t)||e.push(t)}static mergeUnique(e,t){for(let n of t)d.pushUnique(e,n);return e}static findByKey(e,t,n){e=Array.isArray(e)?e:[];for(let r in e)if(e[r][t]==n)return e[r];return null}static groupByKey(e,t){e=Array.isArray(e)?e:[];const n={};for(let r in e)n[e[r][t]]=n[e[r][t]]||[],n[e[r][t]].push(e[r]);return n}static removeByKey(e,t,n){for(let r in e)if(e[r][t]==n){e.splice(r,1);break}}static pushOrReplaceByKey(e,t,n="id"){for(let r=e.length-1;r>=0;r--)if(e[r][n]==t[n]){e[r]=t;return}e.push(t)}static filterDuplicatesByKey(e,t="id"){e=Array.isArray(e)?e:[];const n={};for(const r of e)n[r[t]]=r;return Object.values(n)}static filterRedactedProps(e,t="******"){const n=JSON.parse(JSON.stringify(e||{}));for(let r in n)typeof n[r]=="object"&&n[r]!==null?n[r]=d.filterRedactedProps(n[r],t):n[r]===t&&delete n[r];return n}static getNestedVal(e,t,n=null,r="."){let i=e||{},a=(t||"").split(r);for(const o of a){if(!d.isObject(i)&&!Array.isArray(i)||typeof i[o]>"u")return n;i=i[o]}return i}static setByPath(e,t,n,r="."){if(e===null||typeof e!="object"){console.warn("setByPath: data not an object or array.");return}let i=e,a=t.split(r),o=a.pop();for(const u of a)(!d.isObject(i)&&!Array.isArray(i)||!d.isObject(i[u])&&!Array.isArray(i[u]))&&(i[u]={}),i=i[u];i[o]=n}static deleteByPath(e,t,n="."){let r=e||{},i=(t||"").split(n),a=i.pop();for(const o of i)(!d.isObject(r)&&!Array.isArray(r)||!d.isObject(r[o])&&!Array.isArray(r[o]))&&(r[o]={}),r=r[o];Array.isArray(r)?r.splice(a,1):d.isObject(r)&&delete r[a],i.length>0&&(Array.isArray(r)&&!r.length||d.isObject(r)&&!Object.keys(r).length)&&(Array.isArray(e)&&e.length>0||d.isObject(e)&&Object.keys(e).length>0)&&d.deleteByPath(e,i.join(n),n)}static randomString(e=10){let t="",n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let r=0;r"u")return d.randomString(e);const t=new Uint8Array(e);crypto.getRandomValues(t);const n="-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";let r="";for(let i=0;ii.replaceAll("{_PB_ESCAPED_}",t));for(let i of r)i=i.trim(),d.isEmpty(i)||n.push(i);return n}static joinNonEmpty(e,t=", ",n=!0){e=e||[];const r=[],i=t.length>1?t.trim():t;for(let a of e)a=typeof a=="string"?a.trim():"",!d.isEmpty(a)&&(n&&(a=a.replaceAll(i,"\\"+i)),r.push(a));return r.join(t)}static getInitials(e){if(e=(e||"").split("@")[0].trim(),e.length<=2)return e.toUpperCase();const t=e.split(/[\.\_\-\ ]/);return t.length>=2?(t[0][0]+t[1][0]).toUpperCase():e[0].toUpperCase()}static formattedFileSize(e){const t=e?Math.floor(Math.log(e)/Math.log(1024)):0;return(e/Math.pow(1024,t)).toFixed(2)*1+" "+["B","KB","MB","GB","TB"][t]}static getDateTime(e){if(typeof e=="string"){const t={19:"yyyy-MM-dd HH:mm:ss",23:"yyyy-MM-dd HH:mm:ss.SSS",20:"yyyy-MM-dd HH:mm:ss'Z'",24:"yyyy-MM-dd HH:mm:ss.SSS'Z'"},n=t[e.length]||t[19];return y.fromFormat(e,n,{zone:"UTC"})}return typeof e=="number"?y.fromMillis(e):y.fromJSDate(e)}static formatToUTCDate(e,t="yyyy-MM-dd HH:mm:ss"){return d.getDateTime(e).toUTC().toFormat(t)}static formatToLocalDate(e,t="yyyy-MM-dd HH:mm:ss"){return d.getDateTime(e).toLocal().toFormat(t)}static async copyToClipboard(e){var t;if(typeof e=="object")try{e=JSON.stringify(e,null,2)}catch{}if(e=""+e,!(!e.length||!((t=window==null?void 0:window.navigator)!=null&&t.clipboard)))return window.navigator.clipboard.writeText(e).catch(n=>{console.warn("Failed to copy.",n)})}static download(e,t){const n=document.createElement("a");n.setAttribute("href",e),n.setAttribute("download",t),n.setAttribute("target","_blank"),n.click(),n.remove()}static downloadJson(e,t){t=t.endsWith(".json")?t:t+".json";const n=new Blob([JSON.stringify(e,null,2)],{type:"application/json"}),r=window.URL.createObjectURL(n);d.download(r,t)}static getJWTPayload(e){const t=(e||"").split(".")[1]||"";if(t==="")return{};try{const n=decodeURIComponent(atob(t));return JSON.parse(n)||{}}catch(n){console.warn("Failed to parse JWT payload data.",n)}return{}}static hasImageExtension(e){return e=e||"",!!Yr.find(t=>e.toLowerCase().endsWith(t))}static hasVideoExtension(e){return e=e||"",!!Jr.find(t=>e.toLowerCase().endsWith(t))}static hasAudioExtension(e){return e=e||"",!!Br.find(t=>e.toLowerCase().endsWith(t))}static hasDocumentExtension(e){return e=e||"",!!jr.find(t=>e.toLowerCase().endsWith(t))}static getFileType(e){return d.hasImageExtension(e)?"image":d.hasDocumentExtension(e)?"document":d.hasVideoExtension(e)?"video":d.hasAudioExtension(e)?"audio":"file"}static generateThumb(e,t=100,n=100){return new Promise(r=>{let i=new FileReader;i.onload=function(a){let o=new Image;o.onload=function(){let u=document.createElement("canvas"),l=u.getContext("2d"),f=o.width,h=o.height;return u.width=t,u.height=n,l.drawImage(o,f>h?(f-h)/2:0,0,f>h?h:f,f>h?h:f,0,0,t,n),r(u.toDataURL(e.type))},o.src=a.target.result},i.readAsDataURL(e)})}static addValueToFormData(e,t,n){if(!(typeof n>"u"))if(d.isEmpty(n))e.append(t,"");else if(Array.isArray(n))for(const r of n)d.addValueToFormData(e,t,r);else n instanceof File?e.append(t,n):n instanceof Date?e.append(t,n.toISOString()):d.isObject(n)?e.append(t,JSON.stringify(n)):e.append(t,""+n)}static dummyCollectionRecord(e){return Object.assign({collectionId:e==null?void 0:e.id,collectionName:e==null?void 0:e.name},d.dummyCollectionSchemaData(e))}static dummyCollectionSchemaData(e,t=!1){var i;const n=(e==null?void 0:e.fields)||[],r={};for(const a of n){if(a.hidden||t&&a.primaryKey&&a.autogeneratePattern||t&&a.type==="autodate")continue;let o=null;if(a.type==="number")o=123;else if(a.type==="date"||a.type==="autodate")o="2022-01-01 10:00:00.123Z";else if(a.type=="bool")o=!0;else if(a.type=="email")o="test@example.com";else if(a.type=="url")o="https://example.com";else if(a.type=="json")o="JSON";else if(a.type=="file"){if(t)continue;o="filename.jpg",a.maxSelect!=1&&(o=[o])}else a.type=="select"?(o=(i=a==null?void 0:a.values)==null?void 0:i[0],(a==null?void 0:a.maxSelect)!=1&&(o=[o])):a.type=="relation"?(o="RELATION_RECORD_ID",(a==null?void 0:a.maxSelect)!=1&&(o=[o])):a.type=="geoPoint"?o={lon:0,lat:0}:o="test";r[a.name]=o}return r}static getCollectionTypeIcon(e){switch(e==null?void 0:e.toLowerCase()){case"auth":return"ri-group-line";case"view":return"ri-table-line";default:return"ri-folder-2-line"}}static getFieldTypeIcon(e){switch(e){case"primary":return"ri-key-line";case"text":return"ri-text";case"number":return"ri-hashtag";case"date":return"ri-calendar-line";case"bool":return"ri-toggle-line";case"email":return"ri-mail-line";case"url":return"ri-link";case"editor":return"ri-edit-2-line";case"select":return"ri-list-check";case"json":return"ri-braces-line";case"file":return"ri-image-line";case"relation":return"ri-mind-map";case"password":return"ri-lock-password-line";case"autodate":return"ri-calendar-check-line";case"geoPoint":return"ri-map-pin-2-line";default:return"ri-star-s-line"}}static getFieldValueType(e){switch(e==null?void 0:e.type){case"bool":return"Boolean";case"number":return"Number";case"geoPoint":return"Object";case"file":return"File";case"select":case"relation":return(e==null?void 0:e.maxSelect)==1?"String":"Array";default:return"String"}}static zeroDefaultStr(e){return(e==null?void 0:e.type)==="number"?"0":(e==null?void 0:e.type)==="bool"?"false":(e==null?void 0:e.type)==="geoPoint"?'{"lon":0,"lat":0}':(e==null?void 0:e.type)==="json"?'null, "", [], {}':["select","relation","file"].includes(e==null?void 0:e.type)&&(e==null?void 0:e.maxSelect)!=1?"[]":'""'}static getApiExampleUrl(e){return(window.location.href.substring(0,window.location.href.indexOf("/_"))||e||"/").replace("//localhost","//127.0.0.1")}static hasCollectionChanges(e,t,n=!1){if(e=e||{},t=t||{},e.id!=t.id)return!0;for(let l in e)if(l!=="fields"&&JSON.stringify(e[l])!==JSON.stringify(t[l]))return!0;const r=Array.isArray(e.fields)?e.fields:[],i=Array.isArray(t.fields)?t.fields:[],a=r.filter(l=>(l==null?void 0:l.id)&&!d.findByKey(i,"id",l.id)),o=i.filter(l=>(l==null?void 0:l.id)&&!d.findByKey(r,"id",l.id)),u=i.filter(l=>{const f=d.isObject(l)&&d.findByKey(r,"id",l.id);if(!f)return!1;for(let h in f)if(JSON.stringify(l[h])!=JSON.stringify(f[h]))return!0;return!1});return!!(o.length||u.length||n&&a.length)}static sortCollections(e=[]){const t=[],n=[],r=[];for(const a of e)a.type==="auth"?t.push(a):a.type==="base"?n.push(a):r.push(a);function i(a,o){return a.name>o.name?1:a.namea.id==e.collectionId);if(!i)return r;for(const a of i.fields){if(!a.presentable||a.type!="relation"||n<=0)continue;const o=d.getExpandPresentableRelFields(a,t,n-1);for(const u of o)r.push(e.name+"."+u)}return r.length||r.push(e.name),r}static yieldToMain(){return new Promise(e=>{setTimeout(e,0)})}static defaultFlatpickrOptions(){return{dateFormat:"Y-m-d H:i:S",disableMobile:!0,allowInput:!0,enableTime:!0,enableSeconds:!0,time_24hr:!0,locale:{firstDayOfWeek:1}}}static defaultEditorOptions(){const e=["DIV","P","A","EM","B","STRONG","H1","H2","H3","H4","H5","H6","TABLE","TR","TD","TH","TBODY","THEAD","TFOOT","BR","HR","Q","SUP","SUB","DEL","IMG","OL","UL","LI","CODE"];function t(r){let i=r.parentNode;for(;r.firstChild;)i.insertBefore(r.firstChild,r);i.removeChild(r)}function n(r){if(r){for(const i of r.children)n(i);e.includes(r.tagName)?(r.removeAttribute("style"),r.removeAttribute("class")):t(r)}}return{branding:!1,promotion:!1,menubar:!1,min_height:270,height:270,max_height:700,autoresize_bottom_margin:30,convert_unsafe_embeds:!0,skin:"pocketbase",content_style:"body { font-size: 14px }",plugins:["autoresize","autolink","lists","link","image","searchreplace","fullscreen","media","table","code","codesample","directionality"],codesample_global_prismjs:!0,codesample_languages:[{text:"HTML/XML",value:"markup"},{text:"CSS",value:"css"},{text:"SQL",value:"sql"},{text:"JavaScript",value:"javascript"},{text:"Go",value:"go"},{text:"Dart",value:"dart"},{text:"Zig",value:"zig"},{text:"Rust",value:"rust"},{text:"Lua",value:"lua"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"},{text:"Markdown",value:"markdown"},{text:"Swift",value:"swift"},{text:"Kotlin",value:"kotlin"},{text:"Elixir",value:"elixir"},{text:"Scala",value:"scala"},{text:"Julia",value:"julia"},{text:"Haskell",value:"haskell"}],toolbar:"styles | alignleft aligncenter alignright | bold italic forecolor backcolor | bullist numlist | link image_picker table codesample direction | code fullscreen",paste_postprocess:(r,i)=>{n(i.node)},file_picker_types:"image",file_picker_callback:(r,i,a)=>{const o=document.createElement("input");o.setAttribute("type","file"),o.setAttribute("accept","image/*"),o.addEventListener("change",u=>{const l=u.target.files[0],f=new FileReader;f.addEventListener("load",()=>{if(!tinymce)return;const h="blobid"+new Date().getTime(),w=tinymce.activeEditor.editorUpload.blobCache,m=f.result.split(",")[1],T=w.create(h,l,m);w.add(T),r(T.blobUri(),{title:l.name})}),f.readAsDataURL(l)}),o.click()},setup:r=>{r.on("keydown",a=>{(a.ctrlKey||a.metaKey)&&a.code=="KeyS"&&r.formElement&&(a.preventDefault(),a.stopPropagation(),r.formElement.dispatchEvent(new KeyboardEvent("keydown",a)))});const i="tinymce_last_direction";r.on("init",()=>{var o;const a=(o=window==null?void 0:window.localStorage)==null?void 0:o.getItem(i);!r.isDirty()&&r.getContent()==""&&a=="rtl"&&r.execCommand("mceDirectionRTL")}),r.ui.registry.addMenuButton("direction",{icon:"visualchars",fetch:a=>{a([{type:"menuitem",text:"LTR content",icon:"ltr",onAction:()=>{var u;(u=window==null?void 0:window.localStorage)==null||u.setItem(i,"ltr"),r.execCommand("mceDirectionLTR")}},{type:"menuitem",text:"RTL content",icon:"rtl",onAction:()=>{var u;(u=window==null?void 0:window.localStorage)==null||u.setItem(i,"rtl"),r.execCommand("mceDirectionRTL")}}])}}),r.ui.registry.addMenuButton("image_picker",{icon:"image",fetch:a=>{a([{type:"menuitem",text:"From collection",icon:"gallery",onAction:()=>{r.dispatch("collections_file_picker",{})}},{type:"menuitem",text:"Inline",icon:"browse",onAction:()=>{r.execCommand("mceImage")}}])}})}}}static displayValue(e,t,n="N/A"){e=e||{},t=t||[];let r=[];for(const a of t){let o=e[a];typeof o>"u"||(o=d.stringifyValue(o,n),r.push(o))}if(r.length>0)return r.join(", ");const i=["title","name","slug","email","username","nickname","label","heading","message","key","identifier","id"];for(const a of i){let o=d.stringifyValue(e[a],"");if(o)return o}return n}static stringifyValue(e,t="N/A",n=150){if(d.isEmpty(e))return t;if(typeof e=="number")return""+e;if(typeof e=="boolean")return e?"True":"False";if(typeof e=="string")return e=e.indexOf("<")>=0?d.plainText(e):e,d.truncate(e,n)||t;if(Array.isArray(e)&&typeof e[0]!="object")return d.truncate(e.join(","),n);if(typeof e=="object")try{return d.truncate(JSON.stringify(e),n)||t}catch{return t}return e}static extractColumnsFromQuery(e){var a;const t="__GROUP__";e=(e||"").replace(/\([\s\S]+?\)/gm,t).replace(/[\t\r\n]|(?:\s\s)+/g," ");const n=e.match(/select\s+([\s\S]+)\s+from/),r=((a=n==null?void 0:n[1])==null?void 0:a.split(","))||[],i=[];for(let o of r){const u=o.trim().split(" ").pop();u!=""&&u!=t&&i.push(u.replace(/[\'\"\`\[\]\s]/g,""))}return i}static getAllCollectionIdentifiers(e,t=""){if(!e)return[];let n=[t+"id"];if(e.type==="view")for(let i of d.extractColumnsFromQuery(e.viewQuery))d.pushUnique(n,t+i);const r=e.fields||[];for(const i of r)i.type=="geoPoint"?(d.pushUnique(n,t+i.name+".lon"),d.pushUnique(n,t+i.name+".lat")):d.pushUnique(n,t+i.name);return n}static getExcerptCollectionFieldsList(e,t=200){let n=["*"];const r=(e==null?void 0:e.fields)||[];for(const i of r)i.primaryKey||i.type=="relation"||n.push(`${i.name}:excerpt(${t})`);return n.join(",")}static getCollectionAutocompleteKeys(e,t,n="",r=0){let i=e.find(o=>o.name==t||o.id==t);if(!i||r>=4)return[];i.fields=i.fields||[];let a=d.getAllCollectionIdentifiers(i,n);for(const o of i.fields){const u=n+o.name;if(o.type=="relation"&&o.collectionId){const l=d.getCollectionAutocompleteKeys(e,o.collectionId,u+".",r+1);l.length&&(a=a.concat(l))}o.maxSelect!=1&&Gr.includes(o.type)?(a.push(u+":each"),a.push(u+":length")):Kr.includes(o.type)&&a.push(u+":lower")}for(const o of e){o.fields=o.fields||[];for(const u of o.fields)if(u.type=="relation"&&u.collectionId==i.id){const l=n+o.name+"_via_"+u.name,f=d.getCollectionAutocompleteKeys(e,o.id,l+".",r+2);f.length&&(a=a.concat(f))}}return a}static getCollectionJoinAutocompleteKeys(e){const t=[];let n,r;for(const i of e)if(!i.system){n="@collection."+i.name+".",r=d.getCollectionAutocompleteKeys(e,i.name,n);for(const a of r)t.push(a)}return t}static getRequestAutocompleteKeys(e,t){const n=[];n.push("@request.context"),n.push("@request.method"),n.push("@request.query."),n.push("@request.body."),n.push("@request.headers."),n.push("@request.auth.collectionId"),n.push("@request.auth.collectionName");const r=e.filter(i=>i.type==="auth");for(const i of r){if(i.system)continue;const a=d.getCollectionAutocompleteKeys(e,i.id,"@request.auth.");for(const o of a)d.pushUnique(n,o)}if(t){const i=d.getCollectionAutocompleteKeys(e,t,"@request.body.");for(const a of i){n.push(a);const o=a.split(".");o.length===3&&o[2].indexOf(":")===-1&&(n.push(a+":changed"),n.push(a+":isset"))}}return n}static parseIndex(e){var u,l,f,h,w;const t={unique:!1,optional:!1,schemaName:"",indexName:"",tableName:"",columns:[],where:""},r=/create\s+(unique\s+)?\s*index\s*(if\s+not\s+exists\s+)?(\S*)\s+on\s+(\S*)\s*\(([\s\S]*)\)(?:\s*where\s+([\s\S]*))?/gmi.exec((e||"").trim());if((r==null?void 0:r.length)!=7)return t;const i=/^[\"\'\`\[\{}]|[\"\'\`\]\}]$/gm;t.unique=((u=r[1])==null?void 0:u.trim().toLowerCase())==="unique",t.optional=!d.isEmpty((l=r[2])==null?void 0:l.trim());const a=(r[3]||"").split(".");a.length==2?(t.schemaName=a[0].replace(i,""),t.indexName=a[1].replace(i,"")):(t.schemaName="",t.indexName=a[0].replace(i,"")),t.tableName=(r[4]||"").replace(i,"");const o=(r[5]||"").replace(/,(?=[^\(]*\))/gmi,"{PB_TEMP}").split(",");for(let m of o){m=m.trim().replaceAll("{PB_TEMP}",",");const N=/^([\s\S]+?)(?:\s+collate\s+([\w]+))?(?:\s+(asc|desc))?$/gmi.exec(m);if((N==null?void 0:N.length)!=4)continue;const D=(h=(f=N[1])==null?void 0:f.trim())==null?void 0:h.replace(i,"");D&&t.columns.push({name:D,collate:N[2]||"",sort:((w=N[3])==null?void 0:w.toUpperCase())||""})}return t.where=r[6]||"",t}static buildIndex(e){let t="CREATE ";e.unique&&(t+="UNIQUE "),t+="INDEX ",e.optional&&(t+="IF NOT EXISTS "),e.schemaName&&(t+=`\`${e.schemaName}\`.`),t+=`\`${e.indexName||"idx_"+d.randomString(10)}\` `,t+=`ON \`${e.tableName}\` (`;const n=e.columns.filter(r=>!!(r!=null&&r.name));return n.length>1&&(t+=` - `),t+=n.map(r=>{let i="";return r.name.includes("(")||r.name.includes(" ")?i+=r.name:i+="`"+r.name+"`",r.collate&&(i+=" COLLATE "+r.collate),r.sort&&(i+=" "+r.sort.toUpperCase()),i}).join(`, - `),n.length>1&&(t+=` -`),t+=")",e.where&&(t+=` WHERE ${e.where}`),t}static replaceIndexTableName(e,t){const n=d.parseIndex(e);return n.tableName=t,d.buildIndex(n)}static replaceIndexColumn(e,t,n){if(t===n)return e;const r=d.parseIndex(e);let i=!1;for(let a of r.columns)a.name===t&&(a.name=n,i=!0);return i?d.buildIndex(r):e}static normalizeSearchFilter(e,t){if(e=(e||"").trim(),!e||!t.length)return e;const n=["=","!=","~","!~",">",">=","<","<="];for(const r of n)if(e.includes(r))return e;return e=isNaN(e)&&e!="true"&&e!="false"?`"${e.replace(/^[\"\'\`]|[\"\'\`]$/gm,"")}"`:e,t.map(r=>`${r}~${e}`).join("||")}static normalizeLogsFilter(e,t=[]){return d.normalizeSearchFilter(e,["level","message","data"].concat(t))}static initSchemaField(e){return Object.assign({id:"",name:"",type:"text",system:!1,hidden:!1,required:!1},e)}static triggerResize(){window.dispatchEvent(new Event("resize"))}static getHashQueryParams(){let e="";const t=window.location.hash.indexOf("?");return t>-1&&(e=window.location.hash.substring(t+1)),Object.fromEntries(new URLSearchParams(e))}static replaceHashQueryParams(e){e=e||{};let t="",n=window.location.hash;const r=n.indexOf("?");r>-1&&(t=n.substring(r+1),n=n.substring(0,r));const i=new URLSearchParams(t);for(let u in e){const l=e[u];l===null?i.delete(u):i.set(u,l)}t=i.toString(),t!=""&&(n+="?"+t);let a=window.location.href;const o=a.indexOf("#");o>-1&&(a=a.substring(0,o)),window.location.replace(a+n)}}const ct=11e3;onmessage=s=>{var t,n;if(!s.data.collections)return;const e={};e.baseKeys=d.getCollectionAutocompleteKeys(s.data.collections,(t=s.data.baseCollection)==null?void 0:t.name),e.baseKeys=dt(e.baseKeys.sort(ft),ct),s.data.disableRequestKeys||(e.requestKeys=d.getRequestAutocompleteKeys(s.data.collections,(n=s.data.baseCollection)==null?void 0:n.name),e.requestKeys=dt(e.requestKeys.sort(ft),ct)),s.data.disableCollectionJoinKeys||(e.collectionJoinKeys=d.getCollectionJoinAutocompleteKeys(s.data.collections),e.collectionJoinKeys=dt(e.collectionJoinKeys.sort(ft),ct)),postMessage(e)};function ft(s,e){return s.length-e.length}function dt(s,e){return s.length>e?s.slice(0,e):s}})(); diff --git a/ui/dist/assets/docsAuthRefresh-UjveHHwo.js b/ui/dist/assets/docsAuthRefresh-UjveHHwo.js new file mode 100644 index 00000000..5f75e5dd --- /dev/null +++ b/ui/dist/assets/docsAuthRefresh-UjveHHwo.js @@ -0,0 +1,49 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(r){let i=app.utils.getApiExampleURL(),a={collectionId:r.id,collectionName:r.name},o=[{title:200,value:JSON.stringify({token:`...JWT...`,record:Object.assign(a,app.utils.getDummyFieldsData(r))},null,2)},{title:401,value:` + { + "status": 401, + "message": "The request requires valid record authorization token to be set.", + "data": {} + } + `},{title:403,value:` + { + "status": 403, + "message": "The authorized record model is not allowed to perform this action.", + "data": {} + } + `},{title:404,value:` + { + "status": 404, + "message": "Missing auth record context.", + "data": {} + } + `}];return t.div({pbEvent:`apiPreviewAuthRefresh`,className:`content`},t.p(null,`Returns a new auth response (token and record data) for an already authenticated record.`),t.p(null,`This method is usually called by users on page/screen reload to ensure that the previously stored data in `,t.code(null,`pb.authStore`),` is still valid and up-to-date.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + const authData = await pb.collection('${r.name}').authRefresh(); + + // after the above you can also access the refreshed auth data from the authStore + console.log(pb.authStore.isValid); + console.log(pb.authStore.token); + console.log(pb.authStore.record.id); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + final authData = await pb.collection('${r.name}').authRefresh(); + + // after the above you can also access the refreshed auth data from the authStore + print(pb.authStore.isValid); + print(pb.authStore.token); + print(pb.authStore.record.id); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X POST \\ + -H 'Authorization:TOKEN' \\ + '${i}/api/collections/${r.name}/auth-refresh' + `}]}),t.div({className:`m-t-base`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${r.name}/auth-refresh`),t.small({className:`extra`},`Requires`,t.br(),`Authorization:TOKEN header`)),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:o}))}export{r as docsAuthRefresh}; \ No newline at end of file diff --git a/ui/dist/assets/docsAuthWithOAuth2-DUIE4EoY.js b/ui/dist/assets/docsAuthWithOAuth2-DUIE4EoY.js new file mode 100644 index 00000000..253d3593 --- /dev/null +++ b/ui/dist/assets/docsAuthWithOAuth2-DUIE4EoY.js @@ -0,0 +1,67 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(r){let i=app.utils.getApiExampleURL(),a={collectionId:r.id,collectionName:r.name},o=[{title:200,value:JSON.stringify({token:`...JWT...`,record:Object.assign(a,app.utils.getDummyFieldsData(r)),meta:{id:`abc123`,name:`John Doe`,username:`john.doe`,email:`test@example.com`,avatarURL:`https://example.com/avatar.png`,accessToken:`...`,refreshToken:`...`,expiry:`2022-01-01 10:00:00.123Z`,isNew:!1,rawUser:{}}},null,2)},{title:400,value:` + { + "status": 400, + "message": "An error occurred while submitting the form.", + "data": { + "provider": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}];return t.div({pbEvent:`apiPreviewAuthWithOAuth2`,className:`content`},t.p(null,`Authenticate with an OAuth2 provider and returns a new auth token and record data.`),t.p(null,`For more details please check the `,t.a({href:`https://pocketbase.io/docs/authentication#authenticate-with-oauth2`,target:`_blank`,rel:`noopener noreferrer`,textContent:`OAuth2 integration documentation`}),`.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + // OAuth2 authentication with a single realtime call. + // + // Make sure to register ${i}/api/oauth2-redirect + // as redirect url in the OAuth2 app configuration. + const authData = await pb.collection('${r.name}').authWithOAuth2({ provider: 'google' }); + + // OR authenticate with manual OAuth2 code exchange + // const authData = await pb.collection('${r.name}').authWithOAuth2Code(...); + + // after the above you can also access the auth data from the authStore + console.log(pb.authStore.isValid); + console.log(pb.authStore.token); + console.log(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + import 'package:url_launcher/url_launcher.dart'; + + final pb = PocketBase('${i}'); + + ... + + // OAuth2 authentication with a single realtime call. + // + // Make sure to register ${i}/api/oauth2-redirect + // as redirect url in the OAuth2 app configuration. + final authData = await pb.collection('${r.name}').authWithOAuth2('google', (url) async { + await launchUrl(url); + }); + + // OR authenticate with manual OAuth2 code exchange + // final authData = await pb.collection('${r.name}').authWithOAuth2Code(...); + + // after the above you can also access the auth data from the authStore + print(pb.authStore.isValid); + print(pb.authStore.token); + print(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # authenticate with manual OAuth2 code exchange + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "provider":"google", "code":"OAUTH2_CODE", "codeVerifier":"...", "redirectURL":"..." }' \\ + '${i}/api/collections/${r.name}/auth-with-oauth2' + `}]}),t.div({className:`m-t-base`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${r.name}/auth-with-password`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`provider `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The name of the OAuth2 client provider (eg. "google").`)),t.tr(null,t.td({className:`min-width`},`code `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The authorization code returned from the initial request.`)),t.tr(null,t.td({className:`min-width`},`codeVerifier `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The code verifier sent with the initial request as part of the code_challenge.`)),t.tr(null,t.td({className:`min-width`},`redirectURL `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The redirect url sent with the initial request.`)),t.tr(null,t.td({className:`min-width`},`createData `,t.em(null,`(optional)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,t.p(null,`Optional data that will be used when creating the auth record on OAuth2 sign-up.`),t.p(null,`The created auth record must comply with the same requirements and validations in the regular create action.`),t.p(null,`The data can only be in JSON, aka. user uploaded files currently are not supported during OAuth2 sign-ups.`))))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:o}))}export{r as docsAuthWithOAuth2}; \ No newline at end of file diff --git a/ui/dist/assets/docsAuthWithOTP-B7z2VJzp.js b/ui/dist/assets/docsAuthWithOTP-B7z2VJzp.js new file mode 100644 index 00000000..059b9d2f --- /dev/null +++ b/ui/dist/assets/docsAuthWithOTP-B7z2VJzp.js @@ -0,0 +1,95 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(e){let n=app.utils.getApiExampleURL(),r=[{title:`OTP request`,content:i},{title:`OTP auth`,content:a}],o=store({activeActionIndex:0});return t.div({pbEvent:`apiPreviewAuthWithOTP`,className:`content`},t.p(null,`Authenticate with an one-time/short-lived password (OTP).`),t.p(null,`Note that when requesting an OTP we return an `,t.code(null,`otpId`),` even if a user with the provided email doesn't exist as a very basic enumeration protection.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${n}'); + + ... + + // send OTP email to the provided auth record + const req = await pb.collection('${e.name}').requestOTP('test@example.com'); + + // ... show a screen/popup to enter the password from the email ... + + // authenticate with the requested OTP id and the email password + const authData = await pb.collection('${e.name}').authWithOTP( + req.otpId, + "YOUR_OTP", + ); + + // after the above you can also access the auth data from the authStore + console.log(pb.authStore.isValid); + console.log(pb.authStore.token); + console.log(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${n}'); + + ... + + // send OTP email to the provided auth record + final req = await pb.collection('${e.name}').requestOTP('test@example.com'); + + // ... show a screen/popup to enter the password from the email ... + + // authenticate with the requested OTP id and the email password + final authData = await pb.collection('${e.name}').authWithOTP( + req.otpId, + "YOUR_OTP", + ); + + // after the above you can also access the auth data from the authStore + print(pb.authStore.isValid); + print(pb.authStore.token); + print(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # OTP request (sends email to the user if exists) + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "email":"..." }' \\ + '${n}/api/collections/${e.name}/request-otp' + + # OTP auth + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "otpId":"...", "password":"..." }' \\ + '${n}/api/collections/${e.name}/auth-with-otp' + `}]}),t.nav({className:`btns m-t-base m-b-sm`},()=>r.map((e,n)=>t.button({type:`button`,className:()=>`btn sm expanded ${o.activeActionIndex==n?`active`:`secondary`}`,textContent:()=>e.title,onclick:()=>o.activeActionIndex=n}))),()=>r[o.activeActionIndex]?.content?.(e))}function i(e){return[t.div(null,t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/request-otp`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`email `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The auth record email address to send the OTP request (if exists).`)))),t.div({className:`m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:200,value:` + { + "otpId": "njvv1b1lkdbpp3m" + } + `},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "email": { + "code": "validation_is_email", + "message": "Must be a valid email address." + } + } + } + `},{title:429,value:` + { + "status": 429, + "message": "You've send too many OTP requests, please try again later.", + "data": {} + } + `}]})]}function a(r){let i={collectionId:r.id,collectionName:r.name},a=[{title:200,value:JSON.stringify({token:`...JWT...`,record:Object.assign(i,app.utils.getDummyFieldsData(r))},null,2)},{title:400,value:` + { + "status": 400, + "message": "Failed to authenticate.", + "data": { + "otpId": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}];return[t.div(null,t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${r.name}/auth-with-otp`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`otpId `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The id of the OTP request.`)),t.tr(null,t.td({className:`min-width`},`password `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The one-time/short-lived password from the OTP request.`)))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:a})]}export{r as docsAuthWithOTP}; \ No newline at end of file diff --git a/ui/dist/assets/docsAuthWithPassword-DEWj8Jyn.js b/ui/dist/assets/docsAuthWithPassword-DEWj8Jyn.js new file mode 100644 index 00000000..f148d8e9 --- /dev/null +++ b/ui/dist/assets/docsAuthWithPassword-DEWj8Jyn.js @@ -0,0 +1,55 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(r){let i=app.utils.getApiExampleURL(),a=r.passwordAuth?.identityFields||[],o=a.length==0?`NONE`:`YOUR_`+a.join(`_OR_`).toUpperCase(),s={collectionId:r.id,collectionName:r.name},c=[{title:200,value:JSON.stringify({token:`...JWT...`,record:Object.assign(s,app.utils.getDummyFieldsData(r))},null,2)},{title:400,value:` + { + "status": 400, + "message": "Failed to authenticate.", + "data": { + "identity": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}];return t.div({pbEvent:`apiPreviewAuthWithPassword`,className:`content`},t.p(null,`Authenticate with combination of `,t.strong(null,a.join(`/`)),` and `,t.strong(null,`password`),`.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + const authData = await pb.collection('${r.name}').authWithPassword( + '${o}', + 'YOUR_PASSWORD', + ); + + // after the above you can also access the auth data from the authStore + console.log(pb.authStore.isValid); + console.log(pb.authStore.token); + console.log(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + final authData = await pb.collection('${r.name}').authWithPassword( + '${o}', + 'YOUR_PASSWORD', + ); + + // after the above you can also access the auth data from the authStore + print(pb.authStore.isValid); + print(pb.authStore.token); + print(pb.authStore.record.id); + + // "logout" + pb.authStore.clear(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "identity":"${o}", "password":"YOUR_PASSWORD" }' \\ + '${i}/api/collections/${r.name}/auth-with-password' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${r.name}/auth-with-password`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`identity `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,app.utils.sentenize(a.join(` or `),!1),` of the record to authenticate.`)),t.tr(null,t.td({className:`min-width`},`identityField `,t.em(null,`(optional)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`In case of multiple identity fields, explicitly set the field name to use when searching for the auth record.`,t.br(),`Leave it empty for auto detection.`)),t.tr(null,t.td({className:`min-width`},`password `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The auth record password.`)))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:c}))}export{r as docsAuthWithPassword}; \ No newline at end of file diff --git a/ui/dist/assets/docsBatch-DNJl1NTn.js b/ui/dist/assets/docsBatch-DNJl1NTn.js new file mode 100644 index 00000000..bc63bc42 --- /dev/null +++ b/ui/dist/assets/docsBatch-DNJl1NTn.js @@ -0,0 +1,92 @@ +function e(e){let n=app.utils.getApiExampleURL(),r={collectionId:e.id,collectionName:e.name},i=[{title:200,value:JSON.stringify([{status:200,body:Object.assign(r,app.utils.getDummyFieldsData(e))},{status:200,body:Object.assign(r,app.utils.getDummyFieldsData(e))}],null,2)},{title:400,value:` + { + "status": 400, + "message": "Batch transaction failed.", + "data": { + "requests": { + "1": { + "code": "batch_request_failed", + "message": "Batch request failed.", + "response": { + "status": 400, + "message": "Failed to create record.", + "data": { + "id": { + "code": "validation_min_text_constraint", + "message": "Must be at least 3 character(s).", + "params": { "min": 3 } + } + } + } + } + } + } + } + `},{title:403,value:` + { + "status": 403, + "message": "Batch requests are not allowed.", + "data": {} + } + `}];return t.div({pbEvent:`apiPreviewBatch`,className:`content`},t.p(null,`Batch and transactional create/update/upsert/delete of multiple records in a single request.`),t.div({className:`alert warning`},t.p({className:`txt-bold`},`The batch Web API need to be explicitly enabled and configured from the `,t.a({href:`#/settings`,target:`_blank`,title:`Open in new tab`,textContent:`App settings`}),`.`),t.p(null,`Because this endpoint process the requests in a single DB transaction it could degrade the performance of your application if not used with proper care and configuration (use smaller max processing and body size limits, avoid large file uploads over slow S3 networks and custom hooks that communicate with slow external APIs).`)),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${n}'); + + ... + + const batch = pb.createBatch(); + + batch.collection('${e.name}').create({ ... }); + batch.collection('${e.name}').update('RECORD_ID', { ... }); + batch.collection('${e.name}').delete('RECORD_ID'); + batch.collection('${e.name}').upsert({ ... }); + + const result = await batch.send(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${n}'); + + ... + + final batch = pb.createBatch(); + + batch.collection('${e.name}').create(body: { ... }); + batch.collection('${e.name}').update('RECORD_ID', body: { ... }); + batch.collection('${e.name}').delete('RECORD_ID'); + batch.collection('${e.name}').upsert(body: { ... }); + + final result = await batch.send(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X POST \\ + -H 'Authorization:TOKEN' \\ + -H 'Content-Type:application/json' \\ + -d '{ "requests": [...] }' \\ + '${n}/api/batch' + `}]}),t.div({className:`block m-t-sm`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/batch`)),t.p(null,`The request accepts only 1 required `,t.code(null,`requests: Array`),` parameter that defines the list of the batch requests to process.`),t.p(null,`When using the official SDKs the batch requests are transparently constructed by their service handler.`),t.p(null,`For the cases when you don't use the SDKs, the she supported batch request actions are:`),t.ul(null,t.li(null,`record create - `,t.code(null,`POST /api/collections/{collection}/records`)),t.li(null,`record update - `,t.code(null,`PATCH /api/collections/{collection}/records`)),t.li(null,`record upsert - `,t.code(null,`PUT /api/collections/{collection}/records`),t.br(),t.small({className:`txt-hint`},`(the body must have an "id" field)`)),t.li(null,`record delete - `,t.code(null,`DELETE /api/collections/{collection}/records/{id}`))),t.p(null,`Each batch `,t.em(null,`Request`),` element has the following properties:`),t.ul(null,t.li(null,t.code(null,`url`),t.em(null,` (could include query parameters)`)),t.li(null,t.code(null,`method`),t.em(null,` (GET, POST, PUT, PATCH, DELETE)`)),t.li(null,t.code(null,`headers`),t.br(),t.em(null,`(custom per-request Authorization header is not supported at the moment, aka. all batch requests have the same auth state)`)),t.li(null,t.code(null,`body`),t.br(),`When the batch request is send as `,t.code(null,`multipart/form-data`),`, the regular batch action fields are expected to be submitted as serialized json under the `,t.code(null,`@jsonPayload`),` field and file keys need to follow the pattern `,t.code(null,`requests.N.fileField`),` or `,t.code(null,`requests[N].fileField`),`.`,t.br(),`Again this is handled transparently by the official SDKs, but for example if you prefer to manually construct a JS `,t.code(null,`FormData`),` body, then it could look something like:`,app.components.codeBlock({className:`m-t-10`,value:` + const batchBody = new FormData(); + + batchBody.append("@jsonPayload", JSON.stringify({ + requests: [ + // create + { + url: "/api/collections/users/records?expand=someRelField", + method: "POST", + body: { someField: "test1" } + }, + // update + { + url: "/api/collections/users/records/RECORD_ID", + method: "PATCH", + body: { someField: "test2" } + } + ] + })) + + // bind file to the first request + batchBody.append("requests.0.someFileField", new File(...)) + + // bind file to the second request + batchBody.append("requests.1.someFileField", new File(...)) + `}))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:i}))}export{e as docsBatch}; \ No newline at end of file diff --git a/ui/dist/assets/docsCreate-Be3S3y5K.js b/ui/dist/assets/docsCreate-Be3S3y5K.js new file mode 100644 index 00000000..a7b69c17 --- /dev/null +++ b/ui/dist/assets/docsCreate-Be3S3y5K.js @@ -0,0 +1,52 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(r){let s=app.utils.getApiExampleURL(),c=r.createRule===null,l=r.type===`auth`,u=l?[`password`,`verified`,`email`,`emailVisibility`]:[],d=r.fields?.filter(e=>!e.hidden&&e.type!=`autodate`&&!u.includes(e.name))||[],f={collectionId:r.id,collectionName:r.name},p=[{title:200,value:JSON.stringify(Object.assign(f,app.utils.getDummyFieldsData(r)),null,2)},{title:400,value:` + { + "status": 400, + "message": "Failed to create record.", + "data": { + "${l?`email`:d.find(e=>!e.primaryKey)?.name||`someField`}": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}];return c&&p.push({title:403,value:` + { + "status": 403, + "message": "Only superusers can perform this action.", + "data": {} + } + `}),t.div({pbEvent:`apiPreviewCreate`,className:`content`},t.p(null,`Creates a new ${r.name} record.`),t.p(null,`Body parameters could be sent as `,t.code(null,`application/json`),` or `,t.code(null,`multipart/form-data`),`.`),t.p(null,`File upload is supported only via `,t.code(null,`multipart/form-data`),`. For more info and examples you could check the detailed `,t.a({href:`https://pocketbase.io/docs/files-handling`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Files upload and handling docs`}),`.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` +import PocketBase from 'pocketbase'; + +const pb = new PocketBase('${s}'); + +... + +// example create body +const body = ${i(JSON.stringify(a(r),null,2))}; + +const record = await pb.collection('${r.name}').create(body); +`+(l?` +// (optional) send an email verification request +await pb.collection('${r?.name}').requestVerification('test@example.com'); +`:``),footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` +import 'package:pocketbase/pocketbase.dart'; + +final pb = PocketBase('${s}'); + +... + +// example create body +final body = ${JSON.stringify(o(r),null,2)}; + +final record = await pb.collection('${r.name}').create(body: body, files: []); +`+(l?` +// (optional) send an email verification request +await pb.collection('${r?.name}').requestVerification('test@example.com'); +`:``),footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X POST \\ + -H 'Authorization:TOKEN' \\ + -H 'Content-Type:application/json' \\ + -d '{ ... }' \\ + '${s}/api/collections/${r.name}/records/RECORD_ID' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${r.name}/records`),()=>{if(c)return t.small({className:`extra`},`Requires superuser Authorization:TOKEN header`)}),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,()=>{if(l)return[t.tr(null,t.th({colSpan:99},`Auth specific fields`)),t.tr(null,t.td({className:`min-width`},`email `,()=>r.fields?.find(e=>e.name==`email`)?.required?t.em(null,`(required)`):t.em(null,`(optional)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`Auth record email address.`)),t.tr(null,t.td({className:`min-width`},`emailVisibility `,()=>r.fields?.find(e=>e.name==`emailVisibility`)?.required?t.em(null,`(required)`):t.em(null,`(optional)`)),t.td({className:`min-width`},t.span({className:`label`},`Boolean`)),t.td(null,`Whether to show/hide the auth record email when fetching the record data.`,t.br(),`Superusers and the owner of the record always have access to the email address.`)),t.tr(null,t.td({className:`min-width`},`password `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`Auth record password.`)),t.tr(null,t.td({className:`min-width`},`passwordConfirm `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`Auth record password confirmation.`)),t.tr(null,t.td({className:`min-width`},`verified `,t.em(null,`(optional)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,t.p(null,`Indicates whether the auth record is verified or not.`),t.p(null,`This field can be set only by superusers or auth records with "Manage" access.`))),t.tr(null,t.th({colSpan:99},`Other fields`))]},()=>d.map(e=>t.tr(null,t.td({className:`min-width`},e.name,t.em(null,e.required&&!e.autogeneratePattern?` (required)`:` (optional)`)),t.td({className:`min-width`},t.span({className:`label`},()=>{let n=app.fieldTypes[e.type]?.dummyData(e,!0),r=typeof n;return e.type==`file`?`File`:r===`string`?`String`:r==`number`?`Number`:r==`bool`?`Boolean`:Array.isArray(n)?`Array`:app.utils.isObject(n)?`Object`:`Mixed`})),t.td(null,t.code(null,e.type),` field type value.`,t.br(),t.small({className:`txt-hint`},`For more details you could check the `,t.a({href:`https://pocketbase.io/docs/collections/#fields`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Fields docs`}),`.`)))))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:p}))}function i(e){return e.replaceAll(`"[[`,``).replaceAll(`]]"`,``)}function a(e,n=!1){let r=app.utils.getDummyFieldsData(e,!0);return delete r.id,e.type==`auth`&&(n&&(r.oldPassword=`987654321`,delete r.email),r.password=`123456789`,r.passwordConfirm=`123456789`,delete r.verified),r}function o(e,n=!1){let r=a(e,n);for(let e in r){let n=typeof r[e];(r[e]?.startsWith?.(`[[`)||![`number`,`string`,`boolean`].includes(n)&&!Array.isArray(r[e]))&&delete r[e]}return r}export{r as docsCreate,a as fullDummyPayload,o as primitivesDummyPayload,i as replaceDummyPayloadPlaceholder}; \ No newline at end of file diff --git a/ui/dist/assets/docsDelete-CybOn5jy.js b/ui/dist/assets/docsDelete-CybOn5jy.js new file mode 100644 index 00000000..9fc1493c --- /dev/null +++ b/ui/dist/assets/docsDelete-CybOn5jy.js @@ -0,0 +1,39 @@ +function e(e){let n=app.utils.getApiExampleURL(),r=e.deleteRule===null,i=[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "Failed to delete record. Make sure that the record is not part of a required relation reference.", + "data": {} + } + `}];return r&&i.push({title:403,value:` + { + "status": 403, + "message": "Only superusers can access this action.", + "data": {} + } + `}),i.push({title:404,value:` + { + "status": 404, + "message": "The requested resource wasn't found.", + "data": {} + } + `}),t.div({pbEvent:`apiPreviewDelete`,className:`content`},t.p(null,`Delete a single ${e.name} record.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${n}'); + + ... + + await pb.collection('${e.name}').delete('RECORD_ID'); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${n}'); + + ... + + await pb.collection('${e.name}').delete('RECORD_ID'); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X DELETE \\ + -H 'Authorization:TOKEN' \\ + '${n}/api/collections/${e.name}/records/RECORD_ID' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert danger api-preview-alert`},t.span({className:`label method`},`DELETE`),t.span({className:`path`},`/api/collections/${e.name}/records/`,t.strong(null,`:id`)),()=>{if(r)return t.small({className:`extra`},`Requires superuser Authorization:TOKEN header`)}),t.table({className:`api-preview-table path-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Path params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`id`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`ID of the record to delete.`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:i}))}export{e as docsDelete}; \ No newline at end of file diff --git a/ui/dist/assets/docsEmailChange-B---6FKV.js b/ui/dist/assets/docsEmailChange-B---6FKV.js new file mode 100644 index 00000000..55b47ff5 --- /dev/null +++ b/ui/dist/assets/docsEmailChange-B---6FKV.js @@ -0,0 +1,94 @@ +function e(e){let i=app.utils.getApiExampleURL(),a=[{title:`Request email change`,content:n},{title:`Confirm email change`,content:r}],o=store({activeActionIndex:0});return t.div({pbEvent:`apiPreviewEmailChange`,className:`content`},t.p(null,`Sends ${e.name} email change request.`),t.p(null,`On successful email change all previously issued auth tokens for the specific record will be automatically invalidated.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').authWithPassword( + 'test@example.com', + '1234567890' + ); + + await pb.collection('${e.name}').requestEmailChange('new@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + // note: after this call all previously issued auth tokens are invalidated + await pb.collection('${e.name}').confirmEmailChange( + 'EMAIL_CHANGE_TOKEN', + 'YOUR_PASSWORD', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').authWithPassword( + 'test@example.com', + '1234567890' + ); + + await pb.collection('${e.name}').requestEmailChange('new@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + // note: after this call all previously issued auth tokens are invalidated + await pb.collection('${e.name}').confirmEmailChange( + 'EMAIL_CHANGE_TOKEN', + 'YOUR_PASSWORD', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # Request email change + curl -X POST \\ + -H 'Authorization:TOKEN' \\ + -H 'Content-Type:application/json' \\ + -d '{ "newEmail":"..." }' \\ + '${i}/api/collections/${e.name}/request-email-change' + + # Confirm email change + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "token":"...", "password":"" }' \\ + '${i}/api/collections/${e.name}/confirm-email-change' + `}]}),t.nav({className:`btns m-t-base m-b-sm`},()=>a.map((e,n)=>t.button({type:`button`,className:()=>`btn sm expanded ${o.activeActionIndex==n?`active`:`secondary`}`,textContent:()=>e.title,onclick:()=>o.activeActionIndex=n}))),()=>a[o.activeActionIndex]?.content?.(e))}function n(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/request-email-change`),t.small({className:`extra`},`Requires`,t.br(),`Authorization:TOKEN header`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`newEmail `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The new email address to send the change email request.`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "newEmail": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `},{title:401,value:` + { + "status": 401, + "message": "The request requires valid record authorization token to be set.", + "data": {} + } + `},{title:403,value:` + { + "status": 403, + "message": "The authorized record model is not allowed to perform this action.", + "data": {} + } + `}]})]}function r(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/confirm-email-change`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`token `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The token from the change email request email.`)),t.tr(null,t.td({className:`min-width`},`password `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The account password to confirm the email change.`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "token": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}]})]}export{e as docsEmailChange}; \ No newline at end of file diff --git a/ui/dist/assets/docsList-BHALa0P4.js b/ui/dist/assets/docsList-BHALa0P4.js new file mode 100644 index 00000000..25b0b898 --- /dev/null +++ b/ui/dist/assets/docsList-BHALa0P4.js @@ -0,0 +1,64 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";import{t as r}from"./filterSyntax-UQrUrYb5.js";function i(i){let a=app.utils.getApiExampleURL(),o=i.listRule===null,s={collectionId:i.id,collectionName:i.name},c=[{title:200,value:JSON.stringify({page:1,perPage:30,totalPages:1,totalItems:2,items:[Object.assign(s,app.utils.getDummyFieldsData(i)),Object.assign(s,app.utils.getDummyFieldsData(i))]},null,2)},{title:400,value:` + { + "status": 400, + "message": "Something went wrong while processing your request.", + "data": {} + } + `}];return o&&c.push({title:403,value:` + { + "status": 403, + "message": "Only superusers can access this action.", + "data": {} + } + `}),t.div({pbEvent:`apiPreviewList`,className:`content`},t.p(null,`Fetch a paginated ${i.name} records list, supporting sorting and filtering.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${a}'); + + ... + + // fetch a paginated records list + const resultList = await pb.collection('${i.name}').getList(1, 50, { + filter: 'someField1 != someField2', + }); + + // you can also fetch all records at once via getFullList + const records = await pb.collection('${i.name}').getFullList({ + sort: '-someField', + }); + + // or fetch only the first record that matches the specified filter + const record = await pb.collection('${i.name}').getFirstListItem( + 'someField="test"', + { expand: 'relField1,relField2.subRelField' }, + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${a}'); + + ... + + // fetch a paginated records list + final resultList = await pb.collection('${i.name}').getList( + page: 1, + perPage: 50, + filter: 'someField1 != someField2', + ); + + // you can also fetch all records at once via getFullList + final records = await pb.collection('${i.name}').getFullList( + sort: '-someField', + ); + + // or fetch only the first record that matches the specified filter + final record = await pb.collection('${i.name}').getFirstListItem( + 'someField="test"', + expand: 'relField1,relField2.subRelField', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl \\ + -H 'Authorization:TOKEN' \\ + '${a}/api/collections/${i.name}/records?perPage=50' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert info api-preview-alert`},t.span({className:`label method`},`GET`),t.span({className:`path`},`/api/collections/${i.name}/records`),()=>{if(o)return t.small({className:`extra`},`Requires superuser Authorization:TOKEN header`)}),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`page`),t.td({className:`min-width`},t.span({className:`label`},`Number`)),t.td(null,`The page (aka. offset) of the paginated list (default to 1).`)),t.tr(null,t.td({className:`min-width`},`perPage`),t.td({className:`min-width`},t.span({className:`label`},`Number`)),t.td(null,`Specify the max returned records per page (default to 30).`)),t.tr(null,t.td({className:`min-width`},`sort`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,t.p(null,`Specify the records order attribute(s).`,t.br(),`Add -/+ (default) in front of the attribute for DESC / ASC order.`),t.p(null,`For example:`,app.components.codeBlock({value:`// DESC by created and ASC by id +?sort=-created,id`})),t.p(null,`In addition to the collection non-hidden fields, the following special sort fields could be also used: `,t.code(null,`@random`),` `,t.code({hidden:()=>i.type==`view`},`@rowid`),`.`))),t.tr(null,t.td({className:`min-width`},`filter`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,t.p(null,`Filter the returned records. For example:`),app.components.codeBlock({value:`?filter=(id='abc' && created>'2022-01-01')`,footnote:`All query params must be properly URL encoded (the SDKs do this automatically).`}),r())),t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())),t.tr(null,t.td({className:`min-width`},`skipTotal`),t.td({className:`min-width`},t.span({className:`label`},`Boolean`)),t.td(null,t.p(null,`If set to `,t.code(null,`1/true`),` the total counts query will be skipped and the response fields `,t.code(null,`totalItems`),` and `,t.code(null,`totalPages`),` will have -1 value.`),t.p(null,`This could drastically speed up the search queries when the total counters are not needed or cursor based pagination is used.`,` For optimization purposes, it is set by default in the `,t.code(null,`getFirstListItem()`),` and `,t.code(null,`getFullList()`),` SDKs methods.`))))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:c}))}export{i as docsList}; \ No newline at end of file diff --git a/ui/dist/assets/docsListAuthMethods-9feSopQX.js b/ui/dist/assets/docsListAuthMethods-9feSopQX.js new file mode 100644 index 00000000..b64cdbd9 --- /dev/null +++ b/ui/dist/assets/docsListAuthMethods-9feSopQX.js @@ -0,0 +1,25 @@ +import{t as e}from"./fieldsInfo-Bz62125-.js";function n(n){let r=app.utils.getApiExampleURL(),i=store({isLoading:!1,authMethods:[],get responses(){return[{title:200,value:i.isLoading?`...`:JSON.stringify(i.authMethods,null,2)},{title:404,value:` + { + "status": 404, + "message": "Missing collection context.", + "data": {} + } + `}]}});async function a(){i.isLoading=!0;try{i.authMethods=await app.pb.collection(n.name).listAuthMethods()}catch(e){e.isAbort&&app.pb.checkApiError(e)}i.isLoading=!1}return t.div({pbEvent:`apiPreviewListAuthMethods`,className:`content`,onmount:()=>{a()}},t.p(null,`Returns a public list with all allowed ${n.name} authentication methods.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${r}'); + + ... + + const result = await pb.collection('${n.name}').listAuthMethods(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${r}'); + + ... + + final result = await pb.collection('${n.name}').listAuthMethods(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl '${r}/api/collections/${n.name}/auth-methods' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert info api-preview-alert`},t.span({className:`label method`},`GET`),t.span({className:`path`},`/api/collections/${n.name}/auth-methods`)),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:()=>i.responses}))}export{n as docsListAuthMethods}; \ No newline at end of file diff --git a/ui/dist/assets/docsPasswordReset-vLO_ZWrq.js b/ui/dist/assets/docsPasswordReset-vLO_ZWrq.js new file mode 100644 index 00000000..2ae0aa1d --- /dev/null +++ b/ui/dist/assets/docsPasswordReset-vLO_ZWrq.js @@ -0,0 +1,73 @@ +function e(e){let i=app.utils.getApiExampleURL(),a=[{title:`Request password reset`,content:n},{title:`Confirm password reset`,content:r}],o=store({activeActionIndex:0});return t.div({pbEvent:`apiPreviewPasswordReset`,className:`content`},t.p(null,`Sends ${e.name} password reset email request.`),t.p(null,`On successful password reset all previously issued auth tokens for the specific record will be automatically invalidated.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').requestPasswordReset('test@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + // note: after this call all previously issued auth tokens are invalidated + await pb.collection('${e.name}').confirmPasswordReset( + 'RESET_TOKEN', + 'NEW_PASSWORD', + 'NEW_PASSWORD_CONFIRM', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').requestPasswordReset('test@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + // note: after this call all previously issued auth tokens are invalidated + await pb.collection('${e.name}').confirmPasswordReset( + 'RESET_TOKEN', + 'NEW_PASSWORD', + 'NEW_PASSWORD_CONFIRM', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # Request password reset + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "email":"..." }' \\ + '${i}/api/collections/${e.name}/request-password-reset' + + # Confirm password reset + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "token":"...", "password":"", "passwordConfirm":"" }' \\ + '${i}/api/collections/${e.name}/confirm-password-reset' + `}]}),t.nav({className:`btns m-t-base m-b-sm`},()=>a.map((e,n)=>t.button({type:`button`,className:()=>`btn sm expanded ${o.activeActionIndex==n?`active`:`secondary`}`,textContent:()=>e.title,onclick:()=>o.activeActionIndex=n}))),()=>a[o.activeActionIndex]?.content?.(e))}function n(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/request-password-reset`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`email `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The auth record email address to send the password reset request (if exists).`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "email": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}]})]}function r(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/confirm-password-reset`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`token `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The token from the password reset request email.`)),t.tr(null,t.td({className:`min-width`},`password `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The new password to set.`)),t.tr(null,t.td({className:`min-width`},`passwordConfirm `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`Confirmation of the new password.`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "token": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}]})]}export{e as docsPasswordReset}; \ No newline at end of file diff --git a/ui/dist/assets/docsRealtime-PMESvmJN.js b/ui/dist/assets/docsRealtime-PMESvmJN.js new file mode 100644 index 00000000..480e85d8 --- /dev/null +++ b/ui/dist/assets/docsRealtime-PMESvmJN.js @@ -0,0 +1,81 @@ +function e(e){let n=app.utils.getApiExampleURL(),r=Object.assign({collectionId:e.id,collectionName:e.name},app.utils.getDummyFieldsData(e));return t.div({pbEvent:`apiPreviewRealtime`,className:`content`},t.p(null,`Subscribe to realtime changes via Server-Sent Events (SSE).`),t.p(null,`Events are sent for `,t.strong(null,`create`),`, `,t.strong(null,`update`),` and `,t.strong(null,`delete`),` record operations (see "Event data format" below).`),t.div({className:`alert info`},t.p({className:`txt-bold`},`You could subscribe to a single record or to an entire collection.`),t.p(null,`When you subscribe to a `,t.strong(null,`single record`),`, the collection's `,t.strong(null,`View rule`),` will be used to determine whether the subscriber is allowed to receive the event message.`),t.p(null,`When you subscribe to an `,t.strong(null,`entire collection`),`, the collection's `,t.strong(null,`List/Search rule`),` will be used to determine whether the subscriber is allowed to receive the event message.`)),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${n}'); + + ... + + // (optionally) authenticate + await pb.collection('users').authWithPassword('test@example.com', '123456'); + + // subscribe to changes in any ${n} record + pb.collection('${n}').subscribe('*', function (e) { + console.log(e.action); + console.log(e.record); + }, { /* other options like: filter, expand, custom headers, etc. */ }); + + // subscribe to changes only in the specified record + pb.collection('${n}').subscribe('RECORD_ID', function (e) { + console.log(e.action); + console.log(e.record); + }, { /* other options like: filter, expand, custom headers, etc. */ }); + + ... + + // unsubscribe - remove all 'RECORD_ID' subscriptions + pb.collection('${n}').unsubscribe('RECORD_ID'); + + // unsubscribe - remove all '*' topic subscriptions + pb.collection('${n}').unsubscribe('*'); + + // unsubscribe - remove all collection subscriptions + pb.collection('${n}').unsubscribe(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${n}'); + + ... + + // (optionally) authenticate + await pb.collection('users').authWithPassword('test@example.com', '123456'); + + // subscribe to changes in any ${n} record + pb.collection('${n}').subscribe('*', (e) { + print(e.action); + print(e.record); + }, /* other options like: filter, expand, custom headers, etc. */); + + // subscribe to changes only in the specified record + pb.collection('${n}').subscribe('RECORD_ID', (e) { + print(e.action); + print(e.record); + }, /* other options like: filter, expand, custom headers, etc. */); + + ... + + // unsubscribe - remove all 'RECORD_ID' subscriptions + pb.collection('${n}').unsubscribe('RECORD_ID'); + + // unsubscribe - remove all '*' topic subscriptions + pb.collection('${n}').unsubscribe('*'); + + // unsubscribe - remove all collection subscriptions + pb.collection('${n}').unsubscribe(); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # init an SSE connection and start listening for messages + # (the first message is always PB_CONNECT with the connection "clientId") + curl -N '${n}/api/realtime' + + # open a new terminal and submit the subscription topic(s) + # with the "clientId" from the initial PB_CONNECT message + curl -X POST \\ + -H 'Authorization:TOKEN' \\ + -H 'Content-Type:application/json' \\ + -d '{ "clientId": "YOUR_CLIENT_ID", "subscriptions": ["${e.name}/*"] }' \\ + '${n}/api/realtime' + + # create/update/delete a record in the ${e.name} collection and + # you should see the event message(s) in the first terminal + # (as long as your client satisfies the topic API rule) + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert api-preview-alert`},t.span({className:`label method`},`GET/POST`),t.span({className:`path`},`/api/realtime`),t.div({className:`extra`},t.a({href:`https://pocketbase.io/docs/api-realtime/`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Realtime docs`}))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Event data format`)),app.components.codeBlock({value:JSON.stringify({action:`create`,record:r},null,2).replace(`"action": "create",`,`"action": "create", // create, update or delete`)}))}export{e as docsRealtime}; \ No newline at end of file diff --git a/ui/dist/assets/docsUpdate-LtD8DbWI.js b/ui/dist/assets/docsUpdate-LtD8DbWI.js new file mode 100644 index 00000000..aba347e9 --- /dev/null +++ b/ui/dist/assets/docsUpdate-LtD8DbWI.js @@ -0,0 +1,56 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";import{fullDummyPayload as r,primitivesDummyPayload as i,replaceDummyPayloadPlaceholder as a}from"./docsCreate-Be3S3y5K.js";function o(o){let s=app.utils.getApiExampleURL(),c=o.updateRule===null,l=o.type===`auth`?[`id`,`password`,`verified`,`email`,`emailVisibility`]:[`id`],u=o.fields?.filter(e=>!e.hidden&&e.type!=`autodate`&&!l.includes(e.name))||[],d={collectionId:o.id,collectionName:o.name},f=[{title:200,value:JSON.stringify(Object.assign(d,app.utils.getDummyFieldsData(o)),null,2)},{title:400,value:` + { + "status": 400, + "message": "Failed to create record.", + "data": { + "${u.find(e=>!e.primaryKey)?.name||`someField`}": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}];return c&&f.push({title:403,value:` + { + "status": 403, + "message": "Only superusers can perform this action.", + "data": {} + } + `}),f.push({title:404,value:` + { + "status": 404, + "message": "The requested resource wasn't found.", + "data": {} + } + `}),t.div({pbEvent:`apiPreviewUpdate`,className:`content`},t.p(null,`Updates an existing ${o.name} record.`),t.p(null,`Body parameters could be sent as `,t.code(null,`application/json`),` or `,t.code(null,`multipart/form-data`),`.`),t.p(null,`File upload is supported only via `,t.code(null,`multipart/form-data`),`. For more info and examples you could check the detailed `,t.a({href:`https://pocketbase.io/docs/files-handling`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Files upload and handling docs`}),`.`),t.p(null,t.em(null,`Note that in case of a password change all previously issued tokens for the current record will be automatically invalidated and if you want your user to remain signed in you need to reauthenticate manually after the update call.`)),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` +import PocketBase from 'pocketbase'; + +const pb = new PocketBase('${s}'); + +... + +// example update body +const body = ${a(JSON.stringify(r(o,!0),null,2))}; + +const record = await pb.collection('${o.name}').update('RECORD_ID', body); +`,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` +import 'package:pocketbase/pocketbase.dart'; + +final pb = PocketBase('${s}'); + +... + +// example update body +final body = ${JSON.stringify(i(o,!0),null,2)}; + +final record = await pb.collection('${o.name}').update( + 'RECORD_ID', + body: body, + files: [], +); +`,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl -X PATCH \\ + -H 'Authorization:TOKEN' \\ + -H 'Content-Type:application/json' \\ + -d '{ ... }' \\ + '${s}/api/collections/${o.name}/records/RECORD_ID' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert warning api-preview-alert`},t.span({className:`label method`},`PATCH`),t.span({className:`path`},`/api/collections/${o.name}/records/`,t.strong(null,`:id`)),()=>{if(c)return t.small({className:`extra`},`Requires superuser Authorization:TOKEN header`)}),t.table({className:`api-preview-table path-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Path params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`id`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`ID of the record to update.`)))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:f}))}export{o as docsUpdate}; \ No newline at end of file diff --git a/ui/dist/assets/docsVerification-B_Nb90xU.js b/ui/dist/assets/docsVerification-B_Nb90xU.js new file mode 100644 index 00000000..f94d13be --- /dev/null +++ b/ui/dist/assets/docsVerification-B_Nb90xU.js @@ -0,0 +1,63 @@ +function e(e){let i=app.utils.getApiExampleURL(),a=[{title:`Request verification`,content:n},{title:`Confirm verification`,content:r}],o=store({activeActionIndex:0});return t.div({pbEvent:`apiPreviewVerification`,className:`content`},t.p(null,`Sends ${e.name} account verification request.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').requestVerification('test@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + await pb.collection('${e.name}').confirmVerification('VERIFICATION_TOKEN'); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + await pb.collection('${e.name}').requestVerification('test@example.com'); + + // --- + // (optional) in your custom confirmation page: + // --- + + await pb.collection('${e.name}').confirmVerification('VERIFICATION_TOKEN'); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + # Request verification + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "email":"..." }' \\ + '${i}/api/collections/${e.name}/request-verification' + + # Confirm verification + curl -X POST \\ + -H 'Content-Type:application/json' \\ + -d '{ "token":"..." }' \\ + '${i}/api/collections/${e.name}/confirm-verification' + `}]}),t.nav({className:`btns m-t-base m-b-sm`},()=>a.map((e,n)=>t.button({type:`button`,className:()=>`btn sm expanded ${o.activeActionIndex==n?`active`:`secondary`}`,textContent:()=>e.title,onclick:()=>o.activeActionIndex=n}))),()=>a[o.activeActionIndex]?.content?.(e))}function n(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/request-verification`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`email `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The auth record email address to send the verification request (if exists).`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "email": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}]})]}function r(e){return[t.div({className:`block`},t.strong(null,`API details`)),t.div({className:`alert success api-preview-alert`},t.span({className:`label method`},`POST`),t.span({className:`path`},`/api/collections/${e.name}/confirm-verification`)),t.table({className:`api-preview-table body-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Body params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`token `,t.em(null,`(required)`)),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`The token from the verification request email.`)))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:[{title:204,value:`null`},{title:400,value:` + { + "status": 400, + "message": "An error occurred while validating the submitted data.", + "data": { + "token": { + "code": "validation_required", + "message": "Missing required value." + } + } + } + `}]})]}export{e as docsVerification}; \ No newline at end of file diff --git a/ui/dist/assets/docsView-Be6Uhvcf.js b/ui/dist/assets/docsView-Be6Uhvcf.js new file mode 100644 index 00000000..80f4de6b --- /dev/null +++ b/ui/dist/assets/docsView-Be6Uhvcf.js @@ -0,0 +1,37 @@ +import{t as e}from"./expandInfo-DGS0CLSa.js";import{t as n}from"./fieldsInfo-Bz62125-.js";function r(r){let i=app.utils.getApiExampleURL(),a=r.viewRule===null,o={collectionId:r.id,collectionName:r.name},s=[{title:200,value:JSON.stringify(Object.assign(o,app.utils.getDummyFieldsData(r)),null,2)}];return a&&s.push({title:403,value:` + { + "status": 403, + "message": "Only superusers can access this action.", + "data": {} + } + `}),s.push({title:404,value:` + { + "status": 404, + "message": "The requested resource wasn't found.", + "data": {} + } + `}),t.div({pbEvent:`apiPreviewView`,className:`content`},t.p(null,`Fetch a single ${r.name} record.`),app.components.codeBlockTabs({className:`sdk-examples m-t-sm`,historyKey:`pbLastSDK`,tabs:[{title:`JS SDK`,language:`js`,value:` + import PocketBase from 'pocketbase'; + + const pb = new PocketBase('${i}'); + + ... + + const record = await pb.collection('${r.name}').getOne('RECORD_ID', { + expand: 'relField1,relField2.subRelField', + }); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/js-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`JS SDK docs`}))},{title:`Dart SDK`,language:`dart`,value:` + import 'package:pocketbase/pocketbase.dart'; + + final pb = PocketBase('${i}'); + + ... + + final record = await pb.collection('${r.name}').getOne('RECORD_ID', + expand: 'relField1,relField2.subRelField', + ); + `,footnote:t.div({className:`txt-right`},t.a({href:`https://github.com/pocketbase/dart-sdk`,target:`_blank`,rel:`noopener noreferrer`,textContent:`Dart SDK docs`}))},{title:`curl`,language:`bash`,value:` + curl \\ + -H 'Authorization:TOKEN' \\ + '${i}/api/collections/${r.name}/records/RECORD_ID' + `}]}),t.div({className:`block m-t-base`},t.strong(null,`API details`)),t.div({className:`alert info api-preview-alert`},t.span({className:`label method`},`GET`),t.span({className:`path`},`/api/collections/${r.name}/records/`,t.strong(null,`:id`)),()=>{if(a)return t.small({className:`extra`},`Requires superuser Authorization:TOKEN header`)}),t.table({className:`api-preview-table path-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`Path params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`id`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,`ID of the record to view.`)))),t.table({className:`api-preview-table query-params`},t.thead(null,t.tr(null,t.th({className:`min-width txt-primary`},`?query params`),t.th({className:`min-width`},`Type`),t.th(null,`Description`))),t.tbody(null,t.tr(null,t.td({className:`min-width`},`expand`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,e())),t.tr(null,t.td({className:`min-width`},`fields`),t.td({className:`min-width`},t.span({className:`label`},`String`)),t.td(null,n())))),t.div({className:`block m-t-base m-b-sm`},t.strong(null,`Example responses`)),app.components.codeBlockTabs({tabs:s}))}export{r as docsView}; \ No newline at end of file diff --git a/ui/dist/assets/expandInfo-DGS0CLSa.js b/ui/dist/assets/expandInfo-DGS0CLSa.js new file mode 100644 index 00000000..9c5d2e3a --- /dev/null +++ b/ui/dist/assets/expandInfo-DGS0CLSa.js @@ -0,0 +1 @@ +function e(){return t.div({className:`api-expand-info`},t.p(null,`Auto expand record relations. For example:`),app.components.codeBlock({value:`?expand=relField1,relField2.subRelField`}),t.p(null,`Supports up to 6-levels depth nested relations expansion.`,t.br(),`The expanded relations will be appended to each individual record under the `,t.code(null,`expand`),` property (eg. `,t.code(null,`"expand": {"relField1": {...}, ...}`),`).`),t.p(null,`Only the relations to which the request user has permissions to `,t.strong(null,`view`),` will be expanded.`))}export{e as t}; \ No newline at end of file diff --git a/ui/dist/assets/fieldsInfo-Bz62125-.js b/ui/dist/assets/fieldsInfo-Bz62125-.js new file mode 100644 index 00000000..44aa70c9 --- /dev/null +++ b/ui/dist/assets/fieldsInfo-Bz62125-.js @@ -0,0 +1,3 @@ +function e(){return t.div({className:`api-fields-info`},t.p(null,`Comma separated string of the fields to return in the JSON response (by default returns all fields). For example:`),app.components.codeBlock({value:`// return all root level fields and only +// "relField.someField" from expand +?fields=*,expand.relField.someField`}),t.p(null,`Use `,t.code(null,`*`),` to target all keys from the specific depth level.`),t.p(null,`In addition, the following field modifiers are also supported:`),t.ul(null,t.li(null,t.code(null,`:excerpt(maxLength, withEllipsis?)`),t.br(),`Returns a short plain text version of the field string value. Ex.: `,t.code(null,`?fields=*,someTextField:excerpt(200,true)`))))}export{e as t}; \ No newline at end of file diff --git a/ui/dist/assets/filterSyntax-UQrUrYb5.js b/ui/dist/assets/filterSyntax-UQrUrYb5.js new file mode 100644 index 00000000..5e90c95c --- /dev/null +++ b/ui/dist/assets/filterSyntax-UQrUrYb5.js @@ -0,0 +1 @@ +function e(){let e=store({show:!1});return t.div({className:`filter-details m-t-10`},t.button({type:`button`,className:`btn secondary sm`,onclick:()=>e.show=!e.show},()=>e.show?[t.span({className:`txt`},`Hide details`),t.i({className:`ri-arrow-up-s-line`})]:[t.span({className:`txt`},`Show details`),t.i({className:`ri-arrow-down-s-line`})]),app.components.slide(()=>e.show,t.div({className:`block p-t-5`},t.p(null,`The filter syntax follows the format `,t.code(null,t.span({className:`txt-success`},`OPERAND`),t.span({className:`txt-danger`},` OPERATOR `),t.span({className:`txt-success`},`OPERAND`)),`, where:`),t.ul(null,t.li(null,t.span({className:`txt-code txt-success`},`OPERAND`),` could be any of the above field literal, function, string (single or double quoted), number, null, true, false`),t.li(null,t.span({className:`txt-code txt-danger`},`OPERATOR`),` is one of:`,t.ul(null,t.li(null,t.code({className:`filter-op`},`=`),` Equal`),t.li(null,t.code({className:`filter-op`},`!=`),` Not equal`),t.li(null,t.code({className:`filter-op`},`>`),` Greater than`),t.li(null,t.code({className:`filter-op`},`>=`),` Greater than or equal`),t.li(null,t.code({className:`filter-op`},`<`),` Less than`),t.li(null,t.code({className:`filter-op`},`<=`),` Less than or equal`),t.li(null,t.code({className:`filter-op`},`~`),` Like/Contains`,t.div({className:`txt-sm txt-hint`},t.em(null,`(auto wraps the right string OPERAND in a "%" for wildcard match if not explicitly set)`))),t.li(null,t.code({className:`filter-op`},`!~`),` NOT Like/Contains`,t.div({className:`txt-sm txt-hint`},t.em(null,`(auto wraps the right string OPERAND in a "%" for wildcard match if not explicitly set)`))),t.li(null,t.code({className:`filter-op`},`?=`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Equal`),t.li(null,t.code({className:`filter-op`},`?!=`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Not equal`),t.li(null,t.code({className:`filter-op`},`?>`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Greater than`),t.li(null,t.code({className:`filter-op`},`?>=`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Greater than or equal`),t.li(null,t.code({className:`filter-op`},`?<`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Less than`),t.li(null,t.code({className:`filter-op`},`?<=`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Less than or equal`),t.li(null,t.code({className:`filter-op`},`?~`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` Like/Contains`,t.div({className:`txt-sm txt-hint`},t.em(null,`(auto wraps the right string OPERAND in a "%" for wildcard match if not explicitly set)`))),t.li(null,t.code({className:`filter-op`},`?!~`),t.span({className:`txt-hint`},` Any/At-least-one-of`),` NOT Like/Contains`,t.div({className:`txt-sm txt-hint`},t.em(null,`(auto wraps the right string OPERAND in a "%" for wildcard match if not explicitly set)`)))),t.p(null,`To group and combine several expressions you could use brackets `,t.code(null,`(...)`),`, `,t.code(null,`&&`),`, (AND) and `,t.code(null,`||`),` (OR) tokens.`))))))}export{e as t}; \ No newline at end of file diff --git a/ui/dist/assets/index-Bk1sdyO7.js b/ui/dist/assets/index-Bk1sdyO7.js new file mode 100644 index 00000000..ab6d503a --- /dev/null +++ b/ui/dist/assets/index-Bk1sdyO7.js @@ -0,0 +1,80 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./docsList-BHALa0P4.js","./expandInfo-DGS0CLSa.js","./fieldsInfo-Bz62125-.js","./filterSyntax-UQrUrYb5.js","./docsView-Be6Uhvcf.js","./docsCreate-Be3S3y5K.js","./docsUpdate-LtD8DbWI.js","./docsListAuthMethods-9feSopQX.js","./docsAuthWithPassword-DEWj8Jyn.js","./docsAuthWithOAuth2-DUIE4EoY.js","./docsAuthWithOTP-B7z2VJzp.js","./docsAuthRefresh-UjveHHwo.js","./pageInstaller-DeCAFNnQ.js","./pocketbase.es-B_4DUNUU.js","./pageConfirmPasswordReset-9XIqssFn.js","./pageConfirmVerification-BSn_UexA.js","./pageConfirmEmailChange-DErDx8nk.js"])))=>i.map(i=>d[i]); +import{a as e,n,r,t as i}from"./pocketbase.es-B_4DUNUU.js";var a=Object.create,o=Object.defineProperty,s=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,l=Object.getPrototypeOf,u=Object.prototype.hasOwnProperty,d=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports),f=(e,n,r,i)=>{if(n&&typeof n==`object`||typeof n==`function`)for(var a=c(n),l=0,d=a.length,f;ln[e]).bind(null,f),enumerable:!(i=s(n,f))||i.enumerable});return e},p=(e,n,r)=>(r=e==null?{}:a(l(e)),f(n||!e||!e.__esModule?o(r,`default`,{value:e,enumerable:!0}):r,e));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))r(e);new MutationObserver(e=>{for(let n of e)if(n.type===`childList`)for(let e of n.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&r(e)}).observe(document,{childList:!0,subtree:!0});function n(e){let n={};return e.integrity&&(n.integrity=e.integrity),e.referrerPolicy&&(n.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?n.credentials=`include`:e.crossOrigin===`anonymous`?n.credentials=`omit`:n.credentials=`same-origin`,n}function r(e){if(e.ep)return;e.ep=!0;let r=n(e);fetch(e.href,r)}})();var m=`abcdefghijklmnopqrstuvwxyz0123456789`,h=`pb_redirect`,g=store({hash:window.location.hash});window.addEventListener(`hashchange`,()=>{g.hash=window.location.hash}),Prism.languages.pbrule={string:Prism.languages.js.string,number:Prism.languages.js.number,function:Prism.languages.js.function,boolean:/\b(?:true|false)\b/i,constant:/\b(?:null)\b/i,comment:{pattern:/\/\/.*/,greedy:!0},italic:/_via_|\:\w+/,keyword:/&&|\|\||\??(?:!~|!=|>=|<=|=|~|>|>|<)(?=[@\w\s]|$)/};var _={isObject(e){return typeof e==`object`&&!!e&&e.constructor===Object},isEmpty(e){return e==null||e===``||Array.isArray(e)&&e.length===0||typeof e==`object`&&app.utils.isEmptyObject(e)},isEmptyObject(e){for(let n in e)return!1;return!0},toArray(e,n=!1){return Array.isArray(e)?e.slice():(n||!_.isEmpty(e))&&e!==void 0?[e]:[]},removeByValue(e,n){if(!Array.isArray(e)){console.warn(`[removeByValue] not an array:`,e);return}for(let r=e.length-1;r>=0;r--)if(e[r]==n){e.splice(r,1);break}},removeByKey(e,n,r){if(!Array.isArray(e)){console.warn(`[removeByKey] not an array:`,e);return}for(let i in e)if(e[i][n]==r){e.splice(i,1);break}},pushUnique(e,n){if(!Array.isArray(e)){console.warn(`[pushUnique] not an array:`,e);return}e.includes(n)||e.push(n)},mergeUnique(e,n){for(let r of n)app.utils.pushUnique(e,r);return e},pushOrReplaceObject(e,n,r=`id`){for(let i=e.length-1;i>=0;i--)if(e[i][r]==n[r]){e[i]=n;return}e.push(n)},filterDuplicatesByKey(e,n=`id`){e=Array.isArray(e)?e:[];let r={};for(let i of e)r[i[n]]=i;return Object.values(r)},filterRedactedProps(e,n=`******`){let r=JSON.parse(JSON.stringify(e||{}));for(let e in r)typeof r[e]==`object`&&r[e]!==null?r[e]=_.filterRedactedProps(r[e],n):r[e]===n&&delete r[e];return r},getByPath(e,n,r=null,i=`.`){let a=e||{},o=(n||``).split(i);for(let e of o){if(!_.isObject(a)&&!Array.isArray(a)||a[e]===void 0)return r;a=a[e]}return a},setByPath(e,n,r,i=`.`){if(typeof e!=`object`||!e){console.warn(`setByPath: data not an object or array.`);return}let a=e,o=n.split(i),s=o.pop();for(let e of o)(!_.isObject(a)&&!Array.isArray(a)||!_.isObject(a[e])&&!Array.isArray(a[e]))&&(a[e]={}),a=a[e];a[s]=r},deleteByPath(e,n,r=`.`){let i=e||{},a=(n||``).split(r),o=a.pop();for(let e of a)(!_.isObject(i)&&!Array.isArray(i)||!_.isObject(i[e])&&!Array.isArray(i[e]))&&(i[e]={}),i=i[e];Array.isArray(i)?i.splice(o,1):_.isObject(i)&&delete i[o],a.length>0&&(Array.isArray(i)&&!i.length||_.isObject(i)&&!Object.keys(i).length)&&(Array.isArray(e)&&e.length>0||_.isObject(e)&&Object.keys(e).length>0)&&_.deleteByPath(e,a.join(r),r)},emptyClone(e,n=[]){let r=JSON.parse(JSON.stringify(e));for(let e in r)n.includes(e)||(typeof r[e]==`string`?r[e]=``:typeof r[e]==`number`?r[e]=0:Array.isArray(r[e])?r[e]=[]:app.utils.isObject(r[e])&&(r[e]={}));return r},randomString(e=8,n=m){let r=``;for(let i=0;i`u`)return app.utils.randomString(e);let n=new Uint8Array(e);crypto.getRandomValues(n);let r=``;for(let i=0;i`,`>`).replaceAll(`"`,`"`).replaceAll(`'`,`'`):``},plainText(e){return e?(new DOMParser().parseFromString(e,`text/html`).body.textContent||``).trim():``},truncate(e,n=150,r=!0){if(e=``+e,e.length<=n)return e;if(e=e.slice(0,n),r){for(;e.endsWith(`.`);)e=e.slice(0,-1);e+=`...`}return e},truncateObject(e,n=150,r=!0){let i=Array.isArray(e)?[]:{};for(let a in e){let o=e[a];typeof o==`string`?o=app.utils.truncate(o,n,r):(Array.isArray(o)||app.utils.isObject(o))&&(o=app.utils.truncateObject(o,n,r)),i[a]=o}return i},stringifyValue(e,n=`N/A`,r=150){if(_.isEmpty(e))return n;if(typeof e==`number`)return``+e;if(typeof e==`boolean`)return e?`True`:`False`;if(typeof e==`string`)return e=e.indexOf(`<`)>=0?_.plainText(e):e,_.truncate(e,r)||n;if(Array.isArray(e)&&typeof e[0]!=`object`)return _.truncate(e.join(`,`),r);if(typeof e==`object`)try{return _.truncate(JSON.stringify(e),r)||n}catch{return n}return e},splitNonEmpty(e,n=`,`){let r=(e||``).split(n),i=[];for(let e of r)e=e.trim(),_.isEmpty(e)||i.push(e);return i},joinNonEmpty(e,n=`, `){e||=[];let r=[];for(let n of e)n=typeof n==`string`?n.trim():n,_.isEmpty(n)||r.push(``+n);return r.join(n)},formattedFileSize(e){let n=e?Math.floor(Math.log(e)/Math.log(1024)):0;return(e/1024**n).toFixed(2)*1+` `+[`B`,`KB`,`MB`,`GB`,`TB`][n]},toRFC3339Datetime(e){if(!e)return``;let n;return n=e instanceof Date?e:typeof e==`string`?new Date(e.replace(` `,`T`)):new Date(e),n.toISOString().replace(`T`,` `)},toLocalDatetime(e){if(!e)return``;let n;n=e instanceof Date?e:typeof e==`string`?new Date(e.replace(` `,`T`)):new Date(e);let r=n.getFullYear();return isNaN(r)?``:`${r}-${(n.getMonth()+1).toString().padStart(2,`0`)}-${n.getDate().toString().padStart(2,`0`)} ${n.getHours().toString().padStart(2,`0`)}:${n.getMinutes().toString().padStart(2,`0`)}:${n.getSeconds().toString().padStart(2,`0`)}.${n.getMilliseconds().toString().padStart(3,`0`)}`},toDatetimeLocalInputValue(e){if(!e)return``;let n;n=e instanceof Date?e:typeof e==`string`?new Date(e.replaceAll(` `,`T`)):new Date(e);let r=n.getFullYear();return isNaN(r)?``:`${r}-${(n.getMonth()+1).toString().padStart(2,`0`)}-${n.getDate().toString().padStart(2,`0`)}T${n.getHours().toString().padStart(2,`0`)}:${n.getMinutes().toString().padStart(2,`0`)}:${n.getSeconds().toString().padStart(2,`0`)}`},async copyToClipboard(e){if(e=e==null?``:e instanceof Date?e.toISOString():typeof e==`object`?JSON.stringify(e):``+e,!(!e.length||!window.navigator?.clipboard))return window.navigator.clipboard.writeText(e).catch(e=>{console.warn(`Failed to copy.`,e)})},download(e,n){let r=document.createElement(`a`);r.setAttribute(`href`,e),r.setAttribute(`download`,n),r.setAttribute(`target`,`_blank`),r.setAttribute(`rel`,`noopener noreferrer`),r.click(),r=null},downloadJSON(e,n){n=n.endsWith(`.json`)?n:n+`.json`;let r=new Blob([JSON.stringify(e,null,2)],{type:`application/json`}),i=window.URL.createObjectURL(r);_.download(i,n)},getApiExampleURL(){let e;if(app.pb.baseURL.startsWith(`http://`)||app.pb.baseURL.startsWith(`https://`))e=app.pb.baseURL;else{e=window.location.href;let n=e.indexOf(`/_/`);e=n>=0?e.substring(0,n):window.location.origin}return e.replace(`//localhost`,`//127.0.0.1`)},isActivePath(e,n=!0,r=``){r||=g.hash;let i;return i=RegExp(n?`^`+RegExp.escape(e)+`\\/?.*$`:`^`+RegExp.escape(e)+`\\/?(?:\\?.+)?$`),i.test(r)},getHashQueryParams(e=``){e||=g.hash;let n=``,r=e.indexOf(`?`);return r>-1&&(n=window.location.hash.substring(r+1)),Object.fromEntries(new URLSearchParams(n))},replaceHashQueryParams(e,n=null){e||={};let r=``,i=window.location.hash,a=i.indexOf(`?`);a>-1&&(r=i.substring(a+1),i=i.substring(0,a));let o=new URLSearchParams(r);for(let n in e){let r=e[n];_.isEmpty(r)?o.delete(n):o.set(n,r)}r=o.toString(),r!=``&&(i+=`?`+r);let s=window.location.href,c=s.indexOf(`#`);c>-1&&(s=s.substring(0,c));let l=s+i;return n===!1||(n===!0?window.history.pushState(null,``,l):window.history.replaceState(null,``,l)),l},rememberPath(){window.localStorage.setItem(h,window.location.hash)},toRememberedPath(e=`#/collections`){let n=window.localStorage.getItem(h);n&&window.localStorage.removeItem(h),window.location.hash=n||e},getLocalHistory(e,n=null){try{let r=window.localStorage.getItem(e);if(r)return JSON.parse(r)||n}catch(n){console.log(`failed to load local history:`,e,n)}return n},saveLocalHistory(e,n){try{app.utils.isEmpty(n)?window.localStorage.removeItem(e):typeof n==`string`?window.localStorage.setItem(e,n):window.localStorage.setItem(e,JSON.stringify(n))}catch(n){console.log(`failed to save local history:`,e,n)}},generateThumb(e,n=100,r=100){return new Promise(i=>{let a=new FileReader;a.onload=function(a){let o=new Image;o.onload=function(){let a=document.createElement(`canvas`),s=a.getContext(`2d`),c=o.width,l=o.height;return a.width=n,a.height=r,s.drawImage(o,c>l?(c-l)/2:0,0,c>l?l:c,c>l?l:c,0,0,n,r),i(a.toDataURL(e.type))},o.src=a.target.result},a.readAsDataURL(e)})},normalizeSearchFilter(e,n=[]){if(e=(e||``).trim(),!e||!n.length)return e;for(let n of[`=`,`!=`,`~`,`!~`,`>`,`>=`,`<`,`<=`])if(e.includes(n))return e;return e=isNaN(e)&&e!=`true`&&e!=`false`?`"${e.replace(/^[\"\'\`]|[\"\'\`]$/gm,``)}"`:e,n.map(n=>`${n}~${e}`).join(`||`)},logLevels:{[-4]:{label:`DEBUG`,class:``},0:{label:`INFO`,class:`success`},4:{label:`WARN`,class:`warning`},8:{label:`ERROR`,class:`danger`}},logDataFormatters:{execTime:function(e){return e?.data?.execTime===void 0?`N/A`:e.data.execTime+`ms`}},extendStore(e,n={},...r){let i=[];for(let a in n){let o=n[a];typeof e.__raw?.[a]==`function`||typeof o!=`function`||a.length>2&&a.startsWith(`on`)||r.includes(a)?e[a]=o:i.push(watch(o,n=>{e[a]=n}))}return i},cssTimeToMs(e){return e?(e=e.toLowerCase(),e.endsWith(`ms`)?Number(e.substring(0,e.length-2)):e.endsWith(`s`)?Number(e.substring(0,e.length-1)):Number(e)||0):0},isDarkEnoughForWhiteText(e){if(e=e?.startsWith(`#`)?e.substring(1):e,e?.length!=6)return!1;let n=parseInt(e.substring(0,2),16),r=parseInt(e.substring(2,4),16),i=parseInt(e.substring(4,6),16);return(n*299+r*587+i*114)/1e3<128},imageExtensions:[`.jpg`,`.jpeg`,`.png`,`.svg`,`.gif`,`.jfif`,`.webp`,`.avif`],videoExtensions:[`.mp4`,`.avi`,`.mov`,`.3gp`,`.wmv`],audioExtensions:[`.aa`,`.aac`,`.m4v`,`.mp3`,`.ogg`,`.oga`,`.mogg`,`.amr`],documentExtensions:[`.pdf`,`.doc`,`.docx`,`.xls`,`.xlsx`,`.ppt`,`.pptx`,`.odp`,`.odt`,`.ods`,`.txt`],hasImageExtension(e){return e=(e||``).toLowerCase(),!!app.utils.imageExtensions.find(n=>e.endsWith(n))},hasVideoExtension(e){return e=(e||``).toLowerCase(),!!app.utils.videoExtensions.find(n=>e.endsWith(n))},hasAudioExtension(e){return e=(e||``).toLowerCase(),!!app.utils.audioExtensions.find(n=>e.endsWith(n))},hasDocumentExtension(e){return e=(e||``).toLowerCase(),!!app.utils.documentExtensions.find(n=>e.endsWith(n))},getFileType(e){return app.utils.hasImageExtension(e)?`image`:app.utils.hasVideoExtension(e)?`video`:app.utils.hasAudioExtension(e)?`audio`:app.utils.hasDocumentExtension(e)?`document`:`file`},fileTypeIcons:{image:`ri-image-line`,video:`ri-movie-line`,audio:`ri-music-2-line`,document:`ri-file-line`,file:`ri-file-line`},fallbackFieldIcon:`ri-puzzle-line`,fallbackCollectionIcon:`ri-puzzle-line`,fallbackProviderIcon:`ri-puzzle-line`,fallbackPresentableProps:[`title`,`name`,`slug`,`email`,`username`,`nickname`,`displayName`,`label`,`subject`,`topic`,`message`,`heading`,`headline`,`header`,`caption`,`key`,`identifier`,`id`],sortedCollections(e=[]){let n,r;function i(e,i){return n=e.name.startsWith(`_`),r=i.name.startsWith(`_`),n&&!r?1:!n&&r?-1:e.name>i.name?1:e.namee?.id&&!a.find(n=>n.id==e.id)),s=a.filter(e=>e?.id&&!i.find(n=>n.id==e.id)),c=a.filter(e=>{let n=app.utils.isObject(e)&&i.find(n=>n.id==e.id);if(!n)return!1;for(let r in n)if(JSON.stringify(e[r])!=JSON.stringify(n[r]))return!0;return!1});return!!(s.length||c.length||r&&o.length)},extractColumnsFromQuery(e){let n=`__PBGROUP__`;e=(e||``).replace(/\([\s\S]+?\)/gm,n).replace(/[\t\r\n]|(?:\s\s)+/g,` `);let r=e.match(/select\s+([\s\S]+)\s+from/)?.[1]?.split(`,`)||[],i=[];for(let e of r){let r=e.trim().split(` `).pop();r!=``&&r!=n&&i.push(r.replace(/[\'\"\`\[\]\s]/g,``))}return i},getAllCollectionIdentifiers(e,n=``){if(!e)return[];let r=[n+`id`],i=e.type==`auth`;if(e.type===`view`)for(let i of app.utils.extractColumnsFromQuery(e.viewQuery))app.utils.pushUnique(r,n+i);let a=e.fields||[];for(let e of a)if(!(e.type==`password`||i&&e.name==`tokenKey`))if(app.fieldTypes[e.type]?.identifierExtractor){let i=app.utils.toArray(app.fieldTypes[e.type]?.identifierExtractor(e,n));for(let e of i)app.utils.pushUnique(r,e)}else app.utils.pushUnique(r,n+e.name);return r},getDummyFieldsData(e,n=!1){let r=e?.fields||[],i={};for(let e of r)if(!e.hidden)if(app.fieldTypes[e.type]?.dummyData){let r=app.fieldTypes[e.type].dummyData(e,n);r!==void 0&&(i[e.name]=r)}else i[e.name]=`[[DATA]]`;return i},parseIndex(e){let n={unique:!1,optional:!1,schemaName:``,indexName:``,tableName:``,columns:[],where:``},r=/create\s+(unique\s+)?\s*index\s*(if\s+not\s+exists\s+)?(\S*)\s+on\s+(\S*)\s*\(([\s\S]*)\)(?:\s*where\s+([\s\S]*))?/gim.exec((e||``).trim());if(r?.length!=7)return n;let i=/^[\"\'\`\[\{}]|[\"\'\`\]\}]$/gm;n.unique=r[1]?.trim().toLowerCase()===`unique`,n.optional=!app.utils.isEmpty(r[2]?.trim());let a=(r[3]||``).split(`.`);a.length==2?(n.schemaName=a[0].replace(i,``),n.indexName=a[1].replace(i,``)):(n.schemaName=``,n.indexName=a[0].replace(i,``)),n.tableName=(r[4]||``).replace(i,``);let o=(r[5]||``).replace(/,(?=[^\(]*\))/gim,`{PB_TEMP}`).split(`,`);for(let e of o){e=e.trim().replaceAll(`{PB_TEMP}`,`,`);let r=/^([\s\S]+?)(?:\s+collate\s+([\w]+))?(?:\s+(asc|desc))?$/gim.exec(e);if(r?.length!=4)continue;let a=r[1]?.trim()?.replace(i,``);a&&n.columns.push({name:a,collate:r[2]||``,sort:r[3]?.toUpperCase()||``})}return n.where=r[6]||``,n},buildIndex(e){let n=`CREATE `;e.unique&&(n+=`UNIQUE `),n+=`INDEX `,e.optional&&(n+=`IF NOT EXISTS `),e.schemaName&&(n+=`\`${e.schemaName}\`.`),n+=`\`${e.indexName||`idx_`+app.utils.randomString(10)}\` `,n+=`ON \`${e.tableName}\` (`;let r=e.columns.filter(e=>!!e?.name);return r.length>1&&(n+=` + `),n+=r.map(e=>{let n=``;return e.name.includes(`(`)||e.name.includes(` `)?n+=e.name:n+="`"+e.name+"`",e.collate&&(n+=` COLLATE `+e.collate),e.sort&&(n+=` `+e.sort.toUpperCase()),n}).join(`, + `),r.length>1&&(n+=` +`),n+=`)`,e.where&&(n+=` WHERE ${e.where}`),n},replaceIndexFields(e,n){let r=app.utils.parseIndex(e);return typeof n==`function`?Object.assign(r,n(r)||{}):Object.assign(r,n||{}),app.utils.buildIndex(r)},replaceIndexColumn(e,n,r){if(n===r)return e;let i=app.utils.parseIndex(e),a=!1;for(let e of i.columns)e.name===n&&(e.name=r,a=!0);return a?app.utils.buildIndex(i):e}};window.app=window.app||{},window.app.utils=_,window.app=window.app||{},window.app.utils=window.app.utils||{},window.app.utils.mimeTypes=[{ext:``,mimeType:`application/octet-stream`},{ext:`.xpm`,mimeType:`image/x-xpixmap`},{ext:`.7z`,mimeType:`application/x-7z-compressed`},{ext:`.zip`,mimeType:`application/zip`},{ext:`.xlsx`,mimeType:`application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`},{ext:`.docx`,mimeType:`application/vnd.openxmlformats-officedocument.wordprocessingml.document`},{ext:`.pptx`,mimeType:`application/vnd.openxmlformats-officedocument.presentationml.presentation`},{ext:`.epub`,mimeType:`application/epub+zip`},{ext:`.apk`,mimeType:`application/vnd.android.package-archive`},{ext:`.jar`,mimeType:`application/jar`},{ext:`.odt`,mimeType:`application/vnd.oasis.opendocument.text`},{ext:`.ott`,mimeType:`application/vnd.oasis.opendocument.text-template`},{ext:`.ods`,mimeType:`application/vnd.oasis.opendocument.spreadsheet`},{ext:`.ots`,mimeType:`application/vnd.oasis.opendocument.spreadsheet-template`},{ext:`.odp`,mimeType:`application/vnd.oasis.opendocument.presentation`},{ext:`.otp`,mimeType:`application/vnd.oasis.opendocument.presentation-template`},{ext:`.odg`,mimeType:`application/vnd.oasis.opendocument.graphics`},{ext:`.otg`,mimeType:`application/vnd.oasis.opendocument.graphics-template`},{ext:`.odf`,mimeType:`application/vnd.oasis.opendocument.formula`},{ext:`.odc`,mimeType:`application/vnd.oasis.opendocument.chart`},{ext:`.sxc`,mimeType:`application/vnd.sun.xml.calc`},{ext:`.pdf`,mimeType:`application/pdf`},{ext:`.fdf`,mimeType:`application/vnd.fdf`},{ext:``,mimeType:`application/x-ole-storage`},{ext:`.msi`,mimeType:`application/x-ms-installer`},{ext:`.aaf`,mimeType:`application/octet-stream`},{ext:`.msg`,mimeType:`application/vnd.ms-outlook`},{ext:`.xls`,mimeType:`application/vnd.ms-excel`},{ext:`.pub`,mimeType:`application/vnd.ms-publisher`},{ext:`.ppt`,mimeType:`application/vnd.ms-powerpoint`},{ext:`.doc`,mimeType:`application/msword`},{ext:`.ps`,mimeType:`application/postscript`},{ext:`.psd`,mimeType:`image/vnd.adobe.photoshop`},{ext:`.p7s`,mimeType:`application/pkcs7-signature`},{ext:`.ogg`,mimeType:`application/ogg`},{ext:`.oga`,mimeType:`audio/ogg`},{ext:`.ogv`,mimeType:`video/ogg`},{ext:`.png`,mimeType:`image/png`},{ext:`.png`,mimeType:`image/vnd.mozilla.apng`},{ext:`.jpg`,mimeType:`image/jpeg`},{ext:`.jxl`,mimeType:`image/jxl`},{ext:`.jp2`,mimeType:`image/jp2`},{ext:`.jpf`,mimeType:`image/jpx`},{ext:`.jpm`,mimeType:`image/jpm`},{ext:`.jxs`,mimeType:`image/jxs`},{ext:`.gif`,mimeType:`image/gif`},{ext:`.webp`,mimeType:`image/webp`},{ext:`.exe`,mimeType:`application/vnd.microsoft.portable-executable`},{ext:``,mimeType:`application/x-elf`},{ext:``,mimeType:`application/x-object`},{ext:``,mimeType:`application/x-executable`},{ext:`.so`,mimeType:`application/x-sharedlib`},{ext:``,mimeType:`application/x-coredump`},{ext:`.a`,mimeType:`application/x-archive`},{ext:`.deb`,mimeType:`application/vnd.debian.binary-package`},{ext:`.tar`,mimeType:`application/x-tar`},{ext:`.xar`,mimeType:`application/x-xar`},{ext:`.bz2`,mimeType:`application/x-bzip2`},{ext:`.fits`,mimeType:`application/fits`},{ext:`.tiff`,mimeType:`image/tiff`},{ext:`.bmp`,mimeType:`image/bmp`},{ext:`.ico`,mimeType:`image/x-icon`},{ext:`.mp3`,mimeType:`audio/mpeg`},{ext:`.flac`,mimeType:`audio/flac`},{ext:`.midi`,mimeType:`audio/midi`},{ext:`.ape`,mimeType:`audio/ape`},{ext:`.mpc`,mimeType:`audio/musepack`},{ext:`.amr`,mimeType:`audio/amr`},{ext:`.wav`,mimeType:`audio/wav`},{ext:`.aiff`,mimeType:`audio/aiff`},{ext:`.au`,mimeType:`audio/basic`},{ext:`.mpeg`,mimeType:`video/mpeg`},{ext:`.mov`,mimeType:`video/quicktime`},{ext:`.mp4`,mimeType:`video/mp4`},{ext:`.avif`,mimeType:`image/avif`},{ext:`.3gp`,mimeType:`video/3gpp`},{ext:`.3g2`,mimeType:`video/3gpp2`},{ext:`.mp4`,mimeType:`audio/mp4`},{ext:`.mqv`,mimeType:`video/quicktime`},{ext:`.m4a`,mimeType:`audio/x-m4a`},{ext:`.m4v`,mimeType:`video/x-m4v`},{ext:`.heic`,mimeType:`image/heic`},{ext:`.heic`,mimeType:`image/heic-sequence`},{ext:`.heif`,mimeType:`image/heif`},{ext:`.heif`,mimeType:`image/heif-sequence`},{ext:`.mj2`,mimeType:`video/mj2`},{ext:`.dvb`,mimeType:`video/vnd.dvb.file`},{ext:`.webm`,mimeType:`video/webm`},{ext:`.avi`,mimeType:`video/x-msvideo`},{ext:`.flv`,mimeType:`video/x-flv`},{ext:`.mkv`,mimeType:`video/x-matroska`},{ext:`.asf`,mimeType:`video/x-ms-asf`},{ext:`.asf`,mimeType:`video/x-ms-wmv`},{ext:`.asf`,mimeType:`video/asf`},{ext:`.aac`,mimeType:`audio/aac`},{ext:`.voc`,mimeType:`audio/x-unknown`},{ext:`.m3u`,mimeType:`application/vnd.apple.mpegurl`},{ext:`.rmvb`,mimeType:`application/vnd.rn-realmedia-vbr`},{ext:`.gz`,mimeType:`application/gzip`},{ext:`.class`,mimeType:`application/x-java-applet`},{ext:`.swf`,mimeType:`application/x-shockwave-flash`},{ext:`.crx`,mimeType:`application/x-chrome-extension`},{ext:`.ttf`,mimeType:`font/ttf`},{ext:`.woff`,mimeType:`font/woff`},{ext:`.woff2`,mimeType:`font/woff2`},{ext:`.otf`,mimeType:`font/otf`},{ext:`.ttc`,mimeType:`font/collection`},{ext:`.eot`,mimeType:`application/vnd.ms-fontobject`},{ext:`.wasm`,mimeType:`application/wasm`},{ext:`.shx`,mimeType:`application/vnd.shx`},{ext:`.shp`,mimeType:`application/vnd.shp`},{ext:`.dbf`,mimeType:`application/x-dbf`},{ext:`.dcm`,mimeType:`application/dicom`},{ext:`.rar`,mimeType:`application/x-rar-compressed`},{ext:`.djvu`,mimeType:`image/vnd.djvu`},{ext:`.mobi`,mimeType:`application/x-mobipocket-ebook`},{ext:`.lit`,mimeType:`application/x-ms-reader`},{ext:`.bpg`,mimeType:`image/bpg`},{ext:`.cbor`,mimeType:`application/cbor`},{ext:`.sqlite`,mimeType:`application/vnd.sqlite3`},{ext:`.dwg`,mimeType:`image/vnd.dwg`},{ext:`.nes`,mimeType:`application/vnd.nintendo.snes.rom`},{ext:`.lnk`,mimeType:`application/x-ms-shortcut`},{ext:`.macho`,mimeType:`application/x-mach-binary`},{ext:`.qcp`,mimeType:`audio/qcelp`},{ext:`.icns`,mimeType:`image/x-icns`},{ext:`.hdr`,mimeType:`image/vnd.radiance`},{ext:`.mrc`,mimeType:`application/marc`},{ext:`.mdb`,mimeType:`application/x-msaccess`},{ext:`.accdb`,mimeType:`application/x-msaccess`},{ext:`.zst`,mimeType:`application/zstd`},{ext:`.cab`,mimeType:`application/vnd.ms-cab-compressed`},{ext:`.rpm`,mimeType:`application/x-rpm`},{ext:`.xz`,mimeType:`application/x-xz`},{ext:`.lz`,mimeType:`application/lzip`},{ext:`.torrent`,mimeType:`application/x-bittorrent`},{ext:`.cpio`,mimeType:`application/x-cpio`},{ext:``,mimeType:`application/tzif`},{ext:`.xcf`,mimeType:`image/x-xcf`},{ext:`.pat`,mimeType:`image/x-gimp-pat`},{ext:`.gbr`,mimeType:`image/x-gimp-gbr`},{ext:`.glb`,mimeType:`model/gltf-binary`},{ext:`.cab`,mimeType:`application/x-installshield`},{ext:`.jxr`,mimeType:`image/jxr`},{ext:`.parquet`,mimeType:`application/vnd.apache.parquet`},{ext:`.txt`,mimeType:`text/plain`},{ext:`.html`,mimeType:`text/html`},{ext:`.svg`,mimeType:`image/svg+xml`},{ext:`.xml`,mimeType:`text/xml`},{ext:`.rss`,mimeType:`application/rss+xml`},{ext:`.atom`,mimeType:`application/atom+xml`},{ext:`.x3d`,mimeType:`model/x3d+xml`},{ext:`.kml`,mimeType:`application/vnd.google-earth.kml+xml`},{ext:`.xlf`,mimeType:`application/x-xliff+xml`},{ext:`.dae`,mimeType:`model/vnd.collada+xml`},{ext:`.gml`,mimeType:`application/gml+xml`},{ext:`.gpx`,mimeType:`application/gpx+xml`},{ext:`.tcx`,mimeType:`application/vnd.garmin.tcx+xml`},{ext:`.amf`,mimeType:`application/x-amf`},{ext:`.3mf`,mimeType:`application/vnd.ms-package.3dmanufacturing-3dmodel+xml`},{ext:`.xfdf`,mimeType:`application/vnd.adobe.xfdf`},{ext:`.owl`,mimeType:`application/owl+xml`},{ext:`.php`,mimeType:`text/x-php`},{ext:`.js`,mimeType:`text/javascript`},{ext:`.lua`,mimeType:`text/x-lua`},{ext:`.pl`,mimeType:`text/x-perl`},{ext:`.py`,mimeType:`text/x-python`},{ext:`.json`,mimeType:`application/json`},{ext:`.geojson`,mimeType:`application/geo+json`},{ext:`.har`,mimeType:`application/json`},{ext:`.ndjson`,mimeType:`application/x-ndjson`},{ext:`.rtf`,mimeType:`text/rtf`},{ext:`.srt`,mimeType:`application/x-subrip`},{ext:`.tcl`,mimeType:`text/x-tcl`},{ext:`.csv`,mimeType:`text/csv`},{ext:`.tsv`,mimeType:`text/tab-separated-values`},{ext:`.vcf`,mimeType:`text/vcard`},{ext:`.ics`,mimeType:`text/calendar`},{ext:`.warc`,mimeType:`application/warc`},{ext:`.vtt`,mimeType:`text/vtt`},{ext:`.pbm`,mimeType:`image/x-portable-bitmap`},{ext:`.pgm`,mimeType:`image/x-portable-graymap`},{ext:`.ppm`,mimeType:`image/x-portable-pixmap`},{ext:`.eml`,mimeType:`message/rfc822`}];var v=new BroadcastChannel(`tabsSync`),ee=`pbSettings`,te=`pbColorScheme`;window.app=window.app||{},window.app.store=store({_ready:!1,superuser:null,showHeader:!0,page:t.div({className:`page`},()=>{if(!app.store._ready)return t.span({className:`loader lg m-auto`,title:`Loading plugins...`})}),mainLogo:`./images/logo.svg`,headerLogo:`./images/logo_white.svg`,favicon:``,title:``,_mediaColorScheme:``,userColorScheme:window.localStorage.getItem(te)||``,get activeColorScheme(){return app.store.userColorScheme?app.store.userColorScheme:app.store._mediaColorScheme||`light`},errors:null,creditLinks:[{href:`https://pocketbase.io/docs`,icon:`ri-book-open-line`,label:`Docs`},{href:`https://github.com/pocketbase/pocketbase/releases`,icon:`ri-github-line`,label:`PocketBase v0.37.0`}],headerLinks:[{href:`#/collections`,icon:`ri-database-2-line`,label:`Collections`},{href:`#/logs`,icon:`ri-bar-chart-box-line`,label:`Logs`},{href:`#/settings`,icon:`ri-settings-3-line`,label:`Settings`}],settingsNavGroups:{System:[{href:`#/settings`,icon:`ri-home-gear-line`,label:`Application`},{href:`#/settings/mail`,icon:`ri-send-plane-2-line`,label:`Mail settings`},{href:`#/settings/storage`,icon:`ri-archive-drawer-line`,label:`Files storage`},{href:`#/settings/backups`,icon:`ri-archive-line`,label:`Backups`},{href:`#/settings/crons`,icon:`ri-time-line`,label:`Crons`}],Sync:[{href:`#/settings/export-collections`,icon:`ri-uninstall-line`,label:`Export collections`},{href:`#/settings/import-collections`,icon:`ri-install-line`,label:`Import collections`}]},predefinedAccentColors:[`#1055c9`,`#a3142a`,`#096d5c`,`#e6620a`,`#007d9c`,`#3f3da9`],settings:app.utils.getLocalHistory(ee,{}),isLoadingSettings:!1,async loadSettings(){app.store.isLoadingSettings=!0;try{let e=await app.pb.settings.getAll({requestKey:`appStore.loadSettings`});app.store.settings=e,app.store.isLoadingSettings=!1}catch(e){e.isAbort||(app.store.isLoadingSettings=!1,app.checkApiError(e))}},collections:[],collectionScaffolds:{},isLoadingCollections:!1,_activeCollectionIdOrName:``,get activeCollection(){let e=app.store._activeCollectionIdOrName;return app.store.collections.find(n=>n.id==e||n.name==e)||app.store.collections[0]},set activeCollection(e){typeof e==`string`?app.store._activeCollectionIdOrName=e:app.store._activeCollectionIdOrName=e?.id},async silentlyReloadCollections(){try{let e=await app.pb.collections.getFullList({requestKey:`appStore.silentlyReloadCollections`});e=app.utils.sortedCollectionsByType(e),JSON.stringify(e)!=JSON.stringify(app.store.collections)&&(app.store.collections=e)}catch(e){e.isAbort||console.warn(`failed to reload app store collections:`,e)}},async loadCollections(e=null){app.store.isLoadingCollections=!0;try{let[n,r]=await Promise.all([app.pb.collections.getScaffolds({requestKey:`appStore.loadCollections.getScaffolds`}),app.pb.collections.getFullList({requestKey:`appStore.loadCollections.getFullList`})]);app.store.collections=app.utils.sortedCollectionsByType(r),app.store.collectionScaffolds=n,app.store._activeCollectionIdOrName=e||app.store._activeCollectionIdOrName||app.store.collections[0]?.id||``,app.store.isLoadingCollections=!1}catch(e){e.isAbort||(app.store.isLoadingCollections=!1,app.checkApiError(e))}},addOrUpdateCollection(e){let n=app.store.collections.findIndex(n=>n.id==e.id);n>=0?(app.store.activeCollection.id==e.id&&(app.store._activeCollectionIdOrName=e.id),app.store.collections[n]=e):app.store.collections.push(e),app.store.collections=app.utils.sortedCollectionsByType(app.store.collections)},oauth2Providers:[],isLoadingOAuth2Providers:!1,async loadOAuth2Providers(){app.store.isLoadingOAuth2Providers=!0;try{app.store.oauth2Providers=await app.pb.send(`/api/collections/meta/oauth2-providers`),app.store.isLoadingOAuth2Providers=!1}catch(e){e.isAbort||(app.checkApiError(e),app.store.isLoadingOAuth2Providers=!1)}}}),window.addEventListener(`hashchange`,()=>{app.store.title=``,app.store.errors=null}),watch(()=>{let e=app.utils.toArray(app.store.title),n=app.store.settings?.meta?.appName||``;n&&e.push(n),document.title=e.join(` - `)});var ne;watch(()=>app.store.settings?.meta?.accentColor,e=>{ne||(ne=t.meta({name:`theme-color`}),document.head.appendChild(ne)),e?(ne?.setAttribute(`content`,e),document.documentElement.style.setProperty(`--accentColor`,e)):(ne?.removeAttribute(`content`),document.documentElement.style.removeProperty(`--accentColor`))});var re;watch(()=>app.store.favicon,e=>{re||(re=t.link({rel:`icon`}),document.head.appendChild(re)),e?re.href=e:re.href=window.location.href.startsWith(`https://`)?`./images/favicon_prod.png`:`./images/favicon.png`});var ie=window.matchMedia(`(prefers-color-scheme: dark)`);app.store._mediaColorScheme=ie.matches?`dark`:`light`,ie.addEventListener(`change`,({matches:e})=>{app.store._mediaColorScheme=e?`dark`:`light`}),watch(()=>app.store.userColorScheme,e=>{e?window.localStorage.setItem(te,e):window.localStorage.removeItem(te),v?.postMessage({colorScheme:e})});var ae;watch(()=>app.store.activeColorScheme,e=>{clearTimeout(ae),document.documentElement.style.setProperty(`--animationSpeed`,`0`),document.documentElement.setAttribute(`data-color-scheme`,e),ae=setTimeout(()=>{document.documentElement.style.removeProperty(`--animationSpeed`)},100)});function oe(e,n){e.__errListener&&=(e.removeEventListener(`input`,e.__errListener),e.removeEventListener(`change`,e.__errListener),null),e.setCustomValidity&&(e.setCustomValidity(``),e._oldTitle?e.setAttribute(`title`,e._oldTitle):e.removeAttribute(`title`)),e.removeAttribute(`data-error`);let r=n.nextSibling;r&&r.classList?.contains(`generated-error`)&&r.getAttribute(`data-input-name`)==e.getAttribute(`name`)&&r.remove(),n.querySelector(`[data-error]`)||n.classList.remove(`error`)}watch(()=>JSON.stringify(app.store.errors)&&app.store.errors,e=>{let n=document.querySelectorAll(`[name]`);for(let r of n){if(r.classList.contains(`no-error`))continue;let n=r.closest(`.fields`)||r.closest(`.field`);if(!n)continue;let i=r.getAttribute(`name`);oe(r,n);let a=app.utils.getByPath(e,i)?.message;a&&(n.classList.add(`error`),r.__errListener=function(){oe(r,n),app.utils.deleteByPath(app.store.errors,i)},r.addEventListener(`input`,r.__errListener),r.addEventListener(`change`,r.__errListener),r.setAttribute(`data-error`,!0),r.setCustomValidity&&r.reportValidity&&r.classList.contains(`inline-error`)?(r.setCustomValidity(a),r.reportValidity(),r._oldTitle=r.title,r.title=a):n.after(t.div({"html-data-input-name":i,className:`field-help error generated-error`,textContent:a})))}}),v.onmessage=e=>{e.data?.collections&&JSON.stringify(app.store.collections)!=JSON.stringify(e.data.collections)&&(app.store.collections=e.data.collections),e.data?.settings&&JSON.stringify(app.store.settings)!=JSON.stringify(e.data.settings)&&(app.store.settings=e.data.settings),e.data?.colorScheme&&(app.store.userColorScheme=e.data.colorScheme)},watch(()=>JSON.stringify(app.store.collections),(e,n)=>{e&&e!=`[]`&&n&&n!=`[]`&&e!=n&&v?.postMessage({collections:JSON.parse(e)})}),watch(()=>JSON.stringify(app.store.settings),(e,n)=>{e&&e!=`{}`&&n&&n!=`{}`&&e!=n&&v?.postMessage({settings:JSON.parse(e)}),window.localStorage.setItem(ee,e)});var y=`#/login`,b=window.location.pathname.endsWith(`/`)?window.location.pathname.substring(0,window.location.pathname.length-1):window.location.pathname;window.app=window.app||{},window.app.pb=new i(`../`,new r(`__pb_superusers__`+b)),app.pb.beforeSend=function(e,n){return n.headers[`x-request-source`]=`pbui`,{url:e,options:n}},app.store.superuser=app.pb.authStore.record,app.pb.authStore.onChange((e,n)=>{!n&&window.location.hash!=y&&(app.modals.close(),window.location.hash=y),app.store.superuser=n}),app.pb.authStore.isValid&&app.pb.collection(app.pb.authStore.record?.collectionName||`_superusers`).authRefresh().catch(e=>{console.warn(`Failed to refresh the existing auth token:`,e);let n=e?.status<<0;(n==401||n==403)&&(app.utils.rememberPath(),app.pb.cancelAllRequests(),app.pb.authStore.clear())}),app.pb.authStore.onChange((e,n)=>{n?.id&&(app.store.loadCollections(),app.store.loadSettings(),app.store.loadOAuth2Providers())});var se=app.pb.collection;app.pb.collection=function(e){let n=se.call(this,e);return ce(n),n};function ce(e){if(e.__customUIEvents)return;e.__customUIEvents=!0;let n=e.create;e.create=function(){return n.apply(e,arguments).then(e=>(setTimeout(()=>{document.dispatchEvent(new CustomEvent(`record:create`,{detail:e})),document.dispatchEvent(new CustomEvent(`record:save`,{detail:e}))},0),e))};let r=e.update;e.update=function(){return r.apply(e,arguments).then(e=>(setTimeout(()=>{document.dispatchEvent(new CustomEvent(`record:update`,{detail:e})),document.dispatchEvent(new CustomEvent(`record:save`,{detail:e}))},0),e))};let i=e.delete;e.delete=function(){return i.apply(e,arguments).then(n=>{let r={id:arguments[0],collectionId:e.collectionIdOrName,collectionName:e.collectionIdOrName};return setTimeout(()=>{document.dispatchEvent(new CustomEvent(`record:delete`,{detail:r}))},0),n})}}var le=`pbLastFileToken`,x=!1,ue=[];app.pb.authStore.onChange((e,n)=>{n?.id||window.localStorage.removeItem(le)}),window.app.getFileToken=async function(n=``){let r=n&&app.store.collections?.find(e=>e.id==n||e.name==n);if(r&&!r.fields?.find(e=>e.type==`file`&&e.protected))return;let i=window.localStorage.getItem(le);return(!i||e(i,60))&&(i=await S()),i};async function S(){return new Promise(async(e,n)=>{if(ue.push({resolve:e,reject:n}),!x){x=!0;try{let e=await app.pb.files.getToken();window.localStorage.setItem(le,e),ue.forEach(n=>n.resolve(e))}catch(e){ue.forEach(n=>n.reject(e))}x=!1,ue=[]}})}window.app.checkApiError=function(e,n=!0){if(!e||!(e instanceof Error)||e.isAbort){console.warn(`checkApiError - unexpected error type:`,e);return}let r=e?.status<<0,i=e?.response||{},a=n&&(i.message||e.message||`Something went wrong!`);if(a&&app.toasts.error(a),r==0&&console.log(e),app.utils.isEmpty(i.data)||(app.store.errors=i.data),r===401&&window.location.hash!=y)return app.utils.rememberPath(),app.pb.cancelAllRequests(),app.pb.authStore.clear();r===403&&(app.pb.cancelAllRequests(),window.location.hash!=y&&(window.location.hash=y))};function de(){return()=>{if(!(!app.store._ready||!app.store.showHeader||!app.store.superuser?.id))return t.header({pbEvent:`appHeader`,rid:`appHeader`,className:`app-header accent-surface`,onmount:async e=>{await new Promise(e=>setTimeout(e,0)),e._scrollToActiveMenuItem=function(){e?.querySelector(`.app-main-nav .header-link.active`)?.scrollIntoView()},e._scrollToActiveMenuItem(),window.addEventListener(`hashchange`,e._scrollToActiveMenuItem)},onunmount:e=>{window.removeEventListener(`hashchange`,e?._scrollToActiveMenuItem)}},t.a({href:`#/`,className:`logo`},t.img({src:()=>app.store.headerLogo,alt:`App logo`})),t.nav({pbEvent:`mainNav`,className:`app-main-nav`},()=>app.store.headerLinks.map(e=>{let n=e.href.startsWith(`#/`);return t.a({href:()=>e.href,target:()=>n?void 0:`_blank`,rel:()=>n?void 0:`noopener noreferrer`,className:n=>`header-link ${e.isActive?.(n)||app.utils.isActivePath(e.href)?`active`:``}`},()=>{if(e.icon)return t.i({className:e.icon})},t.span({className:`txt`},()=>e.label))})),t.div({className:`flex-fill app-header-separator`}),C(),t.button({className:`header-link logged-user txt-normal`,"html-popovertarget":`logged-user-dropdown`},t.span({className:`superuser-name txt-ellipsis`},()=>app.store.superuser?.email),t.i({className:`ri-arrow-drop-down-line`})),t.div({pbEvent:`loggedUserDropdown`,id:`logged-user-dropdown`,className:`dropdown sm nowrap logged-user-dropdown`,popover:`auto`},t.a({className:`dropdown-item dropdown-item-manage`,href:`#/collections?collection=_superusers`,onclick:e=>{e.target.closest(`.dropdown`).hidePopover()}},t.i({className:`ri-group-line`,ariaHidden:!0}),t.span({className:`txt`},`Manage superusers`)),t.hr(),t.button({type:`button`,className:`dropdown-item txt-danger dropdown-item-logout`,onclick:()=>app.pb.authStore.clear()},t.i({className:`ri-logout-circle-line`,ariaHidden:!0}),t.span({className:`txt`},`Logout`))))}}function C(){let e=[{value:`light`,icon:`ri-sun-line`,label:`Light`},{value:`dark`,icon:`ri-moon-line`,label:`Dark`},{value:``,icon:`ri-subtract-line`,label:`Auto`}];return[t.button({className:`header-link color-scheme-picker`,"html-popovertarget":`color-scheme-dropdown`,title:`Color scheme`},t.i({className:()=>app.store.activeColorScheme==`dark`?`ri-moon-line`:`ri-sun-line`,ariaHidden:!0})),t.div({pbEvent:`colorSchemeDropdown`,id:`color-scheme-dropdown`,className:`dropdown sm nowrap color-scheme-dropdown`,popover:`auto`},()=>e.map(e=>t.button({type:`button`,className:()=>`dropdown-item dropdown-item-light ${app.store.userColorScheme==e.value?`active`:``}`,onclick:n=>{n.target.closest(`.dropdown`).hidePopover(),app.store.userColorScheme=e.value}},t.i({className:e.icon,ariaHidden:!0}),t.span({className:`txt`},e.label))))]}document.addEventListener(`invalid`,e=>{let n=e.target.closest(`details`);n&&!n.open&&!e.target.closest(`summary`)&&(n.open=!0,e.target.reportValidity&&e.target.reportValidity())},!0);var w=`dropdown-item`;document.addEventListener(`toggle`,e=>{if(e.newState!=`open`||!e.target?.matches(`.dropdown`)||e.target.__keyboardNavRegistered)return;e.target.__keyboardNavRegistered=!0;let n=e.target;function r(e){if(!n.isConnected){document.removeEventListener(`keydown`,r);return}let i;if(i=document.activeElement&&document.activeElement.classList.contains(w)?document.activeElement:n.querySelector(`.`+w+`:not([hidden]):not(.disabled)`),i){if(e.key==`ArrowUp`){e.preventDefault();let n=E(i,-1);i==document.activeElement&&n?.classList?.contains(w)?n?.focus():i.focus()}else if(e.key==`ArrowDown`){e.preventDefault();let n=E(i,1);i==document.activeElement&&n?.classList?.contains(w)?n?.focus():i.focus()}else if(e.keyCode>=65&&e.keyCode<=90||e.keyCode>=48&&e.keyCode<=57){let e=n.querySelectorAll(`input,textare,select`);e.length==1&&e[0].focus()}}}n.addEventListener(`toggle`,e=>{e.newState==`open`?(T(e.target.id,!0),document.addEventListener(`keydown`,r)):(T(e.target.id,!1),document.removeEventListener(`keydown`,r))})},!0);function T(e,n=!1){e&&document.querySelectorAll(`[popovertarget='`+e+`']`)?.forEach(e=>e.setAttribute(`data-popover-state`,n))}function E(e,n=-1){let r=n<0?e.previousElementSibling:e.nextElementSibling;return r&&(r.hidden||r.classList.contains(`disabled`)||!r.classList.contains(w))?E(r,n):r}var D=5,O=t.div({popover:`manual`,className:`pb-tooltip`});document.body.appendChild(O);function k(e,n){let r=e.getBoundingClientRect();O.setAttribute(`data-position`,n),O.style.top=`0px`,O.style.left=`0px`;let i=O.offsetHeight,a=O.offsetWidth,o=0,s=0;n==`left`?(o=r.top+r.height/2-i/2,s=r.left-a-D):n==`right`?(o=r.top+r.height/2-i/2,s=r.right+D):n==`top`?(o=r.top-i-D,s=r.left+r.width/2-a/2):n==`top-left`?(o=r.top-i-D,s=r.left):n==`top-right`?(o=r.top-i-D,s=r.right-a):n==`bottom-left`?(o=r.top+r.height+D,s=r.left):n==`bottom-right`?(o=r.top+r.height+D,s=r.right-a):(o=r.top+r.height+D,s=r.left+r.width/2-a/2),s+a>document.documentElement.clientWidth&&(s=document.documentElement.clientWidth-a),s=s>=0?s:0,o+i>document.documentElement.clientHeight&&(o=document.documentElement.clientHeight-i),o=o>=0?o:0,O.style.top=o+`px`,O.style.left=s+`px`}function A(){O.hidePopover()}function fe(e,n,r){if(!e||!n){A();return}O.showPopover(),O.textContent=n,k(e,r)}document.body.addEventListener(`mouseleave`,()=>{A()});function pe(e,n=`top`){return r=>{if(!r._tooltipText){r._tooltipText=store({value:``});let e;function i(){e?.unwatch(),e=watch(()=>r._tooltipText.value,async e=>{fe(r,e,n)})}async function a(){e?.unwatch(),e=null,A()}r.addEventListener(`mouseenter`,i),r.addEventListener(`focusin`,i),r.addEventListener(`mouseleave`,a),r.addEventListener(`focusout`,a),r.addEventListener(`blur`,a);let o=r.onunmount;r.onunmount=n=>{e?.unwatch(),n._tooltipText=null,n?.removeEventListener(`mouseenter`,i),n?.removeEventListener(`focusin`,i),n?.removeEventListener(`mouseleave`,a),n?.removeEventListener(`focusout`,a),n?.removeEventListener(`blur`,a),o(n)}}return typeof e==`function`?r._tooltipText.value=e():r._tooltipText.value=e,r._tooltipText.value}}window.app=window.app||{},window.app.attrs=window.app.attrs||{},window.app.attrs.tooltip=pe,window.app=window.app||{},window.app.modals=window.app.modals||{},window.app.modals.confirm=function(e,n,r,i={className:void 0,yesButton:``,noButton:``}){j.textOrElem=e,j.yesCallback=n,j.yesCallbackWaiting=!1,j.noCallback=r,j.noCallbackWaiting=!1,j.className=typeof i.className==`string`?i.className:`sm`,j.yesButton=i.yesButton||`Yes`,j.noButton=i.noButton||`No`,me.isConnected||document.body.appendChild(me),window.app.modals.open(me)};var j=store({className:``,textOrElem:null,yesButton:``,yesCallback:null,yesCallbackWaiting:!1,noButton:``,noCallback:null,noCallbackWaiting:!1,get isBusy(){return j.yesCallbackWaiting||j.noCallbackWaiting}}),me=t.div({className:()=>`modal popup manual ${j.className||``}`},t.div({className:`modal-content`},e=>typeof j.textOrElem==`string`?t.h6({className:`block txt-center`},j.textOrElem):typeof j.textOrElem==`function`?j.textOrElem(e):j.textOrElem),t.footer({className:`modal-footer p-sm`},t.div({className:`grid sm`},t.div({className:`col-sm-6`},t.button({type:`button`,className:()=>`btn lg block secondary ${j.noCallbackWaiting?`loading`:``}`,disabled:()=>j.isBusy,onclick:async()=>{if(j.noCallback){j.noCallbackWaiting=!0;try{if(await j.noCallback()===!1)return}catch(e){console.log(`confirm noCallback error:`,e)}finally{j.noCallbackWaiting=!1}}window.app.modals.close(me)}},()=>typeof j.noButton==`string`?t.span({className:`txt`},j.noButton):typeof j.noButton==`function`?j.noButton(el):j.noButton)),t.div({className:`col-sm-6`},t.button({type:`button`,className:()=>`btn lg block warning ${j.yesCallbackWaiting?`loading`:``}`,disabled:()=>j.isBusy,onclick:async()=>{if(j.yesCallback){j.yesCallbackWaiting=!0;try{if(await j.yesCallback()===!1)return}catch(e){console.log(`confirm yesCallback error:`,e)}finally{j.yesCallbackWaiting=!1}}window.app.modals.close(me)}},()=>typeof j.yesButton==`string`?t.span({className:`txt`},j.yesButton):typeof j.yesButton==`function`?j.yesButton(el):j.yesButton)))));window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.dragline=function(e={}){let n,r=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,className:``,tolerance:0,ondragstart:function(e){},ondragstop:function(e){},ondragging:function(e,n,r){}}),i=app.utils.extendStore(r,e),a=store({dragStarted:!1}),o,s,c,l;function u(){document.addEventListener(`touchmove`,m),document.addEventListener(`mousemove`,m),document.addEventListener(`touchend`,p),document.addEventListener(`mouseup`,p)}function d(){document.removeEventListener(`touchmove`,m),document.removeEventListener(`mousemove`,m),document.removeEventListener(`touchend`,p),document.removeEventListener(`mouseup`,p)}function f(e){e.stopPropagation(),o=e.clientX,s=e.clientY,c=e.clientX-n.offsetLeft,l=e.clientY-n.offsetTop,u()}function p(e){a.dragStarted&&(e.preventDefault(),a.dragStarted=!1,r.ondragstop?.(e)),d()}function m(e){let i=e.clientX-o,u=e.clientY-s,d=e.clientX-c,f=e.clientY-l;!a.dragStarted&&Math.abs(d-n.offsetLeft)r.id,hidden:()=>r.hidden,inert:()=>r.inert,className:()=>`dragline ${a.dragStarted?`dragging`:``} ${r.className}`,onmousedown:e=>{e.button==0&&f(e)},ontouchstart:f,onunmount:()=>{d(),i.forEach(e=>e?.unwatch())}}),n},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.slide=function(e,...n){let r;return t.div({className:n=>`block slide-block ${e?.(n)?``:`hidden`}`,onmount:e=>{r=setTimeout(()=>{e?.setAttribute(`data-slide`,`1`)},200)},onunmount:()=>{clearTimeout(r)}},...n)},window.app=window.app||{},window.app.modals=window.app.modals||{};var M=`data-modal-state`,he=`manual`,ge;window.app.modals.open=async function(e){if(!e?.isConnected){console.error(`modals.open requies an active DOM element`,e);return}let n;if(e.onbeforeopen&&(n=await e.onbeforeopen(e)),n===!1)return;if(e.onafteropen){let n=new ResizeObserver(r=>{for(let i of r)i.contentRect.height>0&&e?.onafteropen&&(e.onafteropen(e),n.disconnect(),n=null)});n.observe(e)}ge=document.activeElement,_e(e),e._forceClose=()=>app.modals.close(e,!0),window.addEventListener(`popstate`,e._forceClose);let r=Math.max(ve(e)?.style.zIndex<<0,1e3);e.style.zIndex=r+1,e.setAttribute(M,`open`)},window.app.modals.close=async function(e=null,n=!1){if(e||=ve(),e){if(window.removeEventListener(`popstate`,e._forceClose),n)e.onbeforeclose?.(e,!0),e.setAttribute(M,`close`),e.onafterclose?.(e,!0);else{if(e.onbeforeclose&&await e.onbeforeclose(e,!1)===!1)return;if(e.onafterclose){let n=new ResizeObserver(r=>{for(let i of r)i.contentRect.height<=0&&e?.onafterclose&&(e.onafterclose(e,!1),n.disconnect(),n=null)});n.observe(e)}e.setAttribute(M,`close`)}ge&&(ge.focus?.(),setTimeout(()=>{ge?.blur?.(),ge=null},0))}};function _e(e){if(e.getAttribute(`tabindex`)||e.setAttribute(`tabindex`,`-1`),setTimeout(()=>{let n=e?.querySelector(`[autofocus]`);n?n.focus():e?.focus()},0),e.getAttribute(M))return;e.setAttribute(M,``),e.addEventListener(`keydown`,n=>{n.key!=`Escape`||e.classList.contains(he)||n.target!==e&&e.contains(n.target)||window.app.modals.close(e)});let n=!1,r=r=>{n=r.target!==e&&e.contains(r.target)};e.addEventListener(`mousedown`,r),e.addEventListener(`touchstart`,r);let i=!1,a=n=>{i=n.target!==e&&e.contains(n.target)};e.addEventListener(`mouseup`,a),e.addEventListener(`touchend`,a),e.addEventListener(`click`,r=>{n||i||e.classList.contains(he)||r.target!==e&&e.contains(r.target)||window.app.modals.close(e)})}function ve(e){let n=document.querySelectorAll(`[${M}="open"]`),r=0,i=0,a;for(let o of n)e&&o==e||(r=o.style.zIndex<<0,r>i&&(i=r,a=o));return a}var ye=new Map,be=t.div({className:`toasts-container`});function xe(e,n=!0){let r=ye.get(e);!r||!r.isConnected||(ye.delete(e),clearTimeout(r._removeTimeout),n?(r.classList.add(`removing`),setTimeout(()=>{r.remove()},300)):r.remove())}function Se(e=!0){ye.forEach((n,r)=>{window.app.toasts.remove(r,e)})}function Ce(e,n={}){n.type=`info`,n.duration=n.duration||3e3,Ee(e,n)}function we(e,n={}){n.type=`success`,n.duration=n.duration||3e3,Ee(e,n)}function Te(e,n={}){n.type=`error`,n.duration=n.duration||3500,Ee(e,n)}function Ee(e,n={}){n=Object.assign({duration:3e3,key:void 0,type:`info`},n),be.isConnected||document.body.appendChild(be);let r=n.key||e;ye.has(r)&&xe(r,!1);function i(e){e?._removeTimeout&&clearTimeout(e?._removeTimeout),e._removeTimeout=setTimeout(()=>{xe(r)},n.duration)}let a=t.div({className:`toast ${n.type||``}`,onmount:e=>{i(e)},onunmount:e=>{e?._removeTimeout&&(clearTimeout(e?._removeTimeout),a=null)},onmouseover:()=>{clearTimeout(a?._removeTimeout)},onmouseout:()=>{i(a)}},t.div({className:`toast-container`},t.div({className:`toast-icon`}),t.div({className:`toast-content`},e,t.button({className:`m-l-auto btn circle sm transparent secondary toast-remove`,title:`Clear`,onclick:()=>xe(r)},t.i({className:`ri-close-line`})))));ye.set(r,a),be.prepend(a)}window.app=window.app||{},window.app.toasts=window.app.toasts||{},window.app.toasts.info=Ce,window.app.toasts.error=Te,window.app.toasts.success=we,window.app.toasts.remove=xe,window.app.toasts.removeAll=Se,window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.sortable=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,className:``,data:[],dataItem:function(e,n,r){return t.span(null,`Item `+n)},onchange:function(e,n,r){},handle:``,before:void 0,after:void 0}),r=app.utils.extendStore(n,e);function i(e){function r(){e.querySelectorAll(`:scope > [data-dragstart="true"]`)?.forEach(e=>{e.dataset.dragstart=!1}),e.querySelectorAll(`:scope > [data-dragover="true"]`)?.forEach(e=>{e.dataset.dragover=!1})}e.addEventListener(`dragstart`,r=>{if(n.handle&&!r.target.closest(n.handle)){r.preventDefault();return}let i=o(e,r.target);i&&(i.dataset.dragstart=!0)}),e.addEventListener(`dragenter`,n=>{for(let n of e.children)n.dataset.dragover&&(n.dataset.dragover=!1);let r=o(e,n.target);r&&(r.dataset.dragover=!0)}),e.addEventListener(`dragend`,e=>{r()}),e.addEventListener(`dragover`,e=>{e.preventDefault()}),e.addEventListener(`drop`,i=>{if(!n.onchange){r();return}let s=e.querySelector(`:scope > [data-dragstart="true"]`),c=o(e,i.target);if(r(),!s||!c||c==s)return;let l=a(s),u=a(c),d=n.data.slice(),f=d.splice(l,1);d.splice(u,0,f[0]),n.onchange(d,l,u)})}function a(e){if(!e?.parentNode)return-1;for(let n=0;nn.id,hidden:()=>n.hidden,inert:()=>n.inert,className:()=>n.className,onmount:e=>{i(e)},onunmount:e=>{r.forEach(e=>e?.unwatch())}},e=>typeof n.before==`function`?n.before(e):n.before,e=>{let r=[];for(let i=0;itypeof n.after==`function`?n.after(e):n.after)},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.copyButton=function(e,...n){let r=store({active:!1}),i;function a(){let n=e;typeof n==`function`&&(n=e()),app.utils.copyToClipboard(n),r.active=!0,clearTimeout(i),i=setTimeout(()=>{r.active=!1},500)}return t.button({tabIndex:-1,type:`button`,className:()=>`copy-to-clipboard ${r.active?`active`:``}`,title:`Copy`,ariaDescription:app.attrs.tooltip(()=>r.active?`Copied`:null),onclick:e=>{e.preventDefault(),e.stopPropagation(),a()}},t.i({hidden:n?.length,className:()=>`copy-icon ${r.active?`ri-check-double-line`:`ri-file-copy-line`}`}),...n)},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.codeBlock=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,className:``,language:`js`,value:void 0,footnote:void 0}),r=app.utils.extendStore(n,e);return t.div({rid:n.rid,id:()=>n.id,hidden:()=>n.hidden,inert:()=>n.inert,className:()=>`code-wrapper ${n.className}`,tabIndex:-1,onmount:e=>{e.addEventListener(`keydown`,n=>{(n.ctrlKey||n.metaKey)&&(n.key==`a`||n.key==`A`)&&(n.preventDefault(),window.getSelection().selectAllChildren(e))})},onunmount:()=>{r.forEach(e=>e?.unwatch())}},t.code({className:`block`,innerHTML:()=>De(n.value,n.language)}),t.div({className:`footnote`},e=>typeof n.footnote==`function`?n.footnote(e):n.footnote))};function De(e,n){return e=typeof e==`string`?e:``,e=Prism.plugins.NormalizeWhitespace.normalize(e,{"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.highlight(e,Prism.languages[n]||Prism.languages.js,n)}window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.codeEditor=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,name:void 0,className:``,value:``,language:`js`,placeholder:``,disabled:!1,required:!1,singleLine:!1,autocomplete:void 0,oninput:function(e,n){},onfocus:function(e,n){},onblur:function(e,n){}}),r=app.utils.extendStore(n,e,`autocomplete`),i,a,o=!0;function s(e){c(),i=t.div({className:`dropdown autocomplete code-editor-dropdown`,onmount:e=>{e._updatePosition=()=>{o?Fe(i):c()},e._closeOnEsc=e=>{e.key==`Escape`&&(e.preventDefault(),c())},window.addEventListener(`scroll`,e._updatePosition,!0),window.addEventListener(`resize`,e._updatePosition),window.addEventListener(`keydown`,e._closeOnEsc),e._updatePosition()},onunmount:e=>{e&&(window.removeEventListener(`scroll`,e._updatePosition,!0),window.removeEventListener(`resize`,e._updatePosition),window.removeEventListener(`keydown`,e._closeOnEsc))}},e),document.body.appendChild(i),d&&(a?.disconnect(),a=new IntersectionObserver(([e])=>{o=e.isIntersecting},{root:null,threshold:.1}),a.observe(d))}function c(){i&&=(i.remove(),null),a&&=(a.disconnect(),null),o=!0}let l=!1,u,d=t.div({contentEditable:()=>n.disabled?!1:`plaintext-only`,tabIndex:0,spellcheck:!1,autocorrect:!1,autocomplete:`off`,autocapitalize:`off`,role:`textbox`,className:`editor-content`,"html-data-placeholder":()=>n.placeholder,onmount:e=>{u?.unwatch(),u=watch(()=>n.value,e=>{e!=d.textContent&&(d.textContent=e,c())})},onunmount:e=>{u?.unwatch(),c()},onfocus:e=>{n.onfocus?.(n.value,e)},onblur:e=>{i&&!i.contains(e.relatedTarget)&&c(),n.onblur?.(n.value,e)},oninput:e=>{if(c(),n.value=d.textContent,n.oninput?.(n.value,e),d.dispatchEvent(new CustomEvent(`change`,{detail:n.value})),!n.value?.length){d.textContent=``;return}if(!d?.isConnected)return;let r=Pe(d),i=je(n.value,r);if(!i.word.length||r==i.start)return;let a=[];if(typeof n.autocomplete==`function`)a=n.autocomplete(i.word)||[];else if(!app.utils.isEmpty(n.autocomplete)){let e=i.word.toLowerCase();a=n.autocomplete.filter(n=>(typeof n==`object`&&(n=n?.value),n=n?.toLowerCase(),n&&n!=e&&n.includes(e)))}a?.length&&s(()=>a.map((e,r)=>t.button({type:`button`,className:`dropdown-item ${r==0?`active`:``}`,textContent:e.label||e.value||e,onclick:r=>{r.preventDefault(),d.focus();let a=e.value||e;d.textContent=d.textContent.substring(0,i.start)+a+d.textContent.substring(i.end+1),n.value=d.textContent;try{window.getSelection().setPosition(d.childNodes[0],i.start+a.length)}catch(e){console.warn(`failed to set caret position`,e)}c()}})))},onkeydown:e=>{if(l=e.ctrlKey||e.metaKey,(e.key==`Enter`||e.key==`Tab`)&&i?.isConnected){e.preventDefault(),i.querySelector(`.dropdown-item.active`)?.click();return}if(e.key==`ArrowUp`&&i?.isConnected){e.preventDefault();let n=i.querySelector(`.dropdown-item.active`);n?.previousElementSibling&&(n.classList.remove(`active`),n.previousElementSibling.classList.add(`active`),n.previousElementSibling.scrollIntoView(!1));return}if(e.key==`ArrowDown`&&i?.isConnected){e.preventDefault();let n=i.querySelector(`.dropdown-item.active`);n?.nextElementSibling&&(n.classList.remove(`active`),n.nextElementSibling.classList.add(`active`),n.nextElementSibling.scrollIntoView(!1));return}if(l&&e.key.toLowerCase()==`l`){e.preventDefault(),Me(d);return}if(l&&e.key.toLowerCase()==`d`){e.preventDefault(),Ne(d);return}if(!n.singleLine&&e.key==`Tab`){e.preventDefault();let r=window.getSelection();if(!r)return;if(e.shiftKey){r.modify(`extend`,`backward`,`character`),r.toString()[0]==` `?(r.deleteFromDocument(),n.value=d.textContent):(r.modify(`extend`,`forward`,`character`),r.toString()[0]==` `&&(r.deleteFromDocument(),n.value=d.textContent));return}let i=r.getRangeAt(0);i&&(i.deleteContents(),i.insertNode(document.createTextNode(` `)),i.collapse(),n.value=d.textContent);return}if(n.singleLine&&e.key==`Enter`){e.preventDefault(),p.click();return}},onscroll:()=>{c(),f&&(f.scrollLeft=d.scrollLeft,f.scrollTop=d.scrollTop)}}),f=t.div({className:`highlight-overlay`,innerHTML:()=>ke(n.value,n.language),onscroll:()=>{d&&(d.scrollLeft=f.scrollLeft,d.scrollTop=f.scrollTop)}}),p=t.button({type:`submit`,className:`hidden`});return t.div({rid:n.rid,id:()=>n.id,inert:()=>n.inert,hidden:()=>n.hidden,"html-name":()=>n.name,"html-required":()=>n.required||void 0,className:()=>`input code-editor ${n.className} ${n.disabled?`disabled`:``} ${n.singleLine?`single-line`:``}`,onclick:()=>{d?.focus()},onunmount:()=>{r?.forEach(e=>e?.unwatch())}},t.div({className:`code-editor-container`},d,f,p))};var Oe=500;function ke(e,n){return e=typeof e==`string`?e:``,e?((!Prism.languages[n]||e.length>Oe)&&(n=`plain`),Prism.highlight(e,Prism.languages[n],n)):``}var Ae=new RegExp(/[\p{Alphabetic}\p{Number}_@:\."'{}]/,`u`);function je(e,n){let r=n;for(let i=n-1;i>=0&&Ae.test(e[i]);i--)r=i;let i=r;for(let r=n-1;rdocument.documentElement.clientHeight&&(o=Math.max(n.top-r,0)),a+i>document.documentElement.clientWidth&&(a=Math.max(document.documentElement.clientWidth-i,0)),e.style.left=a+`px`,e.style.top=o+`px`}window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.codeBlockTabs=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,className:``,activeTabIndex:0,historyKey:``,tabs:[],get activeTab(){return n.tabs[n.activeTabIndex]||n.tabs[0]}}),r=app.utils.extendStore(n,e);return r.push(watch(()=>n.activeTabIndex,(e,r)=>{r!=null&&n.historyKey&&localStorage.setItem(n.historyKey,e)})),t.div({rid:n.rid,id:()=>n.id,hidden:()=>n.hidden||!n.tabs.length,inert:()=>n.inert,className:()=>`code-block-tabs ${n.className}`,onmount:()=>{n.historyKey&&(n.activeTabIndex=localStorage.getItem(n.historyKey)<<0)},onunmount:()=>{r.forEach(e=>e?.unwatch())}},t.header({className:`tabs-header`},()=>n.tabs.map((e,r)=>t.button({type:`button`,className:()=>`tab-item ${n.activeTabIndex==r?`active`:``}`,onclick:()=>n.activeTabIndex=r},n=>typeof e.title==`function`?e.title(n):e.title))),t.div({className:`code-block-tabs-content`},()=>{if(n.activeTab)return app.components.codeBlock(n.activeTab)}))},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.select=function(e={}){let n=store({rid:void 0,id:void 0,name:void 0,hidden:void 0,inert:void 0,className:``,value:void 0,options:[],before:null,after:null,max:1,searchThreshold:6,required:!1,disabled:!1,placeholder:`- Select -`,noItemsFoundText:`No items found`,onchange:function(e){},ondropdowntoggle:function(e){}}),r=app.utils.extendStore(n,e);n.max<=0&&(n.max=1);let i=store({selected:[],search:``,get hasSearch(){return i.search?.length>0},get allowRemove(){return!n.disabled&&(!n.required||n.max>1)}});function a(){if(n.value===void 0)return;let e=app.utils.toArray(n.value,!0),r=e.slice(0,n.max||1);e.length!=r.length&&(console.warn(`[select] the provided select values (${e.length}) are more than the allowed max selected options (${r.length}):`,e),n.value=n.max>1?r:r[0]),i.selected=e.map(e=>n.options.find(n=>n.value===e)).filter(Boolean)}r.push(watch(()=>n.value,()=>a()));async function o(e){let r=i.selected.findIndex(n=>n.value===e.value);if(r>=0){if(!i.allowRemove){f?.hidePopover();return}i.selected.splice(r,1)}else{let r=i.selected.length-n.max;for(;r>=0;)i.selected.pop(),r--;i.selected.push(e)}n.max<=1&&f?.hidePopover(),n.onchange&&(await n.onchange(i.selected),a()),p?.isConnected&&p.dispatchEvent(new CustomEvent(`change`,{detail:i.selected,bubbles:!0}))}function s(e){return i.selected.findIndex(n=>n.value===e.value)>=0}let c=t.input({type:`text`,placeholder:`Search...`,value:()=>i.search,oninput:e=>i.search=e.target.value});function l(e=!1){i.search=``,e&&c?.focus()}let u=t.div({className:`txt-hint txt-center m-0 p-5`,hidden:!0},n.noItemsFoundText);async function d(){f&&(await new Promise(e=>setTimeout(e,0)),f.querySelector(`.select-option:not([hidden])`)?u.hidden=!0:u.hidden=!1)}let f=t.div({tabIndex:-1,popover:`auto`,className:`dropdown`,onbeforetoggle:e=>(e.newState==`closed`&&l(),n.ondropdowntoggle?.(e))},t.div({className:`fields dropdown-search`,hidden:()=>n.options.length!i.hasSearch},t.button({type:`button`,className:`btn sm secondary transparent circle`,onclick:()=>l(!0)},t.i({className:`ri-close-line`})))),()=>n.before?.__raw||n.before,()=>n.options.map(e=>t.button({type:`button`,className:()=>`dropdown-item select-option ${s(e)?`active`:``}`,onclick:()=>(o(e),!1)},e.label||e.value)),u,()=>n.after?.__raw||n.after),p=t.button({type:`button`,id:()=>n.id,name:()=>n.name,disabled:()=>n.disabled,className:()=>`selected-container ${n.className}`,popoverTargetElement:f,onclick:e=>{e.stopPropagation()}},()=>i.selected.length?i.selected.map(e=>t.div({className:`selected-item`},e.selected||e.label||e.value,()=>{if(i.allowRemove)return t.i({tabIndex:-1,role:`button`,className:`ri-close-line link-hint btn-option-unset`,ariaDescription:app.attrs.tooltip(`Unset`,`left`),onclick:()=>(o(e),!1)})})):t.span({rid:`selected-placeholder`,className:`placeholder`},()=>n.placeholder));r.push(watch(()=>n.options,()=>{d()}));let m;return r.push(watch(()=>i.search,()=>{let e=i.search.toLowerCase().replaceAll(` `,``);clearTimeout(m),m=setTimeout(()=>{let n=f.querySelectorAll(`.select-option`);e.length?n.forEach(n=>{n.textContent.toLowerCase().replaceAll(` `,``).includes(e)?n.hidden=!1:n.hidden=!0}):n.forEach(e=>e.hidden=!1),d()},100)})),t.div({rid:n.rid,hidden:()=>n.hidden,inert:()=>n.inert,onmount:e=>{e.addEventListener(`focusout`,function(n){(!n.relatedTarget||!e.contains(n.relatedTarget))&&f?.hidePopover()})},onunmount:()=>{clearTimeout(m),r.forEach(e=>e.unwatch())},className:()=>[`input`,`select`,n.max>1?`multiple`:`single`,n.disabled?`disabled`:``,n.required?`required`:``].join(` `)},p,f)},window.app=window.app||{},window.app.components=window.app.components||{};var Ie=Intl.DateTimeFormat().resolvedOptions().timeZone;window.app.components.formattedDate=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,value:``,short:!1}),r=app.utils.extendStore(n,e);return t.div({rid:n.rid,id:()=>n.id,hidden:()=>n.hidden,ariaDescription:app.attrs.tooltip(()=>n.short&&n.value?app.utils.toLocalDatetime(n.value)+` +`+Ie:null),"html-class":`formatted-date`,className:()=>`formatted-date ${n.short?`short`:`full`}`,onunmount:()=>{r.forEach(e=>e?.unwatch())}},()=>{if(!n.value)return t.span({className:`missing-value`});if(n.short){let e=n.value.split(` `);return[t.span({className:`primary-date`},e[0]),t.span({className:`secondary-date`},e[1])]}return[t.span({className:`primary-date`},app.utils.toLocalDatetime(n.value)),t.span({className:`secondary-date`},n.value)]})},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.refreshButton=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,tooltip:`Refresh`,className:`btn transparent secondary circle rotate-btn`,disabled:!1,onclick:function(e){}}),r=app.utils.extendStore(n,e),i,a=t.button({rid:n.rid,id:()=>n.id,hidden:()=>n.hidden,inert:()=>n.inert,type:`button`,ariaDescription:app.attrs.tooltip(()=>n.tooltip),disabled:()=>n.disabled,className:()=>n.className,onunmount:()=>{clearTimeout(i),r.forEach(e=>e?.unwatch())},onclick:e=>{e.preventDefault(),n.onclick&&n.onclick(e),a.classList.add(`rotate`),a.addEventListener(`animationend`,()=>{a.classList.remove(`rotate`)}),clearTimeout(i),i=setTimeout(()=>{clearTimeout(i),a.classList.remove(`rotate`)},500)}},t.i({className:`ri-refresh-line`}));return a},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.searchHistoryButton=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,value:void 0,historyKey:`default`,max:15,openInNewTabParam:`filter`,btnClassName:`btn sm pill secondary transparent p-r-5`,onselect:function(e){}}),r=app.utils.extendStore(n,e),i=store({items:app.utils.getLocalHistory(n.historyKey,[])});function a(e){o(e),i.items.unshift(e)}function o(e){app.utils.removeByValue(i.items,e)}let s=`history_dropdown_`+app.utils.randomString();r.push(watch(()=>n.value,e=>{e&&a(e)})),r.push(watch(()=>{i.items.length>n.max&&(i.items=i.items.slice(0,n.max)),app.utils.saveLocalHistory(n.historyKey,i.items)}));let c=t.div({id:s,className:`dropdown sm left nowrap history-searchbar-dropdown`,popover:`hint`,onclick:e=>(e.stopPropagation(),!1)},t.div({className:`block p-5`},t.small({className:`txt-hint`},`Search history`)),()=>i.items?.length?i.items.slice(0,n.max).map(e=>t.button({type:`button`,className:`dropdown-item txt-code`,onclick:()=>{c.hidePopover(),n.onselect?.(e),a(e)},onauxclick:()=>{if(n.openInNewTabParam){a(e),c.hidePopover();let r=app.utils.replaceHashQueryParams({[n.openInNewTabParam]:e},!1);window.open(r,`_blank`)}}},t.span({className:`txt-ellipsis`,title:e,textContent:e}),t.small({role:`button`,className:`remove-btn link-hint m-l-auto p-l-5 p-r-5`,onauxclick:e=>(e.stopPropagation(),!1),onclick:n=>(n.stopPropagation(),o(e),!1)},t.i({className:`ri-close-line`})))):t.div({rid:`no-history`,className:`block p-5`},t.span(null,`Your recent searches will show up here.`)));return t.button({rid:n.rid,id:()=>n.id,hidden:()=>n.hidden,inert:()=>n.inert,type:`button`,className:()=>n.btnClassName,"html-popovertarget":s,onunmount:()=>{r?.forEach(e=>e?.unwatch())}},t.i({className:`ri-search-line`}),t.i({className:`ri-arrow-drop-down-line`}),c)},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.s3Test=function(e={}){let n=`s3_test_request`,r=store({rid:void 0,config:null,label:`Use S3 storage`,testFilesystem:`storage`}),i=app.utils.extendStore(r,e),a=store({isTesting:!1,testError:null,get hasError(){return!app.utils.isEmpty(a.testError)}}),o,s;function c(e=150){if(!r.config.enabled){clearTimeout(o);return}a.isTesting=!0,clearTimeout(o),o=setTimeout(()=>{l()},e)}async function l(){if(a.isTesting=!0,!r.config.enabled||!r.testFilesystem){a.testError=null,a.isTesting=!1;return}app.pb.cancelRequest(n),clearTimeout(s),s=setTimeout(()=>{app.pb.cancelRequest(n),a.testError=Error(`S3 test connection timeout.`),a.isTesting=!1},3e4);try{await app.pb.props.testS3(r.testFilesystem,{requestKey:n}),a.testError=null,a.isTesting=!1}catch(e){e?.isAbort||(a.testError=e,a.isTesting=!1,clearTimeout(s))}}return i.push(watch(()=>r.testFilesystem&&r.config,()=>c())),t.div({pbEvent:`s3Test`,rid:r.rid,hidden:()=>!r.testFilesystem,className:()=>`label s3-test-label txt-nowrap ${a.hasError?`warning`:`success`}`,ariaDescription:app.attrs.tooltip(()=>a.testError?.data?.message),onunmount:()=>{clearTimeout(s),clearTimeout(o),i.forEach(e=>e?.unwatch())}},()=>a.isTesting?t.span({className:`loader sm`}):a.hasError?[t.i({className:`ri-error-warning-line txt-warning`}),t.span({className:`txt`},`Failed to establish S3 connection`)]:[t.i({className:`ri-checkbox-circle-line txt-success`}),t.span({className:`txt`},`S3 connected successfully`)])},window.app=window.app||{},window.app.components=window.app.components||{},window.app.components.s3ConfigFields=function(e={}){let n=store({rid:void 0,id:void 0,hidden:void 0,inert:void 0,className:``,config:{},configKey:`s3`,toggleLabel:`Use S3 storage`,testFilesystem:`storage`,before:null,after:null}),r=app.utils.extendStore(n,e);n.configKey.endsWith(`.`)&&(n.configKey=n.configKey.substring(0,n.configKey.length-1));let i=store({originalHash:``,originalConfig:null});return r.push(watch(()=>n.config,e=>{i.originalHash=JSON.stringify(e),i.originalConfig=JSON.parse(i.originalHash)})),t.div({pbEvent:`s3ConfigFields`,rid:n.rid,id:()=>n.id,hidden:()=>n.hidden,inert:()=>n.inert,className:()=>`block s3-fields s3-config-${n.configKey} ${n.className}`,onunmount:()=>{r.forEach(e=>e?.unwatch())}},t.div({className:`field`},t.input({id:()=>`${n.configKey}.enabled`,name:()=>`${n.configKey}.enabled`,type:`checkbox`,className:`switch`,checked:()=>n.config.enabled,onchange:e=>n.config.enabled=e.target.checked}),t.label({htmlFor:()=>`${n.configKey}.enabled`},()=>n.toggleLabel)),e=>typeof n.before==`function`?n.before(e):n.before,app.components.slide(()=>n.config.enabled,t.div({className:`grid m-t-base`},t.div({className:`col-lg-6`},t.div({className:`field`},t.label({htmlFor:()=>`${n.configKey}.endpoint`},`Endpoint`),t.input({id:()=>`${n.configKey}.endpoint`,name:()=>`${n.configKey}.endpoint`,type:`text`,required:()=>n.config.enabled,value:()=>n.config.endpoint||``,oninput:e=>n.config.endpoint=e.target.value}))),t.div({className:`col-lg-3`},t.div({className:`field`},t.label({htmlFor:()=>`${n.configKey}.bucket`},`Bucket`),t.input({id:()=>`${n.configKey}.bucket`,name:()=>`${n.configKey}.bucket`,type:`text`,required:()=>n.config.enabled,value:()=>n.config.bucket||``,oninput:e=>n.config.bucket=e.target.value}))),t.div({className:`col-lg-3`},t.div({className:`field`},t.label({htmlFor:()=>`${n.configKey}.region`},`Region`),t.input({id:()=>`${n.configKey}.region`,name:()=>`${n.configKey}.region`,type:`text`,required:()=>n.config.enabled,value:()=>n.config.region||``,oninput:e=>n.config.region=e.target.value}))),t.div({className:`col-lg-6`},t.div({className:`field`},t.label({htmlFor:()=>`${n.configKey}.accessKey`},`Access key`),t.input({id:()=>`${n.configKey}.accessKey`,name:()=>`${n.configKey}.accessKey`,type:`text`,autocomplete:`off`,required:()=>n.config.enabled,value:()=>n.config.accessKey||``,oninput:e=>n.config.accessKey=e.target.value}))),t.div({className:`col-lg-6`},t.div({className:()=>`field ${n.config.enabled?``:`required`}`},t.label({htmlFor:()=>`${n.configKey}.secret`},`Secret`),t.input({id:()=>`${n.configKey}.secret`,name:()=>`${n.configKey}.secret`,type:`password`,autocomplete:`new-password`,value:()=>n.config.secret||``,oninput:e=>n.config.secret=e.target.value,onkeyup:e=>{e.key==`Backspace`&&n.config.secret===void 0&&(n.config.secret=``)},placeholder:()=>n.config.secret===void 0?`* * * * * *`:``}))),t.div({className:`col-lg-6`,style:`min-height: 25px`},t.div({className:`field`},t.input({id:()=>`${n.configKey}.forcePathStyle`,name:()=>`${n.configKey}.forcePathStyle`,type:`checkbox`,checked:()=>n.config.forcePathStyle||!1,onchange:e=>n.config.forcePathStyle=e.target.checked}),t.label({htmlFor:()=>`${n.configKey}.forcePathStyle`},t.span({className:`txt`},`Force path-style addressing`),t.i({className:`ri-information-line link-hint`,ariaDescription:app.attrs.tooltip(`Forces the request to use path-style addressing, eg. "https://s3.amazonaws.com/BUCKET/KEY" instead of the default "https://BUCKET.s3.amazonaws.com/KEY".`)})))),t.div({className:`col-lg-6 txt-right`},()=>{if(!(!n.config?.enabled||i.originalHash!=JSON.stringify(n.config)))return app.components.s3Test({config:()=>n.config,testFilesystem:()=>n.testFilesystem})}))),e=>typeof n.after==`function`?n.after(e):n.after)};var Le=p(d(((e,n)=>{(function(r,i){typeof e==`object`&&n!==void 0?i(e):typeof define==`function`&&define.amd?define([`exports`],i):(r=typeof globalThis<`u`?globalThis:r||self,i(r.leaflet={}))})(e,(function(e){var n=`1.9.4`;function r(e){var n,r,i,a;for(r=1,i=arguments.length;r`u`||!L||!L.Mixin)){e=v(e)?e:[e];for(var n=0;n0?Math.floor(e):Math.ceil(e)};S.prototype={clone:function(){return new S(this.x,this.y)},add:function(e){return this.clone()._add(C(e))},_add:function(e){return this.x+=e.x,this.y+=e.y,this},subtract:function(e){return this.clone()._subtract(C(e))},_subtract:function(e){return this.x-=e.x,this.y-=e.y,this},divideBy:function(e){return this.clone()._divideBy(e)},_divideBy:function(e){return this.x/=e,this.y/=e,this},multiplyBy:function(e){return this.clone()._multiplyBy(e)},_multiplyBy:function(e){return this.x*=e,this.y*=e,this},scaleBy:function(e){return new S(this.x*e.x,this.y*e.y)},unscaleBy:function(e){return new S(this.x/e.x,this.y/e.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=de(this.x),this.y=de(this.y),this},distanceTo:function(e){e=C(e);var n=e.x-this.x,r=e.y-this.y;return Math.sqrt(n*n+r*r)},equals:function(e){return e=C(e),e.x===this.x&&e.y===this.y},contains:function(e){return e=C(e),Math.abs(e.x)<=Math.abs(this.x)&&Math.abs(e.y)<=Math.abs(this.y)},toString:function(){return`Point(`+d(this.x)+`, `+d(this.y)+`)`}};function C(e,n,r){return e instanceof S?e:v(e)?new S(e[0],e[1]):e==null?e:typeof e==`object`&&`x`in e&&`y`in e?new S(e.x,e.y):new S(e,n,r)}function w(e,n){if(e)for(var r=n?[e,n]:e,i=0,a=r.length;i=this.min.x&&r.x<=this.max.x&&n.y>=this.min.y&&r.y<=this.max.y},intersects:function(e){e=T(e);var n=this.min,r=this.max,i=e.min,a=e.max,o=a.x>=n.x&&i.x<=r.x,s=a.y>=n.y&&i.y<=r.y;return o&&s},overlaps:function(e){e=T(e);var n=this.min,r=this.max,i=e.min,a=e.max,o=a.x>n.x&&i.xn.y&&i.y=n.lat&&a.lat<=r.lat&&i.lng>=n.lng&&a.lng<=r.lng},intersects:function(e){e=D(e);var n=this._southWest,r=this._northEast,i=e.getSouthWest(),a=e.getNorthEast(),o=a.lat>=n.lat&&i.lat<=r.lat,s=a.lng>=n.lng&&i.lng<=r.lng;return o&&s},overlaps:function(e){e=D(e);var n=this._southWest,r=this._northEast,i=e.getSouthWest(),a=e.getNorthEast(),o=a.lat>n.lat&&i.latn.lng&&i.lng1,Ye=function(){var e=!1;try{var n=Object.defineProperty({},`passive`,{get:function(){e=!0}});window.addEventListener(`testPassiveEventSupport`,u,n),window.removeEventListener(`testPassiveEventSupport`,u,n)}catch{}return e}(),Xe=function(){return!!document.createElement(`canvas`).getContext}(),Ze=!!(document.createElementNS&&_e(`svg`).createSVGRect),Qe=!!Ze&&(function(){var e=document.createElement(`div`);return e.innerHTML=``,(e.firstChild&&e.firstChild.namespaceURI)===`http://www.w3.org/2000/svg`})(),$e=!Ze&&function(){try{var e=document.createElement(`div`);e.innerHTML=``;var n=e.firstChild;return n.style.behavior=`url(#default#VML)`,n&&typeof n.adj==`object`}catch{return!1}}(),et=navigator.platform.indexOf(`Mac`)===0,tt=navigator.platform.indexOf(`Linux`)===0;function nt(e){return navigator.userAgent.toLowerCase().indexOf(e)>=0}var N={ie:be,ielt9:xe,edge:Se,webkit:Ce,android:we,android23:Te,androidStock:De,opera:Oe,chrome:ke,gecko:Ae,safari:je,phantom:Me,opera12:Ne,win:Pe,ie3d:Fe,webkit3d:Ie,gecko3d:Le,any3d:Re,mobile:ze,mobileWebkit:Be,mobileWebkit3d:Ve,msPointer:He,pointer:Ue,touch:Ge,touchNative:We,mobileOpera:Ke,mobileGecko:qe,retina:Je,passiveEvents:Ye,canvas:Xe,svg:Ze,vml:$e,inlineSvg:Qe,mac:et,linux:tt},rt=N.msPointer?`MSPointerDown`:`pointerdown`,it=N.msPointer?`MSPointerMove`:`pointermove`,P=N.msPointer?`MSPointerUp`:`pointerup`,at=N.msPointer?`MSPointerCancel`:`pointercancel`,ot={touchstart:rt,touchmove:it,touchend:P,touchcancel:at},st={touchstart:gt,touchmove:ht,touchend:ht,touchcancel:ht},ct={},lt=!1;function ut(e,n,r){return n===`touchstart`&&mt(),st[n]?(r=st[n].bind(this,r),e.addEventListener(ot[n],r,!1),r):(console.warn(`wrong event specified:`,n),u)}function dt(e,n,r){if(!ot[n]){console.warn(`wrong event specified:`,n);return}e.removeEventListener(ot[n],r,!1)}function F(e){ct[e.pointerId]=e}function ft(e){ct[e.pointerId]&&(ct[e.pointerId]=e)}function pt(e){delete ct[e.pointerId]}function mt(){lt||=(document.addEventListener(rt,F,!0),document.addEventListener(it,ft,!0),document.addEventListener(P,pt,!0),document.addEventListener(at,pt,!0),!0)}function ht(e,n){if(n.pointerType!==(n.MSPOINTER_TYPE_MOUSE||`mouse`)){for(var r in n.touches=[],ct)n.touches.push(ct[r]);n.changedTouches=[n],e(n)}}function gt(e,n){n.MSPOINTER_TYPE_TOUCH&&n.pointerType===n.MSPOINTER_TYPE_TOUCH&&K(n),ht(e,n)}function _t(e){var n={},r,i;for(i in e)r=e[i],n[i]=r&&r.bind?r.bind(e):r;return e=n,n.type=`dblclick`,n.detail=2,n.isTrusted=!1,n._simulated=!0,n}var vt=200;function yt(e,n){e.addEventListener(`dblclick`,n);var r=0,i;function a(e){if(e.detail!==1){i=e.detail;return}if(!(e.pointerType===`mouse`||e.sourceCapabilities&&!e.sourceCapabilities.firesTouchEvents)){var a=rn(e);if(!(a.some(function(e){return e instanceof HTMLLabelElement&&e.attributes.for})&&!a.some(function(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement}))){var o=Date.now();o-r<=vt?(i++,i===2&&n(_t(e))):i=1,r=o}}}return e.addEventListener(`click`,a),{dblclick:n,simDblclick:a}}function bt(e,n){e.removeEventListener(`dblclick`,n.dblclick),e.removeEventListener(`click`,n.simDblclick)}var xt=Nt([`transform`,`webkitTransform`,`OTransform`,`MozTransform`,`msTransform`]),St=Nt([`webkitTransition`,`transition`,`OTransition`,`MozTransition`,`msTransition`]),Ct=St===`webkitTransition`||St===`OTransition`?St+`End`:`transitionend`;function wt(e){return typeof e==`string`?document.getElementById(e):e}function Tt(e,n){var r=e.style[n]||e.currentStyle&&e.currentStyle[n];if((!r||r===`auto`)&&document.defaultView){var i=document.defaultView.getComputedStyle(e,null);r=i?i[n]:null}return r===`auto`?null:r}function I(e,n,r){var i=document.createElement(e);return i.className=n||``,r&&r.appendChild(i),i}function R(e){var n=e.parentNode;n&&n.removeChild(e)}function Et(e){for(;e.firstChild;)e.removeChild(e.firstChild)}function Dt(e){var n=e.parentNode;n&&n.lastChild!==e&&n.appendChild(e)}function Ot(e){var n=e.parentNode;n&&n.firstChild!==e&&n.insertBefore(e,n.firstChild)}function kt(e,n){if(e.classList!==void 0)return e.classList.contains(n);var r=jt(e);return r.length>0&&RegExp(`(^|\\s)`+n+`(\\s|$)`).test(r)}function z(e,n){if(e.classList!==void 0)for(var r=p(n),i=0,a=r.length;i0?2*window.devicePixelRatio:1;function sn(e){return N.edge?e.wheelDeltaY/2:e.deltaY&&e.deltaMode===0?-e.deltaY/on:e.deltaY&&e.deltaMode===1?-e.deltaY*20:e.deltaY&&e.deltaMode===2?-e.deltaY*60:e.deltaX||e.deltaZ?0:e.wheelDelta?(e.wheelDeltaY||e.wheelDelta)/2:e.detail&&Math.abs(e.detail)<32765?-e.detail*20:e.detail?e.detail/-32765*60:0}function cn(e,n){var r=n.relatedTarget;if(!r)return!0;try{for(;r&&r!==e;)r=r.parentNode}catch{return!1}return r!==e}var ln={__proto__:null,on:U,off:G,stopPropagation:$t,disableScrollPropagation:en,disableClickPropagation:tn,preventDefault:K,stop:nn,getPropagationPath:rn,getMousePosition:an,getWheelDelta:sn,isExternalTarget:cn,addListener:U,removeListener:G},un=ue.extend({run:function(e,n,r,i){this.stop(),this._el=e,this._inProgress=!0,this._duration=r||.25,this._easeOutPower=1/Math.max(i||.5,.2),this._startPos=Ft(e),this._offset=n.subtract(this._startPos),this._startTime=+new Date,this.fire(`start`),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=y(this._animate,this),this._step()},_step:function(e){var n=+new Date-this._startTime,r=this._duration*1e3;nthis.options.maxZoom)?this.setZoom(e):this},panInsideBounds:function(e,n){this._enforcingBounds=!0;var r=this.getCenter(),i=this._limitCenter(r,this._zoom,D(e));return r.equals(i)||this.panTo(i,n),this._enforcingBounds=!1,this},panInside:function(e,n){n||={};var r=C(n.paddingTopLeft||n.padding||[0,0]),i=C(n.paddingBottomRight||n.padding||[0,0]),a=this.project(this.getCenter()),o=this.project(e),s=this.getPixelBounds(),c=T([s.min.add(r),s.max.subtract(i)]),l=c.getSize();if(!c.contains(o)){this._enforcingBounds=!0;var u=o.subtract(c.getCenter()),d=c.extend(o).getSize().subtract(l);a.x+=u.x<0?-d.x:d.x,a.y+=u.y<0?-d.y:d.y,this.panTo(this.unproject(a),n),this._enforcingBounds=!1}return this},invalidateSize:function(e){if(!this._loaded)return this;e=r({animate:!1,pan:!0},e===!0?{animate:!0}:e);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var i=this.getSize(),o=n.divideBy(2).round(),s=i.divideBy(2).round(),c=o.subtract(s);return!c.x&&!c.y?this:(e.animate&&e.pan?this.panBy(c):(e.pan&&this._rawPanBy(c),this.fire(`move`),e.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(a(this.fire,this,`moveend`),200)):this.fire(`moveend`)),this.fire(`resize`,{oldSize:n,newSize:i}))},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire(`viewreset`),this._stop()},locate:function(e){if(e=this._locateOptions=r({timeout:1e4,watch:!1},e),!(`geolocation`in navigator))return this._handleGeolocationError({code:0,message:`Geolocation not supported.`}),this;var n=a(this._handleGeolocationResponse,this),i=a(this._handleGeolocationError,this);return e.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,i,e):navigator.geolocation.getCurrentPosition(n,i,e),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(e){if(this._container._leaflet_id){var n=e.code,r=e.message||(n===1?`permission denied`:n===2?`position unavailable`:`timeout`);this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire(`locationerror`,{code:n,message:`Geolocation error: `+r+`.`})}},_handleGeolocationResponse:function(e){if(this._container._leaflet_id){var n=e.coords.latitude,r=e.coords.longitude,i=new O(n,r),a=i.toBounds(e.coords.accuracy*2),o=this._locateOptions;if(o.setView){var s=this.getBoundsZoom(a);this.setView(i,o.maxZoom?Math.min(s,o.maxZoom):s)}var c={latlng:i,bounds:a,timestamp:e.timestamp};for(var l in e.coords)typeof e.coords[l]==`number`&&(c[l]=e.coords[l]);this.fire(`locationfound`,c)}},addHandler:function(e,n){if(!n)return this;var r=this[e]=new n(this);return this._handlers.push(r),this.options[e]&&r.enable(),this},remove:function(){if(this._initEvents(!0),this.options.maxBounds&&this.off(`moveend`,this._panInsideMaxBounds),this._containerId!==this._container._leaflet_id)throw Error(`Map container is being reused by another instance`);try{delete this._container._leaflet_id,delete this._containerId}catch{this._container._leaflet_id=void 0,this._containerId=void 0}for(var e in this._locationWatchId!==void 0&&this.stopLocate(),this._stop(),R(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&=(b(this._resizeRequest),null),this._clearHandlers(),this._loaded&&this.fire(`unload`),this._layers)this._layers[e].remove();for(e in this._panes)R(this._panes[e]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(e,n){var r=I(`div`,`leaflet-pane`+(e?` leaflet-`+e.replace(`Pane`,``)+`-pane`:``),n||this._mapPane);return e&&(this._panes[e]=r),r},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter.clone():this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var e=this.getPixelBounds();return new E(this.unproject(e.getBottomLeft()),this.unproject(e.getTopRight()))},getMinZoom:function(){return this.options.minZoom===void 0?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===void 0?this._layersMaxZoom===void 0?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(e,n,r){e=D(e),r=C(r||[0,0]);var i=this.getZoom()||0,a=this.getMinZoom(),o=this.getMaxZoom(),s=e.getNorthWest(),c=e.getSouthEast(),l=this.getSize().subtract(r),u=T(this.project(c,i),this.project(s,i)).getSize(),d=N.any3d?this.options.zoomSnap:1,f=l.x/u.x,p=l.y/u.y,m=n?Math.max(f,p):Math.min(f,p);return i=this.getScaleZoom(m,i),d&&(i=Math.round(i/(d/100))*(d/100),i=n?Math.ceil(i/d)*d:Math.floor(i/d)*d),Math.max(a,Math.min(o,i))},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new S(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(e,n){var r=this._getTopLeftPoint(e,n);return new w(r,r.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(e){return this.options.crs.getProjectedBounds(e===void 0?this.getZoom():e)},getPane:function(e){return typeof e==`string`?this._panes[e]:e},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(e,n){var r=this.options.crs;return n=n===void 0?this._zoom:n,r.scale(e)/r.scale(n)},getScaleZoom:function(e,n){var r=this.options.crs;n=n===void 0?this._zoom:n;var i=r.zoom(e*r.scale(n));return isNaN(i)?1/0:i},project:function(e,n){return n=n===void 0?this._zoom:n,this.options.crs.latLngToPoint(k(e),n)},unproject:function(e,n){return n=n===void 0?this._zoom:n,this.options.crs.pointToLatLng(C(e),n)},layerPointToLatLng:function(e){var n=C(e).add(this.getPixelOrigin());return this.unproject(n)},latLngToLayerPoint:function(e){return this.project(k(e))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(e){return this.options.crs.wrapLatLng(k(e))},wrapLatLngBounds:function(e){return this.options.crs.wrapLatLngBounds(D(e))},distance:function(e,n){return this.options.crs.distance(k(e),k(n))},containerPointToLayerPoint:function(e){return C(e).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(e){return C(e).add(this._getMapPanePos())},containerPointToLatLng:function(e){var n=this.containerPointToLayerPoint(C(e));return this.layerPointToLatLng(n)},latLngToContainerPoint:function(e){return this.layerPointToContainerPoint(this.latLngToLayerPoint(k(e)))},mouseEventToContainerPoint:function(e){return an(e,this._container)},mouseEventToLayerPoint:function(e){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e))},mouseEventToLatLng:function(e){return this.layerPointToLatLng(this.mouseEventToLayerPoint(e))},_initContainer:function(e){var n=this._container=wt(e);if(!n)throw Error(`Map container not found.`);if(n._leaflet_id)throw Error(`Map container is already initialized.`);U(n,`scroll`,this._onScroll,this),this._containerId=s(n)},_initLayout:function(){var e=this._container;this._fadeAnimated=this.options.fadeAnimation&&N.any3d,z(e,`leaflet-container`+(N.touch?` leaflet-touch`:``)+(N.retina?` leaflet-retina`:``)+(N.ielt9?` leaflet-oldie`:``)+(N.safari?` leaflet-safari`:``)+(this._fadeAnimated?` leaflet-fade-anim`:``));var n=Tt(e,`position`);n!==`absolute`&&n!==`relative`&&n!==`fixed`&&n!==`sticky`&&(e.style.position=`relative`),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var e=this._panes={};this._paneRenderers={},this._mapPane=this.createPane(`mapPane`,this._container),H(this._mapPane,new S(0,0)),this.createPane(`tilePane`),this.createPane(`overlayPane`),this.createPane(`shadowPane`),this.createPane(`markerPane`),this.createPane(`tooltipPane`),this.createPane(`popupPane`),this.options.markerZoomAnimation||(z(e.markerPane,`leaflet-zoom-hide`),z(e.shadowPane,`leaflet-zoom-hide`))},_resetView:function(e,n,r){H(this._mapPane,new S(0,0));var i=!this._loaded;this._loaded=!0,n=this._limitZoom(n),this.fire(`viewprereset`);var a=this._zoom!==n;this._moveStart(a,r)._move(e,n)._moveEnd(a),this.fire(`viewreset`),i&&this.fire(`load`)},_moveStart:function(e,n){return e&&this.fire(`zoomstart`),n||this.fire(`movestart`),this},_move:function(e,n,r,i){n===void 0&&(n=this._zoom);var a=this._zoom!==n;return this._zoom=n,this._lastCenter=e,this._pixelOrigin=this._getNewPixelOrigin(e),i?r&&r.pinch&&this.fire(`zoom`,r):((a||r&&r.pinch)&&this.fire(`zoom`,r),this.fire(`move`,r)),this},_moveEnd:function(e){return e&&this.fire(`zoomend`),this.fire(`moveend`)},_stop:function(){return b(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(e){H(this._mapPane,this._getMapPanePos().subtract(e))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw Error(`Set map center and zoom first.`)},_initEvents:function(e){this._targets={},this._targets[s(this._container)]=this;var n=e?G:U;n(this._container,`click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup`,this._handleDOMEvent,this),this.options.trackResize&&n(window,`resize`,this._onResize,this),N.any3d&&this.options.transform3DLimit&&(e?this.off:this.on).call(this,`moveend`,this._onMoveEnd)},_onResize:function(){b(this._resizeRequest),this._resizeRequest=y(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var e=this._getMapPanePos();Math.max(Math.abs(e.x),Math.abs(e.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(e,n){for(var r=[],i,a=n===`mouseout`||n===`mouseover`,o=e.target||e.srcElement,c=!1;o;){if(i=this._targets[s(o)],i&&(n===`click`||n===`preclick`)&&this._draggableMoved(i)){c=!0;break}if(i&&i.listens(n,!0)&&(a&&!cn(o,e)||(r.push(i),a))||o===this._container)break;o=o.parentNode}return!r.length&&!c&&!a&&this.listens(n,!0)&&(r=[this]),r},_isClickDisabled:function(e){for(;e&&e!==this._container;){if(e._leaflet_disable_click)return!0;e=e.parentNode}},_handleDOMEvent:function(e){var n=e.target||e.srcElement;if(!(!this._loaded||n._leaflet_disable_events||e.type===`click`&&this._isClickDisabled(n))){var r=e.type;r===`mousedown`&&Wt(n),this._fireDOMEvent(e,r)}},_mouseEvents:[`click`,`dblclick`,`mouseover`,`mouseout`,`contextmenu`],_fireDOMEvent:function(e,n,i){if(e.type===`click`){var a=r({},e);a.type=`preclick`,this._fireDOMEvent(a,a.type,i)}var o=this._findEventTargets(e,n);if(i){for(var s=[],c=0;c0?Math.round(e-n)/2:Math.max(0,Math.ceil(e))-Math.max(0,Math.floor(n))},_limitZoom:function(e){var n=this.getMinZoom(),r=this.getMaxZoom(),i=N.any3d?this.options.zoomSnap:1;return i&&(e=Math.round(e/i)*i),Math.max(n,Math.min(r,e))},_onPanTransitionStep:function(){this.fire(`move`)},_onPanTransitionEnd:function(){B(this._mapPane,`leaflet-pan-anim`),this.fire(`moveend`)},_tryAnimatedPan:function(e,n){var r=this._getCenterOffset(e)._trunc();return(n&&n.animate)!==!0&&!this.getSize().contains(r)?!1:(this.panBy(r,n),!0)},_createAnimProxy:function(){var e=this._proxy=I(`div`,`leaflet-proxy leaflet-zoom-animated`);this._panes.mapPane.appendChild(e),this.on(`zoomanim`,function(e){var n=xt,r=this._proxy.style[n];Pt(this._proxy,this.project(e.center,e.zoom),this.getZoomScale(e.zoom,1)),r===this._proxy.style[n]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on(`load moveend`,this._animMoveEnd,this),this._on(`unload`,this._destroyAnimProxy,this)},_destroyAnimProxy:function(){R(this._proxy),this.off(`load moveend`,this._animMoveEnd,this),delete this._proxy},_animMoveEnd:function(){var e=this.getCenter(),n=this.getZoom();Pt(this._proxy,this.project(e,n),this.getZoomScale(n,1))},_catchTransitionEnd:function(e){this._animatingZoom&&e.propertyName.indexOf(`transform`)>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName(`leaflet-zoom-animated`).length},_tryAnimatedZoom:function(e,n,r){if(this._animatingZoom)return!0;if(r||={},!this._zoomAnimated||r.animate===!1||this._nothingToAnimate()||Math.abs(n-this._zoom)>this.options.zoomAnimationThreshold)return!1;var i=this.getZoomScale(n),a=this._getCenterOffset(e)._divideBy(1-1/i);return r.animate!==!0&&!this.getSize().contains(a)?!1:(y(function(){this._moveStart(!0,r.noMoveStart||!1)._animateZoom(e,n,!0)},this),!0)},_animateZoom:function(e,n,r,i){this._mapPane&&(r&&(this._animatingZoom=!0,this._animateToCenter=e,this._animateToZoom=n,z(this._mapPane,`leaflet-zoom-anim`)),this.fire(`zoomanim`,{center:e,zoom:n,noUpdate:i}),this._tempFireZoomEvent||=this._zoom!==this._animateToZoom,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&B(this._mapPane,`leaflet-zoom-anim`),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._tempFireZoomEvent&&this.fire(`zoom`),delete this._tempFireZoomEvent,this.fire(`move`),this._moveEnd(!0))}});function dn(e,n){return new q(e,n)}var J=ce.extend({options:{position:`topright`},initialize:function(e){m(this,e)},getPosition:function(){return this.options.position},setPosition:function(e){var n=this._map;return n&&n.removeControl(this),this.options.position=e,n&&n.addControl(this),this},getContainer:function(){return this._container},addTo:function(e){this.remove(),this._map=e;var n=this._container=this.onAdd(e),r=this.getPosition(),i=e._controlCorners[r];return z(n,`leaflet-control`),r.indexOf(`bottom`)===-1?i.appendChild(n):i.insertBefore(n,i.firstChild),this._map.on(`unload`,this.remove,this),this},remove:function(){return this._map?(R(this._container),this.onRemove&&this.onRemove(this._map),this._map.off(`unload`,this.remove,this),this._map=null,this):this},_refocusOnMap:function(e){this._map&&e&&e.screenX>0&&e.screenY>0&&this._map.getContainer().focus()}}),fn=function(e){return new J(e)};q.include({addControl:function(e){return e.addTo(this),this},removeControl:function(e){return e.remove(),this},_initControlPos:function(){var e=this._controlCorners={},n=`leaflet-`,r=this._controlContainer=I(`div`,n+`control-container`,this._container);function i(i,a){var o=n+i+` `+n+a;e[i+a]=I(`div`,o,r)}i(`top`,`left`),i(`top`,`right`),i(`bottom`,`left`),i(`bottom`,`right`)},_clearControlPos:function(){for(var e in this._controlCorners)R(this._controlCorners[e]);R(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var pn=J.extend({options:{collapsed:!0,position:`topright`,autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(e,n,r,i){return r1,this._baseLayersList.style.display=e?``:`none`),this._separator.style.display=n&&e?``:`none`,this},_onLayerChange:function(e){this._handlingClick||this._update();var n=this._getLayer(s(e.target)),r=n.overlay?e.type===`add`?`overlayadd`:`overlayremove`:e.type===`add`?`baselayerchange`:null;r&&this._map.fire(r,n)},_createRadioElement:function(e,n){var r=``,i=document.createElement(`div`);return i.innerHTML=r,i.firstChild},_addItem:function(e){var n=document.createElement(`label`),r=this._map.hasLayer(e.layer),i;e.overlay?(i=document.createElement(`input`),i.type=`checkbox`,i.className=`leaflet-control-layers-selector`,i.defaultChecked=r):i=this._createRadioElement(`leaflet-base-layers_`+s(this),r),this._layerControlInputs.push(i),i.layerId=s(e.layer),U(i,`click`,this._onInputClick,this);var a=document.createElement(`span`);a.innerHTML=` `+e.name;var o=document.createElement(`span`);return n.appendChild(o),o.appendChild(i),o.appendChild(a),(e.overlay?this._overlaysList:this._baseLayersList).appendChild(n),this._checkDisabledLayers(),n},_onInputClick:function(){if(!this._preventClick){var e=this._layerControlInputs,n,r,i=[],a=[];this._handlingClick=!0;for(var o=e.length-1;o>=0;o--)n=e[o],r=this._getLayer(n.layerId).layer,n.checked?i.push(r):n.checked||a.push(r);for(o=0;o=0;a--)n=e[a],r=this._getLayer(n.layerId).layer,n.disabled=r.options.minZoom!==void 0&&ir.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expandSafely:function(){var e=this._section;this._preventClick=!0,U(e,`click`,K),this.expand();var n=this;setTimeout(function(){G(e,`click`,K),n._preventClick=!1})}}),mn=function(e,n,r){return new pn(e,n,r)},hn=J.extend({options:{position:`topleft`,zoomInText:``,zoomInTitle:`Zoom in`,zoomOutText:``,zoomOutTitle:`Zoom out`},onAdd:function(e){var n=`leaflet-control-zoom`,r=I(`div`,n+` leaflet-bar`),i=this.options;return this._zoomInButton=this._createButton(i.zoomInText,i.zoomInTitle,n+`-in`,r,this._zoomIn),this._zoomOutButton=this._createButton(i.zoomOutText,i.zoomOutTitle,n+`-out`,r,this._zoomOut),this._updateDisabled(),e.on(`zoomend zoomlevelschange`,this._updateDisabled,this),r},onRemove:function(e){e.off(`zoomend zoomlevelschange`,this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(e){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(e.shiftKey?3:1))},_createButton:function(e,n,r,i,a){var o=I(`a`,r,i);return o.innerHTML=e,o.href=`#`,o.title=n,o.setAttribute(`role`,`button`),o.setAttribute(`aria-label`,n),tn(o),U(o,`click`,nn),U(o,`click`,a,this),U(o,`click`,this._refocusOnMap,this),o},_updateDisabled:function(){var e=this._map,n=`leaflet-disabled`;B(this._zoomInButton,n),B(this._zoomOutButton,n),this._zoomInButton.setAttribute(`aria-disabled`,`false`),this._zoomOutButton.setAttribute(`aria-disabled`,`false`),(this._disabled||e._zoom===e.getMinZoom())&&(z(this._zoomOutButton,n),this._zoomOutButton.setAttribute(`aria-disabled`,`true`)),(this._disabled||e._zoom===e.getMaxZoom())&&(z(this._zoomInButton,n),this._zoomInButton.setAttribute(`aria-disabled`,`true`))}});q.mergeOptions({zoomControl:!0}),q.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new hn,this.addControl(this.zoomControl))});var gn=function(e){return new hn(e)},_n=J.extend({options:{position:`bottomleft`,maxWidth:100,metric:!0,imperial:!0},onAdd:function(e){var n=`leaflet-control-scale`,r=I(`div`,n),i=this.options;return this._addScales(i,n+`-line`,r),e.on(i.updateWhenIdle?`moveend`:`move`,this._update,this),e.whenReady(this._update,this),r},onRemove:function(e){e.off(this.options.updateWhenIdle?`moveend`:`move`,this._update,this)},_addScales:function(e,n,r){e.metric&&(this._mScale=I(`div`,n,r)),e.imperial&&(this._iScale=I(`div`,n,r))},_update:function(){var e=this._map,n=e.getSize().y/2,r=e.distance(e.containerPointToLatLng([0,n]),e.containerPointToLatLng([this.options.maxWidth,n]));this._updateScales(r)},_updateScales:function(e){this.options.metric&&e&&this._updateMetric(e),this.options.imperial&&e&&this._updateImperial(e)},_updateMetric:function(e){var n=this._getRoundNum(e),r=n<1e3?n+` m`:n/1e3+` km`;this._updateScale(this._mScale,r,n/e)},_updateImperial:function(e){var n=e*3.2808399,r,i,a;n>5280?(r=n/5280,i=this._getRoundNum(r),this._updateScale(this._iScale,i+` mi`,i/r)):(a=this._getRoundNum(n),this._updateScale(this._iScale,a+` ft`,a/n))},_updateScale:function(e,n,r){e.style.width=Math.round(this.options.maxWidth*r)+`px`,e.innerHTML=n},_getRoundNum:function(e){var n=10**((Math.floor(e)+``).length-1),r=e/n;return r=r>=10?10:r>=5?5:r>=3?3:r>=2?2:1,n*r}}),vn=function(e){return new _n(e)},yn=J.extend({options:{position:`bottomright`,prefix:``+(N.inlineSvg?` `:``)+`Leaflet`},initialize:function(e){m(this,e),this._attributions={}},onAdd:function(e){for(var n in e.attributionControl=this,this._container=I(`div`,`leaflet-control-attribution`),tn(this._container),e._layers)e._layers[n].getAttribution&&this.addAttribution(e._layers[n].getAttribution());return this._update(),e.on(`layeradd`,this._addAttribution,this),this._container},onRemove:function(e){e.off(`layeradd`,this._addAttribution,this)},_addAttribution:function(e){e.layer.getAttribution&&(this.addAttribution(e.layer.getAttribution()),e.layer.once(`remove`,function(){this.removeAttribution(e.layer.getAttribution())},this))},setPrefix:function(e){return this.options.prefix=e,this._update(),this},addAttribution:function(e){return e?(this._attributions[e]||(this._attributions[e]=0),this._attributions[e]++,this._update(),this):this},removeAttribution:function(e){return e&&this._attributions[e]&&(this._attributions[e]--,this._update()),this},_update:function(){if(this._map){var e=[];for(var n in this._attributions)this._attributions[n]&&e.push(n);var r=[];this.options.prefix&&r.push(this.options.prefix),e.length&&r.push(e.join(`, `)),this._container.innerHTML=r.join(` `)}}});q.mergeOptions({attributionControl:!0}),q.addInitHook(function(){this.options.attributionControl&&new yn().addTo(this)}),J.Layers=pn,J.Zoom=hn,J.Scale=_n,J.Attribution=yn,fn.layers=mn,fn.zoom=gn,fn.scale=vn,fn.attribution=function(e){return new yn(e)};var bn=ce.extend({initialize:function(e){this._map=e},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});bn.addTo=function(e,n){return e.addHandler(n,this),this};var xn={Events:x},Sn=N.touch?`touchstart mousedown`:`mousedown`,Cn=ue.extend({options:{clickTolerance:3},initialize:function(e,n,r,i){m(this,i),this._element=e,this._dragStartTarget=n||e,this._preventOutline=r},enable:function(){this._enabled||=(U(this._dragStartTarget,Sn,this._onDown,this),!0)},disable:function(){this._enabled&&(Cn._dragging===this&&this.finishDrag(!0),G(this._dragStartTarget,Sn,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(e){if(this._enabled&&(this._moved=!1,!kt(this._element,`leaflet-zoom-anim`))){if(e.touches&&e.touches.length!==1){Cn._dragging===this&&this.finishDrag();return}if(!(Cn._dragging||e.shiftKey||e.which!==1&&e.button!==1&&!e.touches)&&(Cn._dragging=this,this._preventOutline&&Wt(this._element),Bt(),It(),!this._moving)){this.fire(`down`);var n=e.touches?e.touches[0]:e,r=Kt(this._element);this._startPoint=new S(n.clientX,n.clientY),this._startPos=Ft(this._element),this._parentScale=qt(r);var i=e.type===`mousedown`;U(document,i?`mousemove`:`touchmove`,this._onMove,this),U(document,i?`mouseup`:`touchend touchcancel`,this._onUp,this)}}},_onMove:function(e){if(this._enabled){if(e.touches&&e.touches.length>1){this._moved=!0;return}var n=e.touches&&e.touches.length===1?e.touches[0]:e,r=new S(n.clientX,n.clientY)._subtract(this._startPoint);!r.x&&!r.y||Math.abs(r.x)+Math.abs(r.y)o&&(s=c,o=l);o>r&&(n[s]=1,Mn(e,n,r,i,s),Mn(e,n,r,s,a))}function Nn(e,n){for(var r=[e[0]],i=1,a=0,o=e.length;in&&(r.push(e[i]),a=i);return an.max.x&&(r|=2),e.yn.max.y&&(r|=8),r}function Rn(e,n){var r=n.x-e.x,i=n.y-e.y;return r*r+i*i}function zn(e,n,r,i){var a=n.x,o=n.y,s=r.x-a,c=r.y-o,l=s*s+c*c,u;return l>0&&(u=((e.x-a)*s+(e.y-o)*c)/l,u>1?(a=r.x,o=r.y):u>0&&(a+=s*u,o+=c*u)),s=e.x-a,c=e.y-o,i?s*s+c*c:new S(a,o)}function Y(e){return!v(e[0])||typeof e[0][0]!=`object`&&e[0][0]!==void 0}function Bn(e){return console.warn(`Deprecated use of _flat, please use L.LineUtil.isFlat instead.`),Y(e)}function Vn(e,n){var r,i,a,o,s,c,l,u;if(!e||e.length===0)throw Error(`latlngs not passed`);Y(e)||(console.warn(`latlngs are not flat! Only the first ring will be used`),e=e[0]);var d=k([0,0]),f=D(e);f.getNorthWest().distanceTo(f.getSouthWest())*f.getNorthEast().distanceTo(f.getNorthWest())<1700&&(d=En(e));var p=e.length,m=[];for(r=0;ri){l=(o-i)/a,u=[c.x-l*(c.x-s.x),c.y-l*(c.y-s.y)];break}var g=n.unproject(C(u));return k([g.lat+d.lat,g.lng+d.lng])}var Hn={__proto__:null,simplify:On,pointToSegmentDistance:kn,closestPointOnSegment:An,clipSegment:Fn,_getEdgeIntersection:In,_getBitCode:Ln,_sqClosestPointOnSegment:zn,isFlat:Y,_flat:Bn,polylineCenter:Vn},Un={project:function(e){return new S(e.lng,e.lat)},unproject:function(e){return new O(e.y,e.x)},bounds:new w([-180,-90],[180,90])},Wn={R:6378137,R_MINOR:6356752.314245179,bounds:new w([-20037508.34279,-15496570.73972],[20037508.34279,18764656.23138]),project:function(e){var n=Math.PI/180,r=this.R,i=e.lat*n,a=this.R_MINOR/r,o=Math.sqrt(1-a*a),s=o*Math.sin(i),c=Math.tan(Math.PI/4-i/2)/((1-s)/(1+s))**(o/2);return i=-r*Math.log(Math.max(c,1e-10)),new S(e.lng*n*r,i)},unproject:function(e){for(var n=180/Math.PI,r=this.R,i=this.R_MINOR/r,a=Math.sqrt(1-i*i),o=Math.exp(-e.y/r),s=Math.PI/2-2*Math.atan(o),c=0,l=.1,u;c<15&&Math.abs(l)>1e-7;c++)u=a*Math.sin(s),u=((1-u)/(1+u))**(a/2),l=Math.PI/2-2*Math.atan(o*u)-s,s+=l;return new O(s*n,e.x*n/r)}},Gn={__proto__:null,LonLat:Un,Mercator:Wn,SphericalMercator:j},Kn=r({},fe,{code:`EPSG:3395`,projection:Wn,transformation:function(){var e=.5/(Math.PI*Wn.R);return M(e,.5,-e,.5)}()}),qn=r({},fe,{code:`EPSG:4326`,projection:Un,transformation:M(1/180,1,-1/180,.5)}),Jn=r({},A,{projection:Un,transformation:M(1,0,-1,0),scale:function(e){return 2**e},zoom:function(e){return Math.log(e)/Math.LN2},distance:function(e,n){var r=n.lng-e.lng,i=n.lat-e.lat;return Math.sqrt(r*r+i*i)},infinite:!0});A.Earth=fe,A.EPSG3395=Kn,A.EPSG3857=he,A.EPSG900913=ge,A.EPSG4326=qn,A.Simple=Jn;var X=ue.extend({options:{pane:`overlayPane`,attribution:null,bubblingMouseEvents:!0},addTo:function(e){return e.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(e){return e&&e.removeLayer(this),this},getPane:function(e){return this._map.getPane(e?this.options[e]||e:this.options.pane)},addInteractiveTarget:function(e){return this._map._targets[s(e)]=this,this},removeInteractiveTarget:function(e){return delete this._map._targets[s(e)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(e){var n=e.target;if(n.hasLayer(this)){if(this._map=n,this._zoomAnimated=n._zoomAnimated,this.getEvents){var r=this.getEvents();n.on(r,this),this.once(`remove`,function(){n.off(r,this)},this)}this.onAdd(n),this.fire(`add`),n.fire(`layeradd`,{layer:this})}}});q.include({addLayer:function(e){if(!e._layerAdd)throw Error(`The provided object is not a Layer.`);var n=s(e);return this._layers[n]?this:(this._layers[n]=e,e._mapToAdd=this,e.beforeAdd&&e.beforeAdd(this),this.whenReady(e._layerAdd,e),this)},removeLayer:function(e){var n=s(e);return this._layers[n]?(this._loaded&&e.onRemove(this),delete this._layers[n],this._loaded&&(this.fire(`layerremove`,{layer:e}),e.fire(`remove`)),e._map=e._mapToAdd=null,this):this},hasLayer:function(e){return s(e)in this._layers},eachLayer:function(e,n){for(var r in this._layers)e.call(n,this._layers[r]);return this},_addLayers:function(e){e=e?v(e)?e:[e]:[];for(var n=0,r=e.length;nthis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),this.options.minZoom===void 0&&this._layersMinZoom&&this.getZoom()=2&&n[0]instanceof O&&n[0].equals(n[r-1])&&n.pop(),n},_setLatLngs:function(e){ur.prototype._setLatLngs.call(this,e),Y(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return Y(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var e=this._renderer._bounds,n=this.options.weight,r=new S(n,n);if(e=new w(e.min.subtract(r),e.max.add(r)),this._parts=[],!(!this._pxBounds||!this._pxBounds.intersects(e))){if(this.options.noClip){this._parts=this._rings;return}for(var i=0,a=this._rings.length,o;ie.y!=a.y>e.y&&e.x<(a.x-i.x)*(e.y-i.y)/(a.y-i.y)+i.x&&(n=!n);return n||ur.prototype._containsPoint.call(this,e,!0)}});function pr(e,n){return new fr(e,n)}var mr=Zn.extend({initialize:function(e,n){m(this,n),this._layers={},e&&this.addData(e)},addData:function(e){var n=v(e)?e:e.features,r,i,a;if(n){for(r=0,i=n.length;r0&&a.push(a[0].slice()),a}function xr(e,n){return e.feature?r({},e.feature,{geometry:n}):Sr(n)}function Sr(e){return e.type===`Feature`||e.type===`FeatureCollection`?e:{type:`Feature`,properties:{},geometry:e}}var Cr={toGeoJSON:function(e){return xr(this,{type:`Point`,coordinates:yr(this.getLatLng(),e)})}};rr.include(Cr),cr.include(Cr),or.include(Cr),ur.include({toGeoJSON:function(e){var n=!Y(this._latlngs),r=br(this._latlngs,+!!n,!1,e);return xr(this,{type:(n?`Multi`:``)+`LineString`,coordinates:r})}}),fr.include({toGeoJSON:function(e){var n=!Y(this._latlngs),r=n&&!Y(this._latlngs[0]),i=br(this._latlngs,r?2:+!!n,!0,e);return n||(i=[i]),xr(this,{type:(r?`Multi`:``)+`Polygon`,coordinates:i})}}),Yn.include({toMultiPoint:function(e){var n=[];return this.eachLayer(function(r){n.push(r.toGeoJSON(e).geometry.coordinates)}),xr(this,{type:`MultiPoint`,coordinates:n})},toGeoJSON:function(e){var n=this.feature&&this.feature.geometry&&this.feature.geometry.type;if(n===`MultiPoint`)return this.toMultiPoint(e);var r=n===`GeometryCollection`,i=[];return this.eachLayer(function(n){if(n.toGeoJSON){var a=n.toGeoJSON(e);if(r)i.push(a.geometry);else{var o=Sr(a);o.type===`FeatureCollection`?i.push.apply(i,o.features):i.push(o)}}}),r?xr(this,{geometries:i,type:`GeometryCollection`}):{type:`FeatureCollection`,features:i}}});function wr(e,n){return new mr(e,n)}var Tr=wr,Er=X.extend({options:{opacity:1,alt:``,interactive:!1,crossOrigin:!1,errorOverlayUrl:``,zIndex:1,className:``},initialize:function(e,n,r){this._url=e,this._bounds=D(n),m(this,r)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(z(this._image,`leaflet-interactive`),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){R(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(e){return this.options.opacity=e,this._image&&this._updateOpacity(),this},setStyle:function(e){return e.opacity&&this.setOpacity(e.opacity),this},bringToFront:function(){return this._map&&Dt(this._image),this},bringToBack:function(){return this._map&&Ot(this._image),this},setUrl:function(e){return this._url=e,this._image&&(this._image.src=e),this},setBounds:function(e){return this._bounds=D(e),this._map&&this._reset(),this},getEvents:function(){var e={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(e.zoomanim=this._animateZoom),e},setZIndex:function(e){return this.options.zIndex=e,this._updateZIndex(),this},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var e=this._url.tagName===`IMG`,n=this._image=e?this._url:I(`img`);if(z(n,`leaflet-image-layer`),this._zoomAnimated&&z(n,`leaflet-zoom-animated`),this.options.className&&z(n,this.options.className),n.onselectstart=u,n.onmousemove=u,n.onload=a(this.fire,this,`load`),n.onerror=a(this._overlayOnError,this,`error`),(this.options.crossOrigin||this.options.crossOrigin===``)&&(n.crossOrigin=this.options.crossOrigin===!0?``:this.options.crossOrigin),this.options.zIndex&&this._updateZIndex(),e){this._url=n.src;return}n.src=this._url,n.alt=this.options.alt},_animateZoom:function(e){var n=this._map.getZoomScale(e.zoom),r=this._map._latLngBoundsToNewLayerBounds(this._bounds,e.zoom,e.center).min;Pt(this._image,r,n)},_reset:function(){var e=this._image,n=new w(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),r=n.getSize();H(e,n.min),e.style.width=r.x+`px`,e.style.height=r.y+`px`},_updateOpacity:function(){V(this._image,this.options.opacity)},_updateZIndex:function(){this._image&&this.options.zIndex!==void 0&&this.options.zIndex!==null&&(this._image.style.zIndex=this.options.zIndex)},_overlayOnError:function(){this.fire(`error`);var e=this.options.errorOverlayUrl;e&&this._url!==e&&(this._url=e,this._image.src=e)},getCenter:function(){return this._bounds.getCenter()}}),Dr=function(e,n,r){return new Er(e,n,r)},Or=Er.extend({options:{autoplay:!0,loop:!0,keepAspectRatio:!0,muted:!1,playsInline:!0},_initImage:function(){var e=this._url.tagName===`VIDEO`,n=this._image=e?this._url:I(`video`);if(z(n,`leaflet-image-layer`),this._zoomAnimated&&z(n,`leaflet-zoom-animated`),this.options.className&&z(n,this.options.className),n.onselectstart=u,n.onmousemove=u,n.onloadeddata=a(this.fire,this,`load`),e){for(var r=n.getElementsByTagName(`source`),i=[],o=0;o0?i:[n.src];return}v(this._url)||(this._url=[this._url]),!this.options.keepAspectRatio&&Object.prototype.hasOwnProperty.call(n.style,`objectFit`)&&(n.style.objectFit=`fill`),n.autoplay=!!this.options.autoplay,n.loop=!!this.options.loop,n.muted=!!this.options.muted,n.playsInline=!!this.options.playsInline;for(var s=0;s