@topvisor/ui 1.5.0-updates.0 → 1.5.0-updates.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.chunks/api-CawzY1Cw.amd.js +2 -0
- package/.chunks/api-CawzY1Cw.amd.js.map +1 -0
- package/.chunks/api-CawzY1Cw.esm.js +208 -0
- package/.chunks/api-CawzY1Cw.esm.js.map +1 -0
- package/.chunks/app-CCX-gNqz.amd.js +2 -0
- package/.chunks/app-CCX-gNqz.amd.js.map +1 -0
- package/.chunks/app-CCX-gNqz.esm.js +396 -0
- package/.chunks/app-CCX-gNqz.esm.js.map +1 -0
- package/.chunks/datepicker-BTkZOq7d.amd.js +2 -0
- package/.chunks/datepicker-BTkZOq7d.amd.js.map +1 -0
- package/.chunks/datepicker-BTkZOq7d.esm.js +38 -0
- package/.chunks/datepicker-BTkZOq7d.esm.js.map +1 -0
- package/.chunks/dialog-DeM4SApg.amd.js +2 -0
- package/.chunks/dialog-DeM4SApg.amd.js.map +1 -0
- package/.chunks/dialog-DeM4SApg.esm.js +117 -0
- package/.chunks/dialog-DeM4SApg.esm.js.map +1 -0
- package/.chunks/dialog_regionSelectorRegions-CYrmaDt3.amd.js +2 -0
- package/.chunks/dialog_regionSelectorRegions-CYrmaDt3.amd.js.map +1 -0
- package/.chunks/dialog_regionSelectorRegions-CYrmaDt3.esm.js +169 -0
- package/.chunks/dialog_regionSelectorRegions-CYrmaDt3.esm.js.map +1 -0
- package/.chunks/dialogs-CMrERMI7.amd.js +2 -0
- package/.chunks/dialogs-CMrERMI7.amd.js.map +1 -0
- package/.chunks/dialogs-CMrERMI7.esm.js +237 -0
- package/.chunks/dialogs-CMrERMI7.esm.js.map +1 -0
- package/.chunks/field-CjkpGeA7.amd.js +2 -0
- package/.chunks/field-CjkpGeA7.amd.js.map +1 -0
- package/.chunks/field-CjkpGeA7.esm.js +16 -0
- package/.chunks/field-CjkpGeA7.esm.js.map +1 -0
- package/.chunks/forms-CbUt-6Ff.amd.js +2 -0
- package/.chunks/forms-CbUt-6Ff.amd.js.map +1 -0
- package/.chunks/forms-CbUt-6Ff.esm.js +1991 -0
- package/.chunks/forms-CbUt-6Ff.esm.js.map +1 -0
- package/.chunks/formsExt-CrTmBhja.amd.js +2 -0
- package/.chunks/formsExt-CrTmBhja.amd.js.map +1 -0
- package/.chunks/formsExt-CrTmBhja.esm.js +807 -0
- package/.chunks/formsExt-CrTmBhja.esm.js.map +1 -0
- package/.chunks/lazy-CGswTOPj.amd.js +2 -0
- package/.chunks/lazy-CGswTOPj.amd.js.map +1 -0
- package/.chunks/lazy-CGswTOPj.esm.js +68 -0
- package/.chunks/lazy-CGswTOPj.esm.js.map +1 -0
- package/.chunks/mocker-CwZe-g4N.amd.js +2 -0
- package/.chunks/mocker-CwZe-g4N.amd.js.map +1 -0
- package/.chunks/mocker-CwZe-g4N.esm.js +45 -0
- package/.chunks/mocker-CwZe-g4N.esm.js.map +1 -0
- package/.chunks/notice-CslVdVNm.amd.js +4 -0
- package/.chunks/notice-CslVdVNm.amd.js.map +1 -0
- package/.chunks/notice-CslVdVNm.esm.js +191 -0
- package/.chunks/notice-CslVdVNm.esm.js.map +1 -0
- package/.chunks/popup-DrByVU-k.amd.js +2 -0
- package/.chunks/popup-DrByVU-k.amd.js.map +1 -0
- package/.chunks/popup-DrByVU-k.esm.js +444 -0
- package/.chunks/popup-DrByVU-k.esm.js.map +1 -0
- package/.chunks/popup-dNrN-eKi.amd.js +2 -0
- package/.chunks/popup-dNrN-eKi.amd.js.map +1 -0
- package/.chunks/popup-dNrN-eKi.esm.js +323 -0
- package/.chunks/popup-dNrN-eKi.esm.js.map +1 -0
- package/.chunks/punycode.es6-B-5kB2YI.amd.js +2 -0
- package/.chunks/{punycode.es6-CgGegfA_.es.js.map → punycode.es6-B-5kB2YI.amd.js.map} +1 -1
- package/.chunks/punycode.es6-B-5kB2YI.esm.js +105 -0
- package/.chunks/punycode.es6-B-5kB2YI.esm.js.map +1 -0
- package/.chunks/store-DuQpSSLL.amd.js +2 -0
- package/.chunks/{store-CX_6ZXhO.es.js.map → store-DuQpSSLL.amd.js.map} +1 -1
- package/.chunks/store-DuQpSSLL.esm.js +27 -0
- package/.chunks/store-DuQpSSLL.esm.js.map +1 -0
- package/.chunks/utils-BwiXsV0S.amd.js +2 -0
- package/.chunks/utils-BwiXsV0S.amd.js.map +1 -0
- package/.chunks/utils-BwiXsV0S.esm.js +43 -0
- package/.chunks/utils-BwiXsV0S.esm.js.map +1 -0
- package/.chunks/utils-Dd0MZgyw.amd.js +2 -0
- package/.chunks/utils-Dd0MZgyw.amd.js.map +1 -0
- package/.chunks/utils-Dd0MZgyw.esm.js +287 -0
- package/.chunks/utils-Dd0MZgyw.esm.js.map +1 -0
- package/.chunks/worker-Db8YrEHo.amd.js +2 -0
- package/.chunks/worker-Db8YrEHo.amd.js.map +1 -0
- package/.chunks/worker-Db8YrEHo.esm.js +100 -0
- package/.chunks/worker-Db8YrEHo.esm.js.map +1 -0
- package/api/additional.amd.js +2 -2
- package/api/additional.amd.js.map +1 -1
- package/api/additional.js +70 -66
- package/api/additional.js.map +1 -1
- package/api/index.amd.js +2 -2
- package/api/index.amd.js.map +1 -1
- package/api/index.js +3 -285
- package/assets/charts.css +1 -1
- package/assets/core.css +1 -1
- package/assets/dialog_regionSelectorRegions.css +1 -1
- package/assets/extra.css +1 -1
- package/assets/forms.css +1 -1
- package/assets/formsExt.css +1 -0
- package/assets/layout.css +1 -1
- package/assets/notice.css +1 -1
- package/assets/popup.css +1 -0
- package/assets/project.css +1 -1
- package/assets/tabs.css +1 -1
- package/assets/tabsView.css +1 -1
- package/assets/themes/dark-th.css +1 -1
- package/assets/themes/dark.css +1 -1
- package/assets/themes/light.css +1 -1
- package/autoload-css-manifest.amd.json +79 -0
- package/autoload-css-manifest.json +90 -0
- package/charts/charts.amd.js +2 -2
- package/charts/charts.amd.js.map +1 -1
- package/charts/charts.js +146 -174
- package/charts/charts.js.map +1 -1
- package/core/app.amd.js +2 -2
- package/core/app.amd.js.map +1 -1
- package/core/app.js +5 -213
- package/dialog/dialog.amd.js +2 -2
- package/dialog/dialog.amd.js.map +1 -1
- package/dialog/dialog.js +4 -60
- package/extra/extra.amd.js +2 -2
- package/extra/extra.amd.js.map +1 -1
- package/extra/extra.js +73 -69
- package/extra/extra.js.map +1 -1
- package/forms/forms.amd.js +2 -2
- package/forms/forms.amd.js.map +1 -1
- package/forms/forms.js +2 -19
- package/forms/helpers.amd.js +2 -2
- package/forms/helpers.amd.js.map +1 -1
- package/forms/helpers.js +0 -2
- package/formsExt/formsExt.amd.js +2 -2
- package/formsExt/formsExt.amd.js.map +1 -1
- package/formsExt/formsExt.js +2 -373
- package/icomoon/demo-files/demo.amd.js +2 -0
- package/icomoon/demo-files/demo.amd.js.map +1 -0
- package/icomoon/demo.amd.js +2 -0
- package/icomoon/demo.amd.js.map +1 -0
- package/layout/layout.amd.js +2 -2
- package/layout/layout.amd.js.map +1 -1
- package/layout/layout.js +41 -57
- package/layout/layout.js.map +1 -1
- package/package.json +1 -1
- package/popup/popup.amd.js +2 -2
- package/popup/popup.amd.js.map +1 -1
- package/popup/popup.js +2 -282
- package/popup/worker.amd.js +2 -2
- package/popup/worker.amd.js.map +1 -1
- package/popup/worker.js +2 -144
- package/project/project.amd.js +2 -2
- package/project/project.amd.js.map +1 -1
- package/project/project.js +1684 -1642
- package/project/project.js.map +1 -1
- package/tabs/tabs.amd.js +2 -2
- package/tabs/tabs.amd.js.map +1 -1
- package/tabs/tabs.js +63 -77
- package/tabs/tabs.js.map +1 -1
- package/tabsView/tabsView.amd.js +2 -2
- package/tabsView/tabsView.amd.js.map +1 -1
- package/tabsView/tabsView.js +245 -288
- package/tabsView/tabsView.js.map +1 -1
- package/utils/check.amd.js +2 -2
- package/utils/check.amd.js.map +1 -1
- package/utils/check.js +15 -19
- package/utils/check.js.map +1 -1
- package/utils/clipboard.amd.js +6 -6
- package/utils/clipboard.amd.js.map +1 -1
- package/utils/clipboard.js +26 -31
- package/utils/clipboard.js.map +1 -1
- package/utils/date.amd.js +2 -2
- package/utils/date.amd.js.map +1 -1
- package/utils/date.js +2 -12
- package/utils/device.amd.js +2 -2
- package/utils/device.amd.js.map +1 -1
- package/utils/device.js +2 -15
- package/utils/dom.amd.js +2 -2
- package/utils/dom.amd.js.map +1 -1
- package/utils/dom.js +53 -67
- package/utils/dom.js.map +1 -1
- package/utils/image.amd.js +3 -3
- package/utils/image.amd.js.map +1 -1
- package/utils/image.js +12 -22
- package/utils/image.js.map +1 -1
- package/utils/keyboard.amd.js +2 -2
- package/utils/keyboard.amd.js.map +1 -1
- package/utils/keyboard.js +10 -11
- package/utils/keyboard.js.map +1 -1
- package/utils/lodash.amd.js +2 -2
- package/utils/lodash.amd.js.map +1 -1
- package/utils/lodash.js +2 -9
- package/utils/number.amd.js +2 -2
- package/utils/number.amd.js.map +1 -1
- package/utils/number.js +12 -12
- package/utils/number.js.map +1 -1
- package/utils/price.amd.js +2 -2
- package/utils/price.amd.js.map +1 -1
- package/utils/price.js +14 -9
- package/utils/price.js.map +1 -1
- package/utils/route.amd.js +2 -2
- package/utils/route.amd.js.map +1 -1
- package/utils/route.js +33 -37
- package/utils/route.js.map +1 -1
- package/utils/scroll.amd.js +2 -2
- package/utils/scroll.amd.js.map +1 -1
- package/utils/scroll.js +39 -43
- package/utils/scroll.js.map +1 -1
- package/utils/searchers.amd.js +2 -2
- package/utils/searchers.amd.js.map +1 -1
- package/utils/searchers.js +128 -133
- package/utils/searchers.js.map +1 -1
- package/utils/store.amd.js +2 -2
- package/utils/store.amd.js.map +1 -1
- package/utils/store.js +2 -7
- package/utils/string.amd.js +2 -2
- package/utils/string.amd.js.map +1 -1
- package/utils/string.js +120 -147
- package/utils/string.js.map +1 -1
- package/utils/system.amd.js +2 -2
- package/utils/system.amd.js.map +1 -1
- package/utils/system.js +25 -28
- package/utils/system.js.map +1 -1
- package/utils/url.amd.js +3 -3
- package/utils/url.amd.js.map +1 -1
- package/utils/url.js +36 -47
- package/utils/url.js.map +1 -1
- package/.chunks/core-Dgj_YGWh.es.js +0 -268
- package/.chunks/core-Dgj_YGWh.es.js.map +0 -1
- package/.chunks/core-DzDFXOdI.amd.js +0 -2
- package/.chunks/core-DzDFXOdI.amd.js.map +0 -1
- package/.chunks/datepicker-oa8ZwRhq.amd.js +0 -2
- package/.chunks/datepicker-oa8ZwRhq.amd.js.map +0 -1
- package/.chunks/datepicker-qToxk2nN.es.js +0 -41
- package/.chunks/datepicker-qToxk2nN.es.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-CZ0tMVSq.amd.js +0 -2
- package/.chunks/dialog_regionSelectorRegions-CZ0tMVSq.amd.js.map +0 -1
- package/.chunks/dialog_regionSelectorRegions-qDW2Ejsv.es.js +0 -180
- package/.chunks/dialog_regionSelectorRegions-qDW2Ejsv.es.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-BBix_8WK.amd.js +0 -2
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-BBix_8WK.amd.js.map +0 -1
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CJ97l1ST.es.js +0 -323
- package/.chunks/dialogs.vue_vue_type_script_setup_true_lang-CJ97l1ST.es.js.map +0 -1
- package/.chunks/field-Cvv0SRcJ.amd.js +0 -2
- package/.chunks/field-Cvv0SRcJ.amd.js.map +0 -1
- package/.chunks/field-CyyFzM-Y.es.js +0 -16
- package/.chunks/field-CyyFzM-Y.es.js.map +0 -1
- package/.chunks/forms-DDNzqU6o.amd.js +0 -3
- package/.chunks/forms-DDNzqU6o.amd.js.map +0 -1
- package/.chunks/forms-DtC-EKJL.es.js +0 -2053
- package/.chunks/forms-DtC-EKJL.es.js.map +0 -1
- package/.chunks/index-DLUtoTUg.amd.js +0 -2
- package/.chunks/index-DLUtoTUg.amd.js.map +0 -1
- package/.chunks/index-DkQWJkMc.es.js +0 -54
- package/.chunks/index-DkQWJkMc.es.js.map +0 -1
- package/.chunks/lazy-DDNqYkXn.amd.js +0 -2
- package/.chunks/lazy-DDNqYkXn.amd.js.map +0 -1
- package/.chunks/lazy-HKSyLh72.es.js +0 -75
- package/.chunks/lazy-HKSyLh72.es.js.map +0 -1
- package/.chunks/notice-BvQl911b.es.js +0 -191
- package/.chunks/notice-BvQl911b.es.js.map +0 -1
- package/.chunks/notice-CJ3WOTCM.amd.js +0 -4
- package/.chunks/notice-CJ3WOTCM.amd.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-Dd5-B4Ss.es.js +0 -139
- package/.chunks/page.vue_vue_type_script_setup_true_lang-Dd5-B4Ss.es.js.map +0 -1
- package/.chunks/page.vue_vue_type_script_setup_true_lang-fl6-Ql4d.amd.js +0 -2
- package/.chunks/page.vue_vue_type_script_setup_true_lang-fl6-Ql4d.amd.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-Bv3LwNDC.es.js +0 -519
- package/.chunks/policy.vue_vue_type_style_index_0_lang-Bv3LwNDC.es.js.map +0 -1
- package/.chunks/policy.vue_vue_type_style_index_0_lang-Da7rztT5.amd.js +0 -2
- package/.chunks/policy.vue_vue_type_style_index_0_lang-Da7rztT5.amd.js.map +0 -1
- package/.chunks/popup-OuDglAOF.es.js +0 -470
- package/.chunks/popup-OuDglAOF.es.js.map +0 -1
- package/.chunks/popup-yXIpyok3.amd.js +0 -2
- package/.chunks/popup-yXIpyok3.amd.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-Bu_HvFoW.amd.js +0 -2
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-Bu_HvFoW.amd.js.map +0 -1
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DAQIAxvu.es.js +0 -209
- package/.chunks/popupHint.vue_vue_type_style_index_0_lang-DAQIAxvu.es.js.map +0 -1
- package/.chunks/punycode.es6-CNOnFR2-.amd.js +0 -2
- package/.chunks/punycode.es6-CNOnFR2-.amd.js.map +0 -1
- package/.chunks/punycode.es6-CgGegfA_.es.js +0 -134
- package/.chunks/store-CX_6ZXhO.es.js +0 -29
- package/.chunks/store-YRW59xEF.amd.js +0 -2
- package/.chunks/store-YRW59xEF.amd.js.map +0 -1
- package/.chunks/utils-BNzP9anP.es.js +0 -78
- package/.chunks/utils-BNzP9anP.es.js.map +0 -1
- package/.chunks/utils-CWn_G7OO.amd.js +0 -2
- package/.chunks/utils-CWn_G7OO.amd.js.map +0 -1
- package/.chunks/utils-DIviuVEw.amd.js +0 -2
- package/.chunks/utils-DIviuVEw.amd.js.map +0 -1
- package/.chunks/utils-Dma85ehT.es.js +0 -288
- package/.chunks/utils-Dma85ehT.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CX_BOcVY.es.js +0 -39
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CX_BOcVY.es.js.map +0 -1
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CkOmb3VD.amd.js +0 -2
- package/.chunks/widgetInput.vue_vue_type_script_setup_true_lang-CkOmb3VD.amd.js.map +0 -1
- package/api/index.js.map +0 -1
- package/assets/policy.css +0 -1
- package/assets/popupHint.css +0 -1
- package/core/app.js.map +0 -1
- package/dialog/dialog.js.map +0 -1
- package/forms/forms.js.map +0 -1
- package/forms/helpers.js.map +0 -1
- package/formsExt/formsExt.js.map +0 -1
- package/popup/popup.js.map +0 -1
- package/popup/worker.js.map +0 -1
- package/utils/date.js.map +0 -1
- package/utils/device.js.map +0 -1
- package/utils/lodash.js.map +0 -1
- package/utils/store.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formsExt-CrTmBhja.esm.js","names":["$emit","$slots","$i18n","$core","$slots","$core","$slots","$props","$props","$slots"],"sources":["../../src/components/formsExt/menu/menu.vue","../../src/components/formsExt/menu/menu.vue","../../src/components/formsExt/selector2/itemMulti.vue","../../src/components/formsExt/selector2/itemMulti.vue","../../src/components/formsExt/selector2/cache.ts","../../src/components/formsExt/selector2/composables/useAPI.ts","../../src/components/formsExt/selector2/utils.ts","../../src/components/formsExt/selector2/composables/useMenu.ts","../../src/components/formsExt/selector2/selector2.vue","../../src/components/formsExt/selector2/selector2.vue","../../src/components/formsExt/editArea/editArea.vue","../../src/components/formsExt/editArea/editArea.vue","../../src/components/formsExt/editInput/editInput.vue","../../src/components/formsExt/editInput/editInput.vue","../../src/components/formsExt/libs/optionGroup/optionGroup.vue","../../src/components/formsExt/libs/optionGroup/optionGroup.vue","../../src/components/formsExt/radioGroup/radioGroup.vue","../../src/components/formsExt/radioGroup/radioGroup.vue","../../src/components/formsExt/checkboxGroup/checkboxGroup.vue","../../src/components/formsExt/checkboxGroup/checkboxGroup.vue","../../src/components/formsExt/info/info.vue","../../src/components/formsExt/info/info.vue","../../src/components/formsExt/policy/policy.vue","../../src/components/formsExt/policy/policy.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref } from 'vue';\nimport type { Item, Props } from './types';\nimport Core from '@/core/core/core';\nimport { isSafari } from '@/core/utils/device';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n});\n\nconst model = defineModel({\n\trequired: true,\n});\n\nconst el = ref();\n\n// валидация типа modelValue без возможности выбора нескольких значений (ожидается строка или число)\nif (!props.isMultiple && typeof (model.value) !== 'string' && typeof (model.value) !== 'number') {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected String: ' + typeof (model.value));\n}\n\n// валидация типа modelValue с возможностью выбора нескольких значений (ожидается массив)\nif (props.isMultiple && !Array.isArray(model.value)) {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected Array: ' + typeof (model.value));\n}\n\n/**\n * Для множественного выбора без пустого множества\n *\n * Если ничего не выбрано, присваиваем 1-ое значение\n */\nif (props.isMultiple && !props.canBeEmptyMultiple && Array.isArray(model.value) && !model.value.length && props.items[0]) {\n\tmodel.value = [props.items[0]?.href ?? props.items[0]?.value];\n}\n\nconst itemIsActive = (item: Item) => {\n\tif (!Array.isArray(model.value)) {\n\t\treturn item.value === model.value;\n\t}\n\n\treturn model.value.includes(item.value);\n};\n\n/**\n * Выбрать элемент\n * @param item\n * @param toggle - добавить или исключить элемент, для isMultiple\n */\nconst select = (item: Item, toggle = false) => {\n\tif (Array.isArray(model.value)) {\n\t\tlet modelNew = model.value.slice();\n\n\t\tif (toggle) {\n\t\t\tif (!modelNew.length) modelNew = props.items.map(item => item.value);\n\n\t\t\tconst index = modelNew.indexOf(item.value);\n\t\t\tif (index === -1) {\n\t\t\t\tmodelNew.push(item.value);\n\t\t\t} else {\n\t\t\t\tmodelNew.splice(index, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (modelNew.length === 1 && modelNew[0] === item.value) {\n\t\t\t\tmodelNew = [];\n\t\t\t} else {\n\t\t\t\tmodelNew = [item.value];\n\t\t\t}\n\t\t}\n\n\t\tif (!props.canBeEmptyMultiple && !modelNew.length) modelNew = [item.value];\n\n\t\tmodel.value = modelNew;\n\n\t\treturn;\n\t}\n\n\tmodel.value = item.value;\n};\n\n// вертикальный скролл в горизонтальный скролл\nconst onWheel = (event: WheelEvent) => {\n\tif (el.value.scrollWidth <= el.value.offsetWidth) return;\n\tif (event.shiftKey) return;\n\tif (Math.abs(event.deltaY) < 50) return; // устройство с высокой точностью, например тачпад\n\n\tevent.preventDefault();\n\n\tconst delta = event.deltaY > 0 ? 30 : -30;\n\tel.value.scrollLeft = el.value.scrollLeft + delta;\n};\n\n/**\n * Замена стандартному scrollIntoView, который меняет скролл документа\n *\n * Выравнивание по ближнему краю элемента\n *\n * Выравнивается таким образом, чтобы был виден соседний элемент\n */\nconst scrollIntoView = (isSmooth = true) => {\n\tconst elBtn = el.value.querySelector('.top-active');\n\tif (!elBtn) return;\n\n\tconst gap = 24;\n\n\t// левая и правая координаты элемента\n\tconst leftMargin = elBtn.offsetLeft - el.value.offsetLeft - gap;\n\tconst rightMargin = elBtn.offsetLeft - el.value.offsetLeft + elBtn.clientWidth + gap;\n\n\t// левая и правая границы видимой части меню\n\tconst leftMarginParent = el.value.scrollLeft;\n\tconst rightMarginParent = el.value.clientWidth + el.value.scrollLeft;\n\n\tlet scrollLeft: number | undefined = undefined;\n\n\t// левую границу элемента к левой границе меню\n\tif (leftMargin < leftMarginParent) scrollLeft = leftMargin;\n\n\t// правую границу элемента к правой границе меню\n\tif (rightMargin > rightMarginParent) scrollLeft = rightMargin - el.value.clientWidth;\n\n\tif (scrollLeft !== undefined) {\n\t\tif (isSafari()) {\n\t\t\tCore.$?.(el.value).animate({ scrollLeft: scrollLeft }, isSmooth ? 200 : 0);\n\t\t} else {\n\t\t\tel.value.scrollTo({ left: scrollLeft, behavior: isSmooth ? 'smooth' : 'auto' });\n\t\t}\n\t}\n};\n\n/**\n * Выбрать все элементы в меню\n */\nconst selectAll = () => {\n\tif (!Array.isArray(model.value)) return;\n\n\tif (model.value.length === props.items.length) {\n\t\tmodel.value = [props.items[0].href ?? props.items[0].value];\n\t\treturn;\n\t}\n\n\tmodel.value = props.items.map(item => item.href ?? item.value);\n};\n\nonMounted(() => scrollIntoView(false));\nonUpdated(() => scrollIntoView(true));\n\n</script>\n\n<template>\n\t<div\n\t\tref=\"el\"\n\t\t:class=\"{\n\t\t\t'top-menu': true,\n\t\t\t['top-style_' + styling]: true,\n\t\t\t// ['top-unwrap-x']: styling === 'default',\n\t\t}\"\n\t\t@wheel=\"onWheel\"\n\t>\n\t\t<TopButton\n\t\t\tv-for=\"item in items\"\n\t\t\t:=\"item\"\n\t\t\tclass=\"top-menu_item\"\n\t\t\tcolor=\"theme\"\n\t\t\t@click=\"select(item, $event.ctrlKey || $event.metaKey)\"\n\t\t\t:isActive=\"itemIsActive(item)\"\n\t\t>\n\t\t\t<template #default v-if=\"item.content\">\n\t\t\t\t{{ item.content }}\n\t\t\t</template>\n\t\t</TopButton>\n\n\t\t<div\n\t\t\tv-if=\"Array.isArray(model) && selectAllItem\"\n\t\t\tclass=\"top-menu_selectAll\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\t:=\"selectAllItem\"\n\t\t\t\tclass=\"top-menu_item\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\tstyling=\"\"\n\t\t\t\t@click=\"selectAll()\"\n\t\t\t\t:isActive=\"model.length === items.length\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"selectAllItem.content\">\n\t\t\t\t\t{{ selectAllItem.content }}\n\t\t\t\t</template>\n\t\t\t</TopButton>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-menu {\n\t--scroll-thumb-color: var(--color-line-1);\n\t--scroll-thumb-color-hover: var(--color-line-2);\n\t--scroll-thumb-color-active: var(--color-line-3);\n\n\tmax-width: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: var(--top-gap-2);\n\toverflow-x: auto;\n\tscrollbar-width: none; /* firefox */\n\n\t/* предотвратить натинвые события браузера (назад / вперед) */\n\toverscroll-behavior-x: contain;\n}\n\n.top-menu::-webkit-scrollbar { display: none; }\n\n.top-menu .top-menu_item {\n\t--top-button-color: var(--color-text-2);\n\n\toutline-offset: -2px !important;\n\tmin-width: 0;\n\tmax-width: 200px;\n\tmargin: 0;\n\tflex-shrink: 0;\n}\n\n.top-menu .top-menu_item[data-top-icon] {\n\t--top-icon-color: var(--color-text-2);\n}\n\n.top-menu_selectAll {\n\tposition: sticky;\n\tright: 0;\n\tbackground: var(--color-layout-front-1);\n\tborder-left: 1px solid var(--color-line-1);\n\tpadding-left: var(--top-padding-1);\n\tbox-shadow: var(--color-layout-front-1) var(--top-padding-2) 0px;\n}\n\n/* style default */\n.top-menu.top-style_default .top-menu_item {\n\t--top-forms-radius: 0;\n\t--top-forms-border-color: transparent;\n\t--top-forms-border-width: 2px;\n\n\tfilter: none;\n\tbox-shadow: none;\n\tborder: none;\n\tborder-bottom: var(--top-forms-border-width) solid var(--top-forms-border-color);\n\tbackground: none;\n}\n\n.top-style_default > .top-menu_item > [data-top-badge] {\n\tmargin-top: 0;\n}\n\n.top-menu.top-style_default .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-2);\n}\n\n.top-menu.top-style_default .top-menu_item:active,\n.top-menu.top-style_default .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-primary-1);\n}\n\n.top-menu.top-style_default .top-menu_selectAll {\n\tpadding-left: var(--top-padding-2);\n}\n\n/* style bar */\n.top-menu.top-style_bar {\n\tborder-radius: var(--top-radius-3);\n\tborder: 1px solid var(--color-line-2);\n\tpadding: var(--top-padding-1);\n\tgap: 3px;\n}\n.top-menu.top-style_bar .top-menu_item {\n\t--top-button-background-color-hover: var(--color-layer-1);\n\t--top-button-background-color-active: var(--color-layer-2);\n\t--top-button-background-color-selected: var(--color-layer-primary-1);\n\n\tposition: relative;\n}\n\n.top-menu.top-style_bar .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n}\n\n.top-menu.top-style_bar .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-primary);\n}\n\n/* разделители кнопок в баре */\n.top-menu.top-style_bar .top-menu_item:not(:first-child):not(.top-active):not(:hover):after {\n\tcontent: \"\";\n\tbackground: var(--color-line-1-opacity);\n\twidth: 1px;\n\theight: 60%;\n\tdisplay: block;\n\tposition: absolute;\n\tleft: -2px;\n}\n.top-menu.top-style_bar .top-menu_item.top-active + .top-menu_item:after,\n.top-menu.top-style_bar .top-menu_item:hover + .top-menu_item:after {\n\tcontent: none !important;\n}\n\n/*\n.top-style_bar > .top-menu_item > [data-top-badge] {\n\tmargin-top: -3px;\n}\n*/\n\n/** TODO: .top-unwrap-x надо вынести глобально в UI или добавить в стили для storybook */\n/*\n.top-menu.top-unwrap-x {\n\tpadding-right: var(--top-unwrap-x);\n\tpadding-left: var(--top-unwrap-x);\n\tmargin-right: calc(0px - var(--top-unwrap-x));\n\tmargin-left: calc(0px - var(--top-unwrap-x));\n}\n*/\n</style>\n","<script setup lang=\"ts\">\nimport { onMounted, onUpdated, ref } from 'vue';\nimport type { Item, Props } from './types';\nimport Core from '@/core/core/core';\nimport { isSafari } from '@/core/utils/device';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n});\n\nconst model = defineModel({\n\trequired: true,\n});\n\nconst el = ref();\n\n// валидация типа modelValue без возможности выбора нескольких значений (ожидается строка или число)\nif (!props.isMultiple && typeof (model.value) !== 'string' && typeof (model.value) !== 'number') {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected String: ' + typeof (model.value));\n}\n\n// валидация типа modelValue с возможностью выбора нескольких значений (ожидается массив)\nif (props.isMultiple && !Array.isArray(model.value)) {\n\tconsole.warn('Type check failed for prop \"modelValue\". Expected Array: ' + typeof (model.value));\n}\n\n/**\n * Для множественного выбора без пустого множества\n *\n * Если ничего не выбрано, присваиваем 1-ое значение\n */\nif (props.isMultiple && !props.canBeEmptyMultiple && Array.isArray(model.value) && !model.value.length && props.items[0]) {\n\tmodel.value = [props.items[0]?.href ?? props.items[0]?.value];\n}\n\nconst itemIsActive = (item: Item) => {\n\tif (!Array.isArray(model.value)) {\n\t\treturn item.value === model.value;\n\t}\n\n\treturn model.value.includes(item.value);\n};\n\n/**\n * Выбрать элемент\n * @param item\n * @param toggle - добавить или исключить элемент, для isMultiple\n */\nconst select = (item: Item, toggle = false) => {\n\tif (Array.isArray(model.value)) {\n\t\tlet modelNew = model.value.slice();\n\n\t\tif (toggle) {\n\t\t\tif (!modelNew.length) modelNew = props.items.map(item => item.value);\n\n\t\t\tconst index = modelNew.indexOf(item.value);\n\t\t\tif (index === -1) {\n\t\t\t\tmodelNew.push(item.value);\n\t\t\t} else {\n\t\t\t\tmodelNew.splice(index, 1);\n\t\t\t}\n\t\t} else {\n\t\t\tif (modelNew.length === 1 && modelNew[0] === item.value) {\n\t\t\t\tmodelNew = [];\n\t\t\t} else {\n\t\t\t\tmodelNew = [item.value];\n\t\t\t}\n\t\t}\n\n\t\tif (!props.canBeEmptyMultiple && !modelNew.length) modelNew = [item.value];\n\n\t\tmodel.value = modelNew;\n\n\t\treturn;\n\t}\n\n\tmodel.value = item.value;\n};\n\n// вертикальный скролл в горизонтальный скролл\nconst onWheel = (event: WheelEvent) => {\n\tif (el.value.scrollWidth <= el.value.offsetWidth) return;\n\tif (event.shiftKey) return;\n\tif (Math.abs(event.deltaY) < 50) return; // устройство с высокой точностью, например тачпад\n\n\tevent.preventDefault();\n\n\tconst delta = event.deltaY > 0 ? 30 : -30;\n\tel.value.scrollLeft = el.value.scrollLeft + delta;\n};\n\n/**\n * Замена стандартному scrollIntoView, который меняет скролл документа\n *\n * Выравнивание по ближнему краю элемента\n *\n * Выравнивается таким образом, чтобы был виден соседний элемент\n */\nconst scrollIntoView = (isSmooth = true) => {\n\tconst elBtn = el.value.querySelector('.top-active');\n\tif (!elBtn) return;\n\n\tconst gap = 24;\n\n\t// левая и правая координаты элемента\n\tconst leftMargin = elBtn.offsetLeft - el.value.offsetLeft - gap;\n\tconst rightMargin = elBtn.offsetLeft - el.value.offsetLeft + elBtn.clientWidth + gap;\n\n\t// левая и правая границы видимой части меню\n\tconst leftMarginParent = el.value.scrollLeft;\n\tconst rightMarginParent = el.value.clientWidth + el.value.scrollLeft;\n\n\tlet scrollLeft: number | undefined = undefined;\n\n\t// левую границу элемента к левой границе меню\n\tif (leftMargin < leftMarginParent) scrollLeft = leftMargin;\n\n\t// правую границу элемента к правой границе меню\n\tif (rightMargin > rightMarginParent) scrollLeft = rightMargin - el.value.clientWidth;\n\n\tif (scrollLeft !== undefined) {\n\t\tif (isSafari()) {\n\t\t\tCore.$?.(el.value).animate({ scrollLeft: scrollLeft }, isSmooth ? 200 : 0);\n\t\t} else {\n\t\t\tel.value.scrollTo({ left: scrollLeft, behavior: isSmooth ? 'smooth' : 'auto' });\n\t\t}\n\t}\n};\n\n/**\n * Выбрать все элементы в меню\n */\nconst selectAll = () => {\n\tif (!Array.isArray(model.value)) return;\n\n\tif (model.value.length === props.items.length) {\n\t\tmodel.value = [props.items[0].href ?? props.items[0].value];\n\t\treturn;\n\t}\n\n\tmodel.value = props.items.map(item => item.href ?? item.value);\n};\n\nonMounted(() => scrollIntoView(false));\nonUpdated(() => scrollIntoView(true));\n\n</script>\n\n<template>\n\t<div\n\t\tref=\"el\"\n\t\t:class=\"{\n\t\t\t'top-menu': true,\n\t\t\t['top-style_' + styling]: true,\n\t\t\t// ['top-unwrap-x']: styling === 'default',\n\t\t}\"\n\t\t@wheel=\"onWheel\"\n\t>\n\t\t<TopButton\n\t\t\tv-for=\"item in items\"\n\t\t\t:=\"item\"\n\t\t\tclass=\"top-menu_item\"\n\t\t\tcolor=\"theme\"\n\t\t\t@click=\"select(item, $event.ctrlKey || $event.metaKey)\"\n\t\t\t:isActive=\"itemIsActive(item)\"\n\t\t>\n\t\t\t<template #default v-if=\"item.content\">\n\t\t\t\t{{ item.content }}\n\t\t\t</template>\n\t\t</TopButton>\n\n\t\t<div\n\t\t\tv-if=\"Array.isArray(model) && selectAllItem\"\n\t\t\tclass=\"top-menu_selectAll\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\t:=\"selectAllItem\"\n\t\t\t\tclass=\"top-menu_item\"\n\t\t\t\tcolor=\"theme\"\n\t\t\t\tstyling=\"\"\n\t\t\t\t@click=\"selectAll()\"\n\t\t\t\t:isActive=\"model.length === items.length\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"selectAllItem.content\">\n\t\t\t\t\t{{ selectAllItem.content }}\n\t\t\t\t</template>\n\t\t\t</TopButton>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-menu {\n\t--scroll-thumb-color: var(--color-line-1);\n\t--scroll-thumb-color-hover: var(--color-line-2);\n\t--scroll-thumb-color-active: var(--color-line-3);\n\n\tmax-width: 100%;\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: var(--top-gap-2);\n\toverflow-x: auto;\n\tscrollbar-width: none; /* firefox */\n\n\t/* предотвратить натинвые события браузера (назад / вперед) */\n\toverscroll-behavior-x: contain;\n}\n\n.top-menu::-webkit-scrollbar { display: none; }\n\n.top-menu .top-menu_item {\n\t--top-button-color: var(--color-text-2);\n\n\toutline-offset: -2px !important;\n\tmin-width: 0;\n\tmax-width: 200px;\n\tmargin: 0;\n\tflex-shrink: 0;\n}\n\n.top-menu .top-menu_item[data-top-icon] {\n\t--top-icon-color: var(--color-text-2);\n}\n\n.top-menu_selectAll {\n\tposition: sticky;\n\tright: 0;\n\tbackground: var(--color-layout-front-1);\n\tborder-left: 1px solid var(--color-line-1);\n\tpadding-left: var(--top-padding-1);\n\tbox-shadow: var(--color-layout-front-1) var(--top-padding-2) 0px;\n}\n\n/* style default */\n.top-menu.top-style_default .top-menu_item {\n\t--top-forms-radius: 0;\n\t--top-forms-border-color: transparent;\n\t--top-forms-border-width: 2px;\n\n\tfilter: none;\n\tbox-shadow: none;\n\tborder: none;\n\tborder-bottom: var(--top-forms-border-width) solid var(--top-forms-border-color);\n\tbackground: none;\n}\n\n.top-style_default > .top-menu_item > [data-top-badge] {\n\tmargin-top: 0;\n}\n\n.top-menu.top-style_default .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-2);\n}\n\n.top-menu.top-style_default .top-menu_item:active,\n.top-menu.top-style_default .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-1);\n\t--top-forms-border-color: var(--color-line-primary-1);\n}\n\n.top-menu.top-style_default .top-menu_selectAll {\n\tpadding-left: var(--top-padding-2);\n}\n\n/* style bar */\n.top-menu.top-style_bar {\n\tborder-radius: var(--top-radius-3);\n\tborder: 1px solid var(--color-line-2);\n\tpadding: var(--top-padding-1);\n\tgap: 3px;\n}\n.top-menu.top-style_bar .top-menu_item {\n\t--top-button-background-color-hover: var(--color-layer-1);\n\t--top-button-background-color-active: var(--color-layer-2);\n\t--top-button-background-color-selected: var(--color-layer-primary-1);\n\n\tposition: relative;\n}\n\n.top-menu.top-style_bar .top-menu_item:hover {\n\t--top-icon-color: var(--color-text-1);\n\t--top-button-color: var(--color-text-1);\n}\n\n.top-menu.top-style_bar .top-menu_item.top-active {\n\t--top-icon-color: var(--color-text-primary);\n\t--top-button-color: var(--color-text-primary);\n}\n\n/* разделители кнопок в баре */\n.top-menu.top-style_bar .top-menu_item:not(:first-child):not(.top-active):not(:hover):after {\n\tcontent: \"\";\n\tbackground: var(--color-line-1-opacity);\n\twidth: 1px;\n\theight: 60%;\n\tdisplay: block;\n\tposition: absolute;\n\tleft: -2px;\n}\n.top-menu.top-style_bar .top-menu_item.top-active + .top-menu_item:after,\n.top-menu.top-style_bar .top-menu_item:hover + .top-menu_item:after {\n\tcontent: none !important;\n}\n\n/*\n.top-style_bar > .top-menu_item > [data-top-badge] {\n\tmargin-top: -3px;\n}\n*/\n\n/** TODO: .top-unwrap-x надо вынести глобально в UI или добавить в стили для storybook */\n/*\n.top-menu.top-unwrap-x {\n\tpadding-right: var(--top-unwrap-x);\n\tpadding-left: var(--top-unwrap-x);\n\tmargin-right: calc(0px - var(--top-unwrap-x));\n\tmargin-left: calc(0px - var(--top-unwrap-x));\n}\n*/\n</style>\n","<script setup lang=\"ts\">\nimport type { EmitsItemMulti, PropsItemMulti } from './types';\n\ndefineProps<PropsItemMulti>();\ndefineEmits<EmitsItemMulti>();\n</script>\n\n<template>\n\t<div class=\"top-selector2_itemMulti top-ellipsis\">\n\t\t{{ name }}\n\n\t\t<span\n\t\t\tclass=\"top-selector2_itemMultiDelete\"\n\t\t\tdata-top-icon=\"\"\n\t\t\t@click=\"$emit('delete', {id, name})\"\n\t\t\t@mousedown.stop\n\t\t></span>\n\t</div>\n</template>\n\n<style>\n.top-selector2_itemMulti {\n\tbox-sizing: border-box;\n\tpadding-left: var(--top-padding-2);\n\tborder-radius: var(--top-radius-1, 4px);\n\tborder: 1px solid var(--color-line-primary-1);\n\tbackground: var(--color-layer-primary-2);\n\tmin-height: 22px;\n\tmax-width: 100%;\n\tcolor: var(--color-text-1);\n\tflex-grow: 0;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--top-gap-1);\n}\n\n.top-selector2_itemMultiDelete {\n\t--top-icon-size: 14px;\n\t--top-icon-width: 18px;\n\t--top-icon-color: var(--color-text-1);\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\tcursor: pointer;\n}\n\n.top-selector2_itemMultiDelete:hover {\n\tbackground: var(--color-layer-primary-2);\n}\n\n@media screen and (min-width: 900px) {\n\t.top-selector2.top-active .top-selector2_itemMultiDelete {\n\t\tz-index: calc(var(--top-popup-z-index) + 1);\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { EmitsItemMulti, PropsItemMulti } from './types';\n\ndefineProps<PropsItemMulti>();\ndefineEmits<EmitsItemMulti>();\n</script>\n\n<template>\n\t<div class=\"top-selector2_itemMulti top-ellipsis\">\n\t\t{{ name }}\n\n\t\t<span\n\t\t\tclass=\"top-selector2_itemMultiDelete\"\n\t\t\tdata-top-icon=\"\"\n\t\t\t@click=\"$emit('delete', {id, name})\"\n\t\t\t@mousedown.stop\n\t\t></span>\n\t</div>\n</template>\n\n<style>\n.top-selector2_itemMulti {\n\tbox-sizing: border-box;\n\tpadding-left: var(--top-padding-2);\n\tborder-radius: var(--top-radius-1, 4px);\n\tborder: 1px solid var(--color-line-primary-1);\n\tbackground: var(--color-layer-primary-2);\n\tmin-height: 22px;\n\tmax-width: 100%;\n\tcolor: var(--color-text-1);\n\tflex-grow: 0;\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: var(--top-gap-1);\n}\n\n.top-selector2_itemMultiDelete {\n\t--top-icon-size: 14px;\n\t--top-icon-width: 18px;\n\t--top-icon-color: var(--color-text-1);\n\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\theight: 100%;\n\tcursor: pointer;\n}\n\n.top-selector2_itemMultiDelete:hover {\n\tbackground: var(--color-layer-primary-2);\n}\n\n@media screen and (min-width: 900px) {\n\t.top-selector2.top-active .top-selector2_itemMultiDelete {\n\t\tz-index: calc(var(--top-popup-z-index) + 1);\n\t}\n}\n</style>\n","import type { Props } from './types';\n\n/**\n * Список кешей для конкретного API метода\n */\nexport const cacheByMethod = new Map<Api.PathAbstract, Map<string, any>>();\n\n/**\n * Сброс кеша конкретного API метода\n */\nexport const clearCache = (apiPath: Api.PathAbstract) => {\n\tcacheByMethod.get(apiPath)?.clear();\n};\n\nexport const genCacheKey = (api: NonNullable<Props['api']>) => {\n\tconst userId = window['mo']?.user?.id;\n\n\tconst cacheKey = JSON.stringify(api.params) + ':' + api.url + ':' + userId;\n\n\treturn cacheKey;\n};\n\nexport const getCache = (cacheKey: string, apiPath: Api.PathAbstract) => {\n\treturn cacheByMethod.get(apiPath)?.get(cacheKey);\n};\n\nexport const setCache = (cacheKey: string, apiPath: Api.PathAbstract, data: any) => {\n\tif (!cacheByMethod.has(apiPath)) {\n\t\tcacheByMethod.set(apiPath, new Map());\n\t}\n\n\tcacheByMethod.get(apiPath)?.set(cacheKey, data);\n};\n","import { ref } from 'vue';\nimport { debounce } from '../../../../core/utils/lodash';\nimport type { Item, Props } from '../types';\nimport { genCacheKey, getCache, setCache } from '../cache';\n\nexport type API = ReturnType<typeof useAPI>;\n\nexport const useAPI = (\n\tapi: Props['api'],\n\tapiSetSearchParams: Props['apiSetSearchParams'],\n\tminLength: number,\n\tuseCache: Props['useCache'],\n) => {\n\t/**\n\t * Список, полученный через API\n\t */\n\tconst items = ref<Item[]>([]);\n\n\t/**\n\t * Флаг - идет загрузка\n\t */\n\tconst isLoading = ref(false);\n\n\tconst countLoading = ref(0);\n\n\tlet searchText = '';\n\tlet nextOffset: number | null | undefined;\n\n\tif (api && !api.params.limit) {\n\t\tapi.params.limit = 100;\n\t}\n\n\t/**\n\t * Выполнить обращение к API\n\t *\n\t * При ошибке вернет undefined\n\t */\n\tconst callAPI = async (): Promise<Api.ResponseSuccess<any, 'get'> | undefined> => {\n\t\tif (!api) return;\n\n\t\tconst cacheKey = useCache ? genCacheKey(api) : undefined;\n\n\t\tif (cacheKey) {\n\t\t\tconst cache = getCache(cacheKey, api.path);\n\t\t\tif (cache) {\n\t\t\t\t// остановить запущенные api запросы\n\t\t\t\tapi.abortByFingerprint();\n\n\t\t\t\treturn cache;\n\t\t\t}\n\t\t}\n\n\t\tconst res = await api.call();\n\n\t\tif (res.errors) return;\n\n\t\tif (!Array.isArray(res.result)) {\n\t\t\tconsole.warn('Array expected in `res.result`');\n\n\t\t\treturn;\n\t\t}\n\n\t\tconst indexWithError = (res.result as Array<Item | any>).findIndex(item => item.id === undefined || item.name === undefined);\n\t\tif (indexWithError !== -1) {\n\t\t\tconsole.warn(`В result[${indexWithError}] нет id или name`);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (cacheKey) {\n\t\t\tsetCache(cacheKey, api.path, res);\n\t\t}\n\n\t\treturn res as Api.ResponseSuccess<any, 'get'>;\n\t};\n\n\t/**\n\t * Загрузить items\n\t */\n\tconst load = async (append: boolean) => {\n\t\tif (!api) return;\n\n\t\tif (append) {\n\t\t\t// данных о следующих страницах не обнаружено\n\t\t\tif (!nextOffset) return;\n\n\t\t\t// дозагружать нельзя, если не завершена предыдущая загрузка\n\t\t\tif (isLoading.value) return;\n\n\t\t\tapi.params.offset = nextOffset;\n\t\t} else {\n\t\t\tapi.params.offset = 0;\n\t\t}\n\n\t\tapiSetSearchParams?.(api, searchText);\n\n\t\tisLoading.value = true;\n\t\tconst res = await callAPI();\n\t\tisLoading.value = false;\n\n\t\tcountLoading.value++;\n\n\t\tif (!res) return;\n\n\t\tnextOffset = res.nextOffset;\n\n\t\tif (append) {\n\t\t\titems.value = items.value.concat(res.result);\n\t\t} else {\n\t\t\titems.value = res.result;\n\t\t}\n\t};\n\n\tconst loadDebounce = debounce(() => load(false), 200);\n\n\t/**\n\t * Выполнить поиск по указанному тексту\n\t *\n\t * Если длина текста меньше minLength, поиск не будет произведен\n\t *\n\t * Если текст не изменился, поиск не будет произведен\n\t *\n\t * @param newSearchText - текст поиска\n\t * @param useDebounce - дедупликация загрузки списка\n\t */\n\tconst setSearchTextAndLoad = (newSearchText: string, useDebounce = true) => {\n\t\tif (!api) return;\n\n\t\t// остановить начатый поиск и сбросить результаты\n\t\tif (newSearchText.length < minLength) {\n\t\t\tapi.abortByFingerprint();\n\n\t\t\titems.value = [];\n\n\t\t\treturn;\n\t\t}\n\n\t\t// условия поиска не поменялись, данные загружены\n\t\tif (newSearchText === searchText && items.value.length) return;\n\n\t\tsearchText = newSearchText;\n\n\t\tif (useDebounce) {\n\t\t\tvoid loadDebounce();\n\t\t} else {\n\t\t\tvoid load(false);\n\t\t}\n\t};\n\n\treturn {\n\t\tapiRequest: api,\n\t\titems,\n\t\tisLoading,\n\t\tcountLoading,\n\t\tload,\n\t\tsetSearchTextAndLoad,\n\t};\n};\n","import type { Item, Props } from './types';\nimport { genFieldFilter } from '@/api/api';\n\n/**\n * Универсальный id для всех элементов \"Все элементы\" / \"Без фильтра\" в `TopSelector`\n */\nexport const ITEM_ID_ALL = 0;\n\n/**\n * Универсальный id для всех добавляемых элементов через `TopSelector`\n */\nexport const ITEM_ID_NEW = null;\n\n/**\n * Выбран ли элемент\n */\nexport const isSelected = (modelValue: Props['modelValue'], item: Item, checkNameForNullId = true) => {\n\tif (checkNameForNullId && item.id === ITEM_ID_NEW) {\n\t\tif (Array.isArray(modelValue)) {\n\t\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id && itemSelected.name === item.name);\n\t\t} else {\n\t\t\treturn item.name === modelValue.name;\n\t\t}\n\t}\n\n\tif (Array.isArray(modelValue)) {\n\t\treturn modelValue.some(itemSelected => itemSelected.id === item.id);\n\t} else {\n\t\treturn item.id === modelValue.id;\n\t}\n};\n\n/**\n * Вспомогательная утилита для создания `callback` функции на добавление фильтра по полю в api запрос\n *\n * Другие фильтры по указанному полю будут удалены\n *\n * @param api - api, которое используется в `TopSelector`\n * @param search - введенная строка поиска\n * @param fieldName - имя поля, по которому надо добавить фильтр на поиск по нестрогому соответствию\n *\n * @todo Объединить с apiSetSearchParamsFilter() из @/components/project/projectSelector/utils.ts\n */\nexport const apiSetSearchParamsFilter = (api: NonNullable<Props['api']>, search: string, fieldName: string) => {\n\tlet filters = api.params.filters ?? [];\n\n\t// удаление других фильтров по этому полю\n\tfilters = filters.filter((filter) => filter.name !== fieldName);\n\n\tif (search) {\n\t\tfilters.push(genFieldFilter(fieldName, 'CONTAINS', [search]));\n\t}\n\n\tapi.changeParams({ filters });\n};\n","import { computed, type ComputedRef, ref, type Ref, watch } from 'vue';\nimport { invertKeyboardLayout } from '@/core/utils/keyboard';\nimport type { Item, Props } from '../types';\nimport { type API } from './useAPI';\nimport { isSelected, ITEM_ID_ALL, ITEM_ID_NEW } from '../utils';\nimport { useI18n } from '@/core/plugins/i18n';\n\n/**\n * Функционал поиска\n */\nexport const useMenu = (\n\tmodel: Ref<Props['modelValue']>,\n\temits: ReturnType<typeof defineEmits>,\n\titems: Ref<Props['items']>,\n\tmultiselect: Props['multiselect'],\n\tuseAllItem: Ref<Props['useAllItem']>,\n\tappendSearchToResult: Ref<Props['appendSearchToResult']>,\n\tappendSearchAllowDuplicate: Ref<Props['appendSearchAllowDuplicate']>,\n\tappendSearchToResultCond: Ref<Props['appendSearchToResultCond']>,\n\tappendWithoutSelect: Ref<Props['appendWithoutSelect']>,\n\tsearchFields: Ref<Props['searchFields']>,\n\tsearchType: Ref<Props['searchType']>,\n\tminLength: number,\n\tapi: API,\n) => {\n\t/**\n\t * Текст поиска по результатам\n\t */\n\tconst searchText = ref('');\n\n\t/**\n\t * Объект, представляющий опцию \"Все\"\n\t */\n\tconst itemAll = {\n\t\tid: ITEM_ID_ALL,\n\t\tname: useI18n().Common.All as string,\n\t};\n\n\t/**\n\t * Сброс поиска\n\t */\n\tconst resetSearch = () => {\n\t\tsearchText.value = '';\n\t};\n\n\t/**\n\t * Является ли строка поиска достаточной длины для отображения меню\n\t */\n\tconst genIsShort = () => {\n\t\tif (!api.apiRequest) return false;\n\t\tif (searchText.value.length >= minLength) return false;\n\n\t\treturn true;\n\t};\n\n\t/**\n\t * Варианты выбора: props.items + \"Выбрать все\"\n\t */\n\tconst localItems: ComputedRef<Item[]> = computed(() => {\n\t\tconst localItems: Item[] = [];\n\n\t\tif (!multiselect && useAllItem.value) {\n\t\t\tif (typeof useAllItem.value === 'string') {\n\t\t\t\titemAll.name = useAllItem.value;\n\t\t\t}\n\n\t\t\tlocalItems.push(itemAll);\n\t\t}\n\n\t\titems.value?.forEach(item => localItems.push({ ...item }));\n\n\t\treturn localItems;\n\t});\n\n\t/**\n\t * Не используем `computed` в пользу ручного порядка пересчета значения\n\t */\n\tconst itemsForShow = ref<Item[]>([]);\n\n\tconst recalcItemsForShow = () => {\n\t\titemsForShow.value = genItemsForShow();\n\t};\n\n\t/**\n\t * Подготовленный список меню, который содержит в сумме:\n\t * - prop.items: указанный список с учетом фильтра и опций компонента\n\t * - api.items: результаты api запроса, если используется api\n\t *\n\t * @returns Отфильтрованный массив элементов для отображения\n\t */\n\tconst genItemsForShow = () => {\n\t\tconst searchString = searchText.value.toLowerCase();\n\t\tconst searchStringInvertKeyboard = invertKeyboardLayout(searchString);\n\n\t\tlet items: Item[] = [];\n\n\t\t/**\n\t\t * Элемент текущего разделителя в цикле\n\t\t *\n\t\t * Для скрытия / отображения только нужных заголовков и разделителей при поиске\n\t\t *\n\t\t * Логика для `api.items` должна реализовываться в api или api клиенте при генерации элементов\n\t\t */\n\t\tlet itemTitleCategory: Item | undefined;\n\t\tconst itemsCategory: Item[] = [];\n\n\t\t/**\n\t\t * Добавить элементы в результирующий список\n\t\t */\n\t\tconst flushCategory = () => {\n\t\t\t// крайний разделитель не выводить\n\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') {\n\t\t\t\titemsCategory.pop();\n\t\t\t}\n\n\t\t\tif (itemsCategory.length) {\n\t\t\t\tif (itemTitleCategory) {\n\t\t\t\t\titems.push(itemTitleCategory);\n\t\t\t\t}\n\n\t\t\t\titems.push(...itemsCategory);\n\n\t\t\t\titemsCategory.length = 0;\n\t\t\t}\n\t\t};\n\n\t\tfor (const item of localItems.value) {\n\t\t\tswitch (item.listItemProps?.type) {\n\t\t\t\tcase 'title':\n\t\t\t\t\tflushCategory();\n\n\t\t\t\t\titemTitleCategory = item;\n\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'delimiter':\n\t\t\t\t\t// вставить разделитель один раз и только если категория не пуста\n\t\t\t\t\tif (itemsCategory.length) {\n\t\t\t\t\t\tlet index = itemsCategory.length;\n\t\t\t\t\t\tif (itemsCategory.at(-1)?.listItemProps?.type === 'delimiter') index--;\n\n\t\t\t\t\t\titemsCategory[index] = item;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tconst hasIdSearch = searchFields.value?.includes('id');\n\t\t\t\t\tconst name = item.name.toLowerCase();\n\n\t\t\t\t\tconst searchFieldsText = searchFields.value\n\t\t\t\t\t\t?.filter(field => field !== 'id')\n\t\t\t\t\t\t.map(field => typeof item[field] === 'string' || typeof item[field] === 'number' ? item[field] : '')\n\t\t\t\t\t\t.join('☼')\n\t\t\t\t\t\t.toLowerCase();\n\n\t\t\t\t\tif (\n\t\t\t\t\t\t(hasIdSearch && item.id === Number(searchString)) ||\n\t\t\t\t\t\tsearchFieldsText?.includes(searchString) ||\n\t\t\t\t\t\tsearchFieldsText?.includes(searchStringInvertKeyboard)\n\t\t\t\t\t) {\n\t\t\t\t\t\tif (name === searchString || name === searchStringInvertKeyboard) {\n\t\t\t\t\t\t\t// точные совпадения в начало\n\t\t\t\t\t\t\titemsCategory.unshift(item);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titemsCategory.push(item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tflushCategory();\n\n\t\titems.push(...api.items.value);\n\n\t\t// ввод произвольного значения\n\t\tif (\n\t\t\tappendSearchToResult.value &&\n\t\t\t!!searchText.value &&\n\t\t\t(!appendSearchToResultCond.value || appendSearchToResultCond.value(searchString)) &&\n\n\t\t\t// предложить добавить элемент, если нет точного совпадения или разрешены дубликаты\n\t\t\t(\n\t\t\t\tappendSearchAllowDuplicate.value ||\n\t\t\t\t!items.find((item) => item.name.toLowerCase() === searchString)\n\t\t\t)\n\t\t) {\n\t\t\tconst itemNew: Item = {\n\t\t\t\tid: ITEM_ID_NEW,\n\t\t\t\tname: searchText.value,\n\t\t\t};\n\n\t\t\tif (appendWithoutSelect.value) {\n\t\t\t\titemNew.listItemProps = { closeByClick: false }\n\t\t\t}\n\n\t\t\t// предложение всегда отображается внизу, чтобы не мешать результатам поиска\n\t\t\titems.push(itemNew);\n\t\t}\n\n\t\tif (multiselect) {\n\t\t\titems = items.filter(item => !isSelected(model.value, item));\n\t\t}\n\n\t\treturn items;\n\t};\n\n\t/**\n\t * Выбрать элемент\n\t *\n\t * @param item Элемент для выбора\n\t */\n\tconst selectItem = (item: Item) => {\n\t\t// это невыбираемый элемент\n\t\tif (item.listItemProps?.type === 'title' || item.listItemProps?.type === 'delimiter') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (item.id === ITEM_ID_NEW) {\n\t\t\temits('appendItem', item);\n\n\t\t\tif (appendWithoutSelect.value) return;\n\t\t}\n\n\t\tif (multiselect && Array.isArray(model.value)) {\n\t\t\tif (!isSelected(model.value, item)) {\n\t\t\t\tmodel.value = [...model.value, item];\n\t\t\t}\n\t\t} else {\n\t\t\tmodel.value = item;\n\t\t}\n\n\t\t/**\n\t\t * Отложить перерисовку\n\t\t *\n\t\t * fix: Перерисовка меню выполняется раньше, чем срабатывает `click`.\n\t\t * Из-за этого обработчик кликов думает, что клик был вне меню и не закрывает окно\n\t\t *\n\t\t * Файл: @/components/popup/lib/popup.globalEvents.ts\n\t\t *\n\t\t * Функция: onclick()\n\t\t *\n\t\t * ```\n\t\t * const elPopup = e.target.closest<HTMLElement>('.top-popup-wrapper');\n\t\t * ```\n\t\t */\n\t\tsetTimeout(() => {\n\t\t\t/**\n\t\t\t * Завершить поиск после выбора\n\t\t\t */\n\t\t\tresetSearch();\n\t\t});\n\n\t\t// /**\n\t\t// * При изменении значения модели в режиме inline необходимо очистить поле поиска,\n\t\t// * так как поиск больше не актуален после выбора значения\n\t\t// */\n\t\t// if (searchType.value === 'inline') {\n\t\t// \tresetSearch();\n\t\t// }\n\t};\n\n\tif (api.apiRequest) {\n\t\t// загрузка только при открытии popup\n\t\tconst fieldsForWatch: any = [items, api.items];\n\n\t\t// model нужен только для multiselect, без необходимости не использовать для улучшения UX при работе с API\n\t\tif (multiselect) {\n\t\t\tfieldsForWatch.push(model);\n\t\t}\n\n\t\twatch(fieldsForWatch, () => {\n\t\t\trecalcItemsForShow();\n\t\t});\n\t} else {\n\t\twatch([model, items, searchText], () => {\n\t\t\trecalcItemsForShow();\n\t\t}, {\n\t\t\timmediate: true,\n\n\t\t\t// слежение за изменениями `items`\n\t\t\tdeep: 2,\n\t\t});\n\t}\n\n\t/**\n\t * Выбрать следующее значение\n\t */\n\tconst selectNextItem = () => {\n\t\tif (Array.isArray(model.value)) return;\n\n\t\tconst selectableItems = itemsForShow.value.filter((item) => !['title', 'delimiter'].includes(item.listItemProps?.type ?? ''));\n\n\t\tconst currentIndex = selectableItems.findIndex(item => item.id === (model.value as Item).id);\n\t\tconst nextIndex = (currentIndex + 1) % selectableItems.length;\n\t\tmodel.value = { ...selectableItems[nextIndex] };\n\t};\n\n\t/**\n\t * Удалить элемент, `id` и `name` которого равны указанному `item`\n\t */\n\tconst deleteItemByItem = async (item: Item) => {\n\t\tif (Array.isArray(model.value)) {\n\t\t\tmodel.value = model.value.filter((itemI) => itemI.id !== item.id || itemI.name !== item.name);\n\t\t}\n\t};\n\n\treturn {\n\t\tsearchText,\n\t\tresetSearch,\n\t\tgenIsShort,\n\t\titemsForShow,\n\t\tselectItem,\n\t\tselectNextItem,\n\t\tdeleteItemByItem,\n\t};\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, toRef, watch } from 'vue';\nimport Core from '@/core/core/core';\nimport { TopPopup, TopPopupListItem, TopPopupWidgetInput } from '@/components/popup/popup';\nimport { TopPreloader } from '@/components/forms/forms';\nimport type { Emits, Item, Props, Slots } from './types';\nimport Selector2ItemMulti from './itemMulti.vue';\nimport { useAPI } from './composables/useAPI';\nimport { useMenu } from './composables/useMenu';\nimport type { TopLibPopup } from '../../popup/lib/popup';\nimport { clearCache } from './cache';\nimport { ITEM_ID_ALL, ITEM_ID_NEW } from './utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\titems: () => [] as Item[],\n\tsize: 's',\n\tminLength: 0,\n\tsearchType: 'popup',\n\topenByFocusInput: undefined,\n\tsearchFields: () => ['id', 'name'],\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\ndefineSlots<Slots>();\n\nconst emits = defineEmits<Emits>();\n\ndefineExpose({\n\t/**\n\t * Сброс локального кеша и кеша api\n\t *\n\t * @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными\n\t */\n\tresetCache: (resetAPICache: boolean = false) => {\n\t\tif (!api.apiRequest) return;\n\n\t\t// сброс кеша api\n\t\tif (resetAPICache) {\n\t\t\tclearCache(api.apiRequest.path);\n\t\t}\n\n\t\t// сброс кеша списка\n\t\tapi.items.value = [];\n\n\t\t// сброс флага первичной загрузки\n\t\tapi.countLoading.value = 0;\n\n\t\t// сброс параметров дозагрузки\n\t\tapi.apiRequest.params.offset = 0;\n\n\t\t// сброс кеша локального списка с дополнительными элементами, например `useAllItem`\n\t\trequestAnimationFrame(() => {\n\t\t\tmenu.itemsForShow.value = [];\n\t\t});\n\n\t\t// сразу загрузить данные после сброса, если popup уже открыт\n\t\tif (getPopup()?.elPopup) {\n\t\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t\t}\n\t},\n});\n\nconst searchTypeLocal = computed(() => {\n\t// multiselect не поддерживает inline ввода\n\tif (props.searchType === 'inline' && props.multiselect) return 'popup';\n\n\t// В мобильной версии popup работает в полноэкранном режиме\n\tif (props.searchType === 'inline' && Core.state.isMobile) return 'popup';\n\n\treturn props.searchType;\n});\n\n/**\n * Объект для работы с API\n */\nconst api = useAPI(props.api, props.apiSetSearchParams, props.minLength, props.useCache);\n\n/**\n * Объект для работы с меню\n */\nconst menu = useMenu(\n\tmodel,\n\temits,\n\ttoRef(props, 'items'),\n\tprops.multiselect,\n\ttoRef(props, 'useAllItem'),\n\ttoRef(props, 'appendSearchToResult'),\n\ttoRef(props, 'appendSearchAllowDuplicate'),\n\ttoRef(props, 'appendSearchToResultCond'),\n\ttoRef(props, 'appendWithoutSelect'),\n\ttoRef(props, 'searchFields'),\n\tsearchTypeLocal,\n\tprops.minLength,\n\tapi,\n);\n\nconst component = computed(() => {\n\tif (props.buttonProps) return 'TopButton';\n\tif (searchTypeLocal.value === 'inline') return 'TopInput';\n\n\treturn 'div';\n});\n\n/**\n * Экземпляр компонента Popup\n */\nconst popupRef = ref<any>(null);\n\n/**\n * Получить доступ к объекту popup\n */\nconst getPopup = (): TopLibPopup | undefined => {\n\treturn popupRef.value?.popup;\n};\n\nif (api.apiRequest) {\n\t// отложенный поиск при вводе текста\n\twatch(menu.searchText, () => {\n\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t});\n}\n\nconst placeholder = computed(() => {\n\tif (Array.isArray(model.value) || props.multiselect || !props.selectedAsPlaceholder && searchTypeLocal.value !== 'inline') {\n\t\treturn props.placeholder;\n\t}\n\n\treturn model.value?.name || props.placeholder;\n});\n\n/**\n * Обработчик ввода клавиш на кнопке или поле ввода\n */\nconst onOpenerKeydown = (e: KeyboardEvent) => {\n\tlet needOpen = false;\n\n\tswitch (e.key) {\n\t\tcase 'Delete':\n\t\tcase 'Backspace':\n\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tmodel.value.pop();\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\tcase 'ArrowRight':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowLeft':\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\tneedOpen = true;\n\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tif (searchTypeLocal.value === 'inline') {\n\t\t\t\t// очистка введенного текста\n\t\t\t\tmenu.resetSearch();\n\t\t\t}\n\n\t\t\tbreak;\n\t}\n\n\t// введен символ\n\tconst symbolPressed = e.key.length === 1 && !e.ctrlKey && !e.metaKey;\n\n\t// введен символ\n\tif (searchTypeLocal.value === 'popup' || searchTypeLocal.value === 'inline') {\n\t\tif (symbolPressed) {\n\t\t\tneedOpen = true;\n\t\t}\n\t}\n\n\t// popup уже открыт\n\tif (getPopup()?.elPopup) {\n\t\tneedOpen = false;\n\t}\n\n\tif (needOpen) {\n\t\tif (searchTypeLocal.value === 'popup') {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// введен символ\n\t\t\tif (symbolPressed) {\n\t\t\t\t// начало ввода, сразу ввести первый символ вместе с открытием popup\n\t\t\t\tif (!menu.searchText.value) {\n\t\t\t\t\tmenu.searchText.value = e.key;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(e.currentTarget as HTMLElement)?.click();\n\t}\n};\n\nconst onClickChanger = (e: MouseEvent) => {\n\te.preventDefault();\n\n\tmenu.selectNextItem();\n};\n\n/**\n * Обработчик открытия попапа\n */\nconst onOpen = () => {\n\tif (api.apiRequest) {\n\t\t// при открытии сразу выполнить поиск\n\t\tapi.setSearchTextAndLoad(menu.searchText.value, false);\n\t}\n\n\temits('open');\n};\n\n/**\n * Обработчик закрытия попапа\n */\nconst onClose = () => {\n\t// очистка введенного текста, в режиме `inline` input вызывается при `blur`\n\tif (searchTypeLocal.value === 'popup') {\n\t\tif (menu.searchText.value) menu.resetSearch();\n\t}\n};\n\n/**\n * Обработчик прокрутки списка контента\n *\n * Для дозагрузки элеменов через api\n *\n * @param {Event} e - Событие прокрутки\n */\nconst onScrollContentList = (e: Event) => {\n\tconst el = e.target as HTMLElement;\n\n\tif (el.scrollTop / (el.scrollHeight - el.offsetHeight) > 0.8) {\n\t\tapi.load(true);\n\t}\n};\n\nif (import.meta.env.STORYBOOK) {\n\twatch(\n\t\t() => props.multiselect,\n\t\t() => {\n\t\t\tif (props.multiselect) {\n\t\t\t\tif (!Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Выбери меня',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = {\n\t\t\t\t\t\tid: null,\n\t\t\t\t\t\tname: '',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ immediate: true },\n\t);\n\n\twatch(\n\t\t() => props.searchType,\n\t\t() => {\n\t\t\t// пауза для установки props в адресной строке\n\t\t\tsetTimeout(() => {\n\t\t\t\tlocation.reload();\n\t\t\t}, 500);\n\t\t},\n\t);\n}\n</script>\n\n<template>\n\t<TopPopup\n\t\tref=\"popupRef\"\n\t\t@open=\"onOpen()\"\n\t\t@close=\"onClose()\"\n\t\t@scrollContentList=\"api ? onScrollContentList($event) : undefined\"\n\t\t:notch=\"false\"\n\t\t:transitionDuration=\"0\"\n\t\t:openByFocusInput=\"searchTypeLocal === 'inline' && (openByFocusInput ?? true)\"\n\t\t:disabled=\"searchTypeLocal === 'inline' && menu.genIsShort()\"\n\t>\n\t\t<template #opener>\n\t\t\t<component\n\t\t\t\t:is=\"component\"\n\n\t\t\t\t:=\"buttonProps\"\n\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-selector2': true,\n\t\t\t\t\t'top-selector2-multiselect': multiselect,\n\t\t\t\t\t['top-selector2-' + modificator]: !!modificator,\n\t\t\t\t\t'top-as-input': !buttonProps && searchTypeLocal !== 'inline',\n\t\t\t\t\t'top-as-selector': true,\n\t\t\t\t\t['top-size_' + size]: true,\n\t\t\t\t\t['top-disabled']: disabled,\n\t\t\t\t\t['top-forms-focusable']: !disabled,\n\t\t\t\t\t['top-error']: isError,\n\t\t\t\t}\"\n\t\t\t\t:icon\n\t\t\t\ttabindex=\"0\"\n\t\t\t\t@keydown=\"onOpenerKeydown\"\n\t\t\t\t@blur=\"searchTypeLocal === 'inline' && menu.resetSearch()\"\n\t\t\t\tv-top-focus.onupdate=\"isError\"\n\t\t\t\tv-top-shortcut=\"openerShortcut\"\n\n\t\t\t\t:placeholder\n\t\t\t\t:title\n\t\t\t\t:captionType=\"searchTypeLocal === 'inline' && title !== undefined ? 'top' : undefined\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t>\n\t\t\t\t<template v-if=\"multiselect\">\n\t\t\t\t\t<div class=\"top-selector2_activeItems\">\n\t\t\t\t\t\t<Selector2ItemMulti\n\t\t\t\t\t\t\tv-for=\"item of model as Item[]\"\n\t\t\t\t\t\t\t:id=\"item.id\"\n\t\t\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t\t\t@delete=\"menu.deleteItemByItem\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<span v-if=\"searchTypeLocal !== 'inline' && !multiselect\" class=\"top-selector2_activeName top-ellipsis\">\n\t\t\t\t\t{{ !Array.isArray(model) ? model.name : '' }}\n\t\t\t\t</span>\n\n\t\t\t\t<span v-if=\"multiselect && !model.length\" class=\"top-selector2_placeholder top-ellipsis\">\n\t\t\t\t\t{{ placeholder }}\n\t\t\t\t</span>\n\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"addChanger && !buttonProps && !multiselect && menu.itemsForShow.value.length > 1 && !disabled\"\n\t\t\t\t\tclass=\"top-changer top-changer-selector\"\n\t\t\t\t\tdata-top-popup-disabled=\"true\"\n\t\t\t\t\t@click=\"onClickChanger\"\n\t\t\t\t></span>\n\t\t\t</component>\n\t\t</template>\n\n\t\t<template #widget v-if=\"searchTypeLocal === 'popup'\">\n\t\t\t<div class=\"top-selector2_searchWidget\">\n\t\t\t\t<TopPopupWidgetInput\n\t\t\t\t\ttitle=\"Поиск\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t\t\tv-top-focus.onupdate=\"model\"\n\t\t\t\t\t:isLoading=\"!!api.countLoading.value && api.isLoading.value\"\n\t\t\t\t\t:placeholder\n\t\t\t\t/>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"hasCloserBtn && !$core.state.isMobile\"\n\t\t\t\t\tclass=\"closer\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t>\n\t\t\t\t\t{{ $i18n.Common.Cancel }}\n\t\t\t\t</TopButton>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopPopupListItem\n\t\t\t\tv-for=\"item of menu.itemsForShow.value\"\n\t\t\t\t:key=\"item.id ?? undefined\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-active': !Array.isArray(model) && !multiselect && model.id === item.id && model.name === item.name,\n\t\t\t\t\t'top-selector2_item-all':item.id === ITEM_ID_ALL,\n\t\t\t\t\t'top-selector2_item-new':item.id === ITEM_ID_NEW,\n\t\t\t\t}\"\n\t\t\t\t:closeByClick=\"!multiselect || Core.state.isMobile\"\n\t\t\t\t:=\"item.listItemProps\"\n\t\t\t\t@click=\"menu.selectItem(item)\"\n\t\t\t>\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"$slots.item\"\n\t\t\t\t\tname=\"item\"\n\t\t\t\t\t:item\n\t\t\t\t></slot>\n\n\t\t\t\t<template\n\t\t\t\t\tv-else\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</template>\n\t\t\t</TopPopupListItem>\n\n\t\t\t<!-- Элементов для отображения нет -->\n\t\t\t<template v-if=\"!menu.itemsForShow.value.length && !menu.genIsShort()\">\n\t\t\t\t<TopPopupListItem type=\"regular\">\n\t\t\t\t\t<template v-if=\"!api.isLoading.value || api.countLoading.value\">\n\t\t\t\t\t\t{{ $i18n.Common.No_results }}\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<!-- Индикатор первичной загрузки -->\n\t\t\t\t\t<TopPreloader\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"circles\"\n\t\t\t\t\t/>\n\t\t\t\t</TopPopupListItem>\n\t\t\t</template>\n\n\t\t\t<!-- Индикатор повторной загрузки -->\n\t\t\t<TopLoadbar v-if=\"!!api.countLoading.value && api.isLoading.value && searchTypeLocal === 'inline'\"/>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-selector2 {\n\twidth: 180px;\n}\n\n.top-selector2::placeholder,\n.top-selector2_placeholder {\n\tcolor: var(--color-text-2);\n}\n\n.top-selector2_placeholder {\n\tpadding-left: var(--top-padding-1);\n}\n\n.top-selector2.top-as-input {\n\tpadding: var(--top-padding-1) var(--top-forms-padding);\n}\n\n.top-selector2.top-selector2-multiselect {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tflex-grow: 1;\n}\n\n.top-selector2.top-active {\n\t--top-forms-border-color: var(--top-forms-border-color-hover);\n}\n\n.top-selector2_searchWidget {\n\tdisplay: flex;\n\tgap: var(--top-gap-2);\n}\n\n.top-selector2_activeItems {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--top-padding-1);\n\tmax-width: 100%;\n}\n\n.top-selector2_activeName {\n\twhite-space: nowrap;\n}\n\n.top-changer-selector {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tmargin: calc(0px - var(--top-padding-1));\n\ttransform: translateX(0);\n}\n\n.top-selector2.top-button {\n\tjustify-content: start;\n}\n\n.top-selector2.top-input_input ~ .top-changer-selector {\n\ttransform: translateX(-52px);\n}\n\n.top-selector2.top-as-selector {\n\tpadding-right: calc(var(--top-selector-arrow-width) + var(--top-padding-2));\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, toRef, watch } from 'vue';\nimport Core from '@/core/core/core';\nimport { TopPopup, TopPopupListItem, TopPopupWidgetInput } from '@/components/popup/popup';\nimport { TopPreloader } from '@/components/forms/forms';\nimport type { Emits, Item, Props, Slots } from './types';\nimport Selector2ItemMulti from './itemMulti.vue';\nimport { useAPI } from './composables/useAPI';\nimport { useMenu } from './composables/useMenu';\nimport type { TopLibPopup } from '../../popup/lib/popup';\nimport { clearCache } from './cache';\nimport { ITEM_ID_ALL, ITEM_ID_NEW } from './utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\titems: () => [] as Item[],\n\tsize: 's',\n\tminLength: 0,\n\tsearchType: 'popup',\n\topenByFocusInput: undefined,\n\tsearchFields: () => ['id', 'name'],\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\n\ndefineSlots<Slots>();\n\nconst emits = defineEmits<Emits>();\n\ndefineExpose({\n\t/**\n\t * Сброс локального кеша и кеша api\n\t *\n\t * @param resetAPICache - Сбросить API кеш, по умолчанию не сбрасывается. Для случаев, когда загруженные данные становятся неактуальными\n\t */\n\tresetCache: (resetAPICache: boolean = false) => {\n\t\tif (!api.apiRequest) return;\n\n\t\t// сброс кеша api\n\t\tif (resetAPICache) {\n\t\t\tclearCache(api.apiRequest.path);\n\t\t}\n\n\t\t// сброс кеша списка\n\t\tapi.items.value = [];\n\n\t\t// сброс флага первичной загрузки\n\t\tapi.countLoading.value = 0;\n\n\t\t// сброс параметров дозагрузки\n\t\tapi.apiRequest.params.offset = 0;\n\n\t\t// сброс кеша локального списка с дополнительными элементами, например `useAllItem`\n\t\trequestAnimationFrame(() => {\n\t\t\tmenu.itemsForShow.value = [];\n\t\t});\n\n\t\t// сразу загрузить данные после сброса, если popup уже открыт\n\t\tif (getPopup()?.elPopup) {\n\t\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t\t}\n\t},\n});\n\nconst searchTypeLocal = computed(() => {\n\t// multiselect не поддерживает inline ввода\n\tif (props.searchType === 'inline' && props.multiselect) return 'popup';\n\n\t// В мобильной версии popup работает в полноэкранном режиме\n\tif (props.searchType === 'inline' && Core.state.isMobile) return 'popup';\n\n\treturn props.searchType;\n});\n\n/**\n * Объект для работы с API\n */\nconst api = useAPI(props.api, props.apiSetSearchParams, props.minLength, props.useCache);\n\n/**\n * Объект для работы с меню\n */\nconst menu = useMenu(\n\tmodel,\n\temits,\n\ttoRef(props, 'items'),\n\tprops.multiselect,\n\ttoRef(props, 'useAllItem'),\n\ttoRef(props, 'appendSearchToResult'),\n\ttoRef(props, 'appendSearchAllowDuplicate'),\n\ttoRef(props, 'appendSearchToResultCond'),\n\ttoRef(props, 'appendWithoutSelect'),\n\ttoRef(props, 'searchFields'),\n\tsearchTypeLocal,\n\tprops.minLength,\n\tapi,\n);\n\nconst component = computed(() => {\n\tif (props.buttonProps) return 'TopButton';\n\tif (searchTypeLocal.value === 'inline') return 'TopInput';\n\n\treturn 'div';\n});\n\n/**\n * Экземпляр компонента Popup\n */\nconst popupRef = ref<any>(null);\n\n/**\n * Получить доступ к объекту popup\n */\nconst getPopup = (): TopLibPopup | undefined => {\n\treturn popupRef.value?.popup;\n};\n\nif (api.apiRequest) {\n\t// отложенный поиск при вводе текста\n\twatch(menu.searchText, () => {\n\t\tapi.setSearchTextAndLoad(menu.searchText.value);\n\t});\n}\n\nconst placeholder = computed(() => {\n\tif (Array.isArray(model.value) || props.multiselect || !props.selectedAsPlaceholder && searchTypeLocal.value !== 'inline') {\n\t\treturn props.placeholder;\n\t}\n\n\treturn model.value?.name || props.placeholder;\n});\n\n/**\n * Обработчик ввода клавиш на кнопке или поле ввода\n */\nconst onOpenerKeydown = (e: KeyboardEvent) => {\n\tlet needOpen = false;\n\n\tswitch (e.key) {\n\t\tcase 'Delete':\n\t\tcase 'Backspace':\n\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tmodel.value.pop();\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'ArrowUp':\n\t\tcase 'ArrowRight':\n\t\tcase 'ArrowDown':\n\t\tcase 'ArrowLeft':\n\t\tcase 'Enter':\n\t\tcase ' ':\n\t\t\tneedOpen = true;\n\n\t\t\tbreak;\n\t\tcase 'Escape':\n\t\t\tif (searchTypeLocal.value === 'inline') {\n\t\t\t\t// очистка введенного текста\n\t\t\t\tmenu.resetSearch();\n\t\t\t}\n\n\t\t\tbreak;\n\t}\n\n\t// введен символ\n\tconst symbolPressed = e.key.length === 1 && !e.ctrlKey && !e.metaKey;\n\n\t// введен символ\n\tif (searchTypeLocal.value === 'popup' || searchTypeLocal.value === 'inline') {\n\t\tif (symbolPressed) {\n\t\t\tneedOpen = true;\n\t\t}\n\t}\n\n\t// popup уже открыт\n\tif (getPopup()?.elPopup) {\n\t\tneedOpen = false;\n\t}\n\n\tif (needOpen) {\n\t\tif (searchTypeLocal.value === 'popup') {\n\t\t\te.preventDefault();\n\t\t\te.stopPropagation();\n\n\t\t\t// введен символ\n\t\t\tif (symbolPressed) {\n\t\t\t\t// начало ввода, сразу ввести первый символ вместе с открытием popup\n\t\t\t\tif (!menu.searchText.value) {\n\t\t\t\t\tmenu.searchText.value = e.key;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t(e.currentTarget as HTMLElement)?.click();\n\t}\n};\n\nconst onClickChanger = (e: MouseEvent) => {\n\te.preventDefault();\n\n\tmenu.selectNextItem();\n};\n\n/**\n * Обработчик открытия попапа\n */\nconst onOpen = () => {\n\tif (api.apiRequest) {\n\t\t// при открытии сразу выполнить поиск\n\t\tapi.setSearchTextAndLoad(menu.searchText.value, false);\n\t}\n\n\temits('open');\n};\n\n/**\n * Обработчик закрытия попапа\n */\nconst onClose = () => {\n\t// очистка введенного текста, в режиме `inline` input вызывается при `blur`\n\tif (searchTypeLocal.value === 'popup') {\n\t\tif (menu.searchText.value) menu.resetSearch();\n\t}\n};\n\n/**\n * Обработчик прокрутки списка контента\n *\n * Для дозагрузки элеменов через api\n *\n * @param {Event} e - Событие прокрутки\n */\nconst onScrollContentList = (e: Event) => {\n\tconst el = e.target as HTMLElement;\n\n\tif (el.scrollTop / (el.scrollHeight - el.offsetHeight) > 0.8) {\n\t\tapi.load(true);\n\t}\n};\n\nif (import.meta.env.STORYBOOK) {\n\twatch(\n\t\t() => props.multiselect,\n\t\t() => {\n\t\t\tif (props.multiselect) {\n\t\t\t\tif (!Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid: 1,\n\t\t\t\t\t\t\tname: 'Выбери меня',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (Array.isArray(model.value)) {\n\t\t\t\t\tmodel.value = {\n\t\t\t\t\t\tid: null,\n\t\t\t\t\t\tname: '',\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ immediate: true },\n\t);\n\n\twatch(\n\t\t() => props.searchType,\n\t\t() => {\n\t\t\t// пауза для установки props в адресной строке\n\t\t\tsetTimeout(() => {\n\t\t\t\tlocation.reload();\n\t\t\t}, 500);\n\t\t},\n\t);\n}\n</script>\n\n<template>\n\t<TopPopup\n\t\tref=\"popupRef\"\n\t\t@open=\"onOpen()\"\n\t\t@close=\"onClose()\"\n\t\t@scrollContentList=\"api ? onScrollContentList($event) : undefined\"\n\t\t:notch=\"false\"\n\t\t:transitionDuration=\"0\"\n\t\t:openByFocusInput=\"searchTypeLocal === 'inline' && (openByFocusInput ?? true)\"\n\t\t:disabled=\"searchTypeLocal === 'inline' && menu.genIsShort()\"\n\t>\n\t\t<template #opener>\n\t\t\t<component\n\t\t\t\t:is=\"component\"\n\n\t\t\t\t:=\"buttonProps\"\n\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-selector2': true,\n\t\t\t\t\t'top-selector2-multiselect': multiselect,\n\t\t\t\t\t['top-selector2-' + modificator]: !!modificator,\n\t\t\t\t\t'top-as-input': !buttonProps && searchTypeLocal !== 'inline',\n\t\t\t\t\t'top-as-selector': true,\n\t\t\t\t\t['top-size_' + size]: true,\n\t\t\t\t\t['top-disabled']: disabled,\n\t\t\t\t\t['top-forms-focusable']: !disabled,\n\t\t\t\t\t['top-error']: isError,\n\t\t\t\t}\"\n\t\t\t\t:icon\n\t\t\t\ttabindex=\"0\"\n\t\t\t\t@keydown=\"onOpenerKeydown\"\n\t\t\t\t@blur=\"searchTypeLocal === 'inline' && menu.resetSearch()\"\n\t\t\t\tv-top-focus.onupdate=\"isError\"\n\t\t\t\tv-top-shortcut=\"openerShortcut\"\n\n\t\t\t\t:placeholder\n\t\t\t\t:title\n\t\t\t\t:captionType=\"searchTypeLocal === 'inline' && title !== undefined ? 'top' : undefined\"\n\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t>\n\t\t\t\t<template v-if=\"multiselect\">\n\t\t\t\t\t<div class=\"top-selector2_activeItems\">\n\t\t\t\t\t\t<Selector2ItemMulti\n\t\t\t\t\t\t\tv-for=\"item of model as Item[]\"\n\t\t\t\t\t\t\t:id=\"item.id\"\n\t\t\t\t\t\t\t:name=\"item.name\"\n\t\t\t\t\t\t\t@delete=\"menu.deleteItemByItem\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</template>\n\n\t\t\t\t<span v-if=\"searchTypeLocal !== 'inline' && !multiselect\" class=\"top-selector2_activeName top-ellipsis\">\n\t\t\t\t\t{{ !Array.isArray(model) ? model.name : '' }}\n\t\t\t\t</span>\n\n\t\t\t\t<span v-if=\"multiselect && !model.length\" class=\"top-selector2_placeholder top-ellipsis\">\n\t\t\t\t\t{{ placeholder }}\n\t\t\t\t</span>\n\n\t\t\t\t<span\n\t\t\t\t\tv-if=\"addChanger && !buttonProps && !multiselect && menu.itemsForShow.value.length > 1 && !disabled\"\n\t\t\t\t\tclass=\"top-changer top-changer-selector\"\n\t\t\t\t\tdata-top-popup-disabled=\"true\"\n\t\t\t\t\t@click=\"onClickChanger\"\n\t\t\t\t></span>\n\t\t\t</component>\n\t\t</template>\n\n\t\t<template #widget v-if=\"searchTypeLocal === 'popup'\">\n\t\t\t<div class=\"top-selector2_searchWidget\">\n\t\t\t\t<TopPopupWidgetInput\n\t\t\t\t\ttitle=\"Поиск\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\tv-model=\"menu.searchText.value\"\n\t\t\t\t\tv-top-focus.onupdate=\"model\"\n\t\t\t\t\t:isLoading=\"!!api.countLoading.value && api.isLoading.value\"\n\t\t\t\t\t:placeholder\n\t\t\t\t/>\n\n\t\t\t\t<TopButton\n\t\t\t\t\tv-if=\"hasCloserBtn && !$core.state.isMobile\"\n\t\t\t\t\tclass=\"closer\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t>\n\t\t\t\t\t{{ $i18n.Common.Cancel }}\n\t\t\t\t</TopButton>\n\t\t\t</div>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopPopupListItem\n\t\t\t\tv-for=\"item of menu.itemsForShow.value\"\n\t\t\t\t:key=\"item.id ?? undefined\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'top-active': !Array.isArray(model) && !multiselect && model.id === item.id && model.name === item.name,\n\t\t\t\t\t'top-selector2_item-all':item.id === ITEM_ID_ALL,\n\t\t\t\t\t'top-selector2_item-new':item.id === ITEM_ID_NEW,\n\t\t\t\t}\"\n\t\t\t\t:closeByClick=\"!multiselect || Core.state.isMobile\"\n\t\t\t\t:=\"item.listItemProps\"\n\t\t\t\t@click=\"menu.selectItem(item)\"\n\t\t\t>\n\t\t\t\t<slot\n\t\t\t\t\tv-if=\"$slots.item\"\n\t\t\t\t\tname=\"item\"\n\t\t\t\t\t:item\n\t\t\t\t></slot>\n\n\t\t\t\t<template\n\t\t\t\t\tv-else\n\t\t\t\t>\n\t\t\t\t\t{{ item.name }}\n\t\t\t\t</template>\n\t\t\t</TopPopupListItem>\n\n\t\t\t<!-- Элементов для отображения нет -->\n\t\t\t<template v-if=\"!menu.itemsForShow.value.length && !menu.genIsShort()\">\n\t\t\t\t<TopPopupListItem type=\"regular\">\n\t\t\t\t\t<template v-if=\"!api.isLoading.value || api.countLoading.value\">\n\t\t\t\t\t\t{{ $i18n.Common.No_results }}\n\t\t\t\t\t</template>\n\n\t\t\t\t\t<!-- Индикатор первичной загрузки -->\n\t\t\t\t\t<TopPreloader\n\t\t\t\t\t\tv-else\n\t\t\t\t\t\ttype=\"circles\"\n\t\t\t\t\t/>\n\t\t\t\t</TopPopupListItem>\n\t\t\t</template>\n\n\t\t\t<!-- Индикатор повторной загрузки -->\n\t\t\t<TopLoadbar v-if=\"!!api.countLoading.value && api.isLoading.value && searchTypeLocal === 'inline'\"/>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-selector2 {\n\twidth: 180px;\n}\n\n.top-selector2::placeholder,\n.top-selector2_placeholder {\n\tcolor: var(--color-text-2);\n}\n\n.top-selector2_placeholder {\n\tpadding-left: var(--top-padding-1);\n}\n\n.top-selector2.top-as-input {\n\tpadding: var(--top-padding-1) var(--top-forms-padding);\n}\n\n.top-selector2.top-selector2-multiselect {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tflex-grow: 1;\n}\n\n.top-selector2.top-active {\n\t--top-forms-border-color: var(--top-forms-border-color-hover);\n}\n\n.top-selector2_searchWidget {\n\tdisplay: flex;\n\tgap: var(--top-gap-2);\n}\n\n.top-selector2_activeItems {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: var(--top-padding-1);\n\tmax-width: 100%;\n}\n\n.top-selector2_activeName {\n\twhite-space: nowrap;\n}\n\n.top-changer-selector {\n\twidth: auto;\n\tpadding: var(--top-padding-1);\n\tmargin: calc(0px - var(--top-padding-1));\n\ttransform: translateX(0);\n}\n\n.top-selector2.top-button {\n\tjustify-content: start;\n}\n\n.top-selector2.top-input_input ~ .top-changer-selector {\n\ttransform: translateX(-52px);\n}\n\n.top-selector2.top-as-selector {\n\tpadding-right: calc(var(--top-selector-arrow-width) + var(--top-padding-2));\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport Button from '@/components/forms/button/button.vue';\nimport type { Emits, Props, Slots } from './types';\nimport Textarea from '@/components/forms/textarea/textarea.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tdefaultValue: '',\n\tcancelText: 'Cancel',\n\tsubmitText: 'Send',\n\tcloseText: 'Close',\n\texpandable: true,\n});\n\ndefineSlots<Slots>();\nconst emit = defineEmits<Emits>();\n\nconst localValue = ref(props.defaultValue);\n\nconst isFocused = ref(props.isFocused);\n\nconst isChanged = computed(() => localValue.value !== props.defaultValue);\n\nconst submit = (value: string) => {\n\temit('submit', value);\n\n\tlocalValue.value = props.defaultValue;\n};\n\nconst cancel = () => {\n\tif (props.forceShowCloseBtn && !isChanged.value) {\n\t\temit('close');\n\n\t\treturn;\n\t}\n\n\tlocalValue.value = props.defaultValue;\n};\n\nconst clickOnTitle = () => {\n\tif (props.attachToKeyboard) emit('clickOnTitle');\n};\n</script>\n\n<template>\n\t<div\n\t\t:class=\"{\n\t\t\t'top-editArea': true,\n\t\t\t'top-editArea-attachedToKeyboard': attachToKeyboard,\n\t\t}\"\n\t>\n\t\t<div\n\t\t\tv-if=\"title || $slots.caption\"\n\t\t\tclass=\"top-editArea_caption\"\n\t\t\t@click=\"clickOnTitle()\"\n\t\t>\n\t\t\t<slot name=\"caption\">\n\t\t\t\t{{ title }}\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<div\n\t\t\t:class=\"{\n\t\t\t\t'top-editArea_form': true,\n\t\t\t\t'top-forms-focusable': true,\n\t\t\t\t'top-as-input': true,\n\t\t\t\t'top-error': isError,\n\t\t\t\t'top-focus': isFocused,\n\t\t\t}\"\n\t\t>\n\t\t\t<Textarea\n\t\t\t\tv-model=\"localValue\"\n\t\t\t\t:name=\"name\"\n\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t:rows=\"rows\"\n\t\t\t\t:minHeight=\"minHeight\"\n\t\t\t\t:expandable=\"expandable\"\n\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t:readonly=\"readonly\"\n\t\t\t\t:isError=\"isError\"\n\t\t\t\t:hint=\"hint\"\n\t\t\t\tclass=\"top-editArea_element\"\n\t\t\t\t@focus=\"() => isFocused = true\"\n\t\t\t\t@blur=\"() => isFocused = false\"\n\t\t\t\t@keyup.esc=\"cancel\"\n\t\t\t\t@keyup.ctrl.enter=\"submit(localValue)\"\n\t\t\t/>\n\n\t\t\t<div class=\"top-editArea_footer\">\n\t\t\t\t<Button\n\t\t\t\t\tv-if=\"isChanged || forceShowCloseBtn\"\n\t\t\t\t\t:icon=\"$core.state.isMobile ? '': ''\"\n\t\t\t\t\tclass=\"top-editArea_button\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\tstyling=\"soft\"\n\t\t\t\t\t@click=\"cancel\"\n\t\t\t\t>\n\t\t\t\t\t<template\n\t\t\t\t\t\t#default\n\t\t\t\t\t\tv-if=\"!$core.state.isMobile\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cancelText }}\n\t\t\t\t\t</template>\n\t\t\t\t</Button>\n\n\t\t\t\t<Button\n\t\t\t\t\tclass=\"top-editArea_button\"\n\t\t\t\t\tv-if=\"isChanged\"\n\t\t\t\t\t:icon=\"$core.state.isMobile ? '': ''\"\n\t\t\t\t\t@click=\"submit(localValue)\"\n\t\t\t\t>\n\t\t\t\t\t<template\n\t\t\t\t\t\t#default\n\t\t\t\t\t\tv-if=\"!$core.state.isMobile\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ submitText }}\n\t\t\t\t\t</template>\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-editArea {\n\t--top-editArea-bottom: env(keyboard-inset-height, 0px);\n\t--top-editArea-offset-bottom: 0px;\n\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n}\n\n.top-editArea_caption {\n\tfont-size: 12px;\n}\n\n.top-editArea_form {\n\tflex-direction: column;\n}\n\n/* textarea в EditArea */\n.top-textarea {\n\twidth: 100%;\n}\n\n.top-editArea_element.top-textarea_textarea {\n\t--top-forms-border-width: 0px;\n\n\toutline: none;\n\tanimation: none;\n}\n\n/* footer */\n.top-editArea_footer {\n\tpadding: var(--top-forms-padding);\n\tdisplay: flex;\n\tmin-height: 32px;\n\talign-self: flex-end;\n\tjustify-content: flex-end;\n\tgap: var(--top-forms-padding);\n}\n\n/* attachedToKeyboard */\n.top-editArea-attachedToKeyboard {\n\tbackground: var(--top-forms-background-color);\n\tposition: fixed;\n\tbottom: calc(var(--top-editArea-offset-bottom) + var(--top-editArea-bottom));\n\tright: 0;\n\tleft: 0;\n\tz-index: 2;\n\tgap: 0;\n\ttransition: bottom var(--transition-fast);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_form {\n\tborder-radius: 0;\n\tborder: none;\n\tborder-top: 1px solid var(--top-forms-border-color);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_title {\n\tcursor: pointer;\n\tborder-top: 1px solid var(--color-line-2-opacity);\n\tpadding: var(--top-forms-padding);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_footer > [data-top-icon] {\n\tborder-radius: 100%;\n}\n\n@media screen and (max-width: 900px) {\n\t.top-editArea_form {\n\t\tflex-direction: row;\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport Button from '@/components/forms/button/button.vue';\nimport type { Emits, Props, Slots } from './types';\nimport Textarea from '@/components/forms/textarea/textarea.vue';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tdefaultValue: '',\n\tcancelText: 'Cancel',\n\tsubmitText: 'Send',\n\tcloseText: 'Close',\n\texpandable: true,\n});\n\ndefineSlots<Slots>();\nconst emit = defineEmits<Emits>();\n\nconst localValue = ref(props.defaultValue);\n\nconst isFocused = ref(props.isFocused);\n\nconst isChanged = computed(() => localValue.value !== props.defaultValue);\n\nconst submit = (value: string) => {\n\temit('submit', value);\n\n\tlocalValue.value = props.defaultValue;\n};\n\nconst cancel = () => {\n\tif (props.forceShowCloseBtn && !isChanged.value) {\n\t\temit('close');\n\n\t\treturn;\n\t}\n\n\tlocalValue.value = props.defaultValue;\n};\n\nconst clickOnTitle = () => {\n\tif (props.attachToKeyboard) emit('clickOnTitle');\n};\n</script>\n\n<template>\n\t<div\n\t\t:class=\"{\n\t\t\t'top-editArea': true,\n\t\t\t'top-editArea-attachedToKeyboard': attachToKeyboard,\n\t\t}\"\n\t>\n\t\t<div\n\t\t\tv-if=\"title || $slots.caption\"\n\t\t\tclass=\"top-editArea_caption\"\n\t\t\t@click=\"clickOnTitle()\"\n\t\t>\n\t\t\t<slot name=\"caption\">\n\t\t\t\t{{ title }}\n\t\t\t</slot>\n\t\t</div>\n\n\t\t<div\n\t\t\t:class=\"{\n\t\t\t\t'top-editArea_form': true,\n\t\t\t\t'top-forms-focusable': true,\n\t\t\t\t'top-as-input': true,\n\t\t\t\t'top-error': isError,\n\t\t\t\t'top-focus': isFocused,\n\t\t\t}\"\n\t\t>\n\t\t\t<Textarea\n\t\t\t\tv-model=\"localValue\"\n\t\t\t\t:name=\"name\"\n\t\t\t\t:placeholder=\"placeholder\"\n\t\t\t\t:rows=\"rows\"\n\t\t\t\t:minHeight=\"minHeight\"\n\t\t\t\t:expandable=\"expandable\"\n\t\t\t\t:disabled=\"disabled\"\n\t\t\t\t:readonly=\"readonly\"\n\t\t\t\t:isError=\"isError\"\n\t\t\t\t:hint=\"hint\"\n\t\t\t\tclass=\"top-editArea_element\"\n\t\t\t\t@focus=\"() => isFocused = true\"\n\t\t\t\t@blur=\"() => isFocused = false\"\n\t\t\t\t@keyup.esc=\"cancel\"\n\t\t\t\t@keyup.ctrl.enter=\"submit(localValue)\"\n\t\t\t/>\n\n\t\t\t<div class=\"top-editArea_footer\">\n\t\t\t\t<Button\n\t\t\t\t\tv-if=\"isChanged || forceShowCloseBtn\"\n\t\t\t\t\t:icon=\"$core.state.isMobile ? '': ''\"\n\t\t\t\t\tclass=\"top-editArea_button\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\tstyling=\"soft\"\n\t\t\t\t\t@click=\"cancel\"\n\t\t\t\t>\n\t\t\t\t\t<template\n\t\t\t\t\t\t#default\n\t\t\t\t\t\tv-if=\"!$core.state.isMobile\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ cancelText }}\n\t\t\t\t\t</template>\n\t\t\t\t</Button>\n\n\t\t\t\t<Button\n\t\t\t\t\tclass=\"top-editArea_button\"\n\t\t\t\t\tv-if=\"isChanged\"\n\t\t\t\t\t:icon=\"$core.state.isMobile ? '': ''\"\n\t\t\t\t\t@click=\"submit(localValue)\"\n\t\t\t\t>\n\t\t\t\t\t<template\n\t\t\t\t\t\t#default\n\t\t\t\t\t\tv-if=\"!$core.state.isMobile\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ submitText }}\n\t\t\t\t\t</template>\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<style>\n.top-editArea {\n\t--top-editArea-bottom: env(keyboard-inset-height, 0px);\n\t--top-editArea-offset-bottom: 0px;\n\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n}\n\n.top-editArea_caption {\n\tfont-size: 12px;\n}\n\n.top-editArea_form {\n\tflex-direction: column;\n}\n\n/* textarea в EditArea */\n.top-textarea {\n\twidth: 100%;\n}\n\n.top-editArea_element.top-textarea_textarea {\n\t--top-forms-border-width: 0px;\n\n\toutline: none;\n\tanimation: none;\n}\n\n/* footer */\n.top-editArea_footer {\n\tpadding: var(--top-forms-padding);\n\tdisplay: flex;\n\tmin-height: 32px;\n\talign-self: flex-end;\n\tjustify-content: flex-end;\n\tgap: var(--top-forms-padding);\n}\n\n/* attachedToKeyboard */\n.top-editArea-attachedToKeyboard {\n\tbackground: var(--top-forms-background-color);\n\tposition: fixed;\n\tbottom: calc(var(--top-editArea-offset-bottom) + var(--top-editArea-bottom));\n\tright: 0;\n\tleft: 0;\n\tz-index: 2;\n\tgap: 0;\n\ttransition: bottom var(--transition-fast);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_form {\n\tborder-radius: 0;\n\tborder: none;\n\tborder-top: 1px solid var(--top-forms-border-color);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_title {\n\tcursor: pointer;\n\tborder-top: 1px solid var(--color-line-2-opacity);\n\tpadding: var(--top-forms-padding);\n}\n\n.top-editArea-attachedToKeyboard .top-editArea_footer > [data-top-icon] {\n\tborder-radius: 100%;\n}\n\n@media screen and (max-width: 900px) {\n\t.top-editArea_form {\n\t\tflex-direction: row;\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { Emits, Props } from './types';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = defineProps<Props>();\n\nconst intermediateValue = ref(props.modelValue);\n\nwatch(() => props.modelValue, () => {\n\tintermediateValue.value = props.modelValue;\n});\n\nconst emit = defineEmits<Emits>();\n\nconst submit = () => {\n\temit('update:modelValue', intermediateValue.value);\n};\n</script>\n\n<template>\n\t<div class=\"top-editInput\">\n\t\t<TopInput\n\t\t\t:=\"input\"\n\t\t\t@keydown.esc.capture.stop=\"intermediateValue = modelValue\"\n\t\t\t@keydown.enter.stop=\"submit\"\n\t\t\tv-model=\"intermediateValue\"\n\t\t>\n\t\t\t<template #caption v-if=\"$slots.caption\">\n\t\t\t\t<slot name=\"caption\"></slot>\n\t\t\t</template>\n\t\t</TopInput>\n\n\t\t<TopButton\n\t\t\tv-if=\"intermediateValue !== modelValue || alwaysShowSubmitBtn\"\n\t\t\ticon=\"\"\n\t\t\tstyling=\"soft\"\n\t\t\t:=\"button\"\n\t\t\t@click=\"submit\"\n\t\t/>\n\t</div>\n</template>\n\n<style>\n.top-editInput {\n\twidth: 220px;\n\tflex-grow: 1;\n\tdisplay: flex;\n\talign-items: flex-end;\n\tgap: var(--top-gap-1);\n}\n\n.top-editInput .top-input {\n\twidth: unset;\n\tflex-grow: 1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { Emits, Props } from './types';\nimport TopInput from '@/components/forms/input/input.vue';\nimport TopButton from '@/components/forms/button/button.vue';\n\nconst props = defineProps<Props>();\n\nconst intermediateValue = ref(props.modelValue);\n\nwatch(() => props.modelValue, () => {\n\tintermediateValue.value = props.modelValue;\n});\n\nconst emit = defineEmits<Emits>();\n\nconst submit = () => {\n\temit('update:modelValue', intermediateValue.value);\n};\n</script>\n\n<template>\n\t<div class=\"top-editInput\">\n\t\t<TopInput\n\t\t\t:=\"input\"\n\t\t\t@keydown.esc.capture.stop=\"intermediateValue = modelValue\"\n\t\t\t@keydown.enter.stop=\"submit\"\n\t\t\tv-model=\"intermediateValue\"\n\t\t>\n\t\t\t<template #caption v-if=\"$slots.caption\">\n\t\t\t\t<slot name=\"caption\"></slot>\n\t\t\t</template>\n\t\t</TopInput>\n\n\t\t<TopButton\n\t\t\tv-if=\"intermediateValue !== modelValue || alwaysShowSubmitBtn\"\n\t\t\ticon=\"\"\n\t\t\tstyling=\"soft\"\n\t\t\t:=\"button\"\n\t\t\t@click=\"submit\"\n\t\t/>\n\t</div>\n</template>\n\n<style>\n.top-editInput {\n\twidth: 220px;\n\tflex-grow: 1;\n\tdisplay: flex;\n\talign-items: flex-end;\n\tgap: var(--top-gap-1);\n}\n\n.top-editInput .top-input {\n\twidth: unset;\n\tflex-grow: 1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { Props } from './types';\nimport TopCheckbox from '@/components/forms/checkbox/checkbox.vue';\nimport TopRadio from '@/components/forms/radio/radio.vue';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n\tsize: 's',\n});\n\nconst elRef = ref<HTMLElement | null>(null);\n\nwatch(model, () => {\n\tconst valuesAvailable = props.items.map(item => item.value);\n\n\tif (Array.isArray(model.value)) {\n\t\t// есть ли неподдерживаемые значения\n\t\tconst valueIsWrong = model.value.find((value) => {\n\t\t\treturn !valuesAvailable.includes(value);\n\t\t});\n\n\t\tif (valueIsWrong) {\n\t\t\t// оставить только поддерживаемые значения\n\t\t\tmodel.value = model.value.filter((value) => {\n\t\t\t\treturn valuesAvailable.includes(value);\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (!valuesAvailable.includes(model.value)) {\n\t\t\tmodel.value = valuesAvailable[0] ?? '';\n\t\t}\n\t}\n\n\telRef.value?.querySelector('.radioGroup_item-selected')?.scrollIntoView();\n}, { immediate: true });\n\nconst name = 'optionGroup-' + Math.random();\n</script>\n\n<template>\n\t<div\n\t\tref=\"elRef\"\n\t\t:class=\"{\n\t\t\t['top-optionGroup']: true,\n\t\t\t['top-optionGroup-showIndicator_' + Number(showIndicator)]: true,\n\t\t\t['top-scrollBarXHidding']: true,\n\t\t\t['top-size_' + size]: !!size,\n\t\t\t['top-error']: isError,\n\t\t}\"\n\t>\n\t\t<template v-if=\"Array.isArray(model)\">\n\t\t\t<TopCheckbox\n\t\t\t\t:class=\"{\n\t\t\t\t\t['top-optionGroup_item-selected']: model.includes(item.value),\n\t\t\t\t\t['top-optionGroup_item']: true,\n\t\t\t\t}\"\n\t\t\t\tv-for=\"item of items\"\n\t\t\t\tv-model=\"model\"\n\t\t\t\t:value=\"item.value\"\n\t\t\t\t:title=\"item.title\"\n\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t\t:isError\n\t\t\t\t:data-top-icon=\"item.icon\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"item.label\">\n\t\t\t\t\t{{ item.label }}\n\t\t\t\t</template>\n\t\t\t</TopCheckbox>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<TopRadio\n\t\t\t\t:class=\"{\n\t\t\t\t\t['top-optionGroup_item-selected']: item.value === model,\n\t\t\t\t\t['top-optionGroup_item']: true,\n\t\t\t\t}\"\n\t\t\t\tv-for=\"item of items\"\n\t\t\t\tv-model=\"model\"\n\t\t\t\t:name\n\t\t\t\t:value=\"item.value\"\n\t\t\t\t:title=\"item.title\"\n\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t\t:isError\n\t\t\t\t:data-top-icon=\"item.icon\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"item.label\">\n\t\t\t\t\t{{ item.label }}\n\t\t\t\t</template>\n\t\t\t</TopRadio>\n\t\t</template>\n\t</div>\n</template>\n\n<style>\n.top-optionGroup {\n\tuser-select: none;\n\tbox-sizing: border-box;\n\tborder-radius: 8px;\n\tbackground-color: var(--color-layout-middle);\n\theight: var(--top-forms-base-height);\n\tpadding: 2px;\n\tgap: 2px;\n\tdisplay: flex;\n\talign-items: flex-start;\n}\n\n.top-optionGroup_item {\n\tcursor: pointer;\n\tbox-sizing: border-box;\n\tborder-radius: 6px;\n\theight: calc(var(--top-forms-base-height) - 4px);\n\tpadding: 1px var(--top-padding-2);\n\tcolor: var(--color-text-2);\n\tfont-weight: 400;\n\twhite-space: nowrap;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-grow: 1;\n\tgap: var(--top-gap-1);\n}\n\n.top-optionGroup_item:hover {\n\tbackground-color: var(--color-layout-front-1);\n\tbox-shadow: 0px 4px 32px 0px rgba(4, 9, 84, 0.10), 0px 0px 4px 0px rgba(4, 9, 84, 0.08);\n}\n\n.top-optionGroup_item-selected {\n\tcolor: var(--color-text-1);\n\tbackground-color: var(--color-bg-lightning-1);\n\tbox-shadow: 0px 4px 32px 0px rgba(4, 9, 84, 0.10), 0px 0px 4px 0px rgba(4, 9, 84, 0.08);\n}\n\n.top-optionGroup_item > .top-forms-optionLabel {\n\tflex-grow: 0;\n}\n\n/* indicator */\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item {\n\tjustify-content: center;\n}\n\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item:has(:focus-visible) {\n\toutline: 2px solid var(--color-bg-primary-2);\n\toutline-offset: -1px;\n}\n\n.top-optionGroup-showIndicator_1 > .top-optionGroup_item {\n\tpadding: 1px 3px;\n\tjustify-content: flex-start;\n}\n\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item > .top-forms-option {\n\topacity: 0;\n\twidth: 0;\n\theight: 0;\n\tposition: absolute;\n}\n\n.top-optionGroup_item > .top-forms-option {\n\torder: -1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, watch } from 'vue';\nimport type { Props } from './types';\nimport TopCheckbox from '@/components/forms/checkbox/checkbox.vue';\nimport TopRadio from '@/components/forms/radio/radio.vue';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst props = withDefaults(defineProps<Props>(), {\n\tsize: 's',\n});\n\nconst elRef = ref<HTMLElement | null>(null);\n\nwatch(model, () => {\n\tconst valuesAvailable = props.items.map(item => item.value);\n\n\tif (Array.isArray(model.value)) {\n\t\t// есть ли неподдерживаемые значения\n\t\tconst valueIsWrong = model.value.find((value) => {\n\t\t\treturn !valuesAvailable.includes(value);\n\t\t});\n\n\t\tif (valueIsWrong) {\n\t\t\t// оставить только поддерживаемые значения\n\t\t\tmodel.value = model.value.filter((value) => {\n\t\t\t\treturn valuesAvailable.includes(value);\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (!valuesAvailable.includes(model.value)) {\n\t\t\tmodel.value = valuesAvailable[0] ?? '';\n\t\t}\n\t}\n\n\telRef.value?.querySelector('.radioGroup_item-selected')?.scrollIntoView();\n}, { immediate: true });\n\nconst name = 'optionGroup-' + Math.random();\n</script>\n\n<template>\n\t<div\n\t\tref=\"elRef\"\n\t\t:class=\"{\n\t\t\t['top-optionGroup']: true,\n\t\t\t['top-optionGroup-showIndicator_' + Number(showIndicator)]: true,\n\t\t\t['top-scrollBarXHidding']: true,\n\t\t\t['top-size_' + size]: !!size,\n\t\t\t['top-error']: isError,\n\t\t}\"\n\t>\n\t\t<template v-if=\"Array.isArray(model)\">\n\t\t\t<TopCheckbox\n\t\t\t\t:class=\"{\n\t\t\t\t\t['top-optionGroup_item-selected']: model.includes(item.value),\n\t\t\t\t\t['top-optionGroup_item']: true,\n\t\t\t\t}\"\n\t\t\t\tv-for=\"item of items\"\n\t\t\t\tv-model=\"model\"\n\t\t\t\t:value=\"item.value\"\n\t\t\t\t:title=\"item.title\"\n\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t\t:isError\n\t\t\t\t:data-top-icon=\"item.icon\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"item.label\">\n\t\t\t\t\t{{ item.label }}\n\t\t\t\t</template>\n\t\t\t</TopCheckbox>\n\t\t</template>\n\n\t\t<template v-else>\n\t\t\t<TopRadio\n\t\t\t\t:class=\"{\n\t\t\t\t\t['top-optionGroup_item-selected']: item.value === model,\n\t\t\t\t\t['top-optionGroup_item']: true,\n\t\t\t\t}\"\n\t\t\t\tv-for=\"item of items\"\n\t\t\t\tv-model=\"model\"\n\t\t\t\t:name\n\t\t\t\t:value=\"item.value\"\n\t\t\t\t:title=\"item.title\"\n\t\t\t\t:disabled=\"item.disabled\"\n\t\t\t\t:isError\n\t\t\t\t:data-top-icon=\"item.icon\"\n\t\t\t>\n\t\t\t\t<template #default v-if=\"item.label\">\n\t\t\t\t\t{{ item.label }}\n\t\t\t\t</template>\n\t\t\t</TopRadio>\n\t\t</template>\n\t</div>\n</template>\n\n<style>\n.top-optionGroup {\n\tuser-select: none;\n\tbox-sizing: border-box;\n\tborder-radius: 8px;\n\tbackground-color: var(--color-layout-middle);\n\theight: var(--top-forms-base-height);\n\tpadding: 2px;\n\tgap: 2px;\n\tdisplay: flex;\n\talign-items: flex-start;\n}\n\n.top-optionGroup_item {\n\tcursor: pointer;\n\tbox-sizing: border-box;\n\tborder-radius: 6px;\n\theight: calc(var(--top-forms-base-height) - 4px);\n\tpadding: 1px var(--top-padding-2);\n\tcolor: var(--color-text-2);\n\tfont-weight: 400;\n\twhite-space: nowrap;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-grow: 1;\n\tgap: var(--top-gap-1);\n}\n\n.top-optionGroup_item:hover {\n\tbackground-color: var(--color-layout-front-1);\n\tbox-shadow: 0px 4px 32px 0px rgba(4, 9, 84, 0.10), 0px 0px 4px 0px rgba(4, 9, 84, 0.08);\n}\n\n.top-optionGroup_item-selected {\n\tcolor: var(--color-text-1);\n\tbackground-color: var(--color-bg-lightning-1);\n\tbox-shadow: 0px 4px 32px 0px rgba(4, 9, 84, 0.10), 0px 0px 4px 0px rgba(4, 9, 84, 0.08);\n}\n\n.top-optionGroup_item > .top-forms-optionLabel {\n\tflex-grow: 0;\n}\n\n/* indicator */\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item {\n\tjustify-content: center;\n}\n\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item:has(:focus-visible) {\n\toutline: 2px solid var(--color-bg-primary-2);\n\toutline-offset: -1px;\n}\n\n.top-optionGroup-showIndicator_1 > .top-optionGroup_item {\n\tpadding: 1px 3px;\n\tjustify-content: flex-start;\n}\n\n.top-optionGroup-showIndicator_0 > .top-optionGroup_item > .top-forms-option {\n\topacity: 0;\n\twidth: 0;\n\theight: 0;\n\tposition: absolute;\n}\n\n.top-optionGroup_item > .top-forms-option {\n\torder: -1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport OptionGroup from '../libs/optionGroup/optionGroup.vue';\n\nimport type { Props } from './types';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\ndefineProps<Props>();\n</script>\n\n<template>\n\t<OptionGroup\n\t\tclass=\"top-radioGroup\"\n\t\tv-model=\"model\"\n\t\t:items=\"$props.items\"\n\t\t:size=\"$props.size\"\n\t\t:showIndicator=\"$props.showIndicator\"\n\t\t:isError=\"$props.isError\"\n\t>\n\t\t<slot/>\n\t</OptionGroup>\n</template>\n","<script setup lang=\"ts\">\nimport OptionGroup from '../libs/optionGroup/optionGroup.vue';\n\nimport type { Props } from './types';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\ndefineProps<Props>();\n</script>\n\n<template>\n\t<OptionGroup\n\t\tclass=\"top-radioGroup\"\n\t\tv-model=\"model\"\n\t\t:items=\"$props.items\"\n\t\t:size=\"$props.size\"\n\t\t:showIndicator=\"$props.showIndicator\"\n\t\t:isError=\"$props.isError\"\n\t>\n\t\t<slot/>\n\t</OptionGroup>\n</template>\n","<script setup lang=\"ts\">\nimport OptionGroup from '../libs/optionGroup/optionGroup.vue';\n\nimport type { Props } from './types';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\ndefineProps<Props>();\n</script>\n\n<template>\n\t<OptionGroup\n\t\tclass=\"top-checkboxGroup\"\n\t\tv-model=\"model\"\n\t\t:items=\"$props.items\"\n\t\t:size=\"$props.size\"\n\t\t:showIndicator=\"$props.showIndicator\"\n\t\t:isError=\"$props.isError\"\n\t>\n\t\t<slot/>\n\t</OptionGroup>\n</template>\n","<script setup lang=\"ts\">\nimport OptionGroup from '../libs/optionGroup/optionGroup.vue';\n\nimport type { Props } from './types';\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\ndefineProps<Props>();\n</script>\n\n<template>\n\t<OptionGroup\n\t\tclass=\"top-checkboxGroup\"\n\t\tv-model=\"model\"\n\t\t:items=\"$props.items\"\n\t\t:size=\"$props.size\"\n\t\t:showIndicator=\"$props.showIndicator\"\n\t\t:isError=\"$props.isError\"\n\t>\n\t\t<slot/>\n\t</OptionGroup>\n</template>\n","<script lang=\"ts\" setup>\nimport type { Props, Slots } from './types';\n\nwithDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n\tsize: 'default',\n});\n\ndefineSlots<Slots>();\n</script>\n\n<template>\n\t<div\n\t\t:class=\"{\n\t\t\t['top-info']: true,\n\t\t\t['top-size_' + size]: true,\n\t\t\t['top-info-styling_' + styling]: true,\n\t\t}\"\n\t\t:data-top-icon=\"icon\"\n\t>\n\t\t<div class=\"top-info_text\">\n\t\t\t<slot></slot>\n\t\t</div>\n\n\t\t<span v-if=\"$slots.additional\" class=\"top-info_value\">\n\t\t\t<slot name=\"additional\"></slot>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n.top-info {\n\t--top-icon-width: var(--top-icon-size);\n\n\tborder-radius: var(--top-forms-radius);\n\tbox-sizing: border-box;\n\tmin-height: var(--top-forms-base-height);\n\tpadding: var(--top-padding-1) var(--top-padding-2);\n\tflex-grow: 5;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: var(--top-gap-2);\n}\n\n.top-info_text {\n\tflex-grow: 1;\n}\n\n.top-info_value {\n\tfont-weight: bold;\n}\n\n/* size */\n.top-info.top-size_default {\n\tborder-radius: var(--top-radius-3);\n\tpadding: var(--top-padding-4);\n}\n\n/* styling */\n.top-info-styling_default {\n\t--top-icon-color: var(--color-text-2);\n\n\tbackground: var(--color-layer-1);\n}\n\n.top-info-styling_info {\n\t--top-icon-color: var(--color-text-primary);\n\n\tbackground: var(--color-layer-primary-1);\n}\n\n.top-info-styling_warning {\n\t--top-icon-color: var(--color-text-warning);\n\n\tbackground: var(--color-layer-warning-1);\n}\n\n.top-info-styling_negative {\n\t--top-icon-color: var(--color-text-negative);\n\n\tbackground: var(--color-layer-negative-1);\n}\n</style>\n","<script lang=\"ts\" setup>\nimport type { Props, Slots } from './types';\n\nwithDefaults(defineProps<Props>(), {\n\tstyling: 'default',\n\tsize: 'default',\n});\n\ndefineSlots<Slots>();\n</script>\n\n<template>\n\t<div\n\t\t:class=\"{\n\t\t\t['top-info']: true,\n\t\t\t['top-size_' + size]: true,\n\t\t\t['top-info-styling_' + styling]: true,\n\t\t}\"\n\t\t:data-top-icon=\"icon\"\n\t>\n\t\t<div class=\"top-info_text\">\n\t\t\t<slot></slot>\n\t\t</div>\n\n\t\t<span v-if=\"$slots.additional\" class=\"top-info_value\">\n\t\t\t<slot name=\"additional\"></slot>\n\t\t</span>\n\t</div>\n</template>\n\n<style>\n.top-info {\n\t--top-icon-width: var(--top-icon-size);\n\n\tborder-radius: var(--top-forms-radius);\n\tbox-sizing: border-box;\n\tmin-height: var(--top-forms-base-height);\n\tpadding: var(--top-padding-1) var(--top-padding-2);\n\tflex-grow: 5;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: var(--top-gap-2);\n}\n\n.top-info_text {\n\tflex-grow: 1;\n}\n\n.top-info_value {\n\tfont-weight: bold;\n}\n\n/* size */\n.top-info.top-size_default {\n\tborder-radius: var(--top-radius-3);\n\tpadding: var(--top-padding-4);\n}\n\n/* styling */\n.top-info-styling_default {\n\t--top-icon-color: var(--color-text-2);\n\n\tbackground: var(--color-layer-1);\n}\n\n.top-info-styling_info {\n\t--top-icon-color: var(--color-text-primary);\n\n\tbackground: var(--color-layer-primary-1);\n}\n\n.top-info-styling_warning {\n\t--top-icon-color: var(--color-text-warning);\n\n\tbackground: var(--color-layer-warning-1);\n}\n\n.top-info-styling_negative {\n\t--top-icon-color: var(--color-text-negative);\n\n\tbackground: var(--color-layer-negative-1);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { TopButton } from '@/components/forms/forms';\nimport type { Emits, Props } from '@/components/formsExt/policy/types';\n\ndefineProps<Props>();\nconst emits = defineEmits<Emits>();\n\nconst isVisible = ref(true);\n\nconst onAccept = () => {\n\tisVisible.value = false;\n\n\temits('accept');\n};\n</script>\n\n<template>\n\t<div\n\t\tv-if=\"isVisible\"\n\t\tclass=\"top-policy\"\n\t>\n\t\t<div class=\"top-policy_title\">\n\t\t\t{{ title }}\n\t\t</div>\n\n\t\t<div\n\t\t\tclass=\"top-policy_description\"\n\t\t\tv-html=\"description\"\n\t\t></div>\n\n\t\t<TopButton\n\t\t\tsize=\"m\"\n\t\t\t@click=\"onAccept\"\n\t\t>\n\t\t\t{{ acceptText }}\n\t\t</TopButton>\n\t</div>\n</template>\n\n<style>\n.top-policy {\n\tbox-sizing: border-box;\n\tbox-shadow: var(--top-shadow-b);\n\tborder-radius: var(--top-radius-4);\n\tbackground: var(--color-bg-lightning-1);\n\twidth: 600px;\n\tpadding: var(--top-padding-4);\n\tposition: fixed;\n\tright: var(--top-gap-10);\n\tbottom: var(--top-gap-10);\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--top-gap-4);\n\tz-index: 10000;\n}\n\n.top-policy_title {\n\tfont-size: 24px;\n\tfont-weight: 700;\n}\n\n.top-policy_description {\n\tfont-size: 14px;\n}\n\n@media screen and (max-width: 900px) {\n\t.top-policy {\n\t\twidth: 100%;\n\t\tright: 0;\n\t\tbottom: calc(var(--top-gap-5) + var(--toolbar-height, 0px));\n\t}\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref } from 'vue';\nimport { TopButton } from '@/components/forms/forms';\nimport type { Emits, Props } from '@/components/formsExt/policy/types';\n\ndefineProps<Props>();\nconst emits = defineEmits<Emits>();\n\nconst isVisible = ref(true);\n\nconst onAccept = () => {\n\tisVisible.value = false;\n\n\temits('accept');\n};\n</script>\n\n<template>\n\t<div\n\t\tv-if=\"isVisible\"\n\t\tclass=\"top-policy\"\n\t>\n\t\t<div class=\"top-policy_title\">\n\t\t\t{{ title }}\n\t\t</div>\n\n\t\t<div\n\t\t\tclass=\"top-policy_description\"\n\t\t\tv-html=\"description\"\n\t\t></div>\n\n\t\t<TopButton\n\t\t\tsize=\"m\"\n\t\t\t@click=\"onAccept\"\n\t\t>\n\t\t\t{{ acceptText }}\n\t\t</TopButton>\n\t</div>\n</template>\n\n<style>\n.top-policy {\n\tbox-sizing: border-box;\n\tbox-shadow: var(--top-shadow-b);\n\tborder-radius: var(--top-radius-4);\n\tbackground: var(--color-bg-lightning-1);\n\twidth: 600px;\n\tpadding: var(--top-padding-4);\n\tposition: fixed;\n\tright: var(--top-gap-10);\n\tbottom: var(--top-gap-10);\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--top-gap-4);\n\tz-index: 10000;\n}\n\n.top-policy_title {\n\tfont-size: 24px;\n\tfont-weight: 700;\n}\n\n.top-policy_description {\n\tfont-size: 14px;\n}\n\n@media screen and (max-width: 900px) {\n\t.top-policy {\n\t\twidth: 100%;\n\t\tright: 0;\n\t\tbottom: calc(var(--top-gap-5) + var(--toolbar-height, 0px));\n\t}\n}\n</style>\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
define([`require`,`exports`],function(e,t){"use strict";Object.defineProperty(t,`__esModule`,{value:!0}),t.querySerializer=t.postInWindow=t.formDataSerializer=t.dataToForm=void 0;var n=`__empty_arrays`,r=async(e,t,n)=>{let r=document.createElement(`form`);r.target=n,r.action=e,r.method=`post`,i(r,t),document.body.appendChild(r),r.submit(),r.remove()},i=(e,t)=>{let n=a(t);for(let[t,r]of n.entries()){if(r instanceof File)throw Error("Files can not be manual set in `HTMLFormElement`");let n=document.createElement(`input`);n.name=t,n.value=String(r),e.appendChild(n)}},a=(e,t=new FormData,r)=>{for(let[i,o]of Object.entries(e)){if(o==null)continue;let e=r?`${r}[${i}]`:i;switch(!0){case o instanceof File:t.append(e,o,o.name);break;case o instanceof FileList:for(let n=0;n<o.length;n++){let r=o.item(n);r&&t.append(e+`[]`,r,r.name)}break;case o instanceof Blob:t.append(e,o);break;case Array.isArray(o):if(o.length===0){t.append(n+`[]`,e);break}o.forEach((n,r)=>{a({[e+`[`+r+`]`]:n},t)});break;case o instanceof Date:t.append(e,o.toISOString());break;case typeof o==`object`:a(o,t,e);break;default:t.append(e,String(o))}}return t};t.postInWindow=r,t.dataToForm=i,t.formDataSerializer=a,t.querySerializer=e=>{let t=new URLSearchParams,n=(e,r)=>{if(r!=null){if(Array.isArray(r)){for(let[t,i]of Object.entries(r))n(`${e}[${t}]`,i);return}if(typeof r==`object`){for(let[t,i]of Object.entries(r))n(`${e}[${t}]`,i);return}t.append(e,String(r))}};for(let[t,r]of Object.entries(e))n(t,r);return t.toString()}});
|
|
2
|
+
//# sourceMappingURL=lazy-CGswTOPj.amd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[".chunks/lazy-CGswTOPj.esm.js","../../src/api/api/utils/lazy.ts"],"names":["exports","e","t","i","r","n","a"],"mappings":"AAAA,OAAO,CAAC,UAAW,UAAU,CAAE,SAAU,EAAS,EAAS,CCMrD,aASL,OAAa,eAASA,EAAc,aAAO,CAAA,MAAA,GAAA,CAAA,CACtC,EAAS,gBAEd,EAAK,aAEY,EAEjB,mBAAc,EACT,WACA,IAAA,GAOL,IAAMC,EAA8B,iBAAKC,EAAA,MAAA,EAAA,EAAA,IAAA,CAEpC,IAAOC,EAAK,SAAmB,cAAW,OAAA,CAC1C,EAAA,OAAiBC,EAAA,EACpB,OAAU,EAAA,EAAM,OAAA,OAAAC,EAAAF,EAAA,EAAA,CAAA,SAAA,KAAA,YAAmDA,EAAA,CAAAA,EAAA,QAAA,CAAAA,EAAA,QAAA,EAG9DE,GAAQ,EAAA,IAAS,CAEjB,IAAO,EACPD,EAAA,EAAA,CD/BA,IAAK,GAAI,CAAC,EAAG,KAAM,EAAE,SAAS,CAAE,CCyCsB,GAAqB,aAAc,KAC/E,MAAU,MAAO,mDAAe,CACX,IAAM,EAAA,SAAA,cAAA,QAAA,CAE1B,EAAY,KAAa,EAAO,EAAA,MAAK,OAAA,EAAA,CAAA,EAAA,YAAA,EAAA,GAGrDA,GAAK,EAAA,EAAA,IAAiB,SAAA,IAAA,CACZ,IAAO,GAAU,CAAAE,EAAa,KAAK,OAAA,QAAAJ,EAAA,CAAA,CAE5C,GAAA,GAAA,KACI,SACC,IAAIA,EAAOC,EAAI,GAAMA,EAAA,GAAAG,EAAQ,GAAKA,EAChC,OAAkB,CAAA,EAAlB,CAEI,KAAO,aAA4B,KD3C9BD,EAAE,OAAOH,EAAG,EAAG,EAAE,KAAK,CC+CtC,MACI,KAAiB,aAAA,SACW,IAAA,IAAAD,EAAA,EAAAA,EAAA,EAAA,OAAA,IAAA,CAEhC,IAAA,EAAA,EAAA,KAAAA,EAAA,CACwB,GAAAI,EAAA,OAAAH,EAAA,KAAA,EAAA,EAAA,KAAA,CAEmB,MAE1C,KAAA,aAAA,KD/CeG,EAAE,OAAOH,EAAG,EAAE,CCkDT,MACa,KAAM,MAAM,QAAc,EAAS,CACnE,GAAA,EAAA,SAAA,EAAA,CAEFG,EAAA,OAAAJ,EAAA,KAAAC,EAAA,CACqB,MAIrB,EAAA,SAAA,EAAA,IAAA,CACqBE,EAAA,EAAAF,EAAA,IAAAC,EAAA,KAAAF,EAAA,CAAAI,EAAA,EACwB,CAE7C,MAES,KAAO,aAAwB,KDrDxBA,EAAE,OAAOH,EAAG,EAAE,aAAa,CAAC,CAC5B,MCwDZ,KAAA,OAAA,GAAA,SAMkEE,EAAA,EAAAC,EAAAH,EAAA,CAChD,MAGJ,QAEpBG,EAAA,OAAAH,EAAA,OAAA,EAAA,CAAA,EAIC,OAAAG,GD5CC,EAAQ,aAAeH,EACvB,EAAQ,WAAaG,EACrB,EAAQ,mBAAqBD,EAC7B,EAAQ,gBAvBA,GAAM,CCmEZ,IAAA,EAAO,IAAiB,gBAAU,GAAA,EAAA,IAAA,CAChC,GAAO,GAAK,KAAU,CAG3B,GAAA,MAAA,QAAA,EAAA,CAAA,CDnEiB,IAAK,GAAI,CAAC,EAAG,KAAM,OAAO,QAAQ,EAAE,CCsER,EAAC,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,CDpE7B,OCuEF,GAAU,OAAO,GAAA,SACrB,CAGiB,IAAA,GAAA,CAAA,EAAA,KAAA,OAAA,QAAA,EAAA,CDvEP,EAAE,GAAG,EAAE,GAAG,EAAE,GAAI,EAAE,CACtB,OAEJ,EAAE,OAAO,EAAG,OAAO,EAAE,CAAC,GAG9B,IAAK,GAAI,CAAC,EAAG,KAAM,OAAO,QAAQ,EAAE,CAChC,EAAE,EAAG,EAAE,CACX,OAAO,EAAE,UAAU,GAMzB","sourcesContent":["define([\"require\", \"exports\"], function (require, exports) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.querySerializer = exports.postInWindow = exports.formDataSerializer = exports.dataToForm = void 0;\n //#region src/api/api/utils/lazy.ts\n var e = \"__empty_arrays\", t = async (e, t, r) => {\n let i = document.createElement(\"form\");\n i.target = r, i.action = e, i.method = \"post\", n(i, t), document.body.appendChild(i), i.submit(), i.remove();\n }, n = (e, t) => {\n let n = r(t);\n for (let [t, r] of n.entries()) {\n if (r instanceof File)\n throw Error(\"Files can not be manual set in `HTMLFormElement`\");\n let n = document.createElement(\"input\");\n n.name = t, n.value = String(r), e.appendChild(n);\n }\n }, r = (t, n = new FormData(), i) => {\n for (let [a, o] of Object.entries(t)) {\n if (o == null)\n continue;\n let t = i ? `${i}[${a}]` : a;\n switch (!0) {\n case o instanceof File:\n n.append(t, o, o.name);\n break;\n case o instanceof FileList:\n for (let e = 0; e < o.length; e++) {\n let r = o.item(e);\n r && n.append(t + \"[]\", r, r.name);\n }\n break;\n case o instanceof Blob:\n n.append(t, o);\n break;\n case Array.isArray(o):\n if (o.length === 0) {\n n.append(e + \"[]\", t);\n break;\n }\n o.forEach((e, i) => {\n r({ [t + \"[\" + i + \"]\"]: e }, n);\n });\n break;\n case o instanceof Date:\n n.append(t, o.toISOString());\n break;\n case typeof o == \"object\":\n r(o, n, t);\n break;\n default: n.append(t, String(o));\n }\n }\n return n;\n }, i = (e) => {\n let t = new URLSearchParams(), n = (e, r) => {\n if (r != null) {\n if (Array.isArray(r)) {\n for (let [t, i] of Object.entries(r))\n n(`${e}[${t}]`, i);\n return;\n }\n if (typeof r == \"object\") {\n for (let [t, i] of Object.entries(r))\n n(`${e}[${t}]`, i);\n return;\n }\n t.append(e, String(r));\n }\n };\n for (let [t, r] of Object.entries(e))\n n(t, r);\n return t.toString();\n };\n exports.postInWindow = t;\n exports.dataToForm = n;\n exports.formDataSerializer = r;\n exports.querySerializer = i;\n});\n//# sourceMappingURL=lazy-CGswTOPj.esm.js.map\n","/**\n * Общие утилиты, которые должны грузиться в отложенном режиме\n *\n * Все такие утилиты являются асинхронными\n */\n\nconst EMPTY_ARRAYS_FIELD_NAME = '__empty_arrays';\n\n/**\n * Выполнить post запрос в окне браузера\n *\n * @see Api.ClientRequest.callInNewWindow\n * @see Api.ClientRequest.callInSelfWindow\n */\nexport const postInWindow = async (url: string, data: Record<string, any>, target: '_blank' | '_self'): Promise<void> => {\n\tconst form = document.createElement('form');\n\tform.target = target;\n\tform.action = url;\n\tform.method = 'post';\n\n\tdataToForm(form, data);\n\n\tdocument.body.appendChild(form);\n\tform.submit();\n\tform.remove();\n};\n\n/**\n * Вставляет данные в HTML форму\n */\nexport const dataToForm = (elForm: HTMLFormElement, data: Record<string, any>): void => {\n\tconst formData = formDataSerializer(data);\n\n\tfor (const [key, value] of formData.entries()) {\n\t\tif (value instanceof File) {\n\t\t\tthrow new Error('Files can not be manual set in `HTMLFormElement`');\n\t\t}\n\n\t\tconst input = document.createElement('input');\n\t\t// input.type = 'hidden';\n\t\tinput.name = key;\n\t\tinput.value = String(value);\n\t\telForm.appendChild(input);\n\t}\n};\n\n/**\n * Сериализация данных в объект FormData\n *\n * Для отправки файлов или генерации форм\n */\nexport const formDataSerializer = (data: Record<string, any>, formData: FormData = new FormData(), parentKey?: string): FormData => {\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (value === undefined || value === null) continue;\n\n\t\tconst fieldKey = parentKey ? `${parentKey}[${key}]` : key;\n\n\t\tswitch (true) {\n\t\t\tcase value instanceof File:\n\t\t\t\tformData.append(fieldKey, value, value.name);\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof FileList:\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tconst file = value.item(i);\n\t\t\t\t\tif (file) {\n\t\t\t\t\t\tformData.append(fieldKey + '[]', file, file.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof Blob:\n\t\t\t\tformData.append(fieldKey, value);\n\n\t\t\t\tbreak;\n\t\t\tcase Array.isArray(value):\n\t\t\t\tif (value.length === 0) {\n\t\t\t\t\tformData.append(EMPTY_ARRAYS_FIELD_NAME + '[]', fieldKey);\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tvalue.forEach((item, key) => {\n\t\t\t\t\tformDataSerializer({ [fieldKey + '[' + key + ']']: item }, formData);\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof Date:\n\t\t\t\t// для совместимости с JSON.stringify();\n\t\t\t\tformData.append(fieldKey, value.toISOString());\n\n\t\t\t\tbreak;\n\t\t\tcase typeof value === 'object':\n\t\t\t\tformDataSerializer(value, formData, fieldKey);\n\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tformData.append(fieldKey, String(value));\n\t\t}\n\t}\n\n\treturn formData;\n};\n\n/**\n * Сериализация данных для вставки в виде параметров в url\n */\nexport const querySerializer = (data: Record<string, unknown>): string => {\n\tconst searchParams = new URLSearchParams();\n\n\tconst appendParam = (path: string, currentValue: unknown): void => {\n\t\tif (currentValue == null) return;\n\n\t\tif (Array.isArray(currentValue)) {\n\t\t\tfor (const [key, value] of Object.entries(currentValue)) {\n\t\t\t\tappendParam(`${path}[${key}]`, value);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof currentValue === 'object') {\n\t\t\tfor (const [key, value] of Object.entries(currentValue as Record<string, unknown>)) {\n\t\t\t\tappendParam(`${path}[${key}]`, value);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tsearchParams.append(path, String(currentValue));\n\t};\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tappendParam(key, value);\n\t}\n\n\treturn searchParams.toString();\n};\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
//#region src/api/api/utils/lazy.ts
|
|
2
|
+
var e = "__empty_arrays", t = async (e, t, r) => {
|
|
3
|
+
let i = document.createElement("form");
|
|
4
|
+
i.target = r, i.action = e, i.method = "post", n(i, t), document.body.appendChild(i), i.submit(), i.remove();
|
|
5
|
+
}, n = (e, t) => {
|
|
6
|
+
let n = r(t);
|
|
7
|
+
for (let [t, r] of n.entries()) {
|
|
8
|
+
if (r instanceof File) throw Error("Files can not be manual set in `HTMLFormElement`");
|
|
9
|
+
let n = document.createElement("input");
|
|
10
|
+
n.name = t, n.value = String(r), e.appendChild(n);
|
|
11
|
+
}
|
|
12
|
+
}, r = (t, n = new FormData(), i) => {
|
|
13
|
+
for (let [a, o] of Object.entries(t)) {
|
|
14
|
+
if (o == null) continue;
|
|
15
|
+
let t = i ? `${i}[${a}]` : a;
|
|
16
|
+
switch (!0) {
|
|
17
|
+
case o instanceof File:
|
|
18
|
+
n.append(t, o, o.name);
|
|
19
|
+
break;
|
|
20
|
+
case o instanceof FileList:
|
|
21
|
+
for (let e = 0; e < o.length; e++) {
|
|
22
|
+
let r = o.item(e);
|
|
23
|
+
r && n.append(t + "[]", r, r.name);
|
|
24
|
+
}
|
|
25
|
+
break;
|
|
26
|
+
case o instanceof Blob:
|
|
27
|
+
n.append(t, o);
|
|
28
|
+
break;
|
|
29
|
+
case Array.isArray(o):
|
|
30
|
+
if (o.length === 0) {
|
|
31
|
+
n.append(e + "[]", t);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
o.forEach((e, i) => {
|
|
35
|
+
r({ [t + "[" + i + "]"]: e }, n);
|
|
36
|
+
});
|
|
37
|
+
break;
|
|
38
|
+
case o instanceof Date:
|
|
39
|
+
n.append(t, o.toISOString());
|
|
40
|
+
break;
|
|
41
|
+
case typeof o == "object":
|
|
42
|
+
r(o, n, t);
|
|
43
|
+
break;
|
|
44
|
+
default: n.append(t, String(o));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return n;
|
|
48
|
+
}, i = (e) => {
|
|
49
|
+
let t = new URLSearchParams(), n = (e, r) => {
|
|
50
|
+
if (r != null) {
|
|
51
|
+
if (Array.isArray(r)) {
|
|
52
|
+
for (let [t, i] of Object.entries(r)) n(`${e}[${t}]`, i);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (typeof r == "object") {
|
|
56
|
+
for (let [t, i] of Object.entries(r)) n(`${e}[${t}]`, i);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
t.append(e, String(r));
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
for (let [t, r] of Object.entries(e)) n(t, r);
|
|
63
|
+
return t.toString();
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { n as dataToForm, r as formDataSerializer, t as postInWindow, i as querySerializer };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=lazy-CGswTOPj.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-CGswTOPj.esm.js","names":[],"sources":["../../src/api/api/utils/lazy.ts"],"sourcesContent":["/**\n * Общие утилиты, которые должны грузиться в отложенном режиме\n *\n * Все такие утилиты являются асинхронными\n */\n\nconst EMPTY_ARRAYS_FIELD_NAME = '__empty_arrays';\n\n/**\n * Выполнить post запрос в окне браузера\n *\n * @see Api.ClientRequest.callInNewWindow\n * @see Api.ClientRequest.callInSelfWindow\n */\nexport const postInWindow = async (url: string, data: Record<string, any>, target: '_blank' | '_self'): Promise<void> => {\n\tconst form = document.createElement('form');\n\tform.target = target;\n\tform.action = url;\n\tform.method = 'post';\n\n\tdataToForm(form, data);\n\n\tdocument.body.appendChild(form);\n\tform.submit();\n\tform.remove();\n};\n\n/**\n * Вставляет данные в HTML форму\n */\nexport const dataToForm = (elForm: HTMLFormElement, data: Record<string, any>): void => {\n\tconst formData = formDataSerializer(data);\n\n\tfor (const [key, value] of formData.entries()) {\n\t\tif (value instanceof File) {\n\t\t\tthrow new Error('Files can not be manual set in `HTMLFormElement`');\n\t\t}\n\n\t\tconst input = document.createElement('input');\n\t\t// input.type = 'hidden';\n\t\tinput.name = key;\n\t\tinput.value = String(value);\n\t\telForm.appendChild(input);\n\t}\n};\n\n/**\n * Сериализация данных в объект FormData\n *\n * Для отправки файлов или генерации форм\n */\nexport const formDataSerializer = (data: Record<string, any>, formData: FormData = new FormData(), parentKey?: string): FormData => {\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tif (value === undefined || value === null) continue;\n\n\t\tconst fieldKey = parentKey ? `${parentKey}[${key}]` : key;\n\n\t\tswitch (true) {\n\t\t\tcase value instanceof File:\n\t\t\t\tformData.append(fieldKey, value, value.name);\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof FileList:\n\t\t\t\tfor (let i = 0; i < value.length; i++) {\n\t\t\t\t\tconst file = value.item(i);\n\t\t\t\t\tif (file) {\n\t\t\t\t\t\tformData.append(fieldKey + '[]', file, file.name);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof Blob:\n\t\t\t\tformData.append(fieldKey, value);\n\n\t\t\t\tbreak;\n\t\t\tcase Array.isArray(value):\n\t\t\t\tif (value.length === 0) {\n\t\t\t\t\tformData.append(EMPTY_ARRAYS_FIELD_NAME + '[]', fieldKey);\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tvalue.forEach((item, key) => {\n\t\t\t\t\tformDataSerializer({ [fieldKey + '[' + key + ']']: item }, formData);\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\tcase value instanceof Date:\n\t\t\t\t// для совместимости с JSON.stringify();\n\t\t\t\tformData.append(fieldKey, value.toISOString());\n\n\t\t\t\tbreak;\n\t\t\tcase typeof value === 'object':\n\t\t\t\tformDataSerializer(value, formData, fieldKey);\n\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tformData.append(fieldKey, String(value));\n\t\t}\n\t}\n\n\treturn formData;\n};\n\n/**\n * Сериализация данных для вставки в виде параметров в url\n */\nexport const querySerializer = (data: Record<string, unknown>): string => {\n\tconst searchParams = new URLSearchParams();\n\n\tconst appendParam = (path: string, currentValue: unknown): void => {\n\t\tif (currentValue == null) return;\n\n\t\tif (Array.isArray(currentValue)) {\n\t\t\tfor (const [key, value] of Object.entries(currentValue)) {\n\t\t\t\tappendParam(`${path}[${key}]`, value);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof currentValue === 'object') {\n\t\t\tfor (const [key, value] of Object.entries(currentValue as Record<string, unknown>)) {\n\t\t\t\tappendParam(`${path}[${key}]`, value);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tsearchParams.append(path, String(currentValue));\n\t};\n\n\tfor (const [key, value] of Object.entries(data)) {\n\t\tappendParam(key, value);\n\t}\n\n\treturn searchParams.toString();\n};\n"],"mappings":";AAMA,IAAM,IAA0B,kBAQnB,IAAe,OAAO,GAAa,GAA2B,MAA8C;CACxH,IAAM,IAAO,SAAS,cAAc,OAAO;AAS3C,CARA,EAAK,SAAS,GACd,EAAK,SAAS,GACd,EAAK,SAAS,QAEd,EAAW,GAAM,EAAK,EAEtB,SAAS,KAAK,YAAY,EAAK,EAC/B,EAAK,QAAQ,EACb,EAAK,QAAQ;GAMD,KAAc,GAAyB,MAAoC;CACvF,IAAM,IAAW,EAAmB,EAAK;AAEzC,MAAK,IAAM,CAAC,GAAK,MAAU,EAAS,SAAS,EAAE;AAC9C,MAAI,aAAiB,KACpB,OAAU,MAAM,mDAAmD;EAGpE,IAAM,IAAQ,SAAS,cAAc,QAAQ;AAI7C,EAFA,EAAM,OAAO,GACb,EAAM,QAAQ,OAAO,EAAM,EAC3B,EAAO,YAAY,EAAM;;GASd,KAAsB,GAA2B,IAAqB,IAAI,UAAU,EAAE,MAAiC;AACnI,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAK,EAAE;AAChD,MAAI,KAAiC,KAAM;EAE3C,IAAM,IAAW,IAAY,GAAG,EAAU,GAAG,EAAI,KAAK;AAEtD,UAAQ,IAAR;GACC,KAAK,aAAiB;AACrB,MAAS,OAAO,GAAU,GAAO,EAAM,KAAK;AAE5C;GACD,KAAK,aAAiB;AACrB,SAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;KACtC,IAAM,IAAO,EAAM,KAAK,EAAE;AAC1B,KAAI,KACH,EAAS,OAAO,IAAW,MAAM,GAAM,EAAK,KAAK;;AAInD;GACD,KAAK,aAAiB;AACrB,MAAS,OAAO,GAAU,EAAM;AAEhC;GACD,KAAK,MAAM,QAAQ,EAAM;AACxB,QAAI,EAAM,WAAW,GAAG;AACvB,OAAS,OAAO,IAA0B,MAAM,EAAS;AAEzD;;AAGD,MAAM,SAAS,GAAM,MAAQ;AAC5B,OAAmB,GAAG,IAAW,MAAM,IAAM,MAAM,GAAM,EAAE,EAAS;MACnE;AAEF;GACD,KAAK,aAAiB;AAErB,MAAS,OAAO,GAAU,EAAM,aAAa,CAAC;AAE9C;GACD,KAAK,OAAO,KAAU;AACrB,MAAmB,GAAO,GAAU,EAAS;AAE7C;GACD,QACC,GAAS,OAAO,GAAU,OAAO,EAAM,CAAC;;;AAI3C,QAAO;GAMK,KAAmB,MAA0C;CACzE,IAAM,IAAe,IAAI,iBAAiB,EAEpC,KAAe,GAAc,MAAgC;AAC9D,WAAgB,MAEpB;OAAI,MAAM,QAAQ,EAAa,EAAE;AAChC,SAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAa,CACtD,GAAY,GAAG,EAAK,GAAG,EAAI,IAAI,EAAM;AAEtC;;AAGD,OAAI,OAAO,KAAiB,UAAU;AACrC,SAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAwC,CACjF,GAAY,GAAG,EAAK,GAAG,EAAI,IAAI,EAAM;AAEtC;;AAGD,KAAa,OAAO,GAAM,OAAO,EAAa,CAAC;;;AAGhD,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAK,CAC9C,GAAY,GAAK,EAAM;AAGxB,QAAO,EAAa,UAAU"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var __createBinding=this&&this.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||(`get`in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,i)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,`default`,{enumerable:!0,value:t})}):function(e,t){e.default=t}),__importStar=this&&this.__importStar||(function(){var n=function(e){return n=Object.getOwnPropertyNames||function(e){var t=[];for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[t.length]=n);return t},n(e)};return function(r){if(r&&r.__esModule)return r;var i={};if(r!=null)for(var a=n(r),o=0;o<a.length;o++)a[o]!==`default`&&__createBinding(i,r,a[o]);return __setModuleDefault(i,r),i}})();define([`require`,`exports`,`@faker-js/faker`],function(e,t,r){"use strict";Object.defineProperty(t,`__esModule`,{value:!0}),t.genMockResponse=void 0;var i=20,a=async(t,r,i,a)=>{if(t.delay){t.showLog&&console.log(`genMock pause`,t.delay);let{sleep:r}=await new Promise((t,n)=>{e([`../utils/system.amd.js`],t,n)}).then(__importStar),i=r(t.delay);a&&(i=Promise.race([i,new Promise((e,t)=>{a.addEventListener(`abort`,()=>{t(new DOMException(`The operation was aborted from API mocker.`,`AbortError`))})})])),await i}let s={result:o(t,r,i),errors:void 0,nextOffset:void 0,total:void 0};if(delete s.errors,delete s.nextOffset,delete s.total,Array.isArray(s.result)&&t.total&&i&&i.limit){t.useFilter&&(s.result=s.result.filter(e=>t.useFilter?.(e,i)));let e=i.offset??0;s.result.length>i.limit+e&&(s.nextOffset=i.limit+e,s.total=t.total),s.result=s.result.slice(e,e+i.limit)}return t.showLog&&console.log(`genMock complete`,s),s},o=(e,t,n)=>{let a=e.seed??0;if(a===-1&&(a=Math.random()),e.result instanceof Function)return r.faker.seed(a),c(e.result,0,t,n);if(Array.isArray(e.result)){let r=e.result[0],o=[],c=e.total??n?.limit??i;for(let e=0;e<c;e++)o.push(s(r,e,a,t,n));return o}return s(e.result,0,a,t,n)},s=(e,t,n,i,a)=>{let o={};for(let s in e){let l=e[s];i&&!i.includes(s)||(r.faker.seed(n+t),o[s]=c(l,t,i,a))}return o},c=(e,t=0,n,r)=>e(t,n,r);t.genMockResponse=a});
|
|
2
|
+
//# sourceMappingURL=mocker-CwZe-g4N.amd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[".chunks/mocker-CwZe-g4N.esm.js","../../src/api/api/mocker/index.ts"],"names":["k2","k","desc","m","o","v","\"default\"","ownKeys","ar","mod","result","i","exports","t","n","e","require","resolve_1","reject_1","a","r","s","faker_1","c"],"mappings":"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","sourcesContent":["var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || (function () {\n var ownKeys = function(o) {\n ownKeys = Object.getOwnPropertyNames || function (o) {\n var ar = [];\n for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;\n return ar;\n };\n return ownKeys(o);\n };\n return function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== \"default\") __createBinding(result, mod, k[i]);\n __setModuleDefault(result, mod);\n return result;\n };\n})();\ndefine([\"require\", \"exports\", \"@faker-js/faker\"], function (require, exports, faker_1) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.genMockResponse = void 0;\n //#region src/api/api/mocker/index.ts\n var t = 20, n = async (e, t, n, i) => {\n if (e.delay) {\n e.showLog && console.log(\"genMock pause\", e.delay);\n let { sleep: t } = await new Promise((resolve_1, reject_1) => { require([\"../utils/system.js\"], resolve_1, reject_1); }).then(__importStar), n = t(e.delay);\n i && (n = Promise.race([n, new Promise((e, t) => {\n i.addEventListener(\"abort\", () => {\n t(new DOMException(\"The operation was aborted from API mocker.\", \"AbortError\"));\n });\n })])), await n;\n }\n let a = {\n result: r(e, t, n),\n errors: void 0,\n nextOffset: void 0,\n total: void 0\n };\n if (delete a.errors, delete a.nextOffset, delete a.total, Array.isArray(a.result) && e.total && n && n.limit) {\n e.useFilter && (a.result = a.result.filter((t) => e.useFilter?.(t, n)));\n let t = n.offset ?? 0;\n a.result.length > n.limit + t && (a.nextOffset = n.limit + t, a.total = e.total), a.result = a.result.slice(t, t + n.limit);\n }\n return e.showLog && console.log(\"genMock complete\", a), a;\n }, r = (n, r, o) => {\n let s = n.seed ?? 0;\n if (s === -1 && (s = Math.random()), n.result instanceof Function)\n return faker_1.faker.seed(s), a(n.result, 0, r, o);\n if (Array.isArray(n.result)) {\n let e = n.result[0], a = [], c = n.total ?? o?.limit ?? t;\n for (let t = 0; t < c; t++)\n a.push(i(e, t, s, r, o));\n return a;\n }\n return i(n.result, 0, s, r, o);\n }, i = (t, n, r, i, o) => {\n let s = {};\n for (let c in t) {\n let l = t[c];\n i && !i.includes(c) || (faker_1.faker.seed(r + n), s[c] = a(l, n, i, o));\n }\n return s;\n }, a = (e, t = 0, n, r) => e(t, n, r);\n exports.genMockResponse = n;\n});\n//# sourceMappingURL=mocker-CwZe-g4N.esm.js.map\n","import { faker } from '@faker-js/faker';\n\nconst DEFAULT_LIMIT = 20;\n\nexport const genMockResponse = async (\n\toptions: Api.Mocker.Options<any, any>,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n\trequestInitSignal?: ReturnType<Api.ClientRequest<any>['abortByFingerprint']>,\n) => {\n\tif (options.delay) {\n\t\tif (options.showLog) {\n\t\t\tconsole.log('genMock pause', options.delay);\n\t\t}\n\n\t\tconst { sleep } = await import('@/core/utils/system');\n\n\t\tlet promise = sleep(options.delay);\n\n\t\tif (requestInitSignal) {\n\t\t\tpromise = Promise.race<void>([\n\t\t\t\tpromise,\n\n\t\t\t\t// обработчик отмены\n\t\t\t\tnew Promise((_resolve, reject) => {\n\t\t\t\t\trequestInitSignal.addEventListener('abort', () => {\n\t\t\t\t\t\treject(new DOMException('The operation was aborted from API mocker.', 'AbortError'));\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t]);\n\t\t}\n\n\t\tawait promise;\n\t}\n\n\tconst res = {\n\t\tresult: genMockResult(options, fields, params),\n\t\terrors: undefined,\n\t\tnextOffset: undefined as number | undefined,\n\t\ttotal: undefined as number | undefined,\n\t};\n\n\tdelete res.errors;\n\tdelete res.nextOffset;\n\tdelete res.total;\n\n\t// реализация `limit` и `offset`\n\tif (Array.isArray(res.result) && options.total && params && params.limit) {\n\t\tif (options.useFilter) {\n\t\t\tres.result = res.result.filter((resultItem) => options.useFilter?.(resultItem, params));\n\t\t}\n\n\t\tconst offset = params.offset ?? 0;\n\n\t\tif (res.result.length > params.limit + offset) {\n\t\t\tres.nextOffset = params.limit + offset;\n\t\t\tres.total = options.total;\n\t\t}\n\n\t\tres.result = res.result.slice(offset, offset + params.limit);\n\t}\n\n\tif (options.showLog) {\n\t\tconsole.log('genMock complete', res);\n\t}\n\n\treturn res;\n};\n\nexport const genMockResult = <Options extends Api.Mocker.Options<any, any>>(\n\toptions: Options,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockResult<Options['result']> => {\n\tlet seed: number | undefined = options.seed ?? 0;\n\tif (seed === -1) seed = Math.random();\n\n\tif (options.result instanceof Function) {\n\t\tfaker.seed(seed);\n\n\t\treturn genMockValue(options.result, 0, fields, params);\n\t}\n\n\tif (Array.isArray(options.result)) {\n\t\tconst genItem = options.result[0];\n\n\t\tconst result = [] as Api.Mocker.ToMockResult<Options['result']>;\n\n\t\t// для работы `useFilter()` применять `params.limit` можно только после применения фильтра\n\t\tconst total = options.total ?? params?.limit ?? DEFAULT_LIMIT;\n\n\t\tfor (let i = 0; i < total; i++) {\n\t\t\tresult.push(genMockItem(genItem, i, seed, fields, params));\n\t\t}\n\n\t\treturn result;\n\t}\n\n\treturn genMockItem(options.result, 0, seed, fields, params) as Api.Mocker.ToMockResult<Options['result']>;\n};\n\nexport const genMockItem = <T extends Api.Mocker.Item>(\n\tgenItem: T,\n\tn: number,\n\tseed: number,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockItem<T> => {\n\tconst item = {} as Api.Mocker.ToMockItem<T>;\n\n\tfor (const key in genItem) {\n\t\tconst genValue = genItem[key];\n\n\t\tif (fields && !fields.includes(key)) continue;\n\n\t\t// seed для генерации одного объекта всегда одинаковый\n\t\tfaker.seed(seed + n);\n\n\t\titem[key] = genMockValue(genValue, n, fields, params);\n\t}\n\n\treturn item;\n};\n\nexport const genMockValue = <T extends Api.Mocker.Value>(\n\tgenValue: T,\n\tn: number = 0,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockValue<T> => {\n\treturn genValue(n, fields, params);\n};\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { faker as e } from "@faker-js/faker";
|
|
2
|
+
//#region src/api/api/mocker/index.ts
|
|
3
|
+
var t = 20, n = async (e, t, n, i) => {
|
|
4
|
+
if (e.delay) {
|
|
5
|
+
e.showLog && console.log("genMock pause", e.delay);
|
|
6
|
+
let { sleep: t } = await import("../utils/system.js"), n = t(e.delay);
|
|
7
|
+
i && (n = Promise.race([n, new Promise((e, t) => {
|
|
8
|
+
i.addEventListener("abort", () => {
|
|
9
|
+
t(new DOMException("The operation was aborted from API mocker.", "AbortError"));
|
|
10
|
+
});
|
|
11
|
+
})])), await n;
|
|
12
|
+
}
|
|
13
|
+
let a = {
|
|
14
|
+
result: r(e, t, n),
|
|
15
|
+
errors: void 0,
|
|
16
|
+
nextOffset: void 0,
|
|
17
|
+
total: void 0
|
|
18
|
+
};
|
|
19
|
+
if (delete a.errors, delete a.nextOffset, delete a.total, Array.isArray(a.result) && e.total && n && n.limit) {
|
|
20
|
+
e.useFilter && (a.result = a.result.filter((t) => e.useFilter?.(t, n)));
|
|
21
|
+
let t = n.offset ?? 0;
|
|
22
|
+
a.result.length > n.limit + t && (a.nextOffset = n.limit + t, a.total = e.total), a.result = a.result.slice(t, t + n.limit);
|
|
23
|
+
}
|
|
24
|
+
return e.showLog && console.log("genMock complete", a), a;
|
|
25
|
+
}, r = (n, r, o) => {
|
|
26
|
+
let s = n.seed ?? 0;
|
|
27
|
+
if (s === -1 && (s = Math.random()), n.result instanceof Function) return e.seed(s), a(n.result, 0, r, o);
|
|
28
|
+
if (Array.isArray(n.result)) {
|
|
29
|
+
let e = n.result[0], a = [], c = n.total ?? o?.limit ?? t;
|
|
30
|
+
for (let t = 0; t < c; t++) a.push(i(e, t, s, r, o));
|
|
31
|
+
return a;
|
|
32
|
+
}
|
|
33
|
+
return i(n.result, 0, s, r, o);
|
|
34
|
+
}, i = (t, n, r, i, o) => {
|
|
35
|
+
let s = {};
|
|
36
|
+
for (let c in t) {
|
|
37
|
+
let l = t[c];
|
|
38
|
+
i && !i.includes(c) || (e.seed(r + n), s[c] = a(l, n, i, o));
|
|
39
|
+
}
|
|
40
|
+
return s;
|
|
41
|
+
}, a = (e, t = 0, n, r) => e(t, n, r);
|
|
42
|
+
//#endregion
|
|
43
|
+
export { n as genMockResponse };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=mocker-CwZe-g4N.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocker-CwZe-g4N.esm.js","names":[],"sources":["../../src/api/api/mocker/index.ts"],"sourcesContent":["import { faker } from '@faker-js/faker';\n\nconst DEFAULT_LIMIT = 20;\n\nexport const genMockResponse = async (\n\toptions: Api.Mocker.Options<any, any>,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n\trequestInitSignal?: ReturnType<Api.ClientRequest<any>['abortByFingerprint']>,\n) => {\n\tif (options.delay) {\n\t\tif (options.showLog) {\n\t\t\tconsole.log('genMock pause', options.delay);\n\t\t}\n\n\t\tconst { sleep } = await import('@/core/utils/system');\n\n\t\tlet promise = sleep(options.delay);\n\n\t\tif (requestInitSignal) {\n\t\t\tpromise = Promise.race<void>([\n\t\t\t\tpromise,\n\n\t\t\t\t// обработчик отмены\n\t\t\t\tnew Promise((_resolve, reject) => {\n\t\t\t\t\trequestInitSignal.addEventListener('abort', () => {\n\t\t\t\t\t\treject(new DOMException('The operation was aborted from API mocker.', 'AbortError'));\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\t]);\n\t\t}\n\n\t\tawait promise;\n\t}\n\n\tconst res = {\n\t\tresult: genMockResult(options, fields, params),\n\t\terrors: undefined,\n\t\tnextOffset: undefined as number | undefined,\n\t\ttotal: undefined as number | undefined,\n\t};\n\n\tdelete res.errors;\n\tdelete res.nextOffset;\n\tdelete res.total;\n\n\t// реализация `limit` и `offset`\n\tif (Array.isArray(res.result) && options.total && params && params.limit) {\n\t\tif (options.useFilter) {\n\t\t\tres.result = res.result.filter((resultItem) => options.useFilter?.(resultItem, params));\n\t\t}\n\n\t\tconst offset = params.offset ?? 0;\n\n\t\tif (res.result.length > params.limit + offset) {\n\t\t\tres.nextOffset = params.limit + offset;\n\t\t\tres.total = options.total;\n\t\t}\n\n\t\tres.result = res.result.slice(offset, offset + params.limit);\n\t}\n\n\tif (options.showLog) {\n\t\tconsole.log('genMock complete', res);\n\t}\n\n\treturn res;\n};\n\nexport const genMockResult = <Options extends Api.Mocker.Options<any, any>>(\n\toptions: Options,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockResult<Options['result']> => {\n\tlet seed: number | undefined = options.seed ?? 0;\n\tif (seed === -1) seed = Math.random();\n\n\tif (options.result instanceof Function) {\n\t\tfaker.seed(seed);\n\n\t\treturn genMockValue(options.result, 0, fields, params);\n\t}\n\n\tif (Array.isArray(options.result)) {\n\t\tconst genItem = options.result[0];\n\n\t\tconst result = [] as Api.Mocker.ToMockResult<Options['result']>;\n\n\t\t// для работы `useFilter()` применять `params.limit` можно только после применения фильтра\n\t\tconst total = options.total ?? params?.limit ?? DEFAULT_LIMIT;\n\n\t\tfor (let i = 0; i < total; i++) {\n\t\t\tresult.push(genMockItem(genItem, i, seed, fields, params));\n\t\t}\n\n\t\treturn result;\n\t}\n\n\treturn genMockItem(options.result, 0, seed, fields, params) as Api.Mocker.ToMockResult<Options['result']>;\n};\n\nexport const genMockItem = <T extends Api.Mocker.Item>(\n\tgenItem: T,\n\tn: number,\n\tseed: number,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockItem<T> => {\n\tconst item = {} as Api.Mocker.ToMockItem<T>;\n\n\tfor (const key in genItem) {\n\t\tconst genValue = genItem[key];\n\n\t\tif (fields && !fields.includes(key)) continue;\n\n\t\t// seed для генерации одного объекта всегда одинаковый\n\t\tfaker.seed(seed + n);\n\n\t\titem[key] = genMockValue(genValue, n, fields, params);\n\t}\n\n\treturn item;\n};\n\nexport const genMockValue = <T extends Api.Mocker.Value>(\n\tgenValue: T,\n\tn: number = 0,\n\tfields?: readonly string[],\n\tparams?: Api.Mocker.Params,\n): Api.Mocker.ToMockValue<T> => {\n\treturn genValue(n, fields, params);\n};\n"],"mappings":";;AAEA,IAAM,IAAgB,IAET,IAAkB,OAC9B,GACA,GACA,GACA,MACI;AACJ,KAAI,EAAQ,OAAO;AAClB,EAAI,EAAQ,WACX,QAAQ,IAAI,iBAAiB,EAAQ,MAAM;EAG5C,IAAM,EAAE,aAAU,MAAM,OAAO,uBAE3B,IAAU,EAAM,EAAQ,MAAM;AAelC,EAbI,MACH,IAAU,QAAQ,KAAW,CAC5B,GAGA,IAAI,SAAS,GAAU,MAAW;AACjC,KAAkB,iBAAiB,eAAe;AACjD,MAAO,IAAI,aAAa,8CAA8C,aAAa,CAAC;KACnF;IACD,CACF,CAAC,GAGH,MAAM;;CAGP,IAAM,IAAM;EACX,QAAQ,EAAc,GAAS,GAAQ,EAAO;EAC9C,QAAQ,KAAA;EACR,YAAY,KAAA;EACZ,OAAO,KAAA;EACP;AAOD,KALA,OAAO,EAAI,QACX,OAAO,EAAI,YACX,OAAO,EAAI,OAGP,MAAM,QAAQ,EAAI,OAAO,IAAI,EAAQ,SAAS,KAAU,EAAO,OAAO;AACzE,EAAI,EAAQ,cACX,EAAI,SAAS,EAAI,OAAO,QAAQ,MAAe,EAAQ,YAAY,GAAY,EAAO,CAAC;EAGxF,IAAM,IAAS,EAAO,UAAU;AAOhC,EALI,EAAI,OAAO,SAAS,EAAO,QAAQ,MACtC,EAAI,aAAa,EAAO,QAAQ,GAChC,EAAI,QAAQ,EAAQ,QAGrB,EAAI,SAAS,EAAI,OAAO,MAAM,GAAQ,IAAS,EAAO,MAAM;;AAO7D,QAJI,EAAQ,WACX,QAAQ,IAAI,oBAAoB,EAAI,EAG9B;GAGK,KACZ,GACA,GACA,MACgD;CAChD,IAAI,IAA2B,EAAQ,QAAQ;AAG/C,KAFI,MAAS,OAAI,IAAO,KAAK,QAAQ,GAEjC,EAAQ,kBAAkB,SAG7B,QAFA,EAAM,KAAK,EAAK,EAET,EAAa,EAAQ,QAAQ,GAAG,GAAQ,EAAO;AAGvD,KAAI,MAAM,QAAQ,EAAQ,OAAO,EAAE;EAClC,IAAM,IAAU,EAAQ,OAAO,IAEzB,IAAS,EAAE,EAGX,IAAQ,EAAQ,SAAS,GAAQ,SAAS;AAEhD,OAAK,IAAI,IAAI,GAAG,IAAI,GAAO,IAC1B,GAAO,KAAK,EAAY,GAAS,GAAG,GAAM,GAAQ,EAAO,CAAC;AAG3D,SAAO;;AAGR,QAAO,EAAY,EAAQ,QAAQ,GAAG,GAAM,GAAQ,EAAO;GAG/C,KACZ,GACA,GACA,GACA,GACA,MAC8B;CAC9B,IAAM,IAAO,EAAE;AAEf,MAAK,IAAM,KAAO,GAAS;EAC1B,IAAM,IAAW,EAAQ;AAErB,OAAU,CAAC,EAAO,SAAS,EAAI,KAGnC,EAAM,KAAK,IAAO,EAAE,EAEpB,EAAK,KAAO,EAAa,GAAU,GAAG,GAAQ,EAAO;;AAGtD,QAAO;GAGK,KACZ,GACA,IAAY,GACZ,GACA,MAEO,EAAS,GAAG,GAAQ,EAAO"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
define([`require`,`exports`,`./forms-CbUt-6Ff.amd.js`,`../utils/string.amd.js`,`vue`,`../require/css.amd!../assets/notice.css`],function(e,t,n,r,i){"use strict";Object.defineProperty(t,`__esModule`,{value:!0}),t.show=t.default=void 0;var a=(0,i.reactive)(new Map),o=(e,t,n)=>`top-notice_`+(0,r.genIntHash)(e+t+JSON.stringify(n)),s=(e,t=`info`,r)=>{let i=``;e=String(e);let s=o(e,t,r);if(r?.title)i=r.title;else{let t=e.split(`
|
|
2
|
+
`);t.length&&(i=String(t.shift()),e=t.join(`
|
|
3
|
+
`))}let u=a.get(s);if(u){c(u);return}let d={id:s,title:i,text:e,style:t,buttonProps:r?.buttonProps,buttonsProps:r?.buttonsProps,metaText:r?.metaText,isSafeHTML:r?.isSafeHTML,selectToClose:r?.selectToClose,onClose:r?.onClose};if(a.set(d.id,d),a.size>5){let[e,t]=[...a].at(0)||[];t&&l(t)}n.O.state.isMobile&&$(`input`).one(`click`,()=>l(d))},c=e=>{e.hightlight=!0,setTimeout(()=>e.hightlight=!1,300)},l=e=>{e.forceClosed=!0,setTimeout(()=>{e.onClose?.(),a.delete(e.id)},300)},u=e=>{let t=`hacking was detected`;return e=e.replace(/<script/g,t),e=e.replace(/<img/g,t),e=e.replace(/<iframe/g,t),e=e.replace(/javascript:/g,t),e=e.replace(/<[^>]+ (@|on)\w+=[^>]+>?/g,t),e},d={class:`top-notice_itemTextWrapper`},f=[`innerHTML`],p=[`innerHTML`],m={key:1,class:`top-notice_itemButtons`},h=[`innerHTML`],g=[`title`],_=(0,i.defineComponent)({__name:`item`,props:{id:{},title:{},text:{},style:{},metaText:{},buttonProps:{},buttonsProps:{},isSafeHTML:{type:Boolean},hightlight:{type:Boolean},selectToClose:{type:Boolean,default:!0},forceClosed:{type:Boolean}},emits:[`close`],setup(e,{emit:t}){let a=e,o=t,s=(0,i.ref)(!1);setTimeout(()=>s.value=!0,10);let c=(0,i.ref)(!1),l=(0,i.ref)(`right`),_=(0,i.computed)(()=>{let e=a.title.replace(/ {2}/g,` `);return a.isSafeHTML||(e=u(e)),e}),v=(0,i.computed)(()=>{let e=(0,r.nl2br)(a.text);return e=e.replace(/ {2}/g,` `),a.isSafeHTML||(e=u(e)),e}),y=e=>{c.value=!0,e&&(l.value=e),setTimeout(()=>o(`close`),300)},b=e=>{if(!a.selectToClose)return;let{tagName:t}=e.target;t===`A`&&y(),t===`BUTTON`&&y()},x={mounted:e=>{if(!n.O.state.isMobile||!n.O.$||!n.O.$.ui.draggable)return;let t=`right`;n.O.$(e).draggable({revert:!1,axis:`x`,drag:(e,n)=>{t=n.position.left>0?`right`:`left`},stop:(e,n)=>{y(t)}})}};return(t,n)=>{let r=(0,i.resolveComponent)(`TopButton`);return(0,i.withDirectives)(((0,i.openBlock)(),(0,i.createElementBlock)(`div`,{class:(0,i.normalizeClass)([`top-notice_item`,{[`top-notice_item-`+e.style]:!0,"top-notice_item-hightlight":e.hightlight,"top-notice_item-showed":s.value,"top-notice_item-closed":c.value||e.forceClosed,[`top-notice_item-closed_`+l.value]:c.value}]),onClick:b},[(0,i.createElementVNode)(`div`,d,[_.value?((0,i.openBlock)(),(0,i.createElementBlock)(`div`,{key:0,class:`top-notice_itemTitle`,innerHTML:_.value},null,8,f)):(0,i.createCommentVNode)(``,!0),v.value?((0,i.openBlock)(),(0,i.createElementBlock)(`div`,{key:1,class:`top-notice_itemText`,innerHTML:v.value},null,8,p)):(0,i.createCommentVNode)(``,!0)]),e.buttonProps?((0,i.openBlock)(),(0,i.createBlock)(r,(0,i.mergeProps)({key:0,class:`top-notice_itemButton`,size:`s`},e.buttonProps,{title:e.buttonProps.title,innerHTML:e.buttonProps.default,onClick:n[0]||=e=>y()}),null,16,[`title`,`innerHTML`])):(0,i.createCommentVNode)(``,!0),e.buttonsProps?.length?((0,i.openBlock)(),(0,i.createElementBlock)(`div`,m,[((0,i.openBlock)(!0),(0,i.createElementBlock)(i.Fragment,null,(0,i.renderList)(e.buttonsProps,e=>((0,i.openBlock)(),(0,i.createBlock)(r,(0,i.mergeProps)({class:`top-notice_itemButton`,size:`s`},{ref_for:!0},e,{title:e.title,innerHTML:e.default,onClick:n[1]||=e=>y()}),null,16,[`title`,`innerHTML`]))),256))])):(0,i.createCommentVNode)(``,!0),e.metaText?((0,i.openBlock)(),(0,i.createElementBlock)(`div`,{key:2,class:`top-notice_itemMetaText`,innerHTML:e.metaText},null,8,h)):(0,i.createCommentVNode)(``,!0),(0,i.createElementVNode)(`div`,{class:`top-notice_itemClose`,"data-top-icon":``,title:t.$i18n.Common.Close,onClick:n[2]||=()=>y()},null,8,g)],2)),[[x]])}}}),v={class:`top-notice`},y=(0,i.defineComponent)({__name:`notice`,setup(e){let t=e=>{e.onClose?.(),a.delete(e.id)};return(e,n)=>((0,i.openBlock)(),(0,i.createBlock)(i.Teleport,{to:`body`},[(0,i.createElementVNode)(`div`,v,[((0,i.openBlock)(!0),(0,i.createElementBlock)(i.Fragment,null,(0,i.renderList)((0,i.unref)(a),([e,n])=>((0,i.openBlock)(),(0,i.createBlock)(_,{key:n.id,id:n.id,title:n.title,text:n.text,style:(0,i.normalizeStyle)(n.style),buttonProps:n.buttonProps,buttonsProps:n.buttonsProps,metaText:n.metaText,isSafeHTML:n.isSafeHTML,forceClosed:n.forceClosed,hightlight:n.hightlight,onClose:e=>t(n)},null,8,[`id`,`title`,`text`,`style`,`buttonProps`,`buttonsProps`,`metaText`,`isSafeHTML`,`forceClosed`,`hightlight`,`onClose`]))),128))])]))}});t.show=s,t.default=y});
|
|
4
|
+
//# sourceMappingURL=notice-CslVdVNm.amd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[".chunks/notice-CslVdVNm.esm.js","../../src/components/core/notice/utils.ts","../../src/components/core/notice/item/item.vue","../../src/components/core/notice/notice.vue"],"names":["exports","x","vue_1","S","string_js_1","n","r","C","t","a","e","o","w","s","T","forms_CbUt_6Ff_esm_js_1","E","D","O","k","A","j","M","N","i","u","p","h","y","P","F"],"mappings":"AAAA,OAAO,CAAC,UAAW,UAAW,0BAA2B,yBAAsB,MAAK,0CAAC,CAAE,SAAU,EAAS,EAAS,EAAyB,EAAa,EAAO,CAC5J,aACA,OAAO,eAAeA,EAAS,aAAc,CAAE,MAAO,GAAM,CAAC,CCOpD,EAAW,KAAA,EAAS,QAAwB,IAEnD,GAsBL,IAAIC,GAAQ,EAAAC,EAAA,UAAA,IAAA,IAAA,CAAAC,GAAA,EAAA,EAAA,IAAA,eAAA,EAAAC,EAAA,YAAA,EAAAC,EAAA,KAAA,UAAAC,EAAA,CAAA,CAAAC,GAAA,EAAA,EAAA,OAAA,IAAA,CAEL,IAAO,EAAK,GAEb,EAAe,OAAqBC,EAAA,CAE7B,IAAAC,EACZN,EAAAK,EAAgBH,EAAA,EAAA,CACV,GAAA,GAAA,MACc,EAAA,EAAM,UAEf,CDjCD,IAAIK,EAAIF,EAAE,MAAM;EAAK,CCuCJE,EAAA,SAAO,EAAA,OAAAA,EAAA,OAAA,CAAA,CAAA,EAAAA,EAAA,KAAA;EAAA,EAEZ,IAAAC,EAAAV,EAAA,IAAAQ,EAAA,CAEtB,GAAAE,EAAA,CDtCUC,EAAED,EAAE,CCyCI,OAElB,IAAAE,EAAA,CACA,GAAAJ,EACA,MAAA,EACA,KAAsBD,EACtB,MAAuBH,EACb,YAAS,GAAA,YACnB,aAAqB,GAAA,aACrB,SAAwB,GAAA,SACf,WAAS,GAAA,WAClB,cAAA,GAAA,cAEY,QAET,GAAS,QACL,CACQ,GAAgBJ,EAAA,IAAAY,EAAA,GAAAA,EAAA,CAAAZ,EAAA,KAAA,EAAA,CD1CrB,GAAI,CAAC,EAAG,GAAK,CAAC,GAAGA,EAAE,CAAC,GAAG,EAAE,EAAI,EAAE,CCkD3B,GAAAa,EAAA,EACd,CAKIC,EAEL,EAAA,MAAsB,UAAa,EAAA,QAA0B,CAAA,IAAA,YAAAD,EAAAD,EAAA,CAAA,EAGxDD,EAAS,GAAe,CACxB,EAAA,WAEL,CAAA,EAAA,eAAiB,EAAA,WAAA,CAAA,EAAA,IAAA,EACXE,EAAA,GAEL,CACqB,EAAA,YAAA,CAAA,EAAA,eAAA,CAMK,EAAiB,WAAA,CAAAb,EAAA,OAAA,EAAA,GAAA,EACvB,IAAA,EAQrBe,EANO,GAAK,CDlEL,IAAI,EAAI,uBACR,MAAO,GAAI,EAAE,QAAQ,WAAY,EAAE,CAAE,EAAI,EAAE,QAAQ,QAAS,EAAE,CAAE,EAAI,EAAE,QAAQ,WAAY,EAAE,CAAE,EAAI,EAAE,QAAQ,eAAgB,EAAE,CAAE,EAAI,EAAE,QAAQ,4BAA6B,EAAE,CAAE,GAChLC,EAAI,CAAE,MAAO,6BAA8B,CAAEC,EAAI,CAAC,YAAY,CAAEC,EAAI,CAAC,YAAY,CAAEC,EAAI,CACtF,IAAK,EACL,MAAO,yBACV,CAAEC,EAAI,CAAC,YAAY,CAAEC,EAAI,CAAC,QAAQ,CAAEC,GAAqB,EAAGrB,EAAM,iBAAiB,CAChF,OAAQ,OACR,MAAO,CACH,GAAI,EAAE,CACN,MAAO,EAAE,CACT,KAAM,EAAE,CACR,MAAO,EAAE,CACT,SAAU,EAAE,CACZ,YAAa,EAAE,CACf,aAAc,EAAE,CAChB,WAAY,CAAE,KAAM,QAAS,CAC7B,WAAY,CAAE,KAAM,QAAS,CAC7B,cAAe,CACX,KAAM,QACN,QAAS,CAAC,EACb,CACD,YAAa,CAAE,KAAM,QAAQ,CAChC,CExDH,MAIA,CAAA,QAGS,CACf,MAAA,EAAA,CAAiB,KAAOsB,GAAQ,CAGb,IAAMC,EACnBjB,EAA2DkB,EAAAF,EAAAG,GAE3D,EAAQzB,EAAA,KAAe,CAAA,EAAA,CAClB,eAAoB,EAAA,MAAS,CAAA,EAAA,GAAS,CAErC,IAAA0B,GAAA,EAAA1B,EAAY,KAAsB,CAAA,EAEtC,CAAAD,GAAA,EAAAC,EAAA,KAAA,QAAA,CAAAC,GAAA,EAAAD,EAAA,cAAA,CAGK,IAAe,EAAAuB,EAAA,MAAA,QAAA,QAAA,SAAA,CACL,OAAKA,EAAA,aAAA,EAAAT,EAAA,EAAA,EAAA,GAErB,CAAIT,GAAA,EAAQL,EAAA,cAEP,CAKG,IAA6C,GAAA,EAAAE,EAAA,OAAAqB,EAAA,KAAA,CAC5C,MAGd,GAAgB,EAAA,QAGjB,QAAA,SAAiB,CAAKA,EAAA,aAA6B,EAAAT,EAAA,EAAA,EAAA,GAGnC,CAAkBJ,EAAA,GAAA,CACvB,EAAA,MAAe,CAAA,EAAA,IAAA,EAAA,MAAA,GAAA,eAAAc,EAAA,QAAA,CAAA,IAAA,EAElBZ,EAAA,GAAc,CAED,GAAO,CACxBW,EAAA,cAIJ,OACiB,GAAA,CAAA,QAEN,GAAM,EAAK,OAEyB,IAAA,KAAAb,GAAA,CAAA,IAAA,UAAAA,GAAA,EAKnCW,EAAA,CAAU,QAAA,GAAA,CACZ,GAAA,CAAAR,EAAA,EAAA,MAAA,UAAA,CAAAA,EAAA,EAAA,GAAA,CAAAA,EAAA,EAAA,EAAA,GAAA,UACR,OACkB,IAAAV,EAAA,QAEQU,EAAqB,EAAA,EAAAP,EAAA,CAAA,UAAA,CFY1B,OAAQ,CAAC,EEPX,KAAA,IACF,MAAA,EAAA,IAAA,CFSQ,EAAIA,EAAE,SAAS,KAAO,EAAI,QAAU,QEL/D,MAAA,EAAA,IAAA,CFQ2BI,EAAEP,EAAE,EE4DzB,CAAA,EAjDC,CFPI,OAAQ,EAAG,IEQc,CFPrB,IAAImB,GAAK,EAAGtB,EAAM,kBEOkD,YAAA,CFNpE,OAAQ,EAAGA,EEMkG,kBAAA,EAAAA,EAAA,YAAA,EAAA,EAAAA,EAAA,oBAAA,MAAA,CFLzG,OAAQ,EEKsIA,EAAA,gBAAU,CAAA,kBAAA,EFJ/I,mBEI8MM,EAAA,OAAA,CAAA,EFH/M,6BAA8BA,EAAE,WEUlD,yBAAAmB,EAAA,MFRkB,yBAA0BC,EAAE,OAASpB,EAAE,aEYrD,0BAAyDP,EAAA,OAAA2B,EAAA,MFV9C,CAAC,CAAC,CEUA,QAAAd,EAA+B,CAAA,EFPrC,EAAGZ,EAAM,oBEQ3B,MAAiEe,EAAA,CAAAd,EAAA,QAAA,EAAAD,EAAA,YAAA,EAAA,EAAAA,EAAA,oBAAA,MAAA,CFPxC,IAAK,EEOP,MAAA,uBAA8B,UAAAC,EAAA,MFJ/B,CAAE,KAAM,EAAGe,EAAE,GAAK,EAAGhB,EAAM,oBAAoB,GAAI,CAAC,EAAE,CAAEK,EAAE,QAAU,EAAGL,EAAM,YAAY,EAAG,EAAGA,EAAM,oBAAoB,MAAO,CEerJ,IAAA,EFbwB,MAAO,sBEO1B,UAAAK,EAAA,MACD,CAAA,KAAA,EAAAY,EAAA,GAAA,EAAAjB,EAAA,oBAAA,GAAA,CAAA,EAAA,CAAA,CAAA,CACFM,EAAW,cAAA,EAAAN,EAAA,YAAA,EAAA,EAAAA,EAAA,aAAAsB,GAAA,EAAAtB,EAAA,YAAA,CACN,IAAY,EACZ,MAAY,wBACd,KAAE,IFLU,CAAEM,EAAE,YAAa,CESf,MAAAA,EAAA,YADrB,MAMQ,UAAAA,EAAA,YAAA,QACD,QAAA,EAAA,KAAA,GAAAI,GAAA,CFXY,CAAC,CEYf,KAAW,GAAA,CAAA,QAAA,YAAA,CAAA,GAAA,EAAAV,EAAA,oBAAA,GAAA,CAAA,EAAA,CACMM,EAAA,cAAA,SAAA,EAAAN,EAAA,YAAA,EAAA,EAAAA,EAAA,oBAAA,MAAAkB,EAAA,GAAA,EAAAlB,EAAA,WAAA,CAAA,EAAA,EAAA,EAAAA,EAAA,oBAAAA,EAAA,SAAA,MAAA,EAAAA,EAAA,YAAAM,EAAA,aAAA,KAAA,EAAAN,EAAA,YAAA,EAAA,EAAAA,EAAA,aAAAsB,GAAA,EAAAtB,EAAA,YAAA,CACA,MAAA,wBACd,KAAO,IFXQ,CAAE,CAAE,QAAS,CAAC,EAAG,CAAE,EAAG,CEegC,MAAA,EAAA,MFbnD,UAAW,EAAE,QEaZ,QAAA,EAAA,KAAA,GAAAU,GAAA,CAAkC,CAAA,CAAA,KAAA,GAAA,CAAA,QAAA,YAAA,CAAA,EAAA,CAAA,IAAA,EAAA,CAAA,GAAA,EAAAV,EAAA,oBAAA,GAAA,CAAA,EAAA,CFV3CM,EAAE,WAAa,EAAGN,EAAM,YAAY,EAAG,EAAGA,EAAM,oBAAoB,MAAO,CEiBtF,IAAA,EAJA,MAAA,0BACQ,UAAAM,EAAA,SACA,CAAA,KAAO,EAAAa,EAAA,GAAA,EAAAnB,EAAA,oBAAA,GAAA,CAAA,EAAA,EACf,EAAAA,EAAQ,oBAAK,MAAA,CFVE,MAAO,uBACP,gBAAiB,IACjB,MAAOQ,EAAE,MAAM,OAAO,MACtB,QAAS,EAAE,SAAaE,GAAE,CAC7B,CAAE,KAAM,EAAGU,EAAC,CAChB,CAAE,EAAE,EAAG,CAAC,CAACC,EAAE,CAAC,CAAC,GGpIxB,CAAA,CAAAM,EAAA,CAAA,MAEI,aAAe,CAAAC,GAAA,EAAA5B,EAAA,iBAAA,CHsIjB,OAAQ,SACR,MAAM,EAAG,CG9HF,IAAA,EAAA,GAAA,CACD,EAAA,WAAA,CAAAD,EAAA,OAAA,EAAA,GAAA,EAEE,OAAA,EAAA,MAAA,EAAAC,EAAA,YAAA,EAAA,EAAAA,EAAA,aAAAA,EAAA,SAAA,CAAA,GAAA,OAAA,CAAA,EAAA,EAAAA,EAAA,oBAAA,MAAA2B,EAAA,GAAA,EAAA3B,EAAA,WAAA,CAAA,EAAA,EAAA,EAAAA,EAAA,oBAAAA,EAAA,SAAA,MAAA,EAAAA,EAAA,aAAA,EAAAA,EAAA,OAAAD,EAAA,EAAA,CAAA,EAAA,OAAA,EAAAC,EAAA,YAAA,EAAA,EAAAA,EAAA,aAAAqB,EAAA,CACM,IAAA,EAAA,GACC,GAAA,EAAA,GACC,MAAA,EAAA,MACJ,KAAA,EAAA,KACE,OAAA,EAAArB,EAAA,gBAAA,EAAA,MAAA,CACC,YAAA,EAAA,YACD,aAAA,EAAA,aACM,SAAA,EAAA,SHgIJ,WAAY,EAAE,WACd,YAAa,EAAE,YACf,WAAY,EAAE,WACd,QAAU,GAAM,EAAE,EAAC,CACtB,CAAE,KAAM,EAAG,CACR,KACA,QACA,OACA,QACA,cACA,eACA,WACA,aACA,cACA,aACA,UACH,CAAC,EAAE,CAAE,IAAI,EAAE,CAAC,CAAC,CAAC,GAE9B,CAAC,CACF,EAAQ,KAAOK,EACf,EAAQ,QAAUuB,GACpB","sourcesContent":["define([\"require\", \"exports\", \"./forms-CbUt-6Ff.esm.js\", \"../utils/string.js\", \"vue\"], function (require, exports, forms_CbUt_6Ff_esm_js_1, string_js_1, vue_1) {\n \"use strict\";\n Object.defineProperty(exports, \"__esModule\", { value: true });\n exports.show = exports.default = void 0;\n var x = (0, vue_1.reactive)(/* @__PURE__ */ new Map()), S = (e, n, r) => \"top-notice_\" + (0, string_js_1.genIntHash)(e + n + JSON.stringify(r)), C = (t, n = \"info\", r) => {\n let i = \"\";\n t = String(t);\n let a = S(t, n, r);\n if (r?.title)\n i = r.title;\n else {\n let e = t.split(\"\\n\");\n e.length && (i = String(e.shift()), t = e.join(\"\\n\"));\n }\n let o = x.get(a);\n if (o) {\n w(o);\n return;\n }\n let s = {\n id: a,\n title: i,\n text: t,\n style: n,\n buttonProps: r?.buttonProps,\n buttonsProps: r?.buttonsProps,\n metaText: r?.metaText,\n isSafeHTML: r?.isSafeHTML,\n selectToClose: r?.selectToClose,\n onClose: r?.onClose\n };\n if (x.set(s.id, s), x.size > 5) {\n let [e, t] = [...x].at(0) || [];\n t && T(t);\n }\n forms_CbUt_6Ff_esm_js_1.O.state.isMobile && $(\"input\").one(\"click\", () => T(s));\n }, w = (e) => {\n e.hightlight = !0, setTimeout(() => e.hightlight = !1, 300);\n }, T = (e) => {\n e.forceClosed = !0, setTimeout(() => {\n e.onClose?.(), x.delete(e.id);\n }, 300);\n }, E = (e) => {\n let t = \"hacking was detected\";\n return e = e.replace(/<script/g, t), e = e.replace(/<img/g, t), e = e.replace(/<iframe/g, t), e = e.replace(/javascript:/g, t), e = e.replace(/<[^>]+ (@|on)\\w+=[^>]+>?/g, t), e;\n }, D = { class: \"top-notice_itemTextWrapper\" }, O = [\"innerHTML\"], k = [\"innerHTML\"], A = {\n key: 1,\n class: \"top-notice_itemButtons\"\n }, j = [\"innerHTML\"], M = [\"title\"], N = /* @__PURE__ */ (0, vue_1.defineComponent)({\n __name: \"item\",\n props: {\n id: {},\n title: {},\n text: {},\n style: {},\n metaText: {},\n buttonProps: {},\n buttonsProps: {},\n isSafeHTML: { type: Boolean },\n hightlight: { type: Boolean },\n selectToClose: {\n type: Boolean,\n default: !0\n },\n forceClosed: { type: Boolean }\n },\n emits: [\"close\"],\n setup(t, { emit: i }) {\n let u = t, p = i, h = (0, vue_1.ref)(!1);\n setTimeout(() => h.value = !0, 10);\n let y = (0, vue_1.ref)(!1), x = (0, vue_1.ref)(\"right\"), S = (0, vue_1.computed)(() => {\n let e = u.title.replace(/ {2}/g, \" \");\n return u.isSafeHTML || (e = E(e)), e;\n }), C = (0, vue_1.computed)(() => {\n let e = (0, string_js_1.nl2br)(u.text);\n return e = e.replace(/ {2}/g, \" \"), u.isSafeHTML || (e = E(e)), e;\n }), w = (e) => {\n y.value = !0, e && (x.value = e), setTimeout(() => p(\"close\"), 300);\n }, T = (e) => {\n if (!u.selectToClose)\n return;\n let { tagName: t } = e.target;\n t === \"A\" && w(), t === \"BUTTON\" && w();\n }, N = { mounted: (t) => {\n if (!forms_CbUt_6Ff_esm_js_1.O.state.isMobile || !forms_CbUt_6Ff_esm_js_1.O.$ || !forms_CbUt_6Ff_esm_js_1.O.$.ui.draggable)\n return;\n let n = \"right\";\n forms_CbUt_6Ff_esm_js_1.O.$(t).draggable({\n revert: !1,\n axis: \"x\",\n drag: (e, t) => {\n n = t.position.left > 0 ? \"right\" : \"left\";\n },\n stop: (e, t) => {\n w(n);\n }\n });\n } };\n return (e, n) => {\n let i = (0, vue_1.resolveComponent)(\"TopButton\");\n return (0, vue_1.withDirectives)(((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(\"div\", {\n class: (0, vue_1.normalizeClass)([\"top-notice_item\", {\n [\"top-notice_item-\" + t.style]: !0,\n \"top-notice_item-hightlight\": t.hightlight,\n \"top-notice_item-showed\": h.value,\n \"top-notice_item-closed\": y.value || t.forceClosed,\n [\"top-notice_item-closed_\" + x.value]: y.value\n }]),\n onClick: T\n }, [\n (0, vue_1.createElementVNode)(\"div\", D, [S.value ? ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(\"div\", {\n key: 0,\n class: \"top-notice_itemTitle\",\n innerHTML: S.value\n }, null, 8, O)) : (0, vue_1.createCommentVNode)(\"\", !0), C.value ? ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(\"div\", {\n key: 1,\n class: \"top-notice_itemText\",\n innerHTML: C.value\n }, null, 8, k)) : (0, vue_1.createCommentVNode)(\"\", !0)]),\n t.buttonProps ? ((0, vue_1.openBlock)(), (0, vue_1.createBlock)(i, (0, vue_1.mergeProps)({\n key: 0,\n class: \"top-notice_itemButton\",\n size: \"s\"\n }, t.buttonProps, {\n title: t.buttonProps.title,\n innerHTML: t.buttonProps.default,\n onClick: n[0] ||= (e) => w()\n }), null, 16, [\"title\", \"innerHTML\"])) : (0, vue_1.createCommentVNode)(\"\", !0),\n t.buttonsProps?.length ? ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(\"div\", A, [((0, vue_1.openBlock)(!0), (0, vue_1.createElementBlock)(vue_1.Fragment, null, (0, vue_1.renderList)(t.buttonsProps, (e) => ((0, vue_1.openBlock)(), (0, vue_1.createBlock)(i, (0, vue_1.mergeProps)({\n class: \"top-notice_itemButton\",\n size: \"s\"\n }, { ref_for: !0 }, e, {\n title: e.title,\n innerHTML: e.default,\n onClick: n[1] ||= (e) => w()\n }), null, 16, [\"title\", \"innerHTML\"]))), 256))])) : (0, vue_1.createCommentVNode)(\"\", !0),\n t.metaText ? ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(\"div\", {\n key: 2,\n class: \"top-notice_itemMetaText\",\n innerHTML: t.metaText\n }, null, 8, j)) : (0, vue_1.createCommentVNode)(\"\", !0),\n (0, vue_1.createElementVNode)(\"div\", {\n class: \"top-notice_itemClose\",\n \"data-top-icon\": \"\",\n title: e.$i18n.Common.Close,\n onClick: n[2] ||= () => w()\n }, null, 8, M)\n ], 2)), [[N]]);\n };\n }\n }), P = { class: \"top-notice\" }, F = /* @__PURE__ */ (0, vue_1.defineComponent)({\n __name: \"notice\",\n setup(e) {\n let t = (e) => {\n e.onClose?.(), x.delete(e.id);\n };\n return (e, n) => ((0, vue_1.openBlock)(), (0, vue_1.createBlock)(vue_1.Teleport, { to: \"body\" }, [(0, vue_1.createElementVNode)(\"div\", P, [((0, vue_1.openBlock)(!0), (0, vue_1.createElementBlock)(vue_1.Fragment, null, (0, vue_1.renderList)((0, vue_1.unref)(x), ([e, n]) => ((0, vue_1.openBlock)(), (0, vue_1.createBlock)(N, {\n key: n.id,\n id: n.id,\n title: n.title,\n text: n.text,\n style: (0, vue_1.normalizeStyle)(n.style),\n buttonProps: n.buttonProps,\n buttonsProps: n.buttonsProps,\n metaText: n.metaText,\n isSafeHTML: n.isSafeHTML,\n forceClosed: n.forceClosed,\n hightlight: n.hightlight,\n onClose: (e) => t(n)\n }, null, 8, [\n \"id\",\n \"title\",\n \"text\",\n \"style\",\n \"buttonProps\",\n \"buttonsProps\",\n \"metaText\",\n \"isSafeHTML\",\n \"forceClosed\",\n \"hightlight\",\n \"onClose\"\n ]))), 128))])]));\n }\n });\n exports.show = C;\n exports.default = F;\n});\n//# sourceMappingURL=notice-CslVdVNm.esm.js.map\n","import { reactive } from 'vue';\nimport type { Props as ItemProps, Props, Style } from '@/components/core/notice/item/types';\nimport Core from '@/core/core/core';\nimport { genIntHash } from '@/core/utils/string';\n\nexport const transitionDuration = 300;\n\nexport type Item = Props & { onClose?: Function };\n\nexport const itemById = reactive(new Map<string, Item>());\n\nconst genItemId = (text: ItemProps['text'], style: ItemProps['style'], options?: Options) => {\n\treturn 'top-notice_' + genIntHash(text + style + JSON.stringify(options));\n};\n\nexport type Options = {\n\ttitle?: ItemProps['title'],\n\tmetaText?: ItemProps['metaText'],\n\tbuttonProps?: ItemProps['buttonProps'],\n\tbuttonsProps?: ItemProps['buttonsProps'],\n\tisSafeHTML?: ItemProps['isSafeHTML'],\n\tselectToClose?: ItemProps['selectToClose'],\n\tonClose?: Function\n}\n\n/**\n * Показать сообщением в стиле push уведомления\n *\n * title будет получен из первой строки text\n *\n * Если в options указан title, он будет взят оттуда\n */\nexport const show = (text: string, style: Style = 'info', options?: Options) => {\n\tlet title = '';\n\n\ttext = String(text);\n\n\tconst id = genItemId(text, style, options);\n\n\tif (options?.title) {\n\t\ttitle = options.title;\n\t} else {\n\t\tconst chunks = text.split('\\n');\n\n\t\tif (chunks.length) {\n\t\t\ttitle = String(chunks.shift());\n\t\t\ttext = chunks.join('\\n');\n\t\t}\n\t}\n\n\tconst itemExists = itemById.get(id);\n\tif (itemExists) {\n\t\thightlight(itemExists);\n\n\t\treturn;\n\t}\n\n\tconst item: Item = {\n\t\tid,\n\t\ttitle,\n\t\ttext,\n\t\tstyle,\n\t\tbuttonProps: options?.buttonProps,\n\t\tbuttonsProps: options?.buttonsProps,\n\t\tmetaText: options?.metaText,\n\t\tisSafeHTML: options?.isSafeHTML,\n\t\tselectToClose: options?.selectToClose,\n\t\tonClose: options?.onClose,\n\t};\n\n\titemById.set(item.id, item);\n\n\tif (itemById.size > 5) {\n\t\tconst [_firstId, firstItem] = [...itemById].at(0) || [];\n\t\tif (firstItem) close(firstItem);\n\t}\n\n\t/**\n\t * Автозакрытие ошибок форм\n\t *\n\t * Добавляет\n\t */\n\tif (Core.state.isMobile) {\n\t\t$('input').one('click', () => close(item));\n\t}\n};\n\nconst hightlight = (item: Item) => {\n\titem.hightlight = true;\n\n\tsetTimeout(() => item.hightlight = false, transitionDuration);\n};\n\nconst close = (item: Item) => {\n\titem.forceClosed = true;\n\n\tsetTimeout(() => {\n\t\titem.onClose?.();\n\n\t\titemById.delete(item.id);\n\t}, transitionDuration);\n};\n\n/**\n * Убрать подозрительный html код\n */\nexport const prepareText = (text: string) => {\n\tconst textNoSafety = 'hacking was detected';\n\n\ttext = text.replace(/<script/g, textNoSafety);\n\ttext = text.replace(/<img/g, textNoSafety);\n\ttext = text.replace(/<iframe/g, textNoSafety);\n\ttext = text.replace(/javascript:/g, textNoSafety);\n\ttext = text.replace(/<[^>]+ (@|on)\\w+=[^>]+>?/g, textNoSafety);\n\n\treturn text;\n};\n","<script setup lang=\"ts\">\nimport { computed, ref, withDefaults } from 'vue';\n\nimport Core from '@/core/core/core';\nimport { nl2br } from '@/core/utils/string';\n\nimport type { Emits, Props } from './types';\nimport { prepareText, transitionDuration } from '@/components/core/notice/utils';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tselectToClose: true,\n});\n\nconst emit = defineEmits<Emits>();\n\n// анимация появления\nconst showed = ref(false);\nsetTimeout(() => showed.value = true, 10);\n\n// анимация закрытия\nconst closed = ref(false);\nconst closedDirection = ref<'top' | 'right' | 'bottom' | 'left'>('right');\n\nconst title = computed(() => {\n\tlet res = props.title.replace(/ {2}/g, ' ');\n\n\tif (!props.isSafeHTML) res = prepareText(res);\n\n\treturn res;\n});\n\nconst text = computed(() => {\n\tlet res = nl2br(props.text);\n\n\tres = res.replace(/ {2}/g, ' ');\n\n\tif (!props.isSafeHTML) res = prepareText(res);\n\n\treturn res;\n});\n\nconst close = (direction?: typeof closedDirection.value) => {\n\tclosed.value = true;\n\n\tif (direction) {\n\t\tclosedDirection.value = direction;\n\t}\n\n\tsetTimeout(() => emit('close'), transitionDuration);\n};\n\nconst onClick = (e: MouseEvent) => {\n\tif (!props.selectToClose) return;\n\n\tconst { tagName } = e.target as HTMLElement;\n\n\tif (tagName === 'A') close();\n\tif (tagName === 'BUTTON') close();\n};\n\nconst vSwipe = {\n\tmounted: (el: HTMLElement) => {\n\t\tif (!Core.state.isMobile) return;\n\n\t\tif (!Core.$ || !Core.$.ui['draggable']) return;\n\n\t\tlet direction: typeof closedDirection.value = 'right';\n\n\t\tlet axis = 'x';\n\t\t// if (getOS() === 'iOS') axis = 'y';\n\n\t\tCore.$(el).draggable({\n\t\t\trevert: false,\n\t\t\taxis,\n\t\t\tdrag: (_e, ui) => {\n\t\t\t\tif (axis == 'x') {\n\t\t\t\t\tdirection = ui.position.left > 0 ? 'right' : 'left';\n\t\t\t\t} else {\n\t\t\t\t\tdirection = ui.position.top > 0 ? 'bottom' : 'top';\n\t\t\t\t}\n\t\t\t},\n\t\t\tstop: (_e, _ui) => {\n\t\t\t\tclose(direction);\n\t\t\t},\n\t\t});\n\t},\n};\n\n// const vSwipe = {\n// \tmounted: (el: HTMLElement) => {\n// \t\tconst { distanceX, direction } = usePointerSwipe(el, {\n// \t\t\tdisableTextSelect: true,\n// \t\t\tonSwipe(e: PointerEvent) {\n// \t\t\t\tleft.value = -distanceX.value + 'px';\n// \t\t\t},\n// \t\t\tonSwipeEnd: (_e, direction) => {\n// \t\t\t\tclose(direction);\n// \t\t\t},\n// \t\t});\n// \t},\n// };\n</script>\n\n<template>\n\t<div\n\t\tclass=\"top-notice_item\"\n\t\t:class=\"{\n\t\t\t['top-notice_item-' + style]: true,\n\t\t\t'top-notice_item-hightlight': hightlight,\n\t\t\t'top-notice_item-showed': showed,\n\t\t\t'top-notice_item-closed': closed || forceClosed,\n\t\t\t['top-notice_item-closed_' + closedDirection]: closed,\n\t\t}\"\n\t\t@click=\"onClick\"\n\t\tv-swipe\n\t>\n\t\t<div class=\"top-notice_itemTextWrapper\">\n\t\t\t<div v-if=\"title\" class=\"top-notice_itemTitle\" v-html=\"title\"></div>\n\t\t\t<div v-if=\"text\" class=\"top-notice_itemText\" v-html=\"text\"></div>\n\t\t</div>\n\n\t\t<TopButton\n\t\t\tv-if=\"buttonProps\"\n\t\t\tclass=\"top-notice_itemButton\"\n\t\t\tsize=\"s\"\n\t\t\t:=\"buttonProps\"\n\t\t\t:title=\"buttonProps.title\"\n\t\t\tv-html=\"buttonProps.default\"\n\t\t\t@click=\"close()\"\n\t\t/>\n\n\t\t<div\n\t\t\tv-if=\"buttonsProps?.length\"\n\t\t\tclass=\"top-notice_itemButtons\"\n\t\t>\n\t\t\t<TopButton\n\t\t\t\tv-for=\"buttonProps in buttonsProps\"\n\t\t\t\tclass=\"top-notice_itemButton\"\n\t\t\t\tsize=\"s\"\n\t\t\t\t:=\"buttonProps\"\n\t\t\t\t:title=\"buttonProps.title\"\n\t\t\t\tv-html=\"buttonProps.default\"\n\t\t\t\t@click=\"close()\"\n\t\t\t/>\n\t\t</div>\n\n\t\t<div v-if=\"metaText\" class=\"top-notice_itemMetaText\" v-html=\"metaText\"></div>\n\n\t\t<div\n\t\t\tclass=\"top-notice_itemClose\"\n\t\t\tdata-top-icon=\"\"\n\t\t\t:title=\"$i18n.Common.Close\"\n\t\t\t@click=\"() => close()\"\n\t\t></div>\n\t</div>\n</template>\n\n<style>\n@import \"style.css\";\n</style>\n","<!-- performance all in one file component, для Core.notice() -->\n<script lang=\"ts\">\nexport { show } from './utils';\n</script>\n\n<script setup lang=\"ts\">\nimport type { Item } from './utils';\nimport { itemById } from './utils';\n\nimport type { Props } from './types';\nimport TopNoticeItem from './item/item.vue';\n\ndefineProps<Props>();\n\nconst onCloseItem = (item: Item) => {\n\titem.onClose?.();\n\n\titemById.delete(item.id);\n};\n</script>\n\n<template>\n\t<teleport to=\"body\">\n\t\t<div class=\"top-notice\">\n\t\t\t<TopNoticeItem\n\t\t\t\tv-for=\"[_index, item] in itemById\"\n\t\t\t\t:key=\"item.id\"\n\t\t\t\t:id=\"item.id\"\n\t\t\t\t:title=\"item.title\"\n\t\t\t\t:text=\"item.text\"\n\t\t\t\t:style=\"item.style\"\n\t\t\t\t:buttonProps=\"item.buttonProps\"\n\t\t\t\t:buttonsProps=\"item.buttonsProps\"\n\t\t\t\t:metaText=\"item.metaText\"\n\t\t\t\t:isSafeHTML=\"item.isSafeHTML\"\n\t\t\t\t:forceClosed=\"item.forceClosed\"\n\t\t\t\t:hightlight=\"item.hightlight\"\n\t\t\t\t@close=\"onCloseItem(item)\"\n\t\t\t/>\n\t\t</div>\n\t</teleport>\n</template>\n\n<style>\n:root {\n\t--top-notice-top: var(--top-padding-4);\n\t--top-notice-right: var(--top-padding-4);\n}\n\n.top-notice {\n\twidth: 400px;\n\tfont-size: 14px;\n\tposition: fixed; top: var(--top-notice-top); right: var(--top-notice-right);\n\tz-index: 1000010;\n\tdisplay: flex; flex-direction: column-reverse; gap: var(--top-gap-2);\n}\n\n.top-notice ul {\n\tpadding: 0 0 0 var(--top-padding-5);\n}\n\n@media only screen and (max-width: 600px) {\n\t:root {\n\t\t--top-notice-top: var(--top-padding-4);\n\t\t--top-notice-right: var(--top-padding-4);\n\t}\n\n\t.top-notice { width: auto; left: var(--top-notice-right); }\n}\n</style>\n"]}
|