@topvisor/ui 1.0.18 → 1.0.20-focus-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.
Files changed (232) hide show
  1. package/.chunks/{datepicker-EJRX31J1.es.js → datepicker-BbASdlXo.es.js} +2 -2
  2. package/.chunks/datepicker-BbASdlXo.es.js.map +1 -0
  3. package/.chunks/{datepicker-DKvr3NYw.amd.js → datepicker-CSpzAz1a.amd.js} +2 -2
  4. package/.chunks/datepicker-CSpzAz1a.amd.js.map +1 -0
  5. package/.chunks/forms-BciWy0wX.es.js +1992 -0
  6. package/.chunks/forms-BciWy0wX.es.js.map +1 -0
  7. package/.chunks/forms-Dh0QU6P9.amd.js +3 -0
  8. package/.chunks/forms-Dh0QU6P9.amd.js.map +1 -0
  9. package/.chunks/{listItem.vue_vue_type_script_setup_true_lang-3UaZvDrd.es.js → listItem.vue_vue_type_script_setup_true_lang-CZqS-tRD.es.js} +5 -5
  10. package/.chunks/listItem.vue_vue_type_script_setup_true_lang-CZqS-tRD.es.js.map +1 -0
  11. package/.chunks/{listItem.vue_vue_type_script_setup_true_lang-CnEbgJbu.amd.js → listItem.vue_vue_type_script_setup_true_lang-Del8bjSk.amd.js} +2 -2
  12. package/.chunks/listItem.vue_vue_type_script_setup_true_lang-Del8bjSk.amd.js.map +1 -0
  13. package/.chunks/{menu.vue_vue_type_style_index_0_lang-DcFQyQgs.amd.js → menu.vue_vue_type_style_index_0_lang-B8-UPDGJ.amd.js} +2 -2
  14. package/.chunks/menu.vue_vue_type_style_index_0_lang-B8-UPDGJ.amd.js.map +1 -0
  15. package/.chunks/{menu.vue_vue_type_style_index_0_lang-C4q81rOQ.es.js → menu.vue_vue_type_style_index_0_lang-yNOWbXpd.es.js} +6 -6
  16. package/.chunks/menu.vue_vue_type_style_index_0_lang-yNOWbXpd.es.js.map +1 -0
  17. package/.chunks/{notice-CYeec0mu.amd.js → notice-DEcP2RCJ.amd.js} +2 -2
  18. package/.chunks/notice-DEcP2RCJ.amd.js.map +1 -0
  19. package/.chunks/{notice-CtXmQ8xM.es.js → notice-DQSQs6yC.es.js} +3 -3
  20. package/.chunks/notice-DQSQs6yC.es.js.map +1 -0
  21. package/.chunks/{popup-38TbXxcV.amd.js → popup-BdJJx21M.amd.js} +2 -2
  22. package/.chunks/popup-BdJJx21M.amd.js.map +1 -0
  23. package/.chunks/{popup-BzCXSDdA.es.js → popup-D-6PIelY.es.js} +7 -7
  24. package/.chunks/popup-D-6PIelY.es.js.map +1 -0
  25. package/.chunks/punycode.es6-C2yitnNb.amd.js.map +1 -1
  26. package/.chunks/punycode.es6-CNI-zL6U.es.js.map +1 -1
  27. package/.chunks/store-CX_6ZXhO.es.js.map +1 -1
  28. package/.chunks/store-esTid5oI.amd.js.map +1 -1
  29. package/.chunks/{utils-DXI6F7F9.es.js → utils-9b7woobj.es.js} +3 -3
  30. package/.chunks/utils-9b7woobj.es.js.map +1 -0
  31. package/.chunks/utils-BvHwHAyQ.es.js +225 -0
  32. package/.chunks/utils-BvHwHAyQ.es.js.map +1 -0
  33. package/.chunks/{utils-CI9JyH64.amd.js → utils-CPty_L5T.amd.js} +2 -2
  34. package/.chunks/utils-CPty_L5T.amd.js.map +1 -0
  35. package/.chunks/utils-DAfofcEq.amd.js +2 -0
  36. package/.chunks/utils-DAfofcEq.amd.js.map +1 -0
  37. package/README.md +82 -82
  38. package/assets/charts.css +1 -1
  39. package/assets/core.css +1 -1
  40. package/assets/forms.css +1 -1
  41. package/assets/formsExt.css +1 -1
  42. package/assets/layout.css +1 -1
  43. package/assets/notice.css +1 -1
  44. package/charts/charts.amd.js +1 -1
  45. package/charts/charts.amd.js.map +1 -1
  46. package/charts/charts.js +8 -8
  47. package/charts/charts.js.map +1 -1
  48. package/components/charts/miniChart/miniChart.vue.d.ts +5 -5
  49. package/components/charts/miniCharts/miniCharts.vue.d.ts +9 -6
  50. package/components/core/notice/item/item.vue.d.ts +1 -1
  51. package/components/dialog/dialog/dialog.vue.d.ts +3 -2
  52. package/components/dialog/dialog/dialogs/dialogs.vue.d.ts +1 -1
  53. package/components/dialog/dialog/page/page.vue.d.ts +2 -1
  54. package/components/dialog/dialog/page/types.d.ts +7 -0
  55. package/components/forms/avatar/avatar.vue.d.ts +1 -1
  56. package/components/forms/button/button.vue.d.ts +2 -1
  57. package/components/forms/checkbox/checkbox.d.ts +5 -3
  58. package/components/forms/checkbox/checkbox.vue.d.ts +7 -6
  59. package/components/forms/controlLabel/controlLabel.vue.d.ts +3 -2
  60. package/components/forms/hint/hint.vue.d.ts +1 -1
  61. package/components/forms/input/input.vue.d.ts +2 -1
  62. package/components/forms/inputDate/inputDate.vue.d.ts +3 -1
  63. package/components/forms/inputRange/inputRange.vue.d.ts +3 -2
  64. package/components/forms/loadbar/loadbar.vue.d.ts +1 -1
  65. package/components/forms/radio/radio.d.ts +1 -1
  66. package/components/forms/radio/radio.vue.d.ts +5 -4
  67. package/components/forms/select/select.vue.d.ts +5 -5
  68. package/components/forms/switcher/switcher.vue.d.ts +3 -2
  69. package/components/formsExt/editArea/editArea.vue.d.ts +1 -1
  70. package/components/formsExt/editInput/editInput.vue.d.ts +1 -1
  71. package/components/formsExt/formsExt.d.ts +2 -0
  72. package/components/formsExt/info/info.vue.d.ts +20 -0
  73. package/components/formsExt/info/types.d.ts +21 -0
  74. package/components/formsExt/menu/menu.vue.d.ts +7 -5
  75. package/components/formsExt/radioGroup/radioGroup.vue.d.ts +7 -5
  76. package/components/formsExt/selector2/itemMulti.vue.d.ts +1 -1
  77. package/components/formsExt/selector2/selector2.vue.d.ts +98 -8
  78. package/components/layout/islandRows/islandRows.vue.d.ts +3 -2
  79. package/components/layout/islandRows/islandRowsRow/islandRowsRow.vue.d.ts +3 -2
  80. package/components/layout/islandRows/islandRowsSubTitle/islandRowsSubTitle.vue.d.ts +3 -2
  81. package/components/layout/rows/rows.vue.d.ts +3 -2
  82. package/components/popup/alert/alert.vue.d.ts +2 -1
  83. package/components/popup/confirm/confirm.vue.d.ts +2 -1
  84. package/components/popup/lib/popup.d.ts +2 -3
  85. package/components/popup/lib/worker.d.ts +7 -7
  86. package/components/popup/popup/listItem.vue.d.ts +2 -1
  87. package/components/popup/popup/opener.vue.d.ts +2 -1
  88. package/components/popup/popup/popup.vue.d.ts +2 -1
  89. package/components/popup/popup/widgetInput.vue.d.ts +4 -4
  90. package/components/popup/prompt/prompt.vue.d.ts +2 -1
  91. package/components/project/selectorCompetitors/selectorCompetitors.vue.d.ts +5 -5
  92. package/components/project/selectorRegion/selectorRegion.vue.d.ts +7 -7
  93. package/components/project/selectorRegion/utils/consts.d.ts +0 -2
  94. package/components/project/tagSelector/popupListItem/tagPopupListItem.vue.d.ts +5 -3
  95. package/components/project/tagSelector/popupOpener/popupOpener.vue.d.ts +6 -5
  96. package/components/project/tagSelector/tagIcon/tagIcon.vue.d.ts +1 -1
  97. package/components/project/tagSelector/tagSelector.vue.d.ts +6 -6
  98. package/components/tabs/tabs/content.vue.d.ts +3 -2
  99. package/components/tabs/tabs/tab.vue.d.ts +2 -1
  100. package/components/tabs/tabs/tabs.vue.d.ts +3 -2
  101. package/components/tabsView/tabsView/menu.vue.d.ts +9 -6
  102. package/components/tabsView/tabsView/menuDelimeter.vue.d.ts +1 -1
  103. package/components/tabsView/tabsView/menuItem.vue.d.ts +2 -1
  104. package/components/tabsView/tabsView/menuTitle.vue.d.ts +2 -1
  105. package/components/tabsView/tabsView/store.d.ts +5 -5
  106. package/components/tabsView/tabsView/tabsView.vue.d.ts +9 -6
  107. package/core/app.amd.js +1 -1
  108. package/core/app.amd.js.map +1 -1
  109. package/core/app.d.ts +2 -2
  110. package/core/app.js +149 -128
  111. package/core/app.js.map +1 -1
  112. package/core/core/core.d.ts +2 -0
  113. package/core/core/preloaders.d.ts +19 -0
  114. package/core/directives/focus.d.ts +3 -1
  115. package/core/directives/scrollIntoView.d.ts +3 -0
  116. package/core/directives/scrollShadow.d.ts +2 -2
  117. package/core/plugins/i18n.d.ts +13 -13
  118. package/core/utils/scroll.d.ts +18 -0
  119. package/core/utils/searchers.d.ts +0 -2
  120. package/dialog/dialog.amd.js +1 -1
  121. package/dialog/dialog.amd.js.map +1 -1
  122. package/dialog/dialog.js +60 -55
  123. package/dialog/dialog.js.map +1 -1
  124. package/forms/forms.amd.js +1 -1
  125. package/forms/forms.js +1 -1
  126. package/forms/helpers.amd.js.map +1 -1
  127. package/forms/helpers.js.map +1 -1
  128. package/formsExt/formsExt.amd.js +1 -1
  129. package/formsExt/formsExt.amd.js.map +1 -1
  130. package/formsExt/formsExt.js +344 -301
  131. package/formsExt/formsExt.js.map +1 -1
  132. package/icomoon/Read Me.txt +7 -7
  133. package/icomoon/Topvisor icons.json +6259 -6144
  134. package/icomoon/demo-files/demo.css +158 -158
  135. package/icomoon/demo-files/demo.js +30 -30
  136. package/icomoon/demo.html +3558 -3488
  137. package/icomoon/fonts/Topvisor-2.eot +0 -0
  138. package/icomoon/fonts/Topvisor-2.svg +276 -271
  139. package/icomoon/fonts/Topvisor-2.ttf +0 -0
  140. package/icomoon/fonts/Topvisor-2.woff +0 -0
  141. package/icomoon/selection.json +1 -1
  142. package/icomoon/style.css +780 -765
  143. package/jquery-ui.min.css +5 -5
  144. package/layout/layout.amd.js +1 -1
  145. package/layout/layout.amd.js.map +1 -1
  146. package/layout/layout.js +27 -26
  147. package/layout/layout.js.map +1 -1
  148. package/package.json +33 -33
  149. package/popup/popup.amd.js +1 -1
  150. package/popup/popup.amd.js.map +1 -1
  151. package/popup/popup.js +8 -8
  152. package/popup/popup.js.map +1 -1
  153. package/popup/worker.amd.js +1 -1
  154. package/popup/worker.amd.js.map +1 -1
  155. package/popup/worker.js +3 -3
  156. package/popup/worker.js.map +1 -1
  157. package/project/project.amd.js +1 -1
  158. package/project/project.amd.js.map +1 -1
  159. package/project/project.js +22 -24
  160. package/project/project.js.map +1 -1
  161. package/require/css.amd.js +12 -12
  162. package/tabs/tabs.amd.js.map +1 -1
  163. package/tabs/tabs.js +5 -5
  164. package/tabs/tabs.js.map +1 -1
  165. package/tabsView/tabsView.amd.js +1 -1
  166. package/tabsView/tabsView.amd.js.map +1 -1
  167. package/tabsView/tabsView.js +5 -5
  168. package/tabsView/tabsView.js.map +1 -1
  169. package/utils/check.amd.js.map +1 -1
  170. package/utils/check.js.map +1 -1
  171. package/utils/clipboard.amd.js +1 -1
  172. package/utils/clipboard.amd.js.map +1 -1
  173. package/utils/clipboard.js +1 -1
  174. package/utils/clipboard.js.map +1 -1
  175. package/utils/date.amd.js +1 -1
  176. package/utils/date.js +1 -1
  177. package/utils/device.amd.js +1 -1
  178. package/utils/device.js +1 -1
  179. package/utils/dom.amd.js.map +1 -1
  180. package/utils/dom.js.map +1 -1
  181. package/utils/image.amd.js.map +1 -1
  182. package/utils/image.js.map +1 -1
  183. package/utils/keyboard.amd.js.map +1 -1
  184. package/utils/keyboard.js.map +1 -1
  185. package/utils/lodash.amd.js +1 -1
  186. package/utils/lodash.js +5 -5
  187. package/utils/number.amd.js.map +1 -1
  188. package/utils/number.js.map +1 -1
  189. package/utils/price.amd.js +1 -1
  190. package/utils/price.amd.js.map +1 -1
  191. package/utils/price.js +3 -3
  192. package/utils/price.js.map +1 -1
  193. package/utils/route.amd.js.map +1 -1
  194. package/utils/route.js.map +1 -1
  195. package/utils/scroll.amd.js +1 -1
  196. package/utils/scroll.amd.js.map +1 -1
  197. package/utils/scroll.js +39 -7
  198. package/utils/scroll.js.map +1 -1
  199. package/utils/searchers.amd.js +1 -1
  200. package/utils/searchers.amd.js.map +1 -1
  201. package/utils/searchers.js +2 -2
  202. package/utils/searchers.js.map +1 -1
  203. package/utils/string.amd.js +1 -1
  204. package/utils/string.amd.js.map +1 -1
  205. package/utils/string.js +1 -1
  206. package/utils/string.js.map +1 -1
  207. package/utils/system.amd.js.map +1 -1
  208. package/utils/system.js.map +1 -1
  209. package/utils/url.amd.js.map +1 -1
  210. package/utils/url.js.map +1 -1
  211. package/web-types.json +130 -102
  212. package/.chunks/datepicker-DKvr3NYw.amd.js.map +0 -1
  213. package/.chunks/datepicker-EJRX31J1.es.js.map +0 -1
  214. package/.chunks/forms-CmlWMEyk.amd.js +0 -3
  215. package/.chunks/forms-CmlWMEyk.amd.js.map +0 -1
  216. package/.chunks/forms-DDIlFXbF.es.js +0 -1944
  217. package/.chunks/forms-DDIlFXbF.es.js.map +0 -1
  218. package/.chunks/listItem.vue_vue_type_script_setup_true_lang-3UaZvDrd.es.js.map +0 -1
  219. package/.chunks/listItem.vue_vue_type_script_setup_true_lang-CnEbgJbu.amd.js.map +0 -1
  220. package/.chunks/menu.vue_vue_type_style_index_0_lang-C4q81rOQ.es.js.map +0 -1
  221. package/.chunks/menu.vue_vue_type_style_index_0_lang-DcFQyQgs.amd.js.map +0 -1
  222. package/.chunks/notice-CYeec0mu.amd.js.map +0 -1
  223. package/.chunks/notice-CtXmQ8xM.es.js.map +0 -1
  224. package/.chunks/popup-38TbXxcV.amd.js.map +0 -1
  225. package/.chunks/popup-BzCXSDdA.es.js.map +0 -1
  226. package/.chunks/utils-CFCfvsI8.es.js +0 -223
  227. package/.chunks/utils-CFCfvsI8.es.js.map +0 -1
  228. package/.chunks/utils-CI9JyH64.amd.js.map +0 -1
  229. package/.chunks/utils-DXI6F7F9.es.js.map +0 -1
  230. package/.chunks/utils-lvXB5hbW.amd.js +0 -2
  231. package/.chunks/utils-lvXB5hbW.amd.js.map +0 -1
  232. package/components/formsExt/info/info.d.ts +0 -20
@@ -1 +1 @@
1
- {"version":3,"file":"project.amd.js","sources":["../../src/components/project/selectorCompetitors/selectorCompetitors.vue","../../src/components/project/selectorRegion/utils/consts.ts","../../src/components/project/selectorRegion/utils/utils.ts","../../src/components/project/selectorRegion/composables/selectSearcher.ts","../../src/components/project/selectorRegion/composables/selectRegion.ts","../../src/components/project/selectorRegion/composables/compare.ts","../../src/components/project/selectorRegion/composables/selectorRegion.ts","../../src/components/project/selectorRegion/selectorRegion.vue","../../src/components/project/tagSelector/tagsDefaults.ts","../../src/components/project/tagSelector/utils/utils.ts","../../src/components/project/tagSelector/popupListItem/tagPopupListItem.vue","../../src/components/project/tagSelector/popupOpener/popupOpener.vue","../../src/components/project/tagSelector/tagSelector.vue","../../src/components/project/selectorCompetitors/composables.ts","../../src/components/project/tagSelector/utils/el.ts","../../src/components/project/project.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { Props } from './selectorCompetitors';\nimport Core from '@/core/core/core';\nimport Button from '@/components/forms/button/button.vue';\nimport Popup from '@/components/popup/popup/popup.vue';\nimport ListItem from '@/components/popup/popup/listItem.vue';\nimport Menu from '@/components/formsExt/menu/menu.vue';\nimport { useI18n } from '@/core/plugins/i18n';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tshowSelectAllItem: true,\n});\nconst model = defineModel<Props['modelValue']>();\n\nconst selectAllItem = computed(() => {\n\tif (props.showSelectAllItem) {\n\t\treturn {\n\t\t\ticon: '',\n\t\t\ttitle: useI18n().Common.Select_all,\n\t\t\tvalue: 'all',\n\t\t\tcontent: '',\n\t\t};\n\t}\n});\n</script>\n\n<template>\n\t<div class=\"top-selectorCompetitors\">\n\t\t<Popup v-if=\"Core.state.isMobile\">\n\t\t\t<template #opener>\n\t\t\t\t<Button\n\t\t\t\t\tclass=\"top-selectorCompetitors_opener\"\n\t\t\t\t\tcolor=\"theme\"\n\t\t\t\t\ticon=\"\"\n\t\t\t\t\ticon2=\"\"\n\t\t\t\t>\n\t\t\t\t\t{{ items.find((item) => item.value === model?.[0])?.content }}\n\t\t\t\t</Button>\n\t\t\t</template>\n\n\t\t\t<template #contentList>\n\t\t\t\t<ListItem\n\t\t\t\t\tv-for=\"(item, index) in items\"\n\t\t\t\t\t:class=\"{\n\t\t\t\t\t\t'top-active': model?.includes(item.value)\n\t\t\t\t\t}\"\n\t\t\t\t\t:data-top-icon=\"item.icon\"\n\t\t\t\t\t:title=\"item.title\"\n\t\t\t\t\t@click=\"() => model = [item.value]\"\n\t\t\t\t>\n\t\t\t\t\t<span class=\"top-ellipsis1\">\n\t\t\t\t\t\t{{ item.content }}\n\t\t\t\t\t</span>\n\t\t\t\t</ListItem>\n\t\t\t</template>\n\t\t</Popup>\n\n\t\t<Menu\n\t\t\tv-else\n\t\t\tv-model=\"model\"\n\t\t\t:items=\"items\"\n\t\t\t:isMultiple=\"true\"\n\t\t\tstyling=\"bar\"\n\t\t\t:canBeEmptyMultiple=\"false\"\n\t\t\t:selectAllItem=\"selectAllItem\"\n\t\t/>\n\t</div>\n</template>\n\n<style>\n.top-selectorCompetitors_opener.top-button {\n\twidth: 100%;\n}\n</style>\n","import type { Region, SearcherIndexed } from '../selectorRegion';\nimport { useI18n } from '@/core/plugins/i18n';\n\nexport const dummyIndex = -2;\n\nexport const searchersNames = {\n\t0: 'Yandex',\n\t1: 'Google',\n\t2: 'go.Mail',\n\t4: 'YouTube',\n\t5: 'Bing',\n\t6: 'Yahoo',\n\t7: 'Seznam',\n\t8: 'AppStore',\n\t9: 'GoogleStore',\n\t20: 'Yandex.com',\n\t21: 'Yandex.com.tr',\n};\n\nexport const regionUndefined: Region = {\n\tkey: dummyIndex,\n\tname: '--',\n\tindex: dummyIndex,\n};\n\nexport const searcherUndefined: SearcherIndexed = {\n\tkey: dummyIndex,\n\tname: '--',\n\tregions: [regionUndefined],\n\tregionByIndex: new Map([[dummyIndex, regionUndefined]]),\n};\n\nconst regionAuto: Region = {\n\tkey: dummyIndex,\n\tname: 'Autoselect',\n\tindex: dummyIndex,\n};\n\nconst searcherAuto: SearcherIndexed = {\n\tkey: dummyIndex,\n\tname: 'Autoselect',\n\tregions: [regionAuto],\n\tregionByIndex: new Map([[dummyIndex, regionAuto]]),\n};\n\nconst regionGlobal: Region = {\n\tcountryCode: '00',\n\tdepth: 1,\n\tdevice: 0,\n\tkey: -1,\n\tindex: -1,\n\tlang: 'ru',\n\tname: 'Without region',\n};\n\nexport const getRegionAuto = () => {\n\tregionAuto.name = useI18n().Common.Autoselect!;\n\n\treturn regionAuto;\n};\n\nexport const getSearcherAuto = () => {\n\tgetRegionAuto();\n\n\tsearcherAuto.name = useI18n().Common.Autoselect!;\n\tconsole.log(searcherAuto);\n\n\treturn searcherAuto;\n};\n\nexport const getRegionGlobal = () => {\n\tregionGlobal.name = useI18n().Keywords.Without_region!;\n\n\treturn regionGlobal;\n};\n","import type { Region, Searcher, SearcherByKey, SearcherIndexed } from '../selectorRegion';\nimport { dummyIndex, getRegionGlobal, getSearcherAuto, regionUndefined, searchersNames, searcherUndefined } from './consts';\n\n/**\n * Генерация Map ПС с Map регионов из массива searchers\n * - ключ для ПС - searcherKey\n * - ключ для региона - regionIndex\n *\n * Если поисковиков в списке нет, в список будет добавлен searcherUndefined\n *\n * Если регионов в списке нет, в список будет добавлен regionUndefined\n *\n * @param forFrequency - получить массив для просмотра частоты (или ставок)\n * @param autoRegion - добавить элемент с ключем -2, который в API заменяется на нужный ключ в зависимости от контекста\n * @param searchers - поисковики с регионами проекта, см.: get/projects_2/projects, show_searchers_and_regions = 1\n */\nexport const genSearcherByKey = (\n\tforFrequency: boolean = false,\n\tautoRegion: boolean = false,\n\tsearchers: Searcher[] = [],\n) => {\n\tlet searcherByKey: SearcherByKey;\n\n\tif (forFrequency) {\n\t\tsearcherByKey = genSearchersMapVolume(searchers);\n\t} else {\n\t\tsearcherByKey = genSearchersMapCommon(searchers);\n\t}\n\n\tif (autoRegion) searcherByKey.set(dummyIndex, getSearcherAuto());\n\tif (!searcherByKey.size) searcherByKey.set(dummyIndex, searcherUndefined);\n\n\treturn searcherByKey;\n};\n\n/**\n * Список ПС с регионами\n *\n * @param searchers\n * @param onlyEnabledRegions\n * @param forceSearchersKeys - ключи ПС, которые нееобходимо вывести в любом случае\n * @param forFrequency - для частоты будут выводиться только Яндекс, Google и Mail\n */\nconst genSearchersMapCommon = (\n\tsearchers: Searcher[],\n\tonlyEnabledRegions: boolean = true,\n\tforceSearchersKeys: Searcher['key'][] = [],\n\tforFrequency: boolean = false,\n) => {\n\tconst searcherByKey: Map<Searcher['key'], SearcherIndexed> = new Map();\n\n\t// настроенные ПС\n\tsearchers.forEach((searcher) => {\n\t\tif (!searcher.enabled) return;\n\t\tif (forFrequency && typeof searcher.key === 'number' && searcher.key > 1) return;\n\n\t\tconst searcherI = { ...searcher } as SearcherIndexed;\n\t\tsearcherI.regionByIndex = new Map();\n\n\t\tif (searcher.regions) {\n\t\t\tsearcher.regions.forEach((region: Region) => {\n\t\t\t\tif (onlyEnabledRegions && !region.enabled) return;\n\n\t\t\t\tconst regionI = { ...region };\n\t\t\t\tif (searcherI.regionByIndex) searcherI.regionByIndex.set(regionI.index, regionI);\n\t\t\t});\n\t\t}\n\n\t\tif (!searcherI.regionByIndex.size && !forceSearchersKeys.length) {\n\t\t\tsearcherI.regionByIndex.set(regionUndefined.index, regionUndefined);\n\t\t}\n\n\t\tif (typeof searcherI.key === 'number') searcherByKey.set(searcherI.key, searcherI);\n\t});\n\n\t// дополнительные ПС\n\tforceSearchersKeys.forEach((searcherKey) => {\n\t\tif (searcherByKey.has(searcherKey)) return;\n\n\t\tconst searcherI: SearcherIndexed = {\n\t\t\tkey: searcherKey,\n\t\t\tname: searchersNames[searcherKey],\n\t\t\tregions: [],\n\t\t\tregionByIndex: new Map(),\n\t\t};\n\n\t\tsearcherByKey.set(searcherI.key, searcherI);\n\t});\n\n\treturn searcherByKey;\n};\n\n/**\n * Список ПС с регионами для проверки частоты (Яндекс, Google, Mail если добавлен в проект)\n *\n * @param searchers\n */\nconst genSearchersMapVolume = (searchers: Searcher[]) => {\n\tconst serarcherByKey = genSearchersMapCommon(searchers, false, [0, 1], true);\n\n\t// в Mail нет регионов\n\tif (serarcherByKey.has(2)) {\n\t\tconst searcherMail = serarcherByKey.get(2);\n\t\tif (searcherMail) searcherMail.regionByIndex = new Map();\n\t}\n\n\t// добавление глобального региона\n\tserarcherByKey.forEach((searcher) => {\n\t\tif (!searcher.regionByIndex) return;\n\n\t\tconst region = { ...getRegionGlobal() };\n\t\tsearcher.regionByIndex.set(region.index, region);\n\t});\n\n\treturn serarcherByKey;\n};\n\n/**\n * Поиск региона по заданному критерию из списка поисковиков проекта\n *\n * @param forFrequency - поиск региона для просмотра частоты или ставок\n * @param searchRegion - объект с параметрами региона, который следует найти\n * @param searchers\n */\nexport const findRegion = (forFrequency: boolean, searchRegion: Partial<Region>, searchers: Searcher[] = []) => {\n\tconst searcherByKey = genSearcherByKey(forFrequency, false, searchers);\n\n\tlet findedRegion: Region | undefined;\n\n\t// поиск ПС\n\tsearcherByKey.forEach((searcher) => {\n\t\tif (searchRegion.searcher_key !== undefined && searchRegion.searcher_key != searcher.key) return;\n\t\tif (!searcher.regions) return;\n\n\t\t// поиск региона\n\t\tsearcher.regions.forEach((region) => {\n\t\t\tif (findedRegion) return;\n\n\t\t\tif (searchRegion.key !== undefined && searchRegion.key != region.key) return;\n\t\t\tif (searchRegion.index !== undefined && searchRegion.index != region.index) return;\n\n\t\t\tif (!forFrequency) {\n\t\t\t\tif (searchRegion.lang !== undefined && searchRegion.lang != region.lang) return;\n\t\t\t\tif (searchRegion.device !== undefined && searchRegion.device != region.device) return;\n\t\t\t}\n\n\t\t\tregion.searcher_key = searcher.key;\n\t\t\tfindedRegion = region;\n\n\t\t\treturn false;\n\t\t});\n\n\t\tif (findedRegion) return false;\n\t});\n\n\treturn findedRegion;\n};\n","import { computed, type ComputedRef, ref } from 'vue';\nimport { useI18n } from '@/core/plugins/i18n';\nimport type { Props, SearcherByKey } from '../selectorRegion';\nimport type { Option, Options } from '@/components/forms/select/select';\nimport { dummyIndex } from '../utils/consts';\nimport { getSearcherGIcon } from '@/core/utils/searchers';\n\n/**\n * Создание и управление реактивными переменными для выбора ПС\n *\n * @param props - входные props компонента\n * @param mapSearchers - Map ПС (реактивная)\n */\nexport const useSelectSearcher = (\n\tprops: Props,\n\tmapSearchers: ComputedRef<SearcherByKey>,\n) => {\n\tconst i18n = useI18n();\n\n\t/**\n\t * Ключ выбранной поисковой системы\n\t */\n\tconst searcherKey = ref(mapSearchers.value.keys().next().value ?? dummyIndex);\n\n\t/**\n\t * Коллекция опций для выбора ПС\n\t */\n\tconst optionBySearcherKey = computed(() => {\n\t\tconst res: Options = new Map();\n\t\tmapSearchers.value.forEach((searcher) => {\n\t\t\tlet option: Option = {\n\t\t\t\tvalue: searcher.key,\n\t\t\t\ttitle: searcher.name,\n\t\t\t};\n\n\t\t\tif (props.addSearcherIcon) option.icon = getSearcherGIcon(searcher.key);\n\n\t\t\tres.set(searcher.key, option);\n\t\t});\n\n\t\t// добавить режим сравнения, если есть хотя бы одна ПС\n\t\tif (props.addCompare && !res.has(dummyIndex)) {\n\t\t\tconst dummyOption: Option = {\n\t\t\t\tvalue: '',\n\t\t\t\ttitle: '--------------------',\n\t\t\t\tdisabled: true,\n\t\t\t};\n\t\t\tres.set(dummyOption.value, dummyOption);\n\n\t\t\tconst compareOption: Option = {\n\t\t\t\tvalue: -1,\n\t\t\t\ttitle: i18n.Common.Compare!,\n\t\t\t};\n\t\t\tres.set(compareOption.value, compareOption);\n\t\t}\n\n\t\treturn res;\n\t});\n\n\treturn {\n\t\tsearcherKey,\n\t\toptionBySearcherKey,\n\t};\n};\n","import { computed, type ComputedRef, ref, watch } from 'vue';\nimport { useI18n } from '@/core/plugins/i18n';\nimport { getDeviceGIcon, getLangLabel } from '@/core/utils/searchers';\nimport type { Option } from '@/components/forms/select/select';\nimport { dummyIndex } from '../utils/consts';\nimport type { Props, Region, SearcherIndexed } from '../selectorRegion';\n\n/**\n * Создание и управление реактивными переменными для выбора региона\n *\n * @param props - входные props компонента\n * @param activeSearcherIndexed - объект активной поисковой системы (реактивная)\n * @param regionsIndexes - входные индексы регионов/ПС\n */\nexport const useSelectRegion = (props: Props, activeSearcherIndexed: ComputedRef<SearcherIndexed>) => {\n\tconst i18n = useI18n();\n\n\t/**\n\t * Индекс выбранного региона\n\t */\n\tconst regionIndex = ref(dummyIndex);\n\n\tif (props.modelValue.length === 1) {\n\t\tregionIndex.value = props.modelValue[0];\n\t}\n\n\tif (regionIndex.value === dummyIndex) {\n\t\tif (props.forFrequency) {\n\t\t\t// в качетсве ключа используется region.key, а не region.index\n\t\t\tregionIndex.value = activeSearcherIndexed.value?.regionByIndex.values().next().value?.key ?? dummyIndex;\n\t\t} else {\n\t\t\tregionIndex.value = activeSearcherIndexed.value?.regionByIndex.keys().next().value ?? dummyIndex;\n\t\t}\n\t}\n\n\t/**\n\t * Коллекция опций для выбора региона\n\t */\n\tconst optionByRegionIndex = computed(() => {\n\t\tconst options = new Map<number, Option>();\n\n\t\tactiveSearcherIndexed.value.regionByIndex?.forEach((region) => {\n\t\t\tlet regionLabel = region.name;\n\n\t\t\t// на частоту в текущей версии устройство и язык не влияют\n\t\t\t// обратите внимание, в качетсве ключа используется region.key, а не region.index\n\t\t\tif (props.forFrequency) {\n\t\t\t\tconst option: Option = {\n\t\t\t\t\tvalue: region.key,\n\t\t\t\t\ttitle: regionLabel,\n\t\t\t\t};\n\t\t\t\tif (!options.has(region.key)) options.set(region.key, option);\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (region.device) {\n\t\t\t\tregionLabel += ' (' + i18n.Common['Device_' + region.device] + ')';\n\t\t\t}\n\n\t\t\tconst langLabel = getLangLabel(activeSearcherIndexed.value.key || 0, region.lang ?? '');\n\t\t\tif (langLabel) regionLabel += ' / ' + langLabel;\n\n\t\t\tconst option: Option = {\n\t\t\t\tvalue: region.index,\n\t\t\t\ttitle: regionLabel,\n\t\t\t\ticon: region.device ? getDeviceGIcon(region.device) : undefined,\n\t\t\t};\n\n\t\t\toptions.set(region.index, option);\n\t\t});\n\n\t\treturn options;\n\t});\n\n\t/**\n\t * Выбор максимально похожего региона в новой коллекции регионов\n\t */\n\twatch(optionByRegionIndex, (optionByRegionIndex, oldOptionByRegionIndex) => {\n\t\tif (props.onlySearcher || regionIndex.value !== undefined && optionByRegionIndex.get(regionIndex.value)) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet newRegionIndex = optionByRegionIndex.keys().next().value as Region['index'];\n\t\tif (regionIndex.value === dummyIndex || newRegionIndex === dummyIndex) {\n\t\t\tregionIndex.value = newRegionIndex;\n\n\t\t\treturn;\n\t\t}\n\n\t\tlet regionName = (oldOptionByRegionIndex?.get(regionIndex.value) as Option)?.title || '';\n\t\tlet regionMatchLevel = -1;\n\t\tfor (const [index, option] of optionByRegionIndex.entries()) {\n\t\t\tconst title = (option as Option).title;\n\n\t\t\tif (typeof title !== 'string' || typeof index === 'string') {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// полное совпадение\n\t\t\tif (title === regionName) {\n\t\t\t\tnewRegionIndex = index;\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst regexpDevice = new RegExp(` \\\\((${i18n.Common['Device_1']}|${i18n.Common['Device_2']})\\\\)`);\n\t\t\tlet regionNameCompare = regionName;\n\t\t\tlet regionMatchLevelI = 3;\n\n\t\t\t// без устройства\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\n\t\t\t\tregionNameCompare = regionName.replace(/^[^a-zа-я]/i, '').replace(regexpDevice, '');\n\n\t\t\t\tregionMatchLevelI--;\n\t\t\t}\n\n\t\t\t// без языка\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\n\t\t\t\tregionNameCompare = regionName.replace(/ \\/.*/, '');\n\n\t\t\t\tregionMatchLevelI--;\n\t\t\t}\n\n\t\t\t// без устройства и без языка\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\n\t\t\t\tregionNameCompare = regionName.replace(/ \\/.*/, '');\n\t\t\t\tregionNameCompare = regionNameCompare.replace(/^[^a-zа-я]/i, '').replace(regexpDevice, '');\n\n\t\t\t\tregionMatchLevelI--;\n\t\t\t}\n\n\t\t\tif (title.indexOf(regionNameCompare) === -1) continue;\n\t\t\tif (regionMatchLevelI <= regionMatchLevel) continue;\n\n\t\t\tregionMatchLevel = regionMatchLevelI;\n\t\t\tnewRegionIndex = index;\n\t\t}\n\n\t\tregionIndex.value = newRegionIndex;\n\t});\n\n\treturn {\n\t\tregionIndex,\n\t\toptionByRegionIndex,\n\t};\n};\n","import { type ComputedRef, ref, watch } from 'vue';\nimport type { Props, SearcherByKey } from '../selectorRegion';\n\n/**\n * Создание и управление реактивными переменными для сравнения\n *\n * @param props - входные props компонента\n * @param searcherByKey - Map ПС (реактивная)\n * @param allRegionsIndexes - Все доступные индексы регионов (реактивная)\n */\nexport const useCompare = (props: Props, searcherByKey: ComputedRef<SearcherByKey>, allRegionsIndexes: ComputedRef<Set<number>>) => {\n\t/**\n\t * Индексы регионов/ПС в сравнение\n\t */\n\tconst regionsIndexes = ref([] as number[]);\n\n\t/**\n\t * Загрузка индексов регионов для сравнения\n\t *\n\t * Если в modelValue передано несколько регионов, они будут установлены как выбранные для сравнения\n\t */\n\tconst compareLoad = () => {\n\t\tif (props.onlySearcher && searcherByKey.value) {\n\t\t\tregionsIndexes.value = Array.from(searcherByKey.value.keys());\n\n\t\t\treturn;\n\t\t}\n\n\t\tlet regionsIndexesSaved: Props['modelValue'] = [];\n\n\t\tif (props.modelValue.length > 1) {\n\t\t\tregionsIndexesSaved = [...props.modelValue];\n\t\t} else {\n\t\t\ttry {\n\t\t\t\t// загрузить индексы регионов, если они были сохранены\n\t\t\t\tregionsIndexesSaved = JSON.parse(\n\t\t\t\t\tlocalStorage.getItem('ui:project:regionSelector' + props.projectId + ':regionsIndexes') as string,\n\t\t\t\t) ?? [];\n\t\t\t} catch (e) {\n\n\t\t\t}\n\t\t}\n\n\t\t// убрать из сравнения регионы, которых нет в props.searchers\n\t\tif (regionsIndexesSaved.length) {\n\t\t\tregionsIndexesSaved = regionsIndexesSaved.filter((regionIndex) => {\n\t\t\t\treturn allRegionsIndexes.value.has(regionIndex);\n\t\t\t});\n\t\t}\n\n\t\t// если не сохранено ни одного региона, выбрать все регионы проекта\n\t\tif (!regionsIndexesSaved.length) {\n\t\t\tregionsIndexesSaved = Array.from(allRegionsIndexes.value);\n\t\t}\n\n\t\tregionsIndexes.value = [...regionsIndexesSaved];\n\t};\n\n\t/**\n\t * Сохранение выбранных регионов\n\t */\n\tconst compareSave = () => {\n\t\tif (regionsIndexes.value.length) {\n\t\t\tlocalStorage.setItem('ui:project:regionSelector:' + props.projectId + ':regionsIndexes', JSON.stringify(regionsIndexes.value));\n\t\t} else {\n\t\t\tlocalStorage.removeItem('ui:project:regionSelector:' + props.projectId + ':regionsIndexes');\n\t\t}\n\t};\n\n\twatch(regionsIndexes, () => {\n\t\tcompareSave();\n\t});\n\n\tif (props.addCompare) {\n\t\t// if (props.compareRegionsIndexes?.length) {\n\t\t// \tcompareRegionsIndexes.value = [...props.compareRegionsIndexes];\n\t\t// } else {\n\t\t// \tcompareLoad();\n\t\t// }\n\n\t\tcompareLoad();\n\t}\n\n\treturn {\n\t\tregionsIndexes,\n\t};\n};\n","import { computed, watch } from 'vue';\nimport { findRegion, genSearcherByKey } from '../utils/utils';\nimport { dummyIndex, searcherUndefined } from '../utils/consts';\nimport type { Props, Region, SearcherIndexed } from '../selectorRegion';\nimport { useSelectSearcher } from './selectSearcher';\nimport { useSelectRegion } from './selectRegion';\nimport { useCompare } from './compare';\n\n/**\n * Создание и управления рективными переменными компонента\n *\n * @param props - входные props компонента\n */\nexport const useSelectorRegion = (props: Props) => {\n\tconst searcherByKey = computed(() => {\n\t\treturn genSearcherByKey(props.forFrequency, props.autoRegion, props.searchers);\n\t});\n\n\tconst activeSearcherIndexed = computed(() => {\n\t\treturn searcherByKey.value.get(selectSearcher.searcherKey.value) || searcherUndefined;\n\t});\n\n\t/**\n\t * Все индексы регионов из mapSearchers\n\t */\n\tconst allRegionsIndexes = computed(() => {\n\t\tconst regionsIndexes = new Set<number>();\n\n\t\tsearcherByKey.value.forEach((searcher) => {\n\t\t\tsearcher.regions?.forEach((region) => {\n\t\t\t\tif (region.index === -1) return;\n\t\t\t\tif (region.index === dummyIndex) return;\n\n\t\t\t\tregionsIndexes.add(region.index);\n\t\t\t});\n\t\t});\n\n\t\treturn regionsIndexes;\n\t});\n\n\tconst selectSearcher = useSelectSearcher(props, searcherByKey);\n\tconst selectRegion = useSelectRegion(props, activeSearcherIndexed);\n\tconst compare = useCompare(props, searcherByKey, allRegionsIndexes);\n\n\t// контроль за внешним изменением списка ПС\n\twatch(searcherByKey, () => {\n\t\t// возможные значения для сравнения регионов/пс\n\t\tif (props.onlySearcher) {\n\t\t\tcompare.regionsIndexes.value = Array.from(searcherByKey.value.keys());\n\t\t} else {\n\t\t\tcompare.regionsIndexes.value = compare.regionsIndexes.value.filter(regionIndex => {\n\t\t\t\treturn allRegionsIndexes.value.has(regionIndex);\n\t\t\t});\n\t\t}\n\n\t\tif (selectSearcher.searcherKey.value === -1) return;\n\n\t\tlet newSearcherKey = searcherByKey.value.keys().next().value;\n\n\t\tsearcherByKey.value.forEach((searcher) => {\n\t\t\t// определить выбранную ПС\n\t\t\tif (props.onlySearcher && searcher.key === selectSearcher.searcherKey.value) {\n\t\t\t\tnewSearcherKey = selectSearcher.searcherKey.value;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tselectRegion.regionIndex.value &&\n\t\t\t\tsearcher.regionByIndex?.has(selectRegion.regionIndex.value)\n\t\t\t) {\n\t\t\t\tnewSearcherKey = searcher.key;\n\t\t\t}\n\n\t\t\t// выбрать первую ПС с выбранным регионом\n\t\t\tif (!props.onlySearcher) {\n\t\t\t\tlet regionsNewSearcher: SearcherIndexed['regionByIndex'] | undefined;\n\n\t\t\t\tif (newSearcherKey !== undefined) {\n\t\t\t\t\tregionsNewSearcher = searcherByKey.value.get(newSearcherKey)?.regionByIndex;\n\t\t\t\t}\n\n\t\t\t\tconst regionsCurrentSearcher = searcherByKey.value.get(searcher.key)?.regionByIndex;\n\t\t\t\tif (\n\t\t\t\t\tregionsNewSearcher?.has(dummyIndex) &&\n\t\t\t\t\t!regionsCurrentSearcher?.has(dummyIndex)\n\t\t\t\t) {\n\t\t\t\t\tnewSearcherKey = searcher.key;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// if (props.addCompare && !selectSearcher.optionBySearcherKey.value.has(dummyIndex)) {\n\t\t// \tif (!selectRegion.regionIndex.value && compare.regionsIndexes.value?.length) newSearcherKey = -1;\n\t\t// }\n\n\t\t// if (props.onlySearcher && selectRegion.regionIndex.value !== dummyIndex) newSearcherKey = selectRegion.regionIndex.value;\n\n\t\tif (newSearcherKey !== undefined) {\n\t\t\tselectSearcher.searcherKey.value = newSearcherKey;\n\t\t}\n\n\t\tif (\n\t\t\tselectRegion.regionIndex.value !== undefined &&\n\t\t\t!(activeSearcherIndexed.value?.regionByIndex)?.has(selectRegion.regionIndex.value)\n\t\t) {\n\t\t\tselectRegion.regionIndex.value = activeSearcherIndexed.value?.regions?.keys().next().value as number;\n\t\t}\n\t}, { immediate: true });\n\n\tconst getSearcherKey = () => {\n\t\tif (selectSearcher.searcherKey.value === -1 || selectSearcher.searcherKey.value === dummyIndex) return;\n\n\t\treturn selectSearcher.searcherKey.value;\n\t};\n\n\tconst getRegionIndex = () => {\n\t\tif (props.onlySearcher) return;\n\n\t\tif (selectRegion.regionIndex.value === dummyIndex) return;\n\n\t\tlet res: Region['index'] | undefined = selectRegion.regionIndex.value;\n\n\t\t// в качестве ключа используется region.key\n\t\tif (props.forFrequency) {\n\t\t\tconst regionKey = selectRegion.regionIndex.value;\n\t\t\tconst region = findRegion(props.forFrequency, { searcher_key: getSearcherKey(), key: regionKey } as Region, props.searchers);\n\n\t\t\tres = region?.index;\n\t\t}\n\n\t\treturn res;\n\t};\n\n\t/**\n\t * Получить выбранную ПС\n\t */\n\tconst getSearcher = () => {\n\t\tconst searcherKey = getSearcherKey();\n\t\tif (searcherKey === undefined) return;\n\n\t\treturn searcherByKey.value.get(searcherKey);\n\t};\n\n\t/**\n\t * Получить выбранный регион\n\t */\n\tconst getRegion = () => {\n\t\tconst regionIndex = getRegionIndex();\n\t\tif (regionIndex === undefined) return;\n\n\t\treturn getSearcher()?.regionByIndex?.get(regionIndex);\n\t};\n\n\treturn {\n\t\tselectSearcher,\n\t\tselectRegion,\n\t\tcompare,\n\n\t\tsearcherByKey,\n\t\tallRegionsIndexes,\n\n\t\tgetSearcher,\n\t\tgetRegion,\n\t};\n};\n","<script setup lang=\"ts\">\nimport { watch } from 'vue';\nimport type { Emits, Props, Region } from './selectorRegion';\nimport Select from '@/components/forms/select/select.vue';\nimport Button from '@/components/forms/button/button.vue';\nimport { useSelectorRegion } from './composables/selectorRegion';\nimport { dummyIndex } from './utils/consts';\n\nconst props = withDefaults(defineProps<Props>(), {\n\tsearchers: () => [],\n\t// compareRegionsIndexes: () => [],\n\taddSearcherIcon: true,\n\taddRegionIcon: true,\n\taddChanger: true,\n});\n\nconst model = defineModel<Props['modelValue']>({ required: true });\nconst modelSingle = defineModel<Props['modelValueSingle']>('modelValueSingle');\n\nconst emit = defineEmits<Emits>();\n\nconst {\n\tselectSearcher,\n\tselectRegion,\n\tcompare,\n\n\tsearcherByKey,\n\tallRegionsIndexes,\n\n\tgetSearcher,\n\tgetRegion,\n} = useSelectorRegion(props);\n\nconst onClickCompare = () => {\n\t// ### TODO: сделать выбор регионов через UI (сейчас в UI выбор региона не работает)\n\tif (window['fieldTemplates'] && window['fieldTemplates']?.openSelectorRegions) {\n\t\twindow['fieldTemplates'].openSelectorRegions(\n\t\t\tsearcherByKey.value,\n\t\t\tcompare.regionsIndexes.value,\n\t\t\t(regionsIndexes: Region['index'][]) => compare.regionsIndexes.value = regionsIndexes,\n\t\t);\n\t\treturn;\n\t}\n\n\temit('compareRegions', searcherByKey.value);\n};\n\nwatch([selectRegion.regionIndex, selectSearcher.searcherKey, compare.regionsIndexes], () => {\n\tif (selectSearcher.searcherKey.value === -1 && compare.regionsIndexes.value.length) {\n\t\tif (JSON.stringify(model.value) === JSON.stringify(compare.regionsIndexes.value)) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.value = [...compare.regionsIndexes.value];\n\t} else {\n\t\tmodel.value = [props.onlySearcher ? selectSearcher.searcherKey.value : selectRegion.regionIndex.value];\n\t}\n\n\t// регионов нет\n\tif (!props.onlySearcher && !allRegionsIndexes.value.size) {\n\t\tselectSearcher.searcherKey.value = dummyIndex;\n\t}\n});\n\nif (modelSingle.value) {\n\twatch(modelSingle, () => {\n\t\tmodel.value = [modelSingle.value!];\n\t}, { immediate: true });\n}\n\nwatch(model, () => {\n\tif (model.value[0]) {\n\t\tmodelSingle.value = model.value[0];\n\t}\n\n\t// проверка входных данных v-model на корректность\n\tif (props.onlySearcher) {\n\t\tif (\n\t\t\t!model.value.length ||\n\t\t\tmodel.value.length === 1 && !searcherByKey.value.has(model.value[0])\n\t\t) {\n\t\t\tlet defaultKey: number | undefined = searcherByKey.value.keys().next().value;\n\n\t\t\tif (defaultKey !== undefined) {\n\t\t\t\tmodel.value = [defaultKey];\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tmodel.value.length > 1 &&\n\t\t\tJSON.stringify(model.value) !== JSON.stringify(compare.regionsIndexes.value)\n\t\t) {\n\t\t\tmodel.value = [...compare.regionsIndexes.value];\n\n\t\t\treturn;\n\t\t}\n\t} else {\n\t\tlet newModel = [...new Set(model.value)];\n\n\t\tlet defaultIndex = searcherByKey.value.values().next().value?.regionByIndex?.keys().next().value;\n\t\tif (props.forFrequency) {\n\t\t\tdefaultIndex = searcherByKey.value.values().next().value?.regionByIndex?.values().next().value?.key;\n\t\t}\n\n\t\tif (!newModel.length) {\n\t\t\tif (defaultIndex !== undefined) {\n\t\t\t\tnewModel.push(defaultIndex);\n\t\t\t}\n\t\t} else if (newModel.length === 1) {\n\t\t\tlet all = allRegionsIndexes.value;\n\n\t\t\tif (props.forFrequency) {\n\t\t\t\tall = new Set();\n\t\t\t\tsearcherByKey.value.forEach((searcher) => {\n\t\t\t\t\tsearcher.regionByIndex.forEach((region) => {\n\t\t\t\t\t\tif (region.index === -1) return;\n\t\t\t\t\t\tif (region.index === dummyIndex) return;\n\n\t\t\t\t\t\tall.add(region.key);\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!all.has(newModel[0]) && newModel[0] !== -2) {\n\t\t\t\tnewModel = [];\n\t\t\t\tif (defaultIndex !== undefined) {\n\t\t\t\t\tnewModel.push(defaultIndex);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tnewModel = newModel.filter(index => allRegionsIndexes.value.has(index));\n\t\t\tif (!newModel.length && defaultIndex !== undefined) {\n\t\t\t\tnewModel.push(defaultIndex);\n\t\t\t}\n\t\t}\n\n\t\tif (JSON.stringify(model.value) !== JSON.stringify(newModel)) {\n\t\t\tmodel.value = newModel;\n\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// входные данные v-model совпадают с внутренними значениями\n\tif (\n\t\tmodel.value.length === 1 &&\n\t\tmodel.value[0] === (props.onlySearcher ? selectSearcher.searcherKey.value : selectRegion.regionIndex.value)\n\t) {\n\t\treturn;\n\t}\n\n\t// if (\n\t// \tmodel.value.length > 1 &&\n\t// \tselectorSearcher.searcherKey.value === -1 &&\n\t// \tJSON.stringify(model.value) === JSON.stringify(selectorCompare.regionsIndexes.value)\n\t// ) {\n\t// \treturn;\n\t// }\n\n\t// обновление regionIndex, searcherKey, selectorCompare.regionsIndexes\n\tif (props.onlySearcher) {\n\t\t// if (!model.value.length) {\n\t\t// \tselectorSearcher.searcherKey.value = dummyIndex;\n\t\t//\n\t\t// \treturn;\n\t\t// }\n\n\t\tif (model.value.length === 1) {\n\t\t\tselectSearcher.searcherKey.value = model.value[0];\n\n\t\t\treturn;\n\t\t}\n\n\t\tselectSearcher.searcherKey.value = -1;\n\n\t\treturn;\n\t} else {\n\t\t// if (!model.value.length) {\n\t\t// \tselectorSearcher.searcherKey.value = dummyIndex;\n\t\t// \tselectorRegion.regionIndex.value = dummyIndex;\n\t\t//\n\t\t// \treturn;\n\t\t// }\n\n\t\tif (model.value.length === 1 && selectSearcher.searcherKey.value !== -1) {\n\t\t\tselectRegion.regionIndex.value = model.value[0];\n\n\t\t\tlet newSearherKey: number | undefined;\n\t\t\tfor (const searcher of searcherByKey.value.values()) {\n\t\t\t\tfor (const region of searcher.regionByIndex.values()) {\n\t\t\t\t\tconst currentRegionIndex = props.forFrequency ? region.key : region.index;\n\t\t\t\t\tif (currentRegionIndex === selectRegion.regionIndex.value) {\n\t\t\t\t\t\tnewSearherKey = searcher.key;\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (newSearherKey !== undefined) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (newSearherKey !== undefined) {\n\t\t\t\tselectSearcher.searcherKey.value = newSearherKey;\n\t\t\t}\n\t\t} else {\n\t\t\tselectSearcher.searcherKey.value = -1;\n\t\t\tcompare.regionsIndexes.value = [...model.value];\n\t\t}\n\t}\n}, { immediate: true });\n\ndefineExpose({\n\tgetSearcher,\n\tgetRegion,\n});\n</script>\n\n<template>\n\t<div\n\t\t:class=\"{\n\t\t\t'top-selectorRegion': true,\n\t\t\t'top-selectorRegion-onlySearcher': onlySearcher,\n\t\t}\"\n\t>\n\t\t<Select\n\t\t\t:options=\"selectSearcher.optionBySearcherKey.value\"\n\t\t\tv-model=\"selectSearcher.searcherKey.value\"\n\t\t\tname=\"searcher_key\"\n\t\t\t:addChanger=\"addChanger\"\n\t\t/>\n\n\t\t<Select\n\t\t\tv-if=\"!onlySearcher && selectSearcher.searcherKey.value !== -1\"\n\t\t\tclass=\"top-select-region\"\n\t\t\t:options=\"selectRegion.optionByRegionIndex.value\"\n\t\t\tv-model=\"selectRegion.regionIndex.value\"\n\t\t\t:name=\"forFrequency ? 'region_key' : 'region_index'\"\n\t\t\t:addChanger=\"addChanger\"\n\t\t\t:data-top-icon=\"addRegionIcon ? '' : undefined\"\n\t\t/>\n\n\t\t<Button\n\t\t\tv-if=\"addCompare && !onlySearcher && selectSearcher.searcherKey.value === -1\"\n\t\t\tname=\"compare\"\n\t\t\t@click=\"onClickCompare\"\n\t\t\t:data-count-compare-regions-indexes=\"compare.regionsIndexes.value.length\"\n\t\t>\n\t\t\t{{ $i18n.Common.Selected_regions }}\n\t\t</Button>\n\t</div>\n</template>\n\n<style>\n@import \"./styles/searcherColors.css\";\n\n.top-selectorRegion {\n\twidth: 320px;\n\tdisplay: inline-flex;\n\tvertical-align: middle;\n}\n\n.top-selectorRegion > .top-select {\n\tflex-grow: 1;\n}\n\n.top-selectorRegion > .top-select:focus-within {\n\tz-index: 4;\n}\n\n.top-selectorRegion > .top-select > .top-select_select:hover,\n.top-selectorRegion > .top-select > .top-select_select.top-error {\n\tz-index: 1;\n}\n\n.top-selectorRegion > .top-select-searcher_key {\n\twidth: 120px;\n\tmax-width: 140px;\n\tmargin-right: -1px;\n}\n\n.top-selectorRegion > .top-select-region > select {\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n}\n\n.top-selectorRegion > .top-select-region {\n\t--top-icon-size: 20px;\n\t--top-icon-color: var(--color-text-primary-1);\n\n\t--top-icon2-size: 20px;\n\t--top-icon2-color: var(--color-text-primary-1);\n}\n\n.top-selectorRegion > .top-select-region[data-top-icon][data-top-icon2] {\n\t--top-icon2-size: 16px;\n}\n\n.top-selectorRegion > .top-select-region[data-top-icon][data-top-icon2]:after {\n\ttext-indent: -4px;\n}\n\n.top-selectorRegion > [name=\"compare\"] {\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n\tflex-grow: 1;\n}\n\n.top-selectorRegion > [name=\"compare\"]:after {\n\tcontent: \"(\" attr(data-count-compare-regions-indexes) \")\";\n\tmargin: 0 0 0 6px;\n}\n\n.top-selectorRegion:not(.top-selectorRegion-onlySearcher) > .top-select-searcher_key > select {\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n\tmargin-right: 0;\n}\n\n.top-selectorRegion:not(.top-selectorRegion-onlySearcher) > .top-select-searcher_key[data-value=\"-1\"] > select {\n\tborder-right: none;\n}\n\n.top-selectorRegion-onlySearcher {\n\twidth: 120px;\n}\n</style>\n","import type { Tag } from './types';\n\nexport default [\n\t{\n\t\tid: '1',\n\t\tname: 'Without Tag',\n\t\tcolor_id: '1',\n\t},\n\t{\n\t\tid: '2',\n\t\tname: 'Red',\n\t\tcolor_id: '2',\n\t},\n\t{\n\t\tid: '3',\n\t\tname: 'Orange',\n\t\tcolor_id: '3',\n\t},\n\t{\n\t\tid: '4',\n\t\tname: 'Yellow',\n\t\tcolor_id: '4',\n\t},\n\t{\n\t\tid: '5',\n\t\tname: 'Blue',\n\t\tcolor_id: '5',\n\t},\n\t{\n\t\tid: '6',\n\t\tname: 'Purple',\n\t\tcolor_id: '6',\n\t},\n\t{\n\t\tid: '7',\n\t\tname: 'Green',\n\t\tcolor_id: '7',\n\t},\n\t{\n\t\tid: '8',\n\t\tname: 'Magenta',\n\t\tcolor_id: '8',\n\t},\n\t{\n\t\tid: '9',\n\t\tname: 'Dark blue',\n\t\tcolor_id: '9',\n\t},\n\t{\n\t\tid: '10',\n\t\tname: 'Turquoise',\n\t\tcolor_id: '10',\n\t},\n] as Tag[];\n","import type { Props as TagSelectorOpenerProps, TagSelectorTarget } from '../popupOpener/types';\nimport type { Tag, TagIdExclude } from '../types';\n\n/**\n * Полуичить значение исключения тега tagId\n */\nexport const genTagIdExcluded = (tagId: Tag['id']): TagIdExclude => {\n\treturn '-' + tagId as TagIdExclude;\n};\n\n/**\n * Вернуть чистый tagId без exclude флага\n */\nexport const genTagIdClear = (tagId: Tag['id'] | TagIdExclude) => {\n\tif (tagId[0] === '-') return tagId.substring(1) as Tag['id'];\n\n\treturn tagId as Tag['id'];\n};\n\n/**\n * Получить инфомрацию о теге по его id\n */\nexport const getTagById = (tagId: Tag['id'] | TagIdExclude, tags: TagSelectorOpenerProps['tags']) => {\n\ttagId = genTagIdClear(tagId);\n\n\tconst tag = tags.find(tag => tag.id === tagId);\n\tif (!tag) return;\n\n\treturn tag;\n};\n","<script setup lang=\"ts\">\nimport { computed, nextTick, ref } from 'vue';\nimport type { Emits, Props } from './types';\nimport TopTagIcon from '../tagIcon/tagIcon.vue';\nimport TopPopupListItem from '@/components/popup/popup/listItem.vue';\n\nconst props = defineProps<Props>();\nconst emit = defineEmits<Emits>();\n\nconst name = defineModel<Props['name']>('name', {\n\trequired: true,\n});\n\nconst elName = ref<HTMLElement | null>(null);\n\n/**\n * @todo Удалить через пол года после выхода версии firefox с поддержкой contenteditable plaintext-only, включая бета версии\n */\nconst firefoxProps = computed(() => {\n\tif (navigator.userAgent.indexOf('Firefox') != -1) {\n\n\t\treturn {\n\t\t\tcontenteditable: inEdit.value,\n\t\t\tonpaste: (event: Event) => event.preventDefault(),\n\t\t};\n\t}\n\n\treturn {};\n});\n\n/**\n * Включен режим редактирвоания\n */\nconst inEdit = ref(false);\n\n/**\n * Включить режим редактирование\n */\nconst turnToEdit = async () => {\n\tinEdit.value = true;\n\n\tawait nextTick();\n\n\telName.value?.focus();\n};\n\n/**\n * Применить редактирование\n */\nconst editCommit = () => {\n\tconst name = elName.value?.innerText;\n\tif (!name) return editCancel();\n\n\tif (elName.value) elName.value.innerText = name;\n\n\tinEdit.value = false;\n\n\temit('update:name', name);\n};\n\n/**\n * Отменить редактирование\n */\nconst editCancel = async () => {\n\tif (elName.value) elName.value.innerText = props.name;\n\n\tinEdit.value = false;\n};\n\n/**\n * Применить выбор\n */\nconst changeSelect = (e: MouseEvent) => {\n\t// в режиме редактирования выбор не применяется\n\tif (inEdit.value) return;\n\n\t// тег запрещено выбирать\n\tif (props.disabled) return;\n\n\tlet toState: Props['state'] = 'selected';\n\n\tif (props.canExclude) {\n\t\tif (e.ctrlKey || e.metaKey) {\n\t\t\ttoState = 'excluded';\n\t\t}\n\t}\n\n\tif (props.state == toState) {\n\t\ttoState = '';\n\t}\n\n\tif (toState === '') emit('unselect');\n\tif (toState === 'selected') emit('select');\n\tif (toState === 'excluded') emit('exclude');\n};\n</script>\n\n<template>\n\t<TopPopupListItem\n\t\t:class=\"{\n\t\t\t'top-tagSelector_tagListItem': true,\n\t\t\t'top-tagSelector_tagListItem-inEdit': inEdit,\n\t\t\t'top-tagSelector_tagListItem-disabled': disabled,\n\t\t\t'top-tagSelector_tagListItem-canExclude': canExclude,\n\t\t\t'top-tagSelector-active': !!state,\n\t\t\t'top-tagSelector-excluded': state === 'excluded'\n\t\t}\"\n\t\t@click.stop=\"changeSelect\"\n\t>\n\t\t<TopTagIcon\n\t\t\t:id\n\t\t\t:name\n\t\t\t:colorId\n\t\t\t:state\n\t\t/>\n\n\t\t<span\n\t\t\tref=\"elName\"\n\t\t\tclass=\"top-tagSelector_tagListItemName\"\n\t\t\t:contenteditable=\"inEdit ? 'plaintext-only' : false\"\n\t\t\t:=\"firefoxProps\"\n\t\t\t@keydown.enter.stop=\"editCommit\"\n\t\t\t@keydown.esc.stop=\"editCancel\"\n\t\t>\n\t\t\t{{ name }}\n\t\t</span>\n\n\t\t<template v-if=\"editable\">\n\t\t\t<span\n\t\t\t\tv-if=\"!inEdit\"\n\t\t\t\tdata-top-icon=\"\"\n\t\t\t\tclass=\"top-tagSelector_edit\"\n\t\t\t\t@click=\"turnToEdit\"\n\t\t\t></span>\n\n\t\t\t<span\n\t\t\t\tv-else\n\t\t\t\tdata-top-icon=\"\"\n\t\t\t\tclass=\"top-tagSelector_edit\"\n\t\t\t\t@click.stop=\"editCommit\"\n\t\t\t></span>\n\t\t</template>\n\t</TopPopupListItem>\n</template>\n\n<style>\n.top-tagSelector_tagListItem.top-popup_listItem {\n\tpadding-top: var(--top-padding-2) !important;\n\tpadding-bottom: var(--top-padding-2) !important;\n\tgap: 10px;\n}\n\n.top-tagSelector_tagListItemName {\n\tborder-radius: var(--top-radius-1);\n\twidth: 120px;\n\tpadding: 4px 2px;\n\tmargin: -4px -2px;\n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n\tflex-grow: 1;\n}\n\n/* редактирование */\n.top-tagSelector_edit {\n\t--top-icon-size: 18px;\n\t--top-icon-color: var(--color-text-3);\n\n\twidth: 20px;\n\tflex-grow: 0;\n}\n\n.top-tagSelector_edit:before {\n\tline-height: 0;\n}\n\n.top-tagSelector_edit { opacity: 0; }\n.top-tagSelector_edit:hover {\n\t--top-icon-color: var(--color-text-primary);\n}\n\n.top-tagSelector_tagListItem:hover .top-tagSelector_edit,\n.top-tagSelector_tagListItem-inEdit .top-tagSelector_edit {\n\tcursor: pointer;\n\topacity: 1;\n}\n\n.top-tagSelector_tagListItem-inEdit {\n\tbackground: var(--color-layout-front-3) !important;\n\toutline: 1px dashed var(--color-line-2);\n\toutline-offset: -1px;\n}\n\n.top-tagSelector_tagListItem-inEdit .top-tagSelector_tagListItemName {\n\tcursor: text;\n\tbackground: var(--color-layout-front-1);\n}\n\n/* disabled */\n.top-tagSelector_tagListItem-disabled {\n\tcursor: not-allowed !important;\n\topacity: 0.85;\n}\n.top-tagSelector_tagListItem-disabled:hover {\n\tbackground: inherit;\n}\n.top-tagSelector_tagListItem-disabled [data-tag_id] {\n\topacity: 0.6;\n}\n</style>\n","<script setup lang=\"ts\">\nimport type { Props, TagSelectorTarget } from './types';\nimport TopPopupOpener from '../../../popup/popup/opener.vue';\nimport TopButton from '@/components/forms/button/button.vue';\nimport { genTagIdClear, getTagById } from '../utils/utils';\nimport TopTagIcon from '../tagIcon/tagIcon.vue';\n\ndefineOptions({\n\tinheritAttrs: false,\n});\n\nconst props = defineProps<Props>();\n\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\nconst component = props.useTopButton ? TopButton : 'div';\nconst componentSlotName = props.useTopButton ? 'html' : 'default';\n\nconst topTagSelectorTarget: TagSelectorTarget = {\n\tmodel,\n\tmode: props.mode,\n\ttargetId: props.targetId,\n\tfilters: props.filters,\n\tpayload: props.payload,\n};\n</script>\n\n<template>\n\t<TopPopupOpener :id>\n\t\t<component\n\t\t\t:is=\"component\"\n\t\t\t:class=\"{\n\t\t\t\t'top-tagSelector': true,\n\t\t\t\t'top-tagSelector-filter': props.mode === 'filter',\n\t\t\t\t'top-tagSelector-setter_single': props.mode === 'setter' && !filters,\n\t\t\t\t'top-tagSelector-setter_several': props.mode === 'setter' && filters,\n\t\t\t\t'top-tagSelector-selectedOne': !model.length || model.length === 1,\n\t\t\t\t'top-tagSelector-toTwoLine': model.length > 5,\n\t\t\t}\"\n\t\t\tcolor=\"theme\"\n\t\t\tstyling=\"\"\n\t\t\tv-top-data:topTagSelectorTarget=\"topTagSelectorTarget\"\n\t\t\t:=$attrs\n\t\t>\n\t\t\t<template #[componentSlotName]>\n\t\t\t\t<TopTagIcon\n\t\t\t\t\tv-if=\"!model.length && mode === 'filter'\"\n\t\t\t\t\tid=\"all\"\n\t\t\t\t\tcolorId=\"\"\n\t\t\t\t\t:name=\"$i18n.Common.All_tags ?? ''\"\n\t\t\t\t\tstate=\"\"\n\t\t\t\t/>\n\n\t\t\t\t<!-- Массовое редактирование -->\n\t\t\t\t<div v-if=\"mode === 'setter' && filters\">\n\t\t\t\t\t<slot></slot>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Список тегов -->\n\t\t\t\t<TopTagIcon\n\t\t\t\t\tv-else\n\t\t\t\t\tv-for=\"tagId in model\"\n\t\t\t\t\t:id=\"genTagIdClear(tagId)\"\n\t\t\t\t\t:colorId=\"getTagById(tagId, tags)?.color_id ?? ''\"\n\t\t\t\t\t:name=\"getTagById(tagId, tags)?.name ?? ''\"\n\t\t\t\t\t:state=\"genTagIdClear(tagId) === tagId ? 'selected' : 'excluded'\"\n\t\t\t\t/>\n\t\t\t</template>\n\t\t</component>\n\t</TopPopupOpener>\n</template>\n\n<style>\n.top-tagSelector {\n\tcursor: pointer;\n\tmin-width: 0;\n\twhite-space: nowrap;\n\tjustify-content: left;\n}\n\n.top-tagSelector.top-button {\n\twidth: 112px;\n\tvertical-align: middle;\n}\n\n.top-tagSelector.top-button.top-select_arrow {\n\twidth: calc(112px + 20px);\n}\n\n.top-tagSelector-filter {\n\tgap: var(--top-gap-1);\n}\n\n/* все теги в фильтре */\n.top-tagSelector-filter [data-tag_id=\"all\"] {\n\tmargin-left: 0;\n}\n.top-tagSelector-filter [data-tag_id=\"all\"]:before {\n\tborder: none;\n\tmargin-left: 3px;\n\topacity: 0.5;\n}\n\n/* фильтр по одному тегу */\n.top-tagSelector-filter.top-tagSelector-selectedOne [data-tag_id]:after {\n\tcontent: attr(title);\n\tmargin-left: 20px;\n\tmin-width: 74px;\n\ttext-align: left;\n\tline-height: 1.2;\n\ttext-overflow: ellipsis;\n\toverflow: hidden;\n}\n\n.top-tagSelector-filter.top-tagSelector-selectedOne [data-tag_id=\"all\"]:after {\n\tmargin-left: 0;\n}\n\n/* фильтр по многим тегам */\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine {\n\tflex-wrap: wrap;\n\talign-content: center;\n}\n\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine [data-tag_id] {\n\t--top-tag-selector-size: 8px;\n}\n\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine [data-tag_id]:nth-child(5) {\n\tmargin-right: 5px;\n}\n\n/* установка тегов */\n.top-tagSelector-setter_single {\n\tposition: relative;\n\tdisplay: flex !important; flex-direction: column; flex-wrap: wrap; align-items: stretch !important;\n}\n\n.top-tagSelector-setter_single [data-tag_id] {\n\twidth: auto; min-height: 20%; min-width: 50%;\n\tflex: 1 1 auto;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, reactive, ref, shallowRef, watch } from 'vue';\n\nimport Core from '@/core/core/core';\nimport { useI18n } from '@/core/plugins/i18n';\nimport { storage } from '@/core/utils/dom';\nimport { debounce } from '@/core/utils/lodash';\n\nimport type { Option } from '@/components/forms/select/select';\nimport TopSelect from '@/components/forms/select/select.vue';\n\nimport TopButton from '@/components/forms/button/button.vue';\n\nimport type { PopupEvent } from '@/components/popup/popup/popup';\nimport TopPopup from '../../popup/popup/popup.vue';\nimport TopPopupListItem from '../../popup/popup/listItem.vue';\n\nimport type { Emits, FiltersAction, Props, Tag } from './types';\nimport tagsDefaults from './tagsDefaults';\nimport { genTagIdExcluded } from './utils/utils';\n\nimport type { Props as TagListItemProps } from './popupListItem/types';\nimport TopTagListItem from './popupListItem/tagPopupListItem.vue';\n\nimport type { TagSelectorTarget } from './popupOpener/types';\nimport TopTagSelectorPopupOpener from './popupOpener/popupOpener.vue';\n\nconst i18n = useI18n();\n\nconst props = withDefaults(defineProps<Props>(), {\n\ttagsMax: 10,\n\trequiredForSetter: true,\n\temitDelay: 500,\n});\n\n/**\n * Выбранные теги кнопки в этом компоненте\n *\n * Редактирвоание ведется только через `editTarget.model`\n */\nconst model = defineModel<Props['modelValue']>({\n\trequired: true,\n});\n\n/**\n * Список тегов\n */\nconst tags = defineModel<Tag[]>('tags', {\n\tdefault: reactive(tagsDefaults),\n});\n\nconst emit = defineEmits<Emits>();\n\nconst emitDebounce: typeof emit = debounce((name, e) => {\n\temit(name, e);\n}, props.emitDelay);\n\n// требуется сразу указать один тег\nif (props.singleMode && !model.value.length) {\n\tmodel.value = [tags.value[0].id];\n}\n\nconst id = props.id ?? 'top-popup-id-' + Math.random() + '';\n\nconst filtersAction = ref<FiltersAction>('add');\n\n/**\n * Сгенерировать опции для выбора дейсвтия массого редактирования\n */\nconst genFiltersActionOptions = () => {\n\tconst tagsText = ' ' + i18n.Common.Tags?.toLowerCase();\n\n\tconst res = new Map<FiltersAction, Option>();\n\tres.set('add', { value: 'add', title: i18n.Common.Add + tagsText });\n\tres.set('replace', { value: 'replace', title: i18n.Common.Replace + tagsText });\n\tres.set('delete', { value: 'delete', title: i18n.Common.Delete + tagsText });\n\n\treturn res;\n};\n\n/**\n * Целевой объект редактирвоания тегов\n *\n * Определяется кнопкой, которая открыла popup выбора тегов\n */\nlet target = shallowRef<TagSelectorTarget>({\n\tmodel,\n\tmode: 'filter',\n\ttargetId: undefined,\n\tfilters: undefined,\n\tpayload: undefined,\n});\n\nwatch(model, () => {\n\temitDebounce('selector', model.value);\n});\n\n/**\n * Можно ли выбрать еще теги\n */\nconst disabled = computed(() => {\n\tif (target.value.mode !== 'setter') return;\n\n\tif (!props.maxTagsForSetter) return;\n\n\t// массовая смена тегов, количество тегов в результате узнать невозможно\n\tif (target.value.filters) return;\n\n\treturn target.value.model.value.length >= props.maxTagsForSetter;\n});\n\nconst genTargetTagState = (tagId: Tag['id'] | 'all'): TagListItemProps['state'] => {\n\tif (tagId !== 'all') {\n\t\tif (target.value.model.value.includes(tagId)) return 'selected';\n\n\t\tif (target.value.model.value.includes(genTagIdExcluded(tagId))) return 'excluded';\n\t}\n\n\t// Все теги, ни один из тегов не выбран\n\tif (tagId === 'all' && !target.value.model.value.length) return 'selected';\n\n\treturn '';\n};\n\nconst updateTargetModel = (tagId: Tag['id'], action: 'unselect' | 'select' | 'exclude') => {\n\tconst tagIdExcluded = genTagIdExcluded(tagId);\n\n\tlet tagsIds = target.value.model.value.filter(modelTagId => modelTagId !== tagId && modelTagId !== tagIdExcluded);\n\n\tif (action === 'select') tagsIds.push(tagId);\n\tif (action === 'exclude') tagsIds.push(tagIdExcluded);\n\n\t// режим редактирвоания тегов одного объекта с требованием указать хотя бы один тег\n\tif (target.value.mode === 'setter' && target.value.targetId !== undefined && props.requiredForSetter) {\n\t\t// нельзя снимать выделение со всех тегов\n\t\tif (!tagsIds.length) {\n\t\t\ttagsIds.push('1');\n\t\t}\n\n\t\t// при первом выборе сразу снять тег \"Без тега\"\n\t\tif (tagsIds.length === 2 && target.value.model.value.length === 1 && target.value.model.value[0] === '1') {\n\t\t\ttagsIds = tagsIds.filter((tagId) => tagId !== '1');\n\t\t}\n\t}\n\n\t// режим выбора одного тега\n\tif (props.singleMode && !target.value.filters) {\n\t\t// нужно указать хотя бы один тег\n\t\tif (!tagsIds.length) {\n\t\t\ttagsIds = target.value.model.value;\n\t\t}\n\n\t\tif (tagsIds.length > 1) {\n\t\t\ttagsIds = [tagsIds[tagsIds.length - 1]];\n\t\t}\n\t}\n\n\t// всегда выводить теги в порядке, указанном в настройках tags\n\ttagsIds.sort((a, b) => {\n\t\tif (!props.tags) return 0;\n\n\t\tconst aIndex = props.tags.findIndex((tag) => tag.id === a);\n\t\tconst bIndex = props.tags.findIndex((tag) => tag.id === b);\n\n\t\treturn aIndex - bIndex;\n\t});\n\n\ttarget.value.model.value = tagsIds;\n\n\tif (target.value.mode === 'setter' && target.value.targetId !== undefined) {\n\t\temitDebounce('setter', {\n\t\t\ttagsIds: tagsIds as Tag['id'][],\n\t\t\ttargetId: target.value.targetId,\n\t\t\tpayload: target.value.payload,\n\t\t});\n\t}\n};\n\nconst classString = computed(() => {\n\tlet res = 'top-tagSelector_popup';\n\n\tif (target.value.mode === 'filter') res += ' top-tagSelector_popup-filter';\n\tif (target.value.mode === 'setter') res += ' top-tagSelector_popup-setter';\n\n\treturn res;\n});\n\n/**\n * Добавить тег\n */\nconst addTag = () => {\n\tconst tagName = prompt('', 'New tag');\n\tif (!tagName || tagName === 'New tag') return;\n\n\tconst tagId = tags.value.length + 1;\n\n\ttags.value.push({\n\t\tid: String(tagId) as Tag['id'],\n\t\tname: tagName,\n\t\tcolor_id: String((tagId - 1) % 10 + 1) as Tag['color_id'],\n\t});\n\n\temit('tagsChanged', tags.value);\n};\n\nconst onOpen = (popupEvent: PopupEvent) => {\n\t// popup открыт другой кнопкой c другим modelValue, для редактирвоания объектов\n\ttarget.value = storage(popupEvent.elPopupOpener, 'topTagSelectorTarget');\n\tif (!target.value) throw new Error('Open popup TopTagSelector required v-data:topTagSelectorTarget');\n\n\t// при начале массовой установки тегов сбросить состояние формы\n\tif (target.value.filters) {\n\t\tfiltersAction.value = 'add';\n\t\ttarget.value.model.value = [];\n\t}\n\n\tif (!Core.$?.ui['sortable']) {\n\t\tconsole.info('Для работы сортировки требуется глобальная загрузка jQuery UI Sortable');\n\n\t\treturn;\n\t}\n\n\tif (!Core.state.isMobile && !Core.state.isMobileUA && tags.value) {\n\t\t$(popupEvent.elPopup).sortable({\n\t\t\titems: 'li:has([data-tag_id]:not([data-tag_id=\"all\"]))',\n\n\t\t\t/**\n\t\t\t * @todo Удалить `[contenteditable=\"true\"]` через пол года после выхода версии firefox с поддержкой contenteditable plaintext-only, включая бета версии\n\t\t\t */\n\t\t\tcancel: '[contenteditable=\"plaintext-only\"], [contenteditable=\"true\"]',\n\n\t\t\tdistance: 10,\n\t\t\tstop: function (_e, ui) {\n\t\t\t\tif (!tags.value) return;\n\n\t\t\t\tconst $tags = $(ui.item).parent().find('[data-tag_id]');\n\n\t\t\t\tconst tagsSorted: Tag['id'][] = [];\n\t\t\t\t$tags.each((_index, elTag) => {\n\t\t\t\t\tif (!tags.value) return;\n\n\t\t\t\t\tconst tagId = $(elTag).attr('data-tag_id') as Tag['id'];\n\t\t\t\t\ttagsSorted.push(tagId);\n\t\t\t\t});\n\n\t\t\t\ttags.value.sort((tagIdA, tagIdB) => {\n\t\t\t\t\tconst a = tagsSorted.findIndex(tagSorted => tagSorted === tagIdA.id);\n\t\t\t\t\tconst b = tagsSorted.findIndex(tagSorted => tagSorted === tagIdB.id);\n\n\t\t\t\t\treturn a - b;\n\t\t\t\t});\n\n\t\t\t\temitDebounce('tagsChanged', tags.value);\n\t\t\t},\n\t\t});\n\t}\n};\n\nconst onClose = (popupEvent: PopupEvent) => {\n\tif (!Core.$?.ui['sortable']) return;\n\n\tif ($(popupEvent.elPopup).data('ui-sortable')) {\n\t\t$(popupEvent.elPopup).sortable('destroy');\n\t}\n};\n</script>\n\n<template>\n\t<TopTagSelectorPopupOpener\n\t\tclass=\"top-select_arrow\"\n\t\tv-model=\"model\"\n\t\t:id\n\t\t:tags\n\t\tmode=\"filter\"\n\t\tuseTopButton\n\t/>\n\n\t<TopPopup\n\t\t:id\n\t\t:class=\"classString\"\n\t\t@open=\"onOpen($event)\"\n\t\t@close=\"onClose($event)\"\n\t\t:transition-duration=\"50\"\n\t>\n\t\t<!-- Массовое редактирвоание-->\n\t\t<template #header v-if=\"target.mode === 'setter' && target.filters\">\n\t\t\t<TopSelect\n\t\t\t\tv-model=\"filtersAction\"\n\t\t\t\t:options=\"genFiltersActionOptions()\"\n\t\t\t/>\n\t\t</template>\n\n\t\t<template #footer v-if=\"target.mode === 'setter' && target.filters\">\n\t\t\t<TopButton color=\"theme\">\n\t\t\t\t{{ $i18n.Common.Cancel }}\n\t\t\t</TopButton>\n\n\t\t\t<TopButton\n\t\t\t\t@click=\"emitDebounce('setter', {\n\t\t\t\t\ttagsIds: target.model.value as Tag['id'][],\n\t\t\t\t\tfilters: target.filters,\n\t\t\t\t\tfiltersAction,\n\t\t\t\t\tpayload: target.payload,\n\t\t\t\t})\"\n\t\t\t>\n\t\t\t\t{{ filtersAction === 'add' ? $i18n.Common['Add'] : '' }}\n\t\t\t\t{{ filtersAction === 'replace' ? $i18n.Common['Replace'] : '' }}\n\t\t\t\t{{ filtersAction === 'delete' ? $i18n.Common['Remove'] : '' }}\n\t\t\t</TopButton>\n\t\t</template>\n\n\t\t<template #contentList>\n\t\t\t<TopTagListItem\n\t\t\t\tv-if=\"target.mode === 'filter' && !singleMode\"\n\t\t\t\tid=\"all\"\n\t\t\t\tcolorId=\"\"\n\t\t\t\t:name=\"$i18n.Common.All_tags ?? ''\"\n\t\t\t\t:state=\"target.model.value.length ? '' : 'selected'\"\n\t\t\t\t@select=\"target.model.value = []\"\n\t\t\t/>\n\n\t\t\t<TopTagListItem\n\t\t\t\tv-for=\"tag in tags\"\n\t\t\t\t:key=\"tag.id\"\n\t\t\t\t:id=\"tag.id\"\n\t\t\t\t:colorId=\"tag.color_id\"\n\t\t\t\t:name=\"tag.name\"\n\t\t\t\t:state=\"genTargetTagState(tag.id)\"\n\t\t\t\t:canExclude=\"target.mode === 'filter' && !singleMode\"\n\t\t\t\t:editable=\"tagsEditable\"\n\t\t\t\t:disabled=\"disabled && genTargetTagState(tag.id) === ''\"\n\t\t\t\t@unselect=\"updateTargetModel(tag.id, 'unselect')\"\n\t\t\t\t@select=\"updateTargetModel(tag.id, 'select')\"\n\t\t\t\t@exclude=\"updateTargetModel(tag.id, 'exclude')\"\n\t\t\t\t@update:name=\"tag.name = $event as string, emitDebounce('tagsChanged', tags);\"\n\t\t\t/>\n\n\t\t\t<TopPopupListItem\n\t\t\t\tv-if=\"tagsEditable && tags.length < tagsMax && tags.length < 20\"\n\t\t\t\tdata-top-icon=\"\"\n\t\t\t\t@click.stop=\"addTag\"\n\t\t\t>\n\t\t\t\t{{ $i18n.Common.Add }}\n\t\t\t</TopPopupListItem>\n\t\t</template>\n\t</TopPopup>\n</template>\n\n<style>\n.top-tagSelector_popup .top-popup {\n\tuser-select: none;\n\tmin-width: 220px !important;\n\ttext-align: left;\n}\n\n.top-tagSelector_popup .top-popup_header .top-select{\n\tflex-grow: 1;\n}\n</style>\n","import type { MaybeRefOrGetter } from 'vue';\nimport { computed, toValue } from 'vue';\nimport type { Item } from '@/components/project/selectorCompetitors/selectorCompetitors';\nimport type { Competitor } from '@/components/project/selectorCompetitors/types/competitor';\n\nexport const useItemsFromCompetitors = (competitors: MaybeRefOrGetter<Competitor[]>, projectId: MaybeRefOrGetter<number>) => {\n\treturn computed(() => {\n\t\tconst activeCompetitors = toValue(competitors).filter(competitor => competitor.on >= 0 || competitor.id === projectId);\n\n\t\tconst items: Item[] = activeCompetitors.map(competitor => {\n\t\t\treturn {\n\t\t\t\tvalue: competitor.id,\n\t\t\t\ttitle: competitor.url + ` [${competitor.id}]`,\n\t\t\t\ticon: competitor.id === toValue(projectId) ? '' : '',\n\t\t\t\tcontent: competitor.name,\n\t\t\t};\n\t\t});\n\n\t\treturn items;\n\t});\n};\n","import { isRef, type Ref, ref, unref, watch } from 'vue';\nimport { useI18n } from '@/core/plugins/i18n';\nimport { storage } from '@/core/utils/dom';\nimport TopPopupWorker from '@/components/popup/lib/worker';\nimport type { OpenerProps as PopupOpenerProps } from '@/components/popup/popup/popup';\nimport type { Props as TagSelectorOpenerProps, TagSelectorTarget } from '../popupOpener/types';\nimport type { Props as TagIconProps } from '../tagIcon/types';\nimport { genTagIdClear, getTagById } from '../utils/utils';\n\n/**\n * Сгенерировтаь элемент для открытия popup с выбором тегов\n *\n * Альтернатива TopTagSelecorPopupOpener для работы вне vue\n *\n * Требует монтирования компонента TopTagSelecor\n */\nexport const genElPopupOpener = (\n\tprops: TagSelectorOpenerProps & { modelValue: TagSelectorOpenerProps['modelValue'] | Ref<TagSelectorOpenerProps['modelValue']> },\n\tpropsPopup?: Partial<PopupOpenerProps>,\n\thtmlSetterSeveral?: string,\n): HTMLElement => {\n\tif (!propsPopup) propsPopup = { id: props.id };\n\n\tpropsPopup.id = props.id;\n\n\tconst el = TopPopupWorker.genElPopupOpener('div', propsPopup as PopupOpenerProps);\n\n\tel.classList.add('top-tagSelector');\n\tif (props.useTopButton) el.classList.add('top-button', 'top-color_theme');\n\tif (props.mode === 'filter') el.classList.add('top-tagSelector-filter');\n\tif (props.mode === 'setter' && !props.filters) el.classList.add('top-tagSelector-setter_single');\n\tif (props.mode === 'setter' && props.filters) el.classList.add('top-tagSelector-setter_several');\n\n\t// прокcи клик: lazy connect\n\tel.onclick = (e) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\n\t\tel.onclick = null;\n\n\t\tconst model = ref(props.modelValue);\n\n\t\tconst target: TagSelectorTarget = {\n\t\t\tmodel,\n\t\t\tmode: props.mode,\n\t\t\ttargetId: props.targetId,\n\t\t\tfilters: props.filters,\n\t\t\tpayload: props.payload,\n\t\t};\n\n\t\tstorage(el, 'topTagSelectorTarget', target);\n\n\t\tdelete el.dataset.topPopupDisabled;\n\n\t\tif (!isRef(props.modelValue)) {\n\t\t\twatch(model, () => {\n\t\t\t\tprops.modelValue = model.value;\n\n\t\t\t\telPopupOpenerRender(el, props, htmlSetterSeveral);\n\t\t\t});\n\t\t}\n\n\t\t// выполнение клика\n\t\tel.click();\n\t};\n\n\tif (isRef(props.modelValue)) {\n\t\twatch(props.modelValue, () => elPopupOpenerRender(el, props, htmlSetterSeveral));\n\t} else {\n\t\tstorage(el, 'topTagSelectorRender', (modelValue: TagSelectorOpenerProps['modelValue']) => {\n\t\t\tprops.modelValue = modelValue;\n\n\t\t\tconst target = storage(el, 'topTagSelectorTarget');\n\t\t\tif (target) target.model.value = modelValue;\n\n\t\t\telPopupOpenerRender(el, props, htmlSetterSeveral);\n\t\t});\n\t}\n\n\telPopupOpenerRender(el, props, htmlSetterSeveral);\n\n\treturn el;\n};\n\n/**\n * Вызвать перерисовку элемента, который был создан через genElPopupOpener()\n *\n * Работет только для элементов не с реактивным modelValue\n */\nexport const renderElPopupOpener = (el: HTMLElement, modelValue: TagSelectorOpenerProps['modelValue']) => {\n\tstorage(el, 'topTagSelectorRender')?.(modelValue);\n};\n\n/**\n * Отрисовать TopTagSelecorPopupOpener\n */\nconst elPopupOpenerRender = (el, props: TagSelectorOpenerProps, htmlSetterSeveral?: string) => {\n\tconst tagsIds = unref(props.modelValue);\n\n\tel.classList.toggle('top-tagSelector-selectedOne', !tagsIds.length || tagsIds.length === 1);\n\tel.classList.toggle('top-tagSelector-toTwoLine', tagsIds.length > 5);\n\n\tif (props.mode === 'setter' && props.filters) {\n\t\tel.innerHTML = `<div>${htmlSetterSeveral}</div>`;\n\n\t\treturn;\n\t}\n\n\tel.innerHTML = '';\n\n\tif (!tagsIds.length && props.mode === 'filter') {\n\t\tconst elTagIcon = genElTagIcon({\n\t\t\tid: 'all',\n\t\t\tcolorId: '',\n\t\t\tname: useI18n().Common?.All_tags ?? '',\n\t\t\tstate: '',\n\t\t});\n\n\t\tel.append(elTagIcon);\n\t}\n\n\ttagsIds.forEach(tagId => {\n\t\tconst elTagIcon = genElTagIcon({\n\t\t\tid: genTagIdClear(tagId),\n\t\t\tcolorId: getTagById(tagId, props.tags)?.color_id ?? '',\n\t\t\tname: getTagById(tagId, props.tags)?.name ?? '',\n\t\t\tstate: genTagIdClear(tagId) === tagId ? 'selected' : 'excluded',\n\t\t});\n\n\t\tel.append(elTagIcon);\n\t});\n};\n\n/**\n * Сгенерировтаь элемент для открытия popup с выбором тегов\n *\n * Альтернатива TopTagSelecorTagIcon для работы вне vue\n */\nconst genElTagIcon = (props: TagIconProps) => {\n\tconst el = document.createElement('div');\n\n\tel.classList.add('top-tagSelector_tagIcon');\n\tel.classList.toggle('top-tagSelector-active', !!props.state);\n\tel.classList.toggle('top-tagSelector-excluded', props.state === 'excluded');\n\n\tel.dataset.tag_id = props.id;\n\tel.dataset.tag_color_id = props.colorId;\n\tel.title = props.name;\n\n\treturn el;\n};\n","import type { ComponentCustomProps } from 'vue';\n\nimport SelectorCompetitors from './selectorCompetitors/selectorCompetitors.vue';\nimport SelectorRegion from './selectorRegion/selectorRegion.vue';\n\nimport TagSelector from './tagSelector/tagSelector.vue';\nimport TagSelectorPopupOpener from './tagSelector/popupOpener/popupOpener.vue';\nimport TagSelectorTagIcon from './tagSelector/tagIcon/tagIcon.vue';\n\nexport const TopSelectorCompetitors = SelectorCompetitors as typeof SelectorCompetitors & ComponentCustomProps;\nexport { useItemsFromCompetitors } from './selectorCompetitors/composables';\n\nexport { findRegion, genSearcherByKey } from './selectorRegion/utils/utils';\nexport const TopSelectorRegion = SelectorRegion as typeof SelectorRegion & ComponentCustomProps;\n\nexport type { Emits as TopTagSelectorEmits, Tag, TagId, TagIdExclude } from './tagSelector/types';\nexport {\n\tgenElPopupOpener as genElTopTagSelectorPopupOpener,\n\trenderElPopupOpener as renderElTopTagSelectorPopupOpener,\n} from './tagSelector/utils/el';\nexport const TopTagSelector = TagSelector as typeof TagSelector & ComponentCustomProps;\nexport const TopTagSelectorPopupOpener = TagSelectorPopupOpener as typeof TagSelectorPopupOpener & ComponentCustomProps;\nexport const TopTagSelectorTagIcon = TagSelectorTagIcon as typeof TagSelectorTagIcon & ComponentCustomProps;\n"],"names":["props","__props","selectAllItem","vue","forms","dummyIndex","searchersNames","regionUndefined","searcherUndefined","regionAuto","searcherAuto","regionGlobal","genSearcherByKey","forFrequency","autoRegion","searchers","searcherByKey","genSearchersMapVolume","genSearchersMapCommon","getSearcherAuto","onlyEnabledRegions","forceSearchersKeys","searcher","searcherI","regionI","region","searcherKey","serarcherByKey","findRegion","searchRegion","findedRegion","useSelectSearcher","mapSearchers","i18n","optionBySearcherKey","res","option","utils_searchers","useSelectRegion","activeSearcherIndexed","regionIndex","_c","optionByRegionIndex","options","regionLabel","langLabel","newRegionIndex","optionByRegionIndex2","regionName","_a","oldOptionByRegionIndex","regionMatchLevel","index","title","regexpDevice","regionNameCompare","regionMatchLevelI","regionsIndexes","regionsIndexesSaved","useSelectorRegion","selectSearcher","allRegionsIndexes","compare","newSearcherKey","selectRegion","regionsNewSearcher","_b","regionsCurrentSearcher","_d","getSearcherKey","getSearcher","getRegionIndex","emit","__emit","getRegion","model","modelSingle","defaultKey","newModel","defaultIndex","all","newSearherKey","__expose","tagsDefaults","genTagIdExcluded","tagId","genTagIdClear","getTagById","tags","tag","tag2","elName","firefoxProps","inEdit","name2","editCancel","changeSelect","e","toState","name","id","filtersAction","tagsText","target","disabled","genTargetTagState","updateTargetModel","action","tagIdExcluded","tagsIds","tagId2","aIndex","a","bIndex","b","classString","onOpen","popupEvent","utils_dom","_e","ui","$tags","tagsSorted","elTag","tagSorted","tagIdA","tagIdB","onClose","useItemsFromCompetitors","competitors","projectId","competitor","genElPopupOpener","propsPopup","htmlSetterSeveral","el","elPopupOpenerRender","modelValue","renderElPopupOpener","elTagIcon","genElTagIcon","TopSelectorCompetitors","_sfc_main$5","TopSelectorRegion","_sfc_main$4","TopTagSelector","_sfc_main","TopTagSelectorPopupOpener","_sfc_main$1","TopTagSelectorTagIcon","_sfc_main$3"],"mappings":"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"}
1
+ {"version":3,"file":"project.amd.js","sources":["../../src/components/project/selectorCompetitors/selectorCompetitors.vue","../../src/components/project/selectorRegion/utils/consts.ts","../../src/components/project/selectorRegion/utils/utils.ts","../../src/components/project/selectorRegion/composables/selectSearcher.ts","../../src/components/project/selectorRegion/composables/selectRegion.ts","../../src/components/project/selectorRegion/composables/compare.ts","../../src/components/project/selectorRegion/composables/selectorRegion.ts","../../src/components/project/selectorRegion/selectorRegion.vue","../../src/components/project/tagSelector/tagsDefaults.ts","../../src/components/project/tagSelector/utils/utils.ts","../../src/components/project/tagSelector/popupListItem/tagPopupListItem.vue","../../src/components/project/tagSelector/popupOpener/popupOpener.vue","../../src/components/project/tagSelector/tagSelector.vue","../../src/components/project/selectorCompetitors/composables.ts","../../src/components/project/tagSelector/utils/el.ts","../../src/components/project/project.ts"],"sourcesContent":["<script setup lang=\"ts\">\r\nimport { computed } from 'vue';\r\nimport type { Props } from './selectorCompetitors';\r\nimport Core from '@/core/core/core';\r\nimport Button from '@/components/forms/button/button.vue';\r\nimport Popup from '@/components/popup/popup/popup.vue';\r\nimport ListItem from '@/components/popup/popup/listItem.vue';\r\nimport Menu from '@/components/formsExt/menu/menu.vue';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tshowSelectAllItem: true,\r\n});\r\nconst model = defineModel<Props['modelValue']>();\r\n\r\nconst selectAllItem = computed(() => {\r\n\tif (props.showSelectAllItem) {\r\n\t\treturn {\r\n\t\t\ticon: '',\r\n\t\t\ttitle: useI18n().Common.Select_all,\r\n\t\t\tvalue: 'all',\r\n\t\t\tcontent: '',\r\n\t\t};\r\n\t}\r\n});\r\n</script>\r\n\r\n<template>\r\n\t<div class=\"top-selectorCompetitors\">\r\n\t\t<Popup v-if=\"Core.state.isMobile\">\r\n\t\t\t<template #opener>\r\n\t\t\t\t<Button\r\n\t\t\t\t\tclass=\"top-selectorCompetitors_opener\"\r\n\t\t\t\t\tcolor=\"theme\"\r\n\t\t\t\t\ticon=\"\"\r\n\t\t\t\t\ticon2=\"\"\r\n\t\t\t\t>\r\n\t\t\t\t\t{{ items.find((item) => item.value === model?.[0])?.content }}\r\n\t\t\t\t</Button>\r\n\t\t\t</template>\r\n\r\n\t\t\t<template #contentList>\r\n\t\t\t\t<ListItem\r\n\t\t\t\t\tv-for=\"(item, index) in items\"\r\n\t\t\t\t\t:class=\"{\r\n\t\t\t\t\t\t'top-active': model?.includes(item.value)\r\n\t\t\t\t\t}\"\r\n\t\t\t\t\t:data-top-icon=\"item.icon\"\r\n\t\t\t\t\t:title=\"item.title\"\r\n\t\t\t\t\t@click=\"() => model = [item.value]\"\r\n\t\t\t\t>\r\n\t\t\t\t\t<span class=\"top-ellipsis1\">\r\n\t\t\t\t\t\t{{ item.content }}\r\n\t\t\t\t\t</span>\r\n\t\t\t\t</ListItem>\r\n\t\t\t</template>\r\n\t\t</Popup>\r\n\r\n\t\t<Menu\r\n\t\t\tv-else\r\n\t\t\tv-model=\"model\"\r\n\t\t\t:items=\"items\"\r\n\t\t\t:isMultiple=\"true\"\r\n\t\t\tstyling=\"bar\"\r\n\t\t\t:canBeEmptyMultiple=\"false\"\r\n\t\t\t:selectAllItem=\"selectAllItem\"\r\n\t\t/>\r\n\t</div>\r\n</template>\r\n\r\n<style>\r\n.top-selectorCompetitors_opener.top-button {\r\n\twidth: 100%;\r\n}\r\n</style>\r\n","import type { Region, SearcherIndexed } from '../selectorRegion';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\n\r\nexport const dummyIndex = -2;\r\n\r\nexport const searchersNames = {\r\n\t0: 'Yandex',\r\n\t1: 'Google',\r\n\t4: 'YouTube',\r\n\t5: 'Bing',\r\n\t7: 'Seznam',\r\n\t8: 'AppStore',\r\n\t9: 'GoogleStore',\r\n\t20: 'Yandex.com',\r\n\t21: 'Yandex.com.tr',\r\n};\r\n\r\nexport const regionUndefined: Region = {\r\n\tkey: dummyIndex,\r\n\tname: '--',\r\n\tindex: dummyIndex,\r\n};\r\n\r\nexport const searcherUndefined: SearcherIndexed = {\r\n\tkey: dummyIndex,\r\n\tname: '--',\r\n\tregions: [regionUndefined],\r\n\tregionByIndex: new Map([[dummyIndex, regionUndefined]]),\r\n};\r\n\r\nconst regionAuto: Region = {\r\n\tkey: dummyIndex,\r\n\tname: 'Autoselect',\r\n\tindex: dummyIndex,\r\n};\r\n\r\nconst searcherAuto: SearcherIndexed = {\r\n\tkey: dummyIndex,\r\n\tname: 'Autoselect',\r\n\tregions: [regionAuto],\r\n\tregionByIndex: new Map([[dummyIndex, regionAuto]]),\r\n};\r\n\r\nconst regionGlobal: Region = {\r\n\tcountryCode: '00',\r\n\tdepth: 1,\r\n\tdevice: 0,\r\n\tkey: -1,\r\n\tindex: -1,\r\n\tlang: 'ru',\r\n\tname: 'Without region',\r\n};\r\n\r\nexport const getRegionAuto = () => {\r\n\tregionAuto.name = useI18n().Common.Autoselect!;\r\n\r\n\treturn regionAuto;\r\n};\r\n\r\nexport const getSearcherAuto = () => {\r\n\tgetRegionAuto();\r\n\r\n\tsearcherAuto.name = useI18n().Common.Autoselect!;\r\n\tconsole.log(searcherAuto);\r\n\r\n\treturn searcherAuto;\r\n};\r\n\r\nexport const getRegionGlobal = () => {\r\n\tregionGlobal.name = useI18n().Keywords.Without_region!;\r\n\r\n\treturn regionGlobal;\r\n};\r\n","import type { Region, Searcher, SearcherByKey, SearcherIndexed } from '../selectorRegion';\r\nimport { dummyIndex, getRegionGlobal, getSearcherAuto, regionUndefined, searchersNames, searcherUndefined } from './consts';\r\n\r\n/**\r\n * Генерация Map ПС с Map регионов из массива searchers\r\n * - ключ для ПС - searcherKey\r\n * - ключ для региона - regionIndex\r\n *\r\n * Если поисковиков в списке нет, в список будет добавлен searcherUndefined\r\n *\r\n * Если регионов в списке нет, в список будет добавлен regionUndefined\r\n *\r\n * @param forFrequency - получить массив для просмотра частоты (или ставок)\r\n * @param autoRegion - добавить элемент с ключем -2, который в API заменяется на нужный ключ в зависимости от контекста\r\n * @param searchers - поисковики с регионами проекта, см.: get/projects_2/projects, show_searchers_and_regions = 1\r\n */\r\nexport const genSearcherByKey = (\r\n\tforFrequency: boolean = false,\r\n\tautoRegion: boolean = false,\r\n\tsearchers: Searcher[] = [],\r\n) => {\r\n\tlet searcherByKey: SearcherByKey;\r\n\r\n\tif (forFrequency) {\r\n\t\tsearcherByKey = genSearchersMapVolume(searchers);\r\n\t} else {\r\n\t\tsearcherByKey = genSearchersMapCommon(searchers);\r\n\t}\r\n\r\n\tif (autoRegion) searcherByKey.set(dummyIndex, getSearcherAuto());\r\n\tif (!searcherByKey.size) searcherByKey.set(dummyIndex, searcherUndefined);\r\n\r\n\treturn searcherByKey;\r\n};\r\n\r\n/**\r\n * Список ПС с регионами\r\n *\r\n * @param searchers\r\n * @param onlyEnabledRegions\r\n * @param forceSearchersKeys - ключи ПС, которые нееобходимо вывести в любом случае\r\n * @param forFrequency - для частоты будут выводиться только Яндекс, Google и Mail\r\n */\r\nconst genSearchersMapCommon = (\r\n\tsearchers: Searcher[],\r\n\tonlyEnabledRegions: boolean = true,\r\n\tforceSearchersKeys: Searcher['key'][] = [],\r\n\tforFrequency: boolean = false,\r\n) => {\r\n\tconst searcherByKey: Map<Searcher['key'], SearcherIndexed> = new Map();\r\n\r\n\t// настроенные ПС\r\n\tsearchers.forEach((searcher) => {\r\n\t\tif (!searcher.enabled) return;\r\n\t\tif (forFrequency && typeof searcher.key === 'number' && searcher.key > 1) return;\r\n\r\n\t\tconst searcherI = { ...searcher } as SearcherIndexed;\r\n\t\tsearcherI.regionByIndex = new Map();\r\n\r\n\t\tif (searcher.regions) {\r\n\t\t\tsearcher.regions.forEach((region: Region) => {\r\n\t\t\t\tif (onlyEnabledRegions && !region.enabled) return;\r\n\r\n\t\t\t\tconst regionI = { ...region };\r\n\t\t\t\tif (searcherI.regionByIndex) searcherI.regionByIndex.set(regionI.index, regionI);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (!searcherI.regionByIndex.size && !forceSearchersKeys.length) {\r\n\t\t\tsearcherI.regionByIndex.set(regionUndefined.index, regionUndefined);\r\n\t\t}\r\n\r\n\t\tif (typeof searcherI.key === 'number') searcherByKey.set(searcherI.key, searcherI);\r\n\t});\r\n\r\n\t// дополнительные ПС\r\n\tforceSearchersKeys.forEach((searcherKey) => {\r\n\t\tif (searcherByKey.has(searcherKey)) return;\r\n\r\n\t\tconst searcherI: SearcherIndexed = {\r\n\t\t\tkey: searcherKey,\r\n\t\t\tname: searchersNames[searcherKey],\r\n\t\t\tregions: [],\r\n\t\t\tregionByIndex: new Map(),\r\n\t\t};\r\n\r\n\t\tsearcherByKey.set(searcherI.key, searcherI);\r\n\t});\r\n\r\n\treturn searcherByKey;\r\n};\r\n\r\n/**\r\n * Список ПС с регионами для проверки частоты (Яндекс, Google, Mail если добавлен в проект)\r\n *\r\n * @param searchers\r\n */\r\nconst genSearchersMapVolume = (searchers: Searcher[]) => {\r\n\tconst serarcherByKey = genSearchersMapCommon(searchers, false, [0, 1], true);\r\n\r\n\t// в Mail нет регионов\r\n\tif (serarcherByKey.has(2)) {\r\n\t\tconst searcherMail = serarcherByKey.get(2);\r\n\t\tif (searcherMail) searcherMail.regionByIndex = new Map();\r\n\t}\r\n\r\n\t// добавление глобального региона\r\n\tserarcherByKey.forEach((searcher) => {\r\n\t\tif (!searcher.regionByIndex) return;\r\n\r\n\t\tconst region = { ...getRegionGlobal() };\r\n\t\tsearcher.regionByIndex.set(region.index, region);\r\n\t});\r\n\r\n\treturn serarcherByKey;\r\n};\r\n\r\n/**\r\n * Поиск региона по заданному критерию из списка поисковиков проекта\r\n *\r\n * @param forFrequency - поиск региона для просмотра частоты или ставок\r\n * @param searchRegion - объект с параметрами региона, который следует найти\r\n * @param searchers\r\n */\r\nexport const findRegion = (forFrequency: boolean, searchRegion: Partial<Region>, searchers: Searcher[] = []) => {\r\n\tconst searcherByKey = genSearcherByKey(forFrequency, false, searchers);\r\n\r\n\tlet findedRegion: Region | undefined;\r\n\r\n\t// поиск ПС\r\n\tsearcherByKey.forEach((searcher) => {\r\n\t\tif (searchRegion.searcher_key !== undefined && searchRegion.searcher_key != searcher.key) return;\r\n\t\tif (!searcher.regions) return;\r\n\r\n\t\t// поиск региона\r\n\t\tsearcher.regions.forEach((region) => {\r\n\t\t\tif (findedRegion) return;\r\n\r\n\t\t\tif (searchRegion.key !== undefined && searchRegion.key != region.key) return;\r\n\t\t\tif (searchRegion.index !== undefined && searchRegion.index != region.index) return;\r\n\r\n\t\t\tif (!forFrequency) {\r\n\t\t\t\tif (searchRegion.lang !== undefined && searchRegion.lang != region.lang) return;\r\n\t\t\t\tif (searchRegion.device !== undefined && searchRegion.device != region.device) return;\r\n\t\t\t}\r\n\r\n\t\t\tregion.searcher_key = searcher.key;\r\n\t\t\tfindedRegion = region;\r\n\r\n\t\t\treturn false;\r\n\t\t});\r\n\r\n\t\tif (findedRegion) return false;\r\n\t});\r\n\r\n\treturn findedRegion;\r\n};\r\n","import { computed, type ComputedRef, ref } from 'vue';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\nimport type { Props, SearcherByKey } from '../selectorRegion';\r\nimport type { Option, Options } from '@/components/forms/select/select';\r\nimport { dummyIndex } from '../utils/consts';\r\nimport { getSearcherGIcon } from '@/core/utils/searchers';\r\n\r\n/**\r\n * Создание и управление реактивными переменными для выбора ПС\r\n *\r\n * @param props - входные props компонента\r\n * @param mapSearchers - Map ПС (реактивная)\r\n */\r\nexport const useSelectSearcher = (\r\n\tprops: Props,\r\n\tmapSearchers: ComputedRef<SearcherByKey>,\r\n) => {\r\n\tconst i18n = useI18n();\r\n\r\n\t/**\r\n\t * Ключ выбранной поисковой системы\r\n\t */\r\n\tconst searcherKey = ref(mapSearchers.value.keys().next().value ?? dummyIndex);\r\n\r\n\t/**\r\n\t * Коллекция опций для выбора ПС\r\n\t */\r\n\tconst optionBySearcherKey = computed(() => {\r\n\t\tconst res: Options = new Map();\r\n\t\tmapSearchers.value.forEach((searcher) => {\r\n\t\t\tlet option: Option = {\r\n\t\t\t\tvalue: searcher.key,\r\n\t\t\t\ttitle: searcher.name,\r\n\t\t\t};\r\n\r\n\t\t\tif (props.addSearcherIcon) option.icon = getSearcherGIcon(searcher.key);\r\n\r\n\t\t\tres.set(searcher.key, option);\r\n\t\t});\r\n\r\n\t\t// добавить режим сравнения, если есть хотя бы одна ПС\r\n\t\tif (props.addCompare && !res.has(dummyIndex)) {\r\n\t\t\tconst dummyOption: Option = {\r\n\t\t\t\tvalue: '',\r\n\t\t\t\ttitle: '--------------------',\r\n\t\t\t\tdisabled: true,\r\n\t\t\t};\r\n\t\t\tres.set(dummyOption.value, dummyOption);\r\n\r\n\t\t\tconst compareOption: Option = {\r\n\t\t\t\tvalue: -1,\r\n\t\t\t\ttitle: i18n.Common.Compare!,\r\n\t\t\t};\r\n\t\t\tres.set(compareOption.value, compareOption);\r\n\t\t}\r\n\r\n\t\treturn res;\r\n\t});\r\n\r\n\treturn {\r\n\t\tsearcherKey,\r\n\t\toptionBySearcherKey,\r\n\t};\r\n};\r\n","import { computed, type ComputedRef, ref, watch } from 'vue';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\nimport { getDeviceGIcon, getLangLabel } from '@/core/utils/searchers';\r\nimport type { Option } from '@/components/forms/select/select';\r\nimport { dummyIndex } from '../utils/consts';\r\nimport type { Props, Region, SearcherIndexed } from '../selectorRegion';\r\n\r\n/**\r\n * Создание и управление реактивными переменными для выбора региона\r\n *\r\n * @param props - входные props компонента\r\n * @param activeSearcherIndexed - объект активной поисковой системы (реактивная)\r\n * @param regionsIndexes - входные индексы регионов/ПС\r\n */\r\nexport const useSelectRegion = (props: Props, activeSearcherIndexed: ComputedRef<SearcherIndexed>) => {\r\n\tconst i18n = useI18n();\r\n\r\n\t/**\r\n\t * Индекс выбранного региона\r\n\t */\r\n\tconst regionIndex = ref(dummyIndex);\r\n\r\n\tif (props.modelValue.length === 1) {\r\n\t\tregionIndex.value = props.modelValue[0];\r\n\t}\r\n\r\n\tif (regionIndex.value === dummyIndex) {\r\n\t\tif (props.forFrequency) {\r\n\t\t\t// в качетсве ключа используется region.key, а не region.index\r\n\t\t\tregionIndex.value = activeSearcherIndexed.value?.regionByIndex.values().next().value?.key ?? dummyIndex;\r\n\t\t} else {\r\n\t\t\tregionIndex.value = activeSearcherIndexed.value?.regionByIndex.keys().next().value ?? dummyIndex;\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Коллекция опций для выбора региона\r\n\t */\r\n\tconst optionByRegionIndex = computed(() => {\r\n\t\tconst options = new Map<number, Option>();\r\n\r\n\t\tactiveSearcherIndexed.value.regionByIndex?.forEach((region) => {\r\n\t\t\tlet regionLabel = region.name;\r\n\r\n\t\t\t// на частоту в текущей версии устройство и язык не влияют\r\n\t\t\t// обратите внимание, в качетсве ключа используется region.key, а не region.index\r\n\t\t\tif (props.forFrequency) {\r\n\t\t\t\tconst option: Option = {\r\n\t\t\t\t\tvalue: region.key,\r\n\t\t\t\t\ttitle: regionLabel,\r\n\t\t\t\t};\r\n\t\t\t\tif (!options.has(region.key)) options.set(region.key, option);\r\n\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (region.device) {\r\n\t\t\t\tregionLabel += ' (' + i18n.Common['Device_' + region.device] + ')';\r\n\t\t\t}\r\n\r\n\t\t\tconst langLabel = getLangLabel(activeSearcherIndexed.value.key || 0, region.lang ?? '');\r\n\t\t\tif (langLabel) regionLabel += ' / ' + langLabel;\r\n\r\n\t\t\tconst option: Option = {\r\n\t\t\t\tvalue: region.index,\r\n\t\t\t\ttitle: regionLabel,\r\n\t\t\t\ticon: region.device ? getDeviceGIcon(region.device) : undefined,\r\n\t\t\t};\r\n\r\n\t\t\toptions.set(region.index, option);\r\n\t\t});\r\n\r\n\t\treturn options;\r\n\t});\r\n\r\n\t/**\r\n\t * Выбор максимально похожего региона в новой коллекции регионов\r\n\t */\r\n\twatch(optionByRegionIndex, (optionByRegionIndex, oldOptionByRegionIndex) => {\r\n\t\tif (props.onlySearcher || regionIndex.value !== undefined && optionByRegionIndex.get(regionIndex.value)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet newRegionIndex = optionByRegionIndex.keys().next().value as Region['index'];\r\n\t\tif (regionIndex.value === dummyIndex || newRegionIndex === dummyIndex) {\r\n\t\t\tregionIndex.value = newRegionIndex;\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet regionName = (oldOptionByRegionIndex?.get(regionIndex.value) as Option)?.title || '';\r\n\t\tlet regionMatchLevel = -1;\r\n\t\tfor (const [index, option] of optionByRegionIndex.entries()) {\r\n\t\t\tconst title = (option as Option).title;\r\n\r\n\t\t\tif (typeof title !== 'string' || typeof index === 'string') {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// полное совпадение\r\n\t\t\tif (title === regionName) {\r\n\t\t\t\tnewRegionIndex = index;\r\n\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tconst regexpDevice = new RegExp(` \\\\((${i18n.Common['Device_1']}|${i18n.Common['Device_2']})\\\\)`);\r\n\t\t\tlet regionNameCompare = regionName;\r\n\t\t\tlet regionMatchLevelI = 3;\r\n\r\n\t\t\t// без устройства\r\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\r\n\t\t\t\tregionNameCompare = regionName.replace(/^[^a-zа-я]/i, '').replace(regexpDevice, '');\r\n\r\n\t\t\t\tregionMatchLevelI--;\r\n\t\t\t}\r\n\r\n\t\t\t// без языка\r\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\r\n\t\t\t\tregionNameCompare = regionName.replace(/ \\/.*/, '');\r\n\r\n\t\t\t\tregionMatchLevelI--;\r\n\t\t\t}\r\n\r\n\t\t\t// без устройства и без языка\r\n\t\t\tif (title.indexOf(regionNameCompare) === -1) {\r\n\t\t\t\tregionNameCompare = regionName.replace(/ \\/.*/, '');\r\n\t\t\t\tregionNameCompare = regionNameCompare.replace(/^[^a-zа-я]/i, '').replace(regexpDevice, '');\r\n\r\n\t\t\t\tregionMatchLevelI--;\r\n\t\t\t}\r\n\r\n\t\t\tif (title.indexOf(regionNameCompare) === -1) continue;\r\n\t\t\tif (regionMatchLevelI <= regionMatchLevel) continue;\r\n\r\n\t\t\tregionMatchLevel = regionMatchLevelI;\r\n\t\t\tnewRegionIndex = index;\r\n\t\t}\r\n\r\n\t\tregionIndex.value = newRegionIndex;\r\n\t});\r\n\r\n\treturn {\r\n\t\tregionIndex,\r\n\t\toptionByRegionIndex,\r\n\t};\r\n};\r\n","import { type ComputedRef, ref, watch } from 'vue';\r\nimport type { Props, SearcherByKey } from '../selectorRegion';\r\n\r\n/**\r\n * Создание и управление реактивными переменными для сравнения\r\n *\r\n * @param props - входные props компонента\r\n * @param searcherByKey - Map ПС (реактивная)\r\n * @param allRegionsIndexes - Все доступные индексы регионов (реактивная)\r\n */\r\nexport const useCompare = (props: Props, searcherByKey: ComputedRef<SearcherByKey>, allRegionsIndexes: ComputedRef<Set<number>>) => {\r\n\t/**\r\n\t * Индексы регионов/ПС в сравнение\r\n\t */\r\n\tconst regionsIndexes = ref([] as number[]);\r\n\r\n\t/**\r\n\t * Загрузка индексов регионов для сравнения\r\n\t *\r\n\t * Если в modelValue передано несколько регионов, они будут установлены как выбранные для сравнения\r\n\t */\r\n\tconst compareLoad = () => {\r\n\t\tif (props.onlySearcher && searcherByKey.value) {\r\n\t\t\tregionsIndexes.value = Array.from(searcherByKey.value.keys());\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet regionsIndexesSaved: Props['modelValue'] = [];\r\n\r\n\t\tif (props.modelValue.length > 1) {\r\n\t\t\tregionsIndexesSaved = [...props.modelValue];\r\n\t\t} else {\r\n\t\t\ttry {\r\n\t\t\t\t// загрузить индексы регионов, если они были сохранены\r\n\t\t\t\tregionsIndexesSaved = JSON.parse(\r\n\t\t\t\t\tlocalStorage.getItem('ui:project:regionSelector' + props.projectId + ':regionsIndexes') as string,\r\n\t\t\t\t) ?? [];\r\n\t\t\t} catch (e) {\r\n\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// убрать из сравнения регионы, которых нет в props.searchers\r\n\t\tif (regionsIndexesSaved.length) {\r\n\t\t\tregionsIndexesSaved = regionsIndexesSaved.filter((regionIndex) => {\r\n\t\t\t\treturn allRegionsIndexes.value.has(regionIndex);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// если не сохранено ни одного региона, выбрать все регионы проекта\r\n\t\tif (!regionsIndexesSaved.length) {\r\n\t\t\tregionsIndexesSaved = Array.from(allRegionsIndexes.value);\r\n\t\t}\r\n\r\n\t\tregionsIndexes.value = [...regionsIndexesSaved];\r\n\t};\r\n\r\n\t/**\r\n\t * Сохранение выбранных регионов\r\n\t */\r\n\tconst compareSave = () => {\r\n\t\tif (regionsIndexes.value.length) {\r\n\t\t\tlocalStorage.setItem('ui:project:regionSelector:' + props.projectId + ':regionsIndexes', JSON.stringify(regionsIndexes.value));\r\n\t\t} else {\r\n\t\t\tlocalStorage.removeItem('ui:project:regionSelector:' + props.projectId + ':regionsIndexes');\r\n\t\t}\r\n\t};\r\n\r\n\twatch(regionsIndexes, () => {\r\n\t\tcompareSave();\r\n\t});\r\n\r\n\tif (props.addCompare) {\r\n\t\t// if (props.compareRegionsIndexes?.length) {\r\n\t\t// \tcompareRegionsIndexes.value = [...props.compareRegionsIndexes];\r\n\t\t// } else {\r\n\t\t// \tcompareLoad();\r\n\t\t// }\r\n\r\n\t\tcompareLoad();\r\n\t}\r\n\r\n\treturn {\r\n\t\tregionsIndexes,\r\n\t};\r\n};\r\n","import { computed, watch } from 'vue';\r\nimport { findRegion, genSearcherByKey } from '../utils/utils';\r\nimport { dummyIndex, searcherUndefined } from '../utils/consts';\r\nimport type { Props, Region, SearcherIndexed } from '../selectorRegion';\r\nimport { useSelectSearcher } from './selectSearcher';\r\nimport { useSelectRegion } from './selectRegion';\r\nimport { useCompare } from './compare';\r\n\r\n/**\r\n * Создание и управления рективными переменными компонента\r\n *\r\n * @param props - входные props компонента\r\n */\r\nexport const useSelectorRegion = (props: Props) => {\r\n\tconst searcherByKey = computed(() => {\r\n\t\treturn genSearcherByKey(props.forFrequency, props.autoRegion, props.searchers);\r\n\t});\r\n\r\n\tconst activeSearcherIndexed = computed(() => {\r\n\t\treturn searcherByKey.value.get(selectSearcher.searcherKey.value) || searcherUndefined;\r\n\t});\r\n\r\n\t/**\r\n\t * Все индексы регионов из mapSearchers\r\n\t */\r\n\tconst allRegionsIndexes = computed(() => {\r\n\t\tconst regionsIndexes = new Set<number>();\r\n\r\n\t\tsearcherByKey.value.forEach((searcher) => {\r\n\t\t\tsearcher.regions?.forEach((region) => {\r\n\t\t\t\tif (region.index === -1) return;\r\n\t\t\t\tif (region.index === dummyIndex) return;\r\n\r\n\t\t\t\tregionsIndexes.add(region.index);\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\treturn regionsIndexes;\r\n\t});\r\n\r\n\tconst selectSearcher = useSelectSearcher(props, searcherByKey);\r\n\tconst selectRegion = useSelectRegion(props, activeSearcherIndexed);\r\n\tconst compare = useCompare(props, searcherByKey, allRegionsIndexes);\r\n\r\n\t// контроль за внешним изменением списка ПС\r\n\twatch(searcherByKey, () => {\r\n\t\t// возможные значения для сравнения регионов/пс\r\n\t\tif (props.onlySearcher) {\r\n\t\t\tcompare.regionsIndexes.value = Array.from(searcherByKey.value.keys());\r\n\t\t} else {\r\n\t\t\tcompare.regionsIndexes.value = compare.regionsIndexes.value.filter(regionIndex => {\r\n\t\t\t\treturn allRegionsIndexes.value.has(regionIndex);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (selectSearcher.searcherKey.value === -1) return;\r\n\r\n\t\tlet newSearcherKey = searcherByKey.value.keys().next().value;\r\n\r\n\t\tsearcherByKey.value.forEach((searcher) => {\r\n\t\t\t// определить выбранную ПС\r\n\t\t\tif (props.onlySearcher && searcher.key === selectSearcher.searcherKey.value) {\r\n\t\t\t\tnewSearcherKey = selectSearcher.searcherKey.value;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (\r\n\t\t\t\tselectRegion.regionIndex.value &&\r\n\t\t\t\tsearcher.regionByIndex?.has(selectRegion.regionIndex.value)\r\n\t\t\t) {\r\n\t\t\t\tnewSearcherKey = searcher.key;\r\n\t\t\t}\r\n\r\n\t\t\t// выбрать первую ПС с выбранным регионом\r\n\t\t\tif (!props.onlySearcher) {\r\n\t\t\t\tlet regionsNewSearcher: SearcherIndexed['regionByIndex'] | undefined;\r\n\r\n\t\t\t\tif (newSearcherKey !== undefined) {\r\n\t\t\t\t\tregionsNewSearcher = searcherByKey.value.get(newSearcherKey)?.regionByIndex;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tconst regionsCurrentSearcher = searcherByKey.value.get(searcher.key)?.regionByIndex;\r\n\t\t\t\tif (\r\n\t\t\t\t\tregionsNewSearcher?.has(dummyIndex) &&\r\n\t\t\t\t\t!regionsCurrentSearcher?.has(dummyIndex)\r\n\t\t\t\t) {\r\n\t\t\t\t\tnewSearcherKey = searcher.key;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t// if (props.addCompare && !selectSearcher.optionBySearcherKey.value.has(dummyIndex)) {\r\n\t\t// \tif (!selectRegion.regionIndex.value && compare.regionsIndexes.value?.length) newSearcherKey = -1;\r\n\t\t// }\r\n\r\n\t\t// if (props.onlySearcher && selectRegion.regionIndex.value !== dummyIndex) newSearcherKey = selectRegion.regionIndex.value;\r\n\r\n\t\tif (newSearcherKey !== undefined) {\r\n\t\t\tselectSearcher.searcherKey.value = newSearcherKey;\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\tselectRegion.regionIndex.value !== undefined &&\r\n\t\t\t!(activeSearcherIndexed.value?.regionByIndex)?.has(selectRegion.regionIndex.value)\r\n\t\t) {\r\n\t\t\tselectRegion.regionIndex.value = activeSearcherIndexed.value?.regions?.keys().next().value as number;\r\n\t\t}\r\n\t}, { immediate: true });\r\n\r\n\tconst getSearcherKey = () => {\r\n\t\tif (selectSearcher.searcherKey.value === -1 || selectSearcher.searcherKey.value === dummyIndex) return;\r\n\r\n\t\treturn selectSearcher.searcherKey.value;\r\n\t};\r\n\r\n\tconst getRegionIndex = () => {\r\n\t\tif (props.onlySearcher) return;\r\n\r\n\t\tif (selectRegion.regionIndex.value === dummyIndex) return;\r\n\r\n\t\tlet res: Region['index'] | undefined = selectRegion.regionIndex.value;\r\n\r\n\t\t// в качестве ключа используется region.key\r\n\t\tif (props.forFrequency) {\r\n\t\t\tconst regionKey = selectRegion.regionIndex.value;\r\n\t\t\tconst region = findRegion(props.forFrequency, { searcher_key: getSearcherKey(), key: regionKey } as Region, props.searchers);\r\n\r\n\t\t\tres = region?.index;\r\n\t\t}\r\n\r\n\t\treturn res;\r\n\t};\r\n\r\n\t/**\r\n\t * Получить выбранную ПС\r\n\t */\r\n\tconst getSearcher = () => {\r\n\t\tconst searcherKey = getSearcherKey();\r\n\t\tif (searcherKey === undefined) return;\r\n\r\n\t\treturn searcherByKey.value.get(searcherKey);\r\n\t};\r\n\r\n\t/**\r\n\t * Получить выбранный регион\r\n\t */\r\n\tconst getRegion = () => {\r\n\t\tconst regionIndex = getRegionIndex();\r\n\t\tif (regionIndex === undefined) return;\r\n\r\n\t\treturn getSearcher()?.regionByIndex?.get(regionIndex);\r\n\t};\r\n\r\n\treturn {\r\n\t\tselectSearcher,\r\n\t\tselectRegion,\r\n\t\tcompare,\r\n\r\n\t\tsearcherByKey,\r\n\t\tallRegionsIndexes,\r\n\r\n\t\tgetSearcher,\r\n\t\tgetRegion,\r\n\t};\r\n};\r\n","<script setup lang=\"ts\">\r\nimport { watch } from 'vue';\r\nimport type { Emits, Props, Region } from './selectorRegion';\r\nimport Select from '@/components/forms/select/select.vue';\r\nimport Button from '@/components/forms/button/button.vue';\r\nimport { useSelectorRegion } from './composables/selectorRegion';\r\nimport { dummyIndex } from './utils/consts';\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\tsearchers: () => [],\r\n\t// compareRegionsIndexes: () => [],\r\n\taddSearcherIcon: true,\r\n\taddRegionIcon: true,\r\n\taddChanger: true,\r\n});\r\n\r\nconst model = defineModel<Props['modelValue']>({ required: true });\r\nconst modelSingle = defineModel<Props['modelValueSingle']>('modelValueSingle');\r\n\r\nconst emit = defineEmits<Emits>();\r\n\r\nconst {\r\n\tselectSearcher,\r\n\tselectRegion,\r\n\tcompare,\r\n\r\n\tsearcherByKey,\r\n\tallRegionsIndexes,\r\n\r\n\tgetSearcher,\r\n\tgetRegion,\r\n} = useSelectorRegion(props);\r\n\r\nconst onClickCompare = () => {\r\n\t// ### TODO: сделать выбор регионов через UI (сейчас в UI выбор региона не работает)\r\n\tif (window['fieldTemplates'] && window['fieldTemplates']?.openSelectorRegions) {\r\n\t\twindow['fieldTemplates'].openSelectorRegions(\r\n\t\t\tsearcherByKey.value,\r\n\t\t\tcompare.regionsIndexes.value,\r\n\t\t\t(regionsIndexes: Region['index'][]) => compare.regionsIndexes.value = regionsIndexes,\r\n\t\t);\r\n\t\treturn;\r\n\t}\r\n\r\n\temit('compareRegions', searcherByKey.value);\r\n};\r\n\r\nwatch([selectRegion.regionIndex, selectSearcher.searcherKey, compare.regionsIndexes], () => {\r\n\tif (selectSearcher.searcherKey.value === -1 && compare.regionsIndexes.value.length) {\r\n\t\tif (JSON.stringify(model.value) === JSON.stringify(compare.regionsIndexes.value)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmodel.value = [...compare.regionsIndexes.value];\r\n\t} else {\r\n\t\tmodel.value = [props.onlySearcher ? selectSearcher.searcherKey.value : selectRegion.regionIndex.value];\r\n\t}\r\n\r\n\t// регионов нет\r\n\tif (!props.onlySearcher && !allRegionsIndexes.value.size) {\r\n\t\tselectSearcher.searcherKey.value = dummyIndex;\r\n\t}\r\n});\r\n\r\nif (modelSingle.value) {\r\n\twatch(modelSingle, () => {\r\n\t\tmodel.value = [modelSingle.value!];\r\n\t}, { immediate: true });\r\n}\r\n\r\nwatch(model, () => {\r\n\tif (model.value[0]) {\r\n\t\tmodelSingle.value = model.value[0];\r\n\t}\r\n\r\n\t// проверка входных данных v-model на корректность\r\n\tif (props.onlySearcher) {\r\n\t\tif (\r\n\t\t\t!model.value.length ||\r\n\t\t\tmodel.value.length === 1 && !searcherByKey.value.has(model.value[0])\r\n\t\t) {\r\n\t\t\tlet defaultKey: number | undefined = searcherByKey.value.keys().next().value;\r\n\r\n\t\t\tif (defaultKey !== undefined) {\r\n\t\t\t\tmodel.value = [defaultKey];\r\n\t\t\t}\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (\r\n\t\t\tmodel.value.length > 1 &&\r\n\t\t\tJSON.stringify(model.value) !== JSON.stringify(compare.regionsIndexes.value)\r\n\t\t) {\r\n\t\t\tmodel.value = [...compare.regionsIndexes.value];\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\t} else {\r\n\t\tlet newModel = [...new Set(model.value)];\r\n\r\n\t\tlet defaultIndex = searcherByKey.value.values().next().value?.regionByIndex?.keys().next().value;\r\n\t\tif (props.forFrequency) {\r\n\t\t\tdefaultIndex = searcherByKey.value.values().next().value?.regionByIndex?.values().next().value?.key;\r\n\t\t}\r\n\r\n\t\tif (!newModel.length) {\r\n\t\t\tif (defaultIndex !== undefined) {\r\n\t\t\t\tnewModel.push(defaultIndex);\r\n\t\t\t}\r\n\t\t} else if (newModel.length === 1) {\r\n\t\t\tlet all = allRegionsIndexes.value;\r\n\r\n\t\t\tif (props.forFrequency) {\r\n\t\t\t\tall = new Set();\r\n\t\t\t\tsearcherByKey.value.forEach((searcher) => {\r\n\t\t\t\t\tsearcher.regionByIndex.forEach((region) => {\r\n\t\t\t\t\t\tif (region.index === -1) return;\r\n\t\t\t\t\t\tif (region.index === dummyIndex) return;\r\n\r\n\t\t\t\t\t\tall.add(region.key);\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tif (!all.has(newModel[0]) && newModel[0] !== -2) {\r\n\t\t\t\tnewModel = [];\r\n\t\t\t\tif (defaultIndex !== undefined) {\r\n\t\t\t\t\tnewModel.push(defaultIndex);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tnewModel = newModel.filter(index => allRegionsIndexes.value.has(index));\r\n\t\t\tif (!newModel.length && defaultIndex !== undefined) {\r\n\t\t\t\tnewModel.push(defaultIndex);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (JSON.stringify(model.value) !== JSON.stringify(newModel)) {\r\n\t\t\tmodel.value = newModel;\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n\r\n\t// входные данные v-model совпадают с внутренними значениями\r\n\tif (\r\n\t\tmodel.value.length === 1 &&\r\n\t\tmodel.value[0] === (props.onlySearcher ? selectSearcher.searcherKey.value : selectRegion.regionIndex.value)\r\n\t) {\r\n\t\treturn;\r\n\t}\r\n\r\n\t// if (\r\n\t// \tmodel.value.length > 1 &&\r\n\t// \tselectorSearcher.searcherKey.value === -1 &&\r\n\t// \tJSON.stringify(model.value) === JSON.stringify(selectorCompare.regionsIndexes.value)\r\n\t// ) {\r\n\t// \treturn;\r\n\t// }\r\n\r\n\t// обновление regionIndex, searcherKey, selectorCompare.regionsIndexes\r\n\tif (props.onlySearcher) {\r\n\t\t// if (!model.value.length) {\r\n\t\t// \tselectorSearcher.searcherKey.value = dummyIndex;\r\n\t\t//\r\n\t\t// \treturn;\r\n\t\t// }\r\n\r\n\t\tif (model.value.length === 1) {\r\n\t\t\tselectSearcher.searcherKey.value = model.value[0];\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tselectSearcher.searcherKey.value = -1;\r\n\r\n\t\treturn;\r\n\t} else {\r\n\t\t// if (!model.value.length) {\r\n\t\t// \tselectorSearcher.searcherKey.value = dummyIndex;\r\n\t\t// \tselectorRegion.regionIndex.value = dummyIndex;\r\n\t\t//\r\n\t\t// \treturn;\r\n\t\t// }\r\n\r\n\t\tif (model.value.length === 1 && selectSearcher.searcherKey.value !== -1) {\r\n\t\t\tselectRegion.regionIndex.value = model.value[0];\r\n\r\n\t\t\tlet newSearherKey: number | undefined;\r\n\t\t\tfor (const searcher of searcherByKey.value.values()) {\r\n\t\t\t\tfor (const region of searcher.regionByIndex.values()) {\r\n\t\t\t\t\tconst currentRegionIndex = props.forFrequency ? region.key : region.index;\r\n\t\t\t\t\tif (currentRegionIndex === selectRegion.regionIndex.value) {\r\n\t\t\t\t\t\tnewSearherKey = searcher.key;\r\n\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (newSearherKey !== undefined) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (newSearherKey !== undefined) {\r\n\t\t\t\tselectSearcher.searcherKey.value = newSearherKey;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tselectSearcher.searcherKey.value = -1;\r\n\t\t\tcompare.regionsIndexes.value = [...model.value];\r\n\t\t}\r\n\t}\r\n}, { immediate: true });\r\n\r\ndefineExpose({\r\n\tgetSearcher,\r\n\tgetRegion,\r\n});\r\n</script>\r\n\r\n<template>\r\n\t<div\r\n\t\t:class=\"{\r\n\t\t\t'top-selectorRegion': true,\r\n\t\t\t'top-selectorRegion-onlySearcher': onlySearcher,\r\n\t\t}\"\r\n\t>\r\n\t\t<Select\r\n\t\t\t:options=\"selectSearcher.optionBySearcherKey.value\"\r\n\t\t\tv-model=\"selectSearcher.searcherKey.value\"\r\n\t\t\tname=\"searcher_key\"\r\n\t\t\t:addChanger=\"addChanger\"\r\n\t\t/>\r\n\r\n\t\t<Select\r\n\t\t\tv-if=\"!onlySearcher && selectSearcher.searcherKey.value !== -1\"\r\n\t\t\tclass=\"top-select-region\"\r\n\t\t\t:options=\"selectRegion.optionByRegionIndex.value\"\r\n\t\t\tv-model=\"selectRegion.regionIndex.value\"\r\n\t\t\t:name=\"forFrequency ? 'region_key' : 'region_index'\"\r\n\t\t\t:addChanger=\"addChanger\"\r\n\t\t\t:data-top-icon=\"addRegionIcon ? '' : undefined\"\r\n\t\t/>\r\n\r\n\t\t<Button\r\n\t\t\tv-if=\"addCompare && !onlySearcher && selectSearcher.searcherKey.value === -1\"\r\n\t\t\tname=\"compare\"\r\n\t\t\t@click=\"onClickCompare\"\r\n\t\t\t:data-count-compare-regions-indexes=\"compare.regionsIndexes.value.length\"\r\n\t\t>\r\n\t\t\t{{ $i18n.Common.Selected_regions }}\r\n\t\t</Button>\r\n\t</div>\r\n</template>\r\n\r\n<style>\r\n@import \"./styles/searcherColors.css\";\r\n\r\n.top-selectorRegion {\r\n\twidth: 320px;\r\n\tdisplay: inline-flex;\r\n\tvertical-align: middle;\r\n}\r\n\r\n.top-selectorRegion > .top-select {\r\n\tflex-grow: 1;\r\n}\r\n\r\n.top-selectorRegion > .top-select:focus-within {\r\n\tz-index: 4;\r\n}\r\n\r\n.top-selectorRegion > .top-select > .top-select_select:hover,\r\n.top-selectorRegion > .top-select > .top-select_select.top-error {\r\n\tz-index: 1;\r\n}\r\n\r\n.top-selectorRegion > .top-select-searcher_key {\r\n\twidth: 120px;\r\n\tmax-width: 140px;\r\n\tmargin-right: -1px;\r\n}\r\n\r\n.top-selectorRegion > .top-select-region > select {\r\n\tborder-top-left-radius: 0;\r\n\tborder-bottom-left-radius: 0;\r\n}\r\n\r\n.top-selectorRegion > .top-select-region {\r\n\t--top-icon-size: 20px;\r\n\t--top-icon-color: var(--color-text-primary-1);\r\n\r\n\t--top-icon2-size: 20px;\r\n\t--top-icon2-color: var(--color-text-primary-1);\r\n}\r\n\r\n.top-selectorRegion > .top-select-region[data-top-icon][data-top-icon2] {\r\n\t--top-icon2-size: 16px;\r\n}\r\n\r\n.top-selectorRegion > .top-select-region[data-top-icon][data-top-icon2]:after {\r\n\ttext-indent: -4px;\r\n}\r\n\r\n.top-selectorRegion > [name=\"compare\"] {\r\n\tborder-top-left-radius: 0;\r\n\tborder-bottom-left-radius: 0;\r\n\tflex-grow: 1;\r\n}\r\n\r\n.top-selectorRegion > [name=\"compare\"]:after {\r\n\tcontent: \"(\" attr(data-count-compare-regions-indexes) \")\";\r\n\tmargin: 0 0 0 6px;\r\n}\r\n\r\n.top-selectorRegion:not(.top-selectorRegion-onlySearcher) > .top-select-searcher_key > select {\r\n\tborder-top-right-radius: 0;\r\n\tborder-bottom-right-radius: 0;\r\n\tmargin-right: 0;\r\n}\r\n\r\n.top-selectorRegion:not(.top-selectorRegion-onlySearcher) > .top-select-searcher_key[data-value=\"-1\"] > select {\r\n\tborder-right: none;\r\n}\r\n\r\n.top-selectorRegion-onlySearcher {\r\n\twidth: 120px;\r\n}\r\n</style>\r\n","import type { Tag } from './types';\r\n\r\nexport default [\r\n\t{\r\n\t\tid: '1',\r\n\t\tname: 'Without Tag',\r\n\t\tcolor_id: '1',\r\n\t},\r\n\t{\r\n\t\tid: '2',\r\n\t\tname: 'Red',\r\n\t\tcolor_id: '2',\r\n\t},\r\n\t{\r\n\t\tid: '3',\r\n\t\tname: 'Orange',\r\n\t\tcolor_id: '3',\r\n\t},\r\n\t{\r\n\t\tid: '4',\r\n\t\tname: 'Yellow',\r\n\t\tcolor_id: '4',\r\n\t},\r\n\t{\r\n\t\tid: '5',\r\n\t\tname: 'Blue',\r\n\t\tcolor_id: '5',\r\n\t},\r\n\t{\r\n\t\tid: '6',\r\n\t\tname: 'Purple',\r\n\t\tcolor_id: '6',\r\n\t},\r\n\t{\r\n\t\tid: '7',\r\n\t\tname: 'Green',\r\n\t\tcolor_id: '7',\r\n\t},\r\n\t{\r\n\t\tid: '8',\r\n\t\tname: 'Magenta',\r\n\t\tcolor_id: '8',\r\n\t},\r\n\t{\r\n\t\tid: '9',\r\n\t\tname: 'Dark blue',\r\n\t\tcolor_id: '9',\r\n\t},\r\n\t{\r\n\t\tid: '10',\r\n\t\tname: 'Turquoise',\r\n\t\tcolor_id: '10',\r\n\t},\r\n] as Tag[];\r\n","import type { Props as TagSelectorOpenerProps, TagSelectorTarget } from '../popupOpener/types';\r\nimport type { Tag, TagIdExclude } from '../types';\r\n\r\n/**\r\n * Полуичить значение исключения тега tagId\r\n */\r\nexport const genTagIdExcluded = (tagId: Tag['id']): TagIdExclude => {\r\n\treturn '-' + tagId as TagIdExclude;\r\n};\r\n\r\n/**\r\n * Вернуть чистый tagId без exclude флага\r\n */\r\nexport const genTagIdClear = (tagId: Tag['id'] | TagIdExclude) => {\r\n\tif (tagId[0] === '-') return tagId.substring(1) as Tag['id'];\r\n\r\n\treturn tagId as Tag['id'];\r\n};\r\n\r\n/**\r\n * Получить инфомрацию о теге по его id\r\n */\r\nexport const getTagById = (tagId: Tag['id'] | TagIdExclude, tags: TagSelectorOpenerProps['tags']) => {\r\n\ttagId = genTagIdClear(tagId);\r\n\r\n\tconst tag = tags.find(tag => tag.id === tagId);\r\n\tif (!tag) return;\r\n\r\n\treturn tag;\r\n};\r\n","<script setup lang=\"ts\">\r\nimport { computed, nextTick, ref } from 'vue';\r\nimport type { Emits, Props } from './types';\r\nimport TopTagIcon from '../tagIcon/tagIcon.vue';\r\nimport TopPopupListItem from '@/components/popup/popup/listItem.vue';\r\n\r\nconst props = defineProps<Props>();\r\nconst emit = defineEmits<Emits>();\r\n\r\nconst name = defineModel<Props['name']>('name', {\r\n\trequired: true,\r\n});\r\n\r\nconst elName = ref<HTMLElement | null>(null);\r\n\r\n/**\r\n * @todo Удалить через пол года после выхода версии firefox с поддержкой contenteditable plaintext-only, включая бета версии\r\n */\r\nconst firefoxProps = computed(() => {\r\n\tif (navigator.userAgent.indexOf('Firefox') != -1) {\r\n\r\n\t\treturn {\r\n\t\t\tcontenteditable: inEdit.value,\r\n\t\t\tonpaste: (event: Event) => event.preventDefault(),\r\n\t\t};\r\n\t}\r\n\r\n\treturn {};\r\n});\r\n\r\n/**\r\n * Включен режим редактирвоания\r\n */\r\nconst inEdit = ref(false);\r\n\r\n/**\r\n * Включить режим редактирование\r\n */\r\nconst turnToEdit = async () => {\r\n\tinEdit.value = true;\r\n\r\n\tawait nextTick();\r\n\r\n\telName.value?.focus();\r\n};\r\n\r\n/**\r\n * Применить редактирование\r\n */\r\nconst editCommit = () => {\r\n\tconst name = elName.value?.innerText;\r\n\tif (!name) return editCancel();\r\n\r\n\tif (elName.value) elName.value.innerText = name;\r\n\r\n\tinEdit.value = false;\r\n\r\n\temit('update:name', name);\r\n};\r\n\r\n/**\r\n * Отменить редактирование\r\n */\r\nconst editCancel = async () => {\r\n\tif (elName.value) elName.value.innerText = props.name;\r\n\r\n\tinEdit.value = false;\r\n};\r\n\r\n/**\r\n * Применить выбор\r\n */\r\nconst changeSelect = (e: MouseEvent) => {\r\n\t// в режиме редактирования выбор не применяется\r\n\tif (inEdit.value) return;\r\n\r\n\t// тег запрещено выбирать\r\n\tif (props.disabled) return;\r\n\r\n\tlet toState: Props['state'] = 'selected';\r\n\r\n\tif (props.canExclude) {\r\n\t\tif (e.ctrlKey || e.metaKey) {\r\n\t\t\ttoState = 'excluded';\r\n\t\t}\r\n\t}\r\n\r\n\tif (props.state == toState) {\r\n\t\ttoState = '';\r\n\t}\r\n\r\n\tif (toState === '') emit('unselect');\r\n\tif (toState === 'selected') emit('select');\r\n\tif (toState === 'excluded') emit('exclude');\r\n};\r\n</script>\r\n\r\n<template>\r\n\t<TopPopupListItem\r\n\t\t:class=\"{\r\n\t\t\t'top-tagSelector_tagListItem': true,\r\n\t\t\t'top-tagSelector_tagListItem-inEdit': inEdit,\r\n\t\t\t'top-tagSelector_tagListItem-disabled': disabled,\r\n\t\t\t'top-tagSelector_tagListItem-canExclude': canExclude,\r\n\t\t\t'top-tagSelector-active': !!state,\r\n\t\t\t'top-tagSelector-excluded': state === 'excluded'\r\n\t\t}\"\r\n\t\t@click.stop=\"changeSelect\"\r\n\t>\r\n\t\t<TopTagIcon\r\n\t\t\t:id\r\n\t\t\t:name\r\n\t\t\t:colorId\r\n\t\t\t:state\r\n\t\t/>\r\n\r\n\t\t<span\r\n\t\t\tref=\"elName\"\r\n\t\t\tclass=\"top-tagSelector_tagListItemName\"\r\n\t\t\t:contenteditable=\"inEdit ? 'plaintext-only' : false\"\r\n\t\t\t:=\"firefoxProps\"\r\n\t\t\t@keydown.enter.stop=\"editCommit\"\r\n\t\t\t@keydown.esc.stop=\"editCancel\"\r\n\t\t>\r\n\t\t\t{{ name }}\r\n\t\t</span>\r\n\r\n\t\t<template v-if=\"editable\">\r\n\t\t\t<span\r\n\t\t\t\tv-if=\"!inEdit\"\r\n\t\t\t\tdata-top-icon=\"\"\r\n\t\t\t\tclass=\"top-tagSelector_edit\"\r\n\t\t\t\t@click=\"turnToEdit\"\r\n\t\t\t></span>\r\n\r\n\t\t\t<span\r\n\t\t\t\tv-else\r\n\t\t\t\tdata-top-icon=\"\"\r\n\t\t\t\tclass=\"top-tagSelector_edit\"\r\n\t\t\t\t@click.stop=\"editCommit\"\r\n\t\t\t></span>\r\n\t\t</template>\r\n\t</TopPopupListItem>\r\n</template>\r\n\r\n<style>\r\n.top-tagSelector_tagListItem.top-popup_listItem {\r\n\tpadding-top: var(--top-padding-2) !important;\r\n\tpadding-bottom: var(--top-padding-2) !important;\r\n\tgap: 10px;\r\n}\r\n\r\n.top-tagSelector_tagListItemName {\r\n\tborder-radius: var(--top-radius-1);\r\n\twidth: 120px;\r\n\tpadding: 4px 2px;\r\n\tmargin: -4px -2px;\r\n\ttext-overflow: ellipsis;\r\n\toverflow: hidden;\r\n\tflex-grow: 1;\r\n}\r\n\r\n/* редактирование */\r\n.top-tagSelector_edit {\r\n\t--top-icon-size: 18px;\r\n\t--top-icon-color: var(--color-text-3);\r\n\r\n\twidth: 20px;\r\n\tflex-grow: 0;\r\n}\r\n\r\n.top-tagSelector_edit:before {\r\n\tline-height: 0;\r\n}\r\n\r\n.top-tagSelector_edit { opacity: 0; }\r\n.top-tagSelector_edit:hover {\r\n\t--top-icon-color: var(--color-text-primary);\r\n}\r\n\r\n.top-tagSelector_tagListItem:hover .top-tagSelector_edit,\r\n.top-tagSelector_tagListItem-inEdit .top-tagSelector_edit {\r\n\tcursor: pointer;\r\n\topacity: 1;\r\n}\r\n\r\n.top-tagSelector_tagListItem-inEdit {\r\n\tbackground: var(--color-layout-front-3) !important;\r\n\toutline: 1px dashed var(--color-line-2);\r\n\toutline-offset: -1px;\r\n}\r\n\r\n.top-tagSelector_tagListItem-inEdit .top-tagSelector_tagListItemName {\r\n\tcursor: text;\r\n\tbackground: var(--color-layout-front-1);\r\n}\r\n\r\n/* disabled */\r\n.top-tagSelector_tagListItem-disabled {\r\n\tcursor: not-allowed !important;\r\n\topacity: 0.85;\r\n}\r\n.top-tagSelector_tagListItem-disabled:hover {\r\n\tbackground: inherit;\r\n}\r\n.top-tagSelector_tagListItem-disabled [data-tag_id] {\r\n\topacity: 0.6;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport type { Props, TagSelectorTarget } from './types';\r\nimport TopPopupOpener from '../../../popup/popup/opener.vue';\r\nimport TopButton from '@/components/forms/button/button.vue';\r\nimport { genTagIdClear, getTagById } from '../utils/utils';\r\nimport TopTagIcon from '../tagIcon/tagIcon.vue';\r\n\r\ndefineOptions({\r\n\tinheritAttrs: false,\r\n});\r\n\r\nconst props = defineProps<Props>();\r\n\r\nconst model = defineModel<Props['modelValue']>({\r\n\trequired: true,\r\n});\r\n\r\nconst component = props.useTopButton ? TopButton : 'div';\r\nconst componentSlotName = props.useTopButton ? 'html' : 'default';\r\n\r\nconst topTagSelectorTarget: TagSelectorTarget = {\r\n\tmodel,\r\n\tmode: props.mode,\r\n\ttargetId: props.targetId,\r\n\tfilters: props.filters,\r\n\tpayload: props.payload,\r\n};\r\n</script>\r\n\r\n<template>\r\n\t<TopPopupOpener :id>\r\n\t\t<component\r\n\t\t\t:is=\"component\"\r\n\t\t\t:class=\"{\r\n\t\t\t\t'top-tagSelector': true,\r\n\t\t\t\t'top-tagSelector-filter': props.mode === 'filter',\r\n\t\t\t\t'top-tagSelector-setter_single': props.mode === 'setter' && !filters,\r\n\t\t\t\t'top-tagSelector-setter_several': props.mode === 'setter' && filters,\r\n\t\t\t\t'top-tagSelector-selectedOne': !model.length || model.length === 1,\r\n\t\t\t\t'top-tagSelector-toTwoLine': model.length > 5,\r\n\t\t\t}\"\r\n\t\t\tcolor=\"theme\"\r\n\t\t\tstyling=\"\"\r\n\t\t\tv-top-data:topTagSelectorTarget=\"topTagSelectorTarget\"\r\n\t\t\t:=$attrs\r\n\t\t>\r\n\t\t\t<template #[componentSlotName]>\r\n\t\t\t\t<TopTagIcon\r\n\t\t\t\t\tv-if=\"!model.length && mode === 'filter'\"\r\n\t\t\t\t\tid=\"all\"\r\n\t\t\t\t\tcolorId=\"\"\r\n\t\t\t\t\t:name=\"$i18n.Common.All_tags ?? ''\"\r\n\t\t\t\t\tstate=\"\"\r\n\t\t\t\t/>\r\n\r\n\t\t\t\t<!-- Массовое редактирование -->\r\n\t\t\t\t<div v-if=\"mode === 'setter' && filters\">\r\n\t\t\t\t\t<slot></slot>\r\n\t\t\t\t</div>\r\n\r\n\t\t\t\t<!-- Список тегов -->\r\n\t\t\t\t<TopTagIcon\r\n\t\t\t\t\tv-else\r\n\t\t\t\t\tv-for=\"tagId in model\"\r\n\t\t\t\t\t:id=\"genTagIdClear(tagId)\"\r\n\t\t\t\t\t:colorId=\"getTagById(tagId, tags)?.color_id ?? ''\"\r\n\t\t\t\t\t:name=\"getTagById(tagId, tags)?.name ?? ''\"\r\n\t\t\t\t\t:state=\"genTagIdClear(tagId) === tagId ? 'selected' : 'excluded'\"\r\n\t\t\t\t/>\r\n\t\t\t</template>\r\n\t\t</component>\r\n\t</TopPopupOpener>\r\n</template>\r\n\r\n<style>\r\n.top-tagSelector {\r\n\tcursor: pointer;\r\n\tmin-width: 0;\r\n\twhite-space: nowrap;\r\n\tjustify-content: left;\r\n}\r\n\r\n.top-tagSelector.top-button {\r\n\twidth: 112px;\r\n\tvertical-align: middle;\r\n}\r\n\r\n.top-tagSelector.top-button.top-select_arrow {\r\n\twidth: calc(112px + 20px);\r\n}\r\n\r\n.top-tagSelector-filter {\r\n\tgap: var(--top-gap-1);\r\n}\r\n\r\n/* все теги в фильтре */\r\n.top-tagSelector-filter [data-tag_id=\"all\"] {\r\n\tmargin-left: 0;\r\n}\r\n.top-tagSelector-filter [data-tag_id=\"all\"]:before {\r\n\tborder: none;\r\n\tmargin-left: 3px;\r\n\topacity: 0.5;\r\n}\r\n\r\n/* фильтр по одному тегу */\r\n.top-tagSelector-filter.top-tagSelector-selectedOne [data-tag_id]:after {\r\n\tcontent: attr(title);\r\n\tmargin-left: 20px;\r\n\tmin-width: 74px;\r\n\ttext-align: left;\r\n\tline-height: 1.2;\r\n\ttext-overflow: ellipsis;\r\n\toverflow: hidden;\r\n}\r\n\r\n.top-tagSelector-filter.top-tagSelector-selectedOne [data-tag_id=\"all\"]:after {\r\n\tmargin-left: 0;\r\n}\r\n\r\n/* фильтр по многим тегам */\r\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine {\r\n\tflex-wrap: wrap;\r\n\talign-content: center;\r\n}\r\n\r\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine [data-tag_id] {\r\n\t--top-tag-selector-size: 8px;\r\n}\r\n\r\n.top-button.top-tagSelector-filter.top-tagSelector-toTwoLine [data-tag_id]:nth-child(5) {\r\n\tmargin-right: 5px;\r\n}\r\n\r\n/* установка тегов */\r\n.top-tagSelector-setter_single {\r\n\tposition: relative;\r\n\tdisplay: flex !important; flex-direction: column; flex-wrap: wrap; align-items: stretch !important;\r\n}\r\n\r\n.top-tagSelector-setter_single [data-tag_id] {\r\n\twidth: auto; min-height: 20%; min-width: 50%;\r\n\tflex: 1 1 auto;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport { computed, reactive, ref, shallowRef, watch } from 'vue';\r\n\r\nimport Core from '@/core/core/core';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\nimport { storage } from '@/core/utils/dom';\r\nimport { debounce } from '@/core/utils/lodash';\r\n\r\nimport type { Option } from '@/components/forms/select/select';\r\nimport TopSelect from '@/components/forms/select/select.vue';\r\n\r\nimport TopButton from '@/components/forms/button/button.vue';\r\n\r\nimport type { PopupEvent } from '@/components/popup/popup/popup';\r\nimport TopPopup from '../../popup/popup/popup.vue';\r\nimport TopPopupListItem from '../../popup/popup/listItem.vue';\r\n\r\nimport type { Emits, FiltersAction, Props, Tag } from './types';\r\nimport tagsDefaults from './tagsDefaults';\r\nimport { genTagIdExcluded } from './utils/utils';\r\n\r\nimport type { Props as TagListItemProps } from './popupListItem/types';\r\nimport TopTagListItem from './popupListItem/tagPopupListItem.vue';\r\n\r\nimport type { TagSelectorTarget } from './popupOpener/types';\r\nimport TopTagSelectorPopupOpener from './popupOpener/popupOpener.vue';\r\n\r\nconst i18n = useI18n();\r\n\r\nconst props = withDefaults(defineProps<Props>(), {\r\n\ttagsMax: 10,\r\n\trequiredForSetter: true,\r\n\temitDelay: 500,\r\n});\r\n\r\n/**\r\n * Выбранные теги кнопки в этом компоненте\r\n *\r\n * Редактирвоание ведется только через `editTarget.model`\r\n */\r\nconst model = defineModel<Props['modelValue']>({\r\n\trequired: true,\r\n});\r\n\r\n/**\r\n * Список тегов\r\n */\r\nconst tags = defineModel<Tag[]>('tags', {\r\n\tdefault: reactive(tagsDefaults),\r\n});\r\n\r\nconst emit = defineEmits<Emits>();\r\n\r\nconst emitDebounce: typeof emit = debounce((name, e) => {\r\n\temit(name, e);\r\n}, props.emitDelay);\r\n\r\n// требуется сразу указать один тег\r\nif (props.singleMode && !model.value.length) {\r\n\tmodel.value = [tags.value[0].id];\r\n}\r\n\r\nconst id = props.id ?? 'top-popup-id-' + Math.random() + '';\r\n\r\nconst filtersAction = ref<FiltersAction>('add');\r\n\r\n/**\r\n * Сгенерировать опции для выбора дейсвтия массого редактирования\r\n */\r\nconst genFiltersActionOptions = () => {\r\n\tconst tagsText = ' ' + i18n.Common.Tags?.toLowerCase();\r\n\r\n\tconst res = new Map<FiltersAction, Option>();\r\n\tres.set('add', { value: 'add', title: i18n.Common.Add + tagsText });\r\n\tres.set('replace', { value: 'replace', title: i18n.Common.Replace + tagsText });\r\n\tres.set('delete', { value: 'delete', title: i18n.Common.Delete + tagsText });\r\n\r\n\treturn res;\r\n};\r\n\r\n/**\r\n * Целевой объект редактирвоания тегов\r\n *\r\n * Определяется кнопкой, которая открыла popup выбора тегов\r\n */\r\nlet target = shallowRef<TagSelectorTarget>({\r\n\tmodel,\r\n\tmode: 'filter',\r\n\ttargetId: undefined,\r\n\tfilters: undefined,\r\n\tpayload: undefined,\r\n});\r\n\r\nwatch(model, () => {\r\n\temitDebounce('selector', model.value);\r\n});\r\n\r\n/**\r\n * Можно ли выбрать еще теги\r\n */\r\nconst disabled = computed(() => {\r\n\tif (target.value.mode !== 'setter') return;\r\n\r\n\tif (!props.maxTagsForSetter) return;\r\n\r\n\t// массовая смена тегов, количество тегов в результате узнать невозможно\r\n\tif (target.value.filters) return;\r\n\r\n\treturn target.value.model.value.length >= props.maxTagsForSetter;\r\n});\r\n\r\nconst genTargetTagState = (tagId: Tag['id'] | 'all'): TagListItemProps['state'] => {\r\n\tif (tagId !== 'all') {\r\n\t\tif (target.value.model.value.includes(tagId)) return 'selected';\r\n\r\n\t\tif (target.value.model.value.includes(genTagIdExcluded(tagId))) return 'excluded';\r\n\t}\r\n\r\n\t// Все теги, ни один из тегов не выбран\r\n\tif (tagId === 'all' && !target.value.model.value.length) return 'selected';\r\n\r\n\treturn '';\r\n};\r\n\r\nconst updateTargetModel = (tagId: Tag['id'], action: 'unselect' | 'select' | 'exclude') => {\r\n\tconst tagIdExcluded = genTagIdExcluded(tagId);\r\n\r\n\tlet tagsIds = target.value.model.value.filter(modelTagId => modelTagId !== tagId && modelTagId !== tagIdExcluded);\r\n\r\n\tif (action === 'select') tagsIds.push(tagId);\r\n\tif (action === 'exclude') tagsIds.push(tagIdExcluded);\r\n\r\n\t// режим редактирвоания тегов одного объекта с требованием указать хотя бы один тег\r\n\tif (target.value.mode === 'setter' && target.value.targetId !== undefined && props.requiredForSetter) {\r\n\t\t// нельзя снимать выделение со всех тегов\r\n\t\tif (!tagsIds.length) {\r\n\t\t\ttagsIds.push('1');\r\n\t\t}\r\n\r\n\t\t// при первом выборе сразу снять тег \"Без тега\"\r\n\t\tif (tagsIds.length === 2 && target.value.model.value.length === 1 && target.value.model.value[0] === '1') {\r\n\t\t\ttagsIds = tagsIds.filter((tagId) => tagId !== '1');\r\n\t\t}\r\n\t}\r\n\r\n\t// режим выбора одного тега\r\n\tif (props.singleMode && !target.value.filters) {\r\n\t\t// нужно указать хотя бы один тег\r\n\t\tif (!tagsIds.length) {\r\n\t\t\ttagsIds = target.value.model.value;\r\n\t\t}\r\n\r\n\t\tif (tagsIds.length > 1) {\r\n\t\t\ttagsIds = [tagsIds[tagsIds.length - 1]];\r\n\t\t}\r\n\t}\r\n\r\n\t// всегда выводить теги в порядке, указанном в настройках tags\r\n\ttagsIds.sort((a, b) => {\r\n\t\tif (!props.tags) return 0;\r\n\r\n\t\tconst aIndex = props.tags.findIndex((tag) => tag.id === a);\r\n\t\tconst bIndex = props.tags.findIndex((tag) => tag.id === b);\r\n\r\n\t\treturn aIndex - bIndex;\r\n\t});\r\n\r\n\ttarget.value.model.value = tagsIds;\r\n\r\n\tif (target.value.mode === 'setter' && target.value.targetId !== undefined) {\r\n\t\temitDebounce('setter', {\r\n\t\t\ttagsIds: tagsIds as Tag['id'][],\r\n\t\t\ttargetId: target.value.targetId,\r\n\t\t\tpayload: target.value.payload,\r\n\t\t});\r\n\t}\r\n};\r\n\r\nconst classString = computed(() => {\r\n\tlet res = 'top-tagSelector_popup';\r\n\r\n\tif (target.value.mode === 'filter') res += ' top-tagSelector_popup-filter';\r\n\tif (target.value.mode === 'setter') res += ' top-tagSelector_popup-setter';\r\n\r\n\treturn res;\r\n});\r\n\r\n/**\r\n * Добавить тег\r\n */\r\nconst addTag = () => {\r\n\tconst tagName = prompt('', 'New tag');\r\n\tif (!tagName || tagName === 'New tag') return;\r\n\r\n\tconst tagId = tags.value.length + 1;\r\n\r\n\ttags.value.push({\r\n\t\tid: String(tagId) as Tag['id'],\r\n\t\tname: tagName,\r\n\t\tcolor_id: String((tagId - 1) % 10 + 1) as Tag['color_id'],\r\n\t});\r\n\r\n\temit('tagsChanged', tags.value);\r\n};\r\n\r\nconst onOpen = (popupEvent: PopupEvent) => {\r\n\t// popup открыт другой кнопкой c другим modelValue, для редактирвоания объектов\r\n\ttarget.value = storage(popupEvent.elPopupOpener, 'topTagSelectorTarget');\r\n\tif (!target.value) throw new Error('Open popup TopTagSelector required v-data:topTagSelectorTarget');\r\n\r\n\t// при начале массовой установки тегов сбросить состояние формы\r\n\tif (target.value.filters) {\r\n\t\tfiltersAction.value = 'add';\r\n\t\ttarget.value.model.value = [];\r\n\t}\r\n\r\n\tif (!Core.$?.ui['sortable']) {\r\n\t\tconsole.info('Для работы сортировки требуется глобальная загрузка jQuery UI Sortable');\r\n\r\n\t\treturn;\r\n\t}\r\n\r\n\tif (!Core.state.isMobile && !Core.state.isMobileUA && tags.value) {\r\n\t\t$(popupEvent.elPopup).sortable({\r\n\t\t\titems: 'li:has([data-tag_id]:not([data-tag_id=\"all\"]))',\r\n\r\n\t\t\t/**\r\n\t\t\t * @todo Удалить `[contenteditable=\"true\"]` через пол года после выхода версии firefox с поддержкой contenteditable plaintext-only, включая бета версии\r\n\t\t\t */\r\n\t\t\tcancel: '[contenteditable=\"plaintext-only\"], [contenteditable=\"true\"]',\r\n\r\n\t\t\tdistance: 10,\r\n\t\t\tstop: function (_e, ui) {\r\n\t\t\t\tif (!tags.value) return;\r\n\r\n\t\t\t\tconst $tags = $(ui.item).parent().find('[data-tag_id]');\r\n\r\n\t\t\t\tconst tagsSorted: Tag['id'][] = [];\r\n\t\t\t\t$tags.each((_index, elTag) => {\r\n\t\t\t\t\tif (!tags.value) return;\r\n\r\n\t\t\t\t\tconst tagId = $(elTag).attr('data-tag_id') as Tag['id'];\r\n\t\t\t\t\ttagsSorted.push(tagId);\r\n\t\t\t\t});\r\n\r\n\t\t\t\ttags.value.sort((tagIdA, tagIdB) => {\r\n\t\t\t\t\tconst a = tagsSorted.findIndex(tagSorted => tagSorted === tagIdA.id);\r\n\t\t\t\t\tconst b = tagsSorted.findIndex(tagSorted => tagSorted === tagIdB.id);\r\n\r\n\t\t\t\t\treturn a - b;\r\n\t\t\t\t});\r\n\r\n\t\t\t\temitDebounce('tagsChanged', tags.value);\r\n\t\t\t},\r\n\t\t});\r\n\t}\r\n};\r\n\r\nconst onClose = (popupEvent: PopupEvent) => {\r\n\tif (!Core.$?.ui['sortable']) return;\r\n\r\n\tif ($(popupEvent.elPopup).data('ui-sortable')) {\r\n\t\t$(popupEvent.elPopup).sortable('destroy');\r\n\t}\r\n};\r\n</script>\r\n\r\n<template>\r\n\t<TopTagSelectorPopupOpener\r\n\t\tclass=\"top-select_arrow\"\r\n\t\tv-model=\"model\"\r\n\t\t:id\r\n\t\t:tags\r\n\t\tmode=\"filter\"\r\n\t\tuseTopButton\r\n\t/>\r\n\r\n\t<TopPopup\r\n\t\t:id\r\n\t\t:class=\"classString\"\r\n\t\t@open=\"onOpen($event)\"\r\n\t\t@close=\"onClose($event)\"\r\n\t\t:transition-duration=\"50\"\r\n\t>\r\n\t\t<!-- Массовое редактирвоание-->\r\n\t\t<template #header v-if=\"target.mode === 'setter' && target.filters\">\r\n\t\t\t<TopSelect\r\n\t\t\t\tv-model=\"filtersAction\"\r\n\t\t\t\t:options=\"genFiltersActionOptions()\"\r\n\t\t\t/>\r\n\t\t</template>\r\n\r\n\t\t<template #footer v-if=\"target.mode === 'setter' && target.filters\">\r\n\t\t\t<TopButton color=\"theme\">\r\n\t\t\t\t{{ $i18n.Common.Cancel }}\r\n\t\t\t</TopButton>\r\n\r\n\t\t\t<TopButton\r\n\t\t\t\t@click=\"emitDebounce('setter', {\r\n\t\t\t\t\ttagsIds: target.model.value as Tag['id'][],\r\n\t\t\t\t\tfilters: target.filters,\r\n\t\t\t\t\tfiltersAction,\r\n\t\t\t\t\tpayload: target.payload,\r\n\t\t\t\t})\"\r\n\t\t\t>\r\n\t\t\t\t{{ filtersAction === 'add' ? $i18n.Common['Add'] : '' }}\r\n\t\t\t\t{{ filtersAction === 'replace' ? $i18n.Common['Replace'] : '' }}\r\n\t\t\t\t{{ filtersAction === 'delete' ? $i18n.Common['Remove'] : '' }}\r\n\t\t\t</TopButton>\r\n\t\t</template>\r\n\r\n\t\t<template #contentList>\r\n\t\t\t<TopTagListItem\r\n\t\t\t\tv-if=\"target.mode === 'filter' && !singleMode\"\r\n\t\t\t\tid=\"all\"\r\n\t\t\t\tcolorId=\"\"\r\n\t\t\t\t:name=\"$i18n.Common.All_tags ?? ''\"\r\n\t\t\t\t:state=\"target.model.value.length ? '' : 'selected'\"\r\n\t\t\t\t@select=\"target.model.value = []\"\r\n\t\t\t/>\r\n\r\n\t\t\t<TopTagListItem\r\n\t\t\t\tv-for=\"tag in tags\"\r\n\t\t\t\t:key=\"tag.id\"\r\n\t\t\t\t:id=\"tag.id\"\r\n\t\t\t\t:colorId=\"tag.color_id\"\r\n\t\t\t\t:name=\"tag.name\"\r\n\t\t\t\t:state=\"genTargetTagState(tag.id)\"\r\n\t\t\t\t:canExclude=\"target.mode === 'filter' && !singleMode\"\r\n\t\t\t\t:editable=\"tagsEditable\"\r\n\t\t\t\t:disabled=\"disabled && genTargetTagState(tag.id) === ''\"\r\n\t\t\t\t@unselect=\"updateTargetModel(tag.id, 'unselect')\"\r\n\t\t\t\t@select=\"updateTargetModel(tag.id, 'select')\"\r\n\t\t\t\t@exclude=\"updateTargetModel(tag.id, 'exclude')\"\r\n\t\t\t\t@update:name=\"tag.name = $event as string, emitDebounce('tagsChanged', tags);\"\r\n\t\t\t/>\r\n\r\n\t\t\t<TopPopupListItem\r\n\t\t\t\tv-if=\"tagsEditable && tags.length < tagsMax && tags.length < 20\"\r\n\t\t\t\tdata-top-icon=\"\"\r\n\t\t\t\t@click.stop=\"addTag\"\r\n\t\t\t>\r\n\t\t\t\t{{ $i18n.Common.Add }}\r\n\t\t\t</TopPopupListItem>\r\n\t\t</template>\r\n\t</TopPopup>\r\n</template>\r\n\r\n<style>\r\n.top-tagSelector_popup .top-popup {\r\n\tuser-select: none;\r\n\tmin-width: 220px !important;\r\n\ttext-align: left;\r\n}\r\n\r\n.top-tagSelector_popup .top-popup_header .top-select{\r\n\tflex-grow: 1;\r\n}\r\n</style>\r\n","import type { MaybeRefOrGetter } from 'vue';\r\nimport { computed, toValue } from 'vue';\r\nimport type { Item } from '@/components/project/selectorCompetitors/selectorCompetitors';\r\nimport type { Competitor } from '@/components/project/selectorCompetitors/types/competitor';\r\n\r\nexport const useItemsFromCompetitors = (competitors: MaybeRefOrGetter<Competitor[]>, projectId: MaybeRefOrGetter<number>) => {\r\n\treturn computed(() => {\r\n\t\tconst activeCompetitors = toValue(competitors).filter(competitor => competitor.on >= 0 || competitor.id === projectId);\r\n\r\n\t\tconst items: Item[] = activeCompetitors.map(competitor => {\r\n\t\t\treturn {\r\n\t\t\t\tvalue: competitor.id,\r\n\t\t\t\ttitle: competitor.url + ` [${competitor.id}]`,\r\n\t\t\t\ticon: competitor.id === toValue(projectId) ? '' : '',\r\n\t\t\t\tcontent: competitor.name,\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\treturn items;\r\n\t});\r\n};\r\n","import { isRef, type Ref, ref, unref, watch } from 'vue';\r\nimport { useI18n } from '@/core/plugins/i18n';\r\nimport { storage } from '@/core/utils/dom';\r\nimport TopPopupWorker from '@/components/popup/lib/worker';\r\nimport type { OpenerProps as PopupOpenerProps } from '@/components/popup/popup/popup';\r\nimport type { Props as TagSelectorOpenerProps, TagSelectorTarget } from '../popupOpener/types';\r\nimport type { Props as TagIconProps } from '../tagIcon/types';\r\nimport { genTagIdClear, getTagById } from '../utils/utils';\r\n\r\n/**\r\n * Сгенерировтаь элемент для открытия popup с выбором тегов\r\n *\r\n * Альтернатива TopTagSelecorPopupOpener для работы вне vue\r\n *\r\n * Требует монтирования компонента TopTagSelecor\r\n */\r\nexport const genElPopupOpener = (\r\n\tprops: TagSelectorOpenerProps & { modelValue: TagSelectorOpenerProps['modelValue'] | Ref<TagSelectorOpenerProps['modelValue']> },\r\n\tpropsPopup?: Partial<PopupOpenerProps>,\r\n\thtmlSetterSeveral?: string,\r\n): HTMLElement => {\r\n\tif (!propsPopup) propsPopup = { id: props.id };\r\n\r\n\tpropsPopup.id = props.id;\r\n\r\n\tconst el = TopPopupWorker.genElPopupOpener('div', propsPopup as PopupOpenerProps);\r\n\r\n\tel.classList.add('top-tagSelector');\r\n\tif (props.useTopButton) el.classList.add('top-button', 'top-color_theme');\r\n\tif (props.mode === 'filter') el.classList.add('top-tagSelector-filter');\r\n\tif (props.mode === 'setter' && !props.filters) el.classList.add('top-tagSelector-setter_single');\r\n\tif (props.mode === 'setter' && props.filters) el.classList.add('top-tagSelector-setter_several');\r\n\r\n\t// прокcи клик: lazy connect\r\n\tel.onclick = (e) => {\r\n\t\te.preventDefault();\r\n\t\te.stopPropagation();\r\n\r\n\t\tel.onclick = null;\r\n\r\n\t\tconst model = ref(props.modelValue);\r\n\r\n\t\tconst target: TagSelectorTarget = {\r\n\t\t\tmodel,\r\n\t\t\tmode: props.mode,\r\n\t\t\ttargetId: props.targetId,\r\n\t\t\tfilters: props.filters,\r\n\t\t\tpayload: props.payload,\r\n\t\t};\r\n\r\n\t\tstorage(el, 'topTagSelectorTarget', target);\r\n\r\n\t\tdelete el.dataset.topPopupDisabled;\r\n\r\n\t\tif (!isRef(props.modelValue)) {\r\n\t\t\twatch(model, () => {\r\n\t\t\t\tprops.modelValue = model.value;\r\n\r\n\t\t\t\telPopupOpenerRender(el, props, htmlSetterSeveral);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// выполнение клика\r\n\t\tel.click();\r\n\t};\r\n\r\n\tif (isRef(props.modelValue)) {\r\n\t\twatch(props.modelValue, () => elPopupOpenerRender(el, props, htmlSetterSeveral));\r\n\t} else {\r\n\t\tstorage(el, 'topTagSelectorRender', (modelValue: TagSelectorOpenerProps['modelValue']) => {\r\n\t\t\tprops.modelValue = modelValue;\r\n\r\n\t\t\tconst target = storage(el, 'topTagSelectorTarget');\r\n\t\t\tif (target) target.model.value = modelValue;\r\n\r\n\t\t\telPopupOpenerRender(el, props, htmlSetterSeveral);\r\n\t\t});\r\n\t}\r\n\r\n\telPopupOpenerRender(el, props, htmlSetterSeveral);\r\n\r\n\treturn el;\r\n};\r\n\r\n/**\r\n * Вызвать перерисовку элемента, который был создан через genElPopupOpener()\r\n *\r\n * Работет только для элементов не с реактивным modelValue\r\n */\r\nexport const renderElPopupOpener = (el: HTMLElement, modelValue: TagSelectorOpenerProps['modelValue']) => {\r\n\tstorage(el, 'topTagSelectorRender')?.(modelValue);\r\n};\r\n\r\n/**\r\n * Отрисовать TopTagSelecorPopupOpener\r\n */\r\nconst elPopupOpenerRender = (el, props: TagSelectorOpenerProps, htmlSetterSeveral?: string) => {\r\n\tconst tagsIds = unref(props.modelValue);\r\n\r\n\tel.classList.toggle('top-tagSelector-selectedOne', !tagsIds.length || tagsIds.length === 1);\r\n\tel.classList.toggle('top-tagSelector-toTwoLine', tagsIds.length > 5);\r\n\r\n\tif (props.mode === 'setter' && props.filters) {\r\n\t\tel.innerHTML = `<div>${htmlSetterSeveral}</div>`;\r\n\r\n\t\treturn;\r\n\t}\r\n\r\n\tel.innerHTML = '';\r\n\r\n\tif (!tagsIds.length && props.mode === 'filter') {\r\n\t\tconst elTagIcon = genElTagIcon({\r\n\t\t\tid: 'all',\r\n\t\t\tcolorId: '',\r\n\t\t\tname: useI18n().Common?.All_tags ?? '',\r\n\t\t\tstate: '',\r\n\t\t});\r\n\r\n\t\tel.append(elTagIcon);\r\n\t}\r\n\r\n\ttagsIds.forEach(tagId => {\r\n\t\tconst elTagIcon = genElTagIcon({\r\n\t\t\tid: genTagIdClear(tagId),\r\n\t\t\tcolorId: getTagById(tagId, props.tags)?.color_id ?? '',\r\n\t\t\tname: getTagById(tagId, props.tags)?.name ?? '',\r\n\t\t\tstate: genTagIdClear(tagId) === tagId ? 'selected' : 'excluded',\r\n\t\t});\r\n\r\n\t\tel.append(elTagIcon);\r\n\t});\r\n};\r\n\r\n/**\r\n * Сгенерировтаь элемент для открытия popup с выбором тегов\r\n *\r\n * Альтернатива TopTagSelecorTagIcon для работы вне vue\r\n */\r\nconst genElTagIcon = (props: TagIconProps) => {\r\n\tconst el = document.createElement('div');\r\n\r\n\tel.classList.add('top-tagSelector_tagIcon');\r\n\tel.classList.toggle('top-tagSelector-active', !!props.state);\r\n\tel.classList.toggle('top-tagSelector-excluded', props.state === 'excluded');\r\n\r\n\tel.dataset.tag_id = props.id;\r\n\tel.dataset.tag_color_id = props.colorId;\r\n\tel.title = props.name;\r\n\r\n\treturn el;\r\n};\r\n","import type { ComponentCustomProps } from 'vue';\r\n\r\nimport SelectorCompetitors from './selectorCompetitors/selectorCompetitors.vue';\r\nimport SelectorRegion from './selectorRegion/selectorRegion.vue';\r\n\r\nimport TagSelector from './tagSelector/tagSelector.vue';\r\nimport TagSelectorPopupOpener from './tagSelector/popupOpener/popupOpener.vue';\r\nimport TagSelectorTagIcon from './tagSelector/tagIcon/tagIcon.vue';\r\n\r\nexport const TopSelectorCompetitors = SelectorCompetitors as typeof SelectorCompetitors & ComponentCustomProps;\r\nexport { useItemsFromCompetitors } from './selectorCompetitors/composables';\r\n\r\nexport { findRegion, genSearcherByKey } from './selectorRegion/utils/utils';\r\nexport const TopSelectorRegion = SelectorRegion as typeof SelectorRegion & ComponentCustomProps;\r\n\r\nexport type { Emits as TopTagSelectorEmits, Tag, TagId, TagIdExclude } from './tagSelector/types';\r\nexport {\r\n\tgenElPopupOpener as genElTopTagSelectorPopupOpener,\r\n\trenderElPopupOpener as renderElTopTagSelectorPopupOpener,\r\n} from './tagSelector/utils/el';\r\nexport const TopTagSelector = TagSelector as typeof TagSelector & ComponentCustomProps;\r\nexport const TopTagSelectorPopupOpener = TagSelectorPopupOpener as typeof TagSelectorPopupOpener & ComponentCustomProps;\r\nexport const TopTagSelectorTagIcon = TagSelectorTagIcon as typeof TagSelectorTagIcon & ComponentCustomProps;\r\n"],"names":["selectAllItem","vue","props","forms","searchersNames","regionUndefined","dummyIndex","searcherUndefined","regionAuto","searcherAuto","regionGlobal","getRegionAuto","genSearcherByKey","forFrequency","autoRegion","searchers","searcherByKey","genSearchersMapVolume","genSearchersMapCommon","onlyEnabledRegions","forceSearchersKeys","searcher","searcherI","region","regionI","searcherKey","serarcherByKey","getRegionGlobal","findRegion","searchRegion","findedRegion","useSelectSearcher","mapSearchers","i18n","optionBySearcherKey","res","option","utils_searchers","useSelectRegion","activeSearcherIndexed","regionIndex","_c","optionByRegionIndex","options","regionLabel","langLabel","optionByRegionIndex2","newRegionIndex","regionName","_a","oldOptionByRegionIndex","index","title","regionNameCompare","regexpDevice","regionMatchLevelI","regionMatchLevel","regionsIndexes","regionsIndexesSaved","compareSave","compareLoad","useSelectorRegion","selectSearcher","allRegionsIndexes","compare","newSearcherKey","selectRegion","regionsNewSearcher","regionsCurrentSearcher","_d","regionKey","getSearcherKey","getSearcher","getRegionIndex","emit","modelSingle","model","defaultKey","newModel","defaultIndex","all","newSearherKey","__expose","tagsDefaults","genTagIdExcluded","tagId","genTagIdClear","getTagById","tags","tag","tag2","elName","firefoxProps","inEdit","event","name2","editCancel","changeSelect","e","toState","name","id","filtersAction","tagsText","target","emitDebounce","disabled","genTargetTagState","updateTargetModel","action","tagIdExcluded","tagsIds","tagId2","aIndex","a","bIndex","b","classString","tagName","onOpen","popupEvent","_e","ui","$tags","tagsSorted","tagSorted","tagIdA","tagIdB","onClose","useItemsFromCompetitors","competitors","projectId","competitor","genElPopupOpener","propsPopup","htmlSetterSeveral","el","utils_dom","elPopupOpenerRender","modelValue","renderElPopupOpener","elTagIcon","genElTagIcon","_b","TopSelectorCompetitors","_sfc_main$5","TopSelectorRegion","_sfc_main$4","TopTagSelector","_sfc_main","TopTagSelectorPopupOpener","_sfc_main$1","TopTagSelectorTagIcon","_sfc_main$3"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { Core as Te } from "../core/app.js";
2
- import { defineComponent as P, mergeModels as O, useModel as D, computed as M, openBlock as x, createElementBlock as w, unref as h, createBlock as B, withCtx as b, createVNode as A, createTextVNode as z, toDisplayString as K, Fragment as Y, renderList as ie, normalizeClass as Q, createElementVNode as ye, ref as F, watch as L, createCommentVNode as q, withModifiers as j, mergeProps as pe, withKeys as de, nextTick as be, resolveDirective as Be, withDirectives as Ve, resolveDynamicComponent as we, renderSlot as Me, reactive as $e, shallowRef as Ee, createSlots as Ke, toValue as ue, isRef as ce } from "vue";
3
- import { a as R, C as J, _ as W, y as re, r as Le } from "../.chunks/forms-DDIlFXbF.es.js";
4
- import { _ as he, b as se, a as Ae } from "../.chunks/listItem.vue_vue_type_script_setup_true_lang-3UaZvDrd.es.js";
5
- import { _ as Oe } from "../.chunks/menu.vue_vue_type_style_index_0_lang-C4q81rOQ.es.js";
2
+ import { defineComponent as P, mergeModels as O, useModel as D, computed as M, createElementBlock as w, openBlock as x, createBlock as B, unref as h, withCtx as b, Fragment as W, renderList as ie, normalizeClass as Q, createElementVNode as ye, toDisplayString as K, createVNode as A, createTextVNode as z, ref as F, watch as L, createCommentVNode as q, withModifiers as j, mergeProps as pe, withKeys as de, nextTick as be, resolveDirective as Be, withDirectives as Ve, resolveDynamicComponent as we, renderSlot as Me, shallowRef as $e, createSlots as Ee, reactive as Ke, toValue as ue, isRef as ce } from "vue";
3
+ import { a as R, C as J, _ as Y, x as re, s as Le } from "../.chunks/forms-BciWy0wX.es.js";
4
+ import { _ as he, a as se, b as Ae } from "../.chunks/listItem.vue_vue_type_script_setup_true_lang-CZqS-tRD.es.js";
5
+ import { _ as Oe } from "../.chunks/menu.vue_vue_type_style_index_0_lang-yNOWbXpd.es.js";
6
6
  import { getSearcherGIcon as Re, getLangLabel as Ne, getDeviceGIcon as De } from "../utils/searchers.js";
7
7
  import { storage as G } from "../utils/dom.js";
8
8
  import { TopPopupWorker as Fe } from "../popup/worker.js";
@@ -32,7 +32,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
32
32
  return (l, o) => (x(), w("div", qe, [
33
33
  h(J).state.isMobile ? (x(), B(he, { key: 0 }, {
34
34
  opener: b(() => [
35
- A(W, {
35
+ A(Y, {
36
36
  class: "top-selectorCompetitors_opener",
37
37
  color: "theme",
38
38
  icon: "",
@@ -51,7 +51,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
51
51
  })
52
52
  ]),
53
53
  contentList: b(() => [
54
- (x(!0), w(Y, null, ie(l.items, (n, d) => {
54
+ (x(!0), w(W, null, ie(l.items, (n, d) => {
55
55
  var g;
56
56
  return x(), B(se, {
57
57
  class: Q({
@@ -84,10 +84,8 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
84
84
  }), I = -2, je = {
85
85
  0: "Yandex",
86
86
  1: "Google",
87
- 2: "go.Mail",
88
87
  4: "YouTube",
89
88
  5: "Bing",
90
- 6: "Yahoo",
91
89
  7: "Seznam",
92
90
  8: "AppStore",
93
91
  9: "GoogleStore",
@@ -121,7 +119,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
121
119
  name: "Without region"
122
120
  }, Je = () => (te.name = R().Common.Autoselect, te), ze = () => (Je(), ne.name = R().Common.Autoselect, console.log(ne), ne), Ge = () => (me.name = R().Keywords.Without_region, me), Ie = (e = !1, a = !1, i = []) => {
123
121
  let t;
124
- return e ? t = Ye(i) : t = xe(i), a && t.set(I, ze()), t.size || t.set(I, Se), t;
122
+ return e ? t = We(i) : t = xe(i), a && t.set(I, ze()), t.size || t.set(I, Se), t;
125
123
  }, xe = (e, a = !0, i = [], t = !1) => {
126
124
  const l = /* @__PURE__ */ new Map();
127
125
  return e.forEach((o) => {
@@ -142,7 +140,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
142
140
  };
143
141
  l.set(n.key, n);
144
142
  }), l;
145
- }, Ye = (e) => {
143
+ }, We = (e) => {
146
144
  const a = xe(e, !1, [0, 1], !0);
147
145
  if (a.has(2)) {
148
146
  const i = a.get(2);
@@ -153,7 +151,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
153
151
  const t = { ...Ge() };
154
152
  i.regionByIndex.set(t.index, t);
155
153
  }), a;
156
- }, We = (e, a, i = []) => {
154
+ }, Ye = (e, a, i = []) => {
157
155
  const t = Ie(e, !1, i);
158
156
  let l;
159
157
  return t.forEach((o) => {
@@ -306,7 +304,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
306
304
  if (e.onlySearcher || o.regionIndex.value === I) return;
307
305
  let r = o.regionIndex.value;
308
306
  if (e.forFrequency) {
309
- const m = o.regionIndex.value, y = We(e.forFrequency, { searcher_key: d(), key: m }, e.searchers);
307
+ const m = o.regionIndex.value, y = Ye(e.forFrequency, { searcher_key: d(), key: m }, e.searchers);
310
308
  r = y == null ? void 0 : y.index;
311
309
  }
312
310
  return r;
@@ -460,7 +458,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
460
458
  addChanger: k.addChanger,
461
459
  "data-top-icon": k.addRegionIcon ? "" : void 0
462
460
  }, null, 8, ["options", "modelValue", "name", "addChanger", "data-top-icon"])) : q("", !0),
463
- k.addCompare && !k.onlySearcher && h(d).searcherKey.value === -1 ? (x(), B(W, {
461
+ k.addCompare && !k.onlySearcher && h(d).searcherKey.value === -1 ? (x(), B(Y, {
464
462
  key: 1,
465
463
  name: "compare",
466
464
  onClick: C,
@@ -614,7 +612,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
614
612
  de(j(v, ["stop"]), ["esc"])
615
613
  ]
616
614
  }), K(l.value), 17, lt),
617
- m.editable ? (x(), w(Y, { key: 0 }, [
615
+ m.editable ? (x(), w(W, { key: 0 }, [
618
616
  d.value ? (x(), w("span", {
619
617
  key: 1,
620
618
  "data-top-icon": "",
@@ -651,7 +649,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
651
649
  }),
652
650
  emits: ["update:modelValue"],
653
651
  setup(e) {
654
- const a = e, i = D(e, "modelValue"), t = a.useTopButton ? W : "div", l = a.useTopButton ? "html" : "default", o = {
652
+ const a = e, i = D(e, "modelValue"), t = a.useTopButton ? Y : "div", l = a.useTopButton ? "html" : "default", o = {
655
653
  model: i,
656
654
  mode: a.mode,
657
655
  targetId: a.targetId,
@@ -684,7 +682,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
684
682
  }, null, 8, ["name"])) : q("", !0),
685
683
  n.mode === "setter" && n.filters ? (x(), w("div", ot, [
686
684
  Me(n.$slots, "default")
687
- ])) : (x(!0), w(Y, { key: 2 }, ie(i.value, (f) => {
685
+ ])) : (x(!0), w(W, { key: 2 }, ie(i.value, (f) => {
688
686
  var v, r;
689
687
  return x(), B(le, {
690
688
  id: h(H)(f),
@@ -721,7 +719,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
721
719
  },
722
720
  modelModifiers: {},
723
721
  tags: {
724
- default: $e(tt)
722
+ default: Ke(tt)
725
723
  },
726
724
  tagsModifiers: {}
727
725
  }),
@@ -736,7 +734,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
736
734
  const u = " " + ((c = i.Common.Tags) == null ? void 0 : c.toLowerCase()), s = /* @__PURE__ */ new Map();
737
735
  return s.set("add", { value: "add", title: i.Common.Add + u }), s.set("replace", { value: "replace", title: i.Common.Replace + u }), s.set("delete", { value: "delete", title: i.Common.Delete + u }), s;
738
736
  };
739
- let r = Ee({
737
+ let r = $e({
740
738
  model: l,
741
739
  mode: "filter",
742
740
  targetId: void 0,
@@ -810,7 +808,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
810
808
  var s;
811
809
  (s = J.$) != null && s.ui.sortable && $(u.elPopup).data("ui-sortable") && $(u.elPopup).sortable("destroy");
812
810
  };
813
- return (u, s) => (x(), w(Y, null, [
811
+ return (u, s) => (x(), w(W, null, [
814
812
  A(ke, {
815
813
  class: "top-select_arrow",
816
814
  modelValue: l.value,
@@ -826,7 +824,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
826
824
  onOpen: s[4] || (s[4] = (c) => _(c)),
827
825
  onClose: s[5] || (s[5] = (c) => T(c)),
828
826
  "transition-duration": 50
829
- }, Ke({
827
+ }, Ee({
830
828
  contentList: b(() => [
831
829
  h(r).mode === "filter" && !u.singleMode ? (x(), B(fe, {
832
830
  key: 0,
@@ -836,7 +834,7 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
836
834
  state: h(r).model.value.length ? "" : "selected",
837
835
  onSelect: s[3] || (s[3] = (c) => h(r).model.value = [])
838
836
  }, null, 8, ["name", "state"])) : q("", !0),
839
- (x(!0), w(Y, null, ie(o.value, (c) => (x(), B(fe, {
837
+ (x(!0), w(W, null, ie(o.value, (c) => (x(), B(fe, {
840
838
  key: c.id,
841
839
  id: c.id,
842
840
  colorId: c.color_id,
@@ -879,13 +877,13 @@ const qe = { class: "top-selectorCompetitors" }, Pe = { class: "top-ellipsis1" }
879
877
  h(r).mode === "setter" && h(r).filters ? {
880
878
  name: "footer",
881
879
  fn: b(() => [
882
- A(W, { color: "theme" }, {
880
+ A(Y, { color: "theme" }, {
883
881
  default: b(() => [
884
882
  z(K(u.$i18n.Common.Cancel), 1)
885
883
  ]),
886
884
  _: 1
887
885
  }),
888
- A(W, {
886
+ A(Y, {
889
887
  onClick: s[2] || (s[2] = (c) => h(d)("setter", {
890
888
  tagsIds: h(r).model.value,
891
889
  filters: h(r).filters,
@@ -968,7 +966,7 @@ export {
968
966
  St as TopTagSelector,
969
967
  It as TopTagSelectorPopupOpener,
970
968
  xt as TopTagSelectorTagIcon,
971
- We as findRegion,
969
+ Ye as findRegion,
972
970
  vt as genElTopTagSelectorPopupOpener,
973
971
  Ie as genSearcherByKey,
974
972
  yt as renderElTopTagSelectorPopupOpener,